How to change actors from ZScript menus (ui scope) ?

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 a reply

Smilies
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :geek: :ugeek: :!: :?: :idea: :arrow: :| :mrgreen: :3: :wub: >:( :blergh:
View more smilies

BBCode is OFF
Smilies are ON

Topic review
   

Expand view Topic review: How to change actors from ZScript menus (ui scope) ?

Re: How to change actors from ZScript menus (ui scope) ?

by Blue Shadow » Thu Dec 07, 2017 5:20 pm

Use [wiki]A_SetHealth[/wiki]. It handles everything for you.

Re: How to change actors from ZScript menus (ui scope) ?

by Graf Zahl » Thu Dec 07, 2017 7:39 am

In short: Both must be the same. This all is just historic bad design on id's part and cannot be changed for various technical reasons.

Re: How to change actors from ZScript menus (ui scope) ?

by krokots » Thu Dec 07, 2017 5:53 am

Graf Zahl wrote:You also need to adjust the PlayerPawn's health to make it have an effect.
Cool, I made it work, but I'm still not sure what the hell is going on.

Code: Select all

Class GEventHandlers : EventHandler
{
	
	override void NetworkProcess(ConsoleEvent e)
	{
		int playerNumber = e.Player;
		let plr = players[playerNumber].mo;
		
		if(plr)
		{
			if (e.Name == "TestNetEvent")
			{
				Console.Printf(e.Name.." called by player : "..playerNumber);
				plr.Health++;
				players[playerNumber].Health++;
			}
			else
			{
				Console.Printf("Invalid event");			
			}		
		}
	}
}
So there is "PlayerInfo" and "PlayerInfo.mo" which is "PlayerPawn". "PlayerPawn" is just an Actor, so if I want to change health obviously I need to change Actor's health variable. But I see that player's health calculations are based on "PlayerInfo's" health, not Actor's health ? Doomguy dies if his PlayerInfo health drops below 0, not his PlayerPawn's health. I'm probably making this more coplicated than it is.

Re: How to change actors from ZScript menus (ui scope) ?

by Graf Zahl » Thu Dec 07, 2017 4:40 am

You also need to adjust the PlayerPawn's health to make it have an effect.

Re: How to change actors from ZScript menus (ui scope) ?

by krokots » Thu Dec 07, 2017 4:28 am

OK Just to be sure if I'm making this correctly (the easiest example possible) :

This is the custom event handler :

Code: Select all

Class GEventHandlers : EventHandler
{
	
	override void NetworkProcess(ConsoleEvent e)
	{
		int playerNumber = e.Player;
		let plr = players[playerNumber].mo;
		
		if(plr)
		{
			if (e.Name == "TestNetEvent")
			{
				Console.Printf(e.Name.." called by player : "..playerNumber);
				Console.Printf(plr.GetClassName());
				Console.Printf("Before : "..plr.Health);
				//plr.health++;	//health is not updating properly
				plr.A_SetInventory("Shotgun", 1);
				Console.Printf("After : "..plr.Health);
			}
			else
			{
				Console.Printf("Invalid event");			
			}		
		}
	}
}
And this is menu :

Code: Select all

Class TMenu : ListMenu
{
	Actor plr;
	override void Init(Menu parent, ListMenuDescriptor desc)
	{
		//plr = players[consoleplayer].mo;
		GEventHandlers.SendNetworkEvent("TestNetEvent",1,0,0);
		Super.Init(parent, desc);
	}
}
It works for player getting an item, but not for health. When I change health, console output from event shows it has changed, but in the HUD it is not changing (eg. I have 100 health and open the menu, the Console.printf("After : "..plr.health) prints 101 but HUD says 100).

Re: How to change actors from ZScript menus (ui scope) ?

by Graf Zahl » Thu Dec 07, 2017 3:44 am

... not to mention if we actually do C/S with real decoupling of play and UI state. This could even have some real benefits on single player because both systems could run on different threads. In that case all the UI would have is a read-only snapshot of the last calculated play frame and any modification of it would write into the void.

Re: How to change actors from ZScript menus (ui scope) ?

by dpJudas » Thu Dec 07, 2017 3:36 am

The blocking is actually very intentional. Without it, you'd accidentally do stuff that doesn't work and be essentially screwed the day you decide to add multiplayer support to your mod. For what its worth, some game engines are even more annoying where you can't even read directly from the play state in ui code.

Re: How to change actors from ZScript menus (ui scope) ?

by Nash » Thu Dec 07, 2017 2:32 am

Graf Zahl wrote:BTW, in games like Quake or Quake 2, everything had to be explicitly routed through the C/S protocol.
I take comfort in knowing that all this zealous blocking is also how other games do it. :mrgreen:

(Not a sarcastic remark; I really mean that in a positive way)

Re: How to change actors from ZScript menus (ui scope) ?

by Graf Zahl » Thu Dec 07, 2017 2:01 am

The only way to do this is through a network event. The reason is that changing play data directly from the menu not only can cause network/demo desyncs but in case of perfectly implemented C/S wouldn't necessarily even exist on the same machine, except for a mirrored read-only copy of the play data.

BTW, in games like Quake or Quake 2, everything had to be explicitly routed through the C/S protocol.

Re: How to change actors from ZScript menus (ui scope) ?

by ZippeyKeys12 » Wed Dec 06, 2017 10:14 pm

Look at events [wiki=Events_and_handlers]here[/wiki]. If you don't understand it, I can try and write an example.

How to change actors from ZScript menus (ui scope) ?

by krokots » Wed Dec 06, 2017 5:42 pm

Let's say I want to make a menu which increases player health on open :

Code: Select all

class TMenu : ListMenu
{
	Actor plr;
	override void Init(Menu parent, ListMenuDescriptor desc)
	{
		plr = players[consoleplayer].mo;
		if(plr)
			plr.health++;
		Super.Init(parent, desc);
	}
}
Unfortunately it can't be done in this way cause the UI scope of Menu class. So how can I do this?

Top