Inheriting from an actor that uses VisualThinker

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
SPZ1
Posts: 373
Joined: Wed Aug 02, 2017 3:01 pm
Location: Illinois

Inheriting from an actor that uses VisualThinker

Post by SPZ1 »

I thought inheriting from an actor that utilizes VisualThinkers would slim my code down a bit. This code only uses the parent's random spawn coordinates and not the newly specified ones. :evil:

Code: Select all

class SnowArea_MAP12_MainArea : ACTOR {

	TextureID texID;
	Array<VisualThinker> vtArray;

	Default {
		Radius 64;
		Height 16;
		Scale 0.25;
		+NOINTERACTION;
		+NOBLOCKMAP;
		+NOGRAVITY;
		+BRIGHT;
	}

	override void PostBeginPlay(){
		Super.PostBeginPlay();
		texID = TexMan.CheckForTexture("SNOFLAKE");
		
	}

	override void OnDestroy(){
		foreach (vt : vtArray){
			if (vt){
				vt.Destroy();
			}
		}

	}

	void Create(){
		VisualThinker vt = Level.SpawnVisualThinker("SnowFlake1");

		if (vt){
			vt.Texture = texID;
			vt.pos = (random(-4736, 1024), random(-3456, 3712), 3200);
			vt.vel = (random(-12.0, 12.0), random(-12.0, 12.0), -16.0);
			vt.scale = (0.5, 0.5);
			vtArray.Push(vt);
		}
	}

	States {
		Spawn:
			EMPT A 1;
		PostSpawnLoop:
			EMPT A 1 {
				Create();
				Create();
			}

			Loop;
	}

}

class SnowArea_MAP12_WalkWayLeft : SnowArea_MAP12_MainArea  {
	void Create(){
		VisualThinker vt = Level.SpawnVisualThinker("SnowFlake1");

		if (vt){
			vt.Texture = texID;
			vt.pos = (random(-5760, -4256), random(4608, 5888), 3200);
			vt.vel = (random(-12.0, 12.0), random(-12.0, 12.0), -16.0);
			vt.scale = (0.5, 0.5);
			vtArray.Push(vt);
		}
	}
}

class SnowArea_MAP12_WalkWayRight: SnowArea_MAP12_MainArea  {
	void Create(){
		VisualThinker vt = Level.SpawnVisualThinker("SnowFlake1");

		if (vt){
			vt.Texture = texID;
			vt.pos = (random(416, 1920), random(4608, 5888), 3200);
			vt.vel = (random(-12.0, 12.0), random(-12.0, 12.0), -16.0);
			vt.scale = (0.5, 0.5);
			vtArray.Push(vt);
		}
	}
}

class SnowFlake1 : VisualThinker {

	override void PostBeginPlay(){
		Super.PostBeginPlay();
		
	}	

	override void Tick(){
		Super.Tick();

		if (Pos.Z < 1280){
			Destroy();
		}
	}
}
User avatar
SPZ1
Posts: 373
Joined: Wed Aug 02, 2017 3:01 pm
Location: Illinois

Re: Inheriting from an actor that uses VisualThinker

Post by SPZ1 »

I found that I had to explicitly define the states block to make it work.
User avatar
Player701
 
 
Posts: 1701
Joined: Wed May 13, 2009 3:15 am
Graphics Processor: nVidia with Vulkan support

Re: Inheriting from an actor that uses VisualThinker

Post by Player701 »

A few more elegant ways to solve this:
  1. Declare the Create method virtual;
  2. Refactor the coordinates into ZScript custom properties and override their values in each subclass;
  3. If these actors are added to the level via a map editor, you could also read the coordinates from thing arguments (the args array) - but since your values are in the thousands, it would require that your maps are in the UDMF format. (Hexen map format supports only 8-bit arguments: that is, 0 to 255.)

Return to “Scripting”