From 64b8409b2d6fb93dc51ba24a82d219c8cd56a907 Mon Sep 17 00:00:00 2001
From: TimePath <andrew.hardaker1995@gmail.com>
Date: Mon, 7 Dec 2015 13:46:01 +1100
Subject: [PATCH] Impulses: migration pathway

---
 qcsrc/client/progs.inc                        |   1 +
 qcsrc/common/impulses/all.qc                  |   1 +
 qcsrc/common/impulses/all.qh                  | 148 ++++++++++++++++++
 qcsrc/common/minigames/sv_minigames.qc        |  11 +-
 qcsrc/common/minigames/sv_minigames.qh        |   2 +-
 qcsrc/common/vehicles/sv_vehicles.qc          |  12 +-
 qcsrc/common/vehicles/sv_vehicles.qh          |   2 +-
 qcsrc/server/cheats.qc                        |  16 +-
 qcsrc/server/cheats.qh                        |  10 +-
 qcsrc/server/cl_client.qc                     |   4 +-
 qcsrc/server/cl_impulse.qc                    |  38 ++---
 qcsrc/server/mutators/mutator/gamemode_ctf.qc |   2 +-
 qcsrc/server/progs.inc                        |   1 +
 13 files changed, 192 insertions(+), 56 deletions(-)
 create mode 100644 qcsrc/common/impulses/all.qc
 create mode 100644 qcsrc/common/impulses/all.qh

diff --git a/qcsrc/client/progs.inc b/qcsrc/client/progs.inc
index 775e031481..2727db46e6 100644
--- a/qcsrc/client/progs.inc
+++ b/qcsrc/client/progs.inc
@@ -45,6 +45,7 @@
 #include "../common/deathtypes/all.qc"
 #include "../common/effects/all.qc"
 #include "../common/gamemodes/all.qc"
+#include "../common/impulses/all.qc"
 #include "../common/items/all.qc"
 #include "../common/monsters/all.qc"
 #include "../common/mutators/all.qc"
diff --git a/qcsrc/common/impulses/all.qc b/qcsrc/common/impulses/all.qc
new file mode 100644
index 0000000000..b056751624
--- /dev/null
+++ b/qcsrc/common/impulses/all.qc
@@ -0,0 +1 @@
+#include "all.qh"
diff --git a/qcsrc/common/impulses/all.qh b/qcsrc/common/impulses/all.qh
new file mode 100644
index 0000000000..7bca7c20fa
--- /dev/null
+++ b/qcsrc/common/impulses/all.qh
@@ -0,0 +1,148 @@
+#ifndef IMPULSES_ALL_H
+#define IMPULSES_ALL_H
+
+REGISTRY(IMPULSES, 255)
+REGISTER_REGISTRY(IMPULSES)
+REGISTRY_SORT(IMPULSES)
+STATIC_INIT(IMPULSES_renumber)
+{
+	FOREACH(IMPULSES, true, LAMBDA(it.m_id = i));
+}
+REGISTRY_CHECK(IMPULSES)
+
+.void(entity this) impulse_handle;
+
+#if defined(CSQC)
+#define IMPULSE_ALIAS(alias, id) localcmd("\nalias " #alias " \"" id "\"\n")
+#else
+#define IMPULSE_ALIAS(alias, id)
+#endif
+
+#define REGISTER_IMPULSE(id, n) _REGISTER_IMPULSE(IMP_##id, id, n)
+#define _REGISTER_IMPULSE(id, alias, n) \
+	REGISTER(IMPULSES, id, m_id, new(Impulse)) \
+	{ \
+		make_pure(this); \
+		this.impulse = n; \
+		IMPULSE_ALIAS(alias, "impulse " #n); \
+	}
+
+#define LEGACY_IMPULSE(alias, id, new) \
+	STATIC_INIT(legacy_##alias) { IMPULSE_ALIAS(alias, new); } \
+	SHUTDOWN(legacy_##alias) { IMPULSE_ALIAS(alias, "impulse " #id); }
+
+#define X(slot, imp) \
+	REGISTER_IMPULSE(weapon_group_##slot, imp) LEGACY_IMPULSE(weapon_group_##slot, imp, "impulse" #imp)
+X(1, 1)
+X(2, 2)
+X(3, 3)
+X(4, 4)
+X(5, 5)
+X(6, 6)
+X(7, 7)
+X(8, 8)
+X(9, 9)
+X(0, 14)
+#undef X
+
+REGISTER_IMPULSE(weapon_next_byid, 10)
+LEGACY_IMPULSE(_weapnext_2, 10, "weapon_next_byid")
+
+REGISTER_IMPULSE(weapon_prev_byid, 12)
+LEGACY_IMPULSE(_weapprev_2, 12, "weapon_prev_byid")
+
+REGISTER_IMPULSE(weapon_next_bygroup, 18)
+LEGACY_IMPULSE(_weapnext_0, 18, "weapon_next_bygroup")
+
+REGISTER_IMPULSE(weapon_prev_bygroup, 19)
+LEGACY_IMPULSE(_weapprev_0, 19, "weapon_prev_bygroup")
+
+REGISTER_IMPULSE(weapon_next_bypriority, 15)
+LEGACY_IMPULSE(_weapnext_1, 15, "weapon_next_bypriority")
+
+REGISTER_IMPULSE(weapon_prev_bypriority, 16)
+LEGACY_IMPULSE(_weapprev_1, 16, "weapon_prev_bypriority")
+
+REGISTER_IMPULSE(weapon_last, 11)
+LEGACY_IMPULSE(weaplast, 11, "weapon_last")
+
+REGISTER_IMPULSE(weapon_best, 13)
+LEGACY_IMPULSE(weapbest, 13, "weapon_best")
+
+REGISTER_IMPULSE(weapon_drop, 17)
+LEGACY_IMPULSE(dropweapon, 17, "weapon_drop")
+
+REGISTER_IMPULSE(weapon_reload, 20)
+LEGACY_IMPULSE(reload, 20, "weapon_reload")
+
+REGISTER_IMPULSE(use, 21)
+LEGACY_IMPULSE(use, 21, "use")
+
+REGISTER_IMPULSE(waypoint_personal_here, 30)
+LEGACY_IMPULSE(g_waypointsprite_personal, 30, "waypoint_personal_here")
+
+REGISTER_IMPULSE(waypoint_personal_crosshair, 31)
+LEGACY_IMPULSE(g_waypointsprite_personal_p, 31, "waypoint_personal_crosshair")
+
+REGISTER_IMPULSE(waypoint_personal_death, 32)
+LEGACY_IMPULSE(g_waypointsprite_personal_d, 32, "waypoint_personal_death")
+
+REGISTER_IMPULSE(waypoint_here_follow, 33)
+LEGACY_IMPULSE(g_waypointsprite_team_helpme, 33, "waypoint_here_follow")
+
+REGISTER_IMPULSE(waypoint_here_here, 34)
+LEGACY_IMPULSE(g_waypointsprite_team_here, 34, "waypoint_here_here")
+
+REGISTER_IMPULSE(waypoint_here_crosshair, 35)
+LEGACY_IMPULSE(g_waypointsprite_team_here_p, 35, "waypoint_here_crosshair")
+
+REGISTER_IMPULSE(waypoint_here_death, 36)
+LEGACY_IMPULSE(g_waypointsprite_team_here_d, 36, "waypoint_here_death")
+
+REGISTER_IMPULSE(waypoint_danger_here, 37)
+LEGACY_IMPULSE(g_waypointsprite_team_danger, 37, "waypoint_danger_here")
+
+REGISTER_IMPULSE(waypoint_danger_crosshair, 38)
+LEGACY_IMPULSE(g_waypointsprite_team_danger_p, 38, "waypoint_danger_crosshair")
+
+REGISTER_IMPULSE(waypoint_danger_death, 39)
+LEGACY_IMPULSE(g_waypointsprite_team_danger_d, 39, "waypoint_danger_death")
+
+REGISTER_IMPULSE(waypoint_clear_personal, 47)
+LEGACY_IMPULSE(g_waypointsprite_clear_personal, 47, "waypoint_clear_personal")
+
+REGISTER_IMPULSE(waypoint_clear, 48)
+LEGACY_IMPULSE(g_waypointsprite_clear, 48, "waypoint_clear")
+
+REGISTER_IMPULSE(navwaypoint_spawn, 103)
+LEGACY_IMPULSE(g_waypointeditor_spawn, 103, "navwaypoint_spawn")
+
+REGISTER_IMPULSE(navwaypoint_remove, 104)
+LEGACY_IMPULSE(g_waypointeditor_remove, 104, "navwaypoint_remove")
+
+REGISTER_IMPULSE(navwaypoint_relink, 105)
+LEGACY_IMPULSE(g_waypointeditor_relinkall, 105, "navwaypoint_relink")
+
+REGISTER_IMPULSE(navwaypoint_save, 106)
+LEGACY_IMPULSE(g_waypointeditor_saveall, 106, "navwaypoint_save")
+
+REGISTER_IMPULSE(navwaypoint_unreachable, 107)
+LEGACY_IMPULSE(g_waypointeditor_unreachable, 107, "navwaypoint_unreachable")
+
+#define CHIMPULSE(id, n) _CHIMPULSE(CHIMPULSE_##id, n)
+#define _CHIMPULSE(id, n) \
+	REGISTER(IMPULSES, id, m_id, new(Impulse)) \
+	{ \
+		make_pure(this); \
+		this.impulse = n; \
+	}
+
+CHIMPULSE(SPEEDRUN_INIT, 30)
+CHIMPULSE(GIVE_ALL, 99)
+CHIMPULSE(CLONE_MOVING, 140)
+CHIMPULSE(SPEEDRUN, 141)
+CHIMPULSE(CLONE_STANDING, 142)
+CHIMPULSE(TELEPORT, 143)
+CHIMPULSE(R00T, 148)
+
+#endif
diff --git a/qcsrc/common/minigames/sv_minigames.qc b/qcsrc/common/minigames/sv_minigames.qc
index f69fc15b54..672f7f0bdf 100644
--- a/qcsrc/common/minigames/sv_minigames.qc
+++ b/qcsrc/common/minigames/sv_minigames.qc
@@ -290,12 +290,13 @@ entity minigame_find_player(entity client)
 	return world;
 }
 
-bool MinigameImpulse(int imp)
-{SELFPARAM();
-	entity e = minigame_find_player(self);
-	if ( imp && self.active_minigame && e )
+bool MinigameImpulse(entity this, int imp)
+{
+	if (!this.active_minigame) return false;
+	entity e = minigame_find_player(this);
+	if ( imp && this.active_minigame && e )
 	{
-		return self.active_minigame.minigame_event(self.active_minigame,"impulse",e,imp);
+		return this.active_minigame.minigame_event(this.active_minigame,"impulse",e,imp);
 	}
 	return false;
 }
diff --git a/qcsrc/common/minigames/sv_minigames.qh b/qcsrc/common/minigames/sv_minigames.qh
index 10e0a039fe..2a8496932c 100644
--- a/qcsrc/common/minigames/sv_minigames.qh
+++ b/qcsrc/common/minigames/sv_minigames.qh
@@ -27,7 +27,7 @@ void end_minigames();
 bool minigame_CheckSend();
 
 // Check for minigame impulses
-bool MinigameImpulse(int imp);
+bool MinigameImpulse(entity this, int imp);
 
 // Parse a client command ( cmd minigame ... )
 void ClientCommand_minigame(int request, int argc, string command);
diff --git a/qcsrc/common/vehicles/sv_vehicles.qc b/qcsrc/common/vehicles/sv_vehicles.qc
index 0068a51e24..a2cbbb7e2c 100644
--- a/qcsrc/common/vehicles/sv_vehicles.qc
+++ b/qcsrc/common/vehicles/sv_vehicles.qc
@@ -951,9 +951,14 @@ void vehicles_touch()
 	vehicles_enter(other, self);
 }
 
-bool vehicle_impulse(int imp)
-{SELFPARAM();
-	switch(imp)
+bool vehicle_impulse(entity this, int imp)
+{
+	entity v = this.vehicle;
+	if (!v) return false;
+	if (v.deadflag != DEAD_NO) return false;
+	bool(int) f = v.vehicles_impulse;
+	if (f && f(imp)) return true;
+	switch (imp)
 	{
 		case 17:
 		{
@@ -961,7 +966,6 @@ bool vehicle_impulse(int imp)
 			return true;
 		}
 	}
-
 	return false;
 }
 
diff --git a/qcsrc/common/vehicles/sv_vehicles.qh b/qcsrc/common/vehicles/sv_vehicles.qh
index 423c8ec047..496ef9c40b 100644
--- a/qcsrc/common/vehicles/sv_vehicles.qh
+++ b/qcsrc/common/vehicles/sv_vehicles.qh
@@ -101,7 +101,7 @@ float vehicles_exit_running;
 
 void vehicles_exit(float eject);
 float vehicle_initialize(entity vehicle, float nodrop);
-bool vehicle_impulse(int imp);
+bool vehicle_impulse(entity this, int imp);
 bool vehicles_crushable(entity e);
 
 #endif
diff --git a/qcsrc/server/cheats.qc b/qcsrc/server/cheats.qc
index 5d6fba14fd..996058f1d4 100644
--- a/qcsrc/server/cheats.qc
+++ b/qcsrc/server/cheats.qc
@@ -71,7 +71,7 @@ float CheatsAllowed(float i, float argc, float fr) // the cheat gets passed as a
 		return 0;
 
 	// sv_clones
-	if(i == CHIMPULSE_CLONE_MOVING || i == CHIMPULSE_CLONE_STANDING)
+	if(i == CHIMPULSE_CLONE_MOVING.impulse || i == CHIMPULSE_CLONE_STANDING.impulse)
 		if(self.lip < sv_clones)
 			return 1;
 
@@ -146,7 +146,7 @@ float CheatImpulse(float i)
 	{
 		entity e, e2;
 
-		case CHIMPULSE_SPEEDRUN_INIT: // deploy personal waypoint
+		case CHIMPULSE_SPEEDRUN_INIT.impulse: // deploy personal waypoint
 			// shared with regular waypoint init, so this is not a cheat by itself
 			if(!self.personal)
 			{
@@ -173,7 +173,7 @@ float CheatImpulse(float i)
 			self.personal.invincible_finished = self.invincible_finished;
 			self.personal.teleport_time = time;
 			break; // this part itself doesn't cheat, so let's not count this
-		case CHIMPULSE_CLONE_MOVING:
+		case CHIMPULSE_CLONE_MOVING.impulse:
 			IS_CHEAT(i, 0, 0);
 			makevectors (self.v_angle);
 			self.velocity = self.velocity + v_forward * 300;
@@ -182,17 +182,17 @@ float CheatImpulse(float i)
 			self.velocity = self.velocity - v_forward * 300;
 			DID_CHEAT();
 			break;
-		case CHIMPULSE_CLONE_STANDING:
+		case CHIMPULSE_CLONE_STANDING.impulse:
 			IS_CHEAT(i, 0, 0);
 			CopyBody(0);
 			self.lip += 1;
 			DID_CHEAT();
 			break;
-		case CHIMPULSE_GIVE_ALL:
+		case CHIMPULSE_GIVE_ALL.impulse:
 			IS_CHEAT(i, 0, 0);
 			CheatCommand(tokenize_console("give all"));
 			break; // already counted as cheat
-		case CHIMPULSE_SPEEDRUN:
+		case CHIMPULSE_SPEEDRUN.impulse:
 			IS_CHEAT(i, 0, 0);
 			if(self.personal)
 			{
@@ -238,7 +238,7 @@ float CheatImpulse(float i)
 			else
 				sprint(self, "No waypoint set, cheater (use g_waypointsprite_personal to set one)\n");
 			break;
-		case CHIMPULSE_TELEPORT:
+		case CHIMPULSE_TELEPORT.impulse:
 			IS_CHEAT(i, 0, 0);
 			if(self.movetype == MOVETYPE_NOCLIP)
 			{
@@ -267,7 +267,7 @@ float CheatImpulse(float i)
 			}
 			sprint(self, "Emergency teleport could not find a good location, forget it!\n");
 			break;
-		case CHIMPULSE_R00T:
+		case CHIMPULSE_R00T.impulse:
 			IS_CHEAT(i, 0, 0);
 			RandomSelection_Init();
 			FOR_EACH_PLAYER(e)
diff --git a/qcsrc/server/cheats.qh b/qcsrc/server/cheats.qh
index f200c4c867..122d2f7e94 100644
--- a/qcsrc/server/cheats.qh
+++ b/qcsrc/server/cheats.qh
@@ -1,6 +1,8 @@
 #ifndef CHEATS_H
 #define CHEATS_H
 
+#include "../common/impulses/all.qh"
+
 //float autocvar_sv_cheats; // must... declare... global
 
 float cheatcount_total;
@@ -13,14 +15,6 @@ float CheatImpulse(float i);
 float CheatCommand(float argc);
 float CheatFrame();
 
-const float CHIMPULSE_SPEEDRUN_INIT = 30;
-const float CHIMPULSE_GIVE_ALL = 99;
-const float CHIMPULSE_CLONE_MOVING = 140;
-const float CHIMPULSE_SPEEDRUN = 141;
-const float CHIMPULSE_CLONE_STANDING = 142;
-const float CHIMPULSE_TELEPORT = 143;
-const float CHIMPULSE_R00T = 148;
-
 const float CHRAME_DRAG = 8;
 
 void Drag_MoveDrag(entity from, entity to); // call this from CopyBody
diff --git a/qcsrc/server/cl_client.qc b/qcsrc/server/cl_client.qc
index 2001d94044..7d26e4f7ba 100644
--- a/qcsrc/server/cl_client.qc
+++ b/qcsrc/server/cl_client.qc
@@ -2014,7 +2014,7 @@ void ObserverThink()
 {SELFPARAM();
 	if ( self.impulse )
 	{
-		MinigameImpulse(self.impulse);
+		MinigameImpulse(self, self.impulse);
 		self.impulse = 0;
 	}
 	float prefered_movetype;
@@ -2049,7 +2049,7 @@ void SpectatorThink()
 {SELFPARAM();
 	if ( self.impulse )
 	{
-		if(MinigameImpulse(self.impulse))
+		if(MinigameImpulse(self, self.impulse))
 			self.impulse = 0;
 	}
 	if (self.flags & FL_JUMPRELEASED) {
diff --git a/qcsrc/server/cl_impulse.qc b/qcsrc/server/cl_impulse.qc
index 879567b1d6..f51f7e1d40 100644
--- a/qcsrc/server/cl_impulse.qc
+++ b/qcsrc/server/cl_impulse.qc
@@ -19,25 +19,12 @@
 
 .entity vehicle;
 
-REGISTRY(IMPULSES, 255)
-REGISTER_REGISTRY(IMPULSES)
-REGISTRY_SORT(IMPULSES)
-STATIC_INIT(IMPULSES_renumber)
-{
-	FOREACH(IMPULSES, true, LAMBDA(it.m_id = i));
-}
-REGISTRY_CHECK(IMPULSES)
-
-.void(entity this) impulse_handle;
-
 #define IMPULSE(id, n) _IMPULSE(IMP_##id, n)
 #define _IMPULSE(id, n) \
 	void id##_handle(entity this); \
-	REGISTER(IMPULSES, id, m_id, new(Impulse)) \
+	STATIC_INIT_LATE(id) \
 	{ \
-		make_pure(this); \
-		this.impulse = n; \
-		this.impulse_handle = id##_handle; \
+		id.impulse_handle = id##_handle; \
 	} \
 	void id##_handle(entity this)
 
@@ -101,6 +88,7 @@ IMPULSE(weapon_next_bygroup, 18)
 	if (this.deadflag != DEAD_NO) return;
 	W_NextWeapon(1);
 }
+
 IMPULSE(weapon_prev_bygroup, 19)
 {
 	if (this.vehicle) return;
@@ -114,6 +102,7 @@ IMPULSE(weapon_next_bypriority, 15)
 	if (this.deadflag != DEAD_NO) return;
 	W_NextWeapon(2);
 }
+
 IMPULSE(weapon_prev_bypriority, 16)
 {
 	if (this.vehicle) return;
@@ -135,7 +124,7 @@ IMPULSE(weapon_best, 13)
 	W_SwitchWeapon(w_getbestweapon(this));
 }
 
-IMPULSE(weapon_throw, 17)
+IMPULSE(weapon_drop, 17)
 {
 	if (this.vehicle) return;
 	if (this.deadflag != DEAD_NO) return;
@@ -159,7 +148,7 @@ void ImpulseCommands(entity this)
 	if (!imp) return;
 	this.impulse = 0;
 
-	if (this.active_minigame && MinigameImpulse(imp)) return;
+	if (MinigameImpulse(this, imp)) return;
 
 	if (timeout_status == TIMEOUT_ACTIVE) return;  // don't allow any impulses while the game is paused
 
@@ -167,17 +156,14 @@ void ImpulseCommands(entity this)
 	if (round_handler_IsActive() && !round_handler_IsRoundStarted())
 		if (imp == 17 || (imp >= 20 && imp < 200) || imp > 253) return;
 
-	if (this.vehicle && this.vehicle.deadflag == DEAD_NO)
-	{
-		bool(int) f = this.vehicle.vehicles_impulse;
-		if (f && f(imp)) return;
-		if (vehicle_impulse(imp)) return;
-	}
+	if (vehicle_impulse(this, imp)) return;
 
 	if (CheatImpulse(imp)) return;
 
 	FOREACH(IMPULSES, it.impulse == imp, {
-		it.impulse_handle(this);
+		void(entity) f = it.impulse_handle;
+		if (!f) continue;
+		f(this);
 		return;
 	});
 
@@ -299,7 +285,7 @@ IMPULSE(waypoint_clear_personal, 47)
 	sprint(this, "personal waypoint cleared\n");
 }
 
-IMPULSE(waypoint_clear_team, 48)
+IMPULSE(waypoint_clear, 48)
 {
 	WaypointSprite_ClearOwned();
 	if (this.personal)
@@ -339,7 +325,7 @@ IMPULSE(navwaypoint_save, 106)
 	waypoint_saveall();
 }
 
-IMPULSE(navwaypoint_debug, 107)
+IMPULSE(navwaypoint_unreachable, 107)
 {
 	if (!autocvar_g_waypointeditor) return;
 	for (entity e = findchain(classname, "waypoint"); e; e = e.chain)
diff --git a/qcsrc/server/mutators/mutator/gamemode_ctf.qc b/qcsrc/server/mutators/mutator/gamemode_ctf.qc
index 40ce3ce95f..51395b8658 100644
--- a/qcsrc/server/mutators/mutator/gamemode_ctf.qc
+++ b/qcsrc/server/mutators/mutator/gamemode_ctf.qc
@@ -1125,7 +1125,7 @@ void ctf_FlagThink()
 				ctf_CheckFlagReturn(self, RETURN_SPEEDRUN);
 
 				setself(self.owner);
-				self.impulse = CHIMPULSE_SPEEDRUN; // move the player back to the waypoint they set
+				self.impulse = CHIMPULSE_SPEEDRUN.impulse; // move the player back to the waypoint they set
 				ImpulseCommands(self);
 				setself(this);
 			}
diff --git a/qcsrc/server/progs.inc b/qcsrc/server/progs.inc
index 5c79a0d884..8bfab2052e 100644
--- a/qcsrc/server/progs.inc
+++ b/qcsrc/server/progs.inc
@@ -76,6 +76,7 @@
 #include "../common/deathtypes/all.qc"
 #include "../common/effects/all.qc"
 #include "../common/gamemodes/all.qc"
+#include "../common/impulses/all.qc"
 #include "../common/items/all.qc"
 #include "../common/monsters/all.qc"
 #include "../common/turrets/all.qc"
-- 
2.39.5