Skip to content

Commit

Permalink
Tweaks: add `NWNX_TWEAKS_RESIST_ENERGY_STACKS_WITH_EPIC_ENERGY_RESIST…
Browse files Browse the repository at this point in the history
…ANCE` (#1803)

* Tweaks: add `NWNX_TWEAKS_RESIST_ENERGY_STACKS_WITH_EPIC_ENERGY_RESISTANCE`

* Update CHANGELOG.md

---------

Co-authored-by: Daz <[email protected]>
  • Loading branch information
hendrikgit and Daztek authored Jan 25, 2025
1 parent 0efe7e6 commit 69ba8de
Show file tree
Hide file tree
Showing 5 changed files with 174 additions and 2 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
https://github.com/nwnxee/unified/compare/build8193.37.13...HEAD

### Added
- N/A
- Tweaks: added `NWNX_TWEAKS_RESIST_ENERGY_STACKS_WITH_EPIC_ENERGY_RESISTANCE` to make Resist Energy feats stack with Epic Energy Resistance.

##### New Plugins
- N/A
Expand Down
2 changes: 2 additions & 0 deletions NWNXLib/API/FunctionsLinux.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,6 @@ NWNXLIB_FUNCTION(_ZN23CNWSItemPropertyHandler24InitializeItemPropertiesEv)
NWNXLIB_FUNCTION(_ZN23CNWSItemPropertyHandler21OnItemPropertyAppliedEP8CNWSItemP15CNWItemPropertyP12CNWSCreatureji)
NWNXLIB_FUNCTION(_ZN23CNWSItemPropertyHandler21OnItemPropertyRemovedEP8CNWSItemP15CNWItemPropertyP12CNWSCreaturej)

NWNXLIB_FUNCTION(_ZN10CNWSObject18DoDamageResistanceEP12CNWSCreatureijiiii)

// ***
3 changes: 2 additions & 1 deletion Plugins/Tweaks/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,5 @@ add_plugin(Tweaks
"SetAreaCallsSetPosition.cpp"
"EquipUnequipEventTweaks.cpp"
"CutsceneModeNoTURD.cpp"
"CanUseItemsWhilePolymorphed.cpp")
"CanUseItemsWhilePolymorphed.cpp"
"ResistEnergyStacksWithEpicEnergyResistance.cpp")
1 change: 1 addition & 0 deletions Plugins/Tweaks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ Tweaks stuff. See below.
| `NWNX_TWEAKS_DONT_DELAY_EQUIP_EVENT` | true or false | Fixes Unequip/Equip events being out of sync if an item is equipped/unequipped multiple times per server tick |
| `NWNX_TWEAKS_CUTSCENE_MODE_NO_TURD` | true or false | SetCutsceneMode() will not cause a TURD to be dropped. |
| `NWNX_TWEAKS_CAN_USE_ITEMS_WHILE_POLYMORPHED` | true or false | Allow all items to be used while polymorphed. |
| `NWNX_TWEAKS_RESIST_ENERGY_STACKS_WITH_EPIC_ENERGY_RESISTANCE` | true or false | Resist Energy feats stack with Epic Energy Resistance. |

## Environment variable values

Expand Down
168 changes: 168 additions & 0 deletions Plugins/Tweaks/ResistEnergyStacksWithEpicEnergyResistance.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
#include "nwnx.hpp"

#include "API/CNWSCreature.hpp"
#include "API/CNWRules.hpp"

namespace Tweaks {

using namespace NWNXLib;
using namespace NWNXLib::API;

void ResistEnergyStacksWithEpicEnergyResistance() __attribute__((constructor));
void ResistEnergyStacksWithEpicEnergyResistance()
{
if (!Config::Get<bool>("RESIST_ENERGY_STACKS_WITH_EPIC_ENERGY_RESISTANCE", false)) return;

LOG_INFO("Resist Energy feats stack with Epic Energy Resistance.");

static Hooks::Hook s_DoDamageResistanceHook = Hooks::HookFunction(Functions::_ZN10CNWSObject18DoDamageResistanceEP12CNWSCreatureijiiii,
+[](CNWSObject *thisPtr, CNWSCreature *pDamager, int32_t nDamage, uint32_t nFlags, BOOL bSimulation, BOOL bCombatDamage, BOOL bBaseWeaponDamage, BOOL bRangedAttack) -> int32_t
{
const CNWSCreature *thisCreature = Utils::AsNWSCreature(thisPtr);
if (!thisCreature || !thisCreature->m_pStats->m_bIsPC)
return s_DoDamageResistanceHook->CallOriginal<int32_t>(thisPtr, pDamager, nDamage, nFlags, bSimulation, bCombatDamage, bBaseWeaponDamage, bRangedAttack);

uint64_t hashedFeatLabel = 0;

if (thisCreature->m_pStats->HasFeat(Constants::Feat::ResistEnergy_Acid))
{
if (thisCreature->m_pStats->HasFeat(Constants::Feat::EpicEnergyResistance_Acid10))
hashedFeatLabel = CRULES_HASHEDSTR("EPIC_ENERGY_RESISTANCE_AMOUNT_10");
else if (thisCreature->m_pStats->HasFeat(Constants::Feat::EpicEnergyResistance_Acid9))
hashedFeatLabel = CRULES_HASHEDSTR("EPIC_ENERGY_RESISTANCE_AMOUNT_9");
else if (thisCreature->m_pStats->HasFeat(Constants::Feat::EpicEnergyResistance_Acid8))
hashedFeatLabel = CRULES_HASHEDSTR("EPIC_ENERGY_RESISTANCE_AMOUNT_8");
else if (thisCreature->m_pStats->HasFeat(Constants::Feat::EpicEnergyResistance_Acid7))
hashedFeatLabel = CRULES_HASHEDSTR("EPIC_ENERGY_RESISTANCE_AMOUNT_7");
else if (thisCreature->m_pStats->HasFeat(Constants::Feat::EpicEnergyResistance_Acid6))
hashedFeatLabel = CRULES_HASHEDSTR("EPIC_ENERGY_RESISTANCE_AMOUNT_6");
else if (thisCreature->m_pStats->HasFeat(Constants::Feat::EpicEnergyResistance_Acid5))
hashedFeatLabel = CRULES_HASHEDSTR("EPIC_ENERGY_RESISTANCE_AMOUNT_5");
else if (thisCreature->m_pStats->HasFeat(Constants::Feat::EpicEnergyResistance_Acid4))
hashedFeatLabel = CRULES_HASHEDSTR("EPIC_ENERGY_RESISTANCE_AMOUNT_4");
else if (thisCreature->m_pStats->HasFeat(Constants::Feat::EpicEnergyResistance_Acid3))
hashedFeatLabel = CRULES_HASHEDSTR("EPIC_ENERGY_RESISTANCE_AMOUNT_3");
else if (thisCreature->m_pStats->HasFeat(Constants::Feat::EpicEnergyResistance_Acid2))
hashedFeatLabel = CRULES_HASHEDSTR("EPIC_ENERGY_RESISTANCE_AMOUNT_2");
else if (thisCreature->m_pStats->HasFeat(Constants::Feat::EpicEnergyResistance_Acid1))
hashedFeatLabel = CRULES_HASHEDSTR("EPIC_ENERGY_RESISTANCE_AMOUNT_1");
}
else if (thisCreature->m_pStats->HasFeat(Constants::Feat::ResistEnergy_Cold))
{
if (thisCreature->m_pStats->HasFeat(Constants::Feat::EpicEnergyResistance_Cold10))
hashedFeatLabel = CRULES_HASHEDSTR("EPIC_ENERGY_RESISTANCE_AMOUNT_10");
else if (thisCreature->m_pStats->HasFeat(Constants::Feat::EpicEnergyResistance_Cold9))
hashedFeatLabel = CRULES_HASHEDSTR("EPIC_ENERGY_RESISTANCE_AMOUNT_9");
else if (thisCreature->m_pStats->HasFeat(Constants::Feat::EpicEnergyResistance_Cold8))
hashedFeatLabel = CRULES_HASHEDSTR("EPIC_ENERGY_RESISTANCE_AMOUNT_8");
else if (thisCreature->m_pStats->HasFeat(Constants::Feat::EpicEnergyResistance_Cold7))
hashedFeatLabel = CRULES_HASHEDSTR("EPIC_ENERGY_RESISTANCE_AMOUNT_7");
else if (thisCreature->m_pStats->HasFeat(Constants::Feat::EpicEnergyResistance_Cold6))
hashedFeatLabel = CRULES_HASHEDSTR("EPIC_ENERGY_RESISTANCE_AMOUNT_6");
else if (thisCreature->m_pStats->HasFeat(Constants::Feat::EpicEnergyResistance_Cold5))
hashedFeatLabel = CRULES_HASHEDSTR("EPIC_ENERGY_RESISTANCE_AMOUNT_5");
else if (thisCreature->m_pStats->HasFeat(Constants::Feat::EpicEnergyResistance_Cold4))
hashedFeatLabel = CRULES_HASHEDSTR("EPIC_ENERGY_RESISTANCE_AMOUNT_4");
else if (thisCreature->m_pStats->HasFeat(Constants::Feat::EpicEnergyResistance_Cold3))
hashedFeatLabel = CRULES_HASHEDSTR("EPIC_ENERGY_RESISTANCE_AMOUNT_3");
else if (thisCreature->m_pStats->HasFeat(Constants::Feat::EpicEnergyResistance_Cold2))
hashedFeatLabel = CRULES_HASHEDSTR("EPIC_ENERGY_RESISTANCE_AMOUNT_2");
else if (thisCreature->m_pStats->HasFeat(Constants::Feat::EpicEnergyResistance_Cold1))
hashedFeatLabel = CRULES_HASHEDSTR("EPIC_ENERGY_RESISTANCE_AMOUNT_1");
}
else if (thisCreature->m_pStats->HasFeat(Constants::Feat::ResistEnergy_Electrical))
{
if (thisCreature->m_pStats->HasFeat(Constants::Feat::EpicEnergyResistance_Electrical10))
hashedFeatLabel = CRULES_HASHEDSTR("EPIC_ENERGY_RESISTANCE_AMOUNT_10");
else if (thisCreature->m_pStats->HasFeat(Constants::Feat::EpicEnergyResistance_Electrical9))
hashedFeatLabel = CRULES_HASHEDSTR("EPIC_ENERGY_RESISTANCE_AMOUNT_9");
else if (thisCreature->m_pStats->HasFeat(Constants::Feat::EpicEnergyResistance_Electrical8))
hashedFeatLabel = CRULES_HASHEDSTR("EPIC_ENERGY_RESISTANCE_AMOUNT_8");
else if (thisCreature->m_pStats->HasFeat(Constants::Feat::EpicEnergyResistance_Electrical7))
hashedFeatLabel = CRULES_HASHEDSTR("EPIC_ENERGY_RESISTANCE_AMOUNT_7");
else if (thisCreature->m_pStats->HasFeat(Constants::Feat::EpicEnergyResistance_Electrical6))
hashedFeatLabel = CRULES_HASHEDSTR("EPIC_ENERGY_RESISTANCE_AMOUNT_6");
else if (thisCreature->m_pStats->HasFeat(Constants::Feat::EpicEnergyResistance_Electrical5))
hashedFeatLabel = CRULES_HASHEDSTR("EPIC_ENERGY_RESISTANCE_AMOUNT_5");
else if (thisCreature->m_pStats->HasFeat(Constants::Feat::EpicEnergyResistance_Electrical4))
hashedFeatLabel = CRULES_HASHEDSTR("EPIC_ENERGY_RESISTANCE_AMOUNT_4");
else if (thisCreature->m_pStats->HasFeat(Constants::Feat::EpicEnergyResistance_Electrical3))
hashedFeatLabel = CRULES_HASHEDSTR("EPIC_ENERGY_RESISTANCE_AMOUNT_3");
else if (thisCreature->m_pStats->HasFeat(Constants::Feat::EpicEnergyResistance_Electrical2))
hashedFeatLabel = CRULES_HASHEDSTR("EPIC_ENERGY_RESISTANCE_AMOUNT_2");
else if (thisCreature->m_pStats->HasFeat(Constants::Feat::EpicEnergyResistance_Electrical1))
hashedFeatLabel = CRULES_HASHEDSTR("EPIC_ENERGY_RESISTANCE_AMOUNT_1");
}
else if (thisCreature->m_pStats->HasFeat(Constants::Feat::ResistEnergy_Fire))
{
if (thisCreature->m_pStats->HasFeat(Constants::Feat::EpicEnergyResistance_Fire10))
hashedFeatLabel = CRULES_HASHEDSTR("EPIC_ENERGY_RESISTANCE_AMOUNT_10");
else if (thisCreature->m_pStats->HasFeat(Constants::Feat::EpicEnergyResistance_Fire9))
hashedFeatLabel = CRULES_HASHEDSTR("EPIC_ENERGY_RESISTANCE_AMOUNT_9");
else if (thisCreature->m_pStats->HasFeat(Constants::Feat::EpicEnergyResistance_Fire8))
hashedFeatLabel = CRULES_HASHEDSTR("EPIC_ENERGY_RESISTANCE_AMOUNT_8");
else if (thisCreature->m_pStats->HasFeat(Constants::Feat::EpicEnergyResistance_Fire7))
hashedFeatLabel = CRULES_HASHEDSTR("EPIC_ENERGY_RESISTANCE_AMOUNT_7");
else if (thisCreature->m_pStats->HasFeat(Constants::Feat::EpicEnergyResistance_Fire6))
hashedFeatLabel = CRULES_HASHEDSTR("EPIC_ENERGY_RESISTANCE_AMOUNT_6");
else if (thisCreature->m_pStats->HasFeat(Constants::Feat::EpicEnergyResistance_Fire5))
hashedFeatLabel = CRULES_HASHEDSTR("EPIC_ENERGY_RESISTANCE_AMOUNT_5");
else if (thisCreature->m_pStats->HasFeat(Constants::Feat::EpicEnergyResistance_Fire4))
hashedFeatLabel = CRULES_HASHEDSTR("EPIC_ENERGY_RESISTANCE_AMOUNT_4");
else if (thisCreature->m_pStats->HasFeat(Constants::Feat::EpicEnergyResistance_Fire3))
hashedFeatLabel = CRULES_HASHEDSTR("EPIC_ENERGY_RESISTANCE_AMOUNT_3");
else if (thisCreature->m_pStats->HasFeat(Constants::Feat::EpicEnergyResistance_Fire2))
hashedFeatLabel = CRULES_HASHEDSTR("EPIC_ENERGY_RESISTANCE_AMOUNT_2");
else if (thisCreature->m_pStats->HasFeat(Constants::Feat::EpicEnergyResistance_Fire1))
hashedFeatLabel = CRULES_HASHEDSTR("EPIC_ENERGY_RESISTANCE_AMOUNT_1");
}
else if (thisCreature->m_pStats->HasFeat(Constants::Feat::ResistEnergy_Sonic))
{
if (thisCreature->m_pStats->HasFeat(Constants::Feat::EpicEnergyResistance_Sonic10))
hashedFeatLabel = CRULES_HASHEDSTR("EPIC_ENERGY_RESISTANCE_AMOUNT_10");
else if (thisCreature->m_pStats->HasFeat(Constants::Feat::EpicEnergyResistance_Sonic9))
hashedFeatLabel = CRULES_HASHEDSTR("EPIC_ENERGY_RESISTANCE_AMOUNT_9");
else if (thisCreature->m_pStats->HasFeat(Constants::Feat::EpicEnergyResistance_Sonic8))
hashedFeatLabel = CRULES_HASHEDSTR("EPIC_ENERGY_RESISTANCE_AMOUNT_8");
else if (thisCreature->m_pStats->HasFeat(Constants::Feat::EpicEnergyResistance_Sonic7))
hashedFeatLabel = CRULES_HASHEDSTR("EPIC_ENERGY_RESISTANCE_AMOUNT_7");
else if (thisCreature->m_pStats->HasFeat(Constants::Feat::EpicEnergyResistance_Sonic6))
hashedFeatLabel = CRULES_HASHEDSTR("EPIC_ENERGY_RESISTANCE_AMOUNT_6");
else if (thisCreature->m_pStats->HasFeat(Constants::Feat::EpicEnergyResistance_Sonic5))
hashedFeatLabel = CRULES_HASHEDSTR("EPIC_ENERGY_RESISTANCE_AMOUNT_5");
else if (thisCreature->m_pStats->HasFeat(Constants::Feat::EpicEnergyResistance_Sonic4))
hashedFeatLabel = CRULES_HASHEDSTR("EPIC_ENERGY_RESISTANCE_AMOUNT_4");
else if (thisCreature->m_pStats->HasFeat(Constants::Feat::EpicEnergyResistance_Sonic3))
hashedFeatLabel = CRULES_HASHEDSTR("EPIC_ENERGY_RESISTANCE_AMOUNT_3");
else if (thisCreature->m_pStats->HasFeat(Constants::Feat::EpicEnergyResistance_Sonic2))
hashedFeatLabel = CRULES_HASHEDSTR("EPIC_ENERGY_RESISTANCE_AMOUNT_2");
else if (thisCreature->m_pStats->HasFeat(Constants::Feat::EpicEnergyResistance_Sonic1))
hashedFeatLabel = CRULES_HASHEDSTR("EPIC_ENERGY_RESISTANCE_AMOUNT_1");
}

if (hashedFeatLabel != 0)
{
auto it = Globals::Rules()->m_ruleset_2da_cache.find(hashedFeatLabel);
if (it != Globals::Rules()->m_ruleset_2da_cache.end())
{
CachedRulesetEntry *epicResistanceEntry = &it->second;
int32_t resistance = Globals::Rules()->GetRulesetIntEntry(CRULES_HASHEDSTR("RESISTANCE_TO_ENERGY"), 5);

epicResistanceEntry->i += resistance;

int32_t retVal = s_DoDamageResistanceHook->CallOriginal<int32_t>(thisPtr, pDamager, nDamage, nFlags, bSimulation, bCombatDamage, bBaseWeaponDamage, bRangedAttack);

epicResistanceEntry->i -= resistance;
return retVal;
}
else
{
LOG_WARNING("Ruleset entry for EPIC_ENERGY_RESISTANCE_AMOUNT_? not found. Tweak is not working!");
}
}

return s_DoDamageResistanceHook->CallOriginal<int32_t>(thisPtr, pDamager, nDamage, nFlags, bSimulation, bCombatDamage, bBaseWeaponDamage, bRangedAttack);
}, Hooks::Order::Early);
}

}

0 comments on commit 69ba8de

Please sign in to comment.