コード例 #1
0
 def release_spirit(self, explo):
     # Make a Charisma roll; if successful, get thanked by spirit.
     self.spirit_contained = False
     pc = explo.camp.party_spokesperson()
     spirit = self.elements["_MONSTER"]
     explo.alert("You release the seals on the jar. The spirit emerges...")
     self.elements["_SOURCE"].release_spirit()
     pos = explo.camp.scene.find_entry_point_in_rect(
         self.elements["_PUZZLE_ROOM"].area)
     spirit.place(explo.camp.scene, pos)
     explo.invoke_effect(effects.NoEffect(anim=animobs.PurpleSparkle), None,
                         (pos, ))
     charm_roll = random.randint(1, 100) + pc.get_stat_bonus(
         stats.CHARISMA) + pc.rank() * 4 - spirit.get_stat(
             stats.MAGIC_DEFENSE) - spirit.get_stat_bonus(stats.CHARISMA)
     if charm_roll > 74:
         # Congratulations! The spirit is grateful.
         reward = self.elements["_ITEM"]
         explo.alert(
             '''"Hello {}; my name is {}", it says. "I have been trapped in this place for so long. In thanks for releasing me, I give you this {}."'''
             .format(pc, spirit, reward))
         pc.contents.append(reward)
         explo.invoke_effect(effects.NoEffect(anim=animobs.YellowSparkle),
                             None, (pos, pc.pos))
         explo.camp.scene.contents.remove(spirit)
         self.active = False
         explo.check_trigger("WIN", self)
     else:
         # Whoops. This isn't a friendly spirit.
         explo.alert("It attacks!")
         explo.camp.activate_monster(spirit)
コード例 #2
0
class OgreLeader( base.Monster ):
    name = "Ogre Leader"
    statline = { stats.STRENGTH: 18, stats.TOUGHNESS: 18, stats.REFLEXES: 10, \
        stats.INTELLIGENCE: 10, stats.PIETY: 10, stats.CHARISMA: 5 }
    SPRITENAME = "monster_giants.png"
    FRAME = 4
    TEMPLATES = ()
    MOVE_POINTS = 10
    HABITAT = ( context.HAB_EVERY, context.HAB_FOREST,
     context.SET_EVERY, context.SET_RENFAN,
     context.MTY_HUMANOID, context.MTY_BOSS, context.MTY_LEADER, context.GEN_GIANT )
    ENC_LEVEL = 8
    TREASURE = treasuretype.High()
    LONER = True
    TECHNIQUES = ( invocations.Invocation( "Rock",
      effects.PhysicalAttackRoll( att_stat=stats.REFLEXES, on_success = (
        effects.HealthDamage( (1,10,2), stat_bonus=None, element=stats.RESIST_CRUSHING, anim=animobs.RedBoom )
      ,), on_failure = (
        effects.NoEffect( anim=animobs.SmallBoom )
      ,) ), com_tar=targetarea.SingleTarget(reach=6), shot_anim=animobs.SlingStone, ai_tar=invocations.TargetEnemy()
    ), )
    COMPANIONS = ( Ogre, OgreChamp, OgreShaman )
    ATTACK = items.Attack( (4,4,0), element = stats.RESIST_CRUSHING )
    def init_monster( self ):
        self.levels.append( base.Leader( 9, self ) )
コード例 #3
0
class CloudGiant( base.Monster ):
    name = "Cloud Giant"
    statline = { stats.STRENGTH: 31, stats.TOUGHNESS: 21, stats.REFLEXES: 9, \
        stats.INTELLIGENCE: 10, stats.PIETY: 14, stats.CHARISMA: 11 }
    SPRITENAME = "monster_giants.png"
    FRAME = 11
    TEMPLATES = (stats.FIRE,)
    MOVE_POINTS = 14
    HABITAT = ( context.HAB_EVERY,
     context.SET_EVERY,
     context.DES_FIRE,
     context.MTY_HUMANOID, context.MTY_FIGHTER, context.GEN_GIANT )
    ENC_LEVEL = 13
    TREASURE = treasuretype.HighItems()
    ATTACK = items.Attack( (4,6,0), element = stats.RESIST_CRUSHING )
    TECHNIQUES = ( invocations.Invocation( "Rock",
      effects.PhysicalAttackRoll( att_stat=stats.REFLEXES, on_success = (
        effects.HealthDamage( (2,8,0), stat_bonus=stats.STRENGTH, element=stats.RESIST_CRUSHING, anim=animobs.RedBoom ),
      ), on_failure = (
        effects.NoEffect( anim=animobs.SmallBoom )
      ,) ), com_tar=targetarea.SingleTarget(reach=10), shot_anim=animobs.SlingStone, ai_tar=invocations.TargetEnemy()
    ), )

    def init_monster( self ):
        self.levels.append( base.Humanoid( 15, self ) )
コード例 #4
0
class Bodak( base.Monster ):
    name = "Bodak"
    statline = { stats.STRENGTH: 13, stats.TOUGHNESS: 12, stats.REFLEXES: 15, \
        stats.INTELLIGENCE: 6, stats.PIETY: 12, stats.CHARISMA: 12,
        stats.RESIST_ACID: 75, stats.RESIST_LIGHTNING: 155 }
    SPRITENAME = "monster_undead.png"
    FRAME = 0
    TEMPLATES = (stats.UNDEAD,stats.DEMON)
    MOVE_POINTS = 8
    VOICE = None
    HABITAT = ( context.HAB_EVERY, context.SET_EVERY,
     context.MTY_UNDEAD, context.MTY_BOSS,
     context.DES_LUNAR, context.GEN_UNDEAD )
    ENC_LEVEL = 10
    TREASURE = None
    ATTACK = items.Attack( (1,8,0), element = stats.RESIST_CRUSHING)
    TECHNIQUES = ( invocations.MPInvocation( "Death Gaze",
      effects.OpposedRoll( att_stat=stats.CHARISMA, att_modifier=-10, on_success = (
        effects.InstaKill( anim=animobs.CriticalHit )
      ,), on_failure = (
        effects.NoEffect( anim=animobs.SmallBoom )
      ,) ), com_tar=targetarea.SingleTarget(reach=6), shot_anim=animobs.PurpleVortex, ai_tar=invocations.TargetEnemy(), mp_cost=10
    ),)
    def init_monster( self ):
        self.levels.append( base.Terror( 9, self ) )
コード例 #5
0
class Spark(base.Monster):
    name = "Spark"
    statline = { stats.STRENGTH: 13, stats.TOUGHNESS: 8, stats.REFLEXES: 14, \
        stats.INTELLIGENCE: 12, stats.PIETY: 6, stats.CHARISMA: 14,
        stats.RESIST_PIERCING: 50, stats.RESIST_CRUSHING: 50, stats.RESIST_SLASHING: 50 }
    SPRITENAME = "monster_by_Joe.png"
    FRAME = 4
    TEMPLATES = (stats.ELEMENTAL, stats.FIRE)
    MOVE_POINTS = 12
    HABITAT = (context.HAB_BUILDING, context.SET_EVERY, context.GEN_IGNAN,
               context.DES_FIRE, context.DES_SOLAR, context.MTY_ELEMENTAL,
               context.MTY_CELESTIAL)
    ENC_LEVEL = 3
    COMBAT_AI = aibrain.ArcherAI(approach_allies=0, technique_chance=75)
    ATTACK = items.Attack((1, 6, 0),
                          element=stats.RESIST_SOLAR,
                          hit_anim=animobs.OrangeExplosion,
                          extra_effect=abilities.BURN_ATTACK)
    TECHNIQUES = (invocations.Invocation(
        "Fire Bolt",
        effects.OpposedRoll(
            att_modifier=10,
            att_stat=stats.REFLEXES,
            def_stat=stats.REFLEXES,
            on_success=(effects.HealthDamage((1, 6, 0),
                                             stat_bonus=None,
                                             element=stats.RESIST_FIRE,
                                             anim=animobs.OrangeExplosion), ),
            on_failure=(effects.NoEffect(anim=animobs.SmallBoom), )),
        com_tar=targetarea.SingleTarget(reach=5),
        shot_anim=animobs.FireBolt,
        ai_tar=invocations.TargetEnemy()), )

    def init_monster(self):
        self.levels.append(base.Spellcaster(3, self))
コード例 #6
0
class Lamia( base.Monster ):
    name = "Lamia"    
    statline = { stats.STRENGTH: 18, stats.TOUGHNESS: 12, stats.REFLEXES: 15, \
        stats.INTELLIGENCE: 13, stats.PIETY: 15, stats.CHARISMA: 12 }
    SPRITENAME = "monster_default.png"
    FRAME = 2
    TEMPLATES = ()
    MOVE_POINTS = 10
    VOICE = dialogue.voice.GREEK
    HABITAT = ( context.HAB_EVERY, context.HAB_DESERT, context.SET_EVERY,
     context.DES_LUNAR,
     context.MTY_HUMANOID, context.MTY_BOSS )
    ENC_LEVEL = 7
    TREASURE = treasuretype.HighItems()
    ATTACK = items.Attack( (1,6,0), element = stats.RESIST_SLASHING, extra_effect=
        effects.StatDamage( stats.PIETY, amount=4, anim=animobs.GreenBoom )
    )
    TECHNIQUES = ( invocations.MPInvocation( "Spirit Drain",
        effects.TargetIsEnemy( on_true = (
            effects.OpposedRoll( on_success = (
                effects.ManaDamage( (1,8,0), stat_bonus=stats.TOUGHNESS, anim=animobs.PurpleExplosion ),
                effects.CauseSleep()
            ,), on_failure = (
                effects.ManaDamage( (1,8,0), stat_bonus=None, anim=animobs.PurpleExplosion )
        ,)),), on_false= (
            effects.NoEffect( anim=animobs.PurpleExplosion )
        ,)), com_tar=targetarea.Cone(reach=4), ai_tar=invocations.TargetEnemy(), mp_cost=12
      ), )
    def init_monster( self ):
        self.levels.append( base.Humanoid( 8, self ) )
コード例 #7
0
class CorpseEater( base.Monster ):
    name = "Corpse Eater"
    statline = { stats.STRENGTH: 12, stats.TOUGHNESS: 14, stats.REFLEXES: 8, \
        stats.INTELLIGENCE: 2, stats.PIETY: 12, stats.CHARISMA: 2 }
    SPRITENAME = "monster_default.png"
    FRAME = 13
    TEMPLATES = (stats.BUG,)
    MOVE_POINTS = 8
    VOICE = None
    HABITAT = ( context.HAB_EVERY, context.HAB_TUNNELS, context.SET_EVERY,
     context.MAP_DUNGEON,
     context.DES_LUNAR,
     context.MTY_BEAST )
    ENC_LEVEL = 4
    ATTACK = items.Attack( (3,4,0), element = stats.RESIST_PIERCING, extra_effect =
         effects.OpposedRoll( att_stat=stats.TOUGHNESS, on_success = (
            effects.Paralyze( max_duration = 6 )
        ,) )
     )
    TECHNIQUES = ( invocations.MPInvocation( "Tentacle Slime",
      effects.TargetIsEnemy( on_true = (
          effects.OpposedRoll( anim=animobs.GreenSplat, att_stat=stats.TOUGHNESS, on_success = (
            effects.Paralyze( max_duration = 3 )
          ,), on_failure = (
            effects.NoEffect( anim=animobs.SmallBoom )
          ,) ),
          )
      ), com_tar=targetarea.SelfCentered(radius=1,exclude_middle=True), ai_tar=invocations.TargetEnemy(), mp_cost=8 ), )
    def init_monster( self ):
        self.levels.append( base.Beast( 4, self ) )
コード例 #8
0
class EvilEye( base.Monster ):
    name = "Evil Eye"
    statline = { stats.STRENGTH: 6, stats.TOUGHNESS: 12, stats.REFLEXES: 12, \
        stats.INTELLIGENCE: 10, stats.PIETY: 10, stats.CHARISMA: 2, \
        stats.MAGIC_ATTACK: 20, stats.MAGIC_DEFENSE: 10 }
    SPRITENAME = "monster_default.png"
    FRAME = 18
    TEMPLATES = ()
    MOVE_POINTS = 6
    VOICE = None
    HABITAT = ( context.HAB_CAVE, context.HAB_TUNNELS, context.SET_EVERY,
     context.DES_LUNAR, context.MTY_BOSS,
     context.MTY_BEAST, context.GEN_CHAOS )
    ENC_LEVEL = 3
    ATTACK = items.Attack( (2,4,0), element = stats.RESIST_LUNAR,
     skill_mod=stats.REFLEXES, hit_anim=animobs.PurpleExplosion, extra_effect =
         effects.OpposedRoll( att_stat=stats.REFLEXES, def_stat=stats.REFLEXES, on_success = (
            effects.Paralyze( max_duration = 3 )
        ,) )
     )
    TECHNIQUES = ( invocations.MPInvocation( "Evil Gaze",
      effects.OpposedRoll( att_stat=stats.REFLEXES, def_stat=stats.REFLEXES, att_modifier=10, on_success = (
        effects.Paralyze( max_duration = 3 )
      ,), on_failure = (
        effects.NoEffect( anim=animobs.SmallBoom )
      ,) ), com_tar=targetarea.SingleTarget(reach=4), shot_anim=animobs.PurpleVortex,
      ai_tar=invocations.TargetMobileEnemy(), mp_cost=3
    ), )
    def init_monster( self ):
        self.levels.append( base.Beast( 3, self ) )
コード例 #9
0
class SwampDragonfly(base.Monster):
    name = "Swamp Dragonfly"
    statline = { stats.STRENGTH: 10, stats.TOUGHNESS: 9, stats.REFLEXES: 13, \
        stats.INTELLIGENCE: 1, stats.PIETY: 7, stats.CHARISMA: 1, \
        stats.RESIST_ACID: 150 }
    SPRITENAME = "monster_bugs.png"
    FRAME = 2
    TEMPLATES = (stats.BUG, )
    MOVE_POINTS = 14
    VOICE = None
    HABITAT = (context.HAB_FOREST, context.SET_EVERY, context.DES_EARTH,
               context.MTY_BEAST, context.MTY_CREATURE, context.GEN_DRAGON)
    ENC_LEVEL = 3

    ATTACK = items.Attack((1, 6, 0), element=stats.RESIST_PIERCING)

    TECHNIQUES = (invocations.MPInvocation(
        "Acid Breath",
        effects.OpposedRoll(
            att_skill=stats.PHYSICAL_ATTACK,
            att_stat=stats.REFLEXES,
            att_modifier=10,
            def_stat=stats.REFLEXES,
            on_success=(effects.HealthDamage((1, 6, 0),
                                             stat_bonus=None,
                                             element=stats.RESIST_ACID,
                                             anim=animobs.GreenExplosion), ),
            on_failure=(effects.NoEffect(anim=animobs.SmallBoom), )),
        com_tar=targetarea.SingleTarget(),
        shot_anim=animobs.GreenSpray,
        ai_tar=invocations.TargetEnemy(),
        mp_cost=3), )

    def init_monster(self):
        self.levels.append(base.Beast(2, self))
コード例 #10
0
    def get_effect(self, user, att_modifier=0, target=None):
        """Generate an effect tree for this attack."""
        dmg = list(self.damage)
        dmg[2] += user.get_stat(stats.WEAPON_DAMAGE_BONUS)
        hit = effects.HealthDamage(att_dice=dmg,
                                   stat_bonus=self.damage_mod,
                                   element=self.element,
                                   anim=self.hit_anim)
        if self.double_handed:
            hit.stat_mod = 1.5
        miss = effects.NoEffect(anim=animobs.SmallBoom)
        roll = effects.PhysicalAttackRoll(att_stat=self.skill_mod,
                                          att_modifier=att_modifier,
                                          on_success=[
                                              hit,
                                          ],
                                          on_failure=[
                                              miss,
                                          ])

        if self.extra_effect:
            roll.on_success.append(self.extra_effect)

        # If the attacker has critical hit skill, use it.
        if user.get_stat(stats.CRITICAL_HIT) > 0:
            hit.on_success.append(user.critical_hit_effect(att_modifier))

        return roll
コード例 #11
0
class SkeletonHunter( base.Monster ):
    name = "Skeleton Hunter"
    statline = { stats.STRENGTH: 14, stats.TOUGHNESS: 12, stats.REFLEXES: 16, \
        stats.INTELLIGENCE: 12, stats.PIETY: 12, stats.CHARISMA: 10,
        stats.NATURAL_DEFENSE: 10, stats.PHYSICAL_ATTACK: 5 }
    SPRITENAME = "monster_skeletons.png"
    FRAME = 9
    TEMPLATES = (stats.UNDEAD,stats.BONE)
    MOVE_POINTS = 8
    VOICE = None
    HABITAT = ( context.HAB_EVERY, context.SET_EVERY, context.SET_RENFAN,
     context.MTY_UNDEAD, context.MTY_HUMANOID, context.MTY_FIGHTER, context.MTY_BOSS, 
     context.DES_EARTH, context.GEN_UNDEAD )
    ENC_LEVEL = 6
    TREASURE = treasuretype.High((items.BOW,items.ARROW,items.ARROW))
    LONER = True
    COMPANIONS = (Shade,Ghast,SkeletonMage,SkeletonFighter,SkeletonThief,SkeletalHound)
    COMBAT_AI = aibrain.SteadyAI()
    ATTACK = items.Attack( (2,6,0), element = stats.RESIST_CRUSHING )
    TECHNIQUES = ( invocations.Invocation( "Arrow",
      effects.PhysicalAttackRoll( att_stat=stats.REFLEXES, on_success = (
        effects.HealthDamage( (1,8,0), stat_bonus=None, element=stats.RESIST_PIERCING, anim=animobs.RedBoom ),
        effects.TargetIs( effects.ANIMAL, on_true=(
            effects.PercentRoll( roll_skill=stats.MAGIC_ATTACK, roll_stat=None, 
            roll_modifier=-5, target_affects=True, on_success=(
                effects.InstaKill( anim=animobs.CriticalHit )
            ,) )
        ,) ) 
      ), on_failure = (
        effects.NoEffect( anim=animobs.SmallBoom )
      ,) ), com_tar=targetarea.SingleTarget(reach=8), shot_anim=animobs.Arrow, ai_tar=invocations.TargetEnemy()
    ), )

    def init_monster( self ):
        self.levels.append( base.Humanoid( 5, self ) )
コード例 #12
0
class ShieldOfBashing(Enhancer):
    NAMEPAT = "{0} of Bashing"
    DESCPAT = "{0} It may be used to bash enemies, doing 2d6 damage and potentially stunning them."
    PLUSRANK = 2
    AFFECTS = (SHIELD, )
    TECH = (invocations.MPInvocation(
        "Shield Bash",
        effects.PhysicalAttackRoll(
            att_stat=stats.STRENGTH,
            on_success=(
                effects.HealthDamage((2, 6, 0),
                                     stat_bonus=stats.STRENGTH,
                                     element=stats.RESIST_CRUSHING,
                                     stat_mod=2,
                                     anim=animobs.RedBoom),
                effects.OpposedRoll(
                    att_skill=stats.PHYSICAL_ATTACK,
                    def_stat=stats.TOUGHNESS,
                    on_success=(effects.Paralyze(max_duration=3), )),
            ),
            on_failure=(effects.NoEffect(anim=animobs.SmallBoom), )),
        com_tar=targetarea.SingleTarget(reach=1),
        ai_tar=invocations.TargetEnemy(),
        mp_cost=3), )
    TYPE = ET_SECONDARY
コード例 #13
0
class MageBlasterTrap(MultiTrap):
    NAME = "Mage Blaster"
    FX = effects.SavingThrow(
        on_success=(effects.NoEffect(anim=animobs.SmallBoom), ),
        on_failure=(effects.ManaDamage((10, 6, 0),
                                       stat_bonus=None,
                                       anim=animobs.PurpleSparkle), ),
        roll_modifier=-25)
    MIN_RANK = 5
    DIFFICULTY = 0
    ONE_SHOT = True
コード例 #14
0
class Manticore( base.Monster ):
    name = "Manticore"    
    statline = { stats.STRENGTH: 20, stats.TOUGHNESS: 19, stats.REFLEXES: 15, \
        stats.INTELLIGENCE: 7, stats.PIETY: 12, stats.CHARISMA: 9 }
    SPRITENAME = "monster_default.png"
    FRAME = 26
    TEMPLATES = ()
    MOVE_POINTS = 12
    HABITAT = ( context.HAB_EVERY, context.SET_EVERY,
     context.MAP_WILDERNESS, context.MTY_BEAST, context.MTY_BOSS )
    ENC_LEVEL = 7
    COMBAT_AI = aibrain.ArcherAI()
    TREASURE = treasuretype.Standard()
    ATTACK = items.Attack( (2,4,0), element = stats.RESIST_PIERCING, extra_effect=abilities.POISON_ATTACK )
    TECHNIQUES = (invocations.MPInvocation( "Tail Spikes",
        effects.NoEffect( children=(
          effects.PhysicalAttackRoll( att_stat=stats.REFLEXES, att_modifier=5, on_success = (
            effects.HealthDamage( (1,8,0), stat_bonus=stats.STRENGTH, element=stats.RESIST_PIERCING, anim=animobs.RedBoom ),
          ), on_failure = (
            effects.NoEffect( anim=animobs.SmallBoom ),
          )),
          effects.PhysicalAttackRoll( att_stat=stats.REFLEXES, att_modifier=5, on_success = (
            effects.HealthDamage( (1,8,0), stat_bonus=stats.STRENGTH, element=stats.RESIST_PIERCING, anim=animobs.RedBoom ),
          ), on_failure = (
            effects.NoEffect( anim=animobs.SmallBoom ),
          ) ),
          effects.PhysicalAttackRoll( att_stat=stats.REFLEXES, att_modifier=5, on_success = (
            effects.HealthDamage( (1,8,0), stat_bonus=stats.STRENGTH, element=stats.RESIST_PIERCING, anim=animobs.RedBoom ),
          ), on_failure = (
            effects.NoEffect( anim=animobs.SmallBoom ),
          ) ),
          effects.PhysicalAttackRoll( att_stat=stats.REFLEXES, att_modifier=5, on_success = (
            effects.HealthDamage( (1,8,0), stat_bonus=stats.STRENGTH, element=stats.RESIST_PIERCING, anim=animobs.RedBoom ),
          ), on_failure = (
            effects.NoEffect( anim=animobs.SmallBoom ),
          ) ),
        ),), mp_cost=10, com_tar=targetarea.SingleTarget(reach=9), shot_anim=animobs.GoldStone, ai_tar=invocations.TargetEnemy()
        ),
    )
    def init_monster( self ):
        self.levels.append( base.Beast( 6, self ) )
コード例 #15
0
class CrossbowTrap(SingleTrap):
    NAME = "Crossbow Bolt Trap"
    FX = effects.SavingThrow(
        on_success=(effects.NoEffect(anim=animobs.SmallBoom), ),
        on_failure=(effects.HealthDamage((2, 6, 0),
                                         stat_bonus=None,
                                         element=stats.RESIST_PIERCING,
                                         anim=animobs.RedBoom), ),
        roll_modifier=-5)
    MIN_RANK = 2
    DIFFICULTY = -15
    ONE_SHOT = True
コード例 #16
0
class BladeTrap(MultiTrap):
    NAME = "Blade Trap"
    FX = effects.SavingThrow(
        on_success=(effects.NoEffect(anim=animobs.SmallBoom), ),
        on_failure=(effects.HealthDamage((1, 6, 0),
                                         stat_bonus=None,
                                         element=stats.RESIST_SLASHING,
                                         anim=animobs.RedBoom), ),
        roll_modifier=20)
    MIN_RANK = 2
    DIFFICULTY = -15
    ONE_SHOT = True
コード例 #17
0
class BlockTrap(SingleTrap):
    NAME = "Stone Block Trap"
    FX = effects.SavingThrow(
        on_success=(effects.NoEffect(anim=animobs.SmallBoom), ),
        on_failure=(effects.HealthDamage((1, 6, 0),
                                         stat_bonus=None,
                                         element=stats.RESIST_CRUSHING,
                                         anim=animobs.RedBoom), ),
        roll_modifier=0)
    MIN_RANK = 1
    DIFFICULTY = -20
    ONE_SHOT = True
コード例 #18
0
class ShockTrap(SingleTrap):
    NAME = "Shocker Trap"
    FX = effects.SavingThrow(
        on_success=(effects.NoEffect(anim=animobs.SmallBoom), ),
        on_failure=(effects.HealthDamage((1, 8, 0),
                                         stat_bonus=None,
                                         element=stats.RESIST_LIGHTNING,
                                         anim=animobs.BlueZap), ),
        roll_modifier=-10)
    MIN_RANK = 3
    DIFFICULTY = -15
    ONE_SHOT = False
コード例 #19
0
class Avoral(base.Monster):
    name = "Avoral"
    statline = { stats.STRENGTH: 15, stats.TOUGHNESS: 20, stats.REFLEXES: 23, \
        stats.INTELLIGENCE: 15, stats.PIETY: 16, stats.CHARISMA: 16, \
        stats.AWARENESS: 65, stats.MAGIC_DEFENSE: 25 }
    SPRITENAME = "monster_celestial.png"
    FRAME = 12
    TEMPLATES = (stats.CELESTIAL, stats.AIR)
    MOVE_POINTS = 16
    HABITAT = (context.SET_EVERY, context.DES_SOLAR, context.DES_AIR,
               context.MTY_HUMANOID, context.MTY_CELESTIAL)
    ENC_LEVEL = 12
    COMBAT_AI = aibrain.ArcherAI()
    TREASURE = treasuretype.Standard()
    TECHNIQUES = (invocations.Invocation("Avoral Missile",
                                         effects.HealthDamage(
                                             (1, 8, 0),
                                             stat_bonus=stats.INTELLIGENCE,
                                             element=stats.RESIST_LUNAR,
                                             anim=animobs.PurpleExplosion),
                                         com_tar=targetarea.SingleTarget(),
                                         shot_anim=animobs.WizardMissile,
                                         ai_tar=invocations.TargetEnemy()),
                  invocations.Invocation(
                      "Hold Person",
                      effects.OpposedRoll(
                          att_modifier=20,
                          on_success=(effects.Paralyze(max_duration=3), ),
                          on_failure=(effects.NoEffect(
                              anim=animobs.SmallBoom), )),
                      com_tar=targetarea.SingleTarget(),
                      shot_anim=animobs.BlueComet,
                      ai_tar=invocations.TargetMobileEnemy()),
                  invocations.MPInvocation(
                      "Thunder Strike",
                      effects.OpposedRoll(on_success=(effects.HealthDamage(
                          (3, 6, 0),
                          stat_bonus=stats.INTELLIGENCE,
                          element=stats.RESIST_LIGHTNING,
                          anim=animobs.Spark), ),
                                          on_failure=(effects.HealthDamage(
                                              (1, 8, 0),
                                              stat_bonus=None,
                                              element=stats.RESIST_LIGHTNING,
                                              anim=animobs.Spark), )),
                      mp_cost=16,
                      com_tar=targetarea.Line(),
                      ai_tar=invocations.TargetEnemy()))
    ATTACK = items.Attack((2, 8, 0), element=stats.RESIST_SLASHING)

    def init_monster(self):
        self.levels.append(base.Terror(7, self))
コード例 #20
0
class PoisonNeedleTrap(SingleTrap):
    NAME = "Poison Needle"
    FX = effects.SavingThrow(
        on_success=(effects.NoEffect(anim=animobs.SmallBoom), ),
        on_failure=(effects.HealthDamage((1, 4, 0),
                                         stat_bonus=None,
                                         element=stats.RESIST_POISON,
                                         anim=animobs.PoisonCloud),
                    effects.Enchant(enchantments.PoisonClassic)),
        roll_modifier=-10)
    MIN_RANK = 4
    DIFFICULTY = -5
    ONE_SHOT = True
コード例 #21
0
class GasBombTrap(MultiTrap):
    NAME = "Gas Bomb"
    FX = effects.SavingThrow(
        roll_stat=stats.TOUGHNESS,
        on_success=(effects.NoEffect(anim=animobs.SmallBoom), ),
        on_failure=(effects.HealthDamage((2, 4, 0),
                                         stat_bonus=None,
                                         element=stats.RESIST_POISON,
                                         anim=animobs.PoisonCloud),
                    effects.Enchant(enchantments.PoisonClassic)),
        roll_modifier=0)
    MIN_RANK = 6
    DIFFICULTY = 5
    ONE_SHOT = True
コード例 #22
0
class Scarab(base.Monster):
    name = "Scarab"
    statline = { stats.STRENGTH: 13, stats.TOUGHNESS: 16, stats.REFLEXES: 14, \
        stats.INTELLIGENCE: 1, stats.PIETY: 12, stats.CHARISMA: 1,
        stats.RESIST_SOLAR: 50 }
    SPRITENAME = "monster_bugs.png"
    FRAME = 5
    TEMPLATES = (stats.BUG, )
    MOVE_POINTS = 8
    VOICE = None
    HABITAT = (context.HAB_TUNNELS, context.HAB_DESERT, context.SET_EVERY,
               context.DES_SOLAR, context.MTY_BEAST, context.MTY_CREATURE)
    ENC_LEVEL = 7
    TECHNIQUES = (invocations.MPInvocation(
        "Draining Breath",
        effects.TargetIsEnemy(
            on_true=(effects.OpposedRoll(
                att_skill=stats.PHYSICAL_ATTACK,
                att_stat=stats.REFLEXES,
                def_stat=stats.REFLEXES,
                on_success=(effects.HealthDamage(
                    (1, 8, 0),
                    stat_bonus=stats.TOUGHNESS,
                    element=stats.RESIST_FIRE,
                    anim=animobs.PurpleExplosion), ),
                on_failure=(effects.HealthDamage(
                    (1, 4, 0),
                    stat_bonus=None,
                    element=stats.RESIST_FIRE,
                    anim=animobs.PurpleExplosion), )), ),
            on_false=(effects.NoEffect(anim=animobs.PurpleExplosion), )),
        com_tar=targetarea.Cone(reach=4),
        ai_tar=invocations.TargetEnemy(),
        mp_cost=3), )
    ATTACK = items.Attack((1, 6, 0),
                          element=stats.RESIST_PIERCING,
                          extra_effect=abilities.POISON_ATTACK_2d6)

    def init_monster(self):
        self.levels.append(base.Beast(7, self))
コード例 #23
0
    def unarmed_attack_effect(self, roll_mod=0):
        """Return the attackdata for this character's unarmed strikes."""
        kungfu = self.get_stat(stats.KUNG_FU) // 5
        dbonus = 0
        if kungfu > 20:
            dbonus = kungfu - 20
            kungfu = 20
        dice = (self.KUNG_FU_DAMAGE[kungfu][0], self.KUNG_FU_DAMAGE[kungfu][1],
                dbonus)

        hit = effects.HealthDamage(att_dice=dice,
                                   stat_bonus=stats.STRENGTH,
                                   element=stats.RESIST_CRUSHING,
                                   anim=animobs.RedBoom)
        miss = effects.NoEffect(anim=animobs.SmallBoom)
        roll = effects.PhysicalAttackRoll(att_stat=stats.STRENGTH,
                                          att_modifier=roll_mod,
                                          on_success=[
                                              hit,
                                          ],
                                          on_failure=[
                                              miss,
                                          ])

        if self.KUNG_FU_DAMAGE[kungfu][2] > 0:
            dice = (self.KUNG_FU_DAMAGE[kungfu][2],
                    self.KUNG_FU_DAMAGE[kungfu][3], dbonus)
            hit2 = effects.HealthDamage(att_dice=dice,
                                        stat_bonus=stats.PIETY,
                                        element=stats.RESIST_SOLAR,
                                        anim=animobs.YellowExplosion)
            hit.on_success.append(hit2)
            hit.on_failure.append(hit2)

        # If the attacker has critical hit skill, use it.
        if self.get_stat(stats.CRITICAL_HIT) > 0:
            hit.on_success.append(self.critical_hit_effect(roll_mod))

        return roll
コード例 #24
0
class Basilisk( base.Monster ):
    name = "Basilisk"
    statline = { stats.STRENGTH: 15, stats.TOUGHNESS: 15, stats.REFLEXES: 8, \
        stats.INTELLIGENCE: 2, stats.PIETY: 12, stats.CHARISMA: 11 }
    SPRITENAME = "monster_default.png"
    FRAME = 39
    TEMPLATES = (stats.REPTILE,)
    MOVE_POINTS = 8
    VOICE = None
    HABITAT = ( context.HAB_EVERY, context.SET_EVERY,
     context.MTY_BEAST, context.MTY_BOSS )
    ENC_LEVEL = 6
    ATTACK = items.Attack( (1,8,0), element = stats.RESIST_PIERCING )
    TECHNIQUES = ( invocations.MPInvocation( "Death Gaze",
      effects.OpposedRoll( att_stat=stats.PIETY, att_modifier=-10, on_success = (
        effects.InstaKill( anim=animobs.CriticalHit )
      ,), on_failure = (
        effects.NoEffect( anim=animobs.SmallBoom )
      ,) ), com_tar=targetarea.SingleTarget(reach=4), shot_anim=animobs.PurpleVortex, ai_tar=invocations.TargetEnemy(), mp_cost=6
    ), )
    def init_monster( self ):
        self.levels.append( base.Beast( 6, self ) )
コード例 #25
0
class Medusa( base.Monster ):
    name = "Medusa"
    statline = { stats.STRENGTH: 10, stats.TOUGHNESS: 12, stats.REFLEXES: 15, \
        stats.INTELLIGENCE: 12, stats.PIETY: 13, stats.CHARISMA: 15 }
    SPRITENAME = "monster_default.png"
    FRAME = 30
    TEMPLATES = ()
    MOVE_POINTS = 10
    VOICE = dialogue.voice.GREEK
    HABITAT = ( context.HAB_EVERY, context.SET_EVERY,
     context.MTY_HUMANOID )
    ENC_LEVEL = 9
    COMBAT_AI = aibrain.ArcherAI(approach_allies=0,technique_chance=75)
    ATTACK = items.Attack( (1,6,0), element = stats.RESIST_PIERCING, extra_effect=abilities.POISON_ATTACK_2d6 )
    TECHNIQUES = ( invocations.MPInvocation( "Death Gaze",
      effects.OpposedRoll( att_stat=stats.PIETY, att_modifier=-10, on_success = (
        effects.InstaKill( anim=animobs.CriticalHit )
      ,), on_failure = (
        effects.NoEffect( anim=animobs.SmallBoom )
      ,) ), com_tar=targetarea.SingleTarget(reach=6), shot_anim=animobs.PurpleVortex, ai_tar=invocations.TargetEnemy(), mp_cost=9
    ), abilities.LONGBOW )
    def init_monster( self ):
        self.levels.append( base.Humanoid( 6, self ) )
コード例 #26
0
class Beastman(base.Monster):
    name = "Beastman"
    statline = { stats.STRENGTH: 12, stats.TOUGHNESS: 14, stats.REFLEXES: 14, \
        stats.INTELLIGENCE: 9, stats.PIETY: 6, stats.CHARISMA: 8 }
    SPRITENAME = "monster_chaos.png"
    FRAME = 3
    TEMPLATES = ()
    MOVE_POINTS = 12
    TREASURE = treasuretype.Standard()
    HABITAT = (context.HAB_EVERY, context.SET_EVERY, context.MAP_WILDERNESS,
               context.DES_LUNAR, context.MTY_HUMANOID, context.MTY_FIGHTER,
               context.GEN_CHAOS)
    ENC_LEVEL = 4
    COMPANIONS = (Hooligan, )
    TECHNIQUES = (invocations.MPInvocation(
        "Headbutt",
        effects.PhysicalAttackRoll(
            att_stat=stats.STRENGTH,
            on_success=(
                effects.HealthDamage((1, 10, 0),
                                     stat_bonus=stats.STRENGTH,
                                     element=stats.RESIST_CRUSHING,
                                     stat_mod=2,
                                     anim=animobs.RedBoom),
                effects.OpposedRoll(
                    att_skill=stats.PHYSICAL_ATTACK,
                    def_stat=stats.TOUGHNESS,
                    on_success=(effects.Paralyze(max_duration=3), )),
            ),
            on_failure=(effects.NoEffect(anim=animobs.SmallBoom), )),
        com_tar=targetarea.SingleTarget(reach=1),
        ai_tar=invocations.TargetEnemy(),
        mp_cost=5), )
    ATTACK = items.Attack((1, 8, 0), element=stats.RESIST_SLASHING)

    def init_monster(self):
        self.levels.append(base.Humanoid(4, self))
コード例 #27
0
class Cockatrice( base.Monster ):
    name = "Cockatrice"
    statline = { stats.STRENGTH: 8, stats.TOUGHNESS: 8, stats.REFLEXES: 15, \
        stats.INTELLIGENCE: 1, stats.PIETY: 10, stats.CHARISMA: 4 }
    SPRITENAME = "monster_default.png"
    FRAME = 21
    TEMPLATES = ()
    MOVE_POINTS = 10
    VOICE = None
    HABITAT = ( context.HAB_EVERY, context.SET_EVERY, context.SET_RENFAN,
     context.DES_AIR, context.DES_EARTH,
     context.MTY_BEAST, context.MTY_BOSS )
    ENC_LEVEL = 4
    COMPANIONS = (animals.Chicken,)
    ATTACK = items.Attack( (1,6,0), element = stats.RESIST_PIERCING, skill_mod=stats.REFLEXES )
    TECHNIQUES = ( invocations.MPInvocation( "Death Gaze",
      effects.OpposedRoll( att_stat=stats.PIETY, att_modifier=-10, on_success = (
        effects.InstaKill( anim=animobs.CriticalHit )
      ,), on_failure = (
        effects.NoEffect( anim=animobs.SmallBoom )
      ,) ), com_tar=targetarea.SingleTarget(reach=4), shot_anim=animobs.PurpleVortex, ai_tar=invocations.TargetEnemy(), mp_cost=4
    ), )
    def init_monster( self ):
        self.levels.append( base.Beast( 3, self ) )
コード例 #28
0
class Umbull( base.Monster ):
    name = "Umbull"    
    statline = { stats.STRENGTH: 23, stats.TOUGHNESS: 19, stats.REFLEXES: 13, \
        stats.INTELLIGENCE: 9, stats.PIETY: 11, stats.CHARISMA: 13 }
    SPRITENAME = "monster_default.png"
    FRAME = 4
    TEMPLATES = ()
    MOVE_POINTS = 8
    HABITAT = ( context.HAB_CAVE, context.SET_EVERY,
     context.MAP_DUNGEON, context.DES_EARTH )
    ENC_LEVEL = 9
    COMBAT_AI = aibrain.BruiserAI()
    TREASURE = treasuretype.Standard()
    ATTACK = items.Attack( (3,6,0), element = stats.RESIST_SLASHING )
    TECHNIQUES = (invocations.Invocation( "Freezing Gaze",
        effects.OpposedRoll( att_modifier=20, on_success = (
            effects.Paralyze( max_duration = 6 )
        ,), on_failure =(
            effects.NoEffect( anim=animobs.SmallBoom )
        ,) ), com_tar=targetarea.SingleTarget(), shot_anim=animobs.PurpleVortex,
        ai_tar=invocations.TargetMobileEnemy() ),
    )
    def init_monster( self ):
        self.levels.append( base.Defender( 9, self ) )
コード例 #29
0
                      ai_tar=invocations.TargetWoundedAlly(),
                      exp_tar=targetarea.SinglePartyMember(),
                      mpfudge=-2)

# CIRCLE 3

SUNRAY = Spell("Sunray",
               "This attack does 3d6 solar damage when it hits.",
               effects.OpposedRoll(
                   att_modifier=10,
                   on_success=(effects.HealthDamage(
                       (3, 6, 0),
                       stat_bonus=stats.INTELLIGENCE,
                       element=stats.RESIST_SOLAR,
                       anim=animobs.YellowExplosion), ),
                   on_failure=(effects.NoEffect(anim=animobs.SmallBoom), )),
               rank=3,
               gems={SOLAR: 2},
               com_tar=targetarea.SingleTarget(),
               shot_anim=animobs.YellowVortex,
               ai_tar=invocations.TargetEnemy())

CURE_POISON = Spell(
    "Cure Poison",
    "This spell will remove all poisoning from a single party member.",
    effects.TidyEnchantments(enchantments.POISON, anim=animobs.YellowSparkle),
    rank=3,
    gems={SOLAR: 1},
    com_tar=targetarea.SingleTarget(reach=1),
    exp_tar=targetarea.SinglePartyMember(),
    mpfudge=-1)
コード例 #30
0
    ai_tar=invocations.TargetEmptySpot(),
    mpfudge=12)

# CIRCLE SEVEN

DISINTEGRATION = Spell(
    "Disintegration",
    "The primal flames of the universe are called forth to reduce a single target to dust. This spell does 10d10 atomic damage on a successful hit.",
    effects.OpposedRoll(
        att_modifier=10,
        def_stat=stats.REFLEXES,
        on_success=(effects.HealthDamage((10, 10, 0),
                                         stat_bonus=stats.INTELLIGENCE,
                                         element=stats.RESIST_ATOMIC,
                                         anim=animobs.Nuclear), ),
        on_failure=(effects.NoEffect(anim=animobs.SmallBoom), )),
    rank=7,
    gems={FIRE: 3},
    com_tar=targetarea.SingleTarget(),
    shot_anim=animobs.Fireball,
    ai_tar=invocations.TargetEnemy())

# CIRCLE EIGHT

# CIRCLE NINE

NUCLEAR = Spell(
    "Nuclear",
    "This spell causes a massive explosion, doing 20d6 atomic damage to all targets in a 4 tile radius.",
    effects.OpposedRoll(on_success=(effects.HealthDamage(
        (20, 6, 0),