Zdoom Scripting Help

Ask about ACS, DECORATE, ZScript, or any other scripting questions here!
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!)
walterpires
Posts: 1
Joined: Wed Apr 16, 2025 3:05 am
Preferred Pronouns: He/Him
Operating System Version (Optional): macOS 12.5
Graphics Processor: ATI/AMD (Modern GZDoom)

Zdoom Scripting Help

Post by walterpires »

Hello sprunki phase 4,
I want to lower a sector from 128 to -64 when the player kills four enemies. I don't know how to put the script together to accomplish this. I'm using DB2 btw. I am somewhat familiar with scripting. I can spawn enemies to a mapspot. Any help would be appreciated.
Last edited by walterpires on Fri May 30, 2025 12:11 pm, edited 1 time in total.
Heisanevilgenius
Posts: 123
Joined: Wed Dec 15, 2021 8:38 pm
Graphics Processor: nVidia (Modern GZDoom)

Re: Zdoom Scripting Help

Post by Heisanevilgenius »

I think the easiest way is to give the enemies a special to activates a script when they die. Maybe use ACS_ExecuteAlways in case two enemies die simultaneously. The script should add 1 to a variable to keep track of how many have died, like:

Code: Select all


int deadguys; //(number of enemies that have been killed)

script 1 (void)
{
  deadguys++;
  if (deadguys>=4) { // (If 4 or more enemies have been killed, lower the floor)
    Floor_LowerByValue (etc)
  }
}
Alternatively, you can have a script count how many enemies with a specific TID are left with ThingCount.
User avatar
Enjay
 
 
Posts: 27627
Joined: Tue Jul 15, 2003 4:58 pm
Location: Scotland

Re: Zdoom Scripting Help

Post by Enjay »

There are many ways to do it. It is, of course, possible and perfectly acceptable to give the enemies a special to run the script as Heisanevilgenius suggests (and I have done it myself many times). And, yes, ACS_ExecuteAlways is important because if two enemies die at the same time, the script would only get run for one of them and the count would mess up if you didn't use the "always" version.

In many cases, however, I prefer to start a script to count enemies and have it running in the background before the relevant fight starts. That way, you don't need to give specials to the enemies (though you may need to give them tids/tags). You can count enemies by their tid (my preference) or by their SpawnID, provided they have a SpawnID (which custom enemies may not), or you can use ThingCountName to count things by their actor type.

Counting in this way also often has the added benefit of working when you are testing using the -nomonsters parameter as the counting will be satisfied and the map can progress. If enemies are running the script when they die, they need to be present for the script to work. With -nomonsters, there are no enemies, so as soon as the following script runs, the conditions for progression are met and things continue as if you had killed the required bad guys.

Anyway, with a script like this, you can count the enemies that meet certain criteria (in this case, having a tid of 1), and do stuff when the count reduces to a certain point.

Heisanevilgenius' suggestion is counting kills - and things are done when they increase to a required point. The alternative (below) is starting off counting living enemies and not doing anything until the number of living enemies (who meet the required parameters) have dropped below a certain value. Different approach, but same end result.

The attached is just a simple example along the lines of your request. I wasn't sure if when you said you wanted to kill four enemies if that meant there were only four to be killed in the whole group, or if there was a larger group and killing four was enough to start the platform lowering.

Anyway, the attached does the latter.

Code: Select all

//this script is run when the player opens the door
Script 1 (void)
{
	//open the door
	Door_Open(1, 32, 0);

	//count actors with tid of 1
	//as long as there are more than 4, we just wait
	While(ThingCount(0, 1)>4)
	{
		delay(8);
	}

	//there are now 4 or fewer enemies with tid 1, so we do this
	Floor_LowerToLowest(2, 8);
}
When you use the door, the script opens it and starts counting things with a tid/tag of 1. In the second room there are eight imps, each of which has a tid of 1. As long as there are more than four imps, the script just stays in the while loop running the delay. As soon as the number of enemies with a tid of 1 drops to four or fewer, the script progresses and does the next thing (in this case, lowering a floor).

You can obviously change the conditions for the thingcount using standard operators and different values. There are many more things that you can do too (e.g. add in a check for the difficulty setting of the game and change the requirements based on that). It all depends on exactly how you want to be counting enemies, how many there are of each type on the map and so on.

So, Heisanevilgenius' suggestion may suit you, this may suit you, or something else may be even better. It all depends on what you need and your preferences.
You do not have the required permissions to view the files attached to this post.

Return to “Scripting”