Start Script After Another Has finished

Ask about ACS, DECORATE, ZScript, or any other scripting questions here!

Moderator: GZDoom Developers

Forum rules
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. If you still don't understand how to use a feature, then ask here.

Please bear in mind that the people helping you do not automatically know how much you know. You may be asked to upload your project file to look at. Don't be afraid to ask questions about what things mean, but also please be patient with the people trying to help you. (And helpers, please be patient with the person you're trying to help!)
Guest

Start Script After Another Has finished

Post by Guest »

I apologize in advance if this is has been asked but there is a boat load of information out here and using search hasn't come up with what I'm looking for. Perhaps I'm not asking it correctly?

I have two questions - for a lot of you I'm sure this is easy but I'm relatively a beginner at coding

Basically I'm looking for script 1 to execute, once it finishes executing, I want script 2 to start. This is basically a "room clearing" event with multiple triggers/actions that happen.

Script 1 (void) /////this happens when I push a switch - this all works correctly
{
Door_Close(5, 128, 0);
Floor_LowerToLowest(8, 16);
Thing_Spawn(6, 1, 0, 0);
Thing_Spawn(8, 5, 0, 0);
Delay(3);
Door_Open (5, 32, 0);
}


script 2 (Void) //////this is what I want to happen after Script 1 completes
{
ACS_ExecuteWait(2, 0, 0, 0, 0);


While(thingcount(6, 0) > 0) /////// - This line and the next line - aren't technically counted until they spawn, because they aren't counted until they spawn, then the door open functions below this don't work
While(Thingcount(8, 0) > 0)

Delay (1);

Door_open(4, 32, 0);
Door_Open(9, 32, 0);
}


Help coding this would be greatly appreciated.

I also have a question about how to make a specific monster (not a whole class of them) drop an item on death.

For example - I have 5 HellKnights in a map - I want only one of them that I designate to drop a blue keycard on death - How exactly would that be scripted? I'm assuming I would have to assign the specific HellKnight a TID

Please go easy on me. I'm sure once the answer is provided it will seem simple to me. Maybe I'm way over thinking it. Although TBH i'm coming from SNAPMAPS on Doom for the PS4 and it was much easier to "code" there lol.

Thank you in advance.
User avatar
Enjay
 
 
Posts: 26874
Joined: Tue Jul 15, 2003 4:58 pm
Location: Scotland

Re: Start Script After Another Has finished

Post by Enjay »

With the scripting question, would it not be better to just use ACS_Execute at the end of script 1 and tell it to run script 2 and miss out the ACS_ExecuteWait (which I don't *think* is set up to wait properly anyway - I never use it) entirely?
Or, given that there doesn't seem to be anything going on that is desperately complicated or needs the code to be separated, why not put it all into one script?

I would also suggest using SpawnSpot, rather than ThingSpawn. ThingSpawn has its uses, and has been around since Hexen was the only ACS game, but it is tied to SpawnID numbers. The various versions of SpawnSpot have more flexibility because they call an actor by name, not an allocated SpawnID. Personally, I like SpawnSpotFacing because it spawns actors facing the direction of the MapSpot where they are being spawned. So, you get to place things in the map rather than having to script the appearance angles.

Also, it seems as if you are trying (oh wow!, I sound like Clippy) to count two groups at the same time. With any of the spawning functions, you can allocate the spawned actors tids as they spawn, and then just count the actors with that tid. So, you could give several different types of monsters the same tid, but count them all in one go.

Suggestion...

Code: Select all

Script 1 (void) /////this happens when I push a switch
{
	Door_Close(5, 128, 0);
	Floor_LowerToLowest(8, 16);
	
	//spawn enemies at tids X or Y and give them tid Z
	SpawnSpotFacing("Arachnotron", X, Z);
	SpawnSpotFacing("Demon", Y, Z);
	
	Delay(3);
	Door_Open (5, 32, 0);

	//Count enemies with tid Z and just wait until they are all gone
	while (thingcount (0, Z))
		{
			Delay (1);
		}

	Door_open(4, 32, 0);
	Door_Open(9, 32, 0);
}
Notes:
I don't know if those are the monster types you want to spawn - they are the ones with SpawnIDs 6 and 8 respectively.
X is the tid of the mapspot where you want Arachnotrons to spawn.
Y is the tid of the mapspot where you want demons to spawn.
Z is the tid that these enemies will be allocated when they spawn.
Substitute X, Y and Z for the actual numbers that you will be using.

You can also use the >0 that you were using too, but, unless otherwise specified, while treats it the same way.

Code: Select all

while (thingcount (0, Z)>0)
[Edit]
Oh, an addition. SpawnSpot does not spawn using a teleport flash. If you want that to happen, just add an instruction to spawn a teleport flash too.

Code: Select all

	SpawnSpot("TeleportFlash", X, 0, 0);
	SpawnSpot("TeleportFlash", Y, 0, 0);
The "0, 0" at the end means that we are not giving the flashes a tid, and we don't care what angle they spawn at because teleport flashes look the same from every angle.
[/edit]

If you do ever need to count things with more than one tid, you can still do it with a single "while". You just join them together with && (and) or ||(or) as appropriate

Code: Select all

while (thingcount (0, A) || thingcount (0, B))
	{
		DoStuffLikeMaybeWaiting;
	}
DoOtherStuff;
A and B would be the tid numbers that you are counting.

If you want to force enemies to spawn, you can use SpawnSpotFacingForced but be careful with it because enemies could spawn stuck in something.

As for the Hellknight dropping a key, you can give actors a special directly. So, in UDB, you can right click the enemy, go to the "Action/Tag/Misc" tab and set it up there. No need for scripting.

This will make a key spawn when the Hell Knight dies. The key will spawn at tid 25, which is also the tid that I gave to the Hell Knight. You will probably want to change that to a different number.

One thing to point out - all this does is spawn a key exactly where the Hell Knight is when it dies. The key just appears. It does not behave like a dropped item (i.e. it doesn't get "tossed out". You can create a cloned Hell Knight in ZScript and give it a dropitem of a blue key and then just use that one in your map instead of a normal Hell Knight for the one where you want the key to be dropped.

Code: Select all

CLASS HellKnightBlueKeyDropper : HellKnight
{
	Default
	{
		DropItem "BlueCard";
	}
}
Then, add a section to your MAPINFO to give it a unique EditNumber that you use to put it into a map:

Code: Select all

DoomEdNums
{
     12345 = HellKnightBlueKeyDropper
}
where 12345 is any unique number that you want to use. I suggest not using 12345. Try to pick something that other people are unlikely to have used.
Then, in UDB use 12345 (or whatever you use) as the edit number to place the modified actor:


Or, if you don't want to give it an edit number, you can just spawn it using one of the SpawnSpot functions - because they use actor names, not SpawnIDs, as I mentioned:

Code: Select all

SpawnSpotFacing("HellKnightBlueKeyDropper", X, Z);
Fortunately keys already have the +DONTGIB flag, which means that they do not get crushed under doors like most dropped items do. Otherwise you'd have to add that too.
Guest

Re: Start Script After Another Has finished

Post by Guest »

THANK YOU! - This worked perfectly. I need to add the teleflash because I do want that in there for aesthetic purposes of course. Also, I was able to combine Script 1 and 2 together instead of making it complicated by trying to run two separate scripts one after the other.

I haven't tried the HellKnight dropping the key card but it seems pretty straight forward with your instructions. I would like to have it "tossed out" on death rather than just magically spawn out of thin air where it dies. Visually, it looks better being "tossed out" rather than spawned. Functionally it does the same thing, either way, when the HK dies, the blue key cards appears, the difference is do you want it spawned or "tossed out."

Thanks again. Much appreciated!
kadubi

Re: Start Script After Another Has finished

Post by kadubi »

There's an ACS function which is called DropItem (https://zdoom.org/wiki/DropItem). You can make the monster execute a script which contains a call to that function to drop the desired item.
User avatar
Enjay
 
 
Posts: 26874
Joined: Tue Jul 15, 2003 4:58 pm
Location: Scotland

Re: Start Script After Another Has finished

Post by Enjay »

kadubi wrote: Wed Feb 26, 2025 2:33 pm There's an ACS function which is called DropItem (https://zdoom.org/wiki/DropItem).
Quite right! I forgot about that one.
So, there are several options for doing this. "Guest" just needs to pick the one that suits them best.

Return to “Scripting”