//::///////////////////////////////////////////////
//:: Phantasmal Killer
//:: NW_S0_PhantKill
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Target of the spell must make 2 saves or die.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Dec 14 , 2001
//:://////////////////////////////////////////////
//:: VFX Pass By: Preston W, On: June 22, 2001
//:: Update Pass By: Preston W, On: Aug 3, 2001
// Drammel 5/16/2009 - Added support for Mettle.

#include "nw_i0_spells"
#include "x2_inc_spellhook"

int MySavingThrow2(int nSavingThrow, object oTarget, int nDC, int nSaveType=SAVING_THROW_TYPE_NONE, object oSaveVersus = OBJECT_SELF, float fDelay = 0.0);

void main()
{

/*
  Spellcast Hook Code
  Added 2003-06-23 by GeorgZ
  If you want to make changes to all spells,
  check x2_inc_spellhook.nss to find out more

*/

    if (!X2PreSpellCastCode())
    {
    // If code within the PreSpellCastHook (i.e. UMD) reports FALSE, do not run this spell
        return;
    }

// End of Spell Cast Hook


    //Declare major variables
    int nDamage = d6(3);
    int nMetaMagic = GetMetaMagicFeat();
    object oTarget = GetSpellTargetObject();
    effect eDam;
    effect eVis = EffectVisualEffect(VFX_IMP_DEATH);
    effect eVis2 = EffectVisualEffect(VFX_HIT_SPELL_ILLUSION);
    if (spellsIsTarget(oTarget, SPELL_TARGET_STANDARDHOSTILE, OBJECT_SELF))
    {
        //Fire cast spell at event for the specified target
        SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, SPELL_PHANTASMAL_KILLER));
        //Make an SR check
        if(!MyResistSpell(OBJECT_SELF, oTarget))
        {
			// AFW-OEI 04/20/2006: If you have Immunity to Phantasms, you're completely immune to the spell.
			if (!GetHasFeat(FEAT_IMMUNITY_PHANTASMS, oTarget) && !GetIsImmune(oTarget, IMMUNITY_TYPE_FEAR))
			{
	            //Make a Will save
	            // Feb 17, 2004
	            // !MySavingThrow does not work here, because it does not take into account whether
	            // the creature is immune to the effect. If immune, it still does the fort save, so
	            // the target will still take damage or die. To avoid messing with things too much,
	            // I've made a copy of the function in this script, with an edit to return the proper
	            // value if the spell was resisted.
	            if (!MySavingThrow2(SAVING_THROW_WILL,  oTarget, GetSpellSaveDC(), SAVING_THROW_TYPE_MIND_SPELLS))
	            {
	                //Make a Fort save
	                if (MySavingThrow(SAVING_THROW_FORT, oTarget, GetSpellSaveDC(),SAVING_THROW_TYPE_DEATH))
	                {
	                    //Check for metamagic
	                    if (nMetaMagic == METAMAGIC_MAXIMIZE)
	                    {
	                       nDamage = 18;
	                    }
	                    if (nMetaMagic == METAMAGIC_EMPOWER)
	                    {
	                       nDamage = FloatToInt( IntToFloat(nDamage) * 1.5 );
	                    }

						if (GetHasFeat(6818, oTarget)) //Mettle
						{
							nDamage = 0;
						}
	                    //Set the damage property
	                    eDam = EffectDamage(nDamage, DAMAGE_TYPE_MAGICAL);
	                    //Apply the damage effect and VFX impact
	                    ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget);
	                    ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis2, oTarget);
	                }
	                else
	                {
	                     //Apply the death effect and VFX impact
	                     ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDeath(), oTarget);
	                     ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
	                }
	            }
			}
        }
    }
}

int MySavingThrow2(int nSavingThrow, object oTarget, int nDC, int nSaveType=SAVING_THROW_TYPE_NONE, object oSaveVersus = OBJECT_SELF, float fDelay = 0.0)
{
    // -------------------------------------------------------------------------
    // GZ: sanity checks to prevent wrapping around
    // -------------------------------------------------------------------------
    if (nDC<1)
    {
       nDC = 1;
    }
    else if (nDC > 255)
    {
      nDC = 255;
    }

    effect eVis;
    int bValid = FALSE;
    int nSpellID;
    if(nSavingThrow == SAVING_THROW_FORT)
    {
        bValid = FortitudeSave(oTarget, nDC, nSaveType, oSaveVersus);
        if(bValid == 1)
        {
            //eVis = EffectVisualEffect(VFX_IMP_FORTITUDE_SAVING_THROW_USE);
        }
    }
    else if(nSavingThrow == SAVING_THROW_REFLEX)
    {
        bValid = ReflexSave(oTarget, nDC, nSaveType, oSaveVersus);
        if(bValid == 1)
        {
            //eVis = EffectVisualEffect(VFX_IMP_REFLEX_SAVE_THROW_USE);
        }
    }
    else if(nSavingThrow == SAVING_THROW_WILL)
    {
        bValid = WillSave(oTarget, nDC, nSaveType, oSaveVersus);
        if(bValid == 1)
        {
            //eVis = EffectVisualEffect(VFX_IMP_WILL_SAVING_THROW_USE);
        }
    }

    nSpellID = GetSpellId();

    /*
        return 0 = FAILED SAVE
        return 1 = SAVE SUCCESSFUL
        return 2 = IMMUNE TO WHAT WAS BEING SAVED AGAINST
    */
    if(bValid == 0)
    {
        if((nSaveType == SAVING_THROW_TYPE_DEATH
         || nSpellID == SPELL_WEIRD
         || nSpellID == SPELL_FINGER_OF_DEATH) &&
         nSpellID != SPELL_HORRID_WILTING)
        {
            eVis = EffectVisualEffect(VFX_IMP_DEATH);
            DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
        }
    }
    if(bValid == 2)
    {
        eVis = EffectVisualEffect( VFX_DUR_SPELL_SPELL_RESISTANCE );
    }
    if(bValid == 1 || bValid == 2)
    {
        if(bValid == 2)
        {
            /*
            If the spell is save immune then the link must be applied in order to get the true immunity
            to be resisted.  That is the reason for returing false and not true.  True blocks the
            application of effects.
            */
// This is the edit, so that a positive value can be return when resisted.
//            bValid = FALSE;
        }
        DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
    }
    return bValid;
}