No ZScript eq. for GetActorLightLevel()?

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!)
User avatar
Josh771
Posts: 676
Joined: Wed Apr 03, 2013 11:36 am
Location: Elsewhere.

No ZScript eq. for GetActorLightLevel()?

Post by Josh771 »

I'm having some fun learning ZScript. And by fun I mean wading through buckets of red text everytime I try to launch GZDoom.

I am attempting to do something like this:

Code: Select all

class StuffThingy : Actor
{
	int n;
	
	property Prop : n;
	
	default
	{
		Prop 0;				//Does not work
		StuffThingy.Prop 0	//Also does not work
	}
}
I am beginning to suspect that in order to have a custom property with a default value I must actually define two classes: one that defines the custom properties, and one that assigns to them. I really hope I'm wrong, because I'd be making a child class for no better reason than to initialize some properties.

Or am I going about this in entirely the wrong way altogether? I understand that you can only initialize a variable at declaration within anonymous functions, but is there some other way I can add a non-constant variable with an initial value to my class? I don't believe "int n = 0;" is valid in a class definition.
Last edited by Josh771 on Fri Jul 13, 2018 10:14 am, edited 2 times in total.
User avatar
gwHero
Posts: 360
Joined: Mon May 08, 2017 3:23 am
Graphics Processor: Intel with Vulkan/Metal Support
Location: The Netherlands

Re: Assigning to custom properties in default block

Post by gwHero »

Well, this should work:

Code: Select all

StuffThingy.Prop 0; // note the semicolon
User avatar
Josh771
Posts: 676
Joined: Wed Apr 03, 2013 11:36 am
Location: Elsewhere.

Re: Assigning to custom properties in default block

Post by Josh771 »

The missing semicolon was (I'm 99.99% sure) a matter only of my opening post. But I'll try it again all the same. Ultimately my final error messages were complaining that no such property existed, and I had to wonder if it was because I was accessing the property on the same Actor that had defined it. I might post the original code here...

EDIT: Okay, interesting... VM is crying out: "Self pointer used in ambiguous context"

Code: Select all

class SensoryMonster : Actor
{
	double sight_max_dist, sight_light_mult, sight_mult, hear_max_dist,
		hear_mult, sight_fov;
	
	double aware;
	
	property Awareness : aware;
	property Vision : sight_mult, sight_light_mult, sight_max_dist;
	property Hearing : hear_mult, hear_max_dist;
	property FoV : sight_fov;
	
	default
	{
		SensoryMonster.Awareness 0.0;
		SensoryMonster.Vision 1.0, 1.0, 8192.0;
		SensoryMonster.Hearing 1.0, 8192.0;
		SensoryMonster.FoV 150.0;
	}
	
	action state A_Sense(StateLabel detected)
	{
		LookExParams see_params;
		see_params.FoV = sight_fov;	//Problem starts here apparently
		see_params.minDist = 0;
		see_params.maxDist = sight_max_dist;
		see_params.maxHeardist = hear_max_dist;
		see_params.flags = LOF_NOSOUNDCHECK|LOF_NOSEESOUND|LOF_NOJUMP;
		see_params.seestate = null;
		LookExParams hear_params;
		hear_params.Fov = sight_fov;
		hear_params.minDist = 0;
		hear_params.maxDist = sight_max_dist;
		hear_params.maxHeardist = hear_max_dist;
		hear_params.flags = LOF_NOSIGHTCHECK|LOF_NOSEESOUND|LOF_NOJUMP;
		hear_params.seestate = null;
		let see_check = LookForEnemies(false, see_params);
		let hear_check = LookForEnemies(false, hear_params);
		if (see_check)
		{
			aware += sight_mult;
			return ResolveState(detected);
		}
		if (hear_check)
		{
			aware += hear_mult;
			return ResolveState(detected);
		}
		return ResolveState(null);
	}
}
That error spews out 10 times starting with the commented line above and continuing for every reference to a local variable declared in the SensoryMonster class. I think I've done something maybe unrelated to properties after all; sorry about that. Still confused and in need of an explanation though. Can I not define an action within a class so that it has access to its local variables?

EDIT 2: A quick search has informed me that I need to be using "invoker.localvar" to access these. I'll pop back in if somehow that doesn't fix it, but I bet that'll do it.

EDIT 3: Yeah, that fixed it. I mean, I completely broke the ZombieMan now, but that's my business. At least I may continue coding. Thanks.
User avatar
gwHero
Posts: 360
Joined: Mon May 08, 2017 3:23 am
Graphics Processor: Intel with Vulkan/Metal Support
Location: The Netherlands

Re: Assigning to custom properties in default block

Post by gwHero »

Yes, using invoker would indeed solve it. Although I thought that this was only needed in case of weapons/inventory stuff.
Another solution maybe is to remove the keyword 'action' in 'action state A_Sense(StateLabel detected)' (because I doubt if that's needed but I could be wrong), but in that case you wouldn't need invoker)
User avatar
Josh771
Posts: 676
Joined: Wed Apr 03, 2013 11:36 am
Location: Elsewhere.

StateLabel Custom Property

Post by Josh771 »

I just assumed that you need the action keyword if you intended to call the function from an actor's state definitions (as you would any of the old DECORATE A_Action functions). If that isn't necessary, the code would certainly be cleaner without it.

I have a new quandary though. Is there not a way to make a State or StateLabel into a custom property? If I try something along the lines of:

Code: Select all

StateLabel stlabel;

property MyStateProperty : stlabel;

default
{
	MyStateProperty "Spawn";
}
I get the error "Numeric type expected." I understand that internally the StateLabel type is apparently an integer or some other numeric type, but in practice we just use string literals and they must be getting converted to StateLabels somewhere along the way. If I change the variable type to string, I get a different error: "Cannot convert String to StateLabel." So I'm at an impasse.[/s] NEVERMIND, I'm not doing this anyway. Might be useful for someone else at some point, though, worth figuring out. Also, I am impressed with BBCode's powerful strikeout, able even to reach into the depths of code boxes.

Yeah, I'll just use StateLabel arguments for all my actions; I think that will work better than what I'd planned anyway.

Here's my real problem. is there actually no ZScript equivalent to ACS' GetActorLightLevel()? You can't use ACS functions from ZScript, can you? How do I get sector light from an actor in ZScript, if at all possible?
Last edited by Josh771 on Fri Jul 13, 2018 10:20 am, edited 2 times in total.
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49183
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: StateLabel Custom Property

Post by Graf Zahl »

You cannot define properties of type StateLabel - plain and simple.
User avatar
Josh771
Posts: 676
Joined: Wed Apr 03, 2013 11:36 am
Location: Elsewhere.

Re: No ZScript eq. for GetActorLightLevel()?

Post by Josh771 »

Thanks, Graf! I believe the wiki states that only arrays are not permitted, so that needs correction (whoever will; I understand you're not a docs man yourself, Graf).

So, is there a way to get actor light level without resorting to ACS? I really need to check actor light levels or I've been wasting my time. I can always dust off my ACS compiler if needs must.
User avatar
gwHero
Posts: 360
Joined: Mon May 08, 2017 3:23 am
Graphics Processor: Intel with Vulkan/Metal Support
Location: The Netherlands

Re: No ZScript eq. for GetActorLightLevel()?

Post by gwHero »

Josh771 wrote: So, is there a way to get actor light level without resorting to ACS? I really need to check actor light levels or I've been wasting my time. I can always dust off my ACS compiler if needs must.
Absolutely! Like this:

Code: Select all

console.printf("%d", self.cursector.GetLightLevel());
User avatar
Caligari87
Admin
Posts: 6191
Joined: Thu Feb 26, 2004 3:02 pm
Preferred Pronouns: He/Him

Re: No ZScript eq. for GetActorLightLevel()?

Post by Caligari87 »

Ninja'd by gwHero, consarnit. :ninja: Oh well, posting anyway because this kind of detective-work thought process is important here when learning Zscript:

-----

According to the Actor class definition, every actor should have a variable called cursector, which is, appropriately, of the type Sector. Bouncing over to the Sector struct definition, there's a member called lightlevel.

I have not tried this yet, but my first implementation would be to simply check cursector.lightlevel in your actor (or invoker.cursector.lightlevel if it's from an action function). Zscript is really convenient like that.

By extension, if you have a pointer to an actor from another actor, you can check it as well. For example, from a monster, target.cursector.lightlevel.

8-)
User avatar
Josh771
Posts: 676
Joined: Wed Apr 03, 2013 11:36 am
Location: Elsewhere.

Re: No ZScript eq. for GetActorLightLevel()?

Post by Josh771 »

Awesome, I like it! I've discovered the ZDoom Discord so maybe I can stop spamming the Scripting forum with requests now. :P
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49183
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: No ZScript eq. for GetActorLightLevel()?

Post by Graf Zahl »

Please don't repurpose threads like this. This is not helpful if other people try to find stuff later.

Return to “Scripting”