File: storms.py

package info (click to toggle)
lightyears 1.4-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, buster, jessie, jessie-kfreebsd, sid, stretch
  • size: 1,324 kB
  • ctags: 454
  • sloc: python: 3,499; makefile: 2
file content (145 lines) | stat: -rw-r--r-- 4,132 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# 
# 20,000 Light Years Into Space
# This game is licensed under GPL v2, and copyright (C) Jack Whitham 2006-07.
# 

import math , pygame , random
from pygame.locals import *

import extra , particle , sound
from quiet_season import Quiet_Season
from primitives import *
from map_items import *


storm_sound = storm_graphics = None

def Init_Storms():
    # This is rather slow.
    global storm_graphics
    storm_graphics = particle.Make_Particle_Effect(particle.Storm_Particle)

    global storm_sound
    storm_sound = sound.Persisting_Sound("stormdmg", "stormbeeps")

class Storm_Season(Quiet_Season):
    def __init__(self, net, storm_difficulty):
        Quiet_Season.__init__(self, net)
        self.name = "Storm"
        self.storms = []
        self.storm_difficulty = storm_difficulty

        global storm_graphics
        assert ( storm_graphics != None )

    def Get_Period(self):
        return 20

    def Per_Period(self):
        self.storms.append(Storm(self.net, self.storm_difficulty))
        removal = []
        for (i, s) in enumerate(self.storms):
            if ( s.Is_Offscreen() ):
                removal.insert(0, i)
        for i in removal:
            self.storms.pop(i)

    def Draw(self, output, update_area):
        for s in self.storms:
            s.Draw(output, update_area)
            
    def Get_Extra_Info(self):
        return [] #[ ((255,0,0), 16, "Storms are coming!" )]

    def Per_Frame(self, frame_time):
        for s in self.storms:
            s.Think(frame_time)


class Storm:
    def __init__(self, net, difficulty):
        self.net = net
        self.difficulty = difficulty
        self.storm_frame = 0

        [a, b] = extra.Make_Quake_SF_Points(5)
        if ( random.randint(0,1) == 0 ):
            (a, b) = (b, a) # flip - ensures start point is not always on top or left

        (self.pos, dest) = (a, b)

        (sx,sy) = self.pos
        (tx,ty) = dest
        dx = tx - sx
        dy = ty - sy
       
        speed = (( random.random() * 1.5 ) + 0.6 ) * self.difficulty

        # Convert the overall displacement vector (dx,dy) into a velocity.
        distance = math.hypot(dx,dy)
        self.velocity = extra.Partial_Vector((0, 0), (dx, dy), (speed, distance))

        # How long does this storm live?
        self.countdown = distance / speed


    def Draw(self, output, update_area):
        global storm_graphics
        sfx = storm_graphics[ self.storm_frame ]

        r = sfx.get_rect()
        r.center = Grid_To_Scr(self.pos)
        (x, y) = r.topleft
        x = int(x)
        y = int(y)
        r.topleft = (x,y)
        #pygame.draw.rect(output, (255,255,255), r, 1)
        output.blit(sfx, r.topleft)
        update_area(r)

    def Think(self, frame_time):
        # Do damage to things within the storm
        (cx,cy) = self.pos
        cx = int(cx)
        cy = int(cy)

        dmg = STORM_DAMAGE * self.difficulty

        for x in range(cx - 1, cx + 2):
            for y in range(cy - 1, cy + 2):
                key = (x,y)

                global storm_sound

                if ( self.net.pipe_grid.has_key( key ) ):
                    for pipe in self.net.pipe_grid[ key ]:
                        if (( not pipe.Is_Destroyed() )
                        and ( pipe.Take_Damage(dmg) )):
                            self.net.Destroy(pipe, "storms")
                            storm_sound.Set(1.0)

                if ( self.net.ground_grid.has_key( key ) ):
                    node = self.net.ground_grid[ key ]

                    if (( not node.Is_Destroyed() )
                    and ( node.Take_Damage(dmg) )):
                        self.net.Destroy(node, "storms")
                        storm_sound.Set(1.0)

        # Move
        (x,y) = self.pos
        (dx,dy) = self.velocity
        dx *= frame_time
        dy *= frame_time
        #print (x,y),(dx,dy)
        self.pos = (x + dx, y + dy)

        global storm_graphics
        self.storm_frame = ( self.storm_frame + 1 ) % len(storm_graphics)

        self.countdown -= frame_time

    def Is_Offscreen(self):
        return ( self.countdown < 0 )