All pastes #453821 Raw Edit

destroying-items-on-

public c v1 · immutable
·published 2007-04-23 06:41 UTC
rendered paste body
Index: src/game/g_client.c===================================================================--- src/game/g_client.c	(Revision 7823)+++ src/game/g_client.c	(Arbeitskopie)@@ -889,8 +889,8 @@ void G_InventoryToFloor (edict_t * ent) { 	invList_t *ic, *next;-	edict_t *floor;-	int k;+	edict_t *floor, *floorAdjacent = NULL;+	int k, i; 	/* check for items */ 	for (k = 0; k < gi.csi->numIDs; k++)@@ -906,6 +906,7 @@ 	if (!floor) { 		floor = G_SpawnFloor(ent->pos); 	} else {+		/* destroy this edict (send this event to all clients that see the edict) */ 		gi.AddEvent(G_VisToPM(floor->visflags), EV_ENT_PERISH); 		gi.WriteShort(floor->number); 		floor->visflags = 0;@@ -927,6 +928,7 @@ 		/* now cycle through all items for the container of the character (or the entity) */ 		for (ic = ent->i.c[k]; ic; ic = next) { 			int x, y;+			vec2_t oldPos; /**< if we have to place it to adjacent  */ 			/* Save the next inv-list before it gets overwritten below. 			   Do not put this in the "for" statement,@@ -937,9 +939,40 @@ 			if (x == NONE) { 				assert (y == NONE); 				/* Run out of space on the floor or the item is armor-				   --- destroy the offending item.-				   TODO: for items other than armor we should really-				   just spill into adjacent locations */+				   destroy the offending item if no adjacent places are free */+				/* store pos for later restoring the original value */+				Vector2Copy(ent->pos, oldPos);+				for (i = 0; i < DIRECTIONS; i++) {+					/* extend pos with the direction vectors */+					Vector2Set(ent->pos, ent->pos[0] + dvecs[i][0], ent->pos[0] + dvecs[i][1]);+					/* now try to get a floor entity for that new location */+					floorAdjacent = G_GetFloorItems(ent);+					if (!floorAdjacent) {+						floorAdjacent = G_SpawnFloor(ent->pos);+					} else {+						/* destroy this edict (send this event to all clients that see the edict) */+						gi.AddEvent(G_VisToPM(floorAdjacent->visflags), EV_ENT_PERISH);+						gi.WriteShort(floorAdjacent->number);+						floorAdjacent->visflags = 0;+					}+					Com_FindSpace(&floorAdjacent->i, ic->item.t, gi.csi->idFloor, &x, &y);+					if (x != NONE) {+						ic->x = x;+						ic->y = y;+						ic->next = FLOOR(floorAdjacent);+						FLOOR(floorAdjacent) = ic;+						break;+					}+					/* restore original pos */+					Vector2Copy(oldPos, ent->pos);+				}+				/* added to adjacent pos? */+				if (i < DIRECTIONS) {+					/* restore original pos - if no free space, this was done+					 * already in the for loop */+					Vector2Copy(oldPos, ent->pos);+					continue;+				} 				if (Q_strncmp(gi.csi->ods[ic->item.t].type, "armor", MAX_VAR)) 					gi.dprintf("G_InventoryToFloor: Warning: could not drop item to floor: %s\n", gi.csi->ods[ic->item.t].id); 				if (!Com_RemoveFromInventory(&ent->i, k, ic->x, ic->y))@@ -969,6 +1002,8 @@ 	/* send item info to the clients */ 	G_CheckVis(floor, qtrue);+	if (floorAdjacent)+		G_CheckVis(floorAdjacent, qtrue); }