#include "NW_I0_GENERIC"
void main()
{

    object oKiller = GetLastKiller();


location lDeath = GetLocation(OBJECT_SELF);

ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY,EffectVisualEffect( VFX_FNF_SUMMON_GATE ), lDeath, 3.0);
ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY,EffectVisualEffect( VFX_FNF_FIRESTORM ), lDeath, 3.0);
 ApplyEffectToObject(DURATION_TYPE_PERMANENT,EffectNegativeLevel(19), oKiller);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY,SupernaturalEffect(EffectKnockdown()), oKiller, 6.0);



    int noleech = 0;
    int nClass = GetLevelByClass(CLASS_TYPE_COMMONER);
    int nAlign = GetAlignmentGoodEvil(OBJECT_SELF);

    if(nClass > 0 && (nAlign == ALIGNMENT_GOOD || nAlign == ALIGNMENT_NEUTRAL))
    {
        AdjustAlignment(oKiller, ALIGNMENT_EVIL, 5);
    }
    SpeakString("NW_I_AM_DEAD", TALKVOLUME_SILENT_TALK);
    //Shout Attack my target, only works with the On Spawn In setup
    SpeakString("NW_ATTACK_MY_TARGET", TALKVOLUME_SILENT_TALK);
    if(GetSpawnInCondition(NW_FLAG_DEATH_EVENT))
    {
        SignalEvent(OBJECT_SELF, EventUserDefined(1007));
    }
    float BaseEXP = ((GetChallengeRating(OBJECT_SELF)*3.0)+5);
    float BonusEXP = GetChallengeRating(OBJECT_SELF)+5;
    float BaseMonEXP = BaseEXP;
    int NumOfParty = 0;
    float PartyLevelSum = 0.0;
    object oPartyMember = GetFirstFactionMember(oKiller, TRUE);
    while(GetIsObjectValid(oPartyMember))  {
        if (GetArea(OBJECT_SELF) == GetArea(oPartyMember))
        {
        int leech = GetHitDice(oPartyMember);
        if (leech >= noleech){
        noleech = leech;
        }
        NumOfParty++;
        PartyLevelSum += GetCharacterLevel(oPartyMember);
        }
        oPartyMember = GetNextFactionMember(oKiller, TRUE);
    }
     if (PartyLevelSum <= 1.0)
    {
       PartyLevelSum = 1.0;
    }
     if (NumOfParty <= 1)
    {
       NumOfParty = 1;
    }
    float PartyAvgLvl = PartyLevelSum / NumOfParty;
    //Calculate Adjustment Value
         if (PartyAvgLvl <= 1.0)
    {
       PartyAvgLvl = 1.0;
    }
    float x =  GetChallengeRating(OBJECT_SELF);
             if (x <= 1.0)
    {
       x = 1.0;
    }
    float z =  (x / PartyAvgLvl);

    float AdjustValue = ((z+2)/3);
    float FinalMonValue;
    //Determine Final Experience Value
    if (AdjustValue == 0.0) {
        FinalMonValue = BaseMonEXP;
     } else {
        if (AdjustValue < 1.0) {
            FinalMonValue = BaseMonEXP * AdjustValue;
        } else {
            FinalMonValue = BaseMonEXP + (BonusEXP * (AdjustValue * (1.10)));
        }
     }
     //Determine the value of the Split EXP
    if (NumOfParty >= 6)
    {
       NumOfParty = 5;
    }
     if (NumOfParty <= 1)
    {
       NumOfParty = 1;
    }
         if (FinalMonValue <= 1.0)
    {
       FinalMonValue = 1.0;
    }
     float SplitFinalEXP = FinalMonValue / NumOfParty;
             if (SplitFinalEXP <= 1.0)
    {
       SplitFinalEXP = 1.0;
    }
    float y = (FinalMonValue - SplitFinalEXP);
                if (y <= 1.0)
    {
       y = 1.0;
    }
              if (PartyAvgLvl >= 15.0)
    {
        FinalMonValue = FinalMonValue - ( PartyAvgLvl);
    }
     float PartyBonus = ((y +1)/ 1.75) + (FinalMonValue + ((21-PartyAvgLvl)/3));
     int SFEint = FloatToInt(PartyBonus);
     //Distribute EXP to all PCs in the Party

     oPartyMember = GetFirstFactionMember(oKiller, TRUE);
     while (GetIsObjectValid(oPartyMember)) {
     if (GetArea(OBJECT_SELF) == GetArea(oPartyMember))
     {

int nHD = GetHitDice(oPartyMember) + 1;
     int nMax = (((nHD * (nHD - 1)) / 2) * 1000)+1;
       GiveXPToCreature(oPartyMember, SFEint);
       if (nMax <= GetXP(oPartyMember) && nHD <= 20){

       int b = ( nMax);
       SetXP(oPartyMember, b);
       SendMessageToPC(oPartyMember, "You cannot gain experience untill you have leveled.");

       }
       if (GetIsDead(oPartyMember)){
       int a = GetXP(oPartyMember);
       int b = ( a-SFEint);
       SetXP(oPartyMember, b);
       SendMessageToPC(oPartyMember, "You cannot gain experience while dead. Your XP has been reset.");

       }

       if ((GetHitDice(oPartyMember)) <= (noleech - 5) || (GetHitDice(oPartyMember)) >= FloatToInt(PartyAvgLvl) + 5){
       int a = GetXP(oPartyMember);
       int b = ( a-SFEint);
       SetXP(oPartyMember, b);
       SendMessageToPC(oPartyMember, "All party members must be within 4 levels of each other. Your XP has been reset.");

     }

    }
        oPartyMember = GetNextFactionMember(oKiller, TRUE);
     }
}