2026/03/20 Update

Fixed issue where Factotum's Arcane Dilettante post rest dialog wasn't appearing.
Desecrate now correctly doubles a caster's Animate Dead HD pool.
Effects are now removed when leaving an area of Desecration.
Undead HD pool is now calculated correctly in Animate Dead.
This commit is contained in:
Jaysyn904
2026-03-20 18:07:36 -04:00
parent ef380d9efb
commit 01eb86d307
5 changed files with 49 additions and 26 deletions

View File

@@ -61,7 +61,7 @@ void main()
if(nEvent == FALSE) if(nEvent == FALSE)
{ {
// Add eventhook to OnRestFinished to reset the used marker // Add eventhook to OnRestFinished to reset the used marker
AddEventScript(oPC, EVENT_ONPLAYERREST_FINISHED, "prc_factotum", FALSE, FALSE); AddEventScript(oPC, EVENT_ONPLAYERREST_FINISHED, "prc_factotum", TRUE, FALSE);
if (!GetLocalInt(oPC, "InspirationHBRunning")) DeleteLocalInt(oPC, "InspirationHB"); if (!GetLocalInt(oPC, "InspirationHBRunning")) DeleteLocalInt(oPC, "InspirationHB");
if (!GetLocalInt(oPC, "InspirationHB") && !GetLocalInt(oPC, "InspirationHBRunning")) if (!GetLocalInt(oPC, "InspirationHB") && !GetLocalInt(oPC, "InspirationHBRunning"))
{ {
@@ -69,7 +69,7 @@ void main()
SetLocalInt(oPC, "InspirationHB", TRUE); SetLocalInt(oPC, "InspirationHB", TRUE);
} }
} }
else if(EVENT_ONCLIENTENTER) else if(nEvent == EVENT_ONCLIENTENTER)
{ {
if(GetLevelByClass(CLASS_TYPE_FACTOTUM, oPC) > 0) if(GetLevelByClass(CLASS_TYPE_FACTOTUM, oPC) > 0)
{ {
@@ -84,6 +84,6 @@ void main()
AssignCommand(oPC, ClearAllActions(TRUE)); AssignCommand(oPC, ClearAllActions(TRUE));
ClearFactotumSlots(oPC); ClearFactotumSlots(oPC);
SetLocalInt(oPC, "FactotumArcDil", GetMaxArcDilSpellLevel(oPC)); SetLocalInt(oPC, "FactotumArcDil", GetMaxArcDilSpellLevel(oPC));
StartDynamicConversation("prc_fact_splconv", oPC, DYNCONV_EXIT_NOT_ALLOWED, FALSE, TRUE, oPC); DelayCommand(0.1f, StartDynamicConversation("prc_fact_splconv", oPC, DYNCONV_EXIT_NOT_ALLOWED, FALSE, TRUE, oPC));
} }
} }

View File

@@ -74,6 +74,8 @@ void main()
eLink = EffectLinkEffects(eLink, EffectAttackIncrease(1)); eLink = EffectLinkEffects(eLink, EffectAttackIncrease(1));
eLink = EffectLinkEffects(eLink, EffectSavingThrowIncrease(SAVING_THROW_ALL, 1)); eLink = EffectLinkEffects(eLink, EffectSavingThrowIncrease(SAVING_THROW_ALL, 1));
eLink = EffectLinkEffects(eLink, EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE)); eLink = EffectLinkEffects(eLink, EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE));
eLink = EffectLinkEffects(eLink, EffectTurnResistanceIncrease(3));
effect eHP = EffectTemporaryHitpoints(GetHitDice(oTarget)); effect eHP = EffectTemporaryHitpoints(GetHitDice(oTarget));
effect eVis = EffectVisualEffect(VFX_IMP_HOLY_AID); effect eVis = EffectVisualEffect(VFX_IMP_HOLY_AID);
@@ -82,13 +84,27 @@ void main()
eHP = TagEffect(eHP, "EFFECT_DESECRATE_HP"); eHP = TagEffect(eHP, "EFFECT_DESECRATE_HP");
if(!GetPRCSwitch(PRC_TRUE_NECROMANCER_ALTERNATE_VISUAL)) if(!GetPRCSwitch(PRC_TRUE_NECROMANCER_ALTERNATE_VISUAL))
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget); SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
else else
eLink = EffectLinkEffects(eLink, EffectVisualEffect(VFX_DUR_PROTECTION_EVIL_MINOR)); eLink = EffectLinkEffects(eLink, EffectVisualEffect(VFX_DUR_PROTECTION_EVIL_MINOR));
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eLink, oTarget); SPApplyEffectToObject(DURATION_TYPE_PERMANENT, eLink, oTarget, 0.0f, SPELL_DESECRATE);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eHP, oTarget); SPApplyEffectToObject(DURATION_TYPE_PERMANENT, eHP, oTarget, 0.0f, SPELL_DESECRATE);
} }
else
{
// Apply visual indicator for non-undead
effect eIcon = EffectIcon(EFFECT_ICON_FRIGHTENED);
effect eVis = EffectVisualEffect(VFX_DUR_CESSATE_NEGATIVE);
//effect eLink = EffectLinkEffects(eIcon, eVis);
effect eLink = EffectLinkEffects(eLink, eVis);
eLink = EffectLinkEffects(eLink, EffectSavingThrowIncrease(SAVING_THROW_ALL, 1));
eLink = EffectLinkEffects(eLink, EffectSavingThrowDecrease(SAVING_THROW_ALL, 1));
eLink = TagEffect(eLink, "EFFECT_DESECRATE_AURA");
SPApplyEffectToObject(DURATION_TYPE_PERMANENT, eLink, oTarget, 0.0f, SPELL_DESECRATE);
}
} }

View File

@@ -1,5 +1,5 @@
//:://///////////////////////////////////////////// //::///////////////////////////////////////////////
//:: Desecrate //:: Desecrate onExit script
//:: prc_tn_des_b //:: prc_tn_des_b
//::////////////////////////////////////////////// //:://////////////////////////////////////////////
/* /*
@@ -10,15 +10,23 @@
void main() void main()
{ {
object oTarget = GetExitingObject(); object oTarget = GetExitingObject();
effect eAOE = GetFirstEffect(oTarget); // Search through the valid effects on the target
if(GetEffectCreator(eAOE) == GetAreaOfEffectCreator()) effect eAOE = GetFirstEffect(oTarget);
{ while (GetIsEffectValid(eAOE))
string sTag = GetEffectTag(eAOE); {
if(sTag == "EFFECT_DESECRATE_AURA" || sTag == "EFFECT_DESECRATE_HP") // If the effect was created by the AoE then remove it
RemoveEffect(oTarget, eAOE); if (GetEffectCreator(eAOE) == GetAreaOfEffectCreator())
} {
string sTag = GetEffectTag(eAOE);
if(sTag == "EFFECT_DESECRATE_AURA" || sTag == "EFFECT_DESECRATE_HP")
RemoveEffect(oTarget, eAOE);
}
// Get next effect on the target
eAOE = GetNextEffect(oTarget);
}
}
/* object oTarget = GetExitingObject(); /* object oTarget = GetExitingObject();
@@ -37,4 +45,3 @@ void main()
eAOE = GetNextEffect(oTarget); eAOE = GetNextEffect(oTarget);
} }
} */ } */
}

View File

@@ -64,7 +64,7 @@ void main()
if(GetPRCSwitch(PRC_PNP_ANIMATE_DEAD)) if(GetPRCSwitch(PRC_PNP_ANIMATE_DEAD))
{ {
int nMaxHD = GetLevelByClass(CLASS_TYPE_DREAD_NECROMANCER, oCaster) >= 8 ? int nMaxHD = GetLevelByClass(CLASS_TYPE_DREAD_NECROMANCER, oCaster) >= 8 ?
nCasterLevel * (4 + GetAbilityModifier(ABILITY_CHARISMA, oCaster)) : nCasterLevel * 4; nCasterLevel * (4 + GetAbilityModifier(ABILITY_CHARISMA, oCaster)) : nCasterLevel * 2;
if(GetHasSpellEffect(SPELL_DES_20) || GetHasSpellEffect(SPELL_DES_100) || GetHasSpellEffect(SPELL_DESECRATE)) if(GetHasSpellEffect(SPELL_DES_20) || GetHasSpellEffect(SPELL_DES_100) || GetHasSpellEffect(SPELL_DESECRATE))
nMaxHD *= 2; nMaxHD *= 2;

View File

@@ -1,5 +1,5 @@
//:://///////////////////////////////////////////// //::///////////////////////////////////////////////
//:: Desecrate //:: Desecrate onEnter script
//:: sp_desecrate.nss //:: sp_desecrate.nss
//:: ////////////////////////////////////////////// //:: //////////////////////////////////////////////
/* /*
@@ -41,7 +41,7 @@ void main()
float fDuration = HoursToSeconds(2 * nCastLvl); float fDuration = HoursToSeconds(2 * nCastLvl);
int nMetaMagic = PRCGetMetaMagicFeat(); int nMetaMagic = PRCGetMetaMagicFeat();
int nDesecrate; int nDesecrate;
string sTag = Get2DACache("vfx_persistent", "LABEL", AOE_PER_CONSECRATE); string sTag = Get2DACache("vfx_persistent", "LABEL", AOE_PER_DESECRATE);
//Make sure duration does no equal 0 //Make sure duration does no equal 0
if(fDuration < 2.0) if(fDuration < 2.0)
@@ -76,7 +76,7 @@ void main()
ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY, eVis, lLoc, fDuration); ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY, eVis, lLoc, fDuration);
oAoE = GetAreaOfEffectObject(lLoc, "VFX_AOE_DESECRATE_20"); oAoE = GetAreaOfEffectObject(lLoc, "VFX_AOE_DESECRATE_20");
SetAllAoEInts(SPELL_CONSECRATE, oAoE, 20, 0, nCastLvl); SetAllAoEInts(SPELL_DESECRATE, oAoE, 20, 0, nCastLvl);
} }
PRCSetSchool(); PRCSetSchool();