diff --git a/tpdatasrc/tpgamefiles/mes/help/spell_compendium_help.tab b/tpdatasrc/tpgamefiles/mes/help/spell_compendium_help.tab index e7d7f078c..f1dbd803a 100644 --- a/tpdatasrc/tpgamefiles/mes/help/spell_compendium_help.tab +++ b/tpdatasrc/tpgamefiles/mes/help/spell_compendium_help.tab @@ -91,7 +91,7 @@ TAG_SPELLS_SHOCK_AND_AWE TAG_SPELLS TAG_ASSASSIN_1 TAG_BARD_1 TAG_SORCERER_1 TA TAG_SPELLS_SIRINES_GRACE TAG_SPELLS TAG_BARD_4 TAG_DRUID_5 Sirine's Grace ~Evocation~[TAG_MAGIC_SCHOOLS_EVOCATION] Level: ~Bard~[TAG_BARDS] 4, ~Druid~[TAG_DRUIDS] 5 Components: V, S Casting Time: 1 ~standard action~[TAG_STANDARD_ACTION] Range: Personal Target: You Duration: 1 round/level Upon completion of this spell, you are infused with unearthly grace and confidence. For the duration of this spell, you gain a +4 ~enhancement~[TAG_ENHANCEMENT_BONUS] bonus to ~Charisma~[TAG_CHARISMA] and ~Dexterity~[TAG_DEXTERITY], a ~deflection~[TAG_DEFLECTION_BONUS] bonus to ~AC~[TAG_ARMOR_CLASS] equal to your ~Charisma modifier~[TAG_ABILITY_SCORES], and a +8 bonus on ~Perform~[TAG_PERFORM] checks. You also gain a swim speed of 60 feet and the ability to breathe water. You can move and attack normally while underwater, even with slashing or bludgeoning weapons. Note: The underwater parts are not applicable to TOEE and due to this not implemented. TAG_SPELLS_SLASHING_DARKNESS TAG_SPELLS TAG_CLERIC_3 Slashing Darkness ~Evocation~[TAG_MAGIC_SCHOOLS_EVOCATION] Level: ~Cleric~[TAG_CLERICS] 3 Components: V, S Casting Time: 1 ~standard action~[TAG_STANDARD_ACTION] Range: Medium (100 ft. + 10 ft./level) Target: One creature Duration: Instantaneous Saving Throw: None Spell Resistance: Yes You complete this spell and a hissing, hurtling ribbon of pure darkness flies from your hand. You must succeed on a ~ranged touch attack~[TAG_TOUCH_ATTACK] with the ray to strike a target. A creature struck by this ray of negative energy takes 1d8 points of damage per two caster levels (maximum 5d8). An undead creature instead heals 1d8 points of damage per two caster levels (maximum 5d8). TAG_SPELLS_SNIPERS_SHOT TAG_SPELLS TAG_ASSASSIN_1, TAG_RANGER_1, TAG_SORCERER_1 TAG_WIZARD_1 Sniper's Shot ~Divination~[TAG_MAGIC_SCHOOLS_DIVINATION] Level: ~Assassin~[TAG_ASSASSINS] 1, ~Ranger~[TAG_RANGERS] 1, ~Sorcerer~[TAG_SORCERERS]/~Wizard~[TAG_WIZARDS] 1 Components: V, S Casting Time: ~Free action~[TAG_FREE_ACTION] Range: Personal Target: You Duration: 1 round While muttering a short chant you focus your awareness, looking only at the areas of your foe that seem most vital to its survival. Your ~ranged attacks~[TAG_RANGED_ATTACKS] made before the start of your next turn can be ~sneak attacks~[TAG_CLASS_FEATURES_ROGUE_SNEAK_ATTACK] regardless of the distance between you and your target. You must still fulfill the other conditions for making a sneak attack against the target. Note: This spell doesn't grant you the ability to make a sneak attack if you don't already have that ability. -TAG_SPELLS_SONIC_WEAPON TAG_SPELLS TAG_BARD_1 TAG_SORCERER_1 TAG_WIZARD_1 Sonic Weapon ~Transmutation~[TAG_MAGIC_SCHOOLS_TRANSMUTATION] Level: ~Bard~[TAG_BARDS] 1, ~Sorcerer~[TAG_SORCERERS]/~Wizard~[TAG_WIZARDS] 1 Components: V Casting Time: 1 ~standard action~[TAG_STANDARD_ACTION] Range: Personal Target: Wapon touched Duration: 1 minute/level Holding the weapon to your mouth, you whisper the spell's arcane words, shrouding the weapon in visible sound like a thin sheen of water. While the spell is in effect, the affected weapon deals an extra 1d6 points of sonic damage with each successful attack. The sonic energy does not harm the weapon's wielder. Bows, crossbows, and slings that are affected by this spell bestow the sonic energy upon their ammunition. +TAG_SPELLS_SONIC_WEAPON TAG_SPELLS TAG_BARD_1 TAG_SORCERER_1 TAG_WIZARD_1 Sonic Weapon ~Transmutation~[TAG_MAGIC_SCHOOLS_TRANSMUTATION] Level: ~Bard~[TAG_BARDS] 1, ~Sorcerer~[TAG_SORCERERS]/~Wizard~[TAG_WIZARDS] 1 Components: V Casting Time: 1 ~standard action~[TAG_STANDARD_ACTION] Range: Touch Target: Weapon touched Duration: 1 minute/level Holding the weapon to your mouth, you whisper the spell's arcane words, shrouding the weapon in visible sound like a thin sheen of water. While the spell is in effect, the affected weapon deals an extra 1d6 points of sonic damage with each successful attack. The sonic energy does not harm the weapon's wielder. Bows, crossbows, and slings that are affected by this spell bestow the sonic energy upon their ammunition. Note: The ammunition part is not implemented yet. TAG_SPELLS_SOUND_LANCE TAG_SPELLS TAG_SORCERER_3 TAG_WIZARD_3 TAG_CLERIC_4 Sound Lance ~Evocation~[TAG_MAGIC_SCHOOLS_EVOCATION](Sonic) Level: ~Sorcerer~[TAG_SORCERERS]/~Wizard~[TAG_WIZARDS] 3, ~Cleric~[TAG_CLERICS] 4 Components: V, S Casting Time: 1 ~standard action~[TAG_STANDARD_ACTION] Range: Medium (100 ft. +10 ft./level) Target: One creature or object Duration: Instantaneous Saving Throw: ~Fortitude~[TAG_FORTITUDE] half Spell Resistance: Yes You unleash a shrill, piercing cry at your target, which takes the barely visible form of a translucent lance hurtling through the air. This spell causes a projectile of intense sonic energy to leap from you to a target within range. The sound deals 1d8 points of sonic damage per caster level (maximum 10d8). A sound lance cannot penetrate the area of a ~silence~[TAG_SPELLS_SILENCE] spell. TAG_SPELLS_SPIKES TAG_SPELLS TAG_CLERIC_3 TAG_DRUID_3 Spikes ~Transmutation~[TAG_MAGIC_SCHOOLS_TRANSMUTATION] Level: ~Cleric~[TAG_CLERICS] 3, ~Druid~[TAG_DRUIDS] 3 Components: V, S Casting Time: 1 ~standard action~[TAG_STANDARD_ACTION] Range: Touch Target: Weapon touched Duration: 1 round/level Saving Throw: None Spell Resistance: No With the sound of twisting wood, the weapon you touch grows sharp spikes like rose thorns. This spell functions like ~Brambles~[TAG_SPELLS_BRAMBLES], except that the affected weapon gains a +2 ~enhancement~[TAG_ENHANCEMENT_BONUS] bonus on its ~attack rolls~[TAG_ATTACK_ROLL], and its threat range is doubled. This effect does not stack with other effects that increase a weapon's threat range, such as the Improved Critical feat. Note: the spell only works on weapons equipped in the mainhand. TAG_SPELLS_STRATEGIC_CHARGE TAG_SPELLS TAG_BLACKGUARD_1 TAG_PALADIN_1 Strategic Charge ~Abjuration~[TAG_MAGIC_SCHOOLS_ABJURATION] Level: ~Blackguard~[TAG_BLACKGUARDS] 1, ~Paladin~[TAG_PALADINS] 1 Components: V Casting Time: 1 ~Free action~[TAG_FREE_ACTION] Range: Personal Target: You Duration: 1 round/level A red nimbus surrounds you as you move smoothly across the crowded battlefield. You gain the benefit of the ~Mobility~[TAG_MOBILITY] feat, even if you not meet the prerequisites. You do not have to be charging to gain this benefit. diff --git a/tpdatasrc/tpgamefiles/rules/spells/039 - Bless Weapon.txt b/tpdatasrc/tpgamefiles/rules/spells/039 - Bless Weapon.txt new file mode 100644 index 000000000..7c812590b --- /dev/null +++ b/tpdatasrc/tpgamefiles/rules/spells/039 - Bless Weapon.txt @@ -0,0 +1,18 @@ +School: Transmutation +Level: Pal 1 +Component: V +Casting Time: 1 action +Range: Touch +Saving Throw: None +Spell Resistance: No +Projectile: No +flags_Target: Range +inc_flags_Target: Self +inc_flags_Target: Other +exc_flags_Target: Dead +exc_flags_Target: Non-critter +mode_Target: Single +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/1075 - Sonic Weapon.txt b/tpdatasrc/tpgamefiles/rules/spells/1075 - Sonic Weapon.txt new file mode 100644 index 000000000..b48bb49b5 --- /dev/null +++ b/tpdatasrc/tpgamefiles/rules/spells/1075 - Sonic Weapon.txt @@ -0,0 +1,22 @@ +School: Transmutation +Descriptor: Sonic +Level: Brd 2 +Level: Sor 2 +Level: Wiz 2 +Component: V +Casting Time: 1 action +Range: Touch +Saving Throw: None +Spell Resistance: No +Projectile: No +flags_Target: Range +inc_flags_Target: Self +inc_flags_Target: Other +exc_flags_Target: Dead +exc_flags_Target: Non-critter +mode_Target: Single +min_Target: 1 +max_Target: 1 +radius_Target: 0 +ai_type: ai_action_defensive +choices: 3011 3012 \ No newline at end of file diff --git a/tpdatasrc/tpgamefiles/rules/spells/1103 - Dolorous Blow.txt b/tpdatasrc/tpgamefiles/rules/spells/1103 - Dolorous Blow.txt new file mode 100644 index 000000000..f9d9b63e1 --- /dev/null +++ b/tpdatasrc/tpgamefiles/rules/spells/1103 - Dolorous Blow.txt @@ -0,0 +1,21 @@ +School: Transmutation +Level: Brd 3 +Level: Sor 3 +Level: Wiz 3 +Component: V +Component: S +Casting Time: 1 action +Range: Touch +Saving Throw: None +Spell Resistance: No +Projectile: No +flags_Target: Range +inc_flags_Target: Self +inc_flags_Target: Other +exc_flags_Target: Dead +exc_flags_Target: Non-critter +mode_Target: Single +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/1115 - Deafening Clang.txt b/tpdatasrc/tpgamefiles/rules/spells/1115 - Deafening Clang.txt new file mode 100644 index 000000000..414ea9e35 --- /dev/null +++ b/tpdatasrc/tpgamefiles/rules/spells/1115 - Deafening Clang.txt @@ -0,0 +1,20 @@ +School: Transmutation +Descriptor: Sonic +Level: Pal 1 +Component: V +Component: S +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/1130 - Shield of Warding.txt b/tpdatasrc/tpgamefiles/rules/spells/1130 - Shield of Warding.txt new file mode 100644 index 000000000..ffea8f875 --- /dev/null +++ b/tpdatasrc/tpgamefiles/rules/spells/1130 - Shield of Warding.txt @@ -0,0 +1,21 @@ +School: Abjuration +Descriptor: Good +Level: Clr 3 +Level: Pal 2 +Component: V +Component: S +Casting Time: 1 action +Range: Touch +Saving Throw: None +Spell Resistance: No +Projectile: No +flags_Target: Range +inc_flags_Target: Self +inc_flags_Target: Other +exc_flags_Target: Dead +exc_flags_Target: Non-critter +mode_Target: Single +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/1134 - Undead Bane Weapon.txt b/tpdatasrc/tpgamefiles/rules/spells/1134 - Undead Bane Weapon.txt new file mode 100644 index 000000000..cf5d8ff1c --- /dev/null +++ b/tpdatasrc/tpgamefiles/rules/spells/1134 - Undead Bane Weapon.txt @@ -0,0 +1,20 @@ +School: Transmutation +Level: Clr 4 +Level: Pal 3 +Component: V +Component: S +Casting Time: 1 action +Range: Touch +Saving Throw: None +Spell Resistance: No +Projectile: No +flags_Target: Range +inc_flags_Target: Self +inc_flags_Target: Other +exc_flags_Target: Dead +exc_flags_Target: Non-critter +mode_Target: Single +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/1141 - Lawful Sword.txt b/tpdatasrc/tpgamefiles/rules/spells/1141 - Lawful Sword.txt new file mode 100644 index 000000000..9ff56cc1b --- /dev/null +++ b/tpdatasrc/tpgamefiles/rules/spells/1141 - Lawful Sword.txt @@ -0,0 +1,18 @@ +School: Evocation +Descriptor: Lawful +Level: Pal 4 +Component: V +Component: S +Casting Time: 1 action +Range: Personal +Saving Throw: None +Spell Resistance: No +Projectile: No +flags_Target: Range +inc_flags_Target: Self +exc_flags_Target: Dead +exc_flags_Target: Non-critter +exc_flags_Target: Other +mode_Target: Personal +radius_Target: 0 +ai_type: ai_action_defensive \ No newline at end of file diff --git a/tpdatasrc/tpgamefiles/rules/spells/1149 - Brambles.txt b/tpdatasrc/tpgamefiles/rules/spells/1149 - Brambles.txt new file mode 100644 index 000000000..2f519b0fb --- /dev/null +++ b/tpdatasrc/tpgamefiles/rules/spells/1149 - Brambles.txt @@ -0,0 +1,20 @@ +School: Transmutation +Level: Clr 2 +Level: Drd 2 +Component: V +Component: S +Casting Time: 1 action +Range: Touch +Saving Throw: None +Spell Resistance: No +Projectile: No +flags_Target: Range +inc_flags_Target: Other +inc_flags_Target: Self +exc_flags_Target: Dead +exc_flags_Target: Non-critter +mode_Target: Single +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/1154 - Align Weapon Mass.txt b/tpdatasrc/tpgamefiles/rules/spells/1154 - Align Weapon Mass.txt new file mode 100644 index 000000000..8f5a474f6 --- /dev/null +++ b/tpdatasrc/tpgamefiles/rules/spells/1154 - Align Weapon Mass.txt @@ -0,0 +1,23 @@ +School: Transmutation +Level: Clr 3 +Component: V +Component: S +Casting Time: 1 action +Range: Close +Saving Throw: None +Spell Resistance: No +Projectile: No +flags_Target: Range +inc_flags_Target: Other +inc_flags_Target: Self +exc_flags_Target: Dead +exc_flags_Target: Non-critter +mode_Target: Multi +mode_Target: Once-Multi +mode_Target: Any 30 Feet +mode_Target: End Early Multi +min_Target: 1 +max_Target: 0 +radius_Target: 0 +ai_type: ai_action_defensive +choices: 3001 3002 3003 3004 \ No newline at end of file diff --git a/tpdatasrc/tpgamefiles/rules/spells/1155 - Bless Weapon Swift.txt b/tpdatasrc/tpgamefiles/rules/spells/1155 - Bless Weapon Swift.txt new file mode 100644 index 000000000..156067f30 --- /dev/null +++ b/tpdatasrc/tpgamefiles/rules/spells/1155 - Bless Weapon Swift.txt @@ -0,0 +1,16 @@ +School: Transmutation +Level: Pal 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: Dead +exc_flags_Target: Non-critter +exc_flags_Target: Other +mode_Target: Personal +radius_Target: 0 +ai_type: ai_action_defensive \ No newline at end of file diff --git a/tpdatasrc/tpgamefiles/rules/spells/1160 - Align Weapon.txt b/tpdatasrc/tpgamefiles/rules/spells/1160 - Align Weapon.txt new file mode 100644 index 000000000..4dfd55da5 --- /dev/null +++ b/tpdatasrc/tpgamefiles/rules/spells/1160 - Align Weapon.txt @@ -0,0 +1,20 @@ +School: Transmutation +Level: Clr 2 +Component: V +Component: S +Casting Time: 1 action +Range: Touch +Saving Throw: None +Spell Resistance: No +Projectile: No +flags_Target: Range +inc_flags_Target: Other +inc_flags_Target: Self +exc_flags_Target: Dead +exc_flags_Target: Non-critter +mode_Target: Single +min_Target: 1 +max_Target: 1 +radius_Target: 0 +ai_type: ai_action_defensive +choices: 3001 3002 3003 3004 \ No newline at end of file diff --git a/tpdatasrc/tpgamefiles/rules/spells/1168 - Spikes.txt b/tpdatasrc/tpgamefiles/rules/spells/1168 - Spikes.txt new file mode 100644 index 000000000..41ce4a9e3 --- /dev/null +++ b/tpdatasrc/tpgamefiles/rules/spells/1168 - Spikes.txt @@ -0,0 +1,20 @@ +School: Transmutation +Level: Clr 3 +Level: Drd 3 +Component: V +Component: S +Casting Time: 1 action +Range: Touch +Saving Throw: None +Spell Resistance: No +Projectile: No +flags_Target: Range +inc_flags_Target: Other +inc_flags_Target: Self +exc_flags_Target: Dead +exc_flags_Target: Non-critter +mode_Target: Single +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/1170 - Weapon of Energy.txt b/tpdatasrc/tpgamefiles/rules/spells/1170 - Weapon of Energy.txt new file mode 100644 index 000000000..88d83f095 --- /dev/null +++ b/tpdatasrc/tpgamefiles/rules/spells/1170 - Weapon of Energy.txt @@ -0,0 +1,22 @@ +School: Transmutation +Level: Clr 3 +Level: Sor 3 +Level: Wiz 3 +Component: V +Component: S +Casting Time: 1 action +Range: Touch +Saving Throw: None +Spell Resistance: No +Projectile: No +flags_Target: Range +inc_flags_Target: Other +inc_flags_Target: Self +exc_flags_Target: Dead +exc_flags_Target: Non-critter +mode_Target: Single +min_Target: 1 +max_Target: 1 +radius_Target: 0 +ai_type: ai_action_defensive +choices: 3041 3042 3043 3044 diff --git a/tpdatasrc/tpgamefiles/scr/Spell039 - Bless Weapon.py b/tpdatasrc/tpgamefiles/scr/Spell039 - Bless Weapon.py new file mode 100644 index 000000000..094fee794 --- /dev/null +++ b/tpdatasrc/tpgamefiles/scr/Spell039 - Bless Weapon.py @@ -0,0 +1,32 @@ +from toee import * + +def OnBeginSpellCast(spell): + print "Bless Weapon OnBeginSpellCast" + print "spell.target_list=", spell.target_list + print "spell.caster=", spell.caster, " caster.level= ", spell.caster_level + +def OnSpellEffect(spell): + print "Bless Weapon OnSpellEffect" + + spell.duration = 10 * spell.caster_level + spellTarget = spell.target_list[0] + mainhandWeapon = spellTarget.obj.item_worn_at(item_wear_weapon_primary) + + if mainhandWeapon.obj_get_int(obj_f_type) == obj_t_weapon: + mainhandWeapon.d20_status_init() + if not mainhandWeapon.condition_add_with_args('sp-Bless Weapon', spell.id, spell.duration, 0): + spellTarget.obj.float_mesfile_line('mes\\spell.mes', 30000) + game.particles('Fizzle', spellTarget.obj) + else: + spellTarget.obj.float_text_line("Weapon required", tf_red) + game.particles('Fizzle', spellTarget.obj) + + spell.target_list.remove_target(spellTarget.obj) + spell.spell_end(spell.id) + +def OnBeginRound(spell): + print "Bless Weapon OnBeginRound" + +def OnEndSpellCast(spell): + print "Bless Weapon OnEndSpellCast" + diff --git a/tpdatasrc/tpgamefiles/scr/Spell1075 - Sonic Weapon.py b/tpdatasrc/tpgamefiles/scr/Spell1075 - Sonic Weapon.py new file mode 100644 index 000000000..993f5f7c6 --- /dev/null +++ b/tpdatasrc/tpgamefiles/scr/Spell1075 - Sonic Weapon.py @@ -0,0 +1,45 @@ +from toee import * + +def OnBeginSpellCast(spell): + print "Sonic Weapon OnBeginSpellCast" + print "spell.target_list=", spell.target_list + print "spell.caster=", spell.caster, " caster.level= ", spell.caster_level + +def OnSpellEffect(spell): + print "Sonic Weapon OnSpellEffect" + + spell.duration = 10 * spell.caster_level # 1 min/cl + spellTarget = spell.target_list[0] + radialChoice = spell.spell_get_menu_arg(RADIAL_MENU_PARAM_MIN_SETTING) + if radialChoice == 1: + itemToEnchant = spellTarget.obj.item_worn_at(item_wear_weapon_primary) + elif radialChoice == 2: + itemToEnchant = spellTarget.obj.item_worn_at(item_wear_weapon_secondary) + elif radialChoice == 3: + itemToEnchant = spellTarget.obj.item_worn_at(item_wear_ammo) + else: #Fallback + radialChoice == 1 + itemToEnchant = spellTarget.obj.item_worn_at(item_wear_weapon_primary) + + if radialChoice < 3: + if itemToEnchant.obj_get_int(obj_f_type) == obj_t_weapon: + itemToEnchant.d20_status_init() + if itemToEnchant.condition_add_with_args('sp-Sonic Weapon', spell.id, spell.duration, 0): + spellTarget.partsys_id = game.particles('sp-Sound Burst', spellTarget.obj) + else: + spellTarget.obj.float_mesfile_line('mes\\spell.mes', 30000) + game.particles('Fizzle', spellTarget.obj) + else: + spellTarget.obj.float_text_line("Weapon required", tf_red) + game.particles('Fizzle', spellTarget.obj) + else: + pass + + spell.target_list.remove_target(spellTarget.obj) + spell.spell_end(spell.id) + +def OnBeginRound(spell): + print "Sonic Weapon OnBeginRound" + +def OnEndSpellCast(spell): + print "Sonic Weapon OnEndSpellCast" \ No newline at end of file diff --git a/tpdatasrc/tpgamefiles/scr/Spell1103 - Dolorous Blow.py b/tpdatasrc/tpgamefiles/scr/Spell1103 - Dolorous Blow.py new file mode 100644 index 000000000..12c741c4d --- /dev/null +++ b/tpdatasrc/tpgamefiles/scr/Spell1103 - Dolorous Blow.py @@ -0,0 +1,35 @@ +from toee import * + +def OnBeginSpellCast(spell): + print "Dolorous Blow OnBeginSpellCast" + print "spell.target_list=", spell.target_list + print "spell.caster=", spell.caster, " caster.level= ", spell.caster_level + +def OnSpellEffect(spell): + print "Dolorous Blow OnSpellEffect" + + spell.duration = 10 * spell.caster_level # 1 min/cl + spellTarget = spell.target_list[0] + mainhandWeapon = spellTarget.obj.item_worn_at(item_wear_weapon_primary) + + if mainhandWeapon.obj_get_int(obj_f_type) == obj_t_weapon: + mainhandWeapon.d20_status_init() + if mainhandWeapon.condition_add_with_args('sp-Dolorous Blow', spell.id, spell.duration, 0): + spellTarget.partsys_id = game.particles('sp-True Strike', spellTarget.obj) + else: + spellTarget.obj.float_mesfile_line('mes\\spell.mes', 30000) + game.particles('Fizzle', spellTarget.obj) + spell.target_list.remove_target(spellTarget.obj) + else: + spell.caster.float_text_line("Weapon required", tf_red) + game.particles('Fizzle', spell.caster) + spell.target_list.remove_target(spellTarget.obj) + + spell.spell_end(spell.id) + + +def OnBeginRound(spell): + print "Dolorous Blow OnBeginRound" + +def OnEndSpellCast(spell): + print "Dolorous Blow OnEndSpellCast" \ No newline at end of file diff --git a/tpdatasrc/tpgamefiles/scr/Spell1115 - Deafening Clang.py b/tpdatasrc/tpgamefiles/scr/Spell1115 - Deafening Clang.py new file mode 100644 index 000000000..2dc8aecfb --- /dev/null +++ b/tpdatasrc/tpgamefiles/scr/Spell1115 - Deafening Clang.py @@ -0,0 +1,31 @@ +from toee import * + +def OnBeginSpellCast(spell): + print "Deafening Clang OnBeginSpellCast" + print "spell.target_list=", spell.target_list + print "spell.caster=", spell.caster, " caster.level= ", spell.caster_level + +def OnSpellEffect(spell): + print "Deafening Clang OnSpellEffect" + + spell.duration = 0 #current round + spellTarget = spell.target_list[0] + mainhandWeapon = spellTarget.obj.item_worn_at(item_wear_weapon_primary) + + if mainhandWeapon.obj_get_int(obj_f_type) == obj_t_weapon: + mainhandWeapon.d20_status_init() + mainhandWeapon.condition_add_with_args('sp-Deafening Clang', spell.id, spell.duration, spell.dc, 0) + spellTarget.partsys_id = game.particles('sp-Sound Burst', spellTarget.obj) + else: + spell.caster.float_text_line("Weapon required", tf_red) + game.particles('Fizzle', spell.caster) + + spell.target_list.remove_target(spellTarget.obj) + spell.spell_end(spell.id) + + +def OnBeginRound(spell): + print "Deafening Clang OnBeginRound" + +def OnEndSpellCast(spell): + print "Deafening Clang OnEndSpellCast" \ No newline at end of file diff --git a/tpdatasrc/tpgamefiles/scr/Spell1130 - Shield of Warding.py b/tpdatasrc/tpgamefiles/scr/Spell1130 - Shield of Warding.py new file mode 100644 index 000000000..358de1e77 --- /dev/null +++ b/tpdatasrc/tpgamefiles/scr/Spell1130 - Shield of Warding.py @@ -0,0 +1,33 @@ +from toee import * + +def OnBeginSpellCast(spell): + print "Shield of Warding OnBeginSpellCast" + print "spell.target_list=", spell.target_list + print "spell.caster=", spell.caster, " caster.level= ", spell.caster_level + +def OnSpellEffect(spell): + print "Shield of Warding OnSpellEffect" + + spell.duration = 10 * spell.caster_level # 1 min/cl + spellTarget = spell.target_list[0] + bonusValue = min ((1 + (spell.caster_level/5)), 5) + shieldItem = spellTarget.obj.item_worn_at(item_wear_shield) + + #check if a shield is equipped + if shieldItem.obj_get_int(obj_f_type) == obj_t_armor: + shieldItem.d20_status_init() + if not shieldItem.condition_add_with_args('sp-Shield of Warding', spell.id, spell.duration, bonusValue, 0): + spellTarget.obj.float_mesfile_line('mes\\spell.mes', 30000) + game.particles('Fizzle', spellTarget.obj) + else: + spellTarget.obj.float_text_line("Shield required", tf_red) + game.particles('Fizzle', spellTarget.obj) + + spell.target_list.remove_target(spellTarget.obj) + spell.spell_end(spell.id) + +def OnBeginRound(spell): + print "Shield of Warding OnBeginRound" + +def OnEndSpellCast(spell): + print "Shield of Warding OnEndSpellCast" \ No newline at end of file diff --git a/tpdatasrc/tpgamefiles/scr/Spell1134 - Undead Bane Weapon.py b/tpdatasrc/tpgamefiles/scr/Spell1134 - Undead Bane Weapon.py new file mode 100644 index 000000000..026b005d7 --- /dev/null +++ b/tpdatasrc/tpgamefiles/scr/Spell1134 - Undead Bane Weapon.py @@ -0,0 +1,32 @@ +from toee import * + +def OnBeginSpellCast(spell): + print "Undead Bane Weapon OnBeginSpellCast" + print "spell.target_list=", spell.target_list + print "spell.caster=", spell.caster, " caster.level= ", spell.caster_level + +def OnSpellEffect(spell): + print "Undead Bane Weapon OnSpellEffect" + + spell.duration = 600 * spell.caster_level # 1 hour/caster_level + spellTarget = spell.target_list[0] + mainhandWeapon = spellTarget.obj.item_worn_at(item_wear_weapon_primary) + + if mainhandWeapon.obj_get_int(obj_f_type) == obj_t_weapon: + mainhandWeapon.d20_status_init() + if not mainhandWeapon.condition_add_with_args('sp-Undead Bane Weapon', spell.id, spell.duration, 0): + spellTarget.obj.float_mesfile_line('mes\\spell.mes', 30000) + game.particles('Fizzle', spellTarget.obj) + else: + spellTarget.obj.float_text_line("Weapon required", tf_red) + game.particles('Fizzle', spellTarget.obj) + + spell.target_list.remove_target(spellTarget.obj) + spell.spell_end(spell.id) + +def OnBeginRound(spell): + print "Undead Bane Weapon OnBeginRound" + +def OnEndSpellCast(spell): + print "Undead Bane Weapon OnEndSpellCast" + diff --git a/tpdatasrc/tpgamefiles/scr/Spell1141 - Lawful Sword.py b/tpdatasrc/tpgamefiles/scr/Spell1141 - Lawful Sword.py new file mode 100644 index 000000000..c45a94913 --- /dev/null +++ b/tpdatasrc/tpgamefiles/scr/Spell1141 - Lawful Sword.py @@ -0,0 +1,35 @@ +from toee import * + +def OnBeginSpellCast(spell): + print "Lawful Sword OnBeginSpellCast" + print "spell.target_list=", spell.target_list + print "spell.caster=", spell.caster, " caster.level= ", spell.caster_level + +def OnSpellEffect(spell): + print "Lawful Sword OnSpellEffect" + + spell.duration = 1 * spell.caster_level + spellTarget = spell.target_list[0] + mainhandWeapon = spellTarget.obj.item_worn_at(item_wear_weapon_primary) + if mainhandWeapon.obj_get_int(obj_f_type) == obj_t_weapon: + if mainhandWeapon.obj_get_int(obj_f_weapon_flags) & OWF_RANGED_WEAPON: + spell.caster.float_text_line("Melee Weapon required", tf_red) + game.particles('Fizzle', spell.caster) + else: + mainhandWeapon.d20_status_init() + if not mainhandWeapon.condition_add_with_args('sp-Lawful Sword', spell.id, spell.duration, 0): + spellTarget.obj.float_mesfile_line('mes\\spell.mes', 30000) + game.particles('Fizzle', spellTarget.obj) + else: + spellTarget.obj.float_text_line("Weapon required", tf_red) + game.particles('Fizzle', spellTarget.obj) + + spell.target_list.remove_target(spellTarget.obj) + spell.spell_end(spell.id) + +def OnBeginRound(spell): + print "Lawful Sword OnBeginRound" + +def OnEndSpellCast(spell): + print "Lawful Sword OnEndSpellCast" + diff --git a/tpdatasrc/tpgamefiles/scr/Spell1149 - Brambles.py b/tpdatasrc/tpgamefiles/scr/Spell1149 - Brambles.py new file mode 100644 index 000000000..604a137d9 --- /dev/null +++ b/tpdatasrc/tpgamefiles/scr/Spell1149 - Brambles.py @@ -0,0 +1,42 @@ +from toee import * + +def OnBeginSpellCast(spell): + print "Brambles OnBeginSpellCast" + print "spell.target_list=", spell.target_list + print "spell.caster=", spell.caster, " caster.level= ", spell.caster_level + +def OnSpellEffect(spell): + print "Brambles OnSpellEffect" + + spell.duration = 1 * spell.caster_level + spellTarget = spell.target_list[0] + bonusDamage = min(spell.caster_level, 10) + mainhandWeapon = spellTarget.obj.item_worn_at(item_wear_weapon_primary) + + if mainhandWeapon == OBJ_HANDLE_NULL: + isWoodenMeleeWeapen = False + elif mainhandWeapon.obj_get_int(obj_f_weapon_flags) & OWF_RANGED_WEAPON: + isWoodenMeleeWeapen = False + elif mainhandWeapon.obj_get_int(obj_f_material) == mat_wood: + isWoodenMeleeWeapen = True + else: + isWoodenMeleeWeapen = False + + if isWoodenMeleeWeapen: + mainhandWeapon.d20_status_init() + if not mainhandWeapon.condition_add_with_args('sp-Brambles', spell.id, spell.duration, bonusDamage, 0): + spellTarget.obj.float_mesfile_line('mes\\spell.mes', 30000) + game.particles('Fizzle', spellTarget.obj) + else: + spellTarget.obj.float_text_line("Not a wooden melee weapon", tf_red) + game.particles('Fizzle', spellTarget.obj) + + spell.target_list.remove_target(spellTarget.obj) + spell.spell_end(spell.id) + +def OnBeginRound(spell): + print "Brambles OnBeginRound" + +def OnEndSpellCast(spell): + print "Brambles OnEndSpellCast" + diff --git a/tpdatasrc/tpgamefiles/scr/Spell1154 - Align Weapon Mass.py b/tpdatasrc/tpgamefiles/scr/Spell1154 - Align Weapon Mass.py new file mode 100644 index 000000000..435fb3e23 --- /dev/null +++ b/tpdatasrc/tpgamefiles/scr/Spell1154 - Align Weapon Mass.py @@ -0,0 +1,55 @@ +from toee import * + +def OnBeginSpellCast(spell): + print "Align Weapon Mass OnBeginSpellCast" + print "spell.target_list=", spell.target_list + print "spell.caster=", spell.caster, " caster.level= ", spell.caster_level + +def OnSpellEffect(spell): + print "Align Weapon Mass OnSpellEffect" + + targetsToRemove = [] + spell.duration = 10 * spell.caster_level + spellCasterAlignment = spell.caster.critter_get_alignment() + alignType = spell.spell_get_menu_arg(RADIAL_MENU_PARAM_MIN_SETTING) # 1 = Good; 2 = Evil; 3 = Lawful; 4 = Chaotic + if not alignType in range(1,5): #Fallback + alignType = 1 #sets it to good in fallback; alignType = game.random_range(1,4) would be a different option if a random type is prefered as a fallback + + if alignType == 1 and spellCasterAlignment & ALIGNMENT_EVIL: + passedAlignmentCheck = False + elif alignType == 2 and spellCasterAlignment & ALIGNMENT_GOOD: + passedAlignmentCheck = False + elif alignType == 3 and spellCasterAlignment & ALIGNMENT_CHAOTIC: + passedAlignmentCheck = False + elif alignType == 4 and spellCasterAlignment & ALIGNMENT_LAWFUL: + passedAlignmentCheck = False + else: + passedAlignmentCheck = True + + if passedAlignmentCheck: + for spellTarget in spell.target_list: + mainhandWeapon = spellTarget.obj.item_worn_at(item_wear_weapon_primary) + if mainhandWeapon.obj_get_int(obj_f_type) == obj_t_weapon: + mainhandWeapon.d20_status_init() + if not mainhandWeapon.condition_add_with_args('sp-Align Weapon', spell.id, spell.duration, alignType, 0): + spellTarget.obj.float_mesfile_line('mes\\spell.mes', 30000) + game.particles('Fizzle', spellTarget.obj) + else: + spellTarget.obj.float_text_line("Weapon required", tf_red) + game.particles('Fizzle', spellTarget.obj) + targetsToRemove.append(spellTarget.obj) + else: + for spellTarget in spell.target_list: + targetsToRemove.append(spellTarget.obj) + spell.caster.float_text_line("Wrong Alignment", tf_red) + game.particles('Fizzle', spell.caster) + + spell.target_list.remove_list(targetsToRemove) + spell.spell_end(spell.id) + +def OnBeginRound(spell): + print "Align Weapon Mass OnBeginRound" + +def OnEndSpellCast(spell): + print "Align Weapon Mass OnEndSpellCast" + diff --git a/tpdatasrc/tpgamefiles/scr/Spell1155 - Bless Weapon Swift.py b/tpdatasrc/tpgamefiles/scr/Spell1155 - Bless Weapon Swift.py new file mode 100644 index 000000000..ab5e36847 --- /dev/null +++ b/tpdatasrc/tpgamefiles/scr/Spell1155 - Bless Weapon Swift.py @@ -0,0 +1,32 @@ +from toee import * + +def OnBeginSpellCast(spell): + print "Bless Weapon Swift OnBeginSpellCast" + print "spell.target_list=", spell.target_list + print "spell.caster=", spell.caster, " caster.level= ", spell.caster_level + +def OnSpellEffect(spell): + print "Bless Weapon Swift OnSpellEffect" + + spell.duration = 0 + spellTarget = spell.target_list[0] + mainhandWeapon = spellTarget.obj.item_worn_at(item_wear_weapon_primary) + + if mainhandWeapon.obj_get_int(obj_f_type) == obj_t_weapon: + mainhandWeapon.d20_status_init() + if not mainhandWeapon.condition_add_with_args('sp-Bless Weapon', spell.id, spell.duration, 0): + spellTarget.obj.float_mesfile_line('mes\\spell.mes', 30000) + game.particles('Fizzle', spellTarget.obj) + else: + spellTarget.obj.float_text_line("Weapon required", tf_red) + game.particles('Fizzle', spellTarget.obj) + + spell.target_list.remove_target(spellTarget.obj) + spell.spell_end(spell.id) + +def OnBeginRound(spell): + print "Bless Weapon Swift OnBeginRound" + +def OnEndSpellCast(spell): + print "Bless Weapon Swift OnEndSpellCast" + diff --git a/tpdatasrc/tpgamefiles/scr/Spell1160 - Align Weapon.py b/tpdatasrc/tpgamefiles/scr/Spell1160 - Align Weapon.py new file mode 100644 index 000000000..d1d671eaf --- /dev/null +++ b/tpdatasrc/tpgamefiles/scr/Spell1160 - Align Weapon.py @@ -0,0 +1,51 @@ +from toee import * + +def OnBeginSpellCast(spell): + print "Align Weapon OnBeginSpellCast" + print "spell.target_list=", spell.target_list + print "spell.caster=", spell.caster, " caster.level= ", spell.caster_level + +def OnSpellEffect(spell): + print "Align Weapon OnSpellEffect" + + spell.duration = 10 * spell.caster_level + spellTarget = spell.target_list[0] + spellCasterAlignment = spell.caster.critter_get_alignment() + alignType = spell.spell_get_menu_arg(RADIAL_MENU_PARAM_MIN_SETTING) # 1 = Good; 2 = Evil; 3 = Lawful; 4 = Chaotic + if not alignType in range(1,5): #Fallback + alignType = 1 #sets it to good in fallback; alignType = game.random_range(1,4) would be a different option if a random type is prefered as a fallback + + if alignType == 1 and spellCasterAlignment & ALIGNMENT_EVIL: + passedAlignmentCheck = False + elif alignType == 2 and spellCasterAlignment & ALIGNMENT_GOOD: + passedAlignmentCheck = False + elif alignType == 3 and spellCasterAlignment & ALIGNMENT_CHAOTIC: + passedAlignmentCheck = False + elif alignType == 4 and spellCasterAlignment & ALIGNMENT_LAWFUL: + passedAlignmentCheck = False + else: + passedAlignmentCheck = True + + if passedAlignmentCheck: + mainhandWeapon = spellTarget.obj.item_worn_at(item_wear_weapon_primary) + if mainhandWeapon.obj_get_int(obj_f_type) == obj_t_weapon: + mainhandWeapon.d20_status_init() + if not mainhandWeapon.condition_add_with_args('sp-Align Weapon', spell.id, spell.duration, alignType, 0): + spellTarget.obj.float_mesfile_line('mes\\spell.mes', 30000) + game.particles('Fizzle', spellTarget.obj) + else: + spellTarget.obj.float_text_line("Weapon required", tf_red) + game.particles('Fizzle', spellTarget.obj) + else: + spell.caster.float_text_line("Wrong Alignment", tf_red) + game.particles('Fizzle', spell.caster) + + spell.target_list.remove_target(spellTarget.obj) + spell.spell_end(spell.id) + +def OnBeginRound(spell): + print "Align Weapon OnBeginRound" + +def OnEndSpellCast(spell): + print "Align Weapon OnEndSpellCast" + diff --git a/tpdatasrc/tpgamefiles/scr/Spell1168 - Spikes.py b/tpdatasrc/tpgamefiles/scr/Spell1168 - Spikes.py new file mode 100644 index 000000000..34f1534d3 --- /dev/null +++ b/tpdatasrc/tpgamefiles/scr/Spell1168 - Spikes.py @@ -0,0 +1,42 @@ +from toee import * + +def OnBeginSpellCast(spell): + print "Spikes OnBeginSpellCast" + print "spell.target_list=", spell.target_list + print "spell.caster=", spell.caster, " caster.level= ", spell.caster_level + +def OnSpellEffect(spell): + print "Spikes OnSpellEffect" + + spell.duration = 1 * spell.caster_level + spellTarget = spell.target_list[0] + bonusDamage = min(spell.caster_level, 10) + mainhandWeapon = spellTarget.obj.item_worn_at(item_wear_weapon_primary) + + if mainhandWeapon == OBJ_HANDLE_NULL: + isWoodenMeleeWeapen = False + elif mainhandWeapon.obj_get_int(obj_f_weapon_flags) & OWF_RANGED_WEAPON: + isWoodenMeleeWeapen = False + elif mainhandWeapon.obj_get_int(obj_f_material) == mat_wood: + isWoodenMeleeWeapen = True + else: + isWoodenMeleeWeapen = False + + if isWoodenMeleeWeapen: + mainhandWeapon.d20_status_init() + if not mainhandWeapon.condition_add_with_args('sp-Spikes', spell.id, spell.duration, bonusDamage, 0) + spellTarget.obj.float_mesfile_line('mes\\spell.mes', 30000) + game.particles('Fizzle', spellTarget.obj) + else: + spellTarget.obj.float_text_line("Not a wooden melee weapon", tf_red) + game.particles('Fizzle', spellTarget.obj) + + spell.target_list.remove_target(spellTarget.obj) + spell.spell_end(spell.id) + +def OnBeginRound(spell): + print "Spikes OnBeginRound" + +def OnEndSpellCast(spell): + print "Spikes OnEndSpellCast" + diff --git a/tpdatasrc/tpgamefiles/scr/Spell1170 - Weapon of Energy.py b/tpdatasrc/tpgamefiles/scr/Spell1170 - Weapon of Energy.py new file mode 100644 index 000000000..3e9bbf902 --- /dev/null +++ b/tpdatasrc/tpgamefiles/scr/Spell1170 - Weapon of Energy.py @@ -0,0 +1,38 @@ +from toee import * + +def OnBeginSpellCast(spell): + print "Weapon of Energy OnBeginSpellCast" + print "spell.target_list=", spell.target_list + print "spell.caster=", spell.caster, " caster.level= ", spell.caster_level + +def OnSpellEffect(spell): + print "Weapon of Energy OnSpellEffect" + + spell.duration = 1 * spell.caster_level + spellTarget = spell.target_list[0] + radialChoice = spell.spell_get_menu_arg(RADIAL_MENU_PARAM_MIN_SETTING) #1 = Acid, 2 = Cold, 3 = Electricity, 4 = Fire + mainhandWeapon = spellTarget.obj.item_worn_at(item_wear_weapon_primary) + + #Fallback for radialChoice + if not radialChoice in range(1,5): + radialChoice = game.random_range(1,4) + + #Check if mainhandWeapon is actually a weapon + if mainhandWeapon.obj_get_int(obj_f_type) == obj_t_weapon: + mainhandWeapon.d20_status_init() + if not mainhandWeapon.condition_add_with_args('sp-Weapon of Energy', spell.id, spell.duration, radialChoice, 0): + spellTarget.obj.float_mesfile_line('mes\\spell.mes', 30000) + game.particles('Fizzle', spellTarget.obj) + else: + spellTarget.obj.float_text_line("Weapon required", tf_red) + game.particles('Fizzle', spellTarget.obj) + + spell.target_list.remove_target(spellTarget.obj) + spell.spell_end(spell.id) + +def OnBeginRound(spell): + print "Weapon of Energy OnBeginRound" + +def OnEndSpellCast(spell): + print "Weapon of Energy OnEndSpellCast" + diff --git a/tpdatasrc/tpgamefiles/scr/spell_utils.py b/tpdatasrc/tpgamefiles/scr/spell_utils.py index 1414dab1f..540c244d3 100644 --- a/tpdatasrc/tpgamefiles/scr/spell_utils.py +++ b/tpdatasrc/tpgamefiles/scr/spell_utils.py @@ -240,6 +240,52 @@ def verifyItem(item, args): return item_loc == target_loc +# getItemObj, itemTooltip and itemEffectTooltip are needed for +# buff tooltip icon handling +def getItemObj(attachee, args): + itemLocation = args.get_arg(2) + if itemLocation == 203: #mainhand + item = attachee.item_worn_at(item_wear_weapon_primary) + itemWornAt = "mainhand" + elif itemLocation == 204: #offhand + item = attachee.item_worn_at(item_wear_weapon_secondary) + itemWornAt = "offhand" + elif itemLocation == 205: #armor + item = attachee.item_worn_at(item_wear_armor) + itemWornAt = "" + elif itemLocation == 211: #shield + item = attachee.item_worn_at(item_wear_shield) + itemWornAt = "" + return item, itemWornAt + +def itemTooltip(attachee, args, evt_obj): + item, itemWornAt = getItemObj(attachee, args) + spellId = args.get_arg(4) + durationQuery = item.d20_query_with_data("PQ_Item_Buff_Duration", spellId, 0) + if durationQuery: + duration = spellTime(durationQuery) + if args.get_param(0): + name = game.get_spell_mesline(args.get_param(0)) + else: + name = spellName(spellId) + evt_obj.append("{}({}) ({})".format(name, itemWornAt, duration)) + return 0 + +def itemEffectTooltip(attachee, args, evt_obj): + item, itemWornAt = getItemObj(attachee, args) + spellId = args.get_arg(4) + durationQuery = item.d20_query_with_data("PQ_Item_Buff_Duration", spellId, 0) + if durationQuery: + duration = spellTime(durationQuery) + if args.get_param(0): + name = game.get_spell_mesline(args.get_param(0)).upper().replace(" ", "_") + key = tpdp.hash(name) + else: + key = spellKey(spellId) + evt_obj.append(key, -2, "({}) ({})".format(itemWornAt, duration)) + return 0 + + ### Utilities for defining touch attacks with held charge ### # Keys off 'SPELL_NAME_CHARGE' so that a buff indicator for the holding diff --git a/tpdatasrc/tpgamefiles/scr/tpModifiers/sp_align_weapon.py b/tpdatasrc/tpgamefiles/scr/tpModifiers/sp_align_weapon.py new file mode 100644 index 000000000..af4ebeb23 --- /dev/null +++ b/tpdatasrc/tpgamefiles/scr/tpModifiers/sp_align_weapon.py @@ -0,0 +1,78 @@ +from templeplus.pymod import PythonModifier +from toee import * +import tpdp +from utilities import * +import spell_utils +print "Registering sp-Align Weapon" + +def alignWeaponSpellOnConditionAdd(attachee, args, evt_obj): + spellPacket = tpdp.SpellPacket(args.get_arg(0)) + spellPacket.add_target(attachee, 0) + attachee.item_condition_add_with_args('Weapon Align', 0, args.get_arg(2), 0, 0, args.get_arg(0)) + return 0 + +def alignWeaponSpellOnConditionRemove(attachee, args, evt_obj): + attachee.item_condition_remove('Weapon Align', args.get_arg(0)) + return 0 + +alignWeaponSpell = PythonModifier("sp-Align Weapon", 4) # spell_id, duration, alignType, empty +alignWeaponSpell.AddHook(ET_OnConditionAdd, EK_NONE, alignWeaponSpellOnConditionAdd,()) +alignWeaponSpell.AddHook(ET_OnConditionRemove, EK_NONE, alignWeaponSpellOnConditionRemove, ()) +alignWeaponSpell.AddHook(ET_OnD20Query, EK_Q_Critter_Has_Spell_Active, spell_utils.queryActiveSpell, ()) +alignWeaponSpell.AddHook(ET_OnD20Signal, EK_S_Killed, spell_utils.spellKilled, ()) +alignWeaponSpell.AddSpellDispelCheckStandard() +alignWeaponSpell.AddSpellTeleportPrepareStandard() +alignWeaponSpell.AddSpellTeleportReconnectStandard() +alignWeaponSpell.AddSpellCountdownStandardHook() + + +###### Align Weapon Condition ###### + +def weaponAlignOnDamage(attachee, args, evt_obj): + usedWeapon = evt_obj.attack_packet.get_weapon_used() + if not spell_utils.verifyItem(usedWeapon, args): + return 0 + #Check if weapon is already aligned + if evt_obj.damage_packet.attack_power & D20DAP_HOLY: + return 0 + elif evt_obj.damage_packet.attack_power & D20DAP_UNHOLY: + return 0 + elif evt_obj.damage_packet.attack_power & D20DAP_LAW: + return 0 + elif evt_obj.damage_packet.attack_power & D20DAP_CHAOS: + return 0 + + alignType = args.get_arg(1) + + if alignType == 1: + evt_obj.damage_packet.attack_power |= D20DAP_HOLY + game.particles('hit-HOLY-medium', evt_obj.attack_packet.target) + elif alignType == 2: + evt_obj.damage_packet.attack_power |= D20DAP_UNHOLY + game.particles('hit-UNHOLY-medium', evt_obj.attack_packet.target) + elif alignType == 3: + evt_obj.damage_packet.attack_power |= D20DAP_LAW + game.particles('hit-LAW-medium', evt_obj.attack_packet.target) + elif alignType == 4: + evt_obj.damage_packet.attack_power |= D20DAP_CHAOS + game.particles('hit-CHAOTIC-medium', evt_obj.attack_packet.target) + return 0 + +def weaponAlignGlowEffect(attachee, args, evt_obj): + usedWeapon = evt_obj.get_obj_from_args() + if not spell_utils.verifyItem(usedWeapon, args): + return 0 + alignType = args.get_arg(1) + if alignType == 1: + evt_obj.return_val = 7 + elif alignType == 2: + evt_obj.return_val = 10 + elif alignType == 3: + evt_obj.return_val = 8 + elif alignType == 4: + evt_obj.return_val = 4 + return 0 + +weaponAlign = PythonModifier("Weapon Align", 5) # empty, alignType, inventoryLocation, empty, spell_id +weaponAlign.AddHook(ET_OnDealingDamage, EK_NONE, weaponAlignOnDamage,()) +weaponAlign.AddHook(ET_OnWeaponGlowType, EK_NONE, weaponAlignGlowEffect, ()) diff --git a/tpdatasrc/tpgamefiles/scr/tpModifiers/sp_bless_weapon.py b/tpdatasrc/tpgamefiles/scr/tpModifiers/sp_bless_weapon.py new file mode 100644 index 000000000..d475270e2 --- /dev/null +++ b/tpdatasrc/tpgamefiles/scr/tpModifiers/sp_bless_weapon.py @@ -0,0 +1,79 @@ +from templeplus.pymod import PythonModifier +from toee import * +import tpdp +from utilities import * +import spell_utils +print "Registering sp-Bless Weapon" + +def blessWeaponSpellOnConditionAdd(attachee, args, evt_obj): + spellPacket = tpdp.SpellPacket(args.get_arg(0)) + spellPacket.add_target(attachee, 0) + attachee.item_condition_add_with_args('Weapon Bless', 0, 0, 0, 0, args.get_arg(0)) + return 0 + +def blessWeaponSpellConditionRemove(attachee, args, evt_obj): + attachee.item_condition_remove('Weapon Bless', args.get_arg(0)) + return 0 + +blessWeaponSpell = PythonModifier("sp-Bless Weapon", 3) # spell_id, duration, empty +blessWeaponSpell.AddHook(ET_OnConditionAdd, EK_NONE, blessWeaponSpellOnConditionAdd,()) +blessWeaponSpell.AddHook(ET_OnConditionRemove, EK_NONE, blessWeaponSpellConditionRemove, ()) +blessWeaponSpell.AddHook(ET_OnD20Query, EK_Q_Critter_Has_Spell_Active, spell_utils.queryActiveSpell, ()) +blessWeaponSpell.AddHook(ET_OnD20Signal, EK_S_Killed, spell_utils.spellKilled, ()) +blessWeaponSpell.AddSpellDispelCheckStandard() +blessWeaponSpell.AddSpellTeleportPrepareStandard() +blessWeaponSpell.AddSpellTeleportReconnectStandard() +blessWeaponSpell.AddSpellCountdownStandardHook() + +###### Bless Weapon Condition ###### + +def weaponBlessOnDamage(attachee, args, evt_obj): + usedWeapon = evt_obj.attack_packet.get_weapon_used() + if not spell_utils.verifyItem(usedWeapon, args): + return 0 + targetAlignment = evt_obj.attack_packet.target.critter_get_alignment() + if not evt_obj.damage_packet.attack_power & D20DAP_HOLY: + evt_obj.damage_packet.attack_power |= D20DAP_HOLY + game.particles('hit-HOLY-medium', evt_obj.attack_packet.target) + if targetAlignment & ALIGNMENT_EVIL: + if not evt_obj.damage_packet.attack_power & D20DAP_MAGIC: + evt_obj.damage_packet.attack_power |= D20DAP_MAGIC + return 0 + +def weaponBlessCheckThreatRange(attachee, args, evt_obj): + usedWeapon = evt_obj.attack_packet.get_weapon_used() + if not spell_utils.verifyItem(usedWeapon, args): + return 0 + appliedKeenRange = evt_obj.bonus_list.get_sum() + weaponKeenRange = usedWeapon.obj_get_int(obj_f_weapon_crit_range) + if appliedKeenRange == weaponKeenRange: + args.set_arg(1, 0) + else: + args.set_arg(1, 1) + return 0 + +def weaponBlessConfirmCrit(attachee, args, evt_obj): + usedWeapon = evt_obj.attack_packet.get_weapon_used() + targetAlignment = evt_obj.attack_packet.target.critter_get_alignment() + if not spell_utils.verifyItem(usedWeapon, args): + return 0 + if not targetAlignment & ALIGNMENT_EVIL: + return 0 + if args.get_arg(1): + return 0 + flags = evt_obj.attack_packet.get_flags() + flags |= D20CAF_CRITICAL + evt_obj.attack_packet.set_flags(flags) + return 0 + +def weaponBlessGlowEffect(attachee, args, evt_obj): + usedWeapon = evt_obj.get_obj_from_args() + if spell_utils.verifyItem(usedWeapon, args): + evt_obj.return_val = 7 + return 0 + +weaponBless = PythonModifier("Weapon Bless", 5) # empty, keenFlag, inventoryLocation, empty, spell_id +weaponBless.AddHook(ET_OnDealingDamage, EK_NONE, weaponBlessOnDamage,()) +weaponBless.AddHook(ET_OnGetCriticalHitRange, EK_NONE, weaponBlessCheckThreatRange,()) +weaponBless.AddHook(ET_OnConfirmCriticalBonus, EK_NONE, weaponBlessConfirmCrit,()) +weaponBless.AddHook(ET_OnWeaponGlowType, EK_NONE, weaponBlessGlowEffect, ()) diff --git a/tpdatasrc/tpgamefiles/scr/tpModifiers/sp_brambles.py b/tpdatasrc/tpgamefiles/scr/tpModifiers/sp_brambles.py new file mode 100644 index 000000000..ecabce4da --- /dev/null +++ b/tpdatasrc/tpgamefiles/scr/tpModifiers/sp_brambles.py @@ -0,0 +1,65 @@ +from templeplus.pymod import PythonModifier +from toee import * +import tpdp +from utilities import * +import spell_utils +print "Registering sp-Brambles" + +def bramblesSpellAddWeaponCondition(attachee, args, evt_obj): + spellPacket = tpdp.SpellPacket(args.get_arg(0)) + spellPacket.add_target(attachee, 0) + attachee.item_condition_add_with_args('Weapon Brambles', 0, args.get_arg(2), 0, 0, args.get_arg(0)) + return 0 + +def bramblesSpellWeaponConditionRemove(attachee, args, evt_obj): + attachee.item_condition_remove('Weapon Brambles', args.get_arg(0)) + return 0 + +bramblesSpell = PythonModifier("sp-Brambles", 4) # spell_id, duration, bonusDamage, empty +bramblesSpell.AddHook(ET_OnConditionAdd, EK_NONE, bramblesSpellAddWeaponCondition,()) +bramblesSpell.AddHook(ET_OnConditionRemove, EK_NONE, bramblesSpellWeaponConditionRemove, ()) +bramblesSpell.AddHook(ET_OnD20Query, EK_Q_Critter_Has_Spell_Active, spell_utils.queryActiveSpell, ()) +bramblesSpell.AddHook(ET_OnD20Signal, EK_S_Killed, spell_utils.spellKilled, ()) +bramblesSpell.AddSpellDispelCheckStandard() +bramblesSpell.AddSpellTeleportPrepareStandard() +bramblesSpell.AddSpellTeleportReconnectStandard() +bramblesSpell.AddSpellCountdownStandardHook() + +###### Brambles Weapon Condition ###### + +def bramblesWeaponConditionToHitBonus(attachee, args, evt_obj): + usedWeapon = evt_obj.attack_packet.get_weapon_used() + if spell_utils.verifyItem(usedWeapon, args): + bonusValue = 1 #Brambles grants a +1 enhancement bonus to the weapon + bonusType = 12 #ID 12 = Enhancement + evt_obj.bonus_list.add(bonusValue, bonusType, "~Enhancement~[TAG_ENHANCEMENT_BONUS] : ~Brambles~[TAG_SPELLS_BRAMBLES]") + return 0 + +def bramblesWeaponConditionBonusToDamage(attachee, args, evt_obj): + usedWeapon = evt_obj.attack_packet.get_weapon_used() + if not spell_utils.verifyItem(usedWeapon, args): + return 0 + weaponDamageType = attachee.obj_get_int(obj_f_weapon_attacktype) + if not weaponDamageType == D20DT_BLUDGEONING_AND_PIERCING: + if not weaponDamageType == D20DT_BLUDGEONING: + evt_obj.damage_packet.attack_power |= D20DAP_BLUDGEONING + if not weaponDamageType == D20DT_PIERCING: + evt_obj.damage_packet.attack_power |= D20DAP_PIERCING + if not evt_obj.damage_packet.attack_power & D20DAP_MAGIC: + evt_obj.damage_packet.attack_power |= D20DAP_MAGIC + bonusValue = args.get_arg(1) #Brambles grants a bonus equal to the casterlevel on damage (caps at 10) + bonusType = 12 #ID 12 = Enhancement + evt_obj.damage_packet.bonus_list.add(bonusValue, bonusType, "~Enhancement~[TAG_ENHANCEMENT_BONUS] : ~Brambles~[TAG_SPELLS_BRAMBLES]") + return 0 + +def bramblesWeaponConditionGlowEffect(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 = 1 + return 0 + +weaponBrambles = PythonModifier("Weapon Brambles", 5) # empty, bonusDamage, inventoryLocation, empty, spell_id +weaponBrambles.AddHook(ET_OnToHitBonus2, EK_NONE, bramblesWeaponConditionToHitBonus, ()) +weaponBrambles.AddHook(ET_OnDealingDamage, EK_NONE, bramblesWeaponConditionBonusToDamage,()) +weaponBrambles.AddHook(ET_OnWeaponGlowType, EK_NONE, bramblesWeaponConditionGlowEffect, ()) diff --git a/tpdatasrc/tpgamefiles/scr/tpModifiers/sp_deafening_clang.py b/tpdatasrc/tpgamefiles/scr/tpModifiers/sp_deafening_clang.py new file mode 100644 index 000000000..524249777 --- /dev/null +++ b/tpdatasrc/tpgamefiles/scr/tpModifiers/sp_deafening_clang.py @@ -0,0 +1,83 @@ +from templeplus.pymod import PythonModifier +from toee import * +import tpdp +from utilities import * +import spell_utils +print "Registering sp-Deafening Clang" + +def deafeningClangSpellOnConditionAdd(attachee, args, evt_obj): + spellPacket = tpdp.SpellPacket(args.get_arg(0)) + spellPacket.add_target(attachee, 0) + attachee.item_condition_add_with_args('Weapon Deafening Clang', 0, args.get_arg(2), 0, 0, args.get_arg(0)) + return 0 + +def deafeningClangSpellWeaponConditionRemove(attachee, args, evt_obj): + attachee.item_condition_remove('Weapon Deafening Clang', args.get_arg(0)) + return 0 + +deafeningClangSpell = PythonModifier("sp-Deafening Clang", 4) # spell_id, duration, spellDc, empty +deafeningClangSpell.AddHook(ET_OnConditionAdd, EK_NONE, deafeningClangSpellOnConditionAdd,()) +deafeningClangSpell.AddHook(ET_OnConditionRemove, EK_NONE, deafeningClangSpellWeaponConditionRemove, ()) +deafeningClangSpell.AddHook(ET_OnD20Query, EK_Q_Critter_Has_Spell_Active, spell_utils.queryActiveSpell, ()) +deafeningClangSpell.AddHook(ET_OnD20Signal, EK_S_Killed, spell_utils.spellKilled, ()) +deafeningClangSpell.AddSpellDispelCheckStandard() +deafeningClangSpell.AddSpellTeleportPrepareStandard() +deafeningClangSpell.AddSpellTeleportReconnectStandard() +deafeningClangSpell.AddSpellCountdownStandardHook() + +###### Deafening Clang Weapon Condition ###### + +def weaponDeafeningClangOnDamage(attachee, args, evt_obj): + usedWeapon = evt_obj.attack_packet.get_weapon_used() + if not spell_utils.verifyItem(usedWeapon, args): + return 0 + + target = evt_obj.attack_packet.target + spellPacket = tpdp.SpellPacket(args.get_arg(4)) + + #Apply extra sonic damage + damageDice = dice_new('1d6') + damageType = D20DT_SONIC + damageMesId = 3004 #ID 3001 added in damage.mes + evt_obj.damage_packet.add_dice(damageDice, damageType, damageMesId) + + #Handle deafened part of the spell + targetIsAlreadyDeaf = target.d20_query(Q_Critter_Is_Deafened) + if targetIsAlreadyDeaf: + return 0 + if target.saving_throw_spell(args.get_arg(1), D20_Save_Fortitude, D20STD_F_NONE, spellPacket.caster, args.get_arg(4)): #success + target.float_mesfile_line('mes\\spell.mes', 30001) + else: + target.float_mesfile_line('mes\\spell.mes', 30002) + if target.condition_add_with_args('sp-Deafness', 0, 10, 0): #sp-Deafness is permanent, no matter what duration you pass. + game.particles('sp-Blindness-Deafness', target) + target.condition_add_with_args('Deafening Clang Remove', 10) #helper condition to remove deafness after 1 min + else: + game.particles('Fizzle', target) + return 0 + +def weaponDeafeningClangGlowEffect(attachee, args, evt_obj): + usedWeapon = evt_obj.get_obj_from_args() + if spell_utils.verifyItem(usedWeapon, args): + evt_obj.return_val = 7 #There is no sonic weapon glow effect, using holy + return 1 + +weaponDeafeningClang = PythonModifier("Weapon Deafening Clang", 5) # empty, spellDc, inventoryLocation, empty, spell_id +weaponDeafeningClang.AddHook(ET_OnDealingDamage, EK_NONE, weaponDeafeningClangOnDamage,()) +weaponDeafeningClang.AddHook(ET_OnWeaponGlowType, EK_NONE, weaponDeafeningClangGlowEffect, ()) + +##### Deafening Clang Remove Deafness Helper Condition ##### + +def helperDeafeningClangOnRemove(attachee, args, evt_obj): + attachee.condition_add_with_args('sp-Remove Deafness', 0, 0, 0) + return 0 + +def helperDeafeningClangTickdown(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 + +helperDeafeningClang = PythonModifier("Deafening Clang Remove", 1) #duration +helperDeafeningClang.AddHook(ET_OnConditionRemove, EK_NONE, helperDeafeningClangOnRemove, ()) +helperDeafeningClang.AddHook(ET_OnBeginRound, EK_NONE, helperDeafeningClangTickdown, ()) \ No newline at end of file diff --git a/tpdatasrc/tpgamefiles/scr/tpModifiers/sp_dolorous_blow.py b/tpdatasrc/tpgamefiles/scr/tpModifiers/sp_dolorous_blow.py new file mode 100644 index 000000000..9ca356e11 --- /dev/null +++ b/tpdatasrc/tpgamefiles/scr/tpModifiers/sp_dolorous_blow.py @@ -0,0 +1,51 @@ +from templeplus.pymod import PythonModifier +from toee import * +import tpdp +from utilities import * +import spell_utils +print "Registering sp-Dolorous Blow" + +def dolorousBlowSpellOnConditionAdd(attachee, args, evt_obj): + attachee.item_condition_add_with_args('Weapon Dolorous Blow', 0, 0, 0, 0, args.get_arg(0)) + return 0 + +def dolorousBlowSpellWeaponConditionRemove(attachee, args, evt_obj): + attachee.item_condition_remove('Weapon Dolorous Blow', args.get_arg(0)) + return 0 + +dolorousBlowSpell = PythonModifier("sp-Dolorous Blow", 3) # spell_id, duration, empty +dolorousBlowSpell.AddHook(ET_OnConditionAdd, EK_NONE, dolorousBlowSpellOnConditionAdd,()) +dolorousBlowSpell.AddHook(ET_OnConditionRemove, EK_NONE, dolorousBlowSpellWeaponConditionRemove,()) +dolorousBlowSpell.AddHook(ET_OnD20Query, EK_Q_Critter_Has_Spell_Active, spell_utils.queryActiveSpell, ()) +dolorousBlowSpell.AddHook(ET_OnD20Signal, EK_S_Killed, spell_utils.spellKilled, ()) +dolorousBlowSpell.AddSpellDispelCheckStandard() +dolorousBlowSpell.AddSpellTeleportPrepareStandard() +dolorousBlowSpell.AddSpellTeleportReconnectStandard() +dolorousBlowSpell.AddSpellCountdownStandardHook() + +###### Dolorous Blow Weapon Condition ###### + +def weaponDolorousBlowModifyThreatRange(attachee, args, evt_obj): + usedWeapon = evt_obj.attack_packet.get_weapon_used() + if spell_utils.verifyItem(usedWeapon, args): + bonusValue = usedWeapon.obj_get_int(obj_f_weapon_crit_range) #Dolorous Blow doubles Threat Range + bonusType = 12 #ID 12 = Enhancement + evt_obj.bonus_list.add(bonusValue, bonusType, "~Dolorous Blow~[TAG_SPELLS_DOLORUS_BLOW] Bonus") + return 0 + +def weaponDolorousBlowAutoConfirmCrit(attachee, args, evt_obj): + usedWeapon = evt_obj.attack_packet.get_weapon_used() + if spell_utils.verifyItem(usedWeapon, args): + evt_obj.return_val = 1 + return 0 + +def weaponDolorousBlowGlowEffect(attachee, args, evt_obj): + usedWeapon = evt_obj.get_obj_from_args() + if spell_utils.verifyItem(usedWeapon, args): + evt_obj.return_val = 1 + return 1 + +weaponDolorousBlow = PythonModifier("Weapon Dolorous Blow", 5) # empty, empty, inventoryLocation, empty, spell_id +weaponDolorousBlow.AddHook(ET_OnGetCriticalHitRange, EK_NONE, weaponDolorousBlowModifyThreatRange,()) +weaponDolorousBlow.AddHook(ET_OnD20PythonQuery, "Always Confirm Criticals", weaponDolorousBlowAutoConfirmCrit,()) +weaponDolorousBlow.AddHook(ET_OnWeaponGlowType, EK_NONE, weaponDolorousBlowGlowEffect, ()) diff --git a/tpdatasrc/tpgamefiles/scr/tpModifiers/sp_lawful_sword.py b/tpdatasrc/tpgamefiles/scr/tpModifiers/sp_lawful_sword.py new file mode 100644 index 000000000..82c2c4d3b --- /dev/null +++ b/tpdatasrc/tpgamefiles/scr/tpModifiers/sp_lawful_sword.py @@ -0,0 +1,72 @@ +from templeplus.pymod import PythonModifier +from toee import * +import tpdp +from utilities import * +import spell_utils +print "Registering sp-Lawful Sword" + +def lawfulSwordSpellAddWeaponCondition(attachee, args, evt_obj): + spellPacket = tpdp.SpellPacket(args.get_arg(0)) + spellPacket.add_target(attachee, 0) + attachee.item_condition_add_with_args('Weapon Lawful Sword', 0, 0, 0, 0, args.get_arg(0)) + return 0 + +def lawfulSwordSpellWeaponConditionRemove(attachee, args, evt_obj): + attachee.item_condition_remove('Weapon Lawful Sword', args.get_arg(0)) + return 0 + +lawfulSwordSpell = PythonModifier("sp-Lawful Sword", 3) # spell_id, duration, empty +lawfulSwordSpell.AddHook(ET_OnConditionAdd, EK_NONE, lawfulSwordSpellAddWeaponCondition,()) +lawfulSwordSpell.AddHook(ET_OnConditionRemove, EK_NONE, lawfulSwordSpellWeaponConditionRemove, ()) +lawfulSwordSpell.AddHook(ET_OnD20Query, EK_Q_Critter_Has_Spell_Active, spell_utils.queryActiveSpell, ()) +lawfulSwordSpell.AddHook(ET_OnD20Signal, EK_S_Killed, spell_utils.spellKilled, ()) +lawfulSwordSpell.AddSpellDispelCheckStandard() +lawfulSwordSpell.AddSpellTeleportPrepareStandard() +lawfulSwordSpell.AddSpellTeleportReconnectStandard() +lawfulSwordSpell.AddSpellCountdownStandardHook() + +###### Lawful Sword Weapon Condition ###### + +def weaponLawfulSwordBonusToHit(attachee, args, evt_obj): + usedWeapon = evt_obj.attack_packet.get_weapon_used() + if spell_utils.verifyItem(usedWeapon, args): + bonusValue = 5 #Lawful Sword grants a +5 enhancement bonus to hit + bonusType = 12 #ID 12 = Enhancement + evt_obj.bonus_list.add(bonusValue, bonusType, "~Enhancement~[TAG_ENHANCEMENT_BONUS] : ~Lawful Sword~[TAG_SPELLS_LAWFUL_SWORD]") + return 0 + +def weaponLawfulSwordOnDamage(attachee, args, evt_obj): + usedWeapon = evt_obj.attack_packet.get_weapon_used() + if spell_utils.verifyItem(usedWeapon, args): + spellPacket = tpdp.SpellPacket(args.get_arg(0)) + target = evt_obj.attack_packet.target + targetAlignment = target.critter_get_alignment() + #Add enhancement bonus to damage + bonusValue = 5 #Lawful Sword grants a +5 enhancement bonus to damage + bonusType = 12 #ID 12 = Enhancement + evt_obj.damage_packet.bonus_list.add(bonusValue, bonusType, "~Enhancement~[TAG_ENHANCEMENT_BONUS] : ~Lawful Sword~[TAG_SPELLS_LAWFUL_SWORD]") + #Check if magic damage property needs to be added + if not evt_obj.damage_packet.attack_power & D20DAP_MAGIC: + evt_obj.damage_packet.attack_power |= D20DAP_MAGIC + #Check if Lawful damage property needs to be added + if not evt_obj.damage_packet.attack_power & D20DAP_LAW: + evt_obj.damage_packet.attack_power |= D20DAP_LAW + game.particles('hit-LAW-medium', evt_obj.attack_packet.target) + #Add extra damage if target is chaotic + if targetAlignment & ALIGNMENT_CHAOTIC: + damageDice = dice_new('1d6') + damageDice.number = 2 + damageType = D20DT_UNSPECIFIED + damageMesId = 3007 #ID 3007 added in damage.mes + evt_obj.damage_packet.add_dice(damageDice, damageType, damageMesId) + return 0 + +def weaponLawfulSwordGlowEffect(attachee, args, evt_obj): + usedWeapon = evt_obj.get_obj_from_args() + if spell_utils.verifyItem(usedWeapon, args): + evt_obj.return_val = 8 #Law Glow effect + return 0 +weaponLawfulSword = PythonModifier("Weapon Lawful Sword", 5) # empty, empty, inventoryLocation, empty, spell_id +weaponLawfulSword.AddHook(ET_OnToHitBonus2, EK_NONE, weaponLawfulSwordBonusToHit, ()) +weaponLawfulSword.AddHook(ET_OnDealingDamage, EK_NONE, weaponLawfulSwordOnDamage, ()) +weaponLawfulSword.AddHook(ET_OnWeaponGlowType, EK_NONE, weaponLawfulSwordGlowEffect, ()) diff --git a/tpdatasrc/tpgamefiles/scr/tpModifiers/sp_shield_of_warding.py b/tpdatasrc/tpgamefiles/scr/tpModifiers/sp_shield_of_warding.py new file mode 100644 index 000000000..8837b51be --- /dev/null +++ b/tpdatasrc/tpgamefiles/scr/tpModifiers/sp_shield_of_warding.py @@ -0,0 +1,38 @@ +from templeplus.pymod import PythonModifier +from toee import * +import tpdp +from utilities import * +import spell_utils +print "Registering sp-Shield of Warding" + +def shieldOfWardingSpellAddShieldCondition(attachee, args, evt_obj): + spellPacket = tpdp.SpellPacket(args.get_arg(0)) + spellPacket.add_target(attachee, 0) + attachee.item_condition_add_with_args('Shield of Warding Condition', args.get_arg(2), 0, 0, 0, args.get_arg(0)) + return 0 + +def shieldOfWardingSpellRemoveShieldCondition(attachee, args, evt_obj): + attachee.item_condition_remove('Shield of Warding Condition', args.get_arg(0)) + return 0 + +shieldOfWardingSpell = PythonModifier("sp-Shield of Warding", 4) # spell_id, duration, bonusValue, empty +shieldOfWardingSpell.AddHook(ET_OnConditionAdd, EK_NONE, shieldOfWardingSpellAddShieldCondition,()) +shieldOfWardingSpell.AddHook(ET_OnConditionRemove, EK_NONE, shieldOfWardingSpellRemoveShieldCondition, ()) +shieldOfWardingSpell.AddHook(ET_OnD20Query, EK_Q_Critter_Has_Spell_Active, spell_utils.queryActiveSpell, ()) +shieldOfWardingSpell.AddHook(ET_OnD20Signal, EK_S_Killed, spell_utils.spellKilled, ()) +shieldOfWardingSpell.AddSpellDispelCheckStandard() +shieldOfWardingSpell.AddSpellTeleportPrepareStandard() +shieldOfWardingSpell.AddSpellTeleportReconnectStandard() +shieldOfWardingSpell.AddSpellCountdownStandardHook() + +###### Shield of Warding Condition ###### +def shieldOfWardingConditionBonus(attachee, args, evt_obj): + if args.get_arg(2) == 211: #Shield needs to be equipped to have spell effects work + #Shield of Warding grants a bonus to AC and Reflex save; value(arg2) is passed by spell + bonusValue = args.get_arg(0) + bonusType = 153 #ID 153 Sacred; This might be wrong! + evt_obj.bonus_list.add(bonusValue, bonusType, "~Sacred~[TAG_MODIFIER_SACRED] : ~Shield of Warding~[TAG_SPELLS_SHIELD_OF_WARDING]") + +shieldOfWardingCondition = PythonModifier("Shield of Warding Condition", 5) # bonusValue, empty, inventoryLocation, empty, spell_id +shieldOfWardingCondition.AddHook(ET_OnSaveThrowLevel, EK_SAVE_REFLEX, shieldOfWardingConditionBonus, ()) +shieldOfWardingCondition.AddHook(ET_OnGetAC, EK_NONE, shieldOfWardingConditionBonus, ()) diff --git a/tpdatasrc/tpgamefiles/scr/tpModifiers/sp_sonic_weapon.py b/tpdatasrc/tpgamefiles/scr/tpModifiers/sp_sonic_weapon.py new file mode 100644 index 000000000..1077891a1 --- /dev/null +++ b/tpdatasrc/tpgamefiles/scr/tpModifiers/sp_sonic_weapon.py @@ -0,0 +1,66 @@ +from templeplus.pymod import PythonModifier +from toee import * +import tpdp +from utilities import * +import spell_utils +print "Registering sp-Sonic Weapon" + +def sonicWeaponSpellAddWeaponCondition(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 Sonic', 0, 0, 0, 0, spellId) + attachee.item_condition_add_with_args('Weapon Sonic Tooltip', 0, 0, 0, 0, spellId) + return 0 + +def sonicWeaponSpellDurationQuery(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 sonicWeaponSpellWeaponConditionRemove(attachee, args, evt_obj): + attachee.item_condition_remove('Weapon Sonic', args.get_arg(0)) + attachee.item_condition_remove('Weapon Sonic Tooltip', args.get_arg(0)) + return 0 + +sonicWeaponSpell = PythonModifier("sp-Sonic Weapon", 3) # spell_id, duration, empty +sonicWeaponSpell.AddHook(ET_OnConditionAdd, EK_NONE, sonicWeaponSpellAddWeaponCondition,()) +sonicWeaponSpell.AddHook(ET_OnD20PythonQuery, "PQ_Item_Buff_Duration", sonicWeaponSpellDurationQuery, ()) +sonicWeaponSpell.AddHook(ET_OnConditionRemove, EK_NONE, sonicWeaponSpellWeaponConditionRemove, ()) +sonicWeaponSpell.AddHook(ET_OnD20Query, EK_Q_Critter_Has_Spell_Active, spell_utils.queryActiveSpell, ()) +sonicWeaponSpell.AddHook(ET_OnD20Signal, EK_S_Killed, spell_utils.spellKilled, ()) +sonicWeaponSpell.AddSpellDispelCheckStandard() +sonicWeaponSpell.AddSpellTeleportPrepareStandard() +sonicWeaponSpell.AddSpellTeleportReconnectStandard() +sonicWeaponSpell.AddSpellCountdownStandardHook() + +#### Weapon Sonic Condition #### + +def weaponSonicOnDealingDamage(attachee, args, evt_obj): + usedWeapon = evt_obj.attack_packet.get_weapon_used() + if spell_utils.verifyItem(usedWeapon, args): + damageDice = dice_new('1d6') #Sonic Weapon Bonus Damage + damageType = D20DT_SONIC + damageMesId = 3001 #ID 3001 added in damage.mes + evt_obj.damage_packet.add_dice(damageDice, damageType, damageMesId) + return 0 + +def weaponSonicGlowType(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 = 7 #there is no sonic Weapon Glow in the game I think using holy for now + return 0 + +weaponSonic = PythonModifier("Weapon Sonic", 5) # empty, empty, inventoryLocation, empty, spell_id +weaponSonic.AddHook(ET_OnDealingDamage, EK_NONE, weaponSonicOnDealingDamage, ()) +weaponSonic.AddHook(ET_OnWeaponGlowType, EK_NONE, weaponSonicGlowType, ()) + + +#### Weapon Sonic Tooltip Condition #### + +weaponSonicToolTip = PythonModifier("Weapon Sonic Tooltip", 5) # empty, empty, inventoryLocation, empty, spellId +weaponSonicToolTip.AddHook(ET_OnGetTooltip, EK_NONE, spell_utils.itemTooltip, ()) +weaponSonicToolTip.AddHook(ET_OnGetEffectTooltip, EK_NONE, spell_utils.itemEffectTooltip, ()) diff --git a/tpdatasrc/tpgamefiles/scr/tpModifiers/sp_spikes.py b/tpdatasrc/tpgamefiles/scr/tpModifiers/sp_spikes.py new file mode 100644 index 000000000..e31bc368d --- /dev/null +++ b/tpdatasrc/tpgamefiles/scr/tpModifiers/sp_spikes.py @@ -0,0 +1,74 @@ +from templeplus.pymod import PythonModifier +from toee import * +import tpdp +from utilities import * +import spell_utils +print "Registering sp-Spikes" + +def spikesSpellAddWeaponCondition(attachee, args, evt_obj): + spellPacket = tpdp.SpellPacket(args.get_arg(0)) + spellPacket.add_target(attachee, 0) + attachee.item_condition_add_with_args('Weapon Spikes', 0, args.get_arg(2), 0, 0, args.get_arg(0)) + return 0 + +def spikesSpellWeaponConditionRemove(attachee, args, evt_obj): + attachee.item_condition_remove('Weapon Spikes', args.get_arg(0)) + return 0 + +spikesSpell = PythonModifier("sp-Spikes", 4) # spell_id, duration, bonusDamage, empty +spikesSpell.AddHook(ET_OnConditionAdd, EK_NONE, spikesSpellAddWeaponCondition,()) +spikesSpell.AddHook(ET_OnConditionRemove, EK_NONE, spikesSpellWeaponConditionRemove, ()) +spikesSpell.AddHook(ET_OnD20Query, EK_Q_Critter_Has_Spell_Active, spell_utils.queryActiveSpell, ()) +spikesSpell.AddHook(ET_OnD20Signal, EK_S_Killed, spell_utils.spellKilled, ()) +spikesSpell.AddSpellDispelCheckStandard() +spikesSpell.AddSpellTeleportPrepareStandard() +spikesSpell.AddSpellTeleportReconnectStandard() +spikesSpell.AddSpellCountdownStandardHook() + +###### Spikes Weapon Condition ###### + +def weaponSpikesToHitBonus(attachee, args, evt_obj): + usedWeapon = evt_obj.attack_packet.get_weapon_used() + if spell_utils.verifyItem(usedWeapon, args): + bonusValue = 2 #Spikes grants a +2 enhancement bonus to hit + bonusType = 12 #ID 12 = Enhancement + evt_obj.bonus_list.add(bonusValue, bonusType, "~Enhancement~[TAG_ENHANCEMENT_BONUS] : ~Spikes~[TAG_SPELLS_SPIKES]") + return 0 + +def weaponSpikesBonusToDamage(attachee, args, evt_obj): + usedWeapon = evt_obj.attack_packet.get_weapon_used() + if not spell_utils.verifyItem(usedWeapon, args): + return 0 + weaponDamageType = attachee.obj_get_int(obj_f_weapon_attacktype) + if not weaponDamageType == D20DT_BLUDGEONING_AND_PIERCING: + if not weaponDamageType == D20DT_BLUDGEONING: + evt_obj.damage_packet.attack_power |= D20DAP_BLUDGEONING + if not weaponDamageType == D20DT_PIERCING: + evt_obj.damage_packet.attack_power |= D20DAP_PIERCING + if not evt_obj.damage_packet.attack_power & D20DAP_MAGIC: + evt_obj.damage_packet.attack_power |= D20DAP_MAGIC + bonusValue = args.get_arg(1) #Spikes grants a bonus equal to the casterlevel on damage (caps at 10) + bonusType = 12 #ID 12 = Enhancement + evt_obj.damage_packet.bonus_list.add(bonusValue, bonusType, "~Enhancement~[TAG_ENHANCEMENT_BONUS] : ~Spikes~[TAG_SPELLS_SPIKES]") + return 0 + +def weaponSpikesModifyCritRange(attachee, args, evt_obj): + usedWeapon = evt_obj.attack_packet.get_weapon_used() + if spell_utils.verifyItem(usedWeapon, args): + bonusValue = usedWeapon.obj_get_int(obj_f_weapon_crit_range) #Spikes doubles Threat Range + bonusType = 12 #ID 12 = Enhancement + evt_obj.bonus_list.add(bonusValue, bonusType, "~Enhancement~[TAG_ENHANCEMENT_BONUS] : ~Spikes~[TAG_SPELLS_SPIKES]") + return 0 + +def weaponSpikesGlowEffect(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 = 1 + return 0 + +weaponSpikes = PythonModifier("Weapon Spikes", 5) # empty, bonusDamage, inventoryLocation, empty, spell_id +weaponSpikes.AddHook(ET_OnToHitBonus2, EK_NONE, weaponSpikesToHitBonus, ()) +weaponSpikes.AddHook(ET_OnDealingDamage, EK_NONE, weaponSpikesBonusToDamage, ()) +weaponSpikes.AddHook(ET_OnGetCriticalHitRange, EK_NONE, weaponSpikesModifyCritRange, ()) +weaponSpikes.AddHook(ET_OnWeaponGlowType, EK_NONE, weaponSpikesGlowEffect, ()) diff --git a/tpdatasrc/tpgamefiles/scr/tpModifiers/sp_undead_bane_weapon.py b/tpdatasrc/tpgamefiles/scr/tpModifiers/sp_undead_bane_weapon.py new file mode 100644 index 000000000..72c7bb0e1 --- /dev/null +++ b/tpdatasrc/tpgamefiles/scr/tpModifiers/sp_undead_bane_weapon.py @@ -0,0 +1,71 @@ +from templeplus.pymod import PythonModifier +from toee import * +import tpdp +from utilities import * +import spell_utils +print "Registering sp-Undead Bane Weapon" + +def undeadBaneWeaponSpellAddWeaponCondition(attachee, args, evt_obj): + spellPacket = tpdp.SpellPacket(args.get_arg(0)) + spellPacket.add_target(attachee, 0) + attachee.item_condition_add_with_args('Weapon Undead Bane', 0, 0, 0, 0, args.get_arg(0)) + return 0 + +def undeadBaneWeaponSpellWeaponConditionRemove(attachee, args, evt_obj): + attachee.item_condition_remove('Weapon Undead Bane', args.get_arg(0)) + return 0 + +undeadBaneWeaponSpell = PythonModifier("sp-Undead Bane Weapon", 3) # spell_id, duration, empty +undeadBaneWeaponSpell.AddHook(ET_OnConditionAdd, EK_NONE, undeadBaneWeaponSpellAddWeaponCondition,()) +undeadBaneWeaponSpell.AddHook(ET_OnConditionRemove, EK_NONE, undeadBaneWeaponSpellWeaponConditionRemove, ()) +undeadBaneWeaponSpell.AddHook(ET_OnD20Query, EK_Q_Critter_Has_Spell_Active, spell_utils.queryActiveSpell, ()) +undeadBaneWeaponSpell.AddHook(ET_OnD20Signal, EK_S_Killed, spell_utils.spellKilled, ()) +undeadBaneWeaponSpell.AddSpellDispelCheckStandard() +undeadBaneWeaponSpell.AddSpellTeleportPrepareStandard() +undeadBaneWeaponSpell.AddSpellTeleportReconnectStandard() +undeadBaneWeaponSpell.AddSpellCountdownStandardHook() + +###### Undead Bane Weapon Condition ###### + +def weaponUndeadBaneBonusToHit(attachee, args, evt_obj): + usedWeapon = evt_obj.attack_packet.get_weapon_used() + if spell_utils.verifyItem(usedWeapon, args): + target = evt_obj.attack_packet.target + if target.is_category_type(mc_type_undead): + bonusValue = 2 #Undead Bane Weapon grants an additional (stacking) +2 enhancement bonus if target is undead; I dont think I can query a weapons enhancement bonus so I will simply add +2 stacking + bonusType = 0 #ID 0 = Untyped (stacking) + evt_obj.bonus_list.add(bonusValue, bonusType, "~Undead Bane Weapon~[TAG_SPELLS_UNDEAD_BANE_WEAPON] Bonus") + + return 0 + +def weaponUndeadBaneOnDamage(attachee, args, evt_obj): + usedWeapon = evt_obj.attack_packet.get_weapon_used() + if spell_utils.verifyItem(usedWeapon, args): + target = evt_obj.attack_packet.target + #Add Holy property + if not evt_obj.damage_packet.attack_power & D20DAP_HOLY: + evt_obj.damage_packet.attack_power |= D20DAP_HOLY + if not target.is_category_type(mc_type_undead): + game.particles('hit-HOLY-medium', evt_obj.attack_packet.target) + #Add bonus damage if target is undead (2d6) + if target.is_category_type(mc_type_undead): + if not evt_obj.damage_packet.attack_power & D20DAP_MAGIC: + evt_obj.damage_packet.attack_power |= D20DAP_MAGIC + damageDice = dice_new('1d6') + damageDice.number = 2 + damageType = D20DT_UNSPECIFIED + damageMesId = 3006 #ID3006 added in damage.mes + evt_obj.damage_packet.add_dice(damageDice, damageType, damageMesId) + game.particles('hit-BANE-medium', evt_obj.attack_packet.target) + return 0 + +def undeadBaneWeaponConditionGlowEffect(attachee, args, evt_obj): + usedWeapon = evt_obj.get_obj_from_args() + if spell_utils.verifyItem(usedWeapon, args): + evt_obj.return_val = 7 #ID 7 = Holy + return 1 + +weaponUndeadBane = PythonModifier("Weapon Undead Bane", 5) # empty, empty, inventoryLocation, empty, spell_id +weaponUndeadBane.AddHook(ET_OnToHitBonus2, EK_NONE, weaponUndeadBaneBonusToHit, ()) +weaponUndeadBane.AddHook(ET_OnDealingDamage, EK_NONE, weaponUndeadBaneOnDamage, ()) +weaponUndeadBane.AddHook(ET_OnWeaponGlowType, EK_NONE, undeadBaneWeaponConditionGlowEffect, ()) diff --git a/tpdatasrc/tpgamefiles/scr/tpModifiers/sp_weapon_of_energy.py b/tpdatasrc/tpgamefiles/scr/tpModifiers/sp_weapon_of_energy.py new file mode 100644 index 000000000..1178573e3 --- /dev/null +++ b/tpdatasrc/tpgamefiles/scr/tpModifiers/sp_weapon_of_energy.py @@ -0,0 +1,97 @@ +from templeplus.pymod import PythonModifier +from toee import * +import tpdp +from utilities import * +import spell_utils +print "Registering sp-Weapon of Energy" + +def weaponOfEnergySpellAddWeaponCondition(attachee, args, evt_obj): + spellPacket = tpdp.SpellPacket(args.get_arg(0)) + spellPacket.add_target(attachee, 0) + attachee.item_condition_add_with_args('Weapon Energy', 0, args.get_arg(2), 0, 0, args.get_arg(0)) + return 0 + +def weaponOfEnergySpellWeaponConditionRemove(attachee, args, evt_obj): + attachee.item_condition_remove('Weapon Energy', args.get_arg(0)) + return 0 + +weaponOfEnergySpell = PythonModifier("sp-Weapon of Energy", 4) # spell_id, duration, elementType, empty +weaponOfEnergySpell.AddHook(ET_OnConditionAdd, EK_NONE, weaponOfEnergySpellAddWeaponCondition,()) +weaponOfEnergySpell.AddHook(ET_OnConditionRemove, EK_NONE, weaponOfEnergySpellWeaponConditionRemove, ()) +weaponOfEnergySpell.AddHook(ET_OnD20Query, EK_Q_Critter_Has_Spell_Active, spell_utils.queryActiveSpell, ()) +weaponOfEnergySpell.AddHook(ET_OnD20Signal, EK_S_Killed, spell_utils.spellKilled, ()) +weaponOfEnergySpell.AddSpellDispelCheckStandard() +weaponOfEnergySpell.AddSpellTeleportPrepareStandard() +weaponOfEnergySpell.AddSpellTeleportReconnectStandard() +weaponOfEnergySpell.AddSpellCountdownStandardHook() + +#### Weapon Energy Condition #### + +def getParticleEffect(elementType): + particleDict = { + 1:"hit-ACID-medium", + 2:"hit-COLD-medium", + 3:"hit-SHOCK-medium", + 4:"hit-FIRE-medium", + 5:"hit-ACID-heavy", + 6:"hit-COLD-Burst", + 7:"hit-SHOCK-burst", + 8:"hit-FIRE-burst" + } + return particleDict.get(elementType) + +def weaponEnergyOnDealingDamage(attachee, args, evt_obj): + usedWeapon = evt_obj.attack_packet.get_weapon_used() + if spell_utils.verifyItem(usedWeapon, args): + #Set damageType to chosen element + elementType = args.get_arg(1) + if elementType == 1: + damageType = D20DT_ACID + elif elementType == 2: + damageType = D20DT_COLD + elif elementType == 3: + damageType = D20DT_ELECTRICITY + elif elementType == 4: + damageType = D20DT_FIRE + else: + return 0 + #Add damage dice + damageDice = dice_new('1d6') + damageDice.number = 2 + damageMesId = 3008 #ID 3008 added in damage.mes + evt_obj.damage_packet.add_dice(damageDice, damageType, damageMesId) + #Handle Crit + isCritical = evt_obj.attack_packet.get_flags() & D20CAF_CRITICAL + if isCritical: + damageDiceBurst = dice_new('1d10') + critMultiplier = evt_obj.damage_packet.critical_multiplier + if critMultiplier > 3: #unsure if needed; D20SRD description ends at x4 + critMultiplier = 3 + damageDiceBurst.number = critMultiplier + evt_obj.damage_packet.add_dice(damageDiceBurst, damageType, damageMesId) + #Add particle effects + particleEffect = getParticleEffect(elementType) + game.particles("{}".format(particleEffect), evt_obj.attack_packet.target) + if isCritical: + elementType += 4 + particleCrit = getParticleEffect(elementType) + game.particles("{}".format(particleCrit), evt_obj.attack_packet.target) + return 0 + +def weaponEnergyGlowEffect(attachee, args, evt_obj): + usedWeapon = evt_obj.get_obj_from_args() + if spell_utils.verifyItem(usedWeapon, args): + elementType = args.get_arg(1) + if elementType == 1: #acid + evt_obj.return_val = 2 + elif elementType == 2: #cold + evt_obj.return_val = 5 + elif elementType == 3: #electricity + evt_obj.return_val = 9 + elif elementType == 4: #fire + evt_obj.return_val = 6 + return 0 + +weaponEnergy = PythonModifier("Weapon Energy", 5) # empty, elementType, inventoryLocation, empty, spell_id +weaponEnergy.AddHook(ET_OnDealingDamage, EK_NONE, weaponEnergyOnDealingDamage, ()) +weaponEnergy.AddHook(ET_OnWeaponGlowType, EK_NONE, weaponEnergyGlowEffect, ()) \ No newline at end of file