Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[EEex] Allow Yeslick to Use Axes #99

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2,582 changes: 2,582 additions & 0 deletions cdtweaks/argent/add_kit_ex.tph

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions cdtweaks/languages/english/yeslick_axes.tra
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
@0 = "Tweaks Anthology: Yeslick is the only Fighter/Cleric who can equip axes."
@1 = "Fighter / Cleric (Yeslick)"
2 changes: 2 additions & 0 deletions cdtweaks/languages/italian/yeslick_axes.tra
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
@0 = "Tweaks Anthology: Yeslick è l'unico Guerriero/Chierico in grado di utilizzare le asce."
@1 = "Guerriero / Chierico (Yeslick)"
96 changes: 82 additions & 14 deletions cdtweaks/lib/comp_4160.tpa
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,88 @@
/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\
/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\

COPY_EXISTING_REGEXP GLOB ~^.+\.itm$~ ~override~
READ_SHORT 0x1c type
PATCH_IF type = 25 BEGIN
WRITE_LONG 0x1e (THIS BAND `BIT14) // removes f/c flag
END
BUT_ONLY
ACTION_IF !(MOD_IS_INSTALLED "EEex.tp2" 0) BEGIN
COPY_EXISTING_REGEXP GLOB ~^.+\.itm$~ ~override~
READ_SHORT 0x1c type
PATCH_IF type = 25 BEGIN
WRITE_LONG 0x1e (THIS BAND `BIT14) // removes f/c flag
END
BUT_ONLY

COPY_EXISTING ~clasweap.2da~ ~override~ //add axe general-weapon type to fighter-cleric
REPLACE_TEXTUALLY ~^\(FIGHTER_CLERIC[ %TAB%]+[^ %TAB%]+[ %TAB%]+[^ %TAB%]+[ %TAB%]+[^ %TAB%]+[ %TAB%]+[^ %TAB%]+[ %TAB%]+[^ %TAB%]+[ %TAB%]+[^ %TAB%]+[ %TAB%]+\)[^ %TAB%]+~ ~\11~
COPY_EXISTING ~clasweap.2da~ ~override~ //add axe general-weapon type to fighter-cleric
REPLACE_TEXTUALLY ~^\(FIGHTER_CLERIC[ %TAB%]+[^ %TAB%]+[ %TAB%]+[^ %TAB%]+[ %TAB%]+[^ %TAB%]+[ %TAB%]+[^ %TAB%]+[ %TAB%]+[^ %TAB%]+[ %TAB%]+[^ %TAB%]+[ %TAB%]+\)[^ %TAB%]+~ ~\11~

OUTER_SET profmax = 2
ACTION_IF MOD_IS_INSTALLED ~cdtweaks/setup-cdtweaks.tp2~ ~2200~ THEN BEGIN OUTER_SET profmax = 5 END // multiclass grandmastery
OUTER_SET profmax = 2
ACTION_IF MOD_IS_INSTALLED ~cdtweaks/setup-cdtweaks.tp2~ ~2200~ THEN BEGIN OUTER_SET profmax = 5 END // multiclass grandmastery

COPY_EXISTING ~weapprof.2da~ ~override~ //give fighter-clerics the ability to specialise in axes
REPLACE_TEXTUALLY ~^\(AXE[ %TAB%]+[^ %TAB%]+[ %TAB%]+[^ %TAB%]+[ %TAB%]+[^ %TAB%]+[ %TAB%]+[^ %TAB%]+[ %TAB%]+[^ %TAB%]+[ %TAB%]+[^ %TAB%]+[ %TAB%]+[^ %TAB%]+[ %TAB%]+[^ %TAB%]+[ %TAB%]+[^ %TAB%]+[ %TAB%]+[^ %TAB%]+[ %TAB%]+[^ %TAB%]+[ %TAB%]+[^ %TAB%]+[ %TAB%]+\)[^ %TAB%]+~
~\1%profmax%~
IF_EXISTS
COPY_EXISTING ~weapprof.2da~ ~override~ //give fighter-clerics the ability to specialise in axes
REPLACE_TEXTUALLY ~^\(AXE[ %TAB%]+[^ %TAB%]+[ %TAB%]+[^ %TAB%]+[ %TAB%]+[^ %TAB%]+[ %TAB%]+[^ %TAB%]+[ %TAB%]+[^ %TAB%]+[ %TAB%]+[^ %TAB%]+[ %TAB%]+[^ %TAB%]+[ %TAB%]+[^ %TAB%]+[ %TAB%]+[^ %TAB%]+[ %TAB%]+[^ %TAB%]+[ %TAB%]+[^ %TAB%]+[ %TAB%]+[^ %TAB%]+[ %TAB%]+\)[^ %TAB%]+~
~\1%profmax%~
IF_EXISTS
END ELSE BEGIN
// [Luke]
WITH_SCOPE BEGIN
INCLUDE "cdtweaks\argent\add_kit_ex.tph"
INCLUDE "cdtweaks\luke\misc.tph"
//
WITH_TRA "cdtweaks\languages\english\yeslick_axes.tra" "cdtweaks\languages\%LANGUAGE%\yeslick_axes.tra" BEGIN
// lua magic
WITH_SCOPE BEGIN
OUTER_SET "feedback_strref" = RESOLVE_STR_REF (@0)
//
LAF "APPEND_LUA_FUNCTION"
STR_VAR
"description" = "Misc Tweaks (NPCs)"
"sourceFileSpec" = "cdtweaks\luke\lua\npc\yeslick.lua"
"destRes" = "m_gt#npc"
END
END
// let us add a new dummy fighter/cleric kit that can put pips in axes
WITH_SCOPE BEGIN
OUTER_SET "profmax" = 2
ACTION_IF MOD_IS_INSTALLED ~cdtweaks/setup-cdtweaks.tp2~ ~2200~ BEGIN
OUTER_SET "profmax" = 5 END // multiclass grandmastery
END
//
LAF "ADD_KIT_EX"
INT_VAR
"kit_class" = IDS_OF_SYMBOL ("class" "FIGHTER_CLERIC")
"mixed" = RESOLVE_STR_REF (@1)
"visible" = 0 // not available to PCs
STR_VAR
"kit_name" = "CDTWEAKS_YESLICK_AXES"
END
//
COPY_EXISTING - "kitlist.2da" "override"
COUNT_2DA_COLS "cols"
READ_2DA_ENTRIES_NOW "read_kitlist" "%cols%"
FOR ("i" = 0 ; "%i%" < "%read_kitlist%" ; "i" += 1) BEGIN
READ_2DA_ENTRY_FORMER "read_kitlist" "%i%" 1 "kit_name"
PATCH_IF ("%kit_name%" STR_EQ "CDTWEAKS_YESLICK_AXES") BEGIN
READ_2DA_ENTRY_FORMER "read_kitlist" "%i%" 6 "proficiency"
SET "i" = "%read_kitlist%" // kill for-loop
END
END
BUT_ONLY
//
COPY_EXISTING "weapprof.2da" "override"
COUNT_2DA_COLS "cols"
READ_2DA_ENTRIES_NOW "read_weapprof" "%cols%"
FOR ("i" = 0 ; "%i%" < "%read_weapprof%" ; "i" += 1) BEGIN
READ_2DA_ENTRY_FORMER "read_weapprof" "%i%" 0 "prof_name"
PATCH_IF ("%prof_name%" STR_EQ "AXE") BEGIN
SET_2DA_ENTRY "%i%" "%proficiency%" "%cols%" "%profmax%"
END
END
BUT_ONLY
END
// update CREs
COPY_EXISTING "yeslic.cre" "override"
"yeslic5.cre" "override"
"yeslid.cre" "override"
WRITE_SHORT 0x244 (IDS_OF_SYMBOL ("kit" "CDTWEAKS_YESLICK_AXES") >> 16) & 0xFFFF
WRITE_SHORT 0x246 (IDS_OF_SYMBOL ("kit" "CDTWEAKS_YESLICK_AXES") & 0xFFFF)
BUT_ONLY IF_EXISTS
END
END
END
1 change: 1 addition & 0 deletions cdtweaks/lib/comp_4200.tpa
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\

WITH_SCOPE BEGIN
INCLUDE "cdtweaks\luke\misc.tph"
INCLUDE "cdtweaks\lib\dorns_sword.tph"
LAF "DORNS_SWORD" END
END
2 changes: 1 addition & 1 deletion cdtweaks/lib/dorns_sword.tph
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,5 @@ BEGIN
LPF "ADD_CRE_EFFECT" INT_VAR "opcode" = 402 "target" = 1 "timing" = 9 STR_VAR "resource" = "GTDRNSW1" END // Invoke lua
BUT_ONLY IF_EXISTS
// lua magic
LAF "APPEND_LUA_FUNCTION" STR_VAR "description" = "Functions to be invoked via op402" "sourceFileSpec" = "cdtweaks\luke\lua\dorns_sword.lua" "destRes" = "m_gt#402" END
LAF "APPEND_LUA_FUNCTION" STR_VAR "description" = "Misc Tweaks (NPCs)" "sourceFileSpec" = "cdtweaks\luke\lua\npc\dorns_sword.lua" "destRes" = "m_gt#npc" END
END
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,16 @@

function GTDRNSW1(CGameEffect, CGameSprite)
local equipment = CGameSprite.m_equipment -- CGameSpriteEquipment
local selectedItem = equipment.m_items:get(equipment.m_selectedWeapon) -- CItem
local itemResRef = selectedItem.pRes.resref:get() -- We need to use :get() to export a CResRef field as a Lua string!
local selectedWeapon = equipment.m_items:get(equipment.m_selectedWeapon) -- CItem
local selectedWeaponResRef = selectedWeapon.pRes.resref:get() -- We need to use :get() to export a CResRef field as a Lua string!
-- if Dorn is not wielding Rancor +1, then remove bonus ...
if itemResRef ~= "SW2HD1" then
if selectedWeaponResRef ~= "SW2HD1" then
if EEex_Sprite_GetLocalInt(CGameSprite, "ohdornsw") ~= 0 then
EEex_Sprite_SetLocalInt(CGameSprite, "ohdornsw", 0)
--
EEex_GameObject_ApplyEffect(CGameSprite,
{
["effectID"] = 146, -- Cast spell
["durationType"] = 1,
["dwFlags"] = 1, -- Cast instantly (caster level)
["res"] = "OHDSW0",
["sourceID"] = CGameEffect.m_sourceId, -- Certain opcodes (see f.i. op326) use this field internally... it's probably a good idea to always specify it...
Expand All @@ -38,4 +37,4 @@ function GTDRNSW2(CGameEffect, CGameSprite)
["sourceTarget"] = CGameEffect.m_sourceTarget, -- Certain opcodes (see f.i. op326) use this field internally... it's probably a good idea to always specify it...
})
end
end
end
72 changes: 72 additions & 0 deletions cdtweaks/luke/lua/npc/yeslick.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
-- cdtweaks, Yeslick (axes): remove f/c unusability flag from all axes --

EEex_GameState_AddInitializedListener(function()
local itmFileList = Infinity_GetFilesOfType("itm")
-- for some unknown reason, we need two nested loops in order to get the resref...
for _, temp in ipairs(itmFileList) do
for _, res in pairs(temp) do
local header = EEex_Resource_Demand(res, "ITM")
if header.itemType == 0x19 then -- axe
local headerUnusabilityFlags = header.notUsableBy
header.notUsableBy = EEex_UnsetBit(headerUnusabilityFlags, 14) -- remove f/c bit
end
end
end
end)

-- cdtweaks, Yeslick (axes): make sure only Yeslick can equip axes --

EEex_Opcode_AddListsResolvedListener(function(sprite)
-- internal function that applies the actual restriction
local apply = function()
-- Mark the creature as 'condition applied'
sprite:setLocalInt("cdtweaksYeslickAxes", 1)
--
sprite:applyEffect({
["effectID"] = 321, -- Remove spell
["durationType"] = 1,
["res"] = "CDYSLAXE",
["sourceID"] = sprite.m_id,
["sourceTarget"] = sprite.m_id,
})
sprite:applyEffect({
["effectID"] = 181, -- Restrict item
["durationType"] = 9,
["special"] = %feedback_strref%,
["effectAmount"] = 0x19, -- axes
["m_sourceRes"] = "CDYSLAXE",
["sourceID"] = sprite.m_id,
["sourceTarget"] = sprite.m_id,
})
end
-- Check creature's class / flags
local spriteClassStr = GT_Resource_IDSToSymbol["class"][sprite.m_typeAI.m_Class]
--
local spriteFlags = sprite.m_baseStats.m_flags
-- since ``EEex_Opcode_AddListsResolvedListener`` is running after the effect lists have been evaluated, ``m_bonusStats`` has already been added to ``m_derivedStats`` by the engine
local spriteLevel1 = sprite.m_derivedStats.m_nLevel1
local spriteLevel2 = sprite.m_derivedStats.m_nLevel2
-- Check if F/C (all but Yeslick)
local applyCondition = spriteClassStr == "FIGHTER_CLERIC" and (EEex_IsBitUnset(spriteFlags, 0x5) or spriteLevel1 > spriteLevel2) and not (string.upper(sprite.m_scriptName:get()) == "YESLICK")
--
if sprite:getLocalInt("cdtweaksYeslickAxes") == 0 then
if applyCondition then
apply()
end
else
if applyCondition then
-- do nothing
else
-- Mark the creature as 'condition removed'
sprite:setLocalInt("cdtweaksYeslickAxes", 0)
--
sprite:applyEffect({
["effectID"] = 321, -- Remove effects by resource
["durationType"] = 1,
["res"] = "CDYSLAXE",
["sourceID"] = sprite.m_id,
["sourceTarget"] = sprite.m_id,
})
end
end
end)
2 changes: 1 addition & 1 deletion cdtweaks/readme-cdtweaks.html
Original file line number Diff line number Diff line change
Expand Up @@ -1446,7 +1446,7 @@ <h3> <a id="contents_npc" name="contents_npc"></a>Joinable <abbr title="Non-Play
<p> <strong>Allow Yeslick to Use Axes</strong><br />
<em><abbr title="Baldur's Gate: Enhanced Edition">BGEE</abbr>, <abbr title="Enhanced Edition Trilogy">EET</abbr>, <abbr title="Baldur's Gate">BG</abbr>, <abbr title="Baldur's Gate Trilogy">BGT</abbr>, Tutu</em> </p>
<p> It seems appropriate that Yeslick, who is a dwarven fighter-cleric, ought to be able to use the traditional dwarven weapon; this component allows him to. </p>
<p> (There is a loophole here: due to the way the game engine works, this actually allows all fighter-clerics (not just Yeslick) to use axes. Yeslick is actually the only <abbr title="Non-Player Character">NPC</abbr> fighter-cleric in the core game but it might affect third-party <abbr title="Non-Player Characters">NPCs</abbr>, or your primary character (and, for <abbr title="Baldur's Gate Trilogy">BGT</abbr> users, it will affect Anomen). If you want to take advantage of this then be my guest, but it wasn&#39;t the intended function of the component.) </p>
<p> (There is a loophole here if <a href="https://github.com/Bubb13/EEex">EEex</a> is not installed: due to the way the game engine works, this actually allows all fighter-clerics (not just Yeslick) to use axes. Yeslick is actually the only <abbr title="Non-Player Character">NPC</abbr> fighter-cleric in the core game but it might affect third-party <abbr title="Non-Player Characters">NPCs</abbr>, or your primary character (and, for <abbr title="Baldur's Gate Trilogy">BGT</abbr> users, it will affect Anomen). If you want to take advantage of this then be my guest, but it wasn&#39;t the intended function of the component.) </p>
<p> <strong>Ensure Shar-Teel Doesn&#39;t Die in the Original Challenge</strong><br />
<em><abbr title="Baldur's Gate: Enhanced Edition">BGEE</abbr>, <abbr title="Enhanced Edition Trilogy">EET</abbr>, <abbr title="Baldur's Gate">BG</abbr>, <abbr title="Baldur's Gate Trilogy">BGT</abbr>, Tutu</em> </p>
<p> Shar-Teel is rather fragile: it&#39;s easy to kill her by mistake in the battle where you recruit her. This component guarantees that she survives the battle. </p>
Expand Down