File diff r7376:c436274a8ff0 → r7377:722cd70012ed
src/station.cpp
Show inline comments
 
@@ -70,71 +70,48 @@ Station::~Station()
 

	
 
	DeleteWindowById(WC_STATION_VIEW, index);
 

	
 
	/* Now delete all orders that go to the station */
 
	RemoveOrderFromAllVehicles(OT_GOTO_STATION, index);
 

	
 
	/* Subsidies need removal as well */
 
	DeleteSubsidyWithStation(index);
 

	
 
	xy = 0;
 

	
 
	for (CargoID c = 0; c < NUM_CARGO; c++) {
 
		goods[c].cargo.Truncate(0);
 
	}
 

	
 
	this->QuickFree();
 
}
 

	
 
void Station::QuickFree()
 
{
 
	DeleteName(this->string_id);
 
	free(this->speclist);
 
}
 

	
 
void *Station::operator new(size_t size)
 
{
 
	Station *st = AllocateRaw();
 
	return st;
 
}
 

	
 
void *Station::operator new(size_t size, int st_idx)
 
{
 
	if (!AddBlockIfNeeded(&_Station_pool, st_idx))
 
		error("Stations: failed loading savegame: too many stations");
 

	
 
	Station *st = GetStation(st_idx);
 
	return st;
 
}
 

	
 
void Station::operator delete(void *p)
 
{
 
}
 

	
 
void Station::operator delete(void *p, int st_idx)
 
{
 
}
 

	
 
/** Called when new facility is built on the station. If it is the first facility
 
 * it initializes also 'xy' and 'random_bits' members */
 
void Station::AddFacility(byte new_facility_bit, TileIndex facil_xy)
 
{
 
	if (facilities == 0) {
 
		xy = facil_xy;
 
		random_bits = Random();
 
	}
 
	facilities |= new_facility_bit;
 
	owner = _current_player;
 
	build_date = _date;
 
}
 

	
 
void Station::MarkDirty() const
 
{
 
	if (sign.width_1 != 0) {
 
		InvalidateWindowWidget(WC_STATION_VIEW, index, 1);
 

	
 
		/* We use ZOOM_LVL_MAX here, as every viewport can have an other zoom,
 
		 *  and there is no way for us to know which is the biggest. So make the
 
		 *  biggest area dirty, and we are safe for sure. */
 
		MarkAllViewportsDirty(
 
			sign.left - 6,
 
			sign.top,
 
@@ -155,72 +132,48 @@ void Station::MarkTilesDirty(bool cargo_
 
	 * around. */
 
	if (cargo_change) {
 
		/* Don't waste time updating if there are no custom station graphics
 
		 * that might change. Even if there are custom graphics, they might
 
		 * not change. Unfortunately we have no way of telling. */
 
		if (this->num_specs == 0) return;
 
	}
 

	
 
	for (h = 0; h < trainst_h; h++) {
 
		for (w = 0; w < trainst_w; w++) {
 
			if (TileBelongsToRailStation(tile)) {
 
				MarkTileDirtyByTile(tile);
 
			}
 
			tile += TileDiffXY(1, 0);
 
		}
 
		tile += TileDiffXY(-w, 1);
 
	}
 
}
 

	
 
bool Station::TileBelongsToRailStation(TileIndex tile) const
 
{
 
	return IsTileType(tile, MP_STATION) && GetStationIndex(tile) == index && IsRailwayStation(tile);
 
}
 

	
 
/*static*/ Station *Station::AllocateRaw()
 
{
 
	Station *st = NULL;
 

	
 
	/* We don't use FOR_ALL here, because FOR_ALL skips invalid items.
 
	 * TODO - This is just a temporary stage, this will be removed. */
 
	for (st = GetStation(0); st != NULL; st = (st->index + 1U < GetStationPoolSize()) ? GetStation(st->index + 1U) : NULL) {
 
		if (!st->IsValid()) {
 
			StationID index = st->index;
 

	
 
			memset(st, 0, sizeof(Station));
 
			st->index = index;
 
			return st;
 
		}
 
	}
 

	
 
	/* Check if we can add a block to the pool */
 
	if (AddBlockToPool(&_Station_pool)) return AllocateRaw();
 

	
 
	_error_message = STR_3008_TOO_MANY_STATIONS_LOADING;
 
	return NULL;
 
}
 

	
 

	
 
/** Obtain the length of a platform
 
 * @pre tile must be a railway station tile
 
 * @param tile A tile that contains the platform in question
 
 * @return The length of the platform
 
 */
 
uint Station::GetPlatformLength(TileIndex tile) const
 
{
 
	TileIndex t;
 
	TileIndexDiff delta;
 
	uint len = 0;
 
	assert(TileBelongsToRailStation(tile));
 

	
 
	delta = (GetRailStationAxis(tile) == AXIS_X ? TileDiffXY(1, 0) : TileDiffXY(0, 1));
 

	
 
	t = tile;
 
	do {
 
		t -= delta;
 
		len++;
 
	} while (IsCompatibleTrainStationTile(t, tile));
 

	
 
	t = tile;
 
	do {
 
		t += delta;
 
		len++;
 
@@ -405,136 +358,82 @@ bool StationRect::AfterRemoveTile(Statio
 
bool StationRect::AfterRemoveRect(Station *st, TileIndex tile, int w, int h)
 
{
 
	assert(PtInExtendedRect(TileX(tile), TileY(tile)));
 
	assert(PtInExtendedRect(TileX(tile) + w - 1, TileY(tile) + h - 1));
 

	
 
	bool empty = AfterRemoveTile(st, tile);
 
	if (w != 1 || h != 1) empty = empty || AfterRemoveTile(st, TILE_ADDXY(tile, w - 1, h - 1));
 
	return empty;
 
}
 

	
 
StationRect& StationRect::operator = (Rect src)
 
{
 
	left = src.left;
 
	top = src.top;
 
	right = src.right;
 
	bottom = src.bottom;
 
	return *this;
 
}
 

	
 

	
 
/************************************************************************/
 
/*                     RoadStop implementation                          */
 
/************************************************************************/
 

	
 
/** Allocates a new RoadStop onto the pool, or recycles an unsed one
 
 *  @return a pointer to the new roadstop
 
 */
 
void *RoadStop::operator new(size_t size)
 
{
 
	RoadStop *rs = AllocateRaw();
 
	return rs;
 
}
 

	
 
/** Gets a RoadStop with a given index and allocates it when needed
 
  * @return a pointer to the roadstop
 
  */
 
void *RoadStop::operator new(size_t size, int index)
 
{
 
	if (!AddBlockIfNeeded(&_RoadStop_pool, index)) {
 
		error("RoadStops: failed loading savegame: too many RoadStops");
 
	}
 

	
 
	RoadStop *rs = GetRoadStop(index);
 
	return rs;
 
}
 

	
 
void RoadStop::operator delete(void *p)
 
{
 
}
 

	
 
void RoadStop::operator delete(void *p, int index)
 
{
 
}
 

	
 
/** Initializes a RoadStop */
 
RoadStop::RoadStop(TileIndex tile) :
 
	xy(tile),
 
	status(3), // stop is free
 
	num_vehicles(0),
 
	next(NULL)
 
{
 
	DEBUG(ms, cDebugCtorLevel,  "I+ at %d[0x%x]", tile, tile);
 
}
 

	
 
/** De-Initializes a RoadStops. This includes clearing all slots that vehicles might
 
  * have and unlinks it from the linked list of road stops at the given station
 
  */
 
RoadStop::~RoadStop()
 
{
 
	/* Clear the slot assignment of all vehicles heading for this road stop */
 
	if (num_vehicles != 0) {
 
		Vehicle *v;
 

	
 
		FOR_ALL_VEHICLES(v) {
 
			if (v->type == VEH_ROAD && v->u.road.slot == this) ClearSlot(v);
 
		}
 
	}
 
	assert(num_vehicles == 0);
 

	
 
	DEBUG(ms, cDebugCtorLevel , "I- at %d[0x%x]", xy, xy);
 

	
 
	xy = INVALID_TILE;
 
}
 

	
 
/** Low-level function for allocating a RoadStop on the pool */
 
RoadStop *RoadStop::AllocateRaw()
 
{
 
	RoadStop *rs;
 

	
 
	/* We don't use FOR_ALL here, because FOR_ALL skips invalid items.
 
	 * TODO - This is just a temporary stage, this will be removed. */
 
	for (rs = GetRoadStop(0); rs != NULL; rs = (rs->index + 1U < GetRoadStopPoolSize()) ? GetRoadStop(rs->index + 1U) : NULL) {
 
		if (!rs->IsValid()) {
 
			RoadStopID index = rs->index;
 

	
 
			memset(rs, 0, sizeof(*rs));
 
			rs->index = index;
 

	
 
			return rs;
 
		}
 
	}
 

	
 
	/* Check if we can add a block to the pool */
 
	if (AddBlockToPool(&_RoadStop_pool)) return AllocateRaw();
 

	
 
	return NULL;
 
	xy = 0;
 
}
 

	
 
/** Determines whether a RoadStop is a valid (i.e. existing) one */
 
bool RoadStop::IsValid() const
 
{
 
	return xy != INVALID_TILE;
 
	return xy != 0;
 
}
 

	
 
/** Checks whether there is a free bay in this road stop */
 
bool RoadStop::HasFreeBay() const
 
{
 
	return GB(status, 0, MAX_BAY_COUNT) != 0;
 
}
 

	
 
/** Checks whether the given bay is free in this road stop */
 
bool RoadStop::IsFreeBay(uint nr) const
 
{
 
	assert(nr < MAX_BAY_COUNT);
 
	return HASBIT(status, nr);
 
}
 

	
 
/**
 
 * Allocates a bay
 
 * @return the allocated bay number
 
 * @pre this->HasFreeBay()
 
 */
 
uint RoadStop::AllocateBay()
 
{
 
	assert(HasFreeBay());