source: gamelib/equipment.py @ 380:1586eccdefe4

Last change on this file since 380:1586eccdefe4 was 380:1586eccdefe4, checked in by Jeremy Thurgood <firxen@…>, 11 years ago

Ripped out legacy animation infrastructure in favour of layered sprites.

File size: 5.6 KB
Line 
1"""Stuff for animals to use."""
2
3import random
4import sound
5import imagecache
6import animations
7
8class Equipment(object):
9    IS_EQUIPMENT = True
10    DRAW_LAYER = 0
11    UNDER_LIMB = False
12    UNDER_EYE = False
13
14    def __init__(self):
15        self._buy_price = self.BUY_PRICE
16        self._sell_price = self.SELL_PRICE
17        self._name = self.NAME
18
19    def buy_price(self):
20        return self._buy_price
21
22    def sell_price(self):
23        return self._sell_price
24
25    def name(self):
26        return self._name
27
28    def images(self, eq_image_attr):
29        eq_image_file = getattr(self, eq_image_attr, None)
30        if not eq_image_file:
31            return None
32        eq_image_left = imagecache.load_image(eq_image_file)
33        eq_image_right = imagecache.load_image(eq_image_file, ("right_facing",))
34        if eq_image_attr == "CHICKEN_IMAGE_FILE":
35            # a bit hacky; eventually the chicken should have a stack of images and layering should take care of everything
36            if self.UNDER_LIMB:
37                wing_left = imagecache.load_image("sprites/wing.png")
38                wing_right = imagecache.load_image("sprites/wing.png", ("right_facing",))
39                eq_image_left.blit(wing_left, (0,0))
40                eq_image_right.blit(wing_right, (0,0))
41            if self.UNDER_EYE:
42                eye_left = imagecache.load_image("sprites/eye.png")
43                eye_right = imagecache.load_image("sprites/eye.png", ("right_facing",))
44                eq_image_left.blit(eye_left, (0,0))
45                eq_image_right.blit(eye_right, (0,0))
46        return eq_image_left, eq_image_right, self.DRAW_LAYER
47
48class Weapon(Equipment):
49    IS_WEAPON = True
50    DRAW_LAYER = 10
51    UNDER_LIMB = True
52
53    def _get_parameter(self, parameter, wielder):
54        param = getattr(self, parameter)
55        if wielder.abode:
56            mod_attr = 'MODIFY_%s_%s' % (self.TYPE, parameter)
57            modifier = getattr(wielder.abode.building, mod_attr, lambda r: r)
58            param = modifier(param)
59        return param
60
61    def in_range(self, gameboard, wielder, target):
62        """Can the lucky wielder hit the potentially unlucky target with this?"""
63        return wielder.pos.dist(target.pos) <= self._get_parameter('RANGE', wielder)
64
65    def hit(self, gameboard, wielder, target):
66        """Is the potentially unlucky target actually unlucky?"""
67        if hasattr(self, 'HIT_SOUND'):
68            sound.play_sound(self.HIT_SOUND)
69        if hasattr(self, 'ANIMATION'):
70            self.ANIMATION(gameboard.tv, wielder)
71        roll = random.randint(1, 100)
72        base_hit = self._get_parameter('BASE_HIT', wielder)
73        range_penalty = self._get_parameter('RANGE_PENALTY', wielder)
74        return roll > (100-base_hit) + range_penalty*wielder.pos.dist(target.pos)
75
76    def place(self, animal):
77        for eq in animal.equipment:
78            if is_weapon(eq):
79                return False
80        return True
81
82class Rifle(Weapon):
83    TYPE = "GUN"
84    NAME = "Rifle"
85    BUY_PRICE = 100
86    SELL_PRICE = 75
87
88    RANGE = 3
89    BASE_HIT = 55
90    RANGE_PENALTY = 15
91    HIT_SOUND = "fire-rifle.ogg"
92
93    CHICKEN_IMAGE_FILE = 'sprites/equip_rifle.png'
94
95    ANIMATION = animations.MuzzleFlash
96
97class Knife(Weapon):
98    TYPE = "KNIFE"
99    NAME = "Knife"
100    BUY_PRICE = 25
101    SELL_PRICE = 15
102
103    RANGE = 1
104    BASE_HIT = 70
105    RANGE_PENALTY = 0
106
107    CHICKEN_IMAGE_FILE = 'sprites/equip_knife.png'
108
109class Armour(Equipment):
110    IS_ARMOUR = True
111    DRAW_LAYER = 5
112
113    def __init__(self):
114        super(Armour, self).__init__()
115        self.hitpoints = self.STARTING_HITPOINTS
116
117    def place(self, animal):
118        for eq in animal.equipment:
119            if eq.NAME == self.NAME:
120                return False
121        return True
122
123    def survive_damage(self):
124        self.hitpoints -= 1
125        if self.hitpoints > 0:
126            self._sell_price = int(self._sell_price*self.hitpoints/float(self.hitpoints+1))
127            return True
128        return False
129
130class Helmet(Armour):
131    NAME = "Helmet"
132    BUY_PRICE = 25
133    SELL_PRICE = 15
134    DRAW_LAYER = 6
135
136    STARTING_HITPOINTS = 1
137
138    CHICKEN_IMAGE_FILE = 'sprites/equip_helmet.png'
139    UNDER_EYE = True
140
141class Kevlar(Armour):
142    NAME = "Kevlar"
143    BUY_PRICE = 100
144    SELL_PRICE = 75
145
146    STARTING_HITPOINTS = 2
147
148    CHICKEN_IMAGE_FILE = 'sprites/equip_kevlar.png'
149
150class Accoutrement(Equipment):
151    """Things which are not equipment, but are displayed in the same way"""
152    IS_EQUIPMENT = False
153    IS_ACCOUTREMENT = True
154    BUY_PRICE = 0
155    SELL_PRICE = 0
156
157    def place(self, animal):
158        for eq in animal.accoutrements:
159            if eq.NAME == self.NAME:
160                return False
161        return True
162
163class Spotlight(Accoutrement):
164    NAME = "Spotlight"
165    CHICKEN_IMAGE_FILE = 'sprites/select_chkn.png'
166    DRAW_LAYER = -5
167
168class Nest(Accoutrement):
169    NAME = "Nest"
170    CHICKEN_IMAGE_FILE = 'sprites/nest.png'
171    DRAW_LAYER = 15
172
173class NestEgg(Accoutrement):
174    NAME = "Nestegg"
175    CHICKEN_IMAGE_FILE = 'sprites/equip_egg.png'
176    DRAW_LAYER = 14
177
178def is_equipment(obj):
179    """Return true if obj is a build class."""
180    return getattr(obj, "IS_EQUIPMENT", False) and hasattr(obj, "NAME")
181
182def is_weapon(obj):
183    return is_equipment(obj) and getattr(obj, 'IS_WEAPON', False)
184
185def is_armour(obj):
186    return is_equipment(obj) and getattr(obj, 'IS_ARMOUR', False)
187
188def is_accoutrement(obj):
189    return not getattr(obj, "IS_EQUIPMENT", False) and hasattr(obj, "NAME") and getattr(obj, 'IS_ACCOUTREMENT', False)
190
191EQUIPMENT = []
192for name in dir():
193    obj = eval(name)
194    try:
195        if is_equipment(obj):
196            EQUIPMENT.append(obj)
197    except TypeError:
198        pass
Note: See TracBrowser for help on using the repository browser.