예제 #1
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))
예제 #2
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 ) )
예제 #3
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))
예제 #4
0
class Unicorn(base.Monster):
    name = "Unicorn"
    statline = { stats.STRENGTH: 16, stats.TOUGHNESS: 18, stats.REFLEXES: 16, \
        stats.INTELLIGENCE: 16, stats.PIETY: 20, stats.CHARISMA: 18, \
        stats.RESIST_LUNAR: 100, stats.MAGIC_DEFENSE: 25 }
    SPRITENAME = "monster_animals.png"
    FRAME = 31
    TEMPLATES = ()
    MOVE_POINTS = 12
    VOICE = None
    HABITAT = (context.HAB_FOREST, context.SET_EVERY, context.DES_SOLAR,
               context.MTY_BEAST, context.MTY_CREATURE, context.MTY_LEADER,
               context.MTY_BOSS, context.GEN_NATURE)
    ENC_LEVEL = 13
    ATTACK = items.Attack((3, 6, 0), element=stats.RESIST_PIERCING)
    TECHNIQUES = (invocations.MPInvocation(
        "Radiance",
        effects.HealthRestore(dice=(5, 8, 20)),
        mp_cost=7,
        com_tar=targetarea.SingleTarget(reach=10),
        ai_tar=invocations.TargetWoundedAlly(),
        exp_tar=targetarea.SinglePartyMember(),
        shot_anim=animobs.YellowVortex), )

    def init_monster(self):
        self.levels.append(base.Defender(12, self))
예제 #5
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 ) )
예제 #6
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 ) )
예제 #7
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 ) )
예제 #8
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))
예제 #9
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 ) )
예제 #10
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
예제 #11
0
class AirElemental(base.Monster):
    name = "Air Elemental"
    statline = { stats.STRENGTH: 20, stats.TOUGHNESS: 20, stats.REFLEXES: 30, \
        stats.INTELLIGENCE: 12, stats.PIETY: 12, stats.CHARISMA: 12,
        stats.RESIST_WIND: 100 }
    SPRITENAME = "monster_e_air.png"
    FRAME = 0
    TEMPLATES = (stats.ELEMENTAL, stats.AIR)
    MOVE_POINTS = 20
    HABITAT = (context.HAB_EVERY, context.SET_EVERY, context.DES_AIR,
               context.MTY_ELEMENTAL, context.SUMMON_ELEMENTAL)
    ENC_LEVEL = 12
    ATTACK = items.Attack((1, 10, 0),
                          element=stats.RESIST_SLASHING,
                          extra_effect=effects.HealthDamage(
                              (1, 10, 0),
                              stat_bonus=stats.INTELLIGENCE,
                              element=stats.RESIST_WIND,
                              anim=animobs.Spiral))
    TECHNIQUES = (invocations.MPInvocation(
        "Tornado",
        effects.OpposedRoll(def_stat=stats.REFLEXES,
                            on_success=(effects.HealthDamage(
                                (3, 8, 0),
                                stat_bonus=stats.INTELLIGENCE,
                                element=stats.RESIST_WIND,
                                anim=animobs.Spiral), ),
                            on_failure=(effects.HealthDamage(
                                (1, 12, 0),
                                stat_bonus=None,
                                element=stats.RESIST_WIND,
                                anim=animobs.Spiral), )),
        mp_cost=10,
        com_tar=targetarea.Blast(radius=3),
        shot_anim=animobs.Whirlwind,
        ai_tar=invocations.TargetEnemy()),
                  invocations.MPInvocation(
                      "Lightning Bolt",
                      effects.OpposedRoll(def_stat=stats.REFLEXES,
                                          on_success=(effects.HealthDamage(
                                              (3, 12, 0),
                                              stat_bonus=stats.INTELLIGENCE,
                                              element=stats.RESIST_LIGHTNING,
                                              anim=animobs.BlueZap), ),
                                          on_failure=(effects.HealthDamage(
                                              (2, 10, 0),
                                              stat_bonus=None,
                                              element=stats.RESIST_LIGHTNING,
                                              anim=animobs.BlueZap), )),
                      mp_cost=5,
                      com_tar=targetarea.SingleTarget(),
                      shot_anim=animobs.Lightning,
                      ai_tar=invocations.TargetEnemy()))

    def init_monster(self):
        self.levels.append(base.Beast(12, self))
예제 #12
0
class FireBat(base.Monster):
    name = "Fire Bat"
    statline = { stats.STRENGTH: 12, stats.TOUGHNESS: 12, stats.REFLEXES: 14, \
        stats.INTELLIGENCE: 2, stats.PIETY: 9, stats.CHARISMA: 3, }
    SPRITENAME = "monster_animals.png"
    FRAME = 26
    TEMPLATES = (stats.FIRE, )
    MOVE_POINTS = 14
    VOICE = None
    HABITAT = (context.HAB_CAVE, context.SET_EVERY, context.DES_FIRE,
               context.DES_LUNAR, context.MTY_BEAST)
    ENC_LEVEL = 4

    ATTACK = items.Attack((2, 4, 0),
                          element=stats.RESIST_PIERCING,
                          extra_effect=effects.OpposedRoll(
                              att_stat=stats.TOUGHNESS,
                              att_modifier=-10,
                              on_success=(
                                  effects.HealthDamage(
                                      (1, 6, 0),
                                      stat_bonus=None,
                                      element=stats.RESIST_FIRE,
                                      anim=animobs.OrangeExplosion),
                                  effects.Enchant(enchantments.BurnLowEn),
                              )))

    TECHNIQUES = (invocations.MPInvocation(
        "Fire Breath",
        effects.OpposedRoll(att_skill=stats.PHYSICAL_ATTACK,
                            att_stat=stats.REFLEXES,
                            att_modifier=-10,
                            def_stat=stats.REFLEXES,
                            on_success=(
                                effects.HealthDamage(
                                    (1, 8, 0),
                                    stat_bonus=None,
                                    element=stats.RESIST_FIRE,
                                    anim=animobs.OrangeExplosion),
                                effects.Enchant(enchantments.BurnLowEn),
                            ),
                            on_failure=(effects.HealthDamage(
                                (1, 8, 0),
                                stat_bonus=None,
                                element=stats.RESIST_FIRE,
                                anim=animobs.OrangeExplosion), )),
        com_tar=targetarea.SingleTarget(),
        shot_anim=animobs.Fireball,
        ai_tar=invocations.TargetEnemy(),
        mp_cost=3), )

    def init_monster(self):
        self.levels.append(base.Beast(3, self))
예제 #13
0
class GemOfHolograms(Consumable):
    true_name = "Gem of Holograms"
    true_desc = "This gem may be used to summon an illusory monster to aid you in combat."
    itemtype = GEM
    mass_per_q = 3
    cost_per_q = 600
    tech = invocations.Invocation(
        "Create Illusion",
        effects.CallMonster({(context.HAB_EVERY, context.SET_EVERY): True},
                            5,
                            anim=animobs.BlueSparkle),
        com_tar=targetarea.SingleTarget(reach=5),
        ai_tar=invocations.TargetEmptySpot(),
        exp_tar=None)
예제 #14
0
class Belker(base.Monster):
    name = "Belker"
    statline = { stats.STRENGTH: 14, stats.TOUGHNESS: 13, stats.REFLEXES: 21, \
        stats.INTELLIGENCE: 6, stats.PIETY: 11, stats.CHARISMA: 11 }
    SPRITENAME = "monster_e_air.png"
    FRAME = 10
    TEMPLATES = (stats.ELEMENTAL, stats.AIR, stats.INCORPOREAL)
    MOVE_POINTS = 12
    VOICE = None
    HABITAT = (context.HAB_EVERY, context.SET_EVERY, context.DES_AIR,
               context.DES_LUNAR, context.MTY_ELEMENTAL)
    ENC_LEVEL = 8
    ATTACK = items.Attack((2, 4, 0), element=stats.RESIST_WIND)
    TECHNIQUES = (invocations.MPInvocation(
        "Smoke Claw",
        effects.OpposedRoll(
            att_stat=stats.STRENGTH,
            def_stat=stats.TOUGHNESS,
            on_success=(
                effects.HealthDamage((2, 4, 0),
                                     stat_bonus=stats.STRENGTH,
                                     element=stats.RESIST_WIND,
                                     anim=animobs.RedBoom),
                effects.TargetIs(effects.ALIVE,
                                 on_true=(
                                     effects.HealthDamage(
                                         (3, 4, 0),
                                         stat_bonus=None,
                                         element=None,
                                         anim=animobs.BloodSplat),
                                     effects.Enchant(enchantments.Bleeding),
                                 )),
            ),
            on_failure=(effects.HealthDamage((2, 4, 0),
                                             stat_bonus=None,
                                             element=stats.RESIST_WIND,
                                             anim=animobs.RedBoom), )),
        mp_cost=5,
        com_tar=targetarea.SingleTarget(reach=1),
        ai_tar=invocations.TargetEnemy()), )

    def init_monster(self):
        self.levels.append(base.Humanoid(8, self))
예제 #15
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 ) )
예제 #16
0
class AnimatedCandlestick(base.Monster):
    name = "Candlestick"
    statline = { stats.STRENGTH: 12, stats.TOUGHNESS: 12, stats.REFLEXES: 12, \
        stats.INTELLIGENCE: 12, stats.PIETY: 12, stats.CHARISMA: 12 }
    SPRITENAME = "monster_constructs.png"
    FRAME = 19
    TEMPLATES = (stats.CONSTRUCT, )
    MOVE_POINTS = 10
    VOICE = None
    HABITAT = (context.HAB_BUILDING, context.SET_EVERY, context.MTY_CONSTRUCT,
               context.DES_FIRE)
    ENC_LEVEL = 7
    COMBAT_AI = aibrain.SteadyAI()
    ATTACK = items.Attack(
        (2, 6, 0),
        element=stats.RESIST_PIERCING,
        extra_effect=effects.OpposedRoll(att_modifier=-10,
                                         on_success=(effects.Enchant(
                                             enchantments.BurnLowEn,
                                             anim=animobs.RedCloud), )))
    TECHNIQUES = (invocations.MPInvocation(
        "Fireball",
        effects.OpposedRoll(def_stat=stats.REFLEXES,
                            on_success=(effects.HealthDamage(
                                (1, 10, 0),
                                stat_bonus=None,
                                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.SingleTarget(),
        ai_tar=invocations.TargetEnemy(),
        shot_anim=animobs.Fireball,
        mp_cost=5), )

    def init_monster(self):
        self.levels.append(base.Beast(7, self))
예제 #17
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 ) )
예제 #18
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 ) )
예제 #19
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))
예제 #20
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 ) )
예제 #21
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 ) )
예제 #22
0
import targetarea
import enchantments

# Techniques

SHORTBOW = invocations.Invocation(
    "Arrow",
    effects.PhysicalAttackRoll(
        att_stat=stats.REFLEXES,
        att_modifier=5,
        on_success=(effects.HealthDamage((1, 6, 0),
                                         stat_bonus=None,
                                         element=stats.RESIST_PIERCING,
                                         anim=animobs.RedBoom), ),
        on_failure=(effects.NoEffect(anim=animobs.SmallBoom), )),
    com_tar=targetarea.SingleTarget(reach=7),
    shot_anim=animobs.Arrow,
    ai_tar=invocations.TargetEnemy())

LONGBOW = invocations.Invocation(
    "Arrow",
    effects.PhysicalAttackRoll(
        att_stat=stats.REFLEXES,
        att_modifier=5,
        on_success=(effects.HealthDamage((1, 8, 0),
                                         stat_bonus=None,
                                         element=stats.RESIST_PIERCING,
                                         anim=animobs.RedBoom), ),
        on_failure=(effects.NoEffect(anim=animobs.SmallBoom), )),
    com_tar=targetarea.SingleTarget(reach=8),
    shot_anim=animobs.Arrow,
예제 #23
0
    "Blessing",
    "Increases the physical and magic attack scores of all allies within 6 tiles by +5%. This effect lasts until the end of combat.",
    effects.TargetIsAlly(on_true=(effects.Enchant(
        enchantments.BlessingEn, anim=animobs.YellowSparkle), )),
    rank=1,
    gems={SOLAR: 1},
    com_tar=targetarea.SelfCentered(),
    ai_tar=invocations.TargetAllyWithoutEnchantment(enchantments.BlessingEn),
    mpfudge=-1)

MINOR_CURE = Spell("Minor Cure",
                   "This spell will heal one nearby ally for 1-10 damage.",
                   effects.HealthRestore(dice=(1, 10, 0)),
                   rank=1,
                   gems={SOLAR: 1},
                   com_tar=targetarea.SingleTarget(reach=1),
                   ai_tar=invocations.TargetWoundedAlly(),
                   exp_tar=targetarea.SinglePartyMember())

# CIRCLE 2

MODERATE_CURE = Spell("Moderate Cure",
                      "This spell will heal one nearby ally for 6-20 damage.",
                      effects.HealthRestore(dice=(2, 8, 4)),
                      rank=2,
                      gems={SOLAR: 2},
                      com_tar=targetarea.SingleTarget(reach=1),
                      ai_tar=invocations.TargetWoundedAlly(),
                      exp_tar=targetarea.SinglePartyMember(),
                      mpfudge=-2)
예제 #24
0
import stats
import invocations

# CIRCLE ONE

CURSE = Spell( "Curse",
    "Decreases the physical attack score of enemies within 6 tiles by 5%. This effect lasts until the end of combat.",
    effects.TargetIsEnemy( on_true = (
        effects.Enchant( enchantments.CurseEn, anim=animobs.PurpleSparkle )
    ,) ), rank=1, gems={LUNAR:1}, com_tar=targetarea.SelfCentered(), 
    ai_tar=invocations.TargetEnemyWithoutEnchantment(enchantments.CurseEn), mpfudge=-1 )

WIZARD_MISSILE = Spell( "Wizard Missile",
    "This mystic bolt always strikes its target for 1-6 damage.",
    effects.HealthDamage((1,6,0), stat_bonus=None, element=stats.RESIST_LUNAR, anim=animobs.PurpleExplosion ),
    rank=1, gems={LUNAR:1}, com_tar=targetarea.SingleTarget(), shot_anim=animobs.WizardMissile,
    ai_tar=invocations.TargetEnemy(), mpfudge=-1 )

# CIRCLE TWO

SLEEP = Spell( "Sleep",
    "Causes living creatures in a 2 tile radius to fall asleep.",
    effects.TargetIs( pat=effects.ANIMAL, anim=animobs.PurpleSparkle, on_true = (
        effects.OpposedRoll( att_modifier=0, on_success = (
            effects.CauseSleep(),
        ))
    ,) ), rank=2, gems={LUNAR:2}, com_tar=targetarea.Blast(radius=2), 
    ai_tar=invocations.TargetMobileEnemy(min_distance=3) )

ENERVATE = Spell( "Enervate",
    "A ray of negative energy strikes one opponent, draining 4-16 mana instantly.",
예제 #25
0
# CIRCLE ONE


# CIRCLE TWO

CHAOS_BOLT = Spell( "Chaos Bolt",
    "This mystic bolt does 1d8 damage to health and an additional 1d8 damage to mana.",
    effects.OpposedRoll( on_success = (
        effects.HealthDamage((1,8,0), stat_bonus=stats.INTELLIGENCE, element=stats.RESIST_SOLAR, anim=animobs.YellowExplosion ),
        effects.ManaDamage((1,8,0), stat_bonus=stats.INTELLIGENCE, anim=animobs.PurpleExplosion ),
    ), on_failure = (
        effects.HealthDamage((1,4,0), stat_bonus=None, element=stats.RESIST_SOLAR, anim=animobs.YellowExplosion ),
        effects.ManaDamage((1,4,0), stat_bonus=None, anim=animobs.PurpleExplosion ),
    )),
    rank=2, gems={LUNAR:1,SOLAR:1}, com_tar=targetarea.SingleTarget(), shot_anim=animobs.WizardMissile,
    ai_tar=invocations.TargetEnemy(), mpfudge=-3 )



# CIRCLE THREE

CHAOTIC_AID = Spell( "Chaotic Aid",
    "This spell calls forth a servant of chaos to aid you in battle.",
    effects.CallMonster( {context.GEN_CHAOS: True, context.MTY_FIGHTER: True}, 5, anim=animobs.OrangeSparkle ),
    rank=3, gems={EARTH:1,AIR:1}, com_tar=targetarea.SingleTarget(reach=2), ai_tar=invocations.TargetEmptySpot(), mpfudge = 3 )


# CIRCLE FOUR

예제 #26
0
import stats
import context
import invocations

# Necromancers get EARTH, LUNAR, and WATER magic. These spells use at least two
# of those colors.

# CIRCLE ONE

ICE_BOLT = Spell( "Icy Bolt",
    "This attack does 1d8 cold damage to a single target.",
    effects.OpposedRoll( att_modifier=15, on_success = (
        effects.HealthDamage( (1,8,0), stat_bonus=stats.INTELLIGENCE, element=stats.RESIST_COLD, anim=animobs.BlueExplosion )
    ,), on_failure = (
        effects.HealthDamage( (1,3,0), stat_bonus=None, element=stats.RESIST_COLD, anim=animobs.BlueExplosion )
    ,) ), rank=1, gems={LUNAR:1,WATER:1}, com_tar=targetarea.SingleTarget(), shot_anim=animobs.BlueBolt, mpfudge=-1,
    ai_tar=invocations.TargetEnemy() )

RAISE_SKELETON = Spell( "Raise Skeleton",
    "You conjure dark forces to animate a skeleton which will fight on your behaf.",
    effects.CallMonster( {context.MTY_UNDEAD: True, context.DES_LUNAR: context.MAYBE, context.GEN_UNDEAD: context.MAYBE}, 2, anim=animobs.PurpleSparkle ),
    rank=1, gems={EARTH:1,LUNAR:1}, com_tar=targetarea.SingleTarget(reach=2), ai_tar=invocations.TargetEmptySpot() )

# CIRCLE 2

RAISE_CORPSE = Spell( "Raise Corpse",
    "You conjure dark forces to animate a lesser undead creature which will fight on your behaf.",
    effects.CallMonster( {context.MTY_UNDEAD: True, context.DES_LUNAR: context.MAYBE, context.GEN_UNDEAD: context.MAYBE}, 4, anim=animobs.PurpleSparkle ),
    rank=2, gems={EARTH:1,LUNAR:1}, com_tar=targetarea.SingleTarget(reach=2), ai_tar=invocations.TargetEmptySpot(), mpfudge=4 )

TOUCH_OF_DEATH = Spell( "Touch of Death",
예제 #27
0
    "Increases the physical and magical defense of all allies within 6 tiles by +5%. This effect lasts until the end of combat.",
    effects.TargetIsAlly(on_true=(
        effects.Enchant(enchantments.AirArmor, anim=animobs.BlueSparkle), )),
    rank=1,
    gems={AIR: 1},
    com_tar=targetarea.SelfCentered(),
    ai_tar=invocations.TargetAllyWithoutEnchantment(enchantments.AirArmor))

PROBE = Spell("Probe",
              "This spell reveals secret knowledge about one target creature.",
              effects.NoEffect(anim=animobs.BlueSparkle,
                               children=(effects.Probe(), )),
              rank=1,
              gems={AIR: 1},
              mpfudge=-1,
              com_tar=targetarea.SingleTarget(),
              exp_tar=targetarea.SingleTarget())

# CIRCLE TWO

SILENCE = Spell(
    "Silence",
    "Targets within a 2 tile radius may be silenced, preventing them from casting spells.",
    effects.OpposedRoll(
        att_modifier=0,
        on_success=(effects.CauseSilence(), ),
        on_failure=(effects.NoEffect(anim=animobs.SmallBoom), )),
    rank=2,
    gems={AIR: 1},
    com_tar=targetarea.Blast(radius=2),
    ai_tar=invocations.TargetEnemy())
예제 #28
0
ACID_SPRAY = Spell( "Acid Spray",
    "A stream of acid sprays forth, burning enemies for 1d6 damage. This spell has a short range but can affect several targets.",
    effects.OpposedRoll( on_success = (
        effects.HealthDamage( (1,6,0), stat_bonus=stats.INTELLIGENCE, element=stats.RESIST_ACID, anim=animobs.GreenExplosion )
    ,), on_failure = (
        effects.HealthDamage( (1,2,0), stat_bonus=None, element=stats.RESIST_ACID, anim=animobs.GreenExplosion )
    ,) ), rank=1, gems={FIRE:1,EARTH:1}, com_tar=targetarea.Cone(reach=3), ai_tar=invocations.TargetEnemy() )


# CIRCLE TWO

CALL_ANIMAL = Spell( "Call Animal",
    "This spell will summon a natural creature to fight on your behaf.",
    effects.CallMonster( {context.MTY_CREATURE: True, context.DES_EARTH: context.MAYBE, context.GEN_NATURE: context.MAYBE, context.DES_SOLAR: context.MAYBE}, 4, anim=animobs.OrangeSparkle ),
    rank=2, gems={EARTH:1,SOLAR:1}, com_tar=targetarea.SingleTarget(reach=2), ai_tar=invocations.TargetEmptySpot(), mpfudge = 4 )

# CIRCLE THREE

CALL_CREATURE = Spell( "Call Creature",
    "This spell will summon a large natural creature to fight on your behaf.",
    effects.CallMonster( {context.MTY_CREATURE: True, context.DES_EARTH: context.MAYBE, context.GEN_NATURE: context.MAYBE, context.DES_SOLAR: context.MAYBE}, 6, anim=animobs.OrangeSparkle ),
    rank=3, gems={EARTH:2,SOLAR:1}, com_tar=targetarea.SingleTarget(reach=2), ai_tar=invocations.TargetEmptySpot(), mpfudge = 6 )

SLIMY_WEAPON = Spell( "Slimy Weapon",
    "One ally's weapon will be coated in caustic slime which causes an extra 1d10 acid damage and may corrode an opponent's armor.",
    effects.Enchant( enchantments.AcidWepEn, anim=animobs.OrangeSparkle ),
    rank=3, gems={EARTH:1}, com_tar=targetarea.SingleTarget(),
    ai_tar=invocations.TargetAllyWithoutEnchantment(enchantments.AcidWepEn) )

예제 #29
0
SHOCK_SPHERE = Spell( "Shock Sphere",
    "An electrical burst will deal 1-6 points of damage to all enemies within two tiles of the caster.",
    effects.TargetIsEnemy( on_true = (
        effects.OpposedRoll( on_success = (
            effects.HealthDamage( (1,6,0), stat_bonus=stats.INTELLIGENCE, element=stats.RESIST_LIGHTNING, anim=animobs.BlueZap )
        ,), on_failure = (
            effects.HealthDamage( (1,3,0), stat_bonus=None, element=stats.RESIST_LIGHTNING, anim=animobs.BlueZap )
    ,) ) ,) ), rank=1, gems={AIR:1,LUNAR:1}, com_tar=targetarea.SelfCentered(radius=2,exclude_middle=True),
    ai_tar=invocations.TargetEnemy() )

# CIRCLE TWO

LIGHTNING_BOLT = Spell( "Lightning Bolt",
    "This spell conjures magical lightning, which will unerringly hit one foe for 2d8 damage.",
    effects.HealthDamage((2,8,0), stat_bonus=stats.INTELLIGENCE, element=stats.RESIST_LIGHTNING, anim=animobs.BlueZap ),
    rank=2, gems={AIR:1,LUNAR:1}, com_tar=targetarea.SingleTarget(), shot_anim=animobs.Lightning, ai_tar=invocations.TargetEnemy(),
    mpfudge=-2 )

# CIRCLE THREE

FIRE_SIGN = Spell( "Fire Sign",
    "Burns all enemies within 6 tiles with a flaming sigil, doing 2d4 damage and preventing them from hiding.",
    effects.TargetIsEnemy( on_true = (
        effects.OpposedRoll( on_success = (
            effects.HealthDamage( (2,4,0), stat_bonus=stats.INTELLIGENCE, element=stats.RESIST_FIRE, anim=animobs.RedCloud )
        ,), on_failure = (
            effects.HealthDamage( (1,4,1), stat_bonus=None, element=stats.RESIST_FIRE, anim=animobs.RedCloud )
        ,)),
        effects.Enchant( enchantments.FireSignEn, anim=None )
    ) ), rank=3, gems={AIR:1,FIRE:1}, com_tar=targetarea.SelfCentered(), ai_tar=invocations.TargetEnemy() )
BLAST_UNDEAD = Spell(
    "Blast Undead",
    "This mystic bolt deals 1-6 damage to undead creatures.",
    effects.TargetIs(pat=effects.UNDEAD,
                     on_true=(effects.HealthDamage(
                         (1, 6, 0),
                         stat_bonus=stats.PIETY,
                         element=stats.RESIST_SOLAR,
                         anim=animobs.YellowExplosion), ),
                     on_false=(effects.NoEffect(anim=animobs.SmallBoom), )),
    rank=1,
    gems={
        SOLAR: 1,
        WATER: 1
    },
    com_tar=targetarea.SingleTarget(),
    shot_anim=animobs.YellowBolt,
    mpfudge=-1)

# CIRCLE TWO

WEAPON_BLESSING = Spell(
    "Weapon Blessing",
    "One ally's weapon will be blessed to do an extra 1-8 points of damage.",
    effects.Enchant(enchantments.BlessedWepEn, anim=animobs.YellowSparkle),
    rank=2,
    gems={
        AIR: 1,
        SOLAR: 1
    },
    com_tar=targetarea.SinglePartyMember(),