Author Topic: NPCs fall unconscious  (Read 482 times)

Legacy_mordy_was_here

  • Newbie
  • *
  • Posts: 19
  • Karma: +0/-0
NPCs fall unconscious
« on: October 14, 2010, 06:10:32 pm »


               Hello, all. I've run into a bit of a jam with a script I'm using, and was wondering if there was a better way to work it out. First, I should say that I ran a search for this on these forums and the old Bioware scripting boards, no dice.
And second, I'm a total scripting muppet, and, unfortunately, the idea that I want to realize is complicated. 'Image 

Basically, after an NPC has had enough of their hitpoints sheered off in combat, I need them to fall 'unconscious', dropping aggro, and waiting at near-death until they've regenerated enough hitpoints to return to the fray, or until they've been healed. This, of course, would take place instead of actual death, or anything else that would cause the player to have to resurrect them. (Resurrection is something I'm trying to avoid like the plague.)

I'm working with three scripts, all borrowed from a thread asking for the same thing. Now, they work like a charm... except for the part where the NPC is actually supposed to get knocked down. He'll be struck dead, fall to the ground with his death cry and all, and then pop back up into a knock-down position and remain at near death until he's regenerated. What I need to know is if there is a way to smooth out that animation, instead of having him actually die first. It's creating all sorts of awkward situations. 'Image


Here's the scripts, the first one goes OnDeath:

//Used after all immunities are stripped to create a subconscious stupor
void Subconscious(object oSelf)
{
effect eRes = EffectResurrection();
effect eSub = SupernaturalEffect(EffectKnockdown());
AssignCommand(oSelf, ActionWait(999999.9f));
ApplyEffectToObject(DURATION_TYPE_INSTANT, eRes, oSelf);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eSub, oSelf);
SetImmortal(oSelf, TRUE);
//Get the Factions so that they can be reset later
//Make sure the character will not be attacked
int nFac = 0;
int nRep;
while(nFac < 4)
  {
  nRep = GetStandardFactionReputation(nFac, oSelf);
  SetStandardFactionReputation(nFac, 100, oSelf);
  SetLocalInt(oSelf, "DEATHFAC" + IntToString(nFac), nRep);
  nFac++;
  }
}
//Prepares the subconscious state.  Removes all effects.
void main()
{
object oSelf = OBJECT_SELF;
//The Henchman is not reassigned later, dialogue for rejoining is assumed.
RemoveHenchman(GetMaster(oSelf), oSelf);
int nDeathPoints = 1 - GetCurrentHitPoints(oSelf);
if(nDeathPoints < 1) nDeathPoints = 11; //Standard for instant death.
SetLocalInt(oSelf, "DEATH", nDeathPoints);
ClearAllActions(TRUE);
SetIsDestroyable(FALSE);
effect eCheck = GetFirstEffect(oSelf);
while(GetIsEffectValid(eCheck))
  {
  RemoveEffect(oSelf, eCheck);
  eCheck = GetNextEffect(oSelf);
  }
int nSlot = 0;
object oItem;
//Unequip items without an action
/*
while(nSlot < 18) //All equipped inventory slots
  {
  oItem = GetItemInSlot(nSlot);
  DestroyObject(oItem, 0.1);
  oItem = CopyItem(oItem, oSelf, TRUE);
  //Bug.  If the NPC's inventory is full he will not later be able to reequip creature items.
  if(nSlot > 14) //Creature Item
    SetLocalObject(oSelf, "DEATHSLOT" + IntToString(nSlot), oItem);
  nSlot++;
  }
*/
DelayCommand(2.0, Subconscious(oSelf));
return;
}


The second goes in the OnHeartbeat tab:

//Allows healed hitpoints to go against the death count
//Restores back to life if health exceeds death
void HitPointCheck(object oCreature)
{
effect eCheck, eDamage;
object oCreat;
int nSlot, nRep, nFac;
int nHitPoints = GetCurrentHitPoints(oCreature);
int nDeathPoints = GetLocalInt(oCreature, "DEATH");
//Ensures that a creature damaged more than its total hit points is still able to be restored by healing
if(nHitPoints > 1 && nHitPoints <= nDeathPoints)
  {
  nDeathPoints -= nHitPoints - 1;
  eDamage = EffectDamage(nHitPoints -1);
  ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oCreature);
  SetLocalInt(oCreature, "DEATH", nDeathPoints);
  }
//Restores Back to Life
else if(nHitPoints > nDeathPoints)
  {
  eDamage = EffectDamage(nDeathPoints);
  ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oCreature);
  AssignCommand(oCreature, ClearAllActions(TRUE));
  eCheck = GetFirstEffect(oCreature);
  while(GetIsEffectValid(eCheck))
    {
    RemoveEffect(oCreature, eCheck);
    eCheck = GetNextEffect(oCreature);
    }
  DeleteLocalInt(oCreature, "DEATH");
  SetImmortal(oCreature, FALSE);
  nSlot = 15;
  while(nSlot < 18)
    {
    oCreat = GetLocalObject(oCreature, "DEATHSLOT" + IntToString(nSlot));
    if(GetIsObjectValid(oCreat))
      AssignCommand(oCreature, ActionEquipItem(oCreat, nSlot));
    DeleteLocalObject(oCreature, "DEATHSLOT" + IntToString(nSlot));
    nSlot++;
    }
  nFac = 0;
  while(nFac < 4)
    {
    nRep = GetLocalInt(oCreature, "DEATHFAC" + IntToString(nFac));
    SetStandardFactionReputation(nFac, nRep, oCreature);
    DeleteLocalInt(oCreature, "DEATHFAC" + IntToString(nFac));
    nFac++;
    }
  }
}
void main()
{
object oSelf = OBJECT_SELF;
if(GetLocalInt(oSelf, "DEATH"))
  {
  HitPointCheck(oSelf);
  return;
  }
//The rest of the on HeartBeat Script can go here
return;
}



And the third goes into OnSpellCastAt:

void main()
{
object oSelf = OBJECT_SELF;
int nSpell = GetLastSpell();
int nDeath = GetLocalInt(oSelf, "DEATH");
effect eCheck, eHeal;
int nSlot, nFac, nRep;
object oCreat;
//Remove All Subconscious Effects if a life-restoring spell is cast
if((nSpell == SPELL_RAISE_DEAD || nSpell == SPELL_RESURRECTION)  && nDeath != FALSE)
  {
  if(nSpell == SPELL_RESURRECTION)
    {
    eHeal = EffectHeal(GetMaxHitPoints(oSelf));
    ApplyEffectToObject(DURATION_TYPE_INSTANT, eHeal, oSelf);
    }
  AssignCommand(oSelf, ClearAllActions(TRUE));
  eCheck = GetFirstEffect(oSelf);
  while(GetIsEffectValid(eCheck))
    {
    RemoveEffect(oSelf, eCheck);
    eCheck = GetNextEffect(oSelf);
    }
  DeleteLocalInt(oSelf, "DEATH");
  SetImmortal(oSelf, FALSE);
  //Equip Creature Items
  nSlot = 15;
  while(nSlot < 18)
    {
    oCreat = GetLocalObject(oSelf, "DEATHSLOT" + IntToString(nSlot));
    if(GetIsObjectValid(oCreat))
      AssignCommand(oSelf, ActionEquipItem(oCreat, nSlot));
    DeleteLocalObject(oSelf, "DEATHSLOT" + IntToString(nSlot));
    nSlot++;
    }
  //Adjust Faction
  nFac = 0;
  while(nFac < 4)
    {
    nRep = GetLocalInt(oSelf, "DEATHFAC" + IntToString(nFac));
    SetStandardFactionReputation(nFac, nRep, oSelf);
    DeleteLocalInt(oSelf, "DEATHFAC" + IntToString(nFac));
    nFac++;
    }
  }
//Place Rest of onSpellCastAt script here.
return;
}


I greatly appreciate any help that can be offered. And if there's a better way to post scripts, please let me know. The above is a total eyesore. ><
               
               

               
            

Legacy_Mudeye

  • Full Member
  • ***
  • Posts: 238
  • Karma: +0/-0
NPCs fall unconscious
« Reply #1 on: October 14, 2010, 06:39:36 pm »


               If you look at the scripts for SoU henchmen, they sort of do that.  When "killed" they drop to one hit point, cry out to be healed, drop to the ground and don't move.  You have a period of time to revive them before the officially die.  You might be able to use those scripts or make your own variations.
               
               

               
            

Legacy_Dagesh

  • Jr. Member
  • **
  • Posts: 55
  • Karma: +0/-0
NPCs fall unconscious
« Reply #2 on: October 14, 2010, 06:42:02 pm »


               Hmmm.  You may want to change this:

effect eSub = SupernaturalEffect(EffectKnockdown());
AssignCommand(oSelf, ActionWait(999999.9f));
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eSub, oSelf);

to this:

effect eSub = SupernaturalEffect(EffectKnockdown());
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eSub, oSelf, 99999);

From the Lexicon:
"[EffectKnockdown] cannot be applied instantly or permanently, only temporarily."

Therefore you should change the duration type to temporary and set the duration for longer (and removing the ActionWait command).  It is difficult to remove this effect because it will return 0 when you loop through to find the effect type.  The reason that is a problem is because other effects also have 0.  Since you are removing ALL effects in the code you posted this may not be such an issue.

Another thing you could do instead, and this is helpful if the NPC has high discipline, is have the NPC play an animation instead of the section I posted above.  With this you would have to be careful when you "ClearAllActions" any time after he was playing the animation because it would cause the NPC to stand back up.

edit: typo
               
               

               


                     Modifié par Dagesh, 14 octobre 2010 - 06:03 .
                     
                  


            

Legacy_mordy_was_here

  • Newbie
  • *
  • Posts: 19
  • Karma: +0/-0
NPCs fall unconscious
« Reply #3 on: October 14, 2010, 06:44:58 pm »


               Thank you! 'Image I'll give all of that a try as soon as I can.