Hotfix for Vow Poverty item unequip bug. Invoke Divine Wrath now accepts all Smites as a prereq. Added IsUnagumentablePower(). Added GetCanSmite(). Fixed Crown of Might Discharge Crown.
680 lines
26 KiB
Plaintext
680 lines
26 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();
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
*/ |