Disable COOP Respawn (Revive Only)

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!)
Post Reply
User avatar
ZDL_800
Posts: 448
Joined: Wed May 15, 2019 3:06 am

Disable COOP Respawn (Revive Only)

Post by ZDL_800 »

Hello.

Can I ask how do you completely disable COOP respawn in GZDoom applications?

We have a problem with an RPG mod which breaks the health stats when you respawn, you start with 48 health, and basically when you die, you respawn with 100 so it breaks.

We have a decent revive mod that works and fixes the issue but I need to disable COOP respawn.

I have searched online and found no answer to this, please help.

Thankyou for your time and hope to speak soon.
User avatar
StroggVorbis
Posts: 866
Joined: Wed Nov 08, 2017 4:23 pm
Graphics Processor: nVidia with Vulkan support
Location: Germany

Re: Disable COOP Respawn (Revive Only)

Post by StroggVorbis »

Try to enable DMFlags2 16384 (No Respawn) and set AlwaysApplyDMFlags in console to 1. This makes deathmatch only flags apply to singleplayer and coop too.
User avatar
ZDL_800
Posts: 448
Joined: Wed May 15, 2019 3:06 am

Re: Disable COOP Respawn (Revive Only)

Post by ZDL_800 »

Hello and thankyou for the reply.

Can I ask is that the only way to disable respawn? The only way to disable the parameter is by console commands? The problem is we are releasing this update for the mod and console commands might be difficult for some users.

We had a talk and we think locking respawn out will be too difficult so I have another idea for Coop.

Could it be possible to respawn with 1% health and remove lets say for example 100 mana from the players inventory in COOP mode? Also can I ask could this be possible with scripts?

Basically the mana in this mod is an 'Ammotype' string so could we remove a set amount of Ammotype upon respawn as a penalty?

Thankyou for your time and hope to speak soon.
User avatar
Matt
Posts: 9696
Joined: Sun Jan 04, 2004 5:37 pm
Preferred Pronouns: They/Them
Operating System Version (Optional): Debian Bullseye
Location: Gotham City SAR, Wyld-Lands of the Lotus People, Dominionist PetroConfederacy of Saudi Canadia
Contact:

Re: Disable COOP Respawn (Revive Only)

Post by Matt »

In ZScript you can create a custom player pawn that overrides the DeathThink function so that all the press-use-to-respawn stuff is ignored.

But it's also possible to prevent the player from dying entirely by overriding the playerpawn's DamageMobj function so that the actual applied damage is always less than the player's actual health. An incapacitated player can then either be a morph, or forced every tick to select a certain weapon and shrink down in size to a crumpled mess or something.


For changing stuff for respawn, that first linked page also has this function. It's a good idea before going further to poke around on that page for a bit to get an idea of what else is possible.
Last edited by Matt on Tue Aug 20, 2019 11:50 am, edited 1 time in total.
User avatar
Void Weaver
Posts: 724
Joined: Thu Dec 18, 2014 7:15 am
Contact:

Re: Disable COOP Respawn (Revive Only)

Post by Void Weaver »

Imho, Matt's advice do override P_DeathThink (from this thread) is the best way to disable\modify respawn function:

Code: Select all

override void DeathThink()
    {
        if(player)player.cmd.buttons&=~BT_USE;
        super.DeathThink();
    } 
Ofc it is ZScript.
Ninjad by Matt. :)
User avatar
ZDL_800
Posts: 448
Joined: Wed May 15, 2019 3:06 am

Re: Disable COOP Respawn (Revive Only)

Post by ZDL_800 »

Hello and thankyou very much for the replies.

After reading the links on the scripts, I literally cannot figure this out? This is way beyond my capabilities.

The theory is to update the resurrect pk3 with the new parameters, there's a zscript located in the file.

The coop resurrect mod works fine, when you revive a player they start with 1 health. The issue is with players not revived and just respawning.

So basically if all players die or a player cannot revive the deadplayer, then you have the option of pressing any key to respawn which would remove 50 of each Ammotype, 'RedMana' GreenMana and 'BlueMana' and start you again with 1 health.

Here is the Zscript for the resurrect mod.

Code: Select all

version "2.4"

class ResurrectHandler : EventHandler
{
	bool isFrozen[MAXPLAYERS];
	int frozenTime[MAXPLAYERS];
	int resurrectTarget[MAXPLAYERS];
	int resurrectTime;

	override void NetworkProcess(ConsoleEvent e)
	{
		Actor player = getTriggerer(e.Player);
		if (!deathmatch && !isFrozen[player.PlayerNumber()] && e.Name == "DoResurrect")
		{
			
			resurrectBestTarget(player);
		}
		Super.NetworkProcess(e);
	}
	
	override void WorldTick()
	{
		for (int i=0; i<MAXPLAYERS; i++)
		{
			if (isFrozen[i]) countdownFreeze(i);
		}
		Super.WorldTick();
	}
	
	Actor getTriggerer(int playerNumber)
	{
		int pn = playerNumber >= 0 ? playerNumber : consoleplayer;
		Actor player = players[playerNumber].mo;
		return player;
	}
	
	void resurrectBestTarget(Actor player)
	{
		for (int i=0; i<MAXPLAYERS;i++)
		{
			
			Actor target = player.GetPointer(AAPTR_PLAYER1<<i);
			resurrectIfValid(player,target);
		}
	}
	
	void resurrectIfValid(Actor player, Actor target)
	{
		if (target && player.PlayerNumber() != target.PlayerNumber() && player.Distance3D(target) <= 55)
		{
			beginResurrection(player,target);
		}
	}
	
	void beginResurrection(Actor player, Actor target)
	{
		resurrectTime = CVar.FindCVar("resurrect_seconds").GetInt() * 35;
		printNotification("$MSG_STARTED_RESURRECT",player,target.Player.getUserName());
		freezePlayer(player,target);
	}
	
	void freezePlayer(Actor player, Actor target)
	{
		player.Player.cheats += CF_FROZEN;
		resurrectTarget[player.PlayerNumber()] = target.PlayerNumber();
		isFrozen[player.PlayerNumber()] = true;
	}
	
	void countdownFreeze(int playerNumber)
	{
		if (frozenTime[playerNumber] == resurrectTime)
		{
			Actor player = players[playerNumber].mo;
			Actor target = players[resurrectTarget[playerNumber]].mo;
			finishResurrection(player,target);
		}
		frozenTime[playerNumber]++;
	}
	
	void finishResurrection(Actor player, Actor target)
	{
		unfreezePlayer(player);
		performResurrection(target);
		printNotification("$MSG_FINISHED_RESURRECT",player,target.Player.getUserName());
	}
	
	void unfreezePlayer(Actor player)
	{
		frozenTime[player.PlayerNumber()] = 0;
		isFrozen[player.PlayerNumber()] = false;
		player.Player.cheats -= CF_FROZEN;
	}
	
	void performResurrection(Actor target)
	{
		target.Player.Resurrect();
		target.A_Pain();
		int life = CVar.FindCVar("resurrect_life").GetInt();
		target.A_SetHealth(life);
	}
	
	void printNotification(String localString, Actor player, String targetName)
	{
		String msg = StringTable.Localize(localString);
		player.A_Log("\cl"..targetName..msg..player.Player.GetUserName()..".");
	}
}
Can I ask would it be possible to edit this Zscript and apply the custom respawn parameters? This is extremely complicated indeed. Any help would be greatly appreciated as this would truly fix the coop issues.

Thankyou for your time and hope to speak soon.
User avatar
ZDL_800
Posts: 448
Joined: Wed May 15, 2019 3:06 am

Re: Disable COOP Respawn (Revive Only)

Post by ZDL_800 »

Hello.

We cannot figure this out? I literally do not know how to remove a set amount of an ammotype? I cannot find any sort of strings?

I did find this to remove half of your ammo but how do you remove a set amount example 50 from each Ammotype?

Code: Select all

					if (sv_cooploseammo) 
 					{ 
 						item.Amount = defitem.Amount; 
 					} 
 					else if (item.Amount > 1) 
 					{ 
 						item.Amount = MAX(item.Amount / 2, defitem.Amount); 
 					} 
So would it be allocated like this?

Code: Select all

	override void DeathThink()
    {
        if(player)player.cmd.buttons&=~BT_USE;
        super.DeathThink();				
        if (sv_cooploseammo) 
 					{ 
 						item.Amount = defitem.Amount; 
					} 
 					else if (item.Amount > 1) 
 					{ 
 						item.Amount = MAX(item.Amount / 2, defitem.Amount); 
 					} 
Searched online for over a week now and cannot find any code which could remove a set amount of an ammotype on respawn.

Can anyone help us please?

Thanks again.
Last edited by ZDL_800 on Mon Sep 09, 2019 10:03 am, edited 1 time in total.
User avatar
ZDL_800
Posts: 448
Joined: Wed May 15, 2019 3:06 am

Re: Disable COOP Respawn (Revive Only)

Post by ZDL_800 »

Hello.

Any assistance would be brilliant as this update would fix many Coop games which break in coop.

Thanks again.
User avatar
Matt
Posts: 9696
Joined: Sun Jan 04, 2004 5:37 pm
Preferred Pronouns: They/Them
Operating System Version (Optional): Debian Bullseye
Location: Gotham City SAR, Wyld-Lands of the Lotus People, Dominionist PetroConfederacy of Saudi Canadia
Contact:

Re: Disable COOP Respawn (Revive Only)

Post by Matt »

Would it work to put an A_TakeInventory in the playerpawn's Die() override?

e.g.

Code: Select all

override void Die(actor source,actor inflictor,int dmgflags,name MeansOfDeath){
    A_TakeInventory("Clip",50);
    ...
    super.Die(source,inflictor,dmgflags,meansofdeath); 
User avatar
ZDL_800
Posts: 448
Joined: Wed May 15, 2019 3:06 am

Re: Disable COOP Respawn (Revive Only)

Post by ZDL_800 »

Hello and thankyou for the reply.

This is complicated indeed, can I ask could the code snippet be updated into the zscript resurrect mod? I'm not sure if this would work correctly?

Code: Select all

version "2.4"

class ResurrectHandler : EventHandler
{
   bool isFrozen[MAXPLAYERS];
   int frozenTime[MAXPLAYERS];
   int resurrectTarget[MAXPLAYERS];
   int resurrectTime;

   override void NetworkProcess(ConsoleEvent e)
   {
      Actor player = getTriggerer(e.Player);
      if (!deathmatch && !isFrozen[player.PlayerNumber()] && e.Name == "DoResurrect")
      {
         
         resurrectBestTarget(player);
      }
      Super.NetworkProcess(e);
   }
   
   override void WorldTick()
   {
      for (int i=0; i<MAXPLAYERS; i++)
      {
         if (isFrozen[i]) countdownFreeze(i);
      }
      Super.WorldTick();
   }
   
   Actor getTriggerer(int playerNumber)
   {
      int pn = playerNumber >= 0 ? playerNumber : consoleplayer;
      Actor player = players[playerNumber].mo;
      return player;
   }
   
   void resurrectBestTarget(Actor player)
   {
      for (int i=0; i<MAXPLAYERS;i++)
      {
         
         Actor target = player.GetPointer(AAPTR_PLAYER1<<i);
         resurrectIfValid(player,target);
      }
   }
   
   void resurrectIfValid(Actor player, Actor target)
   {
      if (target && player.PlayerNumber() != target.PlayerNumber() && player.Distance3D(target) <= 55)
      {
         beginResurrection(player,target);
      }
   }
   
   void beginResurrection(Actor player, Actor target)
   {
      resurrectTime = CVar.FindCVar("resurrect_seconds").GetInt() * 35;
      printNotification("$MSG_STARTED_RESURRECT",player,target.Player.getUserName());
      freezePlayer(player,target);
   }
   
   void freezePlayer(Actor player, Actor target)
   {
      player.Player.cheats += CF_FROZEN;
      resurrectTarget[player.PlayerNumber()] = target.PlayerNumber();
      isFrozen[player.PlayerNumber()] = true;
   }
   
   void countdownFreeze(int playerNumber)
   {
      if (frozenTime[playerNumber] == resurrectTime)
      {
         Actor player = players[playerNumber].mo;
         Actor target = players[resurrectTarget[playerNumber]].mo;
         finishResurrection(player,target);
      }
      frozenTime[playerNumber]++;
   }
   
   void finishResurrection(Actor player, Actor target)
   {
      unfreezePlayer(player);
      performResurrection(target);
      printNotification("$MSG_FINISHED_RESURRECT",player,target.Player.getUserName());
   }
   
   void unfreezePlayer(Actor player)
   {
      frozenTime[player.PlayerNumber()] = 0;
      isFrozen[player.PlayerNumber()] = false;
      player.Player.cheats -= CF_FROZEN;
   }
   
   void performResurrection(Actor target)
   {
      target.Player.Resurrect();
      target.A_Pain();
      int life = CVar.FindCVar("resurrect_life").GetInt();
      target.A_SetHealth(life);
   }
   
   void printNotification(String localString, Actor player, String targetName)
   {
      String msg = StringTable.Localize(localString);
      player.A_Log("\cl"..targetName..msg..player.Player.GetUserName()..".");
   }

   override void Die(actor source,actor inflictor,int dmgflags,name MeansOfDeath)
   {
    A_TakeInventory("Redmana",50);
    A_TakeInventory("Bluemana",50);
    A_TakeInventory("Greenmana",50);
    super.Die(source,inflictor,dmgflags,meansofdeath);
   }
}
The theory is to edit the resurrect mod zscript and add the update to remove an ammotype amount. Does this look ok?

Thanks again.
User avatar
Matt
Posts: 9696
Joined: Sun Jan 04, 2004 5:37 pm
Preferred Pronouns: They/Them
Operating System Version (Optional): Debian Bullseye
Location: Gotham City SAR, Wyld-Lands of the Lotus People, Dominionist PetroConfederacy of Saudi Canadia
Contact:

Re: Disable COOP Respawn (Revive Only)

Post by Matt »

Ugh, resurrect.

Is there any chance that this could be done by having the player respawn and warp to their corpse?
User avatar
ZDL_800
Posts: 448
Joined: Wed May 15, 2019 3:06 am

Re: Disable COOP Respawn (Revive Only)

Post by ZDL_800 »

Hello and thanks for the reply.

No that's not right, otherwise what's the point of reviving a player if you could respawn next to your corpse anyway?

How can the code update be implemented into the resurrect mod?

Does the script look ok to you?

Thanks again.
User avatar
Matt
Posts: 9696
Joined: Sun Jan 04, 2004 5:37 pm
Preferred Pronouns: They/Them
Operating System Version (Optional): Debian Bullseye
Location: Gotham City SAR, Wyld-Lands of the Lotus People, Dominionist PetroConfederacy of Saudi Canadia
Contact:

Re: Disable COOP Respawn (Revive Only)

Post by Matt »

A script can look ok to me but still require 4 hours of debugging once I put it in, or it could work flawlessly immediately, so.... it looks ok to me.
User avatar
Void Weaver
Posts: 724
Joined: Thu Dec 18, 2014 7:15 am
Contact:

Re: Disable COOP Respawn (Revive Only)

Post by Void Weaver »

Maybe fixed version are already located in the origin thread?
User avatar
ZDL_800
Posts: 448
Joined: Wed May 15, 2019 3:06 am

Re: Disable COOP Respawn (Revive Only)

Post by ZDL_800 »

Hello Void Weaver and thanks for the reply.

The actual resurrect mod works fine and the link you provided is the mod we use here.

We wanted to add a new rule so that if a player presses any key to respawn back to the nearest waypoint theres a penalty for that action, which would remove ammo and start you with low health.

The main problem is that for example Brutal Hexen don't start players at 100 health, you have to level up your health to reach 100+ so the resurrect mod breaks the game upon respawn.

To fix this, we need to make sure when a player respawns to the nearest waypoint instead of revive, you don't start back with 100 health, but respawn you with example 10 health and remove ammo also as a penalty.

If a player revives you it shouldn't remove ammo but again bring the player back with 10 health to not break the RPG elements.

This is complicated indeed but its the only way I see to fix coop. Also theres other GZDoom mods which break in coop and this fix would work with other mods also.

So just to recap.

1. Player respawns at nearest waypoint = Health 10 and remove 50 ammo << This is the update we request help with
2. Player is revived = Health 10 << This works fine

Thanks again
Post Reply

Return to “Scripting”