//::///////////////////////////////////////////////
//:: Name x2_def_spawn
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Default On Spawn script


    2003-07-28: Georg Zoeller:

    If you set a ninteger on the creature named
    "X2_USERDEFINED_ONSPAWN_EVENTS"
    The creature will fire a pre and a post-spawn
    event on itself, depending on the value of that
    variable
    1 - Fire Userdefined Event 1510 (pre spawn)
    2 - Fire Userdefined Event 1511 (post spawn)
    3 - Fire both events

    2007-12-31: Deva Winblood
    Modified to look for X3_HORSE_OWNER_TAG and if
    it is defined look for an NPC with that tag
    nearby or in the module (checks near first).
    It will make that NPC this horse's master.

*/
//:://////////////////////////////////////////////
//:: Created By: Keith Warner, Georg Zoeller
//:: Created On: June 11/03
//:://////////////////////////////////////////////

const int EVENT_USER_DEFINED_PRESPAWN = 1510;
const int EVENT_USER_DEFINED_POSTSPAWN = 1511;


#include "x2_inc_switches"
#include "x3_inc_horse"
#include "x4_inc_functions"
#include "x2_inc_itemprop"

void EpicBonuses()
{
    //This part is a substitute for lacking NPC OnEquip and OnUnequip
    int nACBonus;
    int nSRBonus;
    object oPC = OBJECT_SELF;
    effect eEffect;
    int nLevel = GetHitDice(oPC);

    if (GetTag(GetItemInSlot(INVENTORY_SLOT_HEAD, oPC)) == "anc_it_epiche") //if the item is an equipped epic helmet
    {
    switch (nLevel)
        {
        case 40: nACBonus = 12; break;
        case 39: nACBonus = 12; break;
        case 38: nACBonus = 11; break;
        case 37: nACBonus = 11; break;
        case 36: nACBonus = 11; break;
        case 35: nACBonus = 10; break;
        case 34: nACBonus = 9; break;
        case 33: nACBonus = 8; break;
        case 32: nACBonus = 8; break;
        case 31: nACBonus = 7; break;
        case 30: nACBonus = 7; break;
        case 29: nACBonus = 7; break;
        case 28: nACBonus = 7; break;
        case 27: nACBonus = 6; break;
        case 26: nACBonus = 6; break;
        case 25: nACBonus = 5; break;
        case 24: nACBonus = 5; break;
        case 23: nACBonus = 4; break;
        case 22: nACBonus = 4; break;
        default: nACBonus = 3; break;
        }

    eEffect = ExtraordinaryEffect(EffectACIncrease(nACBonus, AC_DEFLECTION_BONUS));
    ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEffect, oPC);
    }

    if (GetTag(GetItemInSlot(INVENTORY_SLOT_CHEST, oPC)) == "anc_it_epicar" && GetLocalInt(oPC, "X4_CASTER_CLERIC") == FALSE) //if the item is an equipped epic armor
    {
    switch (nLevel)
        {
        case 40: nACBonus = 13; break;
        case 39: nACBonus = 13; break;
        case 38: nACBonus = 12; break;
        case 37: nACBonus = 12; break;
        case 36: nACBonus = 12; break;
        case 35: nACBonus = 10; break;
        case 34: nACBonus = 9; break;
        case 33: nACBonus = 9; break;
        case 32: nACBonus = 9; break;
        case 31: nACBonus = 8; break;
        case 30: nACBonus = 8; break;
        case 29: nACBonus = 7; break;
        case 28: nACBonus = 7; break;
        case 27: nACBonus = 6; break;
        case 26: nACBonus = 6; break;
        case 25: nACBonus = 6; break;
        case 24: nACBonus = 6; break;
        case 23: nACBonus = 4; break;
        case 22: nACBonus = 4; break;
        default: nACBonus = 3; break;
        }

    eEffect = ExtraordinaryEffect(EffectACIncrease(nACBonus, AC_ARMOUR_ENCHANTMENT_BONUS));
    ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEffect, oPC);
    }

    if (GetTag(GetItemInSlot(INVENTORY_SLOT_BELT, oPC)) == "anc_it_epicsr") //if the item is an equipped epic belt
    {
    nSRBonus = nLevel-18;
    if (nLevel < 21) nSRBonus = 12;
    nSRBonus = nSRBonus*2 + 10;

    eEffect = ExtraordinaryEffect(EffectSpellResistanceIncrease(nSRBonus));
    ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEffect, oPC);
    }

    //Give monks an attack bonus equal to wis modifier / 2
        if (GetHasFeat(FEAT_MONK_AC_BONUS, oPC))
        {
            int nBonus = (GetWisdom(oPC)-10)/4;
            effect eBonus = EffectAttackIncrease(nBonus);
            eBonus = SupernaturalEffect(eBonus);
            if (nBonus > 0) AssignCommand(GetModule(), ApplyEffectToPCAndHideIcon(eBonus, oPC));
        }

    //Give assassins an attack bonus equal to int modifier
        if (GetHasFeat(1120, oPC))
        {
            int nBonus = (GetIntelligence(oPC)-10)/2;
            effect eBonus = EffectAttackIncrease(nBonus);
            eBonus = SupernaturalEffect(eBonus);
            if (nBonus > 0) AssignCommand(GetModule(), ApplyEffectToPCAndHideIcon(eBonus, oPC));
        }

    //Apply Dwarven Defender damage reduction
        if (GetHasFeat(1118, oPC))
            {
            int nReduction;
            switch (GetLevelByClass(CLASS_TYPE_DWARVEN_DEFENDER, oPC))
                {
                case 6: nReduction = 3; break;
                case 7: nReduction = 3; break;
                case 8: nReduction = 3; break;
                case 9: nReduction = 3; break;
                case 10: nReduction = 6; break;
                case 11: nReduction = 6; break;
                case 12: nReduction = 6; break;
                case 13: nReduction = 6; break;
                case 14: nReduction = 9; break;
                case 15: nReduction = 9; break;
                case 16: nReduction = 9; break;
                case 17: nReduction = 9; break;
                case 18: nReduction = 12; break;
                case 19: nReduction = 12; break;
                case 20: nReduction = 12; break;
                case 21: nReduction = 12; break;
                case 22: nReduction = 15; break;
                case 23: nReduction = 15; break;
                case 24: nReduction = 15; break;
                case 25: nReduction = 15; break;
                case 26: nReduction = 18; break;
                case 27: nReduction = 18; break;
                case 28: nReduction = 18; break;
                case 29: nReduction = 18; break;
                case 30: nReduction = 21; break;
                }
            effect eReduction = EffectDamageReduction(nReduction, DAMAGE_POWER_PLUS_TEN);
            eReduction = SupernaturalEffect(eReduction);
            AssignCommand(GetModule(), ApplyEffectToPCAndHideIcon(eReduction, oPC));
            }
        //Done applying damage reduction

        //Check for Parry being used and apply bonus then
        if (GetActionMode(oPC, ACTION_MODE_PARRY)==TRUE)
        {
        int nParryAC = GetSkillRank(SKILL_PARRY, oPC) / 5;
        if(nParryAC>6)nParryAC=6;
        effect eParryAC = SupernaturalEffect(EffectACIncrease(nParryAC, AC_DODGE_BONUS));
        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eParryAC, oPC, 7.0);
        }
        //End of Parry part

        //Halve the normal Tumble AC bonus and restrict Pale Master AC bonus to 6
        if (GetSkillRank(SKILL_TUMBLE, oPC, TRUE) != 0 || GetLevelByClass(CLASS_TYPE_PALE_MASTER, oPC) > 11)
        {
        int nOld = GetSkillRank(SKILL_TUMBLE, oPC, TRUE)/5;
        int nNew = GetSkillRank(SKILL_TUMBLE, oPC, TRUE)/10;
        int nPalePenalty;
        switch (GetLevelByClass(CLASS_TYPE_PALE_MASTER, oPC))
            {
            case 30: nPalePenalty = 10; break;
            case 29: nPalePenalty = 10; break;
            case 28: nPalePenalty = 10; break;
            case 27: nPalePenalty = 8; break;
            case 26: nPalePenalty = 8; break;
            case 25: nPalePenalty = 8; break;
            case 24: nPalePenalty = 8; break;
            case 23: nPalePenalty = 6; break;
            case 22: nPalePenalty = 6; break;
            case 21: nPalePenalty = 6; break;
            case 20: nPalePenalty = 6; break;
            case 19: nPalePenalty = 4; break;
            case 18: nPalePenalty = 4; break;
            case 17: nPalePenalty = 4; break;
            case 16: nPalePenalty = 4; break;
            case 15: nPalePenalty = 2; break;
            case 14: nPalePenalty = 2; break;
            case 13: nPalePenalty = 2; break;
            case 12: nPalePenalty = 2; break;
            }
        int nPenalty = nOld - nNew;
        if ( GetLevelByClass(CLASS_TYPE_PALE_MASTER, oPC) > 11) nPenalty = nPenalty + nPalePenalty;
        effect eEffect = SupernaturalEffect(EffectACDecrease(nPenalty, AC_DODGE_BONUS));
        AssignCommand(GetModule(), ApplyEffectToPCAndHideIcon(eEffect, oPC));
        }

        // Grant the PC dragon immunity if he has that feat
        if ( GetHasFeat(1116, oPC) == TRUE )
        {
        int nType;
        switch(GetCreatureWingType(oPC))
        {
        case 4: nType = DAMAGE_TYPE_FIRE; break; //red dragon disciple
        case 34: nType = DAMAGE_TYPE_ACID; break; //black dragon disciple
        case 35: nType = DAMAGE_TYPE_ELECTRICAL; break; //blue dragon disciple
        case 36: nType = DAMAGE_TYPE_FIRE; break; //brass dragon disciple
        case 37: nType = DAMAGE_TYPE_ELECTRICAL; break; //bronze dragon disciple
        case 38: nType = DAMAGE_TYPE_ACID; break; //copper dragon disciple
        case 39: nType = DAMAGE_TYPE_FIRE; break; //gold dragon disciple
        case 40: nType = DAMAGE_TYPE_ACID; break; //green dragon disciple
        case 41: nType = DAMAGE_TYPE_COLD; break; //silver dragon disciple
        case 42: nType = DAMAGE_TYPE_COLD; break; //white dragon disciple
        default: nType = DAMAGE_TYPE_FIRE; break;
        }
        effect eImmunity = ExtraordinaryEffect(EffectDamageImmunityIncrease(nType, 100));
        AssignCommand(GetModule(), ApplyEffectToPCAndHideIcon(eImmunity, oPC));
        }

}

void main()
{

    DelayCommand(2.0, EpicBonuses());
    string sTag;
    object oNPC;
    // User defined OnSpawn event requested?
    int nSpecEvent = GetLocalInt(OBJECT_SELF,"X2_USERDEFINED_ONSPAWN_EVENTS");


    // Pre Spawn Event requested
    if (nSpecEvent == 1  || nSpecEvent == 3  )
    {
    SignalEvent(OBJECT_SELF,EventUserDefined(EVENT_USER_DEFINED_PRESPAWN ));
    }

    sTag=GetLocalString(OBJECT_SELF,"X3_HORSE_OWNER_TAG");
    if (GetStringLength(sTag)>0)
    { // look for master
        oNPC=GetNearestObjectByTag(sTag);
        if (GetIsObjectValid(oNPC)&&GetObjectType(oNPC)==OBJECT_TYPE_CREATURE)
        { // master found
            AddHenchman(oNPC);
        } // master found
        else
        { // look in module
            oNPC=GetObjectByTag(sTag);
            if (GetIsObjectValid(oNPC)&&GetObjectType(oNPC)==OBJECT_TYPE_CREATURE)
            { // master found
                AddHenchman(oNPC);
            } // master found
            else
            { // master does not exist - remove X3_HORSE_OWNER_TAG
                DeleteLocalString(OBJECT_SELF,"X3_HORSE_OWNER_TAG");
            } // master does not exist - remove X3_HORSE_OWNER_TAG
        } // look in module
    } // look for master

    /*  Fix for the new golems to reduce their number of attacks */

    int nNumber = GetLocalInt(OBJECT_SELF,CREATURE_VAR_NUMBER_OF_ATTACKS);
    if (nNumber >0 )
    {
        SetBaseAttackBonus(nNumber);
    }

    //Apply penalties/bonuses based on world difficulty
    string sDifficulty = GetLocalString(GetModule(), "mDiffAdven");
    if (sDifficulty != "ADVENTURER")
    {
        effect eImmunity;
        if (sDifficulty == "COMMONER")
        {
            eImmunity = EffectDamageImmunityDecrease(DAMAGE_TYPE_SLASHING, 25);
            eImmunity = EffectLinkEffects(EffectDamageImmunityDecrease(DAMAGE_TYPE_PIERCING, 25), eImmunity);
            eImmunity = EffectLinkEffects(EffectDamageImmunityDecrease(DAMAGE_TYPE_BLUDGEONING, 25), eImmunity);
            eImmunity = EffectLinkEffects(EffectDamageImmunityDecrease(DAMAGE_TYPE_ACID, 25), eImmunity);
            eImmunity = EffectLinkEffects(EffectDamageImmunityDecrease(DAMAGE_TYPE_COLD, 25), eImmunity);
            eImmunity = EffectLinkEffects(EffectDamageImmunityDecrease(DAMAGE_TYPE_DIVINE, 25), eImmunity);
            eImmunity = EffectLinkEffects(EffectDamageImmunityDecrease(DAMAGE_TYPE_ELECTRICAL, 25), eImmunity);
            eImmunity = EffectLinkEffects(EffectDamageImmunityDecrease(DAMAGE_TYPE_FIRE, 25), eImmunity);
            eImmunity = EffectLinkEffects(EffectDamageImmunityDecrease(DAMAGE_TYPE_MAGICAL, 25), eImmunity);
            eImmunity = EffectLinkEffects(EffectDamageImmunityDecrease(DAMAGE_TYPE_NEGATIVE, 25), eImmunity);
            eImmunity = EffectLinkEffects(EffectDamageImmunityDecrease(DAMAGE_TYPE_POSITIVE, 25), eImmunity);
            eImmunity = EffectLinkEffects(EffectDamageImmunityDecrease(DAMAGE_TYPE_SONIC, 25), eImmunity);
            eImmunity = SupernaturalEffect(eImmunity);
        }
        else
        {
            int nValue;
            if (sDifficulty == "HERO") nValue = 10;
            if (sDifficulty == "LEGEND") nValue = 25;
            if (sDifficulty == "DEMIGOD") nValue = 50;

            eImmunity = EffectDamageImmunityIncrease(DAMAGE_TYPE_SLASHING, nValue);
            eImmunity = EffectLinkEffects(EffectDamageImmunityIncrease(DAMAGE_TYPE_PIERCING, nValue), eImmunity);
            eImmunity = EffectLinkEffects(EffectDamageImmunityIncrease(DAMAGE_TYPE_BLUDGEONING, nValue), eImmunity);
            eImmunity = EffectLinkEffects(EffectDamageImmunityIncrease(DAMAGE_TYPE_ACID, nValue), eImmunity);
            eImmunity = EffectLinkEffects(EffectDamageImmunityIncrease(DAMAGE_TYPE_COLD, nValue), eImmunity);
            eImmunity = EffectLinkEffects(EffectDamageImmunityIncrease(DAMAGE_TYPE_DIVINE, nValue), eImmunity);
            eImmunity = EffectLinkEffects(EffectDamageImmunityIncrease(DAMAGE_TYPE_ELECTRICAL, nValue), eImmunity);
            eImmunity = EffectLinkEffects(EffectDamageImmunityIncrease(DAMAGE_TYPE_FIRE, nValue), eImmunity);
            eImmunity = EffectLinkEffects(EffectDamageImmunityIncrease(DAMAGE_TYPE_MAGICAL, nValue), eImmunity);
            eImmunity = EffectLinkEffects(EffectDamageImmunityIncrease(DAMAGE_TYPE_NEGATIVE, nValue), eImmunity);
            eImmunity = EffectLinkEffects(EffectDamageImmunityIncrease(DAMAGE_TYPE_POSITIVE, nValue), eImmunity);
            eImmunity = EffectLinkEffects(EffectDamageImmunityIncrease(DAMAGE_TYPE_SONIC, nValue), eImmunity);
            eImmunity = SupernaturalEffect(eImmunity);
        }
        ApplyEffectToObject(DURATION_TYPE_PERMANENT, eImmunity, OBJECT_SELF);
    }

    // Execute default OnSpawn script.
    if (GetLevelByClass(CLASS_TYPE_CLERIC, OBJECT_SELF) != 0) SetLocalInt(OBJECT_SELF, "X4_EXTRA_HEALS", 3);
    if(GetLocalInt(GetModule(), "X4_VANILLA_AI") == TRUE /*|| GetLevelByClass(CLASS_TYPE_CLERIC, OBJECT_SELF) != 0*/)
        SetLocalInt(OBJECT_SELF, "X4_VANILLA_AI", TRUE);
    if(GetLocalInt(OBJECT_SELF, "X4_VANILLA_AI") == TRUE) ExecuteScript("nw_c2_default9_v", OBJECT_SELF);
    else ExecuteScript("nw_c2_default9", OBJECT_SELF);


    //Post Spawn event requeste
    if (nSpecEvent == 2 || nSpecEvent == 3)
    {
    SignalEvent(OBJECT_SELF,EventUserDefined(EVENT_USER_DEFINED_POSTSPAWN));
    }

}