All pastes #937811 Raw Edit

ufo:ai breakables interaction

public text v1 · immutable
·published 2008-03-11 06:01 UTC
rendered paste body
Index: common/cmodel.c
===================================================================
--- common/cmodel.c	(revision 15680)
+++ common/cmodel.c	(working copy)
@@ -682,6 +682,7 @@
 	return 0;
 }
 
+
 /**
  * @brief Checks traces against the world and all inline models
  * @param[in] start The position to start the trace.
@@ -689,24 +690,23 @@
  * @sa CM_TestLine
  * @sa CM_InlineModel
  * @sa CM_TransformedBoxTrace
- * @return 1 - hit something
- * @return 0 - hit nothing
+ * @return qtrue - hit something
+ * @return qfalse - hit nothing
  */
-static int CM_EntTestLine (vec3_t start, vec3_t stop)
+qboolean CM_EntTestLine (vec3_t start, vec3_t stop)
 {
 	trace_t trace;
 	cBspModel_t *model;
 	const char **name;
-	int worldFound;
 
 	/* trace against world first */
 	if (CM_TestLine(start, stop))
-		worldFound = 1;
-	else
-		worldFound = 0;
-	/* no local models */
+		/* We hit the world, so we didn't make it anyway... */
+		return qtrue;
+
+	/* no local models, so we made it. */
 	if (!inlineList)
-		return worldFound;
+		return qfalse;
 
 	for (name = inlineList; *name; name++) {
 		/* check whether this is really an inline model */
@@ -719,15 +719,39 @@
 		/* if we started the trace in a wall */
 		/* or the trace is not finished */
 		if (trace.startsolid || trace.fraction < 1.0)
-			return 1;
+			return qtrue;
 	}
 
 	/* not blocked */
-	return worldFound;
+	return qfalse;
 }
 
 
 /**
+ * @brief Checks traces against the world and all inline models
+ * @param[in] start The position to start the trace.
+ * @param[in] stop The position where the trace ends.
+ * @param[in] list of entities that might be on this line
+ * @sa CM_EntTestLine
+ * @return qtrue - hit something
+ * @return qfalse - hit nothing
+ */
+qboolean CM_TestLineWithEnt (vec3_t start, vec3_t stop, const char **entlist)
+{
+	qboolean hit;
+
+	/* set the list of entities to check */
+	inlineList = entlist;
+	/* do the line test */
+	hit = CM_EntTestLine(start, stop);
+	/* zero the list */
+	inlineList = NULL;
+
+	return hit;
+}
+
+
+/**
  * @brief Checks traces against the world and all inline models, gives the hit position back
  * @param[in] start The position to start the trace.
  * @param[in] stop The position where the trace ends.
Index: common/cmodel.h
===================================================================
--- common/cmodel.h	(revision 15680)
+++ common/cmodel.h	(working copy)
@@ -51,6 +51,7 @@
 trace_t CM_CompleteBoxTrace(vec3_t start, vec3_t end, const vec3_t mins, const vec3_t maxs, int levelmask, int brushmask);
 
 qboolean CM_TestLine(const vec3_t start, const vec3_t stop);
+qboolean CM_TestLineWithEnt(vec3_t start, vec3_t stop, const char **entlist);
 qboolean CM_TestLineDM(const vec3_t start, const vec3_t stop, vec3_t end);
 
 /*==========================================================
Index: game/g_client.c
===================================================================
--- game/g_client.c	(revision 15680)
+++ game/g_client.c	(working copy)
@@ -329,12 +329,18 @@
  */
 static qboolean G_LineVis (vec3_t from, vec3_t to)
 {
-#if 0 /* this version is more accurate the other version is much faster */
+#if 0 /* this version is more accurate and includes entity tests */
 	trace_t tr;
 	tr = gi.trace(from, NULL, NULL, to, NULL, MASK_SOLID);
-	return (tr.fraction >= 1.0);
-#else
+	return (tr.fraction < 1.0);
+#elif 0 /* this version is much faster but has no entity test*/
 	return gi.TestLine(from, to);
+#else /* a compromise- but still checks for entities that may obstruct view */
+	const char *entList[MAX_EDICTS];
+	/* generate entity list */
+	G_GenerateEntList (entList);
+	/* test for visibility */
+	return gi.TestLineWithEnt(from, to, entList);
 #endif
 }
 
Index: game/g_spawn.c
===================================================================
--- game/g_spawn.c	(revision 15680)
+++ game/g_spawn.c	(working copy)
@@ -297,13 +297,20 @@
 			ent = g_edicts;
 		else
 			ent = G_Spawn();
+
 		entities = ED_ParseEdict(entities, ent);
 
+		ent->mapNum = entnum++;
+
+		/* Set the position of the entity */
 		VecToPos(ent->origin, ent->pos);
-		gi.GridPosToVec(gi.routingMap, ent->pos, ent->origin);
 
-		ent->mapNum = entnum++;
+		/*Call this entity's specific initializer (sets ent->type) */
 		ED_CallSpawn(ent);
+
+		/* if this entity is not an actor, then center its origin based on its position */
+		if (ent->type != ET_BREAKABLE && ent->type != ET_BREAKABLE)
+			gi.GridPosToVec(gi.routingMap, ent->pos, ent->origin);
 	}
 
 	/* spawn ai players, if needed */
Index: game/g_utils.c
===================================================================
--- game/g_utils.c	(revision 15680)
+++ game/g_utils.c	(working copy)
@@ -234,21 +234,32 @@
 }
 
 /**
- * @sa G_CompleteRecalcRouting
- * @sa Grid_RecalcRouting
+ * @brief creates an entity list
+ * @param[out] entList A list of all active inline model entities
+ * @sa G_RecalcRouting
+ * @sa G_LineVis
  */
-void G_RecalcRouting (const edict_t * self)
+void G_GenerateEntList (const char *entList[MAX_EDICTS])
 {
 	int i;
 	edict_t *ent;
-	const char *entList[MAX_EDICTS];
 
 	/* generate entity list */
 	for (i = 0, ent = g_edicts; ent < &g_edicts[globals.num_edicts]; ent++)
 		if (ent->inuse && ent->model && *ent->model == '*' && ent->solid == SOLID_BSP)
 			entList[i++] = ent->model;
 	entList[i] = NULL;
+}
 
+/**
+ * @sa G_CompleteRecalcRouting
+ * @sa Grid_RecalcRouting
+ */
+void G_RecalcRouting (const edict_t * self)
+{
+	const char *entList[MAX_EDICTS];
+	/* generate entity list */
+	G_GenerateEntList (entList);
 	/* recalculate routing */
 	gi.GridRecalcRouting(gi.routingMap, self->model, self->angles, entList);
 }
Index: game/game.h
===================================================================
--- game/game.h	(revision 15680)
+++ game/game.h	(working copy)
@@ -151,6 +151,7 @@
 	int (IMPORT *BoxEdicts) (vec3_t mins, vec3_t maxs, edict_t **list, int maxcount, int areatype);
 
 	qboolean (IMPORT *TestLine) (const vec3_t start, const vec3_t stop);
+	qboolean (IMPORT *TestLineWithEnt) (vec3_t start, vec3_t stop, const char **entlist);
 	float (IMPORT *GrenadeTarget) (vec3_t from, vec3_t at, float speed, qboolean launched, qboolean rolled, vec3_t v0);
 
 	void (IMPORT *MoveCalc) (struct routing_s * map, pos3_t from, int size, int distance, pos_t ** fb_list, int fb_length);
Index: server/sv_game.c
===================================================================
--- server/sv_game.c	(revision 15680)
+++ server/sv_game.c	(working copy)
@@ -388,6 +388,7 @@
 	import.BoxEdicts = SV_AreaEdicts;
 
 	import.TestLine = CM_TestLine;
+	import.TestLineWithEnt = CM_TestLineWithEnt;
 	import.GrenadeTarget = Com_GrenadeTarget;
 
 	import.MoveCalc = Grid_MoveCalc;
Index: server/sv_world.c
===================================================================
--- server/sv_world.c	(revision 15680)
+++ server/sv_world.c	(working copy)
@@ -497,9 +497,16 @@
 	clip.maxs = maxs;
 	clip.passedict = passedict;
 
-	/* create the bounding box of the entire move */
+	/* create the bounding box for the entire path traveled by the shot */
 	SV_TraceBounds(start, clip.mins, clip.maxs, end, clip.boxmins, clip.boxmaxs);
 
+#if 0
+	/* Output the trace bounds */
+	Com_Printf("Trace: (%i, %i, %i) (%i, %i, %i)\n",
+		(int) clip.boxmins[0], (int) clip.boxmins[1], (int) clip.boxmins[2],
+		(int) clip.boxmaxs[0], (int) clip.boxmaxs[1], (int) clip.boxmaxs[2]);
+#endif
+
 	/* clip to other solid entities */
 	SV_ClipMoveToEntities(&clip);