Mercurial > rinkhals
view gamelib/equipment.py @ 553:7963fc09fac2
Make checkdialog take strings to show as input. Add possiblity of 3rd button on dialog
author | Neil Muller <drnlmuller@gmail.com> |
---|---|
date | Sat, 28 Nov 2009 17:45:28 +0000 |
parents | 05e0c3fd20ec |
children | 3ec614e6fd4a |
line wrap: on
line source
"""Stuff for animals to use.""" import random import sound import imagecache import animations import serializer class Equipment(serializer.Simplifiable): IS_EQUIPMENT = True DRAW_LAYER = 0 UNDER_LIMB = False UNDER_EYE = False AMMUNITION = None SIMPLIFY = [ '_buy_price', '_sell_price', '_name', 'ammunition', ] def __init__(self): self._buy_price = self.BUY_PRICE self._sell_price = self.SELL_PRICE self._name = self.NAME self.refresh_ammo() @classmethod def make(cls): """Override default Simplifiable object creation.""" return cls() def buy_price(self): return self._buy_price def sell_price(self): return self._sell_price def name(self): return self._name def images(self, eq_image_attr): eq_image_file = getattr(self, eq_image_attr, None) if not eq_image_file: return None eq_image_left = imagecache.load_image(eq_image_file) eq_image_right = imagecache.load_image(eq_image_file, ("right_facing",)) if eq_image_attr == "CHICKEN_IMAGE_FILE": # a bit hacky; eventually the chicken should have a stack of images and layering should take care of everything if self.UNDER_LIMB: wing_left = imagecache.load_image("sprites/wing.png") wing_right = imagecache.load_image("sprites/wing.png", ("right_facing",)) eq_image_left.blit(wing_left, (0,0)) eq_image_right.blit(wing_right, (0,0)) if self.UNDER_EYE: eye_left = imagecache.load_image("sprites/eye.png") eye_right = imagecache.load_image("sprites/eye.png", ("right_facing",)) eq_image_left.blit(eye_left, (0,0)) eq_image_right.blit(eye_right, (0,0)) return eq_image_left, eq_image_right, self.DRAW_LAYER def refresh_ammo(self): self.ammunition = getattr(self, 'AMMUNITION', None) class Weapon(Equipment): IS_WEAPON = True DRAW_LAYER = 10 UNDER_LIMB = True def _get_parameter(self, parameter, wielder): param = getattr(self, parameter) if wielder.abode: mod_attr = 'MODIFY_%s_%s' % (self.TYPE, parameter) modifier = getattr(wielder.abode.building, mod_attr, lambda r: r) param = modifier(param) return param def in_range(self, gameboard, wielder, target): """Can the lucky wielder hit the potentially unlucky target with this?""" return wielder.pos.dist(target.pos) <= self._get_parameter('RANGE', wielder) def hit(self, gameboard, wielder, target): """Is the potentially unlucky target actually unlucky?""" if self.ammunition is not None: if self.ammunition <= 0: # Out of ammunition, so we don't get to shoot. return else: self.ammunition -= 1 if hasattr(self, 'HIT_SOUND'): sound.play_sound(self.HIT_SOUND) if hasattr(self, 'ANIMATION'): self.ANIMATION(gameboard.tv, wielder) roll = random.randint(1, 100) base_hit = self._get_parameter('BASE_HIT', wielder) range_penalty = self._get_parameter('RANGE_PENALTY', wielder) return roll > (100-base_hit) + range_penalty*wielder.pos.dist(target.pos) def place(self, animal): for eq in animal.equipment: if is_weapon(eq): return False return True class Rifle(Weapon): TYPE = "GUN" NAME = "Rifle" BUY_PRICE = 100 SELL_PRICE = 75 AMMUNITION = 30 RANGE = 3 BASE_HIT = 55 RANGE_PENALTY = 15 HIT_SOUND = "fire-rifle.ogg" CHICKEN_IMAGE_FILE = 'sprites/equip_rifle.png' ANIMATION = animations.MuzzleFlash class SniperRifle(Weapon): TYPE = "GUN" NAME = "Sniper Rifle" BUY_PRICE = 150 SELL_PRICE = 100 AMMUNITION = 3 RANGE = 5 BASE_HIT = 80 RANGE_PENALTY = 10 HIT_SOUND = "fire-rifle.ogg" CHICKEN_IMAGE_FILE = 'sprites/equip_sniper_rifle.png' ANIMATION = animations.MuzzleFlash class Knife(Weapon): TYPE = "KNIFE" NAME = "Knife" BUY_PRICE = 25 SELL_PRICE = 15 RANGE = 1 BASE_HIT = 70 RANGE_PENALTY = 0 CHICKEN_IMAGE_FILE = 'sprites/equip_knife.png' class Axe(Weapon): TYPE = "AXE" NAME = "Axe" BUY_PRICE = 50 SELL_PRICE = 30 RANGE = 1 BASE_HIT = 35 RANGE_PENALTY = 0 CHICKEN_IMAGE_FILE = 'sprites/equip_axe.png' class Armour(Equipment): IS_ARMOUR = True DRAW_LAYER = 5 def __init__(self): super(Armour, self).__init__() self.hitpoints = self.STARTING_HITPOINTS def place(self, animal): for eq in animal.equipment: if eq.NAME == self.NAME: return False return True def survive_damage(self): self.hitpoints -= 1 if self.hitpoints > 0: self._sell_price = int(self._sell_price*self.hitpoints/float(self.hitpoints+1)) return True return False class Helmet(Armour): NAME = "Helmet" BUY_PRICE = 25 SELL_PRICE = 15 DRAW_LAYER = 6 STARTING_HITPOINTS = 1 CHICKEN_IMAGE_FILE = 'sprites/equip_helmet.png' UNDER_EYE = True class Kevlar(Armour): NAME = "Kevlar" BUY_PRICE = 100 SELL_PRICE = 75 STARTING_HITPOINTS = 2 CHICKEN_IMAGE_FILE = 'sprites/equip_kevlar.png' class Accoutrement(Equipment): """Things which are not equipment, but are displayed in the same way""" IS_EQUIPMENT = False IS_ACCOUTREMENT = True BUY_PRICE = 0 SELL_PRICE = 0 def place(self, animal): for eq in animal.accoutrements: if eq.NAME == self.NAME: return False return True class Spotlight(Accoutrement): NAME = "Spotlight" CHICKEN_IMAGE_FILE = 'sprites/select_chkn.png' DRAW_LAYER = -5 class Nest(Accoutrement): NAME = "Nest" CHICKEN_IMAGE_FILE = 'sprites/nest.png' DRAW_LAYER = 15 class NestEgg(Accoutrement): NAME = "Nestegg" CHICKEN_IMAGE_FILE = 'sprites/equip_egg.png' DRAW_LAYER = 14 def is_equipment(obj): """Return true if obj is a build class.""" return getattr(obj, "IS_EQUIPMENT", False) and hasattr(obj, "NAME") def is_weapon(obj): return is_equipment(obj) and getattr(obj, 'IS_WEAPON', False) def is_armour(obj): return is_equipment(obj) and getattr(obj, 'IS_ARMOUR', False) def is_accoutrement(obj): return not getattr(obj, "IS_EQUIPMENT", False) and hasattr(obj, "NAME") and getattr(obj, 'IS_ACCOUTREMENT', False) EQUIPMENT = [] for name in dir(): obj = eval(name) try: if is_equipment(obj): EQUIPMENT.append(obj) except TypeError: pass EQUIP_MAP = { # Map chicken level codes to equipment 1 : [], 2 : [Helmet], 3 : [Kevlar], 4 : [Knife], 5 : [Rifle], 6 : [Kevlar, Helmet], 7 : [Helmet, Knife], 8 : [Kevlar, Knife], 9 : [Kevlar, Helmet, Knife], 10 : [Helmet, Rifle], 11 : [Kevlar, Rifle], 12 : [Kevlar, Helmet, Rifle], 13 : [Axe], 14 : [Helmet, Axe], 15 : [Kevlar, Axe], 16 : [Kevlar, Helmet, Axe], }