Spawning items/monsters to random map spots

Archive of the old editing forum
Forum rules
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. This forum is archived - please use this set of forums to ask new questions.
Dave_B
Posts: 54
Joined: Tue Jun 08, 2010 8:20 am

Spawning items/monsters to random map spots

Post by Dave_B »

I've spent half the day wracking my brain trying to get this to work. What I'm trying to do is spawn a smaller set of monsters and items to a larger set of map spots randomly, with the purpose of having not only each monster/item spawn from a different map spot each time the map loads, but without having each map spot being used more than once. The current script I'm trying spawns an item to a randomly selected map spot, which works, but it seems to be spawning items more than once to each map spot. How do I stop it from doing this? How do I get the script to pick a random number only once?

Thanks.
User avatar
corysykes
Posts: 329
Joined: Mon May 07, 2007 6:03 pm
Location: Location i have no Location

Re: Spawning items/monsters to random map spots

Post by corysykes »

Post your current script then people can help.
User avatar
cocka
Posts: 1520
Joined: Sat Jul 02, 2011 7:21 am
Location: Hungary

Re: Spawning items/monsters to random map spots

Post by cocka »

Gosh! That was a bit confusing. Now I see what you want.

Here is the solution:

http://forum.zdoom.org/viewtopic.php?f= ... 37#p680914

Instead of kapcsolok, you can use any arrayname you want.
Dave_B
Posts: 54
Joined: Tue Jun 08, 2010 8:20 am

Re: Spawning items/monsters to random map spots

Post by Dave_B »

I could try implementing an array, in fact I was thinking about doing that, but here's the code anyway, I'd rather keep things as simple as possible:

Code: Select all

script 2 (void) 
    {
    spawnvile=(random(2,49));
    Thing_Spawn(spawnvile,T_VILE,0,666);
    acs_execute(7,0,0,0,0);
    spawncount=spawncount + 1;
    if (spawncount == 8 ){
        terminate;
            }
        else {
        restart;
            }
        }
As you can see, the script is written to spawn eight Archviles to randomly chosen map spots tagged between the numbers 2 to 49. Of course, it works, but the number it actually spawns varies between six and eight every time the map is loaded. I suspect this is due to the script attempting to spawn more than one monster to the same map spot at the same time, as I've noticed this is happening with the items and ammo random spawn scripts. I need it to spawn one monster to one map spot only.

Basically, I would like the script to pick a number from within the specified range, spawn a monster at the map spot with the selected tag number, and then remove the tag number from the number range.
User avatar
cocka
Posts: 1520
Joined: Sat Jul 02, 2011 7:21 am
Location: Hungary

Re: Spawning items/monsters to random map spots

Post by cocka »

I suspect this is due to the script attempting to spawn more than one monster to the same map spot at the same time
Yes, exactly. Thing_Spawn won't spawn monster to the mapspot where there has already been another thing.

Now let's see how we can benefit from my linked function.

In this case you have a range from 2 and 49. The number of elements can be calculated like this: elements = lasttag-firsttag+1

So if you have an arithmetic sequence you can apply this function easily.

Code: Select all

#define arraysize 48 
int mapspots[arraysize]; // as this is a map array you always have to define its size, but if you don't want to do this, you can use arrays from libraries, so you don't need to define it in advance.

function void upload(int elements /* you don't need this if you use a dynamic array invoked from a library */, int firsttag, int lasttag)
{
 /* int elements = lasttag-firsttag+1; only if you use it from library */
 int tal;
 int k = firsttag - 1 ;
 if(elements <= lasttag)
 {
   mapspots[k] = random(firsttag, lasttag);
   for(int i = 1; i<elements; i++)
   {
     do
     {
       tal = 0;
       mapspots[i+k] = random(firsttag, lasttag);
       for(int j = k; j<i+k; j++)
       {
         if(mapspots[j] == mapspots[i+k])
         {
           tal = 1;
         }
       }
     }while(tal == 1);
   }
 }
}
Then you have to modify your script 2 like this:

Code: Select all

script 2 (void)
{
	upload(arraysize, 2, 49);
	for(spawncount = 0; spawncount < 8; spawncount++)
	{
		for(int i = 0; i<arraysize; i++)
		{
		Thing_Spawn(mapspots[i],T_VILE,0,666+i);
		}
		acs_execute(7,0,0,0,0);
	}
}
User avatar
cocka
Posts: 1520
Joined: Sat Jul 02, 2011 7:21 am
Location: Hungary

Re: Spawning items/monsters to random map spots

Post by cocka »

Oh, I think this is not the correct one, but you can modify it like this:

Code: Select all

script 2 (void)
{
   upload(arraysize, 2, 49);
      for(spawncount = 0; spawncount<8; spawncount++)
      {
      Thing_Spawn(mapspots[spawncount],T_VILE,0,666+spawncount);
      }
      acs_execute(7,0,0,0,0);  // By the way, why do you need to run script 7 eight times? 
}
Additional info to this line:

Code: Select all

int k = firsttag - 1 ;


If you use an array without a size in a library , then this is the correct form, because (I guess) within signed integer range you can specify any large value as the size of an array. But if you use this in a map array you should give a large number as the size of array lest you would run out of array space.

Otherwise you should use this:

Code: Select all

int k = 0; 
Dave_B
Posts: 54
Joined: Tue Jun 08, 2010 8:20 am

Re: Spawning items/monsters to random map spots

Post by Dave_B »

I'm not using libraries at all. Would you be able to rewrite it so that excludes library references? Thanks
Dave_B
Posts: 54
Joined: Tue Jun 08, 2010 8:20 am

Re: Spawning items/monsters to random map spots

Post by Dave_B »

Sorry, forget about the last message, I've implemented it and it works :D thanks for that. Now I'll try to do the same for ammo and health.
User avatar
cocka
Posts: 1520
Joined: Sat Jul 02, 2011 7:21 am
Location: Hungary

Re: Spawning items/monsters to random map spots

Post by cocka »

The only drawback is that you cannot see where and what has been spawned at the same time.

The first script 2 spawns monsters on all the 48 mapspots eight times. :lol: So it's obviously wrong.

And what does the script 7 do? Because if it runs eight times then you have to consider whether it is running at the time when the loop reaches it again.

And another question: How many times do you want to run script 2? Because every time when the script 2 runs it'll upload the array again with new values. So you should decide whether it is necessary or not.
User avatar
cocka
Posts: 1520
Joined: Sat Jul 02, 2011 7:21 am
Location: Hungary

Re: Spawning items/monsters to random map spots

Post by cocka »

So when you want to upload the array only once during the whole game, then:

Code: Select all

int once;
script 2 (void)
{
if(once == 0)
{
 once = 1;
 upload(arraysize, 2, 49);
}
// the rest of the code
}
Dave_B
Posts: 54
Joined: Tue Jun 08, 2010 8:20 am

Re: Spawning items/monsters to random map spots

Post by Dave_B »

Script 7 simply checks the number of monsters in the map and executes accordingly, so it isn't needed there anymore
Dave_B
Posts: 54
Joined: Tue Jun 08, 2010 8:20 am

Re: Spawning items/monsters to random map spots

Post by Dave_B »

cocka wrote:The only drawback is that you cannot see where and what has been spawned at the same time.

The first script 2 spawns monsters on all the 48 mapspots eight times. :lol: So it's obviously wrong.

And what does the script 7 do? Because if it runs eight times then you have to consider whether it is running at the time when the loop reaches it again.

And another question: How many times do you want to run script 2? Because every time when the script 2 runs it'll upload the array again with new values. So you should decide whether it is necessary or not.
Script 2 should run every time the map loads. Every time the map is loaded it should spawn monsters to randomly selected map spots.
User avatar
cocka
Posts: 1520
Joined: Sat Jul 02, 2011 7:21 am
Location: Hungary

Re: Spawning items/monsters to random map spots

Post by cocka »

Every time the map is loaded it should spawn monsters to randomly selected map spots.
Then you might have used OPEN script instead of a simple void one.
Dave_B
Posts: 54
Joined: Tue Jun 08, 2010 8:20 am

Re: Spawning items/monsters to random map spots

Post by Dave_B »

So now that I've got this working, can I duplicate the script and use it to spawn other things, i.e. ammo, health, etc?
User avatar
cocka
Posts: 1520
Joined: Sat Jul 02, 2011 7:21 am
Location: Hungary

Re: Spawning items/monsters to random map spots

Post by cocka »

to spawn other things, i.e. ammo, health, etc?
To the other mapspots or where to? Well, just think it over what we have done so far. :D

You should rewrite this part of the script:

Code: Select all

for(spawncount = 0; spawncount<8; spawncount++)
{
 Thing_Spawn(mapspots[spawncount],T_VILE,0,666+spawncount);
}
In this case you get the first eight random values from the mapspots array. So the script randomly chooses eight different mapspots.
Now, if you want to spawn other things on the rest of the places you can simply modify the indices and the spawn number(type).

Example (you place eight medikits on another eight different mapspots):

Code: Select all

for(spawncount = 8; spawncount<16; spawncount++)
{
 Thing_Spawn(mapspots[spawncount],T_MEDKIT,0,666+spawncount);
}
You can also randomize what to spawn, but as far as I don't know what you want to spawn, I cannot help you for the moment. Later you can generalize your script accordingly.
Locked

Return to “Editing (Archive)”