From: havoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Date: Mon, 17 Jan 2005 22:52:16 +0000 (+0000)
Subject: reverted back to per-entity prethink-think-move-postthink process to fix mods
X-Git-Tag: xonotic-v0.1.0preview~5208
X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=fc0e457ed26ef1d2d568c753bbac2b4ca9dd6324;p=xonotic%2Fdarkplaces.git

reverted back to per-entity prethink-think-move-postthink process to fix mods


git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@4941 d7cf8633-e32d-0410-b094-e92efae38249
---

diff --git a/sv_phys.c b/sv_phys.c
index 9f7a0adc..b1e8814a 100644
--- a/sv_phys.c
+++ b/sv_phys.c
@@ -128,6 +128,37 @@ void SV_CheckVelocity (edict_t *ent)
 	}
 }
 
+/*
+=============
+SV_RunThink
+
+Runs thinking code if time.  There is some play in the exact time the think
+function will be called, because it is called before any movement is done
+in a frame.  Not used for pushmove objects, because they must be exact.
+Returns false if the entity removed itself.
+=============
+*/
+qboolean SV_RunThink (edict_t *ent)
+{
+	float thinktime;
+
+	thinktime = ent->v->nextthink;
+	if (thinktime <= 0 || thinktime > sv.time + sv.frametime)
+		return true;
+
+	// don't let things stay in the past.
+	// it is possible to start that way by a trigger with a local time.
+	if (thinktime < sv.time)
+		thinktime = sv.time;
+
+	ent->v->nextthink = 0;
+	pr_global_struct->time = thinktime;
+	pr_global_struct->self = EDICT_TO_PROG(ent);
+	pr_global_struct->other = EDICT_TO_PROG(sv.edicts);
+	PR_ExecuteProgram (ent->v->think, "QC function self.think is missing");
+	return !ent->e->free;
+}
+
 /*
 ==================
 SV_Impact
@@ -1105,6 +1136,9 @@ void SV_Physics_Follow (edict_t *ent)
 	edict_t *e;
 
 	// regular thinking
+	if (!SV_RunThink (ent))
+		return;
+
 	// LordHavoc: implemented rotation on MOVETYPE_FOLLOW objects
 	e = PROG_TO_EDICT(ent->v->aiment);
 	if (e->v->angles[0] == ent->v->punchangle[0] && e->v->angles[1] == ent->v->punchangle[1] && e->v->angles[2] == ent->v->punchangle[2])
@@ -1188,6 +1222,10 @@ void SV_Physics_Toss (edict_t *ent)
 	vec3_t move;
 	edict_t *groundentity;
 
+	// regular thinking
+	if (!SV_RunThink (ent))
+		return;
+
 	// don't stick to ground if onground and moving upward
 	if (ent->v->velocity[2] >= (1.0 / 32.0) && ((int)ent->v->flags & FL_ONGROUND))
 		ent->v->flags = (int)ent->v->flags & ~FL_ONGROUND;
@@ -1329,6 +1367,9 @@ void SV_Physics_Step (edict_t *ent)
 			SV_StartSound(ent, 0, "demon/dland2.wav", 255, 1);
 	}
 
+// regular thinking
+	SV_RunThink(ent);
+
 	SV_CheckWaterTransition(ent);
 }
 
@@ -1342,9 +1383,7 @@ SV_Physics
 */
 void SV_Physics (void)
 {
-	int i, end, retouch;
-	float nexttime;
-	vec3_t oldorigin;
+	int i;
 	edict_t *ent;
 
 // let the progs know that a new frame has started
@@ -1353,16 +1392,32 @@ void SV_Physics (void)
 	pr_global_struct->time = sv.time;
 	PR_ExecuteProgram (pr_global_struct->StartFrame, "QC function StartFrame is missing");
 
-	retouch = pr_global_struct->force_retouch > 0;
-	end = i = sv_freezenonclients.integer ? svs.maxclients + 1 : sv.num_edicts;
-	for (i = 0, ent = sv.edicts;i < end;i++, ent = NEXT_EDICT(ent))
+//
+// treat each object in turn
+//
+	ent = sv.edicts;
+	for (i=0 ; i<sv.num_edicts ; i++, ent = NEXT_EDICT(ent))
 	{
-		if (ent->e->free || ent->v->movetype == MOVETYPE_NONE)
+		if (ent->e->free)
 			continue;
 
-		// LordHavoc: merged client and normal entity physics
-		VectorCopy(ent->v->origin, oldorigin);
+		if (pr_global_struct->force_retouch)
+			SV_LinkEdict (ent, true);	// force retouch even for stationary
+
+		if (i >= 1 && i <= svs.maxclients && svs.clients[i-1].spawned)
+		{
+			// connected slot
+			// call standard client pre-think
+			SV_CheckVelocity (ent);
+			pr_global_struct->time = sv.time;
+			pr_global_struct->self = EDICT_TO_PROG(ent);
+			PR_ExecuteProgram (pr_global_struct->PlayerPreThink, "QC function PlayerPreThink is missing");
+			SV_CheckVelocity (ent);
+		}
+		else if (sv_freezenonclients.integer)
+			continue;
 
+		// LordHavoc: merged client and normal entity physics
 		switch ((int) ent->v->movetype)
 		{
 		case MOVETYPE_PUSH:
@@ -1370,127 +1425,77 @@ void SV_Physics (void)
 			SV_Physics_Pusher (ent);
 			break;
 		case MOVETYPE_NONE:
+			// LordHavoc: manually inlined the thinktime check here because MOVETYPE_NONE is used on so many objects
+			if (ent->v->nextthink > 0 && ent->v->nextthink <= sv.time + sv.frametime)
+				SV_RunThink (ent);
 			break;
 		case MOVETYPE_FOLLOW:
 			SV_Physics_Follow (ent);
 			break;
 		case MOVETYPE_NOCLIP:
-			SV_CheckWater(ent);
-			VectorMA(ent->v->origin, sv.frametime, ent->v->velocity, ent->v->origin);
-			VectorMA(ent->v->angles, sv.frametime, ent->v->avelocity, ent->v->angles);
+			if (SV_RunThink(ent))
+			{
+				SV_CheckWater(ent);
+				VectorMA(ent->v->origin, sv.frametime, ent->v->velocity, ent->v->origin);
+				VectorMA(ent->v->angles, sv.frametime, ent->v->avelocity, ent->v->angles);
+			}
+			// relink normal entities here, players always get relinked so don't relink twice
+			if (!(i > 0 && i <= svs.maxclients))
+				SV_LinkEdict(ent, false);
 			break;
 		case MOVETYPE_STEP:
 			SV_Physics_Step (ent);
 			break;
 		case MOVETYPE_WALK:
-			if (!SV_CheckWater(ent) && ! ((int)ent->v->flags & FL_WATERJUMP) )
-				SV_AddGravity(ent);
-			SV_CheckStuck(ent);
-			SV_WalkMove(ent);
+			if (SV_RunThink (ent))
+			{
+				if (!SV_CheckWater (ent) && ! ((int)ent->v->flags & FL_WATERJUMP) )
+					SV_AddGravity (ent);
+				SV_CheckStuck (ent);
+				SV_WalkMove (ent);
+				// relink normal entities here, players always get relinked so don't relink twice
+				if (!(i > 0 && i <= svs.maxclients))
+					SV_LinkEdict (ent, true);
+			}
 			break;
 		case MOVETYPE_TOSS:
 		case MOVETYPE_BOUNCE:
 		case MOVETYPE_BOUNCEMISSILE:
 		case MOVETYPE_FLYMISSILE:
-			SV_Physics_Toss(ent);
+			SV_Physics_Toss (ent);
 			break;
 		case MOVETYPE_FLY:
-			if (i >= 1 && i <= svs.maxclients && svs.clients[i-1].spawned)
+			if (i > 0 && i <= svs.maxclients)
 			{
-				SV_CheckWater(ent);
-				SV_WalkMove(ent);
+				if (SV_RunThink (ent))
+				{
+					SV_CheckWater (ent);
+					SV_WalkMove (ent);
+				}
 			}
 			else
-				SV_Physics_Toss(ent);
+				SV_Physics_Toss (ent);
 			break;
 		default:
 			Host_Error ("SV_Physics: bad movetype %i", (int)ent->v->movetype);
 			break;
 		}
 
-		if (!VectorCompare(ent->v->origin, oldorigin) || retouch)
-			SV_LinkEdict(ent, true);
-	}
-
-	for (i = 1, ent = NEXT_EDICT(sv.edicts);i <= svs.maxclients;i++, ent = NEXT_EDICT(ent))
-	{
-		if (ent->e->free || !svs.clients[i-1].spawned)
-			continue;
+		if (i >= 1 && i <= svs.maxclients && svs.clients[i-1].spawned)
+		{
+			SV_CheckVelocity (ent);
 
-		// call standard client pre-think
-		SV_CheckVelocity (ent);
-		pr_global_struct->time = sv.time;
-		pr_global_struct->self = EDICT_TO_PROG(ent);
-		PR_ExecuteProgram (pr_global_struct->PlayerPreThink, "QC function PlayerPreThink is missing");
-		SV_CheckVelocity (ent);
-	}
+			// call standard player post-think
+			SV_LinkEdict (ent, true);
 
-	nexttime = sv.time + sv.frametime;
-	end = i = sv_freezenonclients.integer ? svs.maxclients + 1 : sv.num_edicts;
-	for (i = 0, ent = sv.edicts;i < end;i++, ent = NEXT_EDICT(ent))
-	{
-		if (ent->e->free)
-			continue;
+			SV_CheckVelocity (ent);
 
-		// LordHavoc: merged client and normal entity physics
-		switch ((int) ent->v->movetype)
-		{
-		case MOVETYPE_PUSH:
-		case MOVETYPE_FAKEPUSH:
-			// push thinks are called from SV_Physics_Pusher 
-			break;
-		case MOVETYPE_NONE:
-		case MOVETYPE_FOLLOW:
-		case MOVETYPE_NOCLIP:
-		case MOVETYPE_STEP:
-		case MOVETYPE_WALK:
-		case MOVETYPE_TOSS:
-		case MOVETYPE_BOUNCE:
-		case MOVETYPE_BOUNCEMISSILE:
-		case MOVETYPE_FLY:
-		case MOVETYPE_FLYMISSILE:
-			// LordHavoc: manually inlined SV_RunThink here
-			if (ent->v->nextthink > 0 && ent->v->nextthink <= nexttime)
-			{
-				/*
-				SV_RunThink
-				Runs thinking code if time.  There is some play in the exact time the think
-				function will be called, because it is called before any movement is done
-				in a frame.  Not used for pushmove objects, because they must be exact.
-				Returns false if the entity removed itself.
-				*/
-				float thinktime = ent->v->nextthink;
-				if (thinktime && thinktime < sv.time + sv.frametime)
-				{
-					ent->v->nextthink = 0;
-					// don't let things stay in the past.
-					// it is possible to start that way by a trigger with a local time.
-					pr_global_struct->time = max(thinktime, sv.time);
-					pr_global_struct->self = EDICT_TO_PROG(ent);
-					pr_global_struct->other = EDICT_TO_PROG(sv.edicts);
-					PR_ExecuteProgram (ent->v->think, "QC function self.think is missing");
-				}
-			}
-			break;
-		default:
-			Host_Error ("SV_Physics: bad movetype %i", (int)ent->v->movetype);
-			break;
+			pr_global_struct->time = sv.time;
+			pr_global_struct->self = EDICT_TO_PROG(ent);
+			PR_ExecuteProgram (pr_global_struct->PlayerPostThink, "QC function PlayerPostThink is missing");
 		}
 	}
 
-	for (i = 1, ent = NEXT_EDICT(sv.edicts);i <= svs.maxclients;i++, ent = NEXT_EDICT(ent))
-	{
-		if (ent->e->free || !svs.clients[i-1].spawned)
-			continue;
-
-		// call standard player post-think
-		SV_LinkEdict (ent, true);
-		SV_CheckVelocity (ent);
-		pr_global_struct->time = sv.time;
-		pr_global_struct->self = EDICT_TO_PROG(ent);
-		PR_ExecuteProgram (pr_global_struct->PlayerPostThink, "QC function PlayerPostThink is missing");
-	}
-
 	if (pr_global_struct->force_retouch > 0)
 		pr_global_struct->force_retouch = max(0, pr_global_struct->force_retouch - 1);