///////////////////////////////////////////////////////////////////////
// hos_bleeding - If bleeding is enabled this script will be called
// By Deva Bryson Winblood.  04/26/2005
///////////////////////////////////////////////////////////////////////
#include "nw_I0_generic"

void fnKickThemWhileTheirDown(object oPC)
{ // PURPOSE: Look for enemy to finish the job
  object oEnemy=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oPC,1,CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_ENEMY,CREATURE_TYPE_PLAYER_CHAR,PLAYER_CHAR_NOT_PC);
  object oFriend=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oEnemy,1,CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_ENEMY,CREATURE_TYPE_PERCEPTION,PERCEPTION_SEEN);
  int nN=1;
  effect eDeath=EffectDeath(TRUE);
  if (oEnemy!=OBJECT_INVALID)
  { // enemy exists
    while(oFriend!=OBJECT_INVALID&&oFriend==oPC)
    { // find a different friend
      nN++;
      oFriend=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oEnemy,1,CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_ENEMY,CREATURE_TYPE_PERCEPTION,PERCEPTION_SEEN);
    } // find a different friend
    if (oFriend==OBJECT_INVALID)
    { // can attack you
      if (GetObjectSeen(oPC,oEnemy))
      { // enemy can see PC
        if (GetDistanceBetween(oPC,oEnemy)>2.0)
        { // move
          AssignCommand(oEnemy,ActionMoveToObject(oPC));
        } // move
        else
        { // kill
          AssignCommand(oEnemy,ActionAttack(oPC));
          AssignCommand(oEnemy,ActionDoCommand(ApplyEffectToObject(DURATION_TYPE_INSTANT,eDeath,oPC)));
        } // kill
      } // enemy can see PC
    } // can attack you
  } // enemy exists
} // fnKickThemWhileTheirDown()

int fnGetHealingSpell(object oNPC)
{ // PURPOSE: See if the NPC has a healing spell
  int nRet=0;
  if (GetHasSpell(SPELL_CURE_CRITICAL_WOUNDS,oNPC)) nRet=SPELL_CURE_CRITICAL_WOUNDS;
  else if (GetHasSpell(SPELL_CURE_SERIOUS_WOUNDS,oNPC)) nRet=SPELL_CURE_SERIOUS_WOUNDS;
  else if (GetHasSpell(SPELL_HEAL,oNPC)) nRet=SPELL_HEAL;
  else if (GetHasSpell(SPELL_CURE_MODERATE_WOUNDS,oNPC)) nRet=SPELL_CURE_MODERATE_WOUNDS;
  else if (GetHasSpell(SPELL_HEALING_STING,oNPC)) nRet=SPELL_HEALING_STING;
  else if (GetHasSpell(SPELL_CURE_MINOR_WOUNDS,oNPC)) nRet=SPELL_CURE_MINOR_WOUNDS;
  else if (GetHasSpell(SPELL_REGENERATE,oNPC)) nRet=SPELL_REGENERATE;
  return nRet;
} // fnHealingSpell()

void fnLookForNPCHelp(object oPC)
{ // PURPOSE: See if their is a friendly NPC nearby that can heal
  int nN=1;
  object oFriend=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oPC,nN,CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_FRIEND,CREATURE_TYPE_PLAYER_CHAR,PLAYER_CHAR_NOT_PC);
  int nSpell=0;
  float fDist=GetDistanceBetween(oPC,oFriend);
  while(oFriend!=OBJECT_INVALID&&nSpell==0&&fDist<10.0)
  { // seek help
    nSpell=fnGetHealingSpell(oFriend);
    if (nSpell==0)
    { // no spell
      nN++;
      oFriend=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oPC,nN,CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_FRIEND,CREATURE_TYPE_PLAYER_CHAR,PLAYER_CHAR_NOT_PC);
      fDist=GetDistanceBetween(oPC,oFriend);
    } // no spell
  } // seek help
  if (oFriend!=OBJECT_INVALID&&nSpell!=0)
  { // try healing
    AssignCommand(oFriend,ActionCastSpellAtObject(nSpell,oPC));
  } // try healing
} // fnLookForNPCHelp()

void fnBleed(object oPC)
{ // PURPOSE: Handle bleeding
   object oMod=GetModule();
   effect eDeath=EffectDamage(9);
   effect eDmg=EffectDamage(1);
   int nHP=GetCurrentHitPoints(oPC);
   object oOb;
   object oNewTarg;
   int nN;
   int nTimeDif;
   if (GetLocalInt(oPC,"bBleedResetAttacker")!=TRUE)
   { // reset
       SetLocalInt(oPC,"bBleedResetAttacker",TRUE);
       nN=1;
       oOb=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oPC,nN,CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_ENEMY);
       while(oOb!=OBJECT_INVALID&&GetDistanceBetween(oPC,oOb)<20.0)
       { // attacker present
         if (GetIsPC(oOb)==FALSE)
         { // is not PC
           oNewTarg=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oOb,1,CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_ENEMY,CREATURE_TYPE_PERCEPTION,PERCEPTION_SEEN);
           if (oNewTarg==oPC) oNewTarg=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oOb,2,CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_ENEMY,CREATURE_TYPE_PERCEPTION,PERCEPTION_SEEN);
           if (oNewTarg!=OBJECT_INVALID&&oNewTarg!=oPC)
           { // pick new target
             AssignCommand(oOb,ClearAllActions(TRUE));
             SetIsTemporaryFriend(oPC,oOb,TRUE,8.0);
             DelayCommand(0.1,AssignCommand(oOb,DetermineCombatRound(oNewTarg)));
           } // pick new target
         } // is not PC
         nN++;
         oOb=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oPC,nN,CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_ENEMY);
       } // attacker present
     } // reset
     if (nHP<-9)
     { // die
       DeleteLocalInt(oPC,"bBleedResetAttacker");
       oOb=GetLastDamager(oPC);
       if (oOb==OBJECT_INVALID) oOb=GetModule();
       AssignCommand(oOb,ApplyEffectToObject(DURATION_TYPE_INSTANT,eDeath,oPC));
     } // die
     else
     { // bleeding
       SendMessageToPC(oPC,"You are bleeding to death.");
       oOb=GetLastDamager(oPC);
       if (oOb==OBJECT_INVALID) oOb=GetModule();
       AssignCommand(oOb,ApplyEffectToObject(DURATION_TYPE_INSTANT,eDmg,oPC));
        if (d4()==1)
        { // shout
          nTimeDif=d4();
          if (nTimeDif==1) PlayVoiceChat(VOICE_CHAT_PAIN1,oPC);
          else if (nTimeDif==2) PlayVoiceChat(VOICE_CHAT_PAIN2,oPC);
          else if (nTimeDif==3) PlayVoiceChat(VOICE_CHAT_PAIN3,oPC);
          else if (nTimeDif==4) PlayVoiceChat(VOICE_CHAT_NEARDEATH,oPC);
        } // shout
        DelayCommand(2.0,fnLookForNPCHelp(oPC));
        DelayCommand(12.0,fnKickThemWhileTheirDown(oPC));
     } // bleeding
} // fnBleed()



void main()
{
   object oPC=GetFirstPC();
   int nCHP;
   while(oPC!=OBJECT_INVALID)
   { // check each PC
     nCHP=GetCurrentHitPoints(oPC);
     if (nCHP<1) DelayCommand(0.5,fnBleed(oPC));
     if (nCHP<-9&&GetIsDead(oPC)&&d4()==1) PopUpDeathGUIPanel(oPC,TRUE,TRUE);
     oPC=GetNextPC();
   } // check each PC
}