"How do I 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!)
- Matt
- Posts: 9696
- Joined: Sun Jan 04, 2004 5:37 pm
- Preferred Pronouns: They/Them
- Operating System Version (Optional): Debian Bullseye
- Location: Gotham City SAR, Wyld-Lands of the Lotus People, Dominionist PetroConfederacy of Saudi Canadia
- Contact:
Re: ZScript-only "How do I..." thread
Everything's a mess so it might take longer for me to extract something workable than to figure out that what I'm trying is impossible.
EDIT: turns out the target was being reset with each A_Chase call. Putting the A_Chase before the target switch helps a bit. Is there a way to replicate all the movement/dropoff/etc. checks and move towards a specific actor/point without all the extras A_Chase does?
How do I return an actor's class name?
EDIT: turns out the target was being reset with each A_Chase call. Putting the A_Chase before the target switch helps a bit. Is there a way to replicate all the movement/dropoff/etc. checks and move towards a specific actor/point without all the extras A_Chase does?
How do I return an actor's class name?
Last edited by Matt on Sun Jan 29, 2017 12:42 pm, edited 1 time in total.
- Ed the Bat
- Posts: 3060
- Joined: Thu May 03, 2012 1:18 pm
- Graphics Processor: nVidia with Vulkan support
- Location: Maryland, US
- Contact:
Re: ZScript-only "How do I..." thread
GetClassName()
- Matt
- Posts: 9696
- Joined: Sun Jan 04, 2004 5:37 pm
- Preferred Pronouns: They/Them
- Operating System Version (Optional): Debian Bullseye
- Location: Gotham City SAR, Wyld-Lands of the Lotus People, Dominionist PetroConfederacy of Saudi Canadia
- Contact:
Re: ZScript-only "How do I..." thread
Thanks!
(Added it to the big list... on that note, is there any particular order in which these are listed?)
(Added it to the big list... on that note, is there any particular order in which these are listed?)
Re: ZScript-only "How do I..." thread
So in A Boy and His Barrel ( viewtopic.php?f=19&t=53399 ), I recently implemented a carrying mechanic which Jimmy noticed has the annoying side effect of Violet not triggering any "Actor Hits Floor" things when moved into a sector as it is done with a warp - is there a way to force an actor to trigger these actions regardless of how they moved into the sector (moved "naturally", teleported in, warped in, etc.) as long as their Z pos is equal to their Floor Z pos? If it comes to it I can probably do some hack with setting the Z pos slightly above the floor, but i'd rather avoid hacks when possible.
Re: ZScript-only "How do I..." thread
Ok I have my RayTracer and that's an acs+decorate salad code and I wanted to convert it into 100% zscript.
The thing is, in acs CheckSight can work with a source and a destination tid, while in decorate (And I belie in zscript) I can only CheckSight with the object and the player.
Do I need to change the pointers every time before I call the a_CheckSight function?
Also, is there a way to make an extern like var in c where you can have access to a global var from acs?
Here's the acs script that I'm converting to zscript
and the decorate
and also my first try with zscript where I try to get those two codes and mix it together
Why I'm not using a jump if target in los?because it's slow, think about 3000 objects calling it every tic, the checksight acs version was alot faster, but I do belive that by calling 2000x acs calls with a return will also drop the performance alot, so maybe a solution 100% made in zscript will work better.
The thing is, in acs CheckSight can work with a source and a destination tid, while in decorate (And I belie in zscript) I can only CheckSight with the object and the player.
Do I need to change the pointers every time before I call the a_CheckSight function?
Also, is there a way to make an extern like var in c where you can have access to a global var from acs?
Here's the acs script that I'm converting to zscript
Code: Select all
script 4 (int tid) //check if visible by the tid
{
switch(tid)
{
case 45:
case 5:
if(checksight(0,102,0)==true)
{
SetResultValue(true);
}
else
{
SetResultValue(checksight(0,103,0));
}
break;
case 48:
case 44:
case 2:
SetResultValue(checksight(0,101,0));
break;
case 1:
SetResultValue(checksight(0,100,0));
break;
case 68:
SetResultValue(checksight(0,67,0));
break;
}
}
script 5 (int tid) // check if player is under a specific room
{
switch(tid)
{
case 5:
case 45:
SetResultValue(camera_sector == 2);
break;
case 48:
case 44:
case 2:
SetResultValue(camera_sector == 1);
break;
case 1:
SetResultValue(true);
break;
case 68:
SetResultValue(camera_sector == 3);
break;
}
}
Code: Select all
Actor RayCast 32766
{
//$Category RayCast_Fixed
-SOLID
+NOGRAVITY
+NOCLIP
+INVISIBLE
+NOINTERACTION
height 4.0
Scale 0.5
var int user_RayState;//true = is lighting, false is shadowing
States
{
Spawn:
C000 A 1
C000 A 0 A_SetUserVar("user_RayState",1)
C000 A 1 A_RearrangePointers(AAPTR_NULL, AAPTR_PLAYER1, AAPTR_DEFAULT)
goto "FindRay"
"NoShadow":
C000 A 1 // LIGHT
Goto "FindRay"
"Shadow":
C001 A 1 // SHADOW
goto "FindRay"
"StartShadow":
C001 D 1
C001 C 1 A_SetUserVar("user_RayState",0)
C001 B 1
Goto "Shadow"
"EndShadow":
C001 B 1
C001 C 1 A_SetUserVar("user_RayState",1)
C001 D 1
Goto "NoShadow"
"SleepRay":
C000 A 50 // I better replace this one with some thing_deactivate
goto "NoShadow"
"FindRay":
//PART 1: OPTIMIZE THE CODE, GET A SOLUTION TO KNOW IF THE RAY SHOULD BE CHECKED OR NOT
//THE RAY COULD BE CHECKED IF THE RAY IS OVER THE PLAYER's VIEWPOINT OR OTHER TRICKS...
//solution 7:
TNT1 A 0 A_Jumpif(Acs_executewithresult(5,tid)==false,"SleepRay")
//=============
//PART2: MAIN RAY CODE, CHECK IF THE RAY WAS HIT BY A LIGHT SOURCE
//check if was hit
//METHOD 2:
// TNT1 A 0 A_jumpiftargetinlos(3,360,JLOSF_TARGETLOS | JLOSF_CHECKMASTER ,0,0)
// TNT1 A 0 A_jump(256,"See")
TNT1 A 0 A_Jumpif(Acs_executewithresult(4,tid)==true,3) //check all the light sources
TNT1 A 0 A_jumpif(user_RayState == 1,"StartShadow") // make light shade effect
TNT1 A 0 a_jump(256,"Shadow") //else, this ray is already shadow
TNT1 A 0 A_jumpif(user_RayState == 0,"EndShadow") // make light shade effect
Goto "NoShadow"
}
}
Code: Select all
struct RayEnum
{
enum RayEnum
{
NoLightSource,
WithLightSource
};
}
class Z_RayCast : Actor 22766
{
//$Category RayCast_Fixed
Default
{
-SOLID
+NOGRAVITY
+NOCLIP
+INVISIBLE
+NOINTERACTION
RayEnum user_RayState = NoLightSource;
}
States
{
Spawn:
C000 A 1
C000 A 1 A_RearrangePointers(AAPTR_NULL, AAPTR_PLAYER1, AAPTR_DEFAULT);
goto "FindRay"
"NoLightSource":
{
C000 A 1
Goto "FindRay"
}
"WithLightSource":
{
C001 A 1
Goto "FindRay";
}
"StartShadow":
{
C001 D 1
C001 C 1
{
user_RayState = RayEnum.NoLightSource;
}
C001 B 1
Goto "NoLightSource";
}
"EndShadow":
{
C001 B 1
C001 C 1
{
user_RayState =RayEnum.WithRaySource;
}
C001 D 1
Goto "WithLightSource";
}
"Sleep"
{
C000 A 50
goto "FindRay";
}
"FindRay":
{
TNT1 A 0
{
if(IsPlayerNearMySector() == false)
{
goto "Sleep"
}
else if(CheckVisibility() == RayEnum.WithRaySource)
{
if(user_RayState == RayEnum.NoRaySource)
{
goto "EndShadow";
}
else
{
goto "WithLightSource";
}
}
else // RayEnum.NoRaySource
{
if(user_RayState == RayEnum.WithRaySource)
{
goto "StartShadow";
}
else
{
goto "NoLightSource";
}
}
}
Goto "NoShadow"
}
}
bool CheckVisibility()
{
// is there a switch struct for zscript?
if(tid == 5 || tid == 45)
{
if(A_checksight(102) == false)// where 102 is a light source tid
{
return A_checksight(103);
}
else
{
return true;
}
}
else if(tid == 48 || tid == 44 || tid == 2)
{
return A_checksight(101);
}
else if(tid == 1)
{
return A_checksight(100);
}
else if(tid == 68)
{
return A_checksight(67);
}
}
extern int camera_sector; // acs global var
bool IsPlayerNearMySector()
{
if(tid == 5 || tid == 45)
{
return camera_sector == 2;
}
else if(tid == 48 || tid == 44 || tid == 2)
{
return camera_sector == 1;
}
else if( tid == 1)
{
return true;
}
else if( tid == 68)
{
return camera_sector == 3;
}
}
}
- monkeybtm6
- Posts: 115
- Joined: Thu Dec 18, 2014 9:03 pm
Re: ZScript-only "How do I..." thread
This may have already been asked somewhere but i cant find it. Can you set another actors properties in zscript? Like an ACS code with SetActorProperty. Trying to increase the players spawnhealth.
- Agentbromsnor
- Posts: 265
- Joined: Wed Mar 28, 2012 2:27 am
Re: ZScript-only "How do I..." thread
I'm sorry for the delayed reply, but... What? Who is zombiekiller, and what do I need to contact him for? What file? h666_isolated.pk3? Reading someone else's code can be very difficult, especially when it's in C-style, so I need a lot more to go on than that I'm afraid.Major Cooke wrote:Try pming zombiekiller about it directly. I don't have the file anymore myself.
Re: ZScript-only "How do I..." thread
ok I'm evolving...
So, I found that in zscript has the CheckSight function just like the acs one, but instead of requesting a tid as input it request an actor.
Soooo, should I just pass the tid and it's oj or do I need to get some actor pointer from the given tid? if yes, how?
EDIT:
ALLLSO.
How do I use enums, and how to convert bool to enum?
like
So, I found that in zscript has the CheckSight function just like the acs one, but instead of requesting a tid as input it request an actor.
Soooo, should I just pass the tid and it's oj or do I need to get some actor pointer from the given tid? if yes, how?
EDIT:
ALLLSO.
How do I use enums, and how to convert bool to enum?
like
Code: Select all
class Z_RayCast : Actor
{
//$Category RayCast_Fixed
enum RayEnum
{
NoLightSource,
WithLightSource
};
...
RayEnum user_RayState;
...
States
{
Spawn:
C000 A 1;
C000 A 1
{
camera_sector = 0;
user_RayState = /*RayEnum.*/NoLightSource;
}
user_RayState = CheckSight(ptr_LightSrc,0);
...
[code][/s]
got it, well, I prefer the C# style of enums but ansi c is ok
- Matt
- Posts: 9696
- Joined: Sun Jan 04, 2004 5:37 pm
- Preferred Pronouns: They/Them
- Operating System Version (Optional): Debian Bullseye
- Location: Gotham City SAR, Wyld-Lands of the Lotus People, Dominionist PetroConfederacy of Saudi Canadia
- Contact:
Re: ZScript-only "How do I..." thread
The function says "bool CheckSight(Actor target, int flags = 0);"
which means that you can do something like (assuming it's the player calling all these)
//who knows what this does
CheckSight(target);
//OR - see master and grovel
if(CheckSight(master)) A_PlaySound("sub/grovel");
//OR - if a point is not visible 1 second away, start braking
actor loscheck=Spawn("Blood",pos+vel*35);
if(!CheckSight(loscheck)) vel*=0.9;
loscheck.destroy();
I don't know how to search for an actor using a TID in ZScript, but basically you can use any function that outputs an "actor" and checksight using that.
which means that you can do something like (assuming it's the player calling all these)
//who knows what this does
CheckSight(target);
//OR - see master and grovel
if(CheckSight(master)) A_PlaySound("sub/grovel");
//OR - if a point is not visible 1 second away, start braking
actor loscheck=Spawn("Blood",pos+vel*35);
if(!CheckSight(loscheck)) vel*=0.9;
loscheck.destroy();
I don't know how to search for an actor using a TID in ZScript, but basically you can use any function that outputs an "actor" and checksight using that.
Re: ZScript-only "How do I..." thread
those CheckSight are going to be called by a specific actor that simulates a raytracing engine.
so lets say each dot object over a map needs to check if any kind of light source is visible or not.
I have all the light source tids, but I really don't know what could I do with that
so lets say each dot object over a map needs to check if any kind of light source is visible or not.
I have all the light source tids, but I really don't know what could I do with that
- Matt
- Posts: 9696
- Joined: Sun Jan 04, 2004 5:37 pm
- Preferred Pronouns: They/Them
- Operating System Version (Optional): Debian Bullseye
- Location: Gotham City SAR, Wyld-Lands of the Lotus People, Dominionist PetroConfederacy of Saudi Canadia
- Contact:
Re: ZScript-only "How do I..." thread
I think I see what you mean. Basically we need a way to check LOS between two actors.
So far I've been using one or more of A_JumpIfTargetInLOS, A_JumpIfInTargetLOS and A_CheckLOF, but all of those have some limitations and screwiness and I'd really like to see some way to check if there's anything blocking a line between two arbitrary points and if so what it is.
Yes, I would like an answer for this too.
(Also, since I'm posting questions anyway: what's the best way (i.e., least processing required) to get all monsters in an area to
1. store its target in an internal variable;
2. target the activator; and
3. change a flag?
The area can be a sphere or a cube, I don't really care.)
So far I've been using one or more of A_JumpIfTargetInLOS, A_JumpIfInTargetLOS and A_CheckLOF, but all of those have some limitations and screwiness and I'd really like to see some way to check if there's anything blocking a line between two arbitrary points and if so what it is.
Yes, I would like an answer for this too.
(Also, since I'm posting questions anyway: what's the best way (i.e., least processing required) to get all monsters in an area to
1. store its target in an internal variable;
2. target the activator; and
3. change a flag?
The area can be a sphere or a cube, I don't really care.)
Re: ZScript-only "How do I..." thread
From the way this is phrased, it seems like you've already answered your own question a post ago: CheckSight is the function you want. The following function will indeed cause the actor to grovel if its target is within line-of-sight:Vaecrius wrote:I think I see what you mean. Basically we need a way to check LOS between two actors.
Code: Select all
if(self.CheckSight(self.target)) {
self.A_PlaySound("sub/grovel");
}
Dunno if you're meaning to ask a different/more-specific question; if so, that's a different story.
Regarding TIDs, unless you're messing with map stuff, it's best to try and stop thinking in terms of TIDs; you can now pass pointers to actors around, and it's likely your specific problem can be solved more elegantly that way instead. For helpfulness' sake though, if you can't avoid a TID (e.g. stepping stone while porting old ACS-based logic or doing map things, as mentioned), you'll need to use an ActorIterator to loop through everything with a given TID (it's a looping action since you can have more than one thing with the same TID, so you gotta be explicit about it).
You'll want a BlockThingsIterator -- this loops through all actors within a given radius (excluding any actors with +NOBLOCKMAP). You'll need to do additional checks to see if it's a monster (and if it's alive, etc.), but fortunately, I happened to write almost exactly this code a couple of days ago, so here's a handy example. Replace the ArgNeuralStunner spawn bit with the logic described and you'll be good to go.Vaecrius wrote:(Also, since I'm posting questions anyway: what's the best way (i.e., least processing required) to get all monsters in an area to
1. store its target in an internal variable;
2. target the activator; and
3. change a flag?
The area can be a sphere or a cube, I don't really care.)
Hope this puts you on the right track.
Re: ZScript-only "How do I..." thread
I belive you gave me a light xase
...
Now, I have a question about this:
I see "A" and after "C" but not "A" "B", what's going on? a_Jump is not supported in zscript? (before there was a goto there but it looks like zscript doesnt like goto inside ifs.
So what should I use to replace the a_jump/goto inside the code?
...
Now, I have a question about this:
Code: Select all
"Sleep":
C000 A 50 a_log("B");
goto FindRay;
"FindRay":
TNT1 A 0
{
if(IsPlayerNearMySector() == false)
{
A_Log("A");
a_jump(256,"Sleep");
A_Log("C");
}
}
...
So what should I use to replace the a_jump/goto inside the code?
- Graf Zahl
- Lead GZDoom+Raze Developer
- Posts: 49067
- Joined: Sat Jul 19, 2003 10:19 am
- Location: Germany
Re: ZScript-only "How do I..." thread
Why are your labels quoted? That doesn't work and will make the quotes part of the label.
Re: ZScript-only "How do I..." thread
Oh I don't need to do like the decoate label style...
I also found this, but with the return before the a_jump, I get this error message:
"
Script error, "Ray.pk3:actors/z_ray/raycaststatic.txt" line 69:
Return type mismatch
Execution could not continue.
1 errors while parsing DECORATE scripts
"
since I'm noob at this language, I'm kinda lost
EDIT: return from what I saw, the return should be in the last line inside the anonymous function (It's "sad" because I waited for some c style (or even acs) where you can return on the mid of the code)
I also found this, but with the return before the a_jump, I get this error message:
"
Script error, "Ray.pk3:actors/z_ray/raycaststatic.txt" line 69:
Return type mismatch
Execution could not continue.
1 errors while parsing DECORATE scripts
"
since I'm noob at this language, I'm kinda lost
EDIT: return from what I saw, the return should be in the last line inside the anonymous function (It's "sad" because I waited for some c style (or even acs) where you can return on the mid of the code)