Sun Domain power actually destroys undead. Fixed BCM's Pouncing Strike. Monkey Grip only applies penalty when appropriate. Forsaker should stack all sources of Spell Resistance. Hexblade's Dark Companion retains the sanctuary effect across game saves. Ottiluke's Resilient Sphere is a Reflex save, not a WIll save.
684 lines
27 KiB
Plaintext
684 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))
|
|
{
|
|
// REMOVED: Aggressive inventory scanning that was removing all magical items
|
|
// This was causing permanent property loss for players
|
|
// The Forsaker class should still prevent magical item usage through equip events
|
|
|
|
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();
|
|
if(DEBUG) DoDebug("prc_forsaker - OnEquip\n"
|
|
+ "oPC = " + DebugObject2Str(oPC) + "\n"
|
|
+ "oItem = " + DebugObject2Str(oItem) + "\n");
|
|
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
*/ |