New to scripting!

Hello everyone,

I started to learn NWNscript a few weeks ago, and doing simply things at the moment. Right now im creating a script that does spawn some winter placeables arround some waypoints arround the module in winter months ( 11, 12, and 1), when spring comes they are removed. It is executed in each area.

The problem I have is that even without giving it a loop to create many, they do spawn arround 1-6 placeables, overstacking the place. I want to decide how many they spawn. I though about a while or for loop, but having this issue no matter what I write, it always spawns 1-6 placeables >.<

This is the code I have got so far. As far as I know, this should spawn 1 placeable in each waypoint in the module with that tag.

//This is a random placeable spawn for iceblocks in winter. sObject is the tag of the placeable

void Randomspawn(object oArea,string sOject)
{

object oFirst = GetFirstObjectInArea(oArea);
while(GetIsObjectValid(oFirst) )
{
   // All area objects are checked to detect the waypoing by tag

    if(GetTag(oFirst) == "NO_IS_SPAWN01")
    {
         //Random location from that waypointin that area
         location lLocation = GetRandomLocation(oArea,oFirst,IntToFloat(d4()));
         //Create the placeable in tha tlocation
         object oDog = CreateObject(OBJECT_TYPE_PLACEABLE,sOject,lLocation,TRUE);


    }
 //Go for the next object in the area to check if there are more waypoints.
oFirst= GetNextObjectInArea(oArea);


}

DelayCommand(120.0,Randomspawn(oArea,sOject));

}

//This deletes the above placeables each cycle.

void Despawnrandom(object oArea,string sOject)
{

object oFirst = GetFirstObjectInArea(oArea);
while(GetIsObjectValid(oFirst))
{
    if(GetTag(oFirst) == sOject)
    {
        SetPlotFlag(oFirst,FALSE);
        DestroyObject(oFirst,0.1);
    }
    oFirst= GetNextObjectInArea(oArea);
}
DelayCommand(120.0,Despawnrandom(oArea,sOject));

}


The functions are called on the onloadmodule script, so the cycle begins every 2 minuts./ hour ingame.

object oArea =GetFirstArea();
while(GetIsObjectValid(oArea))
{
     Despawnrandom(oArea,"x3_plc_flame001");
     DelayCommand(0.5,Randomspawn(oArea,"x3_plc_flame001"));
     oArea = GetNextArea();
}

It detects all waypoints in each area correctly, but the number of spawns isnt correct. If im not mistaken this code should place only 1.

Anoyne sees anything wrong?

Thanks!

Welcome.

Try this code. It is not a complete solution, but an example of spawned placeable’s life & death cycle. Explanation is below.

// By NWShacker, 2020-11-15
#include "x0_i0_position"

void Life(string sPlaceTag, string sSpawnResRef, string sSpawnTag)
{
    object oMyObject;
    location lSpawn;
    int i;

    while(GetIsObjectValid(oMyObject = GetObjectByTag(sPlaceTag, i++)))
    {
        lSpawn = GetRandomLocation(GetArea(oMyObject), oMyObject, IntToFloat(d4()));
        CreateObject(OBJECT_TYPE_PLACEABLE, sSpawnResRef, lSpawn, FALSE, sSpawnTag);
    }
}

void Death(string sSpawnTag)
{
    object oMyObject;
    int i;

    while(GetIsObjectValid(oMyObject = GetObjectByTag(sSpawnTag, i++)))
    {
        DestroyObject(oMyObject);
    }
}

// sPlaceTag - waypoint tag
// sSpawnResRef - ResRef of placeable to spawn
// sSpawnTag - new tag of spawned placeable
// fDelay - delay between this function's calls
void LifeDeathCycle(string sPlaceTag, string sSpawnResRef, string sSpawnTag, float fDelay=10.0)
{
    Death(sSpawnTag);
    Life(sPlaceTag, sSpawnResRef, sSpawnTag);

    DelayCommand(fDelay, LifeDeathCycle(sPlaceTag, sSpawnResRef, sSpawnTag, fDelay));
}

void main()
{
    LifeDeathCycle("NO_IS_SPAWN01", "x3_plc_flame001", "MY_SPAWN");
}

If all your waypoints have exactly the same tag, you can (and should - for performance reasons) use GetObjectByTag instead of iterating every object in every area to see if the tag matches. Rationale: there is usually a handful of waypoints versus thousands of other objects. It also allows you to have a single repeating function instead of one (two) per area.

In my script object deletion immediately precedes object creation. You can also call DestroyObject directly for a plot object and it will be gone.

Finally, since you want this to happen during season change, edit LifeDeathCycle to check for month number. If it is 11, call Life, if it is 2, call Death. You will also need a local sentinel variable to make sure these functions are actually called once per year.

1 Like

Unless I missed something, the script will spawn one placeable for every waypoint tagged NO_IS_SPAWN01 in the module, so, for example, if there are 6 waypoints in an area, it will spawn six.

Is that what’s happening?

Sorry if I’ve misunderstood.

Thanks!! Gona try that and see what changes ^^

Yeah i already got the season variable :P.

I have an already working script that does this same thing im trying with the waypoints, but it uses random locations in the area and spawns X placeables depending the area size. I had problems with areas with diferent heights so im trying this method. Dont know why they spawn more than 1 placeable in each waypoint… hope this fixes it!

thanks.

That is is what supposed to be doing, but it spawns a random quantity, form 1 to 4 usually…sometimes i got 12 O.o, i did some log tests and it executes the script like 5 times on each call T.T

Hello!

Copied your code but now seems that nothing is spawning :confused: i just copy pasted everything in an include i have and called the LifeDeathCycle(“NO_IS_SPAWN01”, “x3_plc_flame001”, “MY_SPAWN”); on the module load event.

There was a mistake in that code - ++i instead of i++ - fixed the post (but it shouldn’t cause the code to completely fail).

Just for test, try saving my code as separate script and runscript it manually via DebugMode in an area with the waypoints.

Are you positive that NO_IS_SPAWN01 is the single tag of all your destination waypoints? It must be exactly that, no NO_IS_SPAWN01_1, NO_IS_SPAWN02, etc.

1 Like

Hello!

Ok that change made the placeable spawn. :stuck_out_tongue: you say it shouldnt be only that but atleast now its spawning.

ok had to modify death too, now It works! it only spawns 1!!!

cant figure out why i wast geting 1-4 spawns with my old script T.T

1 Like

My only guess why you ran into issues before is that you had two concurrent scripts: one for spawning things and one for deleting same things. Or perhaps somehow more than 1 loop was started.

If you need to debug, the best thing to do is to fill your script with debug messages, for example - in Life's while loop:

SendMessageToPC(GetFirstPC(), "Spawning near " + GetName(oMyObject));

SpeakString is another way to do it.


By the way, thank you for using the solution button :white_check_mark:.

This is a new feature of this forum and - if I’m not mistaken - your thread is now the first to be marked as SOLVED.

Oh, didnt know that was new. I’m new to the vault from yesterday :smiley: if that works that way its great!

1 Like

That feature has only been added in the past week. As you’re new I’m guessing you haven’t looked in the General Natter section of these forums. There you’ll find a pinned thread called A Short Tour of These Forums that should help you navigate around here (short note to self must add a couple of updates to that thread). While you’re in that section take your time to lookout for other pinned threads. You may find them useful.

TR

1 Like

I generally just use latest list on the right. But what does pinning actually do on this weird forum? The post you referenced is way down the page on general natter when I look, in order by date. Pinning doesn’t seem to do what it does on other forums.

It is explained in that thread :smile_cat:. Hint - if for you it is halfway down the list it means that you have read it at least once.

TR

1 Like

Thanks will look into that ^^