Using User Variables in ZScript?
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!)
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!)
-
- 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?
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?
Zscript allows you to define normal variables and access them directly.
For example you can define a custom integer inside your actor like this:
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:
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;
}
}
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
}
}
-
- 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?
Cool, many thanks for the info.
-
- 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?
I'm quite new to this, so, sorry if it sounds stupid, but is this the correct way to do this?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:You can also specify a variable as a user variable by adding this prefix: user_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; } }
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 } }
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;
-
- 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?
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.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:You can also specify a variable as a user variable by adding this prefix: user_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; } }
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 } }
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;
Re: Using User Variables in ZScript?
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:
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.
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");
So instead you can just call it miscount.