--- a/src/station_cmd.cpp Wed Jan 09 18:11:12 2008 +0000
+++ b/src/station_cmd.cpp Sun Feb 03 20:17:54 2008 +0000
@@ -11,15 +11,12 @@
#include "tile_cmd.h"
#include "landscape.h"
#include "station_map.h"
-#include "table/sprites.h"
-#include "table/strings.h"
#include "station.h"
#include "viewport_func.h"
#include "command_func.h"
#include "town.h"
#include "news.h"
#include "saveload.h"
-#include "player.h"
#include "airport.h"
#include "sprite.h"
#include "depot.h"
@@ -45,6 +42,10 @@
#include "date_func.h"
#include "vehicle_func.h"
#include "string_func.h"
+#include "signal_func.h"
+
+#include "table/sprites.h"
+#include "table/strings.h"
DEFINE_OLD_POOL_GENERIC(Station, Station)
DEFINE_OLD_POOL_GENERIC(RoadStop, RoadStop)
@@ -699,7 +700,7 @@
* @param w width of search area
* @param h height of search area
* @param flags operation to perform
- * @param invalid_dirs prohibited directions
+ * @param invalid_dirs prohibited directions (set of DiagDirections)
* @param station StationID to be queried and returned if available
* @param check_clear if clearing tile should be performed (in wich case, cost will be added)
* @return the cost in case of success, or an error code if it failed.
@@ -734,11 +735,12 @@
int flat_z = z;
if (tileh != SLOPE_FLAT) {
- /* need to check so the entrance to the station is not pointing at a slope. */
- if ((invalid_dirs & 1 && !(tileh & SLOPE_NE) && (uint)w_cur == w) ||
- (invalid_dirs & 2 && !(tileh & SLOPE_SE) && h_cur == 1) ||
- (invalid_dirs & 4 && !(tileh & SLOPE_SW) && w_cur == 1) ||
- (invalid_dirs & 8 && !(tileh & SLOPE_NW) && (uint)h_cur == h)) {
+ /* need to check so the entrance to the station is not pointing at a slope.
+ * This must be valid for all station tiles, as the user can remove single station tiles. */
+ if ((HasBit(invalid_dirs, DIAGDIR_NE) && !(tileh & SLOPE_NE)) ||
+ (HasBit(invalid_dirs, DIAGDIR_SE) && !(tileh & SLOPE_SE)) ||
+ (HasBit(invalid_dirs, DIAGDIR_SW) && !(tileh & SLOPE_SW)) ||
+ (HasBit(invalid_dirs, DIAGDIR_NW) && !(tileh & SLOPE_NW))) {
return_cmd_error(STR_0007_FLAT_LAND_REQUIRED);
}
cost.AddCost(_price.terraform);
@@ -797,14 +799,14 @@
* the uniform-stations code wouldn't handle it well */
BEGIN_TILE_LOOP(t, st->trainst_w, st->trainst_h, st->train_tile)
if (!st->TileBelongsToRailStation(t)) { // there may be adjoined station
- _error_message = STR_306D_NONUNIFORM_STATIONS_DISALLOWED;
+ _error_message = STR_NONUNIFORM_STATIONS_DISALLOWED;
return false;
}
END_TILE_LOOP(t, st->trainst_w, st->trainst_h, st->train_tile)
/* check so the orientation is the same */
if (GetRailStationAxis(st->train_tile) != axis) {
- _error_message = STR_306D_NONUNIFORM_STATIONS_DISALLOWED;
+ _error_message = STR_NONUNIFORM_STATIONS_DISALLOWED;
return false;
}
@@ -824,7 +826,7 @@
tile -= TileDiffXY(curw, 0);
curw += w;
} else {
- _error_message = STR_306D_NONUNIFORM_STATIONS_DISALLOWED;
+ _error_message = STR_NONUNIFORM_STATIONS_DISALLOWED;
return false;
}
}
@@ -905,7 +907,7 @@
/* Does the authority allow this? */
if (!(flags & DC_NO_TOWN_RATING) && !CheckIfAuthorityAllows(tile_org)) return CMD_ERROR;
- if (!ValParamRailtype(p2 & 0xF)) return CMD_ERROR;
+ if (!ValParamRailtype((RailType)(p2 & 0xF))) return CMD_ERROR;
/* unpack parameters */
Axis axis = Extract<Axis, 0>(p1);
@@ -1003,7 +1005,7 @@
}
/* Check if the given station class is valid */
- if (GB(p2, 8, 8) >= STAT_CLASS_MAX) return CMD_ERROR;
+ if (GB(p2, 8, 8) >= GetNumStationClasses()) 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));
@@ -1072,7 +1074,7 @@
tile += tile_delta;
} while (--w);
- SetSignalsOnBothDir(tile_org, track);
+ AddTrackToSignalBuffer(tile_org, track, _current_player);
YapfNotifyTrackLayoutChange(tile_org, track);
tile_org += tile_delta ^ TileDiffXY(1, 1); // perpendicular to tile_delta
} while (--numtracks);
@@ -1195,17 +1197,20 @@
/* Do not allow removing from stations if non-uniform stations are not enabled
* The check must be here to give correct error message
*/
- if (!_patches.nonuniform_stations) return_cmd_error(STR_306D_NONUNIFORM_STATIONS_DISALLOWED);
+ if (!_patches.nonuniform_stations) return_cmd_error(STR_NONUNIFORM_STATIONS_DISALLOWED);
/* If we reached here, the tile is valid so increase the quantity of tiles we will remove */
quantity++;
if (flags & DC_EXEC) {
+ /* read variables before the station tile is removed */
uint specindex = GetCustomStationSpecIndex(tile2);
Track track = GetRailStationTrack(tile2);
+ Owner owner = GetTileOwner(tile2);
+
DoClearSquare(tile2);
st->rect.AfterRemoveTile(st, tile2);
- SetSignalsOnBothDir(tile2, track);
+ AddTrackToSignalBuffer(tile2, track, owner);
YapfNotifyTrackLayoutChange(tile2, track);
DeallocateSpecFromStation(st, specindex);
@@ -1256,15 +1261,17 @@
do {
int w_bak = w;
do {
- // for nonuniform stations, only remove tiles that are actually train station tiles
+ /* for nonuniform stations, only remove tiles that are actually train station tiles */
if (st->TileBelongsToRailStation(tile)) {
if (!EnsureNoVehicleOnGround(tile))
return CMD_ERROR;
cost.AddCost(_price.remove_rail_station);
if (flags & DC_EXEC) {
+ /* read variables before the station tile is removed */
Track track = GetRailStationTrack(tile);
+ Owner owner = GetTileOwner(tile); // _current_player can be OWNER_WATER
DoClearSquare(tile);
- SetSignalsOnBothDir(tile, track);
+ AddTrackToSignalBuffer(tile, track, owner);
YapfNotifyTrackLayoutChange(tile, track);
}
}
@@ -1351,13 +1358,23 @@
if (IsTileOwner(tile, OWNER_TOWN) && !_patches.road_stop_on_town_road) return_cmd_error(STR_DRIVE_THROUGH_ERROR_ON_TOWN_ROAD);
if (GetRoadTileType(tile) != ROAD_TILE_NORMAL) return CMD_ERROR;
+ RoadTypes cur_rts = GetRoadTypes(tile);
+
+ /* there is a road, check if we can build road+tram stop over it */
+ if (HasBit(cur_rts, ROADTYPE_ROAD)) {
+ Owner road_owner = GetRoadOwner(tile, ROADTYPE_ROAD);
+ if (road_owner != OWNER_TOWN && road_owner != OWNER_NONE && !CheckOwnership(road_owner)) return CMD_ERROR;
+ }
+
+ /* there is a tram, check if we can build road+tram stop over it */
+ if (HasBit(cur_rts, ROADTYPE_TRAM)) {
+ Owner tram_owner = GetRoadOwner(tile, ROADTYPE_TRAM);
+ if (tram_owner != OWNER_NONE && !CheckOwnership(tram_owner)) return CMD_ERROR;
+ }
+
/* Don't allow building the roadstop when vehicles are already driving on it */
if (!EnsureNoVehicleOnGround(tile)) return CMD_ERROR;
- RoadTypes cur_rts = GetRoadTypes(tile);
- if (GetRoadOwner(tile, ROADTYPE_ROAD) != OWNER_TOWN && HasBit(cur_rts, ROADTYPE_ROAD) && !CheckOwnership(GetRoadOwner(tile, ROADTYPE_ROAD))) return CMD_ERROR;
- if (HasBit(cur_rts, ROADTYPE_TRAM) && !CheckOwnership(GetRoadOwner(tile, ROADTYPE_TRAM))) return CMD_ERROR;
-
/* Do not remove roadtypes! */
rts |= cur_rts;
}
@@ -1377,7 +1394,7 @@
/* 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);
+ return_cmd_error(type ? STR_TOO_MANY_TRUCK_STOPS : STR_TOO_MANY_BUS_STOPS);
}
/* ensure that in case of error (or no DC_EXEC) the new road stop gets deleted upon return */
@@ -1385,7 +1402,7 @@
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);
+ return_cmd_error(type ? STR_TOO_MANY_TRUCK_STOPS : STR_TOO_MANY_BUS_STOPS);
}
/* In case of new station if DC_EXEC is NOT set we still need to create the station
@@ -1820,6 +1837,8 @@
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);
+ if (GetTileSlope(tile, NULL) != SLOPE_FLAT) return_cmd_error(STR_304B_SITE_UNSUITABLE);
+
/* allocate and initialize new station */
Station *st = new Station(tile);
if (st == NULL) return_cmd_error(STR_3008_TOO_MANY_STATIONS_LOADING);
@@ -1842,7 +1861,7 @@
st->build_date = _date;
- MakeBuoy(tile, st->index);
+ MakeBuoy(tile, st->index, GetWaterClass(tile));
UpdateStationVirtCoordDirty(st);
UpdateStationAcceptance(st, false);
@@ -1900,7 +1919,7 @@
/* We have to set the water tile's state to the same state as before the
* buoy was placed. Otherwise one could plant a buoy on a canal edge,
* remove it and flood the land (if the canal edge is at level 0) */
- MakeWaterOrCanalDependingOnOwner(tile, GetTileOwner(tile));
+ MakeWaterKeepingClass(tile, GetTileOwner(tile));
MarkTileDirtyByTile(tile);
UpdateStationVirtCoordDirty(st);
@@ -1929,14 +1948,12 @@
{
CommandCost cost;
- DiagDirection direction;
- switch (GetTileSlope(tile, NULL)) {
- case SLOPE_SW: direction = DIAGDIR_NE; break;
- case SLOPE_SE: direction = DIAGDIR_NW; break;
- case SLOPE_NW: direction = DIAGDIR_SE; break;
- case SLOPE_NE: direction = DIAGDIR_SW; break;
- default: return_cmd_error(STR_304B_SITE_UNSUITABLE);
- }
+ DiagDirection direction = GetInclinedSlopeDirection(GetTileSlope(tile, NULL));
+ if (direction == INVALID_DIAGDIR) return_cmd_error(STR_304B_SITE_UNSUITABLE);
+ direction = ReverseDiagDir(direction);
+
+ /* Docks cannot be placed on rapids */
+ if (IsWaterTile(tile)) return_cmd_error(STR_304B_SITE_UNSUITABLE);
if (!(flags & DC_NO_TOWN_RATING) && !CheckIfAuthorityAllows(tile)) return CMD_ERROR;
@@ -1953,6 +1970,9 @@
if (MayHaveBridgeAbove(tile_cur) && IsBridgeAbove(tile_cur)) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
+ /* Get the water class of the water tile before it is cleared.*/
+ WaterClass wc = GetWaterClass(tile_cur);
+
cost = DoCommand(tile_cur, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
if (CmdFailed(cost)) return CMD_ERROR;
@@ -2010,7 +2030,7 @@
st->rect.BeforeAddRect(tile, _dock_w_chk[direction], _dock_h_chk[direction], StationRect::ADD_TRY);
- MakeDock(tile, st->owner, st->index, direction);
+ MakeDock(tile, st->owner, st->index, direction, wc);
UpdateStationVirtCoordDirty(st);
UpdateStationAcceptance(st, false);
@@ -2035,7 +2055,7 @@
if (flags & DC_EXEC) {
DoClearSquare(tile1);
- MakeWaterOrCanalDependingOnSurroundings(tile2, st->owner);
+ MakeWaterKeepingClass(tile2, st->owner);
st->rect.AfterRemoveTile(st, tile1);
st->rect.AfterRemoveTile(st, tile2);
@@ -2073,7 +2093,7 @@
total_offset = rti->total_offset;
custom_ground_offset = rti->custom_ground_offset;
} else {
- roadtypes = GetRoadTypes(ti->tile);
+ roadtypes = IsRoadStop(ti->tile) ? GetRoadTypes(ti->tile) : ROADTYPES_NONE;
total_offset = 0;
custom_ground_offset = 0;
}
@@ -2140,7 +2160,14 @@
DrawTramCatenary(ti, axis == AXIS_X ? ROAD_X : ROAD_Y);
}
- if (IsCanalBuoyTile(ti->tile)) DrawCanalWater(ti->tile);
+ if (IsBuoy(ti->tile)) {
+ /* Draw appropriate water edges */
+ switch (GetWaterClass(ti->tile)) {
+ case WATER_CLASS_SEA: break;
+ case WATER_CLASS_CANAL: DrawCanalWater(ti->tile, false); break;
+ case WATER_CLASS_RIVER: DrawRiverWater(ti, false); break;
+ }
+ }
const DrawTileSeqStruct *dtss;
foreach_draw_tile_seq(dtss, t->seq) {
@@ -2348,9 +2375,9 @@
!IsCompatibleTrainStationTile(tile + TileOffsByDiagDir(DirToDiagDir(v->direction)), tile)) {
StationID station_id = GetStationIndex(tile);
- if ((!(v->current_order.flags & OF_NON_STOP) && !_patches.new_nonstop) ||
+ if ((!(v->current_order.flags & OFB_NON_STOP) && !_patches.new_nonstop) ||
(v->current_order.type == OT_GOTO_STATION && v->current_order.dest == station_id)) {
- if (!(_patches.new_nonstop && v->current_order.flags & OF_NON_STOP) &&
+ if (!(_patches.new_nonstop && v->current_order.flags & OFB_NON_STOP) &&
v->current_order.type != OT_LEAVESTATION &&
v->last_station_visited != station_id) {
DiagDirection dir = DirToDiagDir(v->direction);
@@ -2624,19 +2651,13 @@
if (!IsUniqueStationName(_cmd_text)) return_cmd_error(STR_NAME_MUST_BE_UNIQUE);
- StringID str = AllocateName(_cmd_text, 6);
- if (str == 0) return CMD_ERROR;
-
if (flags & DC_EXEC) {
- StringID old_str = st->string_id;
-
- st->string_id = str;
+ free(st->name);
+ st->name = strdup(_cmd_text);
+
UpdateStationVirtCoord(st);
- DeleteName(old_str);
ResortStationLists();
MarkWholeScreenDirty();
- } else {
- DeleteName(str);
}
return CommandCost();
@@ -2895,8 +2916,8 @@
switch (GetStationType(tile)) {
case STATION_RAIL: return_cmd_error(STR_300B_MUST_DEMOLISH_RAILROAD);
case STATION_AIRPORT: return_cmd_error(STR_300E_MUST_DEMOLISH_AIRPORT_FIRST);
- case STATION_TRUCK: return_cmd_error(HasBit(GetRoadTypes(tile), ROADTYPE_TRAM) ? STR_3047_MUST_DEMOLISH_CARGO_TRAM_STATION : STR_3047_MUST_DEMOLISH_TRUCK_STATION);
- case STATION_BUS: return_cmd_error(HasBit(GetRoadTypes(tile), ROADTYPE_TRAM) ? STR_3046_MUST_DEMOLISH_PASSENGER_TRAM_STATION : STR_3046_MUST_DEMOLISH_BUS_STATION);
+ case STATION_TRUCK: return_cmd_error(HasBit(GetRoadTypes(tile), ROADTYPE_TRAM) ? STR_MUST_DEMOLISH_CARGO_TRAM_STATION : STR_3047_MUST_DEMOLISH_TRUCK_STATION);
+ case STATION_BUS: return_cmd_error(HasBit(GetRoadTypes(tile), ROADTYPE_TRAM) ? STR_MUST_DEMOLISH_PASSENGER_TRAM_STATION : STR_3046_MUST_DEMOLISH_BUS_STATION);
case STATION_BUOY: return_cmd_error(STR_306A_BUOY_IN_THE_WAY);
case STATION_DOCK: return_cmd_error(STR_304D_MUST_DEMOLISH_DOCK_FIRST);
case STATION_OILRIG:
@@ -3045,6 +3066,7 @@
SLE_CONDNULL(1, 0, 3),
SLE_VAR(Station, string_id, SLE_STRINGID),
+ SLE_CONDSTR(Station, name, SLE_STR, 0, 84, SL_MAX_VERSION),
SLE_VAR(Station, had_vehicle_of_type, SLE_UINT16),
SLE_VAR(Station, time_since_load, SLE_UINT8),