Author Topic: Limiting an Autospawn problem...  (Read 453 times)

Legacy_datamaster

  • Jr. Member
  • **
  • Posts: 94
  • Karma: +0/-0
Limiting an Autospawn problem...
« on: May 05, 2011, 01:58:38 am »


               I am working on a mod that has an area that is where I want creatures to autospawn to a degree.
This script is run from a campfire's heartbeat script.

#include "nw_i0_generic"
//object heartbeat
void main()
{
object oArea = GetArea(OBJECT_SELF);
object oCreature = GetFirstObjectInArea(oArea);
object oPC = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR,
    PLAYER_CHAR_IS_PC, OBJECT_SELF, 1, CREATURE_TYPE_PERCEPTION,
    PERCEPTION_SEEN);
location lTarget = GetLocation(OBJECT_SELF);
int iGoblinInArea;
int iPCInArea;
//iLimit is to set the limit to be spawned.
int iLimit = 0;
string sMob = GetLocalString(oPC, "mnstrspwntyp");
//AInt is used to turn the autospawn function of the area on/off.
int AInt = (GetLocalInt(oPC, "autoact"));
if (AInt == 1)
{
while (GetIsObjectValid(oCreature) && (iLimit != (GetLocalInt(oPC, "autoval"))))
    {
    if (GetIsPC(oCreature))
        {
        iPCInArea = TRUE;
        }
    if (GetResRef(oCreature) == sMob && !GetIsDead(oCreature))
        {
        iGoblinInArea = TRUE;
        }
    iLimit = iLimit + 1;
    oCreature = GetNextObjectInArea(oArea);
    }
if (iPCInArea != TRUE) return;
if (iGoblinInArea != TRUE)
    {
    object oSpawn = CreateObject(OBJECT_TYPE_CREATURE, sMob, lTarget);
    SetIsTemporaryEnemy(oPC, oSpawn);
    AssignCommand(oSpawn, DetermineCombatRound(oPC));
    }
}
else
{
return;
}
}


I have an npc elsewhere that you talk to to activate the spawning option of this script.
I have a sundial with a conversation asking how many do you want to limit this spawning to.  This sets an int variable.  Since I have another creature in the area that stays, the scripts that set the limit I have it set to one higher than the one the player picks.  Ex. they want 1 that script says set to 2, they want 2 the script says 3.

I want this to be able to limit the total number spawned to the player's choice and if they want any more, they have to kill some.  The limiting is not working.

Another problem I am having with this is with the other creature that is always in the area.  It deletes it before it starts the spawning.

Any thoughts?
               
               

               
            

Legacy_Werehound

  • Newbie
  • *
  • Posts: 22
  • Karma: +0/-0
Limiting an Autospawn problem...
« Reply #1 on: May 05, 2011, 03:54:59 am »


               TBH I'd modify your OnDeath event of your monsters to check for the area, and if the dieing creature is in the area, spawn it again at a location of your choosing, going until they are DESTROYED (which does NOT fire an OnDeath event) or if they die with a variable set to not respawn. That would work much more efficiently, as HB scripts are resource heavy, and you could spawn the monsters in the conversation and not worry about them until cleanup-time.
               
               

               
            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Limiting an Autospawn problem...
« Reply #2 on: May 05, 2011, 08:07:14 am »


               Ok I Moved thing around and changed a few things.  

My thoughts are, If you want to keep it as a HB you need to move the  "autoact"  int off of the PC and place it on the area.  The function to find the PC in the area is the most expensive function in the entire script.  With the PERCEPTION_SEEN enabled It probably takes more time to run then the entire rest of the script.

I myself think it would be better written on a trigger placed around the campfire  That way you could control how close the PC has to get inorder for it to spawn.   


#include "nw_i0_generic"
//object heartbeat
void main()
{

  object oPC = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR,
      PLAYER_CHAR_IS_PC/*, OBJECT_SELF, 1, CREATURE_TYPE_PERCEPTION,
      PERCEPTION_SEEN */);  // I dont think Placeables have perception to see
  //autoact is used to turn the autospawn function of the area on/off.
  if (GetLocalInt(oPC, "autoact") != 1) return;

  object oArea = GetArea(OBJECT_SELF);
  location lTarget = GetLocation(OBJECT_SELF);
  int iGoblinInArea;
  //iLimit is to set the limit to be spawned.
  int iLimit = 4; //  Edit to grab the int for your max spawn.
  string sMob = GetLocalString(oPC, "mnstrspwntyp");

    object oCreature = GetFirstObjectInArea(oArea);
    while (GetIsObjectValid(oCreature) && (iLimit != (GetLocalInt(oPC, "autoval"))))
    {
      if (GetResRef(oCreature) == sMob && !GetIsDead(oCreature))
         iGoblinInArea=iGoblinInArea +1 ;
      oCreature = GetNextObjectInArea(oArea);
    }

    while (iGoblinInArea < iLimit )
    {
      object oSpawn = CreateObject(OBJECT_TYPE_CREATURE, sMob, lTarget);
      SetIsTemporaryEnemy(oPC, oSpawn);
      AssignCommand(oSpawn, DetermineCombatRound(oPC));
      iGoblinInArea= iGoblinInArea +1;
    }
}
 


               
               

               
            

Legacy_datamaster

  • Jr. Member
  • **
  • Posts: 94
  • Karma: +0/-0
Limiting an Autospawn problem...
« Reply #3 on: May 05, 2011, 08:19:21 pm »


               Lightfoot,

That script did not do exactly what I was wanting, although it did have it's points.
That script would spawn 4 creatures every HB.  The max creatures I meant was not max each
HB but the total in the area.  Ex. if the player picks 4, then each HB if there is not for creatures in the area then
it spawns one(or whatever number).  Then the next HB, again if there is not 4, spawn another.
If there is 4(or whatever the player picked) during a HB, then nothing is spawned.
One of the creatures would have to be killed before another is spawned.

I also had a question about your first while loop.

"while (GetIsObjectValid(oCreature) && (iLimit != (GetLocalInt(oPC, "autoval"))))
    {
      if (GetResRef(oCreature) == sMob && !GetIsDead(oCreature))
         iGoblinInArea=iGoblinInArea +1 ;
      oCreature = GetNextObjectInArea(oArea);
    }
"

Most of the time the number the player puts in "autoval" will NOT be the same as iLimit, so since
it is not incremented in the loop, this looks to me like it would be an infinite loop.  Is it supposed
to be?

Basically, I want the script to autospawn creatures in an area up to a maximum total number the
player specifies in a conversation elsewhere.

"Knowledge knows no bounds!" But knowledge hindsight might wish there had been some!
               
               

               
            

Legacy_datamaster

  • Jr. Member
  • **
  • Posts: 94
  • Karma: +0/-0
Limiting an Autospawn problem...
« Reply #4 on: May 05, 2011, 08:23:13 pm »


               Werehound,
I know HB scripts are resource heavy, but I don't want the autospawn to always function, just to function when the PC wants it to.  And then up to a maximum total number, not just on and on, taking up computer resources.
               
               

               
            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Limiting an Autospawn problem...
« Reply #5 on: May 05, 2011, 09:48:17 pm »


               You ar correct on that first While loop being questionable. I did not look at it that hard. It is the same condition that you had set in the first post. On looking at it again I see not reason at all for the second check just change it to: while (GetIsObjectValid(oCreature))

As far as the number od creatures go, If you read the comment after the line where I set it to four.

int iLimit = 4; // Edit to grab the int for your max spawn.

So you will want to change that line to get what ever Local Int you are setting From where ever you are setting it.


Ex.

int iLimit = GetLocalInt( oIDontKnow, "SomeVarName");

EDIT: and no it would not be an inifinite loop even the way it is written since the object would have to be valid and the int not equal in order for it to fire.  The porblem with leaving it there is there will be times when the loop would just not fire.  Sorry I missed that the first time around. 

With that fixed the script should work the way you described.   Every round if the number of creatures do not match the iLimit  retrived (once you have it retrive the Int ) It will spawn enough to bring it back to the full limit.   If you only want one spawned a round untill it is brought up to the limit change the second While to an If.
               
               

               


                     Modifié par Lightfoot8, 05 mai 2011 - 08:54 .
                     
                  


            

Legacy_datamaster

  • Jr. Member
  • **
  • Posts: 94
  • Karma: +0/-0
Limiting an Autospawn problem...
« Reply #6 on: May 05, 2011, 10:33:26 pm »


               Lightfoot,

I am still having problems.  The script is:

#include "nw_i0_generic"
//object heartbeat
void main()
{
  object oPC = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR,
      PLAYER_CHAR_IS_PC/*, OBJECT_SELF, 1, CREATURE_TYPE_PERCEPTION,
      PERCEPTION_SEEN */);  // I dont think Placeables have perception to see
  //autoact is used to turn the autospawn function of the area on/off.
  if (GetLocalInt(oPC, "autoact") != 1) return;
  object oArea = GetArea(OBJECT_SELF);
  location lTarget = GetLocation(OBJECT_SELF);
  int iGoblinInArea = 0;
  //iLimit is to set the limit to be spawned.
  int iLimit = (GetLocalInt(oPC, "autoval")); //  Edit to set the max number to spawn at at time.
  string sMob = GetLocalString(oPC, "mnstrspwntyp");
    object oCreature = GetFirstObjectInArea(oArea);
    while (GetIsObjectValid(oCreature))
    {
      if (GetResRef(oCreature) == sMob && !GetIsDead(oCreature))
         iGoblinInArea=iGoblinInArea +1 ;
      oCreature = GetNextObjectInArea(oArea);
    }
    while (iGoblinInArea < iLimit )
    {
      object oSpawn = CreateObject(OBJECT_TYPE_CREATURE, sMob, lTarget);
      SetIsTemporaryEnemy(oPC, oSpawn);
      AssignCommand(oSpawn, DetermineCombatRound(oPC));
      iGoblinInArea= iGoblinInArea +1;
    }
}

That script spawns on each HB the number picked by the PC, not up to a maximum total.
If the PC picks 3, it spawns 3 each HB, if they pick 1, it spawns 1 each HB.
I am trying to step through this to figure out what the problem is, not seeing it though.

edit-To try testing this I made this change to the first loop:
    while (GetIsObjectValid(oCreature))
    {
      if (GetResRef(oCreature) == sMob && !GetIsDead(oCreature))
         iGoblinInArea=iGoblinInArea +1 ;
      SendMessageToPC(oPC, "Went through first loop");
      oCreature = GetNextObjectInArea(oArea);
    }
Just to see how many times it goes through the loop.
With the PC selecting 1, it spawns 1 mob each HB but if I counted right, it goes
through the loop 13 times.  This 13 is the number if objects in the area plus whatever
creatures had spawned at that time(which I think was 3).
I tried the same thing with the second loop.  And if the PC wants just 1, it only goes through once,
like expected.  So basically just need to figure out how to set a maximum number in the area to stop
spawning until at least one is killed.
               
               

               


                     Modifié par datamaster, 05 mai 2011 - 10:14 .
                     
                  


            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Limiting an Autospawn problem...
« Reply #7 on: May 05, 2011, 11:18:16 pm »


               Ok I tested what you just posted.   It worked fine for me.  

It only spawned 4 creatures untill one was killed then replaced it.
               
               

               
            

Legacy_datamaster

  • Jr. Member
  • **
  • Posts: 94
  • Karma: +0/-0
Limiting an Autospawn problem...
« Reply #8 on: May 05, 2011, 11:32:20 pm »


               I am going to post my current module to the NWN vault so you can test it with what I am testing it with.  In case you want to.
               
               

               
            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Limiting an Autospawn problem...
« Reply #9 on: May 05, 2011, 11:41:44 pm »


               With the vault having to validate it.  It would be faster if you just opened a project here and posted it there.  
Or you could just eMail it to me.   RicRtsm@hotmail.com
Also you may want to try useing the script Debuger. 
 
SpawnScriptDebugger
               
               

               
            

Legacy_datamaster

  • Jr. Member
  • **
  • Posts: 94
  • Karma: +0/-0
Limiting an Autospawn problem...
« Reply #10 on: May 05, 2011, 11:44:46 pm »


               http://nwvault.ign.c....Detail&id=5263
is the link to the module on the vault.
To get to the place I am using this script:
click through the greeter, talk to the Areena guy(pick any place), talk to the person right beside the two switches and pick any.
Go through the door(that is NOT going down) then through the door opposite it.
Talk to the Auto person in here(she turns the auto spawn on/off) and use the sundial and pick a number.
Next go down the nearby stairs and in the first door to the left.  This has the campfire in it that uses this script.  It will be across the river. With it turned on, just stand near river(opposite the campfire) and it will keep spawning creatures every HB.
               
               

               
            

Legacy_datamaster

  • Jr. Member
  • **
  • Posts: 94
  • Karma: +0/-0
Limiting an Autospawn problem...
« Reply #11 on: May 05, 2011, 11:45:30 pm »


               I just had to update it on the vault.  I already had a previous version there.
               
               

               
            

Legacy_Werehound

  • Newbie
  • *
  • Posts: 22
  • Karma: +0/-0
Limiting an Autospawn problem...
« Reply #12 on: May 05, 2011, 11:59:29 pm »


               The OnDeath fix will go on and on as long as you're not checking for a variable on the PC.

Simply add "if (GetLocalInt(oPC, "FightRespawns") != 1) return;" before the respawn code. Set eh variable through conversation or use of a placeable or even a chat command =P/
               
               

               
            

Legacy_datamaster

  • Jr. Member
  • **
  • Posts: 94
  • Karma: +0/-0
Limiting an Autospawn problem...
« Reply #13 on: May 06, 2011, 12:07:10 am »


               I tried using the Debugger.  And apparently through the first loop it never did the if statement inside it.  It never increased iGoblinInArea.
               
               

               
            

Legacy_datamaster

  • Jr. Member
  • **
  • Posts: 94
  • Karma: +0/-0
Limiting an Autospawn problem...
« Reply #14 on: May 06, 2011, 12:17:34 am »


               Werehound,
Altering the OnDeath script like you are saying will spawn a new monster when you kill one.  Kill one, another immediately spawns.  That is not what I am wanting.  I want it where through a conversation elsewhere you set the maximum you want in total, NOT spawned at once, but the total number in the area it is to reach, then it WILL stop spawning until you kill one, which starts the spawning again.