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 )
示例#2
0
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 )
示例#5
0
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, )
示例#6
0
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, )
示例#7
0
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, )
示例#8
0
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)
示例#9
0
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)
示例#10
0
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
示例#11
0
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)
示例#12
0
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)
示例#13
0
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)
示例#14
0
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, )
示例#15
0
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
示例#16
0
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, )
示例#17
0
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)
示例#18
0
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()), )
示例#19
0
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)
示例#20
0
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})
示例#21
0
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})
示例#22
0
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})
示例#23
0
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})
示例#24
0
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)
示例#25
0
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
示例#26
0
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})
示例#27
0
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})
示例#28
0
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})
示例#29
0
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})
示例#30
0
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})