source: gamelib/equipment.py @ 198:355eaae40b1f

Last change on this file since 198:355eaae40b1f was 198:355eaae40b1f, checked in by Jeremy Thurgood <firxen@…>, 11 years ago

Buildings now affect weapon range and accuracy.

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