Improvements over "Game Over" Zscript Plugin

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!)
User avatar
zvx333
Posts: 22
Joined: Mon Jan 24, 2022 2:51 pm

Improvements over "Game Over" Zscript Plugin

Post by zvx333 »

Hi!

I'm writing a new universal "Game Over" Zscript Plugin.

The idea behind this is that I found out that I prefer having more keys set to let me "continue" my game, instead of just the use key.

The script would load the last saved game if I die, or restart the level.

This is what I have so far:

Code: Select all

class GameOver : EventHandler {

	static const name commands[] =
	{
		"+use",
		"+attack",
		"+altattack",
		"+jump"
	};

	override bool InputProcess(InputEvent e) {
		if (e.Type == InputEvent.Type_KeyDown) {
			SendNetworkEvent("keypress", e.KeyScan);
		}
		return false;
	}

	override void NetworkProcess(ConsoleEvent e) {
		if (e.Name == "keypress") {
			PlayerInfo player = players[consoleplayer];
			PlayerPawn playerPawn = player.mo;
			int key1, key2;
			for (int i = 0; i < commands.size(); i++)
			{
				[key1, key2] = Bindings.GetKeysForCommand(commands[i]);
				if ((key1 && key1 == e.Args[0]) || (key2 && key2 == e.Args[0]))
				{
					if (player.playerstate == PST_DEAD) {
						player.playerstate = PST_REBORN;
					}
				}
			}

		}
	}

}
Before making a release, I'd like more experienced people to tell me if there are some improvements that can be made over this, or if there is something that would probably not work under certain mods or whatever

Thanks in advance!
User avatar
m8f
 
 
Posts: 1440
Joined: Fri Dec 29, 2017 4:15 am
Preferred Pronouns: He/Him
Operating System Version (Optional): Manjaro Linux
Location: Siberia (UTC+7)

Re: Improvements over "Game Over" Zscript Plugin

Post by m8f »

You can use Bindings.getAllKeysForCommand in case somebody has more than two key bindings for a command. Example here.
User avatar
Nash
 
 
Posts: 17386
Joined: Mon Oct 27, 2003 12:07 am
Location: Kuala Lumpur, Malaysia

Re: Improvements over "Game Over" Zscript Plugin

Post by Nash »

Just so everyone knows - the method of eating keys through InputProcess is not perfect - if I were to mash the +use key fast enough, there is a non-zero chance that the input will get through BEFORE InputProcess catches it, therefore resurrecting the player normally (and bypassing or messing up any of your custom scripting).

By "fast enough", I mean simply: just pressing the +use key rapidly and very fast, perhaps moments before actually dying. There is a decent chance that the input command will get through at just the exact tic right after the player's state is changed to be dead.

The only real way to override the behavior of the +use key upon player death is to override a PlayerPawn's DeathThink, which, of course, makes it not universal.
User avatar
zvx333
Posts: 22
Joined: Mon Jan 24, 2022 2:51 pm

Re: Improvements over "Game Over" Zscript Plugin

Post by zvx333 »

Thanks to both of you for your answers.

Here's the updated script, I've also changed the KeyDown for a KeyUp type to prevent accidental firing of weapons

Code: Select all

class GameOver : EventHandler {

	static const name commands[] =
	{
		"+use",
		"+attack",
		"+altattack",
		"+jump"
	};

	override bool InputProcess(InputEvent e) {
		if (e.Type == InputEvent.Type_KeyUp) {
			SendNetworkEvent("keyUp", e.KeyScan);
		}
		return false;
	}

	override void NetworkProcess(ConsoleEvent e) {
		if (e.Name == "keyUp") {
			PlayerInfo player = players[consoleplayer];
			PlayerPawn playerPawn = player.mo;
			for (int i = 0; i < commands.size(); i++)
			{
				if (isKeyForCommand(e.Args[0], commands[i])) {
					if (player.playerstate == PST_DEAD) {
						player.playerstate = PST_REBORN;
					}
				}
			}
		}
	}

	private static bool isKeyForCommand(int key, string command) {
		Array<int> keys;
		bindings.getAllKeysForCommand(keys, command);
		for (int i = 0; i < keys.size(); i++)
		{
		  if (keys[i] == key) return true;
		}
		return false;
	}

}

Return to “Scripting”