diff --git a/src/g_heretic/a_hereticweaps.cpp b/src/g_heretic/a_hereticweaps.cpp
index dc34fd206..196bd3240 100644
--- a/src/g_heretic/a_hereticweaps.cpp
+++ b/src/g_heretic/a_hereticweaps.cpp
@@ -15,10 +15,6 @@
 #include "doomstat.h"
 */
 
-static FRandom pr_sap ("StaffAtkPL1");
-static FRandom pr_sap2 ("StaffAtkPL2");
-static FRandom pr_fgw ("FireWandPL1");
-static FRandom pr_fgw2 ("FireWandPL2");
 static FRandom pr_boltspark ("BoltSpark");
 static FRandom pr_macerespawn ("MaceRespawn");
 static FRandom pr_maceatk ("FireMacePL1");
@@ -50,134 +46,6 @@ void P_DSparilTeleport (AActor *actor);
 
 extern bool P_AutoUseChaosDevice (player_t *player);
 
-// --- Staff ----------------------------------------------------------------
-
-//----------------------------------------------------------------------------
-//
-// PROC A_StaffAttackPL1
-//
-//----------------------------------------------------------------------------
-
-DEFINE_ACTION_FUNCTION(AActor, A_StaffAttack)
-{
-	PARAM_ACTION_PROLOGUE(AActor);
-
-	DAngle angle;
-	DAngle slope;
-	player_t *player;
-	FTranslatedLineTarget t;
-
-	if (NULL == (player = self->player))
-	{
-		return 0;
-	}
-
-	PARAM_INT	(damage);
-	PARAM_CLASS	(puff, AActor);
-
-	AWeapon *weapon = player->ReadyWeapon;
-	if (weapon != NULL)
-	{
-		if (!weapon->DepleteAmmo (weapon->bAltFire))
-			return 0;
-	}
-	if (puff == NULL)
-	{
-		puff = PClass::FindActor(NAME_BulletPuff);	// just to be sure
-	}
-	angle = self->Angles.Yaw + pr_sap.Random2() * (5.625 / 256);
-	slope = P_AimLineAttack (self, angle, MELEERANGE);
-	P_LineAttack (self, angle, MELEERANGE, slope, damage, NAME_Melee, puff, true, &t);
-	if (t.linetarget)
-	{
-		//S_StartSound(player->mo, sfx_stfhit);
-		// turn to face target
-		self->Angles.Yaw = t.angleFromSource;
-	}
-	return 0;
-}
-
-
-//----------------------------------------------------------------------------
-//
-// PROC A_FireGoldWandPL1
-//
-//----------------------------------------------------------------------------
-
-DEFINE_ACTION_FUNCTION(AActor, A_FireGoldWandPL1)
-{
-	PARAM_ACTION_PROLOGUE(AActor);
-
-	DAngle angle;
-	int damage;
-	player_t *player;
-
-	if (NULL == (player = self->player))
-	{
-		return 0;
-	}
-
-	AWeapon *weapon = player->ReadyWeapon;
-	if (weapon != NULL)
-	{
-		if (!weapon->DepleteAmmo(weapon->bAltFire))
-			return 0;
-	}
-	DAngle pitch = P_BulletSlope(self);
-	damage = 7 + (pr_fgw() & 7);
-	angle = self->Angles.Yaw;
-	if (player->refire)
-	{
-		angle += pr_fgw.Random2() * (5.625 / 256);
-	}
-	P_LineAttack(self, angle, PLAYERMISSILERANGE, pitch, damage, NAME_Hitscan, "GoldWandPuff1");
-	S_Sound(self, CHAN_WEAPON, "weapons/wandhit", 1, ATTN_NORM);
-	return 0;
-}
-
-//----------------------------------------------------------------------------
-//
-// PROC A_FireGoldWandPL2
-//
-//----------------------------------------------------------------------------
-
-DEFINE_ACTION_FUNCTION(AActor, A_FireGoldWandPL2)
-{
-	PARAM_ACTION_PROLOGUE(AActor);
-
-	int i;
-	DAngle angle;
-	int damage;
-	double vz;
-	player_t *player;
-
-	if (NULL == (player = self->player))
-	{
-		return 0;
-	}
-
-	AWeapon *weapon = player->ReadyWeapon;
-	if (weapon != NULL)
-	{
-		if (!weapon->DepleteAmmo (weapon->bAltFire))
-			return 0;
-	}
-	DAngle pitch = P_BulletSlope(self);
-
-	vz = -GetDefaultByName("GoldWandFX2")->Speed * pitch.TanClamped();
-	P_SpawnMissileAngle(self, PClass::FindActor("GoldWandFX2"), self->Angles.Yaw - (45. / 8), vz);
-	P_SpawnMissileAngle(self, PClass::FindActor("GoldWandFX2"), self->Angles.Yaw + (45. / 8), vz);
-	angle = self->Angles.Yaw - (45. / 8);
-	for(i = 0; i < 5; i++)
-	{
-		damage = 1+(pr_fgw2()&7);
-		P_LineAttack (self, angle, PLAYERMISSILERANGE, pitch, damage, NAME_Hitscan, "GoldWandPuff2");
-		angle += ((45. / 8) * 2) / 4;
-	}
-	S_Sound (self, CHAN_WEAPON, "weapons/wandhit", 1, ATTN_NORM);
-	return 0;
-}
-
 //----------------------------------------------------------------------------
 //
 // PROC A_FireCrossbowPL1
@@ -323,20 +191,20 @@ DEFINE_ACTION_FUNCTION(AActor, A_GauntletAttack)
 		S_Sound (self, CHAN_AUTO, "weapons/gauntletshit", 1, ATTN_NORM);
 	}
 	// turn to face target
-	DAngle angle = t.angleFromSource;
-	DAngle anglediff = deltaangle(self->Angles.Yaw, angle);
+	DAngle ang = t.angleFromSource;
+	DAngle anglediff = deltaangle(self->Angles.Yaw, ang);
 
 	if (anglediff < 0.0)
 	{
 		if (anglediff < -4.5)
-			self->Angles.Yaw = angle + 90.0 / 21;
+			self->Angles.Yaw = ang + 90.0 / 21;
 		else
 			self->Angles.Yaw -= 4.5;
 	}
 	else
 	{
 		if (anglediff > 4.5)
-			self->Angles.Yaw = angle - 90.0 / 21;
+			self->Angles.Yaw = ang - 90.0 / 21;
 		else
 			self->Angles.Yaw += 4.5;
 	}
@@ -477,9 +345,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_MacePL1Check)
 	// [RH] Avoid some precision loss by scaling the velocity directly
 #if 0
 	// This is the original code, for reference.
-	a.ngle_t angle = self->angle>>ANGLETOF.INESHIFT;
-	self->velx = F.ixedMul(7*F.RACUNIT, f.inecosine[angle]);
-	self->vely = F.ixedMul(7*F.RACUNIT, f.inesine[angle]);
+	a.ngle_t ang = self->ang>>ANGLETOF.INESHIFT;
+	self->velx = F.ixedMul(7*F.RACUNIT, f.inecosine[ang]);
+	self->vely = F.ixedMul(7*F.RACUNIT, f.inesine[ang]);
 #else
 	double velscale = 7 / self->Vel.XY().Length();
 	self->Vel.X *= velscale;
@@ -621,7 +489,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_DeathBallImpact)
 
 	int i;
 	AActor *target;
-	DAngle angle = 0.;
+	DAngle ang = 0.;
 	bool newAngle;
 	FTranslatedLineTarget t;
 
@@ -648,29 +516,29 @@ DEFINE_ACTION_FUNCTION(AActor, A_DeathBallImpact)
 			}
 			else
 			{ // Seek
-				angle = self->AngleTo(target);
+				ang = self->AngleTo(target);
 				newAngle = true;
 			}
 		}
 		else
 		{ // Find new target
-			angle = 0.;
+			ang = 0.;
 			for (i = 0; i < 16; i++)
 			{
-				P_AimLineAttack (self, angle, 640., &t, 0., ALF_NOFRIENDS|ALF_PORTALRESTRICT, NULL, self->target);
+				P_AimLineAttack (self, ang, 640., &t, 0., ALF_NOFRIENDS|ALF_PORTALRESTRICT, NULL, self->target);
 				if (t.linetarget && self->target != t.linetarget)
 				{
 					self->tracer = t.linetarget;
-					angle = t.angleFromSource;
+					ang = t.angleFromSource;
 					newAngle = true;
 					break;
 				}
-				angle += 22.5;
+				ang += 22.5;
 			}
 		}
 		if (newAngle)
 		{
-			self->Angles.Yaw = angle;
+			self->Angles.Yaw = ang;
 			self->VelFromAngle();
 		}
 		self->SetState (self->SpawnState);
@@ -762,7 +630,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireBlasterPL1)
 {
 	PARAM_ACTION_PROLOGUE(AActor);
 
-	DAngle angle;
+	DAngle ang;
 	int damage;
 	player_t *player;
 
@@ -779,12 +647,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireBlasterPL1)
 	}
 	DAngle pitch = P_BulletSlope(self);
 	damage = pr_fb1.HitDice (4);
-	angle = self->Angles.Yaw;
+	ang = self->Angles.Yaw;
 	if (player->refire)
 	{
-		angle += pr_fb1.Random2() * (5.625 / 256);
+		ang += pr_fb1.Random2() * (5.625 / 256);
 	}
-	P_LineAttack (self, angle, PLAYERMISSILERANGE, pitch, damage, NAME_Hitscan, "BlasterPuff");
+	P_LineAttack (self, ang, PLAYERMISSILERANGE, pitch, damage, NAME_Hitscan, "BlasterPuff");
 	S_Sound (self, CHAN_WEAPON, "weapons/blastershoot", 1, ATTN_NORM);
 	return 0;
 }
@@ -800,15 +668,15 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpawnRippers)
 	PARAM_SELF_PROLOGUE(AActor);
 
 	unsigned int i;
-	DAngle angle;
+	DAngle ang;
 	AActor *ripper;
 
 	for(i = 0; i < 8; i++)
 	{
 		ripper = Spawn<ARipper> (self->Pos(), ALLOW_REPLACE);
-		angle = i*45.;
+		ang = i*45.;
 		ripper->target = self->target;
-		ripper->Angles.Yaw = angle;
+		ripper->Angles.Yaw = ang;
 		ripper->VelFromAngle();
 		P_CheckMissileSpawn (ripper, self->radius);
 	}
@@ -1207,17 +1075,17 @@ DEFINE_ACTION_FUNCTION(AActor, A_PhoenixPuff)
 	PARAM_SELF_PROLOGUE(AActor);
 
 	AActor *puff;
-	DAngle angle;
+	DAngle ang;
 
 	//[RH] Heretic never sets the target for seeking
 	//P_SeekerMissile (self, 5, 10);
 	puff = Spawn("PhoenixPuff", self->Pos(), ALLOW_REPLACE);
-	angle = self->Angles.Yaw + 90;
-	puff->Vel = DVector3(angle.ToVector(1.3), 0);
+	ang = self->Angles.Yaw + 90;
+	puff->Vel = DVector3(ang.ToVector(1.3), 0);
 
 	puff = Spawn("PhoenixPuff", self->Pos(), ALLOW_REPLACE);
-	angle = self->Angles.Yaw - 90;
-	puff->Vel = DVector3(angle.ToVector(1.3), 0);
+	ang = self->Angles.Yaw - 90;
+	puff->Vel = DVector3(ang.ToVector(1.3), 0);
 	return 0;
 }
 
diff --git a/src/sc_man_tokens.h b/src/sc_man_tokens.h
index 8ea05d7e4..dfa6c044c 100644
--- a/src/sc_man_tokens.h
+++ b/src/sc_man_tokens.h
@@ -49,6 +49,7 @@ xx(TK_Until,				"'until'")
 xx(TK_While,				"'while'")
 xx(TK_Bool,					"'bool'")
 xx(TK_Float,				"'float'")
+xx(TK_Float32,				"'float32'")
 xx(TK_Double,				"'double'")
 xx(TK_Char,					"'char'")
 xx(TK_Byte,					"'byte'")
diff --git a/wadsrc/static/zscript.txt b/wadsrc/static/zscript.txt
index fdf057b58..1e73cc0dd 100644
--- a/wadsrc/static/zscript.txt
+++ b/wadsrc/static/zscript.txt
@@ -95,6 +95,8 @@ zscript/heretic/wizard.txt
 zscript/heretic/ironlich.txt
 zscript/heretic/dsparil.txt
 zscript/heretic/chicken.txt
+zscript/heretic/weaponstaff.txt
+zscript/heretic/weaponwand.txt
 
 zscript/hexen/baseweapons.txt
 zscript/hexen/korax.txt
diff --git a/wadsrc/static/zscript/heretic/hereticweaps.txt b/wadsrc/static/zscript/heretic/hereticweaps.txt
index e309ba095..00985b2ba 100644
--- a/wadsrc/static/zscript/heretic/hereticweaps.txt
+++ b/wadsrc/static/zscript/heretic/hereticweaps.txt
@@ -8,276 +8,6 @@ class HereticWeapon : Weapon
 }
 
 
-// Staff --------------------------------------------------------------------
-
-class Staff : HereticWeapon
-{
-	Default
-	{
-		Weapon.SelectionOrder 3800;
-		+THRUGHOST
-		+WEAPON.WIMPY_WEAPON
-		+WEAPON.MELEEWEAPON
-		Weapon.sisterweapon "StaffPowered";
-		Obituary "$OB_MPSTAFF";
-		Tag "$TAG_STAFF";
-	}
-
-	action native void A_StaffAttack (int damage, class<Actor> puff);
-
-	States
-	{
-	Ready:	
-		STFF A 1 A_WeaponReady;
-		Loop;
-	Deselect:
-		STFF A 1 A_Lower;
-		Loop;
-	Select:
-		STFF A 1 A_Raise;
-		Loop;
-	Fire:
-		STFF B 6;
-		STFF C 8 A_StaffAttack(random[StaffAttack](5, 20), "StaffPuff");
-		STFF B 8 A_ReFire;
-		Goto Ready;
-	}
-}
-
-class StaffPowered : Staff
-{
-	Default
-	{
-		Weapon.sisterweapon "Staff";
-		Weapon.ReadySound "weapons/staffcrackle";
-		+WEAPON.POWERED_UP
-		+WEAPON.READYSNDHALF
-		+WEAPON.STAFF2_KICKBACK
-		Obituary "$OB_MPPSTAFF";
-		Tag "$TAG_STAFFP";
-	}
-
-	States
-	{
-	Ready:	
-		STFF DEF 4 A_WeaponReady;
-		Loop;
-	Deselect:
-		STFF D 1 A_Lower;
-		Loop;
-	Select:
-		STFF D 1 A_Raise;
-		Loop;
-	Fire:
-		STFF G 6;
-		STFF H 8 A_StaffAttack(random[StaffAttack](18, 81), "StaffPuff2");
-		STFF G 8 A_ReFire;
-		Goto Ready;
-	}
-}
-
-
-// Staff puff ---------------------------------------------------------------
-
-class StaffPuff : Actor
-{
-	Default
-	{
-		RenderStyle "Translucent";
-		Alpha 0.4;
-		VSpeed 1;
-		+NOBLOCKMAP
-		+NOGRAVITY
-		+PUFFONACTORS
-		AttackSound "weapons/staffhit";
-	}
-
-	States
-	{
-	Spawn:
-		PUF3 A 4 BRIGHT;
-		PUF3 BCD 4;
-		Stop;
-	}
-}
-
-// Staff puff 2 -------------------------------------------------------------
-
-class StaffPuff2 : Actor
-{
-	Default
-	{
-		RenderStyle "Add";
-		+NOBLOCKMAP
-		+NOGRAVITY
-		+PUFFONACTORS
-		AttackSound "weapons/staffpowerhit";
-	}
-
-	States
-	{
-	Spawn:
-		PUF4 ABCDEF 4 BRIGHT;
-		Stop;
-	}
-}	
-
-
-
-// Gold wand ----------------------------------------------------------------
-
-class GoldWand : HereticWeapon
-{
-	Default
-	{
-		+BLOODSPLATTER
-		Weapon.SelectionOrder 2000;
-		Weapon.AmmoGive 25;
-		Weapon.AmmoUse 1;
-		Weapon.AmmoType "GoldWandAmmo";
-		Weapon.SisterWeapon "GoldWandPowered";
-		Weapon.YAdjust 5;
-		Inventory.PickupMessage "$TXT_WPNGOLDWAND";
-		Obituary "$OB_MPGOLDWAND";
-		Tag "$TAG_GOLDWAND";
-	}
-
-	action native void A_FireGoldWandPL1 ();
-	
-	States
-	{
-	Spawn:
-		GWAN A -1;
-		Stop;
-	Ready:
-		GWND A 1 A_WeaponReady;
-		Loop;
-	Deselect:
-		GWND A 1 A_Lower;
-		Loop;
-	Select:
-		GWND A 1 A_Raise;
-		Loop;
-	Fire:
-		GWND B 3;
-		GWND C 5 A_FireGoldWandPL1;
-		GWND D 3;
-		GWND D 0 A_ReFire;
-		Goto Ready;
-	}
-}
-
-class GoldWandPowered : GoldWand
-{
-	Default
-	{
-		+WEAPON.POWERED_UP
-		Weapon.AmmoGive 0;
-		Weapon.SisterWeapon "GoldWand";
-		Obituary "$OB_MPPGOLDWAND";
-		Tag "$TAG_GOLDWANDP";
-	}
-
-	action native void A_FireGoldWandPL2 ();
-
-	States
-	{
-	Fire:
-		GWND B 3;
-		GWND C 4 A_FireGoldWandPL2;
-		GWND D 3;
-		GWND D 0 A_ReFire;
-		Goto Ready;
-	}
-}
-	
-
-// Gold wand FX1 ------------------------------------------------------------
-
-class GoldWandFX1 : Actor
-{
-	Default
-	{
-		Radius 10;
-		Height 6;
-		Speed 22;
-		Damage 2;
-		Projectile;
-		RenderStyle "Add";
-		DeathSound "weapons/wandhit";
-		Obituary "$OB_MPPGOLDWAND";
-	}
-
-	States
-	{
-	Spawn:
-		FX01 AB 6 BRIGHT;
-		Loop;
-	Death:
-		FX01 EFGH 3 BRIGHT;
-		Stop;
-	}
-}
-
-// Gold wand FX2 ------------------------------------------------------------
-
-class GoldWandFX2 : GoldWandFX1
-{
-	Default
-	{
-		Speed 18;
-		Damage 1;
-		DeathSound "";
-	}
-
-	States
-	{
-	Spawn:
-		FX01 CD 6 BRIGHT;
-		Loop;
-	}
-}
-
-// Gold wand puff 1 ---------------------------------------------------------
-
-class GoldWandPuff1 : Actor
-{
-	Default
-	{
-		+NOBLOCKMAP
-		+NOGRAVITY
-		+PUFFONACTORS
-		RenderStyle "Add";
-	}
-
-	States
-	{
-	Spawn:
-		PUF2 ABCDE 3 BRIGHT;
-		Stop;
-	}
-}
-
-// Gold wand puff 2 ---------------------------------------------------------
-
-class GoldWandPuff2 : GoldWandFX1
-{
-	Default
-	{
-		Skip_Super;
-		+NOBLOCKMAP
-		+NOGRAVITY
-		+PUFFONACTORS
-	}
-
-	States
-	{
-	Spawn:
-		Goto Super::Death;
-	}
-}
-
-
 // Crossbow -----------------------------------------------------------------
 
 class Crossbow : HereticWeapon
diff --git a/wadsrc/static/zscript/heretic/weaponstaff.txt b/wadsrc/static/zscript/heretic/weaponstaff.txt
new file mode 100644
index 000000000..6349bd61b
--- /dev/null
+++ b/wadsrc/static/zscript/heretic/weaponstaff.txt
@@ -0,0 +1,147 @@
+// Staff --------------------------------------------------------------------
+
+class Staff : HereticWeapon
+{
+	Default
+	{
+		Weapon.SelectionOrder 3800;
+		+THRUGHOST
+		+WEAPON.WIMPY_WEAPON
+		+WEAPON.MELEEWEAPON
+		Weapon.sisterweapon "StaffPowered";
+		Obituary "$OB_MPSTAFF";
+		Tag "$TAG_STAFF";
+	}
+
+
+	States
+	{
+	Ready:	
+		STFF A 1 A_WeaponReady;
+		Loop;
+	Deselect:
+		STFF A 1 A_Lower;
+		Loop;
+	Select:
+		STFF A 1 A_Raise;
+		Loop;
+	Fire:
+		STFF B 6;
+		STFF C 8 A_StaffAttack(random[StaffAttack](5, 20), "StaffPuff");
+		STFF B 8 A_ReFire;
+		Goto Ready;
+	}
+	
+	//----------------------------------------------------------------------------
+	//
+	// PROC A_StaffAttackPL1
+	//
+	//----------------------------------------------------------------------------
+
+	action void A_StaffAttack (int damage, class<Actor> puff)
+	{
+		FTranslatedLineTarget t;
+
+		if (player == null)
+		{
+			return;
+		}
+
+		Weapon weapon = player.ReadyWeapon;
+		if (weapon != null)
+		{
+			if (!weapon.DepleteAmmo (weapon.bAltFire))
+				return;
+		}
+		double ang = angle + Random2[StaffAtk]() * (5.625 / 256);
+		double slope = AimLineAttack (ang, MELEERANGE);
+		LineAttack (ang, MELEERANGE, slope, damage, 'Melee', puff, true, t);
+		if (t.linetarget)
+		{
+			//S_StartSound(player.mo, sfx_stfhit);
+			// turn to face target
+			angle = t.angleFromSource;
+		}
+	}
+}
+
+class StaffPowered : Staff
+{
+	Default
+	{
+		Weapon.sisterweapon "Staff";
+		Weapon.ReadySound "weapons/staffcrackle";
+		+WEAPON.POWERED_UP
+		+WEAPON.READYSNDHALF
+		+WEAPON.STAFF2_KICKBACK
+		Obituary "$OB_MPPSTAFF";
+		Tag "$TAG_STAFFP";
+	}
+
+	States
+	{
+	Ready:	
+		STFF DEF 4 A_WeaponReady;
+		Loop;
+	Deselect:
+		STFF D 1 A_Lower;
+		Loop;
+	Select:
+		STFF D 1 A_Raise;
+		Loop;
+	Fire:
+		STFF G 6;
+		STFF H 8 A_StaffAttack(random[StaffAttack](18, 81), "StaffPuff2");
+		STFF G 8 A_ReFire;
+		Goto Ready;
+	}
+}
+
+
+// Staff puff ---------------------------------------------------------------
+
+class StaffPuff : Actor
+{
+	Default
+	{
+		RenderStyle "Translucent";
+		Alpha 0.4;
+		VSpeed 1;
+		+NOBLOCKMAP
+		+NOGRAVITY
+		+PUFFONACTORS
+		AttackSound "weapons/staffhit";
+	}
+
+	States
+	{
+	Spawn:
+		PUF3 A 4 BRIGHT;
+		PUF3 BCD 4;
+		Stop;
+	}
+}
+
+// Staff puff 2 -------------------------------------------------------------
+
+class StaffPuff2 : Actor
+{
+	Default
+	{
+		RenderStyle "Add";
+		+NOBLOCKMAP
+		+NOGRAVITY
+		+PUFFONACTORS
+		AttackSound "weapons/staffpowerhit";
+	}
+
+	States
+	{
+	Spawn:
+		PUF4 ABCDEF 4 BRIGHT;
+		Stop;
+	}
+}	
+
+
+
diff --git a/wadsrc/static/zscript/heretic/weaponwand.txt b/wadsrc/static/zscript/heretic/weaponwand.txt
new file mode 100644
index 000000000..bd1475adb
--- /dev/null
+++ b/wadsrc/static/zscript/heretic/weaponwand.txt
@@ -0,0 +1,217 @@
+// Gold wand ----------------------------------------------------------------
+
+class GoldWand : HereticWeapon
+{
+	Default
+	{
+		+BLOODSPLATTER
+		Weapon.SelectionOrder 2000;
+		Weapon.AmmoGive 25;
+		Weapon.AmmoUse 1;
+		Weapon.AmmoType "GoldWandAmmo";
+		Weapon.SisterWeapon "GoldWandPowered";
+		Weapon.YAdjust 5;
+		Inventory.PickupMessage "$TXT_WPNGOLDWAND";
+		Obituary "$OB_MPGOLDWAND";
+		Tag "$TAG_GOLDWAND";
+	}
+
+	States
+	{
+	Spawn:
+		GWAN A -1;
+		Stop;
+	Ready:
+		GWND A 1 A_WeaponReady;
+		Loop;
+	Deselect:
+		GWND A 1 A_Lower;
+		Loop;
+	Select:
+		GWND A 1 A_Raise;
+		Loop;
+	Fire:
+		GWND B 3;
+		GWND C 5 A_FireGoldWandPL1;
+		GWND D 3;
+		GWND D 0 A_ReFire;
+		Goto Ready;
+	}
+	
+
+	//----------------------------------------------------------------------------
+	//
+	// PROC A_FireGoldWandPL1
+	//
+	//----------------------------------------------------------------------------
+
+	action void A_FireGoldWandPL1 ()
+	{
+		if (player == null)
+		{
+			return;
+		}
+
+		Weapon weapon = player.ReadyWeapon;
+		if (weapon != null)
+		{
+			if (!weapon.DepleteAmmo (weapon.bAltFire))
+				return;
+		}
+		double pitch = BulletSlope();
+		int damage = 7 + random[FireGoldWand]() & 7;
+		double ang = angle;
+		if (player.refire)
+		{
+			ang += Random2[FireGoldWand]() * (5.625 / 256);
+		}
+		LineAttack(ang, PLAYERMISSILERANGE, pitch, damage, 'Hitscan', "GoldWandPuff1");
+		A_PlaySound("weapons/wandhit", CHAN_WEAPON);
+	}
+	
+}
+
+class GoldWandPowered : GoldWand
+{
+	Default
+	{
+		+WEAPON.POWERED_UP
+		Weapon.AmmoGive 0;
+		Weapon.SisterWeapon "GoldWand";
+		Obituary "$OB_MPPGOLDWAND";
+		Tag "$TAG_GOLDWANDP";
+	}
+
+	States
+	{
+	Fire:
+		GWND B 3;
+		GWND C 4 A_FireGoldWandPL2;
+		GWND D 3;
+		GWND D 0 A_ReFire;
+		Goto Ready;
+	}
+	
+	//----------------------------------------------------------------------------
+	//
+	// PROC A_FireGoldWandPL2
+	//
+	//----------------------------------------------------------------------------
+
+	action void A_FireGoldWandPL2 ()
+	{
+		if (player == null)
+		{
+			return;
+		}
+
+		Weapon weapon = player.ReadyWeapon;
+		if (weapon != null)
+		{
+			if (!weapon.DepleteAmmo (weapon.bAltFire))
+				return;
+		}
+		double pitch = BulletSlope();
+
+		double vz = -GetDefaultByType("GoldWandFX2").Speed * clamp(tan(pitch), -5, 5);
+		SpawnMissileAngle("GoldWandFX2", angle - (45. / 8), vz);
+		SpawnMissileAngle("GoldWandFX2", angle + (45. / 8), vz);
+		double ang = angle - (45. / 8);
+		for(int i = 0; i < 5; i++)
+		{
+			int damage = random[FireGoldWand](1, 8);
+			LineAttack (ang, PLAYERMISSILERANGE, pitch, damage, 'Hitscan', "GoldWandPuff2");
+			ang += ((45. / 8) * 2) / 4;
+		}
+		A_PlaySound("weapons/wandhit", CHAN_WEAPON);
+	}
+
+	
+}
+	
+
+// Gold wand FX1 ------------------------------------------------------------
+
+class GoldWandFX1 : Actor
+{
+	Default
+	{
+		Radius 10;
+		Height 6;
+		Speed 22;
+		Damage 2;
+		Projectile;
+		RenderStyle "Add";
+		DeathSound "weapons/wandhit";
+		Obituary "$OB_MPPGOLDWAND";
+	}
+
+	States
+	{
+	Spawn:
+		FX01 AB 6 BRIGHT;
+		Loop;
+	Death:
+		FX01 EFGH 3 BRIGHT;
+		Stop;
+	}
+}
+
+// Gold wand FX2 ------------------------------------------------------------
+
+class GoldWandFX2 : GoldWandFX1
+{
+	Default
+	{
+		Speed 18;
+		Damage 1;
+		DeathSound "";
+	}
+
+	States
+	{
+	Spawn:
+		FX01 CD 6 BRIGHT;
+		Loop;
+	}
+}
+
+// Gold wand puff 1 ---------------------------------------------------------
+
+class GoldWandPuff1 : Actor
+{
+	Default
+	{
+		+NOBLOCKMAP
+		+NOGRAVITY
+		+PUFFONACTORS
+		RenderStyle "Add";
+	}
+
+	States
+	{
+	Spawn:
+		PUF2 ABCDE 3 BRIGHT;
+		Stop;
+	}
+}
+
+// Gold wand puff 2 ---------------------------------------------------------
+
+class GoldWandPuff2 : GoldWandFX1
+{
+	Default
+	{
+		Skip_Super;
+		+NOBLOCKMAP
+		+NOGRAVITY
+		+PUFFONACTORS
+	}
+
+	States
+	{
+	Spawn:
+		Goto Super::Death;
+	}
+}
+