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

New component: Overwhelming/Devastating Critical #113

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
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@0 = "Overwhelming Critical"
@1 = "Unaffected by effects from Overwhelming Critical"
@2 = "Devastating Critical"
@3 = "Unaffected by effects from Devastating Critical"
10 changes: 10 additions & 0 deletions cdtweaks/languages/english/weidu.tra
Original file line number Diff line number Diff line change
Expand Up @@ -802,3 +802,13 @@ Use Baldur.lua options: a7_interval_ini
@504000 = ~Allow Yeslick to Use Axes~

@505000 = ~Ensure Shar-Teel Doesn't Die in the Original Challenge~

/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\
/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\
///// \\\\\
///// NWN-ish feats collection \\\\\
///// \\\\\
/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\
/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\

@600200 = "Overwhelming/Devastating Critical class feat for Trueclass Fighters [Luke]"
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@0 = "Colpo Critico Possente"
@1 = "Non soggetto agli effetti di Colpo Critico Possente"
@2 = "Colpo Critico Devastante"
@3 = "Non soggetto agli effetti di Colpo Critico Devastante"
10 changes: 10 additions & 0 deletions cdtweaks/languages/italian/weidu.tra
Original file line number Diff line number Diff line change
Expand Up @@ -718,3 +718,13 @@ Usa opzioni di Baldur.lua: a7_interval_ini
@504000 = ~Permettere a Yeslick di usare le asce~

@505000 = ~Assicura che Shar-Teel non muoia nella sfida iniziale~

/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\
/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\
///// \\\\\
///// Raccolta di talenti in stile NWN \\\\\
///// \\\\\
/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\
/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\

@600200 = "Aggiungi talento di classe Colpo Critico Possente/Devastante per i Guerrieri [Luke]"
18 changes: 18 additions & 0 deletions cdtweaks/lib/comp_6200.tpa
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\////\\\\////
/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\////\\\\////
///// \\\\\////\\\\////
///// Overwhelming/Devastating Critical class feat for Trueclass Fighters \\\\\
///// \\\\\////\\\\////
/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\////\\\\////
/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\////\\\\////

WITH_SCOPE BEGIN
INCLUDE "cdtweaks\luke\misc.tph"
INCLUDE "cdtweaks\ardanis\functions.tph"
//
INCLUDE "cdtweaks\lib\overwhelming_devastating_critical.tph"
//
WITH_TRA "cdtweaks\languages\english\overwhelming_devastating_critical.tra" "cdtweaks\languages\%LANGUAGE%\overwhelming_devastating_critical.tra" BEGIN
LAF "OVERWHELMING_DEVASTATING_CRITICAL" END
END
END
53 changes: 53 additions & 0 deletions cdtweaks/lib/overwhelming_devastating_critical.tph
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
DEFINE_ACTION_FUNCTION "OVERWHELMING_DEVASTATING_CRITICAL"
BEGIN
LAF "GT_ADD_SPELL"
INT_VAR
"level" = 1
"type" = 4
STR_VAR
"idsName" = "TRUECLASS_FIGHTER_CRITICAL"
RET
"TRUECLASS_FIGHTER_CRITICAL" = "resName"
END
//
WITH_SCOPE BEGIN
ACTION_TO_LOWER "TRUECLASS_FIGHTER_CRITICAL"
//
CREATE "eff" "%TRUECLASS_FIGHTER_CRITICAL%b"
COPY_EXISTING "%TRUECLASS_FIGHTER_CRITICAL%b.eff" "override"
WRITE_LONG 0x10 341 // opcode: critical hit effect
WRITE_LONG 0x20 1 // mode: by this weapon only
WRITE_SHORT 0x2C 100 // prob1
WRITE_ASCII 0x30 "%TRUECLASS_FIGHTER_CRITICAL%" #8 // SPL resref
BUT_ONLY
//
CREATE "spl" "%TRUECLASS_FIGHTER_CRITICAL%"
COPY_EXISTING "%TRUECLASS_FIGHTER_CRITICAL%.spl" "override"
WRITE_LONG NAME1 "-1"
WRITE_LONG UNIDENTIFIED_DESC "-1"
WRITE_LONG 0x18 (BIT9 BOR BIT10 BOR BIT14 BOR BIT25) // break sanctuary/invisibility, ignore dead/wild magic, castable when silenced
WRITE_LONG 0x1C 4 // type: innate
WRITE_LONG 0x34 1 // level
WRITE_ASCII 0x3A "SPCL905B" #8 // icon
//
LPF ~ADD_SPELL_HEADER~ STR_VAR "icon" = "SPCL905B" END
LPF ~ADD_SPELL_HEADER~ INT_VAR "required_level" = 30 STR_VAR "icon" = "SPCL905B" END
//
LPF "ADD_SPELL_EFFECT" INT_VAR "header" = 1 "opcode" = 402 "target" = 2 "parameter1" = 1 STR_VAR "resource" = "%DEST_RES%" END // invoke lua
LPF "ADD_SPELL_EFFECT" INT_VAR "header" = 2 "opcode" = 402 "target" = 2 "parameter1" = 2 STR_VAR "resource" = "%DEST_RES%" END // invoke lua
BUT_ONLY_IF_IT_CHANGES
END
// Listener: run 'func' each time a sprite has finished evaluating its effects
WITH_SCOPE BEGIN
OUTER_SET "feedback_strref_overwhelming_crit_hit" = RESOLVE_STR_REF (@0)
OUTER_SET "feedback_strref_overwhelming_crit_immune" = RESOLVE_STR_REF (@1)
OUTER_SET "feedback_strref_devastating_crit_hit" = RESOLVE_STR_REF (@2)
OUTER_SET "feedback_strref_devastating_crit_immune" = RESOLVE_STR_REF (@3)
//
LAF "APPEND_LUA_FUNCTION" STR_VAR "description" = "Class/Kit Abilities" "sourceFileSpec" = "cdtweaks\luke\lua\class\overwhelming_devastating_critical.lua" "destRes" = "m_gtspcl" END
END
//
ACTION_IF !(FILE_EXISTS_IN_GAME "m_gttbls.lua") BEGIN
COPY "cdtweaks\luke\lua\m_gttbls.lua" "override"
END
END
204 changes: 204 additions & 0 deletions cdtweaks/luke/lua/class/overwhelming_devastating_critical.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
--[[
+---------------------------------------------------------------------------------------+
| cdtweaks, NWN-ish Overwhelming/Devastating Critical class feat for Trueclass Fighters |
+---------------------------------------------------------------------------------------+
--]]

-- Apply ability --

EEex_Opcode_AddListsResolvedListener(function(sprite)
-- Sanity check
if not EEex_GameObject_IsSprite(sprite) then
return
end
-- internal function that applies the actual feat
local apply = function(mainHandResRef)
-- Update tracking var
sprite:setLocalString("cdtweaksTrueFigCritMainHand", mainHandResRef)
-- Mark the creature as 'feat applied'
sprite:setLocalInt("cdtweaksTrueFigCrit", 1)
--
sprite:applyEffect({
["effectID"] = 321, -- Remove effects by resource
["res"] = "CDTFCRIT",
["sourceID"] = sprite.m_id,
["sourceTarget"] = sprite.m_id,
})
sprite:applyEffect({
["effectID"] = 182, -- Use EFF file while ITM is equipped
["durationType"] = 9,
["res"] = string.upper(mainHandResRef), -- ITM
["m_res2"] = "%TRUECLASS_FIGHTER_CRITICAL%B", -- EFF
["m_sourceRes"] = "CDTFCRIT",
["sourceID"] = sprite.m_id,
["sourceTarget"] = sprite.m_id,
})
end
-- Check creature's equipment / class / pips
local equipment = sprite.m_equipment -- CGameSpriteEquipment
local selectedWeapon = equipment.m_items:get(equipment.m_selectedWeapon) -- CItem
local selectedWeaponHeader = selectedWeapon.pRes.pHeader -- Item_Header_st
local selectedWeaponResRef = selectedWeapon.pRes.resref:get()
--
local selectedWeaponProficiencyType = selectedWeaponHeader.proficiencyType
-- get launcher if needed
local launcher = sprite:getLauncher(selectedWeapon:getAbility(equipment.m_selectedWeaponAbility)) -- CItem
if launcher ~= nil then
local pHeader = launcher.pRes.pHeader -- Item_Header_st
selectedWeaponProficiencyType = pHeader.proficiencyType
end
--
local spriteClassStr = GT_Resource_IDSToSymbol["class"][sprite.m_typeAI.m_Class]
-- 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 spriteKitStr = sprite.m_derivedStats.m_nKit == 0 and "TRUECLASS" or GT_Resource_IDSToSymbol["kit"][sprite.m_derivedStats.m_nKit]
--
local grandmastery = EEex_Trigger_ParseConditionalString(string.format("ProficiencyGT(Myself,%d,4)", selectedWeaponProficiencyType))
--
local applyAbility = spriteClassStr == "FIGHTER" and (spriteKitStr == "TRUECLASS" or spriteKitStr == "MAGESCHOOL_GENERALIST") and grandmastery:evalConditionalAsAIBase(sprite)
--
if sprite:getLocalInt("cdtweaksTrueFigCrit") == 0 then
if applyAbility then
apply(selectedWeaponResRef)
end
else
if applyCondition then
-- Check if weapon resref has changed since the last application
if selectedWeaponResRef ~= sprite:getLocalString("cdtweaksTrueFigCritMainHand") then
apply(selectedWeaponResRef)
end
else
-- Mark the creature as 'feat removed'
sprite:setLocalInt("cdtweaksTrueFigCrit", 0)
--
sprite:applyEffect({
["effectID"] = 321, -- Remove effects by resource
["res"] = "CDTFCRIT",
["sourceID"] = sprite.m_id,
["sourceTarget"] = sprite.m_id,
})
end
end
--
grandmastery:free()
end)

-- Core function --

function %TRUECLASS_FIGHTER_CRITICAL%(CGameEffect, CGameSprite)
local sourceSprite = EEex_GameObject_Get(CGameEffect.m_sourceId)
--
local equipment = sourceSprite.m_equipment -- CGameSpriteEquipment
local selectedWeapon = equipment.m_items:get(equipment.m_selectedWeapon) -- CItem
local selectedWeaponHeader = selectedWeapon.pRes.pHeader -- Item_Header_st
local selectedWeaponAbility = EEex_Resource_GetItemAbility(selectedWeaponHeader, equipment.m_selectedWeaponAbility) -- Item_ability_st
--
if CGameEffect.m_effectAmount == 1 then
-- Overwhelming Critical
local immunityToDamage = EEex_Trigger_ParseConditionalString("EEex_IsImmuneToOpcode(Myself,12)")
--
local targetActiveStats = EEex_Sprite_GetActiveStats(CGameSprite)
--
local itmDamageTypeToIDS = {
0x10, -- piercing
0x0, -- crushing
0x100, -- slashing
0x80, -- missile
0x800, -- non-lethal
targetActiveStats.m_nResistPiercing > targetActiveStats.m_nResistCrushing and 0x0 or 0x10, -- piercing/crushing (better)
targetActiveStats.m_nResistPiercing > targetActiveStats.m_nResistSlashing and 0x100 or 0x10, -- piercing/slashing (better)
targetActiveStats.m_nResistCrushing > targetActiveStats.m_nResistSlashing and 0x0 or 0x100, -- slashing/crushing (worse)
}
--
if itmDamageTypeToIDS[selectedWeaponAbility.damageType] then -- sanity check
if not immunityToDamage:evalConditionalAsAIBase(CGameSprite) then
EEex_GameObject_ApplyEffect(sourceSprite,
{
["effectID"] = 139, -- Display string
["effectAmount"] = %feedback_strref_overwhelming_crit_hit%,
["m_sourceRes"] = CGameEffect.m_sourceRes:get(),
["m_sourceType"] = CGameEffect.m_sourceType,
["sourceID"] = sourceSprite.m_id,
["sourceTarget"] = sourceSprite.m_id,
})
--
EEex_GameObject_ApplyEffect(CGameSprite,
{
["effectID"] = 12, -- Damage
["dwFlags"] = itmDamageTypeToIDS[selectedWeaponAbility.damageType] * 0x10000, -- mode: normal
["numDice"] = 2,
["diceSize"] = 6,
["m_sourceRes"] = CGameEffect.m_sourceRes:get(),
["m_sourceType"] = CGameEffect.m_sourceType,
["sourceID"] = CGameEffect.m_sourceId,
["sourceTarget"] = CGameEffect.m_sourceTarget,
})
else
EEex_GameObject_ApplyEffect(CGameSprite,
{
["effectID"] = 139, -- Display string
["effectAmount"] = %feedback_strref_overwhelming_crit_immune%,
["m_sourceRes"] = CGameEffect.m_sourceRes:get(),
["m_sourceType"] = CGameEffect.m_sourceType,
["sourceID"] = CGameEffect.m_sourceId,
["sourceTarget"] = CGameEffect.m_sourceTarget,
})
end
end
--
immunityToDamage:free()
elseif CGameEffect.m_effectAmount == 2 then
-- Devastating Critical
local sourceActiveStats = EEex_Sprite_GetActiveStats(sourceSprite)
--
local savebonus = math.floor((sourceActiveStats.m_nSTR - 10) / 2)
if selectedWeaponAbility.type == 2 then -- if ranged, make it scale with Dexterity
savebonus = math.floor((sourceActiveStats.m_nDEX - 10) / 2)
end
--
local immunityToKillTarget = EEex_Trigger_ParseConditionalString("EEex_IsImmuneToOpcode(Myself,13)")
--
if not immunityToKillTarget:evalConditionalAsAIBase(CGameSprite) then
EEex_GameObject_ApplyEffect(sourceSprite,
{
["effectID"] = 139, -- Display string
["effectAmount"] = %feedback_strref_devastating_crit_hit%,
["m_sourceRes"] = CGameEffect.m_sourceRes:get(),
["m_sourceType"] = CGameEffect.m_sourceType,
["sourceID"] = sourceSprite.m_id,
["sourceTarget"] = sourceSprite.m_id,
})
--
local effectCodes = {
{["op"] = 0xD7, ["tmg"] = 1, ["res"] = "SPBOLTGL"}, -- feedback vfx
{["op"] = 0xD, ["tmg"] = 4, ["p2"] = 0x4} -- kill target (normal death)
}
--
for _, attributes in ipairs(effectCodes) do
CGameSprite:applyEffect({
["effectID"] = attributes["op"] or EEex_Error("opcode number not specified"),
["dwFlags"] = attributes["p2"] or 0,
["durationType"] = attributes["tmg"] or 0,
["res"] = attributes["res"] or "",
["savingThrow"] = 0x4, -- save vs. death
["saveMod"] = -1 * savebonus,
["m_sourceRes"] = CGameEffect.m_sourceRes:get(),
["m_sourceType"] = CGameEffect.m_sourceType,
["sourceID"] = CGameEffect.m_sourceId,
["sourceTarget"] = CGameEffect.m_sourceTarget,
})
end
else
EEex_GameObject_ApplyEffect(CGameSprite,
{
["effectID"] = 139, -- Display string
["effectAmount"] = %feedback_strref_devastating_crit_immune%,
["m_sourceRes"] = CGameEffect.m_sourceRes:get(),
["m_sourceType"] = CGameEffect.m_sourceType,
["sourceID"] = CGameEffect.m_sourceId,
["sourceTarget"] = CGameEffect.m_sourceTarget,
})
end
--
immunityToKillTarget:free()
end
end
40 changes: 40 additions & 0 deletions cdtweaks/readme-cdtweaks.html
Original file line number Diff line number Diff line change
Expand Up @@ -1461,6 +1461,46 @@ <h3> <a id="contents_npc" name="contents_npc"></a>Joinable <abbr title="Non-Play
<p> Internally, Dorn's sword (Rancor +1) relies upon scripting. As modders know, items should not rely upon scripting to work correctly, since it is unreliable and may quickly become messy.
This component simply removes scripting from this weapon (the upshot of which is that the weapon should become a bit more reliable). </p>
</div>

<div class="ribbon_rectangle_h3">
<h3> <a id="NWN-ish_feats" name="NWN-ish_feats"></a>NWN-ish Feats Collection </h3>
</div>
<div class="ribbon_triangle_h3-l"></div>
<div class="ribbon_triangle_h3-r"></div>
<div class="section">
<p> Components in this category are inspired from <a href="https://nwn.beamdog.com/">NWN</a> and are aimed at providing new class/kit abilities.</p>

<p> <strong>Overwhelming/Devastating Critical class feat for Trueclass Fighters [Luke]</strong><br />
<em><abbr title="Enhanced Edition">EEex</abbr></em></p>
<p>
This component aims at giving Trueclass Fighters the passive feats Overwhelming/Devastating Critical.
</p>
<p>
Overwhelming Critical: If the character is wielding a weapon he is grandmaster (+++++) with, he will deal 2d6 extra points of damage on a successful critical hit.
</p>
<p>
Devastating Critical: If the character is wielding a weapon he is grandmaster (+++++) with and he is level 30+, the character's target must make a Save vs. Death or die instantly.
</p>
<p>
Notes:
<ul>
<li>Use: automatic, but only available to Trueclass Fighters.</li>
<li>Creatures who are immune to critical hits are not affected by these feats.</li>
<li>
Devastating Critical: the saving throw penalty scales with either Strength (melee weapons) or Dexterity (ranged weapons). In particular:
<ul>
<li>melee weapons: <code>(STR - 10) / 2</code>, rounded down.</li>
<li>ranged weapons: <code>(DEX - 10) / 2</code>, rounded down.</li>
</ul>
</li>
<li>Only the mainhand weapon can trigger these feats (in case of dual-wielding).</li>
</ul>
</p>
</div>




<div class="ribbon_rectangle_h2"> <a id="Contact" name="Contact"></a>
<h2> Contact Information </h2>
</div>
Expand Down
23 changes: 23 additions & 0 deletions cdtweaks/setup-cdtweaks.tp2
Original file line number Diff line number Diff line change
Expand Up @@ -4903,3 +4903,26 @@ GROUP @0
REQUIRE_PREDICATE GAME_IS ~bgee bg2ee eet~ @25
REQUIRE_PREDICATE MOD_IS_INSTALLED "EEex.tp2" 0 @29
LABEL ~cd_tweaks_dorns_sword~

/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\
/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\
///// \\\\\
///// NWN-ish feats collection \\\\\
///// \\\\\
/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\
/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\

/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\////\\\\////
/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\////\\\\////
///// \\\\\////\\\\////
///// Overwhelming/Devastating Critical class feat for Trueclass Fighters \\\\\
///// \\\\\////\\\\////
/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\////\\\\////
/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\/////\\\\\////\\\\////

BEGIN @600200 DESIGNATED 6200
GROUP @30
REQUIRE_PREDICATE GAME_IS ~bgee bg2ee eet iwdee~ @25
REQUIRE_PREDICATE MOD_IS_INSTALLED "EEex.tp2" 0 @29
REQUIRE_PREDICATE FILE_EXISTS ~cdtweaks/languages/%LANGUAGE%/overwhelming_devastating_critical.tra~ @7
LABEL ~cd_tweaks_nwn_overwhelming_devastating_critical~