From 4fcb397346b1ffd1a68eb8777a40d89086b20940 Mon Sep 17 00:00:00 2001
From: Christoph Oelckers <c.oelckers@users.noreply.github.com>
Date: Sat, 26 Nov 2016 14:06:41 +0100
Subject: [PATCH] - scriptified the remaining parts of the Wraithverge.

---
 src/CMakeLists.txt                         |   1 -
 src/g_hexen/a_clericholy.cpp               | 173 ---------------------
 src/g_hexen/a_hexenmisc.cpp                |   1 -
 wadsrc/static/zscript/hexen/clericholy.txt | 142 ++++++++++++++++-
 4 files changed, 136 insertions(+), 181 deletions(-)
 delete mode 100644 src/g_hexen/a_clericholy.cpp

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 376d33887..c1242853d 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -855,7 +855,6 @@ set( NOT_COMPILED_SOURCE_FILES
 	${OTHER_SYSTEM_SOURCES}
 	sc_man_scanner.h
 	sc_man_scanner.re
-	g_hexen/a_clericholy.cpp
 	g_hexen/a_clericmace.cpp
 	g_hexen/a_clericstaff.cpp
 	g_hexen/a_fighteraxe.cpp
diff --git a/src/g_hexen/a_clericholy.cpp b/src/g_hexen/a_clericholy.cpp
deleted file mode 100644
index 8ffb5be27..000000000
--- a/src/g_hexen/a_clericholy.cpp
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
-#include "actor.h"
-#include "info.h"
-#include "p_local.h"
-#include "m_random.h"
-#include "s_sound.h"
-#include "a_hexenglobal.h"
-#include "gstrings.h"
-#include "a_weaponpiece.h"
-#include "vm.h"
-#include "g_level.h"
-#include "doomstat.h"
-*/
-
-#define BLAST_FULLSTRENGTH	255
-
-static FRandom pr_holyatk2 ("CHolyAtk2");
-static FRandom pr_holyseeker ("CHolySeeker");
-static FRandom pr_holyweave ("CHolyWeave");
-static FRandom pr_holyseek ("CHolySeek");
-static FRandom pr_checkscream ("CCheckScream");
-static FRandom pr_spiritslam ("CHolySlam");
-static FRandom pr_wraithvergedrop ("WraithvergeDrop");
-
-void SpawnSpiritTail (AActor *spirit);
-
-// Holy Spirit --------------------------------------------------------------
-
-//============================================================================
-//
-// CHolyFindTarget
-//
-//============================================================================
-
-static void CHolyFindTarget (AActor *actor)
-{
-	AActor *target;
-
-	if ( (target = P_RoughMonsterSearch (actor, 6, true)) )
-	{
-		actor->tracer = target;
-		actor->flags |= MF_NOCLIP|MF_SKULLFLY;
-		actor->flags &= ~MF_MISSILE;
-	}
-}
-
-//============================================================================
-//
-// CHolySeekerMissile
-//
-// 	 Similar to P_SeekerMissile, but seeks to a random Z on the target
-//============================================================================
-
-static void CHolySeekerMissile (AActor *actor, DAngle thresh, DAngle turnMax)
-{
-	int dir;
-	DAngle delta;
-	AActor *target;
-	double newZ;
-	double deltaZ;
-
-	target = actor->tracer;
-	if (target == NULL)
-	{
-		return;
-	}
-	if (!(target->flags&MF_SHOOTABLE)
-		|| (!(target->flags3&MF3_ISMONSTER) && !target->player))
-	{ // Target died/target isn't a player or creature
-		actor->tracer = NULL;
-		actor->flags &= ~(MF_NOCLIP | MF_SKULLFLY);
-		actor->flags |= MF_MISSILE;
-		CHolyFindTarget(actor);
-		return;
-	}
-	dir = P_FaceMobj (actor, target, &delta);
-	if (delta > thresh)
-	{
-		delta /= 2;
-		if (delta > turnMax)
-		{
-			delta = turnMax;
-		}
-	}
-	if (dir)
-	{ // Turn clockwise
-		actor->Angles.Yaw += delta;
-	}
-	else
-	{ // Turn counter clockwise
-		actor->Angles.Yaw -= delta;
-	}
-	actor->VelFromAngle();
-
-	if (!(level.time&15) 
-		|| actor->Z() > target->Top()
-		|| actor->Top() < target->Z())
-	{
-		newZ = target->Z() + ((pr_holyseeker()*target->Height) / 256.);
-		deltaZ = newZ - actor->Z();
-		if (fabs(deltaZ) > 15)
-		{
-			if (deltaZ > 0)
-			{
-				deltaZ = 15;
-			}
-			else
-			{
-				deltaZ = -15;
-			}
-		}
-		actor->Vel.Z = deltaZ / actor->DistanceBySpeed(target, actor->Speed);
-	}
-	return;
-}
-
-//============================================================================
-//
-// A_CHolySeek
-//
-//============================================================================
-
-DEFINE_ACTION_FUNCTION(AActor, A_CHolySeek)
-{
-	PARAM_SELF_PROLOGUE(AActor);
-
-	self->health--;
-	if (self->health <= 0)
-	{
-		self->Vel.X /= 4;
-		self->Vel.Y /= 4;
-		self->Vel.Z = 0;
-		self->SetState (self->FindState(NAME_Death));
-		self->tics -= pr_holyseek()&3;
-		return 0;
-	}
-	if (self->tracer)
-	{
-		CHolySeekerMissile (self, (double)self->args[0], self->args[0]*2.);
-		if (!((level.time+7)&15))
-		{
-			self->args[0] = 5+(pr_holyseek()/20);
-		}
-	}
-
-	int xyspeed = (pr_holyweave() % 5);
-	int zspeed = (pr_holyweave() % 5);
-	A_Weave(self, xyspeed, zspeed, 4., 2.);
-	return 0;
-}
-
-//============================================================================
-//
-// A_CHolyCheckScream
-//
-//============================================================================
-
-DEFINE_ACTION_FUNCTION(AActor, A_CHolyCheckScream)
-{
-	PARAM_SELF_PROLOGUE(AActor);
-
-	CALL_ACTION(A_CHolySeek, self);
-	if (pr_checkscream() < 20)
-	{
-		S_Sound (self, CHAN_VOICE, "SpiritActive", 1, ATTN_NORM);
-	}
-	if (!self->tracer)
-	{
-		CHolyFindTarget(self);
-	}
-	return 0;
-}
-
diff --git a/src/g_hexen/a_hexenmisc.cpp b/src/g_hexen/a_hexenmisc.cpp
index cbe9d3c12..7bd38ceab 100644
--- a/src/g_hexen/a_hexenmisc.cpp
+++ b/src/g_hexen/a_hexenmisc.cpp
@@ -24,7 +24,6 @@
 #include "serializer.h"
 
 // Include all the Hexen stuff here to reduce compile time
-#include "a_clericholy.cpp"
 #include "a_clericmace.cpp"
 #include "a_clericstaff.cpp"
 #include "a_fighteraxe.cpp"
diff --git a/wadsrc/static/zscript/hexen/clericholy.txt b/wadsrc/static/zscript/hexen/clericholy.txt
index 593462d00..33b69bf25 100644
--- a/wadsrc/static/zscript/hexen/clericholy.txt
+++ b/wadsrc/static/zscript/hexen/clericholy.txt
@@ -323,9 +323,6 @@ class HolySpirit : Actor
 		Obituary "$OB_MPCWEAPWRAITHVERGE";
 	}
 
-	native void A_CHolySeek();
-	native void A_CHolyCheckScream();
-
 	States
 	{
 	Spawn:
@@ -401,7 +398,140 @@ class HolySpirit : Actor
 		return true;
 	}
 
-	
+	//============================================================================
+	//
+	// CHolyFindTarget
+	//
+	//============================================================================
+
+	private void CHolyFindTarget ()
+	{
+		Actor target;
+
+		if ( (target = RoughMonsterSearch (6, true)) )
+		{
+			tracer = target;
+			bNoClip = true;
+			bSkullFly = true;
+			bMissile = false;
+		}
+	}
+
+	//============================================================================
+	//
+	// CHolySeekerMissile
+	//
+	// 	 Similar to P_SeekerMissile, but seeks to a random Z on the target
+	//============================================================================
+
+	private void CHolySeekerMissile (double thresh, double turnMax)
+	{
+		Actor target = tracer;
+		if (target == NULL)
+		{
+			return;
+		}
+		if (!target.bShootable || (!target.bIsMonster && !target.player))
+		{ // Target died/target isn't a player or creature
+			tracer = null;
+			bNoClip = false;
+			bSkullFly = false;
+			bMissile = true;
+			CHolyFindTarget();
+			return;
+		}
+		double ang = deltaangle(angle, AngleTo(target));
+		double delta = abs(ang);
+		
+		if (delta > thresh)
+		{
+			delta /= 2;
+			if (delta > turnMax)
+			{
+				delta = turnMax;
+			}
+		}
+		if (ang > 0)
+		{ // Turn clockwise
+			angle += delta;
+		}
+		else
+		{ // Turn counter clockwise
+			angle -= delta;
+		}
+		VelFromAngle();
+
+		if (!(level.time&15) 
+			|| pos.z > target.pos.z + target.height
+			|| pos.z + height < target.pos.z)
+		{
+			double newZ = target.pos.z + ((random[HolySeeker]()*target.Height) / 256.);
+			double deltaZ = newZ - pos.z;
+			if (abs(deltaZ) > 15)
+			{
+				if (deltaZ > 0)
+				{
+					deltaZ = 15;
+				}
+				else
+				{
+					deltaZ = -15;
+				}
+			}
+			Vel.Z = deltaZ / DistanceBySpeed(target, Speed);
+		}
+	}
+
+	//============================================================================
+	//
+	// A_CHolySeek
+	//
+	//============================================================================
+
+	void A_CHolySeek()
+	{
+		health--;
+		if (health <= 0)
+		{
+			Vel.X /= 4;
+			Vel.Y /= 4;
+			Vel.Z = 0;
+			SetStateLabel ("Death");
+			tics -= random[HolySeeker]()&3;
+			return;
+		}
+		if (tracer)
+		{
+			CHolySeekerMissile (args[0], args[0]*2.);
+			if (!((level.time+7)&15))
+			{
+				args[0] = 5+(random[HolySeeker]()/20);
+			}
+		}
+
+		int xyspeed = (random[HolySeeker]() % 5);
+		int zspeed = (random[HolySeeker]() % 5);
+		A_Weave(xyspeed, zspeed, 4., 2.);
+	}
+
+	//============================================================================
+	//
+	// A_CHolyCheckScream
+	//
+	//============================================================================
+
+	void A_CHolyCheckScream()
+	{
+		A_CHolySeek();
+		if (random[HolyScream]() < 20)
+		{
+			A_PlaySound ("SpiritActive", CHAN_VOICE);
+		}
+		if (!tracer)
+		{
+			CHolyFindTarget();
+		}
+	}
 }
 
 // Holy Tail ----------------------------------------------------------------
@@ -513,7 +643,7 @@ class HolyTail : Actor
 
 	void A_CHolyTail()
 	{
-		Actor parent = self.target;
+		Actor parent = target;
 
 		if (parent == null || parent.health <= 0)	// better check for health than current state - it's safer!
 		{ // Ghost removed, so remove all tail parts
@@ -524,7 +654,7 @@ class HolyTail : Actor
 		{
 			if (TryMove(parent.Vec2Angle(14., parent.Angle, true), true))
 			{
-				self.SetZ(parent.pos.z - 5.);
+				SetZ(parent.pos.z - 5.);
 			}
 			CHolyTailFollow(10);
 		}