|
@@ -1828,47 +1828,49 @@ static CommandCost RemoveAirport(Station
|
|
|
|
|
|
/** 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)
|
|
|
{
|
|
|
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);
|
|
|
|
|
|
/* 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, 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);
|
|
|
MakeBuoy(tile, st->index, GetWaterClass(tile));
|
|
|
|
|
|
UpdateStationVirtCoordDirty(st);
|
|
|
UpdateStationAcceptance(st, false);
|
|
|
RebuildStationLists();
|
|
|
InvalidateWindow(WC_STATION_LIST, st->owner);
|
|
|
InvalidateWindowWidget(WC_STATION_VIEW, st->index, SVW_SHIPS);
|
|
|
/* success, so don't delete the new station */
|
|
|
st_auto_delete.Detach();
|
|
|
}
|
|
|
|
|
|
return CommandCost(EXPENSES_CONSTRUCTION, _price.build_dock);
|
|
|
}
|
|
@@ -1908,25 +1910,25 @@ static CommandCost RemoveBuoy(Station *s
|
|
|
if (flags & DC_EXEC) {
|
|
|
st->dock_tile = 0;
|
|
|
/* Buoys are marked in the Station struct by this flag. Yes, it is this
|
|
|
* braindead.. */
|
|
|
st->facilities &= ~FACIL_DOCK;
|
|
|
st->had_vehicle_of_type &= ~HVOT_BUOY;
|
|
|
|
|
|
InvalidateWindowWidget(WC_STATION_VIEW, st->index, SVW_SHIPS);
|
|
|
|
|
|
/* 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);
|
|
|
DeleteStationIfEmpty(st);
|
|
|
}
|
|
|
|
|
|
return CommandCost(EXPENSES_CONSTRUCTION, _price.remove_truck_station);
|
|
|
}
|
|
|
|
|
|
static const TileIndexDiffC _dock_tileoffs_chkaround[] = {
|
|
|
{-1, 0},
|
|
|
{ 0, 0},
|
|
@@ -1942,41 +1944,44 @@ static const byte _dock_h_chk[4] = { 1,
|
|
|
* @param p1 (bit 0) - allow docks directly adjacent to other docks.
|
|
|
* @param p2 unused
|
|
|
*/
|
|
|
CommandCost CmdBuildDock(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|
|
{
|
|
|
CommandCost cost;
|
|
|
|
|
|
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 (IsRiverTile(tile)) return_cmd_error(STR_304B_SITE_UNSUITABLE);
|
|
|
if (IsWaterTile(tile)) return_cmd_error(STR_304B_SITE_UNSUITABLE);
|
|
|
|
|
|
if (!(flags & DC_NO_TOWN_RATING) && !CheckIfAuthorityAllows(tile)) return CMD_ERROR;
|
|
|
|
|
|
if (MayHaveBridgeAbove(tile) && IsBridgeAbove(tile)) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
|
|
|
|
|
|
cost = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
|
|
|
if (CmdFailed(cost)) return CMD_ERROR;
|
|
|
|
|
|
TileIndex tile_cur = tile + TileOffsByDiagDir(direction);
|
|
|
|
|
|
if (!IsTileType(tile_cur, MP_WATER) || GetTileSlope(tile_cur, NULL) != SLOPE_FLAT) {
|
|
|
return_cmd_error(STR_304B_SITE_UNSUITABLE);
|
|
|
}
|
|
|
|
|
|
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;
|
|
|
|
|
|
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)) {
|
|
@@ -2016,50 +2021,50 @@ CommandCost CmdBuildDock(TileIndex tile,
|
|
|
|
|
|
st->sign.width_1 = 0;
|
|
|
|
|
|
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);
|
|
|
MakeDock(tile, st->owner, st->index, direction, wc);
|
|
|
|
|
|
UpdateStationVirtCoordDirty(st);
|
|
|
UpdateStationAcceptance(st, false);
|
|
|
RebuildStationLists();
|
|
|
InvalidateWindow(WC_STATION_LIST, st->owner);
|
|
|
InvalidateWindowWidget(WC_STATION_VIEW, st->index, SVW_SHIPS);
|
|
|
/* success, so don't delete the new station */
|
|
|
st_auto_delete.Detach();
|
|
|
}
|
|
|
return CommandCost(EXPENSES_CONSTRUCTION, _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);
|
|
|
MakeWaterOrCanalDependingOnSurroundings(tile2, st->owner);
|
|
|
MakeWaterKeepingClass(tile2, st->owner);
|
|
|
|
|
|
st->rect.AfterRemoveTile(st, tile1);
|
|
|
st->rect.AfterRemoveTile(st, tile2);
|
|
|
|
|
|
MarkTileDirtyByTile(tile2);
|
|
|
|
|
|
st->dock_tile = 0;
|
|
|
st->facilities &= ~FACIL_DOCK;
|
|
|
|
|
|
InvalidateWindowWidget(WC_STATION_VIEW, st->index, SVW_SHIPS);
|
|
|
UpdateStationVirtCoordDirty(st);
|
|
|
DeleteStationIfEmpty(st);
|
|
@@ -2146,25 +2151,32 @@ static void DrawTile_Station(TileInfo *t
|
|
|
/* station_land array has been increased from 82 elements to 114
|
|
|
* but this is something else. If AI builds station with 114 it looks all weird */
|
|
|
DrawGroundSprite(image, HasBit(image, PALETTE_MODIFIER_COLOR) ? palette : PAL_NONE);
|
|
|
|
|
|
if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC && IsStationTileElectrifiable(ti->tile)) DrawCatenary(ti);
|
|
|
|
|
|
if (HasBit(roadtypes, ROADTYPE_TRAM)) {
|
|
|
Axis axis = GetRoadStopDir(ti->tile) == DIAGDIR_NE ? AXIS_X : AXIS_Y;
|
|
|
DrawGroundSprite((HasBit(roadtypes, ROADTYPE_ROAD) ? SPR_TRAMWAY_OVERLAY : SPR_TRAMWAY_TRAM) + (axis ^ 1), PAL_NONE);
|
|
|
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) {
|
|
|
image = dtss->image;
|
|
|
if (relocation == 0 || HasBit(image, SPRITE_MODIFIER_USE_OFFSET)) {
|
|
|
image += total_offset;
|
|
|
} else {
|
|
|
image += relocation;
|
|
|
}
|
|
|
|
|
|
SpriteID pal;
|
|
|
if (!(!HasBit(image, SPRITE_MODIFIER_OPAQUE) && IsTransparencySet(TO_BUILDINGS)) && HasBit(image, PALETTE_MODIFIER_COLOR)) {
|