mirror of https://github.com/OpenTTD/OpenTTD.git
(svn r16909) -Fix [FS#2996]: NewGRF stations would be triggering assertions all over the place when using the more advanced station types.
-Change: make (rail) waypoints sub classes of 'base stations', make buoys waypoints and unify code between them where possible.
This commit is contained in:
parent
2646a99d29
commit
68ead6b84f
|
@ -3,12 +3,12 @@
|
|||
/** @file ai_buoylist.cpp Implementation of AIBuoyList and friends. */
|
||||
|
||||
#include "ai_buoylist.hpp"
|
||||
#include "../../station_base.h"
|
||||
#include "../../waypoint.h"
|
||||
|
||||
AIBuoyList::AIBuoyList()
|
||||
{
|
||||
Station *st;
|
||||
FOR_ALL_STATIONS(st) {
|
||||
if (st->IsBuoy()) this->AddItem(st->xy);
|
||||
Waypoint *wp;
|
||||
FOR_ALL_WAYPOINTS(wp) {
|
||||
if (wp->facilities & FACIL_DOCK) this->AddItem(wp->xy);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,18 +25,14 @@ static OrderType GetOrderTypeByTile(TileIndex t)
|
|||
switch (::GetTileType(t)) {
|
||||
default: break;
|
||||
case MP_STATION:
|
||||
if (IsBuoy(t) || IsRailWaypoint(t)) return OT_GOTO_WAYPOINT;
|
||||
if (IsHangar(t)) return OT_GOTO_DEPOT;
|
||||
if (IsBuoy(t)) return OT_GOTO_WAYPOINT;
|
||||
return OT_GOTO_STATION;
|
||||
break;
|
||||
case MP_WATER: if (::IsShipDepot(t)) return OT_GOTO_DEPOT; break;
|
||||
case MP_ROAD: if (::GetRoadTileType(t) == ROAD_TILE_DEPOT) return OT_GOTO_DEPOT; break;
|
||||
case MP_RAILWAY:
|
||||
switch (::GetRailTileType(t)) {
|
||||
case RAIL_TILE_DEPOT: return OT_GOTO_DEPOT;
|
||||
case RAIL_TILE_WAYPOINT: return OT_GOTO_WAYPOINT;
|
||||
default: break;
|
||||
}
|
||||
if (IsRailDepot(t)) return OT_GOTO_DEPOT;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -359,7 +355,7 @@ static const Order *ResolveOrder(VehicleID vehicle_id, AIOrder::OrderPosition or
|
|||
break;
|
||||
|
||||
case OT_GOTO_WAYPOINT:
|
||||
order.MakeGoToWaypoint(::Vehicle::Get(vehicle_id)->type == VEH_TRAIN ? ::GetWaypointIndex(destination) : ::GetStationIndex(destination));
|
||||
order.MakeGoToWaypoint(::GetStationIndex(destination));
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
{
|
||||
if (!::IsValidTile(tile)) return false;
|
||||
|
||||
return ::IsTileType(tile, MP_RAILWAY) && ::IsRailWaypointTile(tile);
|
||||
return ::IsRailWaypointTile(tile);
|
||||
}
|
||||
|
||||
/* static */ bool AIRail::IsRailTypeAvailable(RailType rail_type)
|
||||
|
@ -200,8 +200,7 @@
|
|||
{
|
||||
if (!IsRailTile(tile)) return RAILTRACK_INVALID;
|
||||
|
||||
if (IsRailWaypointTile(tile)) return ::GetRailWaypointBits(tile);
|
||||
if (IsRailStationTile(tile)) return ::TrackToTrackBits(::GetRailStationTrack(tile));
|
||||
if (IsRailStationTile(tile) || IsRailWaypointTile(tile)) return ::TrackToTrackBits(::GetRailStationTrack(tile));
|
||||
if (IsLevelCrossingTile(tile)) return ::GetCrossingRailBits(tile);
|
||||
if (IsRailDepotTile(tile)) return ::TRACK_BIT_NONE;
|
||||
return ::GetTrackBits(tile);
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
{
|
||||
if (!AIRail::IsRailWaypointTile(tile)) return WAYPOINT_INVALID;
|
||||
|
||||
return ::GetWaypointIndex(tile);
|
||||
return ::GetStationIndex(tile);
|
||||
}
|
||||
|
||||
/* static */ char *AIWaypoint::GetName(WaypointID waypoint_id)
|
||||
|
|
|
@ -13,7 +13,7 @@ AIWaypointList::AIWaypointList()
|
|||
{
|
||||
const Waypoint *wp;
|
||||
FOR_ALL_WAYPOINTS(wp) {
|
||||
if (wp->owner == _current_company) this->AddItem(wp->index);
|
||||
if (wp->facilities & FACIL_TRAIN && wp->owner == _current_company) this->AddItem(wp->index);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -154,7 +154,6 @@ Date ConvertYMDToDate(Year year, Month month, Day day)
|
|||
|
||||
/** Functions used by the IncreaseDate function */
|
||||
|
||||
extern void WaypointsDailyLoop();
|
||||
extern void EnginesDailyLoop();
|
||||
extern void DisasterDailyLoop();
|
||||
extern void IndustryDailyLoop();
|
||||
|
@ -222,7 +221,6 @@ void IncreaseDate()
|
|||
#endif /* ENABLE_NETWORK */
|
||||
|
||||
DisasterDailyLoop();
|
||||
WaypointsDailyLoop();
|
||||
IndustryDailyLoop();
|
||||
|
||||
if (_game_mode != GM_MENU) {
|
||||
|
|
|
@ -81,8 +81,6 @@ static TrackBits GetRailTrackBitsUniversal(TileIndex t, byte *override)
|
|||
switch (GetRailTileType(t)) {
|
||||
case RAIL_TILE_NORMAL: case RAIL_TILE_SIGNALS:
|
||||
return GetTrackBits(t);
|
||||
case RAIL_TILE_WAYPOINT:
|
||||
return GetRailWaypointBits(t);
|
||||
default:
|
||||
return TRACK_BIT_NONE;
|
||||
}
|
||||
|
@ -101,7 +99,7 @@ static TrackBits GetRailTrackBitsUniversal(TileIndex t, byte *override)
|
|||
return GetCrossingRailBits(t);
|
||||
|
||||
case MP_STATION:
|
||||
if (!IsRailwayStation(t)) return TRACK_BIT_NONE;
|
||||
if (!IsRailwayStation(t) && !IsRailWaypoint(t)) return TRACK_BIT_NONE;
|
||||
if (!HasCatenary(GetRailType(t))) return TRACK_BIT_NONE;
|
||||
if (!IsStationTileElectrifiable(t)) return TRACK_BIT_NONE;
|
||||
return TrackToTrackBits(GetRailStationTrack(t));
|
||||
|
|
|
@ -1185,8 +1185,10 @@ STR_HEADING_FOR_WAYPOINT_VEL :{LTBLUE}Heading
|
|||
STR_GO_TO_WAYPOINT :Go via {WAYPOINT}
|
||||
STR_GO_NON_STOP_TO_WAYPOINT :Go non-stop via {WAYPOINT}
|
||||
|
||||
STR_WAYPOINTNAME_CITY :Waypoint {TOWN}
|
||||
STR_WAYPOINTNAME_CITY_SERIAL :Waypoint {TOWN} #{COMMA}
|
||||
STR_WAYPOINTNAME_CITY :{TOWN} Waypoint
|
||||
STR_WAYPOINTNAME_CITY_SERIAL :{TOWN} Waypoint #{COMMA}
|
||||
STR_BUOYNAME_CITY :{TOWN} Buoy
|
||||
STR_BUOYNAME_CITY_SERIAL :{TOWN} Buoy #{COMMA}
|
||||
STR_LANDINFO_WAYPOINT :Waypoint
|
||||
|
||||
STR_WAYPOINT :{WHITE}Waypoint
|
||||
|
@ -2077,15 +2079,9 @@ STR_SV_STNAME_AIRPORT :{STRING1} Airpo
|
|||
STR_SV_STNAME_OILFIELD :{STRING1} Oilfield
|
||||
STR_SV_STNAME_MINES :{STRING1} Mines
|
||||
STR_SV_STNAME_DOCKS :{STRING1} Docks
|
||||
STR_SV_STNAME_BUOY_1 :{STRING1} Buoy 1
|
||||
STR_SV_STNAME_BUOY_2 :{STRING1} Buoy 2
|
||||
STR_SV_STNAME_BUOY_3 :{STRING1} Buoy 3
|
||||
STR_SV_STNAME_BUOY_4 :{STRING1} Buoy 4
|
||||
STR_SV_STNAME_BUOY_5 :{STRING1} Buoy 5
|
||||
STR_SV_STNAME_BUOY_6 :{STRING1} Buoy 6
|
||||
STR_SV_STNAME_BUOY_7 :{STRING1} Buoy 7
|
||||
STR_SV_STNAME_BUOY_8 :{STRING1} Buoy 8
|
||||
STR_SV_STNAME_BUOY_9 :{STRING1} Buoy 9
|
||||
STR_SV_STNAME_BUOY :{STRING2}
|
||||
STR_SV_STNAME_WAYPOINT :{STRING2}
|
||||
##id 0x6020
|
||||
STR_SV_STNAME_ANNEXE :{STRING1} Annexe
|
||||
STR_SV_STNAME_SIDINGS :{STRING1} Sidings
|
||||
STR_SV_STNAME_BRANCH :{STRING1} Branch
|
||||
|
|
|
@ -31,7 +31,6 @@ extern TileIndex _cur_tileloop_tile;
|
|||
extern void MakeNewgameSettingsLive();
|
||||
|
||||
void InitializeVehicles();
|
||||
void InitializeWaypoints();
|
||||
void InitializeDepots();
|
||||
void InitializeEngineRenews();
|
||||
void InitializeOrders();
|
||||
|
@ -79,7 +78,6 @@ void InitializeGame(uint size_x, uint size_y, bool reset_date)
|
|||
|
||||
InitializeEngineRenews();
|
||||
InitializeVehicles();
|
||||
InitializeWaypoints();
|
||||
InitializeDepots();
|
||||
InitializeOrders();
|
||||
InitializeGroup();
|
||||
|
|
|
@ -272,30 +272,20 @@ uint32 GetPlatformInfo(Axis axis, byte tile, int platforms, int length, int x, i
|
|||
*/
|
||||
static TileIndex FindRailStationEnd(TileIndex tile, TileIndexDiff delta, bool check_type, bool check_axis)
|
||||
{
|
||||
bool waypoint;
|
||||
byte orig_type = 0;
|
||||
Axis orig_axis = AXIS_X;
|
||||
StationID sid = GetStationIndex(tile);
|
||||
|
||||
waypoint = IsTileType(tile, MP_RAILWAY);
|
||||
|
||||
if (waypoint) {
|
||||
if (check_axis) orig_axis = GetWaypointAxis(tile);
|
||||
} else {
|
||||
if (check_type) orig_type = GetCustomStationSpecIndex(tile);
|
||||
if (check_axis) orig_axis = GetRailStationAxis(tile);
|
||||
}
|
||||
if (check_type) orig_type = GetCustomStationSpecIndex(tile);
|
||||
if (check_axis) orig_axis = GetRailStationAxis(tile);
|
||||
|
||||
while (true) {
|
||||
TileIndex new_tile = TILE_ADD(tile, delta);
|
||||
|
||||
if (waypoint) {
|
||||
if (!IsRailWaypointTile(new_tile)) break;
|
||||
if (check_axis && GetWaypointAxis(new_tile) != orig_axis) break;
|
||||
} else {
|
||||
if (!IsRailwayStationTile(new_tile)) break;
|
||||
if (check_type && GetCustomStationSpecIndex(new_tile) != orig_type) break;
|
||||
if (check_axis && GetRailStationAxis(new_tile) != orig_axis) break;
|
||||
}
|
||||
if (!IsTileType(new_tile, MP_STATION) || GetStationIndex(new_tile) != sid) break;
|
||||
if (!IsRailwayStation(new_tile) && !IsRailWaypoint(new_tile)) break;
|
||||
if (check_type && GetCustomStationSpecIndex(new_tile) != orig_type) break;
|
||||
if (check_axis && GetRailStationAxis(new_tile) != orig_axis) break;
|
||||
|
||||
tile = new_tile;
|
||||
}
|
||||
|
@ -311,12 +301,11 @@ static uint32 GetPlatformInfoHelper(TileIndex tile, bool check_type, bool check_
|
|||
int sy = TileY(FindRailStationEnd(tile, TileDiffXY( 0, -1), check_type, check_axis));
|
||||
int ex = TileX(FindRailStationEnd(tile, TileDiffXY( 1, 0), check_type, check_axis)) + 1;
|
||||
int ey = TileY(FindRailStationEnd(tile, TileDiffXY( 0, 1), check_type, check_axis)) + 1;
|
||||
Axis axis = IsTileType(tile, MP_RAILWAY) ? GetWaypointAxis(tile) : GetRailStationAxis(tile);
|
||||
|
||||
tx -= sx; ex -= sx;
|
||||
ty -= sy; ey -= sy;
|
||||
|
||||
return GetPlatformInfo(axis, IsTileType(tile, MP_RAILWAY) ? 2 : GetStationGfx(tile), ex, ey, tx, ty, centred);
|
||||
return GetPlatformInfo(GetRailStationAxis(tile), GetStationGfx(tile), ex, ey, tx, ty, centred);
|
||||
}
|
||||
|
||||
|
||||
|
@ -330,7 +319,7 @@ static uint32 GetRailContinuationInfo(TileIndex tile)
|
|||
static const Direction y_dir[8] = { DIR_SE, DIR_NW, DIR_SW, DIR_NE, DIR_S, DIR_W, DIR_E, DIR_N };
|
||||
static const DiagDirection y_exits[8] = { DIAGDIR_SE, DIAGDIR_NW, DIAGDIR_SW, DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_NW, DIAGDIR_SE, DIAGDIR_NW };
|
||||
|
||||
Axis axis = IsTileType(tile, MP_RAILWAY) ? GetWaypointAxis(tile) : GetRailStationAxis(tile);
|
||||
Axis axis = GetRailStationAxis(tile);
|
||||
|
||||
/* Choose appropriate lookup table to use */
|
||||
const Direction *dir = axis == AXIS_X ? x_dir : y_dir;
|
||||
|
@ -450,12 +439,7 @@ static uint32 StationGetVariable(const ResolverObject *object, byte variable, by
|
|||
|
||||
case 0x42: return GetTerrainType(tile) | (GetRailType(tile) << 8);
|
||||
case 0x43: return st->owner; // Station owner
|
||||
case 0x44:
|
||||
if (IsRailWaypointTile(tile)) {
|
||||
return HasDepotReservation(tile) ? 7 : 4;
|
||||
} else {
|
||||
return HasStationReservation(tile) ? 7 : 4; // PBS status
|
||||
}
|
||||
case 0x44: return HasStationReservation(tile) ? 7 : 4; // PBS status
|
||||
case 0x45:
|
||||
if (!HasBit(_svc.valid, 2)) { _svc.v45 = GetRailContinuationInfo(tile); SetBit(_svc.valid, 2); }
|
||||
return _svc.v45;
|
||||
|
@ -583,7 +567,7 @@ uint32 Waypoint::GetNewGRFVariable(const ResolverObject *object, byte variable,
|
|||
{
|
||||
switch (variable) {
|
||||
case 0x48: return 0; // Accepted cargo types
|
||||
case 0x8A: return HVOT_TRAIN;
|
||||
case 0x8A: return HVOT_WAYPOINT;
|
||||
case 0xF1: return 0; // airport type
|
||||
case 0xF2: return 0; // truck stop status
|
||||
case 0xF3: return 0; // bus stop status
|
||||
|
@ -944,20 +928,11 @@ bool DrawStationTile(int x, int y, RailType railtype, Axis axis, StationClassID
|
|||
|
||||
const StationSpec *GetStationSpec(TileIndex t)
|
||||
{
|
||||
if (IsRailwayStationTile(t)) {
|
||||
if (!IsCustomStationSpecIndex(t)) return NULL;
|
||||
if (!IsCustomStationSpecIndex(t)) return NULL;
|
||||
|
||||
const BaseStation *st = BaseStation::GetByTile(t);
|
||||
uint specindex = GetCustomStationSpecIndex(t);
|
||||
return specindex < st->num_specs ? st->speclist[specindex].spec : NULL;
|
||||
}
|
||||
|
||||
if (IsRailWaypointTile(t)) {
|
||||
const BaseStation *st = BaseStation::GetByTile(t);
|
||||
return st->num_specs != 0 ? st->speclist[1].spec : NULL;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
const BaseStation *st = BaseStation::GetByTile(t);
|
||||
uint specindex = GetCustomStationSpecIndex(t);
|
||||
return specindex < st->num_specs ? st->speclist[specindex].spec : NULL;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -542,18 +542,19 @@ CommandCost CmdInsertOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
|
|||
}
|
||||
|
||||
case OT_GOTO_WAYPOINT: {
|
||||
const Waypoint *wp = Waypoint::GetIfValid(new_order.GetDestination());
|
||||
if (wp == NULL) return CMD_ERROR;
|
||||
|
||||
switch (v->type) {
|
||||
default: return CMD_ERROR;
|
||||
|
||||
case VEH_TRAIN: {
|
||||
const Waypoint *wp = Waypoint::GetIfValid(new_order.GetDestination());
|
||||
if (wp == NULL || !CheckOwnership(wp->owner)) return CMD_ERROR;
|
||||
} break;
|
||||
case VEH_TRAIN:
|
||||
if (!CheckOwnership(wp->owner)) return CMD_ERROR;
|
||||
break;
|
||||
|
||||
case VEH_SHIP: {
|
||||
const Station *st = Station::GetIfValid(new_order.GetDestination());
|
||||
if (st == NULL || (!CheckOwnership(st->owner) && st->owner != OWNER_NONE)) return CMD_ERROR;
|
||||
} break;
|
||||
case VEH_SHIP:
|
||||
if (!CheckOwnership(wp->owner) && wp->owner != OWNER_NONE) return CMD_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Order flags can be any of the following for waypoints:
|
||||
|
|
|
@ -253,15 +253,8 @@ void DrawOrderString(const Vehicle *v, const Order *order, int order_index, int
|
|||
break;
|
||||
|
||||
case OT_GOTO_WAYPOINT:
|
||||
if (v->type == VEH_TRAIN) {
|
||||
SetDParam(1, (order->GetNonStopType() & ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS) ? STR_GO_NON_STOP_TO_WAYPOINT : STR_GO_TO_WAYPOINT);
|
||||
SetDParam(2, order->GetDestination());
|
||||
} else {
|
||||
SetDParam(1, STR_GO_TO_STATION);
|
||||
SetDParam(2, STR_ORDER_GO_VIA);
|
||||
SetDParam(3, order->GetDestination());
|
||||
SetDParam(4, STR_EMPTY);
|
||||
}
|
||||
SetDParam(1, (order->GetNonStopType() & ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS) ? STR_GO_NON_STOP_TO_WAYPOINT : STR_GO_TO_WAYPOINT);
|
||||
SetDParam(2, order->GetDestination());
|
||||
break;
|
||||
|
||||
case OT_CONDITIONAL:
|
||||
|
@ -357,7 +350,7 @@ static Order GetOrderCmdFromTile(const Vehicle *v, TileIndex tile)
|
|||
return order;
|
||||
}
|
||||
|
||||
if (IsBuoyTile(tile) && v->type == VEH_SHIP) {
|
||||
if ((IsBuoyTile(tile) && v->type == VEH_SHIP) || (IsRailWaypointTile(tile) && v->type == VEH_TRAIN)) {
|
||||
order.MakeGoToWaypoint(GetStationIndex(tile));
|
||||
return order;
|
||||
}
|
||||
|
@ -775,12 +768,9 @@ public:
|
|||
this->SetWidgetLoweredState(ORDER_WIDGET_NON_STOP, order->GetNonStopType() & ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS);
|
||||
switch (order->GetType()) {
|
||||
case OT_GOTO_STATION:
|
||||
if (!Station::Get(order->GetDestination())->IsBuoy()) {
|
||||
this->SetWidgetLoweredState(ORDER_WIDGET_FULL_LOAD, order->GetLoadType() == OLF_FULL_LOAD_ANY);
|
||||
this->SetWidgetLoweredState(ORDER_WIDGET_UNLOAD, order->GetUnloadType() == OUFB_UNLOAD);
|
||||
break;
|
||||
}
|
||||
/* Fall-through */
|
||||
this->SetWidgetLoweredState(ORDER_WIDGET_FULL_LOAD, order->GetLoadType() == OLF_FULL_LOAD_ANY);
|
||||
this->SetWidgetLoweredState(ORDER_WIDGET_UNLOAD, order->GetUnloadType() == OUFB_UNLOAD);
|
||||
break;
|
||||
|
||||
case OT_GOTO_WAYPOINT:
|
||||
this->DisableWidget(ORDER_WIDGET_FULL_LOAD_DROPDOWN);
|
||||
|
|
|
@ -26,7 +26,7 @@ TrackBits GetReservedTrackbits(TileIndex t)
|
|||
break;
|
||||
|
||||
case MP_STATION:
|
||||
if (IsRailwayStation(t)) return GetStationReservationTrackBits(t);
|
||||
if (IsRailwayStation(t) || IsRailWaypoint(t)) return GetStationReservationTrackBits(t);
|
||||
break;
|
||||
|
||||
case MP_TUNNELBRIDGE:
|
||||
|
@ -99,7 +99,7 @@ bool TryReserveRailTrack(TileIndex tile, Track t)
|
|||
break;
|
||||
|
||||
case MP_STATION:
|
||||
if (IsRailwayStation(tile) && !HasStationReservation(tile)) {
|
||||
if ((IsRailwayStation(tile) || IsRailWaypoint(tile)) && !HasStationReservation(tile)) {
|
||||
SetRailwayStationReservation(tile, true);
|
||||
MarkTileDirtyByTile(tile); // some GRFs need redraw after reserving track
|
||||
return true;
|
||||
|
@ -150,7 +150,7 @@ bool TryReserveRailTrack(TileIndex tile, Track t)
|
|||
break;
|
||||
|
||||
case MP_STATION:
|
||||
if (IsRailwayStation(tile)) {
|
||||
if (IsRailwayStation(tile) || IsRailWaypoint(tile)) {
|
||||
SetRailwayStationReservation(tile, false);
|
||||
MarkTileDirtyByTile(tile);
|
||||
}
|
||||
|
|
|
@ -155,7 +155,7 @@ RailType GetTileRailType(TileIndex tile)
|
|||
break;
|
||||
|
||||
case MP_STATION:
|
||||
if (IsRailwayStationTile(tile)) return GetRailType(tile);
|
||||
if (IsRailwayStation(tile) || IsRailWaypoint(tile)) return GetRailType(tile);
|
||||
break;
|
||||
|
||||
case MP_TUNNELBRIDGE:
|
||||
|
|
132
src/rail_cmd.cpp
132
src/rail_cmd.cpp
|
@ -1281,7 +1281,7 @@ CommandCost CmdConvertRail(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
|
|||
case MP_RAILWAY:
|
||||
break;
|
||||
case MP_STATION:
|
||||
if (!IsRailwayStation(tile)) continue;
|
||||
if (!IsRailwayStation(tile) && !IsRailWaypoint(tile)) continue;
|
||||
break;
|
||||
case MP_ROAD:
|
||||
if (!IsLevelCrossing(tile)) continue;
|
||||
|
@ -1329,14 +1329,6 @@ CommandCost CmdConvertRail(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
|
|||
switch (tt) {
|
||||
case MP_RAILWAY:
|
||||
switch (GetRailTileType(tile)) {
|
||||
case RAIL_TILE_WAYPOINT:
|
||||
if (flags & DC_EXEC) {
|
||||
/* notify YAPF about the track layout change */
|
||||
YapfNotifyTrackLayoutChange(tile, GetRailWaypointTrack(tile));
|
||||
}
|
||||
cost.AddCost(RailConvertCost(type, totype));
|
||||
break;
|
||||
|
||||
case RAIL_TILE_DEPOT:
|
||||
if (flags & DC_EXEC) {
|
||||
/* notify YAPF about the track layout change */
|
||||
|
@ -1501,9 +1493,6 @@ static CommandCost ClearTile_Track(TileIndex tile, DoCommandFlag flags)
|
|||
case RAIL_TILE_DEPOT:
|
||||
return RemoveTrainDepot(tile, flags);
|
||||
|
||||
case RAIL_TILE_WAYPOINT:
|
||||
return RemoveTrainWaypoint(tile, flags, false);
|
||||
|
||||
default:
|
||||
return CMD_ERROR;
|
||||
}
|
||||
|
@ -1906,7 +1895,7 @@ static void DrawTile_Track(TileInfo *ti)
|
|||
|
||||
if (HasSignals(ti->tile)) DrawSignals(ti->tile, rails);
|
||||
} else {
|
||||
/* draw depot/waypoint */
|
||||
/* draw depot */
|
||||
const DrawTileSprites *dts;
|
||||
const DrawTileSeqStruct *dtss;
|
||||
uint32 relocation;
|
||||
|
@ -1914,78 +1903,37 @@ static void DrawTile_Track(TileInfo *ti)
|
|||
|
||||
if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, FOUNDATION_LEVELED);
|
||||
|
||||
if (IsRailDepot(ti->tile)) {
|
||||
if (IsInvisibilitySet(TO_BUILDINGS)) {
|
||||
/* Draw rail instead of depot */
|
||||
dts = &_depot_invisible_gfx_table[GetRailDepotDirection(ti->tile)];
|
||||
} else {
|
||||
dts = &_depot_gfx_table[GetRailDepotDirection(ti->tile)];
|
||||
}
|
||||
|
||||
relocation = rti->total_offset;
|
||||
|
||||
image = dts->ground.sprite;
|
||||
if (image != SPR_FLAT_GRASS_TILE) image += rti->total_offset;
|
||||
|
||||
/* adjust ground tile for desert
|
||||
* don't adjust for snow, because snow in depots looks weird */
|
||||
if (IsSnowRailGround(ti->tile) && _settings_game.game_creation.landscape == LT_TROPIC) {
|
||||
if (image != SPR_FLAT_GRASS_TILE) {
|
||||
image += rti->snow_offset; // tile with tracks
|
||||
} else {
|
||||
image = SPR_FLAT_SNOWY_TILE; // flat ground
|
||||
}
|
||||
}
|
||||
if (IsInvisibilitySet(TO_BUILDINGS)) {
|
||||
/* Draw rail instead of depot */
|
||||
dts = &_depot_invisible_gfx_table[GetRailDepotDirection(ti->tile)];
|
||||
} else {
|
||||
/* look for customization */
|
||||
const StationSpec *statspec = GetStationSpec(ti->tile);
|
||||
dts = &_depot_gfx_table[GetRailDepotDirection(ti->tile)];
|
||||
}
|
||||
|
||||
if (statspec != NULL) {
|
||||
const BaseStation *st = BaseStation::GetByTile(ti->tile);
|
||||
uint gfx = 2;
|
||||
relocation = rti->total_offset;
|
||||
|
||||
if (HasBit(statspec->callbackmask, CBM_STATION_SPRITE_LAYOUT)) {
|
||||
uint16 callback = GetStationCallback(CBID_STATION_SPRITE_LAYOUT, 0, 0, statspec, st, ti->tile);
|
||||
if (callback != CALLBACK_FAILED) gfx = callback;
|
||||
}
|
||||
image = dts->ground.sprite;
|
||||
if (image != SPR_FLAT_GRASS_TILE) image += rti->total_offset;
|
||||
|
||||
if (statspec->renderdata == NULL) {
|
||||
dts = GetStationTileLayout(STATION_RAIL, gfx);
|
||||
} else {
|
||||
dts = &statspec->renderdata[(gfx < statspec->tiles ? gfx : 0) + GetWaypointAxis(ti->tile)];
|
||||
}
|
||||
|
||||
if (dts != NULL && dts->seq != NULL) {
|
||||
relocation = GetCustomStationRelocation(statspec, st, ti->tile);
|
||||
|
||||
image = dts->ground.sprite;
|
||||
if (HasBit(image, SPRITE_MODIFIER_USE_OFFSET)) {
|
||||
image += GetCustomStationGroundRelocation(statspec, st, ti->tile);
|
||||
image += rti->custom_ground_offset;
|
||||
} else {
|
||||
image += rti->total_offset;
|
||||
}
|
||||
|
||||
pal = dts->ground.pal;
|
||||
} else {
|
||||
goto default_waypoint;
|
||||
}
|
||||
/* adjust ground tile for desert
|
||||
* don't adjust for snow, because snow in depots looks weird */
|
||||
if (IsSnowRailGround(ti->tile) && _settings_game.game_creation.landscape == LT_TROPIC) {
|
||||
if (image != SPR_FLAT_GRASS_TILE) {
|
||||
image += rti->snow_offset; // tile with tracks
|
||||
} else {
|
||||
default_waypoint:
|
||||
/* There is no custom layout, fall back to the default graphics */
|
||||
dts = GetStationTileLayout(STATION_WAYPOINT, GetWaypointAxis(ti->tile));
|
||||
relocation = 0;
|
||||
image = dts->ground.sprite + rti->total_offset;
|
||||
if (IsSnowRailGround(ti->tile)) image += rti->snow_offset;
|
||||
image = SPR_FLAT_SNOWY_TILE; // flat ground
|
||||
}
|
||||
}
|
||||
|
||||
DrawGroundSprite(image, GroundSpritePaletteTransform(image, pal, _drawtile_track_palette));
|
||||
|
||||
/* PBS debugging, draw reserved tracks darker */
|
||||
if (_game_mode != GM_MENU && _settings_client.gui.show_track_reservation && HasDepotReservation(ti->tile) &&
|
||||
(!IsRailDepot(ti->tile) || GetRailDepotDirection(ti->tile) == DIAGDIR_SW || GetRailDepotDirection(ti->tile) == DIAGDIR_SE)) {
|
||||
DrawGroundSprite(GetWaypointAxis(ti->tile) == AXIS_X ? rti->base_sprites.single_y : rti->base_sprites.single_x, PALETTE_CRASH);
|
||||
if (_game_mode != GM_MENU && _settings_client.gui.show_track_reservation && HasDepotReservation(ti->tile)) {
|
||||
switch (GetRailDepotDirection(ti->tile)) {
|
||||
case DIAGDIR_SW: DrawGroundSprite(rti->base_sprites.single_y, PALETTE_CRASH); break;
|
||||
case DIAGDIR_SE: DrawGroundSprite(rti->base_sprites.single_x, PALETTE_CRASH); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
if (HasCatenaryDrawn(GetRailType(ti->tile))) DrawCatenary(ti);
|
||||
|
@ -2292,10 +2240,6 @@ static TrackStatus GetTileTrackStatus_Track(TileIndex tile, TransportType mode,
|
|||
trackbits = DiagDirToDiagTrackBits(dir);
|
||||
break;
|
||||
}
|
||||
|
||||
case RAIL_TILE_WAYPOINT:
|
||||
trackbits = GetRailWaypointBits(tile);
|
||||
break;
|
||||
}
|
||||
|
||||
return CombineTrackStatus(TrackBitsToTrackdirBits(trackbits), red_signals);
|
||||
|
@ -2303,11 +2247,10 @@ static TrackStatus GetTileTrackStatus_Track(TileIndex tile, TransportType mode,
|
|||
|
||||
static bool ClickTile_Track(TileIndex tile)
|
||||
{
|
||||
switch (GetRailTileType(tile)) {
|
||||
case RAIL_TILE_DEPOT: ShowDepotWindow(tile, VEH_TRAIN); return true;
|
||||
case RAIL_TILE_WAYPOINT: ShowWaypointWindow(Waypoint::GetByTile(tile)); return true;
|
||||
default: return false;
|
||||
}
|
||||
if (!IsRailDepot(tile)) return false;
|
||||
|
||||
ShowDepotWindow(tile, VEH_TRAIN);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void GetTileDesc_Track(TileIndex tile, TileDesc *td)
|
||||
|
@ -2387,10 +2330,8 @@ static void GetTileDesc_Track(TileIndex tile, TileDesc *td)
|
|||
td->str = STR_RAILROAD_TRAIN_DEPOT;
|
||||
break;
|
||||
|
||||
case RAIL_TILE_WAYPOINT:
|
||||
default:
|
||||
td->str = STR_LANDINFO_WAYPOINT;
|
||||
break;
|
||||
NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2579,22 +2520,9 @@ static CommandCost TerraformTile_Track(TileIndex tile, DoCommandFlag flags, uint
|
|||
|
||||
/* allow terraforming */
|
||||
return CommandCost(EXPENSES_CONSTRUCTION, was_water ? _price.clear_water : (Money)0);
|
||||
} else {
|
||||
if (_settings_game.construction.build_on_slopes && AutoslopeEnabled()) {
|
||||
switch (GetRailTileType(tile)) {
|
||||
case RAIL_TILE_WAYPOINT: {
|
||||
CommandCost cost = TestAutoslopeOnRailTile(tile, flags, z_old, tileh_old, z_new, tileh_new, GetRailWaypointBits(tile));
|
||||
if (!CmdFailed(cost)) return cost; // allow autoslope
|
||||
break;
|
||||
}
|
||||
|
||||
case RAIL_TILE_DEPOT:
|
||||
if (AutoslopeCheckForEntranceEdge(tile, z_new, tileh_new, GetRailDepotDirection(tile))) return CommandCost(EXPENSES_CONSTRUCTION, _price.terraform);
|
||||
break;
|
||||
|
||||
default: NOT_REACHED();
|
||||
}
|
||||
}
|
||||
} else if (_settings_game.construction.build_on_slopes && AutoslopeEnabled() &&
|
||||
AutoslopeCheckForEntranceEdge(tile, z_new, tileh_new, GetRailDepotDirection(tile))) {
|
||||
return CommandCost(EXPENSES_CONSTRUCTION, _price.terraform);
|
||||
}
|
||||
return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
enum RailTileType {
|
||||
RAIL_TILE_NORMAL = 0, ///< Normal rail tile without signals
|
||||
RAIL_TILE_SIGNALS = 1, ///< Normal rail tile with signals
|
||||
RAIL_TILE_WAYPOINT = 2, ///< Waypoint (X or Y direction)
|
||||
RAIL_TILE_DEPOT = 3, ///< Depot (one entrance)
|
||||
};
|
||||
|
||||
|
@ -82,27 +81,6 @@ static inline void SetHasSignals(TileIndex tile, bool signals)
|
|||
SB(_m[tile].m5, 6, 1, signals);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this rail tile a rail waypoint?
|
||||
* @param t the tile to get the information from
|
||||
* @pre IsTileType(t, MP_RAILWAY)
|
||||
* @return true if and only if the tile is a rail waypoint
|
||||
*/
|
||||
static inline bool IsRailWaypoint(TileIndex t)
|
||||
{
|
||||
return GetRailTileType(t) == RAIL_TILE_WAYPOINT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this tile rail tile and a rail waypoint?
|
||||
* @param t the tile to get the information from
|
||||
* @return true if and only if the tile is a rail waypoint
|
||||
*/
|
||||
static inline bool IsRailWaypointTile(TileIndex t)
|
||||
{
|
||||
return IsTileType(t, MP_RAILWAY) && IsRailWaypoint(t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this rail tile a rail depot?
|
||||
* @param t the tile to get the information from
|
||||
|
@ -202,51 +180,6 @@ static inline Track GetRailDepotTrack(TileIndex t)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the axis of the waypoint
|
||||
* @param t the tile to get the waypoint axis from
|
||||
* @pre IsRailWaypointTile(t)
|
||||
* @return the axis of the waypoint
|
||||
*/
|
||||
static inline Axis GetWaypointAxis(TileIndex t)
|
||||
{
|
||||
return (Axis)GB(_m[t].m5, 0, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the track of the waypoint
|
||||
* @param t the tile to get the waypoint track from
|
||||
* @pre IsRailWaypointTile(t)
|
||||
* @return the track of the waypoint
|
||||
*/
|
||||
static inline Track GetRailWaypointTrack(TileIndex t)
|
||||
{
|
||||
return AxisToTrack(GetWaypointAxis(t));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the track bits of the waypoint
|
||||
* @param t the tile to get the waypoint track bits from
|
||||
* @pre IsRailWaypointTile(t)
|
||||
* @return the track bits of the waypoint
|
||||
*/
|
||||
static inline TrackBits GetRailWaypointBits(TileIndex t)
|
||||
{
|
||||
return TrackToTrackBits(GetRailWaypointTrack(t));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns waypoint index (for the waypoint pool)
|
||||
* @param t the tile to get the waypoint index from
|
||||
* @pre IsRailWaypointTile(t)
|
||||
* @return the waypoint index
|
||||
*/
|
||||
static inline WaypointID GetWaypointIndex(TileIndex t)
|
||||
{
|
||||
return (WaypointID)_m[t].m2;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the reserved track bits of the tile
|
||||
* @pre IsPlainRailTile(t)
|
||||
|
@ -335,17 +268,6 @@ static inline void SetDepotReservation(TileIndex t, bool b)
|
|||
SB(_m[t].m5, 4, 1, (byte)b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the reserved track bits for a waypoint
|
||||
* @pre IsRailWaypoint(t)
|
||||
* @param t the tile
|
||||
* @return reserved track bits
|
||||
*/
|
||||
static inline TrackBits GetWaypointReservationTrackBits(TileIndex t)
|
||||
{
|
||||
return HasDepotReservation(t) ? GetRailWaypointBits(t) : TRACK_BIT_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the reserved track bits for a depot
|
||||
* @pre IsRailDepot(t)
|
||||
|
@ -635,17 +557,4 @@ static inline void MakeRailDepot(TileIndex t, Owner o, DiagDirection d, RailType
|
|||
_me[t].m7 = 0;
|
||||
}
|
||||
|
||||
|
||||
static inline void MakeRailWaypoint(TileIndex t, Owner o, Axis a, RailType r, uint index)
|
||||
{
|
||||
SetTileType(t, MP_RAILWAY);
|
||||
SetTileOwner(t, o);
|
||||
_m[t].m2 = index;
|
||||
_m[t].m3 = r;
|
||||
_m[t].m4 = 0;
|
||||
_m[t].m5 = RAIL_TILE_WAYPOINT << 6 | a;
|
||||
SB(_m[t].m6, 2, 4, 0);
|
||||
_me[t].m7 = 0;
|
||||
}
|
||||
|
||||
#endif /* RAIL_MAP_H */
|
||||
|
|
|
@ -606,9 +606,7 @@ bool AfterLoadGame()
|
|||
switch (GetTileType(t)) {
|
||||
case MP_STATION: {
|
||||
Station *st = Station::GetByTile(t);
|
||||
|
||||
/* Set up station spread; buoys do not have one */
|
||||
if (!IsBuoy(t)) st->rect.BeforeAddTile(t, StationRect::ADD_FORCE);
|
||||
if (st == NULL) break;
|
||||
|
||||
switch (GetStationType(t)) {
|
||||
case STATION_TRUCK:
|
||||
|
@ -987,29 +985,11 @@ bool AfterLoadGame()
|
|||
FOR_ALL_COMPANIES(c) c->settings.renew_keep_length = false;
|
||||
}
|
||||
|
||||
/* In version 17, ground type is moved from m2 to m4 for depots and
|
||||
* waypoints to make way for storing the index in m2. The custom graphics
|
||||
* id which was stored in m4 is now saved as a grf/id reference in the
|
||||
* waypoint struct. */
|
||||
if (CheckSavegameVersion(17)) {
|
||||
Waypoint *wp;
|
||||
|
||||
FOR_ALL_WAYPOINTS(wp) {
|
||||
if (wp->delete_ctr == 0) {
|
||||
if (HasBit(_m[wp->xy].m3, 4)) {
|
||||
AllocateSpecToStation(GetCustomStationSpec(STAT_CLASS_WAYP, _m[wp->xy].m4 + 1), wp, true);
|
||||
}
|
||||
|
||||
/* Move ground type bits from m2 to m4. */
|
||||
_m[wp->xy].m4 = GB(_m[wp->xy].m2, 0, 4);
|
||||
/* Store waypoint index in the tile. */
|
||||
_m[wp->xy].m2 = wp->index;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* As of version 17, we recalculate the custom graphic ID of waypoints
|
||||
* from the GRF ID / station index. */
|
||||
AfterLoadWaypoints();
|
||||
if (CheckSavegameVersion(123)) {
|
||||
/* Waypoints became subclasses of stations ... */
|
||||
MoveWaypointsToBaseStations();
|
||||
/* ... and buoys were moved to waypoints. */
|
||||
MoveBuoysToWaypoints();
|
||||
}
|
||||
|
||||
/* From version 15, we moved a semaphore bit from bit 2 to bit 3 in m4, making
|
||||
|
@ -1275,9 +1255,9 @@ bool AfterLoadGame()
|
|||
/* Buoys do now store the owner of the previous water tile, which can never
|
||||
* be OWNER_NONE. So replace OWNER_NONE with OWNER_WATER. */
|
||||
if (CheckSavegameVersion(46)) {
|
||||
Station *st;
|
||||
FOR_ALL_STATIONS(st) {
|
||||
if (st->IsBuoy() && IsTileOwner(st->xy, OWNER_NONE) && TileHeight(st->xy) == 0) SetTileOwner(st->xy, OWNER_WATER);
|
||||
Waypoint *wp;
|
||||
FOR_ALL_WAYPOINTS(wp) {
|
||||
if ((wp->facilities & FACIL_DOCK) != 0 && IsTileOwner(wp->xy, OWNER_NONE) && TileHeight(wp->xy) == 0) SetTileOwner(wp->xy, OWNER_WATER);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1487,15 +1467,6 @@ bool AfterLoadGame()
|
|||
}
|
||||
|
||||
if (CheckSavegameVersion(84)) {
|
||||
/* Update go to buoy orders because they are just waypoints */
|
||||
Order *order;
|
||||
FOR_ALL_ORDERS(order) {
|
||||
if (order->IsType(OT_GOTO_STATION) && Station::Get(order->GetDestination())->IsBuoy()) {
|
||||
order->SetLoadType(OLF_LOAD_IF_POSSIBLE);
|
||||
order->SetUnloadType(OUF_UNLOAD_IF_POSSIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Set all share owners to INVALID_COMPANY for
|
||||
* 1) all inactive companies
|
||||
* (when inactive companies were stored in the savegame - TTD, TTDP and some
|
||||
|
@ -1561,7 +1532,7 @@ bool AfterLoadGame()
|
|||
if (IsBuoyTile(t)) {
|
||||
/* reset buoy owner to OWNER_NONE in the station struct
|
||||
* (even if it is owned by active company) */
|
||||
Station::GetByTile(t)->owner = OWNER_NONE;
|
||||
Waypoint::GetByTile(t)->owner = OWNER_NONE;
|
||||
}
|
||||
} else if (IsTileType(t, MP_ROAD)) {
|
||||
/* works for all RoadTileType */
|
||||
|
@ -1805,16 +1776,6 @@ bool AfterLoadGame()
|
|||
FOR_ALL_STATIONS(st) {
|
||||
if (!Company::IsValidID(st->owner)) st->owner = OWNER_NONE;
|
||||
}
|
||||
|
||||
/* Give owners to waypoints, based on rail tracks it is sitting on.
|
||||
* If none is available, specify OWNER_NONE.
|
||||
* This code was in CheckSavegameVersion(101) in the past, but in some cases,
|
||||
* the owner of waypoints could be incorrect. */
|
||||
Waypoint *wp;
|
||||
FOR_ALL_WAYPOINTS(wp) {
|
||||
Owner owner = IsTileType(wp->xy, MP_RAILWAY) ? GetTileOwner(wp->xy) : OWNER_NONE;
|
||||
wp->owner = Company::IsValidID(owner) ? owner : OWNER_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Trains could now stop in a specific location. */
|
||||
|
@ -1913,14 +1874,6 @@ bool AfterLoadGame()
|
|||
}
|
||||
s->cargo_type = CT_INVALID;
|
||||
}
|
||||
|
||||
Order *o;
|
||||
FOR_ALL_ORDERS(o) {
|
||||
/* Buoys are now go to waypoint orders */
|
||||
if (!o->IsType(OT_GOTO_STATION) || !Station::Get(o->GetDestination())->IsBuoy()) continue;
|
||||
|
||||
o->MakeGoToWaypoint(o->GetDestination());
|
||||
}
|
||||
}
|
||||
|
||||
AfterLoadLabelMaps();
|
||||
|
@ -1950,8 +1903,7 @@ void ReloadNewGRFData()
|
|||
AfterLoadVehicles(false);
|
||||
StartupEngines();
|
||||
SetCachedEngineCounts();
|
||||
/* update station and waypoint graphics */
|
||||
AfterLoadWaypoints();
|
||||
/* update station graphics */
|
||||
AfterLoadStations();
|
||||
/* Check and update house and town values */
|
||||
UpdateHousesAndTowns();
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
|
||||
#include "saveload_internal.h"
|
||||
|
||||
extern const uint16 SAVEGAME_VERSION = 122;
|
||||
extern const uint16 SAVEGAME_VERSION = 123;
|
||||
|
||||
SavegameType _savegame_type; ///< type of savegame we are loading
|
||||
|
||||
|
@ -873,6 +873,7 @@ size_t SlCalcObjMemberLength(const void *object, const SaveLoad *sld)
|
|||
break;
|
||||
case SL_WRITEBYTE: return 1; // a byte is logically of size 1
|
||||
case SL_VEH_INCLUDE: return SlCalcObjLength(object, GetVehicleDescription(VEH_END));
|
||||
case SL_ST_INCLUDE: return SlCalcObjLength(object, GetBaseStationDescription());
|
||||
default: NOT_REACHED();
|
||||
}
|
||||
return 0;
|
||||
|
@ -934,6 +935,10 @@ bool SlObjectMember(void *ptr, const SaveLoad *sld)
|
|||
SlObject(ptr, GetVehicleDescription(VEH_END));
|
||||
break;
|
||||
|
||||
case SL_ST_INCLUDE:
|
||||
SlObject(ptr, GetBaseStationDescription());
|
||||
break;
|
||||
|
||||
default: NOT_REACHED();
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -182,6 +182,7 @@ enum SaveLoadTypes {
|
|||
/* non-normal save-load types */
|
||||
SL_WRITEBYTE = 8,
|
||||
SL_VEH_INCLUDE = 9,
|
||||
SL_ST_INCLUDE = 10,
|
||||
SL_END = 15
|
||||
};
|
||||
|
||||
|
@ -235,6 +236,7 @@ typedef SaveLoad SaveLoadGlobVarList;
|
|||
|
||||
#define SLE_WRITEBYTEX(offset, something) SLE_GENERALX(SL_WRITEBYTE, offset, 0, 0, something, 0)
|
||||
#define SLE_VEH_INCLUDEX() SLE_GENERALX(SL_VEH_INCLUDE, 0, 0, 0, 0, SL_MAX_VERSION)
|
||||
#define SLE_ST_INCLUDEX() SLE_GENERALX(SL_ST_INCLUDE, 0, 0, 0, 0, SL_MAX_VERSION)
|
||||
|
||||
/* End marker */
|
||||
#define SLE_END() {false, SL_END, 0, 0, 0, 0, NULL}
|
||||
|
|
|
@ -16,7 +16,10 @@ StringID RemapOldStringID(StringID s);
|
|||
char *CopyFromOldName(StringID id);
|
||||
void ResetOldNames();
|
||||
|
||||
void AfterLoadWaypoints();
|
||||
void MoveBuoysToWaypoints();
|
||||
void MoveWaypointsToBaseStations();
|
||||
const SaveLoad *GetBaseStationDescription();
|
||||
|
||||
void AfterLoadVehicles(bool part_of_load);
|
||||
void AfterLoadStations();
|
||||
void AfterLoadLabelMaps();
|
||||
|
|
|
@ -4,27 +4,98 @@
|
|||
|
||||
#include "../stdafx.h"
|
||||
#include "../station_base.h"
|
||||
#include "../waypoint.h"
|
||||
#include "../roadstop_base.h"
|
||||
#include "../order_base.h"
|
||||
#include "../vehicle_base.h"
|
||||
#include "../core/bitmath_func.hpp"
|
||||
#include "../core/alloc_func.hpp"
|
||||
#include "../variables.h"
|
||||
#include "../newgrf_station.h"
|
||||
|
||||
#include "saveload.h"
|
||||
#include "table/strings.h"
|
||||
|
||||
/**
|
||||
* Update the buoy orders to be waypoint orders.
|
||||
* @param o the order 'list' to check.
|
||||
*/
|
||||
static void UpdateWaypointOrder(Order *o)
|
||||
{
|
||||
if (!o->IsType(OT_GOTO_STATION)) return;
|
||||
|
||||
const Station *st = Station::Get(o->GetDestination());
|
||||
if ((st->had_vehicle_of_type & HVOT_WAYPOINT) == 0) return;
|
||||
|
||||
o->MakeGoToWaypoint(o->GetDestination());
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform all steps to upgrade from the old station buoys to the new version
|
||||
* that uses waypoints. This includes some old saveload mechanics.
|
||||
*/
|
||||
void MoveBuoysToWaypoints()
|
||||
{
|
||||
/* Buoy orders become waypoint orders */
|
||||
OrderList *ol;
|
||||
FOR_ALL_ORDER_LISTS(ol) {
|
||||
if (ol->GetFirstSharedVehicle()->type != VEH_SHIP) continue;
|
||||
|
||||
for (Order *o = ol->GetFirstOrder(); o != NULL; o = o->next) UpdateWaypointOrder(o);
|
||||
}
|
||||
|
||||
Vehicle *v;
|
||||
FOR_ALL_VEHICLES(v) {
|
||||
if (v->type != VEH_SHIP) continue;
|
||||
|
||||
UpdateWaypointOrder(&v->current_order);
|
||||
}
|
||||
|
||||
/* Now make the stations waypoints */
|
||||
Station *st;
|
||||
FOR_ALL_STATIONS(st) {
|
||||
if ((st->had_vehicle_of_type & HVOT_WAYPOINT) == 0) continue;
|
||||
|
||||
StationID index = st->index;
|
||||
TileIndex xy = st->xy;
|
||||
Town *town = st->town;
|
||||
StringID string_id = st->string_id;
|
||||
char *name = st->name;
|
||||
Date build_date = st->build_date;
|
||||
|
||||
/* Delete the station, so we can make it a real waypoint. */
|
||||
delete st;
|
||||
|
||||
Waypoint *wp = new (index) Waypoint(xy);
|
||||
wp->town = town;
|
||||
wp->string_id = STR_SV_STNAME_BUOY;
|
||||
wp->name = name;
|
||||
wp->delete_ctr = 0; // Just reset delete counter for once.
|
||||
wp->build_date = build_date;
|
||||
wp->owner = OWNER_NONE;
|
||||
|
||||
if (IsInsideBS(string_id, STR_SV_STNAME_BUOY, 9)) wp->town_cn = string_id - STR_SV_STNAME_BUOY;
|
||||
|
||||
if (IsBuoyTile(xy) && GetStationIndex(xy) == index) {
|
||||
wp->facilities |= FACIL_DOCK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AfterLoadStations()
|
||||
{
|
||||
/* Update the speclists of all stations to point to the currently loaded custom stations. */
|
||||
Station *st;
|
||||
FOR_ALL_STATIONS(st) {
|
||||
BaseStation *st;
|
||||
FOR_ALL_BASE_STATIONS(st) {
|
||||
for (uint i = 0; i < st->num_specs; i++) {
|
||||
if (st->speclist[i].grfid == 0) continue;
|
||||
|
||||
st->speclist[i].spec = GetCustomStationSpecByGrf(st->speclist[i].grfid, st->speclist[i].localidx, NULL);
|
||||
}
|
||||
|
||||
for (CargoID c = 0; c < NUM_CARGO; c++) st->goods[c].cargo.InvalidateCache();
|
||||
if (Station::IsExpected(st)) {
|
||||
for (CargoID c = 0; c < NUM_CARGO; c++) Station::From(st)->goods[c].cargo.InvalidateCache();
|
||||
}
|
||||
|
||||
StationUpdateAnimTriggers(st);
|
||||
}
|
||||
|
@ -48,7 +119,7 @@ static const SaveLoad _roadstop_desc[] = {
|
|||
SLE_END()
|
||||
};
|
||||
|
||||
static const SaveLoad _station_desc[] = {
|
||||
static const SaveLoad _old_station_desc[] = {
|
||||
SLE_CONDVAR(Station, xy, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
|
||||
SLE_CONDVAR(Station, xy, SLE_UINT32, 6, SL_MAX_VERSION),
|
||||
SLE_CONDNULL(4, 0, 5), ///< bus/lorry tile
|
||||
|
@ -145,66 +216,54 @@ const SaveLoad *GetGoodsDesc()
|
|||
}
|
||||
|
||||
|
||||
static void SaveLoad_STNS(Station *st)
|
||||
{
|
||||
SlObject(st, _station_desc);
|
||||
|
||||
_waiting_acceptance = 0;
|
||||
|
||||
uint num_cargo = CheckSavegameVersion(55) ? 12 : NUM_CARGO;
|
||||
for (CargoID i = 0; i < num_cargo; i++) {
|
||||
GoodsEntry *ge = &st->goods[i];
|
||||
SlObject(ge, GetGoodsDesc());
|
||||
if (CheckSavegameVersion(68)) {
|
||||
SB(ge->acceptance_pickup, GoodsEntry::ACCEPTANCE, 1, HasBit(_waiting_acceptance, 15));
|
||||
if (GB(_waiting_acceptance, 0, 12) != 0) {
|
||||
/* Don't construct the packet with station here, because that'll fail with old savegames */
|
||||
CargoPacket *cp = new CargoPacket();
|
||||
/* In old versions, enroute_from used 0xFF as INVALID_STATION */
|
||||
cp->source = (CheckSavegameVersion(7) && _cargo_source == 0xFF) ? INVALID_STATION : _cargo_source;
|
||||
cp->count = GB(_waiting_acceptance, 0, 12);
|
||||
cp->days_in_transit = _cargo_days;
|
||||
cp->feeder_share = _cargo_feeder_share;
|
||||
cp->source_xy = _cargo_source_xy;
|
||||
cp->days_in_transit = _cargo_days;
|
||||
cp->feeder_share = _cargo_feeder_share;
|
||||
SB(ge->acceptance_pickup, GoodsEntry::PICKUP, 1, 1);
|
||||
ge->cargo.Append(cp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (st->num_specs != 0) {
|
||||
/* Allocate speclist memory when loading a game */
|
||||
if (st->speclist == NULL) st->speclist = CallocT<StationSpecList>(st->num_specs);
|
||||
for (uint i = 0; i < st->num_specs; i++) {
|
||||
SlObject(&st->speclist[i], _station_speclist_desc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void Save_STNS()
|
||||
{
|
||||
Station *st;
|
||||
/* Write the stations */
|
||||
FOR_ALL_STATIONS(st) {
|
||||
SlSetArrayIndex(st->index);
|
||||
SlAutolength((AutolengthProc*)SaveLoad_STNS, st);
|
||||
}
|
||||
}
|
||||
|
||||
static void Load_STNS()
|
||||
{
|
||||
int index;
|
||||
while ((index = SlIterateArray()) != -1) {
|
||||
Station *st = new (index) Station();
|
||||
|
||||
SaveLoad_STNS(st);
|
||||
SlObject(st, _old_station_desc);
|
||||
|
||||
_waiting_acceptance = 0;
|
||||
|
||||
uint num_cargo = CheckSavegameVersion(55) ? 12 : NUM_CARGO;
|
||||
for (CargoID i = 0; i < num_cargo; i++) {
|
||||
GoodsEntry *ge = &st->goods[i];
|
||||
SlObject(ge, GetGoodsDesc());
|
||||
if (CheckSavegameVersion(68)) {
|
||||
SB(ge->acceptance_pickup, GoodsEntry::ACCEPTANCE, 1, HasBit(_waiting_acceptance, 15));
|
||||
if (GB(_waiting_acceptance, 0, 12) != 0) {
|
||||
/* Don't construct the packet with station here, because that'll fail with old savegames */
|
||||
CargoPacket *cp = new CargoPacket();
|
||||
/* In old versions, enroute_from used 0xFF as INVALID_STATION */
|
||||
cp->source = (CheckSavegameVersion(7) && _cargo_source == 0xFF) ? INVALID_STATION : _cargo_source;
|
||||
cp->count = GB(_waiting_acceptance, 0, 12);
|
||||
cp->days_in_transit = _cargo_days;
|
||||
cp->feeder_share = _cargo_feeder_share;
|
||||
cp->source_xy = _cargo_source_xy;
|
||||
cp->days_in_transit = _cargo_days;
|
||||
cp->feeder_share = _cargo_feeder_share;
|
||||
SB(ge->acceptance_pickup, GoodsEntry::PICKUP, 1, 1);
|
||||
ge->cargo.Append(cp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (st->num_specs != 0) {
|
||||
/* Allocate speclist memory when loading a game */
|
||||
st->speclist = CallocT<StationSpecList>(st->num_specs);
|
||||
for (uint i = 0; i < st->num_specs; i++) {
|
||||
SlObject(&st->speclist[i], _station_speclist_desc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Ptrs_STNS()
|
||||
{
|
||||
/* Don't run when savegame version is higher than or equal to 123. */
|
||||
if (!CheckSavegameVersion(123)) return;
|
||||
|
||||
Station *st;
|
||||
FOR_ALL_STATIONS(st) {
|
||||
if (!CheckSavegameVersion(68)) {
|
||||
|
@ -213,11 +272,147 @@ void Ptrs_STNS()
|
|||
SlObject(ge, GetGoodsDesc());
|
||||
}
|
||||
}
|
||||
SlObject(st, _station_desc);
|
||||
SlObject(st, _old_station_desc);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static const SaveLoad _base_station_desc[] = {
|
||||
SLE_VAR(BaseStation, xy, SLE_UINT32),
|
||||
SLE_REF(BaseStation, town, REF_TOWN),
|
||||
SLE_VAR(BaseStation, string_id, SLE_STRINGID),
|
||||
SLE_STR(BaseStation, name, SLE_STR, 0),
|
||||
SLE_VAR(BaseStation, delete_ctr, SLE_UINT8),
|
||||
SLE_VAR(BaseStation, owner, SLE_UINT8),
|
||||
SLE_VAR(BaseStation, facilities, SLE_UINT8),
|
||||
SLE_VAR(BaseStation, build_date, SLE_INT32),
|
||||
|
||||
/* Used by newstations for graphic variations */
|
||||
SLE_VAR(BaseStation, random_bits, SLE_UINT16),
|
||||
SLE_VAR(BaseStation, waiting_triggers, SLE_UINT8),
|
||||
SLE_VAR(BaseStation, num_specs, SLE_UINT8),
|
||||
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
static const SaveLoad _station_desc[] = {
|
||||
SLE_WRITEBYTE(Station, facilities, FACIL_NONE),
|
||||
SLE_ST_INCLUDEX(),
|
||||
|
||||
SLE_VAR(Station, train_tile, SLE_UINT32),
|
||||
SLE_VAR(Station, trainst_w, SLE_UINT8),
|
||||
SLE_VAR(Station, trainst_h, SLE_UINT8),
|
||||
|
||||
SLE_REF(Station, bus_stops, REF_ROADSTOPS),
|
||||
SLE_REF(Station, truck_stops, REF_ROADSTOPS),
|
||||
SLE_VAR(Station, dock_tile, SLE_UINT32),
|
||||
SLE_VAR(Station, airport_tile, SLE_UINT32),
|
||||
SLE_VAR(Station, airport_type, SLE_UINT8),
|
||||
SLE_VAR(Station, airport_flags, SLE_UINT64),
|
||||
|
||||
SLE_VAR(Station, indtype, SLE_UINT8),
|
||||
|
||||
SLE_VAR(Station, time_since_load, SLE_UINT8),
|
||||
SLE_VAR(Station, time_since_unload, SLE_UINT8),
|
||||
SLE_VAR(Station, last_vehicle_type, SLE_UINT8),
|
||||
SLE_VAR(Station, had_vehicle_of_type, SLE_UINT8),
|
||||
SLE_LST(Station, loading_vehicles, REF_VEHICLE),
|
||||
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
static const SaveLoad _waypoint_desc[] = {
|
||||
SLE_WRITEBYTE(Waypoint, facilities, FACIL_WAYPOINT),
|
||||
SLE_ST_INCLUDEX(),
|
||||
|
||||
SLE_VAR(Waypoint, town_cn, SLE_UINT16),
|
||||
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the base station description to be used for SL_ST_INCLUDE
|
||||
* @return the base station description.
|
||||
*/
|
||||
const SaveLoad *GetBaseStationDescription()
|
||||
{
|
||||
return _base_station_desc;
|
||||
}
|
||||
|
||||
static void RealSave_STNN(BaseStation *bst)
|
||||
{
|
||||
bool waypoint = (bst->facilities & FACIL_WAYPOINT) != 0;
|
||||
SlObject(bst, waypoint ? _waypoint_desc : _station_desc);
|
||||
|
||||
if (!waypoint) {
|
||||
Station *st = Station::From(bst);
|
||||
for (CargoID i = 0; i < NUM_CARGO; i++) {
|
||||
SlObject(&st->goods[i], GetGoodsDesc());
|
||||
}
|
||||
}
|
||||
|
||||
for (uint i = 0; i < bst->num_specs; i++) {
|
||||
SlObject(&bst->speclist[i], _station_speclist_desc);
|
||||
}
|
||||
}
|
||||
|
||||
static void Save_STNN()
|
||||
{
|
||||
BaseStation *st;
|
||||
/* Write the stations */
|
||||
FOR_ALL_BASE_STATIONS(st) {
|
||||
SlSetArrayIndex(st->index);
|
||||
SlAutolength((AutolengthProc*)RealSave_STNN, st);
|
||||
}
|
||||
}
|
||||
|
||||
static void Load_STNN()
|
||||
{
|
||||
int index;
|
||||
|
||||
while ((index = SlIterateArray()) != -1) {
|
||||
bool waypoint = (SlReadByte() & FACIL_WAYPOINT) != 0;
|
||||
|
||||
BaseStation *bst = waypoint ? (BaseStation *)new (index) Waypoint() : new (index) Station();
|
||||
SlObject(bst, waypoint ? _waypoint_desc : _station_desc);
|
||||
|
||||
if (!waypoint) {
|
||||
Station *st = Station::From(bst);
|
||||
for (CargoID i = 0; i < NUM_CARGO; i++) {
|
||||
SlObject(&st->goods[i], GetGoodsDesc());
|
||||
}
|
||||
}
|
||||
|
||||
if (bst->num_specs != 0) {
|
||||
/* Allocate speclist memory when loading a game */
|
||||
bst->speclist = CallocT<StationSpecList>(bst->num_specs);
|
||||
for (uint i = 0; i < bst->num_specs; i++) {
|
||||
SlObject(&bst->speclist[i], _station_speclist_desc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void Ptrs_STNN()
|
||||
{
|
||||
/* Don't run when savegame version lower than 123. */
|
||||
if (CheckSavegameVersion(123)) return;
|
||||
|
||||
Station *st;
|
||||
FOR_ALL_STATIONS(st) {
|
||||
for (CargoID i = 0; i < NUM_CARGO; i++) {
|
||||
GoodsEntry *ge = &st->goods[i];
|
||||
SlObject(ge, GetGoodsDesc());
|
||||
}
|
||||
SlObject(st, _station_desc);
|
||||
}
|
||||
|
||||
Waypoint *wp;
|
||||
FOR_ALL_WAYPOINTS(wp) {
|
||||
SlObject(wp, _waypoint_desc);
|
||||
}
|
||||
}
|
||||
|
||||
static void Save_ROADSTOP()
|
||||
{
|
||||
RoadStop *rs;
|
||||
|
@ -248,6 +443,7 @@ static void Ptrs_ROADSTOP()
|
|||
}
|
||||
|
||||
extern const ChunkHandler _station_chunk_handlers[] = {
|
||||
{ 'STNS', Save_STNS, Load_STNS, Ptrs_STNS, CH_ARRAY },
|
||||
{ 'STNS', NULL, Load_STNS, Ptrs_STNS, CH_ARRAY },
|
||||
{ 'STNN', Save_STNN, Load_STNN, Ptrs_STNN, CH_ARRAY },
|
||||
{ 'ROAD', Save_ROADSTOP, Load_ROADSTOP, Ptrs_ROADSTOP, CH_ARRAY | CH_LAST},
|
||||
};
|
||||
|
|
|
@ -5,120 +5,187 @@
|
|||
#include "../stdafx.h"
|
||||
#include "../waypoint.h"
|
||||
#include "../newgrf_station.h"
|
||||
#include "../vehicle_base.h"
|
||||
#include "../town.h"
|
||||
#include "../station_map.h"
|
||||
|
||||
#include "table/strings.h"
|
||||
|
||||
#include "saveload.h"
|
||||
#include "saveload_internal.h"
|
||||
|
||||
/** Helper structure to convert from the old waypoint system. */
|
||||
struct OldWaypoint {
|
||||
size_t index;
|
||||
TileIndex xy;
|
||||
TownID town_index;
|
||||
Town *town;
|
||||
uint16 town_cn;
|
||||
StringID string_id;
|
||||
char *name;
|
||||
uint8 delete_ctr;
|
||||
Date build_date;
|
||||
uint8 localidx;
|
||||
uint32 grfid;
|
||||
const StationSpec *spec;
|
||||
OwnerByte owner;
|
||||
|
||||
size_t new_index;
|
||||
};
|
||||
|
||||
/** Temporary array with old waypoints. */
|
||||
static SmallVector<OldWaypoint, 16> _old_waypoints;
|
||||
|
||||
/**
|
||||
* Update waypoint graphics id against saved GRFID/localidx.
|
||||
* This is to ensure the chosen graphics are correct if GRF files are changed.
|
||||
* Update the waypoint orders to get the new waypoint ID.
|
||||
* @param o the order 'list' to check.
|
||||
*/
|
||||
void AfterLoadWaypoints()
|
||||
static void UpdateWaypointOrder(Order *o)
|
||||
{
|
||||
Waypoint *wp;
|
||||
if (!o->IsType(OT_GOTO_WAYPOINT)) return;
|
||||
|
||||
FOR_ALL_WAYPOINTS(wp) {
|
||||
if (wp->num_specs == 0) continue;
|
||||
for (OldWaypoint *wp = _old_waypoints.Begin(); wp != _old_waypoints.End(); wp++) {
|
||||
if (wp->index != o->GetDestination()) continue;
|
||||
|
||||
for (uint i = 0; i < GetNumCustomStations(STAT_CLASS_WAYP); i++) {
|
||||
const StationSpec *statspec = GetCustomStationSpec(STAT_CLASS_WAYP, i);
|
||||
if (statspec != NULL && statspec->grffile->grfid == wp->speclist[1].grfid && statspec->localidx == wp->speclist[1].localidx) {
|
||||
wp->speclist[1].spec = statspec;
|
||||
break;
|
||||
}
|
||||
}
|
||||
o->SetDestination(wp->new_index);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static uint16 _waypoint_town_index;
|
||||
static StringID _waypoint_string_id;
|
||||
static StationSpecList _waypoint_spec;
|
||||
/**
|
||||
* Perform all steps to upgrade from the old waypoints to the new version
|
||||
* that uses station. This includes some old saveload mechanics.
|
||||
*/
|
||||
void MoveWaypointsToBaseStations()
|
||||
{
|
||||
/* In version 17, ground type is moved from m2 to m4 for depots and
|
||||
* waypoints to make way for storing the index in m2. The custom graphics
|
||||
* id which was stored in m4 is now saved as a grf/id reference in the
|
||||
* waypoint struct. */
|
||||
if (CheckSavegameVersion(17)) {
|
||||
for (OldWaypoint *wp = _old_waypoints.Begin(); wp != _old_waypoints.End(); wp++) {
|
||||
if (wp->delete_ctr == 0 && HasBit(_m[wp->xy].m3, 4)) {
|
||||
wp->spec = GetCustomStationSpec(STAT_CLASS_WAYP, _m[wp->xy].m4 + 1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* As of version 17, we recalculate the custom graphic ID of waypoints
|
||||
* from the GRF ID / station index. */
|
||||
for (OldWaypoint *wp = _old_waypoints.Begin(); wp != _old_waypoints.End(); wp++) {
|
||||
for (uint i = 0; i < GetNumCustomStations(STAT_CLASS_WAYP); i++) {
|
||||
const StationSpec *statspec = GetCustomStationSpec(STAT_CLASS_WAYP, i);
|
||||
if (statspec != NULL && statspec->grffile->grfid == wp->grfid && statspec->localidx == wp->localidx) {
|
||||
wp->spec = statspec;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const SaveLoad _waypoint_desc[] = {
|
||||
SLE_CONDVAR(Waypoint, xy, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
|
||||
SLE_CONDVAR(Waypoint, xy, SLE_UINT32, 6, SL_MAX_VERSION),
|
||||
SLEG_CONDVAR(_waypoint_town_index, SLE_UINT16, 12, 121),
|
||||
SLE_CONDREF(Waypoint, town, REF_TOWN, 122, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Waypoint, town_cn, SLE_FILE_U8 | SLE_VAR_U16, 12, 88),
|
||||
SLE_CONDVAR(Waypoint, town_cn, SLE_UINT16, 89, SL_MAX_VERSION),
|
||||
SLEG_CONDVAR(_waypoint_string_id, SLE_STRINGID, 0, 83),
|
||||
SLE_CONDSTR(Waypoint, name, SLE_STR, 0, 84, SL_MAX_VERSION),
|
||||
SLE_VAR(Waypoint, delete_ctr, SLE_UINT8),
|
||||
/* All saveload conversions have been done. Create the new waypoints! */
|
||||
for (OldWaypoint *wp = _old_waypoints.Begin(); wp != _old_waypoints.End(); wp++) {
|
||||
Waypoint *new_wp = new Waypoint(wp->xy);
|
||||
new_wp->town = wp->town;
|
||||
new_wp->town_cn = wp->town_cn;
|
||||
new_wp->name = wp->name;
|
||||
new_wp->delete_ctr = 0; // Just reset delete counter for once.
|
||||
new_wp->build_date = wp->build_date;
|
||||
new_wp->owner = wp->owner;
|
||||
|
||||
SLE_CONDVAR(Waypoint, build_date, SLE_FILE_U16 | SLE_VAR_I32, 3, 30),
|
||||
SLE_CONDVAR(Waypoint, build_date, SLE_INT32, 31, SL_MAX_VERSION),
|
||||
SLEG_CONDVAR(_waypoint_spec.localidx, SLE_UINT8, 3, SL_MAX_VERSION),
|
||||
SLEG_CONDVAR(_waypoint_spec.grfid, SLE_UINT32, 17, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Waypoint, owner, SLE_UINT8, 101, SL_MAX_VERSION),
|
||||
new_wp->string_id = STR_SV_STNAME_WAYPOINT;
|
||||
|
||||
TileIndex t = wp->xy;
|
||||
if (IsTileType(t, MP_RAILWAY) && GetRailTileType(t) == 2 /* RAIL_TILE_WAYPOINT */ && _m[t].m2 == wp->index) {
|
||||
/* The tile might've been reserved! */
|
||||
bool reserved = !CheckSavegameVersion(100) && HasBit(_m[t].m5, 4);
|
||||
|
||||
/* The tile really has our waypoint, so reassign the map array */
|
||||
MakeRailWaypoint(t, GetTileOwner(t), new_wp->index, (Axis)GB(_m[t].m5, 0, 1), 0, GetRailType(t));
|
||||
new_wp->facilities |= FACIL_TRAIN;
|
||||
new_wp->owner = GetTileOwner(t);
|
||||
|
||||
SetRailwayStationReservation(t, reserved);
|
||||
|
||||
if (wp->spec != NULL) {
|
||||
SetCustomStationSpecIndex(t, AllocateSpecToStation(wp->spec, new_wp, true));
|
||||
}
|
||||
}
|
||||
|
||||
wp->new_index = new_wp->index;
|
||||
}
|
||||
|
||||
/* Update the orders of vehicles */
|
||||
OrderList *ol;
|
||||
FOR_ALL_ORDER_LISTS(ol) {
|
||||
if (ol->GetFirstSharedVehicle()->type != VEH_TRAIN) continue;
|
||||
|
||||
for (Order *o = ol->GetFirstOrder(); o != NULL; o = o->next) UpdateWaypointOrder(o);
|
||||
}
|
||||
|
||||
Vehicle *v;
|
||||
FOR_ALL_VEHICLES(v) {
|
||||
if (v->type != VEH_TRAIN) continue;
|
||||
|
||||
UpdateWaypointOrder(&v->current_order);
|
||||
}
|
||||
|
||||
_old_waypoints.Reset();
|
||||
}
|
||||
|
||||
static const SaveLoad _old_waypoint_desc[] = {
|
||||
SLE_CONDVAR(OldWaypoint, xy, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
|
||||
SLE_CONDVAR(OldWaypoint, xy, SLE_UINT32, 6, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(OldWaypoint, town_index, SLE_UINT16, 12, 121),
|
||||
SLE_CONDREF(OldWaypoint, town, REF_TOWN, 122, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(OldWaypoint, town_cn, SLE_FILE_U8 | SLE_VAR_U16, 12, 88),
|
||||
SLE_CONDVAR(OldWaypoint, town_cn, SLE_UINT16, 89, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(OldWaypoint, string_id, SLE_STRINGID, 0, 83),
|
||||
SLE_CONDSTR(OldWaypoint, name, SLE_STR, 0, 84, SL_MAX_VERSION),
|
||||
SLE_VAR(OldWaypoint, delete_ctr, SLE_UINT8),
|
||||
|
||||
SLE_CONDVAR(OldWaypoint, build_date, SLE_FILE_U16 | SLE_VAR_I32, 3, 30),
|
||||
SLE_CONDVAR(OldWaypoint, build_date, SLE_INT32, 31, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(OldWaypoint, localidx, SLE_UINT8, 3, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(OldWaypoint, grfid, SLE_UINT32, 17, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(OldWaypoint, owner, SLE_UINT8, 101, SL_MAX_VERSION),
|
||||
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
static void Save_WAYP()
|
||||
{
|
||||
Waypoint *wp;
|
||||
|
||||
FOR_ALL_WAYPOINTS(wp) {
|
||||
if (wp->num_specs == 0) {
|
||||
_waypoint_spec.grfid = 0;
|
||||
} else {
|
||||
_waypoint_spec = wp->speclist[1];
|
||||
}
|
||||
|
||||
SlSetArrayIndex(wp->index);
|
||||
SlObject(wp, _waypoint_desc);
|
||||
}
|
||||
}
|
||||
|
||||
static void Load_WAYP()
|
||||
{
|
||||
/* Precaution for when loading failed and it didn't get cleared */
|
||||
_old_waypoints.Clear();
|
||||
|
||||
int index;
|
||||
|
||||
while ((index = SlIterateArray()) != -1) {
|
||||
_waypoint_string_id = 0;
|
||||
_waypoint_town_index = 0;
|
||||
_waypoint_spec.grfid = 0;
|
||||
OldWaypoint *wp = _old_waypoints.Append();
|
||||
memset(wp, 0, sizeof(*wp));
|
||||
|
||||
Waypoint *wp = new (index) Waypoint();
|
||||
SlObject(wp, _waypoint_desc);
|
||||
|
||||
wp->facilities |= FACIL_TRAIN;
|
||||
|
||||
if (_waypoint_spec.grfid != 0) {
|
||||
wp->num_specs = 2;
|
||||
wp->speclist = CallocT<StationSpecList>(2);
|
||||
wp->speclist[1] = _waypoint_spec;
|
||||
}
|
||||
|
||||
if (CheckSavegameVersion(84)) wp->name = (char *)(size_t)_waypoint_string_id;
|
||||
if (CheckSavegameVersion(122)) wp->town = (Town *)(size_t)_waypoint_town_index;
|
||||
wp->index = index;
|
||||
SlObject(wp, _old_waypoint_desc);
|
||||
}
|
||||
}
|
||||
|
||||
static void Ptrs_WAYP()
|
||||
{
|
||||
Waypoint *wp;
|
||||
for (OldWaypoint *wp = _old_waypoints.Begin(); wp != _old_waypoints.End(); wp++) {
|
||||
SlObject(wp, _old_waypoint_desc);
|
||||
|
||||
FOR_ALL_WAYPOINTS(wp) {
|
||||
SlObject(wp, _waypoint_desc);
|
||||
|
||||
StringID sid = (StringID)(size_t)wp->name;
|
||||
if (CheckSavegameVersion(12)) {
|
||||
wp->town_cn = (sid & 0xC000) == 0xC000 ? (sid >> 8) & 0x3F : 0;
|
||||
wp->town_cn = (wp->string_id & 0xC000) == 0xC000 ? (wp->string_id >> 8) & 0x3F : 0;
|
||||
wp->town = ClosestTownFromTile(wp->xy, UINT_MAX);
|
||||
} else if (CheckSavegameVersion(122)) {
|
||||
/* Only for versions 12 .. 122 */
|
||||
wp->town = Town::Get((size_t)wp->town);
|
||||
wp->town = Town::Get(wp->town_index);
|
||||
}
|
||||
if (CheckSavegameVersion(84)) {
|
||||
wp->name = CopyFromOldName(sid);
|
||||
wp->name = CopyFromOldName(wp->string_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern const ChunkHandler _waypoint_chunk_handlers[] = {
|
||||
{ 'CHKP', Save_WAYP, Load_WAYP, Ptrs_WAYP, CH_ARRAY | CH_LAST},
|
||||
{ 'CHKP', NULL, Load_WAYP, Ptrs_WAYP, CH_ARRAY | CH_LAST},
|
||||
};
|
||||
|
|
|
@ -288,14 +288,6 @@ static SigFlags ExploreSegment(Owner owner)
|
|||
}
|
||||
}
|
||||
|
||||
if (GetRailTileType(tile) == RAIL_TILE_WAYPOINT) {
|
||||
if (GetWaypointAxis(tile) != DiagDirToAxis(enterdir)) continue;
|
||||
if (!(flags & SF_TRAIN) && HasVehicleOnPos(tile, NULL, &TrainOnTileEnum)) flags |= SF_TRAIN;
|
||||
tile += TileOffsByDiagDir(exitdir);
|
||||
/* enterdir and exitdir stay the same */
|
||||
break;
|
||||
}
|
||||
|
||||
TrackBits tracks = GetTrackBits(tile); // trackbits of tile
|
||||
TrackBits tracks_masked = (TrackBits)(tracks & _enterdir_to_trackbits[enterdir]); // only incidating trackbits
|
||||
|
||||
|
|
|
@ -50,12 +50,6 @@ Station::Station(TileIndex tile) :
|
|||
/* this->random_bits is set in Station::AddFacility() */
|
||||
}
|
||||
|
||||
/* static */ BaseStation *BaseStation::GetByTile(TileIndex tile)
|
||||
{
|
||||
if (IsRailWaypointTile(tile)) return Waypoint::GetByTile(tile);
|
||||
return Station::GetByTile(tile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up a station by clearing vehicle orders and invalidating windows.
|
||||
* Aircraft-Hangar orders need special treatment here, as the hangars are
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include "station_map.h"
|
||||
#include <list>
|
||||
|
||||
typedef Pool<Station, StationID, 32, 64000> StationPool;
|
||||
typedef Pool<BaseStation, StationID, 32, 64000> StationPool;
|
||||
extern StationPool _station_pool;
|
||||
|
||||
static const byte INITIAL_STATION_RATING = 175;
|
||||
|
@ -85,7 +85,7 @@ struct TileArea {
|
|||
};
|
||||
|
||||
/** Base class for all station-ish types */
|
||||
struct BaseStation {
|
||||
struct BaseStation : StationPool::PoolItem<&_station_pool> {
|
||||
TileIndex xy; ///< Base tile of the station
|
||||
ViewportSign sign; ///< NOSAVE: Dimensions of sign
|
||||
byte delete_ctr; ///< Delete counter. If greater than 0 then it is decremented until it reaches 0; the waypoint is then is deleted.
|
||||
|
@ -144,9 +144,14 @@ struct BaseStation {
|
|||
* @param tile The tile to get the base station from.
|
||||
* @return the station associated with that tile.
|
||||
*/
|
||||
static BaseStation *GetByTile(TileIndex tile);
|
||||
static FORCEINLINE BaseStation *GetByTile(TileIndex tile)
|
||||
{
|
||||
return BaseStation::Get(GetStationIndex(tile));
|
||||
}
|
||||
};
|
||||
|
||||
#define FOR_ALL_BASE_STATIONS(var) FOR_ALL_ITEMS_FROM(BaseStation, station_index, var, 0)
|
||||
|
||||
/**
|
||||
* Class defining several overloaded accessors so we don't
|
||||
* have to cast base stations that often
|
||||
|
@ -175,6 +180,44 @@ struct SpecializedStation : public BaseStation {
|
|||
return (st->facilities & FACIL_WAYPOINT) == EXPECTED_FACIL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether given index is a valid index for station of this type
|
||||
* @param index tested index
|
||||
* @return is this index valid index of T?
|
||||
*/
|
||||
static FORCEINLINE bool IsValidID(size_t index)
|
||||
{
|
||||
return BaseStation::IsValidID(index) && IsExpected(BaseStation::Get(index));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets station with given index
|
||||
* @return pointer to station with given index casted to T *
|
||||
*/
|
||||
static FORCEINLINE T *Get(size_t index)
|
||||
{
|
||||
return (T *)BaseStation::Get(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns station if the index is a valid index for this station type
|
||||
* @return pointer to station with given index if it's a station of this type
|
||||
*/
|
||||
static FORCEINLINE T *GetIfValid(size_t index)
|
||||
{
|
||||
return IsValidID(index) ? Get(index) : NULL ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the station belonging to a specific tile.
|
||||
* @param tile The tile to get the station from.
|
||||
* @return the station associated with that tile.
|
||||
*/
|
||||
static FORCEINLINE T *GetByTile(TileIndex tile)
|
||||
{
|
||||
return GetIfValid(GetStationIndex(tile));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a BaseStation to SpecializedStation with type checking.
|
||||
* @param st BaseStation pointer
|
||||
|
@ -198,11 +241,13 @@ struct SpecializedStation : public BaseStation {
|
|||
}
|
||||
};
|
||||
|
||||
#define FOR_ALL_BASE_STATIONS_OF_TYPE(name, var) FOR_ALL_ITEMS_FROM(name, station_index, var, 0) if (name::IsExpected(var))
|
||||
|
||||
|
||||
typedef SmallVector<Industry *, 2> IndustryVector;
|
||||
|
||||
/** Station data structure */
|
||||
struct Station : StationPool::PoolItem<&_station_pool>, SpecializedStation<Station, false> {
|
||||
struct Station : SpecializedStation<Station, false> {
|
||||
public:
|
||||
RoadStop *GetPrimaryRoadStop(RoadStopType type) const
|
||||
{
|
||||
|
@ -274,24 +319,9 @@ public:
|
|||
|
||||
/* virtual */ void GetTileArea(TileArea *ta, StationType type) const;
|
||||
|
||||
/**
|
||||
* Determines whether a station is a buoy only.
|
||||
* @todo Ditch this encoding of buoys
|
||||
*/
|
||||
FORCEINLINE bool IsBuoy() const
|
||||
{
|
||||
return (this->had_vehicle_of_type & HVOT_BUOY) != 0;
|
||||
}
|
||||
|
||||
static FORCEINLINE Station *GetByTile(TileIndex tile)
|
||||
{
|
||||
return Station::Get(GetStationIndex(tile));
|
||||
}
|
||||
|
||||
static void PostDestructor(size_t index);
|
||||
};
|
||||
|
||||
#define FOR_ALL_STATIONS_FROM(var, start) FOR_ALL_ITEMS_FROM(Station, station_index, var, start)
|
||||
#define FOR_ALL_STATIONS(var) FOR_ALL_STATIONS_FROM(var, 0)
|
||||
#define FOR_ALL_STATIONS(var) FOR_ALL_BASE_STATIONS_OF_TYPE(Station, var)
|
||||
|
||||
#endif /* STATION_BASE_H */
|
||||
|
|
|
@ -197,7 +197,6 @@ enum StationNaming {
|
|||
STATIONNAMING_AIRPORT,
|
||||
STATIONNAMING_OILRIG,
|
||||
STATIONNAMING_DOCK,
|
||||
STATIONNAMING_BUOY,
|
||||
STATIONNAMING_HELIPORT,
|
||||
};
|
||||
|
||||
|
@ -239,7 +238,6 @@ static StringID GenerateStationName(Station *st, TileIndex tile, StationNaming n
|
|||
1U << M(STR_SV_STNAME_AIRPORT), // STATIONNAMING_AIRPORT
|
||||
1U << M(STR_SV_STNAME_OILFIELD), // STATIONNAMING_OILRIG
|
||||
1U << M(STR_SV_STNAME_DOCKS), // STATIONNAMING_DOCK
|
||||
0x1FFU << M(STR_SV_STNAME_BUOY_1), // STATIONNAMING_BUOY
|
||||
1U << M(STR_SV_STNAME_HELIPORT), // STATIONNAMING_HELIPORT
|
||||
};
|
||||
|
||||
|
@ -266,24 +264,22 @@ static StringID GenerateStationName(Station *st, TileIndex tile, StationNaming n
|
|||
}
|
||||
}
|
||||
|
||||
if (name_class != STATIONNAMING_BUOY) {
|
||||
TileIndex indtile = tile;
|
||||
StationNameInformation sni = { free_names, indtypes };
|
||||
if (CircularTileSearch(&indtile, 7, FindNearIndustryName, &sni)) {
|
||||
/* An industry has been found nearby */
|
||||
IndustryType indtype = GetIndustryType(indtile);
|
||||
const IndustrySpec *indsp = GetIndustrySpec(indtype);
|
||||
/* STR_NULL means it only disables oil rig/mines */
|
||||
if (indsp->station_name != STR_NULL) {
|
||||
st->indtype = indtype;
|
||||
return STR_SV_STNAME_FALLBACK;
|
||||
}
|
||||
TileIndex indtile = tile;
|
||||
StationNameInformation sni = { free_names, indtypes };
|
||||
if (CircularTileSearch(&indtile, 7, FindNearIndustryName, &sni)) {
|
||||
/* An industry has been found nearby */
|
||||
IndustryType indtype = GetIndustryType(indtile);
|
||||
const IndustrySpec *indsp = GetIndustrySpec(indtype);
|
||||
/* STR_NULL means it only disables oil rig/mines */
|
||||
if (indsp->station_name != STR_NULL) {
|
||||
st->indtype = indtype;
|
||||
return STR_SV_STNAME_FALLBACK;
|
||||
}
|
||||
|
||||
/* Oil rigs/mines name could be marked not free by looking for a near by industry. */
|
||||
free_names = sni.free_names;
|
||||
}
|
||||
|
||||
/* Oil rigs/mines name could be marked not free by looking for a near by industry. */
|
||||
free_names = sni.free_names;
|
||||
|
||||
/* check default names */
|
||||
uint32 tmp = free_names & _gen_station_name_bits[name_class];
|
||||
if (tmp != 0) return STR_SV_STNAME + FindFirstBit(tmp);
|
||||
|
@ -540,9 +536,6 @@ CargoArray GetAcceptanceAroundTiles(TileIndex tile, int w, int h, int rad)
|
|||
*/
|
||||
static void UpdateStationAcceptance(Station *st, bool show_msg)
|
||||
{
|
||||
/* Don't update acceptance for a buoy */
|
||||
if (st->IsBuoy()) return;
|
||||
|
||||
/* old accepted goods types */
|
||||
uint old_acc = GetAcceptanceMask(st);
|
||||
|
||||
|
@ -1963,31 +1956,23 @@ CommandCost CmdBuildBuoy(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
|
|||
if (GetTileSlope(tile, NULL) != SLOPE_FLAT) return_cmd_error(STR_ERROR_SITE_UNSUITABLE);
|
||||
|
||||
/* allocate and initialize new station */
|
||||
if (!Station::CanAllocateItem()) return_cmd_error(STR_ERROR_TOO_MANY_STATIONS_LOADING);
|
||||
if (!Waypoint::CanAllocateItem()) return_cmd_error(STR_ERROR_TOO_MANY_STATIONS_LOADING);
|
||||
|
||||
if (flags & DC_EXEC) {
|
||||
Station *st = new Station(tile);
|
||||
Waypoint *st = new Waypoint(tile);
|
||||
|
||||
st->town = ClosestTownFromTile(tile, UINT_MAX);
|
||||
st->string_id = GenerateStationName(st, tile, STATIONNAMING_BUOY);
|
||||
st->string_id = STR_SV_STNAME_BUOY;
|
||||
|
||||
if (Company::IsValidID(_current_company)) {
|
||||
SetBit(st->town->have_ratings, _current_company);
|
||||
}
|
||||
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;
|
||||
|
||||
if (st->town == NULL) MakeDefaultWaypointName(st);
|
||||
|
||||
MakeBuoy(tile, st->index, GetWaterClass(tile));
|
||||
|
||||
st->UpdateVirtCoord();
|
||||
UpdateStationAcceptance(st, false);
|
||||
st->RecomputeIndustriesNear();
|
||||
InvalidateWindowData(WC_STATION_LIST, st->owner, 0);
|
||||
InvalidateWindowWidget(WC_STATION_VIEW, st->index, SVW_SHIPS);
|
||||
}
|
||||
|
@ -2008,7 +1993,7 @@ bool HasStationInUse(StationID station, CompanyID company)
|
|||
if (company == INVALID_COMPANY || v->owner == company) {
|
||||
const Order *order;
|
||||
FOR_VEHICLE_ORDERS(v, order) {
|
||||
if (order->IsType(OT_GOTO_STATION) && order->GetDestination() == station) {
|
||||
if ((order->IsType(OT_GOTO_STATION) || order->IsType(OT_GOTO_WAYPOINT)) && order->GetDestination() == station) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -2028,18 +2013,14 @@ static CommandCost RemoveBuoy(TileIndex tile, DoCommandFlag flags)
|
|||
/* XXX: strange stuff, allow clearing as invalid company when clearing landscape */
|
||||
if (!Company::IsValidID(_current_company) && !(flags & DC_BANKRUPT)) return_cmd_error(INVALID_STRING_ID);
|
||||
|
||||
Station *st = Station::GetByTile(tile);
|
||||
Waypoint *st = Waypoint::GetByTile(tile);
|
||||
|
||||
if (HasStationInUse(st->index, INVALID_COMPANY)) return_cmd_error(STR_BUOY_IS_IN_USE);
|
||||
/* remove the buoy if there is a ship on tile when company goes bankrupt... */
|
||||
if (!(flags & DC_BANKRUPT) && !EnsureNoVehicleOnGround(tile)) return CMD_ERROR;
|
||||
|
||||
if (flags & DC_EXEC) {
|
||||
st->dock_tile = INVALID_TILE;
|
||||
/* 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);
|
||||
|
||||
|
@ -2050,8 +2031,7 @@ static CommandCost RemoveBuoy(TileIndex tile, DoCommandFlag flags)
|
|||
MarkTileDirtyByTile(tile);
|
||||
|
||||
st->UpdateVirtCoord();
|
||||
st->RecomputeIndustriesNear();
|
||||
DeleteStationIfEmpty(st);
|
||||
st->delete_ctr = 0;
|
||||
}
|
||||
|
||||
return CommandCost(EXPENSES_CONSTRUCTION, _price.remove_truck_station);
|
||||
|
@ -2227,7 +2207,7 @@ static void DrawTile_Station(TileInfo *ti)
|
|||
int32 total_offset;
|
||||
int32 custom_ground_offset;
|
||||
|
||||
if (IsRailwayStation(ti->tile)) {
|
||||
if (IsRailwayStation(ti->tile) || IsRailWaypoint(ti->tile)) {
|
||||
const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile));
|
||||
roadtypes = ROADTYPES_NONE;
|
||||
total_offset = rti->total_offset;
|
||||
|
@ -2238,7 +2218,7 @@ static void DrawTile_Station(TileInfo *ti)
|
|||
custom_ground_offset = 0;
|
||||
}
|
||||
uint32 relocation = 0;
|
||||
const Station *st = NULL;
|
||||
const BaseStation *st = NULL;
|
||||
const StationSpec *statspec = NULL;
|
||||
Owner owner = GetTileOwner(ti->tile);
|
||||
|
||||
|
@ -2256,7 +2236,7 @@ static void DrawTile_Station(TileInfo *ti)
|
|||
|
||||
if (IsCustomStationSpecIndex(ti->tile)) {
|
||||
/* look for customization */
|
||||
st = Station::GetByTile(ti->tile);
|
||||
st = BaseStation::GetByTile(ti->tile);
|
||||
statspec = st->speclist[GetCustomStationSpecIndex(ti->tile)].spec;
|
||||
|
||||
if (statspec != NULL) {
|
||||
|
@ -2304,13 +2284,13 @@ static void DrawTile_Station(TileInfo *ti)
|
|||
DrawGroundSprite(image, GroundSpritePaletteTransform(image, pal, palette));
|
||||
|
||||
/* PBS debugging, draw reserved tracks darker */
|
||||
if (_game_mode != GM_MENU && _settings_client.gui.show_track_reservation && IsRailwayStation(ti->tile) && HasStationReservation(ti->tile)) {
|
||||
if (_game_mode != GM_MENU && _settings_client.gui.show_track_reservation && (IsRailwayStation(ti->tile) || IsRailWaypoint(ti->tile)) && HasStationReservation(ti->tile)) {
|
||||
const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile));
|
||||
DrawGroundSprite(GetRailStationAxis(ti->tile) == AXIS_X ? rti->base_sprites.single_y : rti->base_sprites.single_x, PALETTE_CRASH);
|
||||
}
|
||||
}
|
||||
|
||||
if (IsRailwayStation(ti->tile) && HasCatenaryDrawn(GetRailType(ti->tile)) && IsStationTileElectrifiable(ti->tile)) DrawCatenary(ti);
|
||||
if ((IsRailwayStation(ti->tile) || IsRailWaypoint(ti->tile)) && HasCatenaryDrawn(GetRailType(ti->tile)) && IsStationTileElectrifiable(ti->tile)) DrawCatenary(ti);
|
||||
|
||||
if (HasBit(roadtypes, ROADTYPE_TRAM)) {
|
||||
Axis axis = GetRoadStopDir(ti->tile) == DIAGDIR_NE ? AXIS_X : AXIS_Y;
|
||||
|
@ -2318,6 +2298,11 @@ static void DrawTile_Station(TileInfo *ti)
|
|||
DrawTramCatenary(ti, axis == AXIS_X ? ROAD_X : ROAD_Y);
|
||||
}
|
||||
|
||||
if (IsRailWaypoint(ti->tile)) {
|
||||
/* Don't offset the waypoint graphics; they're always the same. */
|
||||
total_offset = 0;
|
||||
}
|
||||
|
||||
const DrawTileSeqStruct *dtss;
|
||||
foreach_draw_tile_seq(dtss, t->seq) {
|
||||
SpriteID image = dtss->image.sprite;
|
||||
|
@ -2408,7 +2393,7 @@ static void GetTileDesc_Station(TileIndex tile, TileDesc *td)
|
|||
}
|
||||
}
|
||||
}
|
||||
td->build_date = Station::GetByTile(tile)->build_date;
|
||||
td->build_date = BaseStation::GetByTile(tile)->build_date;
|
||||
|
||||
const StationSpec *spec = GetStationSpec(tile);
|
||||
|
||||
|
@ -2425,15 +2410,16 @@ static void GetTileDesc_Station(TileIndex tile, TileDesc *td)
|
|||
StringID str;
|
||||
switch (GetStationType(tile)) {
|
||||
default: NOT_REACHED();
|
||||
case STATION_RAIL: str = STR_STATION_DESCRIPTION_RAILROAD_STATION; break;
|
||||
case STATION_RAIL: str = STR_STATION_DESCRIPTION_RAILROAD_STATION; break;
|
||||
case STATION_AIRPORT:
|
||||
str = (IsHangar(tile) ? STR_STATION_DESCRIPTION_AIRCRAFT_HANGAR : STR_STATION_DESCRIPTION_AIRPORT);
|
||||
break;
|
||||
case STATION_TRUCK: str = STR_STATION_DESCRIPTION_TRUCK_LOADING_AREA; break;
|
||||
case STATION_BUS: str = STR_STATION_DESCRIPTION_BUS_STATION; break;
|
||||
case STATION_OILRIG: str = STR_INDUSTRY_NAME_OIL_RIG; break;
|
||||
case STATION_DOCK: str = STR_STATION_DESCRIPTION_SHIP_DOCK; break;
|
||||
case STATION_BUOY: str = STR_STATION_DESCRIPTION_BUOY; break;
|
||||
case STATION_TRUCK: str = STR_STATION_DESCRIPTION_TRUCK_LOADING_AREA; break;
|
||||
case STATION_BUS: str = STR_STATION_DESCRIPTION_BUS_STATION; break;
|
||||
case STATION_OILRIG: str = STR_INDUSTRY_NAME_OIL_RIG; break;
|
||||
case STATION_DOCK: str = STR_STATION_DESCRIPTION_SHIP_DOCK; break;
|
||||
case STATION_BUOY: str = STR_STATION_DESCRIPTION_BUOY; break;
|
||||
case STATION_WAYPOINT: str = STR_LANDINFO_WAYPOINT; break;
|
||||
}
|
||||
td->str = str;
|
||||
}
|
||||
|
@ -2445,7 +2431,7 @@ static TrackStatus GetTileTrackStatus_Station(TileIndex tile, TransportType mode
|
|||
|
||||
switch (mode) {
|
||||
case TRANSPORT_RAIL:
|
||||
if (IsRailwayStation(tile) && !IsStationTileBlocked(tile)) {
|
||||
if ((IsRailwayStation(tile) || IsRailWaypoint(tile)) && !IsStationTileBlocked(tile)) {
|
||||
trackbits = TrackToTrackBits(GetRailStationTrack(tile));
|
||||
}
|
||||
break;
|
||||
|
@ -2551,10 +2537,14 @@ static void AnimateTile_Station(TileIndex tile)
|
|||
|
||||
static bool ClickTile_Station(TileIndex tile)
|
||||
{
|
||||
if (IsHangar(tile)) {
|
||||
const BaseStation *st = BaseStation::GetByTile(tile);
|
||||
|
||||
if (st->facilities & FACIL_WAYPOINT) {
|
||||
ShowWaypointWindow(Waypoint::From(st));
|
||||
} else if (IsHangar(tile)) {
|
||||
ShowDepotWindow(tile, VEH_AIRCRAFT);
|
||||
} else {
|
||||
ShowStationViewWindow(GetStationIndex(tile));
|
||||
ShowStationViewWindow(st->index);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -2650,15 +2640,15 @@ static VehicleEnterTileStatus VehicleEnter_Station(Vehicle *v, TileIndex tile, i
|
|||
* @param st the station receiving the tick.
|
||||
* @return true if the station is still valid (wasn't deleted)
|
||||
*/
|
||||
static bool StationHandleBigTick(Station *st)
|
||||
static bool StationHandleBigTick(BaseStation *st)
|
||||
{
|
||||
UpdateStationAcceptance(st, true);
|
||||
|
||||
if (st->facilities == 0 && ++st->delete_ctr >= 8) {
|
||||
if ((st->facilities & ~FACIL_WAYPOINT) == 0 && ++st->delete_ctr >= 8) {
|
||||
delete st;
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((st->facilities & FACIL_WAYPOINT) == 0) UpdateStationAcceptance(Station::From(st), true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2778,23 +2768,23 @@ static void UpdateStationRating(Station *st)
|
|||
}
|
||||
|
||||
/* called for every station each tick */
|
||||
static void StationHandleSmallTick(Station *st)
|
||||
static void StationHandleSmallTick(BaseStation *st)
|
||||
{
|
||||
if (st->facilities == 0) return;
|
||||
if ((st->facilities & FACIL_WAYPOINT) != 0 || st->facilities == 0) return;
|
||||
|
||||
byte b = st->delete_ctr + 1;
|
||||
if (b >= 185) b = 0;
|
||||
st->delete_ctr = b;
|
||||
|
||||
if (b == 0) UpdateStationRating(st);
|
||||
if (b == 0) UpdateStationRating(Station::From(st));
|
||||
}
|
||||
|
||||
void OnTick_Station()
|
||||
{
|
||||
if (_game_mode == GM_EDITOR) return;
|
||||
|
||||
Station *st;
|
||||
FOR_ALL_STATIONS(st) {
|
||||
BaseStation *st;
|
||||
FOR_ALL_BASE_STATIONS(st) {
|
||||
StationHandleSmallTick(st);
|
||||
|
||||
/* Run 250 tick interval trigger for station animation.
|
||||
|
@ -2884,7 +2874,7 @@ CommandCost CmdRenameStation(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
|
|||
}
|
||||
|
||||
/**
|
||||
* Find all (non-buoy) stations around a rectangular producer (industry, house, headquarter, ...)
|
||||
* Find all stations around a rectangular producer (industry, house, headquarter, ...)
|
||||
*
|
||||
* @param tile North tile of producer
|
||||
* @param w_prod X extent of producer
|
||||
|
@ -2903,8 +2893,7 @@ void FindStationsAroundTiles(TileIndex tile, int w_prod, int h_prod, StationList
|
|||
if (cur_tile == INVALID_TILE || !IsTileType(cur_tile, MP_STATION)) continue;
|
||||
|
||||
Station *st = Station::GetByTile(cur_tile);
|
||||
|
||||
if (st->IsBuoy()) continue; // bouys don't accept cargo
|
||||
if (st == NULL) continue;
|
||||
|
||||
if (_settings_game.station.modified_catchment) {
|
||||
int rad = st->GetCatchmentRadius();
|
||||
|
@ -3120,12 +3109,13 @@ static CommandCost ClearTile_Station(TileIndex tile, DoCommandFlag flags)
|
|||
if (flags & DC_AUTO) {
|
||||
switch (GetStationType(tile)) {
|
||||
default: break;
|
||||
case STATION_RAIL: return_cmd_error(STR_ERROR_MUST_DEMOLISH_RAILROAD);
|
||||
case STATION_AIRPORT: return_cmd_error(STR_ERROR_MUST_DEMOLISH_AIRPORT_FIRST);
|
||||
case STATION_TRUCK: return_cmd_error(HasTileRoadType(tile, ROADTYPE_TRAM) ? STR_ERROR_MUST_DEMOLISH_CARGO_TRAM_STATION_FIRST : STR_ERROR_MUST_DEMOLISH_TRUCK_STATION_FIRST);
|
||||
case STATION_BUS: return_cmd_error(HasTileRoadType(tile, ROADTYPE_TRAM) ? STR_ERROR_MUST_DEMOLISH_PASSENGER_TRAM_STATION_FIRST : STR_ERROR_MUST_DEMOLISH_BUS_STATION_FIRST);
|
||||
case STATION_BUOY: return_cmd_error(STR_ERROR_BUOY_IN_THE_WAY);
|
||||
case STATION_DOCK: return_cmd_error(STR_ERROR_MUST_DEMOLISH_DOCK_FIRST);
|
||||
case STATION_RAIL: return_cmd_error(STR_ERROR_MUST_DEMOLISH_RAILROAD);
|
||||
case STATION_WAYPOINT: return_cmd_error(STR_ERROR_BUILDING_MUST_BE_DEMOLISHED);
|
||||
case STATION_AIRPORT: return_cmd_error(STR_ERROR_MUST_DEMOLISH_AIRPORT_FIRST);
|
||||
case STATION_TRUCK: return_cmd_error(HasTileRoadType(tile, ROADTYPE_TRAM) ? STR_ERROR_MUST_DEMOLISH_CARGO_TRAM_STATION_FIRST : STR_ERROR_MUST_DEMOLISH_TRUCK_STATION_FIRST);
|
||||
case STATION_BUS: return_cmd_error(HasTileRoadType(tile, ROADTYPE_TRAM) ? STR_ERROR_MUST_DEMOLISH_PASSENGER_TRAM_STATION_FIRST : STR_ERROR_MUST_DEMOLISH_BUS_STATION_FIRST);
|
||||
case STATION_BUOY: return_cmd_error(STR_ERROR_BUOY_IN_THE_WAY);
|
||||
case STATION_DOCK: return_cmd_error(STR_ERROR_MUST_DEMOLISH_DOCK_FIRST);
|
||||
case STATION_OILRIG:
|
||||
SetDParam(0, STR_INDUSTRY_NAME_OIL_RIG);
|
||||
return_cmd_error(STR_OBJECT_IN_THE_WAY);
|
||||
|
@ -3133,8 +3123,9 @@ static CommandCost ClearTile_Station(TileIndex tile, DoCommandFlag flags)
|
|||
}
|
||||
|
||||
switch (GetStationType(tile)) {
|
||||
case STATION_RAIL: return RemoveRailroadStation(tile, flags);
|
||||
case STATION_AIRPORT: return RemoveAirport(tile, flags);
|
||||
case STATION_RAIL: return RemoveRailroadStation(tile, flags);
|
||||
case STATION_WAYPOINT: return RemoveTrainWaypoint(tile, flags, false);
|
||||
case STATION_AIRPORT: return RemoveAirport(tile, flags);
|
||||
case STATION_TRUCK:
|
||||
if (IsDriveThroughStopTile(tile) && !CanRemoveRoadWithStop(tile, flags))
|
||||
return_cmd_error(STR_ERROR_MUST_DEMOLISH_TRUCK_STATION_FIRST);
|
||||
|
@ -3143,8 +3134,8 @@ static CommandCost ClearTile_Station(TileIndex tile, DoCommandFlag flags)
|
|||
if (IsDriveThroughStopTile(tile) && !CanRemoveRoadWithStop(tile, flags))
|
||||
return_cmd_error(STR_ERROR_MUST_DEMOLISH_BUS_STATION_FIRST);
|
||||
return RemoveRoadStop(tile, flags);
|
||||
case STATION_BUOY: return RemoveBuoy(tile, flags);
|
||||
case STATION_DOCK: return RemoveDock(tile, flags);
|
||||
case STATION_BUOY: return RemoveBuoy(tile, flags);
|
||||
case STATION_DOCK: return RemoveDock(tile, flags);
|
||||
default: break;
|
||||
}
|
||||
|
||||
|
@ -3159,6 +3150,7 @@ static CommandCost TerraformTile_Station(TileIndex tile, DoCommandFlag flags, ui
|
|||
*/
|
||||
if (!IsSteepSlope(tileh_new) && (GetTileMaxZ(tile) == z_new + GetSlopeMaxZ(tileh_new))) {
|
||||
switch (GetStationType(tile)) {
|
||||
case STATION_WAYPOINT:
|
||||
case STATION_RAIL: {
|
||||
DiagDirection direction = AxisToDiagDir(GetRailStationAxis(tile));
|
||||
if (!AutoslopeCheckForEntranceEdge(tile, z_new, tileh_new, direction)) break;
|
||||
|
|
|
@ -143,7 +143,7 @@ protected:
|
|||
|
||||
const Station *st;
|
||||
FOR_ALL_STATIONS(st) {
|
||||
if (st->owner == owner || (st->owner == OWNER_NONE && !st->IsBuoy() && HasStationInUse(st->index, owner))) {
|
||||
if (st->owner == owner || (st->owner == OWNER_NONE && HasStationInUse(st->index, owner))) {
|
||||
if (this->facilities & st->facilities) { // only stations with selected facilities
|
||||
int num_waiting_cargo = 0;
|
||||
for (CargoID j = 0; j < NUM_CARGO; j++) {
|
||||
|
@ -378,7 +378,7 @@ public:
|
|||
|
||||
/* Do not do the complex check HasStationInUse here, it may be even false
|
||||
* when the order had been removed and the station list hasn't been removed yet */
|
||||
assert(st->owner == owner || (st->owner == OWNER_NONE && !st->IsBuoy()));
|
||||
assert(st->owner == owner || st->owner == OWNER_NONE);
|
||||
|
||||
SetDParam(0, st->index);
|
||||
SetDParam(1, st->facilities);
|
||||
|
@ -409,7 +409,7 @@ public:
|
|||
|
||||
const Station *st = this->stations[id_v];
|
||||
/* do not check HasStationInUse - it is slow and may be invalid */
|
||||
assert(st->owner == (Owner)this->window_number || (st->owner == OWNER_NONE && !st->IsBuoy()));
|
||||
assert(st->owner == (Owner)this->window_number || st->owner == OWNER_NONE);
|
||||
|
||||
if (_ctrl_pressed) {
|
||||
ShowExtraViewPortWindow(st->xy);
|
||||
|
|
|
@ -88,6 +88,28 @@ static inline bool IsRailwayStationTile(TileIndex t)
|
|||
return IsTileType(t, MP_STATION) && IsRailwayStation(t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this station tile a rail waypoint?
|
||||
* @param t the tile to get the information from
|
||||
* @pre IsTileType(t, MP_STATION)
|
||||
* @return true if and only if the tile is a rail waypoint
|
||||
*/
|
||||
static inline bool IsRailWaypoint(TileIndex t)
|
||||
{
|
||||
return GetStationType(t) == STATION_WAYPOINT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this tile a station tile and a rail waypoint?
|
||||
* @param t the tile to get the information from
|
||||
* @return true if and only if the tile is a rail waypoint
|
||||
*/
|
||||
static inline bool IsRailWaypointTile(TileIndex t)
|
||||
{
|
||||
return IsTileType(t, MP_STATION) && IsRailWaypoint(t);
|
||||
}
|
||||
|
||||
|
||||
static inline bool IsAirport(TileIndex t)
|
||||
{
|
||||
return GetStationType(t) == STATION_AIRPORT;
|
||||
|
@ -186,7 +208,7 @@ static inline bool IsHangarTile(TileIndex t)
|
|||
|
||||
static inline Axis GetRailStationAxis(TileIndex t)
|
||||
{
|
||||
assert(IsRailwayStation(t));
|
||||
assert(IsRailwayStation(t) || IsRailWaypoint(t));
|
||||
return HasBit(GetStationGfx(t), 0) ? AXIS_Y : AXIS_X;
|
||||
}
|
||||
|
||||
|
@ -214,31 +236,31 @@ static inline bool IsCompatibleTrainStationTile(TileIndex t1, TileIndex t2)
|
|||
|
||||
/**
|
||||
* Get the reservation state of the rail station
|
||||
* @pre IsRailwayStationTile(t)
|
||||
* @pre IsRailwayStation(t) || IsRailWaypoint(t)
|
||||
* @param t the station tile
|
||||
* @return reservation state
|
||||
*/
|
||||
static inline bool HasStationReservation(TileIndex t)
|
||||
{
|
||||
assert(IsRailwayStationTile(t));
|
||||
assert(IsRailwayStation(t) || IsRailWaypoint(t));
|
||||
return HasBit(_m[t].m6, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the reservation state of the rail station
|
||||
* @pre IsRailwayStationTile(t)
|
||||
* @pre IsRailwayStation(t) || IsRailWaypoint(t)
|
||||
* @param t the station tile
|
||||
* @param b the reservation state
|
||||
*/
|
||||
static inline void SetRailwayStationReservation(TileIndex t, bool b)
|
||||
{
|
||||
assert(IsRailwayStationTile(t));
|
||||
assert(IsRailwayStation(t) || IsRailWaypoint(t));
|
||||
SB(_m[t].m6, 2, 1, b ? 1 : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the reserved track bits for a waypoint
|
||||
* @pre IsRailwayStationTile(t)
|
||||
* @pre IsRailwayStation(t) || IsRailWaypoint(t)
|
||||
* @param t the tile
|
||||
* @return reserved track bits
|
||||
*/
|
||||
|
@ -325,6 +347,13 @@ static inline void MakeRailStation(TileIndex t, Owner o, StationID sid, Axis a,
|
|||
SetRailwayStationReservation(t, false);
|
||||
}
|
||||
|
||||
static inline void MakeRailWaypoint(TileIndex t, Owner o, StationID sid, Axis a, byte section, RailType rt)
|
||||
{
|
||||
MakeStation(t, o, sid, STATION_WAYPOINT, section + a);
|
||||
SetRailType(t, rt);
|
||||
SetRailwayStationReservation(t, false);
|
||||
}
|
||||
|
||||
static inline void MakeRoadStop(TileIndex t, Owner o, StationID sid, RoadStopType rst, RoadTypes rt, DiagDirection d)
|
||||
{
|
||||
MakeStation(t, o, sid, (rst == ROADSTOP_BUS ? STATION_BUS : STATION_TRUCK), d);
|
||||
|
|
|
@ -57,9 +57,8 @@ enum StationHadVehicleOfType {
|
|||
HVOT_TRUCK = 1 << 3, ///< Station has seen a truck
|
||||
HVOT_AIRCRAFT = 1 << 4, ///< Station has seen an aircraft
|
||||
HVOT_SHIP = 1 << 5, ///< Station has seen a ship
|
||||
/* This bit is used to mark stations. No, it does not belong here, but what
|
||||
* can we do? ;-) */
|
||||
HVOT_BUOY = 1 << 6
|
||||
|
||||
HVOT_WAYPOINT = 1 << 6, ///< Station is a waypoint (NewGRF only!)
|
||||
};
|
||||
DECLARE_ENUM_AS_BIT_SET(StationHadVehicleOfType);
|
||||
typedef SimpleTinyEnumT<StationHadVehicleOfType, byte> StationHadVehicleOfTypeByte;
|
||||
|
|
|
@ -863,8 +863,8 @@ static char *FormatString(char *buff, const char *str, int64 *argv, uint casei,
|
|||
int64 temp[2];
|
||||
temp[0] = wp->town->index;
|
||||
temp[1] = wp->town_cn + 1;
|
||||
StringID str = wp->town_cn == 0 ? STR_WAYPOINTNAME_CITY : STR_WAYPOINTNAME_CITY_SERIAL;
|
||||
|
||||
StringID str = ((wp->string_id == STR_SV_STNAME_BUOY) ? STR_BUOYNAME_CITY : STR_WAYPOINTNAME_CITY);
|
||||
if (wp->town_cn != 0) str++;
|
||||
buff = GetStringWithArgs(buff, str, temp, last);
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -635,10 +635,10 @@ static void ResetLandscapeConfirmationCallback(Window *w, bool confirmed)
|
|||
_generating_world = false;
|
||||
|
||||
/* Delete all station signs */
|
||||
Station *st;
|
||||
FOR_ALL_STATIONS(st) {
|
||||
BaseStation *st;
|
||||
FOR_ALL_BASE_STATIONS(st) {
|
||||
/* There can be buoys, remove them */
|
||||
if (st->IsBuoy() && IsBuoyTile(st->xy)) DoCommand(st->xy, 0, 0, DC_EXEC | DC_BANKRUPT, CMD_LANDSCAPE_CLEAR);
|
||||
if (IsBuoyTile(st->xy)) DoCommand(st->xy, 0, 0, DC_EXEC | DC_BANKRUPT, CMD_LANDSCAPE_CLEAR);
|
||||
if (st->facilities == 0) delete st;
|
||||
}
|
||||
|
||||
|
|
|
@ -482,7 +482,7 @@ static int GetTrainAcceleration(Train *v, bool mode)
|
|||
assert(max_speed == GetTrainCurveSpeedLimit(v)); // safety check, will be removed later
|
||||
int speed = v->cur_speed * 10 / 16; // km-ish/h -> mp/h
|
||||
|
||||
if (IsTileType(v->tile, MP_STATION) && v->IsFrontEngine()) {
|
||||
if (IsRailwayStationTile(v->tile) && v->IsFrontEngine()) {
|
||||
StationID sid = GetStationIndex(v->tile);
|
||||
if (v->current_order.ShouldStopAtStation(v, sid)) {
|
||||
int station_ahead;
|
||||
|
@ -4443,12 +4443,10 @@ static bool TrainLocoHandler(Train *v, bool mode)
|
|||
|
||||
OrderType order_type = v->current_order.GetType();
|
||||
/* Do not skip waypoints (incl. 'via' stations) when passing through at full speed. */
|
||||
if ((order_type == OT_GOTO_WAYPOINT &&
|
||||
v->dest_tile == v->tile) ||
|
||||
(order_type == OT_GOTO_STATION &&
|
||||
if ((order_type == OT_GOTO_WAYPOINT || order_type == OT_GOTO_STATION) &&
|
||||
(v->current_order.GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION) &&
|
||||
IsTileType(v->tile, MP_STATION) &&
|
||||
v->current_order.GetDestination() == GetStationIndex(v->tile))) {
|
||||
v->current_order.GetDestination() == GetStationIndex(v->tile)) {
|
||||
ProcessOrders(v);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -788,8 +788,6 @@ static void DrawSmallOrderList(const Vehicle *v, int left, int right, int y)
|
|||
sel--;
|
||||
|
||||
if (order->IsType(OT_GOTO_STATION)) {
|
||||
if (v->type == VEH_SHIP && Station::Get(order->GetDestination())->IsBuoy()) continue;
|
||||
|
||||
SetDParam(0, order->GetDestination());
|
||||
DrawString(left, right, y, STR_ORDER_STATION_SMALL);
|
||||
|
||||
|
@ -1950,7 +1948,7 @@ struct VehicleViewWindow : Window {
|
|||
case OT_GOTO_WAYPOINT: {
|
||||
assert(v->type == VEH_TRAIN || v->type == VEH_SHIP);
|
||||
SetDParam(0, v->current_order.GetDestination());
|
||||
str = (v->type == VEH_TRAIN ? STR_HEADING_FOR_WAYPOINT : STR_HEADING_FOR_STATION) + _settings_client.gui.vehicle_speed;
|
||||
str = STR_HEADING_FOR_WAYPOINT + _settings_client.gui.vehicle_speed;
|
||||
SetDParam(1, v->GetDisplaySpeed());
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1218,7 +1218,7 @@ static void ViewportAddSigns(DrawPixelInfo *dpi)
|
|||
|
||||
static void AddWaypoint(const Waypoint *wp, StringID str, uint16 width)
|
||||
{
|
||||
AddStringToDraw(wp->sign.left + 1, wp->sign.top + 1, str, wp->index, 0, (wp->delete_ctr != 0 ? 0xE : _company_colours[wp->owner]), width);
|
||||
AddStringToDraw(wp->sign.left + 1, wp->sign.top + 1, str, wp->index, 0, (wp->owner == OWNER_NONE || (wp->facilities & ~FACIL_WAYPOINT) == 0) ? 0xE : _company_colours[wp->owner], width);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -12,23 +12,6 @@
|
|||
#include "window_func.h"
|
||||
#include "newgrf_station.h"
|
||||
#include "order_func.h"
|
||||
#include "core/pool_func.hpp"
|
||||
|
||||
WaypointPool _waypoint_pool("Waypoint");
|
||||
INSTANTIATE_POOL_METHODS(Waypoint)
|
||||
|
||||
/**
|
||||
* Daily loop for waypoints
|
||||
*/
|
||||
void WaypointsDailyLoop()
|
||||
{
|
||||
Waypoint *wp;
|
||||
|
||||
/* Check if we need to delete a waypoint */
|
||||
FOR_ALL_WAYPOINTS(wp) {
|
||||
if (wp->delete_ctr != 0 && --wp->delete_ctr == 0) delete wp;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw a waypoint
|
||||
|
@ -67,8 +50,3 @@ Waypoint::~Waypoint()
|
|||
|
||||
this->sign.MarkDirty();
|
||||
}
|
||||
|
||||
void InitializeWaypoints()
|
||||
{
|
||||
_waypoint_pool.CleanPool();
|
||||
}
|
||||
|
|
|
@ -14,10 +14,7 @@
|
|||
#include "date_type.h"
|
||||
#include "core/pool_type.hpp"
|
||||
|
||||
typedef Pool<Waypoint, WaypointID, 32, 64000> WaypointPool;
|
||||
extern WaypointPool _waypoint_pool;
|
||||
|
||||
struct Waypoint : WaypointPool::PoolItem<&_waypoint_pool>, SpecializedStation<Waypoint, true> {
|
||||
struct Waypoint : SpecializedStation<Waypoint, true> {
|
||||
uint16 town_cn; ///< The Nth waypoint for this town (consecutive number)
|
||||
|
||||
Waypoint(TileIndex tile = INVALID_TILE) : SpecializedStation<Waypoint, true>(tile) { }
|
||||
|
@ -27,29 +24,19 @@ struct Waypoint : WaypointPool::PoolItem<&_waypoint_pool>, SpecializedStation<Wa
|
|||
|
||||
/* virtual */ FORCEINLINE bool TileBelongsToRailStation(TileIndex tile) const
|
||||
{
|
||||
return this->delete_ctr == 0 && this->xy == tile;
|
||||
return IsRailWaypointTile(tile) && GetStationIndex(tile) == this->index;
|
||||
}
|
||||
|
||||
/* virtual */ uint32 GetNewGRFVariable(const struct ResolverObject *object, byte variable, byte parameter, bool *available) const;
|
||||
|
||||
/* virtual */ void GetTileArea(TileArea *ta, StationType type) const;
|
||||
|
||||
/**
|
||||
* Fetch a waypoint by tile
|
||||
* @param tile Tile of waypoint
|
||||
* @return Waypoint
|
||||
*/
|
||||
static FORCEINLINE Waypoint *GetByTile(TileIndex tile)
|
||||
{
|
||||
return Waypoint::Get(GetWaypointIndex(tile));
|
||||
}
|
||||
};
|
||||
|
||||
#define FOR_ALL_WAYPOINTS_FROM(var, start) FOR_ALL_ITEMS_FROM(Waypoint, waypoint_index, var, start)
|
||||
#define FOR_ALL_WAYPOINTS(var) FOR_ALL_WAYPOINTS_FROM(var, 0)
|
||||
#define FOR_ALL_WAYPOINTS(var) FOR_ALL_BASE_STATIONS_OF_TYPE(Waypoint, var)
|
||||
|
||||
CommandCost RemoveTrainWaypoint(TileIndex tile, DoCommandFlag flags, bool justremove);
|
||||
void ShowWaypointWindow(const Waypoint *wp);
|
||||
void DrawWaypointSprite(int x, int y, int stat_id, RailType railtype);
|
||||
void MakeDefaultWaypointName(Waypoint *wp);
|
||||
|
||||
#endif /* WAYPOINT_H */
|
||||
|
|
|
@ -39,7 +39,7 @@ void Waypoint::UpdateVirtCoord()
|
|||
* Set the default name for a waypoint
|
||||
* @param wp Waypoint to work on
|
||||
*/
|
||||
static void MakeDefaultWaypointName(Waypoint *wp)
|
||||
void MakeDefaultWaypointName(Waypoint *wp)
|
||||
{
|
||||
uint32 used = 0; // bitmap of used waypoint numbers, sliding window with 'next' as base
|
||||
uint32 next = 0; // first waypoint number in the bitmap
|
||||
|
@ -64,7 +64,7 @@ static void MakeDefaultWaypointName(Waypoint *wp)
|
|||
/* check only valid waypoints... */
|
||||
if (lwp != NULL && wp != lwp) {
|
||||
/* only waypoints with 'generic' name within the same city */
|
||||
if (lwp->name == NULL && lwp->town == wp->town) {
|
||||
if (lwp->name == NULL && lwp->town == wp->town && lwp->string_id == wp->string_id) {
|
||||
/* if lwp->town_cn < next, uint will overflow to '+inf' */
|
||||
uint i = (uint)lwp->town_cn - next;
|
||||
|
||||
|
@ -104,7 +104,7 @@ static Waypoint *FindDeletedWaypointCloseTo(TileIndex tile)
|
|||
uint thres = 8;
|
||||
|
||||
FOR_ALL_WAYPOINTS(wp) {
|
||||
if (wp->delete_ctr != 0 && wp->owner == _current_company) {
|
||||
if ((wp->facilities & ~FACIL_WAYPOINT) == 0 && wp->owner == _current_company) {
|
||||
uint cur_dist = DistanceManhattan(tile, wp->xy);
|
||||
|
||||
if (cur_dist < thres) {
|
||||
|
@ -163,10 +163,6 @@ CommandCost CmdBuildTrainWaypoint(TileIndex tile, DoCommandFlag flags, uint32 p1
|
|||
if (flags & DC_EXEC) {
|
||||
if (wp == NULL) {
|
||||
wp = new Waypoint(tile);
|
||||
|
||||
wp->town = NULL;
|
||||
wp->name = NULL;
|
||||
wp->town_cn = 0;
|
||||
} else {
|
||||
/* Move existing (recently deleted) waypoint to the new location */
|
||||
|
||||
|
@ -186,15 +182,16 @@ CommandCost CmdBuildTrainWaypoint(TileIndex tile, DoCommandFlag flags, uint32 p1
|
|||
wp->owner = owner;
|
||||
|
||||
bool reserved = HasBit(GetRailReservationTrackBits(tile), AxisToTrack(axis));
|
||||
MakeRailWaypoint(tile, owner, axis, GetRailType(tile), wp->index);
|
||||
SetDepotReservation(tile, reserved);
|
||||
MakeRailWaypoint(tile, owner, wp->index, axis, 0, GetRailType(tile));
|
||||
SetRailwayStationReservation(tile, reserved);
|
||||
MarkTileDirtyByTile(tile);
|
||||
|
||||
AllocateSpecToStation(GetCustomStationSpec(STAT_CLASS_WAYP, p1), wp, true);
|
||||
SetCustomStationSpecIndex(tile, AllocateSpecToStation(GetCustomStationSpec(STAT_CLASS_WAYP, p1), wp, true));
|
||||
|
||||
wp->delete_ctr = 0;
|
||||
wp->facilities |= FACIL_TRAIN;
|
||||
wp->build_date = _date;
|
||||
wp->string_id = STR_SV_STNAME_WAYPOINT;
|
||||
|
||||
if (wp->town == NULL) MakeDefaultWaypointName(wp);
|
||||
|
||||
|
@ -224,22 +221,22 @@ CommandCost RemoveTrainWaypoint(TileIndex tile, DoCommandFlag flags, bool justre
|
|||
}
|
||||
|
||||
if (flags & DC_EXEC) {
|
||||
Track track = GetRailWaypointTrack(tile);
|
||||
Track track = GetRailStationTrack(tile);
|
||||
wp = Waypoint::GetByTile(tile);
|
||||
|
||||
wp->delete_ctr = 30; // let it live for this many days before we do the actual deletion.
|
||||
wp->sign.MarkDirty();
|
||||
wp->facilities &= ~FACIL_TRAIN;
|
||||
|
||||
Train *v = NULL;
|
||||
uint specindex = GetCustomStationSpecIndex(tile);
|
||||
if (justremove) {
|
||||
TrackBits tracks = GetRailWaypointBits(tile);
|
||||
bool reserved = HasDepotReservation(tile);
|
||||
TrackBits tracks = GetRailStationTrackBits(tile);
|
||||
bool reserved = HasStationReservation(tile);
|
||||
MakeRailNormal(tile, wp->owner, tracks, GetRailType(tile));
|
||||
if (reserved) SetTrackReservation(tile, tracks);
|
||||
MarkTileDirtyByTile(tile);
|
||||
} else {
|
||||
if (HasDepotReservation(tile)) {
|
||||
if (HasStationReservation(tile)) {
|
||||
v = GetTrainForReservation(tile, track);
|
||||
if (v != NULL) FreeTrainTrackReservation(v);
|
||||
}
|
||||
|
@ -249,7 +246,7 @@ CommandCost RemoveTrainWaypoint(TileIndex tile, DoCommandFlag flags, bool justre
|
|||
YapfNotifyTrackLayoutChange(tile, track);
|
||||
if (v != NULL) TryPathReserve(v, true);
|
||||
|
||||
DeallocateSpecFromStation(wp, wp->num_specs > 0 ? 1 : 0);
|
||||
DeallocateSpecFromStation(wp, specindex);
|
||||
}
|
||||
|
||||
return CommandCost(EXPENSES_CONSTRUCTION, _price.remove_train_depot);
|
||||
|
@ -290,7 +287,7 @@ static bool IsUniqueWaypointName(const char *name)
|
|||
CommandCost CmdRenameWaypoint(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
||||
{
|
||||
Waypoint *wp = Waypoint::GetIfValid(p1);
|
||||
if (wp == NULL || !CheckOwnership(wp->owner)) return CMD_ERROR;
|
||||
if (wp == NULL || !(CheckOwnership(wp->owner) || wp->owner == OWNER_NONE)) return CMD_ERROR;
|
||||
|
||||
bool reset = StrEmpty(text);
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ public:
|
|||
WaypointWindow(const WindowDesc *desc, WindowNumber window_number) : Window(desc, window_number)
|
||||
{
|
||||
this->wp = Waypoint::Get(this->window_number);
|
||||
this->vt = (wp->facilities & FACIL_TRAIN) ? VEH_TRAIN : VEH_SHIP;
|
||||
this->vt = (wp->string_id == STR_SV_STNAME_WAYPOINT) ? VEH_TRAIN : VEH_SHIP;
|
||||
|
||||
if (this->wp->owner != OWNER_NONE) this->owner = this->wp->owner;
|
||||
|
||||
|
|
|
@ -406,7 +406,7 @@ no_entry_cost: // jump here at the beginning if the node has no parent (it is th
|
|||
/* We will end in this pass (station is possible target) */
|
||||
end_segment_reason |= ESRB_STATION;
|
||||
|
||||
} else if (cur.tile_type == MP_RAILWAY && IsRailWaypoint(cur.tile)) {
|
||||
} else if (cur.tile_type == MP_STATION && IsRailWaypoint(cur.tile)) {
|
||||
/* Waypoint is also a good reason to finish. */
|
||||
end_segment_reason |= ESRB_WAYPOINT;
|
||||
} else if (TrackFollower::DoTrackMasking() && cur.tile_type == MP_RAILWAY) {
|
||||
|
|
|
@ -134,22 +134,11 @@ public:
|
|||
m_destTrackdirs = INVALID_TRACKDIR_BIT;
|
||||
break;
|
||||
|
||||
case OT_GOTO_WAYPOINT: {
|
||||
Waypoint *wp = Waypoint::Get(v->current_order.GetDestination());
|
||||
if (wp == NULL) {
|
||||
/* Invalid waypoint in orders! */
|
||||
DEBUG(yapf, 0, "Invalid waypoint in orders == 0x%04X (train %d, company %d)", v->current_order.GetDestination(), v->unitnumber, (CompanyID)v->owner);
|
||||
break;
|
||||
}
|
||||
m_destTile = wp->xy;
|
||||
if (m_destTile != v->dest_tile) {
|
||||
/* Something is wrong with orders! */
|
||||
DEBUG(yapf, 0, "Invalid v->dest_tile == 0x%04X (train %d, company %d)", v->dest_tile, v->unitnumber, (CompanyID)v->owner);
|
||||
}
|
||||
case OT_GOTO_WAYPOINT:
|
||||
m_destTile = Waypoint::Get(v->current_order.GetDestination())->xy;
|
||||
m_dest_station_id = INVALID_STATION;
|
||||
m_destTrackdirs = TrackToTrackdirBits(AxisToTrack(GetWaypointAxis(wp->xy)));
|
||||
m_destTrackdirs = IsRailWaypointTile(m_destTile) ? TrackToTrackdirBits(GetRailStationTrack(m_destTile)) : INVALID_TRACKDIR_BIT;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
m_destTile = v->dest_tile;
|
||||
|
|
Loading…
Reference in New Issue