Class ZScapeMissileMarker : RedParticleFountain {
	Default {
		+FLOORCLIP;
		-NOGRAVITY;
		-NOBLOCKMAP;
		-INVISIBLE;
		MaxStepHeight 8192;
	}
	
	ZScapeMissileLight Light;
	ZScapeMissileLight2 Light2;
	Actor ToFollow;
	
	int GlideSpeed;
	
	// --- Let there be light(s) ---
	
	Override Void BeginPlay() {
		Super.BeginPlay();
		Light = ZScapeMissileLight(Actor.Spawn("ZScapeMissileLight"));
		Light.ToFollow = self;
			
		Light2 = ZScapeMissileLight2(Actor.Spawn("ZScapeMissileLight2"));
		Light2.ToFollow = self;
		
		GlideSpeed = Random(4, 10);
	}
	
	// --- Commence stalking of Thy Player ---
	
	Override Void Tick() {
		Super.Tick();
		If (ACS_NamedExecuteWithResult("ZMarkerSkyCheck") == 1) {
			GlideToPlayer();
			self.SetZ(0.0);
		}
		else Light.Fire_ZSMissile();
	}
	
	Void GlideToPlayer() { 
		A_Face(ToFollow);
		VelFromAngle(GlideSpeed);
	}
}

Class ZScapeMissileLight : PointLight {
	ZScapeMissileMarker ToFollow;
	ZScapeHomingMissile ZSMissile;
	Color C;
	bool REACHED;
	Vector3 MissileV3;
	
	Default {
		+FLOORCLIP
	}
	
	// --- THE ACTUAL LOGIC ---
	
	Override Void Tick() {
		Super.Tick();
		if(!REACHED) {
			SetOrigin(self.ToFollow.pos, true);
		}
		self.SetZ(0.0);
		ZDoMissileCheck();
	}
	
	Void ZDoMissileCheck () {
		For(let i = BlockThingsIterator.Create(self,2); i.Next();) {
			If(i.thing is "PlayerPawn") Fire_ZSMissile();
		}	
	}
	
	Void Fire_ZSMissile() {
		ZSMissile = ZScapeHomingMissile(Actor.Spawn("ZScapeHomingMissile"));
				
		MissileV3 = (self.pos.x+ random(-80, 80), // X  with an offset of -80/+80
					 self.pos.y+ random(-80, 80), // Y  with an offset of -80/+80
					 GetZAt(self.pos.x, self.pos.y, self.angle, GZF_CEILING) - random(25, 50)); // 25 = Z - (Height Of Rocket+1)
							 
		ZSMissile.SetOrigin(MissileV3, true);
		if(ZSMissile.pos.z < 512) ZSMissile.Destroy(); // if it gets spawned on one of the edge-skies , remove it
		REACHED = true;
		ToFollow.Light2.REACHED = true;
		SDestroy();
	}
	
	Void SDestroy() {
		ToFollow.Light2.Destroy();
		ToFollow.Destroy();
		self.Destroy();
	}
	
	// --- COLOR STUFF ---
	
	Override Void Activate(Actor activator) {
		UpdateColor();
		UpdateCVAR();
		REACHED = false;
		
		Super.Activate(activator);		
	}
	
	Void UpdateColor () {
		C = "FF 00 00";
		args[3] = 16;
	}
	
	Void UpdateCVAR () {
		args[0] = c.r;
		args[1] = c.g;
		args[2] = c.b;				
	}
}

Class ZScapeMissileLight2 : ZScapeMissileLight {
	Void UpdateColor () {
		C = "FF FF 00";
		args[3] = 8;
	}
	
	Void ZDoMissileCheck () {} // Fix the double rocket bug
}

Class ZScapeHomingMissile : Rocket {
	Default {
		Radius 4;
		Height 24;
		Scale 1.3;
		+BRIGHT;
		+ROCKETTRAIL;
	}
	
	// --- "It's Raining High-Speed Ballistic Missiles" -Yours Truely ---
	
	Override Void BeginPlay() {
		Super.BeginPlay();
		For(int i = 0; i < 125; i++) { // 125 being the Max Speed
			ThrustThingZ(0, i, 1, 0);
			i++;
		}
	}
	
	States 
	{
		Spawn:
			TNT1 A 2; // This is a lazy fix for the rocket to not appear for a split second at coords 0, 0 on the map
				goto ASpawn;
		ASpawn:
			MISL Y 4;
			MISL Z 4;
			Loop;
	}
}