From b8cf377d9e7a6825a5c2ec48399be122d5290e85 Mon Sep 17 00:00:00 2001
From: Christoph Oelckers <c.oelckers@users.noreply.github.com>
Date: Mon, 28 Nov 2016 18:36:13 +0100
Subject: [PATCH] - scriptified the Crusader.

---
 src/CMakeLists.txt                        |   1 -
 src/g_strife/a_coin.cpp                   | 110 ----------------------
 src/g_strife/a_crusader.cpp               | 100 --------------------
 src/g_strife/a_strifestuff.cpp            |   2 -
 src/p_mobj.cpp                            |   9 ++
 wadsrc/static/zscript/actor.txt           |   1 +
 wadsrc/static/zscript/strife/crusader.txt |  85 +++++++++++++++--
 7 files changed, 88 insertions(+), 220 deletions(-)
 delete mode 100644 src/g_strife/a_coin.cpp
 delete mode 100644 src/g_strife/a_crusader.cpp

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index c5156cbf46..c8d560c2be 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -861,7 +861,6 @@ set( NOT_COMPILED_SOURCE_FILES
 	sc_man_scanner.re
 	g_hexen/a_heresiarch.cpp
 	g_hexen/a_spike.cpp
-	g_strife/a_coin.cpp
 	g_strife/a_crusader.cpp
 	g_strife/a_inquisitor.cpp
 	g_strife/a_loremaster.cpp
diff --git a/src/g_strife/a_coin.cpp b/src/g_strife/a_coin.cpp
deleted file mode 100644
index dcbbecf10b..0000000000
--- a/src/g_strife/a_coin.cpp
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
-#include "a_pickups.h"
-#include "a_strifeglobal.h"
-#include "gstrings.h"
-*/
-
-// Coin ---------------------------------------------------------------------
-
-/*
-IMPLEMENT_CLASS(ACoin, false, false)
-
-const char *ACoin::PickupMessage ()
-{
-	if (Amount == 1)
-	{
-		return Super::PickupMessage();
-	}
-	else
-	{
-		static char msg[64];
-
-		mysnprintf (msg, countof(msg), GStrings("TXT_XGOLD"), Amount);
-		return msg;
-	}
-}
-
-bool ACoin::HandlePickup (AInventory *item)
-{
-	if (item->IsKindOf (RUNTIME_CLASS(ACoin)))
-	{
-		if (Amount < MaxAmount)
-		{
-			if (MaxAmount - Amount < item->Amount)
-			{
-				Amount = MaxAmount;
-			}
-			else
-			{
-				Amount += item->Amount;
-			}
-			item->ItemFlags |= IF_PICKUPGOOD;
-		}
-		return true;
-	}
-	return false;
-}
-
-AInventory *ACoin::CreateCopy (AActor *other)
-{
-	if (GetClass() == RUNTIME_CLASS(ACoin))
-	{
-		return Super::CreateCopy (other);
-	}
-	AInventory *copy = Spawn<ACoin> ();
-	copy->Amount = Amount;
-	copy->BecomeItem ();
-	GoAwayAndDie ();
-	return copy;
-}
-
-//===========================================================================
-//
-// ACoin :: CreateTossable
-//
-// Gold drops in increments of 50 if you have that much, less if you don't.
-//
-//===========================================================================
-
-AInventory *ACoin::CreateTossable ()
-{
-	ACoin *tossed;
-
-	if ((ItemFlags & IF_UNDROPPABLE) || Owner == NULL || Amount <= 0)
-	{
-		return NULL;
-	}
-	if (Amount >= 50)
-	{
-		Amount -= 50;
-		tossed = static_cast<ACoin*>(Spawn("Gold50", Owner->Pos(), NO_REPLACE));
-	}
-	else if (Amount >= 25)
-	{
-		Amount -= 25;
-		tossed = static_cast<ACoin*>(Spawn("Gold25", Owner->Pos(), NO_REPLACE));
-	}
-	else if (Amount >= 10)
-	{
-		Amount -= 10;
-		tossed = static_cast<ACoin*>(Spawn("Gold10", Owner->Pos(), NO_REPLACE));
-	}
-	else if (Amount > 1 || (ItemFlags & IF_KEEPDEPLETED))
-	{
-		Amount -= 1;
-		tossed = static_cast<ACoin*>(Spawn("Coin", Owner->Pos(), NO_REPLACE));
-	}
-	else // Amount == 1 && !(ItemFlags & IF_KEEPDEPLETED)
-	{
-		BecomePickup ();
-		tossed = this;
-	}
-	tossed->flags &= ~(MF_SPECIAL|MF_SOLID);
-	tossed->DropTime = 30;
-	if (tossed != this && Amount <= 0)
-	{
-		Destroy ();
-	}
-	return tossed;
-}
-*/
diff --git a/src/g_strife/a_crusader.cpp b/src/g_strife/a_crusader.cpp
deleted file mode 100644
index 05835a5f98..0000000000
--- a/src/g_strife/a_crusader.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
-#include "actor.h"
-#include "m_random.h"
-#include "a_action.h"
-#include "p_local.h"
-#include "p_enemy.h"
-#include "s_sound.h"
-#include "a_strifeglobal.h"
-#include "vm.h"
-*/
-
-static bool CrusaderCheckRange (AActor *self)
-{
-	if (self->reactiontime == 0 && P_CheckSight (self, self->target))
-	{
-		return self->Distance2D (self->target) < 264.;
-	}
-	return false;
-}
-
-DEFINE_ACTION_FUNCTION(AActor, A_CrusaderChoose)
-{
-	PARAM_SELF_PROLOGUE(AActor);
-
-	if (self->target == NULL)
-		return 0;
-
-	if (CrusaderCheckRange (self))
-	{
-		A_FaceTarget (self);
-		self->Angles.Yaw -= 180./16;
-		P_SpawnMissileZAimed (self, self->Z() + 40, self->target, PClass::FindActor("FastFlameMissile"));
-	}
-	else
-	{
-		if (P_CheckMissileRange (self))
-		{
-			A_FaceTarget (self);
-			P_SpawnMissileZAimed (self, self->Z() + 56, self->target, PClass::FindActor("CrusaderMissile"));
-			self->Angles.Yaw -= 45./32;
-			P_SpawnMissileZAimed (self, self->Z() + 40, self->target, PClass::FindActor("CrusaderMissile"));
-			self->Angles.Yaw += 45./16;
-			P_SpawnMissileZAimed (self, self->Z() + 40, self->target, PClass::FindActor("CrusaderMissile"));
-			self->Angles.Yaw -= 45./16;
-			self->reactiontime += 15;
-		}
-		self->SetState (self->SeeState);
-	}
-	return 0;
-}
-
-DEFINE_ACTION_FUNCTION(AActor, A_CrusaderSweepLeft)
-{
-	PARAM_SELF_PROLOGUE(AActor);
-
-	self->Angles.Yaw += 90./16;
-	AActor *misl = P_SpawnMissileZAimed (self, self->Z() + 48, self->target, PClass::FindActor("FastFlameMissile"));
-	if (misl != NULL)
-	{
-		misl->Vel.Z += 1;
-	}
-	return 0;
-}
-
-DEFINE_ACTION_FUNCTION(AActor, A_CrusaderSweepRight)
-{
-	PARAM_SELF_PROLOGUE(AActor);
-
-	self->Angles.Yaw -= 90./16;
-	AActor *misl = P_SpawnMissileZAimed (self, self->Z() + 48, self->target, PClass::FindActor("FastFlameMissile"));
-	if (misl != NULL)
-	{
-		misl->Vel.Z += 1;
-	}
-	return 0;
-}
-
-DEFINE_ACTION_FUNCTION(AActor, A_CrusaderRefire)
-{
-	PARAM_SELF_PROLOGUE(AActor);
-
-	if (self->target == NULL ||
-		self->target->health <= 0 ||
-		!P_CheckSight (self, self->target))
-	{
-		self->SetState (self->SeeState);
-	}
-	return 0;
-}
-
-DEFINE_ACTION_FUNCTION(AActor, A_CrusaderDeath)
-{
-	PARAM_SELF_PROLOGUE(AActor);
-
-	if (CheckBossDeath (self))
-	{
-		EV_DoFloor (DFloor::floorLowerToLowest, NULL, 667, 1., 0., -1, 0, false);
-	}
-	return 0;
-}
diff --git a/src/g_strife/a_strifestuff.cpp b/src/g_strife/a_strifestuff.cpp
index 78ceaa0971..d38e4130bb 100644
--- a/src/g_strife/a_strifestuff.cpp
+++ b/src/g_strife/a_strifestuff.cpp
@@ -24,8 +24,6 @@
 #include "vm.h"
 
 // Include all the other Strife stuff here to reduce compile time
-#include "a_coin.cpp"
-#include "a_crusader.cpp"
 #include "a_inquisitor.cpp"
 #include "a_loremaster.cpp"
 //#include "a_macil.cpp"
diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp
index 0f58b600c4..93c9b80f35 100644
--- a/src/p_mobj.cpp
+++ b/src/p_mobj.cpp
@@ -6520,6 +6520,15 @@ AActor *P_SpawnMissileZAimed (AActor *source, double z, AActor *dest, PClassActo
 	return P_SpawnMissileAngleZSpeed (source, z, type, an, vz, speed);
 }
 
+DEFINE_ACTION_FUNCTION(AActor, SpawnMissileZAimed)
+{
+	PARAM_SELF_PROLOGUE(AActor);
+	PARAM_FLOAT(z);
+	PARAM_OBJECT(dest, AActor);
+	PARAM_CLASS(type, AActor);
+	ACTION_RETURN_OBJECT(P_SpawnMissileZAimed(self, z, dest, type));
+}
+
 //---------------------------------------------------------------------------
 //
 // FUNC P_SpawnMissileAngleZSpeed
diff --git a/wadsrc/static/zscript/actor.txt b/wadsrc/static/zscript/actor.txt
index cdcc630b5e..3b49e3e3c3 100644
--- a/wadsrc/static/zscript/actor.txt
+++ b/wadsrc/static/zscript/actor.txt
@@ -310,6 +310,7 @@ class Actor : Thinker native
 	native Actor SpawnMissileXYZ(Vector3 pos, Actor dest, Class<Actor> type, bool checkspawn = true, Actor owner = null);
 	native Actor SpawnMissileZ (double z, Actor dest, class<Actor> type);
 	native Actor SpawnMissileAngleZSpeed (double z, class<Actor> type, double angle, double vz, double speed, Actor owner = null, bool checkspawn = true);
+	native Actor SpawnMissileZAimed (double z, Actor dest, Class<Actor> type);
 	native Actor SpawnSubMissile(Class<Actor> type, Actor target);
 	native Actor, Actor SpawnPlayerMissile(class<Actor> type, double angle = 0, double x = 0, double y = 0, double z = 0, out FTranslatedLineTarget pLineTarget = null, bool nofreeaim = false, bool noautoaim = false, int aimflags = 0);
 	native void SpawnTeleportFog(Vector3 pos, bool beforeTele, bool setTarget);
diff --git a/wadsrc/static/zscript/strife/crusader.txt b/wadsrc/static/zscript/strife/crusader.txt
index 02b08fc937..834464e063 100644
--- a/wadsrc/static/zscript/strife/crusader.txt
+++ b/wadsrc/static/zscript/strife/crusader.txt
@@ -28,12 +28,6 @@ class Crusader : Actor
 		Obituary "$OB_CRUSADER";
 	}
 
-	native void A_CrusaderChoose ();
-	native void A_CrusaderSweepLeft ();
-	native void A_CrusaderSweepRight ();
-	native void A_CrusaderRefire ();
-	native void A_CrusaderDeath ();
-
 	States
 	{
 	Spawn:
@@ -66,6 +60,83 @@ class Crusader : Actor
 		ROB2 P -1 A_CrusaderDeath;
 		Stop;
 	}
+	
+// Crusader -----------------------------------------------------------------
+
+	private bool CrusaderCheckRange ()
+	{
+		if (reactiontime == 0 && CheckSight (target))
+		{
+			return Distance2D (target) < 264.;
+		}
+		return false;
+	}
+
+	void A_CrusaderChoose ()
+	{
+		if (target == null)
+			return;
+
+		if (CrusaderCheckRange ())
+		{
+			A_FaceTarget ();
+			angle -= 180./16;
+			SpawnMissileZAimed (pos.z + 40, target, "FastFlameMissile");
+		}
+		else
+		{
+			if (CheckMissileRange ())
+			{
+				A_FaceTarget ();
+				SpawnMissileZAimed (pos.z + 56, target, "CrusaderMissile");
+				angle -= 45./32;
+				SpawnMissileZAimed (pos.z + 40, target, "CrusaderMissile");
+				angle += 45./16;
+				SpawnMissileZAimed (pos.z + 40, target, "CrusaderMissile");
+				angle -= 45./16;
+				reactiontime += 15;
+			}
+			SetState (SeeState);
+		}
+	}
+
+	void A_CrusaderSweepLeft ()
+	{
+		angle += 90./16;
+		Actor misl = SpawnMissileZAimed (pos.z + 48, target, "FastFlameMissile");
+		if (misl != null)
+		{
+			misl.Vel.Z += 1;
+		}
+	}
+
+	void A_CrusaderSweepRight ()
+	{
+		angle -= 90./16;
+		Actor misl = SpawnMissileZAimed (pos.z + 48, target, "FastFlameMissile");
+		if (misl != null)
+		{
+			misl.Vel.Z += 1;
+		}
+	}
+
+	void A_CrusaderRefire ()
+	{
+		if (target == null ||
+			target.health <= 0 ||
+			!CheckSight (target))
+		{
+			SetState (SeeState);
+		}
+	}
+
+	void A_CrusaderDeath ()
+	{
+		if (CheckBossDeath ())
+		{
+			Floor_LowerToLowest(667, 8);
+		}
+	}
 }
 
 
@@ -105,7 +176,7 @@ class CrusaderMissile : Actor
 		MICR A 6 Bright A_RocketInFlight;
 		Loop;
 	Death:
-		SMIS A 0 Bright A_SetTranslucent(1,1);
+		SMIS A 0 Bright A_SetRenderStyle(1, STYLE_Normal);
 		SMIS A 5 Bright;
 		SMIS B 5 Bright;
 		SMIS C 4 Bright;