Page 1 of 1

Using User Variables in ZScript?

Posted: Mon Dec 23, 2024 2:32 pm
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...

Re: Using User Variables in ZScript?

Posted: Mon Dec 23, 2024 3:29 pm
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
	}
}

Re: Using User Variables in ZScript?

Posted: Mon Dec 23, 2024 4:03 pm
by Torterra18
Cool, many thanks for the info.

Re: Using User Variables in ZScript?

Posted: Mon Dec 23, 2024 4:44 pm
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;

Re: Using User Variables in ZScript?

Posted: Tue Dec 24, 2024 8:12 am
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.

Re: Using User Variables in ZScript?

Posted: Tue Dec 24, 2024 2:27 pm
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.