Author Topic: Spawn and Despawn NPCs  (Read 401 times)

Legacy_BadEagle

  • Newbie
  • *
  • Posts: 4
  • Karma: +0/-0
Spawn and Despawn NPCs
« on: August 14, 2011, 04:43:23 pm »


               Ok so I've made this system for my PW module that when a PC enters an area, NPCs are spawned to points marked with waypoints. When a player leaves the area, all the NPCs are destroyed.

That worked fine until I expanded the script, I made it so that if an NPC is killed, a local int will be stored to his personal waypoint by the name "dead" with value 1, and there's a code in the NPC's OnDeath script to restore the int back to 0 with a delay of 20 seconds. However, this doesn't seem to work and I suspect it is because the DelayCommand gets disturped when the NPC is destroyed and local int "dead" stays with the value of 1 forever.

Here are the scripts:

Area OnEnter:
void main()
{
    object oPC = GetEnteringObject();
    if (!GetIsPC(oPC)) return;
    object oWP  = GetNearestObject(OBJECT_TYPE_WAYPOINT, oPC);
    int    iNth = 1;

    if (GetLocalInt(GetArea(oPC),"spawned")==FALSE)
    {
    while (GetIsObjectValid(oWP))
    {
    SendMessageToPC(oPC,""+GetTag(oWP)+", dead: "+IntToString(GetLocalInt(oWP,"dead")));
    if (GetLocalInt(oWP,"dead")!=1)
    {
    object oCreate = CreateObject(OBJECT_TYPE_CREATURE,GetTag(oWP),GetLocation(oWP));
    SetLocalObject(oCreate, "spawn",oWP);
    }
    oWP = GetNearestObject(OBJECT_TYPE_WAYPOINT, oPC, ++iNth);
    }
    SetLocalInt(GetArea(oPC),"spawned",TRUE);
    }

}

Area OnExit:
/*
This function returns TRUE if oArea currently
has a PC in it and FALSE it doesn't.
*Note: Returns FALSE if oArea is not valid.
*/
int GetIsAreaOccupied(object oArea)
    {
    if (GetIsObjectValid(oArea))
        {
        object oPlayer = GetFirstPC();
        while ((GetArea(oPlayer) != oArea) && (oPlayer != OBJECT_INVALID))
            oPlayer = GetNextPC();
        if (oPlayer != OBJECT_INVALID)
            return TRUE;
        else
            return FALSE;
        }
    else
        return FALSE;
    }

// Destroying the NPCs.
void main()
{
    object oPC = GetExitingObject();
    object oLoop = GetFirstObjectInArea(GetArea(oPC));
    object oPlayer = GetFirstObjectInArea(GetArea(oPC));
    int UnSpawn=TRUE;


if (!GetIsAreaOccupied(OBJECT_SELF))
{
    while (GetIsObjectValid(oLoop))
    {
        if (GetObjectType(oLoop)==OBJECT_TYPE_CREATURE && (GetCurrentHitPoints(oLoop)==GetMaxHitPoints(oLoop) || GetIsObjectValid(GetLocalObject(oLoop,"spawn"))))
        {
            SendMessageToPC(oPC,GetName(oLoop));
            DestroyObject(oLoop);
        }
        SetLocalInt(GetArea(oLoop),"spawned",FALSE);
        oLoop = GetNextObjectInArea(GetArea(oPC));
    }
}
}


NPC OnDeath:

//:://////////////////////////////////////////////////
//:: NW_C2_DEFAULT7
/*
  Default OnDeath event handler for NPCs.

  Adjusts killer's alignment if appropriate and
  alerts allies to our death.
 */
//:://////////////////////////////////////////////////
//:: Copyright © 2002 Floodgate Entertainment
//:: Created By: Naomi Novik
//:: Created On: 12/22/2002
//:://////////////////////////////////////////////////

#include "x2_inc_compon"
#include "x0_i0_spawncond"

void main()
{
    ExecuteScript("wob_xp",OBJECT_SELF);
    ExecuteScript("od_droprandom",OBJECT_SELF);
    if (GetIsObjectValid(GetLocalObject(OBJECT_SELF,"spawn")))
    {
    object oWP = GetLocalObject(OBJECT_SELF,"spawn");
    SetLocalInt(oWP,"dead",1);

    DelayCommand(20.0,SetLocalInt(oWP,"dead",0));
    }
    int nclass = GetLevelByclass(class_TYPE_COMMONER);
    int nAlign = GetAlignmentGoodEvil(OBJECT_SELF);
    object oKiller = GetLastKiller();

    // If we're a good/neutral commoner,
    // adjust the killer's alignment evil
    if(nclass > 0 && (nAlign == ALIGNMENT_GOOD || nAlign == ALIGNMENT_NEUTRAL))
    {
        AdjustAlignment(oKiller, ALIGNMENT_EVIL, 5);
    }

    // Call to allies to let them know we're dead
    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);

    // NOTE: the OnDeath user-defined event does not
    // trigger reliably and should probably be removed
    if(GetSpawnInCondition(NW_FLAG_DEATH_EVENT))
    {
         SignalEvent(OBJECT_SELF, EventUserDefined(1007));
    }
    craft_drop_items(oKiller);
}


I don't know how I could make it so the NPC's would respawn after a certain amount of time.
Please help!

Thanks,
~BadEagle
               
               

               


                     Modifié par BadEagle, 14 août 2011 - 03:43 .
                     
                  


            

Legacy_henesua

  • Hero Member
  • *****
  • Posts: 6519
  • Karma: +0/-0
Spawn and Despawn NPCs
« Reply #1 on: August 14, 2011, 05:10:41 pm »


               Check out my spawn and despawn functions in Simple Spawn. With that system I create a data object that can track a specific NPCs state (hitpoints, dead/alive etc...) across spawns.

I recommend importing the ERF. It will overwrite the default creature death script - with a hook to my custom despawn creature function which tracks death.
               
               

               


                     Modifié par henesua, 14 août 2011 - 04:13 .
                     
                  


            

Legacy_GhostOfGod

  • Hero Member
  • *****
  • Posts: 1490
  • Karma: +0/-0
Spawn and Despawn NPCs
« Reply #2 on: August 14, 2011, 05:13:53 pm »


               You could try assigning the DelayCommand to the area the NPC is in:

AssignCommand(GetArea(OBJECT_SELF), DelayCommand(20.0, SetLocalInt(oWP,"dead",0)));

And I'm not sure the dead NPC will still have the waypoint as a local object since it is dead? Don't quote me on that though. I'm still not sure of what info you can retrieve from NPCs in the OnDeath event.
               
               

               
            

Legacy_BadEagle

  • Newbie
  • *
  • Posts: 4
  • Karma: +0/-0
Spawn and Despawn NPCs
« Reply #3 on: August 14, 2011, 05:21:33 pm »


               

henesua wrote...

Check out my spawn and despawn functions in Simple Spawn. With that system I create a data object that can track a specific NPCs state (hitpoints, dead/alive etc...) across spawns.

I recommend importing the ERF. It will overwrite the default creature death script - with a hook to my custom despawn creature function which tracks death.

It does seem like a good system but I'm not looking for a complete system here, I would like to get as far as I can on my own.

I'd like to know whether or not my theory of DelayCommand getting disturped is correct and what I can do to make it tick all the way despite the NPC running the script getting killed.

I have tried running the delay script through the waypoint (And the area) with AssignCommand with no luck...

EDIT:

GhostOfGod wrote...

You could try assigning the DelayCommand to the area the NPC is in:

AssignCommand(GetArea(OBJECT_SELF), DelayCommand(20.0, SetLocalInt(oWP,"dead",0)));

And
I'm not sure the dead NPC will still have the waypoint as a local
object since it is dead? Don't quote me on that though. I'm still not
sure of what info you can retrieve from NPCs in the OnDeath
event.

Oh this actually worked this time for some reason! Thanks!

Problem solved! Thanks everyone!
               
               

               


                     Modifié par BadEagle, 14 août 2011 - 04:30 .
                     
                  


            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Spawn and Despawn NPCs
« Reply #4 on: August 14, 2011, 07:52:32 pm »


               

BadEagle wrote...


I'd like to know whether or not my theory of DelayCommand getting disturped is correct and what I can do to make it tick all the way despite the NPC running the script getting killed.


Yes, it's correct. It can't execute the command because it's no longer there. AssignCommand the DelayCommand to the area to fix this, as GoG suggested.

[Edit] Whups, just read the bottom half of your post - nm. '<img'>

Funky
               
               

               


                     Modifié par FunkySwerve, 14 août 2011 - 06:56 .
                     
                  


            

Legacy_ffbj

  • Hero Member
  • *****
  • Posts: 1097
  • Karma: +0/-0
Spawn and Despawn NPCs
« Reply #5 on: August 14, 2011, 10:52:58 pm »


               Yes.  Good to keep in mind regarding things that are dead.  They can't do anything, cause they are dead. You can get their name though, not sure of other things that can be retrieved.  Clearly their weapons and inventory since you can have that stuff drop.