[ZScript] Accessing a master's variables

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!)
Post Reply
User avatar
Pixel Eater
 
 
Posts: 667
Joined: Wed Aug 02, 2017 12:31 am
Location: In between the Moon and you, between the buried and me.

[ZScript] Accessing a master's variables

Post by Pixel Eater »

I've got three spriteIDs that a child actor needs to retrieve but I get an error message, Script error, "HorizontalSprites.pk3:zscript.zc" line 69:
Unknown identifier 'TopAngle'.

I declare them this way:

Code: Select all

class HorizDoomImp : DoomImp Replaces DoomImp
{
	spriteID SidAngle ;
	spriteID TopAngle ;
	spriteID BotAngle ;
	
	override void BeginPlay()
	{
		Super.BeginPlay() ;
		
		SidAngle = GetSpriteIndex( "TROO" );
		TopAngle = GetSpriteIndex( "TANG" );
		BotAngle = GetSpriteIndex( "BANG" );
		
		A_SpawnItemEx( "HorizSprites", flags: SXF_SETMASTER| SXF_ABSOLUTEANGLE
		| SXF_TRANSFERPITCH | SXF_TRANSFERSPRITEFRAME | SXF_TRANSFERTRANSLATION
		| SXF_TRANSFERSCALE | SXF_TRANSFERSTENCILCOL | SXF_TRANSFERALPHA
		| SXF_TRANSFERRENDERSTYLE );
	}
}
And in the Tick event of the spawned actor I recall it this way:
self.sprite = master.TopAngle ;

I've been going through the Wiki for hours but I'm just not getting it. I'd be super grateful for some assistance :3:
Here is the file for easier examination:
HorizontalSprites.pk3
(57.6 KiB) Downloaded 23 times
User avatar
kodi
 
 
Posts: 1361
Joined: Mon May 06, 2013 8:02 am

Re: [ZScript] Accessing a master's variables

Post by kodi »

Try this:

Code: Select all

let m = HorizDoomImp(master);
if(m)
{
self.sprite = m.TopAngle;
}
User avatar
Pixel Eater
 
 
Posts: 667
Joined: Wed Aug 02, 2017 12:31 am
Location: In between the Moon and you, between the buried and me.

Re: [ZScript] Accessing a master's variables

Post by Pixel Eater »

Ooh yeah! That certainly works for the Imp :D
Is there also a way to make it treat any actor who's spawned it as the master? I've got every Doom monster spawning it and I'm hoping it will work for all of them.
User avatar
kodi
 
 
Posts: 1361
Joined: Mon May 06, 2013 8:02 am

Re: [ZScript] Accessing a master's variables

Post by kodi »

I think it would be best to do all this with an event handler rather than replacing any monsters at all.
You could override WorldThingSpawned for every monster that has these rotations, and do the A_SpawnItemEx call on each class that's supposed to have a "HorizSprites".
The event handler could also have an array/lookup function where the child actors pass the class name of their master to it, and it returns the correct SidAngle/TopAngle/BotAngle for each class.
By using the "is" keyword for class checking you could support inheritance and get say, colorful doom compatibility out of the box.
User avatar
Pixel Eater
 
 
Posts: 667
Joined: Wed Aug 02, 2017 12:31 am
Location: In between the Moon and you, between the buried and me.

Re: [ZScript] Accessing a master's variables

Post by Pixel Eater »

I thought about learning the WorldThingSpawned way but got the impression it would reduce the portability of this code. I'll give it a try and see what's it's like :thumb:
Alternatively is it possible to declare the spriteIDs within the child actor and then set their values from the master after they've been spawned? Sort of the opposite of what I was doing...

Edit: Shortly after I posted I thought of a way that required little changing and makes it even simpler to manage. I added state labels to the master actors that define the top and bottom angle sprites. Then in the child actor did this:

Code: Select all

spriteID SidAngle ;
spriteID TopAngle ;
spriteID BotAngle ;

override void PostBeginPlay()
{
	Super.PostBeginPlay() ;
		
	master.SetStateLabel( "Spawn" );
	self.SidAngle = master.sprite ;
		
	master.SetStateLabel( "TopAngle" );
	self.TopAngle = master.sprite ;
		
	master.SetStateLabel( "BotAngle" );
	self.BotAngle = master.sprite ;
		
	master.SetStateLabel( "Spawn" );
}
Now all one has to do is make a definition like this:

Code: Select all

class HorizBaron : BaronOfHell Replaces BaronOfHell
{
	States
	{
	TopAngle:
		TANG # 1 ;
	BotAngle:
		BANG # 1 ;
	}
	
	override void BeginPlay()
	{
		Super.BeginPlay() ;
		
		A_SpawnItemEx( "HorizSprites", flags: SXF_SETMASTER | SXF_ABSOLUTEANGLE
		| SXF_TRANSFERPITCH | SXF_TRANSFERSPRITEFRAME | SXF_TRANSFERTRANSLATION
		| SXF_TRANSFERSCALE | SXF_TRANSFERSTENCILCOL | SXF_TRANSFERALPHA
		| SXF_TRANSFERRENDERSTYLE );
	}
}
And voila! Support for top and bottom angles in sprites :D

Thanks Kodi for the suggestions. Btw, I used to find that "let" function confusing but it's starting to make more sense now :cheers:

Edit2: Have put it in the script library: Here
Post Reply

Return to “Scripting”