// -----------------------------------------------------------------------------
// spell_necro_modal.nss
// -----------------------------------------------------------------------------
/*
    Generic Ability Script for modal abilities
*/
// -----------------------------------------------------------------------------
// PeterT
// -----------------------------------------------------------------------------

#include "log_h"
#include "abi_templates"
#include "necro_constants_h"
#include "2da_constants_h"
#include "plt_tut_modal"

// add effects
void _ActivateModalAbility(struct EventSpellScriptImpactStruct stEvent)
{
    // effects
    effect[] eEffects;
    int bPartywide = FALSE;
    int bEffectValid = TRUE;

    if(IsFollower(stEvent.oCaster))
    {
        WR_SetPlotFlag(PLT_TUT_MODAL, TUT_MODAL_1, TRUE);
    }

    if (IsObjectValid(stEvent.oTarget) == TRUE)
    {
        stEvent.lTarget = GetLocation(stEvent.oTarget);
    }

    // -------------------------------------------------------------------------
    // Handle Spells
    // -------------------------------------------------------------------------
    switch (stEvent.nAbility)
    {
        case ABILITY_SPELL_ENTROPIC_FIELD:
        {
            eEffects[0] = EffectAreaOfEffect(ENTROPIC_AOE, SCRIPT_NECRO_AOE_DURATION, 0);
            eEffects[0] = SetEffectEngineFloat(eEffects[0], EFFECT_FLOAT_SCALE, GetM2DAFloat(TABLE_VFX_PERSISTENT, "RADIUS", ENTROPIC_AOE));

            break;
        }

        case ABILITY_SPELL_SOUL_SHIELD:
        {
            float fResistance = SOUL_SHIELD_SPELL_RESISTANCE;
            if (HasAbility(stEvent.oCaster, ABILITY_SPELL_ANTIMAGIC_WARD))
            {
                fResistance += 15.0f;
            }
            else if (HasAbility(stEvent.oCaster, ABILITY_SPELL_SPELL_SHIELD))
            {
                fResistance += 5.0f;
            }
            if (HasAbility(stEvent.oCaster, ABILITY_SPELL_LIFEWARD))
            {
                fResistance += 15.0f;
            }
            else if (HasAbility(stEvent.oCaster, ABILITY_SPELL_HIDDEN_SPIRIT_HEALER) == TRUE)
            {
                fResistance += 5.0f;
            }
            if (HasAbility(stEvent.oCaster, ABILITY_SPELL_WALL_OF_FORCE))
            {
                fResistance += 10.0f;
            }

            eEffects[0] = EffectModifyProperty(PROPERTY_ATTRIBUTE_DAMAGE_RESISTANCE_SPIRIT, fResistance);
            eEffects[0] = SetEffectEngineInteger(eEffects[0], EFFECT_INTEGER_VFX, 0);

            break;
        }
    }

    if (bEffectValid == TRUE)
    {
        Log_Trace_Spell("_ActivateModalAbility", "Activating modal ability.", stEvent.nAbility, OBJECT_INVALID);

        Ability_ApplyUpkeepEffects(stEvent.oCaster, stEvent.nAbility, eEffects, stEvent.oTarget, bPartywide);

        Log_Trace_Spell("_ActivateModalAbility", "Modal ability activated.", stEvent.nAbility, OBJECT_INVALID);
    }
    else
    {
        Log_Trace_Spell("_ActivateModalAbility", "Invalid Effect. We are not activating modal ability.", stEvent.nAbility, OBJECT_INVALID);
    }

}

// remove effects
void _DeactivateModalAbility(object oCaster, int nAbility)
{
    Log_Trace_Spell("_DeactivateModalAbility", "Deactivate modal ability.", nAbility, OBJECT_INVALID);

    // remove effects
    Effects_RemoveUpkeepEffect(oCaster, nAbility);
}

void main()
{
    event ev = GetCurrentEvent();
    int nEventType = GetEventType(ev);

    switch(nEventType)
    {
        case EVENT_TYPE_SPELLSCRIPT_PENDING:
        {
            // hand through
            Ability_SetSpellscriptPendingEventResult(COMMAND_RESULT_SUCCESS);

            break;
        }

        case EVENT_TYPE_SPELLSCRIPT_CAST:
        {
            // Get a structure with the event parameters
            struct EventSpellScriptCastStruct stEvent = Events_GetEventSpellScriptCastParameters(ev);

            /*switch (stEvent.nAbility)
            {
            }*/

            // we just hand this through to cast_impact
            SetAbilityResult(stEvent.oCaster, stEvent.nResistanceCheckResult);


            break;
        }

        case EVENT_TYPE_SPELLSCRIPT_IMPACT:
        {
            // Get a structure with the event parameters
            struct EventSpellScriptImpactStruct stEvent = Events_GetEventSpellScriptImpactParameters(ev);

            Log_Trace(LOG_CHANNEL_COMBAT_ABILITY, GetCurrentScriptName() + ".EVENT_TYPE_SPELLSCRIPT_IMPACT",Log_GetAbilityNameById(stEvent.nAbility));

            // Remove any previously existing effects from same spellid to avoid stacking
            Ability_PreventAbilityEffectStacking(stEvent.oTarget, stEvent.oCaster, stEvent.nAbility);

            // activate ability
            _ActivateModalAbility(stEvent);

            break;
        }

        case EVENT_TYPE_SPELLSCRIPT_DEACTIVATE:
        {
            // Get a structure with the event parameters
            struct EventSpellScriptDeactivateStruct stEvent = Events_GetEventSpellScriptDeactivateParameters(ev);

            // is ability active?
            if (IsModalAbilityActive(stEvent.oCaster, stEvent.nAbility) == TRUE)
            {
                _DeactivateModalAbility(stEvent.oCaster, stEvent.nAbility);
            }

            // Setting Return Value (abort means we aborted the ability)
            Ability_SetSpellscriptPendingEventResult(COMMAND_RESULT_INVALID);

            break;
        }
    }
}