2024-02-11 14:01:05 -05:00
//::///////////////////////////////////////////////
//:: Binding events
//:: bnd_events
//::///////////////////////////////////////////////
/** @file
Does all Binding content that require event scripting.
@author Stratovarius
@date Created - 2021.02.03
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
#include "bnd_inc_bndfunc"
#include "prc_inc_unarmed"
#include "prc_inc_fork"
//////////////////////////////////////////////////
/* Internal Functions */
//////////////////////////////////////////////////
void CheckIsDropped(object oBinder, object oItem)
{
if(DEBUG) DoDebug("bnd_events: CheckIsDropped()");
if(GetItemPossessor(oItem) == oBinder)
{
if(DEBUG) DoDebug("bnd_events:GetItemPosessor(oItem) == oBinder");
// No check for commandability here. Let's not break any cutscenes
// If cheating does occur, set the char to commandable first here.
//And remember to restore the setting.
AssignCommand(oBinder, ClearAllActions());
AssignCommand(oBinder, ActionPutDownItem(oItem));
DelayCommand(2.0, CheckIsDropped(oBinder, oItem));
}
}
//////////////////////////////////////////////////
/* Content Functions */
//////////////////////////////////////////////////
void AymHaloOfFire(object oBinder, object oTarget)
{
if (GetDistanceBetween(oBinder, oTarget) <= FeetToMeters(10.0f))
{
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(d6(1), DAMAGE_TYPE_FIRE), oTarget);
}
}
void NaberiusHeal(object oBinder)
{
int nCount = GetLocalInt(oBinder, "NaberiusCount");
//FloatingTextStringOnCreature("Naberius heal has spell effect, nCount: "+IntToString(nCount), oBinder, FALSE);
if (nCount == 20) // Default timer is 2 real world minutes to an hour
{
RecoverUnHealableAbilityDamage(oBinder, ABILITY_STRENGTH, 1);
RecoverUnHealableAbilityDamage(oBinder, ABILITY_DEXTERITY, 1);
RecoverUnHealableAbilityDamage(oBinder, ABILITY_CONSTITUTION, 1);
RecoverUnHealableAbilityDamage(oBinder, ABILITY_INTELLIGENCE, 1);
RecoverUnHealableAbilityDamage(oBinder, ABILITY_WISDOM, 1);
RecoverUnHealableAbilityDamage(oBinder, ABILITY_CHARISMA, 1);
// Reset the number
nCount -= 20;
}
effect eEffect = GetFirstEffect(oBinder);
while(GetIsEffectValid(eEffect) && !GetLocalInt(oBinder, "NaberiusHealLock"))
{
// Is it an ability decrease?
if(GetEffectType(eEffect) == EFFECT_TYPE_ABILITY_DECREASE)
{
string sTag = GetEffectTag(eEffect);
//FloatingTextStringOnCreature("Effect tag is "+sTag, oBinder, FALSE);
int nAbil = StringToInt(GetSubString(sTag, 0, 1));
//FloatingTextStringOnCreature("Effect ability is "+IntToString(nAbil), oBinder, FALSE);
int nAmount = StringToInt(GetSubString(sTag, 1, 2));
//FloatingTextStringOnCreature("Effect ability is "+IntToString(nAmount), oBinder, FALSE);
SetLocalInt(oBinder, "NaberiusHealLock", TRUE);
DelayCommand(nAmount * 6.0, RemoveEffect(oBinder, eEffect));
DelayCommand(nAmount * 6.0, DeleteLocalInt(oBinder, "NaberiusHealLock"));
//DelayCommand(nAmount * 6.0, FloatingTextStringOnCreature("Naberius heal removed nAmount: "+IntToString(nAmount), oBinder, FALSE));
}
eEffect = GetNextEffect(oBinder);
}
SetLocalInt(oBinder, "NaberiusCount", nCount+1);
}
void HaagentiTrans(object oBinder)
{
effect eEffect = GetFirstEffect(oBinder);
while(GetIsEffectValid(eEffect))
{
// Is it poly or petr
if(GetEffectType(eEffect) == EFFECT_TYPE_PETRIFY || GetEffectType(eEffect) == EFFECT_TYPE_POLYMORPH)
RemoveEffect(oBinder, eEffect);
eEffect = GetNextEffect(oBinder);
}
}
void AndrasInfluence(object oBinder)
{
int nCombat = GetIsInCombat(oBinder);
int nCount = GetLocalInt(oBinder, "AndrasCombat");
if (nCombat)
{
nCount += 1;
SetLocalInt(oBinder, "AndrasCombat", nCount);
if (nCount >= 10)
{
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, ExtraordinaryEffect(EffectExhausted()), oBinder, HoursToSeconds(1));
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, ExtraordinaryEffect(EffectFrightened()), oBinder, RoundsToSeconds(d4()));
}
}
else
DeleteLocalInt(oBinder, "AndrasCombat");
}
void EurynomePoisonBloodDelay(object oBinder, object oTarget, int nDC)
{
if(!PRCMySavingThrow(SAVING_THROW_FORT, oTarget, nDC, SAVING_THROW_TYPE_POISON))
{
2025-01-29 22:46:38 -05:00
int nDice = PRCMin(5, GetBinderLevel(oBinder, VESTIGE_EURYNOME)/3);
2024-02-11 14:01:05 -05:00
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_ACID_S), oTarget);
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(d6(nDice), DAMAGE_TYPE_ACID), oTarget);
}
}
void EurynomePoisonBlood(object oBinder, object oTarget)
{
// Enemy in vaguely melee range, wolves and other long creatures can actually hit outside of 10.0
if (GetDistanceBetween(oBinder, oTarget) <= FeetToMeters(15.0f))
{
// No weapon equipped, and the target has a bite attack
if (!GetIsObjectValid(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oTarget)) && GetIsObjectValid(GetItemInSlot(INVENTORY_SLOT_CWEAPON_B, oTarget)))
{
int nDC = GetBinderDC(oBinder, VESTIGE_EURYNOME);
if(!PRCMySavingThrow(SAVING_THROW_FORT, oTarget, nDC, SAVING_THROW_TYPE_POISON))
{
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_ACID_S), oTarget);
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(d6(), DAMAGE_TYPE_ACID), oTarget);
}
DelayCommand(60.0, EurynomePoisonBloodDelay(oBinder, oTarget, nDC));
}
}
}
void TenebrousVoid(object oBinder, object oTarget)
{
if (!GetLocalInt(oBinder, "TenebrousVoidStrike"))
{
int nDice = 1 + (GetBinderLevel(oBinder, VESTIGE_TENEBROUS)-7)/4;
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(d8(nDice), DAMAGE_TYPE_COLD), oTarget);
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_FROST_L), oTarget);
SetLocalInt(oBinder, "TenebrousVoidStrike", TRUE);
DelayCommand(4.5, DeleteLocalInt(oBinder, "TenebrousVoidStrike"));
}
}
void ReapplyTenebrous(object oBinder)
{
SetLocalInt(GetModule(), PRC_SPELL_TARGET_OBJECT_OVERRIDE, TRUE);
SetLocalObject(GetModule(), PRC_SPELL_TARGET_OBJECT_OVERRIDE, oBinder);
DoBindingCheck(oBinder, 18);
DelayCommand(0.1, ApplyVestige(oBinder, VESTIGE_TENEBROUS)); // Tenebrous vestiges.2da rowid
DelayCommand(1.0, DeleteLocalInt(GetModule(), PRC_SPELL_TARGET_OBJECT_OVERRIDE));
DelayCommand(1.0, DeleteLocalObject(GetModule(), PRC_SPELL_TARGET_OBJECT_OVERRIDE));
}
void SavnokInfluence(object oBinder, object oItem)
{
if (GetItemACValue(oItem) && !GetLocalInt(oBinder, "SavnokDelay"))
{
int nBase = GetBaseItemType(oItem);
AssignCommand(oBinder, ClearAllActions());
if (nBase == BASE_ITEM_SMALLSHIELD || nBase == BASE_ITEM_LARGESHIELD || nBase == BASE_ITEM_TOWERSHIELD)
AssignCommand(oBinder, ActionEquipItem(oItem, INVENTORY_SLOT_LEFTHAND));
if (nBase == BASE_ITEM_ARMOR)
AssignCommand(oBinder, ActionEquipItem(oItem, INVENTORY_SLOT_CHEST));
SetLocalInt(oBinder, "SavnokDelay", TRUE);
DelayCommand(0.5, DeleteLocalInt(oBinder, "SavnokDelay"));
DelayCommand(0.5, ExecuteScript("prc_speed", oBinder));
}
}
void ExpelledVestigeCleanup(object oBinder)
{
if (!GetHasSpellEffect(VESTIGE_ANDROMALIUS, oBinder))
{
DeleteLocalInt(oBinder, "AndroSneak");
DelayCommand(0.1, ExecuteScript("prc_sneak_att", oBinder));
}
if (!GetHasSpellEffect(VESTIGE_MALPHAS, oBinder))
{
DeleteLocalInt(oBinder, "MalphasSneak");
DelayCommand(0.1, ExecuteScript("prc_sneak_att", oBinder));
}
if (!GetHasSpellEffect(VESTIGE_FOCALOR, oBinder))
{
PRCRemoveSpellEffects(VESTIGE_FOCALOR_AURA_SADNESS, oBinder, oBinder);
PRCRemoveSpellEffects(VESTIGE_FOCALOR_AURA_SADNESS, oBinder, oBinder);
}
if (!GetHasSpellEffect(VESTIGE_RONOVE, oBinder))
{
DeleteLocalInt(oBinder, "RonovesFists");
}
if (!GetHasSpellEffect(VESTIGE_SAVNOK, oBinder) && GetIsObjectValid(GetItemPossessedBy(oBinder, "SavnokCallArmor")))
{
object oArmor = GetItemPossessedBy(oBinder, "SavnokCallArmor");
SetPlotFlag(oArmor, FALSE);
DestroyObject(oArmor);
}
if (!GetHasSpellEffect(VESTIGE_EURYNOME, oBinder) && GetIsObjectValid(GetItemPossessedBy(oBinder, "bnd_eury_hammer")))
{
object oHammer = GetItemPossessedBy(oBinder, "bnd_eury_hammer");
SetPlotFlag(oHammer, FALSE);
AssignCommand(oHammer, SetIsDestroyable(TRUE, TRUE, TRUE));
DestroyObject(oHammer);
}
// Using Disguise Self strips the hide of all the vestige feats, this reapplies them
// Checks for having naberius, but not the disguise self feat
if (GetHasSpellEffect(VESTIGE_NABERIUS, oBinder) && !GetHasFeat(9033, oBinder))
{
int i;
for(i = VESTIGE_AMON; i <= VESTIGE_ABYSM; i++)
{
if(GetHasSpellEffect(i, oBinder))
{
ApplyVestige(oBinder, i);
//FloatingTextStringOnCreature("Applying vestige "+IntToString(i), oBinder, FALSE);
}
}
}
if (!GetHasSpellEffect(VESTIGE_ACERERAK, oBinder)) DeleteLocalInt(oBinder, "AcererakHealing");
if (!GetHasSpellEffect(VESTIGE_ARETE, oBinder))
{
PRCRemoveSpellEffects(VESTIGE_ARETE_RESIST, oBinder, oBinder);
GZPRCRemoveSpellEffects(VESTIGE_ARETE_RESIST, oBinder, FALSE);
}
}
void ChupoclopsEth(object oBinder)
{
// Check to see if the WP is valid
string sWPTag = "bnd_eventsWP_" + GetName(oBinder);
object oTestWP = GetWaypointByTag(sWPTag);
if (!GetIsObjectValid(oTestWP))
{
// Create waypoint for the movement
CreateObject(OBJECT_TYPE_WAYPOINT, "nw_waypoint001", GetLocation(oBinder), FALSE, sWPTag);
if(DEBUG) DoDebug("bnd_events: Chupoclops WP for " + DebugObject2Str(oBinder) + " didn't exist, creating. Tag: " + sWPTag);
}
else // We have a test waypoint, now to check the distance
{
// Distance moved in the last round
float fDist = GetDistanceBetween(oBinder, oTestWP);
// Distance needed to move
float fCheck = FeetToMeters(10.0);
// Now clean up the WP and create a new one for next round's check
DestroyObject(oTestWP);
CreateObject(OBJECT_TYPE_WAYPOINT, "nw_waypoint001", GetLocation(oBinder), FALSE, sWPTag);
if(DEBUG) DoDebug("bnd_events: Moved enough: " + DebugBool2String(fDist >= fCheck));
// Moved too far or in combat
if (fDist >= fCheck || GetIsInCombat(oBinder))
{
PRCRemoveSpellEffects(VESTIGE_CHUPOCLOPS_ETHEREAL_WATCHER, oBinder, oBinder);
GZPRCRemoveSpellEffects(VESTIGE_CHUPOCLOPS_ETHEREAL_WATCHER, oBinder, FALSE);
BindAbilCooldown(oBinder, VESTIGE_CHUPOCLOPS_ETHEREAL_WATCHER, VESTIGE_CHUPOCLOPS);
}
}
}
void ShaxStormStrike(object oBinder, object oTarget)
{
if (!GetLocalInt(oBinder, "ShaxStormStrike"))
{
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(d6(), DAMAGE_TYPE_SONIC), oTarget);
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_SONIC), oTarget);
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(d6(), DAMAGE_TYPE_ELECTRICAL), oTarget);
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_SPARKS), oTarget);
SetLocalInt(oBinder, "ShaxStormStrike", TRUE);
DelayCommand(4.5, DeleteLocalInt(oBinder, "ShaxStormStrike"));
}
}
void VanusDisdain(object oBinder, object oTarget)
{
if (GetHitDice(oBinder) > GetHitDice(oTarget))
{
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(d6(), DAMAGE_TYPE_DIVINE), oTarget);
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_SPARKS), oTarget);
}
}
void VanusInfluence(object oBinder)
{
if (!GetLocalInt(oBinder, "PactQuality"+IntToString(VESTIGE_VANUS)))
{
int nCombat = GetLocalInt(oBinder, "VanusInfluence");
int nCurrent = GetIsInCombat(oBinder);
// We just left combat
if (nCurrent == FALSE && nCombat == TRUE)
{
SetCutsceneMode(oBinder, TRUE);
FloatingTextStringOnCreature("Victory over my enemies!", oBinder);
AssignCommand(oBinder, ActionPlayAnimation(ANIMATION_LOOPING_TALK_LAUGHING, 1.0, 6.0));
DelayCommand(6.0, SetCutsceneMode(oBinder, FALSE));
}
//FloatingTextStringOnCreature("Vanus Combat State "+IntToString(nCurrent), oBinder);
SetLocalInt(oBinder, "VanusInfluence", nCurrent);
}
}
void CityDweller(object oBinder)
{
object oArea = GetArea(oBinder);
// Urban environment, so not natural and aboveground
if (GetIsAreaNatural(oArea) != AREA_NATURAL && GetIsAreaAboveGround(oArea) == AREA_ABOVEGROUND)
{
SetLocalInt(oBinder, "DesharisSpeed", TRUE);
ExecuteScript("prc_speed", oBinder);
}
else
{
DeleteLocalInt(oBinder, "DesharisSpeed");
ExecuteScript("prc_speed", oBinder);
}
}
void EligorChromatic(object oBinder, object oTarget)
{
if (!GetLocalInt(oBinder, "EligorStrikeTimer"))
{
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(d6(), GetLocalInt(oBinder, "EligorStrike")), oTarget);
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_FAERIE_FIRE), oTarget);
SetLocalInt(oBinder, "EligorStrikeTimer", TRUE);
DelayCommand(4.5, DeleteLocalInt(oBinder, "EligorStrikeTimer"));
}
}
void MarchosiasRetribution(object oBinder, object oTarget)
{
// Skirmish or sneak attack
if (GetLevelByClass(CLASS_TYPE_SCOUT, oTarget) || GetTotalSneakAttackDice(oTarget))
{
if (GetDistanceBetween(oBinder, oTarget) < FeetToMeters(30.0))
{
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(d6(3), DAMAGE_TYPE_FIRE), oTarget);
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_SPARKS), oTarget);
}
}
}
/*
All of this below here is for the Karsite suppress item ability
*/
void SuppressItem(object oTrueSpeaker, object oTarget, int nBeats);
object GetChest(object oCreature)
{
object oChest = GetObjectByTag("npf_chest" + ObjectToString(oCreature));
if(oChest == OBJECT_INVALID)
{
object oWP = GetWaypointByTag("npf_wp_chest_sp");
oChest = CreateObject(OBJECT_TYPE_PLACEABLE, "npf_keep_chest", GetLocation(oWP), FALSE,
"npf_chest" + ObjectToString(oCreature));
}
return oChest;
}
void RemoveAllProperties(object oItem, object oPC)
{
if(DEBUG) DoDebug("ture_utr_supitem: About to remove properties from item: " + DebugObject2Str(oItem));
if(oItem == OBJECT_INVALID)
return;
int nType = GetBaseItemType(oItem);
if(nType == BASE_ITEM_TORCH
|| nType == BASE_ITEM_TRAPKIT
|| nType == BASE_ITEM_HEALERSKIT
|| nType == BASE_ITEM_GRENADE
|| nType == BASE_ITEM_THIEVESTOOLS
|| nType == BASE_ITEM_CRAFTMATERIALMED
|| nType == BASE_ITEM_CRAFTMATERIALSML
|| nType == 112)//craftbase
return;
object oWP = GetWaypointByTag("npf_wp_chest_sp");
// Generate UID
int nKey = GetLocalInt(GetModule(), "PRC_NullPsionicsField_Item_UID_Counter") + 1;
SetLocalInt(GetModule(), "PRC_NullPsionicsField_Item_UID_Counter", nKey);
string sKey = IntToString(nKey);
if(DEBUG) DoDebug("prc_pow_npfent: Removing itemproperties from item " + DebugObject2Str(oItem) + " with key value of '" + sKey + "' of creature " + DebugObject2Str(oPC));
//object oChest = GetChest(oPC);
//object oCopy = CopyObject(oItem, GetLocation(oChest), oChest);
// copying original item to a secluded waypoint in the area
// and giving it a tag that contains the key string
object oCopy = CopyObject(oItem, GetLocation(oWP), OBJECT_INVALID, "npf_item" + sKey);
//storing the key value on the original item (key value would point to the copy item)
SetLocalString(oItem, "PRC_NullPsionicsField_Item_UID", sKey);
//SetLocalObject(oItem, "ITEM_CHEST", oChest); // so the chest can be found
//SetLocalObject(oChest, sKey, oCopy); // and referenced in the chest
// Stripping original item from all properties
itemproperty ip = GetFirstItemProperty(oItem);
while(GetIsItemPropertyValid(ip))
{
RemoveItemProperty(oItem, ip);
ip = GetNextItemProperty(oItem);
}
}
void RestoreAllProperties(object oItem, object oPC, int nSlot = -1)
{
if(DEBUG) DoDebug("psi_pow_npfext: Attempting to restore itemproperties to: " + DebugObject2Str(oItem));
if(oPC != OBJECT_INVALID) // this is a pc object that has an item in inventory slot or normal inventory
{
if(oItem == OBJECT_INVALID)
oItem = GetItemInSlot(nSlot, oPC);
if(oItem == OBJECT_INVALID)
return;
}
//object oChest = GetLocalObject(oItem, "ITEM_CHEST");
// getting the key value - this points to the tag of the copy item
string sKey = GetLocalString(oItem, "PRC_NullPsionicsField_Item_UID");
// retrieving the copy item that is in this area
object oOriginalItem = GetObjectByTag("npf_item" + sKey);
if(DEBUG) DoDebug("psi_pow_npfext: Restoring itemproperties to item: " + DebugObject2Str(oItem) + " with key value of '" + sKey + "' for creature " + DebugObject2Str(oPC));
//object oOriginalItem = GetLocalObject(oChest, sKey);
object oNewItem;
if(oOriginalItem != OBJECT_INVALID) // item has not been restored yet
{
// replace current item with original
IPCopyItemProperties(oOriginalItem, oItem);
DestroyObject(oOriginalItem); // destroy dup item on player
//DeleteLocalObject(oChest, GetResRef(oItem)); // so it won't be restored again
DeleteLocalString(oItem, "PRC_NullPsionicsField_Item_UID");
}
}
void SuppressItem(object oTrueSpeaker, object oTarget, int nBeats)
{
// Break if they fail concentration or it runs out
if (GetBreakConcentrationCheck(oTrueSpeaker) || nBeats == 0) return;
// Remove and restore the properties
RemoveAllProperties(oTarget, GetItemPossessor(oTarget));
// Has to run before RemoveAll is called again
DelayCommand(5.8, RestoreAllProperties(oTarget, GetItemPossessor(oTarget)));
// Apply VFX
effect eImp = EffectVisualEffect(VFX_IMP_PULSE_BOMB);
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eImp, GetItemPossessor(oTarget));
DelayCommand(6.0, SuppressItem(oTrueSpeaker, oTarget, nBeats - 1));
}
void KarsiteOnHit(object oBinder, object oTarget)
{
// If the target succeeds, bail
if(PRCMySavingThrow(SAVING_THROW_WILL, oTarget, 10 + GetAbilityModifier(ABILITY_CHARISMA, oBinder), SAVING_THROW_TYPE_NONE)) return;
object oItem;
// If the right hand isn't suppressed, that gets priority
if (!GetLocalInt(oTarget, "KarsiteSuppressRight"))
{
oItem = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oTarget);
SuppressItem(oBinder, oItem, 1);
SetLocalInt(oTarget, "KarsiteSuppressRight", TRUE);
DelayCommand(5.8, DeleteLocalInt(oTarget, "KarsiteSuppressRight"));
}
else if (!GetLocalInt(oTarget, "KarsiteSuppressChest"))
{
oItem = GetItemInSlot(INVENTORY_SLOT_CHEST, oTarget);
SuppressItem(oBinder, oItem, 1);
SetLocalInt(oTarget, "KarsiteSuppressChest", TRUE);
DelayCommand(5.8, DeleteLocalInt(oTarget, "KarsiteSuppressChest"));
}
else if (!GetLocalInt(oTarget, "KarsiteSuppressLeft"))
{
oItem = GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oTarget);
SuppressItem(oBinder, oItem, 1);
SetLocalInt(oTarget, "KarsiteSuppressLeft", TRUE);
DelayCommand(5.8, DeleteLocalInt(oTarget, "KarsiteSuppressLeft"));
}
}
//////////////////////////////////////////////////
/* Void Main and Event Triggers */
//////////////////////////////////////////////////
void main()
{
int nEvent = GetRunningEvent();
if(DEBUG) DoDebug("bnd_events running, event: " + IntToString(nEvent));
// Get the PC. This is event-dependent
object oBinder;
switch(nEvent)
{
case EVENT_ITEM_ONHIT: oBinder = OBJECT_SELF; break;
case EVENT_ONPLAYEREQUIPITEM: oBinder = GetItemLastEquippedBy(); break;
case EVENT_ONPLAYERUNEQUIPITEM: oBinder = GetItemLastUnequippedBy(); break;
case EVENT_ONHEARTBEAT: oBinder = OBJECT_SELF; break;
case EVENT_ONPLAYERREST_FINISHED: oBinder = GetLastBeingRested(); break;
case EVENT_ONACQUIREITEM: oBinder = GetModuleItemAcquiredBy(); break;
default:
oBinder = OBJECT_SELF;
}
object oItem;
object oSkin = GetPCSkin(oBinder);
// We aren't being called from any event, instead from EvalPRCFeats
if(nEvent == FALSE)
{
// Hook in the events
if(DEBUG) DoDebug("bnd_events: Adding eventhooks");
AddEventScript(oBinder, EVENT_ONPLAYEREQUIPITEM, "bnd_events", TRUE, FALSE);
AddEventScript(oBinder, EVENT_ONPLAYERUNEQUIPITEM, "bnd_events", TRUE, FALSE);
AddEventScript(oBinder, EVENT_ONHEARTBEAT, "bnd_events", TRUE, FALSE);
AddEventScript(oBinder, EVENT_ONPLAYERREST_FINISHED, "bnd_events", TRUE, FALSE);
AddEventScript(oBinder, EVENT_ONACQUIREITEM , "bnd_events", TRUE, FALSE);
if (GetHasSpellEffect(VESTIGE_RONOVE, oBinder) && !GetIsVestigeExploited(oBinder, VESTIGE_RONOVE_FISTS))
{
SetLocalInt(oBinder, CALL_UNARMED_FEATS, TRUE);
SetLocalInt(oBinder, CALL_UNARMED_FISTS, TRUE);
}
}
else if(nEvent == EVENT_ITEM_ONHIT)
{
oItem = GetSpellCastItem();
object oTarget = PRCGetSpellTargetObject();
if(DEBUG) DoDebug("bnd_events: OnHit:\n"
+ "oBinder = " + DebugObject2Str(oBinder) + "\n"
+ "oItem = " + DebugObject2Str(oItem) + "\n"
+ "oTarget = " + DebugObject2Str(oTarget) + "\n"
);
if(GetBaseItemType(oItem) == BASE_ITEM_ARMOR)
{
if (GetHasSpellEffect(VESTIGE_AYM, oBinder) && GetLevelByClass(CLASS_TYPE_BINDER, oBinder) && !GetIsVestigeExploited(oBinder, VESTIGE_AYM_HALO_FIRE))
AymHaloOfFire(oBinder, oTarget);
if (GetHasSpellEffect(VESTIGE_EURYNOME, oBinder) && !GetIsVestigeExploited(oBinder, VESTIGE_EURYNOME_POISON))
EurynomePoisonBlood(oBinder, oTarget);
}
else // This is always a weapon
{
if (GetHasSpellEffect(VESTIGE_VANUS, oBinder) && !GetIsVestigeExploited(oBinder, VESTIGE_VANUS_DISDAIN)) VanusDisdain(oBinder, oTarget);
if (GetHasSpellEffect(VESTIGE_MARCHOSIAS, oBinder) && !GetIsVestigeExploited(oBinder, VESTIGE_MARCHOSIAS_RETRIBUTION)) MarchosiasRetribution(oBinder, oTarget);
}
// Melee weapon checks
if(IPGetIsMeleeWeapon(oItem))
{
if (GetHasSpellEffect(VESTIGE_TENEBROUS, oBinder) && !GetIsVestigeExploited(oBinder, VESTIGE_TENEBROUS_TOUCH_VOID)) TenebrousVoid(oBinder, oTarget);
if (GetHasSpellEffect(VESTIGE_SHAX, oBinder) && !GetIsVestigeExploited(oBinder, VESTIGE_SHAX_STORM_STRIKE)) ShaxStormStrike(oBinder, oTarget);
if (GetHasSpellEffect(VESTIGE_ELIGOR, oBinder) && !GetIsVestigeExploited(oBinder, VESTIGE_ELIGOR_STRIKE)) EligorChromatic(oBinder, oTarget);
if (GetRacialType(oBinder) == RACIAL_TYPE_KARSITE) KarsiteOnHit(oBinder, oTarget);
}
}// end if - Running OnHit event
else if(nEvent == EVENT_ONPLAYEREQUIPITEM)
{
oItem = GetItemLastEquipped();
if(DEBUG) DoDebug("bnd_events - OnEquip\n"
+ "oBinder = " + DebugObject2Str(oBinder) + "\n"
+ "oItem = " + DebugObject2Str(oItem) + "\n"
);
if(GetBaseItemType(oItem) == BASE_ITEM_ARMOR)
{
// Can't get Aym from Bind Vestige feat
if (GetHasSpellEffect(VESTIGE_AYM, oBinder) && GetLevelByClass(CLASS_TYPE_BINDER, oBinder) && !GetIsVestigeExploited(oBinder, VESTIGE_AYM_HALO_FIRE) ||
(GetHasSpellEffect(VESTIGE_EURYNOME, oBinder) && !GetIsVestigeExploited(oBinder, VESTIGE_EURYNOME_POISON)) )
{
IPSafeAddItemProperty(oItem, ItemPropertyOnHitCastSpell(IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER, 1), HoursToSeconds(24), X2_IP_ADDPROP_POLICY_KEEP_EXISTING);
AddEventScript(oItem, EVENT_ITEM_ONHIT, "bnd_events", TRUE, FALSE);
}
}
// Melee weapon checks
if(IPGetIsMeleeWeapon(oItem))
{
if (GetHasSpellEffect(VESTIGE_AYM, oBinder) && GetLevelByClass(CLASS_TYPE_BINDER, oBinder) && GetBinderLevel(oBinder, VESTIGE_AYM) >= 10 && !GetIsVestigeExploited(oBinder, VESTIGE_AYM_RUINOUS_ATTACK))
{
IPSafeAddItemProperty(oItem, ItemPropertyAttackBonus(5), HoursToSeconds(24), X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, TRUE);
IPSafeAddItemProperty(oItem, ItemPropertyAttackPenalty(5), HoursToSeconds(24), X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, TRUE);
}
if (GetHasSpellEffect(VESTIGE_RONOVE, oBinder) && !GetIsVestigeExploited(oBinder, VESTIGE_RONOVE_COLD_IRON))
{
int nBonus = 1;
if (GetBinderLevel(oBinder, VESTIGE_RONOVE) >= 7) nBonus = 3;
IPSafeAddItemProperty(oItem, ItemPropertyAttackBonus(nBonus), HoursToSeconds(24), X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, TRUE);
IPSafeAddItemProperty(oItem, ItemPropertyAttackPenalty(nBonus), HoursToSeconds(24), X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, TRUE);
}
if ((GetHasSpellEffect(VESTIGE_VANUS, oBinder) && !GetIsVestigeExploited(oBinder, VESTIGE_VANUS_DISDAIN)) ||
(GetHasSpellEffect(VESTIGE_MARCHOSIAS, oBinder) && !GetIsVestigeExploited(oBinder, VESTIGE_MARCHOSIAS_RETRIBUTION)) ||
(GetRacialType(oBinder) == RACIAL_TYPE_KARSITE))
{
AddEventScript(oItem, EVENT_ITEM_ONHIT, "bnd_events", TRUE, FALSE);
IPSafeAddItemProperty(oItem, ItemPropertyOnHitCastSpell(IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER, 1), HoursToSeconds(24), X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
}
}
// Any weapon
if (GetIsWeapon(oItem))
{
if (GetLevelByClass(CLASS_TYPE_KNIGHT_SACRED_SEAL, oBinder))
{
IPSafeAddItemProperty(oItem, ItemPropertyAttackBonus(3), HoursToSeconds(24), X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, TRUE);
IPSafeAddItemProperty(oItem, ItemPropertyAttackPenalty(3), HoursToSeconds(24), X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, TRUE);
}
}
if (GetWeaponRanged(oItem))
{
if ((GetHasSpellEffect(VESTIGE_VANUS, oBinder) && !GetIsVestigeExploited(oBinder, VESTIGE_VANUS_DISDAIN)) ||
(GetHasSpellEffect(VESTIGE_MARCHOSIAS, oBinder) && !GetIsVestigeExploited(oBinder, VESTIGE_MARCHOSIAS_RETRIBUTION)) )
{
IPSafeAddItemProperty(oItem, ItemPropertyOnHitCastSpell(IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER, 1), HoursToSeconds(24), X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
AddEventScript(oItem, EVENT_ITEM_ONHIT, "bnd_events", TRUE, FALSE);
object oAmmo = GetItemInSlot(INVENTORY_SLOT_BOLTS, oBinder);
IPSafeAddItemProperty(oAmmo, ItemPropertyOnHitCastSpell(IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER, 1), HoursToSeconds(24), X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
AddEventScript(oAmmo, EVENT_ITEM_ONHIT, "bnd_events", TRUE, FALSE);
oAmmo = GetItemInSlot(INVENTORY_SLOT_BULLETS, oBinder);
IPSafeAddItemProperty(oAmmo, ItemPropertyOnHitCastSpell(IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER, 1), HoursToSeconds(24), X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
AddEventScript(oAmmo, EVENT_ITEM_ONHIT, "bnd_events", TRUE, FALSE);
oAmmo = GetItemInSlot(INVENTORY_SLOT_ARROWS, oBinder);
IPSafeAddItemProperty(oAmmo, ItemPropertyOnHitCastSpell(IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER, 1), HoursToSeconds(24), X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
AddEventScript(oAmmo, EVENT_ITEM_ONHIT, "bnd_events", TRUE, FALSE);
}
}
}
// We are called from the OnPlayerUnEquipItem eventhook. Remove OnHitCast: Unique Power from oBinder's weapon
else if(nEvent == EVENT_ONPLAYERUNEQUIPITEM)
{
oItem = GetItemLastUnequipped();
if(DEBUG) DoDebug("bnd_events - OnUnEquip\n"
+ "oBinder = " + DebugObject2Str(oBinder) + "\n"
+ "oItem = " + DebugObject2Str(oItem) + "\n"
);
if (GetHasSpellEffect(VESTIGE_SAVNOK, oBinder) && !GetLocalInt(oBinder, "PactQuality"+IntToString(VESTIGE_SAVNOK)))
{
SavnokInfluence(oBinder, oItem);
}
// Only applies to armours
if(GetBaseItemType(oItem) == BASE_ITEM_ARMOR)
{
// Remove the temporary OnHitCastSpell: Unique
RemoveEventScript(oItem, EVENT_ITEM_ONHIT, "bnd_events", TRUE, FALSE);
RemoveSpecificProperty(oItem, ITEM_PROPERTY_ONHITCASTSPELL, IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER, 0, 1, "", 1, DURATION_TYPE_TEMPORARY);
}
// Clean up weapons
if(GetIsWeapon(oItem))
{
// Remove the attack bonus
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);
RemoveEventScript(oItem, EVENT_ITEM_ONHIT, "bnd_events", TRUE, FALSE);
RemoveSpecificProperty(oItem, ITEM_PROPERTY_ONHITCASTSPELL, IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER, 0, 1, "", -1, DURATION_TYPE_TEMPORARY);
object oAmmo = GetItemInSlot(INVENTORY_SLOT_BOLTS, oBinder);
RemoveSpecificProperty(oAmmo, ITEM_PROPERTY_ONHITCASTSPELL, IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER, 0, 1, "", -1, DURATION_TYPE_TEMPORARY);
oAmmo = GetItemInSlot(INVENTORY_SLOT_BULLETS, oBinder);
RemoveSpecificProperty(oAmmo, ITEM_PROPERTY_ONHITCASTSPELL, IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER, 0, 1, "", -1, DURATION_TYPE_TEMPORARY);
oAmmo = GetItemInSlot(INVENTORY_SLOT_ARROWS, oBinder);
RemoveSpecificProperty(oAmmo, ITEM_PROPERTY_ONHITCASTSPELL, IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER, 0, 1, "", -1, DURATION_TYPE_TEMPORARY);
}
}
else if(nEvent == EVENT_ONHEARTBEAT)
{
ExpelledVestigeCleanup(oBinder);
if (GetHasSpellEffect(VESTIGE_NABERIUS, oBinder) && GetLevelByClass(CLASS_TYPE_BINDER, oBinder) && !GetIsVestigeExploited(oBinder, VESTIGE_NABERIUS_ABILITY_HEALING)) NaberiusHeal(oBinder);
if (GetHasSpellEffect(VESTIGE_HAAGENTI, oBinder)) HaagentiTrans(oBinder);
if (GetHasSpellEffect(VESTIGE_PAIMON, oBinder) && GetLevelByClass(CLASS_TYPE_BINDER, oBinder) && !GetIsVestigeExploited(oBinder, VESTIGE_PAIMON_BLADES))
{
int nType = GetBaseItemType(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oBinder));
if (nType == BASE_ITEM_RAPIER || nType == BASE_ITEM_SHORTSWORD)
IPSafeAddItemProperty(oSkin, ItemPropertyBonusFeat(IP_CONST_FEAT_WEAPON_FINESSE), 5.999, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
}
if (GetHasSpellEffect(VESTIGE_ANDRAS, oBinder) && !GetLocalInt(oBinder, "PactQuality"+IntToString(VESTIGE_ANDRAS))) AndrasInfluence(oBinder);
if (GetHasSpellEffect(VESTIGE_TENEBROUS, oBinder) && !GetIsVestigeExploited(oBinder, VESTIGE_TENEBROUS_SEE_DARKNESS)) ActionCastSpellOnSelf(SPELL_DARKVISION);
if (GetHasSpellEffect(VESTIGE_GERYON, oBinder) && !GetIsVestigeExploited(oBinder, VESTIGE_GERYON_DARKNESS)) ActionCastSpellOnSelf(SPELL_DARKVISION);
if (GetIsPatronVestigeBound(oBinder) && GetLevelByClass(CLASS_TYPE_KNIGHT_SACRED_SEAL, oBinder) >= 5)
{
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectDamageReduction(10, DAMAGE_POWER_PLUS_ONE), oBinder, 6.0);
IPSafeAddItemProperty(oSkin, ItemPropertyBonusFeat(IP_CONST_FEAT_OUTSIDER_RACIAL_TYPE), 5.999, X2_IP_ADDPROP_POLICY_KEEP_EXISTING);
}
if (GetHasSpellEffect(VESTIGE_CHUPOCLOPS_ETHEREAL_WATCHER, oBinder)) ChupoclopsEth(oBinder);
if (GetHasSpellEffect(VESTIGE_VANUS, oBinder)) VanusInfluence(oBinder);
if (GetHasSpellEffect(VESTIGE_DESHARIS, oBinder) && !GetIsVestigeExploited(oBinder, VESTIGE_DESHARIS_CITY_DWELLER)) CityDweller(oBinder);
}
else if(nEvent == EVENT_ONPLAYERREST_FINISHED)
{
if (GetHasFeat(FEAT_RAPID_PACT_MAKING, oBinder)) DeleteLocalInt(oBinder, "RapidPactMaking");
// Naberius's Skills
int i;
for(i = 0; i < 40 ; i++)
DeleteLocalInt(oBinder, "NaberiusSkill"+IntToString(i));
DeleteLocalInt(oBinder, "RonovesFists");
DeleteLocalInt(oBinder, "AndrasMount");
DeleteLocalInt(oBinder, "AmonRam");
DeleteLocalInt(oBinder, "ExploitVestige");
if (GetLevelByClass(CLASS_TYPE_ANIMA_MAGE, oBinder))
{
SetLocalInt(oBinder, "BinderRested", TRUE);
DelayCommand(30.0, DeleteLocalInt(oBinder, "BinderRested"));
}
DeleteLocalInt(oBinder, "PRC_WoLUses" + IntToString(VESTIGE_KARSUS_DISPEL));
DeleteLocalInt(oBinder, "PRC_WoLUses" + IntToString(VESTIGE_TENEBROUS_FLICKER));
DeleteLocalInt(oBinder, "PRC_WoLUses" + IntToString(VESTIGE_DANTALION_TRAVEL_SPELL));
DeleteLocalInt(oBinder, "PRC_WoLUses" + IntToString(VESTIGE_THE_TRIAD_SMITE));
DeleteLocalInt(oBinder, "PRC_WoLUses" + IntToString(19139));
DeleteLocalInt(oBinder, "ZceryllTS");
if (GetLevelByClass(CLASS_TYPE_TENEBROUS_APOSTATE, oBinder)) ReapplyTenebrous(oBinder);
}
else if(nEvent == EVENT_ONACQUIREITEM)
{
oItem = GetModuleItemAcquired();
if(DEBUG) DoDebug("bnd_events - OnAcquire\n"
+ "oBinder = " + DebugObject2Str(oBinder) + "\n"
+ "oItem = " + DebugObject2Str(oItem) + "\n"
);
if (GetHasSpellEffect(VESTIGE_ANDROMALIUS, oBinder) && !GetLocalInt(oBinder, "PactQuality"+IntToString(VESTIGE_ANDROMALIUS)))
{
if (GetStolenFlag(oItem))
{
FloatingTextStringOnCreature("Andromalius prevents you from taking a stolen item!", oBinder, FALSE);
AssignCommand(oBinder, ActionPutDownItem(oItem));
DelayCommand(2.0, CheckIsDropped(oBinder, oItem));
}
}
if (GetHasSpellEffect(VESTIGE_KARSUS, oBinder) && GetLevelByClass(CLASS_TYPE_BINDER, oBinder) && !GetIsVestigeExploited(oBinder, VESTIGE_KARSUS_WILL))
{
int nType = GetBaseItemType(oItem);
if(nType == BASE_ITEM_MAGICWAND || nType == BASE_ITEM_ENCHANTED_WAND || nType == BASE_ITEM_MAGICSTAFF || nType == BASE_ITEM_CRAFTED_STAFF || nType == BASE_ITEM_BLANK_WAND || nType == BASE_ITEM_MAGICROD || nType == BASE_ITEM_CRAFTED_ROD)
{
IPSafeAddItemProperty(oItem, ItemPropertyLimitUseByClass(CLASS_TYPE_BINDER), HoursToSeconds(24), X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, TRUE);
}
}
}
}