class Mage( Level ): name = 'Mage' desc = 'Spellcasters who learn lunar, fire, and air magic.' requirements = { stats.INTELLIGENCE: 11, stats.PIETY: 3 } statline = stats.StatMod( { stats.PHYSICAL_ATTACK: 3, stats.MAGIC_ATTACK: 5, stats.MAGIC_DEFENSE: 5, \ stats.AWARENESS: 3 } ) spell_circles = ( spells.LUNAR, spells.FIRE, spells.AIR ) HP_DIE = 4 MP_DIE = 12 LEVELS_PER_GEM = 1 GEMS_PER_AWARD = 2 legal_equipment = ( items.DAGGER, items.STAFF, items.SLING, \ items.BULLET, items.CLOTHES, items.HAT, \ items.GLOVE, items.SANDALS, items.SHOES, \ items.BOOTS, items.CLOAK, items.WAND ) starting_equipment = ( items.staves.Quarterstaff, items.clothes.MageRobe, items.hats.MageHat ) TAGS = ( context.MTY_MAGE, context.GEN_KINGDOM,context.DES_LUNAR, context.DES_AIR,context.DES_FIRE )
class TowerShield(Item): true_name = "Tower Shield" true_desc = "" itemtype = SHIELD avatar_image = "avatar_shield.png" avatar_frame = 0 statline = stats.StatMod({stats.PHYSICAL_DEFENSE: 15}) mass = 215 DESC = { 15: "A very large steel shield.", \ 16: "A very large red and gold shield.", 17: "A very large wooden shield with golden decorations.", \ 18: "A very large dark green shield.", 19: "A very large shield with a spiral pattern.", \ 24: "A very large blue and white quartered shield.", 25: "A very large sky blue shield.", \ 26: "A very large green shield with a starburst design.", 30: "A very large and ornate steel shield." } def __init__(self): self.avatar_frame = random.choice((15, 16, 17, 18, 19, 24, 25, 26, 30)) self.true_desc = self.DESC[self.avatar_frame]
class Priest( Level ): name = 'Priest' desc = 'Priests learn water, solar, and air magic. They can also use a holy sign against undead.' requirements = { stats.PIETY: 11, stats.INTELLIGENCE: 3, stats.CHARISMA: 3 } statline = stats.StatMod( { stats.PHYSICAL_ATTACK: 4, stats.MAGIC_ATTACK: 4, stats.MAGIC_DEFENSE: 4, \ stats.HOLY_SIGN: 5, stats.AWARENESS: 3 } ) spell_circles = ( spells.WATER, spells.SOLAR, spells.AIR ) HP_DIE = 6 MP_DIE = 10 LEVELS_PER_GEM = 1 GEMS_PER_AWARD = 2 legal_equipment = ( items.MACE, items.STAFF, \ items.SHIELD, items.SLING, \ items.BULLET, items.CLOTHES, items.LIGHT_ARMOR, items.HAT, \ items.HELM, items.GLOVE, items.GAUNTLET, items.SANDALS, items.SHOES, \ items.BOOTS, items.CLOAK, items.HOLYSYMBOL ) starting_equipment = ( items.maces.FlangedMace, items.lightarmor.PaddedRobe, items.shoes.NormalBoots, items.holysymbols.WoodSymbol ) TAGS = ( context.MTY_PRIEST, context.GEN_KINGDOM,context.DES_SOLAR, context.DES_AIR,context.DES_WATER )
class Druid( Level ): name = 'Druid' desc = 'A natural spellcaster who learns earth, solar, and fire magic.' requirements = { stats.TOUGHNESS: 9, stats.INTELLIGENCE: 3, stats.PIETY: 11 } statline = stats.StatMod( { stats.PHYSICAL_ATTACK: 3, stats.MAGIC_ATTACK: 5, stats.MAGIC_DEFENSE: 4, \ stats.AWARENESS: 4 } ) spell_circles = ( spells.EARTH, spells.SOLAR, spells.FIRE ) HP_DIE = 6 MP_DIE = 12 LEVELS_PER_GEM = 1 GEMS_PER_AWARD = 2 legal_equipment = ( items.DAGGER, items.STAFF, \ items.BOW, items.POLEARM, items.ARROW, items.SLING, \ items.BULLET, items.CLOTHES, items.HAT, \ items.GLOVE, items.SANDALS, items.SHOES, \ items.BOOTS, items.CLOAK, items.FARMTOOL ) starting_equipment = ( items.farmtools.Sickle, items.clothes.DruidRobe, items.cloaks.NormalCloak ) TAGS = ( context.MTY_PRIEST, context.GEN_NATURE,context.DES_SOLAR, context.DES_FIRE,context.DES_EARTH )
class Thief(Level): name = 'Thief' desc = 'Highly skilled at stealth and disarming traps.' requirements = {stats.REFLEXES: 11, stats.INTELLIGENCE: 3} statline = stats.StatMod( { stats.PHYSICAL_ATTACK: 4, stats.MAGIC_ATTACK: 3, stats.MAGIC_DEFENSE: 5, \ stats.DISARM_TRAPS: 6, stats.STEALTH: 5, stats.AWARENESS: 4, stats.LOOTING: 5 } ) spell_circles = () HP_DIE = 6 MP_DIE = 4 LEVELS_PER_GEM = 0 legal_equipment = ( items.SWORD, items.DAGGER, items.STAFF, \ items.BOW, items.ARROW, items.SLING, \ items.BULLET, items.CLOTHES, items.LIGHT_ARMOR, \ items.HAT, items.GLOVE, items.SANDALS, \ items.SHOES, items.BOOTS, items.CLOAK, items.WAND ) starting_equipment = (items.hats.Bandana, items.daggers.Stiletto, items.lightarmor.PaddedArmor, items.cloaks.ThiefCloak) TAGS = (context.MTY_THIEF, )
class Ninja(Level): name = 'Ninja' desc = 'They have a chance to slay living targets in a single hit.' requirements = { stats.STRENGTH: 13, stats.TOUGHNESS: 13, stats.REFLEXES: 13, \ stats.INTELLIGENCE: 13, stats.PIETY: 13, stats.CHARISMA: 13 } statline = stats.StatMod( { stats.PHYSICAL_ATTACK: 4, stats.MAGIC_ATTACK: 2, \ stats.MAGIC_DEFENSE: 3, stats.DISARM_TRAPS: 4, stats.STEALTH: 5, \ stats.NATURAL_DEFENSE: 4, stats.CRITICAL_HIT: 5, stats.AWARENESS: 4 } ) spell_circles = () HP_DIE = 8 MP_DIE = 4 LEVELS_PER_GEM = 0 legal_equipment = ( items.SWORD, items.DAGGER, items.STAFF, \ items.CLOTHES, items.HAT, \ items.GLOVE, items.SANDALS, items.SHOES, \ items.BOOTS, items.CLOAK ) starting_equipment = (items.clothes.NinjaGear, items.swords.Wakizashi, items.hats.NinjaMask) TAGS = (context.MTY_THIEF, )
class Peasant(characters.Level): name = 'Peasant' desc = '' requirements = {} statline = stats.StatMod({ stats.PHYSICAL_ATTACK: 3, stats.NATURAL_DEFENSE: 3, stats.MAGIC_ATTACK: 3, stats.MAGIC_DEFENSE: 3, stats.AWARENESS: 4 }) HP_DIE = 6 MP_DIE = 4 XP_VALUE = 50 legal_equipment = ( items.MACE, items.DAGGER, items.STAFF, \ items.BOW, items.ARROW, items.SHIELD, items.SLING, \ items.BULLET, items.CLOTHES, items.HAT, \ items.GLOVE, items.SANDALS, items.SHOES, items.BOOTS, items.CLOAK ) starting_equipment = (items.clothes.PeasantGarb, items.maces.Club) TAGS = (context.GEN_KINGDOM, )
class Innkeeper(characters.Level): name = 'Innkeeper' desc = '' requirements = {stats.PIETY: 7, stats.CHARISMA: 7} statline = stats.StatMod({ stats.PHYSICAL_ATTACK: 4, stats.NATURAL_DEFENSE: 4, stats.MAGIC_ATTACK: 3, stats.MAGIC_DEFENSE: 4, stats.AWARENESS: 4 }) HP_DIE = 8 MP_DIE = 4 XP_VALUE = 100 legal_equipment = ( items.SWORD, items.AXE, items.MACE, items.DAGGER, items.STAFF, \ items.BOW, items.ARROW, items.SLING, \ items.BULLET, items.CLOTHES, items.HAT, \ items.GLOVE, items.SANDALS, items.SHOES, \ items.BOOTS, items.CLOAK, items.WAND ) starting_equipment = (items.clothes.NormalClothes, items.daggers.Dirk)
class Necromancer(Level): name = 'Necromancer' desc = 'Wizards who explore the secrets of life and death. They learn lunar, earth, and water magic.' requirements = {stats.INTELLIGENCE: 13, stats.PIETY: 13} statline = stats.StatMod( { stats.PHYSICAL_ATTACK: 3, stats.MAGIC_ATTACK: 5, stats.MAGIC_DEFENSE: 5, \ stats.AWARENESS: 3 } ) spell_circles = (spells.LUNAR, spells.EARTH, spells.WATER) HP_DIE = 4 MP_DIE = 14 LEVELS_PER_GEM = 1 GEMS_PER_AWARD = 2 legal_equipment = ( items.DAGGER, items.STAFF, items.SLING, \ items.BULLET, items.CLOTHES, items.HAT, \ items.GLOVE, items.SANDALS, items.SHOES, \ items.BOOTS, items.CLOAK, items.WAND, items.FARMTOOL ) starting_equipment = (items.staves.Quarterstaff, items.clothes.NecromancerRobe, items.hats.NecromancerHat) TAGS = (context.MTY_MAGE, context.GEN_UNDEAD, context.DES_LUNAR, context.DES_EARTH, context.DES_WATER)
class HolyBow(Enhancer): NAMEPAT = "Holy {0}" DESCPAT = "{0} A hit from this weapon may disrupt unholy creatures." PLUSRANK = 5 AFFECTS = (BOW, SLING) ATTACK_ON_HIT = effects.TargetIs( effects.UNHOLY, on_true=(effects.OpposedRoll( att_stat=stats.PIETY, att_modifier=-10, on_success=(effects.InstaKill(anim=animobs.CriticalHit), ), on_failure=(effects.OpposedRoll( att_modifier=10, on_success=(effects.Paralyze(max_duration=3), ), ), ), ), )) BONUSES_PER_RANK = stats.StatMod({ stats.PHYSICAL_ATTACK: 10, stats.RESIST_LUNAR: 25 }) TYPE = ET_SECONDARY
class Elder(characters.Level): name = 'Elder' desc = 'The person will will probably give you a quest or something.' requirements = { stats.TOUGHNESS: 8, stats.REFLEXES: 8, stats.INTELLIGENCE: 13, stats.PIETY: 13, stats.CHARISMA: 13 } statline = stats.StatMod( { stats.PHYSICAL_ATTACK: 3, stats.MAGIC_ATTACK: 5, stats.MAGIC_DEFENSE: 5, \ stats.NATURAL_DEFENSE: 5, stats.AWARENESS: 3 } ) spell_circles = (spells.SOLAR, spells.FIRE, spells.AIR, spells.WATER, spells.EARTH) HP_DIE = 4 MP_DIE = 16 LEVELS_PER_GEM = 1 GEMS_PER_AWARD = 2 legal_equipment = ( items.STAFF, items.CLOTHES, \ items.GLOVE, items.SANDALS, items.SHOES, \ items.BOOTS, items.CLOAK ) starting_equipment = (items.staves.Quarterstaff, items.clothes.MageRobe)
class Bard(Level): name = 'Bard' desc = 'Jacks of all trades, bards know a bit of fighting, thievery, and air magic.' requirements = { stats.REFLEXES: 13, stats.INTELLIGENCE: 11, stats.CHARISMA: 13 } statline = stats.StatMod( { stats.PHYSICAL_ATTACK: 5, stats.MAGIC_ATTACK: 5, stats.MAGIC_DEFENSE: 4, \ stats.DISARM_TRAPS: 4, stats.AWARENESS: 4 } ) spell_circles = (spells.AIR, ) HP_DIE = 8 MP_DIE = 8 LEVELS_PER_GEM = 2 legal_equipment = ( items.SWORD, items.MACE, items.DAGGER, items.STAFF, \ items.BOW, items.ARROW, items.SLING, \ items.BULLET, items.CLOTHES, items.LIGHT_ARMOR, items.HAT, \ items.GLOVE, items.SANDALS, items.SHOES, \ items.BOOTS, items.CLOAK, items.WAND ) starting_equipment = (items.swords.Rapier, items.hats.JauntyHat, items.lightarmor.LeatherArmor) TAGS = (context.DES_AIR, context.GEN_KINGDOM)
class Ranger(Level): name = 'Ranger' desc = 'Stealthy warriors with limited earth magic.' requirements = { stats.STRENGTH: 11, stats.REFLEXES: 13, stats.INTELLIGENCE: 11 } statline = stats.StatMod( { stats.PHYSICAL_ATTACK: 4, stats.MAGIC_ATTACK: 4, stats.MAGIC_DEFENSE: 3, \ stats.DISARM_TRAPS: 3, stats.STEALTH: 4, stats.AWARENESS: 5 } ) spell_circles = (spells.EARTH, ) HP_DIE = 8 MP_DIE = 6 LEVELS_PER_GEM = 3 legal_equipment = ( items.SWORD, items.AXE, items.MACE, items.DAGGER, items.STAFF, \ items.BOW, items.POLEARM, items.ARROW, items.SHIELD, items.SLING, \ items.BULLET, items.CLOTHES, items.LIGHT_ARMOR, items.HAT, \ items.GLOVE, items.GAUNTLET, items.SANDALS, items.SHOES, \ items.BOOTS, items.CLOAK, items.FARMTOOL ) starting_equipment = (items.axes.HandAxe, items.lightarmor.RangerArmor, items.hats.WoodsmansHat, items.shoes.NormalBoots) TAGS = (context.MTY_FIGHTER, context.GEN_NATURE, context.DES_EARTH)
class Merchant(characters.Level): name = 'Merchant' desc = '' requirements = {stats.INTELLIGENCE: 7, stats.CHARISMA: 7} statline = stats.StatMod({ stats.PHYSICAL_ATTACK: 4, stats.NATURAL_DEFENSE: 4, stats.MAGIC_ATTACK: 3, stats.MAGIC_DEFENSE: 4, stats.AWARENESS: 4 }) HP_DIE = 8 MP_DIE = 4 XP_VALUE = 100 legal_equipment = ( items.SWORD, items.AXE, items.MACE, items.DAGGER, items.STAFF, \ items.BOW, items.ARROW, items.SLING, \ items.BULLET, items.CLOTHES, items.HAT, \ items.GLOVE, items.SANDALS, items.SHOES, \ items.BOOTS, items.CLOAK, items.WAND ) starting_equipment = (items.clothes.MerchantGarb, items.daggers.Dirk) FRIENDMOD = {characters.Thief: -3, characters.Ninja: -3} TAGS = (context.GEN_KINGDOM, )
class HolyWeapon(Enhancer): NAMEPAT = "Holy {0}" DESCPAT = "{0} It does an extra 1d8 holy damage and disrupts unholy creatures." PLUSRANK = 5 AFFECTS = (SWORD, AXE, MACE, DAGGER, STAFF, POLEARM, FARMTOOL, LANCE) ATTACK_ON_HIT = effects.HealthDamage( (1, 8, 0), stat_bonus=None, element=stats.RESIST_SOLAR, anim=animobs.YellowExplosion, on_success=(effects.TargetIs( effects.UNHOLY, on_true=(effects.OpposedRoll( att_stat=stats.PIETY, att_modifier=-20, on_success=(effects.InstaKill(anim=animobs.CriticalHit), ), on_failure=(effects.OpposedRoll(on_success=(effects.Paralyze( max_duration=3), ), ), )), )), )) BONUSES_PER_RANK = stats.StatMod({ stats.PHYSICAL_ATTACK: 5, stats.RESIST_LUNAR: 25 }) TYPE = ET_SECONDARY
class Monk(Level): name = 'Monk' desc = 'Experts at unarmed fighting.' requirements = { stats.STRENGTH: 10, stats.TOUGHNESS: 15, stats.REFLEXES: 13, stats.PIETY: 13 } statline = stats.StatMod( { stats.PHYSICAL_ATTACK: 5, stats.MAGIC_ATTACK: 3, stats.MAGIC_DEFENSE: 4, \ stats.KUNG_FU: 5, stats.NATURAL_DEFENSE: 4, stats.AWARENESS: 4 } ) spell_circles = () HP_DIE = 8 MP_DIE = 6 LEVELS_PER_GEM = 0 legal_equipment = ( items.DAGGER, items.STAFF, \ items.BOW, items.ARROW, items.SLING, \ items.BULLET, items.CLOTHES, items.HAT, \ items.GLOVE, items.SANDALS, items.SHOES, \ items.BOOTS, items.CLOAK ) starting_equipment = (items.clothes.MonkRobe, items.hats.Headband, items.staves.Quarterstaff, items.shoes.NormalSandals) TAGS = (context.MTY_PRIEST, )
class Samurai(Level): name = 'Samurai' desc = "Mystic warriors. They gain fire magic but can't use heavy armor or missile weapons." requirements = { stats.STRENGTH: 15, stats.REFLEXES: 11, stats.INTELLIGENCE: 13, stats.PIETY: 11 } statline = stats.StatMod( { stats.PHYSICAL_ATTACK: 5, stats.MAGIC_ATTACK: 4, stats.MAGIC_DEFENSE: 4, \ stats.KUNG_FU: 2, stats.AWARENESS: 3 } ) spell_circles = (spells.FIRE, ) HP_DIE = 10 MP_DIE = 6 LEVELS_PER_GEM = 2 legal_equipment = ( items.SWORD, items.AXE, items.MACE, items.DAGGER, items.STAFF, \ items.POLEARM, items.SHIELD, \ items.CLOTHES, items.LIGHT_ARMOR, items.HAT, \ items.HELM, items.GLOVE, items.GAUNTLET, items.SANDALS, items.SHOES, \ items.BOOTS, items.CLOAK ) starting_equipment = (items.swords.Wakizashi, items.lightarmor.LeatherCuirass, items.shoes.NormalBoots) TAGS = (context.MTY_FIGHTER, context.DES_FIRE)
class FireGlove(Enhancer): NAMEPAT = "{0} of Fire" DESCPAT = "{0} The user may project an arc of fire from the fingertips." PLUSRANK = 4 AFFECTS = (GLOVE, GAUNTLET) BONUSES_PER_RANK = stats.StatMod({stats.RESIST_FIRE: 15}) TYPE = ET_PRIMARY TECH = (invocations.Invocation("Flamethrower", effects.OpposedRoll( att_skill=stats.PHYSICAL_ATTACK, att_stat=stats.REFLEXES, def_stat=stats.REFLEXES, on_success=(effects.HealthDamage( (2, 5, 0), stat_bonus=stats.TOUGHNESS, element=stats.RESIST_FIRE, anim=animobs.RedCloud), ), on_failure=(effects.HealthDamage( (1, 6, 0), stat_bonus=None, element=stats.RESIST_FIRE, anim=animobs.RedCloud), )), com_tar=targetarea.Cone(reach=4), ai_tar=invocations.TargetEnemy()), )
class Knight(Level): name = 'Knight' desc = 'Blessed warrior with limited solar magic.' requirements = { stats.STRENGTH: 11, stats.TOUGHNESS: 11, stats.PIETY: 17, stats.CHARISMA: 13 } statline = stats.StatMod( { stats.PHYSICAL_ATTACK: 5, stats.MAGIC_ATTACK: 3, stats.MAGIC_DEFENSE: 5, \ stats.RESIST_LUNAR: 3, stats.AWARENESS: 2 } ) spell_circles = (spells.SOLAR, ) HP_DIE = 10 MP_DIE = 4 LEVELS_PER_GEM = 3 legal_equipment = ( items.SWORD, items.MACE, \ items.SHIELD, \ items.CLOTHES, items.LIGHT_ARMOR, items.HEAVY_ARMOR, items.HAT, \ items.HELM, items.GLOVE, items.GAUNTLET, items.SANDALS, items.SHOES, \ items.BOOTS, items.CLOAK, items.LANCE ) starting_equipment = (items.swords.Longsword, items.lightarmor.BrigandineArmor, items.shoes.NormalBoots) TAGS = (context.MTY_FIGHTER, context.GEN_KINGDOM, context.DES_SOLAR)
class ShinyShield(Enhancer): NAMEPAT = "Shiny {0}" DESCPAT = "{0} It provides a bonus to aura." PLUSRANK = 1 AFFECTS = (SHIELD, ) BONUSES_PER_RANK = stats.StatMod({stats.MAGIC_DEFENSE: 5})
class HurthlingSling(Enhancer): NAMEPAT = "Hurthling {0}" DESCPAT = "{0} It gives +5% to attack." PLUSRANK = 1 AFFECTS = (SLING, ) BONUSES_PER_RANK = stats.StatMod({stats.PHYSICAL_ATTACK: 5})
class HandyGlove(Enhancer): NAMEPAT = "Handy {0}" DESCPAT = "{0} They provide a bonus to disarm traps." PLUSRANK = 1 AFFECTS = (GLOVE, GAUNTLET) BONUSES_PER_RANK = stats.StatMod({stats.DISARM_TRAPS: 10})
class ElvenBow(Enhancer): NAMEPAT = "Elven {0}" DESCPAT = "{0} Its elegant craftsmanship provides +5% to attack." PLUSRANK = 1 AFFECTS = (BOW, ) BONUSES_PER_RANK = stats.StatMod({stats.PHYSICAL_ATTACK: 5})
class Enhancer(object): NAMEPAT = "Enhanced {0}" DESCPAT = "{0}" PLUSRANK = 2 # Upranks- lists point costs of subsequent upgrades UPRANKS = () # Upgrades- Dict of upgrades activated at particular ranks UPGRADES = {} AFFECTS = () BONUSES_PER_RANK = stats.StatMod() TYPE = ET_CRAFT FREQUENCY = 10 # Attack Enhancements- for weapons & ammo only ATTACK_ON_HIT = None # Techniques- list of invocations TECH = () def __init__(self, item, points=1, primary=True): # Determine the _rank of this enhancement. self._rank = 1 points -= self.PLUSRANK self._secondary = None if primary and points > 0: s = select_enhancer(item, points, (self.TYPE + 1, )) if s: self._secondary = s(item, points, False) points -= self._secondary.PLUSRANK # Spend any remaining points on upranks. self.spend_points(points) @classmethod def can_enchant(self, item, points=0): return (self.PLUSRANK <= points) and item.itemtype in self.AFFECTS def get_stat(self, stat): it = self.BONUSES_PER_RANK.get(stat, 0) * self._rank if self._secondary: it += self._secondary.get_stat(stat) return it def spend_points(self, points): candidates = [ self, ] if self._secondary: candidates.append(self._secondary) while candidates and points > 0: a = random.choice(candidates) ok, points = a.upgrade(points) if not ok: candidates.remove(a) # Record leftover points for later. self.xp = points def upgrade(self, points): """Upgrade this enhancer if possible; return a tuple telling whether an upgrade was applied and the number of points remaining.""" opoints = points if self.can_be_upgraded() and points >= self.UPRANKS[self._rank - 1]: points -= self.UPRANKS[self._rank - 1] self.PLUSRANK += self.UPRANKS[self._rank - 1] self._rank += 1 # Apply the upgrade for this rank. ug = self.UPGRADES.get(self._rank) if ug: ug(self) return (opoints != points, points) def can_be_upgraded(self): """Return True if this enhancer still has intrinsic upgrades left.""" return len(self.UPRANKS) >= self._rank def get_name(self, it): if self._secondary: basename = self._secondary.get_name(it) return self.NAMEPAT.format(basename, basename, self._rank) return self.NAMEPAT.format(it.true_name, it.itemtype.name, self._rank) def modify_desc(self, odesc): if self._secondary: odesc = self._secondary.modify_desc(odesc) return self.DESCPAT.format(odesc) def cost(self): return 250 * self.min_rank() def min_rank(self): it = self.PLUSRANK if self._secondary: it += self._secondary.min_rank() return it def modify_attack(self, fx, pc): pc.add_attack_enhancements(fx, self) if self._secondary: self._secondary.modify_attack(fx, pc)
class Item(stats.PhysicalThing): true_name = "Item" true_desc = "" statline = stats.StatMod() itemtype = GENERIC identified = True attackdata = None avatar_image = None avatar_frame = 0 mass = 1 equipped = False enhancement = None def cost(self, include_enhancement=True, include_adjust=True): it = 1 if self.statline: it += self.statline.cost() if self.attackdata: it += self.attackdata.cost() if include_adjust: it = int(it * self.itemtype.cost_adjust) if self.enhancement and include_enhancement: it += self.enhancement.cost() return it def stamp_avatar(self, avatar, pc): """Apply this item's sprite to the avatar.""" if self.avatar_image: img = image.Image(self.avatar_image, 54, 54) img.render(avatar.bitmap, frame=self.avatar_frame) def is_better(self, other): """Check whether self is more expensive than other.""" if not other: return True else: try: return self.cost() >= other.cost() except AttributeError: # The other is apparently not an item, so this is obviously better. return True def get_stat(self, stat): it = self.statline.get(stat, 0) if self.enhancement: it += self.enhancement.get_stat(stat) return it def __str__(self): if self.identified: if self.enhancement: return self.enhancement.get_name(self) else: return self.true_name else: return "?{}".format(self.itemtype.name) def desc(self): if self.identified: msg = self.true_desc if self.enhancement: msg = self.enhancement.modify_desc(msg) return msg else: return "???" def stat_desc(self): """Return descriptions of all stat modifiers provided.""" smod = [] if self.attackdata: smod.append(self.attackdata.stat_desc()) for k in stats.PUBLIC_STATS: v = self.get_stat(k) if v: smod.append(str(k) + ":" + "{0:+}".format(v)) return ", ".join(smod) def can_attack(self, user): """Return True if this weapon can be used to attack right now.""" return True def spend_attack_price(self, user): """Spend this weapon's attack price.""" pass def min_rank(self): base_cost = self.cost(include_enhancement=False) mr = int( (-9 + math.sqrt(81 + 36 * base_cost * self.itemtype.rank_adjust)) / 18) if self.enhancement: mr += self.enhancement.min_rank() return mr @property def slot(self): return self.itemtype.slot
class SpikyGlove(Enhancer): NAMEPAT = "Spiky {0}" DESCPAT = "{0} They provide a +5% bonus to attack." PLUSRANK = 3 AFFECTS = (GLOVE, GAUNTLET) BONUSES_PER_RANK = stats.StatMod({stats.PHYSICAL_ATTACK: 5})
class ThiefCloak(NormalCloak): true_name = "Thief Cloak" true_desc = "A dark cloak to help you hide in shadows." avatar_frame = 4 statline = stats.StatMod({stats.STEALTH: 5, stats.RESIST_COLD: 5})
class FireproofCloak(NormalCloak): true_name = "Fireproof Cloak" true_desc = "A thick cloak made of a fireproof material." avatar_frame = 7 statline = stats.StatMod({stats.RESIST_COLD: 5, stats.RESIST_FIRE: 25})
class Evoca(Enhancer): NAMEPAT = "Evoca {0}" DESCPAT = "{0} It aids spellcasting, providing +5% to magic." PLUSRANK = 4 AFFECTS = (WAND, HOLYSYMBOL) BONUSES_PER_RANK = stats.StatMod({stats.MAGIC_ATTACK: 5})
class SturdyShield(Enhancer): NAMEPAT = "Sturdy {0}" DESCPAT = "{0} It is reinforced to provide an additional +5% to defense." PLUSRANK = 2 AFFECTS = (SHIELD, ) BONUSES_PER_RANK = stats.StatMod({stats.PHYSICAL_DEFENSE: 5})