"How do I 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!)
Locked
User avatar
Xaser
 
 
Posts: 10772
Joined: Sun Jul 20, 2003 12:15 pm
Contact:

Re: "How do I ZScript?"

Post by Xaser »

Graf Zahl wrote:Actually, ZScript guards every single pointer dereference, but when you call a function things are a bit different: The pointer is never dereferenced unless you call a virtual function - it's just being passed as a hidden function parameter, which prevents checking in the call instruction because it isn't part of that - the exception only gets triggered when the pointer actually gets used inside the called function.
I suppose it's more accurate then to say that "self" isn't checked for null since it's being treated like any other function parameter?

I do find it convenient that the way the system appears to work the same as C++ in this case, even if there's some abstraction covering the real bits.
User avatar
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: "How do I ZScript?"

Post by Matt »

Thanks for the explanation! I think I have an idea what the problem might be but I'll have to try out the possible solutions I have in mind before commenting further... glad it's not some silly overflow issue at least.
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49073
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: "How do I ZScript?"

Post by Graf Zahl »

Xaser wrote: I suppose it's more accurate then to say that "self" isn't checked for null since it's being treated like any other function parameter?
It isn't just treated like any other function parameter, for the compiler it IS just another function parameter that gets added to the list internally.
User avatar
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: "How do I ZScript?"

Post by Matt »

So I tried to reference self in a line immediately before the one that the stack trace is pointing to:

Code: Select all

class HDActor:Actor{
	void nexttic(){
		if(!CheckNoDelay()) return;
		if(tics!=-1){
			if(tics>0)tics--;
			while(!tics){
A_LogInt(self.pos.x);
				if(!SetState(CurState.NextState)){
					return;
				}
			}
		}
	}
}
Same crash to console, but it's still pointing to the SetState call not the A_LogInt.

What could possibly be null then?
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49073
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: "How do I ZScript?"

Post by Graf Zahl »

Most likely CurState is null, then.
User avatar
ZZYZX
 
 
Posts: 1384
Joined: Sun Oct 14, 2012 1:43 am
Location: Ukraine
Contact:

Re: "How do I ZScript?"

Post by ZZYZX »

If your point is to make the specific actor's ticrate faster, just call Tick() manually, like self.Tick().
User avatar
Gutawer
Posts: 469
Joined: Sat Apr 16, 2016 6:01 am
Preferred Pronouns: She/Her

Re: "How do I ZScript?"

Post by Gutawer »

How can I get the current gravity acting on an actor (not just their gravity property, but also taking into account map gravity & sector gravity), and the current air friction acting on an actor (I know the wiki has a formula for getting air friction based off air control, so getting air control would also be fine)?
User avatar
ZZYZX
 
 
Posts: 1384
Joined: Sun Oct 14, 2012 1:43 am
Location: Ukraine
Contact:

Re: "How do I ZScript?"

Post by ZZYZX »

In global level struct:
native double gravity;
native double aircontrol;
native double airfriction;

Use like level.gravity, level.aircontrol, level.airfriction...
(this can be found in gzdoom.pk3/zscript/base.txt)

In Sector struct:
native double gravity;

You can get the current sector of the actor by using self.CurSector.

Just check these values and compare them to your input, and see what and how gets modified when you alter a sector's gravity for example... Then combine the values and you will get your gravity that affects the actor :)
Note that you will also need to check for NOGRAVITY and FLOAT (?) flags, as well as being submerged... and I don't know how that works really. Probably something hardcoded.

Actually, in Actor class:
native double GetGravity();
native double, double GetFriction();

That's probably why that method is in, it should return you the actual total gravity and friction. Try that.
User avatar
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: "How do I ZScript?"

Post by Matt »

My only purpose for the separate nexttic() function was so I didn't need to retype all of that every time I tried to use a custom Tick() override.

I've made a standalone version here:
Spoiler:
This will cause the dereference. If either I comment out 'setstatelabel("death");' or set the TNT1 A 0 to non-zero, the dereference (or at least the crash) does not happen.

I'm guessing then that the sequence is something like:

1. it sees the setstatelabel and applies it right away; but then
2. it processes the death state immediately; so
3. by the time we get to setstate call, the actual state has already reached "stop" and so the current state is null?

If so, would I be safe just making sure none of these setstatelabels are pointing to anything with a zero length?
User avatar
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: "How do I ZScript?"

Post by Matt »

Is there any way to explicitly call the corpse-rasing process without relying on A_Chase and CHF_RESURRECT?
User avatar
Major Cooke
Posts: 8176
Joined: Sun Jan 28, 2007 3:55 pm
Preferred Pronouns: He/Him
Location: QZDoom Maintenance Team

Re: "How do I ZScript?"

Post by Major Cooke »

Thing_Raise(tid)

Quick question, Graf, what is the schematic of Color? I noticed there were four parameters when used directly from the menu system in zscript.
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49073
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: "How do I ZScript?"

Post by Graf Zahl »

Vaecrius wrote: This will cause the dereference. If either I comment out 'setstatelabel("death");' or set the TNT1 A 0 to non-zero, the dereference (or at least the crash) does not happen.

I'm guessing then that the sequence is something like:

1. it sees the setstatelabel and applies it right away; but then
2. it processes the death state immediately; so
3. by the time we get to setstate call, the actual state has already reached "stop" and so the current state is null?
SetState will destroy the actor if it reaches a state with zero duration and no next state.

[/quote]
If so, would I be safe just making sure none of these setstatelabels are pointing to anything with a zero length?[/quote]

You better check 'bDestroyed' after the SetState call, that's safer.
User avatar
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: "How do I ZScript?"

Post by Matt »

Thanks Graf! Adding "if(bdestroyed) return;" works like a charm.

As for the ACS suggestion for a ZScript question, I ended up with this:

Code: Select all

		TROO A 0{
			int oldtid=healtarget.tid;
			int newtid=FindUniqueTid();
			healtarget.ChangeTid(newtid);
			Thing_Raise(newtid);
			healtarget.ChangeTid(oldtid);
		}
which still doesn't work because the healer is very frequently always just a little inside the corpse's hitbox and that's registered as a block.

Is there any way around this?

EDIT: for anyone curious, so far this works ("A_HDMRaise" is almost identical to the alternative, it just takes advantage of a few custom variables so we don't blithely assume every raisable is 56 tall with a maxstepheight of 24):
Spoiler:
User avatar
Nash
 
 
Posts: 17439
Joined: Mon Oct 27, 2003 12:07 am
Location: Kuala Lumpur, Malaysia
Contact:

Re: "How do I ZScript?"

Post by Nash »

What is this "new" keyword and how is it actually meant to be used? How is it better than just doing FMyClass blah; ?
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49073
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: "How do I ZScript?"

Post by Graf Zahl »

One creates a new object, the other is just a pointer.
Locked

Return to “Scripting”