From 77426a2e14dbe584af811f922a6da3a48d74c074 Mon Sep 17 00:00:00 2001 From: DavidMWWallace Date: Tue, 21 May 2024 17:18:23 -0400 Subject: [PATCH] Collated v35.17 updates --- stratagems/caster_shared/triggers/trigger.2da | 2 +- stratagems/doc/readme-stratagems.html | 18 ++- .../doc/subdocuments_dw/changes_by_spell.html | 18 ++- .../doc/subdocuments_dw/spell_tweaks.html | 14 +- stratagems/initial/initial.tpa | 4 +- stratagems/initial/item_labels.tpa | 19 ++- stratagems/initial/mirror_image_aoe.tph | 135 ++++++++---------- stratagems/initial/mirror_image_aoe_old.tph | 80 +++++++++++ .../lang_som/english/extra_arcane_spells.tra | 6 +- stratagems/lang_som/english/spell.tra | 22 ++- stratagems/leveller/handle_thieves.tpa | 2 + stratagems/leveller/leveller_2.tpa | 15 +- stratagems/leveller/mage_spell_choices_2.tpa | 4 +- .../mage/ssl/combatblocks/areadenial.ssl | 1 + stratagems/setup-stratagems.tp2 | 2 +- stratagems/sfo2e/lib_cre.tph | 107 ++++++++++++++ stratagems/sfo2e/lib_data.tph | 9 ++ stratagems/sfo2e/lib_struct.tph | 12 +- stratagems/sfo2e/lua/data/onopen.ini | 10 +- stratagems/sfo2e/lua/ui_dual_class_kits.tph | 10 +- stratagems/sfo2e/lua/ui_spell_system.tph | 18 ++- stratagems/sfo2e/lua/ui_virtual_class.tph | 4 +- stratagems/spell/antimagic_penetrates_ii.tpa | 2 +- stratagems/spell/data/spelltweaks.2da | 2 + .../spell/data/spelltweaks_descriptions.ini | 13 +- stratagems/spell/glyph_save_for_half.tpa | 27 ++++ stratagems/spell/otiluke_save_for_half.tpa | 18 +++ stratagems/stratagems.ini | 2 + stratagems/test/test.tpa | 12 +- 29 files changed, 454 insertions(+), 134 deletions(-) create mode 100644 stratagems/initial/mirror_image_aoe_old.tph create mode 100644 stratagems/spell/glyph_save_for_half.tpa create mode 100644 stratagems/spell/otiluke_save_for_half.tpa diff --git a/stratagems/caster_shared/triggers/trigger.2da b/stratagems/caster_shared/triggers/trigger.2da index 9d4aed51..a836e8b2 100644 --- a/stratagems/caster_shared/triggers/trigger.2da +++ b/stratagems/caster_shared/triggers/trigger.2da @@ -20,7 +20,7 @@ PROTECTION_FROM_MAGIC_WEAPONS SHADOW_DOOR SPELL_IMMUNITY_DIVINA SECRET_WORD BREACH POWER_WORD_SILENCE * all * * * * dsp DISPEL_MAGIC GREATER_MALISON DEATH_SPELL * all * * * * dsp LOWER_RESISTANCE LOWER_RESISTANCE LOWER_RESISTANCE * all * * * * dsp -SUN_FIRE CLOUDKILL CLOUDKILL * invoker|fighter_mage * * lich|rakshasa * o +SUN_FIRE CLOUDKILL CLOUDKILL * invoker|fighter_mage * * lich|rakshasa * o CHAIN_LIGHTNING CHAIN_LIGHTNING CHAIN_LIGHTNING * invoker|fighter_mage|air * * * * o CHAIN_LIGHTNING CHAIN_LIGHTNING CHAOS * conjurer|fighter_mage|air * * * * o CONE_OF_COLD CONE_OF_COLD CONE_OF_COLD * invoker|fighter_mage|water * * * * o diff --git a/stratagems/doc/readme-stratagems.html b/stratagems/doc/readme-stratagems.html index dcb99249..584ffaa3 100644 --- a/stratagems/doc/readme-stratagems.html +++ b/stratagems/doc/readme-stratagems.html @@ -32,7 +32,7 @@

Sword Coast Stratagems

A Gibberlings Three Mod
Author: DavidW

-

Version 35.16
+

Version 35.17
Languages: English, French, German, Italian, Polish, Russian, Spanish, and Traditional Chinese.
Platforms: Windows, Linux (Enhanced Edition only), Mac OS X (Enhanced Edition only)

Sword Coast Stratagems (SCS @@ -2404,6 +2404,22 @@

Override files

+
  • Version 35.17 (21st May 2024) +
      +
    • Allied spellcasters no longer use Teleport Field.
    • +
    • NPC Customization and Management correctly skips certain characters (notably Hexxat and Caelar) who shouldn't be set to level zero.
    • +
    • Under-the-hood change: changed the function that handles area-effect spells bypassing Mirror Image (used on oBG2 installs) so it runs much faster (5 seconds rather than a couple of minutes).
    • +
    • Fixed a rather subtle bug that was messing with creatures' ability to see when an enemy is unaffected by their spells. The bug probably also caused occasional oBG2 crashes.
    • +
    • NPC Customization and Management correctly skips certain characters (notably Hexxat and Caelar) who shouldn't be set to level zero.
    • +
    • NPC Customization and Management now correctly displays the extra thief skill points you get when advancing to first level.
    • +
    • NPC Customization and Management now populates the spellbooks of generalist mages (including multi-classed and dual-classed mages) and wild mages.
    • +
    • NPC Customization and Management no longer removes character-specific innates (e.g. Minsc's Berserk ability).
    • +
    • Fixed some cosmetic issues in the descriptions of the new arcane spells.
    • +
    • Fixed some cosmetic issues in the changes to spell descriptions in the spell tweaks components.
    • +
    • New spell tweak: Otiluke's Freezing Sphere does half damage on a successful save.
    • +
    • New spell tweak: Gylph of Warding does half damage on a successful save (BG/BG2 only; this is already true on IWD).
    • +
    +
  • diff --git a/stratagems/doc/subdocuments_dw/changes_by_spell.html b/stratagems/doc/subdocuments_dw/changes_by_spell.html index 2e36a165..023d14a0 100644 --- a/stratagems/doc/subdocuments_dw/changes_by_spell.html +++ b/stratagems/doc/subdocuments_dw/changes_by_spell.html @@ -55,9 +55,6 @@

    Stratagems of Mystra: Changes by Spell

    Flame Blade

    The spell now does +1d4 fire damage rather than +2 (IWDEE; source)

    -

    Slow Poison

    -

    The spell now genuinely slows the effect of poison (reducing the speed of its effect by 90%) instead of neutralising it altogether. (BG1TUTU,BG2EE,BGEE,BGT,EET,SoA,ToB; not Spell Revisions; source)

    -

    Level 3 priest

    @@ -73,6 +70,12 @@

    Stratagems of Mystra: Changes by Spell

    Cure Medium Wounds

    The spell now heals 15 hit points, plus 1 per level to a maximum of 15. (not Spell Revisions; source)

    +

    Favor of the Martyr

    +

    This spell has been renamed from 'Favor of Ilmater' to 'Favor of the Martyr'. (source)

    + +

    Glyph of Warding

    +

    The glyph does half damage (rather than no damage) on a successful save. (BG1TUTU,BG2EE,BGEE,BGT,EET,SoA,ToB; not Spell Revisions; source)

    +

    Holy Smite

    The spell now does 1d4 damage per level, rather than 1d6 per two levels with a cap at 5d6. (IWDEE; source)

    @@ -136,7 +139,7 @@

    Stratagems of Mystra: Changes by Spell

    The spell inflicts 150 hit points of damage, but leaves its target with at least 1 hit point. (not Spell Revisions; source)

    Sol's Searing Orb

    -

    Sol's Searing Orb does 6d6 damage, not 3d6, and does not require a hit roll. (BG1TUTU,BG2EE,BGEE,BGT,EET,SoA,ToB; not Spell Revisions; source)

    +

    Sol's Searing Orb does 6d12 damage, not 3d6, and does not require a hit roll. (BG1TUTU,BG2EE,BGEE,BGT,EET; not Spell Revisions; source)

    Level 7 priest

    @@ -301,6 +304,9 @@

    Stratagems of Mystra: Changes by Spell

    Improved Haste

    Haste is cancelled by Slow. (BG2EE,BGEE,EET,IWDEE; not Spell Revisions; source)

    +

    Otiluke's Freezing Sphere

    +

    The sphere does half damage (rather than no damage) on a successful save. (source)

    +

    Pierce Magic

    This spell may be used to remove magical protections even from creatures which could not normally be targetted by spells because they are invisible. (source)

    @@ -344,13 +350,13 @@

    Stratagems of Mystra: Changes by Spell

    Level 8 wizard

    Abi-Dalzim's Horrid Wilting

    -

    The spell no longer affects earth/air/fire elementals, undead, constructs, and the like. (not Spell Revisions; source)

    +

    The spell no longer affects earth/air/fire elementals, undead, constructs, and the like. (BG2EE,BGEE,EET,IWDEE; not Spell Revisions; source)

    Improved Mantle

    The spell protects against weapons of +4 or lesser enchantment. (not Spell Revisions; source)

    Iron Body

    -

    The physical damage protection increases to 75% and the spell now imposes a -2 casting time penalty rather than blocking spellcasting outright. (source)

    +

    The physical damage protection increases to 75% and the spell now imposes a -2 casting time penalty rather than blocking spellcasting outright. (BG2EE,BGEE,EET,IWDEE; source)

    Pierce Shield

    This spell may be used to remove magical protections even from creatures which could not normally be targetted by spells because they are invisible. (source)

    diff --git a/stratagems/doc/subdocuments_dw/spell_tweaks.html b/stratagems/doc/subdocuments_dw/spell_tweaks.html index 74a78f5d..bafd4983 100644 --- a/stratagems/doc/subdocuments_dw/spell_tweaks.html +++ b/stratagems/doc/subdocuments_dw/spell_tweaks.html @@ -97,6 +97,8 @@

    Stratagems of Mystra: Changes by Category

    This tweak removes the automatic killing of summoned creatures from Death Fog and Death Spell, following Icewind Dale's model. Note that since Death Spell kills any creature of 8th level or below without a saving throw, the great majority of summons will still be killed by the spell. The swords summoned by Mordenkainen's Sword and the bears summoned by Conjure Animals have been slightly adjusted so as to be low enough level to be killed by Death Spell.

    Defensive Harmony increases AC by +4 instead of +2 (BG1TUTU,BG2EE,BGEE,BGT,EET,SoA,ToB; not Spell Revisions)

    +

    Glyph of Warding does half damage on a successful save (BG1TUTU,BG2EE,BGEE,BGT,EET,SoA,ToB; not Spell Revisions)

    +

    This component causes a Glyph of Warding to do half damage if the target saves vs. spells, rather than completely avoiding damage.

    Lower Resistance decreases resistance by 30% + 1%/level, not 10% + 1%/level (BG1TUTU,BG2EE,BGEE,BGT,EET,SoA,ToB; not Spell Revisions)

    Magical Stone does 3d4 damage (6d4 vs undead), rather than 1d4 (BG1TUTU,BG2EE,BGEE,BGT,EET,SoA,ToB; not Spell Revisions)

    @@ -105,9 +107,7 @@

    Stratagems of Mystra: Changes by Category

    Slay Living no longer requires a successful melee attack (BG1TUTU,BG2EE,BGEE,BGT,EET,SoA,ToB; not Spell Revisions)

    -

    Slow Poison now genuinely slows the effect of poison (reducing the speed of its effect by 90%) instead of neutralizing it altogether (BG1TUTU,BG2EE,BGEE,BGT,EET,SoA,ToB; not Spell Revisions)

    -

    -

    Sol's Searing Orb does 6d6 damage, not 3d6, and does not require a hit roll (BG1TUTU,BG2EE,BGEE,BGT,EET,SoA,ToB; not Spell Revisions)

    +

    Sol's Searing Orb does 6d12 damage, not 3d6, and does not require a hit roll (BG1TUTU,BG2EE,BGEE,BGT,EET; not Spell Revisions)

    Strength has a duration of 1 hour per level rather than 1 turn per level (BG1TUTU,BG2EE,BGEE,BGT,EET,SoA,ToB; not Spell Revisions)

    @@ -121,7 +121,7 @@

    Stratagems of Mystra: Changes by Category

    Rebalancings of slightly-too-powerful spells

    Tweaks in this section rebalance various slightly too-powerful spells. The enemy AI in Sword Coast Stratagems will sometimes behave a little oddly if this component is not installed.

    -

    Abi-Dalzim's Horrid Wilting does not affect undead, constructs, and (non-water) elementals (not Spell Revisions)

    +

    Abi-Dalzim's Horrid Wilting does not affect undead, constructs, and (non-water) elementals (BG2EE,BGEE,EET,IWDEE; not Spell Revisions)

    From its description, Horrid Wilting ought not to affect creatures with no moisture in their bodies. The actual spell, as implemented, affects basically everything (the IWD version does not affect undead). This component restricts the spell so as not to affect earth/air/fire elementals, undead, constructs and the like

    Note that the 'Telekinetic Storm' spell, introduced by the New Arcane Spells component, does affect all these creatures, at the cost of doing slightly less damage (1d6 per level, not 1d8). This should help fill the tactical hole left by this component's restrictions.

    Cap damage done by Skull Trap at 12d6 (not Spell Revisions)

    Skull Trap, like the other Level 3 spells Fireball and Lightning Bolt, does 1d6 damage per level. Unlike those spells, though (and, I suspect, via an oversight on the developers' part, though I could be wrong) Skull Trap's damage is not capped at 10d6, which makes it extremely lethal for a third level spell by the later part of the game. This component caps the damage of Skull Trap at 12d6 (the slightly higher cap reflects the much shorter range of Skull Trap compared to Fireball.

    @@ -187,8 +187,12 @@

    Stratagems of Mystra: Changes by Category

    The Cure and Cause Wounds families are very weak, especially at higher levels - it really isn't worth (e.g.) using a fourth-level cleric slot to heal 14 hit points or do the same amount of damage. This component increases the effectiveness of these spells somewhat (roughly following 3rd edition D&D): they heal (or cause) 5 hit points per level of the spell, plus a bonus amount equal to 1 per level of the caster but no more than 5 per level of the spell (so a maximum of 5 for Cure Light Wounds, but 20 for Cure Serious Wounds). For lore reasons, this is capped at 20th level on Baldur's Gate and Baldur's Gate II. (The exact amount of enhancement can be customized; see the main readme.)

    Larloch's Minor Drain becomes more powerful at higher levels (not Spell Revisions)

    The necromantic spell 'Larloch's Minor Drain' drains 1d4 hit points (in IWD) or 4 hit points (in BG/BG2) from the target and gives them to the caster. That's minor but not useless at first level, but it quickly becomes worthless at higher levels. This component makes the drain level-dependent: 1d4 at first level, increasing by 1d4 every two levels to a maximum of 5d4. That makes it roughly competitive with Magic Missile (the benefit that it heals the caster is offset against the slightly lower damage and the fact that it doesn't work on undead.)

    -

    Modified version of the Iron Body spell (does not prevent spellcasting)

    +

    Modified version of the Iron Body spell (does not prevent spellcasting) (BG2EE,BGEE,EET,IWDEE)

    Iron Body (an 8th level wizard spell introduced in IWD) is thematically cool but in practice not that useful: it gives moderately nice defensive boosts but they're not that exciting, and it shuts down spellcasting, making it useless to single-class wizards in most circumstances. This component improves the physical damage protection (to 75%) and replaces the outright block on spellcasting with a -2 casting speed penalty. This should make the spell a fairly powerful defensive choice - but it is 8th level, so that seems apposite.

    +

    Otiluke's Freezing Sphere does half damage on a successful save

    +

    This component causes the Freezing Sphere spell to do half damage if the target saves vs. spells, rather than completely dodging the sphere.

    +

    Rename 'Favor of Ilmater' to 'Favor of the Martyr'

    +

    This is a purely cosmetic change, intended to remove mismatches between an in-game character's faith and their memorized spells.

    Rename 'Mist of Eldath' to 'Healing Mist'

    This is a purely cosmetic change, intended to remove mismatches between an in-game character's faith and their memorized spells.

    Rename and tweak Shield of Lathander

    diff --git a/stratagems/initial/initial.tpa b/stratagems/initial/initial.tpa index 9723c4e8..0c911ed0 100644 --- a/stratagems/initial/initial.tpa +++ b/stratagems/initial/initial.tpa @@ -191,8 +191,8 @@ DEFINE_ACTION_FUNCTION initial BEGIN LAF detectable_spells INT_VAR skip_legacy=1 END // core DS - copy of the SoD version, adapted for SCS END CLEAR_IDS_MAP // make sure any DS changes to splstate/stats are logged - - LAF detectable_items END + + LAF detectable_items END LAF run STR_VAR file=detectcloud END LAF general_creature_patch END LAF run STR_VAR file=sim_compat END diff --git a/stratagems/initial/item_labels.tpa b/stratagems/initial/item_labels.tpa index 9efac063..d2b64411 100644 --- a/stratagems/initial/item_labels.tpa +++ b/stratagems/initial/item_labels.tpa @@ -87,15 +87,25 @@ BEGIN END BUT_ONLY + ACTION_PHP_EACH item_ds_array AS resref=>discard BEGIN COPY_EXISTING "%resref%" override LPF CLONE_EFFECT INT_VAR silent=1 STR_VAR match_function=match_ds_entry function=patch_ds_entry END END END - + LAF array_echo STR_VAR array=opcodelist END LAF array_read STR_VAR file="see_protection_spells.2da" path="%MOD_FOLDER%/ds" RET_ARRAY protection_spell_array=array END - ACTION_PHP_EACH protection_spell_array AS spell=>discard BEGIN - spl.edit[%spell%|allow_missing:i=1] + ACTION_PHP_EACH protection_spell_array AS protection_spell=>discard BEGIN + ACTION_IF VARIABLE_IS_SET "%protection_spell%" BEGIN + OUTER_SPRINT protection_spell "%%protection_spell%%" + END ELSE + ACTION_IF VARIABLE_IS_SET "WIZARD_%protection_spell%" BEGIN + OUTER_SPRINT protection_spell "%WIZARD_%protection_spell%%" + END ELSE + ACTION_IF VARIABLE_IS_SET "CLERIC_%protection_spell%" BEGIN + OUTER_SPRINT protection_spell "%CLERIC_%protection_spell%%" + END + spl.edit[%protection_spell%|allow_missing:i=1] [ IF {enhanced_edition} {{ @@ -103,12 +113,11 @@ BEGIN }} ELSE {{ - m.ab_fx.clone{LPF ds_item STR_VAR arguments="%s_opcode%" RET s_parameter2a=value END s_parameter2b=1 s_opcode=328 s_target=2 s_timing=0 s_duration=144 s_parameter1=1|match="VARIABLE_IS_SET $opcodelist(~%s_opcode%~)"} + m.ab_fx.clone{LPF ds_item STR_VAR arguments="%s_opcode%" RET s_parameter2a=value END s_parameter2b=1 s_opcode=318 s_target=2 s_timing=0 s_duration=144 s_parameter1=1|match="VARIABLE_IS_SET $opcodelist(~%s_opcode%~)"} }} ] END - END diff --git a/stratagems/initial/mirror_image_aoe.tph b/stratagems/initial/mirror_image_aoe.tph index 198b728b..bd85a5a7 100644 --- a/stratagems/initial/mirror_image_aoe.tph +++ b/stratagems/initial/mirror_image_aoe.tph @@ -1,80 +1,69 @@ DEFINE_ACTION_FUNCTION ~mirror_image_AoE~ BEGIN // unedited code -ACTION_FOR_EACH ~pronumber~ IN -~3~ //ARROWEX -~18~ //BULLETEX -~38~ //FIREBALL -~40~ //Lightning Bolt -~81~ //Call Lightning -~92~ //FIRESTOR -~95~ //CLOUD -~96~ //TRAPSKUL -~98~ //ICESTORM -~100~ //TRAPGLYP -~187~ //CLOUDKIL -~211~ //FIREBLNS -~213~ //LIGHTCHA -~223~ //CLOUDPC -~224~ //GOLCLOUD -~229~ //METSWARM -~230~ //INSEC3 -~232~ //INSEC4 -~234~ //PFIRE2 -~235~ // PSKULLT -~236~ //PCOMETT -~237~ //PWILT -~244~ //DFIREBL -~246~ //DRAGRED -~247~ //DRAGBLCK -~248~ //DRAGSILV -~250~ //CONECOLD -~251~ //PHOLYST -~252~ //PUNHLST -~253~ //BIGNAREA -~256~ //REDHIT -~258~ //PFIRE3 -~261~ //HOLYAREA -~262~ //UNLYAREA -~266~ //Comet -~270~ //SPDRBRTH -~272~ //DRAGGREE -~273~ //GREEHIT -~276~ //BURNHAND -BEGIN - OUTER_SPRINT $mirror_ignore(~%pronumber%~) ~~ -END + ACTION_FOR_EACH ~pronumber~ IN + ~3~ //ARROWEX + ~18~ //BULLETEX + ~38~ //FIREBALL + ~40~ //Lightning Bolt + ~81~ //Call Lightning + ~92~ //FIRESTOR + ~95~ //CLOUD + ~96~ //TRAPSKUL + ~98~ //ICESTORM + ~100~ //TRAPGLYP + ~187~ //CLOUDKIL + ~211~ //FIREBLNS + ~213~ //LIGHTCHA + ~223~ //CLOUDPC + ~224~ //GOLCLOUD + ~229~ //METSWARM + ~230~ //INSEC3 + ~232~ //INSEC4 + ~234~ //PFIRE2 + ~235~ // PSKULLT + ~236~ //PCOMETT + ~237~ //PWILT + ~244~ //DFIREBL + ~246~ //DRAGRED + ~247~ //DRAGBLCK + ~248~ //DRAGSILV + ~250~ //CONECOLD + ~251~ //PHOLYST + ~252~ //PUNHLST + ~253~ //BIGNAREA + ~256~ //REDHIT + ~258~ //PFIRE3 + ~261~ //HOLYAREA + ~262~ //UNLYAREA + ~266~ //Comet + ~270~ //SPDRBRTH + ~272~ //DRAGGREE + ~273~ //GREEHIT + ~276~ //BURNHAND + BEGIN + OUTER_SPRINT $mirror_ignore(~%pronumber%~) ~~ + END -ACTION_CLEAR_ARRAY patch_data -ACTION_DEFINE_ASSOCIATIVE_ARRAY patch_data BEGIN - match=>should_bypass_mirror - bypass_mirror_image=>1 -END + COPY_EXISTING_REGEXP "spwi304.*\.\(itm\|spl\)" override + PATCH_IF "%SOURCE_EXT%" STR_EQ "itm" BEGIN + GET_OFFSET_ARRAY ab_arr ITM_V10_HEADERS + pro_off=0x2a + END ELSE BEGIN + GET_OFFSET_ARRAY ab_arr SPL_V10_HEADERS + pro_off=0x26 + END + PHP_EACH ab_arr AS ab_ind=>ab_off BEGIN + pro=SHORT_AT (ab_off+pro_off) + PATCH_IF VARIABLE_IS_SET $mirror_ignore("%pro%") BEGIN + GET_OFFSET_ARRAY2 fx_arr ab_off SPL_V10_HEAD_EFFECTS + PHP_EACH fx_arr AS fx_ind=>fx_off BEGIN + WRITE_LONG (fx_off+0x24) (THIS BOR BIT24) + END + END + END + BUT_ONLY -LAF edit_all_spells STR_VAR editstring=~patch_effect=>patch_data~ END -LAF edit_all_items STR_VAR editstring=~patch_effect=>patch_data~ END -OUTER_FOR (i=5;i<10;i+=1) BEGIN - LAF edit_effect STR_VAR effect=~sp313l0%i%~ editstring=~bypass_mirror_image=>1~ END -END -OUTER_FOR (i=11;i<=20;i+=1) BEGIN - ACTION_IF FILE_EXISTS_IN_GAME ~sp313l%i%.eff~ BEGIN // because one is missing without FP - LAF edit_effect STR_VAR effect=~sp313l%i%~ editstring=~bypass_mirror_image=>1~ END - END -END -OUTER_FOR (i=14;i<=20;i+=1) BEGIN - LAF edit_effect STR_VAR effect=~sp707l%i%~ editstring=~bypass_mirror_image=>1~ END -END -END - -DEFINE_PATCH_FUNCTION should_bypass_mirror - RET value -BEGIN - LPF ~%file_ext%_read_projectile~ RET pronum=value END - PATCH_IF VARIABLE_IS_SET $mirror_ignore( ~%pronum%~) BEGIN - SET value=1 - END ELSE BEGIN - SET value=0 - END -END +END \ No newline at end of file diff --git a/stratagems/initial/mirror_image_aoe_old.tph b/stratagems/initial/mirror_image_aoe_old.tph new file mode 100644 index 00000000..77c8f4e5 --- /dev/null +++ b/stratagems/initial/mirror_image_aoe_old.tph @@ -0,0 +1,80 @@ +DEFINE_ACTION_FUNCTION ~mirror_image_AoE~ BEGIN // unedited code + +ACTION_FOR_EACH ~pronumber~ IN +~3~ //ARROWEX +~18~ //BULLETEX +~38~ //FIREBALL +~40~ //Lightning Bolt +~81~ //Call Lightning +~92~ //FIRESTOR +~95~ //CLOUD +~96~ //TRAPSKUL +~98~ //ICESTORM +~100~ //TRAPGLYP +~187~ //CLOUDKIL +~211~ //FIREBLNS +~213~ //LIGHTCHA +~223~ //CLOUDPC +~224~ //GOLCLOUD +~229~ //METSWARM +~230~ //INSEC3 +~232~ //INSEC4 +~234~ //PFIRE2 +~235~ // PSKULLT +~236~ //PCOMETT +~237~ //PWILT +~244~ //DFIREBL +~246~ //DRAGRED +~247~ //DRAGBLCK +~248~ //DRAGSILV +~250~ //CONECOLD +~251~ //PHOLYST +~252~ //PUNHLST +~253~ //BIGNAREA +~256~ //REDHIT +~258~ //PFIRE3 +~261~ //HOLYAREA +~262~ //UNLYAREA +~266~ //Comet +~270~ //SPDRBRTH +~272~ //DRAGGREE +~273~ //GREEHIT +~276~ //BURNHAND +BEGIN + OUTER_SPRINT $mirror_ignore(~%pronumber%~) ~~ +END + +ACTION_CLEAR_ARRAY patch_data +ACTION_DEFINE_ASSOCIATIVE_ARRAY patch_data BEGIN + match=>should_bypass_mirror + bypass_mirror_image=>1 +END + +LAF edit_all_spells STR_VAR editstring=~patch_effect=>patch_data~ END +LAF edit_all_items STR_VAR editstring=~patch_effect=>patch_data~ END + +OUTER_FOR (i=5;i<10;i+=1) BEGIN + LAF edit_effect STR_VAR effect=~sp313l0%i%~ editstring=~bypass_mirror_image=>1~ END +END +OUTER_FOR (i=11;i<=20;i+=1) BEGIN + ACTION_IF FILE_EXISTS_IN_GAME ~sp313l%i%.eff~ BEGIN // because one is missing without FP + LAF edit_effect STR_VAR effect=~sp313l%i%~ editstring=~bypass_mirror_image=>1~ END + END +END +OUTER_FOR (i=14;i<=20;i+=1) BEGIN + LAF edit_effect STR_VAR effect=~sp707l%i%~ editstring=~bypass_mirror_image=>1~ END +END + + +END + +DEFINE_PATCH_FUNCTION should_bypass_mirror + RET value +BEGIN + LPF ~%file_ext%_read_projectile~ RET pronum=value END + PATCH_IF VARIABLE_IS_SET $mirror_ignore( ~%pronum%~) BEGIN + SET value=1 + END ELSE BEGIN + SET value=0 + END +END diff --git a/stratagems/lang_som/english/extra_arcane_spells.tra b/stratagems/lang_som/english/extra_arcane_spells.tra index 8f53825f..c1fa0dfe 100644 --- a/stratagems/lang_som/english/extra_arcane_spells.tra +++ b/stratagems/lang_som/english/extra_arcane_spells.tra @@ -83,10 +83,10 @@ Weight: 0" (Evocation) Level: 9 -Range: visual range of the caster -Duration: instant +Range: Visual range of the caster +Duration: Instant Casting Time: 3 -Area of Effect: 60-ft. line +Area of Effect: 60 ft. line Saving Throw: Special A blue-white ray of freezing air and ice springs from the caster's hand. The ray inflicts 1d8 points of cold damage per level of the caster to any creature caught in the ray, and freezes the creature in place for one round. A successful save vs. spell at a -2 penalty halves the damage and negates the freezing effect." diff --git a/stratagems/lang_som/english/spell.tra b/stratagems/lang_som/english/spell.tra index 70531a9c..b2f0bfa7 100644 --- a/stratagems/lang_som/english/spell.tra +++ b/stratagems/lang_som/english/spell.tra @@ -404,7 +404,7 @@ The combat protection spells dispelled by Breach are" @3700 = ~ -Note: This spell may be used to remove magical protections even from creatures which could not normally be targetted by spells because they are invisible.~ +Note: This spell may be used to remove magical protections even from creatures which could not normally be targetted by spells because they are invisible. ~ // space at end is intentional, it plays nicer with other description appending @5000 = ~Insect Plague (Conjuration/Summoning) @@ -792,7 +792,23 @@ Saving Throw: Special This spell unleashes an acidic downpour on the area of effect. The victim initially suffers 10d6 points of acid damage, with no saving throw. After the initial damage, the victim must save vs. Spell to avoid more damage. If unsuccessful, the victim continues to suffer acid damage in the following rounds, sustaining two fewer dice of damage each round: that is, 8d6 damage with this spell on the first round, 6d6 on the second round, 4d6 on the third round, 2d6 on the fourth round, and the spell ends on the fifth round. Another saving throw is permitted each round to negate the effect. Moving out of the area of effect does not stop the damage.~ -@40014 = ~This spell will also destroy the anti-magic sphere created by a Protection from Magic scroll, or by the Antimagic Shell spell.~ +@40014 = ~This spell will also destroy the anti-magic sphere created by a Protection from Magic scroll.~ + +@40015= "Otiluke's Freezing Sphere +(Alteration, Evocation) + +Level: 6 +Range: Visual range of the caster +Duration: Instant +Casting Time: 6 +Area of Effect: 1 creature +Saving Throw: 1/2 + +This spell fires an orb of cold at a creature that inflicts 1d4+2 points of cold damage per level of the caster, with a saving throw vs. spell for half damage." + +@40016="Saving Throw:" // must be formatted as in spell descriptions +@40017="Saving Throw: 1/2" + @40100 = "Impervious Sanctity of Mind (Abjuration) @@ -857,7 +873,7 @@ Casting Time: 9 Area of Effect: Special Saving Throw: None -With the casting of this spell, the wizard calls forth 1d2 boneguards. These undead monstrosities appear within spell range and can be commanded to attack the caster's opponents until the spell duration expires or the monsters are destoyed." +With the casting of this spell, the wizard calls forth 1d2 boneguards. These undead monstrosities appear within spell range and can be commanded to attack the caster's opponents until the spell duration expires or the monsters are destroyed." @40402="Boneguard" @40500="Thorn Spray diff --git a/stratagems/leveller/handle_thieves.tpa b/stratagems/leveller/handle_thieves.tpa index 97773aa2..5293d7a2 100644 --- a/stratagems/leveller/handle_thieves.tpa +++ b/stratagems/leveller/handle_thieves.tpa @@ -129,7 +129,9 @@ DEFINE_PATCH_FUNCTION thief_sub BEGIN REPLACE_TEXTUALLY EXACT_MATCH ~createCharScreen:OnThiefSkillPlusMinusButtonClick(chargen.thief_skill[currentChargenThiefSkill].id, true)~ ~dw_thiefskill_add(currentChargenThiefSkill)~ REPLACE_TEXTUALLY EXACT_MATCH ~createCharScreen:OnThiefSkillPlusMinusButtonClick(chargen.thief_skill[currentChargenThiefSkill].id, false)~ ~dw_thiefskill_subtract(currentChargenThiefSkill)~ REPLACE_TEXTUALLY EXACT_MATCH ~text lua "chargen.thief_skill[rowNumber].value"~ ~text lua "dw_thiefskill_value(rowNumber)"~ + REPLACE_TEXTUALLY EXACT_MATCH ~text lua "dwFilterKitDesc(chargen.thief_skill[rowNumber].value)"~ ~text lua "dw_thiefskill_value(rowNumber)"~ REPLACE_TEXTUALLY EXACT_MATCH ~text lua "chargen.extraSkillPoints"~ ~text lua "dw_thiefskill_extra_points()"~ + REPLACE_TEXTUALLY EXACT_MATCH ~text lua "dwFilterKitDesc(chargen.extraSkillPoints)"~ ~text lua "dw_thiefskill_extra_points()"~ REPLACE_TEXTUALLY EXACT_MATCH ~clickable lua "createCharScreen:IsDoneButtonClickable()"~ ~clickable lua "dw_thief_skills_finished()"~ END diff --git a/stratagems/leveller/leveller_2.tpa b/stratagems/leveller/leveller_2.tpa index b8fac3e1..3385a125 100644 --- a/stratagems/leveller/leveller_2.tpa +++ b/stratagems/leveller/leveller_2.tpa @@ -49,13 +49,17 @@ DEFINE_ACTION_FUNCTION leveller_2 BEGIN // sort out NPCs + // read in the list of NPCs who don't get set to level zero + + LAF 2da_read STR_VAR file=level_zero_exclude.2da location=data case=lower RET_ARRAY exclude_array=rows END + COPY_EXISTING_REGEXP - GLOB ~.*\.cre~ nowhere PATCH_TRY SPRINT filename "%SOURCE_RES%" READ_ASCII DEATHVAR dv (0x20) NULL TO_LOWER dv - PATCH_IF VARIABLE_IS_SET $sfo_joinable_dvs("%dv%") BEGIN + PATCH_IF VARIABLE_IS_SET $sfo_joinable_dvs("%dv%") && !VARIABLE_IS_SET $exclude_array("%dv%") BEGIN PATCH_MATCH "%filename%" WITH cebear01 ttbran ttimoen ttjaheir ttminsc ttxan arkani cander deder mordai osprey charbase aerbod01 BEGIN END @@ -352,17 +356,14 @@ BEGIN WRITE_LONG 0x18 0 // con LPF ADD_CRE_EFFECT INT_VAR opcode=10 target=2 timing=0 duration=9999999 parameter1=10 parameter2=1 STR_VAR effsource="DW#AULE3" END - // remove spells from sorcerers and shamans - PATCH_IF "%class%" STR_EQ "SHAMAN" || "%class%" STR_EQ "SORCERER" BEGIN - REMOVE_KNOWN_SPELLS - END + // remove spells + LPF cre_delete_spells_of_type INT_VAR core_namespace_only=1 STR_VAR arguments="wizard priest" END + // thief skills+lore WRITE_BYTE 0x45 0 FOR (offset=0x64;offset<=0x6a;++offset) BEGIN WRITE_BYTE offset 0 END - // spells - REMOVE_MEMORIZED_SPELLS // mark to autogain spells (it's harmless to give it to everyone and it makes things easier for the customization tool) LPF ADD_CRE_EFFECT INT_VAR opcode=328 special=1 target=1 timing=9 parameter2=stat_ind STR_VAR effsource="DW#AUSP" END // ranger profs diff --git a/stratagems/leveller/mage_spell_choices_2.tpa b/stratagems/leveller/mage_spell_choices_2.tpa index af9283f9..9b79ee2b 100644 --- a/stratagems/leveller/mage_spell_choices_2.tpa +++ b/stratagems/leveller/mage_spell_choices_2.tpa @@ -41,7 +41,7 @@ DEFINE_ACTION_FUNCTION mage_spell_choices_2 BEGIN LAF ini_read STR_VAR file=spellchoices.ini location=data RET_ARRAY spellbook_array=array END // make the core resources - ACTION_FOR_EACH type IN abjurer conjurer diviner enchanter illusionist invoker necromancer transmuter BEGIN + ACTION_FOR_EACH type IN abjurer conjurer diviner enchanter illusionist invoker necromancer transmuter generalist BEGIN LAF spellbook_maker STR_VAR type END END @@ -141,7 +141,7 @@ BEGIN CREATE spl "%base%%level%" LPF add_basic_spell_ability END PATCH_IF "%type%" STR_EQ "generalist" BEGIN - LPF ADD_SPELL_EFFECT INT_VAR opcode=318 target=2 timing=0 duration=1 parameter1=RESOLVE_STR_REF (class SORCERER) parameter2=105 STR_VAR resource="%base%%level%" END + LPF ADD_SPELL_EFFECT INT_VAR opcode=318 target=2 timing=0 duration=1 parameter1=IDS_OF_SYMBOL (class SORCERER) parameter2=105 STR_VAR resource="%base%%level%" END END LPF ADD_SPELL_EFFECT INT_VAR opcode=318 target=2 timing=0 duration=1 parameter1=stat_ind parameter2=111 STR_VAR resource="%base%%level%" END WHILE "%list%" STR_CMP "" BEGIN diff --git a/stratagems/mage/ssl/combatblocks/areadenial.ssl b/stratagems/mage/ssl/combatblocks/areadenial.ssl index b2d3ad45..962b7c5a 100644 --- a/stratagems/mage/ssl/combatblocks/areadenial.ssl +++ b/stratagems/mage/ssl/combatblocks/areadenial.ssl @@ -142,6 +142,7 @@ IF TRIGGER !AreaCheck("ar2300") // Sahuagin city (ditto) !AreaCheck("ar2202") // drow pitfight (ditto) !GlobalTimerNotExpired("redefend","LOCALS") + TriggerBlock(Enemy) THEN DO Combine() SetGlobalTimer("teleportfield","LOCALS",30) diff --git a/stratagems/setup-stratagems.tp2 b/stratagems/setup-stratagems.tp2 index e1cb72ef..f1c2bcdf 100644 --- a/stratagems/setup-stratagems.tp2 +++ b/stratagems/setup-stratagems.tp2 @@ -1,7 +1,7 @@ BACKUP ~weidu_external/backup/stratagems~ AUTHOR ~For help troubleshooting installation problems, go to the Sword Coast Stratagems forum at gibberlings3.net.~ //MODDER setup_tra none area_variables none missing_extern none missing_resref none ict2_actions none missing_eval none overwriting_file none fun_args warn -VERSION ~35.16~ +VERSION ~35.17~ README ~stratagems/doc/readme-stratagems.html~ AUTO_EVAL_STRINGS diff --git a/stratagems/sfo2e/lib_cre.tph b/stratagems/sfo2e/lib_cre.tph index 800ec2f7..e75fff7c 100644 --- a/stratagems/sfo2e/lib_cre.tph +++ b/stratagems/sfo2e/lib_cre.tph @@ -1174,3 +1174,110 @@ BEGIN END WRITE_LONG 0x244 value END + + +///////////////////////////////////////////// +/* +document{cre_delete_spells_of_type} +{ +NOT a struct function. +Deletes all spells of given type(s) in the CRE file. 'arguments' should be a space-separated (case-insensitive) list containing one or more of 'wizard', 'priest', or 'innate' + +If core_namespace_only=1, require spells to be in the SPPR/SPWI/SPIN/SPCL namespace. + +By default we delete both known and memorized spells. Set known=0 or memorized=0 to override. +} + +*/ +/////////////////////////////////////////////////// + +DEFINE_PATCH_FUNCTION cre_delete_spells_of_type + INT_VAR core_namespace_only=0 + known=1 + memorized=1 + STR_VAR arguments="" +BEGIN + // parse arguments + + PATCH_IF "%arguments%" STR_EQ "" BEGIN + PATCH_WARN "cre_delete_spells_of_type: argument is empty" + END + wizard=0 + priest=0 + innate=0 + WHILE "%arguments%" STR_CMP "" BEGIN + LPF return_first_entry STR_VAR list="%arguments%" RET entry arguments=list END + TO_LOWER entry + PATCH_MATCH "%entry%" WITH + wizard priest innate BEGIN + SET "%entry%"=1 + END + DEFAULT + PATCH_FAIL "Illegal argument %entry% in cre_delete_spells_of_type" + END + END + // main pass - memorized spells + PATCH_IF memorized BEGIN + any_memorized=0 + GET_OFFSET_ARRAY info_arr CRE_V10_SPELL_MEM_INFO + PHP_EACH info_arr AS info_ind=>info_off BEGIN + type=SHORT_AT (0x6+info_off) + PATCH_IF (type=0 && wizard) || (type=1 && priest) || (type=2 && innate) BEGIN + GET_OFFSET_ARRAY2 spl_arr info_off CRE_V10_SPELL_MEM + PHP_EACH spl_arr AS spl_ind=>spl_off BEGIN + PATCH_IF core_namespace_only BEGIN + READ_ASCII spl_off init (4) + PATCH_MATCH "%init%" WITH + SPPR SPWI SPIN SPCL BEGIN + proceed=1 + END + DEFAULT + proceed=0 + END + END ELSE BEGIN + proceed=1 + END + PATCH_IF proceed BEGIN + WRITE_ASCII spl_off DWREMOVE + any_memorized=1 + END + END + END + END + END + // main pass - known spells + PATCH_IF known BEGIN + any_known=0 + GET_OFFSET_ARRAY known_arr CRE_V10_KNOWN_SPELLS + PHP_EACH known_arr AS known_ind=>known_off BEGIN + type=SHORT_AT (0xa+known_off) + PATCH_IF (type=0 && wizard) || (type=1 && priest) || (type=2 && innate) BEGIN + PATCH_IF core_namespace_only BEGIN + READ_ASCII known_off init (4) + PATCH_MATCH "%init%" WITH + SPPR SPWI SPIN SPCL BEGIN + proceed=1 + END + DEFAULT + proceed=0 + END + END ELSE BEGIN + proceed=1 + END + PATCH_IF proceed BEGIN + WRITE_ASCII known_off DWREMOVE + any_known=1 + END + END + END + END + // enact deletion + PATCH_IF any_memorized BEGIN + REMOVE_MEMORIZED_SPELL DWREMOVE + END + PATCH_IF any_known BEGIN + REMOVE_KNOWN_SPELL DWREMOVE + END + + +END \ No newline at end of file diff --git a/stratagems/sfo2e/lib_data.tph b/stratagems/sfo2e/lib_data.tph index 0542bebc..4f5a4b1a 100644 --- a/stratagems/sfo2e/lib_data.tph +++ b/stratagems/sfo2e/lib_data.tph @@ -540,6 +540,15 @@ BEGIN BUT_ONLY END END + // hardcode wizard and bard level-one spells, to avoid clash with ToF's hack + ACTION_FOR_EACH type IN WIZ BRD BEGIN + OUTER_SET $"sfo_mxspl_%type%"("1" "1")=1 + OUTER_FOR (col=2;col<10;++col) BEGIN + ACTION_IF VARIABLE_IS_SET $"sfo_mxspl_%type%"("1" "%col%") BEGIN + OUTER_SET $"sfo_mxspl_%type%"("1" "%col%")=0 + END + END + END VERBOSE ACTION_PHP_EACH SFO_reserved_data_class_map AS class=>type BEGIN // get the main array diff --git a/stratagems/sfo2e/lib_struct.tph b/stratagems/sfo2e/lib_struct.tph index bc69c006..9b1c5bcd 100644 --- a/stratagems/sfo2e/lib_struct.tph +++ b/stratagems/sfo2e/lib_struct.tph @@ -1126,7 +1126,7 @@ BEGIN END strref BEGIN SPRINT sound $"%struct%"("%label%" sound) - PATCH_IF "%value%" STR_EQ "-1" BEGIN + PATCH_IF "%value%" STR_EQ "-1" && "%sound%" STR_EQ "" BEGIN WRITE_LONG offset value END ELSE BEGIN PATCH_MATCH "%value%" WITH @@ -1145,6 +1145,9 @@ BEGIN "[0-9]+" BEGIN WRITE_LONG offset value END + "-1" BEGIN // only here if there is a sound + SAY offset "" [%sound%] + END DEFAULT PATCH_IF "%sound%" STR_EQ "" BEGIN PATCH_IF edit_strrefs_in_place && "%struct%_%label%-strref">0 BEGIN @@ -3000,8 +3003,11 @@ DEFINE_DIMORPHIC_FUNCTION struct_debug//internal BEGIN OUTER_PATCH "%function%" BEGIN REPLACE_EVALUATE "\(^\|[^a-z]\)%struct%_\([a-z0-9_]+\)" BEGIN - PATCH_IF !VARIABLE_IS_SET $"SFO_%strtype%_types"("%MATCH2%") && INDEX ("blockcount" "%MATCH2%")<0 BEGIN - PATCH_WARN "Apparent reference to %struct%_%MATCH2%; %MATCH2% is not a field of %strtype%" + INNER_PATCH_SAVE check "%MATCH2%" BEGIN + REPLACE_TEXTUALLY "_sound$" "" + END + PATCH_IF (!VARIABLE_IS_SET $"SFO_%strtype%_types"("%check%") && INDEX ("blockcount" "%check%")<0) && (!VARIABLE_IS_SET $"SFO_%strtype%_types"("%MATCH2%") && INDEX ("blockcount" "%MATCH2%")<0) BEGIN + PATCH_WARN "Apparent reference to %struct%_%check%; %check% is not a field of %strtype%" END END "" diff --git a/stratagems/sfo2e/lua/data/onopen.ini b/stratagems/sfo2e/lua/data/onopen.ini index 40faec87..bd413972 100644 --- a/stratagems/sfo2e/lua/data/onopen.ini +++ b/stratagems/sfo2e/lua/data/onopen.ini @@ -29,11 +29,11 @@ main=dwCharacterScreenRecordRace,dwXPAdjust,DEFAULT [MAGE] -main=dwUpdateCurrentID,DEFAULT +main=dwUpdateCurrentID,dwSetAsNotPriest,DEFAULT [PRIEST] -main=dwUpdateCurrentID,DEFAULT +main=dwUpdateCurrentID,dwSetAsPriest,DEFAULT [INVENTORY] @@ -83,9 +83,13 @@ main=dwGrantDefaultProficiencies,dw_thiefskill_initialize,dwBuildProficiencyTabl main=dwUpdateChooseSpells,dwLearnSpecialistSpells,dwBuildChooseSpell,dwMarkBonusSpellsKnown,DEFAULT +[CHARGEN_MEMORIZE_MAGE] + +main=dwSetAsNotPriest,DEFAULT + [CHARGEN_MEMORIZE_PRIEST] -main=dwBuildChargenPriestChooseSpell,DEFAULT +main=dwBuildChargenPriestChooseSpell,dwSetAsPriest,DEFAULT [CHARGEN_HIGH_LEVEL_ABILITIES] diff --git a/stratagems/sfo2e/lua/ui_dual_class_kits.tph b/stratagems/sfo2e/lua/ui_dual_class_kits.tph index e87e4ce9..305232d0 100644 --- a/stratagems/sfo2e/lua/ui_dual_class_kits.tph +++ b/stratagems/sfo2e/lua/ui_dual_class_kits.tph @@ -402,14 +402,14 @@ DEFINE_ACTION_FUNCTION ui_dualclass_specialist_bonus_spells BEGIN CREATE spl dwdcmb LPF add_basic_spell_ability END - LPF ADD_SPELL_EFFECT INT_VAR opcode=326 timing=1 target=2 parameter1=IDS_OF_SYMBOL(splstate ORIGINAL_CLASS_FIGHTER) parameter2=110 STR_VAR resource=dwdcmbp END - LPF ADD_SPELL_EFFECT INT_VAR opcode=326 timing=1 target=2 parameter1=IDS_OF_SYMBOL(splstate ORIGINAL_CLASS_CLERIC) parameter2=110 STR_VAR resource=dwdcmbp END - LPF ADD_SPELL_EFFECT INT_VAR opcode=326 timing=1 target=2 parameter1=IDS_OF_SYMBOL(splstate ORIGINAL_CLASS_THIEF) parameter2=110 STR_VAR resource=dwdcmbp END + LPF ADD_SPELL_EFFECT INT_VAR opcode=326 timing=9 target=2 parameter1=IDS_OF_SYMBOL(splstate ORIGINAL_CLASS_FIGHTER) parameter2=110 STR_VAR resource=dwdcmbp END + LPF ADD_SPELL_EFFECT INT_VAR opcode=326 timing=9 target=2 parameter1=IDS_OF_SYMBOL(splstate ORIGINAL_CLASS_CLERIC) parameter2=110 STR_VAR resource=dwdcmbp END + LPF ADD_SPELL_EFFECT INT_VAR opcode=326 timing=9 target=2 parameter1=IDS_OF_SYMBOL(splstate ORIGINAL_CLASS_THIEF) parameter2=110 STR_VAR resource=dwdcmbp END CREATE spl dwdcmbp LPF add_basic_spell_ability END - LPF ADD_SPELL_EFFECT INT_VAR opcode=321 target=2 timing=1 STR_VAR resource=dwdcmbp END // probably not needed, but let's be safe - LPF ADD_SPELL_EFFECT INT_VAR opcode=42 target=2 timing=1 parameter1=1 parameter2=0b111111111 END + LPF ADD_SPELL_EFFECT INT_VAR opcode=321 target=2 timing=9 STR_VAR resource=dwdcmbp END // probably not needed, but let's be safe + LPF ADD_SPELL_EFFECT INT_VAR opcode=42 target=2 timing=9 parameter1=1 parameter2=0b111111111 END LAF kit_edit_all INT_VAR skip_trueclass=1 STR_VAR parent_class="MAGE" edits="sfo_internal_struct.kit_apply_powers{dwdcmb 1}" struct=sfo_internal_struct END diff --git a/stratagems/sfo2e/lua/ui_spell_system.tph b/stratagems/sfo2e/lua/ui_spell_system.tph index a88617ec..45ed5624 100644 --- a/stratagems/sfo2e/lua/ui_spell_system.tph +++ b/stratagems/sfo2e/lua/ui_spell_system.tph @@ -577,7 +577,6 @@ DEFINE_PATCH_FUNCTION memorize_priest_spells_edit//internal BEGIN REPLACE_TEXTUALLY ~clickable lua "createCharScreen:IsDoneButtonClickable()"~ ~clickable lua "createCharScreen:IsDoneButtonClickable() and dwChargenSpecialistRequirementsSatisfied(priestSpells,true)"~ - REPLACE_TEXTUALLY ~currentChargenMemorizePriestSpell ?= ?nil~ ~currentChargenMemorizePriestSpell = nil%WNL%%TAB%%TAB%dwIsPriest=true~ END @@ -629,7 +628,6 @@ BEGIN REPLACE_TEXTUALLY ~bookSpells\[shownSpellOffset \* numberOfKnown\(Mage\|Priest\)SpellSlots \+ \([0-9]+\)\]"~ ~bookSpells[shownSpellOffset * numberOfKnown\1SpellSlots + \2]" clickable lua "dwSpellEnabled(bookSpells[shownSpellOffset * numberOfKnown\1SpellSlots + \2].resref)" greyscale lua "not dwSpellEnabled(bookSpells[shownSpellOffset * numberOfKnown\1SpellSlots + \2].resref)"~ - REPLACE_TEXTUALLY ~showMageMemorizationFlash ?= ?false~ ~showMageMemorizationFlash = false%WNL%%TAB%%TAB%dwIsPriest=nil~ END @@ -638,7 +636,6 @@ BEGIN REPLACE_TEXTUALLY ~bookSpells\[shownSpellOffset \* numberOfKnown\(Mage\|Priest\)SpellSlots \+ \([0-9]+\)\]"~ ~bookSpells[shownSpellOffset * numberOfKnown\1SpellSlots + \2]" clickable lua "dwSpellEnabled(bookSpells[shownSpellOffset * numberOfKnown\1SpellSlots + \2].resref,true)" greyscale lua "not dwSpellEnabled(bookSpells[shownSpellOffset * numberOfKnown\1SpellSlots + \2].resref,true)"~ - REPLACE_TEXTUALLY ~showPriestMemorizationFlash ?= ?false~ ~showPriestMemorizationFlash = false%WNL%%TAB%%TAB%dwIsPriest=true~ END @@ -648,7 +645,6 @@ BEGIN REPLACE_TEXTUALLY ~^\(.*\)bam[ %TAB%]+lua[ %TAB%]+"bookSpells\[rowNumber\]\.icon"~ ~\1bam lua "bookSpells[rowNumber].icon"%WNL%\1greyscale lua "bookMode==0 and not dwSpellEnabled(bookSpells[rowNumber])"~ REPLACE_TEXTUALLY ~\(mageScreen:MemorizeSpell([ %TAB%]*bookSpells\[currentBookSpell\]\.level,[ %TAB%]*bookSpells\[currentBookSpell\]\.index )\)~ ~if dwSpellEnabled(bookSpells[currentBookSpell]) then \1 end~ REPLACE_TEXTUALLY ~#bottomSpells < #bottomSpellsPlaceHolder~ ~#bottomSpells < #bottomSpellsPlaceHolder and dwSpellEnabled(bookSpells[currentBookSpell])~ - REPLACE_TEXTUALLY ~showMageMemorizationFlash ?= ?false~ ~showMageMemorizationFlash = false%WNL%%TAB%%TAB%dwIsPriest=nil~ END DEFINE_PATCH_FUNCTION patch_spec_bg_priest//internal @@ -658,7 +654,6 @@ BEGIN REPLACE_TEXTUALLY ~\(priestScreen:MemorizeSpell([^)]*)\)~ ~if dwSpellEnabled(characters[id].priestSpells[currentSpellLevel][currentBookSpell],true) then \1 end~ REPLACE_TEXTUALLY ~#bottomSpells < #bottomSpellsPlaceHolder~ ~#bottomSpells < #bottomSpellsPlaceHolder and dwSpellEnabled(characters[id].priestSpells[currentSpellLevel][currentBookSpell],true)~ REPLACE_TEXTUALLY "\(#bottomSpells < characters\[id\]\.priestDetails\[currentSpellLevel\]\.maxMemorized and currentBookSpell ~= 0\)" ~\1 and dwSpellEnabled(characters[id].priestSpells[currentSpellLevel][currentBookSpell],true)~ - REPLACE_TEXTUALLY ~showPriestMemorizationFlash ?= ?false~ ~showPriestMemorizationFlash = false%WNL%%TAB%%TAB%dwIsPriest=true~ END @@ -666,7 +661,6 @@ DEFINE_PATCH_FUNCTION chargen_memorize_mage_spells//internal BEGIN REPLACE_TEXTUALLY ~clickable lua "createCharScreen:IsDoneButtonClickable()"~ ~clickable lua "createCharScreen:IsDoneButtonClickable() and dwChargenSpecialistRequirementsSatisfied(mageSpells)"~ - REPLACE_TEXTUALLY ~currentChargenMemorizeMageSpell ?= ?nil~ ~currentChargenMemorizeMageSpell = nil%WNL%%TAB%%TAB%dwIsPriest=nil~ END @@ -2099,6 +2093,18 @@ function dwLearnChanceCancel() end end +function dwSetAsPriest() + + dwIsPriest=true + +end + +function dwSetAsNotPriest() + + dwIsPriest=nil + +end + -- hacks to work around the fact that changing character when on the spellbook page doesn't automatically refresh it function dwRefreshPriestHack() diff --git a/stratagems/sfo2e/lua/ui_virtual_class.tph b/stratagems/sfo2e/lua/ui_virtual_class.tph index e97fd0a0..359aa0f9 100644 --- a/stratagems/sfo2e/lua/ui_virtual_class.tph +++ b/stratagems/sfo2e/lua/ui_virtual_class.tph @@ -679,7 +679,7 @@ BEGIN REPLACE_TEXTUALLY "createCharScreen:OnCancelButtonClick()" "currentChargenKitSec=nil;" REPLACE_TEXTUALLY ~text "CLASS_KIT_TITLE"~ ~text lua "Infinity_FetchString(dwMenu.title)"~ REPLACE_TEXTUALLY ~createCharScreen:IsDoneButtonClickable()~ ~createCharScreen:IsDoneButtonClickable() and currentChargenKit~ - REPLACE_TEXTUALLY ~"Infinity_FetchString(dwKitSecList\[rowNumber\]\.name)"~ ~"dwChargenKitName(dwKitSecList[rowNumber])"~ + REPLACE_TEXTUALLY ~Infinity_FetchString(dwKitSecList\[rowNumber\]\.name)~ ~dwChargenKitName(dwKitSecList[rowNumber])~ END @@ -725,7 +725,7 @@ DEFINE_PATCH_FUNCTION chargen_kit_sub//internal REPLACE_TEXTUALLY EXACT_MATCH ~createCharScreen:OnKitSelectButtonClick(chargen.kit[currentChargenKit].id)~ ~dwChargenKitId,dwMenu=dwOnSelectKitButtonClick(currentChargenKit)~ REPLACE_TEXTUALLY "chargen\.kit" "dwKitList" - REPLACE_TEXTUALLY ~"Infinity_FetchString(dwKitList\[rowNumber\]\.name)"~ ~"dwChargenKitName(dwKitList[rowNumber])"~ + REPLACE_TEXTUALLY ~Infinity_FetchString(dwKitList\[rowNumber\]\.name)~ ~dwChargenKitName(dwKitList[rowNumber])~ REPLACE_TEXTUALLY ~createCharScreen:IsDoneButtonClickable()~ ~(createCharScreen:IsDoneButtonClickable() and currentChargenKit)~ REPLACE_TEXTUALLY ~Infinity_PopMenu(); +createCharScreen:OnDoneButtonClick()~ diff --git a/stratagems/spell/antimagic_penetrates_ii.tpa b/stratagems/spell/antimagic_penetrates_ii.tpa index 89408ed9..d7b58d49 100644 --- a/stratagems/spell/antimagic_penetrates_ii.tpa +++ b/stratagems/spell/antimagic_penetrates_ii.tpa @@ -4,7 +4,7 @@ DEFINE_ACTION_FUNCTION antimagic_penetrates_ii BEGIN spl.edit[%WIZARD_PIERCE_SHIELD% %WIZARD_SPELL_STRIKE% %WIZARD_RUBY_RAY_OF_REVERSAL% %WIZARD_WARDING_WHIP% %WIZARD_PIERCE_MAGIC% %WIZARD_SPELL_THRUST% %WIZARD_SECRET_WORD%|edit_strrefs_in_place:i=1] [ - m_description:="%m_description%%WNL%%desc_add%" + m_description:="%m_description%%desc_add%" m_can_target_invisible=1 LPF log_this INT_VAR repeat=0 STR_VAR file=scs_modified_spells.2da input="%sfo_filename%" END ] diff --git a/stratagems/spell/data/spelltweaks.2da b/stratagems/spell/data/spelltweaks.2da index aa0c27f6..5dee3430 100644 --- a/stratagems/spell/data/spelltweaks.2da +++ b/stratagems/spell/data/spelltweaks.2da @@ -72,3 +72,5 @@ lightning_bolt_damage rebalance all ee,not_sr remove_antimagic_shell rebalance all iwd_arcane mordenkainens_force_blade_thac0 boost all force_blade haste_cancels_slow rebalance all not_sr,ee +otiluke_save_for_half boost all iwd_arcane +glyph_save_for_half iwd bg,bg2 not_sr diff --git a/stratagems/spell/data/spelltweaks_descriptions.ini b/stratagems/spell/data/spelltweaks_descriptions.ini index 5c3f0b87..7fd41e70 100644 --- a/stratagems/spell/data/spelltweaks_descriptions.ini +++ b/stratagems/spell/data/spelltweaks_descriptions.ini @@ -242,9 +242,6 @@ CLERIC_PROTECTION_FROM_FIRE=The spell now lasts for 1 turn per level rather than name=Strength of One increases recipients' strength to 18/76 rather than 18/75 STRENGTH_OF_ONE=Strength of One increases recipients' strength to 18/76 rather than 18/75. -[use_iwd_slow_poison] -name=Slow Poison now genuinely slows the effect of poison (reducing the speed of its effect by 90%) instead of neutralizing it altogether -SLOW_POISON=The spell now genuinely slows the effect of poison (reducing the speed of its effect by 90%) instead of neutralising it altogether. [use_iwd_sols_searing_orb] name=Sol's Searing Orb does 6d12 damage, not 3d6, and does not require a hit roll @@ -414,3 +411,13 @@ description=The Haste and Slow effects cancel each other out; also, Slow effects HASTE=Haste is cancelled by Slow. IMPROVED_HASTE=Haste is cancelled by Slow. SLOW=Slow is cancelled by Haste. + +[otiluke_save_for_half] +name=Otiluke's Freezing Sphere does half damage on a successful save +description=This component causes the Freezing Sphere spell to do half damage if the target saves vs. spells, rather than completely dodging the sphere. +OTILUKES_FREEZING_SPHERE=The sphere does half damage (rather than no damage) on a successful save. + +[glyph_save_for_half] +name=Glyph of Warding does half damage on a successful save +description=This component causes a Glyph of Warding to do half damage if the target saves vs. spells, rather than completely avoiding damage. +GLYPH_OF_WARDING=The glyph does half damage (rather than no damage) on a successful save. diff --git a/stratagems/spell/glyph_save_for_half.tpa b/stratagems/spell/glyph_save_for_half.tpa new file mode 100644 index 00000000..4b39ce6d --- /dev/null +++ b/stratagems/spell/glyph_save_for_half.tpa @@ -0,0 +1,27 @@ +DEFINE_ACTION_FUNCTION glyph_save_for_half BEGIN + + spl.edit[%CLERIC_GLYPH_OF_WARDING%] + [ + old:=@40016 + new:=@40017 + INNER_PATCH_SAVE m_description "%m_description%" BEGIN + REPLACE_TEXTUALLY "%old%" "%new%" + END + PATCH_IF enhanced_edition BEGIN + m.ab_fx.alter{s_save_for_half=1} + END ELSE BEGIN + m.ab_fx.clone{s_opcode=700 s_save_vs_spell=0 s_dicenumber=s_dicenumber - s_dicenumber / 2 |match="s_opcode=12"} + m.ab_fx.clone{s_opcode=700 s_dicenumber=s_dicenumber / 2 |match="s_opcode=12"} + m.ab_fx.delete{s_opcode=12} + m.ab_fx.alter{s_opcode=12|match="s_opcode=700"} + END + + ] + + + + + + + +END diff --git a/stratagems/spell/otiluke_save_for_half.tpa b/stratagems/spell/otiluke_save_for_half.tpa new file mode 100644 index 00000000..10b880a7 --- /dev/null +++ b/stratagems/spell/otiluke_save_for_half.tpa @@ -0,0 +1,18 @@ +DEFINE_ACTION_FUNCTION otiluke_save_for_half BEGIN + + spl.edit[%WIZARD_OTILUKES_FREEZING_SPHERE%|edit_strrefs_in_place:i=1] + [ + m_description:=@40015 + PATCH_IF enhanced_edition BEGIN + m.ab_fx.alter{s_save_for_half=1|match="s_opcode=12"} + END ELSE BEGIN + m.ab_fx.alter{s_save_vs_spell=0 s_dicenumber=s_dicenumber / 2 |match="s_opcode=12"} + m.ab_fx.clone{s_save_vs_spell=1|match="s_opcode=12"} + END + + + ] + + +END + diff --git a/stratagems/stratagems.ini b/stratagems/stratagems.ini index da7d9ad8..d6278bc1 100644 --- a/stratagems/stratagems.ini +++ b/stratagems/stratagems.ini @@ -17,6 +17,7 @@ enhance_thorn_spray=1 entropy_shield_abjuration=1 fiend_summoning=1 freedom_scrolls=1 +glyph_save_for_half=1 harm=1 haste_cancels_slow=1 ilmater_rename=1 @@ -33,6 +34,7 @@ nature_beauty_blindness=1 nerf_beetles=1 nerf_greater_restoration=1 npc_symbols=1 +otiluke_save_for_half=1 power_word_blind=1 power_words_are_enchantment=1 pro_normal_missiles=1 diff --git a/stratagems/test/test.tpa b/stratagems/test/test.tpa index c39f583b..d9a04cd4 100644 --- a/stratagems/test/test.tpa +++ b/stratagems/test/test.tpa @@ -1,8 +1,16 @@ DEFINE_ACTION_FUNCTION test BEGIN - OUTER_SPRINT teststring @101020 - PRINT "teststring is %teststring%" +/* + COPY "spin890.spl" override + OUTER_SPRINT component_loc initial + LAF include STR_VAR file=initial.tpa END + LAF detectable_items END +*/ + + OUTER_SPRINT component_loc initial + LAF include STR_VAR file=mirror_image_aoe.tph END + LAF mirror_image_AoE END END