2026/01/30 Update

Updated version number.
Fixed Touch of Golden Ice.
Removed Leadership related feats from Thrallherds feat list.
Necrocarnum Circlet should only fire the Detect Undead cone VFX once.
Desert Wind maneuvers should to the right amount of damage.
Blade Guide now takes less damage during combat.
FEAT_HOSPITALER_SPELLCASTING_PALADIN was missing from HospitalerMarkerFeats()
Frenzied Berzerker should now work with Vow of Poverty and Forsaker.
prc_wallbreathc now uses PRCEffectDamage().
Changed Mantle of Egregious Might back to Dodge AC.
Tweaked Mirror Image.
This commit is contained in:
Jaysyn904
2026-01-30 18:11:38 -05:00
parent 5464837d0b
commit 875f00c88f
79 changed files with 52563 additions and 47021 deletions

View File

@@ -0,0 +1,147 @@
//:://////////////////////////////////////////////
//: ft_tch_gold_ice.nss
/*
Touch of Golden Ice
(Book of Exalted Deeds, p. 47)
[Exalted]
Your touch is poisonous to evil creatures.
Prerequisite: CON 13
Benefit: Any evil creature you touch with your
bare hand, fist, or natural weapon is ravaged
by golden ice (see Ravages and Afflictions in
Chapter 3: Exalted Equipment for effects).
This handles the onHit events.
*/
//:
//:://////////////////////////////////////////////
//::
//:: Created by: Jaysyn
//:: Created on: 2026-01-30 08:21:32
//::
//:://////////////////////////////////////////////
#include "prc_inc_function"
#include "prc_inc_unarmed"
#include "prc_inc_onhit"
#include "prc_inc_combat"
#include "inc_ravage"
void main()
{
int nEvent = GetRunningEvent();
if(DEBUG) DoDebug("ft_tch_gold_ice running, event: " + IntToString(nEvent));
// Get the PC. This is event-dependent
object oPC;
switch(nEvent)
{
case EVENT_ITEM_ONHIT: oPC = OBJECT_SELF; break;
case EVENT_ONPLAYEREQUIPITEM: oPC = GetItemLastEquippedBy(); break;
case EVENT_ONPLAYERUNEQUIPITEM: oPC = GetItemLastUnequippedBy(); break;
default:
oPC = OBJECT_SELF;
}
// Check if character has the feat and meets requirements
if(!GetHasFeat(FEAT_RAVAGEGOLDENICE, oPC) ||
GetAlignmentGoodEvil(oPC) != ALIGNMENT_GOOD)
return;
// We aren't being called from any event, instead from EvalPRCFeats
if(nEvent == FALSE)
{
// Hook in the events
if(DEBUG) DoDebug("ft_tch_gold_ice: Adding eventhooks");
AddEventScript(oPC, EVENT_ONPLAYEREQUIPITEM, "ft_tch_gold_ice", TRUE, FALSE);
AddEventScript(oPC, EVENT_ONPLAYERUNEQUIPITEM, "ft_tch_gold_ice", TRUE, FALSE);
AddEventScript(oPC, CALLBACKHOOK_UNARMED, "ft_tch_gold_ice", TRUE, FALSE);
}
// We're being called from the OnHit eventhook
else if(nEvent == EVENT_ITEM_ONHIT)
{
object oTarget = PRCGetSpellTargetObject();
if(DEBUG) DoDebug("ft_tch_gold_ice: OnHit:\n"
+ "oPC = " + DebugObject2Str(oPC) + "\n"
+ "oTarget = " + DebugObject2Str(oTarget) + "\n");
// Check constitution prerequisite (Con 13)
if(GetAbilityScore(oPC, ABILITY_CONSTITUTION, TRUE) < 13)
return;
// Only affect evil targets
if(GetAlignmentGoodEvil(oTarget) == ALIGNMENT_EVIL)
{
effect eRavage = EffectPoison(POISON_RAVAGE_GOLDEN_ICE);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eRavage, oTarget);
effect eVFX = EffectVisualEffect(VFX_IMP_PULSE_NATURE);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVFX, oTarget);
}
}
// We are called from the Unarmed Callback eventhook
else if(nEvent == CALLBACKHOOK_UNARMED)
{
if(DEBUG) DoDebug("ft_tch_gold_ice: Unarmed callback - adding to creature weapon");
// Get the creature weapon that was just created
object oCreatureWeapon = GetItemInSlot(INVENTORY_SLOT_CWEAPON_L, oPC);
if(GetIsObjectValid(oCreatureWeapon))
{
IPSafeAddItemProperty(oCreatureWeapon,
ItemPropertyOnHitCastSpell(IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER, 1),
9999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
AddEventScript(oCreatureWeapon, EVENT_ITEM_ONHIT, "ft_tch_gold_ice", TRUE, FALSE);
if(DEBUG) DoDebug("ft_tch_gold_ice: Added on-hit property to creature weapon");
}
}
// We are called from the OnPlayerEquipItem eventhook
else if(nEvent == EVENT_ONPLAYEREQUIPITEM)
{
object oItem = GetItemLastEquipped();
object oSkin = GetPCSkin(oPC);
if(DEBUG) DoDebug("ft_tch_gold_ice - OnEquip\n"
+ "oPC = " + DebugObject2Str(oPC) + "\n"
+ "oItem = " + DebugObject2Str(oItem) + "\n");
// Add to unarmed weapons only
if(oItem == GetItemInSlot(INVENTORY_SLOT_ARMS, oPC))
{
// Add to gloves
IPSafeAddItemProperty(oItem,
ItemPropertyOnHitCastSpell(IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER, 1),
9999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
AddEventScript(oItem, EVENT_ITEM_ONHIT, "ft_tch_gold_ice", TRUE, FALSE);
// Also add to creature weapon if it exists
object oCreatureWeapon = GetItemInSlot(INVENTORY_SLOT_CWEAPON_L, oPC);
if(GetIsObjectValid(oCreatureWeapon))
{
IPSafeAddItemProperty(oCreatureWeapon,
ItemPropertyOnHitCastSpell(IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER, 1),
9999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
AddEventScript(oCreatureWeapon, EVENT_ITEM_ONHIT, "ft_tch_gold_ice", TRUE, FALSE);
}
}
}
// We are called from the OnPlayerUnEquipItem eventhook
else if(nEvent == EVENT_ONPLAYERUNEQUIPITEM)
{
object oItem = GetItemLastUnequipped();
if(DEBUG) DoDebug("ft_tch_gold_ice - OnUnEquip\n"
+ "oPC = " + DebugObject2Str(oPC) + "\n"
+ "oItem = " + DebugObject2Str(oItem) + "\n");
// Remove eventhook and property
RemoveEventScript(oItem, EVENT_ITEM_ONHIT, "ft_tch_gold_ice", TRUE, FALSE);
RemoveSpecificProperty(oItem, ITEM_PROPERTY_ONHITCASTSPELL, IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER, 0, 1, "", -1, DURATION_TYPE_TEMPORARY);
}
}

View File

@@ -1,11 +1,54 @@
#include "prc_alterations"
#include "prc_inc_spells"
#include "inc_poison"
//:://////////////////////////////////////////////
//: gen_sptouchice.nss
/*
Touch of Golden Ice
(Book of Exalted Deeds, p. 47)
void main()
[Exalted]
Your touch is poisonous to evil creatures.
Prerequisite: CON 13
Benefit: Any evil creature you touch with your
bare hand, fist, or natural weapon is ravaged
by golden ice (see Ravages and Afflictions in
Chapter 3: Exalted Equipment for effects).
This handles the activated feat.
*/
//:
//:://////////////////////////////////////////////
//::
//:: Created by: Jaysyn
//:: Created on: 2026-01-30 08:21:32
//::
//:://////////////////////////////////////////////
#include "prc_alterations"
#include "prc_inc_spells"
#include "inc_poison"
#include "prc_inc_sp_tch"
void main()
{
object oTarget = PRCGetSpellTargetObject();
// Perform melee touch attack
int nTouchAttack = PRCDoMeleeTouchAttack(oTarget);
// Only apply ravage if the touch attack hits
if(nTouchAttack > 0)
{
effect ePoison = EffectPoison(POISON_RAVAGE_GOLDEN_ICE);
SPApplyEffectToObject(DURATION_TYPE_PERMANENT, ePoison, oTarget, 0.0f, FALSE);
}
}
/* void main()
{
object oTarget = PRCGetSpellTargetObject();
effect ePoison = EffectPoison(POISON_RAVAGE_GOLDEN_ICE);
SPApplyEffectToObject(DURATION_TYPE_PERMANENT, ePoison, oTarget, 0.0f, FALSE);
}
} */

View File

@@ -1933,6 +1933,7 @@ int HospitalerMarkerFeats()
+ GetHasFeat(FEAT_HOSPITALER_SPELLCASTING_FAVOURED_SOUL)
+ GetHasFeat(FEAT_HOSPITALER_SPELLCASTING_HEALER)
+ GetHasFeat(FEAT_HOSPITALER_SPELLCASTING_OCULAR)
+ GetHasFeat(FEAT_HOSPITALER_SPELLCASTING_PALADIN)
+ GetHasFeat(FEAT_HOSPITALER_SPELLCASTING_OASHAMAN)
+ GetHasFeat(FEAT_HOSPITALER_SPELLCASTING_SPSHAMAN)
+ GetHasFeat(FEAT_HOSPITALER_SPELLCASTING_UR_PRIEST);

View File

@@ -244,6 +244,7 @@ void EvilBrand(object oPC, object oSkin, int iEquip)
BrandApply(oPC, oSkin, 0);
}
*/
void main()
{
object oPC = OBJECT_SELF;
@@ -275,13 +276,19 @@ void main()
}
// Feats are checked here
//if(GetHasFeat(FEAT_SAC_VOW, oPC)) ExecuteScript("prc_vows", oPC);
//if(GetHasFeat(FEAT_LICHLOVED, oPC)) ExecuteScript("prc_lichloved", oPC);
if (GetHasFeat(FEAT_RAVAGEGOLDENICE, oPC)) ExecuteScript("ft_tch_gold_ice", oPC);
if(GetHasFeat(FEAT_EB_HAND, oPC) ||
GetHasFeat(FEAT_EB_HEAD, oPC) ||
GetHasFeat(FEAT_EB_CHEST, oPC) ||
GetHasFeat(FEAT_EB_ARM, oPC) ||
GetHasFeat(FEAT_EB_NECK, oPC) ) ExecuteScript("prc_evilbrand", oPC);
GetHasFeat(FEAT_EB_NECK, oPC) ) ExecuteScript("prc_evilbrand", oPC);
if(GetHasFeat(FEAT_ETERNAL_FREEDOM, oPC)) ExecuteScript("etern_free", oPC);
//if(GetHasFeat(FEAT_SAC_VOW, oPC)) ExecuteScript("prc_vows", oPC);
//if(GetHasFeat(FEAT_LICHLOVED, oPC)) ExecuteScript("prc_lichloved", oPC);
//if(GetHasFeat(FEAT_VILE_WILL_DEFORM, oPC) ||
// GetHasFeat(FEAT_VILE_DEFORM_GAUNT, oPC)||
// GetHasFeat(FEAT_VILE_DEFORM_OBESE, oPC) ) ExecuteScript("prc_vilefeats", oPC);
@@ -316,7 +323,7 @@ void main()
//if(GetHasFeat(FEAT_LINGERING_DAMAGE, oPC)) ExecuteScript("ft_lingdmg", oPC);
//if(GetHasFeat(FEAT_MAGICAL_APTITUDE, oPC)) ExecuteScript("prc_magaptitude", oPC);
if(GetHasFeat(FEAT_ETERNAL_FREEDOM, oPC)) ExecuteScript("etern_free", oPC);
if(GetHasFeat(FEAT_INTUITIVE_ATTACK, oPC) || GetLocalInt(oPC, "VoPFeat"+IntToString(FEAT_INTUITIVE_ATTACK))) ExecuteScript("prc_intuiatk", oPC);
//if(GetPersistantLocalInt(oPC, "EpicSpell_TransVital")) ExecuteScript("trans_vital", oPC);

View File

@@ -41,12 +41,23 @@ void CheckSupremePowerAttack(object oPC, int iEquip)
}
}
void ApplyAutoFrenzy(object oPC, object oArmor)
void ApplyAutoFrenzy(object oPC, object oArmor)
{
// Create the OnHitCastSpell property
itemproperty ipFrenzy = ItemPropertyOnHitCastSpell(IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER, 1);
// Tag it as protected to bypass Vow of Poverty restrictions
ipFrenzy = TagItemProperty(ipFrenzy, "Tag_PRC_OnHitKeeper");
// Apply the tagged property
IPSafeAddItemProperty(oArmor, ipFrenzy, 9999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
SetLocalInt(oPC, "AFrenzy", 2);
}
/* void ApplyAutoFrenzy(object oPC, object oArmor)
{
IPSafeAddItemProperty(oArmor, ItemPropertyOnHitCastSpell(IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER, 1), 9999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
SetLocalInt(oPC, "AFrenzy", 2);
}
*/
void RemoveAutoFrenzy(object oPC, object oArmor)
{
RemoveSpecificProperty(oArmor, ITEM_PROPERTY_ONHITCASTSPELL, IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER, 0, 1, "", -1, DURATION_TYPE_TEMPORARY);

View File

@@ -40,7 +40,8 @@ void main()
int nDiceNumber = GetLocalInt(oDragon, "BarrierDiceNumber");
int nSaveDC = 10 + GetHitDice(oDragon) / 2 + PRCMax(GetAbilityModifier(ABILITY_CONSTITUTION, oDragon), 0);
//Declare and assign personal impact visual effect.
switch (nDamageType)
switch (nDamageType)
{
case DAMAGE_TYPE_ACID:
nSaveDamageType = SAVING_THROW_TYPE_ACID;
@@ -98,7 +99,7 @@ void main()
if(nDamage > 0)
{
// Apply effects to the currently selected target.
eDam = EffectDamage(nDamage, nDamageType);
eDam = PRCEffectDamage(oTarget, nDamage, nDamageType);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
}