diff --git a/cdtweaks/languages/english/weidu.tra b/cdtweaks/languages/english/weidu.tra index 20419e83..85c37e8f 100644 --- a/cdtweaks/languages/english/weidu.tra +++ b/cdtweaks/languages/english/weidu.tra @@ -702,6 +702,8 @@ Use Baldur.lua options: a7_interval_ini @341100 = ~Mage, priest, and innate spells only~ @341200 = ~All spells (check readme)~ +@342000 = "More Sensible Cowled Wizards [Luke (EEex)]" + /////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\ /////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\ ///// \\\\\ diff --git a/cdtweaks/languages/italian/weidu.tra b/cdtweaks/languages/italian/weidu.tra index 355078bc..9e5d3a90 100644 --- a/cdtweaks/languages/italian/weidu.tra +++ b/cdtweaks/languages/italian/weidu.tra @@ -627,6 +627,8 @@ Usa opzioni di Baldur.lua: a7_interval_ini @336000 = ~Ripristina la nebbia di guerra nei sotterranei di Sigil~ +@342000 = "Gli Stregoni Incappucciati reagiranno in maniera piĆ¹ sensata all'uso della magia senza licenza [Luke (EEex)]" + /////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\ /////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\ ///// \\\\\ diff --git a/cdtweaks/lib/comp_3420.tpa b/cdtweaks/lib/comp_3420.tpa new file mode 100644 index 00000000..cc066e22 --- /dev/null +++ b/cdtweaks/lib/comp_3420.tpa @@ -0,0 +1,15 @@ +/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\////\\\\//// +/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\////\\\\//// +///// \\\\\////\\\\//// +///// More Sensible Cowled Wizards \\\\\ +///// \\\\\////\\\\//// +/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\////\\\\//// +/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\////\\\\//// + +WITH_SCOPE BEGIN + INCLUDE "cdtweaks\luke\misc.tph" + // + INCLUDE "cdtweaks\lib\cowled_wizards.tph" + // + LAF "COWLED_WIZARDS" END +END \ No newline at end of file diff --git a/cdtweaks/lib/cowled_wizards.tph b/cdtweaks/lib/cowled_wizards.tph new file mode 100644 index 00000000..32508e9c --- /dev/null +++ b/cdtweaks/lib/cowled_wizards.tph @@ -0,0 +1,53 @@ +DEFINE_ACTION_FUNCTION "COWLED_WIZARDS" +BEGIN + // patch relevant area scripts \\ + WITH_SCOPE BEGIN + COPY_EXISTING + "ar0020.bcs" "override" // City Gates + "ar0300.bcs" "override" // The Docks + "ar0400.bcs" "override" // Slums + "ar0500.bcs" "override" // Bridge District + "ar0700.bcs" "override" // Waukeen's Promenade + "ar0900.bcs" "override" // Temple District + "ar1000.bcs" "override" // Government District + // + DECOMPILE_AND_PATCH BEGIN + // first relevant block + SET "found" = INDEX_BUFFER (CASE_SENSITIVE EXACT_MATCH ~CreateCreatureObjectDoor("COWENF2",LastTrigger,0,0,0)~) + // + PATCH_IF ("%found%" >= 0) BEGIN + SET "start" = RINDEX_BUFFER (CASE_SENSITIVE EXACT_MATCH ~SpellCast([PC],0)~ "%found%") + SET "end" = INDEX_BUFFER (CASE_INSENSITIVE EVALUATE_REGEXP ~$~ "%start%") + // + DELETE_BYTES "%start%" ("%end%" - "%start%") + // + INSERT_BYTES "%start%" STRING_LENGTH ~Global("gt_CowledWizardsTriggered","GLOBAL",1)~ + WRITE_ASCII "%start%" ~Global("gt_CowledWizardsTriggered","GLOBAL",1)~ + // + SET "found" = INDEX_BUFFER (CASE_SENSITIVE EXACT_MATCH ~CreateCreatureObjectDoor("COWENF2",LastTrigger,0,0,0)~) + INSERT_BYTES "%found%" STRING_LENGTH ~SetGlobal("gt_CowledWizardsTriggered","GLOBAL",0)~ + WRITE_ASCII "%found%" ~SetGlobal("gt_CowledWizardsTriggered","GLOBAL",0)~ + END + // second relevant block + SET "found" = INDEX_BUFFER (CASE_SENSITIVE EVALUATE_REGEXP ~[ %TAB%]*GlobalTimerNotExpired("SpellsBad","GLOBAL")~) + // + PATCH_IF ("%found%" >= 0) BEGIN + SET "start" = RINDEX_BUFFER (CASE_SENSITIVE EXACT_MATCH ~SpellCast([PC],0)~) + SET "end" = INDEX_BUFFER (CASE_INSENSITIVE EVALUATE_REGEXP ~$~ "%start%") + // + DELETE_BYTES "%start%" ("%end%" - "%start%") + // + INSERT_BYTES "%start%" STRING_LENGTH ~Global("gt_CowledWizardsTriggered","GLOBAL",1)~ + WRITE_ASCII "%start%" ~Global("gt_CowledWizardsTriggered","GLOBAL",1)~ + // + SET "found" = INDEX_BUFFER (CASE_SENSITIVE EXACT_MATCH ~Wait(1)~ "%start%") + INSERT_BYTES "%found%" STRING_LENGTH ~SetGlobal("gt_CowledWizardsTriggered","GLOBAL",0)~ + WRITE_ASCII "%found%" ~SetGlobal("gt_CowledWizardsTriggered","GLOBAL",0)~ + END + END + BUT_ONLY_IF_IT_CHANGES + END + // lua + LAF "APPEND_LUA_FUNCTION" STR_VAR "description" = "Utility" "sourceFileSpec" = "cdtweaks\luke\lua\utility\decode_spell.lua" "destRes" = "m_gtutil" END + LAF "APPEND_LUA_FUNCTION" STR_VAR "description" = "Misc Tweaks" "sourceFileSpec" = "cdtweaks\luke\lua\tweaks\cowled_wizards.lua" "destRes" = "m_gttwks" END +END \ No newline at end of file diff --git a/cdtweaks/luke/lua/tweaks/cowled_wizards.lua b/cdtweaks/luke/lua/tweaks/cowled_wizards.lua new file mode 100644 index 00000000..ea1ae75d --- /dev/null +++ b/cdtweaks/luke/lua/tweaks/cowled_wizards.lua @@ -0,0 +1,118 @@ +--[[ ++----------------------------------------+ +| cdtweaks, more sensible cowled wizards | ++----------------------------------------+ +--]] + +-- set a GLOBAL var when a PC casts a wizard spell and is in Athkatla -- + +GTCOWENF = { + + ["typeMutator"] = function(context) + local actionSources = { + [EEex_Projectile_DecodeSource.CGameSprite_Spell] = true, + [EEex_Projectile_DecodeSource.CGameSprite_SpellPoint] = true, + [EEex_Projectile_DecodeSource.CGameAIBase_ForceSpell] = true, + [EEex_Projectile_DecodeSource.CGameAIBase_ForceSpellPoint] = true, + } + -- + if not actionSources[context.decodeSource] then + return + end + end, + + ["projectileMutator"] = function(context) + local actionSources = { + [EEex_Projectile_DecodeSource.CGameSprite_Spell] = true, + [EEex_Projectile_DecodeSource.CGameSprite_SpellPoint] = true, + [EEex_Projectile_DecodeSource.CGameAIBase_ForceSpell] = true, + [EEex_Projectile_DecodeSource.CGameAIBase_ForceSpellPoint] = true, + } + -- + if not actionSources[context.decodeSource] then + return + end + -- + local originatingSprite = context["originatingSprite"] -- CGameSprite + -- + local areaCheck = EEex_Trigger_ParseConditionalString('OR(7) \n AreaCheck("AR0020") AreaCheck("AR0300") AreaCheck("AR0400") AreaCheck("AR0500") AreaCheck("AR0700") AreaCheck("AR0900") AreaCheck("AR1000")') + -- + local spellResRef = originatingSprite.m_curAction.m_string1.m_pchData:get() + if spellResRef == "" then + spellResRef = GT_Utility_DecodeSpell(originatingSprite.m_curAction.m_specificID) + end + -- + local spellHeader = EEex_Resource_Demand(spellResRef, "SPL") + -- + if spellHeader.itemType == 1 and areaCheck:evalConditionalAsAIBase(originatingSprite) then -- if wizard spell and in Athkatla ... + EEex_GameState_SetGlobalInt("gt_CowledWizardsTriggered", 1) + end + -- + areaCheck:free() + end, + + ["effectMutator"] = function(context) + local actionSources = { + [EEex_Projectile_AddEffectSource.CGameSprite_Spell] = true, + [EEex_Projectile_AddEffectSource.CGameSprite_SpellPoint] = true, + [EEex_Projectile_AddEffectSource.CGameAIBase_ForceSpell] = true, + [EEex_Projectile_AddEffectSource.CGameAIBase_ForceSpellPoint] = true, + } + -- + if not actionSources[context.addEffectSource] then + return + end + end, +} + +-- + +EEex_Opcode_AddListsResolvedListener(function(sprite) + -- Sanity check + if not EEex_GameObject_IsSprite(sprite) then + return + end + -- internal function that applies the actual condition + local apply = function() + -- Mark the creature as 'condition applied' + sprite:setLocalInt("cdtweaksCowledWizards", 1) + -- + local effectCodes = { + {["op"] = 321}, -- Remove effects by resource + {["op"] = 408}, -- Projectile mutator + } + -- + for _, attributes in ipairs(effectCodes) do + sprite:applyEffect({ + ["effectID"] = attributes["op"] or EEex_Error("opcode number not specified"), + ["durationType"] = 9, + ["res"] = "GTCOWENF", + ["m_sourceRes"] = "GTCOWENF", + ["sourceID"] = sprite.m_id, + ["sourceTarget"] = sprite.m_id, + }) + end + end + -- Check creature's EA + local applyCondition = sprite.m_typeAI.m_EnemyAlly == 2 -- PC + -- + if sprite:getLocalInt("cdtweaksCowledWizards") == 0 then + if applyCondition then + apply() + end + else + if applyCondition then + -- do nothing + else + -- Mark the creature as 'condition removed' + sprite:setLocalInt("cdtweaksCowledWizards", 0) + -- + sprite:applyEffect({ + ["effectID"] = 321, -- Remove effects by resource + ["res"] = "GTCOWENF", + ["sourceID"] = sprite.m_id, + ["sourceTarget"] = sprite.m_id, + }) + end + end +end) diff --git a/cdtweaks/readme-cdtweaks.html b/cdtweaks/readme-cdtweaks.html index 553d0278..171160f2 100644 --- a/cdtweaks/readme-cdtweaks.html +++ b/cdtweaks/readme-cdtweaks.html @@ -1372,6 +1372,12 @@
More Sensible Cowled Wizards
+ EEex
As you probably know, party items that cast spell effects that are coded as "Wizard" spells can trigger the Cowled Wizards - even if the player didn't intend to actually cast an ordinary wizard spell. + This component simply makes sure that such items do not trigger the Cowled Wizards. +