From 6c1b876763dcb2d7e9e8d24c581b655ccce87a6f Mon Sep 17 00:00:00 2001
From: Mario <mario@smbclan.net>
Date: Mon, 4 Jan 2016 00:45:04 +1000
Subject: [PATCH] Add a hack to fix the use of self in .predraw functions

---
 qcsrc/client/main.qc            | 13 +++++++++++++
 qcsrc/client/main.qh            |  2 ++
 qcsrc/client/wall.qc            |  6 +++---
 qcsrc/common/t_items.qc         | 26 +++++++++++++-------------
 qcsrc/lib/csqcmodel/cl_model.qc | 24 ++++++++++++------------
 qcsrc/lib/warpzone/client.qc    | 26 +++++++++++++-------------
 6 files changed, 56 insertions(+), 41 deletions(-)

diff --git a/qcsrc/client/main.qc b/qcsrc/client/main.qc
index 304fc642a..464ae689a 100644
--- a/qcsrc/client/main.qc
+++ b/qcsrc/client/main.qc
@@ -327,6 +327,19 @@ float CSQC_InputEvent(float bInputType, float nPrimary, float nSecondary)
 // --------------------------------------------------------------------------
 // BEGIN OPTIONAL CSQC FUNCTIONS
 
+.void(entity) predraw_qc;
+void PreDraw_self()
+{
+	if(self.predraw_qc)
+		self.predraw_qc(self);
+}
+
+void setpredraw(entity this, void(entity) pdfunc)
+{
+	this.predraw = PreDraw_self;
+	this.predraw_qc = pdfunc;
+}
+
 void Ent_Remove(entity this);
 
 void Ent_RemovePlayerScore(entity this)
diff --git a/qcsrc/client/main.qh b/qcsrc/client/main.qh
index 835acb9ca..31db3f86e 100644
--- a/qcsrc/client/main.qh
+++ b/qcsrc/client/main.qh
@@ -14,6 +14,8 @@ const float DATABUF_PING = 0;
 
 #define DATABUF_NEXT (5*maxclients)
 
+void setpredraw(entity this, void(entity) pdfunc);
+
 // --------------------------------------------------------------------------
 // Onslaught
 
diff --git a/qcsrc/client/wall.qc b/qcsrc/client/wall.qc
index 7b610fb9f..b94fddd8d 100644
--- a/qcsrc/client/wall.qc
+++ b/qcsrc/client/wall.qc
@@ -9,8 +9,8 @@
 .float scale;
 .vector movedir;
 
-void Ent_Wall_PreDraw()
-{SELFPARAM();
+void Ent_Wall_PreDraw(entity this)
+{
 	if (this.inactive)
 	{
 		this.alpha = 0;
@@ -230,5 +230,5 @@ NET_HANDLE(ENT_CLIENT_WALL, bool isnew)
 
 	this.entremove = Ent_Wall_Remove;
 	this.draw = Ent_Wall_Draw;
-	this.predraw = Ent_Wall_PreDraw;
+	setpredraw(this, Ent_Wall_PreDraw);
 }
diff --git a/qcsrc/common/t_items.qc b/qcsrc/common/t_items.qc
index ce3bf352a..87741a66e 100644
--- a/qcsrc/common/t_items.qc
+++ b/qcsrc/common/t_items.qc
@@ -114,30 +114,30 @@ void ItemDrawSimple(entity this)
     Item_SetAlpha(this);
 }
 
-void Item_PreDraw()
-{SELFPARAM();
+void Item_PreDraw(entity this)
+{
 	if(warpzone_warpzones_exist)
 	{
 		// just incase warpzones were initialized last, reset these
-		//self.alpha = 1; // alpha is already set by the draw function
-		self.drawmask = MASK_NORMAL;
+		//this.alpha = 1; // alpha is already set by the draw function
+		this.drawmask = MASK_NORMAL;
 		return;
 	}
 	float alph;
 	vector org = getpropertyvec(VF_ORIGIN);
-	if(!checkpvs(org, self)) // this makes sense as long as we don't support recursive warpzones
+	if(!checkpvs(org, this)) // this makes sense as long as we don't support recursive warpzones
 		alph = 0;
-	else if(self.fade_start)
-		alph = bound(0, (self.fade_end - vlen(org - self.origin - 0.5 * (self.mins + self.maxs))) / (self.fade_end - self.fade_start), 1);
+	else if(this.fade_start)
+		alph = bound(0, (this.fade_end - vlen(org - this.origin - 0.5 * (this.mins + this.maxs))) / (this.fade_end - this.fade_start), 1);
 	else
 		alph = 1;
-	//printf("%v <-> %v\n", view_origin, self.origin + 0.5 * (self.mins + self.maxs));
-	if(!hud && (self.ItemStatus & ITS_AVAILABLE))
-		self.alpha = alph;
+	//printf("%v <-> %v\n", view_origin, this.origin + 0.5 * (this.mins + this.maxs));
+	if(!hud && (this.ItemStatus & ITS_AVAILABLE))
+		this.alpha = alph;
 	if(alph <= 0)
-		self.drawmask = 0;
+		this.drawmask = 0;
 	else
-		self.drawmask = MASK_NORMAL;
+		this.drawmask = MASK_NORMAL;
 }
 
 void ItemRemove(entity this)
@@ -205,7 +205,7 @@ NET_HANDLE(ENT_CLIENT_ITEM, bool isnew)
         self.fade_end = ReadShort();
         self.fade_start = ReadShort();
         if(self.fade_start && !autocvar_cl_items_nofade)
-        	self.predraw = Item_PreDraw;
+        	setpredraw(self, Item_PreDraw);
 
         if(self.mdl)
             strunzone(self.mdl);
diff --git a/qcsrc/lib/csqcmodel/cl_model.qc b/qcsrc/lib/csqcmodel/cl_model.qc
index f3497febe..c07f94954 100644
--- a/qcsrc/lib/csqcmodel/cl_model.qc
+++ b/qcsrc/lib/csqcmodel/cl_model.qc
@@ -179,33 +179,33 @@ void CSQCModel_InterpolateAnimation_Do()
 #endif
 }
 
-void CSQCModel_Draw()
-{SELFPARAM();
+void CSQCModel_Draw(entity this)
+{
 	// some nice flags for CSQCMODEL_IF and the hooks
-	bool isplayer = (self.entnum >= 1 && self.entnum <= maxclients);
-	noref bool islocalplayer = (self.entnum == player_localnum + 1);
-	noref bool isnolocalplayer = (isplayer && (self.entnum != player_localnum + 1));
+	bool isplayer = (this.entnum >= 1 && this.entnum <= maxclients);
+	noref bool islocalplayer = (this.entnum == player_localnum + 1);
+	noref bool isnolocalplayer = (isplayer && (this.entnum != player_localnum + 1));
 
 	// we don't do this for the local player as that one is already handled
 	// by CSQCPlayer_SetCamera()
 	if (!CSQCPlayer_IsLocalPlayer(this)) InterpolateOrigin_Do(this);
 
-	CSQCModel_InterpolateAnimation_Do();
+	WITH(entity, self, this, CSQCModel_InterpolateAnimation_Do());
 
 	{ CSQCMODEL_HOOK_PREDRAW }
 
 	// inherit draw flags easily
-	entity root = self;
+	entity root = this;
 	while(root.tag_entity)
 		root = root.tag_entity;
-	if(self != root)
+	if(this != root)
 	{
-		self.renderflags &= ~(RF_EXTERNALMODEL | RF_VIEWMODEL);
-		self.renderflags |= (root.renderflags & (RF_EXTERNALMODEL | RF_VIEWMODEL));
+		this.renderflags &= ~(RF_EXTERNALMODEL | RF_VIEWMODEL);
+		this.renderflags |= (root.renderflags & (RF_EXTERNALMODEL | RF_VIEWMODEL));
 	}
 
 	// we're drawn, now teleporting is over
-	self.csqcmodel_teleported = 0;
+	this.csqcmodel_teleported = 0;
 }
 
 entity CSQCModel_players[255]; // 255 is engine limit on maxclients
@@ -289,7 +289,7 @@ NET_HANDLE(ENT_CLIENT_MODEL, bool isnew)
 
 	// draw it
 	this.drawmask = MASK_NORMAL;
-	this.predraw = CSQCModel_Draw;
+	setpredraw(this, CSQCModel_Draw);
 	return true;
 }
 
diff --git a/qcsrc/lib/warpzone/client.qc b/qcsrc/lib/warpzone/client.qc
index a0366922c..89f6b84af 100644
--- a/qcsrc/lib/warpzone/client.qc
+++ b/qcsrc/lib/warpzone/client.qc
@@ -8,21 +8,21 @@
 #elif defined(SVQC)
 #endif
 
-void WarpZone_Fade_PreDraw()
-{SELFPARAM();
+void WarpZone_Fade_PreDraw(entity this)
+{
 	vector org;
 	org = getpropertyvec(VF_ORIGIN);
-	if(!checkpvs(org, self)) // this makes sense as long as we don't support recursive warpzones
-		self.alpha = 0;
-	else if(self.warpzone_fadestart)
-		self.alpha = bound(0, (self.warpzone_fadeend - vlen(org - self.origin - 0.5 * (self.mins + self.maxs))) / (self.warpzone_fadeend - self.warpzone_fadestart), 1);
+	if(!checkpvs(org, this)) // this makes sense as long as we don't support recursive warpzones
+		this.alpha = 0;
+	else if(this.warpzone_fadestart)
+		this.alpha = bound(0, (this.warpzone_fadeend - vlen(org - this.origin - 0.5 * (this.mins + this.maxs))) / (this.warpzone_fadeend - this.warpzone_fadestart), 1);
 	else
-		self.alpha = 1;
-	//printf("%v <-> %v\n", view_origin, self.origin + 0.5 * (self.mins + self.maxs));
-	if(self.alpha <= 0)
-		self.drawmask = 0;
+		this.alpha = 1;
+	//printf("%v <-> %v\n", view_origin, this.origin + 0.5 * (this.mins + this.maxs));
+	if(this.alpha <= 0)
+		this.drawmask = 0;
 	else
-		self.drawmask = MASK_NORMAL;
+		this.drawmask = MASK_NORMAL;
 }
 
 void WarpZone_Touch ();
@@ -87,7 +87,7 @@ NET_HANDLE(ENT_CLIENT_WARPZONE, bool isnew)
 
 	// how to draw
 	// engine currently wants this
-	self.predraw = WarpZone_Fade_PreDraw;
+	setpredraw(self, WarpZone_Fade_PreDraw);
 
 	//self.move_touch = WarpZone_Touch;
 	return true;
@@ -146,7 +146,7 @@ NET_HANDLE(ENT_CLIENT_WARPZONE_CAMERA, bool isnew)
 
 	// how to draw
 	// engine currently wants this
-	self.predraw = WarpZone_Fade_PreDraw;
+	setpredraw(self, WarpZone_Fade_PreDraw);
 	return true;
 }
 
-- 
2.39.5