//::////////////////////////////////////////////// //:: FileName: "contingent_reun" /* Purpose: This is the true spell script for Contingent Reunion. The other castable script calls the conversation where the player must choose a trigger, which then gets transferred to this script, which executes the spell effects and results. NOTE: This contingency will last indefinitely, unless it triggers or the player dispels it in the pre-rest conversation. */ //::////////////////////////////////////////////// //:: Created By: Boneshank //:: Last Updated On: //::////////////////////////////////////////////// #include "prc_alterations" #include "inc_epicspells" void MonitorForDeath(object oMonitor, int nCount, object oJumpTo, location lJumpTo, object oPC); void MonitorForDying(object oMonitor, int nCount, object oJumpTo, location lJumpTo, object oPC); void MonitorForIncapacitated(object oMonitor, int nCount, object oJumpTo, location lJumpTo, object oPC); void MonitorForNearDeath(object oMonitor, int nCount, object oJumpTo, location lJumpTo, object oPC); void MonitorForBadlyWounded(object oMonitor, int nCount, object oJumpTo, location lJumpTo, object oPC); void MonitorForAfflicted(object oMonitor, int nCount, object oJumpTo, location lJumpTo, object oPC); void JumpDeadToLocation(object oJumper, location lTarget); void main() { object oPC = OBJECT_SELF; object oTarget = GetLocalObject(oPC, "oSpellTarget"); location lJumpTo = GetLocalLocation(oPC, "lSpellTarget"); int nTrigger = GetLocalInt(oPC, "nReunionTrigger"); // Debug SendMessageToPC(oPC, IntToString(nTrigger)); DeleteLocalObject(oPC, "oSpellTarget"); DeleteLocalLocation(oPC, "lSpellTarget"); DeleteLocalInt(oPC, "nReunionTrigger"); DeleteLocalInt(oPC, "nMyTargetIsACreature"); PenalizeSpellSlotForCaster(oPC); // Start monitoring the chosen condition. switch (nTrigger) { // Monitoring self. case 0: SetLocalInt(oPC, "nContingentReunion0", TRUE); MonitorForDeath(oPC, 1, oTarget, lJumpTo, oPC); break; case 1: SetLocalInt(oPC, "nContingentReunion1", TRUE); MonitorForDying(oPC, 1, oTarget, lJumpTo, oPC); break; case 2: SetLocalInt(oPC, "nContingentReunion2", TRUE); MonitorForIncapacitated(oPC, 1, oTarget, lJumpTo, oPC); break; case 3: SetLocalInt(oPC, "nContingentReunion3", TRUE); MonitorForNearDeath(oPC, 1, oTarget, lJumpTo, oPC); break; case 4: SetLocalInt(oPC, "nContingentReunion4", TRUE); MonitorForBadlyWounded(oPC, 1, oTarget, lJumpTo, oPC); break; case 5: SetLocalInt(oPC, "nContingentReunion5", TRUE); MonitorForAfflicted(oPC, 1, oTarget, lJumpTo, oPC); break; // Monitoring target. case 10: SetLocalInt(oPC, "nContingentReunion0", TRUE); MonitorForDeath(oTarget, 1, oTarget, lJumpTo, oPC); break; case 11: SetLocalInt(oPC, "nContingentReunion1", TRUE); MonitorForDying(oTarget, 1, oTarget, lJumpTo, oPC); break; case 12: SetLocalInt(oPC, "nContingentReunion2", TRUE); MonitorForIncapacitated(oTarget, 1, oTarget, lJumpTo, oPC); break; case 13: SetLocalInt(oPC, "nContingentReunion3", TRUE); MonitorForNearDeath(oTarget, 1, oTarget, lJumpTo, oPC); break; case 14: SetLocalInt(oPC, "nContingentReunion4", TRUE); MonitorForBadlyWounded(oTarget, 1, oTarget, lJumpTo, oPC); break; case 15: SetLocalInt(oPC, "nContingentReunion5", TRUE); MonitorForAfflicted(oTarget, 1, oTarget, lJumpTo, oPC); break; } } void MonitorForDeath(object oMonitor, int nCount, object oJumpTo, location lJumpTo, object oPC) { if (GetLocalInt(oPC, "nContingentReunion0") == TRUE) // Is the contingency still active? { // If the target isn't dead. if (!GetIsDead(oMonitor) && oMonitor != OBJECT_INVALID) { if (nCount >= 10) nCount = 0; if (nCount == 1) FloatingTextStringOnCreature("*Contingency active*", oPC, FALSE); if (oJumpTo != OBJECT_INVALID) // Update the JumpTo location each time through. lJumpTo = GetLocation(oJumpTo); nCount++; DelayCommand(6.0, MonitorForDeath(oMonitor, nCount, oJumpTo, lJumpTo, oPC)); } else // Jump oMonitor to the target, and end the contingency. { FloatingTextStringOnCreature("*Contingency triggered*", oMonitor); effect eVis = EffectVisualEffect(VFX_FNF_SUMMON_MONSTER_3); ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eVis, GetLocation(oPC)); ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eVis, lJumpTo); if (GetIsDead(oPC)) JumpDeadToLocation(oPC, lJumpTo); else AssignCommand(oPC, JumpToLocation(lJumpTo)); DeleteLocalInt(oPC, "nContingentReunion0"); MonitorForDeath(oMonitor, nCount, oJumpTo, lJumpTo, oPC); } } else // Restore the lost spell slot. RestoreSpellSlotForCaster(oPC); } void MonitorForDying(object oMonitor, int nCount, object oJumpTo, location lJumpTo, object oPC) { int nHP = GetCurrentHitPoints(oMonitor); if (GetLocalInt(oPC, "nContingentReunion1") == TRUE) // Is the contingency still active? { // If the target isn't dying. if (nHP >= 1 && oMonitor != OBJECT_INVALID) { if (nCount >= 10) nCount = 0; if (nCount == 1) FloatingTextStringOnCreature("*Contingency active*", oPC, FALSE); if (oJumpTo != OBJECT_INVALID) // Update the JumpTo location each time through. lJumpTo = GetLocation(oJumpTo); nCount++; DelayCommand(4.0, MonitorForDying(oMonitor, nCount, oJumpTo, lJumpTo, oPC)); } else // Jump oMonitor to the target, and end the contingency. { FloatingTextStringOnCreature("*Contingency triggered*", oMonitor); effect eVis = EffectVisualEffect(VFX_FNF_SUMMON_MONSTER_3); ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eVis, GetLocation(oPC)); ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eVis, lJumpTo); if (GetIsDead(oPC)) JumpDeadToLocation(oPC, lJumpTo); else AssignCommand(oPC, JumpToLocation(lJumpTo)); DeleteLocalInt(oPC, "nContingentReunion1"); MonitorForDying(oMonitor, nCount, oJumpTo, lJumpTo, oPC); } } else // Restore the lost spell slot. RestoreSpellSlotForCaster(oPC); } void MonitorForIncapacitated(object oMonitor, int nCount, object oJumpTo, location lJumpTo, object oPC = OBJECT_SELF) { if (GetLocalInt(oPC, "nContingentReunion2") == TRUE) // Is the contingency still active? { // Is oMonitor incapacitated? int nInc; effect eX = GetFirstEffect(oMonitor); while (GetIsEffectValid(eX)) { if (GetEffectType(eX) == EFFECT_TYPE_PARALYZE) nInc = TRUE; if (GetEffectType(eX) == EFFECT_TYPE_PETRIFY) nInc = TRUE; if (GetEffectType(eX) == EFFECT_TYPE_SLEEP) nInc = TRUE; if (GetEffectType(eX) == EFFECT_TYPE_STUNNED) nInc = TRUE; eX = GetNextEffect(oMonitor); } // If the target isn't incapacitated. if (nInc != TRUE && oMonitor != OBJECT_INVALID) { if (nCount >= 10) nCount = 0; if (nCount == 1) FloatingTextStringOnCreature("*Contingency active*", oPC, FALSE); if (oJumpTo != OBJECT_INVALID) // Update the JumpTo location each time through. lJumpTo = GetLocation(oJumpTo); nCount++; DelayCommand(3.0, MonitorForIncapacitated(oMonitor, nCount, oJumpTo, lJumpTo, oPC)); } else // Jump oMonitor to the target, and end the contingency. { FloatingTextStringOnCreature("*Contingency triggered*", oMonitor); effect eVis = EffectVisualEffect(VFX_FNF_SUMMON_MONSTER_3); ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eVis, GetLocation(oPC)); ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eVis, lJumpTo); AssignCommand(oPC, JumpToLocation(lJumpTo)); DeleteLocalInt(oPC, "nContingentReunion2"); MonitorForIncapacitated(oMonitor, nCount, oJumpTo, lJumpTo, oPC); } } else // Restore the lost spell slot. RestoreSpellSlotForCaster(oPC); } void MonitorForNearDeath(object oMonitor, int nCount, object oJumpTo, location lJumpTo, object oPC = OBJECT_SELF) { int nHP = GetCurrentHitPoints(oMonitor); int nX = GetMaxHitPoints(oMonitor) / 4; if (GetLocalInt(oPC, "nContingentReunion3") == TRUE) // Is the contingency still active? { // If the target isn't near death. if (nHP > nX && oMonitor != OBJECT_INVALID) { if (nCount >= 30) nCount = 0; if (nCount == 1) FloatingTextStringOnCreature("*Contingency active*", oPC, FALSE); if (oJumpTo != OBJECT_INVALID) // Update the JumpTo location each time through. lJumpTo = GetLocation(oJumpTo); nCount++; DelayCommand(2.0, MonitorForNearDeath(oMonitor, nCount, oJumpTo, lJumpTo, oPC)); } else // Jump oMonitor to the target, and end the contingency. { FloatingTextStringOnCreature("*Contingency triggered*", oMonitor); effect eVis = EffectVisualEffect(VFX_FNF_SUMMON_MONSTER_3); ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eVis, GetLocation(oPC)); ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eVis, lJumpTo); AssignCommand(oPC, JumpToLocation(lJumpTo)); DeleteLocalInt(oPC, "nContingentReunion3"); MonitorForNearDeath(oMonitor, nCount, oJumpTo, lJumpTo, oPC); } } else // Restore the lost spell slot. RestoreSpellSlotForCaster(oPC); } void MonitorForBadlyWounded(object oMonitor, int nCount, object oJumpTo, location lJumpTo, object oPC = OBJECT_SELF) { int nHP = GetCurrentHitPoints(oMonitor); int nX = GetMaxHitPoints(oMonitor) / 2; if (GetLocalInt(oPC, "nContingentReunion4") == TRUE) // Is the contingency still active? { // If the target isn't badly wounded. if (nHP > nX && oMonitor != OBJECT_INVALID) { if (nCount >= 30) nCount = 0; if (nCount == 1) FloatingTextStringOnCreature("*Contingency active*", oPC, FALSE); if (oJumpTo != OBJECT_INVALID) // Update the JumpTo location each time through. lJumpTo = GetLocation(oJumpTo); nCount++; DelayCommand(2.0, MonitorForBadlyWounded(oMonitor, nCount, oJumpTo, lJumpTo, oPC)); } else // Jump oMonitor to the target, and end the contingency. { FloatingTextStringOnCreature("*Contingency triggered*", oMonitor); effect eVis = EffectVisualEffect(VFX_FNF_SUMMON_MONSTER_3); ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eVis, GetLocation(oPC)); ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eVis, lJumpTo); AssignCommand(oPC, JumpToLocation(lJumpTo)); DeleteLocalInt(oPC, "nContingentReunion4"); MonitorForBadlyWounded(oMonitor, nCount, oJumpTo, lJumpTo, oPC); } } else // Restore the lost spell slot. RestoreSpellSlotForCaster(oPC); } void MonitorForAfflicted(object oMonitor, int nCount, object oJumpTo, location lJumpTo, object oPC = OBJECT_SELF) { if (GetLocalInt(oPC, "nContingentReunion5") == TRUE) // Is the contingency still active? { // Is oMonitor afflicted? int nInc; effect eX = GetFirstEffect(oMonitor); while (GetIsEffectValid(eX)) { if (GetEffectType(eX) == EFFECT_TYPE_CURSE) nInc = TRUE; if (GetEffectType(eX) == EFFECT_TYPE_DISEASE) nInc = TRUE; if (GetEffectType(eX) == EFFECT_TYPE_NEGATIVELEVEL) nInc = TRUE; if (GetEffectType(eX) == EFFECT_TYPE_POISON) nInc = TRUE; eX = GetNextEffect(oMonitor); } // If the target isn't incapacitated. if (nInc != TRUE && oMonitor != OBJECT_INVALID) { if (nCount >= 10) nCount = 0; if (nCount == 1) FloatingTextStringOnCreature("*Contingency active*", oPC, FALSE); if (oJumpTo != OBJECT_INVALID) // Update the JumpTo location each time through. lJumpTo = GetLocation(oJumpTo); nCount++; DelayCommand(6.0, MonitorForAfflicted(oMonitor, nCount, oJumpTo, lJumpTo, oPC)); } else // Jump oMonitor to the target, and end the contingency. { FloatingTextStringOnCreature("*Contingency triggered*", oMonitor); effect eVis = EffectVisualEffect(VFX_FNF_SUMMON_MONSTER_3); ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eVis, GetLocation(oPC)); ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eVis, lJumpTo); AssignCommand(oPC, JumpToLocation(lJumpTo)); DeleteLocalInt(oPC, "nContingentReunion5"); MonitorForAfflicted(oMonitor, nCount, oJumpTo, lJumpTo, oPC); } } else // Restore the lost spell slot. RestoreSpellSlotForCaster(oPC); } void JumpDeadToLocation(object oJumper, location lTarget) { //Debug SendMessageToPC(oJumper, "Jumping dead"); int nDam = 2; effect eRez = EffectResurrection(); effect eKill = EffectDamage(nDam); ApplyEffectToObject(DURATION_TYPE_INSTANT, eRez, oJumper); DelayCommand(0.1, AssignCommand(oJumper, JumpToLocation(lTarget))); DelayCommand(0.2, ApplyEffectToObject(DURATION_TYPE_INSTANT, eKill, oJumper)); }