Files
PRC8/nwn/nwnprc/trunk/scripts/prc_forsaker.nss
Jaysyn904 306779349c 2026/06/05 Update
Added Sanctified damage type.
Added Holy damage type.
Added Unholy damage type.
Added Falling damage type.
Added Ballistic damage type.
Added Desiccation damage type.
Fixed Major Missile's LABEL in spells.2da.
Fixed Major Missile's LABEL in des_cft_spells.2da.
Fixed Major Missile's LABEL in des_cft_scrolls.2da.
Disabled incomplete PnP version of Shades spell.
Astaroth's free crafting feats should drop off onRest, when expelling a vestige & when rebinding a vestige.
Re-enabled caster level override variable clearing in GetInvokerLevel().
Change Piercing Cold's damagetype to Untyped.
Constanted new damagetypes correctly for scripting (@lightbeard)
Changed all force spells damagetype to force.
Fixed issue with Initiators using Shadows Blade, Ironheart Aura and Shadow Trickster with dual-stances.
Changed Eldritch Blast to Untyped damage.
Fixed Path of Shadow screwing up caster levels.
Changed Sanctify Martial strike to be Holy damage.
Changed Vile Martial strike to be Vile damage.
Updated Forsaker to work with Warforged "Armor".
Added a SignalEvent() to Invisible Needle so it would break Invisibility when it should.
Fixed equip exploit with Shou Disciple and monk weapons.
Changed Saint template's Holy Touch to do Holy Damage.
Changed Horrid Wilting to do Desiccation damage.
Fixed Break Enchantment's targeting.
Fixed the Command spell to obey mind immunity.
Changed Damning Darkness to do Unholy damage.
Change the Necrotic spells to do Vile damage.
Made Persistent Blade more like PnP and made it dispellable.
2026-06-05 21:33:30 -04:00

703 lines
27 KiB
Plaintext

//::///////////////////////////////////////////////
//:: Name Forsaker
//:: FileName prc_forsaker.nss
//:: Created By: Stratosvarious
//:: Edited By: Fencas
//:://////////////////////////////////////////////
#include "prc_inc_function"
#include "prc_inc_combat"
#include "inc_dynconv"
#include "prc_alterations"
int PRCStackSpellResistance(object oPC)
{
int nTotalSR = 0;
// Racial Spell Resistance
int nRacialSR = 0;
if(GetHasFeat(FEAT_SPELL27, oPC)) nRacialSR = 27;
else if(GetHasFeat(FEAT_SPELL25, oPC)) nRacialSR = 25;
else if(GetHasFeat(FEAT_SPELL23, oPC)) nRacialSR = 23;
else if(GetHasFeat(FEAT_SPELL22, oPC)) nRacialSR = 22;
else if(GetHasFeat(FEAT_SPELL21, oPC)) nRacialSR = 21;
else if(GetHasFeat(FEAT_SPELL20, oPC)) nRacialSR = 20;
else if(GetHasFeat(FEAT_SPELL19, oPC)) nRacialSR = 19;
else if(GetHasFeat(FEAT_SPELL18, oPC)) nRacialSR = 18;
else if(GetHasFeat(FEAT_SPELL17, oPC)) nRacialSR = 17;
else if(GetHasFeat(FEAT_SPELL16, oPC)) nRacialSR = 16;
else if(GetHasFeat(FEAT_SPELL15, oPC)) nRacialSR = 15;
else if(GetHasFeat(FEAT_SPELL14, oPC)) nRacialSR = 14;
else if(GetHasFeat(FEAT_SPELL13, oPC)) nRacialSR = 13;
else if(GetHasFeat(FEAT_SPELL11, oPC)) nRacialSR = 11;
else if(GetHasFeat(FEAT_SPELL10, oPC)) nRacialSR = 10;
else if(GetHasFeat(FEAT_SPELL8, oPC)) nRacialSR = 8;
else if(GetHasFeat(FEAT_SPELL5, oPC)) nRacialSR = 5;
if(nRacialSR > 0)
{
nTotalSR += nRacialSR + GetHitDice(oPC); // Base SR + 1 per level
}
// Improved Spell Resistance feats (epic feats, +2 SR each, stackable)
int nImprovedSR = 0;
if(GetHasFeat(FEAT_EPIC_IMPROVED_SPELL_RESISTANCE_1, oPC)) nImprovedSR += 2;
if(GetHasFeat(FEAT_EPIC_IMPROVED_SPELL_RESISTANCE_2, oPC)) nImprovedSR += 2;
if(GetHasFeat(FEAT_EPIC_IMPROVED_SPELL_RESISTANCE_3, oPC)) nImprovedSR += 2;
if(GetHasFeat(FEAT_EPIC_IMPROVED_SPELL_RESISTANCE_4, oPC)) nImprovedSR += 2;
if(GetHasFeat(FEAT_EPIC_IMPROVED_SPELL_RESISTANCE_5, oPC)) nImprovedSR += 2;
if(GetHasFeat(FEAT_EPIC_IMPROVED_SPELL_RESISTANCE_6, oPC)) nImprovedSR += 2;
if(GetHasFeat(FEAT_EPIC_IMPROVED_SPELL_RESISTANCE_7, oPC)) nImprovedSR += 2;
if(GetHasFeat(FEAT_EPIC_IMPROVED_SPELL_RESISTANCE_8, oPC)) nImprovedSR += 2;
if(GetHasFeat(FEAT_EPIC_IMPROVED_SPELL_RESISTANCE_9, oPC)) nImprovedSR += 2;
if(GetHasFeat(FEAT_EPIC_IMPROVED_SPELL_RESISTANCE_10, oPC)) nImprovedSR += 2;
nTotalSR += nImprovedSR;
// Class-based Spell Resistance
int nMonkLvl = GetLevelByClass(CLASS_TYPE_MONK, oPC);
int nForsakerLvl = GetLevelByClass(CLASS_TYPE_FORSAKER, oPC);
int nEnlightenedFistLvl = GetLevelByClass(CLASS_TYPE_ENLIGHTENEDFIST, oPC);
int nDraconicMysteriesLvl = GetLevelByClass(CLASS_TYPE_INITIATE_DRACONIC, oPC);
int nSanctifiedMindLvl = GetLevelByClass(CLASS_TYPE_SANCTIFIED_MIND, oPC);
int nUrPriestLvl = GetLevelByClass(CLASS_TYPE_UR_PRIEST, oPC);
// Monk Diamond Soul (level 13+)
if(nMonkLvl >= 13)
{
nTotalSR += (nMonkLvl + 10);
}
// Forsaker SR
if(nForsakerLvl > 0)
{
nTotalSR += (10 + nForsakerLvl);
}
// Enlightened Fist Diamond Soul (level 9+)
if(nEnlightenedFistLvl >= 9)
{
nTotalSR += (10 + nMonkLvl + nEnlightenedFistLvl);
}
// Initiate of Draconic Mysteries (level 7+)
if(nDraconicMysteriesLvl >= 7)
{
nTotalSR += (15 + nDraconicMysteriesLvl);
}
// Sanctified Mind Power Resistance (level 6+)
if(nSanctifiedMindLvl >= 6)
{
nTotalSR += (5 + GetHitDice(oPC));
}
// Ur-Priest Divine Spell Resistance
if(nUrPriestLvl >= 8)
{
nTotalSR += 20; // SR 20 at level 8+
}
else if(nUrPriestLvl >= 4)
{
nTotalSR += 15; // SR 15 at level 4-7
}
return nTotalSR;
}
void main()
{
int nEvent = GetRunningEvent();
if(DEBUG) DoDebug("prc_forsaker 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;
case EVENT_ONHEARTBEAT: oPC = OBJECT_SELF; break;
default:
oPC = OBJECT_SELF;
}
object oItem;
object oArmor;
object oShield;
object oSkin = GetPCSkin(oPC);
int nSlot;
int nForsakerLvl = GetLevelByClass(CLASS_TYPE_FORSAKER, oPC);
int nForsakerLvlCheck;
int nBonus = nForsakerLvl/2;
int nRegen = 1 + nForsakerLvl/4;
int nSR = 10 + nForsakerLvl;
// Calculate stacked spell resistance for Forsaker special case
int nTotalSR = PRCStackSpellResistance(oPC);
// Apply combined SR as single property
IPSafeAddItemProperty(oSkin, ItemPropertyBonusSpellResistance(GetSRByValue(nTotalSR)), 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, FALSE);
if(nEvent == FALSE)
{
//Check if level up bonus has already been chosen and given for any of past Forsaker levels
for(nForsakerLvlCheck=1; nForsakerLvlCheck <= nForsakerLvl; nForsakerLvlCheck++)
{
if(!GetPersistantLocalInt(oPC, "ForsakerBoost"+IntToString(nForsakerLvlCheck)))
{
//Level up box for stat bonus
AssignCommand(oPC, ClearAllActions(TRUE));
SetPersistantLocalInt(oPC,"ForsakerBoostCheck",nForsakerLvlCheck);
StartDynamicConversation("prc_forsake_abil", oPC, DYNCONV_EXIT_NOT_ALLOWED, FALSE, TRUE, oPC);
}
}
//Fast healing 1 (+1 each 4 levels)
SetCompositeBonus(oSkin,"ForsakerFH",nRegen,ITEM_PROPERTY_REGENERATION);
//SR = 10 + Forsaker level
IPSafeAddItemProperty(oSkin, ItemPropertyBonusSpellResistance(GetSRByValue(nSR)), 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, FALSE);
//DR starting on level 2 = (level+1)/(Level/2)
if (nForsakerLvl >=2) ApplyEffectToObject(DURATION_TYPE_PERMANENT,EffectDamageReduction((nForsakerLvl+1),(nForsakerLvl/2)),oPC);
//Natural AC increase by CON starting on level 3
if (nForsakerLvl >= 3)
{
effect eEffect1 = EffectACIncrease(GetAbilityModifier(ABILITY_CONSTITUTION, oPC), AC_NATURAL_BONUS);
eEffect1 = ExtraordinaryEffect(eEffect1);
eEffect1 = TagEffect(eEffect1, "EffectToughDefense");
//Remove any prior bonus to avoid duplication
effect eCheckEffect = GetFirstEffect(oPC);
while (GetIsEffectValid(eCheckEffect))
{
if(GetEffectTag(eCheckEffect) == "EffectToughDefense") RemoveEffect(oPC, eCheckEffect);
eCheckEffect = GetNextEffect(oPC);
}
//Give player the bonus
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEffect1, oPC);
}
if(!GetHasFeat(FEAT_VOWOFPOVERTY,oPC))
{
if(GetIsUnarmed(oPC) && (nForsakerLvl >= 3)) //If it is unarmed, give DR bypass
{
ApplyEffectToObject(DURATION_TYPE_PERMANENT,EffectAttackIncrease(nBonus),oPC);
ApplyEffectToObject(DURATION_TYPE_PERMANENT,EffectAttackDecrease(nBonus),oPC);
}
}
// Hook in the events, needed from level 1 for Magic Hatred
if(DEBUG) DoDebug("prc_forsaker: Adding eventhooks");
AddEventScript(oPC, EVENT_ONPLAYEREQUIPITEM, "prc_forsaker", TRUE, FALSE);
AddEventScript(oPC, EVENT_ONPLAYERUNEQUIPITEM, "prc_forsaker", TRUE, FALSE);
}
// We are called from the OnPlayerEquipItem eventhook. Handle magical item restriction
else if(nEvent == EVENT_ONPLAYEREQUIPITEM)
{
oPC = GetItemLastEquippedBy();
oItem = GetItemLastEquipped();
string sTag = GetTag(oItem);
string sResRef = GetResRef(oItem);
int nRace = GetRacialType(oPC);
if(DEBUG) DoDebug("prc_forsaker - OnEquip\n"
+ "oPC = " + DebugObject2Str(oPC) + "\n"
+ "oItem = " + DebugObject2Str(oItem) + "\n");
if(nRace == RACIAL_TYPE_WARFORGED
|| nRace == RACIAL_TYPE_WARFORGED_SCOUT
|| nRace == RACIAL_TYPE_WARFORGED_CHARGER)
{
if(sResRef == "prc_wf_admtbody"
|| sResRef == "prc_wf_compbody"
|| sResRef == "prc_wf_woodbody"
|| sResRef == "prc_wf_mithbody"
|| sResRef == "prc_wf_helmhead"
|| sResRef == "prc_wf_helmadmt"
|| sResRef == "prc_wf_helmwood"
|| sResRef == "prc_wf_helmmith")
return;
}
if(!GetHasFeat(FEAT_VOWOFPOVERTY,oPC))
{
// Check if item is a creature item - if so, skip magical item check
int nItemType = GetBaseItemType(oItem);
if(nItemType == BASE_ITEM_CBLUDGWEAPON ||
nItemType == BASE_ITEM_CPIERCWEAPON ||
nItemType == BASE_ITEM_CREATUREITEM ||
nItemType == BASE_ITEM_CSLASHWEAPON ||
nItemType == BASE_ITEM_CSLSHPRCWEAP)
{
// Item is a creature weapon, allow it
return;
}
// Check if the item being equipped is magical
// Only check the item being equipped, not entire inventory
int bIsMagical = FALSE;
int nPropertyCount = 0;
itemproperty ipCheck = GetFirstItemProperty(oItem);
while (GetIsItemPropertyValid(ipCheck))
{
string sTag = GetItemPropertyTag(ipCheck);
int nType = GetItemPropertyType(ipCheck);
// Check for protected properties
if(sTag == "Tag_PRC_OnHitKeeper" ||
sTag == "Quality_Masterwork" ||
sTag == "Material_Mithral" ||
sTag == "Material_Adamantine" ||
sTag == "Material_Darkwood" ||
sTag == "Material_ColdIron" ||
sTag == "Material_MundaneCrystal" ||
sTag == "Material_DeepCrystal" ||
nType == ITEM_PROPERTY_MATERIAL) // All material properties
{
// Protected property - skip, don't set bIsMagical
}
else
{
// Check for helmet carveout: +1 Concentration only
if(GetBaseItemType(oItem) == BASE_ITEM_HELMET &&
GetItemPropertyType(ipCheck) == ITEM_PROPERTY_SKILL_BONUS &&
GetItemPropertySubType(ipCheck) == SKILL_CONCENTRATION &&
GetItemPropertyCostTableValue(ipCheck) == 1)
{
// This is a +1 Concentration helmet with no other properties, allow it
bIsMagical = FALSE;
break;
}
else
{
bIsMagical = TRUE;
break;
}
}
ipCheck = GetNextItemProperty(oItem);
}
/* while (GetIsItemPropertyValid(ipCheck))
{
// Skip protected properties
if(GetItemPropertyTag(ipCheck) != "Tag_PRC_OnHitKeeper")
{
nPropertyCount++;
// Check for helmet carveout: +1 Concentration only
if(GetBaseItemType(oItem) == BASE_ITEM_HELMET &&
nPropertyCount == 1 &&
GetItemPropertyType(ipCheck) == ITEM_PROPERTY_SKILL_BONUS &&
GetItemPropertySubType(ipCheck) == SKILL_CONCENTRATION &&
GetItemPropertyCostTableValue(ipCheck) == 1)
{
// This is a +1 Concentration helmet with no other properties, allow it
bIsMagical = FALSE;
break;
}
else
{
bIsMagical = TRUE;
break;
}
}
ipCheck = GetNextItemProperty(oItem);
} */
// Apply torch exclusion here (after magical item determination)
if(bIsMagical && GetResRef(oItem) == "nw_it_torch001")
{
bIsMagical = FALSE;
}
// If item is magical, unequip it
if(bIsMagical)
{
AssignCommand(oPC, ClearAllActions(TRUE));
AssignCommand(oPC, ActionUnequipItem(oItem));
FloatingTextStringOnCreature(GetName(oItem)+" is a magical item!", oPC, FALSE);
}
/* // Check if the item being equipped is magical
// Only check the item being equipped, not entire inventory
int bIsMagical = FALSE;
itemproperty ipCheck = GetFirstItemProperty(oItem);
while (GetIsItemPropertyValid(ipCheck))
{
// Skip protected properties
if(GetItemPropertyTag(ipCheck) != "Tag_PRC_OnHitKeeper")
{
bIsMagical = TRUE;
break;
}
ipCheck = GetNextItemProperty(oItem);
}
// If item is magical and not a torch, unequip it
if(bIsMagical && GetResRef(oItem) != "nw_it_torch001")
{
AssignCommand(oPC, ClearAllActions(TRUE));
AssignCommand(oPC, ActionUnequipItem(oItem));
FloatingTextStringOnCreature(GetName(oItem)+" is a magical item!", oPC, FALSE);
}
*/ // If non-magical weapon and Forsaker has DR bypass, add bonuses
else if(!bIsMagical && (IPGetIsMeleeWeapon(oItem) || GetWeaponRanged(oItem)) && (nForsakerLvl >= 3))
{
// Add DR bypass bonuses to non-magical weapons
itemproperty ipAttack = ItemPropertyAttackBonus(nBonus);
ipAttack = TagItemProperty(ipAttack, "ForsakerDRBypass");
IPSafeAddItemProperty(oItem, ipAttack, 99999.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, FALSE);
itemproperty ipPenalty = ItemPropertyAttackPenalty(nBonus);
ipPenalty = TagItemProperty(ipPenalty, "ForsakerDRBypass");
IPSafeAddItemProperty(oItem, ipPenalty, 99999.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, FALSE);
// Remove unarmed bonus
effect eLoop = GetFirstEffect(oPC);
while(GetIsEffectValid(eLoop))
{
if(GetEffectType(eLoop) == EFFECT_TYPE_ATTACK_INCREASE
|| GetEffectType(eLoop) == EFFECT_TYPE_ATTACK_DECREASE) RemoveEffect(oPC,eLoop);
eLoop = GetNextEffect(oPC);
}
}
}
}
// We are called from the OnPlayerUnEquipItem eventhook. Clean up Forsaker properties
else if(nEvent == EVENT_ONPLAYERUNEQUIPITEM)
{
oPC = GetItemLastUnequippedBy();
oItem = GetItemLastUnequipped();
if(DEBUG) DoDebug("prc_forsaker - OnUnEquip\n"
+ "oPC = " + DebugObject2Str(oPC) + "\n"
+ "oItem = " + DebugObject2Str(oItem) + "\n"
);
// Only remove properties that Forsaker actually added
if(IPGetIsMeleeWeapon(oItem) || GetWeaponRanged(oItem))
{
if (nForsakerLvl >= 3)
{
// Remove only tagged Forsaker properties
itemproperty ipCheck = GetFirstItemProperty(oItem);
while (GetIsItemPropertyValid(ipCheck))
{
if (GetItemPropertyTag(ipCheck) == "ForsakerDRBypass")
{
RemoveItemProperty(oItem, ipCheck);
}
ipCheck = GetNextItemProperty(oItem);
}
}
}
// If now unarmed, give DR bypass back to player
if(GetIsUnarmed(oPC) && (nForsakerLvl >= 3))
{
ApplyEffectToObject(DURATION_TYPE_PERMANENT,EffectAttackIncrease(nBonus),oPC);
ApplyEffectToObject(DURATION_TYPE_PERMANENT,EffectAttackDecrease(nBonus),oPC);
}
}
}
/* void main()
{
int nEvent = GetRunningEvent();
if(DEBUG) DoDebug("prc_forsaker 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;
case EVENT_ONHEARTBEAT: oPC = OBJECT_SELF; break;
default:
oPC = OBJECT_SELF;
}
object oItem;
object oArmor;
object oShield;
object oSkin = GetPCSkin(oPC);
int nSlot;
int nForsakerLvl = GetLevelByClass(CLASS_TYPE_FORSAKER, oPC);
int nForsakerLvlCheck;
int nBonus = nForsakerLvl/2;
int nRegen = 1 + nForsakerLvl/4;
int nSR = 10 + nForsakerLvl;
if(nEvent == FALSE)
{
//Check if level up bonus has already been chosen and given for any of past Forsaker levels
for(nForsakerLvlCheck=1; nForsakerLvlCheck <= nForsakerLvl; nForsakerLvlCheck++)
{
if(!GetPersistantLocalInt(oPC, "ForsakerBoost"+IntToString(nForsakerLvlCheck)))
{
//Level up box for stat bonus
AssignCommand(oPC, ClearAllActions(TRUE));
SetPersistantLocalInt(oPC,"ForsakerBoostCheck",nForsakerLvlCheck);
StartDynamicConversation("prc_forsake_abil", oPC, DYNCONV_EXIT_NOT_ALLOWED, FALSE, TRUE, oPC);
}
}
//Fast healing 1 (+1 each 4 levels)
SetCompositeBonus(oSkin,"ForsakerFH",nRegen,ITEM_PROPERTY_REGENERATION);
//SR = 10 + Forsaker level
IPSafeAddItemProperty(oSkin, ItemPropertyBonusSpellResistance(GetSRByValue(nSR)), 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, FALSE);
//DR starting on level 2 = (level+1)/(Level/2)
if (nForsakerLvl >=2) ApplyEffectToObject(DURATION_TYPE_PERMANENT,EffectDamageReduction((nForsakerLvl+1),(nForsakerLvl/2)),oPC);
//Natural AC increase by CON starting on level 3
if (nForsakerLvl >= 3)
{
effect eEffect1 = EffectACIncrease(GetAbilityModifier(ABILITY_CONSTITUTION, oPC), AC_NATURAL_BONUS);
eEffect1 = ExtraordinaryEffect(eEffect1);
eEffect1 = TagEffect(eEffect1, "EffectToughDefense");
//Remove any prior bonus to avoid duplication
effect eCheckEffect = GetFirstEffect(oPC);
while (GetIsEffectValid(eCheckEffect))
{
if(GetEffectTag(eCheckEffect) == "EffectToughDefense") RemoveEffect(oPC, eCheckEffect);
eCheckEffect = GetNextEffect(oPC);
}
//Give player the bonus
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEffect1, oPC);
}
if(!GetHasFeat(FEAT_VOWOFPOVERTY,oPC))
{
for (nSlot=0; nSlot < 13; nSlot++) //All but creatures slots
{
oItem=GetItemInSlot(nSlot, oPC);
//Check if it is magical and not a torch
if(GetIsItemPropertyValid(GetFirstItemProperty(oItem)) &&
!(GetItemPropertyTag(GetFirstItemProperty(oItem)) == "Tag_PRC_OnHitKeeper") &&
GetResRef(oItem) != "nw_it_torch001")
{
AssignCommand(oPC, ClearAllActions(TRUE));
AssignCommand(oPC, ActionUnequipItem(oItem));
FloatingTextStringOnCreature(GetName(oItem)+" is a magical item!", oPC, FALSE);
}
}
if(GetIsUnarmed(oPC) && (nForsakerLvl >= 3)) //If it is unarmed, give DR bypass
{
ApplyEffectToObject(DURATION_TYPE_PERMANENT,EffectAttackIncrease(nBonus),oPC);
ApplyEffectToObject(DURATION_TYPE_PERMANENT,EffectAttackDecrease(nBonus),oPC);
//Remove last weapon(s) bonus
oItem = GetPCItemLastUnequipped();
if((IPGetIsMeleeWeapon(oItem) || GetWeaponRanged(oItem)))
{
RemoveSpecificProperty(oItem, ITEM_PROPERTY_ATTACK_BONUS, -1, -1, 1, "", -1, DURATION_TYPE_TEMPORARY);
RemoveSpecificProperty(oItem, ITEM_PROPERTY_DECREASED_ATTACK_MODIFIER, -1, -1, 1, "", -1, DURATION_TYPE_TEMPORARY);
}
}
}
// Hook in the events, needed from level 1 for Magic Hatred
if(DEBUG) DoDebug("prc_forsaker: Adding eventhooks");
AddEventScript(oPC, EVENT_ONPLAYEREQUIPITEM, "prc_forsaker", TRUE, FALSE);
AddEventScript(oPC, EVENT_ONPLAYERUNEQUIPITEM, "prc_forsaker", TRUE, FALSE);
}
// We are called from the OnPlayerEquipItem eventhook. Add OnHitCast: Unique Power to oPC's weapon
else if(nEvent == EVENT_ONPLAYEREQUIPITEM)
{
oPC = GetItemLastEquippedBy();
oItem = GetItemLastEquipped();
if(DEBUG) DoDebug("prc_forsaker - OnEquip\n"
+ "oPC = " + DebugObject2Str(oPC) + "\n"
+ "oItem = " + DebugObject2Str(oItem) + "\n");
if(!GetHasFeat(FEAT_VOWOFPOVERTY,oPC))
{
for (nSlot=0; nSlot < 13; nSlot++) //All but creatures slots
{
oItem=GetItemInSlot(nSlot, oPC);
//Check if it is magical and not a torch
if(GetIsItemPropertyValid(GetFirstItemProperty(oItem)) &&
!(GetItemPropertyTag(GetFirstItemProperty(oItem)) == "Tag_PRC_OnHitKeeper") &&
GetResRef(oItem) != "nw_it_torch001")
{
AssignCommand(oPC, ClearAllActions(TRUE));
AssignCommand(oPC, ActionUnequipItem(oItem));
FloatingTextStringOnCreature(GetName(oItem)+" is a magical item!", oPC, FALSE);
}
}
if(GetIsUnarmed(oPC) && (nForsakerLvl >= 3)) //If it is unarmed, give DR bypass
{
ApplyEffectToObject(DURATION_TYPE_PERMANENT,EffectAttackIncrease(nBonus),oPC);
ApplyEffectToObject(DURATION_TYPE_PERMANENT,EffectAttackDecrease(nBonus),oPC);
//Remove last weapon(s) bonus
oItem = GetPCItemLastUnequipped();
if((IPGetIsMeleeWeapon(oItem) || GetWeaponRanged(oItem)))
{
RemoveSpecificProperty(oItem, ITEM_PROPERTY_ATTACK_BONUS, -1, -1, 1, "", -1, DURATION_TYPE_TEMPORARY);
RemoveSpecificProperty(oItem, ITEM_PROPERTY_DECREASED_ATTACK_MODIFIER, -1, -1, 1, "", -1, DURATION_TYPE_TEMPORARY);
}
}
}
}
// We are called from the OnPlayerUnEquipItem eventhook. Remove OnHitCast: Unique Power from oPC's weapon
else if(nEvent == EVENT_ONPLAYERUNEQUIPITEM)
{
oPC = GetItemLastUnequippedBy();
oItem = GetItemLastUnequipped();
if(DEBUG) DoDebug("prc_forsaker - OnUnEquip\n"
+ "oPC = " + DebugObject2Str(oPC) + "\n"
+ "oItem = " + DebugObject2Str(oItem) + "\n"
);
// Only applies to weapons
if(IPGetIsMeleeWeapon(oItem) || GetWeaponRanged(oItem))
{
if (nForsakerLvl >= 3) RemoveSpecificProperty(oItem, ITEM_PROPERTY_ATTACK_BONUS, -1, -1, 1, "", -1, DURATION_TYPE_TEMPORARY);
if (nForsakerLvl >= 3) RemoveSpecificProperty(oItem, ITEM_PROPERTY_DECREASED_ATTACK_MODIFIER, -1, -1, 1, "", -1, DURATION_TYPE_TEMPORARY);
}
}
} */
/* // We aren't being called from any event, instead from EvalPRCFeats
if(nEvent == FALSE)
{
//Check if level up bonus has already been chosen and given for any of past Forsaker levels
for(nForsakerLvlCheck=1; nForsakerLvlCheck <= nForsakerLvl; nForsakerLvlCheck++)
{
if(!GetPersistantLocalInt(oPC, "ForsakerBoost"+IntToString(nForsakerLvlCheck)))
{
//Level up box for stat bonus
AssignCommand(oPC, ClearAllActions(TRUE));
SetPersistantLocalInt(oPC,"ForsakerBoostCheck",nForsakerLvlCheck);
StartDynamicConversation("prc_forsake_abil", oPC, DYNCONV_EXIT_NOT_ALLOWED, FALSE, TRUE, oPC);
}
}
//Fast healing 1 (+1 each 4 levels)
SetCompositeBonus(oSkin,"ForsakerFH",nRegen,ITEM_PROPERTY_REGENERATION);
//SR = 10 + Forsaker level
IPSafeAddItemProperty(oSkin, ItemPropertyBonusSpellResistance(GetSRByValue(nSR)), 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, FALSE);
//DR starting on level 2 = (level+1)/(Level/2)
if (nForsakerLvl >=2) ApplyEffectToObject(DURATION_TYPE_PERMANENT,EffectDamageReduction((nForsakerLvl+1),(nForsakerLvl/2)),oPC);
//Natural AC increase by CON starting on level 3
if (nForsakerLvl >= 3)
{
effect eEffect1 = EffectACIncrease(GetAbilityModifier(ABILITY_CONSTITUTION, oPC), AC_NATURAL_BONUS);
eEffect1 = ExtraordinaryEffect(eEffect1);
eEffect1 = TagEffect(eEffect1, "EffectToughDefense");
//Remove any prior bonus to avoid duplication
effect eCheckEffect = GetFirstEffect(oPC);
while (GetIsEffectValid(eCheckEffect))
{
if(GetEffectTag(eCheckEffect) == "EffectToughDefense") RemoveEffect(oPC, eCheckEffect);
eCheckEffect = GetNextEffect(oPC);
}
//Give player the bonus
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEffect1, oPC);
}
// For some reason, EVENT_ONPLAYEREQUIPITEM just works with weapons, so armors and shields should be checked elsewhere
if(!GetHasFeat(FEAT_VOWOFPOVERTY,oPC))
{
for (nSlot=0; nSlot < 13; nSlot++) //All but creatures slots
{
oItem=GetItemInSlot(nSlot, oPC);
//Check if it is magical
if(GetIsItemPropertyValid(GetFirstItemProperty(oItem)) && !(GetItemPropertyTag(GetFirstItemProperty(oItem)) == "Tag_PRC_OnHitKeeper"))
{
AssignCommand(oPC, ClearAllActions(TRUE));
AssignCommand(oPC, ActionUnequipItem(oItem));
FloatingTextStringOnCreature(GetName(oItem)+" is a magical item!", oPC, FALSE);
}
}
if(GetIsUnarmed(oPC) && (nForsakerLvl >= 3)) //If it is unarmed, give DR bypass
{
ApplyEffectToObject(DURATION_TYPE_PERMANENT,EffectAttackIncrease(nBonus),oPC);
ApplyEffectToObject(DURATION_TYPE_PERMANENT,EffectAttackDecrease(nBonus),oPC);
//Remove last weapon(s) bonus
oItem = GetPCItemLastUnequipped();
if((IPGetIsMeleeWeapon(oItem) || GetWeaponRanged(oItem)))
{
RemoveSpecificProperty(oItem, ITEM_PROPERTY_ATTACK_BONUS, -1, -1, 1, "", -1, DURATION_TYPE_TEMPORARY);
RemoveSpecificProperty(oItem, ITEM_PROPERTY_DECREASED_ATTACK_MODIFIER, -1, -1, 1, "", -1, DURATION_TYPE_TEMPORARY);
}
}
}
// Hook in the events
AddEventScript(oPC, EVENT_SCRIPT_MODULE_ON_EQUIP_ITEM, "prc_forsaker", TRUE, FALSE);
}
// We are called from the OnPlayerEquipItem eventhook. Add OnHitCast: Unique Power to oPC's weapon
else if((nEvent == EVENT_SCRIPT_MODULE_ON_EQUIP_ITEM) && (!GetHasFeat(FEAT_VOWOFPOVERTY,oPC)))
{
oItem = GetPCItemLastEquipped();
//Check if the magic is JUST Sanctify
int iMagic = 0;
itemproperty eCheckIP = GetFirstItemProperty(oItem);
while (GetIsItemPropertyValid(eCheckIP))
{
if(!(GetItemPropertyTag(eCheckIP) == "Sanctify1") && !(GetItemPropertyTag(eCheckIP) == "Sanctify2") && !(GetItemPropertyTag(eCheckIP) == "Sanctify3")
&& !(GetItemPropertyTag(eCheckIP) == "Sanctify4")) iMagic = 1;
eCheckIP = GetNextItemProperty(oItem);
}
//Check if weapons are magical
if(iMagic && (IPGetIsMeleeWeapon(oItem) || GetWeaponRanged(oItem)) &&
!(GetBaseItemType(oItem) == BASE_ITEM_SLING && GetItemPropertyType(GetFirstItemProperty(oItem)) == ITEM_PROPERTY_MIGHTY))
//Check if weapon is magical or not on allowed list
{
AssignCommand(oPC, ClearAllActions(TRUE));
AssignCommand(oPC, ActionUnequipItem(oItem));
FloatingTextStringOnCreature(GetName(oItem)+" is a magical item!", oPC, FALSE);
}
else
{
if(nForsakerLvl>=3)
{
//Give bonus to weapon(s)
IPSafeAddItemProperty(oItem, ItemPropertyAttackBonus(nBonus), 99999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
IPSafeAddItemProperty(oItem, ItemPropertyAttackPenalty(nBonus), 99999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
//Remove unarmed bonus
effect eLoop = GetFirstEffect(oPC);
while(GetIsEffectValid(eLoop))
{
if(GetEffectType(eLoop) == EFFECT_TYPE_ATTACK_INCREASE
|| GetEffectType(eLoop) == EFFECT_TYPE_ATTACK_DECREASE) RemoveEffect(oPC,eLoop);
eLoop = GetNextEffect(oPC);
}
}
}
}
}
*/