// hcr3.1
// took out disabled.
// sr6.1
// fixed delay.
// sr 6.0
// fix to not execute code if dying.
// shortened delay on attackpc.
// 5.5.3
// added code to fix rare bug in which you continue to bleed under -10.
// added attack pc code if hostiles are about. gets rid of walking away from hostile npcs
// in sight.
// 5.5.2
// fixed familiar code so it dies when your bleeding to prevent possessing exploit.
// 5.5.1 fixed stable code to work as per PHB.
// added if to subrace code.
// HCR 5.5 change by Lorinton
// Modified to respawn the subrace after removing effects.
// Modified to reduce (hopefully eliminate) subrace effects being stripped by the game
// and other effects such as level drain being stripped by the subrace system.
// sr5.4
// changed some bleeding issues with self stabilizing.
// hc_bleeding - HardCore Bleeding/Death system
// Archaegeo 2002 July 2

#include "hc_inc"
#include "hc_inc_timecheck"
#include "hc_text_bleed"
//#include "hc_inc_death"
#include "hc_inc_remeff"

object oPlayer;

void CheckBleed()
{
    //SendMessageToPC(oPlayer, "Player State " + IntToString(GPS(oPlayer)));
    DelayCommand(6.0,ExecuteScript("hc_bleeding", oPlayer));
}

void SetHP(string sID, object oPlayer)
{
        SetPersistentInt(oMod,"LastHP" + sID, GetCurrentHitPoints(oPlayer));
}

void main()
{
    if(GetIsObjectValid(OBJECT_SELF)) oPlayer=OBJECT_SELF;
    else return;
    // sr6.0
    if(GPS(oPlayer) == PWS_PLAYER_STATE_DEAD)
       return;
    // 5.5.2
    // added killing familiars on dying to prevent exploits
    object oFamiliar = GetAssociate(ASSOCIATE_TYPE_FAMILIAR, oPlayer);
    effect eDeath = EffectDeath();
    if (GetIsObjectValid(oFamiliar) && GetCurrentHitPoints(oPlayer) < 1)
        DestroyObject(oFamiliar);
    // get player state.
    int iPlayerState = GPS(oPlayer);
    int iPlayerMoving=GetLocalInt(oPlayer,"MOVING");
    // get current hitpoints.
    int iCHP = GetCurrentHitPoints(oPlayer);
    //SendMessageToPC(oPlayer, "iCHP = " + IntToString(iCHP));
    string sName=GetName(oPlayer);
    string sCDK=GetPCPlayerName(oPlayer);
    string sID=sName+sCDK;
    string sAreaTag=GetTag(GetArea(oPlayer));
    string sFT="FuguePlane";
    // if dm return.
    if(GetIsDM(oPlayer)) return;
    int iLHP=GetPersistentInt(oMod, "LastHP"+sID);
    if( iPlayerState==PWS_PLAYER_STATE_DEAD &&
        sAreaTag == sFT)
        return;
    if( iPlayerState!=PWS_PLAYER_STATE_ALIVE &&
        iCHP > 1 &&
        sAreaTag != sFT )
    {
        //debug
        //SendMessageToPC(oPlayer, "Shouldnt be here");
        if(iPlayerMoving)
        {
            return;
        }
        SetPlotFlag(oPlayer,FALSE);
        RemoveEffects(oPlayer);
        SPS(oPlayer, PWS_PLAYER_STATE_ALIVE);
        SetHP(sID, oPlayer);
        object oFR;
        if((oFR=GetItemPossessedBy(oPlayer, "fuguerobe"))!=OBJECT_INVALID)
            DestroyObject(oFR);
        return;
    }
    else if(iPlayerState == PWS_PLAYER_STATE_ALIVE) return;
    // if pc is at 0 he is stabalized and in no danger.
    if (iCHP == 0 && GPS(oPlayer) == PWS_PLAYER_STATE_DYING)
    {
        SPS(oPlayer, PWS_PLAYER_STATE_STABLEHEAL);
        SendMessageToPC(oPlayer, STABLERECMESSAGE);
        SetHP(sID, oPlayer);
        CheckBleed();
        return;
    }
    int nHour=nConv;
    int nDay=24*nConv;
    int nSSB=SecondsSinceBegin();
    // Check for spontaneous healing
    if(  iCHP > iLHP &&
         iPlayerState != PWS_PLAYER_STATE_STABLEHEAL )
        {
            //debug
            //SendMessageToPC(oPlayer, "Shouldnt be here");
            //SendMessageToPC(oPlayer, "iCHP = " + IntToString(iCHP));
            //SendMessageToPC(oPlayer, "iLHP = " + IntToString(iLHP));
            SendMessageToPC(oPlayer, STABLEHEALMESSAGE);
            SPS(oPlayer, PWS_PLAYER_STATE_STABLEHEAL);
            DeleteLocalInt(oPlayer, "HEALED");
            SetHP(sID, oPlayer);
            CheckBleed();
            return;
        }
    if(
       ((iPlayerState == PWS_PLAYER_STATE_STABLE ||
         iPlayerState == PWS_PLAYER_STATE_STABLEHEAL) &&
        (GetPersistentInt(oMod,"LastRecCheck"+sID)+nHour) < nSSB)
      )
    {
        // hcr3.1
        // debug
        //SendMessageToPC(oPlayer, "Hourly Check");
        SetPersistentInt(oMod, "LastRecCheck"+sID, nSSB);
        if(d100() <= 10)
        {
            if(iPlayerState==PWS_PLAYER_STATE_STABLE)
            {
                SPS(oPlayer, PWS_PLAYER_STATE_STABLEHEAL);
                SendMessageToPC(oPlayer, STABLERECMESSAGE);
                SetHP(sID, oPlayer);
                DelayCommand(2.0, ExecuteScript("hc_attackpc" , oPlayer));
                DelayCommand(6.0, CheckBleed());
                return;
            }
            else if(iPlayerState==PWS_PLAYER_STATE_STABLEHEAL)
            {
                SPS(oPlayer, PWS_PLAYER_STATE_ALIVE);
                //hcDisabledSetup(oPlayer);
                SendMessageToPC(oPlayer, ALIVEMESSAGE);
                effect eHeal = EffectHeal(GetMaxHitPoints(oPlayer) + abs(GetCurrentHitPoints(oPlayer))
                                       -( GetMaxHitPoints(oPlayer) - 1 ));
                ApplyEffectToObject(DURATION_TYPE_INSTANT, eHeal, oPlayer);
                // 5.5.3 added code to attack target if ressed near hostiles.
                // sr6.0 shortened delay
                // sr6.1 fixed delay
                DelayCommand(2.0, ExecuteScript("hc_attackpc" , oPlayer));
                return;
            }
        }
        else
        {
            // 5.5.1 only players who are stable bleed.
            if (iPlayerState == PWS_PLAYER_STATE_STABLE)
            {
                 effect eDamage = EffectDamage(1, DAMAGE_TYPE_MAGICAL, DAMAGE_POWER_PLUS_FIVE);
                 ApplyEffectToObject( DURATION_TYPE_INSTANT, eDamage, oPlayer);
                 SendMessageToPC(oPlayer,SLIPDEATH);
            }
            else
                 SendMessageToPC(oPlayer, REMAINUNCONSCIOUS);
            SetHP(sID, oPlayer);
            CheckBleed();
            return;
        }
    }
    else if (iPlayerState==PWS_PLAYER_STATE_DYING)
    {
// Make a stabilization check
        if(iCHP > iLHP)
        {
            SendMessageToPC(oPlayer, STABLEHEALMESSAGE);
            SPS(oPlayer, PWS_PLAYER_STATE_STABLEHEAL);
            CheckBleed();
            SetHP(sID, oPlayer);
            return;
        }
        SetHP(sID, oPlayer);
        if (d100() <= 10 && iCHP > -10)
        {
// They stabilized
            SendMessageToPC(oPlayer, STABLEMESSAGE);
            SPS(oPlayer, PWS_PLAYER_STATE_STABLE);
            CheckBleed();
            return;
        }
        else
        {
// They bleed!
            // 5.5.3 added due to BW bug with not dying sometimes when less than -9.
            if (iCHP < -9)
            {
               ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDeath(), oPlayer);
               return;
            }
            SendMessageToPC(oPlayer,SLIPDEATH);
            effect eDamage = EffectDamage(1, DAMAGE_TYPE_MAGICAL, DAMAGE_POWER_PLUS_FIVE);
            ApplyEffectToObject( DURATION_TYPE_INSTANT, eDamage, oPlayer);
            int which = d6();
            switch (which)
            {
                case 1:
                    PlayVoiceChat (VOICE_CHAT_PAIN1, oPlayer);
                break;
                case 2:
                    PlayVoiceChat (VOICE_CHAT_PAIN2, oPlayer);
                break;
                case 3:
                    PlayVoiceChat (VOICE_CHAT_PAIN3, oPlayer);
                break;
                case 4:
                    PlayVoiceChat (VOICE_CHAT_HEALME, oPlayer);
                break;
                case 5:
                    PlayVoiceChat (VOICE_CHAT_NEARDEATH, oPlayer);
                break;
                case 6:
                    PlayVoiceChat (VOICE_CHAT_HELP, oPlayer);
                break;
            }
            SetHP(sID, oPlayer);
            CheckBleed();
            return;
        }
    //CheckBleed();
    }
  CheckBleed();
}
