Changeset - r7232:d1887dca9a19
[Not reviewed]
master
0 1 0
peter1138 - 17 years ago 2007-07-11 21:31:34
peter1138@openttd.org
(svn r10513) -Fix [FS#1022]: use vehicle subtile position to update cache, not tile, so that collision detection works on bridges and tunnels.
1 file changed with 2 insertions and 2 deletions:
0 comments (0 inline, 0 general)
src/vehicle.cpp
Show inline comments
 
@@ -426,98 +426,98 @@ static void *VehicleFromHash(int xl, int
 
			}
 
			if (x == xu) break;
 
		}
 
		if (y == yu) break;
 
	}
 

	
 
	return NULL;
 
}
 

	
 

	
 
void *VehicleFromPosXY(int x, int y, void *data, VehicleFromPosProc *proc)
 
{
 
	const int COLL_DIST = 6;
 

	
 
	/* Hash area to scan is from xl,yl to xu,yu */
 
	int xl = GB((x - COLL_DIST) / TILE_SIZE, HASH_RES, HASH_BITS);
 
	int xu = GB((x + COLL_DIST) / TILE_SIZE, HASH_RES, HASH_BITS);
 
	int yl = GB((y - COLL_DIST) / TILE_SIZE, HASH_RES, HASH_BITS) << HASH_BITS;
 
	int yu = GB((y + COLL_DIST) / TILE_SIZE, HASH_RES, HASH_BITS) << HASH_BITS;
 

	
 
	return VehicleFromHash(xl, yl, xu, yu, data, proc);
 
}
 

	
 

	
 
void *VehicleFromPos(TileIndex tile, void *data, VehicleFromPosProc *proc)
 
{
 
	int x = GB(TileX(tile), HASH_RES, HASH_BITS);
 
	int y = GB(TileY(tile), HASH_RES, HASH_BITS) << HASH_BITS;
 

	
 
	Vehicle *v = _new_vehicle_position_hash[(x + y) & TOTAL_HASH_MASK];
 
	for (; v != NULL; v = v->next_new_hash) {
 
		if (v->tile != tile) continue;
 

	
 
		void *a = proc(v, data);
 
		if (a != NULL) return a;
 
	}
 

	
 
	return NULL;
 
}
 

	
 
static void UpdateNewVehiclePosHash(Vehicle *v, bool remove)
 
{
 
	Vehicle **old_hash = v->old_new_hash;
 
	Vehicle **new_hash;
 

	
 
	if (remove) {
 
		new_hash = NULL;
 
	} else {
 
		int x = GB(TileX(v->tile), HASH_RES, HASH_BITS);
 
		int y = GB(TileY(v->tile), HASH_RES, HASH_BITS) << HASH_BITS;
 
		int x = GB(v->x_pos / TILE_SIZE, HASH_RES, HASH_BITS);
 
		int y = GB(v->y_pos / TILE_SIZE, HASH_RES, HASH_BITS) << HASH_BITS;
 
		new_hash = &_new_vehicle_position_hash[(x + y) & TOTAL_HASH_MASK];
 
	}
 

	
 
	if (old_hash == new_hash) return;
 

	
 
	/* Remove from the old position in the hash table */
 
	if (old_hash != NULL) {
 
		Vehicle *last = NULL;
 
		Vehicle *u = *old_hash;
 
		while (u != v) {
 
			last = u;
 
			u = u->next_new_hash;
 
			assert(u != NULL);
 
		}
 

	
 
		if (last == NULL) {
 
			*old_hash = v->next_new_hash;
 
		} else {
 
			last->next_new_hash = v->next_new_hash;
 
		}
 
	}
 

	
 
	/* Insert vehicle at beginning of the new position in the hash table */
 
	if (new_hash != NULL) {
 
		v->next_new_hash = *new_hash;
 
		*new_hash = v;
 
		assert(v != v->next_new_hash);
 
	}
 

	
 
	/* Remember current hash position */
 
	v->old_new_hash = new_hash;
 
}
 

	
 
static Vehicle *_vehicle_position_hash[0x1000];
 

	
 
static void UpdateVehiclePosHash(Vehicle* v, int x, int y)
 
{
 
	UpdateNewVehiclePosHash(v, x == INVALID_COORD);
 

	
 
	Vehicle **old_hash, **new_hash;
 
	int old_x = v->left_coord;
 
	int old_y = v->top_coord;
 

	
 
	new_hash = (x == INVALID_COORD) ? NULL : &_vehicle_position_hash[GEN_HASH(x, y)];
 
	old_hash = (old_x == INVALID_COORD) ? NULL : &_vehicle_position_hash[GEN_HASH(old_x, old_y)];
 

	
 
	if (old_hash == new_hash) return;
 

	
0 comments (0 inline, 0 general)