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))
class Healer( base.Monster ): name = "Healer" statline = { stats.STRENGTH: 12, stats.TOUGHNESS: 16, stats.REFLEXES: 12, \ stats.INTELLIGENCE: 14, stats.PIETY: 18, stats.CHARISMA: 18 } SPRITENAME = "monster_spellcasters.png" FRAME = 16 TEMPLATES = () MOVE_POINTS = 10 HABITAT = ( context.HAB_EVERY, context.HAB_BUILDING, context.SET_EVERY, context.DES_CIVILIZED, context.DES_SOLAR, context.DES_WATER, context.MTY_BOSS, context.MTY_HUMANOID, context.MTY_PRIEST, context.GEN_KINGDOM ) ENC_LEVEL = 10 TREASURE = treasuretype.HighItems( ( items.potions.PotionOfHealing, items.scrolls.Rank4Scroll, items.scrolls.Rank5Scroll ) ) COMBAT_AI = aibrain.BasicTechnicalAI() COMPANIONS = (NoviceWarrior,NovicePriest,Warrior) ATTACK = items.Attack( (3,6,0), element = stats.RESIST_SOLAR, hit_anim=animobs.YellowExplosion ) TECHNIQUES = ( spells.priestspells.SMITE, spells.solarspells.MASS_CURE, spells.solarspells.MAXIMUM_CURE, invocations.MPInvocation( "Repent", effects.TargetIsAlly( on_true = ( effects.Enchant( enchantments.BlessingEn, anim=animobs.GreenSparkle ), effects.TargetIsDamaged( on_true= ( effects.HealthRestore( dice=(3,12,12) ), )) ), on_false=( effects.TargetIsEnemy( on_true = ( effects.HealthDamage( (3,12,0), stat_bonus=stats.CHARISMA, element=stats.RESIST_WATER, anim=animobs.Bubbles ), )), )), shot_anim=animobs.BlueComet, com_tar=targetarea.Blast(radius=3), ai_tar=invocations.TargetEnemy(), mp_cost=12 ) ) def init_monster( self ): self.levels.append( base.Spellcaster( 6, self ) ) self.levels.append( base.Defender( 4, self ) )
class MummyPriest( base.Monster ): name = "Mummy Priest" statline = { stats.STRENGTH: 22, stats.TOUGHNESS: 20, stats.REFLEXES: 10, \ stats.INTELLIGENCE: 10, stats.PIETY: 16, stats.CHARISMA: 15 } SPRITENAME = "monster_undead.png" FRAME = 48 TEMPLATES = (stats.UNDEAD,stats.MUMMY) MOVE_POINTS = 6 VOICE = None HABITAT = ( context.HAB_DESERT, context.HAB_TUNNELS, context.SET_EVERY, context.MTY_UNDEAD, context.MTY_HUMANOID, context.MTY_PRIEST, context.MTY_MAGE, context.MTY_BOSS, context.DES_SOLAR, context.GEN_UNDEAD ) ENC_LEVEL = 7 TREASURE = treasuretype.High(( items.scrolls.Rank3Scroll, items.scrolls.Rank4Scroll )) COMPANIONS = (Mummy,animals.Scarab,animals.TombScorpion) COMBAT_AI = aibrain.SteadySpellAI() TECHNIQUES = ( spells.lunarspells.HELLBLAST, spells.priestspells.HEALING_LIGHT, spells.priestspells.DIVINE_HAMMER, spells.solarspells.MAJOR_CURE, spells.priestspells.SANCTUARY, spells.magespells.INCINERATE ) ATTACK = items.Attack( (1,10,0), element = stats.RESIST_CRUSHING, extra_effect = effects.OpposedRoll( att_modifier=-10, on_success = ( effects.StatDamage( stats.TOUGHNESS, anim=animobs.GreenBoom ), effects.Enchant( enchantments.DiseaseEn, anim=None ) ,) ) ) def init_monster( self ): self.levels.append( base.Leader( 7, self ) ) self.condition.append( enchantments.PermaRegeneration() )
class FlamingSword(base.Monster): name = "Flaming Sword" statline = { stats.STRENGTH: 16, stats.TOUGHNESS: 14, stats.REFLEXES: 18, \ stats.INTELLIGENCE: 12, stats.PIETY: 20, stats.CHARISMA: 14, stats.RESIST_SLASHING: 50, stats.MAGIC_DEFENSE: 50, stats.COUNTER_ATTACK: 50 } SPRITENAME = "monster_constructs.png" FRAME = 9 TEMPLATES = (stats.CONSTRUCT, ) MOVE_POINTS = 12 VOICE = None HABITAT = (context.SET_EVERY, context.MTY_CONSTRUCT, context.DES_AIR, context.DES_FIRE, context.SUMMON_FLAMINGSWORD) ENC_LEVEL = 14 COMBAT_AI = aibrain.SteadyAI() ATTACK = items.Attack( (3, 8, 0), element=stats.RESIST_SLASHING, extra_effect=effects.OpposedRoll(on_success=(effects.HealthDamage( (3, 8, 0), stat_bonus=stats.INTELLIGENCE, element=stats.RESIST_FIRE, anim=animobs.RedCloud), effects.Enchant(enchantments.BurnLowEn)), on_failure=(effects.HealthDamage( (3, 8, 0), stat_bonus=None, element=stats.RESIST_FIRE, anim=animobs.RedCloud), ))) def init_monster(self): self.levels.append(base.Defender(14, self))
class Hydra( base.Monster ): name = "Hydra" statline = { stats.STRENGTH: 21, stats.TOUGHNESS: 20, stats.REFLEXES: 12, \ stats.INTELLIGENCE: 3, stats.PIETY: 10, stats.CHARISMA: 9, stats.PHYSICAL_ATTACK: 20 } SPRITENAME = "monster_default.png" FRAME = 3 TEMPLATES = (stats.REPTILE,stats.EARTH,) MOVE_POINTS = 8 HABITAT = ( context.HAB_EVERY, context.SET_EVERY, context.DES_EARTH, context.MTY_BOSS ) ENC_LEVEL = 11 VOICE = dialogue.voice.GREEK COMBAT_AI = aibrain.BruiserAI() TREASURE = treasuretype.Low() ATTACK = items.Attack( (2,10,0), element = stats.RESIST_PIERCING ) TECHNIQUES = ( invocations.MPInvocation( "Poison Breath", effects.OpposedRoll( def_stat=stats.TOUGHNESS, on_success = ( effects.HealthDamage( (3,6,0), stat_bonus=stats.TOUGHNESS, element=stats.RESIST_POISON, anim=animobs.PoisonCloud ), effects.TargetIs( effects.ALIVE, on_true=( effects.OpposedRoll( att_stat=None, def_stat=stats.TOUGHNESS, on_success = ( effects.Enchant( enchantments.PoisonClassic ) ,) ), )) ), on_failure = ( effects.HealthDamage( (2,6,0), stat_bonus=None, element=stats.RESIST_POISON, anim=animobs.PoisonCloud ) ,) ), com_tar=targetarea.Blast(radius=2), ai_tar=invocations.TargetEnemy(min_distance=3), mp_cost=20, shot_anim=animobs.GreenComet ), ) def init_monster( self ): self.levels.append( base.Terror( 10, self ) ) self.condition.append( enchantments.PermaMegaRegeneration() )
class Flaming(Enhancer): NAMEPAT = "Flaming {0}" DESCPAT = "{0} It glows with magical fire that does an extra 1d6 damage." PLUSRANK = 3 AFFECTS = (SWORD, AXE, MACE, DAGGER, STAFF, POLEARM, FARMTOOL, LANCE) ATTACK_ON_HIT = effects.HealthDamage((1, 6, 0), stat_bonus=None, element=stats.RESIST_FIRE, anim=animobs.OrangeExplosion) TYPE = ET_SECONDARY UPRANKS = (2, 2) UPGRADES = { 2: UpgradeTechnique( spells.firespells.PYROTECHNICS, "{0} It glows with magical fire that does an extra 1d6 damage, and allows use of the Pyrotechnics spell." ), 3: UpgradeAttack( effects.HealthDamage( (1, 6, 0), stat_bonus=None, element=stats.RESIST_FIRE, anim=animobs.OrangeExplosion, on_success=(effects.Enchant(enchantments.BurnLowEn), )), "{0} It glows with magical fire that burns continuously for 1d6 damage. It also allows use of the Pyrotechnics spell." ) }
class DreadWeapon(Enhancer): NAMEPAT = "Dread {0}" DESCPAT = "{0} Targets struck by this weapon may find themselves cursed." PLUSRANK = 1 AFFECTS = (SWORD, AXE, MACE, DAGGER, STAFF, POLEARM, FARMTOOL, BOW, SLING) ATTACK_ON_HIT = effects.Enchant(enchantments.CurseEn, anim=animobs.PurpleSparkle) TYPE = ET_SECONDARY
class AcidWepEn( Enchantment ): NAME = "Acid Weapon" def __init__( self ): super(AcidWepEn, self).__init__(statline=stats.StatMod({stats.PHYSICAL_ATTACK:10}),dispel=(COMBAT,MAGIC)) ATTACK_ON_HIT = effects.HealthDamage( (1,10,0), stat_bonus=None, element=stats.RESIST_ACID, anim=animobs.GreenExplosion, on_success=( effects.OpposedRoll( def_stat=stats.TOUGHNESS, on_failure = ( effects.Enchant( ArmorDamage, anim=animobs.OrangeSparkle ) ,)) ,) )
class PoisonWepEn( Enchantment ): NAME = "Poison Weapon" def __init__( self ): super(PoisonWepEn, self).__init__(statline=stats.StatMod({stats.PHYSICAL_ATTACK:10}),dispel=(COMBAT,MAGIC)) ATTACK_ON_HIT = effects.HealthDamage( (2,6,0), stat_bonus=None, element=stats.RESIST_POISON, anim=animobs.PoisonCloud, on_success=( effects.SavingThrow( roll_skill=stats.RESIST_POISON, roll_stat=stats.TOUGHNESS, on_failure = ( effects.Enchant( PoisonClassic, anim=animobs.DeathSparkle ) ,)) ,) )
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
class VenomWand(ManaWeapon): true_name = "Venom Wand" true_desc = "A hit from this wand will poison living creatures." itemtype = WAND MP_COST = 2 avatar_image = "avatar_wand.png" avatar_frame = 10 mass = 5 attackdata = Attack( (1,8,1), skill_mod=stats.REFLEXES, damage_mod=stats.INTELLIGENCE, \ element=stats.RESIST_WATER, reach=7, hit_anim=animobs.GreenCloud, shot_anim = animobs.GreenSpray, extra_effect=effects.TargetIs( effects.ALIVE, on_true=( effects.Enchant( enchantments.PoisonClassic ), ) ) )
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
class FireWeasel(base.Monster): name = "Fire Weasel" statline = { stats.STRENGTH: 12, stats.TOUGHNESS: 12, stats.REFLEXES: 15, \ stats.INTELLIGENCE: 3, stats.PIETY: 14, stats.CHARISMA: 9 } SPRITENAME = "monster_animals.png" FRAME = 29 TEMPLATES = (stats.FIRE, ) MOVE_POINTS = 10 VOICE = None HABITAT = (context.HAB_EVERY, context.SET_EVERY, context.MAP_WILDERNESS, context.DES_FIRE, context.MTY_BEAST, context.MTY_CREATURE, context.MTY_BOSS, context.GEN_NATURE) ENC_LEVEL = 4 ATTACK = items.Attack((1, 6, 0), element=stats.RESIST_PIERCING, extra_effect=effects.OpposedRoll( att_stat=None, att_modifier=5, on_success=( effects.HealthDamage( (1, 6, 0), stat_bonus=None, element=stats.RESIST_FIRE, anim=animobs.RedCloud), effects.Enchant(enchantments.BurnLowEn), ))) TECHNIQUES = (invocations.MPInvocation( "Fire Breath", effects.OpposedRoll(att_skill=stats.PHYSICAL_ATTACK, att_stat=stats.REFLEXES, def_stat=stats.REFLEXES, on_success=(effects.HealthDamage( (1, 6, 0), stat_bonus=stats.TOUGHNESS, element=stats.RESIST_FIRE, anim=animobs.RedCloud), ), on_failure=(effects.HealthDamage( (1, 3, 0), stat_bonus=None, element=stats.RESIST_FIRE, anim=animobs.RedCloud), )), com_tar=targetarea.Cone(reach=4), ai_tar=invocations.TargetEnemy(), mp_cost=3), ) def init_monster(self): self.levels.append(base.Beast(4, self))
class GreatCaveWyrm(base.Monster): name = "Great Cave Wyrm" statline = { stats.STRENGTH: 27, stats.TOUGHNESS: 21, stats.REFLEXES: 10, \ stats.INTELLIGENCE: 16, stats.PIETY: 17, stats.CHARISMA: 16, stats.PHYSICAL_ATTACK: 20, stats.RESIST_POISON: 100 } SPRITENAME = "monster_dragons.png" FRAME = 42 TEMPLATES = (stats.DRAGON, ) MOVE_POINTS = 10 VOICE = dialogue.voice.DRACONIAN HABITAT = (context.HAB_EVERY, context.SET_EVERY, context.HAB_CAVE, context.MAP_DUNGEON, context.MTY_LEADER, context.MTY_DRAGON, context.MTY_BOSS, context.DES_EARTH, context.GEN_DRAGON) ENC_LEVEL = 20 COMBAT_AI = aibrain.BruiserAI() TREASURE = treasuretype.DragonHoard() LONER = True COMPANIONS = ( OldCaveDragon, AncientCaveDragon, ) ATTACK = items.Attack((7, 8, 0), element=stats.RESIST_SLASHING, extra_effect=abilities.POISON_ATTACK_2d6) TECHNIQUES = (invocations.MPInvocation( "Toxic Breath", effects.OpposedRoll(def_stat=stats.TOUGHNESS, anim=None, on_success=( effects.HealthDamage( (9, 6, 0), stat_bonus=None, element=stats.RESIST_POISON, anim=animobs.PoisonCloud), effects.Paralyze(max_duration=3), effects.Enchant(enchantments.PoisonClassic, anim=animobs.DeathSparkle), ), on_failure=(effects.HealthDamage( (3, 9, 0), stat_bonus=None, element=stats.RESIST_POISON, anim=animobs.PoisonCloud), )), com_tar=targetarea.Cone(reach=8), ai_tar=invocations.TargetEnemy(), mp_cost=38), ) def init_monster(self): self.levels.append(base.Terror(28, self))
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))
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))
class FireScorpion(base.Monster): name = "Fire Scorpion" statline = { stats.STRENGTH: 19, stats.TOUGHNESS: 13, stats.REFLEXES: 18, \ stats.INTELLIGENCE: 4, stats.PIETY: 12, stats.CHARISMA: 1 } SPRITENAME = "monster_bugs.png" FRAME = 16 TEMPLATES = (stats.BUG, stats.FIRE) MOVE_POINTS = 10 VOICE = None HABITAT = (context.HAB_CAVE, context.HAB_DESERT, context.SET_EVERY, context.DES_FIRE, context.MTY_BEAST, context.MTY_BOSS, context.MTY_CREATURE, context.GEN_NATURE) ENC_LEVEL = 8 TECHNIQUES = (invocations.MPInvocation( "Flamethrower", effects.OpposedRoll(att_stat=stats.REFLEXES, on_success=( effects.HealthDamage( (2, 6, 0), stat_bonus=stats.INTELLIGENCE, element=stats.RESIST_FIRE, anim=animobs.Ignite), effects.Enchant(enchantments.BurnLowEn), ), on_failure=(effects.HealthDamage( (2, 6, 0), stat_bonus=stats.INTELLIGENCE, element=stats.RESIST_FIRE, anim=animobs.Ignite), )), com_tar=targetarea.Line(reach=6), ai_tar=invocations.TargetEnemy(), mp_cost=12), ) ATTACK = items.Attack((2, 8, 0), element=stats.RESIST_PIERCING, extra_effect=abilities.POISON_ATTACK_1d8) def init_monster(self): self.levels.append(base.Beast(8, self))
class Mummy( base.Monster ): name = "Mummy" statline = { stats.STRENGTH: 20, stats.TOUGHNESS: 20, stats.REFLEXES: 10, \ stats.INTELLIGENCE: 6, stats.PIETY: 14, stats.CHARISMA: 15 } SPRITENAME = "monster_undead.png" FRAME = 47 TEMPLATES = (stats.UNDEAD,stats.MUMMY) MOVE_POINTS = 6 VOICE = None HABITAT = ( context.HAB_DESERT, context.HAB_TUNNELS, context.SET_EVERY, context.MTY_UNDEAD, context.DES_SOLAR, context.GEN_UNDEAD ) ENC_LEVEL = 5 TREASURE = treasuretype.High() COMBAT_AI = aibrain.BrainDeadAI() ATTACK = items.Attack( (1,10,0), element = stats.RESIST_CRUSHING, extra_effect = effects.OpposedRoll( att_modifier=-10, on_success = ( effects.StatDamage( stats.TOUGHNESS, anim=animobs.GreenBoom ), effects.Enchant( enchantments.DiseaseEn, anim=None ) ,) ) ) def init_monster( self ): self.levels.append( base.Humanoid( 5, self ) )
class MadMonk(base.Monster): name = "Mad Monk" statline = { stats.STRENGTH: 12, stats.TOUGHNESS: 14, stats.REFLEXES: 16, \ stats.INTELLIGENCE: 12, stats.PIETY: 16, stats.CHARISMA: 10, stats.NATURAL_DEFENSE: -10, stats.MAGIC_DEFENSE: 10 } SPRITENAME = "monster_chaos.png" FRAME = 7 TEMPLATES = () MOVE_POINTS = 10 HABITAT = (context.HAB_EVERY, context.HAB_DESERT, context.SET_EVERY, context.MTY_HUMANOID, context.MTY_FIGHTER, context.MTY_PRIEST, context.DES_FIRE, context.GEN_CHAOS) ENC_LEVEL = 5 TREASURE = treasuretype.Standard((items.POTION, items.CLOTHES)) TECHNIQUES = (invocations.MPInvocation( "Fire Soul", effects.TargetIsAlly( on_true=(effects.Enchant(enchantments.RegeneratEn, anim=animobs.RedCloud), effects.TargetIsDamaged(on_true=(effects.HealthRestore( dice=(2, 6, 0)), ))), on_false=(effects.HealthDamage((2, 6, 0), stat_bonus=None, element=stats.RESIST_FIRE, anim=animobs.RedCloud), )), com_tar=targetarea.SelfCentered(radius=2, delay_from=-1), ai_tar=invocations.TargetWoundedAlly(), mp_cost=25), ) ATTACK = items.Attack((1, 8, 0), element=stats.RESIST_CRUSHING, extra_effect=effects.ManaDamage( (1, 8, 0), stat_bonus=None, anim=animobs.PurpleExplosion)) def init_monster(self): self.levels.append(base.Humanoid(5, self))
class FireElemental(base.Monster): name = "Fire Elemental" statline = { stats.STRENGTH: 35, stats.TOUGHNESS: 15, stats.REFLEXES: 20, \ stats.INTELLIGENCE: 12, stats.PIETY: 12, stats.CHARISMA: 12, stats.RESIST_FIRE: 100 } SPRITENAME = "monster_e_fire.png" FRAME = 0 TEMPLATES = (stats.ELEMENTAL, stats.FIRE) MOVE_POINTS = 10 HABITAT = (context.HAB_EVERY, context.SET_EVERY, context.GEN_IGNAN, context.DES_FIRE, context.SUMMON_ELEMENTAL) ENC_LEVEL = 12 ATTACK = items.Attack( (2, 8, 0), element=stats.RESIST_ATOMIC, extra_effect=effects.HealthDamage( (2, 8, 0), stat_bonus=stats.INTELLIGENCE, element=stats.RESIST_FIRE, anim=animobs.RedCloud, on_success=(effects.Enchant(enchantments.BurnLowEn), ))) def init_monster(self): self.levels.append(base.Beast(12, self))
self.confusion = 0 self.asleep = False self.silent = False self.aoo_readied = False self.attacks_so_far = 0 def can_act( self ): return self.paralysis < 1 and not self.asleep # This is a complex effect- Check if target is undead. If so, first apply an # enchantment. Then, make skill roll to cause 20-120 solar damage and paralysis. # If that skill roll fails, make an easier skill roll to just cause paralysis. HOLY_SIGN_EFFECT = effects.TargetIs( effects.UNDEAD, on_true = ( \ effects.Enchant(enchantments.HolySignMark,anim=animobs.YellowSparkle,children=( \ effects.OpposedRoll(stats.HOLY_SIGN, stats.CHARISMA, -70, stats.MAGIC_DEFENSE, stats.PIETY, on_success = ( effects.HealthDamage( (20,6,0), stats.PIETY, element=stats.RESIST_SOLAR, anim=animobs.YellowExplosion, on_success= (effects.Paralyze(max_duration=6),) ) ,), on_failure = ( effects.OpposedRoll(stats.HOLY_SIGN, stats.CHARISMA, 5, stats.MAGIC_DEFENSE, stats.PIETY, on_success = ( effects.Paralyze(max_duration=8) # Is there an obfuscated Python competition? ,)),)),)),)) class Combat( object ): def __init__( self, camp, monster_zero ): self.active = [] self.scene = camp.scene self.camp = camp self.ap_spent = collections.defaultdict( int ) self.cstat = collections.defaultdict( CombatStat ) self.no_quit = True self.activate_monster( monster_zero )
anim=animobs.OrangeExplosion), ), on_failure=(effects.HealthDamage( (1, 8, 0), stat_bonus=None, element=stats.RESIST_FIRE, anim=animobs.OrangeExplosion), )), rank=1, gems={FIRE: 1}, com_tar=targetarea.SingleTarget(), shot_anim=animobs.FireBolt, ai_tar=invocations.TargetEnemy()) BURNING_WEAPON = Spell( "Burning Weapon", "Magical flames burst from an ally's weapon, causing an extra 1-6 points of damge per hit. This effect lasts until the end of combat.", effects.Enchant(enchantments.FireWepEn, anim=animobs.RedSparkle), rank=1, gems={FIRE: 1}, com_tar=targetarea.SinglePartyMember(), ai_tar=invocations.TargetAllyWithoutEnchantment(enchantments.FireWepEn)) # CIRCLE 2 BLINDING_FLASH = Spell( "Blinding Flash", "A sudden flash of light will daze, and possibly stun, all enemies within 4 tiles.", effects.TargetIsEnemy(on_true=( effects.Enchant(enchantments.BlindedEn, anim=animobs.RedSparkle), effects.OpposedRoll(att_modifier=-20, on_success=(effects.Paralyze(max_duration=2), )))), rank=2,
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) ) # CIRCLE FOUR CALL_BEAST = Spell( "Call Beast", "This spell will summon a powerful 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}, 8, anim=animobs.OrangeSparkle ), rank=4, gems={EARTH:2,SOLAR:1}, com_tar=targetarea.SingleTarget(reach=2), ai_tar=invocations.TargetEmptySpot(), mpfudge = 9 ) # CIRCLE FIVE CALL_MONSTER = Spell( "Call Monster", "This spell will summon a powerful monster to fight on your behaf.",
ai_tar=invocations.TargetEmptySpot(), mpfudge=3) # CIRCLE 2 ACID_BOLT = Spell( "Acid Bolt", "This attack does 2d5 acid damage to a single target, and may corrode the target's armor.", effects.OpposedRoll( on_success=(effects.HealthDamage((2, 5, 0), stat_bonus=stats.INTELLIGENCE, element=stats.RESIST_ACID, anim=animobs.GreenExplosion), effects.OpposedRoll(def_stat=stats.TOUGHNESS, on_success=(effects.Enchant( enchantments.ArmorDamage, anim=animobs.OrangeSparkle), ))), on_failure=(effects.HealthDamage((1, 5, 0), stat_bonus=None, element=stats.RESIST_ACID, anim=animobs.GreenExplosion), )), rank=2, gems={EARTH: 1}, com_tar=targetarea.SingleTarget(), shot_anim=animobs.GreenSpray, ai_tar=invocations.TargetEnemy()) BEASTLY_MIGHT = Spell( "Beastly Might", "Imbues a single ally with supernatural strength, giving +4 strength, +4 toughness, and +5% to attack.", effects.Enchant(enchantments.BeastlyMightEn, anim=animobs.OrangeSparkle),
# CIRCLE 3 ACID_CLOUD = Spell( "Acid Cloud", "Calls forth billowing clouds of acid which do 2d6 damage to all targets within 3 tiles.", effects.OpposedRoll( on_success = ( effects.HealthDamage( (2,6,0), stat_bonus=stats.INTELLIGENCE, element=stats.RESIST_ACID, anim=animobs.GreenCloud ) ,), on_failure = ( effects.HealthDamage( (1,6,0), stat_bonus=None, element=stats.RESIST_ACID, anim=animobs.GreenCloud ) ,) ), rank=3, gems={EARTH:1,LUNAR:1}, com_tar=targetarea.Blast(radius=3), shot_anim=animobs.GreenComet, ai_tar=invocations.TargetEnemy(min_distance=4) ) PROTECT_FROM_GOOD = Spell( "Protection from Good", "All allies within 6 tiles get +10% defense, +10% aura, and 50% resistance to holy damage for the duration of combat.", effects.TargetIsAlly( on_true = ( effects.Enchant( enchantments.ProtectFromGoodEn, anim=animobs.PurpleSparkle ), )), rank=3, gems={LUNAR:1,WATER:1}, com_tar=targetarea.SelfCentered(), ai_tar=invocations.TargetAllyWithoutEnchantment(enchantments.ProtectFromGoodEn) ) # CIRCLE FOUR RAISE_UNDEAD = Spell( "Raise Undead", "You conjure dark forces to animate an undead creature which will fight on your behaf.", effects.CallMonster( {context.MTY_UNDEAD: True, context.DES_LUNAR: context.MAYBE, context.GEN_UNDEAD: context.MAYBE}, 8, anim=animobs.PurpleSparkle ), rank=4, gems={EARTH:1,LUNAR:2}, com_tar=targetarea.SingleTarget(reach=2), ai_tar=invocations.TargetEmptySpot(), mpfudge=6 ) ICE_WEAPON = Spell( "Icy Weapon", "One ally's weapon will glow with magical cold, causing an extra 1-10 points of damge per hit and potentially freezing enemies solid. This effect lasts until the end of combat.", effects.Enchant( enchantments.FrostWepEn, anim=animobs.PurpleSparkle ),
on_failure=(effects.NoEffect(anim=animobs.SmallBoom), )), com_tar=targetarea.SingleTarget(reach=9), shot_anim=animobs.Arrow, ai_tar=invocations.TargetEnemy()) # Extra Effects for attaching to attacks. BURN_ATTACK = effects.OpposedRoll(att_stat=None, def_stat=stats.REFLEXES, on_success=( effects.HealthDamage( (1, 6, 0), stat_bonus=None, element=stats.RESIST_FIRE, anim=animobs.RedCloud), effects.Enchant(enchantments.BurnLowEn), )) POISON_ATTACK = effects.TargetIs( effects.ALIVE, on_true=(effects.OpposedRoll( att_stat=None, def_stat=stats.TOUGHNESS, on_success=( effects.HealthDamage((1, 4, 0), stat_bonus=None, element=stats.RESIST_POISON, anim=animobs.PoisonCloud), effects.Enchant(enchantments.PoisonClassic), )), ))
"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() ) # CIRCLE FOUR ANIMATION = Spell( "Animation", "This spell will temporarily imbue inanimate objects with life.", effects.CallMonster( {context.MTY_CONSTRUCT: True, context.DES_AIR: context.MAYBE, context.DES_FIRE: context.MAYBE}, 8, anim=animobs.RedSparkle ), rank=4, gems={AIR:1,FIRE:1}, com_tar=targetarea.SingleTarget(reach=2), ai_tar=invocations.TargetEmptySpot(), mpfudge = 10 ) INCINERATE = Spell( "Incinerate", "Eldritch flames envelop a single foe, doing 6d6 fire damage and possibly setting the target alight.", effects.OpposedRoll( on_success = ( effects.HealthDamage( (6,6,0), stat_bonus=stats.INTELLIGENCE, element=stats.RESIST_FIRE, anim=animobs.RedCloud ), effects.Enchant( enchantments.BurnLowEn )
from base import SOLAR, EARTH, WATER, FIRE, AIR, LUNAR, Spell import effects import targetarea import enchantments import animobs import stats import invocations # CIRCLE 1 BLESSING = Spell( "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
from base import SOLAR, EARTH, WATER, FIRE, AIR, LUNAR, Spell import effects import targetarea import enchantments import animobs import stats import invocations import context # CIRCLE ONE AIR_ARMOR = Spell( "Shield of Wind", "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())
import stats import context import invocations # Priests get AIR, SOLAR, and WATER magic. These spells use a mixture of two # or more of those colors. # CIRCLE ONE ARMOR_OF_FAITH = Spell( "Armor of Faith", "The caster is infused with divine energy, healing wounds and bestowing protection.", effects.HealthRestore(dice=(3, 6, 0), anim=animobs.YellowSparkle, children=( effects.Enchant(enchantments.BlessingEn, anim=None), effects.Enchant(enchantments.AirArmor, anim=None), )), rank=1, gems={ SOLAR: 1, AIR: 1 }, com_tar=targetarea.SelfOnly(), ai_tar=invocations.TargetWoundedAlly(), mpfudge=-2) BLAST_UNDEAD = Spell( "Blast Undead", "This mystic bolt deals 1-6 damage to undead creatures.",