Updated Release Archive. Fixed Mage-killer prereqs. Removed old LETO & ConvoCC related files. Added organized spell scroll store. Fixed Gloura spellbook. Various TLK fixes. Reorganized Repo. Removed invalid user folders. Added DocGen back in.
196 lines
7.7 KiB
Plaintext
196 lines
7.7 KiB
Plaintext
/*
|
|
nw_s0_healharm
|
|
|
|
Heal/Harm in the one script
|
|
|
|
By: Flaming_Sword
|
|
Created: Jun 14, 2006
|
|
Modified: Nov 21, 2006
|
|
|
|
Consolidation of heal/harm scripts
|
|
Mass Heal vfx on target looks like heal
|
|
added greater harm, mass harm
|
|
*/
|
|
|
|
#include "prc_sp_func"
|
|
#include "prc_inc_sp_tch"
|
|
#include "prc_inc_function"
|
|
#include "prc_add_spell_dc"
|
|
#include "inc_dispel"
|
|
|
|
//Implements the spell impact, put code here
|
|
// if called in many places, return TRUE if
|
|
// stored charges should be decreased
|
|
// eg. touch attack hits
|
|
//
|
|
// Variables passed may be changed if necessary
|
|
int DoSpell(object oCaster, object oTarget, int nSpellID)
|
|
{
|
|
int bIsHeal = IsHeal(nSpellID); //whether it is a heal or harm spell
|
|
int bMass = IsMassHealHarm(nSpellID);
|
|
int nCasterLevel = PRCGetCasterLevel(oCaster);
|
|
int nMetaMagic = PRCGetMetaMagicFeat();
|
|
int nHealVFX, nHurtVFX, nEnergyType, nDice, iBlastFaith, nHeal;
|
|
float fRadius;
|
|
string nSwitch;
|
|
int nCap = 150;
|
|
if(bIsHeal)
|
|
{
|
|
nHealVFX = VFX_IMP_HEALING_X;
|
|
nHurtVFX = VFX_IMP_SUNSTRIKE;
|
|
nEnergyType = DAMAGE_TYPE_POSITIVE;
|
|
nSwitch = PRC_BIOWARE_HEAL;
|
|
fRadius = RADIUS_SIZE_COLOSSAL;
|
|
if(nSpellID == SPELL_MASS_HEAL)
|
|
{
|
|
nSwitch = PRC_BIOWARE_MASS_HEAL;
|
|
nCap = 250;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
nHealVFX = VFX_IMP_HEALING_G;
|
|
nHurtVFX = 246;
|
|
nEnergyType = DAMAGE_TYPE_NEGATIVE;
|
|
nSwitch = PRC_BIOWARE_HARM;
|
|
fRadius = RADIUS_SIZE_HUGE;
|
|
}
|
|
int iHeal;
|
|
int iAttackRoll = 1;
|
|
if((nSpellID == SPELL_MASS_HARM) || (nSpellID == SPELL_GREATER_HARM))
|
|
{
|
|
nDice = (nCasterLevel > 20) ? 20 : nCasterLevel;
|
|
nHeal = d12(nDice);
|
|
if((nMetaMagic & METAMAGIC_MAXIMIZE) || BlastInfidelOrFaithHeal(oCaster, oTarget, nEnergyType, TRUE))
|
|
nHeal = 12 * nDice; //in case higher level spell slots are available
|
|
}
|
|
else
|
|
{
|
|
nHeal = 10 * nCasterLevel;
|
|
}
|
|
if(nHeal > nCap && !GetPRCSwitch(nSwitch))
|
|
nHeal = nCap;
|
|
location lLoc;
|
|
if(bMass)
|
|
{
|
|
lLoc = (nSpellID == SPELL_MASS_HARM) ? GetLocation(oCaster) : PRCGetSpellTargetLocation();
|
|
oTarget = MyFirstObjectInShape(SHAPE_SPHERE, fRadius, lLoc);
|
|
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(bIsHeal ? VFX_FNF_LOS_HOLY_30 : VFX_FNF_LOS_EVIL_20), lLoc);
|
|
}
|
|
float fDelay = 0.0;
|
|
|
|
while(GetIsObjectValid(oTarget))
|
|
{
|
|
if(bMass) fDelay = PRCGetRandomDelay();
|
|
int iTombTainted = GetHasFeat(FEAT_TOMB_TAINTED_SOUL, oTarget) && GetAlignmentGoodEvil(oTarget) != ALIGNMENT_GOOD;
|
|
|
|
iHeal = GetObjectType(oTarget) == OBJECT_TYPE_CREATURE &&
|
|
((!bIsHeal && (MyPRCGetRacialType(oTarget) == RACIAL_TYPE_UNDEAD || iTombTainted)) ||
|
|
(bIsHeal && MyPRCGetRacialType(oTarget) != RACIAL_TYPE_UNDEAD && !iTombTainted));
|
|
if (GetLocalInt(oTarget, "AcererakHealing")) iHeal = TRUE;
|
|
|
|
if(iHeal && (spellsIsTarget(oTarget, SPELL_TARGET_ALLALLIES, oCaster) || (GetIsDead(oTarget) && (GetCurrentHitPoints(oTarget) > -10))))
|
|
{
|
|
SignalEvent(oTarget, EventSpellCastAt(oCaster, nSpellID, FALSE));
|
|
|
|
//Warforged are only healed for half, none if they have Improved Fortification
|
|
if(GetIsWarforged(oTarget)) nHeal /= 2;
|
|
if(GetHasFeat(FEAT_IMPROVED_FORTIFICATION, oTarget)) nHeal = 0;
|
|
|
|
|
|
DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_INSTANT, PRCEffectHeal(nHeal, oTarget), oTarget));
|
|
DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(nHealVFX), oTarget));
|
|
// Code for FB to remove damage that would be caused at end of Frenzy
|
|
SetLocalInt(oTarget, "PC_Damage", 0);
|
|
}
|
|
else if((GetObjectType(oTarget) != OBJECT_TYPE_CREATURE && !bIsHeal) ||
|
|
(GetObjectType(oTarget) == OBJECT_TYPE_CREATURE && !iHeal))
|
|
{
|
|
if(!GetIsReactionTypeFriendly(oTarget) && oTarget != oCaster)
|
|
{
|
|
SignalEvent(oTarget, EventSpellCastAt(oCaster, nSpellID));
|
|
iAttackRoll = PRCDoMeleeTouchAttack(oTarget);
|
|
if(iAttackRoll)
|
|
{
|
|
if (!PRCDoResistSpell(oCaster, oTarget, nCasterLevel + SPGetPenetr()))
|
|
{
|
|
int nModify = d4();
|
|
iBlastFaith = BlastInfidelOrFaithHeal(oCaster, oTarget, nEnergyType, TRUE);
|
|
if((nMetaMagic & METAMAGIC_MAXIMIZE) || iBlastFaith)
|
|
{
|
|
nModify = 1;
|
|
}
|
|
if((nSpellID == SPELL_MASS_HARM) || (nSpellID == SPELL_GREATER_HARM))
|
|
{
|
|
nHeal = d12(nDice);
|
|
if((nMetaMagic & METAMAGIC_MAXIMIZE) || iBlastFaith)
|
|
nHeal = 12 * nDice;
|
|
|
|
nHeal += SpellDamagePerDice(oCaster, nDice);
|
|
}
|
|
else
|
|
{
|
|
nHeal = 10 * nCasterLevel;
|
|
}
|
|
if(nHeal > nCap && !GetPRCSwitch(nSwitch))
|
|
nHeal = nCap;
|
|
|
|
if(PRCMySavingThrow(SAVING_THROW_WILL, oTarget, PRCGetSaveDC(oTarget, OBJECT_SELF)))
|
|
{
|
|
nHeal /= 2;
|
|
if (GetHasMettle(oTarget, SAVING_THROW_WILL)) // Ignores partial effects
|
|
nHeal = 0;
|
|
}
|
|
int nHP = GetCurrentHitPoints(oTarget);
|
|
if (nHeal > nHP - nModify)
|
|
nHeal = nHP - nModify;
|
|
DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_INSTANT, PRCEffectDamage(oTarget, nHeal, nEnergyType), oTarget));
|
|
DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(nHurtVFX), oTarget));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if(!bMass) break;
|
|
oTarget = MyNextObjectInShape(SHAPE_SPHERE, fRadius, lLoc);
|
|
}
|
|
//Spell Removal Check
|
|
SpellRemovalCheck(oCaster, oTarget);
|
|
return iAttackRoll; //return TRUE if spell charges should be decremented
|
|
}
|
|
|
|
void main()
|
|
{
|
|
if (DEBUG) DoDebug("nw_s0_healharm running "+IntToString(GetIsPC(OBJECT_SELF)));
|
|
int nSpellID = PRCGetSpellId();
|
|
PRCSetSchool(GetSpellSchool(nSpellID));
|
|
|
|
// If code within the PreSpellCastHook (i.e. UMD) reports FALSE, do not run this spell
|
|
if(X2PreSpellCastCode())
|
|
{
|
|
object oCaster = OBJECT_SELF;
|
|
object oTarget = PRCGetSpellTargetObject();
|
|
int nEvent = GetLocalInt(oCaster, PRC_SPELL_EVENT); //use bitwise & to extract flags
|
|
if(!nEvent) //normal cast
|
|
{
|
|
if (DEBUG )DoDebug("nw_s0_healharm running normal casting");
|
|
if(IsTouchSpell(nSpellID) && GetLocalInt(oCaster, PRC_SPELL_HOLD) && oCaster == oTarget)
|
|
{ //holding the charge, casting spell on self
|
|
SetLocalSpellVariables(oCaster, 1); //change 1 to number of charges
|
|
if (DEBUG) DoDebug("nw_s0_healharm running returning");
|
|
return;
|
|
}
|
|
if (DEBUG) DoDebug("nw_s0_healharm running DoSpell");
|
|
DoSpell(oCaster, oTarget, nSpellID);
|
|
}
|
|
else
|
|
{
|
|
if (DEBUG) DoDebug("nw_s0_healharm running else casting");
|
|
if(nEvent & PRC_SPELL_EVENT_ATTACK)
|
|
{
|
|
if(DoSpell(oCaster, oTarget, nSpellID))
|
|
DecrementSpellCharges(oCaster);
|
|
}
|
|
}
|
|
}
|
|
PRCSetSchool();
|
|
} |