Changeset - r7813:e50a8d29e5a0
[Not reviewed]
master
0 1 0
belugas - 17 years ago 2007-10-31 18:01:41
belugas@openttd.org
(svn r11363) -Codechange: Remove some magical numbers
1 file changed with 16 insertions and 6 deletions:
0 comments (0 inline, 0 general)
src/station_cmd.cpp
Show inline comments
 
@@ -181,96 +181,106 @@ static bool CMSAMine(TileIndex tile)
 
	return false;
 
}
 

	
 
/**
 
 * Check whether the tile is water.
 
 * @param tile the tile to investigate.
 
 * @return true if and only if the tile is a mine
 
 */
 
static bool CMSAWater(TileIndex tile)
 
{
 
	return IsTileType(tile, MP_WATER) && IsWater(tile);
 
}
 

	
 
/**
 
 * Check whether the tile is a tree.
 
 * @param tile the tile to investigate.
 
 * @return true if and only if the tile is a mine
 
 */
 
static bool CMSATree(TileIndex tile)
 
{
 
	return IsTileType(tile, MP_TREES);
 
}
 

	
 
/**
 
 * Check whether the tile is a forest.
 
 * @param tile the tile to investigate.
 
 * @return true if and only if the tile is a mine
 
 */
 
static bool CMSAForest(TileIndex tile)
 
{
 
	/* No industry */
 
	if (!IsTileType(tile, MP_INDUSTRY)) return false;
 

	
 
	const Industry *ind = GetIndustryByTile(tile);
 

	
 
	/* No extractive industry */
 
	if ((GetIndustrySpec(ind->type)->life_type & INDUSTRYLIFE_ORGANIC) == 0) return false;
 

	
 
	for (uint i = 0; i < lengthof(ind->produced_cargo); i++) {
 
		/* The industry produces wood. */
 
		if (ind->produced_cargo[i] != CT_INVALID && GetCargo(ind->produced_cargo[i])->label == 'WOOD') return true;
 
	}
 

	
 
	return false;
 
}
 

	
 
#define M(x) ((x) - STR_SV_STNAME)
 

	
 
enum StationNaming = {
 
	STATIONNAMING_RAIL = 0,
 
	STATIONNAMING_ROAD = 0,
 
	STATIONNAMING_AIRPORT,
 
	STATIONNAMING_OILRIG,
 
	STATIONNAMING_DOCK,
 
	STATIONNAMING_BUOY,
 
	STATIONNAMING_HELIPORT,
 
}
 

	
 
static bool GenerateStationName(Station *st, TileIndex tile, int flag)
 
{
 
	static const uint32 _gen_station_name_bits[] = {
 
		0,                                      /* 0 */
 
		1 << M(STR_SV_STNAME_AIRPORT),          /* 1 */
 
		1 << M(STR_SV_STNAME_OILFIELD),         /* 2 */
 
		1 << M(STR_SV_STNAME_DOCKS),            /* 3 */
 
		0x1FF << M(STR_SV_STNAME_BUOY_1),       /* 4 */
 
		1 << M(STR_SV_STNAME_HELIPORT),         /* 5 */
 
	};
 

	
 
	Town *t = st->town;
 
	uint32 free_names = (uint32)-1;
 
	int found;
 
	unsigned long tmp;
 

	
 
	{
 
		Station *s;
 

	
 
		FOR_ALL_STATIONS(s) {
 
			if (s != st && s->town == t) {
 
				uint str = M(s->string_id);
 
				if (str <= 0x20) {
 
					if (str == M(STR_SV_STNAME_FOREST))
 
						str = M(STR_SV_STNAME_WOODS);
 
					CLRBIT(free_names, str);
 
				}
 
			}
 
		}
 
	}
 

	
 
	/* check default names */
 
	tmp = free_names & _gen_station_name_bits[flag];
 
	if (tmp != 0) {
 
		found = FindFirstBit(tmp);
 
		goto done;
 
	}
 

	
 
	/* check mine? */
 
	if (HASBIT(free_names, M(STR_SV_STNAME_MINES))) {
 
		if (CountMapSquareAround(tile, CMSAMine) >= 2) {
 
			found = M(STR_SV_STNAME_MINES);
 
			goto done;
 
		}
 
	}
 

	
 
	/* check close enough to town to get central as name? */
 
	if (DistanceMax(tile, t->xy) < 8) {
 
@@ -917,97 +927,97 @@ CommandCost CmdBuildRailroadStation(Tile
 
				 * be near any other stations. */
 
				st = GetStation(est);
 
				check_surrounding = false;
 
			}
 
		} else {
 
			/* There's no station here. Don't check the tiles surrounding this
 
			 * one if the player wanted to build an adjacent station. */
 
			if (HASBIT(p1, 24)) check_surrounding = false;
 
		}
 
	}
 

	
 
	if (check_surrounding) {
 
		/* Make sure there are no similar stations around us. */
 
		st = GetStationAround(tile_org, w_org, h_org, est);
 
		if (st == CHECK_STATIONS_ERR) return CMD_ERROR;
 
	}
 

	
 
	/* See if there is a deleted station close to us. */
 
	if (st == NULL) st = GetClosestStationFromTile(tile_org);
 

	
 
	/* In case of new station if DC_EXEC is NOT set we still need to create the station
 
	 * to test if everything is OK. In this case we need to delete it before return. */
 
	AutoPtrT<Station> st_auto_delete;
 

	
 
	if (st != NULL) {
 
		/* Reuse an existing station. */
 
		if (st->owner != _current_player)
 
			return_cmd_error(STR_3009_TOO_CLOSE_TO_ANOTHER_STATION);
 

	
 
		if (st->train_tile != 0) {
 
			/* check if we want to expanding an already existing station? */
 
			if (_is_old_ai_player || !_patches.join_stations)
 
				return_cmd_error(STR_3005_TOO_CLOSE_TO_ANOTHER_RAILROAD);
 
			if (!CanExpandRailroadStation(st, finalvalues, axis))
 
				return CMD_ERROR;
 
		}
 

	
 
		/* XXX can't we pack this in the "else" part of the if above? */
 
		if (!st->rect.BeforeAddRect(tile_org, w_org, h_org, StationRect::ADD_TEST)) return CMD_ERROR;
 
	} else {
 
		/* allocate and initialize new station */
 
		st = new Station(tile_org);
 
		if (st == NULL) return_cmd_error(STR_3008_TOO_MANY_STATIONS_LOADING);
 

	
 
		/* ensure that in case of error (or no DC_EXEC) the station gets deleted upon return */
 
		st_auto_delete = st;
 

	
 
		st->town = ClosestTownFromTile(tile_org, (uint)-1);
 
		if (!GenerateStationName(st, tile_org, 0)) return CMD_ERROR;
 
		if (!GenerateStationName(st, tile_org, STATIONNAMING_RAIL)) return CMD_ERROR;
 

	
 
		if (IsValidPlayer(_current_player) && (flags & DC_EXEC) != 0) {
 
			SETBIT(st->town->have_ratings, _current_player);
 
		}
 
	}
 

	
 
	/* Check if the given station class is valid */
 
	if (GB(p2, 8, 8) >= STAT_CLASS_MAX) return CMD_ERROR;
 

	
 
	/* Check if we can allocate a custom stationspec to this station */
 
	const StationSpec *statspec = GetCustomStationSpec((StationClassID)GB(p2, 8, 8), GB(p2, 16, 8));
 
	int specindex = AllocateSpecToStation(statspec, st, flags & DC_EXEC);
 
	if (specindex == -1) return CMD_ERROR;
 

	
 
	if (statspec != NULL) {
 
		/* Perform NewStation checks */
 

	
 
		/* Check if the station size is permitted */
 
		if (HASBIT(statspec->disallowed_platforms, numtracks - 1) || HASBIT(statspec->disallowed_lengths, plat_len - 1)) {
 
			return CMD_ERROR;
 
		}
 

	
 
		/* Check if the station is buildable */
 
		if (HASBIT(statspec->callbackmask, CBM_STATION_AVAIL) && GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, NULL, INVALID_TILE) == 0) {
 
			return CMD_ERROR;
 
		}
 
	}
 

	
 
	if (flags & DC_EXEC) {
 
		TileIndexDiff tile_delta;
 
		byte *layout_ptr;
 
		byte numtracks_orig;
 
		Track track;
 

	
 
		/* Now really clear the land below the station
 
		 * It should never return CMD_ERROR.. but you never know ;)
 
		 * (a bit strange function name for it, but it really does clear the land, when DC_EXEC is in flags) */
 
		ret = CheckFlatLandBelow(tile_org, w_org, h_org, flags, 5 << axis, _patches.nonuniform_stations ? &est : NULL);
 
		if (CmdFailed(ret)) return ret;
 

	
 
		st->train_tile = finalvalues[0];
 
		st->AddFacility(FACIL_TRAIN, finalvalues[0]);
 

	
 
		st->trainst_w = finalvalues[1];
 
		st->trainst_h = finalvalues[2];
 

	
 
		st->rect.BeforeAddRect(tile_org, w_org, h_org, StationRect::ADD_TRY);
 

	
 
@@ -1342,97 +1352,97 @@ CommandCost CmdBuildRoadStop(TileIndex t
 
	}
 
	cost = CheckFlatLandBelow(tile, 1, 1, flags, is_drive_through ? 5 << p1 : 1 << p1, NULL, !build_over_road);
 
	if (CmdFailed(cost)) return cost;
 

	
 
	Station *st = NULL;
 

	
 
	if (!_patches.adjacent_stations || !HASBIT(p2, 5)) {
 
		st = GetStationAround(tile, 1, 1, INVALID_STATION);
 
		if (st == CHECK_STATIONS_ERR) return CMD_ERROR;
 
	}
 

	
 
	/* Find a station close to us */
 
	if (st == NULL) st = GetClosestStationFromTile(tile);
 

	
 
	/* give us a road stop in the list, and check if something went wrong */
 
	RoadStop *road_stop = new RoadStop(tile);
 
	if (road_stop == NULL) {
 
		return_cmd_error(type ? STR_3008B_TOO_MANY_TRUCK_STOPS : STR_3008A_TOO_MANY_BUS_STOPS);
 
	}
 

	
 
	/* ensure that in case of error (or no DC_EXEC) the new road stop gets deleted upon return */
 
	AutoPtrT<RoadStop> rs_auto_delete(road_stop);
 

	
 
	if (st != NULL &&
 
			GetNumRoadStopsInStation(st, RoadStop::BUS) + GetNumRoadStopsInStation(st, RoadStop::TRUCK) >= RoadStop::LIMIT) {
 
		return_cmd_error(type ? STR_3008B_TOO_MANY_TRUCK_STOPS : STR_3008A_TOO_MANY_BUS_STOPS);
 
	}
 

	
 
	/* In case of new station if DC_EXEC is NOT set we still need to create the station
 
	 * to test if everything is OK. In this case we need to delete it before return. */
 
	AutoPtrT<Station> st_auto_delete;
 

	
 
	if (st != NULL) {
 
		if (st->owner != _current_player) {
 
			return_cmd_error(STR_3009_TOO_CLOSE_TO_ANOTHER_STATION);
 
		}
 

	
 
		if (!st->rect.BeforeAddTile(tile, StationRect::ADD_TEST)) return CMD_ERROR;
 
	} else {
 
		/* allocate and initialize new station */
 
		st = new Station(tile);
 
		if (st == NULL) return_cmd_error(STR_3008_TOO_MANY_STATIONS_LOADING);
 

	
 
		/* ensure that in case of error (or no DC_EXEC) the new station gets deleted upon return */
 
		st_auto_delete = st;
 

	
 

	
 
		Town *t = st->town = ClosestTownFromTile(tile, (uint)-1);
 
		if (!GenerateStationName(st, tile, 0)) return CMD_ERROR;
 
		if (!GenerateStationName(st, tile, STATIONNAMING_ROAD)) return CMD_ERROR;
 

	
 
		if (IsValidPlayer(_current_player) && (flags & DC_EXEC) != 0) {
 
			SETBIT(t->have_ratings, _current_player);
 
		}
 

	
 
		st->sign.width_1 = 0;
 
	}
 

	
 
	cost.AddCost((type) ? _price.build_truck_station : _price.build_bus_station);
 

	
 
	if (flags & DC_EXEC) {
 
		/* Insert into linked list of RoadStops */
 
		RoadStop **currstop = FindRoadStopSpot(type, st);
 
		*currstop = road_stop;
 

	
 
		/*initialize an empty station */
 
		st->AddFacility((type) ? FACIL_TRUCK_STOP : FACIL_BUS_STOP, tile);
 

	
 
		st->rect.BeforeAddTile(tile, StationRect::ADD_TRY);
 

	
 
		RoadStop::Type rs_type = type ? RoadStop::TRUCK : RoadStop::BUS;
 
		if (is_drive_through) {
 
			MakeDriveThroughRoadStop(tile, st->owner, st->index, rs_type, rts, (Axis)p1, town_owned_road);
 
		} else {
 
			MakeRoadStop(tile, st->owner, st->index, rs_type, rts, (DiagDirection)p1);
 
		}
 

	
 
		UpdateStationVirtCoordDirty(st);
 
		UpdateStationAcceptance(st, false);
 
		RebuildStationLists();
 
		InvalidateWindow(WC_STATION_LIST, st->owner);
 
		/* success, so don't delete the new station and the new road stop */
 
		st_auto_delete.Detach();
 
		rs_auto_delete.Detach();
 
	}
 
	return cost;
 
}
 

	
 
/** Remove a bus station
 
 * @param st Station to remove
 
 * @param flags operation to perform
 
 * @param tile TileIndex been queried
 
 * @return cost or failure of operation
 
 */
 
static CommandCost RemoveRoadStop(Station *st, uint32 flags, TileIndex tile)
 
{
 
	if (_current_player != OWNER_WATER && !CheckOwnership(st->owner)) {
 
		return CMD_ERROR;
 
@@ -1650,97 +1660,97 @@ CommandCost CmdBuildAirport(TileIndex ti
 

	
 
	Station *st = NULL;
 

	
 
	if (!_patches.adjacent_stations || !HASBIT(p2, 0)) {
 
		st = GetStationAround(tile, w, h, INVALID_STATION);
 
		if (st == CHECK_STATIONS_ERR) return CMD_ERROR;
 
	}
 

	
 
	/* Find a station close to us */
 
	if (st == NULL) st = GetClosestStationFromTile(tile);
 

	
 
	if (w > _patches.station_spread || h > _patches.station_spread) {
 
		_error_message = STR_306C_STATION_TOO_SPREAD_OUT;
 
		return CMD_ERROR;
 
	}
 

	
 
	/* In case of new station if DC_EXEC is NOT set we still need to create the station
 
	 * to test if everything is OK. In this case we need to delete it before return. */
 
	AutoPtrT<Station> st_auto_delete;
 

	
 
	if (st != NULL) {
 
		if (st->owner != _current_player)
 
			return_cmd_error(STR_3009_TOO_CLOSE_TO_ANOTHER_STATION);
 

	
 
		if (!st->rect.BeforeAddRect(tile, w, h, StationRect::ADD_TEST)) return CMD_ERROR;
 

	
 
		if (st->airport_tile != 0)
 
			return_cmd_error(STR_300D_TOO_CLOSE_TO_ANOTHER_AIRPORT);
 
	} else {
 
		airport_upgrade = false;
 

	
 
		/* allocate and initialize new station */
 
		st = new Station(tile);
 
		if (st == NULL) return_cmd_error(STR_3008_TOO_MANY_STATIONS_LOADING);
 

	
 
		/* ensure that in case of error (or no DC_EXEC) the station gets deleted upon return */
 
		st_auto_delete = st;
 

	
 
		st->town = t;
 

	
 
		if (IsValidPlayer(_current_player) && (flags & DC_EXEC) != 0) {
 
			SETBIT(t->have_ratings, _current_player);
 
		}
 

	
 
		st->sign.width_1 = 0;
 

	
 
		/* If only helicopters may use the airport generate a helicopter related (5)
 
		 * station name, otherwise generate a normal airport name (1) */
 
		if (!GenerateStationName(st, tile, !(afc->flags & AirportFTAClass::AIRPLANES) ? 5 : 1)) {
 
		if (!GenerateStationName(st, tile, !(afc->flags & AirportFTAClass::AIRPLANES) ? STATIONNAMING_HELIPORT : STATIONNAMING_AIRPORT)) {
 
			return CMD_ERROR;
 
		}
 
	}
 

	
 
	cost.AddCost(_price.build_airport * w * h);
 

	
 
	if (flags & DC_EXEC) {
 
		st->airport_tile = tile;
 
		st->AddFacility(FACIL_AIRPORT, tile);
 
		st->airport_type = (byte)p1;
 
		st->airport_flags = 0;
 

	
 
		st->rect.BeforeAddRect(tile, w, h, StationRect::ADD_TRY);
 

	
 
		/* if airport was demolished while planes were en-route to it, the
 
		 * positions can no longer be the same (v->u.air.pos), since different
 
		 * airports have different indexes. So update all planes en-route to this
 
		 * airport. Only update if
 
		 * 1. airport is upgraded
 
		 * 2. airport is added to existing station (unfortunately unavoideable)
 
		 */
 
		if (airport_upgrade) UpdateAirplanesOnNewStation(st);
 

	
 
		{
 
			const byte *b = _airport_sections[p1];
 

	
 
			BEGIN_TILE_LOOP(tile_cur, w, h, tile) {
 
				MakeAirport(tile_cur, st->owner, st->index, *b - ((*b < 67) ? 8 : 24));
 
				b++;
 
			} END_TILE_LOOP(tile_cur, w, h, tile)
 
		}
 

	
 
		UpdateStationVirtCoordDirty(st);
 
		UpdateStationAcceptance(st, false);
 
		RebuildStationLists();
 
		InvalidateWindow(WC_STATION_LIST, st->owner);
 
		/* success, so don't delete the new station */
 
		st_auto_delete.Detach();
 
	}
 

	
 
	return cost;
 
}
 

	
 
static CommandCost RemoveAirport(Station *st, uint32 flags)
 
{
 
	if (_current_player != OWNER_WATER && !CheckOwnership(st->owner))
 
		return CMD_ERROR;
 

	
 
@@ -1765,97 +1775,97 @@ static CommandCost RemoveAirport(Station
 
		if (flags & DC_EXEC) {
 
			DeleteAnimatedTile(tile_cur);
 
			DoClearSquare(tile_cur);
 
		}
 
	} END_TILE_LOOP(tile_cur, w, h, tile)
 

	
 
	if (flags & DC_EXEC) {
 
		for (uint i = 0; i < afc->nof_depots; ++i) {
 
			DeleteWindowById(
 
				WC_VEHICLE_DEPOT, tile + ToTileIndexDiff(afc->airport_depots[i])
 
			);
 
		}
 

	
 
		st->rect.AfterRemoveRect(st, tile, w, h);
 

	
 
		st->airport_tile = 0;
 
		st->facilities &= ~FACIL_AIRPORT;
 

	
 
		UpdateStationVirtCoordDirty(st);
 
		DeleteStationIfEmpty(st);
 
	}
 

	
 
	return cost;
 
}
 

	
 
/** Build a buoy.
 
 * @param tile tile where to place the bouy
 
 * @param flags operation to perform
 
 * @param p1 unused
 
 * @param p2 unused
 
 */
 
CommandCost CmdBuildBuoy(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 

	
 
	if (!IsWaterTile(tile) || tile == 0) return_cmd_error(STR_304B_SITE_UNSUITABLE);
 
	if (MayHaveBridgeAbove(tile) && IsBridgeAbove(tile)) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
 

	
 
	/* allocate and initialize new station */
 
	Station *st = new Station(tile);
 
	if (st == NULL) return_cmd_error(STR_3008_TOO_MANY_STATIONS_LOADING);
 

	
 
	/* ensure that in case of error (or no DC_EXEC) the station gets deleted upon return */
 
	AutoPtrT<Station> st_auto_delete(st);
 

	
 
	st->town = ClosestTownFromTile(tile, (uint)-1);
 
	st->sign.width_1 = 0;
 

	
 
	if (!GenerateStationName(st, tile, 4)) return CMD_ERROR;
 
	if (!GenerateStationName(st, tile, STATIONNAMING_BUOY)) return CMD_ERROR;
 

	
 
	if (flags & DC_EXEC) {
 
		st->dock_tile = tile;
 
		st->facilities |= FACIL_DOCK;
 
		/* Buoys are marked in the Station struct by this flag. Yes, it is this
 
		 * braindead.. */
 
		st->had_vehicle_of_type |= HVOT_BUOY;
 
		st->owner = OWNER_NONE;
 

	
 
		st->build_date = _date;
 

	
 
		MakeBuoy(tile, st->index);
 

	
 
		UpdateStationVirtCoordDirty(st);
 
		UpdateStationAcceptance(st, false);
 
		RebuildStationLists();
 
		InvalidateWindow(WC_STATION_LIST, st->owner);
 
		/* success, so don't delete the new station */
 
		st_auto_delete.Detach();
 
	}
 

	
 
	return CommandCost(_price.build_dock);
 
}
 

	
 
/* Checks if any ship is servicing the buoy specified. Returns yes or no */
 
static bool CheckShipsOnBuoy(Station *st)
 
{
 
	const Vehicle *v;
 
	FOR_ALL_VEHICLES(v) {
 
		if (v->type == VEH_SHIP) {
 
			const Order *order;
 
			FOR_VEHICLE_ORDERS(v, order) {
 
				if (order->type == OT_GOTO_STATION && order->dest == st->index) {
 
					return true;
 
				}
 
			}
 
		}
 
	}
 
	return false;
 
}
 

	
 
static CommandCost RemoveBuoy(Station *st, uint32 flags)
 
{
 
	/* XXX: strange stuff */
 
	if (!IsValidPlayer(_current_player))  return_cmd_error(INVALID_STRING_ID);
 

	
 
	TileIndex tile = st->dock_tile;
 

	
 
@@ -1935,97 +1945,97 @@ CommandCost CmdBuildDock(TileIndex tile,
 
	cost = DoCommand(tile_cur, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 
	if (CmdFailed(cost)) return CMD_ERROR;
 

	
 
	tile_cur += TileOffsByDiagDir(direction);
 
	if (!IsTileType(tile_cur, MP_WATER) || GetTileSlope(tile_cur, NULL) != SLOPE_FLAT) {
 
		return_cmd_error(STR_304B_SITE_UNSUITABLE);
 
	}
 

	
 
	/* middle */
 
	Station *st = NULL;
 

	
 
	if (!_patches.adjacent_stations || !HASBIT(p1, 0)) {
 
		st = GetStationAround(
 
				tile + ToTileIndexDiff(_dock_tileoffs_chkaround[direction]),
 
				_dock_w_chk[direction], _dock_h_chk[direction], INVALID_STATION);
 
		if (st == CHECK_STATIONS_ERR) return CMD_ERROR;
 
	}
 

	
 
	/* Find a station close to us */
 
	if (st == NULL) st = GetClosestStationFromTile(tile);
 

	
 
	/* In case of new station if DC_EXEC is NOT set we still need to create the station
 
	 * to test if everything is OK. In this case we need to delete it before return. */
 
	AutoPtrT<Station> st_auto_delete;
 

	
 
	if (st != NULL) {
 
		if (st->owner != _current_player)
 
			return_cmd_error(STR_3009_TOO_CLOSE_TO_ANOTHER_STATION);
 

	
 
		if (!st->rect.BeforeAddRect(tile, _dock_w_chk[direction], _dock_h_chk[direction], StationRect::ADD_TEST)) return CMD_ERROR;
 

	
 
		if (st->dock_tile != 0) return_cmd_error(STR_304C_TOO_CLOSE_TO_ANOTHER_DOCK);
 
	} else {
 
		/* allocate and initialize new station */
 
		st = new Station(tile);
 
		if (st == NULL) return_cmd_error(STR_3008_TOO_MANY_STATIONS_LOADING);
 

	
 
		/* ensure that in case of error (or no DC_EXEC) the station gets deleted upon return */
 
		st_auto_delete = st;
 

	
 
		Town *t = st->town = ClosestTownFromTile(tile, (uint)-1);
 

	
 
		if (IsValidPlayer(_current_player) && (flags & DC_EXEC) != 0) {
 
			SETBIT(t->have_ratings, _current_player);
 
		}
 

	
 
		st->sign.width_1 = 0;
 

	
 
		if (!GenerateStationName(st, tile, 3)) return CMD_ERROR;
 
		if (!GenerateStationName(st, tile, STATIONNAMING_DOCK)) return CMD_ERROR;
 
	}
 

	
 
	if (flags & DC_EXEC) {
 
		st->dock_tile = tile;
 
		st->AddFacility(FACIL_DOCK, tile);
 

	
 
		st->rect.BeforeAddRect(tile, _dock_w_chk[direction], _dock_h_chk[direction], StationRect::ADD_TRY);
 

	
 
		MakeDock(tile, st->owner, st->index, direction);
 

	
 
		UpdateStationVirtCoordDirty(st);
 
		UpdateStationAcceptance(st, false);
 
		RebuildStationLists();
 
		InvalidateWindow(WC_STATION_LIST, st->owner);
 
		/* success, so don't delete the new station */
 
		st_auto_delete.Detach();
 
	}
 
	return CommandCost(_price.build_dock);
 
}
 

	
 
static CommandCost RemoveDock(Station *st, uint32 flags)
 
{
 
	if (!CheckOwnership(st->owner)) return CMD_ERROR;
 

	
 
	TileIndex tile1 = st->dock_tile;
 
	TileIndex tile2 = tile1 + TileOffsByDiagDir(GetDockDirection(tile1));
 

	
 
	if (!EnsureNoVehicleOnGround(tile1)) return CMD_ERROR;
 
	if (!EnsureNoVehicleOnGround(tile2)) return CMD_ERROR;
 

	
 
	if (flags & DC_EXEC) {
 
		DoClearSquare(tile1);
 
		MakeWater(tile2);
 

	
 
		st->rect.AfterRemoveTile(st, tile1);
 
		st->rect.AfterRemoveTile(st, tile2);
 

	
 
		MarkTileDirtyByTile(tile2);
 

	
 
		st->dock_tile = 0;
 
		st->facilities &= ~FACIL_DOCK;
 

	
 
		UpdateStationVirtCoordDirty(st);
 
		DeleteStationIfEmpty(st);
 
	}
 

	
 
	return CommandCost(_price.remove_dock);
 
}
 
@@ -2704,97 +2714,97 @@ uint MoveGoodsToStation(TileIndex tile, 
 

	
 
	for (uint i = 0; i != lengthof(around) && around[i] != NULL; i++) {
 
		if (around[i]->goods[type].rating >= best_rating) {
 
			best_rating2 = best_rating;
 
			st2 = st1;
 

	
 
			best_rating = around[i]->goods[type].rating;
 
			st1 = around[i];
 
		} else if (around[i]->goods[type].rating >= best_rating2) {
 
			best_rating2 = around[i]->goods[type].rating;
 
			st2 = around[i];
 
		}
 
	}
 

	
 
	assert(st1 != NULL);
 
	assert(st2 != NULL);
 
	assert(best_rating != 0 || best_rating2 != 0);
 

	
 
	/* the 2nd highest one gets a penalty */
 
	best_rating2 >>= 1;
 

	
 
	/* amount given to station 1 */
 
	uint t = (best_rating * (amount + 1)) / (best_rating + best_rating2);
 

	
 
	uint moved = 0;
 
	if (t != 0) {
 
		moved = t * best_rating / 256 + 1;
 
		amount -= t;
 
		UpdateStationWaiting(st1, type, moved);
 
	}
 

	
 
	if (amount != 0) {
 
		amount = amount * best_rating2 / 256 + 1;
 
		moved += amount;
 
		UpdateStationWaiting(st2, type, amount);
 
	}
 

	
 
	return moved;
 
}
 

	
 
void BuildOilRig(TileIndex tile)
 
{
 
	Station *st = new Station();
 

	
 
	if (st == NULL) {
 
		DEBUG(misc, 0, "Can't allocate station for oilrig at 0x%X, reverting to oilrig only", tile);
 
		return;
 
	}
 
	if (!GenerateStationName(st, tile, 2)) {
 
	if (!GenerateStationName(st, tile, STATIONNAMING_OILRIG)) {
 
		DEBUG(misc, 0, "Can't allocate station-name for oilrig at 0x%X, reverting to oilrig only", tile);
 
		return;
 
	}
 

	
 
	st->town = ClosestTownFromTile(tile, (uint)-1);
 
	st->sign.width_1 = 0;
 

	
 
	MakeOilrig(tile, st->index);
 

	
 
	st->owner = OWNER_NONE;
 
	st->airport_flags = 0;
 
	st->airport_type = AT_OILRIG;
 
	st->xy = tile;
 
	st->bus_stops = NULL;
 
	st->truck_stops = NULL;
 
	st->airport_tile = tile;
 
	st->dock_tile = tile;
 
	st->train_tile = 0;
 
	st->had_vehicle_of_type = 0;
 
	st->time_since_load = 255;
 
	st->time_since_unload = 255;
 
	st->delete_ctr = 0;
 
	st->last_vehicle_type = VEH_INVALID;
 
	st->facilities = FACIL_AIRPORT | FACIL_DOCK;
 
	st->build_date = _date;
 

	
 
	for (CargoID j = 0; j < NUM_CARGO; j++) {
 
		st->goods[j].acceptance_pickup = 0;
 
		st->goods[j].days_since_pickup = 255;
 
		st->goods[j].rating = INITIAL_STATION_RATING;
 
		st->goods[j].last_speed = 0;
 
		st->goods[j].last_age = 255;
 
	}
 

	
 
	UpdateStationVirtCoordDirty(st);
 
	UpdateStationAcceptance(st, false);
 
}
 

	
 
void DeleteOilRig(TileIndex tile)
 
{
 
	Station* st = GetStationByTile(tile);
 

	
 
	MakeWater(tile);
 

	
 
	st->dock_tile = 0;
 
	st->airport_tile = 0;
 
	st->facilities &= ~(FACIL_AIRPORT | FACIL_DOCK);
 
	st->airport_flags = 0;
0 comments (0 inline, 0 general)