Using User Variables in ZScript?

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
Torterra18
Posts: 5
Joined: Fri Nov 22, 2024 12:30 pm
Preferred Pronouns: He/Him
Operating System Version (Optional): Windows 10

Using User Variables in ZScript?

Post by Torterra18 »

So I've heard about this neat little feature called User Variables, I've seen it being used, I've read about it, it seems useful and versatile and stuff, but the problem is, It seems it is kinda DECORATE only, or maybe I'm just stupid, anyways, what I want to know is how do I use them and define them on ZScript? since I have some actors defined there and I don't want to move them to DECORATE format...
Jarewill
 
 
Posts: 1853
Joined: Sun Jul 21, 2019 8:54 am

Re: Using User Variables in ZScript?

Post by Jarewill »

Zscript allows you to define normal variables and access them directly.
For example you can define a custom integer inside your actor like this:

Code: Select all

Class MyActor : Actor{
	int myvar; //This is a custom integer variable
	Default{
		//Custom variables go outside any blocks like Default{}
	}
	States{
	Spawn:
		TNT1 A 1 A_JumpIf(myvar == 5, "VariableState"); //You can do custom jumps using variables like this
		Loop;
	VariableState:
		TNT1 A 0 {myvar = 0;} //And change them like so, any math function will work here
		Goto Spawn;
	}
}
You can also specify a variable as a user variable by adding this prefix: user_
Doing so will allow you to set that variable in a map editor per thing basis.

ZScript also allows you to do other things with variables that Decorate can't do, such as define them inside weapons (however then you will have to access them with the invoker pointer within states (invoker.myvar)) as well as define them as custom properties, like so:

Code: Select all

Class MyActor : Actor{
	int myvar;
	property MyVariable : myvar; //This is how you define a property
	Default{
		MyActor.MyVariable 5; //And then you can change it like any other
	}
}
Torterra18
Posts: 5
Joined: Fri Nov 22, 2024 12:30 pm
Preferred Pronouns: He/Him
Operating System Version (Optional): Windows 10

Re: Using User Variables in ZScript?

Post by Torterra18 »

Cool, many thanks for the info.
Torterra18
Posts: 5
Joined: Fri Nov 22, 2024 12:30 pm
Preferred Pronouns: He/Him
Operating System Version (Optional): Windows 10

Re: Using User Variables in ZScript?

Post by Torterra18 »

Jarewill wrote: Mon Dec 23, 2024 3:29 pm Zscript allows you to define normal variables and access them directly.
For example you can define a custom integer inside your actor like this:

Code: Select all

Class MyActor : Actor{
	int myvar; //This is a custom integer variable
	Default{
		//Custom variables go outside any blocks like Default{}
	}
	States{
	Spawn:
		TNT1 A 1 A_JumpIf(myvar == 5, "VariableState"); //You can do custom jumps using variables like this
		Loop;
	VariableState:
		TNT1 A 0 {myvar = 0;} //And change them like so, any math function will work here
		Goto Spawn;
	}
}
You can also specify a variable as a user variable by adding this prefix: user_
Doing so will allow you to set that variable in a map editor per thing basis.

ZScript also allows you to do other things with variables that Decorate can't do, such as define them inside weapons (however then you will have to access them with the invoker pointer within states (invoker.myvar)) as well as define them as custom properties, like so:

Code: Select all

Class MyActor : Actor{
	int myvar;
	property MyVariable : myvar; //This is how you define a property
	Default{
		MyActor.MyVariable 5; //And then you can change it like any other
	}
}
I'm quite new to this, so, sorry if it sounds stupid, but is this the correct way to do this?

Code: Select all

	Missile:
		PAI2 C 5 A_FaceTarget;
		PAI2 D 5 BRIGHT A_FaceTarget;
		PAI2 E 5 BRIGHT A_FaceTarget;
		PAI2 E 0 BRIGHT A_DualPainAttack;
		PAI2 A 2 {user_miscount++;}
		PAI2 A 0 A_JumpIf(user_miscount =< 3, "DiceRoll"); //to check if it should repeat the attack
		PAI2 A 0 A_JumpIf(user_miscount == 3, "See"); //the cap to how many times it attacks in a row
		Goto See;
Torterra18
Posts: 5
Joined: Fri Nov 22, 2024 12:30 pm
Preferred Pronouns: He/Him
Operating System Version (Optional): Windows 10

Re: Using User Variables in ZScript?

Post by Torterra18 »

Jarewill wrote: Mon Dec 23, 2024 3:29 pm Zscript allows you to define normal variables and access them directly.
For example you can define a custom integer inside your actor like this:

Code: Select all

Class MyActor : Actor{
	int myvar; //This is a custom integer variable
	Default{
		//Custom variables go outside any blocks like Default{}
	}
	States{
	Spawn:
		TNT1 A 1 A_JumpIf(myvar == 5, "VariableState"); //You can do custom jumps using variables like this
		Loop;
	VariableState:
		TNT1 A 0 {myvar = 0;} //And change them like so, any math function will work here
		Goto Spawn;
	}
}
You can also specify a variable as a user variable by adding this prefix: user_
Doing so will allow you to set that variable in a map editor per thing basis.

ZScript also allows you to do other things with variables that Decorate can't do, such as define them inside weapons (however then you will have to access them with the invoker pointer within states (invoker.myvar)) as well as define them as custom properties, like so:

Code: Select all

Class MyActor : Actor{
	int myvar;
	property MyVariable : myvar; //This is how you define a property
	Default{
		MyActor.MyVariable 5; //And then you can change it like any other
	}
}
Ok so I got a less stupid question this time now, is the syntax(?) here correct? I don't know what's the correct way of doing this.

Code: Select all

	Missile:
		PAI2 C 5 A_FaceTarget;
		PAI2 D 5 BRIGHT A_FaceTarget;
		PAI2 E 5 BRIGHT A_FaceTarget;
		PAI2 E 0 BRIGHT A_DualPainAttack(LostSoulSE);
		PAI2 A 2;
		PAI2 A 0 A_JumpIf(user_miscount == 3, "ClearCheck"); //the cap to how many times it attacks in a row
		PAI2 A 2
		{
			{user_miscount++;};
			A_Jump(200, "ClearCheck");
		}
		Loop;
	ClearCheck:
		PAI2 A 0 {user_miscount = 0;};
		Goto See;
And yes I have already defined it.
Jarewill
 
 
Posts: 1853
Joined: Sun Jul 21, 2019 8:54 am

Re: Using User Variables in ZScript?

Post by Jarewill »

First of all, there exists no such thing as a stupid question.
Being new won't make anything you ask sound stupid so don't worry about that.

The first code block is actually perfect, you only have to change the operator you use from =< to <=.
I call this operator "less or equal to", so maybe that can help with remembering the order.
Then the second jump is not needed because the state will Goto See at the end anyways.
(It will also not trigger because you used the <= operator in the jump above, so it will still pass if the variable is equal to 3)

Now the second will require changing how the last frame is set up.
If you already have brackets open, you don't need to open them again just to change a variable.
Jumps also work differently in anonymous functions, so you will either have to return the jump or split it into 2 frames, depends on preference:

Code: Select all

		//Either this:
		PAI2 A 2
		{
			user_miscount++;
			Return A_Jump(200, "ClearCheck");
		}
		
		//Or this:
		PAI2 A 0 {user_miscount++;}
		PAI2 A 2 A_Jump(200, "ClearCheck");
Now I will also say that you don't need to prefix the variable with user_ unless you really want it to be editable in the map editor, and in your case it doesn't look like that would be needed.
So instead you can just call it miscount.
Post Reply

Return to “Scripting”