From 65b4a0d37d19ad0fcb8bd6f7ae2b1b898561c247 Mon Sep 17 00:00:00 2001 From: doug1234 Date: Sat, 6 Jan 2024 20:35:38 -0500 Subject: [PATCH 01/12] Updated spell utils and pymod from the sagenlicth branch. Also added the warmage spells from the sagenlicth branch essentially as is with the plan to finish them soon. Co-authored-by: Sagenlicht --- tpdata/templeplus/lib/templeplus/pymod.py | 9 + .../co8infra/mes/help/class_spell_lists.tab | 10 + tpdatasrc/tpgamefiles/mes/damage_ext.mes | 1 + .../mes/help/spell_compendium_help.tab | 17 +- .../mes/spell_ext/spell_compendium_spell.mes | 35 +- ...ell_compendium_spell_long_descriptions.mes | 74 ++- .../rules/char_class/class047_warmage.py | 10 +- .../tpgamefiles/rules/indicators/accuracy.txt | 5 + .../rules/indicators/blades_of_fire.txt | 5 + .../partsys/spell_compendium_partsys.tab | 41 +- .../spell_compendium_spell_enum.mes | 63 ++- .../rules/spells/1182 - Accuracy.txt | 17 + .../rules/spells/1183 - Hail of Stone.txt | 17 + .../spells/1184 - Lesser Orb of Acid.txt | 22 + .../spells/1185 - Lesser Orb of Cold.txt | 22 + .../1186 - Lesser Orb of Electricity.txt | 22 + .../spells/1187 - Lesser Orb of Fire.txt | 22 + .../spells/1188 - Lesser Orb of Sound.txt | 22 + .../rules/spells/1189 - Blades of Fire.txt | 22 + .../rules/spells/1190 - Fireburst.txt | 16 + .../rules/spells/1191 - Greater Fireburst.txt | 16 + .../rules/spells/1195 - Blast of Flame.txt | 23 + .../rules/spells/1196 - Orb of Acid.txt | 22 + .../rules/spells/1197 - Orb of Cold.txt | 22 + .../spells/1198 - Orb of Electricity.txt | 22 + .../rules/spells/1199 - Orb of Fire.txt | 22 + .../rules/spells/1200 - Orb of Sonic.txt | 22 + .../tpgamefiles/scr/Spell1182 - Accuracy.py | 26 + .../scr/Spell1183 - Hail of Stone.py | 32 ++ .../scr/Spell1184 - Lesser Orb of Acid.py | 44 ++ .../scr/Spell1185 - Lesser Orb of Cold.py | 44 ++ .../Spell1186 - Lesser Orb of Electricity.py | 44 ++ .../scr/Spell1187 - Lesser Orb of Fire.py | 44 ++ .../scr/Spell1188 - Lesser Orb of Sound.py | 44 ++ .../scr/Spell1189 - Blades of Fire.py | 44 ++ .../tpgamefiles/scr/Spell1190 - Fireburst.py | 37 ++ .../scr/Spell1191 - Greater Fireburst.py | 37 ++ .../scr/Spell1195 - Blast of Flame.py | 37 ++ .../scr/Spell1196 - Orb of Acid.py | 53 ++ .../scr/Spell1197 - Orb of Cold.py | 54 ++ .../scr/Spell1198 - Orb of Electricity.py | 59 ++ .../scr/Spell1199 - Orb of Fire.py | 54 ++ .../scr/Spell1200 - Orb of Sound.py | 56 ++ tpdatasrc/tpgamefiles/scr/spell_utils.py | 508 ++++++++++++++---- .../scr/tpModifiers/sp_accuracy.py | 13 + .../scr/tpModifiers/sp_blades_of_fire.py | 67 +++ .../user_sounds/spell_compendium_sounds.mes | 179 +++++- 47 files changed, 1966 insertions(+), 111 deletions(-) create mode 100644 tpdatasrc/tpgamefiles/rules/indicators/accuracy.txt create mode 100644 tpdatasrc/tpgamefiles/rules/indicators/blades_of_fire.txt create mode 100644 tpdatasrc/tpgamefiles/rules/spells/1182 - Accuracy.txt create mode 100644 tpdatasrc/tpgamefiles/rules/spells/1183 - Hail of Stone.txt create mode 100644 tpdatasrc/tpgamefiles/rules/spells/1184 - Lesser Orb of Acid.txt create mode 100644 tpdatasrc/tpgamefiles/rules/spells/1185 - Lesser Orb of Cold.txt create mode 100644 tpdatasrc/tpgamefiles/rules/spells/1186 - Lesser Orb of Electricity.txt create mode 100644 tpdatasrc/tpgamefiles/rules/spells/1187 - Lesser Orb of Fire.txt create mode 100644 tpdatasrc/tpgamefiles/rules/spells/1188 - Lesser Orb of Sound.txt create mode 100644 tpdatasrc/tpgamefiles/rules/spells/1189 - Blades of Fire.txt create mode 100644 tpdatasrc/tpgamefiles/rules/spells/1190 - Fireburst.txt create mode 100644 tpdatasrc/tpgamefiles/rules/spells/1191 - Greater Fireburst.txt create mode 100644 tpdatasrc/tpgamefiles/rules/spells/1195 - Blast of Flame.txt create mode 100644 tpdatasrc/tpgamefiles/rules/spells/1196 - Orb of Acid.txt create mode 100644 tpdatasrc/tpgamefiles/rules/spells/1197 - Orb of Cold.txt create mode 100644 tpdatasrc/tpgamefiles/rules/spells/1198 - Orb of Electricity.txt create mode 100644 tpdatasrc/tpgamefiles/rules/spells/1199 - Orb of Fire.txt create mode 100644 tpdatasrc/tpgamefiles/rules/spells/1200 - Orb of Sonic.txt create mode 100644 tpdatasrc/tpgamefiles/scr/Spell1182 - Accuracy.py create mode 100644 tpdatasrc/tpgamefiles/scr/Spell1183 - Hail of Stone.py create mode 100644 tpdatasrc/tpgamefiles/scr/Spell1184 - Lesser Orb of Acid.py create mode 100644 tpdatasrc/tpgamefiles/scr/Spell1185 - Lesser Orb of Cold.py create mode 100644 tpdatasrc/tpgamefiles/scr/Spell1186 - Lesser Orb of Electricity.py create mode 100644 tpdatasrc/tpgamefiles/scr/Spell1187 - Lesser Orb of Fire.py create mode 100644 tpdatasrc/tpgamefiles/scr/Spell1188 - Lesser Orb of Sound.py create mode 100644 tpdatasrc/tpgamefiles/scr/Spell1189 - Blades of Fire.py create mode 100644 tpdatasrc/tpgamefiles/scr/Spell1190 - Fireburst.py create mode 100644 tpdatasrc/tpgamefiles/scr/Spell1191 - Greater Fireburst.py create mode 100644 tpdatasrc/tpgamefiles/scr/Spell1195 - Blast of Flame.py create mode 100644 tpdatasrc/tpgamefiles/scr/Spell1196 - Orb of Acid.py create mode 100644 tpdatasrc/tpgamefiles/scr/Spell1197 - Orb of Cold.py create mode 100644 tpdatasrc/tpgamefiles/scr/Spell1198 - Orb of Electricity.py create mode 100644 tpdatasrc/tpgamefiles/scr/Spell1199 - Orb of Fire.py create mode 100644 tpdatasrc/tpgamefiles/scr/Spell1200 - Orb of Sound.py create mode 100644 tpdatasrc/tpgamefiles/scr/tpModifiers/sp_accuracy.py create mode 100644 tpdatasrc/tpgamefiles/scr/tpModifiers/sp_blades_of_fire.py diff --git a/tpdata/templeplus/lib/templeplus/pymod.py b/tpdata/templeplus/lib/templeplus/pymod.py index 93acd621b..99417e359 100644 --- a/tpdata/templeplus/lib/templeplus/pymod.py +++ b/tpdata/templeplus/lib/templeplus/pymod.py @@ -56,3 +56,12 @@ def AddSpellTeleportReconnectStandard(self): def AddSpellDispelCheckStandard(self): self.add_spell_dispel_check_standard() +class BasicPyMod(tpdp.ModifierSpec): + def AddHook(self, eventType, eventKey, callbackFcn, argsTuple): + self.add_hook(eventType, eventKey, callbackFcn, argsTuple) + def ExtendExisting(self, condName): + self.extend_existing(condName) + +class FeatPyMod(BasicPyMod): + def __init__(self, feat_enum, feat_cond_arg2 = 0, args = 2, preventDuplicate = True, feat_list_max = -1): + self.add_to_feat_dict(feat_enum, feat_list_max, feat_cond_arg2) diff --git a/tpdatasrc/co8infra/mes/help/class_spell_lists.tab b/tpdatasrc/co8infra/mes/help/class_spell_lists.tab index 5d9dcc454..78b4538ef 100644 --- a/tpdatasrc/co8infra/mes/help/class_spell_lists.tab +++ b/tpdatasrc/co8infra/mes/help/class_spell_lists.tab @@ -10,6 +10,16 @@ TAG_BLACKGUARD_1 TAG_SPELLS Level 1 Blackguard Spells [CMD_CHILDREN_SORTED] TAG_BLACKGUARD_2 TAG_SPELLS Level 2 Blackguard Spells [CMD_CHILDREN_SORTED] TAG_BLACKGUARD_3 TAG_SPELLS Level 3 Blackguard Spells [CMD_CHILDREN_SORTED] TAG_BLACKGUARD_4 TAG_SPELLS Level 4 Blackguard Spells [CMD_CHILDREN_SORTED] +TAG_WARMAGE_0 TAG_SPELLS Level 0 Warmage Spells [CMD_CHILDREN_SORTED] +TAG_WARMAGE_1 TAG_SPELLS Level 1 Warmage Spells [CMD_CHILDREN_SORTED] +TAG_WARMAGE_2 TAG_SPELLS Level 2 Warmage Spells [CMD_CHILDREN_SORTED] +TAG_WARMAGE_3 TAG_SPELLS Level 3 Warmage Spells [CMD_CHILDREN_SORTED] +TAG_WARMAGE_4 TAG_SPELLS Level 4 Warmage Spells [CMD_CHILDREN_SORTED] +TAG_WARMAGE_5 TAG_SPELLS Level 5 Warmage Spells [CMD_CHILDREN_SORTED] +TAG_WARMAGE_6 TAG_SPELLS Level 6 Warmage Spells [CMD_CHILDREN_SORTED] +TAG_WARMAGE_7 TAG_SPELLS Level 7 Warmage Spells [CMD_CHILDREN_SORTED] +TAG_WARMAGE_8 TAG_SPELLS Level 8 Warmage Spells [CMD_CHILDREN_SORTED] +TAG_WARMAGE_9 TAG_SPELLS Level 9 Warmage Spells [CMD_CHILDREN_SORTED] TAG_SPELLS_BULL'S_STRENGTH TAG_SPELLS TAG_BLACKGUARD_2 TAG_CLERIC_2 TAG_DRUID_2 TAG_PALADIN_2 TAG_SORCERER_2 TAG_STRENGTH_D TAG_WIZARD_2 Bull's Strength ~Transmutation~[TAG_MAGIC_SCHOOLS_TRANSMUTATION] Level: ~Blackguard~[TAG_BLACKGUARDS] 2, ~Cleric~[TAG_CLERICS] 2, ~Druid~[TAG_DRUIDS] 2, ~Paladin~[TAG_PALADINS] 2, ~Sorcerer~[TAG_SORCERERS]/~Wizard~[TAG_WIZARDS] 2, ~Domain: Strength~[TAG_STRENGTH_D] 2 Components: V, S Casting Time: 1 ~standard action~[TAG_STANDARD_ACTION] Range: Touch Target: Creature touched Duration: 1 min./level Saving Throw: ~Will~[TAG_WILL] negates (harmless) Spell Resistance: Yes (harmless) The subject becomes stronger. The spell grants a +4 ~enhancement~[TAG_ENHANCEMENT_BONUS] bonus to ~Strength~[TAG_STRENGTH], adding the usual benefits to melee ~attack rolls~[TAG_ATTACK_ROLL], melee damage rolls, and other uses of the Strength modifier. TAG_SPELLS_CATS_GRACE TAG_SPELLS TAG_ASSASSIN_2 TAG_BARD_2 TAG_DRUID_2 TAG_RANGER_2 TAG_SORCERER_2 TAG_WIZARD_2 Cat's Grace ~Transmutation~[TAG_MAGIC_SCHOOLS_TRANSMUTATION] Level: ~Assassin~[TAG_ASSASSINS] 2, ~Bard~[TAG_BARDS] 2, ~Druid~[TAG_DRUIDS] 2, ~Ranger~[TAG_RANGERS] 2, ~Sorcerer~[TAG_SORCERERS]/~Wizard~[TAG_WIZARDS] 2 Components: V, S Casting Time: 1 ~standard action~[TAG_STANDARD_ACTION] Range: Touch Target: Creature touched Duration: 1 min./level Saving Throw: ~Will~[TAG_WILL] negates (harmless) Spell Resistance: Yes The transmuted creature becomes more graceful, agile, and coordinated. The spell grants a +4 ~enhancement~[TAG_ENHANCEMENT_BONUS] bonus to ~Dexterity~[TAG_DEXTERITY], adding the usual benefits to ~AC~[TAG_ARMOR_CLASS], ~Reflex~[TAG_REFLEX] saves, and other uses of the Dexterity modifier. TAG_SPELLS_CAUSE_FEAR TAG_SPELLS TAG_BARD_1 TAG_BLACKGUARD_1 TAG_CLERIC_1 TAG_DEATH_D TAG_SORCERER_1 TAG_WIZARD_1 Cause Fear ~Necromancy~[TAG_MAGIC_SCHOOLS_NECROMANCY] Fear, Mind-Affecting Level: ~Bard~[TAG_BARDS] 1, ~Blackguard~[TAG_BLACKGUARDS] 1, ~Cleric~[TAG_CLERICS] 1, ~Domain: Death~[TAG_DEATH_D] 1, ~Sorcerer~[TAG_SORCERERS]/~Wizard~[TAG_WIZARDS] 1 Components: V, S Casting Time: 1 ~standard action~[TAG_STANDARD_ACTION] Range: Close (25 ft. + 5 ft./2 levels) Target: One living creature with 5 or fewer HD Duration: 1d4 rounds (if saving throw is failed) or 1 round (if saving throw is successful) Saving Throw: ~Will~[TAG_WILL] partial Spell Resistance: Yes The affected creature becomes ~frightened~[TAG_FRIGHTENED]. If the subject succeeds on a Will save, it is ~shaken~[TAG_SHAKEN] for 1 round. Creatures with 6 or more HD are immune to this effect. Cause Fear counters and dispels ~Remove Fear~[TAG_SPELLS_REMOVE_FEAR]. diff --git a/tpdatasrc/tpgamefiles/mes/damage_ext.mes b/tpdatasrc/tpgamefiles/mes/damage_ext.mes index 8efa92cb5..1e4fb3627 100644 --- a/tpdatasrc/tpgamefiles/mes/damage_ext.mes +++ b/tpdatasrc/tpgamefiles/mes/damage_ext.mes @@ -13,6 +13,7 @@ {3006}{~Undead Bane Weapon~[TAG_SPELLS_UNDEAD_BANE_WEAPON]} {3007}{~Lawful Sword~[TAG_SPELLS_LAWFUL_SWORD]} {3008}{~Weapon of Energy~[TAG_SPELLS_WEAPON_OF_ENERGY]} +{3010}{~Blades of Fire~[TAG_SPELLS_BLADES_OF_FIRE]} // Feat Damage effects {4000}{~Flying Kick~[TAG_FLYING_KICK]} diff --git a/tpdatasrc/tpgamefiles/mes/help/spell_compendium_help.tab b/tpdatasrc/tpgamefiles/mes/help/spell_compendium_help.tab index a9af98fe3..d38ab9f98 100644 --- a/tpdatasrc/tpgamefiles/mes/help/spell_compendium_help.tab +++ b/tpdatasrc/tpgamefiles/mes/help/spell_compendium_help.tab @@ -1,4 +1,5 @@ TAG_WEAPON_SHIELD_PROFICIENCY TAG_COMBAT Weapon, Armor, and Shield Proficiency A character who uses a weapon with which he or she is not proficient takes a -4 penalty on ~attack rolls~[TAG_ATTACK_ROLL]. A character who wears armor and/or uses a shield with which he or she is not proficient takes the armor's (and/or shield's) armor check penalty on attack rolls and on all Strength-based and Dexterity-based ability and skill checks. The penalty for nonproficiency with armor stacks with the penalty for nonproficiency with shields. Weapon, armor, or shield proficiency may be granted by the character's race, class or by the following feats: ~Armor Proficiency (Light)~[TAG_ARMOR_LIGHT] ~Armor Proficiency (Medium)~[TAG_ARMOR_MEDIUM] ~Armor Proficiency (Heavy)~[TAG_ARMOR_HEAVY] ~Exotic Weapon Proficiency~[TAG_EXOTIC_PROF] ~Martial Weapon Proficiency~[TAG_MARTIAL_PROF] ~Simple Weapon Proficiency~[TAG_SIMPLE_PROF] ~Shield Proficiency~[TAG_SHIELD_PROF] Note: I am unsure about the state of simple weapon prof and shield prof and need to verify the help text as they differ from actual D&D. +TAG_SPELLS_ACCURACY TAG_SPELLS TAG_WARMAGE_1 Accuracy ~Transmutation~[TAG_MAGIC_SCHOOLS_TRANSMUTATION] Level: ~Warmage~[TAG_WARMAGES] 1 Components: V, S, M Casting Time: 1 ~standard action~[TAG_STANDARD_ACTION] Range: Personal Target: Touch Duration: 10 minutes/level Saving Throw: None Spell Resistance: No When you cast this spell, you enhance one or more thrown weapons or one projectile weapon to improve its chance of hitting distant targets. For the duration of the spell, the range increment for the affected weapon or weapons is doubled. TAG_SPELLS_ACID_FOG TAG_SPELLS TAG_SORCERER_6 TAG_WIZARD_6 TAG_WATER_D Acid Fog ~Conjuration~[TAG_MAGIC_SCHOOLS_CONJURATION](Creation)[Acid] Level: ~Sorcerer~[TAG_SORCERERS]/~Wizard~[TAG_WIZARDS] 6, ~Domain: Water~[TAG_WATER_D] 7 Components: V, S Casting Time: 1 ~standard action~[TAG_STANDARD_ACTION] Range: Medium (100 ft. + 10 ft./level) Area: 20-ft. radius Duration: 1 round/level Saving Throw: None Spell Resistance: No Acid fog creates a billowing mass of misty vapors similar to that produced by a ~solid fog~[TAG_SPELLS_SOLID_FOG] spell. In addition to slowing creatures down and obscuring sight, this spell's vapors are highly acidic. Each round on your turn, starting when you cast the spell, the fog deals 2d6 points of acid damage to each creature and object within it. TAG_SPELLS_AID_MASS TAG_SPELLS TAG_CLERIC_3 Aid, Mass ~Enchantment~[TAG_MAGIC_SCHOOLS_ENCHANTMENT](Compulsion)[Mind-Affecting] Level: ~Cleric~[TAG_CLERICS] 3 Components: V, S Casting Time: 1 ~standard action~[TAG_STANDARD_ACTION] Range: Close (25 ft. + 5 ft./2 levels) Target: One creature/level no two more than 30 ft. apart Duration: 1 min./level Saving Throw: None Spell Resistance: No You hold your holy symbol aloft and cast the spell. A silvery radiance dances from your hands, leaping over all the nearby party members and strengthening them. Aid, Mass grants the targets a +1 ~morale~[TAG_MODIFIER_MORALE] bonus on ~attack rolls~[TAG_ATTACK_ROLL] and saves against ~fear~[TAG_FEAR] effects, plus ~temporary hit points~[TAG_TEMPORARY_HIT_POINTS] equal to 1d8 + ~caster level~[TAG_CASTER_LEVEL] (to a maximum of 1d8+15 temporary hit points). TAG_SPELLS_ALIGN_WEAPON_MASS TAG_SPELLS TAG_CLERIC_3 Align Weapon, Mass ~Transmutation~[TAG_MAGIC_SCHOOLS_TRANSMUTATION](see text) Level: ~Cleric~[TAG_CLERICS] 3 Components: V, S Casting Time: 1 ~standard action~[TAG_STANDARD_ACTION] Range: Close (25 ft. + 5 ft./2 levels) Target: One creature/level no two more than 30 ft. apart Duration: 1 min./level Saving Throw: None Spell Resistance: No You hold your holy symbol high and speak old words of power. Your party's weapons take on a pale blue radiance. This spell functions like ~align weapon~[TAG_SPELLS_ALIGN_WEAPON], except that it affects multiple weapons or projectiles at a distance. Note: The projectiles part is not implemented. Warning: as a cleric you can't cast a spell that does have an opposed Alignment Descriptor. I can't change the descriptor on the fly, which means you can actually try to cast the spell but it will fizzle and you loose the spell if you try to cast it with the wrong alignment! @@ -8,7 +9,9 @@ TAG_SPELLS_ANGELSKIN TAG_SPELLS TAG_PALADIN_2 Angelskin ~Abjuration~[TAG_MAGIC_ TAG_SPELLS_APPRAISING_TOUCH TAG_SPELLS TAG_BARD_1 TAG_SORCERER_1 TAG_WIZARD_1 Appraising Touch ~Divination~[TAG_MAGIC_SCHOOLS_DIVINATION] Level: ~Bard~[TAG_BARDS] 1, ~Sorcerer~[TAG_SORCERERS]/~Wizard~[TAG_WIZARDS] 1 Components: V, S Casting Time: 1 ~standard action~[TAG_STANDARD_ACTION] Range: Personal Target: You Duration: 1 hour/level Encircling your eye with thumb and forefinger as if holding a jeweler's lens, you speak the arcane words that complete the spell. Objects near you suddenly seem clearer, more in focus. You note blemishes and imperfections you had missed before. You gain an intuitive insight into the value of objects you come into contact with. You gain a +10 ~insight~[TAG_MODIFIER_INSIGHT] bonus on ~Appraise~[TAG_APPRAISE] checks to determine the value of items you touch while this spell is in effect. TAG_SPELLS_AWAKEN_SIN TAG_SPELLS TAG_CLERIC_3 TAG_PALADIN_2 Awaken Sin ~Enchantment~[TAG_MAGIC_SCHOOLS_ENCHANTMENT](Compulsion)[Fear][Good][Mind-Affecting] Level: ~Cleric~[TAG_CLERICS] 3, ~Paladin~[TAG_PALADINS] 2 Components: V, S Casting Time: 1 ~standard action~[TAG_STANDARD_ACTION] Range: Touch Target: One evil creature with intelligence 3+ Duration: Instantaneous Saving Throw: ~Will~[TAG_WILL] negates Spell Resistance: Yes A command for repentance issues from your mouth, carrying with it the power of the spell. The crushing feeling of guilt that grew within you while you cast the spell lifts as you project the feeling at your target. The subject immediately takes 1d6 points of ~nonlethal~[TAG_RADIAL_MENU_NONLETHAL_DAMAGE] damage per caster level (maximum 10d6) and is ~stunned~[TAG_STUNNED] for 1 round. If this knocks the subject ~unconscious~[TAG_UNCONSCIOUS], it also takes 1d6 points of ~Wisdom~[TAG_WISDOM] damage. Note: please be aware of the target restrictions! TAG_SPELLS_AXIOMATIC_STORM TAG_SPELLS TAG_CLERIC_3 TAG_PALADIN_3 Axiomatic Storm ~Conjuration~[TAG_MAGIC_SCHOOLS_CONJURATION](Creation)[Lawful][Water] Level: ~Cleric~[TAG_CLERICS] 3, ~Paladin~[TAG_PALADINS] 3 Components: V, S Casting Time: 1 ~standard action~[TAG_STANDARD_ACTION] Range: 20 ft. Area: 20-ft. radius Duration: 1 round/level Saving Throw: None Spell Resistance: No You call upon the forces of law and a heavy rain begins to fall around you, its raindrops harsh and metallic. Above you, a jet of caustic acid lances down from the heavens. A driving rain falls around you. It falls in a fixed area once created. The storm reduces hearing and visibility, resulting in a -4 penalty on ~Listen~[TAG_LISTEN], ~Spot~[TAG_SPOT], and ~Search~[TAG_SEARCH] checks. It also applies a -4 penalty on ~ranged~[TAG_RANGED_ATTACKS] attacks made into, out of, or through the storm. Finally, it automatically extinguishes any unprotected flames and has a 50% chance to extinguish protected flames (such as those of lanterns). The rain damages chaotic creatures, dealing 2d6 points of damage per round (chaotic outsiders take double damage). In addition, each round, a gout of acid strikes a randomly selected chaotic outsider within the spell's area, dealing 5d6 points of acid damage. After the spell's duration expires, the water disappears. +TAG_SPELLS_BLADES_OF_FIRE TAG_SPELLS TAG_RANGER_1 TAG_SORCERER_1 TAG_WARMAGE_2 TAG_WIZARD_1 Blades of Fire ~Conjuration~[TAG_MAGIC_SCHOOLS_CONJURATION] Level: ~Ranger~[TAG_RANGERS] 1, ~Sorcerer~[TAG_SORCERERS]/~Wizard~[TAG_WIZARDS] 1, ~Warmage~[TAG_WARMAGES] 2 Components: V Casting Time: 1 ~Swift Action~[TAG_SWIFT_ACTION] Range: Touch Target: Weapons touched Duration: 1 round With a word your weapons burst into flame. You feel no heat and the flames merely tickle your skin. Your melee weapons each deal an extra 1d8 points of fire damage. This damage stacks with any energy damage your weapons already deal. TAG_SPELLS_BLADEWEAVE TAG_SPELLS TAG_BARD_2 TAG_SORCERER_2 TAG_WIZARD_2 Bladeweave ~Illusion~[TAG_MAGIC_SCHOOLS_ILLUSION] Level: ~Bard~[TAG_BARDS] 2, ~Sorcerer~[TAG_SORCERERS]/~Wizard~[TAG_WIZARDS] 2 Components: V Casting Time: 1 ~Free action~[TAG_FREE_ACTION] Range: Personal Target: You Duration: 1 round/level With a shout you unleash the power of the spell, causing every movement you make with your weapon to seem beautiful and full of flourish. Once per round, choose one target that you successfully attacked with a melee weapon. That creature must succeed on a ~Will~[TAG_WILL] save or be ~dazed~[TAG_DAZED] for 1 round. Spell resistance applies to this effect. Note: In Temple of Elemental Evil your first successful attack in a given round will try to daze. +TAG_SPELLS_BLAST_OF_FLAME TAG_SPELLS TAG_SORCERER_4 TAG_WARMAGE_4 TAG_WIZARD_4 Blast of Flame ~Conjuration~[TAG_MAGIC_SCHOOLS_CONJURATION](Creation)[Fire] Level: ~Sorcerer~[TAG_SORCERERS]/~Wizard~[TAG_WIZARDS] 4, ~Warmage~[TAG_WARMAGE_4] 4 Components: V, S Casting Time: 1 ~standard action~[TAG_STANDARD_ACTION] Range: 60 ft. Area: Cone-shaped burst Duration: Instantaneous Saving Throw: ~Reflex~[TAG_REFLEX] half Spell Resistance: No As you cast the spell, your hand becomes sheathed in barely perceptible yellow flames. With a roar, the flames burst from your hand in the shape of a cone, leaving your hand trailing wisps of smoke. Flames fill the area, dealing 1d6 points of fire damage per caster level (maximum 10d6) to any creature in the area that fails its saving throw. TAG_SPELLS_BLESS_WEAPON_SWIFT TAG_SPELLS TAG_PALADIN_1 Bless Weapon, Swift ~Transmutation~[TAG_MAGIC_SCHOOLS_TRANSMUTATION] Level: ~Paladin~[TAG_PALADINS] 1 Components: V, S Casting Time: 1 ~free action~[TAG_FREE_ACTION] Range: Personal Target: Weapon touched Duration: 1 round Saving Throw: None Spell Resistance: No You invoke the holy words quickly, and your weapon flashes a momentary blue-white radiance. This spell functions like ~bless weapon~[TAG_SPELLS_BLESS_WEAPON], except as noted above. Notes: The projectiles part is not implemented. TAG_SPELLS_BLESSED_AIM TAG_SPELLS TAG_BLACKGUARD_1 TAG_CLERIC_1 TAG_PALADIN_1 Blessed Aim ~Divination~[TAG_MAGIC_SCHOOLS_DIVINATION] Level: ~Blackguard~[TAG_BLACKGUARDS] 1, ~Cleric~[TAG_CLERICS] 1, ~Paladin~[TAG_PALADINS] 1 Components: V, S Casting Time: 1 ~standard action~[TAG_STANDARD_ACTION] Range: 50 ft. Effect: 50-ft.-radius spread centered on you Duration: 1 minute/level With the blessing of your deity, you bolster your allies' aim with an exhortation. This spell grants your allies within the spread a +2 ~morale~[TAG_MODIFIER_MORALE] bonus on ~ranged~[TAG_RANGED_ATTACKS] attack rolls. TAG_SPELLS_BLESSING_OF_BAHAMUT TAG_SPELLS TAG_PALADIN_3 Blessing of Bahamut ~Abjuration~[TAG_MAGIC_SCHOOLS_ABJURATION][Good] Level: ~Paladin~[TAG_PALADINS] 3 Components: V, S Casting Time: 1 ~standard action~[TAG_STANDARD_ACTION] Range: Personal Target: You Duration: 1 round/level Saving Throw: None Spell Resistance: No You hear a distant dragon's roar that no one else detects, and your skin takes on a platinum sheen You gain ~damage reduction~[TAG_SPECIAL_ABILITIES_DAMAGE_REDUCTION] 10/magic for the spell's duration. @@ -49,12 +52,15 @@ TAG_SPELLS_FELL_THE_GREATEST_FOE TAG_SPELLS TAG_ASSASSIN_2 TAG_CLERIC_3 TAG_PAL TAG_SPELLS_FIND_THE_GAP TAG_SPELLS TAG_ASSASSIN_3 TAG_PALADIN_3 TAG_RANGER_3 Find the Gap ~Divination~[TAG_MAGIC_SCHOOLS_DIVINATION] Level: ~Assassin~[TAG_ASSASSINS] 3, ~Paladin~[TAG_PALADINS] 3, ~Ranger~[TAG_RANGERS] 3 Components: V Casting Time: 1 ~standard action~[TAG_STANDARD_ACTION] Range: Personal Target: You Duration: 1 round/level You speak the words of this spell, and a blue mark that only you can see appears on your opponent, highlighting a weak spot in her defense. You gain the ability to perceive weak points in your opponent's armor. Your first melee or ranged attack each round is resolved as a ~touch attack~[TAG_TOUCH_ATTACK], disregarding the subject's ~armor~[TAG_ARMOR], ~shield~[TAG_SHIELDS], and ~natural~[TAG_MODIFIER_NATURAL_ARMOR] armor bonuses (including any ~enhancement~[TAG_ENHANCEMENT_BONUS] bonuses) to ~Armor Class~[TAG_ARMOR_CLASS]. Other AC bonuses, such as ~dodge~[TAG_DODGE] bonuses, ~deflection~[TAG_DEFLECTION_BONUS] bonuses, and ~luck~[TAG_MODIFIER_LUCK] bonuses, still apply. TAG_SPELLS_FIRE_SHIELD_MASS TAG_SPELLS TAG_SORCERER_5 TAG_WIZARD_5 Fire Shield, Mass ~Evocation~[TAG_MAGIC_SCHOOLS_EVOCATION] (Fire, Cold) Level: ~Sor~[TAG_SORCERERS]/~Wiz~[TAG_WIZARDS] 4 Components: V, S Casting Time: 1 ~standard action~[TAG_STANDARD_ACTION] Range: Close (25 ft. + 5 ft./2 levels) Targets: Creatures no two of which can be more than 30 ft. apart Duration: 1round/level This spell functions like ~fire shield~[TAG_SPELLS_FIRE_SHIELD] except it effects multiple creatures. TAG_SPELLS_FIRE_SHURIKEN TAG_SPELLS TAG_ASSASSIN_2 Fire Shuriken ~Evocation~[TAG_MAGIC_SCHOOLS_EVOCATION][Fire] Level: ~Assassin~[TAG_ASSASSINS] 2 Components: V, S Casting Time: 1 ~standard action~[TAG_STANDARD_ACTION] Range: 0 ft. Effect: One magical shuriken/3 levels Duration: Instantaneous With dark intent you complet the quick motions of the spell and find in your hand several shuriken composed of flame. This spell creates ~shuriken~[TAG_WEAPONS_SHURIKEN] formed of magical fire that you can throw as a normal ~ranged attack~[TAG_RANGED_ATTACKS]. You are automatically considered ~proficient~[TAG_WEAPON_SHIELD_PROFICIENCY] with the fire shuriken, which have a range increment of 10 feet, threaten a ~critical hit~[TAG_CRITICAL_HIT] on a roll of 19-20, and deal 3d6 points of fire damage each on a succesful hit (althouch you and your possessions take no damage as the shuriken are thrown). Any additional damage dealt by the fire shuriken (including your Strength bonus and ~sneak attack~[TAG_CLASS_FEATURES_ROGUE_SNEAK_ATTACK] damage) is also fire damage. The suriken disappear when they hit, so they cannot set fire to combustibles or damage objects. You can create one fire shurken per three caster levels, up to a maximum of six at 18th level. +TAG_SPELLS_FIREBURST TAG_SPELLS TAG_SORCERER_2 TAG_WARMAGE_2 TAG_WIZARD_2 Fireburst ~Evocation~[TAG_MAGIC_SCHOOLS_EVOCATION](Fire) ~Sorcerer~[TAG_SORCERERS]/~Wizard~[TAG_WIZARDS] 2, ~Warmage~[TAG_WARMAGES] 2 Components: V, S, M Casting Time: 1 ~standard action~[TAG_STANDARD_ACTION] Range: 10 Effect: Burst of fire extending 10 ft. from you Duration: Instantaneous Saving Throw: ~Reflex~[TAG_REFLEX] half Spell Resistance: Yes With a grand circular gesture the air around you fills with flame. An instant later the fire explodes outward, engulfing everything close to you. Fireburst causes a powerful explosion of flame to burst from you, damaging anyone within 10 feet of you. All creatures and objects within that area, except for you and any creatures or objects that share your space, take 1d8 points of fire damage per caster level (maximum 5d8). TAG_SPELLS_FOCUSING_CHANT TAG_SPELLS TAG_BARD_1 Focusing Chant ~Enchantment~[TAG_MAGIC_SCHOOLS_ENCHANTMENT](Compulsion) Level: ~Bard~[TAG_BARDS] 1 Components: V Casting Time: ~Free action~[TAG_FREE_ACTION] Range: Personal Target: You Duration: 1 Minute You chant softly under your breath and concentrate on the sound of your voice. Distractions fade from your consciousness, allowing you to focus on the task at hand. You gain a +1 ~circumstance~[TAG_MODIFIER_CIRCUMSTANCE] bonus on ~attack rolls~[TAG_ATTACK_ROLL], ~skill~[TAG_USING_SKILLS] checks, and ~ability~[TAG_ABILITIES] checks for the duration of the spell. TAG_SPELLS_FOUNDATION_OF_STONE TAG_SPELLS TAG_CLERIC_1 TAG_DRUID_1 Foundation of Stone ~Transmutation~[TAG_MAGIC_SCHOOLS_TRANSMUTATION][Earth] Level: ~Cleric~[TAG_CLERICS] 1, ~Druid~[TAG_DRUIDS] 1 Components: V, S Casting Time: 1 ~standard action~[TAG_STANDARD_ACTION] Range: Close (25 ft. + 5 ft./2 levels) Target: One creature/level Duration: 1 round/level Saving Throw: None Spell Resistance: No Calling upon the strength of the earth, you lend some of the stability of stone to your allies. As long as they do not move and remain standing on solid ground, the subject creatures gain a +2 bonus to ~Armor Class~[TAG_ARMOR_CLASS] and a +4 bonus on ~Strength~[TAG_STRENGTH] checks made to resist being ~bull rushed~[TAG_BULLRUSH] or ~tripped~[TAG_TRIP]. If this spell is cast in mountainous terrain, the bonus on Strength checks granted by this spell increases to +6. Note: The terrain component is not implemented in Temple of Elemental Evil. TAG_SPELLS_FROST_BREATH TAG_SPELLS TAG_CLERIC_2 TAG_DRUID_2 TAG_SORCERER_2 TAG_WIZARD_2 Frost Breath ~Evocation~[TAG_MAGIC_SCHOOLS_EVOCATION](Cold) Level: ~Cleric~[TAG_CLERICS] 2, ~Druid~[TAG_DRUIDS] 2, ~Sorcerer~[TAG_SORCERERS]/~Wizard~[TAG_WIZARDS] 2 Components: V, S Casting Time: 1 ~standard action~[TAG_STANDARD_ACTION] Range: 30 ft. Area: Cone-shaped burst Duration: Instantaneous Saving Throw: ~Reflex~[TAG_REFLEX] half Spell Resistance: Yes Giving a forceful exhale across your cupped hand, your breath shoots forth tinged with frost and crystals of ice. You breathe a cone of intense cold at your foes. The spell deals 1d4 points of cold damage per two caster levels (maximum 5d4). In addition, all creatures damaged by the frost breath that fail their ~Reflex~[TAG_REFLEX] save are ~dazed~[TAG_DAZED] for 1 round by the sudden shock of cold. TAG_SPELLS_FUGUE TAG_SPELLS TAG_BARD_4 Fugue ~Evocation~[TAG_MAGIC_SCHOOLS_EVOCATION] Level: ~Bard~[TAG_BARDS] 4 Components: V, S Casting Time: 1 ~standard action~[TAG_STANDARD_ACTION] Range: Medium (100 ft. +10 ft./level) Area: 30-ft. radius Duration: 1 round/level ~Will~[TAG_WILL] negates; see text Spell Resistance: Yeso Upon completing the spell, a discordant cacophony of haunting and alien music rises up in the area you designate. Although the strange music reaches your ears, you feel no effect from it. Creatures that fail their save become affected by the haunting fugue in semirandom ways. On each affected creature's turn (as long as it remains in the affected area), you make a Perform check. The check result determines how the victim's mind and body are affected by the spell. You can select any of the effects for Which your Perform check equals or exceeds the required DC. DC Result 15 Victim takes 3d6 points of ~nonlethal~[TAG_RADIAL_MENU_NONLETHAL_DAMAGE] damage 20 Victim takes 3d6 points of sonic damage 25 Victim is knocked ~prone~[TAG_PRONE] 30 Victim is ~nauseated~[TAG_NAUSEATED] for 1 round 35 Victim is ~stunned~[TAG_STUNNED] for 1 round 40 Victim attacks nearest target All creatures that succeed on their saves against the spell are disoriented and take a -2 penalty on ~attack rolls~[TAG_ATTACK_ROLL] and ~skill~[TAG_SKILLS] checks as long as they remain in te affected area. TAG_SPELLS_GRACE TAG_SPELLS TAG_BARD_2 TAG_CLERIC_3 Grace ~Transmutation~[TAG_MAGIC_SCHOOLS_TRANSMUTATION][Good] Level: ~Bard~[TAG_BARDS] 2, ~Cleric~[TAG_CLERICS] 3 Components: V Casting Time: 1 ~free action~[TAG_FREE_ACTION] Range: Personal Target: You Duration: 1 round/level With a single word, you call upon the might and grace of your deity, bathing your body with divine energy. Your body glows with silvery light and you feel quick and light on your feet. You create a silvery glow around your body that provides illumination to a radius of 60 feet. You gain a -20 ~circumstance~[TAG_MODIFIER_CIRCUMSTANCE] penalty on ~Hide~[TAG_HIDE] checks made while under the effect of this spell. For the duration of the spell, you gain a +2 ~sacred~[TAG_MODIFIER_SACRED] bonus to ~Dexterity~[TAG_DEXTERITY], and your base land ~speed~[TAG_MOVEMENT_RATE] increases by 10 feet. Your touch attacks and any melee weapons you wield become infused with this power as well. They are treated as good-aligned weapons for the purpose of overcoming ~damage reduction~[TAG_SPECIAL_ABILITIES_DAMAGE_REDUCTION]. TAG_SPELLS_GHOST_TOUCH_ARMOR TAG_SPELLS TAG_CLERIC_2 TAG_SORCERER_2 TAG_WIZARD_2 Ghost Touch Armor ~Transmutation~[TAG_MAGIC_SCHOOLS_TRANSMUTATION] Level: ~Cleric~[TAG_CLERICS] 2, ~Sorcerer~[TAG_SORCERERS]/~Wizard~[TAG_WIZARDS] 2 Components: V, S Casting Time: 1 ~standard action~[TAG_STANDARD_ACTION] Range: Touch Target: Armor touched Duration: 1 minute/level Saving Throw: None Spell Resistance: No Confronted with incorporeal enemies, you give the armor you touch the power to defend against such foes. The subject’s armor gains the ghost touch special ability (Both its enhancement bonus and its armor bonus count against the attacks of incorporeal creatures and can be worn by incorpereal creatures). Note: Spell is currently non functional :( +TAG_SPELLS_GREATER_FIREBURST TAG_SPELLS TAG_SORCERER_5 TAG_WARMAGE_5 TAG_WIZARD_5 Greater Fireburst ~Evocation~[TAG_MAGIC_SCHOOLS_EVOCATION](Fire) ~Sorcerer~[TAG_SORCERERS]/~Wizard~[TAG_WIZARDS] 5, ~Warmage~[TAG_WARMAGES] 5 Components: V, S, M Casting Time: 1 ~standard action~[TAG_STANDARD_ACTION] Range: 15 Effect: Burst of fire extending 15 ft. from you Duration: Instantaneous Saving Throw: ~Reflex~[TAG_REFLEX] half Spell Resistance: Yes With a grand circular gesture the air around you fills with flame. An instant later the fire explodes outward, engulfing everything close to you. This spell functions like ~Fireburst~[TAG_SPELLS_FIREBURST], except that it affects creatures within 15 feet of you and deals 1d10 points of fire damage per caster level (maximum 15d10). +TAG_SPELLS_HAIL_OF_STONE TAG_SPELLS TAG_SORCERER_1 TAG_WARMAGE_1 TAG_WIZARD_1 Hail of Stone ~Conjuration~[TAG_MAGIC_SCHOOLS_CONJURATION](Creation)[Earth] Level: ~Sorcerer~[TAG_SORCERERS]/~Wizard~[TAG_WIZARDS] 1, ~Warmage~[TAG_WARMAGES] 1 Components: V, S, M Casting Time: 1 ~standard action~[TAG_STANDARD_ACTION] Range: Medium (100 ft. + 10 ft./level) Area: 5-ft. radius Duration: Instantaneous Saving Throw: None Spell Resistance: No You hold the jade chip before you and blow on it as you end the spell. The chip flares with a green flame and vanishes as rocks begin to fall on your pursuers. You create a rain of stones that deals 1d4 points of damage per caster level (maximum 5d4) to creatures and objects within the area. TAG_SPELLS_HAND_OF_DIVINITY TAG_SPELLS TAG_BLACKGUARD_2 TAG_CLERIC_2 TAG_PALADIN_2 Hand of Divinity ~Evocation~[TAG_MAGIC_SCHOOLS_EVOCATION] Level: ~Blackguard~[TAG_BLACKGUARDS] 2, ~Cleric~[TAG_CLERICS] 2, ~Paladin~[TAG_PALADINS] Components: V, S Casting Time: ~Full Round~[TAG_FULL_ROUND_ACTION] Range: Touch Target: Creature touched Duration: 1 minute/level You call upon your beliefs and a great pair of hands appears around your target, cradling it in its power. The effect fades, but your target briefly glows with a healthy orange nimbus. If your deity is non-evil, this spell grants a +2 ~sacred~[TAG_MODIFIER_SACRED] bonus on ~saving throws~[TAG_SAVING_THROW_DESC], and the spell is a good spell. If your deity is evil, this spell grants a +2 ~profane~[TAG_MODIFIER_PROFANE] bonus on saving throws, and the spell is an evil spell. This spell works only on a creature with the same ~deity~[TAG_RELIGION] as you or the same ~alignment~[TAG_ALIGNMENT] as your deity. If cast on a target that does not meet this criteria, the spell has no effect. TAG_SPELLS_HARMONIC_CHORUS TAG_SPELLS TAG_BARD_2 Harmonic Chorus ~Enchantment~[TAG_MAGIC_SCHOOLS_ENCHANTMENT] Level: ~Bard~[TAG_BARDS] 2 Components: V, S Casting Time: 1 ~standard action~[TAG_STANDARD_ACTION] Range: Close (25 ft. + 5 ft./ 2 levels) Target: One Creature Duration: 1 round/level Saving Throw: ~Will~[TAG_WILL] negates Spell Resistance: Yes Sweeping your arm as if presenting a gift to someone, you call out to the intended subject of your spell. A mantle of sweet tones settles about your subject, whose face is now twisted in concentration. Harmonic chorus lets you improve the spellcasting ability of another spellcaster. For the duration of the spell, the subject gains a +2 ~morale~[TAG_MODIFIER_MORALE] bonus to caster level and a +2 morale bonus on all spell DCs it casts. TAG_SPELLS_HAUNTING_TUNE TAG_SPELLS TAG_BARD_3 Haunting Tune ~Enchantment~[TAG_MAGIC_SCHOOLS_ENCHANTMENT](Compulsion)[Fear][Mind-Affecting][Sonic] Level: ~Bard~[TAG_BARDS] 3 Components: V, S Casting Time: 1 ~standard action~[TAG_STANDARD_ACTION] Range: Medium (100 ft. +10 ft./level) Target: One creature/level Duration: 10 minutes/level Saving Throw: ~Will~[TAG_WILL] negates Spell Resistance: Yes The spell wrapped within your music makes even the most hard-hearted quail. Targets that fail their saves become ~shaken~[TAG_SHAKEN]. @@ -70,13 +76,22 @@ TAG_SPELLS_IRON_SILENCE TAG_SPELLS TAG_ASSASSIN_2 TAG_BARD_2 TAG_CLERIC_2 Iron TAG_SPELLS_IRONGUTS TAG_SPELLS TAG_BARD_1 TAG_CLERIC_1 TAG_SORCERER_1 TAG_WIZARD_1 Ironguts ~Abjuration~[TAG_MAGIC_SCHOOLS_ABJURATION] Level: ~Bard~[TAG_BARDS] 1, ~Cleric~[TAG_CLERICS] 1, ~Sorcerer~[TAG_SORCERERS]/~Wizard~[TAG_WIZARDS] 1 Components: V, S Casting Time: 1 ~standard action~[TAG_STANDARD_ACTION] Range: Touch Target: Creature touched Duration: 10 minutes/level Saving Throw: ~Will~[TAG_WILL] negates Spell Resistance: Yes The subject is filled with antitoxin and gains a +5 ~alchemical~[TAG_MODIFIER_ALCHEMICAL] bonus on ~Fortitude~[TAG_FORTITUDE] saves against all kinds of ~poisons~[TAG_POISON], whether injury, contact, ingestion, or inhalation. After the spell ends, the subject is ~nauseated~[TAG_NAUSEATED] for 1 round. TAG_SPELLS_IRONTHUNDER_HORN TAG_SPELLS TAG_BARD_1, TAG_SORCERER_2 TAG_WIZARD_2 Ironthunder Horn ~Transmutation~[TAG_MAGIC_SCHOOLS_TRANSMUTATION](Sonic) Level: ~Bard~[TAG_BARDS] 1, ~Sorcerer~[TAG_SORCERERS]/~Wizard~[TAG_WIZARDS] 2 Components: V, S Casting Time: 1 ~standard action~[TAG_STANDARD_ACTION] Range: 30 ft. Area: Cone-shaped burst Duration: Instantaneous Saving Throw: ~Reflex~[TAG_REFLEX] negates Spell Resistance: Yes The last words of your spell boom out with a thundering roar, knocking the foes in your path off their feet. You create a deep resonant vibration that can shake creatures off their feet. Creatures in the area must succeed on a ~Reflex~[TAG_REFLEX] saving throw or fall ~prone~[TAG_PRONE]. TAG_SPELLS_LAWFUL_SWORD TAG_SPELLS TAG_PALADIN_4 Lawful Sword ~Evocation~[TAG_MAGIC_SCHOOLS_EVOCATION](Lawful) Level: ~Paladin~[TAG_PALADINS] 4 Components: V, S Casting Time: 1 ~standard action~[TAG_STANDARD_ACTION] Range: Personal Target: Weapon touched Duration: 1 round/level Calling to mind thoughts of justice, you run your fingers along the weapon, imbuing it with power. This spell functions like holy sword (PH242), except as follows. The weapon functions as a +5 axiomatic weapon (+5 ~enhancement~[TAG_ENHANCEMENT_BONUS] bonus on ~attack rolls~[TAG_ATTACK_ROLL] and damage rolls, lawful-aligned, deals an extra 2d6 points of damage against chaotic opponents). It also emits a magic circle against chaos effect (as the spell). +TAG_SPELLS_LESSER_ORB_OF_ACID TAG_SPELLS TAG_SORCERER_1 TAG_WIZARD_1 TAG_WARMAGE_1 Lesser Orb of Acid ~Conjuration~[TAG_MAGIC_SCHOOLS_CONJURATION](Creation)[Acid] Level: ~Sorcerer~[TAG_SORCERERS]/~Wizard~[TAG_WIZARDS] 1, ~Warmage~[TAG_WARMAGES] 1 Components: V, S Casting Time: 1 ~standard action~[TAG_STANDARD_ACTION] Range: Close (25 ft. +5 ft./2 levels) Target: One creature Duration: Instantaneous Saving Throw: None Spell Resistance: No Your quick, precise movements culminate in your open palm facing your target. An orb of dark green acid flies from your hand. An orb of acid about 2 inches across shoots from your palm at its target, dealing 1d8 points of acid damage. You must succeed on a ~ranged touch attack~[TAG_TOUCH_ATTACK] to hit your target. For every two caster levels beyond 1st, your orb deals an additional 1d8 points of damage: 2d8 at 3rd level, 3d8 at 5th level, 4d8 at 7th level, and the maximum of 5d8 at 9th level or higher. +TAG_SPELLS_LESSER_ORB_OF_COLD TAG_SPELLS TAG_SORCERER_1 TAG_WIZARD_1 TAG_WARMAGE_1 Lesser Orb of Cold ~Conjuration~[TAG_MAGIC_SCHOOLS_CONJURATION](Creation)[Cold] Level: ~Sorcerer~[TAG_SORCERERS]/~Wizard~[TAG_WIZARDS] 1, ~Warmage~[TAG_WARMAGES] 1 Components: V, S Casting Time: 1 ~standard action~[TAG_STANDARD_ACTION] Range: Close (25 ft. +5 ft./2 levels) Target: One creature Duration: Instantaneous Saving Throw: None Spell Resistance: No An orb of cold about 2 inches across shoots from your palm at its target, dealing 1d8 points of cold damage. You must succeed on a ~ranged touch attack~[TAG_TOUCH_ATTACK] to hit your target. For every two caster levels beyond 1st, your orb deals an additional 1d8 points of damage: 2d8 at 3rd level, 3d8 at 5th level, 4d8 at 7th level, and the maximum of 5d8 at 9th level or higher. +TAG_SPELLS_LESSER_ORB_OF_ELECTRICITY TAG_SPELLS TAG_SORCERER_1 TAG_WIZARD_1 TAG_WARMAGE_1 Lesser Orb of Electricity ~Conjuration~[TAG_MAGIC_SCHOOLS_CONJURATION](Creation)[Electricity] Level: ~Sorcerer~[TAG_SORCERERS]/~Wizard~[TAG_WIZARDS] 1, ~Warmage~[TAG_WARMAGES] 1 Components: V, S Casting Time: 1 ~standard action~[TAG_STANDARD_ACTION] Range: Close (25 ft. +5 ft./2 levels) Target: One creature Duration: Instantaneous Saving Throw: None Spell Resistance: No An orb of electricity about 2 inches across shoots from your palm at its target, dealing 1d8 points of electricity damage. You must succeed on a ~ranged touch attack~[TAG_TOUCH_ATTACK] to hit your target. For every two caster levels beyond 1st, your orb deals an additional 1d8 points of damage: 2d8 at 3rd level, 3d8 at 5th level, 4d8 at 7th level, and the maximum of 5d8 at 9th level or higher. +TAG_SPELLS_LESSER_ORB_OF_FIRE TAG_SPELLS TAG_SORCERER_1 TAG_WIZARD_1 TAG_WARMAGE_1 Lesser Orb of Fire ~Conjuration~[TAG_MAGIC_SCHOOLS_CONJURATION](Creation)[Fire] Level: ~Sorcerer~[TAG_SORCERERS]/~Wizard~[TAG_WIZARDS] 1, ~Warmage~[TAG_WARMAGES] 1 Components: V, S Casting Time: 1 ~standard action~[TAG_STANDARD_ACTION] Range: Close (25 ft. +5 ft./2 levels) Target: One creature Duration: Instantaneous Saving Throw: None Spell Resistance: No An orb of fire about 2 inches across shoots from your palm at its target, dealing 1d8 points of fire damage. You must succeed on a ~ranged touch attack~[TAG_TOUCH_ATTACK] to hit your target. For every two caster levels beyond 1st, your orb deals an additional 1d8 points of damage: 2d8 at 3rd level, 3d8 at 5th level, 4d8 at 7th level, and the maximum of 5d8 at 9th level or higher. +TAG_SPELLS_LESSER_ORB_OF_SOUND TAG_SPELLS TAG_SORCERER_1 TAG_WIZARD_1 TAG_WARMAGE_1 Lesser Orb of Sound ~Conjuration~[TAG_MAGIC_SCHOOLS_CONJURATION](Creation)[Sonic] Level: ~Sorcerer~[TAG_SORCERERS]/~Wizard~[TAG_WIZARDS] 1, ~Warmage~[TAG_WARMAGES] 1 Components: V, S Casting Time: 1 ~standard action~[TAG_STANDARD_ACTION] Range: Close (25 ft. +5 ft./2 levels) Target: One creature Duration: Instantaneous Saving Throw: None Spell Resistance: No An orb of sound about 2 inches across shoots from your palm at its target, dealing 1d8 points of sonic damage. You must succeed on a ~ranged touch attack~[TAG_TOUCH_ATTACK] to hit your target. For every two caster levels beyond 1st, your orb deals an additional 1d8 points of damage: 2d8 at 3rd level, 3d8 at 5th level, 4d8 at 7th level, and the maximum of 5d8 at 9th level or higher. TAG_SPELLS_LIGHTFOOT TAG_SPELLS TAG_ASSASSIN_1, TAG_RANGER_1 Lightfoot ~Transmutation~[TAG_MAGIC_SCHOOLS_TRANSMUTATION] Level: ~Assassin~[TAG_ASSASSINS] 1, ~Ranger~[TAG_RANGERS] 1 Components: V, S Casting Time: ~Free action~[TAG_FREE_ACTION] Range: Personal Target: You Duration: 1 round You mutter the words of this short spell and dive down the hallway, dancing between the armed guards and out the gate. You provoke no ~attacks of opportunity~[TAG_AOO] when ~moving~[TAG_MOVEMENT_ACTION]. TAG_SPELLS_LOVES_LAMENT TAG_SPELLS TAG_BARD_3 Love's Lament ~Enchantment~[TAG_MAGIC_SCHOOLS_ENCHANTMENT](Compulsion)[Mind-Affecting] Level: ~Bard~[TAG_BARDS] 3 Components: V Casting Time: 1 ~standard action~[TAG_STANDARD_ACTION] Range: 60 ft. Area: Cone-shaped burst Duration: Instantaneous (see text) Saving Throw: ~Will~[TAG_WILL] negates Spell Resistance: Yes Dirgelike music fills the area, reminding those in range of lost loves and life's disappointments. Creatures within the area of this spell that fail their saves take 1d6 points of ~Wisdom~[TAG_WISDOM] damage and are ~nauseated~[TAG_NAUSEATED] for 1d4 rounds. TAG_SPELLS_MASTERS_GIFT TAG_SPELLS TAG_BARD_1 TAG_SORCERER_1 TAG_WIZARD_1 Master's Gift ~Divination~[TAG_MAGIC_SCHOOLS_DIVINATION] Level: ~Bard~[TAG_BARDS] 1, ~Sorcerer~[TAG_SORCERERS]/~Wizard~[TAG_WIZARDS] 1 Components: V Casting Time: ~Free action~[TAG_FREE_ACTION] Range: Personal Target: You Duration: 1 minute/level Holding aloft an item you wish to use effectively, you address it directly with a command to obey your desire to wield it. You gain ~proficiency~[TAG_WEAPON_SHIELD_PROFICIENCY] with a single weapon or shield you hold in your hands when the spell is cast. The lack of a somatic component means the spell can be cast in the middle of a fight while you keep ready whatever items stand between you and danger. Note: In Temple of Elemental Evil, the spell does not grant proficieny but cancels out the penalty and you cannot have multiple Master's Gift at once. TAG_SPELLS_NAUSEATING_BREATH TAG_SPELLS TAG_CLERIC_3 TAG_SORCERER_3 TAG_WIZARD_3 Nauseating Breath ~Conjuration~[TAG_MAGIC_SCHOOLS_CONJURATION] Level: ~Cleric~[TAG_CLERICS] 3, ~Sorcerer~[TAG_SORCERERS]/~Wizard~[TAG_WIZARDS] 3 Components: V, S Casting Time: 1 ~standard action~[TAG_STANDARD_ACTION] Range: 30 ft. Area: Cone-shaped burst Duration: Instantaneous Saving Throw: ~Fortitude~[TAG_FORTITUDE] negates Spell Resistance: No You windmill your arm to complete the spell and nearly gag before exhaling a great gout of putrid-smelling green gas. You breathe out a cone of nauseating vapors. Any creature in the area must succeed on a ~Fortitude~[TAG_FORTITUDE] save or be ~nauseated~[TAG_NAUSEATED] for 1d6 rounds. TAG_SPELLS_NIGHTSHIELD TAG_SPELLS TAG_CLERIC_1 TAG_SORCERER_1 TAG_WIZARD_1 Nightshiled ~Abjuration~[TAG_MAGIC_SCHOOLS_ABJURATION] Level: ~Cleric~[TAG_CLERICS] 1, ~Sorcerer~[TAG_SORCERERS]/~Wizard~[TAG_WIZARDS] 1 Components: V, S Casting Time: 1 ~standard action~[TAG_STANDARD_ACTION] Range: Personal Target: You Duration: 1 minute/level Saving Throw: None Spell Resistance: No With a whisper-quiet whoosh, a field of shadowy energy cloaks your body. This spell provides a +1 ~resistance bonus~[TAG_MODIFIER_RESISTANCE] on ~saving throws~[TAG_SAVING_THROW_DESC]; this resistance bonus increases to +2 at caster level 6th and +3 at caster level 9th. In addition, the spell negates ~magic missile~[TAG_SPELLS_MAGIC_MISSILE] attacks directed at you. TAG_SPELLS_NIMBUS_OF_LIGHT TAG_SPELLS TAG_CLERIC_1 Nimbus of Light ~Evocation~[TAG_MAGIC_SCHOOLS_EVOCATION](Light) Level: ~Cleric~[TAG_CLERICS] 1 Components: V, S Casting Time: 1 ~standard action~[TAG_STANDARD_ACTION] Range: Personal Target: You Duration: 1 minutes/level Saving Throw: None Spell Resistance: No A glittering corona of sunlight surrounds your body at a few inches distance - until you release it as a focused blast of divine energy. The nimbus of light around you glows like a lantern, providing bright illumination in a 30-foot radius (and shadowy illumination for an additional 30 feet) from you. As a ~move~[TAG_MOVEMENT_ACTION] action, you can coalesce the energy from a nimbus of light around your outstretched arm, and then as a ~standard~[TAG_STANDARD_ACTION] action fling it toward a foe within 30 feet. You must succeed on a ~ranged touch attack~[TAG_TOUCH_ATTACK] with the energy to strike a target. A nimbus of light deals 1d8 points of damage +1 point per round that has elapsed since you cast the spell (maximum 1d8 + caster level). Attacking with a nimbus of light ends the spell, whether your ranged touch attack is successful or not. Note: The lantern light part of the spell is not implemented at the moment. Due to this the movement action to focus the light on your arm is omitted. -TAG_SPELLS_NIXIES_GRACE TAG_SPELLS TAG_BARD_6 Nixie's Grace ~Transmutation~[TAG_MAGIC_SCHOOLS_TRANSMUTATION][Water] Level: ~Bard~[TAG_BARDS] 6 Components: V, S Casting Time: 1 ~standard action~[TAG_STANDARD_ACTION] Range: Personal Target: You Duration: 10 minutes/level You feel a longing for cool waters, and a forceful confidence manifests within you. Your movements and thoughts become filled with grace. This potent spell infuses you with powerful fey magic, granting you many of the traits and abilities of a nixie (MM 235). Upon casting this spell, you gain a swim speed of 30 feet. You can breathe underwater, and you gain low-light vision and ~damage reduction~[TAG_SPECIAL_ABILITIES_DAMAGE_REDUCTION] 5/cold iron. You also gain a +6 ~enhancement~[TAG_ENHANCEMENT_BONUS] bonus to ~Dexterity~[TAG_DEXTERITY], a +2 enhancement bonus to ~Wisdom~[TAG_WISDOM], and a +8 enhancement bonus to ~Charisma~[TAG_CHARISMA]. Note: The underwater part is not applicable in Temple of Elemental Evil. +TAG_SPELLS_ORB_OF_ACID TAG_SPELLS TAG_SORCERER_4 TAG_WIZARD_4 TAG_WARMAGE_4 Orb of Acid ~Conjuration~[TAG_MAGIC_SCHOOLS_CONJURATION](Creation)[Acid] Level: ~Sorcerer~[TAG_SORCERERS]/~Wizard~[TAG_WIZARDS] 4, ~Warmage~[TAG_WARMAGES] 4 Components: V, S Casting Time: 1 ~standard action~[TAG_STANDARD_ACTION] Range: Close (25 ft. +5 ft./2 levels) Target: One creature Duration: Instantaneous Saving Throw: ~Fortitude~[TAG_FORTITUDE] partial; see text Spell Resistance: No An orb of acid about 3 inches across shoots from your palm at its target, dealing 1d6 points of acid damage per caster level (maximum 15d6). You must succeed on a ~ranged touch attack~[TAG_TOUCH_ATTACK] to hit your target. A creature struck by the orb takes damage and becomes ~sickened~[TAG_SICKENED] by the acid's noxious fumes for 1 round. A successful ~Fortitude save~[TAG_FORTITUDE] negates the sickened effect but does not reduce the damage. +TAG_SPELLS_ORB_OF_COLD TAG_SPELLS TAG_SORCERER_4 TAG_WIZARD_4 TAG_WARMAGE_4 Orb of Cold ~Conjuration~[TAG_MAGIC_SCHOOLS_CONJURATION](Creation)[Cold] Level: ~Sorcerer~[TAG_SORCERERS]/~Wizard~[TAG_WIZARDS] 4, ~Warmage~[TAG_WARMAGES] 4 Components: V, S Casting Time: 1 ~standard action~[TAG_STANDARD_ACTION] Range: Close (25 ft. +5 ft./2 levels) Target: One creature Duration: Instantaneous Saving Throw: ~Fortitude~[TAG_FORTITUDE] partial; see text Spell Resistance: No An orb of cold about 3 inches across shoots from your palm at its target, dealing 1d6 points of cold damage per caster level (maximum 15d6). You must succeed on a ~ranged touch attack~[TAG_TOUCH_ATTACK] to hit your target. In addition, a creature struck by an orb of cold must make a ~Fortitude save~[TAG_FORTITUDE] or be ~blinded~[TAG_BLINDED] for 1 round. +TAG_SPELLS_ORB_OF_ELECTRICITY TAG_SPELLS TAG_SORCERER_4 TAG_WIZARD_4 TAG_WARMAGE_4 Orb of Electricity ~Conjuration~[TAG_MAGIC_SCHOOLS_CONJURATION](Creation)[Electricity] Level: ~Sorcerer~[TAG_SORCERERS]/~Wizard~[TAG_WIZARDS] 4, ~Warmage~[TAG_WARMAGES] 4 Components: V, S Casting Time: 1 ~standard action~[TAG_STANDARD_ACTION] Range: Close (25 ft. +5 ft./2 levels) Target: One creature Duration: Instantaneous Saving Throw: ~Fortitude~[TAG_FORTITUDE] partial; see text Spell Resistance: No An orb of electricity about 3 inches across shoots from your palm at its target, dealing 1d6 points of electricity damage per caster level (maximum 15d6). You must succeed on a ~ranged touch attack~[TAG_TOUCH_ATTACK] to hit your target. In addition, a creature wearing metal armor struck by an orb of electricity must make a ~Fortitude save~[TAG_FORTITUDE] or be ~entangled~[TAG_ENTANGLED] for 1 round. +TAG_SPELLS_ORB_OF_FIRE TAG_SPELLS TAG_SORCERER_4 TAG_WIZARD_4 TAG_WARMAGE_4 Orb of Fire ~Conjuration~[TAG_MAGIC_SCHOOLS_CONJURATION](Creation)[Fire] Level: ~Sorcerer~[TAG_SORCERERS]/~Wizard~[TAG_WIZARDS] 4, ~Warmage~[TAG_WARMAGES] 4 Components: V, S Casting Time: 1 ~standard action~[TAG_STANDARD_ACTION] Range: Close (25 ft. +5 ft./2 levels) Target: One creature Duration: Instantaneous Saving Throw: ~Fortitude~[TAG_FORTITUDE] partial; see text Spell Resistance: No An orb of fire about 3 inches across shoots from your palm at its target, dealing 1d6 points of fire damage per caster level (maximum 15d6). You must succeed on a ~ranged touch attack~[TAG_TOUCH_ATTACK] to hit your target. In addition, a creature struck by an orb of fire must make a ~Fortitude save~[TAG_FORTITUDE] or be ~dazed~[TAG_DAZED] for 1 round. +TAG_SPELLS_ORB_OF_SOUND TAG_SPELLS TAG_SORCERER_4 TAG_WIZARD_4 TAG_WARMAGE_4 Orb of Sound ~Conjuration~[TAG_MAGIC_SCHOOLS_CONJURATION](Creation)[Sound] Level: ~Sorcerer~[TAG_SORCERERS]/~Wizard~[TAG_WIZARDS] 4, ~Warmage~[TAG_WARMAGES] 4 Components: V, S Casting Time: 1 ~standard action~[TAG_STANDARD_ACTION] Range: Close (25 ft. +5 ft./2 levels) Target: One creature Duration: Instantaneous Saving Throw: ~Fortitude~[TAG_FORTITUDE] partial; see text Spell Resistance: No An orb of sound about 3 inches across shoots from your palm at its target, dealing 1d6 points of sonic damage per caster level (maximum 15d6). You must succeed on a ~ranged touch attack~[TAG_TOUCH_ATTACK] to hit your target. In addition, a creature struck by an orb of sound must make a ~Fortitude save~[TAG_FORTITUDE] or be ~deafened~[TAG_DEAFENED] for 1 round. TAG_SPELLS_PHANTOM_FOE TAG_SPELLS TAG_ASSASSIN_2 TAG_SORCERER_2 TAG_WIZARD_2 Phantom Foe ~Illusion~[TAG_MAGIC_SCHOOLS_ILLUSION](Phantasm)[Mind-Affecting] Level: ~Assassin~[TAG_ASSASSINS] 2, ~Sorcerer~[TAG_SORCERERS]/~Wizard~[TAG_WIZARDS] 2 Components: V, S Casting Time: 1 ~standard action~[TAG_STANDARD_ACTION] Range: Touch Target: One Creature Duration: 1 round/level Saving Throw: ~Will~[TAG_WILL] negates Spell Resistance: No By waving around a tiny pewter figurine and picturing in your mind the figurine attacking the target creature, you complete the spell. You feel a phantasmal force leap from the figurine toward your target. If the target creature fails its saving throw, this spell creates in the subject's mind an illusory double of whichever creature currently threatens it that it deems most dangerous. The form of this phantom foe changes as appropriate whenever the target perceives a different threatening creature more dangerous than the last. This illusory double provides two effects. First, the subject believes it is being ~flanked~[TAG_FLANKED] by the phantom foe and the real creature the foe duplicates. Thus, the duplicated creature is always considered to be flanking the subject in melee. A creature that can't be flanked is immune to this aspect of the spell. Second, the subject of the spell is unable to determine that the phantom foe is not a real threat, and whenever the subject attempts to attack the creature duplicated by the phantom foe, that creature benefits from a 50% miss chance against attacks from the subject of the spell. Because this miss chance comes from the subject's inability to tell the phantom foe from the original, it is rolled separately from any miss chance that applies due to displacement or concealment. Creatures other than the subject cannot see the phantom foe, although they can attempt to guess its location by how the target acts. If the subject is not threatened by any creature at the start of its turn, the spell ends. TAG_SPELLS_PHANTOM_THREAT TAG_SPELLS TAG_BARD_1 Phantom Threat ~Illusion~[TAG_MAGIC_SCHOOLS_ILLUSION](Phantasm)[Mind-Affecting] Level: ~Bard~[TAG_BARDS] 1 Components: V, S Casting Time: 1 ~standard action~[TAG_STANDARD_ACTION] Range: Close (25 ft. + 5 ft./ 2 levels) Target: One Creature Duration: 1 round/level Saving Throw: ~Will~[TAG_WILL] negates Spell Resistance: Yes Reaching out to your foe's mind, you cause him to feel as though a threat looms close behind no matter which way he turns. You create the sensation in the subject's mind that it is threatened by more foes than it actually faces. Though the subject doesn't actually perceive any additional enemies (and thus doesn't waste any attacks on the phantasm), a creature affected by this spell is considered ~flanked~[TAG_FLANKING], even if not threatened by other creatures. No amount of convincing by others can help the subject of this spell avoid its effect-only a successful ~saving throw~[TAG_SAVING_THROW_DESC] against the spell when initially cast can help the target. A creature that can't be flanked is immune to this spell. TAG_SPELLS_RAY_OF_DIZZINESS TAG_SPELLS TAG_BARD_3 Ray of Dizziness ~Enchantment~[TAG_MAGIC_SCHOOLS_ENCHANTMENT](Compulsion)[Mind-Affecting] Level: ~Bard~[TAG_BARDS] 3 Components: V, S Casting Time: 1 ~standard action~[TAG_STANDARD_ACTION] Range: Medium (100 ft. +10 ft./level) Effect: Ray Duration: 1 round/level Saving Throw: None Spell Resistance: Yes You release a drab violet ray from your palm. The ray shoots toward your target in a spiraling corkscrew. You strike out at your enemy with a ray that causes intense feelings of vertigo. You must succeed on a ~ranged touch attack~[TAG_TOUCH_ATTACK] with the ray to strike a target. A struck subject experiences strong feelings of vertigo and can take only a ~move action~[TAG_MOVEMENT_ACTION] or a ~standard action~[TAG_STANDARD_ACTION] each round (but not both, and it cannot take a ~full-round~[TAG_FULL_ROUND_ACTION] action). diff --git a/tpdatasrc/tpgamefiles/mes/spell_ext/spell_compendium_spell.mes b/tpdatasrc/tpgamefiles/mes/spell_ext/spell_compendium_spell.mes index ea4dc8ab0..7bc747392 100644 --- a/tpdatasrc/tpgamefiles/mes/spell_ext/spell_compendium_spell.mes +++ b/tpdatasrc/tpgamefiles/mes/spell_ext/spell_compendium_spell.mes @@ -47,7 +47,7 @@ {1086}{Fire Shuriken} {1087}{Phantom Foe} {1088}{Veil of Shadow} -{1089}{Curse of Imp. Blades Mass} +{1089}{Curse of Imp. Blades, Mass} {1090}{Dissonant Chord} {1091}{Haunting Tune} {1092}{Love's Lament} @@ -134,6 +134,22 @@ {1176}{Draconic Might} {1177}{Vigor, Mass Lesser} {1178}{Vigor, Mass Improved} +{1182}{Accuracy} +{1183}{Hail of Stone} +{1184}{Lesser Orb of Acid} +{1185}{Lesser Orb of Cold} +{1186}{Lesser Orb of Electricity} +{1187}{Lesser Orb of Fire} +{1188}{Lesser Orb of Sound} +{1189}{Blades of Fire} +{1190}{Fireburst} +{1191}{Greater Fireburst} +{1195}{Blast of Flame} +{1196}{Orb of Acid} +{1197}{Orb of Cold} +{1198}{Orb of Electricity} +{1199}{Orb of Fire} +{1200}{Orb of Sound} // Spell Descriptions {5794}Vigor, Lesser {[Conjuration] Fast Healing 1 for 10 +1/level rounds, max 15.} @@ -266,3 +282,20 @@ {6176} Draconic Might {TBD} {6177} Vigor, Mass Lesser {Targets get Fast Healing 1 for 10 +1/level rounds, max 25.} {6178} Vigor, Mass Improved {Targets get Fast Healing 3 for 10 +1/level rounds, max 40.} +{6182} Accuracy {The range increment for the affected weapon or weapons is doubled.} +{6183} Hail of Stone {You create a rain of stones that deals 1d4 points of damage per caster level (maximum 5d4) to creatures and objects within the area.} +{6184} Lesser Orb of Acid {Ranged Touch Attack that deals 1d8/two levels (max 5d8) acid damage.} +{6185} Lesser Orb of Cold {Ranged Touch Attack that deals 1d8/two levels (max 5d8) cold damage.} +{6186} Lesser Orb of Electricity {Ranged Touch Attack that deals 1d8/two levels (max 5d8) electricity damage.} +{6187} Lesser Orb of Fire {Ranged Touch Attack that deals 1d8/two levels (max 5d8) fire damage.} +{6188} Lesser Orb of Sound {Ranged Touch Attack that deals 1d8/two levels (max 5d8) sonic damage.} +{6189} Blades of Fire {Your melee weapons each deal an extra 1d8 points of fire damage.} +{6190} Fireburst {Fire deals 1d8 points of fire damage per caster level (maximum 5d8) to anyone within 5 feet of you.} +{6191} Greater Fireburst {Fire deals 1d8 points of fire damage per caster level (maximum 15d8) to anyone within 10 feet of you.} +{6195} Blast of Flame {A 60 foot cone shaped burst deals 1d6 points of fire damage per caster level (maximum 10d6).} +{6196} Orb of Acid {Ranged Touch Attack that deals 1d6/level (max 15d6) acid damage and in addition sickens for 1 round on a failed fortitude save.} +{6197} Orb of Cold {Ranged Touch Attack that deals 1d6/level (max 15d6) cold damage and in addition blinds for 1 round on a failed fortitude save.} +{6198} Orb of Electricity {Ranged Touch Attack that deals 1d6/level (max 15d6) electricity damage and in addition may entangle for 1 round on a failed fortitude save.} +{6199} Orb of Fire {Ranged Touch Attack that deals 1d6/level (max 15d6) fire damage and in addition dazes for 1 round on a failed fortitude save.} +{6200} Orb of Sound {Ranged Touch Attack that deals 1d6/level (max 15d6) sonic damage and in addition deafens for 1 round on a failed fortitude save.} + diff --git a/tpdatasrc/tpgamefiles/mes/spell_long_descriptions_ext/spell_compendium_spell_long_descriptions.mes b/tpdatasrc/tpgamefiles/mes/spell_long_descriptions_ext/spell_compendium_spell_long_descriptions.mes index cd2d4ee7c..06092fce7 100644 --- a/tpdatasrc/tpgamefiles/mes/spell_long_descriptions_ext/spell_compendium_spell_long_descriptions.mes +++ b/tpdatasrc/tpgamefiles/mes/spell_long_descriptions_ext/spell_compendium_spell_long_descriptions.mes @@ -198,7 +198,7 @@ Duration: 1 round} {6074} Sniper's Shot {No range limit to ranged sneak attacks. School: Divination -Casting: 1 swift action [V] +Casting: 1 swift action [V, S] Range: Personal Target: Self Duration: 1 round} @@ -742,7 +742,7 @@ Range: Touch Target: Armor touched Duration: 1 min/level, Save: None, SR: No} -{6153} Aid Mass {Like spell Aid, but on multiple targets and temp HP are 1d8 + level (max 15). +{6153} Aid, Mass {Like spell Aid, but on multiple targets and temp HP are 1d8 + level (max 15). School: Enchantment(Compulsion)[Mind-Aff.] Casting: 1 action [V,S] Range: Close (25ft. + 5ft./2 lvls) @@ -924,3 +924,73 @@ Casting: 1 std action [Evocation, V,S,M/DF] Range: Close (25ft. + 5ft./2 lvls) Target: allied creatures, no more than 30' apart Duration: 1 round/level (D)} + +{6184} Lesser Orb of Acid {Ranged Touch Attack that deals 1d8/two levels (max 5d8) acid damage. +School: Conjuration(Creation)[Acid] +Casting: 1 action [V,S] +Range: Close (25ft. + 5ft./2 lvls) +Target: One creature +Duration: Instantaneous, Save: None, SR: No} + +{6185} Lesser Orb of Cold {Ranged Touch Attack that deals 1d8/two levels (max 5d8) cold damage. +School: Conjuration(Creation)[Cold] +Casting: 1 action [V,S] +Range: Close (25ft. + 5ft./2 lvls) +Target: One creature +Duration: Instantaneous, Save: None, SR: No} + +{6186} Lesser Orb of Electricity {Ranged Touch Attack that deals 1d8/two levels (max 5d8) electricity damage. +School: Conjuration(Creation)[Electricity] +Casting: 1 action [V,S] +Range: Close (25ft. + 5ft./2 lvls) +Target: One creature +Duration: Instantaneous, Save: None, SR: No} + +{6187} Lesser Orb of Fire {Ranged Touch Attack that deals 1d8/two levels (max 5d8) fire damage. +School: Conjuration(Creation)[Fire] +Casting: 1 action [V,S] +Range: Close (25ft. + 5ft./2 lvls) +Target: One creature +Duration: Instantaneous, Save: None, SR: No} + +{6188} Lesser Orb of Sound {Ranged Touch Attack that deals 1d8/two levels (max 5d8) sonic damage. +School: Conjuration(Creation)[Sonic] +Casting: 1 action [V,S] +Range: Close (25ft. + 5ft./2 lvls) +Target: One creature +Duration: Instantaneous, Save: None, SR: No} + +{6196} Orb of Acid {Ranged Touch Attack that deals 1d6/level (max 15d6) acid damage and in addition sickens for 1 round on a failed fortitude save. +School: Conjuration(Creation)[Acid] +Casting: 1 action [V,S] +Range: Close (25ft. + 5ft./2 lvls) +Target: One creature +Duration: Inst., Save: Fortitude partial, SR: No} + +{6197} Orb of Cold {Ranged Touch Attack that deals 1d6/level (max 15d6) cold damage and in addition blinds for 1 round on a failed fortitude save. +School: Conjuration(Creation)[Cold] +Casting: 1 action [V,S] +Range: Close (25ft. + 5ft./2 lvls) +Target: One creature +Duration: Inst., Save: Fortitude partial, SR: No} + +{6198} Orb of Electricity {Ranged Touch Attack that deals 1d6/level (max 15d6) electricity damage and in addition may entangle for 1 round on a failed fortitude save. +School: Conjuration(Creation)[Electricity] +Casting: 1 action [V,S] +Range: Close (25ft. + 5ft./2 lvls) +Target: One creature +Duration: Inst., Save: Fortitude partial, SR: No} + +{6199} Orb of Fire {Ranged Touch Attack that deals 1d6/level (max 15d6) fire damage and in addition dazes for 1 round on a failed fortitude save. +School: Conjuration(Creation)[Fire] +Casting: 1 action [V,S] +Range: Close (25ft. + 5ft./2 lvls) +Target: One creature +Duration: Inst., Save: Fortitude partial, SR: No} + +{6200} Orb of Sound {Ranged Touch Attack that deals 1d6/level (max 15d6) sonic damage and in addition deafens for 1 round on a failed fortitude save. +School: Conjuration(Creation)[Sonic] +Casting: 1 action [V,S] +Range: Close (25ft. + 5ft./2 lvls) +Target: One creature +Duration: Inst., Save: Fortitude partial, SR: No} diff --git a/tpdatasrc/tpgamefiles/rules/char_class/class047_warmage.py b/tpdatasrc/tpgamefiles/rules/char_class/class047_warmage.py index 09fcfd196..e21fa903a 100644 --- a/tpdatasrc/tpgamefiles/rules/char_class/class047_warmage.py +++ b/tpdatasrc/tpgamefiles/rules/char_class/class047_warmage.py @@ -61,11 +61,11 @@ def GetClassHelpTopic(): # to this list with advanced learning. spell_list = { 0: (spell_acid_splash, spell_disrupt_undead, spell_light, spell_ray_of_frost), - 1: (spell_burning_hands, spell_chill_touch, spell_magic_missile, spell_shocking_grasp, spell_true_strike), - 2: (spell_continual_flame, spell_fire_trap, spell_flaming_sphere, spell_melfs_acid_arrow, spell_pyrotechnics, spell_shatter, spell_scorching_ray), - 3: (spell_fire_shield, spell_fireball, spell_flame_arrow, spell_gust_of_wind, spell_ice_storm, spell_lightning_bolt, spell_poison, spell_sleet_storm, spell_stinking_cloud), - 4: (spell_contagion, spell_evards_black_tentacles, spell_phantasmal_killer, spell_shout, spell_wall_of_fire), - 5: (spell_cloudkill, spell_cone_of_cold, spell_flame_strike, spell_fire_shield_mass), + 1: (spell_accuracy, spell_burning_hands, spell_hail_of_stone, spell_lesser_orb_of_acid, spell_lesser_orb_of_cold, spell_lesser_orb_of_electricity, spell_lesser_orb_of_fire, spell_lesser_orb_of_sound, spell_chill_touch, spell_magic_missile, spell_shocking_grasp, spell_true_strike), + 2: (spell_blades_of_fire, spell_continual_flame, spell_fire_trap, spell_fireburst, spell_flaming_sphere, spell_ice_knife, spell_melfs_acid_arrow, spell_pyrotechnics, spell_shatter, spell_scorching_ray, spell_whirling_blade), + 3: (spell_fire_shield, spell_fireball, spell_flame_arrow, spell_gust_of_wind, spell_ice_storm, spell_lightning_bolt, spell_poison, spell_ring_of_blades, spell_sleet_storm, spell_stinking_cloud), + 4: (spell_blast_of_flame, spell_contagion, spell_evards_black_tentacles, spell_orb_of_acid, spell_orb_of_cold, spell_orb_of_electricity, spell_orb_of_fire, spell_orb_of_sound, spell_phantasmal_killer, spell_shout, spell_wall_of_fire), + 5: (spell_cloudkill, spell_cone_of_cold, spell_flame_strike, spell_fire_shield_mass, spell_greater_fireburst), 6: (spell_blade_barrier, spell_chain_lightning, spell_circle_of_death, spell_disintegrate, spell_fire_seeds, spell_otilukes_freezing_sphere, spell_tensers_transformation), 7: (spell_delayed_blast_fireball, spell_earthquake, spell_finger_of_death, spell_fire_storm, spell_mordenkainens_sword, spell_prismatic_spray, spell_sunbeam, ), 8: (spell_horrid_wilting, spell_incendiary_cloud, spell_polar_ray, spell_prismatic_wall, spell_sunburst), diff --git a/tpdatasrc/tpgamefiles/rules/indicators/accuracy.txt b/tpdatasrc/tpgamefiles/rules/indicators/accuracy.txt new file mode 100644 index 000000000..a7151db2c --- /dev/null +++ b/tpdatasrc/tpgamefiles/rules/indicators/accuracy.txt @@ -0,0 +1,5 @@ +ID_string: ACCURACY +effect_type: 0 +texture_file: art\interface\player_conditions\buffs\Spell True Strike.tga +help_topic: TAG_SPELLS_ACCURACY +tooltip_base_text: Accuracy \ No newline at end of file diff --git a/tpdatasrc/tpgamefiles/rules/indicators/blades_of_fire.txt b/tpdatasrc/tpgamefiles/rules/indicators/blades_of_fire.txt new file mode 100644 index 000000000..4642dfa5b --- /dev/null +++ b/tpdatasrc/tpgamefiles/rules/indicators/blades_of_fire.txt @@ -0,0 +1,5 @@ +ID_string: BLADES_OF_FIRE +effect_type: 0 +texture_file: art\interface\player_conditions\buffs\Spell True Strike.tga +help_topic: TAG_SPELLS_BLADES_OF_FIRE +tooltip_base_text: Blades of Fire \ No newline at end of file diff --git a/tpdatasrc/tpgamefiles/rules/partsys/spell_compendium_partsys.tab b/tpdatasrc/tpgamefiles/rules/partsys/spell_compendium_partsys.tab index 209a2f9d7..f616302e9 100644 --- a/tpdatasrc/tpgamefiles/rules/partsys/spell_compendium_partsys.tab +++ b/tpdatasrc/tpgamefiles/rules/partsys/spell_compendium_partsys.tab @@ -11,6 +11,8 @@ sp-Axiomatic Storm-hit Blast 4 15 3 600 Sprite Polar flare-1 15 Add 0 sp-Axiomatic Storm-hit Blast 5 20 3 600 Sprite Polar flare-1 15 Add 0 0 0 0 0 0 0 0 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0?360 0?180 0,100 5,2,6,1,3,2,5,2,6,1,3,2,5,2,6,1,3,2,5,2,6,1,3,2,5,2,6,1,3,2,5,2,6,1,3,2,5,2,6,1,3,2,5,2,6,1,3,2, 0 0 0 0 0 128,0 76 255 0 sp-Axiomatic Storm-hit body steam 0 10 100 Bones Sprite Polar fire-sprite 90 Add 0 0 0 0 0 0 0 0 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0,40 0 0 0 0 5,30 0 0 0?360 0 0 32,0 76 255 0 sp-Axiomatic Storm-hit blast 1 5 800 Bones Sprite Polar flare-1 40 Add 0 0 0 0 0 0 0 0 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 100,-100 0 0?360 0?180 0,100 5,2,6,1,3,2,5,2,6,1,3,2,5,2,6,1,3,2,5,2,6,1,3,2,5,2,6,1,3,2,5,2,6,1,3,2,5,2,6,1,3,2,5,2,6,1,3,2, 0 0 0 0 0 128,0 76 255 0 200 +sp-Blast of Flame smoke emit 10 20 600 Object YPR Sprite Same as Emitter Polar Cartesian fire-sprite 120 Blend 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0?30 0 -30?30 30?720 5?40 0 0 0?360 0 0 0,16,0 0 0 0 100 +sp-Blast of Flame Fire Strike 30 300 Object YPR Disc Same as Emitter Polar flare 30 Add 0 0 0 0 0 0 0 0 40 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -30?30 0 0,720 0?45 0 0 0?360 0 0 0,255,255,0 255(6),255(10) 255(6),130(10) 0 30 sp-Cloud of Bewilderment smoke emit perm 600 Object YPR Sprite Same as Emitter Polar Cartesian fire-sprite 120 Blend 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0?30 0 0?360 0?120 5?40 0 0 0?360 0 0 0,16,0 0 255 144 100 sp-Cloud of Bewilderment old startup 5 1200 Disc Polar flare-big 60 Add 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0?360 8?120 3?20 0 0 0?360 0 0 0,128,0 128 234 58 100 sp-Cloud of Bewilderment old grumble2 perm 150 Sprite Polar flare-big 60 Blend 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0?10 0?360 0?120 2,15 0 0 0 0 0 0,255,200,150,100,50,0 0?16 0 0 30 @@ -52,10 +54,20 @@ sp-Focusing Chant note 2 0 perm 3 Node Pos bip01 head Sprite World Polar Pol sp-Frost Breath smoke emit 10 20 600 Object YPR Sprite Same as Emitter Polar Cartesian fire-sprite 120 Blend 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0?30 0 -30?30 30?330 5?40 0 0 0?360 0 0 0,16,0 255 255 255 100 sp-Frost Breath Fire Strike 30 100 Object YPR Sprite Same as Emitter Polar flare-big 30 Add 0 0 0 0 0 0 0 0 40 0 0 0 0 0 0 0 0 0 0 0 0 0 64,0 0 0 0 0 0 0 0 0 0 -30?30 0 0,360 20?60 0 0 0?720 0 0 0 0 128 255 20 sp-Frost Breath fire strike 3 sparklies 30 50 Object YPR Sprite Same as Emitter Polar flare-1 30 Add 0 0 0 0 0 0 0 0 40 0 0 0 0 0 0 0 0 0 0 0 0 0 255,0 0 0 0 0 0 0 0 0 0 -30?30 0 0,360 1,30,20,25,6,26,15,2,28,3,1,30,20,25,6,26,15,2,28,3,1,30,20,25,6,26,15,2,28,3,1,30,20,25,6,26,15,2,28,3,1,30,20,25,6,26,15,2,28,3,1,30,20,25,6,26,15,2,28,3, 0 0 0,360 0 0 0 255 255 255 100 -sp-Fugue startup 5 1200 Disc Polar flare-big 60 Add 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0?360 8?360 3?20 0 0 0?360 0 0 0,128,0 87?156 0?28 127?255 100 -sp-Fugue grumble2 perm 150 Sprite Polar flare-big 60 Blend 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0?10 0?360 0?360 2,15 0 0 0 0 0 0,255,200,150,100,50,0 87?156 0?28 127?255 30 -sp-Fugue Earth grumbling perm 150 Sprite Polar fire-sprite 60 Blend 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5,-10 0 0?360 0?360 1?4 0 0 0?360 0 0 0,255,0 87?156 0?28 127?255 30 -sp-Fugue startup perm 150 Sprite Polar fire-sprite 60 Blend 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5,-10 0 0?360 0?360 1?2 0 0 0?360 0 0 0,255,0 87 0 127 30 +sp-Fireburst Fire Ground Spread 3 800 Sprite Polar flare-big 30 Add 0 0 0 0 0 0 0 0 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0?360 0?20 0,120 30,20 0 0 0 0 0 255,0 255,255,255,255 255,128,128,128 255,80,80,80 +sp-Fireburst New Emitter 0 10 20 World Disc World Polar Cartesian flare-3 30 Add 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0?360 0 0 10,130 0 0 0?360 0 0 255,0 255,255 128 64 20 +sp-Greater Fireburst Fire Ground Spread 3 800 Sprite Polar flare-big 30 Add 0 0 0 0 0 0 0 0 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0?360 0?20 0,180 30,20 0 0 0 0 0 255,0 255,255,255,255 255,128,128,128 255,80,80,80 +sp-Greater Fireburst New Emitter 0 10 20 World Disc World Polar Cartesian flare-3 30 Add 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0?360 0 0 10,200 0 0 0?360 0 0 255,0 255,255 128 64 20 +sp-Hail of Stone pebble 1 30 1 Sprite Polar flare-2 30 Add 0 0 0 0 0 0 0 -40 250 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 -300,-302 -10 0,240 11 0 0 0,360 0 0 255 128 64 64 +sp-Hail of Stone pebble 1 30 1 Sprite Polar bigcircle 30 Blend 0 0 0 0 0 0 0 -40 250 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 -300,-302 -10 0,240 4 0 0 0,360 0 0 255 16 8 8 +sp-Hail of Stone pebble 2 30 1 Sprite Polar flare-2 30 Add 0 0 0 0 0 0 0 0 250 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 -300,-302 -10 0,240 11 0 0 0,360 0 0 255 128 64 64 +sp-Hail of Stone pebble 2 30 1 Sprite Polar bigcircle 30 Blend 0 0 0 0 0 0 0 0 250 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 -300,-302 -10 0,240 4 0 0 0,360 0 0 255 16 8 8 +sp-Hail of Stone pebble 3 30 1 Sprite Polar flare-2 30 Add 0 0 0 0 0 0 0 -80 200 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 -300,-302 -10 0,240 11 0 0 0,360 0 0 255 128 64 64 +sp-Hail of Stone pebble 3 30 1 Sprite Polar bigcircle 30 Blend 0 0 0 0 0 0 0 -80 200 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 -300,-302 -10 0,240 4 0 0 0,360 0 0 255 16 8 8 +sp-Hail of Stone pebble 4 30 1 Sprite Polar flare-2 30 Add 0 0 0 0 0 0 0 -120 235 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 -300,-302 -10 0,240 11 0 0 0,360 0 0 255 128 64 64 +sp-Hail of Stone pebble 4 30 1 Sprite Polar bigcircle 30 Blend 0 0 0 0 0 0 0 -120 235 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 -300,-302 -10 0,240 4 0 0 0,360 0 0 255 16 8 8 +sp-Hail of Stone pebble 5 30 1 Sprite Polar flare-2 30 Add 0 0 0 0 0 0 0 -85 230 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 -300,-302 -10 0,240 11 0 0 0,360 0 0 255 128 64 64 +sp-Hail of Stone pebble 5 30 1 Sprite Polar bigcircle 30 Blend 0 0 0 0 0 0 0 -85 230 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 -300,-302 -10 0,240 4 0 0 0,360 0 0 255 16 8 8 sp-Holy Storm ice ice baby Model Verts perm 80 Sprite World Polar shard 10 Blend 0 shard 0 0 0 0 0 0 0 600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1600 0 -240?240 0 -240?240 5?25 0 0 0 0,255,255,255,255,255,255,255,0 128 128 128 20 sp-Holy Storm ground busts discs 20 Point perm 120 World Polar Disc World Polar Cartesian fire-sprite 10 Blend 0 Shard-Breaking 0 0 0 0 0 2 0 0 0 0 0 20?-20 0 0 -250?250 0 -250?250 0,40 0 0 0?360 0 0 64,0 255 255 255 20 sp-Holy Storm circle bounding 20 Point perm 120 World Polar Disc World Polar Cartesian fire-sprite 10 Blend 0 Shard-Breaking 0 0 0 0 0 2 0 0 0 0 0 20?-20 0 0 0?360 0 250 0,40 0 0 0?360 0 0 64,0 255 255 255 20 @@ -63,8 +75,29 @@ sp-Ironthunder Horn shockwave 40 150 Object YPR Sprite Same as Emitter Pol sp-Ironthunder Horn wave1 10 30 150 Object YPR Sprite Same as Emitter Polar ring 20 Add 0 0 0 0 0 0 0 0 40 0 0 0 0 0 0 0 0 0 0 0 0 0 64,0 0 0 0 0 0 0 -15?15 -15?15 -15?15 -30?30 0 0,360 0?75 0 0 0?360 0 0 128,0 15 15 15 1 sp-Ironthunder Horn wave2 20 20 150 Object YPR Sprite Same as Emitter Polar ring 20 Add 0 0 0 0 0 0 0 0 40 0 0 0 0 0 0 0 0 0 0 0 0 0 64,0 0 0 0 0 0 0 -15?15 -15?15 -15?15 -30?30 0 0,360 0?75 0 0 0?360 0 0 128,0 15 15 15 1 sp-Ironthunder Horn wave3 30 10 150 Object YPR Sprite Same as Emitter Polar ring 20 Add 0 0 0 0 0 0 0 0 40 0 0 0 0 0 0 0 0 0 0 0 0 0 64,0 0 0 0 0 0 0 -15?15 -15?15 -15?15 -30?30 0 0,360 0?75 0 0 0?360 0 0 128,0 15 15 15 1 +sp-Lesser Orb of Acid Splashes 2 500 Bones bip01 Spine1 Cartesian Sprite Polar flare-big 15 Add 0 AcidArrow 0 0 0 0 0 0 0 40 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 30?-30 0,-200 30?-30 0?360 0?360 0,60 5,1 0 0 0?360 0 0 255,0 128 255 64 +sp-Lesser Orb of Acid-proj acid-goo-dribbles perm 1000 Object YPR Sprite flare-big 30 Blend 0 AcidArrow 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0?-30 0 0 0 0 2,6 0 0 0 0 0 255,0 255,30,0,0,0 255,200,0,0,0 255,30,0,0,0 +sp-Lesser Orb of Cold Splashes 2 500 Bones bip01 Spine1 Cartesian Sprite Polar flare-1 15 Add 0 AcidArrow 0 0 0 0 0 0 0 40 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 30?-30 0,-200 30?-30 0?360 -15?30 0,60 3,8,15,8,3 0 0 0?360 0 0 0,255,0 240 248 255 +sp-Lesser Orb of Cold-proj acid-goo-dribbles perm 1000 Object YPR Sprite flare-big 30 Blend 0 AcidArrow 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0?-30 0 0 0 0 2,6 0 0 0 0 0 255,0 176,240,255,255,0 224,248,255,255,0 230,255,255,255,0 +sp-Lesser Orb of Electricity graspy 1 30 10 Disc enervation1 5 Add 0 0 0 0 0 0 0 0 #radius 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5?40 0 0 0?360 0 0 64,0 64 128 255 +sp-Lesser Orb of Electricity graspy 2 30 10 Disc enervation2 5 Add 0 0 0 0 0 0 0 0 #radius 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5?40 0 0 0?360 0 0 64,0 64 128 255 +sp-Lesser Orb of Electricity graspy 3 30 10 Disc enervation3 5 Add 0 0 0 0 0 0 0 0 #radius 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5?40 0 0 0?360 0 0 64,0 64 128 255 +sp-Lesser Orb of Electricity Blast blurry 0 3 1000 Bones Sprite Polar flare-big 10 Add 0 0 0 0 0 0 0 0 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0?360 0?90 0,40 10?30 0 0 0 0 0 64,0 255,0,0 255,128,128 255,255,255 200 +sp-Lesser Orb of Electricity blast 1 2 1600 Bones Sprite Polar flare-1 20 Add 0 0 0 0 0 0 0 0 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0?360 0?180 0,50 5,2,6,1,3,2,5,2,6,1,3,2,5,2,6,1,3,2,5,2,6,1,3,2,5,2,6,1,3,2,5,2,6,1,3,2,5,2,6,1,3,2,5,2,6,1,3,2, 0 0 0 0 0 255,0 255,0,0 255,128,128 255,255,255 400 +sp-Lesser Orb of Electricity blast 2 7 2 1600 Bones Sprite Polar flare-1 20 Add 0 0 0 0 0 0 0 0 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0?360 0?180 0,50 5,2,6,1,3,2,5,2,6,1,3,2,5,2,6,1,3,2,5,2,6,1,3,2,5,2,6,1,3,2,5,2,6,1,3,2,5,2,6,1,3,2,5,2,6,1,3,2, 0 0 0 0 0 255,0 255,0,0 255,128,128 255,255,255 400 +sp-Lesser Orb of Electricity blast 3 14 2 1600 Bones Sprite Polar flare-1 20 Add 0 0 0 0 0 0 0 0 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0?360 0?180 0,50 5,2,6,1,3,2,5,2,6,1,3,2,5,2,6,1,3,2,5,2,6,1,3,2,5,2,6,1,3,2,5,2,6,1,3,2,5,2,6,1,3,2,5,2,6,1,3,2, 0 0 0 0 0 255,0 255,0,0 255,128,128 255,255,255 400 +sp-Lesser Orb of Electricity-proj acid-goo-dribbles perm 1000 Object YPR Sprite flare-big 30 Blend 0 AcidArrow 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0?-30 0 0 0 0 2,6 0 0 0 0 0 255,0 176,240,255,255,0 196,248,255,255,0 222,255,255,255,0 +sp-Lesser Orb of Fire Simple Explosion 1 5 300 Bones Sprite Polar fire-sprite 15 Add 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0,50 0 0?360 0?360 0,30 5?20 0 0 0?360 0 0 0,255,200,150,100,50,0 255 128 64 70 +sp-Lesser Orb of Fire Simple Explosion 2 0 300 Bones Sprite Polar flare-1 15 Add 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0,50 0 0?360 0?360 0,30 10,0 0 0 0?360 0 0 0,255,200,150,100,50,0 255 128 64 70 +sp-Lesser Orb of Fire-proj Burning Sphere 1 perm 300 Object Pos Sprite Polar flare-1 15 Add 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0,50 0 0?360 0?360 0,30 4,0 0 0 0?360 0 0 0,255,200,150,100,50,0 255 128 64 70 +sp-Lesser Orb of Fire-proj Burning Sphere 2 perm 1200 Object Pos Sprite Polar fire-sprite 15 Add 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0,50 0 0?360 0?360 0,30 1?4 0 0 0?360 0 0 0,100,90,80,70,60,50,40,30,20,10,0 255 128 64 300 sp-Nauseating Breath smoke emit 10 20 600 Object YPR Sprite Same as Emitter Polar Cartesian fire-sprite 120 Blend 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0?30 0 -30?30 30?360 5?40 0 0 0?360 0 0 0,16,0 0 255 144 100 sp-Nauseating Breath Fire Strike 30 100 Object YPR Sprite Same as Emitter Polar flare-big 30 Add 0 0 0 0 0 0 0 0 40 0 0 0 0 0 0 0 0 0 0 0 0 0 64,0 0 0 0 0 0 0 0 0 0 -30?30 0 0,360 20?60 0 0 0?720 0 0 0 0 255 144 20 +sp-Orb of Acid-proj acid-goo-dribbles perm 1000 Object YPR Sprite flare-big 30 Blend 0 AcidArrow 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0?-30 0 0 0 0 5,10 0 0 0 0 0 255,0 255,30,0,0,0 255,200,0,0,0 255,30,0,0,0 +sp-Orb of Cold-proj acid-goo-dribbles perm 1000 Object YPR Sprite flare-big 30 Blend 0 AcidArrow 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0?-30 0 0 0 0 5,10 0 0 0 0 0 255,0 176,240,255,255,0 224,248,255,255,0 230,255,255,255,0 +sp-Orb of Electricity-proj acid-goo-dribbles perm 1000 Object YPR Sprite flare-big 30 Blend 0 AcidArrow 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0?-30 0 0 0 0 5,10 0 0 0 0 0 255,0 176,240,255,255,0 196,248,255,255,0 222,255,255,255,0 +sp-Orb of Fire-proj Burning Sphere 1 perm 300 Object Pos Sprite Polar flare-1 15 Add 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0,50 0 0?360 0?360 0,30 10,0 0 0 0?360 0 0 0,255,200,150,100,50,0 255 128 64 70 +sp-Orb of Fire-proj Burning Sphere 2 perm 1200 Object Pos Sprite Polar fire-sprite 15 Add 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0,50 0 0?360 0?360 0,30 5?10 0 0 0?360 0 0 0,100,90,80,70,60,50,40,30,20,10,0 255 128 64 300 sp-Shock and Awe shockwave 40 150 Object YPR Sprite Same as Emitter Polar flare-1 20 Add 0 0 0 0 0 0 0 0 40 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -15?15 -15?15 -15?15 0 0 0 0,650 0 0 0?360 0 0 128,0 15 15 15 1 sp-Veil of Shadow veil perm 150 Object Pos Disc Polar fire-sprite 60 Add 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0?360 0?30 1?4 0 0 0?360 0 0 128,0 0 0 0 30 sp-Veil of Shadow veil2 perm 100 Object Pos Sprite Polar fire-sprite 60 Blend 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0?20 0?360 0?30 2,15 0 0 0 0 0 0,150,100,50,0 87?156 0?28 127?255 30 diff --git a/tpdatasrc/tpgamefiles/rules/spell_enums/spell_compendium_spell_enum.mes b/tpdatasrc/tpgamefiles/rules/spell_enums/spell_compendium_spell_enum.mes index 0ecfa0398..847a3eeb8 100644 --- a/tpdatasrc/tpgamefiles/rules/spell_enums/spell_compendium_spell_enum.mes +++ b/tpdatasrc/tpgamefiles/rules/spell_enums/spell_compendium_spell_enum.mes @@ -46,10 +46,10 @@ {1086}{Fire Shuriken} {1087}{Phantom Foe} {1088}{Veil of Shadow} -{1089}{Curse of Impending Blades Mass} +{1089}{Curse of Imp. Blades, Mass} {1090}{Dissonant Chord} {1091}{Haunting Tune} -{1092}{Loves Lament} +{1092}{Love's Lament} {1093}{Ray of Dizziness} {1094}{Wounding Whispers} {1095}{Dirge of Discord} @@ -108,7 +108,7 @@ {1150}{Deific Vengeance} {1151}{Frost Breath} {1152}{Ghost Touch Armor} -{1153}{Aid Mass} +{1153}{Aid, Mass} {1154}{Align Weapon Mass} {1155}{Bless Weapon Swift} {1156}{Anarchic Storm} @@ -133,6 +133,25 @@ {1176}{Draconic Might} {1177}{Vigor, Mass Lesser} {1178}{Vigor, Mass Improved} +{1182}{Accuracy} +{1183}{Hail of Stone} +{1184}{Lesser Orb of Acid} +{1185}{Lesser Orb of Cold} +{1186}{Lesser Orb of Electricity} +{1187}{Lesser Orb of Fire} +{1188}{Lesser Orb of Sound} +{1189}{Blades of Fire} +{1190}{Fireburst} +{1191}{Greater Fireburst} +{1192}{Ice Knife} +{1193}{Whirling Blade} +{1194}{Ring of Blades} +{1195}{Blast of Flame} +{1196}{Orb of Acid} +{1197}{Orb of Cold} +{1198}{Orb of Electricity} +{1199}{Orb of Fire} +{1200}{Orb of Sound} {5794}{Vigor, Lesser} {5795}{Vigor} @@ -263,6 +282,25 @@ {6176}{Draconic Might} {6177}{Vigor, Mass Lesser} {6178}{Vigor, Mass Improved} +{6182}{Accuracy} +{6183}{Hail of Stone} +{6184}{Lesser Orb of Acid} +{6185}{Lesser Orb of Cold} +{6186}{Lesser Orb of Electricity} +{6187}{Lesser Orb of Fire} +{6188}{Lesser Orb of Sound} +{6189}{Blades of Fire} +{6190}{Fireburst} +{6191}{Greater Fireburst} +{6192}{Ice Knife} +{6193}{Whirling Blade} +{6194}{Ring of Blades} +{6195}{Blast of Flame} +{6196}{Orb of Acid} +{6197}{Orb of Cold} +{6198}{Orb of Electricity} +{6199}{Orb of Fire} +{6200}{Orb of Sound} {20794}{TAG_SPELLS_VIGOR,_LESSER} {20795}{TAG_SPELLS_VIGOR} @@ -395,3 +433,22 @@ {21176}{TAG_SPELLS_DRACONIC_MIGHT} {21177}{TAG_SPELLS_VIGOR,_MASS_LESSER} {21178}{TAG_SPELLS_VIGOR,_MASS_IMPROVED} +{21182}{TAG_SPELLS_ACCURACY} +{21183}{TAG_SPELLS_HAIL_OF_STONE} +{21184}{TAG_SPELLS_LESSER_ORB_OF_ACID} +{21185}{TAG_SPELLS_LESSER_ORB_OF_COLD} +{21186}{TAG_SPELLS_LESSER_ORB_OF_ELECTRICITY} +{21187}{TAG_SPELLS_LESSER_ORB_OF_FIRE} +{21188}{TAG_SPELLS_LESSER_ORB_OF_SOUND} +{21189}{TAG_SPELLS_BLADES_OF_FIRE} +{21190}{TAG_SPELLS_FIREBURST} +{21191}{TAG_SPELLS_GREATER_FIREBURST} +{21192}{TAG_SPELLS_ICE_KNIFE} +{21193}{TAG_SPELLS_WHIRLING_BLADE} +{21194}{TAG_SPELLS_RING_OF_BLADES} +{21195}{TAG_SPELLS_BLAST_OF_FLAME} +{21196}{TAG_SPELLS_ORB_OF_ACID} +{21197}{TAG_SPELLS_ORB_OF_COLD} +{21198}{TAG_SPELLS_ORB_OF_ELECTRICITY} +{21199}{TAG_SPELLS_ORB_OF_FIRE} +{21200}{TAG_SPELLS_ORB_OF_SOUND} diff --git a/tpdatasrc/tpgamefiles/rules/spells/1182 - Accuracy.txt b/tpdatasrc/tpgamefiles/rules/spells/1182 - Accuracy.txt new file mode 100644 index 000000000..93dbb533f --- /dev/null +++ b/tpdatasrc/tpgamefiles/rules/spells/1182 - Accuracy.txt @@ -0,0 +1,17 @@ +School: Transmutation +Component: V +Casting Time: 1 action +Range: Personal +Saving Throw: None +Spell Resistance: No +Projectile: No +flags_Target: Range +inc_flags_Target: Self +exc_flags_Target: Other +exc_flags_Target: Dead +exc_flags_Target: Non-critter +mode_Target: Personal +min_Target: 1 +max_Target: 1 +radius_Target: 0 +ai_type: ai_action_defensive \ No newline at end of file diff --git a/tpdatasrc/tpgamefiles/rules/spells/1183 - Hail of Stone.txt b/tpdatasrc/tpgamefiles/rules/spells/1183 - Hail of Stone.txt new file mode 100644 index 000000000..2daa04c3b --- /dev/null +++ b/tpdatasrc/tpgamefiles/rules/spells/1183 - Hail of Stone.txt @@ -0,0 +1,17 @@ +School: Conjuration +Subschool: Creation +Descriptor: Earth +Casting Time: 1 action +Range: Medium +Saving Throw: None +Spell Resistance: No +Projectile: No +flags_Target: Range +flags_Target: Radius +inc_flags_Target: Other +inc_flags_Target: Non-critter +exc_flags_Target: Self +exc_flags_Target: Dead +mode_Target: Area +radius_Target: 5 +ai_type: ai_action_defensive \ No newline at end of file diff --git a/tpdatasrc/tpgamefiles/rules/spells/1184 - Lesser Orb of Acid.txt b/tpdatasrc/tpgamefiles/rules/spells/1184 - Lesser Orb of Acid.txt new file mode 100644 index 000000000..f91a16d21 --- /dev/null +++ b/tpdatasrc/tpgamefiles/rules/spells/1184 - Lesser Orb of Acid.txt @@ -0,0 +1,22 @@ +School: Conjuration +Subschool: Creation +Descriptor: Acid +Level: Sor 1 +Level: Wiz 1 +Component: V +Component: S +Casting Time: 1 action +Range: Close +Saving Throw: None +Spell Resistance: No +Projectile: Yes +flags_Target: Range +inc_flags_Target: Other +exc_flags_Target: Dead +exc_flags_Target: Non-critter +exc_flags_Target: Self +mode_Target: Single +min_Target: 1 +max_Target: 1 +radius_Target: 0 +ai_type: ai_action_offensive \ No newline at end of file diff --git a/tpdatasrc/tpgamefiles/rules/spells/1185 - Lesser Orb of Cold.txt b/tpdatasrc/tpgamefiles/rules/spells/1185 - Lesser Orb of Cold.txt new file mode 100644 index 000000000..00d3efa50 --- /dev/null +++ b/tpdatasrc/tpgamefiles/rules/spells/1185 - Lesser Orb of Cold.txt @@ -0,0 +1,22 @@ +School: Conjuration +Subschool: Creation +Descriptor: Cold +Level: Sor 1 +Level: Wiz 1 +Component: V +Component: S +Casting Time: 1 action +Range: Close +Saving Throw: None +Spell Resistance: No +Projectile: Yes +flags_Target: Range +inc_flags_Target: Other +exc_flags_Target: Dead +exc_flags_Target: Non-critter +exc_flags_Target: Self +mode_Target: Single +min_Target: 1 +max_Target: 1 +radius_Target: 0 +ai_type: ai_action_offensive \ No newline at end of file diff --git a/tpdatasrc/tpgamefiles/rules/spells/1186 - Lesser Orb of Electricity.txt b/tpdatasrc/tpgamefiles/rules/spells/1186 - Lesser Orb of Electricity.txt new file mode 100644 index 000000000..b15033367 --- /dev/null +++ b/tpdatasrc/tpgamefiles/rules/spells/1186 - Lesser Orb of Electricity.txt @@ -0,0 +1,22 @@ +School: Conjuration +Subschool: Creation +Descriptor: Electricity +Level: Sor 1 +Level: Wiz 1 +Component: V +Component: S +Casting Time: 1 action +Range: Close +Saving Throw: None +Spell Resistance: No +Projectile: Yes +flags_Target: Range +inc_flags_Target: Other +exc_flags_Target: Dead +exc_flags_Target: Non-critter +exc_flags_Target: Self +mode_Target: Single +min_Target: 1 +max_Target: 1 +radius_Target: 0 +ai_type: ai_action_offensive \ No newline at end of file diff --git a/tpdatasrc/tpgamefiles/rules/spells/1187 - Lesser Orb of Fire.txt b/tpdatasrc/tpgamefiles/rules/spells/1187 - Lesser Orb of Fire.txt new file mode 100644 index 000000000..d676566a1 --- /dev/null +++ b/tpdatasrc/tpgamefiles/rules/spells/1187 - Lesser Orb of Fire.txt @@ -0,0 +1,22 @@ +School: Conjuration +Subschool: Creation +Descriptor: Fire +Level: Sor 1 +Level: Wiz 1 +Component: V +Component: S +Casting Time: 1 action +Range: Close +Saving Throw: None +Spell Resistance: No +Projectile: Yes +flags_Target: Range +inc_flags_Target: Other +exc_flags_Target: Dead +exc_flags_Target: Non-critter +exc_flags_Target: Self +mode_Target: Single +min_Target: 1 +max_Target: 1 +radius_Target: 0 +ai_type: ai_action_offensive \ No newline at end of file diff --git a/tpdatasrc/tpgamefiles/rules/spells/1188 - Lesser Orb of Sound.txt b/tpdatasrc/tpgamefiles/rules/spells/1188 - Lesser Orb of Sound.txt new file mode 100644 index 000000000..754b8152b --- /dev/null +++ b/tpdatasrc/tpgamefiles/rules/spells/1188 - Lesser Orb of Sound.txt @@ -0,0 +1,22 @@ +School: Conjuration +Subschool: Creation +Descriptor: Sonic +Level: Sor 1 +Level: Wiz 1 +Component: V +Component: S +Casting Time: 1 action +Range: Close +Saving Throw: None +Spell Resistance: No +Projectile: Yes +flags_Target: Range +inc_flags_Target: Other +exc_flags_Target: Dead +exc_flags_Target: Non-critter +exc_flags_Target: Self +mode_Target: Single +min_Target: 1 +max_Target: 1 +radius_Target: 0 +ai_type: ai_action_offensive \ No newline at end of file diff --git a/tpdatasrc/tpgamefiles/rules/spells/1189 - Blades of Fire.txt b/tpdatasrc/tpgamefiles/rules/spells/1189 - Blades of Fire.txt new file mode 100644 index 000000000..d422f3f65 --- /dev/null +++ b/tpdatasrc/tpgamefiles/rules/spells/1189 - Blades of Fire.txt @@ -0,0 +1,22 @@ +School: Conjuration +Subschool: Creation +Descriptor: Fire +Level: Rgr 1 +Level: Sor 1 +Level: Wiz 1 +Component: V +Casting Time: Swift Action +Range: Personal +Saving Throw: None +Spell Resistance: No +Projectile: No +flags_Target: Range +inc_flags_Target: Self +exc_flags_Target: Other +exc_flags_Target: Dead +exc_flags_Target: Non-critter +mode_Target: Personal +min_Target: 1 +max_Target: 1 +radius_Target: 0 +ai_type: ai_action_defensive \ No newline at end of file diff --git a/tpdatasrc/tpgamefiles/rules/spells/1190 - Fireburst.txt b/tpdatasrc/tpgamefiles/rules/spells/1190 - Fireburst.txt new file mode 100644 index 000000000..a80e6c951 --- /dev/null +++ b/tpdatasrc/tpgamefiles/rules/spells/1190 - Fireburst.txt @@ -0,0 +1,16 @@ +School: Evocation +Descriptor: Fire +Casting Time: 1 action +Range: Personal +Saving Throw: Reflex +Spell Resistance: Yes +Projectile: No +flags_Target: Range +flags_Target: Radius +inc_flags_Target: Other +exc_flags_Target: Self +exc_flags_Target: Dead +exc_flags_Target: Non-critter +mode_Target: Personal +radius_Target: 10 +ai_type: ai_action_defensive \ No newline at end of file diff --git a/tpdatasrc/tpgamefiles/rules/spells/1191 - Greater Fireburst.txt b/tpdatasrc/tpgamefiles/rules/spells/1191 - Greater Fireburst.txt new file mode 100644 index 000000000..e573391f9 --- /dev/null +++ b/tpdatasrc/tpgamefiles/rules/spells/1191 - Greater Fireburst.txt @@ -0,0 +1,16 @@ +School: Evocation +Descriptor: Fire +Casting Time: 1 action +Range: Personal +Saving Throw: Reflex +Spell Resistance: Yes +Projectile: No +flags_Target: Range +flags_Target: Radius +inc_flags_Target: Other +exc_flags_Target: Self +exc_flags_Target: Dead +exc_flags_Target: Non-critter +mode_Target: Personal +radius_Target: 15 +ai_type: ai_action_defensive \ No newline at end of file diff --git a/tpdatasrc/tpgamefiles/rules/spells/1195 - Blast of Flame.txt b/tpdatasrc/tpgamefiles/rules/spells/1195 - Blast of Flame.txt new file mode 100644 index 000000000..318ad432b --- /dev/null +++ b/tpdatasrc/tpgamefiles/rules/spells/1195 - Blast of Flame.txt @@ -0,0 +1,23 @@ +School: Conjuration +Subschool: Creation +Descriptor: Fire +Level: Sor 4 +Level: Wiz 4 +Component: V +Component: S +Casting Time: 1 action +Range: Specified 60 +Saving Throw: Reflex +Spell Resistance: No +Projectile: No +flags_Target: Range +flags_Target: Degrees +flags_Target: Fixed-radius +inc_flags_Target: Other +exc_flags_Target: Dead +exc_flags_Target: Non-critter +exc_flags_Target: Self +mode_Target: Cone +radius_Target: 60 +degrees_Target: 90 +ai_type: ai_action_offensive \ No newline at end of file diff --git a/tpdatasrc/tpgamefiles/rules/spells/1196 - Orb of Acid.txt b/tpdatasrc/tpgamefiles/rules/spells/1196 - Orb of Acid.txt new file mode 100644 index 000000000..765c42acb --- /dev/null +++ b/tpdatasrc/tpgamefiles/rules/spells/1196 - Orb of Acid.txt @@ -0,0 +1,22 @@ +School: Conjuration +Subschool: Creation +Descriptor: Acid +Level: Sor 4 +Level: Wiz 4 +Component: V +Component: S +Casting Time: 1 action +Range: Close +Saving Throw: None +Spell Resistance: No +Projectile: Yes +flags_Target: Range +inc_flags_Target: Other +exc_flags_Target: Dead +exc_flags_Target: Non-critter +exc_flags_Target: Self +mode_Target: Single +min_Target: 1 +max_Target: 1 +radius_Target: 0 +ai_type: ai_action_offensive \ No newline at end of file diff --git a/tpdatasrc/tpgamefiles/rules/spells/1197 - Orb of Cold.txt b/tpdatasrc/tpgamefiles/rules/spells/1197 - Orb of Cold.txt new file mode 100644 index 000000000..f79605158 --- /dev/null +++ b/tpdatasrc/tpgamefiles/rules/spells/1197 - Orb of Cold.txt @@ -0,0 +1,22 @@ +School: Conjuration +Subschool: Creation +Descriptor: Cold +Level: Sor 4 +Level: Wiz 4 +Component: V +Component: S +Casting Time: 1 action +Range: Close +Saving Throw: None +Spell Resistance: No +Projectile: Yes +flags_Target: Range +inc_flags_Target: Other +exc_flags_Target: Dead +exc_flags_Target: Non-critter +exc_flags_Target: Self +mode_Target: Single +min_Target: 1 +max_Target: 1 +radius_Target: 0 +ai_type: ai_action_offensive \ No newline at end of file diff --git a/tpdatasrc/tpgamefiles/rules/spells/1198 - Orb of Electricity.txt b/tpdatasrc/tpgamefiles/rules/spells/1198 - Orb of Electricity.txt new file mode 100644 index 000000000..c3e42480e --- /dev/null +++ b/tpdatasrc/tpgamefiles/rules/spells/1198 - Orb of Electricity.txt @@ -0,0 +1,22 @@ +School: Conjuration +Subschool: Creation +Descriptor: Electricity +Level: Sor 4 +Level: Wiz 4 +Component: V +Component: S +Casting Time: 1 action +Range: Close +Saving Throw: None +Spell Resistance: No +Projectile: Yes +flags_Target: Range +inc_flags_Target: Other +exc_flags_Target: Dead +exc_flags_Target: Non-critter +exc_flags_Target: Self +mode_Target: Single +min_Target: 1 +max_Target: 1 +radius_Target: 0 +ai_type: ai_action_offensive \ No newline at end of file diff --git a/tpdatasrc/tpgamefiles/rules/spells/1199 - Orb of Fire.txt b/tpdatasrc/tpgamefiles/rules/spells/1199 - Orb of Fire.txt new file mode 100644 index 000000000..085932fed --- /dev/null +++ b/tpdatasrc/tpgamefiles/rules/spells/1199 - Orb of Fire.txt @@ -0,0 +1,22 @@ +School: Conjuration +Subschool: Creation +Descriptor: Fire +Level: Sor 4 +Level: Wiz 4 +Component: V +Component: S +Casting Time: 1 action +Range: Close +Saving Throw: None +Spell Resistance: No +Projectile: Yes +flags_Target: Range +inc_flags_Target: Other +exc_flags_Target: Dead +exc_flags_Target: Non-critter +exc_flags_Target: Self +mode_Target: Single +min_Target: 1 +max_Target: 1 +radius_Target: 0 +ai_type: ai_action_offensive \ No newline at end of file diff --git a/tpdatasrc/tpgamefiles/rules/spells/1200 - Orb of Sonic.txt b/tpdatasrc/tpgamefiles/rules/spells/1200 - Orb of Sonic.txt new file mode 100644 index 000000000..a2e0f5289 --- /dev/null +++ b/tpdatasrc/tpgamefiles/rules/spells/1200 - Orb of Sonic.txt @@ -0,0 +1,22 @@ +School: Conjuration +Subschool: Creation +Descriptor: Sonic +Level: Sor 4 +Level: Wiz 4 +Component: V +Component: S +Casting Time: 1 action +Range: Close +Saving Throw: None +Spell Resistance: No +Projectile: Yes +flags_Target: Range +inc_flags_Target: Other +exc_flags_Target: Dead +exc_flags_Target: Non-critter +exc_flags_Target: Self +mode_Target: Single +min_Target: 1 +max_Target: 1 +radius_Target: 0 +ai_type: ai_action_offensive \ No newline at end of file diff --git a/tpdatasrc/tpgamefiles/scr/Spell1182 - Accuracy.py b/tpdatasrc/tpgamefiles/scr/Spell1182 - Accuracy.py new file mode 100644 index 000000000..c1250f5ca --- /dev/null +++ b/tpdatasrc/tpgamefiles/scr/Spell1182 - Accuracy.py @@ -0,0 +1,26 @@ +from toee import * + +def OnBeginSpellCast(spell): + print "Accuracy OnBeginSpellCast" + print "spell.target_list=", spell.target_list + print "spell.caster=", spell.caster, " caster.level= ", spell.caster_level + +def OnSpellEffect(spell): + print "Accuracy OnSpellEffect" + + spell.duration = 100 * spell.caster_level # 10 mins/level + spellTarget = spell.target_list[0] + + if spellTarget.obj.condition_add_with_args('sp-Accuracy', spell.id, spell.duration): + spellTarget.partsys_id = game.particles('sp-Sure Strike', spell.caster) + else: + spellTarget.obj.float_mesfile_line('mes\\spell.mes', 30000) + game.particles('Fizzle', spellTarget.obj) + spell.target_list.remove_target(spellTarget.obj) + spell.spell_end(spell.id) + +def OnBeginRound(spell): + print "Accuracy OnBeginRound" + +def OnEndSpellCast(spell): + print "Accuracy OnEndSpellCast" \ No newline at end of file diff --git a/tpdatasrc/tpgamefiles/scr/Spell1183 - Hail of Stone.py b/tpdatasrc/tpgamefiles/scr/Spell1183 - Hail of Stone.py new file mode 100644 index 000000000..e7fe89b54 --- /dev/null +++ b/tpdatasrc/tpgamefiles/scr/Spell1183 - Hail of Stone.py @@ -0,0 +1,32 @@ +from toee import * + +def OnBeginSpellCast(spell): + print "Hail of Stone OnBeginSpellCast" + print "spell.target_list=", spell.target_list + print "spell.caster=", spell.caster, " caster.level= ", spell.caster_level + +def OnSpellEffect(spell): + print "Hail of Stone OnSpellEffect" + + targetsToRemove = [] + spell.duration = 0 + spellDamageDice = dice_new('1d4') + spellDamageDice.number = min(spell.caster_level, 5) + damageType = D20DT_BLUDGEONING + + game.particles('sp-Hail of Stone', spell.target_loc) + + for spellTarget in spell.target_list: + #Hail of Stone has no save + spellTarget.obj.spell_damage(spell.caster, damageType, spellDamageDice, D20DAP_UNSPECIFIED, D20A_CAST_SPELL, spell.id) + targetsToRemove.append(spellTarget.obj) + + spell.target_list.remove_list(targetsToRemove) + spell.spell_end(spell.id) + +def OnBeginRound(spell): + print "Hail of Stone OnBeginRound" + +def OnEndSpellCast(spell): + print "Hail of Stone OnEndSpellCast" + diff --git a/tpdatasrc/tpgamefiles/scr/Spell1184 - Lesser Orb of Acid.py b/tpdatasrc/tpgamefiles/scr/Spell1184 - Lesser Orb of Acid.py new file mode 100644 index 000000000..c28357e62 --- /dev/null +++ b/tpdatasrc/tpgamefiles/scr/Spell1184 - Lesser Orb of Acid.py @@ -0,0 +1,44 @@ +from toee import * + +def OnBeginSpellCast(spell): + print "Lesser Orb of Acid OnBeginSpellCast" + print "spell.target_list=", spell.target_list + print "spell.caster=", spell.caster, " caster.level= ", spell.caster_level + +def OnSpellEffect(spell): + print "Lesser Orb of Acid OnSpellEffect" + +def OnBeginRound(spell): + print "Lesser Orb of Acid OnBeginRound" + +def OnBeginProjectile(spell, projectile, index_of_target): + print "Lesser Orb of Acid OnBeginProjectile" + projectile.obj_set_int(obj_f_projectile_part_sys_id, game.particles("sp-Lesser Orb of Acid-proj", projectile)) + +def OnEndProjectile(spell, projectile, index_of_target): + print "Lesser Orb of Acid OnEndProjectile" + + spell.duration = 0 + spellTarget = spell.target_list[0] + spellDamageDice = dice_new('1d8') + spellDamageDice.number = min((spell.caster_level + 1) / 2, 5) #capped at cl 9 (5d8) + damageType = D20DT_ACID + spellDamageReduction = 100 #100 indicates full damage + + game.particles_end(projectile.obj_get_int(obj_f_projectile_part_sys_id)) + + attackResult = spell.caster.perform_touch_attack(spellTarget.obj) + + if attackResult & D20CAF_HIT: + game.particles("sp-Lesser Orb of Acid", spellTarget.obj) + spellTarget.obj.spell_damage_weaponlike(spell.caster, damageType, spellDamageDice, D20DAP_UNSPECIFIED, spellDamageReduction, D20A_CAST_SPELL, spell.id, attackResult, index_of_target) + else: + spellTarget.obj.float_mesfile_line('mes\\spell.mes', 30007) + game.particles('Fizzle', spellTarget.obj) + + spell.target_list.remove_target(spellTarget.obj) + spell.spell_end(spell.id) + +def OnEndSpellCast(spell): + print "Lesser Orb of Acid OnEndSpellCast" + diff --git a/tpdatasrc/tpgamefiles/scr/Spell1185 - Lesser Orb of Cold.py b/tpdatasrc/tpgamefiles/scr/Spell1185 - Lesser Orb of Cold.py new file mode 100644 index 000000000..9768c90e0 --- /dev/null +++ b/tpdatasrc/tpgamefiles/scr/Spell1185 - Lesser Orb of Cold.py @@ -0,0 +1,44 @@ +from toee import * + +def OnBeginSpellCast(spell): + print "Lesser Orb of Cold OnBeginSpellCast" + print "spell.target_list=", spell.target_list + print "spell.caster=", spell.caster, " caster.level= ", spell.caster_level + +def OnSpellEffect(spell): + print "Lesser Orb of Cold OnSpellEffect" + +def OnBeginRound(spell): + print "Lesser Orb of Cold OnBeginRound" + +def OnBeginProjectile(spell, projectile, index_of_target): + print "Lesser Orb of Cold OnBeginProjectile" + projectile.obj_set_int(obj_f_projectile_part_sys_id, game.particles("sp-Lesser Orb of Cold-proj", projectile)) + +def OnEndProjectile(spell, projectile, index_of_target): + print "Lesser Orb of Cold OnEndProjectile" + + spell.duration = 0 + spellTarget = spell.target_list[0] + spellDamageDice = dice_new('1d8') + spellDamageDice.number = min((spell.caster_level + 1) / 2, 5) #capped at cl 9 (5d8) + damageType = D20DT_COLD + spellDamageReduction = 100 #100 indicates full damage + + game.particles_end(projectile.obj_get_int(obj_f_projectile_part_sys_id)) + + attackResult = spell.caster.perform_touch_attack(spellTarget.obj) + + if attackResult & D20CAF_HIT: + game.particles("sp-Lesser Orb of Cold", spellTarget.obj) + spellTarget.obj.spell_damage_weaponlike(spell.caster, damageType, spellDamageDice, D20DAP_UNSPECIFIED, spellDamageReduction, D20A_CAST_SPELL, spell.id, attackResult, index_of_target) + else: + spellTarget.obj.float_mesfile_line('mes\\spell.mes', 30007) + game.particles('Fizzle', spellTarget.obj) + + spell.target_list.remove_target(spellTarget.obj) + spell.spell_end(spell.id) + +def OnEndSpellCast(spell): + print "Lesser Orb of Cold OnEndSpellCast" + diff --git a/tpdatasrc/tpgamefiles/scr/Spell1186 - Lesser Orb of Electricity.py b/tpdatasrc/tpgamefiles/scr/Spell1186 - Lesser Orb of Electricity.py new file mode 100644 index 000000000..8dcc3ec95 --- /dev/null +++ b/tpdatasrc/tpgamefiles/scr/Spell1186 - Lesser Orb of Electricity.py @@ -0,0 +1,44 @@ +from toee import * + +def OnBeginSpellCast(spell): + print "Lesser Orb of Electricity OnBeginSpellCast" + print "spell.target_list=", spell.target_list + print "spell.caster=", spell.caster, " caster.level= ", spell.caster_level + +def OnSpellEffect(spell): + print "Lesser Orb of Electricity OnSpellEffect" + +def OnBeginRound(spell): + print "Lesser Orb of Electricity OnBeginRound" + +def OnBeginProjectile(spell, projectile, index_of_target): + print "Lesser Orb of Electricity OnBeginProjectile" + projectile.obj_set_int(obj_f_projectile_part_sys_id, game.particles("sp-Lesser Orb of Electricity-proj", projectile)) + +def OnEndProjectile(spell, projectile, index_of_target): + print "Lesser Orb of Electricity OnEndProjectile" + + spell.duration = 0 + spellTarget = spell.target_list[0] + spellDamageDice = dice_new('1d8') + spellDamageDice.number = min((spell.caster_level + 1) / 2, 5) #capped at cl 9 (5d8) + damageType = D20DT_ELECTRICITY + spellDamageReduction = 100 #100 indicates full damage + + game.particles_end(projectile.obj_get_int(obj_f_projectile_part_sys_id)) + + attackResult = spell.caster.perform_touch_attack(spellTarget.obj) + + if attackResult & D20CAF_HIT: + game.particles("sp-Lesser Orb of Electricity", spellTarget.obj) + spellTarget.obj.spell_damage_weaponlike(spell.caster, damageType, spellDamageDice, D20DAP_UNSPECIFIED, spellDamageReduction, D20A_CAST_SPELL, spell.id, attackResult, index_of_target) + else: + spellTarget.obj.float_mesfile_line('mes\\spell.mes', 30007) + game.particles('Fizzle', spellTarget.obj) + + spell.target_list.remove_target(spellTarget.obj) + spell.spell_end(spell.id) + +def OnEndSpellCast(spell): + print "Lesser Orb of Electricity OnEndSpellCast" + diff --git a/tpdatasrc/tpgamefiles/scr/Spell1187 - Lesser Orb of Fire.py b/tpdatasrc/tpgamefiles/scr/Spell1187 - Lesser Orb of Fire.py new file mode 100644 index 000000000..4f0e07917 --- /dev/null +++ b/tpdatasrc/tpgamefiles/scr/Spell1187 - Lesser Orb of Fire.py @@ -0,0 +1,44 @@ +from toee import * + +def OnBeginSpellCast(spell): + print "Lesser Orb of Fire OnBeginSpellCast" + print "spell.target_list=", spell.target_list + print "spell.caster=", spell.caster, " caster.level= ", spell.caster_level + +def OnSpellEffect(spell): + print "Lesser Orb of Fire OnSpellEffect" + +def OnBeginRound(spell): + print "Lesser Orb of Fire OnBeginRound" + +def OnBeginProjectile(spell, projectile, index_of_target): + print "Lesser Orb of Fire OnBeginProjectile" + projectile.obj_set_int(obj_f_projectile_part_sys_id, game.particles("sp-Lesser Orb of Fire-proj", projectile)) + +def OnEndProjectile(spell, projectile, index_of_target): + print "Lesser Orb of Fire OnEndProjectile" + + spell.duration = 0 + spellTarget = spell.target_list[0] + spellDamageDice = dice_new('1d8') + spellDamageDice.number = min((spell.caster_level + 1) / 2, 5) #capped at cl 9 (5d8) + damageType = D20DT_FIRE + spellDamageReduction = 100 #100 indicates full damage + + game.particles_end(projectile.obj_get_int(obj_f_projectile_part_sys_id)) + + attackResult = spell.caster.perform_touch_attack(spellTarget.obj) + + if attackResult & D20CAF_HIT: + game.particles("sp-Lesser Orb of Fire", spellTarget.obj) + spellTarget.obj.spell_damage_weaponlike(spell.caster, damageType, spellDamageDice, D20DAP_UNSPECIFIED, spellDamageReduction, D20A_CAST_SPELL, spell.id, attackResult, index_of_target) + else: + spellTarget.obj.float_mesfile_line('mes\\spell.mes', 30007) + game.particles('Fizzle', spellTarget.obj) + + spell.target_list.remove_target(spellTarget.obj) + spell.spell_end(spell.id) + +def OnEndSpellCast(spell): + print "Lesser Orb of Fire OnEndSpellCast" + diff --git a/tpdatasrc/tpgamefiles/scr/Spell1188 - Lesser Orb of Sound.py b/tpdatasrc/tpgamefiles/scr/Spell1188 - Lesser Orb of Sound.py new file mode 100644 index 000000000..f1fe1acc2 --- /dev/null +++ b/tpdatasrc/tpgamefiles/scr/Spell1188 - Lesser Orb of Sound.py @@ -0,0 +1,44 @@ +from toee import * + +def OnBeginSpellCast(spell): + print "Lesser Orb of Sound OnBeginSpellCast" + print "spell.target_list=", spell.target_list + print "spell.caster=", spell.caster, " caster.level= ", spell.caster_level + +def OnSpellEffect(spell): + print "Lesser Orb of Sound OnSpellEffect" + +def OnBeginRound(spell): + print "Lesser Orb of Sound OnBeginRound" + +def OnBeginProjectile(spell, projectile, index_of_target): + print "Lesser Orb of Sound OnBeginProjectile" + projectile.obj_set_int(obj_f_projectile_part_sys_id, game.particles("sp-Lesser Orb of Cold-proj", projectile)) + +def OnEndProjectile(spell, projectile, index_of_target): + print "Lesser Orb of Sound OnEndProjectile" + + spell.duration = 0 + spellTarget = spell.target_list[0] + spellDamageDice = dice_new('1d8') + spellDamageDice.number = min((spell.caster_level + 1) / 2, 5) #capped at cl 9 (5d8) + damageType = D20DT_SONIC + spellDamageReduction = 100 #100 indicates full damage + + game.particles_end(projectile.obj_get_int(obj_f_projectile_part_sys_id)) + + attackResult = spell.caster.perform_touch_attack(spellTarget.obj) + + if attackResult & D20CAF_HIT: + game.particles("sp-Lesser Orb of Cold", spellTarget.obj) + spellTarget.obj.spell_damage_weaponlike(spell.caster, damageType, spellDamageDice, D20DAP_UNSPECIFIED, spellDamageReduction, D20A_CAST_SPELL, spell.id, attackResult, index_of_target) + else: + spellTarget.obj.float_mesfile_line('mes\\spell.mes', 30007) + game.particles('Fizzle', spellTarget.obj) + + spell.target_list.remove_target(spellTarget.obj) + spell.spell_end(spell.id) + +def OnEndSpellCast(spell): + print "Lesser Orb of Sound OnEndSpellCast" + diff --git a/tpdatasrc/tpgamefiles/scr/Spell1189 - Blades of Fire.py b/tpdatasrc/tpgamefiles/scr/Spell1189 - Blades of Fire.py new file mode 100644 index 000000000..26d034f09 --- /dev/null +++ b/tpdatasrc/tpgamefiles/scr/Spell1189 - Blades of Fire.py @@ -0,0 +1,44 @@ +from toee import * + +def OnBeginSpellCast(spell): + print "Blades of Fire OnBeginSpellCast" + print "spell.target_list=", spell.target_list + print "spell.caster=", spell.caster, " caster.level= ", spell.caster_level + +def OnSpellEffect(spell): + print "Blades of Fire OnSpellEffect" + + spell.duration = 0 # current round + spellTarget = spell.target_list[0] + mainhandWeapon = spellTarget.obj.item_worn_at(item_wear_weapon_primary) + offhandWeapon = spellTarget.obj.item_worn_at(item_wear_weapon_secondary) + actionMesId = AEC_WRONG_WEAPON_TYPE + 1000 #{1017}{Wrong Weapon Type} + weaponTypeMainhand = mainhandWeapon.get_weapon_type() + weaponTypeOffhand = offhandWeapon.get_weapon_type() + + if game.is_melee_weapon(weaponTypeMainhand) and mainhandWeapon != OBJ_HANDLE_NULL: + mainhandWeapon.d20_status_init() + if not mainhandWeapon.condition_add_with_args('sp-Blades of Fire', spell.id, spell.duration, 0): + spellTarget.obj.float_mesfile_line('mes\\spell.mes', 30000) + game.particles('Fizzle', spellTarget.obj) + else: + spellTarget.obj.float_mesfile_line('mes\\action.mes', actionMesId, tf_red) + game.particles('Fizzle', spellTarget.obj) + + if game.is_melee_weapon(weaponTypeOffhand) and offhandWeapon != OBJ_HANDLE_NULL: + offhandWeapon.d20_status_init() + if not offhandWeapon.condition_add_with_args('sp-Blades of Fire', spell.id, spell.duration, 0): + spellTarget.obj.float_mesfile_line('mes\\spell.mes', 30000) + game.particles('Fizzle', spellTarget.obj) + elif offhandWeapon != OBJ_HANDLE_NULL: + spellTarget.obj.float_mesfile_line('mes\\action.mes', actionMesId, tf_red) + game.particles('Fizzle', spellTarget.obj) + + spell.target_list.remove_target(spellTarget.obj) + spell.spell_end(spell.id) + +def OnBeginRound(spell): + print "Blades of Fire OnBeginRound" + +def OnEndSpellCast(spell): + print "Blades of Fire OnEndSpellCast" \ No newline at end of file diff --git a/tpdatasrc/tpgamefiles/scr/Spell1190 - Fireburst.py b/tpdatasrc/tpgamefiles/scr/Spell1190 - Fireburst.py new file mode 100644 index 000000000..0cca670b7 --- /dev/null +++ b/tpdatasrc/tpgamefiles/scr/Spell1190 - Fireburst.py @@ -0,0 +1,37 @@ +from toee import * + +def OnBeginSpellCast(spell): + print "Fireburst OnBeginSpellCast" + print "spell.target_list=", spell.target_list + print "spell.caster=", spell.caster, " caster.level= ", spell.caster_level + +def OnSpellEffect(spell): + print "Fireburst OnSpellEffect" + + targetsToRemove = [] + spell.duration = 0 + saveType = D20_Save_Reduction_Half + saveDescriptor = D20STD_F_NONE + spellDamageDice = dice_new('1d8') + spellDamageDice.number = min(spell.caster_level, 5) + damageType = D20DT_FIRE + + game.particles('sp-Fireburst', spell.caster) + + for spellTarget in spell.target_list: + #Save for half damage: + if spellTarget.obj.reflex_save_and_damage(spell.caster, spell.dc, saveType, saveDescriptor, spellDamageDice, damageType, D20DAP_UNSPECIFIED, D20A_CAST_SPELL, spell.id): #success + spellTarget.obj.float_mesfile_line('mes\\spell.mes', 30001) + else: + spellTarget.obj.float_mesfile_line('mes\\spell.mes', 30002) + targetsToRemove.append(spellTarget.obj) + + spell.target_list.remove_list(targetsToRemove) + spell.spell_end(spell.id) + +def OnBeginRound(spell): + print "Fireburst OnBeginRound" + +def OnEndSpellCast(spell): + print "Fireburst OnEndSpellCast" + diff --git a/tpdatasrc/tpgamefiles/scr/Spell1191 - Greater Fireburst.py b/tpdatasrc/tpgamefiles/scr/Spell1191 - Greater Fireburst.py new file mode 100644 index 000000000..bba1f5d32 --- /dev/null +++ b/tpdatasrc/tpgamefiles/scr/Spell1191 - Greater Fireburst.py @@ -0,0 +1,37 @@ +from toee import * + +def OnBeginSpellCast(spell): + print "Greater Greater Fireburst OnBeginSpellCast" + print "spell.target_list=", spell.target_list + print "spell.caster=", spell.caster, " caster.level= ", spell.caster_level + +def OnSpellEffect(spell): + print "Greater Fireburst OnSpellEffect" + + targetsToRemove = [] + spell.duration = 0 + saveType = D20_Save_Reduction_Half + saveDescriptor = D20STD_F_NONE + spellDamageDice = dice_new('1d10') + spellDamageDice.number = min(spell.caster_level, 15) + damageType = D20DT_FIRE + + game.particles('sp-Greater Fireburst', spell.caster) + + for spellTarget in spell.target_list: + #Save for half damage: + if spellTarget.obj.reflex_save_and_damage(spell.caster, spell.dc, saveType, saveDescriptor, spellDamageDice, damageType, D20DAP_UNSPECIFIED, D20A_CAST_SPELL, spell.id): #success + spellTarget.obj.float_mesfile_line('mes\\spell.mes', 30001) + else: + spellTarget.obj.float_mesfile_line('mes\\spell.mes', 30002) + targetsToRemove.append(spellTarget.obj) + + spell.target_list.remove_list(targetsToRemove) + spell.spell_end(spell.id) + +def OnBeginRound(spell): + print "Greater Fireburst OnBeginRound" + +def OnEndSpellCast(spell): + print "Greater Fireburst OnEndSpellCast" + diff --git a/tpdatasrc/tpgamefiles/scr/Spell1195 - Blast of Flame.py b/tpdatasrc/tpgamefiles/scr/Spell1195 - Blast of Flame.py new file mode 100644 index 000000000..90deff253 --- /dev/null +++ b/tpdatasrc/tpgamefiles/scr/Spell1195 - Blast of Flame.py @@ -0,0 +1,37 @@ +from toee import * + +def OnBeginSpellCast(spell): + print "Blast of Flame OnBeginSpellCast" + print "spell.target_list=", spell.target_list + print "spell.caster=", spell.caster, " caster.level= ", spell.caster_level + +def OnSpellEffect(spell): + print "Blast of Flame OnSpellEffect" + + targetsToRemove = [] + spell.duration = 0 + saveType = D20_Save_Reduction_Half + saveDescriptor = D20STD_F_NONE + spellDamageDice = dice_new('1d6') + spellDamageDice.number = min(spell.caster_level, 10) + damageType = D20DT_FIRE + + game.particles('sp-Blast of Flame', spell.caster) + + for spellTarget in spell.target_list: + #Save for half damage + if spellTarget.obj.reflex_save_and_damage(spell.caster, spell.dc, saveType, saveDescriptor, spellDamageDice, damageType, D20DAP_UNSPECIFIED, D20A_CAST_SPELL, spell.id): #success + spellTarget.obj.float_mesfile_line('mes\\spell.mes', 30001) + else: + spellTarget.obj.float_mesfile_line('mes\\spell.mes', 30002) + targetsToRemove.append(spellTarget.obj) + + spell.target_list.remove_list(targetsToRemove) + spell.spell_end(spell.id) + +def OnBeginRound(spell): + print "Blast of Flame OnBeginRound" + +def OnEndSpellCast(spell): + print "Blast of Flame OnEndSpellCast" + diff --git a/tpdatasrc/tpgamefiles/scr/Spell1196 - Orb of Acid.py b/tpdatasrc/tpgamefiles/scr/Spell1196 - Orb of Acid.py new file mode 100644 index 000000000..304a98f9f --- /dev/null +++ b/tpdatasrc/tpgamefiles/scr/Spell1196 - Orb of Acid.py @@ -0,0 +1,53 @@ +from toee import * + +def OnBeginSpellCast(spell): + print "Orb of Acid OnBeginSpellCast" + print "spell.target_list=", spell.target_list + print "spell.caster=", spell.caster, " caster.level= ", spell.caster_level + +def OnSpellEffect(spell): + print "Orb of Acid OnSpellEffect" + +def OnBeginRound(spell): + print "Orb of Acid OnBeginRound" + +def OnBeginProjectile(spell, projectile, index_of_target): + print "Orb of Acid OnBeginProjectile" + projectile.obj_set_int(obj_f_projectile_part_sys_id, game.particles("sp-Orb of Acid-proj", projectile)) + +def OnEndProjectile(spell, projectile, index_of_target): + print "Orb of Acid OnEndProjectile" + + spell.duration = 0 + spellTarget = spell.target_list[0] + spellDamageDice = dice_new('1d6') + spellDamageDice.number = min(spell.caster_level, 15) #capped at cl 15 (15d6) + damageType = D20DT_ACID + spellDamageReduction = 100 #100 indicates full damage + + game.particles_end(projectile.obj_get_int(obj_f_projectile_part_sys_id)) + + attackResult = spell.caster.perform_touch_attack(spellTarget.obj) + + if attackResult & D20CAF_HIT: + game.particles("sp-Lesser Orb of Acid", spellTarget.obj) + spellTarget.obj.spell_damage_weaponlike(spell.caster, damageType, spellDamageDice, D20DAP_UNSPECIFIED, spellDamageReduction, D20A_CAST_SPELL, spell.id, attackResult, index_of_target) + #Save for secondary effect + if spellTarget.obj.saving_throw_spell(spell.dc, D20_Save_Fortitude, D20STD_F_SPELL_DESCRIPTOR_ACID, spell.caster, spell.id): + spellTarget.obj.float_mesfile_line('mes\\spell.mes', 30001) + game.particles('Fizzle', spellTarget.obj) + else: + spellTarget.obj.float_mesfile_line('mes\\spell.mes', 30002) + duration = 1 + particlesID = 0 + spellTarget.obj.condition_add_with_args("Sickened", duration, particlesID, 0) + else: + spellTarget.obj.float_mesfile_line('mes\\spell.mes', 30007) + game.particles('Fizzle', spellTarget.obj) + + spell.target_list.remove_target(spellTarget.obj) + spell.spell_end(spell.id) + +def OnEndSpellCast(spell): + print "Orb of Acid OnEndSpellCast" + diff --git a/tpdatasrc/tpgamefiles/scr/Spell1197 - Orb of Cold.py b/tpdatasrc/tpgamefiles/scr/Spell1197 - Orb of Cold.py new file mode 100644 index 000000000..ec04b4b5d --- /dev/null +++ b/tpdatasrc/tpgamefiles/scr/Spell1197 - Orb of Cold.py @@ -0,0 +1,54 @@ +from toee import * + +def OnBeginSpellCast(spell): + print "Orb of Cold OnBeginSpellCast" + print "spell.target_list=", spell.target_list + print "spell.caster=", spell.caster, " caster.level= ", spell.caster_level + +def OnSpellEffect(spell): + print "Orb of Cold OnSpellEffect" + +def OnBeginRound(spell): + print "Orb of Cold OnBeginRound" + +def OnBeginProjectile(spell, projectile, index_of_target): + print "Orb of Cold OnBeginProjectile" + projectile.obj_set_int(obj_f_projectile_part_sys_id, game.particles("sp-Orb of Cold-proj", projectile)) + +def OnEndProjectile(spell, projectile, index_of_target): + print "Orb of Cold OnEndProjectile" + + spell.duration = 0 + spellTarget = spell.target_list[0] + spellDamageDice = dice_new('1d6') + spellDamageDice.number = min(spell.caster_level, 15) #capped at cl 15 (15d6) + damageType = D20DT_COLD + spellDamageReduction = 100 #100 indicates full damage + + game.particles_end(projectile.obj_get_int(obj_f_projectile_part_sys_id)) + + attackResult = spell.caster.perform_touch_attack(spellTarget.obj) + + if attackResult & D20CAF_HIT: + game.particles("sp-Lesser Orb of Cold", spellTarget.obj) + spellTarget.obj.spell_damage_weaponlike(spell.caster, damageType, spellDamageDice, D20DAP_UNSPECIFIED, spellDamageReduction, D20A_CAST_SPELL, spell.id, attackResult, index_of_target) + #Save for secondary effect + if spellTarget.obj.saving_throw_spell(spell.dc, D20_Save_Fortitude, D20STD_F_SPELL_DESCRIPTOR_COLD, spell.caster, spell.id): + spellTarget.obj.float_mesfile_line('mes\\spell.mes', 30001) + game.particles('Fizzle', spellTarget.obj) + spell.target_list.remove_target(spellTarget.obj) + else: + spellTarget.obj.float_mesfile_line('mes\\spell.mes', 30002) + spell.duration = 1 + if spellTarget.obj.condition_add_with_args("sp-Blindness", spell.id, spell.duration, 0): + spellTarget.partsys_id = game.particles("sp-Blindness-Deafness", spellTarget.obj) + else: + spellTarget.obj.float_mesfile_line('mes\\spell.mes', 30007) + game.particles('Fizzle', spellTarget.obj) + spell.target_list.remove_target(spellTarget.obj) + + spell.spell_end(spell.id) + +def OnEndSpellCast(spell): + print "Orb of Cold OnEndSpellCast" + diff --git a/tpdatasrc/tpgamefiles/scr/Spell1198 - Orb of Electricity.py b/tpdatasrc/tpgamefiles/scr/Spell1198 - Orb of Electricity.py new file mode 100644 index 000000000..4020c19a9 --- /dev/null +++ b/tpdatasrc/tpgamefiles/scr/Spell1198 - Orb of Electricity.py @@ -0,0 +1,59 @@ +from toee import * + +def OnBeginSpellCast(spell): + print "Orb of Electricity OnBeginSpellCast" + print "spell.target_list=", spell.target_list + print "spell.caster=", spell.caster, " caster.level= ", spell.caster_level + +def OnSpellEffect(spell): + print "Orb of Electricity OnSpellEffect" + +def OnBeginRound(spell): + print "Orb of Electricity OnBeginRound" + +def OnBeginProjectile(spell, projectile, index_of_target): + print "Orb of Electricity OnBeginProjectile" + projectile.obj_set_int(obj_f_projectile_part_sys_id, game.particles("sp-Orb of Electricity-proj", projectile)) + +def OnEndProjectile(spell, projectile, index_of_target): + print "Orb of Electricity OnEndProjectile" + + spell.duration = 0 + spellTarget = spell.target_list[0] + spellDamageDice = dice_new('1d6') + spellDamageDice.number = min(spell.caster_level, 15) #capped at cl 15 (15d6) + damageType = D20DT_ELECTRICITY + spellDamageReduction = 100 #100 indicates full damage + + game.particles_end(projectile.obj_get_int(obj_f_projectile_part_sys_id)) + + attackResult = spell.caster.perform_touch_attack(spellTarget.obj) + + if attackResult & D20CAF_HIT: + game.particles("sp-Lesser Orb of Electricity", spellTarget.obj) + spellTarget.obj.spell_damage_weaponlike(spell.caster, damageType, spellDamageDice, D20DAP_UNSPECIFIED, spellDamageReduction, D20A_CAST_SPELL, spell.id, attackResult, index_of_target) + #Save for secondary effect if spellTarget wears a metal armor + spellTargetWornArmor = spellTarget.obj.item_worn_at(item_wear_armor) + if spellTargetWornArmor.obj_get_int(obj_f_material) == mat_metal: + if spellTarget.obj.saving_throw_spell(spell.dc, D20_Save_Fortitude, D20STD_F_SPELL_DESCRIPTOR_COLD, spell.caster, spell.id): + spellTarget.obj.float_mesfile_line('mes\\spell.mes', 30001) + game.particles('Fizzle', spellTarget.obj) + spell.target_list.remove_target(spellTarget.obj) + else: + spellTarget.obj.float_mesfile_line('mes\\spell.mes', 30002) + spell.duration = 1 + if spellTarget.obj.condition_add_with_args("sp-Daze", spell.id, spell.duration, 0): + spellTarget.partsys_id = game.particles("sp-Daze", spellTarget.obj) + #entangleEvtId = 0 #as there is no real entangle spell, there is no evtId + #if spellTarget.obj.condition_add_with_args("sp-Entangle On", spell.id, spell.duration, entangleEvtId): + # spellTarget.partsys_id = game.particles("sp-Entangle", spellTarget.obj) + else: + spellTarget.obj.float_mesfile_line('mes\\spell.mes', 30007) + game.particles('Fizzle', spellTarget.obj) + spell.target_list.remove_target(spellTarget.obj) + + spell.spell_end(spell.id) + +def OnEndSpellCast(spell): + print "Orb of Electricity OnEndSpellCast" + diff --git a/tpdatasrc/tpgamefiles/scr/Spell1199 - Orb of Fire.py b/tpdatasrc/tpgamefiles/scr/Spell1199 - Orb of Fire.py new file mode 100644 index 000000000..60dbc84c3 --- /dev/null +++ b/tpdatasrc/tpgamefiles/scr/Spell1199 - Orb of Fire.py @@ -0,0 +1,54 @@ +from toee import * + +def OnBeginSpellCast(spell): + print "Orb of Fire OnBeginSpellCast" + print "spell.target_list=", spell.target_list + print "spell.caster=", spell.caster, " caster.level= ", spell.caster_level + +def OnSpellEffect(spell): + print "Orb of Fire OnSpellEffect" + +def OnBeginRound(spell): + print "Orb of Fire OnBeginRound" + +def OnBeginProjectile(spell, projectile, index_of_target): + print "Orb of Fire OnBeginProjectile" + projectile.obj_set_int(obj_f_projectile_part_sys_id, game.particles("sp-Orb of Fire-proj", projectile)) + +def OnEndProjectile(spell, projectile, index_of_target): + print "Orb of Fire OnEndProjectile" + + spell.duration = 0 + spellTarget = spell.target_list[0] + spellDamageDice = dice_new('1d6') + spellDamageDice.number = min(spell.caster_level, 15) #capped at cl 15 (15d6) + damageType = D20DT_FIRE + spellDamageReduction = 100 #100 indicates full damage + + game.particles_end(projectile.obj_get_int(obj_f_projectile_part_sys_id)) + + attackResult = spell.caster.perform_touch_attack(spellTarget.obj) + + if attackResult & D20CAF_HIT: + game.particles("sp-Lesser Orb of Fire", spellTarget.obj) + spellTarget.obj.spell_damage_weaponlike(spell.caster, damageType, spellDamageDice, D20DAP_UNSPECIFIED, spellDamageReduction, D20A_CAST_SPELL, spell.id, attackResult, index_of_target) + #Save for secondary effect + if spellTarget.obj.saving_throw_spell(spell.dc, D20_Save_Fortitude, D20STD_F_SPELL_DESCRIPTOR_COLD, spell.caster, spell.id): + spellTarget.obj.float_mesfile_line('mes\\spell.mes', 30001) + game.particles('Fizzle', spellTarget.obj) + spell.target_list.remove_target(spellTarget.obj) + else: + spellTarget.obj.float_mesfile_line('mes\\spell.mes', 30002) + spell.duration = 1 + if spellTarget.obj.condition_add_with_args("sp-Daze", spell.id, spell.duration, 0): + spellTarget.partsys_id = game.particles("sp-Daze", spellTarget.obj) + else: + spellTarget.obj.float_mesfile_line('mes\\spell.mes', 30007) + game.particles('Fizzle', spellTarget.obj) + spell.target_list.remove_target(spellTarget.obj) + + spell.spell_end(spell.id) + +def OnEndSpellCast(spell): + print "Orb of Fire OnEndSpellCast" + diff --git a/tpdatasrc/tpgamefiles/scr/Spell1200 - Orb of Sound.py b/tpdatasrc/tpgamefiles/scr/Spell1200 - Orb of Sound.py new file mode 100644 index 000000000..4ed9766f5 --- /dev/null +++ b/tpdatasrc/tpgamefiles/scr/Spell1200 - Orb of Sound.py @@ -0,0 +1,56 @@ +from toee import * + +def OnBeginSpellCast(spell): + print "Orb of Sound OnBeginSpellCast" + print "spell.target_list=", spell.target_list + print "spell.caster=", spell.caster, " caster.level= ", spell.caster_level + +def OnSpellEffect(spell): + print "Orb of Sound OnSpellEffect" + +def OnBeginRound(spell): + print "Orb of Sound OnBeginRound" + +def OnBeginProjectile(spell, projectile, index_of_target): + print "Orb of Sound OnBeginProjectile" + projectile.obj_set_int(obj_f_projectile_part_sys_id, game.particles("sp-Orb of Cold-proj", projectile)) + +def OnEndProjectile(spell, projectile, index_of_target): + print "Orb of Sound OnEndProjectile" + + spell.duration = 0 + spellTarget = spell.target_list[0] + spellDamageDice = dice_new('1d6') + spellDamageDice.number = min(spell.caster_level, 15) #capped at cl 15 (15d6) + damageType = D20DT_SONIC + spellDamageReduction = 100 #100 indicates full damage + + game.particles_end(projectile.obj_get_int(obj_f_projectile_part_sys_id)) + + attackResult = spell.caster.perform_touch_attack(spellTarget.obj) + + if attackResult & D20CAF_HIT: + game.particles("sp-Lesser Orb of Cold", spellTarget.obj) + spellTarget.obj.spell_damage_weaponlike(spell.caster, damageType, spellDamageDice, D20DAP_UNSPECIFIED, spellDamageReduction, D20A_CAST_SPELL, spell.id, attackResult, index_of_target) + #Save for secondary effect + if spellTarget.obj.saving_throw_spell(spell.dc, D20_Save_Fortitude, D20STD_F_SPELL_DESCRIPTOR_COLD, spell.caster, spell.id): + spellTarget.obj.float_mesfile_line('mes\\spell.mes', 30001) + game.particles('Fizzle', spellTarget.obj) + else: + spellTarget.obj.float_mesfile_line('mes\\spell.mes', 30002) + duration = 1 + #sp-Deafness is permanent currently, I'll add a helper condition to remove it after it should expire + #as there is no condition_remove in python + if spellTarget.obj.condition_add_with_args("sp-Deafness", spell.id, spell.duration, 0): + spellTarget.partsys_id = game.particles("sp-Blindness-Deafness", spellTarget.obj) + spellTarget.obj.condition_add_with_args("Remove Deafness Helper Condition", duration, 0) + else: + spellTarget.obj.float_mesfile_line('mes\\spell.mes', 30007) + game.particles('Fizzle', spellTarget.obj) + + spell.target_list.remove_target(spellTarget.obj) + spell.spell_end(spell.id) + +def OnEndSpellCast(spell): + print "Orb of Sound OnEndSpellCast" + diff --git a/tpdatasrc/tpgamefiles/scr/spell_utils.py b/tpdatasrc/tpgamefiles/scr/spell_utils.py index b494cb307..6e2fa46c0 100644 --- a/tpdatasrc/tpgamefiles/scr/spell_utils.py +++ b/tpdatasrc/tpgamefiles/scr/spell_utils.py @@ -1,4 +1,4 @@ -from templeplus.pymod import PythonModifier +from templeplus.pymod import PythonModifier, BasicPyMod from toee import * import tpdp from utilities import * @@ -232,6 +232,14 @@ def checkCategoryType(critter, *args): return True return False +# Target is a living creature +def isLivingCreature(critter): + if critter.is_category_type(mc_type_construct): + return False + elif critter.is_category_type(mc_type_undead): + return False + return True + ##### workaround getSpellClassCode ##### def getSpellClassCode(classEnum): dummySpellData = tpdp.D20SpellData() @@ -255,6 +263,100 @@ def performAttack(attacker, target, spellId, isRanged = True): game.create_history_from_id(attackAction.roll_id_0) return attackAction.flags +# Dispatch dispel magic effect +def getDispelFlag(spellEnum): + mappingDict = { + spell_dispel_magic: dispel_magic_single, + spell_greater_dispelling: dispel_magic_single, + spell_dispel_evil: dispel_evil, + spell_dispel_chaos: dispel_chaos, + spell_dispel_good: dispel_good, + spell_dispel_law: dispel_law, + spell_break_enchantment: dispel_break_enchantment, + spell_dispel_air: dispel_air, + spell_dispel_earth: dispel_earth, + spell_dispel_fire: dispel_fire, + spell_dispel_water: dispel_water, + spell_voracious_dispelling: dispel_voracious_single, + spell_relentless_dispelling: dispel_relentless, + spell_devour_magic: dispel_devour, + } + return mappingDict.get(spellEnum) + +def performDispelCheck(target, spellId, isAoe): + returnVal = 1 if isAoe else 0 + spellPacket = tpdp.SpellPacket(spellId) + spellEnum = spellPacket.spell_enum + dispelFlag = getDispelFlag(spellEnum) + if isAoe: + if dispelFlag & dispel_magic_single: + dispelFlag = dispel_magic_area + elif dispelFlag & dispel_voracious_single: + dispelFlag = dispel_voracious_area + dispelCheck = tpdp.EventObjDispelCheck() + dispelCheck.return_val = returnVal + dispelCheck.flags = dispelFlag + dispelCheck.spell_id = spellId + dispelCheck.dispatch(target) + return 0 + +# Add/Change weapon alignment +def modifyWeaponAlignment(attackPower, new_d20dap): + if attackPower & D20DAP_HOLY: + attackPower -= D20DAP_HOLY + if attackPower & D20DAP_UNHOLY: + attackPower -= D20DAP_UNHOLY + if attackPower & D20DAP_CHAOS: + attackPower -= D20DAP_CHAOS + if attackPower & D20DAP_LAW: + attackPower -= D20DAP_LAW + attackPower & new_d20dap + return 0 + +# Check if weapon is a melee weapon +def isMeleeWeapon(weapon): + weaponType = weapon.obj_get_int(obj_f_weapon_type) + return game.is_melee_weapon(weaponType) + +# Get list of spell targets +def getSpellTargets(spellPacket): + targetCount = spellPacket.target_count + targetList = [] + for idx in range(0, targetCount): + target = spellPacket.get_target(idx) + targetList.append(target) + return targetList + +# Map damageType to Descriptor constant +# Resist Elements and Endure Elements queries use the +# Descriptor const for their query in data1 +def getElementEnum(damageType): + mappingDict = { + D20DT_ACID: ACID, + D20DT_COLD: COLD, + D20DT_ELECTRICITY: ELECTRICITY, + D20DT_FIRE: FIRE, + D20DT_SONIC: SONIC + } + return mappingDict.get(damageType) + +def isDaylight(): + if game.is_outdoor() and game.is_daytime(): + return True + return False + +def dispelledByDaylight(attachee, args, evt_obj): + if isDaylight() and not attachee.d20_query_has_condition("sp-Dispel Light"): + spellId = args.get_arg(0) + name = spellName(spellId) + attachee.float_text_line("{} dispelled by daylight".format(name)) + args.remove_spell_mod() + args.remove_spell() + return 0 + +def getSpellEntry(spellId): + spellPacket = tpdp.SpellPacket(spellId) + return tpdp.SpellEntry(spellPacket.spell_enum) ### Item Condition functions @@ -540,6 +642,17 @@ def applyDamageReduction(attachee, args, evt_obj): evt_obj.damage_packet.add_physical_damage_res(drAmount, drBreakType, damageMesId) return 0 +def applyDamageResistance(attachee, args, evt_obj): + resistanceAmount = args.get_param(0) + if not resistanceAmount: + resistanceAmount = args.get_arg(2) + resistanceType = args.get_param(1) + if not resistanceType: + resistanceType = args.get_arg(3) + damageMesId = 124 # ID124 = ~Damage Resistance~[TAG_SPECIAL_ABILITIES_RESISTANCE_TO_ENERGY] + evt_obj.damage_packet.add_damage_resistance(bonusValue, resistanceType, damageMesId) + return 0 + def applySaveBonus(attachee, args, evt_obj): saveDescriptor = args.get_param(2) if saveDescriptor: @@ -563,60 +676,160 @@ def applyTempHp(attachee, args, evt_obj): attachee.condition_add_with_args("Temporary_Hit_Points", spellId, duration, tempHpAmount) return 0 -class SpellPythonModifier(PythonModifier): - #SpellPythonModifier have at least 3 arguments: - #spellId, duration, empty - #if a simple bonusValue is passed by the spell it is set to arg 3: - #spellId, duration, bonusValue, empty - def __init__(self, name, args = 3, preventDuplicate = False): - PythonModifier.__init__(self, name, args, preventDuplicate) - self.AddHook(ET_OnGetTooltip, EK_NONE, spellTooltip, ()) - self.AddHook(ET_OnGetEffectTooltip, EK_NONE, spellEffectTooltip, ()) - self.AddHook(ET_OnD20Query, EK_Q_Critter_Has_Spell_Active, queryActiveSpell, ()) - self.AddHook(ET_OnD20Signal, EK_S_Killed, spellKilled, ()) - self.AddSpellDispelCheckStandard() - self.AddSpellCountdownStandardHook() - self.AddSpellTeleportPrepareStandard() - self.AddSpellTeleportReconnectStandard() - def AddSpellConcentration(self): - self.AddHook(ET_OnConditionAdd, EK_NONE, addConcentration, ()) - self.AddHook(ET_OnD20Signal, EK_S_Concentration_Broken, checkRemoveSpell, ()) - def AddSpellDismiss(self): - self.AddHook(ET_OnConditionAdd, EK_NONE, addDismiss, ()) - self.AddHook(ET_OnD20Signal, EK_S_Dismiss_Spells, checkRemoveSpell, ()) +def getNeededSpellLevel(args): + #Valid param values: + #0: Any light/darkness spell level is suffice to dispel + #-1: Light/Darkness spell level needs to be at least spell level of darkness/light + #1-9: Light/Darkness spell level needs to be at least given spell level + neededLevel = args.get_param(0) + if neededLevel == -1: + spellId = args.get_arg(0) + spellPacket = tpdp.SpellPacket(spellId) + return spellPacket.spell_known_slot_level + elif neededLevel in range(0, 10): + return neededLevel + return 0 #Fallback if somehow a wrong spell level is given + +def dispelledByLight(attachee, args, evt_obj): + if evt_obj.is_modifier("sp-Dispel Darkness"): + neededLevel = getNeededSpellLevel(args) + dispelSpellId = evt_obj.arg1 + dispelName = spellName(dispelSpellId) + dispelSpellPacket = tpdp.SpellPacket(dispelSpellId) + dispelLevel = dispelSpellPacket.spell_known_slot_level + if dispelLevel >= neededLevel: + spellId = args.get_arg(0) + effectName = spellName(spellId) + attachee.float_text_line("{} dispelled by {}".format(effectName, dispelName)) + args.remove_spell() + args.remove_spell_mod() + return 0 + +def dispelledByDarkness(attachee, args, evt_obj): + if evt_obj.is_modifier("sp-Dispel Light"): + neededLevel = getNeededSpellLevel(args) + dispelSpellId = evt_obj.arg1 + dispelName = spellName(dispelSpellId) + dispelSpellPacket = tpdp.SpellPacket(dispelSpellId) + dispelLevel = dispelSpellPacket.spell_known_slot_level + if dispelLevel >= neededLevel: + effectSpellId = args.get_arg(0) + effectName = spellName(effectSpellId) + attachee.float_text_line("{} dispelled by {}".format(effectName, dispelName)) + args.remove_spell() + args.remove_spell_mod() + return 0 + +def dispelLight(attachee, args, evt_obj): + spellId = args.get_arg(0) + duration = args.get_arg(1) + attachee.condition_add_with_args("sp-Dispel Light", spellId, duration, 0) + return 0 + +def dispelDarkness(attachee, args, evt_obj): + spellId = args.get_arg(0) + duration = args.get_arg(1) + attachee.condition_add_with_args("sp-Dispel Darkness", spellId, duration, 0) + return 0 + +class SpellFunctions(BasicPyMod): def AddSpellNoDuplicate(self): - self.AddHook(ET_OnConditionAddPre, EK_NONE, replaceCondition, ()) + self.add_hook(ET_OnConditionAddPre, EK_NONE, replaceCondition, ()) def AddSkillBonus(self, bonusValue, bonusType, *args): if not args: eventKey = EK_NONE - self.AddHook(ET_OnGetSkillLevel, eventKey, applyBonus, (bonusValue, bonusType,)) + self.add_hook(ET_OnGetSkillLevel, eventKey, applyBonus, (bonusValue, bonusType,)) else: for skill in args: eventKey = skill + 20 - self.AddHook(ET_OnGetSkillLevel, eventKey, applyBonus, (bonusValue, bonusType,)) + self.add_hook(ET_OnGetSkillLevel, eventKey, applyBonus, (bonusValue, bonusType,)) def AddAbilityBonus(self, bonusValue, bonusType, *args): for abilityScore in args: eventKey = abilityScore + 1 - self.AddHook(ET_OnAbilityScoreLevel, eventKey, applyBonus,(bonusValue, bonusType,)) + self.add_hook(ET_OnAbilityScoreLevel, eventKey, applyBonus,(bonusValue, bonusType,)) def AddDamageReduction(self, drAmount, drBreakType): - self.AddHook(ET_OnTakingDamage2, EK_NONE, applyDamageReduction,(drAmount, drBreakType,)) + self.add_hook(ET_OnTakingDamage2, EK_NONE, applyDamageReduction,(drAmount, drBreakType,)) + def AddDamageResistance(self, resistanceAmount, resistanceType): + self.add_hook(ET_OnTakingDamage2, EK_NONE, applyDamageResistance, (resistanceAmount, resistanceType,)) def AddSaveBonus(self, bonusValue, bonusType, saveDescriptor = D20STD_F_NONE, eventKey = EK_NONE): - self.AddHook(ET_OnSaveThrowLevel, eventKey, applySaveBonus, (bonusValue, bonusType, saveDescriptor,)) + self.add_hook(ET_OnSaveThrowLevel, eventKey, applySaveBonus, (bonusValue, bonusType, saveDescriptor,)) def AddToHitBonus(self, bonusValue, bonusType, flagRequirement = 0): - self.AddHook(ET_OnToHitBonus2, EK_NONE, applyAttackPacketBonus,(bonusValue, bonusType, flagRequirement,)) + self.add_hook(ET_OnToHitBonus2, EK_NONE, applyAttackPacketBonus,(bonusValue, bonusType, flagRequirement,)) def AddAcBonus(self, bonusValue, bonusType): - self.AddHook(ET_OnGetAC, EK_NONE, applyBonus, (bonusValue, bonusType,)) + self.add_hook(ET_OnGetAC, EK_NONE, applyBonus, (bonusValue, bonusType,)) def AddAbilityCheckBonus(self, bonusValue, bonusType): #might get expanded - self.AddHook(ET_OnGetAbilityCheckModifier, EK_NONE, applyBonus, (bonusValue, bonusType,)) + self.add_hook(ET_OnGetAbilityCheckModifier, EK_NONE, applyBonus, (bonusValue, bonusType,)) def AddMovementBonus(self, bonusValue, bonusType): - self.AddHook(ET_OnGetMoveSpeedBase, EK_NONE, applyBonus, (bonusValue, bonusType,)) - def AddTempHp(self, tempHpAmount): - self.AddHook(ET_OnConditionAdd, EK_NONE, applyTempHp, (tempHpAmount,)) - self.AddHook(ET_OnD20Signal, EK_S_Temporary_Hit_Points_Removed, removeTempHp, ()) + self.add_hook(ET_OnGetMoveSpeedBase, EK_NONE, applyBonus, (bonusValue, bonusType,)) + def AddTempHp(self, tempHpAmount = 0): + self.add_hook(ET_OnConditionAdd, EK_NONE, applyTempHp, (tempHpAmount,)) + self.add_hook(ET_OnD20Signal, EK_S_Temporary_Hit_Points_Removed, removeTempHp, ()) + def AddLightInteraction(self, spellLevelInteraction = -1): + self.add_hook(ET_OnConditionAddPre, EK_NONE, dispelledByLight, (spellLevelInteraction,)) + self.add_hook(ET_OnConditionAdd, EK_NONE, dispelLight, ()) + self.add_hook(ET_OnD20Query, EK_Q_Critter_Has_Condition, querySpellCondition, ()) + def AddDarknessInteraction(self, spellLevelInteraction = -1): + self.add_hook(ET_OnConditionAddPre, EK_NONE, dispelledByDarkness, (spellLevelInteraction,)) + self.add_hook(ET_OnConditionAdd, EK_NONE, dispelDarkness, ()) + self.add_hook(ET_OnD20Query, EK_Q_Critter_Has_Condition, querySpellCondition, ()) + def AddDispelledByLight(self, spellLevelInteraction = -1): + self.add_hook(ET_OnBeginRound, EK_NONE, dispelledByDaylight, ()) + self.add_hook(ET_OnConditionAddPre, EK_NONE, dispelledByLight, (spellLevelInteraction,)) + def AddSpellConcentration(self): + self.add_hook(ET_OnConditionAdd, EK_NONE, addConcentration, ()) + self.add_hook(ET_OnD20Signal, EK_S_Concentration_Broken, checkRemoveSpell, ()) + def AddSpellDismiss(self): + self.add_hook(ET_OnConditionAdd, EK_NONE, addDismiss, ()) + self.add_hook(ET_OnD20Signal, EK_S_Dismiss_Spells, checkRemoveSpell, ()) + +class SpellBasicPyMod(SpellFunctions): + # SpellBasicPyMod have at least 3 arguments: + # spellId, duration, empty + # + # Use this class for spells, that either + # a) do not have a standard spell countdown + # b) can't be dispelled normally (like curses) + # c) do not use tooltips + # + # Standard spell class is below (SpellPythonModifer) + # + def __init__(self, name, args = 3, preventDuplicate = False): + super(SpellFunctions, self).__init__(name, args, preventDuplicate) + self.add_spell_teleport_prepare_standard() + self.add_spell_teleport_reconnect_standard() + self.add_hook(ET_OnD20Query, EK_Q_Critter_Has_Spell_Active, queryActiveSpell, ()) + self.add_hook(ET_OnD20Signal, EK_S_Killed, spellKilled, ()) + def AddSpellTooltips(self): + self.add_hook(ET_OnGetTooltip, EK_NONE, spellTooltip, ()) + self.add_hook(ET_OnGetEffectTooltip, EK_NONE, spellEffectTooltip, ()) + def AddSpellDispelCheck(self): + self.add_spell_dispel_check_standard() + def AddSpellCountdown(self): + self.add_spell_countdown_standard() + +class SpellPythonModifier(SpellFunctions): + #SpellPythonModifier have at least 3 arguments: + #spellId, duration, empty + #if a simple bonusValue is passed by the spell it is set to arg 3: + #spellId, duration, bonusValue, empty + # + #This is the standard spell condition class + # + def __init__(self, name, args = 3, preventDuplicate = False): + super(SpellFunctions, self).__init__(name, args, preventDuplicate) + self.add_hook(ET_OnGetTooltip, EK_NONE, spellTooltip, ()) + self.add_hook(ET_OnGetEffectTooltip, EK_NONE, spellEffectTooltip, ()) + self.add_spell_dispel_check_standard() + self.add_spell_countdown_standard() + self.add_spell_teleport_prepare_standard() + self.add_spell_teleport_reconnect_standard() + self.add_hook(ET_OnD20Query, EK_Q_Critter_Has_Spell_Active, queryActiveSpell, ()) + self.add_hook(ET_OnD20Signal, EK_S_Killed, spellKilled, ()) ### Aoe Modifier Classes ### def addAoeObjToSpellRegistry(attachee, args, evt_obj): - spellPacket = tpdp.SpellPacket(args.get_arg(0)) + spellId = args.get_arg(0) + spellPacket = tpdp.SpellPacket(spellId) conditionName = args.get_cond_name() particlesId = game.particles(conditionName, attachee) spellPacket.add_spell_object(attachee, particlesId) @@ -633,11 +846,18 @@ def verifyAoeEventTarget(args, spellTarget, spellPacket): return False elif affectedTargets == aoe_event_target_non_friendly and spellTarget.is_friendly(spellCaster): return False - #elif spellTarget == attachee: - # return 0 + elif affectedTargets == aoe_event_target_non_friendly and spellTarget == spellPacket.caster: + return False + elif affectedTargets == aoe_event_target_all_exclude_self and spellTarget == spellPacket.caster: + return False + elif affectedTargets == aoe_event_target_friendly_exlude_self and spellTarget == spellPacket.caster: + return False + elif affectedTargets == aoe_event_target_living_creatures and not isLivingCreature(spellTarget): + return False + elif affectedTargets == aoe_event_target_living_creatures_exclude_self and spellTarget == spellPacket.caster: + return False elif spellPacket.check_spell_resistance(spellTarget): return False - return True def verifyEventId(spellEventId, aoeEventId): @@ -646,12 +866,12 @@ def verifyEventId(spellEventId, aoeEventId): return True def aoeOnEnter(attachee, args, evt_obj): - print "aoeOnEnter Hook" spellTarget = evt_obj.target spellId = args.get_arg(0) duration = args.get_arg(1) - spellDc = args.get_arg(2) + bonusValue = args.get_arg(2) spellEventId = args.get_arg(3) + spellDc = args.get_arg(4) spellPacket = tpdp.SpellPacket(spellId) aoeEventId = evt_obj.evt_id @@ -664,23 +884,21 @@ def aoeOnEnter(attachee, args, evt_obj): particlesId = game.particles("{}-hit".format(conditionName), spellTarget) if spellPacket.add_target(spellTarget, particlesId): conditionEffectName = spellName(spellId) - spellTarget.condition_add_with_args(conditionEffectName, spellId, duration + 1, spellDc, spellEventId) + spellTarget.condition_add_with_args(conditionEffectName, spellId, duration + 1, bonusValue, spellEventId, spellDc, 0) spellPacket.update_registry() return 0 def aoeHandleEndSignal(attachee, args, evt_obj): spellId = args.get_arg(0) - if evt_obj.data1 == spellId: + signalId = evt_obj.data1 + if spellId == signalId: spellPacket = tpdp.SpellPacket(spellId) #spellMesId = 20000 # ID 20000 = A spell has expired. - if spellPacket.spell_enum == 0: - return 0 - spellTargetCount = 0 - while spellTargetCount < spellPacket.target_count: - spellTarget = spellPacket.get_target(spellTargetCount) + if spellPacket.spell_enum != 0: + for idx in range(0, spellPacket.target_count): + spellTarget = spellPacket.get_target(idx) spellTarget.d20_send_signal(S_Spell_End, spellId) - #spellTarget.float_mesfile_line('mes\\spell.mes', spellMesId) - spellTargetCount += 1 + #spellTarget.float_mesfile_line("mes\\spell.mes", spellMesId) return 0 def aoeCombatEndSignal(attachee, args, evt_obj): @@ -709,51 +927,153 @@ def aoeSpellEndSignal(attachee, args, evt_obj): args.remove_spell_mod() return 0 -class AoeObjHandleModifier(PythonModifier): - #AoeObjHandleModifier have at least 5 arguments: - #spellId, duration, spellDc, spellEventId, empty +class AoeObjHandleModifier(SpellFunctions): + #AoeObjHandleModifier have at least 6 arguments: + #spellId, duration, bonusValue, spellEventId, spellDc, empty + # #Use this class only, if you have a special onEnterAoE Event #Standard Cases use class below (AoeSpellHandleModifier) - def __init__(self, name, args = 5, preventDuplicate = False): - PythonModifier.__init__(self, name, args, preventDuplicate) - self.AddHook(ET_OnConditionAdd, EK_NONE, addAoeObjToSpellRegistry, ()) - self.AddHook(ET_OnD20Query, EK_Q_Critter_Has_Spell_Active, queryActiveSpell, ()) - self.AddHook(ET_OnD20Signal, EK_S_Combat_End, aoeCombatEndSignal, ()) - self.AddSpellDispelCheckStandard() - self.AddSpellTeleportPrepareStandard() - self.AddSpellTeleportReconnectStandard() - self.AddSpellCountdownStandardHook() - self.AddAoESpellEndStandardHook() + # + def __init__(self, name, args = 6, preventDuplicate = False): + super(SpellFunctions, self).__init__(name, args, preventDuplicate) + self.add_hook(ET_OnD20Signal, EK_S_Combat_End, aoeCombatEndSignal, ()) + self.add_hook(ET_OnD20Query, EK_Q_Critter_Has_Spell_Active, queryActiveSpell, ()) + self.add_hook(ET_OnConditionAdd, EK_NONE, addAoeObjToSpellRegistry, ()) + self.add_spell_teleport_prepare_standard() + self.add_spell_teleport_reconnect_standard() + self.add_aoe_spell_ender() + self.add_spell_dispel_check_standard() + self.add_spell_countdown_standard() + +class AoeSpellHandleModifier(SpellFunctions): + #AoeSpellHandleModifier have at least 6 arguments: + #spellId, duration, bonusValue, spellEventId, spellDc, empty + # + #Standard Class for AoE Handle Spells + # + def __init__(self, name, affectedTargets = aoe_event_target_all, args = 6, preventDuplicate = False): + super(SpellFunctions, self).__init__(name, args, preventDuplicate) + self.add_hook(ET_OnConditionAdd, EK_NONE, addAoeObjToSpellRegistry, ()) + self.add_hook(ET_OnObjectEvent, EK_OnEnterAoE, aoeOnEnter, (affectedTargets,)) + self.add_hook(ET_OnD20Signal, EK_S_Combat_End, aoeCombatEndSignal, ()) + self.add_hook(ET_OnD20Query, EK_Q_Critter_Has_Spell_Active, queryActiveSpell, ()) + self.add_spell_teleport_prepare_standard() + self.add_spell_teleport_reconnect_standard() + self.add_aoe_spell_ender() + self.add_spell_dispel_check_standard() + self.add_spell_countdown_standard() + +def aoeTooltip(attachee, args, evt_obj): + conditionName = args.get_cond_name() + conditionDuration = spellTime(args.get_arg(1)) + evt_obj.append("{} ({})".format(conditionName, conditionDuration)) + return 0 + +def aoeEffectTooltip(attachee, args, evt_obj): + conditionName = args.get_cond_name().upper().replace(" ", "_") + conditionDuration = spellTime(args.get_arg(1)) + conditionKey = tpdp.hash(conditionName) + evt_obj.append(conditionKey, -2, " ({})".format(conditionDuration)) + return 0 + +def applyFogConcealment(attachee, args, evt_obj): + attacker = evt_obj.attack_packet.attacker + bonusValue = 50 if attacker.distance_to(attachee) > 5.0 else 20 + bonusType = bonus_type_concealment + bonusTag = game.get_mesline("mes\\bonus_description.mes", bonusType) + spellId = args.get_arg(0) + spellHelpTag = getSpellHelpTag(spellId) + evt_obj.bonus_list.add(bonusValue, bonusType, "{} : {}".format(bonusTag, spellHelpTag)) + return 0 + +class AoeSpellEffectModifier(SpellFunctions): + #AoeSpellEffectModifier have at least 6 arguments: + #spellId, duration, bonusValue, spellEventId, spellDc, empty + def __init__(self, name, args = 6, preventDuplicate = True): + super(SpellFunctions, self).__init__(name, args, preventDuplicate) + self.add_hook(ET_OnObjectEvent, EK_OnLeaveAoE, aoeOnLeave, ()) + self.add_hook(ET_OnGetTooltip, EK_NONE, aoeTooltip, ()) + self.add_hook(ET_OnGetEffectTooltip, EK_NONE, aoeEffectTooltip, ()) + self.add_hook(ET_OnD20Query, EK_Q_Critter_Has_Condition, querySpellCondition, ()) + self.add_hook(ET_OnD20Signal, EK_S_Spell_End, aoeSpellEndSignal, ()) + self.add_hook(ET_OnD20Signal, EK_S_Combat_End, aoeCombatEndSignal, ()) + self.add_hook(ET_OnD20Query, EK_Q_Critter_Has_Spell_Active, queryActiveSpell, ()) + self.add_hook(ET_OnD20Signal, EK_S_Killed, spellKilled, ()) + self.add_spell_countdown_standard() + self.add_spell_teleport_prepare_standard() + self.add_spell_teleport_reconnect_standard() + def AddFogConcealment(self): + self.add_hook(ET_OnGetDefenderConcealmentMissChance, EK_NONE, applyFogConcealment, ()) def AddSpellConcentration(self): - self.AddHook(ET_OnConditionAdd, EK_NONE, addConcentration, ()) - self.AddHook(ET_OnD20Signal, EK_S_Concentration_Broken, aoeHandleEndSignal, ()) + self.add_hook(ET_OnD20Signal, EK_S_Concentration_Broken, checkRemoveSpell, ()) def AddSpellDismiss(self): - self.AddHook(ET_OnConditionAdd, EK_NONE, addDismiss, ()) - self.AddHook(ET_OnD20Signal, EK_S_Dismiss_Spells, aoeHandleEndSignal, ()) - def AddSpellNoDuplicate(self): - self.AddHook(ET_OnConditionAddPre, EK_NONE, replaceCondition, ()) - -class AoeSpellHandleModifier(AoeObjHandleModifier): - #AoeSpellHandlerModifier have at least 5 arguments: - #spellId, duration, spellDc, spellEventId, empty - def __init__(self, name, affectedTargets = aoe_event_target_all, args = 5, preventDuplicate = False): - super(AoeSpellHandleModifier, self).__init__(name, args, preventDuplicate) - self.AddHook(ET_OnObjectEvent, EK_OnEnterAoE, aoeOnEnter, (affectedTargets,)) - -class AoESpellEffectModifier(PythonModifier): - #AoESpellEffectPythonModifier have at least 5 arguments: - #spellId, duration, spellDc, spellEventId, empty - def __init__(self, name, args = 5, preventDuplicate = True): - PythonModifier.__init__(self, name, args, preventDuplicate) - self.AddHook(ET_OnObjectEvent, EK_OnLeaveAoE, aoeOnLeave, ()) - self.AddHook(ET_OnD20Query, EK_Q_Critter_Has_Spell_Active, queryActiveSpell, ()) - self.AddHook(ET_OnD20Query, EK_Q_Critter_Has_Condition, querySpellCondition, ()) - self.AddHook(ET_OnGetTooltip, EK_NONE, spellTooltip, ()) - self.AddHook(ET_OnGetEffectTooltip, EK_NONE, spellEffectTooltip, ()) - self.AddHook(ET_OnD20Signal, EK_S_Spell_End, aoeSpellEndSignal, ()) - self.AddHook(ET_OnD20Signal, EK_S_Combat_End, aoeCombatEndSignal, ()) - self.AddHook(ET_OnD20Signal, EK_S_Killed, spellKilled, ()) - self.AddSpellCountdownStandardHook() - self.AddSpellDispellCheckHook() - self.AddSpellTeleportPrepareStandard() - self.AddSpellTeleportReconnectStandard() + self.add_hook(ET_OnD20Signal, EK_S_Dismiss_Spells, checkRemoveSpell, ()) + + +##### Begin Aura Classes ###### +### Aura Class Spells are spells that are centered ### +### On the caster and travel with the caster ### + +def setAuraObjToSpellRegistry(attachee, args, evt_obj): + spellId = args.get_arg(0) + spellPacket = tpdp.SpellPacket(spellId) + conditionName = args.get_cond_name() + particlesId = game.particles(conditionName, attachee) + idx = 0 + spellPacket.set_spell_object(idx, attachee, particlesId) + spellPacket.update_registry() + return 0 + +def auraTooltip(attachee, args, evt_obj): + spellId = args.get_arg(0) + conditionName = spellName(spellId) + conditionDuration = spellTime(args.get_arg(1)) + evt_obj.append("{} Aura ({})".format(conditionName, conditionDuration)) + return 0 + +def auraEffectTooltip(attachee, args, evt_obj): + spellId = args.get_arg(0) + conditionName = "{}_AURA".format(spellKeyName(spellId)) + conditionDuration = spellTime(args.get_arg(1)) + conditionKey = tpdp.hash(conditionName) + evt_obj.append(conditionKey, -2, " ({})".format(conditionDuration)) + return 0 + +class AuraSpellHandleModifier(SpellFunctions): + #AuraSpellHandleModifier have at least 6 arguments: + #spellId, duration, bonusValue, spellEventId, spellDc, empty + # + #Class for AoE spells that are "aura" spells (spells centered on caster and move with the caster) + # + def __init__(self, name, affectedTargets = aoe_event_target_friendly, args = 6, preventDuplicate = False): + super(SpellFunctions, self).__init__(name, args, preventDuplicate) + self.add_hook(ET_OnConditionAdd, EK_NONE, setAuraObjToSpellRegistry, ()) + self.add_hook(ET_OnGetTooltip, EK_NONE, auraTooltip, ()) + self.add_hook(ET_OnGetEffectTooltip, EK_NONE, auraEffectTooltip, ()) + self.add_hook(ET_OnObjectEvent, EK_OnEnterAoE, aoeOnEnter, (affectedTargets,)) + self.add_hook(ET_OnD20Query, EK_Q_Critter_Has_Spell_Active, queryActiveSpell, ()) + self.add_spell_teleport_prepare_standard() + self.add_spell_teleport_reconnect_standard() + self.add_aoe_spell_ender() + self.add_spell_dispel_check_standard() + self.add_spell_countdown_standard() + +class AuraSpellEffectModifier(SpellFunctions): + #AuraSpellEffectModifier have at least 6 arguments: + #spellId, duration, bonusValue, spellEventId, spellDc, empty + def __init__(self, name, args = 6, preventDuplicate = True): + super(SpellFunctions, self).__init__(name, args, preventDuplicate) + self.add_hook(ET_OnObjectEvent, EK_OnLeaveAoE, aoeOnLeave, ()) + self.add_hook(ET_OnGetTooltip, EK_NONE, aoeTooltip, ()) + self.add_hook(ET_OnGetEffectTooltip, EK_NONE, aoeEffectTooltip, ()) + self.add_hook(ET_OnD20Query, EK_Q_Critter_Has_Condition, querySpellCondition, ()) + self.add_hook(ET_OnD20Signal, EK_S_Spell_End, aoeSpellEndSignal, ()) + self.add_hook(ET_OnD20Query, EK_Q_Critter_Has_Spell_Active, queryActiveSpell, ()) + self.add_hook(ET_OnD20Signal, EK_S_Killed, spellKilled, ()) + self.add_spell_countdown_standard() + self.add_spell_teleport_prepare_standard() + self.add_spell_teleport_reconnect_standard() + def AddSpellConcentration(self): + self.add_hook(ET_OnD20Signal, EK_S_Concentration_Broken, checkRemoveSpell, ()) + def AddSpellDismiss(self): + self.add_hook(ET_OnD20Signal, EK_S_Dismiss_Spells, checkRemoveSpell, ()) diff --git a/tpdatasrc/tpgamefiles/scr/tpModifiers/sp_accuracy.py b/tpdatasrc/tpgamefiles/scr/tpModifiers/sp_accuracy.py new file mode 100644 index 000000000..a347a2c34 --- /dev/null +++ b/tpdatasrc/tpgamefiles/scr/tpModifiers/sp_accuracy.py @@ -0,0 +1,13 @@ +from toee import * +import tpdp +from spell_utils import SpellPythonModifier + +print "Registering sp-Accuracy" + +def doubleIncrement(attachee, args, evt_obj): + weaponUsed = evt_obj.weapon_used + evt_obj.range_bonus += weaponUsed.obj_get_int(obj_f_weapon_range) + return 0 + +accuracySpell = SpellPythonModifier("sp-Accuracy") # spellId, duration, empty +accuracySpell.AddHook(ET_OnRangeIncrementBonus, EK_NONE, doubleIncrement,()) diff --git a/tpdatasrc/tpgamefiles/scr/tpModifiers/sp_blades_of_fire.py b/tpdatasrc/tpgamefiles/scr/tpModifiers/sp_blades_of_fire.py new file mode 100644 index 000000000..ff0e32596 --- /dev/null +++ b/tpdatasrc/tpgamefiles/scr/tpModifiers/sp_blades_of_fire.py @@ -0,0 +1,67 @@ +from templeplus.pymod import PythonModifier +from toee import * +import tpdp +from utilities import * +import spell_utils +print "Registering sp-Blades of Fire" + +def bladesOfFireSpellAddWeaponCondition(attachee, args, evt_obj): + spellId = args.get_arg(0) + spellPacket = tpdp.SpellPacket(spellId) + spellPacket.add_target(attachee, 0) + attachee.item_condition_add_with_args('Weapon Blades of Fire', 0, 0, 0, 0, spellId) + attachee.item_condition_add_with_args('Weapon Blades of Fire Tooltip', 0, 0, 0, 0, spellId) + return 0 + +def bladesOfFireSpellDurationQuery(attachee, args, evt_obj): + if args.get_arg(0) == evt_obj.data1: + evt_obj.return_val = args.get_arg(1) + else: + evt_obj.return_val = 0 + return 0 + +def bladesOfFireSpellWeaponConditionRemove(attachee, args, evt_obj): + attachee.item_condition_remove('Weapon Blades of Fire', args.get_arg(0)) + attachee.item_condition_remove('Weapon Blades of Fire Tooltip', args.get_arg(0)) + return 0 + +bladesOfFireSpell = PythonModifier("sp-Blades of Fire", 3) # spell_id, duration, empty +bladesOfFireSpell.AddHook(ET_OnConditionAdd, EK_NONE, bladesOfFireSpellAddWeaponCondition,()) +bladesOfFireSpell.AddHook(ET_OnD20PythonQuery, "PQ_Item_Buff_Duration", bladesOfFireSpellDurationQuery, ()) +bladesOfFireSpell.AddHook(ET_OnConditionRemove, EK_NONE, bladesOfFireSpellWeaponConditionRemove, ()) +bladesOfFireSpell.AddHook(ET_OnD20Query, EK_Q_Critter_Has_Spell_Active, spell_utils.queryActiveSpell, ()) +bladesOfFireSpell.AddHook(ET_OnD20Signal, EK_S_Killed, spell_utils.spellKilled, ()) +bladesOfFireSpell.AddSpellDispelCheckStandard() +bladesOfFireSpell.AddSpellTeleportPrepareStandard() +bladesOfFireSpell.AddSpellTeleportReconnectStandard() +bladesOfFireSpell.AddSpellCountdownStandardHook() + +#### Weapon Blades of Fire Condition #### + +def weaponBladesOfFireOnDealingDamage(attachee, args, evt_obj): + usedWeapon = evt_obj.attack_packet.get_weapon_used() + if spell_utils.verifyItem(usedWeapon, args): + #Blades of Fire Bonus Damage; Originally it was 1d6 in Complete Arcane but was raised to 1d8 in the Spell Compendium + damageDice = dice_new('1d8') + damageType = D20DT_FIRE + damageMesId = 3010 #ID 3010 added in damage.mes + evt_obj.damage_packet.add_dice(damageDice, damageType, damageMesId) + return 0 + +def weaponBladesOfFireGlowType(attachee, args, evt_obj): + usedWeapon = evt_obj.get_obj_from_args() + if spell_utils.verifyItem(usedWeapon, args): + if not evt_obj.return_val: + evt_obj.return_val = 6 #Fire Glow + return 0 + +weaponBladesOfFire = PythonModifier("Weapon Blades of Fire", 5) # empty, empty, inventoryLocation, empty, spell_id +weaponBladesOfFire.AddHook(ET_OnDealingDamage, EK_NONE, weaponBladesOfFireOnDealingDamage, ()) +weaponBladesOfFire.AddHook(ET_OnWeaponGlowType, EK_NONE, weaponBladesOfFireGlowType, ()) + + +#### Weapon Blades of Fire Tooltip Condition #### + +weaponBladesOfFireToolTip = PythonModifier("Weapon Blades of Fire Tooltip", 5) # empty, empty, inventoryLocation, empty, spellId +weaponBladesOfFireToolTip.AddHook(ET_OnGetTooltip, EK_NONE, spell_utils.itemTooltip, ()) +weaponBladesOfFireToolTip.AddHook(ET_OnGetEffectTooltip, EK_NONE, spell_utils.itemEffectTooltip, ()) diff --git a/tpdatasrc/tpgamefiles/sound/user_sounds/spell_compendium_sounds.mes b/tpdatasrc/tpgamefiles/sound/user_sounds/spell_compendium_sounds.mes index 2e4352a42..d8a3a7a5e 100644 --- a/tpdatasrc/tpgamefiles/sound/user_sounds/spell_compendium_sounds.mes +++ b/tpdatasrc/tpgamefiles/sound/user_sounds/spell_compendium_sounds.mes @@ -758,7 +758,7 @@ {28327}{} // spell hit {28328}{} // spell struck -// [1117] *[] +// [1117] *[Rhino's Rush] {28340}{} // spell begin {28341}{} // spell end {28342}{} // spell effect @@ -1450,3 +1450,180 @@ {26106}{} // spell projectile in-flight {26107}{} // spell hit {26108}{} // spell struck + +// [1182] *[Accuracy] +{29640}{} // spell begin +{29641}{} // spell end +{29642}{} // spell effect +{29643}{} // spell new round +{29644}{} // spell projectile begin +{29645}{} // spell projectile end +{29646}{} // spell projectile in-flight +{29647}{} // spell hit +{29648}{} // spell struck + +// [1183] *[Hail of Stone] +{29660}{} // spell begin +{29661}{} // spell end +{29662}{} // spell effect +{29663}{} // spell new round +{29664}{} // spell projectile begin +{29665}{} // spell projectile end +{29666}{} // spell projectile in-flight +{29667}{} // spell hit +{29668}{} // spell struck + +// [1184] *[Lesser Orb of Acid] +{29680}{} // spell begin +{29681}{} // spell end +{29682}{} // spell effect +{29683}{} // spell new round +{29684}{} // spell projectile begin +{29685}{} // spell projectile end +{29686}{} // spell projectile in-flight +{29687}{} // spell hit +{29688}{} // spell struck + +// [1185] *[Lesser Orb of Cold] +{29700}{} // spell begin +{29701}{} // spell end +{29702}{} // spell effect +{29703}{} // spell new round +{29704}{} // spell projectile begin +{29705}{} // spell projectile end +{29706}{} // spell projectile in-flight +{29707}{} // spell hit +{29708}{} // spell struck + +// [1186] *[Lesser Orb of Electricity] +{29720}{} // spell begin +{29721}{} // spell end +{29722}{} // spell effect +{29723}{} // spell new round +{29724}{} // spell projectile begin +{29725}{} // spell projectile end +{29726}{} // spell projectile in-flight +{29727}{} // spell hit +{29728}{} // spell struck + +// [1187] *[Lesser Orb of Fire] +{29740}{} // spell begin +{29741}{} // spell end +{29742}{} // spell effect +{29743}{} // spell new round +{29744}{} // spell projectile begin +{29745}{} // spell projectile end +{29746}{} // spell projectile in-flight +{29747}{} // spell hit +{29748}{} // spell struck + +// [1188] *[Lesser Orb of Sound] +{29760}{} // spell begin +{29761}{} // spell end +{29762}{} // spell effect +{29763}{} // spell new round +{29764}{} // spell projectile begin +{29765}{} // spell projectile end +{29766}{} // spell projectile in-flight +{29767}{} // spell hit +{29768}{} // spell struck + +// [1189] *[Blades of Fire] +{29780}{} // spell begin +{29781}{} // spell end +{29782}{} // spell effect +{29783}{} // spell new round +{29784}{} // spell projectile begin +{29785}{} // spell projectile end +{29786}{} // spell projectile in-flight +{29787}{} // spell hit +{29788}{} // spell struck + +// [1190] *[Fireburst] +{29800}{} // spell begin +{29801}{} // spell end +{29802}{} // spell effect +{29803}{} // spell new round +{29804}{} // spell projectile begin +{29805}{} // spell projectile end +{29806}{} // spell projectile in-flight +{29807}{} // spell hit +{29808}{} // spell struck + +// [1191] *[Greater Fireburst] +{29820}{} // spell begin +{29821}{} // spell end +{29822}{spells\sp_burningHands.wav} // spell effect +{29823}{} // spell new round +{29824}{} // spell projectile begin +{29825}{} // spell projectile end +{29826}{} // spell projectile in-flight +{29827}{} // spell hit +{29828}{} // spell struck + +// [1195] *[Blast of Flame] +{29900}{} // spell begin +{29901}{} // spell end +{29902}{spells\sp_burningHands.wav} // spell effect +{29903}{} // spell new round +{29904}{} // spell projectile begin +{29905}{} // spell projectile end +{29906}{} // spell projectile in-flight +{29907}{} // spell hit +{29908}{} // spell struck + +// [1196] *[Orb of Acid] +{29920}{} // spell begin +{29921}{} // spell end +{29922}{spells\sp_acid_splash.WAV} // spell effect +{29923}{} // spell new round +{29924}{} // spell projectile begin +{29925}{} // spell projectile end +{29926}{} // spell projectile in-flight +{29927}{} // spell hit +{29928}{} // spell struck + +// [1197] *[Orb of Cold] +{29940}{} // spell begin +{29941}{} // spell end +{29942}{spells\sp_ray_of_frost.wav} // spell effect +{29943}{} // spell new round +{29944}{} // spell projectile begin +{29945}{} // spell projectile end +{29946}{} // spell projectile in-flight +{29947}{} // spell hit +{29948}{} // spell struck + +// [1198] *[Orb of Electricity] +{29960}{} // spell begin +{29961}{} // spell end +{29962}{spells\sp_shocking_grasp.wav} // spell effect +{29963}{} // spell new round +{29964}{} // spell projectile begin +{29965}{} // spell projectile end +{29966}{} // spell projectile in-flight +{29967}{} // spell hit +{29968}{} // spell struck + +// [1199] *[Orb of Fire] +{29980}{} // spell begin +{29981}{} // spell end +{29982}{spells\sp_Produce_flame.wav} // spell effect +{29983}{} // spell new round +{29984}{} // spell projectile begin +{29985}{} // spell projectile end +{29986}{} // spell projectile in-flight +{29987}{} // spell hit +{29988}{} // spell struck + +// [1200] *[Orb of Sound] +{30000}{} // spell begin +{30001}{} // spell end +{30002}{spells\sp_shout.wav} // spell effect +{30003}{} // spell new round +{30004}{} // spell projectile begin +{30005}{} // spell projectile end +{30006}{} // spell projectile in-flight +{30007}{} // spell hit +{30008}{} // spell struck + From 306eccfbb3ff4103b7ce6261b41038e0d40b99cd Mon Sep 17 00:00:00 2001 From: doug1234 Date: Sun, 7 Jan 2024 16:39:58 -0500 Subject: [PATCH 02/12] Added sounds. --- .../user_sounds/spell_compendium_sounds.mes | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tpdatasrc/tpgamefiles/sound/user_sounds/spell_compendium_sounds.mes b/tpdatasrc/tpgamefiles/sound/user_sounds/spell_compendium_sounds.mes index d8a3a7a5e..5d0ef49fb 100644 --- a/tpdatasrc/tpgamefiles/sound/user_sounds/spell_compendium_sounds.mes +++ b/tpdatasrc/tpgamefiles/sound/user_sounds/spell_compendium_sounds.mes @@ -1454,7 +1454,7 @@ // [1182] *[Accuracy] {29640}{} // spell begin {29641}{} // spell end -{29642}{} // spell effect +{29642}{spells\sp_true_strike.wav} // spell effect {29643}{} // spell new round {29644}{} // spell projectile begin {29645}{} // spell projectile end @@ -1465,7 +1465,7 @@ // [1183] *[Hail of Stone] {29660}{} // spell begin {29661}{} // spell end -{29662}{} // spell effect +{29662}{spells\sp_quench.wav} // spell effect {29663}{} // spell new round {29664}{} // spell projectile begin {29665}{} // spell projectile end @@ -1476,7 +1476,7 @@ // [1184] *[Lesser Orb of Acid] {29680}{} // spell begin {29681}{} // spell end -{29682}{} // spell effect +{29682}{spells\sp_acid_splash.WAV} // spell effect {29683}{} // spell new round {29684}{} // spell projectile begin {29685}{} // spell projectile end @@ -1487,7 +1487,7 @@ // [1185] *[Lesser Orb of Cold] {29700}{} // spell begin {29701}{} // spell end -{29702}{} // spell effect +{29702}{spells\sp_ray_of_frost.wav} // spell effect {29703}{} // spell new round {29704}{} // spell projectile begin {29705}{} // spell projectile end @@ -1498,7 +1498,7 @@ // [1186] *[Lesser Orb of Electricity] {29720}{} // spell begin {29721}{} // spell end -{29722}{} // spell effect +{29722}{spells\sp_shocking_grasp.wav} // spell effect {29723}{} // spell new round {29724}{} // spell projectile begin {29725}{} // spell projectile end @@ -1509,7 +1509,7 @@ // [1187] *[Lesser Orb of Fire] {29740}{} // spell begin {29741}{} // spell end -{29742}{} // spell effect +{29742}{spells\sp_Produce_flame.wav} // spell effect {29743}{} // spell new round {29744}{} // spell projectile begin {29745}{} // spell projectile end @@ -1520,7 +1520,7 @@ // [1188] *[Lesser Orb of Sound] {29760}{} // spell begin {29761}{} // spell end -{29762}{} // spell effect +{29762}{spells\sp_shout.wav} // spell effect {29763}{} // spell new round {29764}{} // spell projectile begin {29765}{} // spell projectile end @@ -1530,8 +1530,8 @@ // [1189] *[Blades of Fire] {29780}{} // spell begin -{29781}{} // spell end -{29782}{} // spell effect +{29781}{spells\sp_flame_blade_end.WAV} // spell end +{29782}{spells\sp_flame_blade.wav} // spell effect {29783}{} // spell new round {29784}{} // spell projectile begin {29785}{} // spell projectile end @@ -1542,7 +1542,7 @@ // [1190] *[Fireburst] {29800}{} // spell begin {29801}{} // spell end -{29802}{} // spell effect +{29802}{spells\sp_burningHands.wav} // spell effect {29803}{} // spell new round {29804}{} // spell projectile begin {29805}{} // spell projectile end From 96806174597fb7f566dfe03237592ce796bc4b31 Mon Sep 17 00:00:00 2001 From: doug1234 Date: Sat, 13 Jan 2024 10:31:58 -0500 Subject: [PATCH 03/12] Added icons for accuracy and blades of fire. Changed blade of fire to set icon to duration 1 instead of zero. Added sure strike particles for the accuracy spell which uses them. --- .../Player_Conditions/Buffs/Accuracy.tga | Bin 0 -> 1563 bytes .../Player_Conditions/Buffs/Blades of Fire.tga | Bin 0 -> 1563 bytes .../art/meshes/Particle/bullseye.mdf | 3 +++ .../art/meshes/Particle/bullseye.tga | Bin 0 -> 65554 bytes .../tpgamefiles/rules/indicators/accuracy.txt | 2 +- .../rules/indicators/blades_of_fire.txt | 2 +- .../rules/partsys/spell_compendium_partsys.tab | 1 + .../scr/Spell1189 - Blades of Fire.py | 4 ++-- 8 files changed, 8 insertions(+), 4 deletions(-) create mode 100644 tpdatasrc/tpgamefiles/art/interface/Player_Conditions/Buffs/Accuracy.tga create mode 100644 tpdatasrc/tpgamefiles/art/interface/Player_Conditions/Buffs/Blades of Fire.tga create mode 100644 tpdatasrc/tpgamefiles/art/meshes/Particle/bullseye.mdf create mode 100644 tpdatasrc/tpgamefiles/art/meshes/Particle/bullseye.tga diff --git a/tpdatasrc/tpgamefiles/art/interface/Player_Conditions/Buffs/Accuracy.tga b/tpdatasrc/tpgamefiles/art/interface/Player_Conditions/Buffs/Accuracy.tga new file mode 100644 index 0000000000000000000000000000000000000000..d6e4a642576baa87aedb5aa3f8f0064febd61c4b GIT binary patch literal 1563 zcmZQzU}As)0R{mE1&;s!|1(gEfhPXX%*_1%KN4sZ2v331KsHDmB#+Mys_A#_SBnn99&P}srD0MX=zA55^ zL1JcJiC$i6iGqoqk)A0&?Ft}CMkqv9$SlMH;f4f-x`ufMd;0t7M!0$Uxau(g0RL8? AL;wH) literal 0 HcmV?d00001 diff --git a/tpdatasrc/tpgamefiles/art/interface/Player_Conditions/Buffs/Blades of Fire.tga b/tpdatasrc/tpgamefiles/art/interface/Player_Conditions/Buffs/Blades of Fire.tga new file mode 100644 index 0000000000000000000000000000000000000000..6eb39dd6225da247e17a7577f62180ef766cb02b GIT binary patch literal 1563 zcmZQzU}As)0R{mE1&;s!|1(gEfhPXX%*_06VPOHrdiks2Y>+re9-kf5(r?aC|9{!C zWpE7QlWIRmkBG$o{~#LVpP{B7*f2R_X_!7z>_s=5620hV(VG9B5$M`cK(7#BWMF4_!7k3g!N5nVl?92Jc_n&z tsU->~dPaJt__Qm4BpIO)Ss}9!3xpdI6zUr08SLrrryJqs>Eo)$003LfhT{ML literal 0 HcmV?d00001 diff --git a/tpdatasrc/tpgamefiles/art/meshes/Particle/bullseye.mdf b/tpdatasrc/tpgamefiles/art/meshes/Particle/bullseye.mdf new file mode 100644 index 000000000..6f9e64904 --- /dev/null +++ b/tpdatasrc/tpgamefiles/art/meshes/Particle/bullseye.mdf @@ -0,0 +1,3 @@ +Textured +Texture "art/meshes/particle/bullseye.tga" +Color 255 255 255 255 diff --git a/tpdatasrc/tpgamefiles/art/meshes/Particle/bullseye.tga b/tpdatasrc/tpgamefiles/art/meshes/Particle/bullseye.tga new file mode 100644 index 0000000000000000000000000000000000000000..d9c724891eefc388f7a9920e47d9a27670771490 GIT binary patch literal 65554 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 literal 0 HcmV?d00001 diff --git a/tpdatasrc/tpgamefiles/rules/indicators/accuracy.txt b/tpdatasrc/tpgamefiles/rules/indicators/accuracy.txt index a7151db2c..3a160a61c 100644 --- a/tpdatasrc/tpgamefiles/rules/indicators/accuracy.txt +++ b/tpdatasrc/tpgamefiles/rules/indicators/accuracy.txt @@ -1,5 +1,5 @@ ID_string: ACCURACY effect_type: 0 -texture_file: art\interface\player_conditions\buffs\Spell True Strike.tga +texture_file: art\interface\player_conditions\buffs\Accuracy.tga help_topic: TAG_SPELLS_ACCURACY tooltip_base_text: Accuracy \ No newline at end of file diff --git a/tpdatasrc/tpgamefiles/rules/indicators/blades_of_fire.txt b/tpdatasrc/tpgamefiles/rules/indicators/blades_of_fire.txt index 4642dfa5b..0bda380c7 100644 --- a/tpdatasrc/tpgamefiles/rules/indicators/blades_of_fire.txt +++ b/tpdatasrc/tpgamefiles/rules/indicators/blades_of_fire.txt @@ -1,5 +1,5 @@ ID_string: BLADES_OF_FIRE effect_type: 0 -texture_file: art\interface\player_conditions\buffs\Spell True Strike.tga +texture_file: art\interface\player_conditions\buffs\Blades of Fire.tga help_topic: TAG_SPELLS_BLADES_OF_FIRE tooltip_base_text: Blades of Fire \ No newline at end of file diff --git a/tpdatasrc/tpgamefiles/rules/partsys/spell_compendium_partsys.tab b/tpdatasrc/tpgamefiles/rules/partsys/spell_compendium_partsys.tab index f616302e9..fb9149b8e 100644 --- a/tpdatasrc/tpgamefiles/rules/partsys/spell_compendium_partsys.tab +++ b/tpdatasrc/tpgamefiles/rules/partsys/spell_compendium_partsys.tab @@ -112,6 +112,7 @@ sp-Storm of Elemental Fury Wind wind 2 10 perm 60 Object Pos bip01 head Spri sp-Storm of Elemental Fury Wind winaround 0 perm 120 Object Pos bip01 head Sprite Polar fire-sprite 15 Add 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0,100 0 360?0 0 80,0 0,40 0 0 0,360 0 0 0,64,0 64 64 64 15 sp-Storm of Elemental Fury Earth ice ice baby Model Verts perm 80 Sprite World Polar flare-small 10 Add 0 0 0 0 0 0 0 0 600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1600 0 -240?240 0 -240?240 15?65 0 0 0 0,255,255,255,255,255,255,255,0 139 117 0 50 sp-Storm of Elemental Fury Earth ground busts discs 5 Point perm 120 World Polar Disc World Polar Cartesian Ring-3 10 Add 0 Shard-Breaking 0 0 0 0 0 2 0 0 0 0 0 20?-20 0 0 -250?250 0 -250?250 0,40 0 0 0?360 0 0 64,0 139 117 0 20 +sp-Sure Strike bullseye 60 1 Node Pos bip01 head Sprite Same as Emitter bullseye 60 Blend 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 35 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 15 0 0 180 0 0 0,192,0 138,0 3,0 3,0 1 sp-Touch Of Madness vampire dribblins 90 10 Node Pos bip01 r hand Sprite Polar Polar flare-big 60 Blend 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0?360 0 30,0 0,20 0 0 0 0 0 0,255,192,128,96,64,0 32 0 64 5 sp-Touch Of Madness dribbles bright 90 20 Node Pos bip01 r hand Sprite Polar Polar flare-1 60 Add 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0?360 0 30,0 0,5 0 0 0 0 0 0,255,192,128,96,64,0 128 0 255 5 sp-Undersong note2 0 perm 7 Node Pos bip01 head Sprite World Polar Polar note2 130 Add 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2?-2 2?-2 2?-2 0,720 0 10?30 2?7 0 0 160?200 0 0 0,255,200,150,100,50,0 255 155 112 2 diff --git a/tpdatasrc/tpgamefiles/scr/Spell1189 - Blades of Fire.py b/tpdatasrc/tpgamefiles/scr/Spell1189 - Blades of Fire.py index 26d034f09..52584ce29 100644 --- a/tpdatasrc/tpgamefiles/scr/Spell1189 - Blades of Fire.py +++ b/tpdatasrc/tpgamefiles/scr/Spell1189 - Blades of Fire.py @@ -18,7 +18,7 @@ def OnSpellEffect(spell): if game.is_melee_weapon(weaponTypeMainhand) and mainhandWeapon != OBJ_HANDLE_NULL: mainhandWeapon.d20_status_init() - if not mainhandWeapon.condition_add_with_args('sp-Blades of Fire', spell.id, spell.duration, 0): + if not mainhandWeapon.condition_add_with_args('sp-Blades of Fire', spell.id, 1, 0): #Icon does not display at 0 spellTarget.obj.float_mesfile_line('mes\\spell.mes', 30000) game.particles('Fizzle', spellTarget.obj) else: @@ -27,7 +27,7 @@ def OnSpellEffect(spell): if game.is_melee_weapon(weaponTypeOffhand) and offhandWeapon != OBJ_HANDLE_NULL: offhandWeapon.d20_status_init() - if not offhandWeapon.condition_add_with_args('sp-Blades of Fire', spell.id, spell.duration, 0): + if not offhandWeapon.condition_add_with_args('sp-Blades of Fire', spell.id, 1, 0): #Icon does not display at 0 spellTarget.obj.float_mesfile_line('mes\\spell.mes', 30000) game.particles('Fizzle', spellTarget.obj) elif offhandWeapon != OBJ_HANDLE_NULL: From 03957a9ef70c5f0e80758ccc8c5b1da370e40f2c Mon Sep 17 00:00:00 2001 From: doug1234 Date: Sat, 13 Jan 2024 11:59:03 -0500 Subject: [PATCH 04/12] Allow accuracy only once. --- tpdatasrc/tpgamefiles/scr/tpModifiers/sp_accuracy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tpdatasrc/tpgamefiles/scr/tpModifiers/sp_accuracy.py b/tpdatasrc/tpgamefiles/scr/tpModifiers/sp_accuracy.py index a347a2c34..21860eb88 100644 --- a/tpdatasrc/tpgamefiles/scr/tpModifiers/sp_accuracy.py +++ b/tpdatasrc/tpgamefiles/scr/tpModifiers/sp_accuracy.py @@ -9,5 +9,5 @@ def doubleIncrement(attachee, args, evt_obj): evt_obj.range_bonus += weaponUsed.obj_get_int(obj_f_weapon_range) return 0 -accuracySpell = SpellPythonModifier("sp-Accuracy") # spellId, duration, empty +accuracySpell = SpellPythonModifier("sp-Accuracy", 3, True) # spellId, duration, empty accuracySpell.AddHook(ET_OnRangeIncrementBonus, EK_NONE, doubleIncrement,()) From 711a0e0803f77db4fdfd7295464f66ce68ea6b29 Mon Sep 17 00:00:00 2001 From: doug1234 Date: Sat, 13 Jan 2024 12:02:28 -0500 Subject: [PATCH 05/12] Switched to blue target and now using a seperate accuracy particle system. Changed the accuracy tga file. --- .../Player_Conditions/Buffs/Accuracy.tga | Bin 1563 -> 1563 bytes .../partsys/spell_compendium_partsys.tab | 2 +- .../tpgamefiles/scr/Spell1182 - Accuracy.py | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tpdatasrc/tpgamefiles/art/interface/Player_Conditions/Buffs/Accuracy.tga b/tpdatasrc/tpgamefiles/art/interface/Player_Conditions/Buffs/Accuracy.tga index d6e4a642576baa87aedb5aa3f8f0064febd61c4b..258b2a273813017dab98df9b6a9fff0a3c2d9a02 100644 GIT binary patch literal 1563 zcmZQzU}As)0R{mE1&;s!|1(gEfhPWMXlTHRLGt+Qpr-!+?p*(280IEo?FZ?D=>gF& zKB@X)`d~EC`Xf=pkyQOKH-q%S^n%2QwIA8<$ZTTtgVZ4Ffw4j2g!F^b2234HABcvD z;Y&NnaxnGe=!KaBGXq4!#7Lzn(Mzgbl&XKv2z2czpjQYmGVn6IU>9I8WiTMs%7Vnq xyb`^<)Di^~JtI9+eA*R2l8jJ@tdLoV1;Pyp3Uv+h4EFT*(~WTR^l{Z=004jTr*!}T literal 1563 zcmZQzU}As)0R{mE1&;s!|1(gEfhPXX%*_1%KN4sZ2v331KsHDmB#+Mys_A#_SBnn99&P}srD0MX=zA55^ zL1JcJiC$i6iGqoqk)A0&?Ft}CMkqv9$SlMH;f4f-x`ufMd;0t7M!0$Uxau(g0RL8? AL;wH) diff --git a/tpdatasrc/tpgamefiles/rules/partsys/spell_compendium_partsys.tab b/tpdatasrc/tpgamefiles/rules/partsys/spell_compendium_partsys.tab index fb9149b8e..459cc5060 100644 --- a/tpdatasrc/tpgamefiles/rules/partsys/spell_compendium_partsys.tab +++ b/tpdatasrc/tpgamefiles/rules/partsys/spell_compendium_partsys.tab @@ -1,3 +1,4 @@ +sp-Accuracy bullseye 60 1 Node Pos bip01 head Sprite Same as Emitter bullseye 60 Blend 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 35 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 15 0 0 180 0 0 0,240,0 3,0 3,0 200,0 1 sp-Acid Fog smoke emit perm 600 Object YPR Sprite Same as Emitter Polar Cartesian fire-sprite 120 Blend 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0?30 0 0?360 0?240 5?40 0 0 0?360 0 0 0,16,0 0 255 144 100 sp-Appraising Touch aura 10 perm 30 Node Pos bip01 head Sprite flare-1 30 Add 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4?10 0 0 0 0 0 0,200,150,100,50,0 200?255 200?255 0?64 sp-Appraising Touch startup 5 200 Node Pos bip01 head Sprite flare-1 30 Add 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4,20 0 0 0 0 0 0,200,150,100,50,0 200?255 200?255 0?64 @@ -112,7 +113,6 @@ sp-Storm of Elemental Fury Wind wind 2 10 perm 60 Object Pos bip01 head Spri sp-Storm of Elemental Fury Wind winaround 0 perm 120 Object Pos bip01 head Sprite Polar fire-sprite 15 Add 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0,100 0 360?0 0 80,0 0,40 0 0 0,360 0 0 0,64,0 64 64 64 15 sp-Storm of Elemental Fury Earth ice ice baby Model Verts perm 80 Sprite World Polar flare-small 10 Add 0 0 0 0 0 0 0 0 600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1600 0 -240?240 0 -240?240 15?65 0 0 0 0,255,255,255,255,255,255,255,0 139 117 0 50 sp-Storm of Elemental Fury Earth ground busts discs 5 Point perm 120 World Polar Disc World Polar Cartesian Ring-3 10 Add 0 Shard-Breaking 0 0 0 0 0 2 0 0 0 0 0 20?-20 0 0 -250?250 0 -250?250 0,40 0 0 0?360 0 0 64,0 139 117 0 20 -sp-Sure Strike bullseye 60 1 Node Pos bip01 head Sprite Same as Emitter bullseye 60 Blend 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 35 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 15 0 0 180 0 0 0,192,0 138,0 3,0 3,0 1 sp-Touch Of Madness vampire dribblins 90 10 Node Pos bip01 r hand Sprite Polar Polar flare-big 60 Blend 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0?360 0 30,0 0,20 0 0 0 0 0 0,255,192,128,96,64,0 32 0 64 5 sp-Touch Of Madness dribbles bright 90 20 Node Pos bip01 r hand Sprite Polar Polar flare-1 60 Add 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0?360 0 30,0 0,5 0 0 0 0 0 0,255,192,128,96,64,0 128 0 255 5 sp-Undersong note2 0 perm 7 Node Pos bip01 head Sprite World Polar Polar note2 130 Add 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2?-2 2?-2 2?-2 0,720 0 10?30 2?7 0 0 160?200 0 0 0,255,200,150,100,50,0 255 155 112 2 diff --git a/tpdatasrc/tpgamefiles/scr/Spell1182 - Accuracy.py b/tpdatasrc/tpgamefiles/scr/Spell1182 - Accuracy.py index c1250f5ca..a4f2fe60f 100644 --- a/tpdatasrc/tpgamefiles/scr/Spell1182 - Accuracy.py +++ b/tpdatasrc/tpgamefiles/scr/Spell1182 - Accuracy.py @@ -12,7 +12,7 @@ def OnSpellEffect(spell): spellTarget = spell.target_list[0] if spellTarget.obj.condition_add_with_args('sp-Accuracy', spell.id, spell.duration): - spellTarget.partsys_id = game.particles('sp-Sure Strike', spell.caster) + spellTarget.partsys_id = game.particles('sp-Accuracy', spell.caster) else: spellTarget.obj.float_mesfile_line('mes\\spell.mes', 30000) game.particles('Fizzle', spellTarget.obj) From 32e2a488035f3cbe0fd619c08a52351bff9845a5 Mon Sep 17 00:00:00 2001 From: doug1234 Date: Sat, 13 Jan 2024 12:38:49 -0500 Subject: [PATCH 06/12] Removed end sound for blades of fire. --- .../tpgamefiles/sound/user_sounds/spell_compendium_sounds.mes | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tpdatasrc/tpgamefiles/sound/user_sounds/spell_compendium_sounds.mes b/tpdatasrc/tpgamefiles/sound/user_sounds/spell_compendium_sounds.mes index 5d0ef49fb..68b7f3f31 100644 --- a/tpdatasrc/tpgamefiles/sound/user_sounds/spell_compendium_sounds.mes +++ b/tpdatasrc/tpgamefiles/sound/user_sounds/spell_compendium_sounds.mes @@ -1531,7 +1531,7 @@ // [1189] *[Blades of Fire] {29780}{} // spell begin {29781}{spells\sp_flame_blade_end.WAV} // spell end -{29782}{spells\sp_flame_blade.wav} // spell effect +{29782}{} // spell effect {29783}{} // spell new round {29784}{} // spell projectile begin {29785}{} // spell projectile end From 2cb1ab057d8557707aeeb53b78913ba19a242fe4 Mon Sep 17 00:00:00 2001 From: doug1234 Date: Sat, 13 Jan 2024 13:15:14 -0500 Subject: [PATCH 07/12] Added remove deafness helper Co-authored-by: Sagenlicht --- .../remove_deafness_helper_condition.py | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 tpdatasrc/tpgamefiles/scr/tpModifiers/remove_deafness_helper_condition.py diff --git a/tpdatasrc/tpgamefiles/scr/tpModifiers/remove_deafness_helper_condition.py b/tpdatasrc/tpgamefiles/scr/tpModifiers/remove_deafness_helper_condition.py new file mode 100644 index 000000000..2d3e9c904 --- /dev/null +++ b/tpdatasrc/tpgamefiles/scr/tpModifiers/remove_deafness_helper_condition.py @@ -0,0 +1,21 @@ +from templeplus.pymod import PythonModifier +from toee import * +import tpdp + +##### sp-Deafness Remove Helper Condition##### + +def removeDeafness(attachee, args, evt_obj): + spellId = 0 + duration = 0 + attachee.condition_add_with_args('sp-Remove Deafness', spellId, duration, 0) + return 0 + +def conditionTickdown(attachee, args, evt_obj): + args.set_arg(0, args.get_arg(0)-evt_obj.data1) # Ticking down duration + if args.get_arg(0) < 0: + args.condition_remove() + return 0 + +remDeafHelper = PythonModifier("Remove Deafness Helper Condition", 2) #duration, empty +remDeafHelper.AddHook(ET_OnConditionRemove, EK_NONE, removeDeafness, ()) +remDeafHelper.AddHook(ET_OnBeginRound, EK_NONE, conditionTickdown, ()) \ No newline at end of file From b9033c71e301f84f82ae3a9fee7a176bcf6aa801 Mon Sep 17 00:00:00 2001 From: doug1234 Date: Sat, 13 Jan 2024 13:17:28 -0500 Subject: [PATCH 08/12] Added sickened condition Co-authored-by: Sagenlicht --- .../tpgamefiles/scr/tpModifiers/sickened.py | 85 +++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 tpdatasrc/tpgamefiles/scr/tpModifiers/sickened.py diff --git a/tpdatasrc/tpgamefiles/scr/tpModifiers/sickened.py b/tpdatasrc/tpgamefiles/scr/tpModifiers/sickened.py new file mode 100644 index 000000000..f2da8d210 --- /dev/null +++ b/tpdatasrc/tpgamefiles/scr/tpModifiers/sickened.py @@ -0,0 +1,85 @@ +from templeplus.pymod import PythonModifier +from toee import * +import tpdp +from spell_utils import isLivingCreature + +print "Registering Sickened" + +def checkConditionalRemoval(attachee, args, evt_obj): + if (evt_obj.is_modifier("sp-Heal") + or evt_obj.is_modifier("sp-Remove Sickened") + or evt_obj.is_modifier("Sickened")): + args.condition_remove() + return 0 + +def checkImmunity(attachee, args, evt_obj): + if isLivingCreature(attachee): + spellMesId = 20026 #ID 20026 = Sickened! + attachee.float_mesfile_line("mes\\spell.mes", spellMesId, tf_red) + game.create_history_freeform("{} is ~sickened~[TAG_SICKENED]\n\n".format(attachee.description)) + particlesId = game.particles("sp-Disease-Filth Fever", attachee) + args.set_arg(1, particlesId) + else: + spellMesId = 32000 #ID 32000 = Target is immune! + attachee.float_mesfile_line("mes\\spell.mes", spellMesId) + args.condition_remove() + return 0 + +def durationTickdown(attachee, args, evt_obj): + duration = args.get_arg(0) + duration -= evt_obj.data1 + args.set_arg(0, duration) + if args.get_arg(0) < 0: + args.condition_remove() + return 0 + +def sickenedPenalty(attachee, args, evt_obj): + conditionName = args.get_cond_name() + conditionTag = "TAG_{}".format(conditionName.upper().replace(" ", "_")) + bonus = -2 #Sickened is a -2 penalty to attack rolls, saving throws, skill checks, and ability checks. + bonusType = bonus_type_untyped # Stacking! + evt_obj.bonus_list.add(bonus, bonusType, "~{}~[{}]".format(conditionName, conditionTag)) + return 0 + +def queryIsSickened(attachee, args, evt_obj): + evt_obj.return_val = 1 + return 0 + +def getDurationLabel(duration): + if duration == 1: + return "1 round" + return "{} rounds".format(duration) + +def sickenedTooltip(attachee, args, evt_obj): + conditionName = args.get_cond_name() + duration = args.get_arg(0) + durationLabel = getDurationLabel(duration) + evt_obj.append("{} ({})".format(conditionName, durationLabel)) + return 0 + +def sickenedEffectTooltip(attachee, args, evt_obj): + conditionName = args.get_cond_name() + conditionKey = conditionName.upper().replace(" ", "_") + duration = args.get_arg(0) + durationLabel = getDurationLabel(duration) + evt_obj.append(tpdp.hash(conditionKey), -2, " ({})".format(durationLabel)) + return 0 + +def removeParticles(attachee, args, evt_obj): + particlesId = args.get_arg(1) + if particlesId: + game.particles_end(particlesId) + return 0 + +SickenedCondition = PythonModifier("Sickened", 3, False) #duration, particlesId, empty +SickenedCondition.AddHook(ET_OnConditionAddPre, EK_NONE, checkConditionalRemoval, ()) +SickenedCondition.AddHook(ET_OnConditionAdd, EK_NONE, checkImmunity, ()) +SickenedCondition.AddHook(ET_OnBeginRound, EK_NONE, durationTickdown, ()) +SickenedCondition.AddHook(ET_OnToHitBonus2, EK_NONE, sickenedPenalty,()) +SickenedCondition.AddHook(ET_OnGetSkillLevel, EK_NONE, sickenedPenalty,()) +SickenedCondition.AddHook(ET_OnGetAbilityCheckModifier, EK_NONE, sickenedPenalty,()) +SickenedCondition.AddHook(ET_OnSaveThrowLevel, EK_NONE, sickenedPenalty,()) +SickenedCondition.AddHook(ET_OnD20PythonQuery, "PQ_Is_Sickened", queryIsSickened, ()) +SickenedCondition.AddHook(ET_OnGetTooltip, EK_NONE, sickenedTooltip, ()) +SickenedCondition.AddHook(ET_OnGetEffectTooltip, EK_NONE, sickenedEffectTooltip, ()) +SickenedCondition.AddHook(ET_OnConditionRemove, EK_NONE, removeParticles, ()) From 6ab36033bfff54a9b1a612dadfd3f8211a68c646 Mon Sep 17 00:00:00 2001 From: doug1234 Date: Wed, 17 Jan 2024 21:47:51 -0500 Subject: [PATCH 09/12] Added indicator and image for sickened. Co-authored-by: Sagenlicht --- .../Player_Conditions/Ailments/Sickened.tga | Bin 0 -> 1042 bytes .../tpgamefiles/rules/indicators/sickened.txt | 5 +++++ 2 files changed, 5 insertions(+) create mode 100644 tpdatasrc/tpgamefiles/art/interface/Player_Conditions/Ailments/Sickened.tga create mode 100644 tpdatasrc/tpgamefiles/rules/indicators/sickened.txt diff --git a/tpdatasrc/tpgamefiles/art/interface/Player_Conditions/Ailments/Sickened.tga b/tpdatasrc/tpgamefiles/art/interface/Player_Conditions/Ailments/Sickened.tga new file mode 100644 index 0000000000000000000000000000000000000000..7020269c9686341d3401cdface1b0d2dd178ffe8 GIT binary patch literal 1042 zcmZQzU}As)0R{mE1&;s!|1%6W40IvTN#wZ;q!)%sH3OzEGc%K9Gm!N*ux&e0n-oD1JVaGixmAJH^cOSXk zAUD7;h);_B#~I%IzuWr-tRF;!_@w9uxffvN1Mx|*AEX|n7vyeOSP-Kh JU)U0o0|0^Xh&liO literal 0 HcmV?d00001 diff --git a/tpdatasrc/tpgamefiles/rules/indicators/sickened.txt b/tpdatasrc/tpgamefiles/rules/indicators/sickened.txt new file mode 100644 index 000000000..b6db5541d --- /dev/null +++ b/tpdatasrc/tpgamefiles/rules/indicators/sickened.txt @@ -0,0 +1,5 @@ +ID_string: SICKENED +effect_type: 1 +texture_file: art\interface\player_conditions\ailments\sickened.tga +help_topic: TAG_SICKENED +tooltip_base_text: Sickened \ No newline at end of file From 9cf23e3b69f1963ff82695f3d62b2940607e6ad2 Mon Sep 17 00:00:00 2001 From: doug1234 Date: Wed, 17 Jan 2024 21:49:45 -0500 Subject: [PATCH 10/12] Fix crash and add log for bad tooltip. --- TemplePlus/dispatcher.cpp | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/TemplePlus/dispatcher.cpp b/TemplePlus/dispatcher.cpp index 50e21858f..b36ed4258 100644 --- a/TemplePlus/dispatcher.cpp +++ b/TemplePlus/dispatcher.cpp @@ -1228,7 +1228,7 @@ int32_t _dispatch1ESkillLevel(objHndl objHnd, SkillEnum skill, BonusList* bonOut void DispIoEffectTooltip::Append(int effectTypeId, int spellEnum, const char* text) const { - BuffDebuffSub * bdbSub; + BuffDebuffSub * bdbSub = nullptr; auto findSpec = uiParty.IndicatorSpecGet(effectTypeId); switch (findSpec.type) { @@ -1250,14 +1250,20 @@ void DispIoEffectTooltip::Append(int effectTypeId, int spellEnum, const char* te } //copy the text - bdbSub->effectTypeId = effectTypeId; - bdbSub->spellEnum = spellEnum; - if (text){ - bdbSub->text = new char[strlen(text) + 1]; - strcpy( const_cast(bdbSub->text), text); - } else - { - bdbSub->text = nullptr; + if (bdbSub != nullptr) { + bdbSub->effectTypeId = effectTypeId; + bdbSub->spellEnum = spellEnum; + if (text) { + bdbSub->text = new char[strlen(text) + 1]; + strcpy(const_cast(bdbSub->text), text); + } + else + { + bdbSub->text = nullptr; + } + } + else { + logger->error("Unknown tooltip effect {}", effectTypeId); } } From 96c2c005d60ba17a3e4dad0cbdcede39d8b7f943 Mon Sep 17 00:00:00 2001 From: doug1234 Date: Fri, 26 Jan 2024 19:28:55 -0500 Subject: [PATCH 11/12] Removed dismiss condition from casters of orb of cold and sound. --- .../tpgamefiles/scr/Spell1197 - Orb of Cold.py | 1 + .../tpgamefiles/scr/Spell1200 - Orb of Sound.py | 1 + tpdatasrc/tpgamefiles/scr/tpModifiers/dismiss.py | 14 ++++++++++++++ 3 files changed, 16 insertions(+) create mode 100644 tpdatasrc/tpgamefiles/scr/tpModifiers/dismiss.py diff --git a/tpdatasrc/tpgamefiles/scr/Spell1197 - Orb of Cold.py b/tpdatasrc/tpgamefiles/scr/Spell1197 - Orb of Cold.py index ec04b4b5d..513088e51 100644 --- a/tpdatasrc/tpgamefiles/scr/Spell1197 - Orb of Cold.py +++ b/tpdatasrc/tpgamefiles/scr/Spell1197 - Orb of Cold.py @@ -41,6 +41,7 @@ def OnEndProjectile(spell, projectile, index_of_target): spellTarget.obj.float_mesfile_line('mes\\spell.mes', 30002) spell.duration = 1 if spellTarget.obj.condition_add_with_args("sp-Blindness", spell.id, spell.duration, 0): + spell.caster.d20_send_signal("Remove Dismiss Condition", spell.id) spellTarget.partsys_id = game.particles("sp-Blindness-Deafness", spellTarget.obj) else: spellTarget.obj.float_mesfile_line('mes\\spell.mes', 30007) diff --git a/tpdatasrc/tpgamefiles/scr/Spell1200 - Orb of Sound.py b/tpdatasrc/tpgamefiles/scr/Spell1200 - Orb of Sound.py index 4ed9766f5..508394e25 100644 --- a/tpdatasrc/tpgamefiles/scr/Spell1200 - Orb of Sound.py +++ b/tpdatasrc/tpgamefiles/scr/Spell1200 - Orb of Sound.py @@ -42,6 +42,7 @@ def OnEndProjectile(spell, projectile, index_of_target): #sp-Deafness is permanent currently, I'll add a helper condition to remove it after it should expire #as there is no condition_remove in python if spellTarget.obj.condition_add_with_args("sp-Deafness", spell.id, spell.duration, 0): + spell.caster.d20_send_signal("Remove Dismiss Condition", spell.id) spellTarget.partsys_id = game.particles("sp-Blindness-Deafness", spellTarget.obj) spellTarget.obj.condition_add_with_args("Remove Deafness Helper Condition", duration, 0) else: diff --git a/tpdatasrc/tpgamefiles/scr/tpModifiers/dismiss.py b/tpdatasrc/tpgamefiles/scr/tpModifiers/dismiss.py new file mode 100644 index 000000000..531120c79 --- /dev/null +++ b/tpdatasrc/tpgamefiles/scr/tpModifiers/dismiss.py @@ -0,0 +1,14 @@ +from templeplus.pymod import PythonModifier +from toee import * +import tpdp + +print "Dismiss Extender" + +def RemoveDismissCondition(attachee, args, evt_obj): + if args.get_arg(0) == evt_obj.data1: + args.condition_remove() + return 0 + +powerAttackExtender = PythonModifier() +powerAttackExtender.ExtendExisting("Dismiss") +powerAttackExtender.AddHook(ET_OnD20PythonSignal, "Remove Dismiss Condition", RemoveDismissCondition, ()) \ No newline at end of file From e017cab7d40df789f0345e5e2ba69fca8d6cd573 Mon Sep 17 00:00:00 2001 From: doug1234 Date: Fri, 26 Jan 2024 21:15:24 -0500 Subject: [PATCH 12/12] Added long descriptions for warmage spells. --- .../mes/spell_ext/spell_compendium_spell.mes | 2 +- ...ell_compendium_spell_long_descriptions.mes | 42 +++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/tpdatasrc/tpgamefiles/mes/spell_ext/spell_compendium_spell.mes b/tpdatasrc/tpgamefiles/mes/spell_ext/spell_compendium_spell.mes index 7bc747392..1eba2aea6 100644 --- a/tpdatasrc/tpgamefiles/mes/spell_ext/spell_compendium_spell.mes +++ b/tpdatasrc/tpgamefiles/mes/spell_ext/spell_compendium_spell.mes @@ -289,7 +289,7 @@ {6186} Lesser Orb of Electricity {Ranged Touch Attack that deals 1d8/two levels (max 5d8) electricity damage.} {6187} Lesser Orb of Fire {Ranged Touch Attack that deals 1d8/two levels (max 5d8) fire damage.} {6188} Lesser Orb of Sound {Ranged Touch Attack that deals 1d8/two levels (max 5d8) sonic damage.} -{6189} Blades of Fire {Your melee weapons each deal an extra 1d8 points of fire damage.} +{6189} Blades of Fire {Up to two melee weapons each deal an extra 1d8 points of fire damage.} {6190} Fireburst {Fire deals 1d8 points of fire damage per caster level (maximum 5d8) to anyone within 5 feet of you.} {6191} Greater Fireburst {Fire deals 1d8 points of fire damage per caster level (maximum 15d8) to anyone within 10 feet of you.} {6195} Blast of Flame {A 60 foot cone shaped burst deals 1d6 points of fire damage per caster level (maximum 10d6).} diff --git a/tpdatasrc/tpgamefiles/mes/spell_long_descriptions_ext/spell_compendium_spell_long_descriptions.mes b/tpdatasrc/tpgamefiles/mes/spell_long_descriptions_ext/spell_compendium_spell_long_descriptions.mes index 06092fce7..cb76ce6a4 100644 --- a/tpdatasrc/tpgamefiles/mes/spell_long_descriptions_ext/spell_compendium_spell_long_descriptions.mes +++ b/tpdatasrc/tpgamefiles/mes/spell_long_descriptions_ext/spell_compendium_spell_long_descriptions.mes @@ -925,6 +925,20 @@ Range: Close (25ft. + 5ft./2 lvls) Target: allied creatures, no more than 30' apart Duration: 1 round/level (D)} +{6182} Accuracy {For the duration of the spell, the range increment for the affected weapon or weapons is doubled. +School: Transmutation +Casting: 1 action [V,S] +Range: Touch +Target: One thrown weapon/level touched or one projectile weapon touched. +Duration: Instantaneous, Save: None, SR: No} + +{6183} Hail of Stones {You create a rain of stones that deals 1d4 points of damage per caster level (maximum 5d4). +School: Conjuration(Creation)[Earth] +Casting: 1 action [V,S] +Range: Medium (100ft. + 10ft./lvl) +Target: Cylinder (5-ft. radius) +Duration: Instantaneous, Save: None, SR: No} + {6184} Lesser Orb of Acid {Ranged Touch Attack that deals 1d8/two levels (max 5d8) acid damage. School: Conjuration(Creation)[Acid] Casting: 1 action [V,S] @@ -960,6 +974,34 @@ Range: Close (25ft. + 5ft./2 lvls) Target: One creature Duration: Instantaneous, Save: None, SR: No} +{6189} Blades of Fire {Your melee weapons each deal an extra 1d8 points of fire damage stacking with other energy damage. +School: Conjuration (Creation)[Fire] +Casting: 1 swift action [V] +Range: Touch +Target: Up to two melee weapons +Duration: 1 round, Save: None, SR: No} + +{6190} Fireburst {An explosion of flame deals 1d8 (max 5d6) fire damage per level to anyone within 5 feet of you. +School: Evocation[Fire] +Casting: 1 action [V,S] +Range: 5 ft. +Target: Creatures 5 ft. from you +Duration: Inst., Save: Reflex partial, SR: Yes} + +{6191} Greater Fireburst {An explosion of flame deals 1d8 (max 15d6) fire damage per level to anyone within 10 feet of you. +School: Evocation[Fire] +Casting: 1 action [V,S] +Range: 10 ft. +Target: Creatures 10 ft. from you +Duration: Inst., Save: Reflex partial, SR: Yes} + +{6195} Blast of Flame {Flames fill a cone shaped area, dealing 1d6 points of fire damage per caster level (maximum 10d6). +School: Conjuration (Creation)[Fire] +Casting: 1 action [V,S] +Range: 60 ft. +Target: Cone-shaped burst +Duration: Inst., Save: Reflex partial, SR: No} + {6196} Orb of Acid {Ranged Touch Attack that deals 1d6/level (max 15d6) acid damage and in addition sickens for 1 round on a failed fortitude save. School: Conjuration(Creation)[Acid] Casting: 1 action [V,S]