I am trying to make sense of the zscript basics so i can, among other things, stop using a_setuservar so that the game stops griping about that particular issue when I start it. But this sort of thing is very difficult for me, since I want to do one specific thing that I already know how to do in decorate and never seems to be strictly what the examples are covering. I try to adapt based on what IS covered and on this occasion am not succeeding. I have been told I can "access variables directly" in zscript but HOW to do that remains unclear, even when starting from other people's code.
In this example, I want the creature to use alternate attack, hop, and hopping-attack frames IF the creature is in the second half of its walk state, and that is all.
so far my attempts either go to the alternate frames regardless of the walk state or the game doesn't start at all. Presumably I only need one instance of the variable usage corrected and then I can fix the other two the same way, so I only included the first
See:
ZIPw g 0
{
let eempfeet = 1;
//i only recently added the "let" but it didn't change anything
}
zipw gghhaabb 2
{
A_Chase();
Return A_CheckNoGround("hopdown", "hopup", random(24, 48));
}
goto midsee;
midsee:
zipw c 0
{
let eempfeet = 2;
}
ZIPw CCddeeff 2
{
A_Chase();
Return A_CheckNoGround("hopdown2", "hopup2", random(24, 48));
}
goto see;
Melee:
ZIPw a 0
{
if (eempfeet = 2);
{
return ResolveState("otherway");
}
else
{
return 0;
}
}
//this causes an error, only the latest of many things I have tried
//
//[and then the right-foot forward attack goes here; it is irrelevant for this question and eats up a lot of space]
GoTo See;
otherway:
//[the same attack with left-foot graphics goes here]
//as stated earlier, when my code attempts don't crash the game i only get the left foot version, but that at least means SOMETHING is happening
GoTo midSee;
also I am using 1 and 2 right now for the variable because 0 and 1 weren't working and i remembered reading something about 0 sometimes meaning not quite what i think it does. i really only need this to be on or off, true or false, but i have other old decorate variables with more than two modes
thank you for any insight into this!
using variables in zscript without A_setuservar
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: 702
- Joined: Tue Jul 15, 2003 5:15 pm
- Location: misplaced
-
- Posts: 36
- Joined: Thu Jan 21, 2016 2:25 am
Re: using variables in zscript without A_setuservar
Look at example below:
I've declared a new field with name "columnColor" with the type "string" inside of a class "Test"
If you'll run this code you'll see that every tick of this actor's life the value of a "columnColor" field is printed into console and you can see how its value is changed inside of this actor's states.
When you write "let" you declare a new variable.
When you write "let" the type of the variable is inferred from its value.
Also in your expression here there are two mistakes at once:
Mistake #1 - semicolon on the line with "if" statement.
Take a look at this example:
Both lines "Correct condition" and "Incorrect condition" will be printed in this example.
It happens because when condition in if statement is true the statement located after it will be executed. And if you want more than one statement - you put them inside of a curly braces. However "the statement located after it" in second case ends with a semicolon and statements grouped by curly braces are no longer part of it. ZScript even puts yellow warning message into a console:"Empty if statement"
Mistake #2:
When you write "eempfeet = 2" you assign "2" to variable "eempfeet". And act of assigning (I think) always resolves to "true".
If you want to compare them instead you need to use == , like this: eempfeet == 2
Code: Select all
version "4.10"
class Test : Actor
{
string columnColor;
Default
{
Radius 16;
Height 40;
+SOLID;
}
States
{
Spawn:
TNT1 A 0
{
columnColor = "green";
}
COL2 A 15;
TNT1 A 0
{
columnColor = "red";
}
COL4 A 15;
loop;
}
override void Tick()
{
Super.Tick();
console.printf("This column is "..columnColor);
}
}
If you'll run this code you'll see that every tick of this actor's life the value of a "columnColor" field is printed into console and you can see how its value is changed inside of this actor's states.
When you write "let" you declare a new variable.
When you write "let" the type of the variable is inferred from its value.
Also in your expression here there are two mistakes at once:
Code: Select all
if (eempfeet = 2);
{
return ResolveState("otherway");
}
Take a look at this example:
Code: Select all
bool condition = true;
if (condition)
{
console.printf("Correct condition");
}
bool incorrectCondition = false;
if (incorrectCondition);
{
console.printf("Incorrect condition");
}
It happens because when condition in if statement is true the statement located after it will be executed. And if you want more than one statement - you put them inside of a curly braces. However "the statement located after it" in second case ends with a semicolon and statements grouped by curly braces are no longer part of it. ZScript even puts yellow warning message into a console:"Empty if statement"
Mistake #2:
When you write "eempfeet = 2" you assign "2" to variable "eempfeet". And act of assigning (I think) always resolves to "true".
If you want to compare them instead you need to use == , like this: eempfeet == 2
-
- Posts: 702
- Joined: Tue Jul 15, 2003 5:15 pm
- Location: misplaced
Re: using variables in zscript without A_setuservar
I was trying to assign 2 to it, but then assign 1 to it afterward, and alternate between them.
I HAVE been trying to cut back on things that the console complains about but doesn't abort the game over so that I might notice ones that are more important. I finally got rid of all the "truncation of floating point" whatever, apparently largely caused by me using numbers like "0.8," after you mentioned if statement warnings, and yes now I do see them! Hopefully I can make further progress from there.
I HAVE been trying to cut back on things that the console complains about but doesn't abort the game over so that I might notice ones that are more important. I finally got rid of all the "truncation of floating point" whatever, apparently largely caused by me using numbers like "0.8," after you mentioned if statement warnings, and yes now I do see them! Hopefully I can make further progress from there.
-
- Posts: 702
- Joined: Tue Jul 15, 2003 5:15 pm
- Location: misplaced
Re: using variables in zscript without A_setuservar
I removed the if's semicolon and added a second equals sign like so
Melee: if (eempfeet == 2) { return ResolveState("otherway"); }
but now I get a "unexpected '==''" error. The game does not like a single '=' either.
if (eempfeet == 2) { goto otherway; }
this makes it worse. There seems to be something very fundamental that I am missing.
if (eempfeet == 2) goto otherway;
this one the game REALLY hates
Melee: if (eempfeet == 2) { return ResolveState("otherway"); }
but now I get a "unexpected '==''" error. The game does not like a single '=' either.
if (eempfeet == 2) { goto otherway; }
this makes it worse. There seems to be something very fundamental that I am missing.
if (eempfeet == 2) goto otherway;
this one the game REALLY hates
-
-
- Posts: 1645
- Joined: Sun Jul 21, 2019 8:54 am
Re: using variables in zscript without A_setuservar
You still need to specify a frame and put that code inside that frame for it to work, like so:
Might be worth also noting that for this case you can also use A_JumpIf:
TNT1 A 0 A_JumpIf(eempfeet == 2, "otherway");
If you just write if(variable) then it will check if it's a non-zero value.
if(variable = 2) will pass, but if(variable = 0) will not.
Code: Select all
Melee:
TNT1 A 0
{
if (eempfeet == 2)
{
return ResolveState("otherway");
}
return ResolveState(null); //This is needed to prevent a return type mismatch
}
TNT1 A 0 A_JumpIf(eempfeet == 2, "otherway");
Actually what is happening is that first it assigns and then it compares.
If you just write if(variable) then it will check if it's a non-zero value.
if(variable = 2) will pass, but if(variable = 0) will not.
-
- Posts: 702
- Joined: Tue Jul 15, 2003 5:15 pm
- Location: misplaced
Re: using variables in zscript without A_setuservar
Thank you, you saved me again! ah ha that resolvestate null, I know I tried that somewhere, I just could not input it properly. It starts to become abstract to me at some point, along with the semi colon and bracketing shenanigans, I forget that they are all part of the same bit, probably why I wondered if attaching it to a frame was necessary.
I don't believe I knew about a_jumpif even though one of the parts I omitted, a silly jump-kicking attack, uses a_jumpifcloser.
although having come to this point, is it possible to have jumpifcloser treat vertical distance differently? I see a way to disable z checking entirely, which I do not think is what I want, unless I can run two jumpifclosers and the other ONLY checks z. Right now the beasts keep trying to jump kick even if i float where they can't hit. my cheap fix is to have a 1 in 4 chance of them switching to a conventional projectile attack if the kick misses and they still have a line-of-sight toward their targets. I also see a way to "get distance" but am not clear what to do with the distance once I get it.
like A_JumpIf(targetz <= 48)
i think
I don't believe I knew about a_jumpif even though one of the parts I omitted, a silly jump-kicking attack, uses a_jumpifcloser.
although having come to this point, is it possible to have jumpifcloser treat vertical distance differently? I see a way to disable z checking entirely, which I do not think is what I want, unless I can run two jumpifclosers and the other ONLY checks z. Right now the beasts keep trying to jump kick even if i float where they can't hit. my cheap fix is to have a 1 in 4 chance of them switching to a conventional projectile attack if the kick misses and they still have a line-of-sight toward their targets. I also see a way to "get distance" but am not clear what to do with the distance once I get it.
like A_JumpIf(targetz <= 48)
i think
-
-
- Posts: 1645
- Joined: Sun Jul 21, 2019 8:54 am
Re: using variables in zscript without A_setuservar
You could use Distance3D to retrieve the distance to the target in 3D, but I'm not sure if it would be any different than A_JumpIfCloser.
If you just want to compare Z positions of both actors, you could use this function:
Throw it into your monster base class and you will be able to use it on any monster.
The use case is A_JumpIfDiffZ(48, "State2"), which will jump to State2 if the Z difference between both the actor and its target is smaller or equal to 48.
It is late where I am and I am very tired, so this is the best I could come up with. I swear I will wake up in the morning and realise that I could have easily used some built-in function instead of this.
If you just want to compare Z positions of both actors, you could use this function:
Code: Select all
state A_JumpIfDiffZ(double difference, statelabel label){
If(target){
double dist = abs(abs(self.pos.z)-abs(target.pos.z));
If(dist <= difference){
Return ResolveState(label);
}
}
Return ResolveState(null);
}
The use case is A_JumpIfDiffZ(48, "State2"), which will jump to State2 if the Z difference between both the actor and its target is smaller or equal to 48.
It is late where I am and I am very tired, so this is the best I could come up with. I swear I will wake up in the morning and realise that I could have easily used some built-in function instead of this.
-
- Posts: 702
- Joined: Tue Jul 15, 2003 5:15 pm
- Location: misplaced
Re: using variables in zscript without A_setuservar
Ha, another good one! a bit funny since the game doesn't differentiate between above or below but that still leaves a lot to work with and sometimes funny is good. It almost feels like you are my underappreciated co-author, though I make sure to mark all the code with where or who I got it from. At least recently I have been doing that.