1
0
Fork 0

(svn r16391) -Codechange: use Train instead of Vehicle where appropriate.

release/1.0
rubidium 2009-05-22 22:22:46 +00:00
parent 7a37220881
commit 80e94b9bb1
33 changed files with 429 additions and 387 deletions

View File

@ -29,7 +29,7 @@
int num = 1; int num = 1;
if (::Vehicle::Get(vehicle_id)->type == VEH_TRAIN) { if (::Vehicle::Get(vehicle_id)->type == VEH_TRAIN) {
const Vehicle *v = ::Vehicle::Get(vehicle_id); const Train *v = (Train *)::Vehicle::Get(vehicle_id);
while ((v = GetNextUnit(v)) != NULL) num++; while ((v = GetNextUnit(v)) != NULL) num++;
} }
@ -85,11 +85,11 @@
EnforcePrecondition(false, ::Vehicle::Get(source_vehicle_id)->type == VEH_TRAIN); EnforcePrecondition(false, ::Vehicle::Get(source_vehicle_id)->type == VEH_TRAIN);
EnforcePrecondition(false, dest_vehicle_id == -1 || ::Vehicle::Get(dest_vehicle_id)->type == VEH_TRAIN); EnforcePrecondition(false, dest_vehicle_id == -1 || ::Vehicle::Get(dest_vehicle_id)->type == VEH_TRAIN);
const Vehicle *v = ::Vehicle::Get(source_vehicle_id); const Train *v = (Train *)::Vehicle::Get(source_vehicle_id);
while (source_wagon-- > 0) v = GetNextUnit(v); while (source_wagon-- > 0) v = GetNextUnit(v);
const Vehicle *w = NULL; const Train *w = NULL;
if (dest_vehicle_id != -1) { if (dest_vehicle_id != -1) {
w = ::Vehicle::Get(dest_vehicle_id); w = (Train *)::Vehicle::Get(dest_vehicle_id);
while (dest_wagon-- > 0) w = GetNextUnit(w); while (dest_wagon-- > 0) w = GetNextUnit(w);
} }
@ -136,7 +136,7 @@
EnforcePrecondition(false, IsValidVehicle(vehicle_id) && wagon < GetNumWagons(vehicle_id)); EnforcePrecondition(false, IsValidVehicle(vehicle_id) && wagon < GetNumWagons(vehicle_id));
EnforcePrecondition(false, ::Vehicle::Get(vehicle_id)->type == VEH_TRAIN); EnforcePrecondition(false, ::Vehicle::Get(vehicle_id)->type == VEH_TRAIN);
const Vehicle *v = ::Vehicle::Get(vehicle_id); const Train *v = (Train *)::Vehicle::Get(vehicle_id);
while (wagon-- > 0) v = GetNextUnit(v); while (wagon-- > 0) v = GetNextUnit(v);
return AIObject::DoCommand(0, v->index, sell_attached_wagons ? 1 : 0, CMD_SELL_RAIL_WAGON); return AIObject::DoCommand(0, v->index, sell_attached_wagons ? 1 : 0, CMD_SELL_RAIL_WAGON);
@ -243,7 +243,7 @@
const Vehicle *v = ::Vehicle::Get(vehicle_id); const Vehicle *v = ::Vehicle::Get(vehicle_id);
if (v->type == VEH_TRAIN) { if (v->type == VEH_TRAIN) {
while (wagon-- > 0) v = GetNextUnit(v); while (wagon-- > 0) v = GetNextUnit((Train *)v);
} }
return v->engine_type; return v->engine_type;
} }
@ -281,7 +281,7 @@
const Vehicle *v = ::Vehicle::Get(vehicle_id); const Vehicle *v = ::Vehicle::Get(vehicle_id);
if (v->type == VEH_TRAIN) { if (v->type == VEH_TRAIN) {
while (wagon-- > 0) v = GetNextUnit(v); while (wagon-- > 0) v = GetNextUnit((Train *)v);
} }
return v->age; return v->age;
} }

View File

@ -208,7 +208,7 @@ bool IsArticulatedVehicleCarryingDifferentCargos(const Vehicle *v, CargoID *carg
switch (v->type) { switch (v->type) {
case VEH_TRAIN: case VEH_TRAIN:
v = (EngineHasArticPart(v) ? GetNextArticPart(v) : NULL); v = (EngineHasArticPart((Train *)v) ? GetNextArticPart((Train *)v) : NULL);
break; break;
case VEH_ROAD: case VEH_ROAD:
@ -256,7 +256,7 @@ void CheckConsistencyOfArticulatedVehicle(const Vehicle *v)
switch (v->type) { switch (v->type) {
case VEH_TRAIN: case VEH_TRAIN:
v = (EngineHasArticPart(v) ? GetNextArticPart(v) : NULL); v = (EngineHasArticPart((Train *)v) ? GetNextArticPart((Train *)v) : NULL);
break; break;
case VEH_ROAD: case VEH_ROAD:
@ -307,25 +307,27 @@ void AddArticulatedParts(Vehicle *first, VehicleType type)
switch (type) { switch (type) {
default: NOT_REACHED(); default: NOT_REACHED();
case VEH_TRAIN: case VEH_TRAIN: {
u = new Train(); Train *front = (Train *)v;
u->subtype = 0; Train *t = new Train();
previous->SetNext(u); t->subtype = 0;
u->u.rail.track = v->u.rail.track; previous->SetNext(t);
u->u.rail.railtype = v->u.rail.railtype; t->u.rail.track = front->u.rail.track;
u->u.rail.first_engine = v->engine_type; t->u.rail.railtype = front->u.rail.railtype;
t->u.rail.first_engine = front->engine_type;
u->spritenum = e_artic->u.rail.image_index; t->spritenum = e_artic->u.rail.image_index;
if (e_artic->CanCarryCargo()) { if (e_artic->CanCarryCargo()) {
u->cargo_type = e_artic->GetDefaultCargoType(); t->cargo_type = e_artic->GetDefaultCargoType();
u->cargo_cap = e_artic->u.rail.capacity; // Callback 36 is called when the consist is finished t->cargo_cap = e_artic->u.rail.capacity; // Callback 36 is called when the consist is finished
} else { } else {
u->cargo_type = v->cargo_type; // Needed for livery selection t->cargo_type = front->cargo_type; // Needed for livery selection
u->cargo_cap = 0; t->cargo_cap = 0;
} }
SetArticulatedPart(u); SetArticulatedPart(t);
break; u = t;
} break;
case VEH_ROAD: { case VEH_ROAD: {
RoadVehicle *front = (RoadVehicle *)v; RoadVehicle *front = (RoadVehicle *)v;

View File

@ -92,18 +92,18 @@ static void TransferCargo(Vehicle *old_veh, Vehicle *new_head, bool part_of_chai
assert(!part_of_chain || new_head->IsPrimaryVehicle()); assert(!part_of_chain || new_head->IsPrimaryVehicle());
/* Loop through source parts */ /* Loop through source parts */
for (Vehicle *src = old_veh; src != NULL; src = src->Next()) { for (Vehicle *src = old_veh; src != NULL; src = src->Next()) {
if (!part_of_chain && src->type == VEH_TRAIN && src != old_veh && src != old_veh->u.rail.other_multiheaded_part && !IsArticulatedPart(src)) { if (!part_of_chain && src->type == VEH_TRAIN && src != old_veh && src != ((Train *)old_veh)->u.rail.other_multiheaded_part && !IsArticulatedPart(src)) {
/* Skip vehicles, which do not belong to old_veh */ /* Skip vehicles, which do not belong to old_veh */
src = GetLastEnginePart(src); src = GetLastEnginePart((Train *)src);
continue; continue;
} }
if (src->cargo_type >= NUM_CARGO || src->cargo.Count() == 0) continue; if (src->cargo_type >= NUM_CARGO || src->cargo.Count() == 0) continue;
/* Find free space in the new chain */ /* Find free space in the new chain */
for (Vehicle *dest = new_head; dest != NULL && src->cargo.Count() > 0; dest = dest->Next()) { for (Vehicle *dest = new_head; dest != NULL && src->cargo.Count() > 0; dest = dest->Next()) {
if (!part_of_chain && dest->type == VEH_TRAIN && dest != new_head && dest != new_head->u.rail.other_multiheaded_part && !IsArticulatedPart(dest)) { if (!part_of_chain && dest->type == VEH_TRAIN && dest != new_head && dest != ((Train *)new_head)->u.rail.other_multiheaded_part && !IsArticulatedPart(dest)) {
/* Skip vehicles, which do not belong to new_head */ /* Skip vehicles, which do not belong to new_head */
dest = GetLastEnginePart(dest); dest = GetLastEnginePart((Train *)dest);
continue; continue;
} }
if (dest->cargo_type != src->cargo_type) continue; if (dest->cargo_type != src->cargo_type) continue;
@ -116,7 +116,7 @@ static void TransferCargo(Vehicle *old_veh, Vehicle *new_head, bool part_of_chai
} }
/* Update train weight etc., the old vehicle will be sold anyway */ /* Update train weight etc., the old vehicle will be sold anyway */
if (part_of_chain && new_head->type == VEH_TRAIN) TrainConsistChanged(new_head, true); if (part_of_chain && new_head->type == VEH_TRAIN) TrainConsistChanged((Train *)new_head, true);
} }
/** /**
@ -269,7 +269,7 @@ static CommandCost BuildReplacementVehicle(Vehicle *old_veh, Vehicle **new_vehic
} }
/* Try to reverse the vehicle, but do not care if it fails as the new type might not be reversible */ /* Try to reverse the vehicle, but do not care if it fails as the new type might not be reversible */
if (new_veh->type == VEH_TRAIN && HasBit(old_veh->u.rail.flags, VRF_REVERSE_DIRECTION)) { if (new_veh->type == VEH_TRAIN && HasBit(((Train *)old_veh)->u.rail.flags, VRF_REVERSE_DIRECTION)) {
DoCommand(0, new_veh->index, true, DC_EXEC, CMD_REVERSE_TRAIN_DIRECTION); DoCommand(0, new_veh->index, true, DC_EXEC, CMD_REVERSE_TRAIN_DIRECTION);
} }
@ -406,33 +406,33 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
uint16 old_total_length = (old_head->u.rail.cached_total_length + TILE_SIZE - 1) / TILE_SIZE * TILE_SIZE; uint16 old_total_length = (old_head->u.rail.cached_total_length + TILE_SIZE - 1) / TILE_SIZE * TILE_SIZE;
int num_units = 0; ///< Number of units in the chain int num_units = 0; ///< Number of units in the chain
for (Vehicle *w = old_head; w != NULL; w = GetNextUnit(w)) num_units++; for (Train *w = (Train *)old_head; w != NULL; w = GetNextUnit(w)) num_units++;
Vehicle **old_vehs = CallocT<Vehicle *>(num_units); ///< Will store vehicles of the old chain in their order Train **old_vehs = CallocT<Train *>(num_units); ///< Will store vehicles of the old chain in their order
Vehicle **new_vehs = CallocT<Vehicle *>(num_units); ///< New vehicles corresponding to old_vehs or NULL if no replacement Train **new_vehs = CallocT<Train *>(num_units); ///< New vehicles corresponding to old_vehs or NULL if no replacement
Money *new_costs = MallocT<Money>(num_units); ///< Costs for buying and refitting the new vehicles Money *new_costs = MallocT<Money>(num_units); ///< Costs for buying and refitting the new vehicles
/* Collect vehicles and build replacements /* Collect vehicles and build replacements
* Note: The replacement vehicles can only successfully build as long as the old vehicles are still in their chain */ * Note: The replacement vehicles can only successfully build as long as the old vehicles are still in their chain */
int i; int i;
Vehicle *w; Train *w;
for (w = old_head, i = 0; w != NULL; w = GetNextUnit(w), i++) { for (w = (Train *)old_head, i = 0; w != NULL; w = GetNextUnit(w), i++) {
assert(i < num_units); assert(i < num_units);
old_vehs[i] = w; old_vehs[i] = w;
CommandCost ret = BuildReplacementVehicle(old_vehs[i], &new_vehs[i], true); CommandCost ret = BuildReplacementVehicle(old_vehs[i], (Vehicle**)&new_vehs[i], true);
cost.AddCost(ret); cost.AddCost(ret);
if (cost.Failed()) break; if (cost.Failed()) break;
new_costs[i] = ret.GetCost(); new_costs[i] = ret.GetCost();
if (new_vehs[i] != NULL) *nothing_to_do = false; if (new_vehs[i] != NULL) *nothing_to_do = false;
} }
Vehicle *new_head = (new_vehs[0] != NULL ? new_vehs[0] : old_vehs[0]); Train *new_head = (new_vehs[0] != NULL ? new_vehs[0] : old_vehs[0]);
/* Note: When autoreplace has already failed here, old_vehs[] is not completely initialized. But it is also not needed. */ /* Note: When autoreplace has already failed here, old_vehs[] is not completely initialized. But it is also not needed. */
if (cost.Succeeded()) { if (cost.Succeeded()) {
/* Separate the head, so we can start constructing the new chain */ /* Separate the head, so we can start constructing the new chain */
Vehicle *second = GetNextUnit(old_head); Train *second = GetNextUnit((Train *)old_head);
if (second != NULL) cost.AddCost(MoveVehicle(second, NULL, DC_EXEC | DC_AUTOREPLACE, true)); if (second != NULL) cost.AddCost(MoveVehicle(second, NULL, DC_EXEC | DC_AUTOREPLACE, true));
assert(GetNextUnit(new_head) == NULL); assert(GetNextUnit(new_head) == NULL);
@ -440,10 +440,10 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
/* Append engines to the new chain /* Append engines to the new chain
* We do this from back to front, so that the head of the temporary vehicle chain does not change all the time. * We do this from back to front, so that the head of the temporary vehicle chain does not change all the time.
* OTOH the vehicle attach callback is more expensive this way :s */ * OTOH the vehicle attach callback is more expensive this way :s */
Vehicle *last_engine = NULL; ///< Shall store the last engine unit after this step Train *last_engine = NULL; ///< Shall store the last engine unit after this step
if (cost.Succeeded()) { if (cost.Succeeded()) {
for (int i = num_units - 1; i > 0; i--) { for (int i = num_units - 1; i > 0; i--) {
Vehicle *append = (new_vehs[i] != NULL ? new_vehs[i] : old_vehs[i]); Train *append = (new_vehs[i] != NULL ? new_vehs[i] : old_vehs[i]);
if (RailVehInfo(append->engine_type)->railveh_type == RAILVEH_WAGON) continue; if (RailVehInfo(append->engine_type)->railveh_type == RAILVEH_WAGON) continue;
@ -538,10 +538,10 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
* Note: The vehicle attach callback is disabled here :) */ * Note: The vehicle attach callback is disabled here :) */
if ((flags & DC_EXEC) == 0) { if ((flags & DC_EXEC) == 0) {
/* Separate the head, so we can reattach the old vehicles */ /* Separate the head, so we can reattach the old vehicles */
Vehicle *second = GetNextUnit(old_head); Train *second = GetNextUnit((Train *)old_head);
if (second != NULL) MoveVehicle(second, NULL, DC_EXEC | DC_AUTOREPLACE, true); if (second != NULL) MoveVehicle(second, NULL, DC_EXEC | DC_AUTOREPLACE, true);
assert(GetNextUnit(old_head) == NULL); assert(GetNextUnit((Train *)old_head) == NULL);
for (int i = num_units - 1; i > 0; i--) { for (int i = num_units - 1; i > 0; i--) {
CommandCost ret = MoveVehicle(old_vehs[i], old_head, DC_EXEC | DC_AUTOREPLACE, false); CommandCost ret = MoveVehicle(old_vehs[i], old_head, DC_EXEC | DC_AUTOREPLACE, false);
@ -632,7 +632,7 @@ CommandCost CmdAutoreplaceVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1
bool any_replacements = false; bool any_replacements = false;
while (w != NULL && !any_replacements) { while (w != NULL && !any_replacements) {
any_replacements = (GetNewEngineType(w, c) != INVALID_ENGINE); any_replacements = (GetNewEngineType(w, c) != INVALID_ENGINE);
w = (!free_wagon && w->type == VEH_TRAIN ? GetNextUnit(w) : NULL); w = (!free_wagon && w->type == VEH_TRAIN ? GetNextUnit((Train *)w) : NULL);
} }
if (any_replacements) { if (any_replacements) {

View File

@ -555,12 +555,15 @@ bool SettingsDisableElrail(int32 p1)
* normal rail too */ * normal rail too */
if (disable) { if (disable) {
FOR_ALL_VEHICLES(v) { FOR_ALL_VEHICLES(v) {
if (v->type == VEH_TRAIN && v->u.rail.railtype == RAILTYPE_ELECTRIC) { if (v->type != VEH_TRAIN) continue;
Train *t = (Train *)v;
if (t->u.rail.railtype == RAILTYPE_ELECTRIC) {
/* this railroad vehicle is now compatible only with elrail, /* this railroad vehicle is now compatible only with elrail,
* so add there also normal rail compatibility */ * so add there also normal rail compatibility */
v->u.rail.compatible_railtypes |= RAILTYPES_RAIL; t->u.rail.compatible_railtypes |= RAILTYPES_RAIL;
v->u.rail.railtype = RAILTYPE_RAIL; t->u.rail.railtype = RAILTYPE_RAIL;
SetBit(v->u.rail.flags, VRF_EL_ENGINE_ALLOWED_NORMAL_RAIL); SetBit(t->u.rail.flags, VRF_EL_ENGINE_ALLOWED_NORMAL_RAIL);
} }
} }
} }
@ -569,8 +572,9 @@ bool SettingsDisableElrail(int32 p1)
FOR_ALL_VEHICLES(v) { FOR_ALL_VEHICLES(v) {
/* power and acceleration is cached only for front engines */ /* power and acceleration is cached only for front engines */
if (v->type == VEH_TRAIN && IsFrontEngine(v)) { if (v->type == VEH_TRAIN && IsFrontEngine(v)) {
TrainPowerChanged(v); Train *t = (Train *)v;
UpdateTrainAcceleration(v); TrainPowerChanged(t);
UpdateTrainAcceleration(t);
} }
} }

View File

@ -668,7 +668,8 @@ static uint32 VehicleGetVariable(const ResolverObject *object, byte variable, by
uint16 modflags = 0; uint16 modflags = 0;
if (v->type == VEH_TRAIN) { if (v->type == VEH_TRAIN) {
const Vehicle *u = IsTrainWagon(v) && HasBit(v->vehicle_flags, VRF_POWEREDWAGON) ? v->First() : v; const Train *t = (const Train *)v;
const Train *u = IsTrainWagon(v) && HasBit(v->vehicle_flags, VRF_POWEREDWAGON) ? t->First() : t;
RailType railtype = GetRailType(v->tile); RailType railtype = GetRailType(v->tile);
bool powered = IsTrainEngine(v) || (IsTrainWagon(v) && HasBit(v->vehicle_flags, VRF_POWEREDWAGON)); bool powered = IsTrainEngine(v) || (IsTrainWagon(v) && HasBit(v->vehicle_flags, VRF_POWEREDWAGON));
bool has_power = powered && HasPowerOnRail(u->u.rail.railtype, railtype); bool has_power = powered && HasPowerOnRail(u->u.rail.railtype, railtype);
@ -676,7 +677,7 @@ static uint32 VehicleGetVariable(const ResolverObject *object, byte variable, by
if (has_power) SetBit(modflags, 5); if (has_power) SetBit(modflags, 5);
if (is_electric && !has_power) SetBit(modflags, 6); if (is_electric && !has_power) SetBit(modflags, 6);
if (HasBit(v->u.rail.flags, VRF_TOGGLE_REVERSE)) SetBit(modflags, 8); if (HasBit(t->u.rail.flags, VRF_TOGGLE_REVERSE)) SetBit(modflags, 8);
} }
if (HasBit(v->vehicle_flags, VF_BUILT_AS_PROTOTYPE)) SetBit(modflags, 10); if (HasBit(v->vehicle_flags, VF_BUILT_AS_PROTOTYPE)) SetBit(modflags, 10);
@ -735,7 +736,7 @@ static uint32 VehicleGetVariable(const ResolverObject *object, byte variable, by
case 0x47: return GB(Engine::Get(v->engine_type)->internal_id, 8, 8); case 0x47: return GB(Engine::Get(v->engine_type)->internal_id, 8, 8);
case 0x48: case 0x48:
if (v->type != VEH_TRAIN || v->spritenum != 0xFD) return v->spritenum; if (v->type != VEH_TRAIN || v->spritenum != 0xFD) return v->spritenum;
return HasBit(v->u.rail.flags, VRF_REVERSE_DIRECTION) ? 0xFE : 0xFD; return HasBit(((Train *)v)->u.rail.flags, VRF_REVERSE_DIRECTION) ? 0xFE : 0xFD;
case 0x49: return v->day_counter; case 0x49: return v->day_counter;
case 0x4A: return v->breakdowns_since_last_service; case 0x4A: return v->breakdowns_since_last_service;
@ -766,20 +767,21 @@ static uint32 VehicleGetVariable(const ResolverObject *object, byte variable, by
/* Vehicle specific properties */ /* Vehicle specific properties */
switch (v->type) { switch (v->type) {
case VEH_TRAIN: case VEH_TRAIN: {
Train *t = (Train *)v;
switch (variable - 0x80) { switch (variable - 0x80) {
case 0x62: return v->u.rail.track; case 0x62: return t->u.rail.track;
case 0x66: return v->u.rail.railtype; case 0x66: return t->u.rail.railtype;
case 0x73: return v->u.rail.cached_veh_length; case 0x73: return t->u.rail.cached_veh_length;
case 0x74: return v->u.rail.cached_power; case 0x74: return t->u.rail.cached_power;
case 0x75: return GB(v->u.rail.cached_power, 8, 24); case 0x75: return GB(t->u.rail.cached_power, 8, 24);
case 0x76: return GB(v->u.rail.cached_power, 16, 16); case 0x76: return GB(t->u.rail.cached_power, 16, 16);
case 0x77: return GB(v->u.rail.cached_power, 24, 8); case 0x77: return GB(t->u.rail.cached_power, 24, 8);
case 0x7C: return v->First()->index; case 0x7C: return t->First()->index;
case 0x7D: return GB(v->First()->index, 8, 8); case 0x7D: return GB(t->First()->index, 8, 8);
case 0x7F: return 0; // Used for vehicle reversing hack in TTDP case 0x7F: return 0; // Used for vehicle reversing hack in TTDP
} }
break; } break;
case VEH_ROAD: { case VEH_ROAD: {
RoadVehicle *rv = (RoadVehicle *)v; RoadVehicle *rv = (RoadVehicle *)v;

View File

@ -16,6 +16,7 @@
#include "pbs.h" #include "pbs.h"
#include "settings_type.h" #include "settings_type.h"
#include "pathfind.h" #include "pathfind.h"
#include "train.h"
static AyStar _npf_aystar; static AyStar _npf_aystar;
@ -424,7 +425,7 @@ static int32 NPFFindDepot(AyStar *as, OpenListNode *current)
/** Find any safe and free tile. */ /** Find any safe and free tile. */
static int32 NPFFindSafeTile(AyStar *as, OpenListNode *current) static int32 NPFFindSafeTile(AyStar *as, OpenListNode *current)
{ {
const Vehicle *v = ((NPFFindStationOrTileData*)as->user_target)->v; const Train *v = (Train *)((NPFFindStationOrTileData*)as->user_target)->v;
return return
IsSafeWaitingPosition(v, current->path.node.tile, current->path.node.direction, true, _settings_game.pf.forbid_90_deg) && IsSafeWaitingPosition(v, current->path.node.tile, current->path.node.direction, true, _settings_game.pf.forbid_90_deg) &&
@ -458,7 +459,7 @@ static int32 NPFFindStationOrTile(AyStar *as, OpenListNode *current)
* the second signal is returnd. If no suitable signal is present, the * the second signal is returnd. If no suitable signal is present, the
* last node of the path is returned. * last node of the path is returned.
*/ */
static const PathNode *FindSafePosition(PathNode *path, const Vehicle *v) static const PathNode *FindSafePosition(PathNode *path, const Train *v)
{ {
/* If there is no signal, reserve the whole path. */ /* If there is no signal, reserve the whole path. */
PathNode *sig = path; PathNode *sig = path;
@ -505,7 +506,7 @@ static void NPFSaveTargetData(AyStar *as, OpenListNode *current)
if (as->user_target != NULL && ((NPFFindStationOrTileData*)as->user_target)->reserve_path && as->user_data[NPF_TYPE] == TRANSPORT_RAIL) { if (as->user_target != NULL && ((NPFFindStationOrTileData*)as->user_target)->reserve_path && as->user_data[NPF_TYPE] == TRANSPORT_RAIL) {
/* Path reservation is requested. */ /* Path reservation is requested. */
const Vehicle *v = ((NPFFindStationOrTileData*)as->user_target)->v; const Train *v = (Train *)((NPFFindStationOrTileData*)as->user_target)->v;
const PathNode *target = FindSafePosition(&current->path, v); const PathNode *target = FindSafePosition(&current->path, v);
ftd->node = target->node; ftd->node = target->node;
@ -1053,7 +1054,7 @@ NPFFoundTargetData NPFRouteToDepotTrialError(TileIndex tile, Trackdir trackdir,
return best_result; return best_result;
} }
NPFFoundTargetData NPFRouteToSafeTile(const Vehicle *v, TileIndex tile, Trackdir trackdir, bool override_railtype) NPFFoundTargetData NPFRouteToSafeTile(const Train *v, TileIndex tile, Trackdir trackdir, bool override_railtype)
{ {
assert(v->type == VEH_TRAIN); assert(v->type == VEH_TRAIN);

View File

@ -115,7 +115,7 @@ NPFFoundTargetData NPFRouteToDepotTrialError(TileIndex tile, Trackdir trackdir,
/** /**
* Search for any safe tile using a breadth first search and try to reserve a path. * Search for any safe tile using a breadth first search and try to reserve a path.
*/ */
NPFFoundTargetData NPFRouteToSafeTile(const Vehicle *v, TileIndex tile, Trackdir trackdir,bool override_railtype); NPFFoundTargetData NPFRouteToSafeTile(const struct Train *v, TileIndex tile, Trackdir trackdir, bool override_railtype);
void NPFFillWithOrderData(NPFFindStationOrTileData *fstd, Vehicle *v, bool reserve_path = false); void NPFFillWithOrderData(NPFFindStationOrTileData *fstd, Vehicle *v, bool reserve_path = false);

View File

@ -31,6 +31,7 @@
#include "fios.h" #include "fios.h"
#include "aircraft.h" #include "aircraft.h"
#include "roadveh.h" #include "roadveh.h"
#include "train.h"
#include "console_func.h" #include "console_func.h"
#include "screenshot.h" #include "screenshot.h"
#include "network/network.h" #include "network/network.h"
@ -1132,7 +1133,7 @@ void StateGameLoop()
length = 0; length = 0;
for (Vehicle *u = v; u != NULL; u = u->Next()) wagons[length++] = u->u.rail; for (Vehicle *u = v; u != NULL; u = u->Next()) wagons[length++] = u->u.rail;
TrainConsistChanged(v, true); TrainConsistChanged((Train *)v, true);
length = 0; length = 0;
for (Vehicle *u = v; u != NULL; u = u->Next()) { for (Vehicle *u = v; u != NULL; u = u->Next()) {

View File

@ -222,7 +222,7 @@ static PBSTileInfo FollowReservation(Owner o, RailTypes rts, TileIndex tile, Tra
*/ */
struct FindTrainOnTrackInfo { struct FindTrainOnTrackInfo {
PBSTileInfo res; ///< Information about the track. PBSTileInfo res; ///< Information about the track.
Vehicle *best; ///< The currently "best" vehicle we have found. Train *best; ///< The currently "best" vehicle we have found.
/** Init the best location to NULL always! */ /** Init the best location to NULL always! */
FindTrainOnTrackInfo() : best(NULL) {} FindTrainOnTrackInfo() : best(NULL) {}
@ -233,12 +233,15 @@ static Vehicle *FindTrainOnTrackEnum(Vehicle *v, void *data)
{ {
FindTrainOnTrackInfo *info = (FindTrainOnTrackInfo *)data; FindTrainOnTrackInfo *info = (FindTrainOnTrackInfo *)data;
if (v->type == VEH_TRAIN && !(v->vehstatus & VS_CRASHED) && HasBit((TrackBits)v->u.rail.track, TrackdirToTrack(info->res.trackdir))) { if (v->type != VEH_TRAIN || (v->vehstatus & VS_CRASHED)) return NULL;
v = v->First();
Train *t = (Train *)v;
if (HasBit((TrackBits)t->u.rail.track, TrackdirToTrack(info->res.trackdir))) {
t = t->First();
/* ALWAYS return the lowest ID (anti-desync!) */ /* ALWAYS return the lowest ID (anti-desync!) */
if (info->best == NULL || v->index < info->best->index) info->best = v; if (info->best == NULL || t->index < info->best->index) info->best = t;
return v; return t;
} }
return NULL; return NULL;
@ -251,7 +254,7 @@ static Vehicle *FindTrainOnTrackEnum(Vehicle *v, void *data)
* @param train_on_res Is set to a train we might encounter * @param train_on_res Is set to a train we might encounter
* @returns The last tile of the reservation or the current train tile if no reservation present. * @returns The last tile of the reservation or the current train tile if no reservation present.
*/ */
PBSTileInfo FollowTrainReservation(const Vehicle *v, bool *train_on_res) PBSTileInfo FollowTrainReservation(const Train *v, bool *train_on_res)
{ {
assert(v->type == VEH_TRAIN); assert(v->type == VEH_TRAIN);
@ -274,7 +277,7 @@ PBSTileInfo FollowTrainReservation(const Vehicle *v, bool *train_on_res)
* @param track A reserved track on the tile. * @param track A reserved track on the tile.
* @return The vehicle holding the reservation or NULL if the path is stray. * @return The vehicle holding the reservation or NULL if the path is stray.
*/ */
Vehicle *GetTrainForReservation(TileIndex tile, Track track) Train *GetTrainForReservation(TileIndex tile, Track track)
{ {
assert(HasReservedTracks(tile, TrackToTrackBits(track))); assert(HasReservedTracks(tile, TrackToTrackBits(track)));
Trackdir trackdir = TrackToTrackdir(track); Trackdir trackdir = TrackToTrackdir(track);
@ -320,7 +323,7 @@ Vehicle *GetTrainForReservation(TileIndex tile, Track track)
* @param forbid_90def Don't allow trains to make 90 degree turns * @param forbid_90def Don't allow trains to make 90 degree turns
* @return True if it is a safe position * @return True if it is a safe position
*/ */
bool IsSafeWaitingPosition(const Vehicle *v, TileIndex tile, Trackdir trackdir, bool include_line_end, bool forbid_90deg) bool IsSafeWaitingPosition(const Train *v, TileIndex tile, Trackdir trackdir, bool include_line_end, bool forbid_90deg)
{ {
if (IsRailDepotTile(tile)) return true; if (IsRailDepotTile(tile)) return true;
@ -360,7 +363,7 @@ bool IsSafeWaitingPosition(const Vehicle *v, TileIndex tile, Trackdir trackdir,
* @param forbid_90def Don't allow trains to make 90 degree turns * @param forbid_90def Don't allow trains to make 90 degree turns
* @return True if the position is free * @return True if the position is free
*/ */
bool IsWaitingPositionFree(const Vehicle *v, TileIndex tile, Trackdir trackdir, bool forbid_90deg) bool IsWaitingPositionFree(const Train *v, TileIndex tile, Trackdir trackdir, bool forbid_90deg)
{ {
Track track = TrackdirToTrack(trackdir); Track track = TrackdirToTrack(trackdir);
TrackBits reserved = GetReservedTrackbits(tile); TrackBits reserved = GetReservedTrackbits(tile);

View File

@ -27,11 +27,11 @@ struct PBSTileInfo {
PBSTileInfo(TileIndex _t, Trackdir _td, bool _okay) : tile(_t), trackdir(_td), okay(_okay) {} PBSTileInfo(TileIndex _t, Trackdir _td, bool _okay) : tile(_t), trackdir(_td), okay(_okay) {}
}; };
PBSTileInfo FollowTrainReservation(const Vehicle *v, bool *train_on_res = NULL); PBSTileInfo FollowTrainReservation(const Train *v, bool *train_on_res = NULL);
bool IsSafeWaitingPosition(const Vehicle *v, TileIndex tile, Trackdir trackdir, bool include_line_end, bool forbid_90deg = false); bool IsSafeWaitingPosition(const Train *v, TileIndex tile, Trackdir trackdir, bool include_line_end, bool forbid_90deg = false);
bool IsWaitingPositionFree(const Vehicle *v, TileIndex tile, Trackdir trackdir, bool forbid_90deg = false); bool IsWaitingPositionFree(const Train *v, TileIndex tile, Trackdir trackdir, bool forbid_90deg = false);
Vehicle *GetTrainForReservation(TileIndex tile, Track track); Train *GetTrainForReservation(TileIndex tile, Track track);
/** /**
* Check whether some of tracks is reserved on a tile. * Check whether some of tracks is reserved on a tile.

View File

@ -92,7 +92,8 @@ Vehicle *EnsureNoTrainOnTrackProc(Vehicle *v, void *data)
if (v->type != VEH_TRAIN) return NULL; if (v->type != VEH_TRAIN) return NULL;
if ((v->u.rail.track != rail_bits) && !TracksOverlap(v->u.rail.track | rail_bits)) return NULL; Train *t = (Train *)v;
if ((t->u.rail.track != rail_bits) && !TracksOverlap(t->u.rail.track | rail_bits)) return NULL;
_error_message = VehicleInTheWayErrMsg(v); _error_message = VehicleInTheWayErrMsg(v);
return v; return v;
@ -456,7 +457,7 @@ CommandCost CmdRemoveSingleRail(TileIndex tile, DoCommandFlag flags, uint32 p1,
* so do not call GetTileOwner(tile) in any case here */ * so do not call GetTileOwner(tile) in any case here */
Owner owner = INVALID_OWNER; Owner owner = INVALID_OWNER;
Vehicle *v = NULL; Train *v = NULL;
switch (GetTileType(tile)) { switch (GetTileType(tile)) {
case MP_ROAD: { case MP_ROAD: {
@ -877,7 +878,7 @@ CommandCost CmdBuildSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1,
} }
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
Vehicle *v = NULL; Train *v = NULL;
/* The new/changed signal could block our path. As this can lead to /* The new/changed signal could block our path. As this can lead to
* stale reservations, we clear the path reservation here and try * stale reservations, we clear the path reservation here and try
* to redo it later on. */ * to redo it later on. */
@ -1184,7 +1185,7 @@ CommandCost CmdRemoveSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1
/* Do it? */ /* Do it? */
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
Vehicle *v = NULL; Train *v = NULL;
if (HasReservedTracks(tile, TrackToTrackBits(track))) { if (HasReservedTracks(tile, TrackToTrackBits(track))) {
v = GetTrainForReservation(tile, track); v = GetTrainForReservation(tile, track);
} }
@ -1234,7 +1235,7 @@ Vehicle *UpdateTrainPowerProc(Vehicle *v, void *data)
if (v->type == VEH_TRAIN && !IsArticulatedPart(v)) { if (v->type == VEH_TRAIN && !IsArticulatedPart(v)) {
const RailVehicleInfo *rvi = RailVehInfo(v->engine_type); const RailVehicleInfo *rvi = RailVehInfo(v->engine_type);
if (GetVehicleProperty(v, 0x0B, rvi->power) != 0) TrainPowerChanged(v->First()); if (GetVehicleProperty(v, 0x0B, rvi->power) != 0) TrainPowerChanged((Train *)v->First());
} }
return NULL; return NULL;
@ -1296,7 +1297,7 @@ CommandCost CmdConvertRail(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
/* Trying to convert other's rail */ /* Trying to convert other's rail */
if (!CheckTileOwnership(tile)) continue; if (!CheckTileOwnership(tile)) continue;
SmallVector<Vehicle*, 2> vehicles_affected; SmallVector<Train *, 2> vehicles_affected;
/* Vehicle on the tile when not converting Rail <-> ElRail /* Vehicle on the tile when not converting Rail <-> ElRail
* Tunnels and bridges have special check later */ * Tunnels and bridges have special check later */
@ -1306,7 +1307,7 @@ CommandCost CmdConvertRail(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
TrackBits reserved = GetReservedTrackbits(tile); TrackBits reserved = GetReservedTrackbits(tile);
Track track; Track track;
while ((track = RemoveFirstTrack(&reserved)) != INVALID_TRACK) { while ((track = RemoveFirstTrack(&reserved)) != INVALID_TRACK) {
Vehicle *v = GetTrainForReservation(tile, track); Train *v = GetTrainForReservation(tile, track);
if (v != NULL && !HasPowerOnRail(v->u.rail.railtype, totype)) { if (v != NULL && !HasPowerOnRail(v->u.rail.railtype, totype)) {
/* No power on new rail type, reroute. */ /* No power on new rail type, reroute. */
FreeTrainTrackReservation(v); FreeTrainTrackReservation(v);
@ -1372,7 +1373,7 @@ CommandCost CmdConvertRail(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
Track track = DiagDirToDiagTrack(GetTunnelBridgeDirection(tile)); Track track = DiagDirToDiagTrack(GetTunnelBridgeDirection(tile));
if (GetTunnelBridgeReservation(tile)) { if (GetTunnelBridgeReservation(tile)) {
Vehicle *v = GetTrainForReservation(tile, track); Train *v = GetTrainForReservation(tile, track);
if (v != NULL && !HasPowerOnRail(v->u.rail.railtype, totype)) { if (v != NULL && !HasPowerOnRail(v->u.rail.railtype, totype)) {
/* No power on new rail type, reroute. */ /* No power on new rail type, reroute. */
FreeTrainTrackReservation(v); FreeTrainTrackReservation(v);
@ -1432,7 +1433,7 @@ static CommandCost RemoveTrainDepot(TileIndex tile, DoCommandFlag flags)
/* read variables before the depot is removed */ /* read variables before the depot is removed */
DiagDirection dir = GetRailDepotDirection(tile); DiagDirection dir = GetRailDepotDirection(tile);
Owner owner = GetTileOwner(tile); Owner owner = GetTileOwner(tile);
Vehicle *v = NULL; Train *v = NULL;
if (GetDepotWaypointReservation(tile)) { if (GetDepotWaypointReservation(tile)) {
v = GetTrainForReservation(tile, DiagDirToDiagTrack(dir)); v = GetTrainForReservation(tile, DiagDirToDiagTrack(dir));
@ -2450,7 +2451,7 @@ int TicksToLeaveDepot(const Vehicle *v)
/** Tile callback routine when vehicle enters tile /** Tile callback routine when vehicle enters tile
* @see vehicle_enter_tile_proc */ * @see vehicle_enter_tile_proc */
static VehicleEnterTileStatus VehicleEnter_Track(Vehicle *v, TileIndex tile, int x, int y) static VehicleEnterTileStatus VehicleEnter_Track(Vehicle *u, TileIndex tile, int x, int y)
{ {
byte fract_coord; byte fract_coord;
byte fract_coord_leave; byte fract_coord_leave;
@ -2458,7 +2459,9 @@ static VehicleEnterTileStatus VehicleEnter_Track(Vehicle *v, TileIndex tile, int
int length; int length;
/* this routine applies only to trains in depot tiles */ /* this routine applies only to trains in depot tiles */
if (v->type != VEH_TRAIN || !IsRailDepotTile(tile)) return VETSB_CONTINUE; if (u->type != VEH_TRAIN || !IsRailDepotTile(tile)) return VETSB_CONTINUE;
Train *v = (Train *)u;
/* depot direction */ /* depot direction */
dir = GetRailDepotDirection(tile); dir = GetRailDepotDirection(tile);

View File

@ -912,7 +912,7 @@ bool AfterLoadGame()
continue; continue;
} }
if (v->type == VEH_TRAIN) { if (v->type == VEH_TRAIN) {
v->u.rail.track = TRACK_BIT_WORMHOLE; ((Train *)v)->u.rail.track = TRACK_BIT_WORMHOLE;
} else { } else {
((RoadVehicle *)v)->state = RVSB_WORMHOLE; ((RoadVehicle *)v)->state = RVSB_WORMHOLE;
} }
@ -928,7 +928,7 @@ bool AfterLoadGame()
if (v->type == VEH_TRAIN) { if (v->type == VEH_TRAIN) {
RailType rt = RailVehInfo(v->engine_type)->railtype; RailType rt = RailVehInfo(v->engine_type)->railtype;
v->u.rail.railtype = rt; ((Train *)v)->u.rail.railtype = rt;
if (rt == RAILTYPE_ELECTRIC) min_rail = RAILTYPE_RAIL; if (rt == RAILTYPE_ELECTRIC) min_rail = RAILTYPE_RAIL;
} }
} }
@ -964,7 +964,7 @@ bool AfterLoadGame()
} }
FOR_ALL_VEHICLES(v) { FOR_ALL_VEHICLES(v) {
if (v->type == VEH_TRAIN && (IsFrontEngine(v) || IsFreeWagon(v))) TrainConsistChanged(v, true); if (v->type == VEH_TRAIN && (IsFrontEngine(v) || IsFreeWagon(v))) TrainConsistChanged((Train *)v, true);
} }
} }
@ -1700,9 +1700,10 @@ bool AfterLoadGame()
/* Reserve all tracks trains are currently on. */ /* Reserve all tracks trains are currently on. */
if (CheckSavegameVersion(101)) { if (CheckSavegameVersion(101)) {
Vehicle *v; Vehicle *u;
FOR_ALL_VEHICLES(v) { FOR_ALL_VEHICLES(u) {
if (v->type == VEH_TRAIN) { if (u->type == VEH_TRAIN) {
Train *v = (Train *)u;
if ((v->u.rail.track & TRACK_BIT_WORMHOLE) == TRACK_BIT_WORMHOLE) { if ((v->u.rail.track & TRACK_BIT_WORMHOLE) == TRACK_BIT_WORMHOLE) {
TryReserveRailTrack(v->tile, DiagDirToDiagTrack(GetTunnelBridgeDirection(v->tile))); TryReserveRailTrack(v->tile, DiagDirToDiagTrack(GetTunnelBridgeDirection(v->tile)));
} else if ((v->u.rail.track & TRACK_BIT_MASK) != TRACK_BIT_NONE) { } else if ((v->u.rail.track & TRACK_BIT_MASK) != TRACK_BIT_NONE) {

View File

@ -1315,7 +1315,7 @@ bool LoadOldVehicle(LoadgameState *ls, int num)
}; };
if (v->spritenum / 2 >= lengthof(spriteset_rail)) return false; if (v->spritenum / 2 >= lengthof(spriteset_rail)) return false;
v->spritenum = spriteset_rail[v->spritenum / 2]; // adjust railway sprite set offset v->spritenum = spriteset_rail[v->spritenum / 2]; // adjust railway sprite set offset
v->u.rail.railtype = type == 0x25 ? 1 : 0; // monorail / rail ((Train *)v)->u.rail.railtype = type == 0x25 ? 1 : 0; // monorail / rail
break; break;
} }

View File

@ -24,7 +24,7 @@ void ConnectMultiheadedTrains()
FOR_ALL_VEHICLES(v) { FOR_ALL_VEHICLES(v) {
if (v->type == VEH_TRAIN) { if (v->type == VEH_TRAIN) {
v->u.rail.other_multiheaded_part = NULL; ((Train *)v)->u.rail.other_multiheaded_part = NULL;
} }
} }
@ -45,7 +45,7 @@ void ConnectMultiheadedTrains()
bool sequential_matching = IsFrontEngine(v); bool sequential_matching = IsFrontEngine(v);
for (Vehicle *u = v; u != NULL; u = GetNextVehicle(u)) { for (Train *u = (Train *)v; u != NULL; u = (Train *)GetNextVehicle(u)) {
if (u->u.rail.other_multiheaded_part != NULL) continue; // we already linked this one if (u->u.rail.other_multiheaded_part != NULL) continue; // we already linked this one
if (IsMultiheaded(u)) { if (IsMultiheaded(u)) {
@ -57,7 +57,7 @@ void ConnectMultiheadedTrains()
/* Find a matching back part */ /* Find a matching back part */
EngineID eid = u->engine_type; EngineID eid = u->engine_type;
Vehicle *w; Train *w;
if (sequential_matching) { if (sequential_matching) {
for (w = GetNextVehicle(u); w != NULL; w = GetNextVehicle(w)) { for (w = GetNextVehicle(u); w != NULL; w = GetNextVehicle(w)) {
if (w->engine_type != eid || w->u.rail.other_multiheaded_part != NULL || !IsMultiheaded(w)) continue; if (w->engine_type != eid || w->u.rail.other_multiheaded_part != NULL || !IsMultiheaded(w)) continue;
@ -318,8 +318,8 @@ void AfterLoadVehicles(bool part_of_load)
assert(v->first != NULL); assert(v->first != NULL);
if (v->type == VEH_TRAIN && (IsFrontEngine(v) || IsFreeWagon(v))) { if (v->type == VEH_TRAIN && (IsFrontEngine(v) || IsFreeWagon(v))) {
if (IsFrontEngine(v)) v->u.rail.last_speed = v->cur_speed; // update displayed train speed if (IsFrontEngine(v)) ((Train *)v)->u.rail.last_speed = v->cur_speed; // update displayed train speed
TrainConsistChanged(v, false); TrainConsistChanged((Train *)v, false);
} else if (v->type == VEH_ROAD && IsRoadVehFront(v)) { } else if (v->type == VEH_ROAD && IsRoadVehFront(v)) {
RoadVehUpdateCache((RoadVehicle *)v); RoadVehUpdateCache((RoadVehicle *)v);
} }

View File

@ -697,7 +697,7 @@ static bool UpdateConsists(int32 p1)
Vehicle *v; Vehicle *v;
FOR_ALL_VEHICLES(v) { FOR_ALL_VEHICLES(v) {
/* Update the consist of all trains so the maximum speed is set correctly. */ /* Update the consist of all trains so the maximum speed is set correctly. */
if (v->type == VEH_TRAIN && (IsFrontEngine(v) || IsFreeWagon(v))) TrainConsistChanged(v, true); if (v->type == VEH_TRAIN && (IsFrontEngine(v) || IsFreeWagon(v))) TrainConsistChanged((Train *)v, true);
} }
return true; return true;
} }
@ -747,7 +747,7 @@ static bool TrainAccelerationModelChanged(int32 p1)
Vehicle *v; Vehicle *v;
FOR_ALL_VEHICLES(v) { FOR_ALL_VEHICLES(v) {
if (v->type == VEH_TRAIN && IsFrontEngine(v)) UpdateTrainAcceleration(v); if (v->type == VEH_TRAIN && IsFrontEngine(v)) UpdateTrainAcceleration((Train *)v);
} }
return true; return true;

View File

@ -7,8 +7,8 @@
#include "station_map.h" #include "station_map.h"
#include "tunnelbridge_map.h" #include "tunnelbridge_map.h"
#include "vehicle_func.h" #include "vehicle_func.h"
#include "vehicle_base.h"
#include "functions.h" #include "functions.h"
#include "train.h"
/** these are the maximums used for updating signal blocks */ /** these are the maximums used for updating signal blocks */
@ -185,7 +185,7 @@ static SmallSet<DiagDirection, SIG_GLOB_SIZE> _globset("_globset"); ///< set of
/** Check whether there is a train on rail, not in a depot */ /** Check whether there is a train on rail, not in a depot */
static Vehicle *TrainOnTileEnum(Vehicle *v, void *) static Vehicle *TrainOnTileEnum(Vehicle *v, void *)
{ {
if (v->type != VEH_TRAIN || v->u.rail.track == TRACK_BIT_DEPOT) return NULL; if (v->type != VEH_TRAIN || ((Train *)v)->u.rail.track == TRACK_BIT_DEPOT) return NULL;
return v; return v;
} }

View File

@ -1015,7 +1015,7 @@ CommandCost CmdBuildRailroadStation(TileIndex tile_org, DoCommandFlag flags, uin
numtracks_orig = numtracks; numtracks_orig = numtracks;
SmallVector<Vehicle*, 4> affected_vehicles; SmallVector<Train*, 4> affected_vehicles;
do { do {
TileIndex tile = tile_org; TileIndex tile = tile_org;
int w = plat_len; int w = plat_len;
@ -1023,7 +1023,7 @@ CommandCost CmdBuildRailroadStation(TileIndex tile_org, DoCommandFlag flags, uin
byte layout = *layout_ptr++; byte layout = *layout_ptr++;
if (IsRailwayStationTile(tile) && GetRailwayStationReservation(tile)) { if (IsRailwayStationTile(tile) && GetRailwayStationReservation(tile)) {
/* Check for trains having a reservation for this tile. */ /* Check for trains having a reservation for this tile. */
Vehicle *v = GetTrainForReservation(tile, AxisToTrack(GetRailStationAxis(tile))); Train *v = GetTrainForReservation(tile, AxisToTrack(GetRailStationAxis(tile)));
if (v != NULL) { if (v != NULL) {
FreeTrainTrackReservation(v); FreeTrainTrackReservation(v);
*affected_vehicles.Append() = v; *affected_vehicles.Append() = v;
@ -1063,7 +1063,7 @@ CommandCost CmdBuildRailroadStation(TileIndex tile_org, DoCommandFlag flags, uin
for (uint i = 0; i < affected_vehicles.Length(); ++i) { for (uint i = 0; i < affected_vehicles.Length(); ++i) {
/* Restore reservations of trains. */ /* Restore reservations of trains. */
Vehicle *v = affected_vehicles[i]; Train *v = affected_vehicles[i];
if (IsRailwayStationTile(v->tile)) SetRailwayStationPlatformReservation(v->tile, TrackdirToExitdir(v->GetVehicleTrackdir()), true); if (IsRailwayStationTile(v->tile)) SetRailwayStationPlatformReservation(v->tile, TrackdirToExitdir(v->GetVehicleTrackdir()), true);
TryPathReserve(v, true, true); TryPathReserve(v, true, true);
for (; v->Next() != NULL; v = v->Next()) ; for (; v->Next() != NULL; v = v->Next()) ;
@ -1196,7 +1196,7 @@ CommandCost CmdRemoveFromRailroadStation(TileIndex tile, DoCommandFlag flags, ui
uint specindex = GetCustomStationSpecIndex(tile2); uint specindex = GetCustomStationSpecIndex(tile2);
Track track = GetRailStationTrack(tile2); Track track = GetRailStationTrack(tile2);
Owner owner = GetTileOwner(tile2); Owner owner = GetTileOwner(tile2);
Vehicle *v = NULL; Train *v = NULL;
if (GetRailwayStationReservation(tile2)) { if (GetRailwayStationReservation(tile2)) {
v = GetTrainForReservation(tile2, track); v = GetTrainForReservation(tile2, track);
@ -1280,7 +1280,7 @@ static CommandCost RemoveRailroadStation(Station *st, TileIndex tile, DoCommandF
/* read variables before the station tile is removed */ /* read variables before the station tile is removed */
Track track = GetRailStationTrack(tile); Track track = GetRailStationTrack(tile);
Owner owner = GetTileOwner(tile); // _current_company can be OWNER_WATER Owner owner = GetTileOwner(tile); // _current_company can be OWNER_WATER
Vehicle *v = NULL; Train *v = NULL;
if (GetRailwayStationReservation(tile)) { if (GetRailwayStationReservation(tile)) {
v = GetTrainForReservation(tile, track); v = GetTrainForReservation(tile, track);
if (v != NULL) FreeTrainTrackReservation(v); if (v != NULL) FreeTrainTrackReservation(v);
@ -2621,7 +2621,7 @@ static VehicleEnterTileStatus VehicleEnter_Station(Vehicle *v, TileIndex tile, i
int station_ahead; int station_ahead;
int station_length; int station_length;
int stop = GetTrainStopLocation(station_id, tile, v, &station_ahead, &station_length); int stop = GetTrainStopLocation(station_id, tile, (Train *)v, &station_ahead, &station_length);
/* Stop whenever that amount of station ahead + the distance from the /* Stop whenever that amount of station ahead + the distance from the
* begin of the platform to the stop location is longer than the length * begin of the platform to the stop location is longer than the length

View File

@ -9,6 +9,7 @@
#include "core/bitmath_func.hpp" #include "core/bitmath_func.hpp"
#include "vehicle_base.h" #include "vehicle_base.h"
struct Train;
/** enum to handle train subtypes /** enum to handle train subtypes
* Do not access it directly unless you have to. Use the access functions below * Do not access it directly unless you have to. Use the access functions below
@ -202,28 +203,6 @@ static inline bool EngineHasArticPart(const Vehicle *v)
return (v->Next() != NULL && IsArticulatedPart(v->Next())); return (v->Next() != NULL && IsArticulatedPart(v->Next()));
} }
/**
* Get the next part of a multi-part engine.
* Will only work on a multi-part engine (EngineHasArticPart(v) == true),
* Result is undefined for normal engine.
*/
static inline Vehicle *GetNextArticPart(const Vehicle *v)
{
assert(EngineHasArticPart(v));
return v->Next();
}
/** Get the last part of a multi-part engine.
* @param v Vehicle.
* @return Last part of the engine.
*/
static inline Vehicle *GetLastEnginePart(Vehicle *v)
{
assert(v->type == VEH_TRAIN);
while (EngineHasArticPart(v)) v = GetNextArticPart(v);
return v;
}
/** Tell if we are dealing with the rear end of a multiheaded engine. /** Tell if we are dealing with the rear end of a multiheaded engine.
* @param v Vehicle. * @param v Vehicle.
* @return True if the engine is the rear part of a dualheaded engine. * @return True if the engine is the rear part of a dualheaded engine.
@ -234,73 +213,24 @@ static inline bool IsRearDualheaded(const Vehicle *v)
return (IsMultiheaded(v) && !IsTrainEngine(v)); return (IsMultiheaded(v) && !IsTrainEngine(v));
} }
/** Get the next real (non-articulated part) vehicle in the consist.
* @param v Vehicle.
* @return Next vehicle in the consist.
*/
static inline Vehicle *GetNextVehicle(const Vehicle *v)
{
assert(v->type == VEH_TRAIN);
while (EngineHasArticPart(v)) v = GetNextArticPart(v);
/* v now contains the last artic part in the engine */
return v->Next();
}
/** Get the previous real (non-articulated part) vehicle in the consist.
* @param w Vehicle.
* @return Previous vehicle in the consist.
*/
static inline Vehicle *GetPrevVehicle(const Vehicle *w)
{
assert(w->type == VEH_TRAIN);
Vehicle *v = w->Previous();
while (v != NULL && IsArticulatedPart(v)) v = v->Previous();
return v;
}
/** Get the next real (non-articulated part and non rear part of dualheaded engine) vehicle in the consist.
* @param v Vehicle.
* @return Next vehicle in the consist.
*/
static inline Vehicle *GetNextUnit(const Vehicle *v)
{
assert(v->type == VEH_TRAIN);
Vehicle *w = GetNextVehicle(v);
if (w != NULL && IsRearDualheaded(w)) w = GetNextVehicle(w);
return w;
}
/** Get the previous real (non-articulated part and non rear part of dualheaded engine) vehicle in the consist.
* @param v Vehicle.
* @return Previous vehicle in the consist.
*/
static inline Vehicle *GetPrevUnit(const Vehicle *v)
{
assert(v->type == VEH_TRAIN);
Vehicle *w = GetPrevVehicle(v);
if (w != NULL && IsRearDualheaded(w)) w = GetPrevVehicle(w);
return w;
}
void CcBuildLoco(bool success, TileIndex tile, uint32 p1, uint32 p2); void CcBuildLoco(bool success, TileIndex tile, uint32 p1, uint32 p2);
void CcBuildWagon(bool success, TileIndex tile, uint32 p1, uint32 p2); void CcBuildWagon(bool success, TileIndex tile, uint32 p1, uint32 p2);
byte FreightWagonMult(CargoID cargo); byte FreightWagonMult(CargoID cargo);
int CheckTrainInDepot(const Vehicle *v, bool needs_to_be_stopped); int CheckTrainInDepot(const Train *v, bool needs_to_be_stopped);
int CheckTrainStoppedInDepot(const Vehicle *v); int CheckTrainStoppedInDepot(const Train *v);
void UpdateTrainAcceleration(Vehicle *v); void UpdateTrainAcceleration(Train *v);
void CheckTrainsLengths(); void CheckTrainsLengths();
void FreeTrainTrackReservation(const Vehicle *v, TileIndex origin = INVALID_TILE, Trackdir orig_td = INVALID_TRACKDIR); void FreeTrainTrackReservation(const Train *v, TileIndex origin = INVALID_TILE, Trackdir orig_td = INVALID_TRACKDIR);
bool TryPathReserve(Vehicle *v, bool mark_as_stuck = false, bool first_tile_okay = false); bool TryPathReserve(Train *v, bool mark_as_stuck = false, bool first_tile_okay = false);
int GetTrainStopLocation(StationID station_id, TileIndex tile, const Vehicle *v, int *station_ahead, int *station_length); int GetTrainStopLocation(StationID station_id, TileIndex tile, const Train *v, int *station_ahead, int *station_length);
void TrainConsistChanged(Train *v, bool same_length);
void TrainPowerChanged(Train *v);
Money GetTrainRunningCost(const Train *v);
/** /**
* This class 'wraps' Vehicle; you do not actually instantiate this class. * This class 'wraps' Vehicle; you do not actually instantiate this class.
@ -334,6 +264,87 @@ struct Train : public Vehicle {
Trackdir GetVehicleTrackdir() const; Trackdir GetVehicleTrackdir() const;
TileIndex GetOrderStationLocation(StationID station); TileIndex GetOrderStationLocation(StationID station);
bool FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse); bool FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse);
Train *First() { return (Train *)this->Vehicle::First(); }
Train *First() const { return (Train *)this->Vehicle::First(); }
Train *Next() { return (Train *)this->Vehicle::Next(); }
Train *Next() const { return (Train *)this->Vehicle::Next(); }
Train *Previous() { return (Train *)this->Vehicle::Previous(); }
Train *Previous() const { return (Train *)this->Vehicle::Previous(); }
}; };
/**
* Get the next part of a multi-part engine.
* Will only work on a multi-part engine (EngineHasArticPart(v) == true),
* Result is undefined for normal engine.
*/
static inline Train *GetNextArticPart(const Train *v)
{
assert(EngineHasArticPart(v));
return v->Next();
}
/** Get the last part of a multi-part engine.
* @param v Vehicle.
* @return Last part of the engine.
*/
static inline Train *GetLastEnginePart(Train *v)
{
assert(v->type == VEH_TRAIN);
while (EngineHasArticPart(v)) v = GetNextArticPart(v);
return v;
}
/** Get the next real (non-articulated part) vehicle in the consist.
* @param v Vehicle.
* @return Next vehicle in the consist.
*/
static inline Train *GetNextVehicle(const Train *v)
{
assert(v->type == VEH_TRAIN);
while (EngineHasArticPart(v)) v = GetNextArticPart(v);
/* v now contains the last artic part in the engine */
return v->Next();
}
/** Get the previous real (non-articulated part) vehicle in the consist.
* @param w Vehicle.
* @return Previous vehicle in the consist.
*/
static inline Train *GetPrevVehicle(const Train *w)
{
assert(w->type == VEH_TRAIN);
Train *v = w->Previous();
while (v != NULL && IsArticulatedPart(v)) v = v->Previous();
return v;
}
/** Get the next real (non-articulated part and non rear part of dualheaded engine) vehicle in the consist.
* @param v Vehicle.
* @return Next vehicle in the consist.
*/
static inline Train *GetNextUnit(const Train *v)
{
assert(v->type == VEH_TRAIN);
Train *w = GetNextVehicle(v);
if (w != NULL && IsRearDualheaded(w)) w = GetNextVehicle(w);
return w;
}
/** Get the previous real (non-articulated part and non rear part of dualheaded engine) vehicle in the consist.
* @param v Vehicle.
* @return Previous vehicle in the consist.
*/
static inline Train *GetPrevUnit(const Train *v)
{
assert(v->type == VEH_TRAIN);
Train *w = GetPrevVehicle(v);
if (w != NULL && IsRearDualheaded(w)) w = GetPrevVehicle(w);
return w;
}
#endif /* TRAIN_H */ #endif /* TRAIN_H */

View File

@ -37,12 +37,12 @@
#include "table/strings.h" #include "table/strings.h"
#include "table/train_cmd.h" #include "table/train_cmd.h"
static Track ChooseTrainTrack(Vehicle *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool force_res, bool *got_reservation, bool mark_stuck); static Track ChooseTrainTrack(Train *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool force_res, bool *got_reservation, bool mark_stuck);
static bool TrainCheckIfLineEnds(Vehicle *v); static bool TrainCheckIfLineEnds(Train *v);
static void TrainController(Vehicle *v, Vehicle *nomove); static void TrainController(Train *v, Vehicle *nomove);
static TileIndex TrainApproachingCrossingTile(const Vehicle *v); static TileIndex TrainApproachingCrossingTile(const Train *v);
static void CheckIfTrainNeedsService(Vehicle *v); static void CheckIfTrainNeedsService(Train *v);
static void CheckNextTrainTile(Vehicle *v); static void CheckNextTrainTile(Train *v);
static const byte _vehicle_initial_x_fract[4] = {10, 8, 4, 8}; static const byte _vehicle_initial_x_fract[4] = {10, 8, 4, 8};
static const byte _vehicle_initial_y_fract[4] = { 8, 4, 8, 10}; static const byte _vehicle_initial_y_fract[4] = { 8, 4, 8, 10};
@ -85,12 +85,12 @@ byte FreightWagonMult(CargoID cargo)
* Recalculates the cached total power of a train. Should be called when the consist is changed * Recalculates the cached total power of a train. Should be called when the consist is changed
* @param v First vehicle of the consist. * @param v First vehicle of the consist.
*/ */
void TrainPowerChanged(Vehicle *v) void TrainPowerChanged(Train *v)
{ {
uint32 total_power = 0; uint32 total_power = 0;
uint32 max_te = 0; uint32 max_te = 0;
for (const Vehicle *u = v; u != NULL; u = u->Next()) { for (const Train *u = v; u != NULL; u = u->Next()) {
RailType railtype = GetRailType(u->tile); RailType railtype = GetRailType(u->tile);
/* Power is not added for articulated parts */ /* Power is not added for articulated parts */
@ -134,11 +134,11 @@ void TrainPowerChanged(Vehicle *v)
* the consist changes. * the consist changes.
* @param v First vehicle of the consist. * @param v First vehicle of the consist.
*/ */
static void TrainCargoChanged(Vehicle *v) static void TrainCargoChanged(Train *v)
{ {
uint32 weight = 0; uint32 weight = 0;
for (Vehicle *u = v; u != NULL; u = u->Next()) { for (Train *u = v; u != NULL; u = u->Next()) {
uint32 vweight = GetCargo(u->cargo_type)->weight * u->cargo.Count() * FreightWagonMult(u->cargo_type) / 16; uint32 vweight = GetCargo(u->cargo_type)->weight * u->cargo.Count() * FreightWagonMult(u->cargo_type) / 16;
/* Vehicle weight is not added for articulated parts. */ /* Vehicle weight is not added for articulated parts. */
@ -171,7 +171,7 @@ static void TrainCargoChanged(Vehicle *v)
* is for the first time this happened. * is for the first time this happened.
* @param u first vehicle of chain * @param u first vehicle of chain
*/ */
static void RailVehicleLengthChanged(const Vehicle *u) static void RailVehicleLengthChanged(const Train *u)
{ {
/* show a warning once for each engine in whole game and once for each GRF after each game load */ /* show a warning once for each engine in whole game and once for each GRF after each game load */
const Engine *engine = Engine::Get(u->engine_type); const Engine *engine = Engine::Get(u->engine_type);
@ -189,7 +189,7 @@ void CheckTrainsLengths()
FOR_ALL_VEHICLES(v) { FOR_ALL_VEHICLES(v) {
if (v->type == VEH_TRAIN && v->First() == v && !(v->vehstatus & VS_CRASHED)) { if (v->type == VEH_TRAIN && v->First() == v && !(v->vehstatus & VS_CRASHED)) {
for (const Vehicle *u = v, *w = v->Next(); w != NULL; u = w, w = w->Next()) { for (const Train *u = (Train *)v, *w = (Train *)v->Next(); w != NULL; u = w, w = w->Next()) {
if (u->u.rail.track != TRACK_BIT_DEPOT) { if (u->u.rail.track != TRACK_BIT_DEPOT) {
if ((w->u.rail.track != TRACK_BIT_DEPOT && if ((w->u.rail.track != TRACK_BIT_DEPOT &&
max(abs(u->x_pos - w->x_pos), abs(u->y_pos - w->y_pos)) != u->u.rail.cached_veh_length) || max(abs(u->x_pos - w->x_pos), abs(u->y_pos - w->y_pos)) != u->u.rail.cached_veh_length) ||
@ -213,7 +213,7 @@ void CheckTrainsLengths()
* @param v First vehicle of the chain. * @param v First vehicle of the chain.
* @param same_length should length of vehicles stay the same? * @param same_length should length of vehicles stay the same?
*/ */
void TrainConsistChanged(Vehicle *v, bool same_length) void TrainConsistChanged(Train *v, bool same_length)
{ {
uint16 max_speed = UINT16_MAX; uint16 max_speed = UINT16_MAX;
@ -227,7 +227,7 @@ void TrainConsistChanged(Vehicle *v, bool same_length)
bool train_can_tilt = true; bool train_can_tilt = true;
for (Vehicle *u = v; u != NULL; u = u->Next()) { for (Train *u = v; u != NULL; u = u->Next()) {
const RailVehicleInfo *rvi_u = RailVehInfo(u->engine_type); const RailVehicleInfo *rvi_u = RailVehInfo(u->engine_type);
/* Check the v->first cache. */ /* Check the v->first cache. */
@ -244,13 +244,13 @@ void TrainConsistChanged(Vehicle *v, bool same_length)
u->cache_valid = 0; u->cache_valid = 0;
} }
for (Vehicle *u = v; u != NULL; u = u->Next()) { for (Train *u = v; u != NULL; u = u->Next()) {
/* Update user defined data (must be done before other properties) */ /* Update user defined data (must be done before other properties) */
u->u.rail.user_def_data = GetVehicleProperty(u, 0x25, u->u.rail.user_def_data); u->u.rail.user_def_data = GetVehicleProperty(u, 0x25, u->u.rail.user_def_data);
u->cache_valid = 0; u->cache_valid = 0;
} }
for (Vehicle *u = v; u != NULL; u = u->Next()) { for (Train *u = v; u != NULL; u = u->Next()) {
const Engine *e_u = Engine::Get(u->engine_type); const Engine *e_u = Engine::Get(u->engine_type);
const RailVehicleInfo *rvi_u = &e_u->u.rail; const RailVehicleInfo *rvi_u = &e_u->u.rail;
@ -364,7 +364,7 @@ enum AccelType {
* @param station_length 'return' the station length in 1/16th tiles * @param station_length 'return' the station length in 1/16th tiles
* @return the location, calculated from the begin of the station to stop at. * @return the location, calculated from the begin of the station to stop at.
*/ */
int GetTrainStopLocation(StationID station_id, TileIndex tile, const Vehicle *v, int *station_ahead, int *station_length) int GetTrainStopLocation(StationID station_id, TileIndex tile, const Train *v, int *station_ahead, int *station_length)
{ {
const Station *st = Station::Get(station_id); const Station *st = Station::Get(station_id);
*station_ahead = st->GetPlatformLength(tile, DirToDiagDir(v->direction)) * TILE_SIZE; *station_ahead = st->GetPlatformLength(tile, DirToDiagDir(v->direction)) * TILE_SIZE;
@ -404,7 +404,7 @@ int GetTrainStopLocation(StationID station_id, TileIndex tile, const Vehicle *v,
} }
/** new acceleration*/ /** new acceleration*/
static int GetTrainAcceleration(Vehicle *v, bool mode) static int GetTrainAcceleration(Train *v, bool mode)
{ {
static const int absolute_max_speed = UINT16_MAX; static const int absolute_max_speed = UINT16_MAX;
int max_speed = absolute_max_speed; int max_speed = absolute_max_speed;
@ -496,7 +496,7 @@ static int GetTrainAcceleration(Vehicle *v, bool mode)
int num = 0; // number of vehicles, change this into the number of axles later int num = 0; // number of vehicles, change this into the number of axles later
int incl = 0; int incl = 0;
int drag_coeff = 20; //[1e-4] int drag_coeff = 20; //[1e-4]
for (const Vehicle *u = v; u != NULL; u = u->Next()) { for (const Train *u = v; u != NULL; u = u->Next()) {
num++; num++;
drag_coeff += 3; drag_coeff += 3;
@ -556,7 +556,7 @@ static int GetTrainAcceleration(Vehicle *v, bool mode)
} }
} }
void UpdateTrainAcceleration(Vehicle *v) void UpdateTrainAcceleration(Train *v)
{ {
assert(IsFrontEngine(v)); assert(IsFrontEngine(v));
@ -660,7 +660,7 @@ static CommandCost CmdBuildRailWagon(EngineID engine, TileIndex tile, DoCommandF
} }
} }
Vehicle *v = new Train(); Train *v = new Train();
v->spritenum = rvi->image_index; v->spritenum = rvi->image_index;
v->engine_type = engine; v->engine_type = engine;
@ -725,14 +725,14 @@ static CommandCost CmdBuildRailWagon(EngineID engine, TileIndex tile, DoCommandF
} }
/** Move all free vehicles in the depot to the train */ /** Move all free vehicles in the depot to the train */
static void NormalizeTrainVehInDepot(const Vehicle *u) static void NormalizeTrainVehInDepot(const Train *u)
{ {
const Vehicle *v; const Vehicle *v;
FOR_ALL_VEHICLES(v) { FOR_ALL_VEHICLES(v) {
if (v->type == VEH_TRAIN && IsFreeWagon(v) && if (v->type == VEH_TRAIN && IsFreeWagon(v) &&
v->tile == u->tile && v->tile == u->tile &&
v->u.rail.track == TRACK_BIT_DEPOT) { ((Train *)v)->u.rail.track == TRACK_BIT_DEPOT) {
if (CmdFailed(DoCommand(0, v->index | (u->index << 16), 1, DC_EXEC, if (CmdFailed(DoCommand(0, v->index | (u->index << 16), 1, DC_EXEC,
CMD_MOVE_RAIL_VEHICLE))) CMD_MOVE_RAIL_VEHICLE)))
break; break;
@ -740,9 +740,9 @@ static void NormalizeTrainVehInDepot(const Vehicle *u)
} }
} }
static void AddRearEngineToMultiheadedTrain(Vehicle *v) static void AddRearEngineToMultiheadedTrain(Train *v)
{ {
Vehicle *u = new Train(); Train *u = new Train();
v->value >>= 1; v->value >>= 1;
u->value = v->value; u->value = v->value;
u->direction = v->direction; u->direction = v->direction;
@ -823,7 +823,7 @@ CommandCost CmdBuildRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1,
int x = TileX(tile) * TILE_SIZE + _vehicle_initial_x_fract[dir]; int x = TileX(tile) * TILE_SIZE + _vehicle_initial_x_fract[dir];
int y = TileY(tile) * TILE_SIZE + _vehicle_initial_y_fract[dir]; int y = TileY(tile) * TILE_SIZE + _vehicle_initial_y_fract[dir];
Vehicle *v = new Train(); Train *v = new Train();
v->unitnumber = unit_num; v->unitnumber = unit_num;
v->direction = DiagDirToDir(dir); v->direction = DiagDirToDir(dir);
v->tile = tile; v->tile = tile;
@ -901,7 +901,7 @@ CommandCost CmdBuildRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1,
/* Check if all the wagons of the given train are in a depot, returns the /* Check if all the wagons of the given train are in a depot, returns the
* number of cars (including loco) then. If not it returns -1 */ * number of cars (including loco) then. If not it returns -1 */
int CheckTrainInDepot(const Vehicle *v, bool needs_to_be_stopped) int CheckTrainInDepot(const Train *v, bool needs_to_be_stopped)
{ {
TileIndex tile = v->tile; TileIndex tile = v->tile;
@ -926,13 +926,13 @@ int CheckTrainInDepot(const Vehicle *v, bool needs_to_be_stopped)
} }
/* Used to check if the train is inside the depot and verifying that the VS_STOPPED flag is set */ /* Used to check if the train is inside the depot and verifying that the VS_STOPPED flag is set */
int CheckTrainStoppedInDepot(const Vehicle *v) int CheckTrainStoppedInDepot(const Train *v)
{ {
return CheckTrainInDepot(v, true); return CheckTrainInDepot(v, true);
} }
/* Used to check if the train is inside the depot, but not checking the VS_STOPPED flag */ /* Used to check if the train is inside the depot, but not checking the VS_STOPPED flag */
inline bool CheckTrainIsInsideDepot(const Vehicle *v) inline bool CheckTrainIsInsideDepot(const Train *v)
{ {
return CheckTrainInDepot(v, false) > 0; return CheckTrainInDepot(v, false) > 0;
} }
@ -943,7 +943,7 @@ inline bool CheckTrainIsInsideDepot(const Vehicle *v)
* @param first The first vehicle of the consist. * @param first The first vehicle of the consist.
* @return The first vehicle of the consist. * @return The first vehicle of the consist.
*/ */
static Vehicle *UnlinkWagon(Vehicle *v, Vehicle *first) static Train *UnlinkWagon(Train *v, Train *first)
{ {
/* unlinking the first vehicle of the chain? */ /* unlinking the first vehicle of the chain? */
if (v == first) { if (v == first) {
@ -960,13 +960,13 @@ static Vehicle *UnlinkWagon(Vehicle *v, Vehicle *first)
return v; return v;
} }
Vehicle *u; Train *u;
for (u = first; GetNextVehicle(u) != v; u = GetNextVehicle(u)) {} for (u = first; GetNextVehicle(u) != v; u = GetNextVehicle(u)) {}
GetLastEnginePart(u)->SetNext(GetNextVehicle(v)); GetLastEnginePart(u)->SetNext(GetNextVehicle(v));
return first; return first;
} }
static Vehicle *FindGoodVehiclePos(const Vehicle *src) static Train *FindGoodVehiclePos(const Train *src)
{ {
Vehicle *dst; Vehicle *dst;
EngineID eng = src->engine_type; EngineID eng = src->engine_type;
@ -979,7 +979,7 @@ static Vehicle *FindGoodVehiclePos(const Vehicle *src)
while (v->engine_type == eng) { while (v->engine_type == eng) {
v = v->Next(); v = v->Next();
if (v == NULL) return dst; if (v == NULL) return (Train *)dst;
} }
} }
} }
@ -991,12 +991,12 @@ static Vehicle *FindGoodVehiclePos(const Vehicle *src)
* add a vehicle v behind vehicle dest * add a vehicle v behind vehicle dest
* use this function since it sets flags as needed * use this function since it sets flags as needed
*/ */
static void AddWagonToConsist(Vehicle *v, Vehicle *dest) static void AddWagonToConsist(Train *v, Train *dest)
{ {
UnlinkWagon(v, v->First()); UnlinkWagon(v, v->First());
if (dest == NULL) return; if (dest == NULL) return;
Vehicle *next = dest->Next(); Train *next = dest->Next();
v->SetNext(NULL); v->SetNext(NULL);
dest->SetNext(v); dest->SetNext(v);
v->SetNext(next); v->SetNext(next);
@ -1008,7 +1008,7 @@ static void AddWagonToConsist(Vehicle *v, Vehicle *dest)
* move around on the train so rear engines are placed correctly according to the other engines * move around on the train so rear engines are placed correctly according to the other engines
* always call with the front engine * always call with the front engine
*/ */
static void NormaliseTrainConsist(Vehicle *v) static void NormaliseTrainConsist(Train *v)
{ {
if (IsFreeWagon(v)) return; if (IsFreeWagon(v)) return;
@ -1018,7 +1018,7 @@ static void NormaliseTrainConsist(Vehicle *v)
if (!IsMultiheaded(v) || !IsTrainEngine(v)) continue; if (!IsMultiheaded(v) || !IsTrainEngine(v)) continue;
/* make sure that there are no free cars before next engine */ /* make sure that there are no free cars before next engine */
Vehicle *u; Train *u;
for (u = v; u->Next() != NULL && !IsTrainEngine(u->Next()); u = u->Next()) {} for (u = v; u->Next() != NULL && !IsTrainEngine(u->Next()); u = u->Next()) {}
if (u == v->u.rail.other_multiheaded_part) continue; if (u == v->u.rail.other_multiheaded_part) continue;
@ -1040,22 +1040,25 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, u
VehicleID s = GB(p1, 0, 16); VehicleID s = GB(p1, 0, 16);
VehicleID d = GB(p1, 16, 16); VehicleID d = GB(p1, 16, 16);
Vehicle *src = Vehicle::GetIfValid(s); Vehicle *src_v = Vehicle::GetIfValid(s);
if (src == NULL || src->type != VEH_TRAIN || !CheckOwnership(src->owner)) return CMD_ERROR; if (src_v == NULL || src_v->type != VEH_TRAIN || !CheckOwnership(src_v->owner)) return CMD_ERROR;
/* Do not allow moving crashed vehicles inside the depot, it is likely to cause asserts later */ /* Do not allow moving crashed vehicles inside the depot, it is likely to cause asserts later */
if (HASBITS(src->vehstatus, VS_CRASHED)) return CMD_ERROR; if (HASBITS(src_v->vehstatus, VS_CRASHED)) return CMD_ERROR;
Train *src = (Train *)src_v;
/* if nothing is selected as destination, try and find a matching vehicle to drag to. */ /* if nothing is selected as destination, try and find a matching vehicle to drag to. */
Vehicle *dst; Train *dst;
if (d == INVALID_VEHICLE) { if (d == INVALID_VEHICLE) {
dst = IsTrainEngine(src) ? NULL : FindGoodVehiclePos(src); dst = IsTrainEngine(src) ? NULL : FindGoodVehiclePos(src);
} else { } else {
dst = Vehicle::GetIfValid(d); Vehicle *dst_v = Vehicle::GetIfValid(d);
if (dst == NULL || dst->type != VEH_TRAIN || !CheckOwnership(dst->owner)) return CMD_ERROR; if (dst_v == NULL || dst_v->type != VEH_TRAIN || !CheckOwnership(dst_v->owner)) return CMD_ERROR;
/* Do not allow appending to crashed vehicles, too */ /* Do not allow appending to crashed vehicles, too */
if (HASBITS(dst->vehstatus, VS_CRASHED)) return CMD_ERROR; if (HASBITS(dst_v->vehstatus, VS_CRASHED)) return CMD_ERROR;
dst = (Train *)dst_v;
} }
/* if an articulated part is being handled, deal with its parent vehicle */ /* if an articulated part is being handled, deal with its parent vehicle */
@ -1068,8 +1071,8 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, u
if (src == dst) return CommandCost(); if (src == dst) return CommandCost();
/* locate the head of the two chains */ /* locate the head of the two chains */
Vehicle *src_head = src->First(); Train *src_head = src->First();
Vehicle *dst_head; Train *dst_head;
if (dst != NULL) { if (dst != NULL) {
dst_head = dst->First(); dst_head = dst->First();
if (dst_head->tile != src_head->tile) return CMD_ERROR; if (dst_head->tile != src_head->tile) return CMD_ERROR;
@ -1105,7 +1108,7 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, u
/* We are moving between rows, so only count the wagons from the source /* We are moving between rows, so only count the wagons from the source
* row that are being moved. */ * row that are being moved. */
if (HasBit(p2, 0)) { if (HasBit(p2, 0)) {
const Vehicle *u; const Train *u;
for (u = src_head; u != src && u != NULL; u = GetNextVehicle(u)) for (u = src_head; u != src && u != NULL; u = GetNextVehicle(u))
src_len--; src_len--;
} else { } else {
@ -1151,7 +1154,7 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, u
* v->Next()->Previous() == v holds (assuming v->Next() != NULL). * v->Next()->Previous() == v holds (assuming v->Next() != NULL).
*/ */
bool src_in_dst = false; bool src_in_dst = false;
for (Vehicle *v = dst_head; !src_in_dst && v != NULL; v = v->Next()) src_in_dst = v == src; for (Train *v = dst_head; !src_in_dst && v != NULL; v = v->Next()) src_in_dst = v == src;
/* /*
* If the source chain is in the destination chain then the user is * If the source chain is in the destination chain then the user is
@ -1171,12 +1174,12 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, u
* attaching fails or succeeds because we are not 'only' doing this * attaching fails or succeeds because we are not 'only' doing this
* in the DC_EXEC state. * in the DC_EXEC state.
*/ */
Vehicle *dst_tail = dst_head; Train *dst_tail = dst_head;
while (dst_tail->Next() != NULL) dst_tail = dst_tail->Next(); while (dst_tail->Next() != NULL) dst_tail = dst_tail->Next();
Vehicle *orig_tail = dst_tail; Train *orig_tail = dst_tail;
Vehicle *next_to_attach = src; Train *next_to_attach = src;
Vehicle *src_previous = src->Previous(); Train *src_previous = src->Previous();
while (next_to_attach != NULL) { while (next_to_attach != NULL) {
/* Don't check callback for articulated or rear dual headed parts */ /* Don't check callback for articulated or rear dual headed parts */
@ -1224,7 +1227,7 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, u
* to the next wagon. Then add that to the tail of the destination * to the next wagon. Then add that to the tail of the destination
* train and update the tail with the new vehicle. * train and update the tail with the new vehicle.
*/ */
Vehicle *to_add = next_to_attach; Train *to_add = next_to_attach;
next_to_attach = next_to_attach->Next(); next_to_attach = next_to_attach->Next();
to_add->SetNext(NULL); to_add->SetNext(NULL);
@ -1259,7 +1262,7 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, u
if (HasBit(p2, 0)) { if (HasBit(p2, 0)) {
/* unlink ALL wagons */ /* unlink ALL wagons */
if (src != src_head) { if (src != src_head) {
Vehicle *v = src_head; Train *v = src_head;
while (GetNextVehicle(v) != src) v = GetNextVehicle(v); while (GetNextVehicle(v) != src) v = GetNextVehicle(v);
GetLastEnginePart(v)->SetNext(NULL); GetLastEnginePart(v)->SetNext(NULL);
} else { } else {
@ -1318,7 +1321,7 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, u
/* link in the wagon(s) in the chain. */ /* link in the wagon(s) in the chain. */
{ {
Vehicle *v; Train *v;
for (v = src; GetNextVehicle(v) != NULL; v = GetNextVehicle(v)) {} for (v = src; GetNextVehicle(v) != NULL; v = GetNextVehicle(v)) {}
GetLastEnginePart(v)->SetNext(dst->Next()); GetLastEnginePart(v)->SetNext(dst->Next());
@ -1391,14 +1394,15 @@ CommandCost CmdSellRailWagon(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
/* Check if we deleted a vehicle window */ /* Check if we deleted a vehicle window */
Window *w = NULL; Window *w = NULL;
Vehicle *v = Vehicle::GetIfValid(p1); Vehicle *vt = Vehicle::GetIfValid(p1);
if (v == NULL || v->type != VEH_TRAIN || !CheckOwnership(v->owner)) return CMD_ERROR; if (vt == NULL || vt->type != VEH_TRAIN || !CheckOwnership(vt->owner)) return CMD_ERROR;
if (p2 > 1) return CMD_ERROR; if (p2 > 1) return CMD_ERROR;
if (HASBITS(v->vehstatus, VS_CRASHED)) return_cmd_error(STR_CAN_T_SELL_DESTROYED_VEHICLE); if (HASBITS(vt->vehstatus, VS_CRASHED)) return_cmd_error(STR_CAN_T_SELL_DESTROYED_VEHICLE);
Train *v = (Train *)vt;
while (IsArticulatedPart(v)) v = v->Previous(); while (IsArticulatedPart(v)) v = v->Previous();
Vehicle *first = v->First(); Train *first = v->First();
/* make sure the vehicle is stopped in the depot */ /* make sure the vehicle is stopped in the depot */
if (CheckTrainStoppedInDepot(first) < 0) { if (CheckTrainStoppedInDepot(first) < 0) {
@ -1426,7 +1430,7 @@ CommandCost CmdSellRailWagon(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
/* 1. Delete the engine, if it is dualheaded also delete the matching /* 1. Delete the engine, if it is dualheaded also delete the matching
* rear engine of the loco (from the point of deletion onwards) */ * rear engine of the loco (from the point of deletion onwards) */
Vehicle *rear = (IsMultiheaded(v) && Train *rear = (IsMultiheaded(v) &&
IsTrainEngine(v)) ? v->u.rail.other_multiheaded_part : NULL; IsTrainEngine(v)) ? v->u.rail.other_multiheaded_part : NULL;
if (rear != NULL) { if (rear != NULL) {
@ -1440,7 +1444,7 @@ CommandCost CmdSellRailWagon(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
/* 2. We are selling the front vehicle, some special action might be required /* 2. We are selling the front vehicle, some special action might be required
* here, so take attention */ * here, so take attention */
if (v == first) { if (v == first) {
Vehicle *new_f = GetNextVehicle(first); Train *new_f = GetNextVehicle(first);
/* 2.2 If there are wagons present after the deleted front engine, check /* 2.2 If there are wagons present after the deleted front engine, check
* if the second wagon (which will be first) is an engine. If it is one, * if the second wagon (which will be first) is an engine. If it is one,
@ -1500,13 +1504,13 @@ CommandCost CmdSellRailWagon(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
/* Start deleting every vehicle after the selected one /* Start deleting every vehicle after the selected one
* If we encounter a matching rear-engine to a front-engine * If we encounter a matching rear-engine to a front-engine
* earlier in the chain (before deletion), leave it alone */ * earlier in the chain (before deletion), leave it alone */
for (Vehicle *tmp; v != NULL; v = tmp) { for (Train *tmp; v != NULL; v = tmp) {
tmp = GetNextVehicle(v); tmp = GetNextVehicle(v);
if (IsMultiheaded(v)) { if (IsMultiheaded(v)) {
if (IsTrainEngine(v)) { if (IsTrainEngine(v)) {
/* We got a front engine of a multiheaded set. Now we will sell the rear end too */ /* We got a front engine of a multiheaded set. Now we will sell the rear end too */
Vehicle *rear = v->u.rail.other_multiheaded_part; Train *rear = v->u.rail.other_multiheaded_part;
if (rear != NULL) { if (rear != NULL) {
cost.AddCost(-rear->value); cost.AddCost(-rear->value);
@ -1572,14 +1576,14 @@ void Train::UpdateDeltaXY(Direction direction)
this->z_extent = 6; this->z_extent = 6;
} }
static void UpdateVarsAfterSwap(Vehicle *v) static void UpdateVarsAfterSwap(Train *v)
{ {
v->UpdateDeltaXY(v->direction); v->UpdateDeltaXY(v->direction);
v->cur_image = v->GetImage(v->direction); v->cur_image = v->GetImage(v->direction);
VehicleMove(v, true); VehicleMove(v, true);
} }
static inline void SetLastSpeed(Vehicle *v, int spd) static inline void SetLastSpeed(Train *v, int spd)
{ {
int old = v->u.rail.last_speed; int old = v->u.rail.last_speed;
if (spd != old) { if (spd != old) {
@ -1591,7 +1595,7 @@ static inline void SetLastSpeed(Vehicle *v, int spd)
} }
/** Mark a train as stuck and stop it if it isn't stopped right now. */ /** Mark a train as stuck and stop it if it isn't stopped right now. */
static void MarkTrainAsStuck(Vehicle *v) static void MarkTrainAsStuck(Train *v)
{ {
if (!HasBit(v->u.rail.flags, VRF_TRAIN_STUCK)) { if (!HasBit(v->u.rail.flags, VRF_TRAIN_STUCK)) {
/* It is the first time the problem occured, set the "train stuck" flag. */ /* It is the first time the problem occured, set the "train stuck" flag. */
@ -1631,9 +1635,9 @@ static void SwapTrainFlags(uint16 *swap_flag1, uint16 *swap_flag2)
} }
} }
static void ReverseTrainSwapVeh(Vehicle *v, int l, int r) static void ReverseTrainSwapVeh(Train *v, int l, int r)
{ {
Vehicle *a, *b; Train *a, *b;
/* locate vehicles to swap */ /* locate vehicles to swap */
for (a = v; l != 0; l--) a = a->Next(); for (a = v; l != 0; l--) a = a->Next();
@ -1704,7 +1708,7 @@ static Vehicle *TrainApproachingCrossingEnum(Vehicle *v, void *data)
TileIndex tile = *(TileIndex*)data; TileIndex tile = *(TileIndex*)data;
if (TrainApproachingCrossingTile(v) != tile) return NULL; if (TrainApproachingCrossingTile((Train *)v) != tile) return NULL;
return v; return v;
} }
@ -1775,11 +1779,11 @@ static inline void MaybeBarCrossingWithSound(TileIndex tile)
* This one is called before the train is reversed. * This one is called before the train is reversed.
* @param v First vehicle in chain * @param v First vehicle in chain
*/ */
static void AdvanceWagonsBeforeSwap(Vehicle *v) static void AdvanceWagonsBeforeSwap(Train *v)
{ {
Vehicle *base = v; Train *base = v;
Vehicle *first = base; // first vehicle to move Train *first = base; // first vehicle to move
Vehicle *last = GetLastVehicleInChain(v); // last vehicle to move Train *last = (Train *)GetLastVehicleInChain(v); // last vehicle to move
uint length = CountVehiclesInChain(v); uint length = CountVehiclesInChain(v);
while (length > 2) { while (length > 2) {
@ -1803,15 +1807,15 @@ static void AdvanceWagonsBeforeSwap(Vehicle *v)
* This one is called after the train is reversed. * This one is called after the train is reversed.
* @param v First vehicle in chain * @param v First vehicle in chain
*/ */
static void AdvanceWagonsAfterSwap(Vehicle *v) static void AdvanceWagonsAfterSwap(Train *v)
{ {
/* first of all, fix the situation when the train was entering a depot */ /* first of all, fix the situation when the train was entering a depot */
Vehicle *dep = v; // last vehicle in front of just left depot Train *dep = v; // last vehicle in front of just left depot
while (dep->Next() != NULL && (dep->u.rail.track == TRACK_BIT_DEPOT || dep->Next()->u.rail.track != TRACK_BIT_DEPOT)) { while (dep->Next() != NULL && (dep->u.rail.track == TRACK_BIT_DEPOT || dep->Next()->u.rail.track != TRACK_BIT_DEPOT)) {
dep = dep->Next(); // find first vehicle outside of a depot, with next vehicle inside a depot dep = dep->Next(); // find first vehicle outside of a depot, with next vehicle inside a depot
} }
Vehicle *leave = dep->Next(); // first vehicle in a depot we are leaving now Train *leave = dep->Next(); // first vehicle in a depot we are leaving now
if (leave != NULL) { if (leave != NULL) {
/* 'pull' next wagon out of the depot, so we won't miss it (it could stay in depot forever) */ /* 'pull' next wagon out of the depot, so we won't miss it (it could stay in depot forever) */
@ -1826,9 +1830,9 @@ static void AdvanceWagonsAfterSwap(Vehicle *v)
dep = NULL; // no vehicle in a depot, so no vehicle leaving a depot dep = NULL; // no vehicle in a depot, so no vehicle leaving a depot
} }
Vehicle *base = v; Train *base = v;
Vehicle *first = base; // first vehicle to move Train *first = base; // first vehicle to move
Vehicle *last = GetLastVehicleInChain(v); // last vehicle to move Train *last = (Train *)GetLastVehicleInChain(v); // last vehicle to move
uint length = CountVehiclesInChain(v); uint length = CountVehiclesInChain(v);
/* we have to make sure all wagons that leave a depot because of train reversing are moved coorectly /* we have to make sure all wagons that leave a depot because of train reversing are moved coorectly
@ -1857,7 +1861,7 @@ static void AdvanceWagonsAfterSwap(Vehicle *v)
} }
static void ReverseTrainDirection(Vehicle *v) static void ReverseTrainDirection(Train *v)
{ {
if (IsRailDepotTile(v->tile)) { if (IsRailDepotTile(v->tile)) {
InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile); InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
@ -1946,8 +1950,10 @@ static void ReverseTrainDirection(Vehicle *v)
*/ */
CommandCost CmdReverseTrainDirection(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) CommandCost CmdReverseTrainDirection(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{ {
Vehicle *v = Vehicle::GetIfValid(p1); Vehicle *vt = Vehicle::GetIfValid(p1);
if (v == NULL || v->type != VEH_TRAIN || !CheckOwnership(v->owner)) return CMD_ERROR; if (vt == NULL || vt->type != VEH_TRAIN || !CheckOwnership(vt->owner)) return CMD_ERROR;
Train *v = (Train *)vt;
if (p2 != 0) { if (p2 != 0) {
/* turn a single unit around */ /* turn a single unit around */
@ -1956,7 +1962,7 @@ CommandCost CmdReverseTrainDirection(TileIndex tile, DoCommandFlag flags, uint32
return_cmd_error(STR_ONLY_TURN_SINGLE_UNIT); return_cmd_error(STR_ONLY_TURN_SINGLE_UNIT);
} }
Vehicle *front = v->First(); Train *front = v->First();
/* make sure the vehicle is stopped in the depot */ /* make sure the vehicle is stopped in the depot */
if (CheckTrainStoppedInDepot(front) < 0) { if (CheckTrainStoppedInDepot(front) < 0) {
return_cmd_error(STR_ERROR_TRAINS_CAN_ONLY_BE_ALTERED_INSIDE_A_DEPOT); return_cmd_error(STR_ERROR_TRAINS_CAN_ONLY_BE_ALTERED_INSIDE_A_DEPOT);
@ -2007,7 +2013,7 @@ CommandCost CmdForceTrainProceed(TileIndex tile, DoCommandFlag flags, uint32 p1,
Vehicle *v = Vehicle::GetIfValid(p1); Vehicle *v = Vehicle::GetIfValid(p1);
if (v == NULL || v->type != VEH_TRAIN || !CheckOwnership(v->owner)) return CMD_ERROR; if (v == NULL || v->type != VEH_TRAIN || !CheckOwnership(v->owner)) return CMD_ERROR;
if (flags & DC_EXEC) v->u.rail.force_proceed = 0x50; if (flags & DC_EXEC) ((Train *)v)->u.rail.force_proceed = 0x50;
return CommandCost(); return CommandCost();
} }
@ -2028,8 +2034,10 @@ CommandCost CmdRefitRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1,
byte new_subtype = GB(p2, 8, 8); byte new_subtype = GB(p2, 8, 8);
bool only_this = HasBit(p2, 16); bool only_this = HasBit(p2, 16);
Vehicle *v = Vehicle::GetIfValid(p1); Vehicle *vt = Vehicle::GetIfValid(p1);
if (v == NULL || v->type != VEH_TRAIN || !CheckOwnership(v->owner)) return CMD_ERROR; if (vt == NULL || vt->type != VEH_TRAIN || !CheckOwnership(vt->owner)) return CMD_ERROR;
Train *v = (Train *)vt;
if (CheckTrainStoppedInDepot(v) < 0) return_cmd_error(STR_TRAIN_MUST_BE_STOPPED); if (CheckTrainStoppedInDepot(v) < 0) return_cmd_error(STR_TRAIN_MUST_BE_STOPPED);
if (v->vehstatus & VS_CRASHED) return_cmd_error(STR_CAN_T_REFIT_DESTROYED_VEHICLE); if (v->vehstatus & VS_CRASHED) return_cmd_error(STR_CAN_T_REFIT_DESTROYED_VEHICLE);
@ -2103,7 +2111,7 @@ CommandCost CmdRefitRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1,
_returned_refit_capacity = num; _returned_refit_capacity = num;
/* Update the train's cached variables */ /* Update the train's cached variables */
if (flags & DC_EXEC) TrainConsistChanged(Vehicle::Get(p1)->First(), false); if (flags & DC_EXEC) TrainConsistChanged((Train *)Vehicle::Get(p1)->First(), false);
return cost; return cost;
} }
@ -2135,7 +2143,7 @@ static bool NtpCallbFindDepot(TileIndex tile, TrainFindDepotData *tfdd, int trac
/** returns the tile of a depot to goto to. The given vehicle must not be /** returns the tile of a depot to goto to. The given vehicle must not be
* crashed! */ * crashed! */
static TrainFindDepotData FindClosestTrainDepot(Vehicle *v, int max_distance) static TrainFindDepotData FindClosestTrainDepot(Train *v, int max_distance)
{ {
assert(!(v->vehstatus & VS_CRASHED)); assert(!(v->vehstatus & VS_CRASHED));
@ -2247,7 +2255,7 @@ static const int8 _vehicle_smoke_pos[8] = {
1, 1, 1, 0, -1, -1, -1, 0 1, 1, 1, 0, -1, -1, -1, 0
}; };
static void HandleLocomotiveSmokeCloud(const Vehicle *v) static void HandleLocomotiveSmokeCloud(const Train *v)
{ {
bool sound = false; bool sound = false;
@ -2255,7 +2263,7 @@ static void HandleLocomotiveSmokeCloud(const Vehicle *v)
return; return;
} }
const Vehicle *u = v; const Train *u = v;
do { do {
const RailVehicleInfo *rvi = RailVehInfo(v->engine_type); const RailVehicleInfo *rvi = RailVehInfo(v->engine_type);
@ -2341,7 +2349,7 @@ void Train::PlayLeaveStationSound() const
} }
/** Check if the train is on the last reserved tile and try to extend the path then. */ /** Check if the train is on the last reserved tile and try to extend the path then. */
static void CheckNextTrainTile(Vehicle *v) static void CheckNextTrainTile(Train *v)
{ {
/* Don't do any look-ahead if path_backoff_interval is 255. */ /* Don't do any look-ahead if path_backoff_interval is 255. */
if (_settings_game.pf.path_backoff_interval == 255) return; if (_settings_game.pf.path_backoff_interval == 255) return;
@ -2378,10 +2386,10 @@ static void CheckNextTrainTile(Vehicle *v)
} }
} }
static bool CheckTrainStayInDepot(Vehicle *v) static bool CheckTrainStayInDepot(Train *v)
{ {
/* bail out if not all wagons are in the same depot or not in a depot at all */ /* bail out if not all wagons are in the same depot or not in a depot at all */
for (const Vehicle *u = v; u != NULL; u = u->Next()) { for (const Train *u = v; u != NULL; u = u->Next()) {
if (u->u.rail.track != TRACK_BIT_DEPOT || u->tile != v->tile) return false; if (u->u.rail.track != TRACK_BIT_DEPOT || u->tile != v->tile) return false;
} }
@ -2454,7 +2462,7 @@ static bool CheckTrainStayInDepot(Vehicle *v)
} }
/** Clear the reservation of a tile that was just left by a wagon on track_dir. */ /** Clear the reservation of a tile that was just left by a wagon on track_dir. */
static void ClearPathReservation(const Vehicle *v, TileIndex tile, Trackdir track_dir) static void ClearPathReservation(const Train *v, TileIndex tile, Trackdir track_dir)
{ {
DiagDirection dir = TrackdirToExitdir(track_dir); DiagDirection dir = TrackdirToExitdir(track_dir);
@ -2488,7 +2496,7 @@ static void ClearPathReservation(const Vehicle *v, TileIndex tile, Trackdir trac
} }
/** Free the reserved path in front of a vehicle. */ /** Free the reserved path in front of a vehicle. */
void FreeTrainTrackReservation(const Vehicle *v, TileIndex origin, Trackdir orig_td) void FreeTrainTrackReservation(const Train *v, TileIndex origin, Trackdir orig_td)
{ {
assert(IsFrontEngine(v)); assert(IsFrontEngine(v));
@ -2613,7 +2621,7 @@ static const byte _pick_track_table[6] = {1, 3, 2, 2, 0, 0};
* @param dest [out] State and destination of the requested path * @param dest [out] State and destination of the requested path
* @return The best track the train should follow * @return The best track the train should follow
*/ */
static Track DoTrainPathfind(Vehicle *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool *path_not_found, bool do_track_reservation, PBSTileInfo *dest) static Track DoTrainPathfind(Train *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool *path_not_found, bool do_track_reservation, PBSTileInfo *dest)
{ {
Track best_track; Track best_track;
@ -2714,7 +2722,7 @@ static Track DoTrainPathfind(Vehicle *v, TileIndex tile, DiagDirection enterdir,
* another reservation or a track choice. * another reservation or a track choice.
* @return INVALID_TILE indicates that the reservation failed. * @return INVALID_TILE indicates that the reservation failed.
*/ */
static PBSTileInfo ExtendTrainReservation(const Vehicle *v, TrackBits *new_tracks, DiagDirection *enterdir) static PBSTileInfo ExtendTrainReservation(const Train *v, TrackBits *new_tracks, DiagDirection *enterdir)
{ {
bool no_90deg_turns = _settings_game.pf.pathfinder_for_trains != VPF_NTP && _settings_game.pf.forbid_90_deg; bool no_90deg_turns = _settings_game.pf.pathfinder_for_trains != VPF_NTP && _settings_game.pf.forbid_90_deg;
PBSTileInfo origin = FollowTrainReservation(v); PBSTileInfo origin = FollowTrainReservation(v);
@ -2807,7 +2815,7 @@ static PBSTileInfo ExtendTrainReservation(const Vehicle *v, TrackBits *new_track
* @param override_tailtype Whether all physically compatible railtypes should be followed. * @param override_tailtype Whether all physically compatible railtypes should be followed.
* @return True if a path to a safe stopping tile could be reserved. * @return True if a path to a safe stopping tile could be reserved.
*/ */
static bool TryReserveSafeTrack(const Vehicle *v, TileIndex tile, Trackdir td, bool override_tailtype) static bool TryReserveSafeTrack(const Train *v, TileIndex tile, Trackdir td, bool override_tailtype)
{ {
if (_settings_game.pf.pathfinder_for_trains == VPF_YAPF) { if (_settings_game.pf.pathfinder_for_trains == VPF_YAPF) {
return YapfRailFindNearestSafeTile(v, tile, td, override_tailtype); return YapfRailFindNearestSafeTile(v, tile, td, override_tailtype);
@ -2896,7 +2904,7 @@ public:
}; };
/* choose a track */ /* choose a track */
static Track ChooseTrainTrack(Vehicle *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool force_res, bool *got_reservation, bool mark_stuck) static Track ChooseTrainTrack(Train *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool force_res, bool *got_reservation, bool mark_stuck)
{ {
Track best_track = INVALID_TRACK; Track best_track = INVALID_TRACK;
bool do_track_reservation = _settings_game.pf.reserve_paths || force_res; bool do_track_reservation = _settings_game.pf.reserve_paths || force_res;
@ -3075,7 +3083,7 @@ static Track ChooseTrainTrack(Vehicle *v, TileIndex tile, DiagDirection enterdir
* @param first_tile_okay True if no path should be reserved if the current tile is a safe position. * @param first_tile_okay True if no path should be reserved if the current tile is a safe position.
* @return True if a path could be reserved. * @return True if a path could be reserved.
*/ */
bool TryPathReserve(Vehicle *v, bool mark_as_stuck, bool first_tile_okay) bool TryPathReserve(Train *v, bool mark_as_stuck, bool first_tile_okay)
{ {
assert(v->type == VEH_TRAIN && IsFrontEngine(v)); assert(v->type == VEH_TRAIN && IsFrontEngine(v));
@ -3155,7 +3163,7 @@ bool TryPathReserve(Vehicle *v, bool mark_as_stuck, bool first_tile_okay)
} }
static bool CheckReverseTrain(Vehicle *v) static bool CheckReverseTrain(Train *v)
{ {
if (_settings_game.difficulty.line_reverse_mode != 0 || if (_settings_game.difficulty.line_reverse_mode != 0 ||
v->u.rail.track == TRACK_BIT_DEPOT || v->u.rail.track == TRACK_BIT_WORMHOLE || v->u.rail.track == TRACK_BIT_DEPOT || v->u.rail.track == TRACK_BIT_WORMHOLE ||
@ -3295,7 +3303,7 @@ void Train::MarkDirty()
* @param v The vehicle to update the speed of. * @param v The vehicle to update the speed of.
* @return distance to drive. * @return distance to drive.
*/ */
static int UpdateTrainSpeed(Vehicle *v) static int UpdateTrainSpeed(Train *v)
{ {
uint accel; uint accel;
@ -3340,7 +3348,7 @@ static int UpdateTrainSpeed(Vehicle *v)
return scaled_spd; return scaled_spd;
} }
static void TrainEnterStation(Vehicle *v, StationID station) static void TrainEnterStation(Train *v, StationID station)
{ {
v->last_station_visited = station; v->last_station_visited = station;
@ -3363,7 +3371,7 @@ static void TrainEnterStation(Vehicle *v, StationID station)
StationAnimationTrigger(st, v->tile, STAT_ANIM_TRAIN_ARRIVES); StationAnimationTrigger(st, v->tile, STAT_ANIM_TRAIN_ARRIVES);
} }
static byte AfterSetTrainPos(Vehicle *v, bool new_tile) static byte AfterSetTrainPos(Train *v, bool new_tile)
{ {
byte old_z = v->z_pos; byte old_z = v->z_pos;
v->z_pos = GetSlopeZ(v->x_pos, v->y_pos); v->z_pos = GetSlopeZ(v->x_pos, v->y_pos);
@ -3396,7 +3404,7 @@ static byte AfterSetTrainPos(Vehicle *v, bool new_tile)
} }
/* Check if the vehicle is compatible with the specified tile */ /* Check if the vehicle is compatible with the specified tile */
static inline bool CheckCompatibleRail(const Vehicle *v, TileIndex tile) static inline bool CheckCompatibleRail(const Train *v, TileIndex tile)
{ {
return return
IsTileOwner(tile, v->owner) && ( IsTileOwner(tile, v->owner) && (
@ -3420,7 +3428,7 @@ static const RailtypeSlowdownParams _railtype_slowdown[] = {
}; };
/** Modify the speed of the vehicle due to a turn */ /** Modify the speed of the vehicle due to a turn */
static inline void AffectSpeedByDirChange(Vehicle *v, Direction new_dir) static inline void AffectSpeedByDirChange(Train *v, Direction new_dir)
{ {
if (_settings_game.vehicle.train_acceleration_model != TAM_ORIGINAL) return; if (_settings_game.vehicle.train_acceleration_model != TAM_ORIGINAL) return;
@ -3432,7 +3440,7 @@ static inline void AffectSpeedByDirChange(Vehicle *v, Direction new_dir)
} }
/** Modify the speed of the vehicle due to a change in altitude */ /** Modify the speed of the vehicle due to a change in altitude */
static inline void AffectSpeedByZChange(Vehicle *v, byte old_z) static inline void AffectSpeedByZChange(Train *v, byte old_z)
{ {
if (old_z == v->z_pos || _settings_game.vehicle.train_acceleration_model != TAM_ORIGINAL) return; if (old_z == v->z_pos || _settings_game.vehicle.train_acceleration_model != TAM_ORIGINAL) return;
@ -3461,7 +3469,7 @@ static bool TrainMovedChangeSignals(TileIndex tile, DiagDirection dir)
} }
static void SetVehicleCrashed(Vehicle *v) static void SetVehicleCrashed(Train *v)
{ {
if (v->u.rail.crash_anim_pos != 0) return; if (v->u.rail.crash_anim_pos != 0) return;
@ -3470,7 +3478,7 @@ static void SetVehicleCrashed(Vehicle *v)
/* Remove all reservations, also the ones currently under the train /* Remove all reservations, also the ones currently under the train
* and any railway station paltform reservation. */ * and any railway station paltform reservation. */
FreeTrainTrackReservation(v); FreeTrainTrackReservation(v);
for (const Vehicle *u = v; u != NULL; u = u->Next()) { for (const Train *u = v; u != NULL; u = u->Next()) {
ClearPathReservation(u, u->tile, u->GetVehicleTrackdir()); ClearPathReservation(u, u->tile, u->GetVehicleTrackdir());
if (IsTileType(u->tile, MP_TUNNELBRIDGE)) { if (IsTileType(u->tile, MP_TUNNELBRIDGE)) {
/* ClearPathReservation will not free the wormhole exit /* ClearPathReservation will not free the wormhole exit
@ -3503,7 +3511,7 @@ static void SetVehicleCrashed(Vehicle *v)
if (crossing != INVALID_TILE) UpdateLevelCrossing(crossing); if (crossing != INVALID_TILE) UpdateLevelCrossing(crossing);
} }
static uint CountPassengersInTrain(const Vehicle *v) static uint CountPassengersInTrain(const Train *v)
{ {
uint num = 0; uint num = 0;
@ -3520,7 +3528,7 @@ static uint CountPassengersInTrain(const Vehicle *v)
* @param v first vehicle of chain * @param v first vehicle of chain
* @return number of victims (including 2 drivers; zero if train was already crashed) * @return number of victims (including 2 drivers; zero if train was already crashed)
*/ */
static uint TrainCrashed(Vehicle *v) static uint TrainCrashed(Train *v)
{ {
/* do not crash train twice */ /* do not crash train twice */
if (v->vehstatus & VS_CRASHED) return 0; if (v->vehstatus & VS_CRASHED) return 0;
@ -3549,7 +3557,7 @@ static Vehicle *FindTrainCollideEnum(Vehicle *v, void *data)
Vehicle *coll = v->First(); Vehicle *coll = v->First();
/* can't collide with own wagons && can't crash in depot && the same height level */ /* can't collide with own wagons && can't crash in depot && the same height level */
if (coll != tcc->v && v->u.rail.track != TRACK_BIT_DEPOT && abs(v->z_pos - tcc->v->z_pos) < 6) { if (coll != tcc->v && ((Train *)v)->u.rail.track != TRACK_BIT_DEPOT && abs(v->z_pos - tcc->v->z_pos) < 6) {
int x_diff = v->x_pos - tcc->v->x_pos; int x_diff = v->x_pos - tcc->v->x_pos;
int y_diff = v->y_pos - tcc->v->y_pos; int y_diff = v->y_pos - tcc->v->y_pos;
@ -3557,15 +3565,15 @@ static Vehicle *FindTrainCollideEnum(Vehicle *v, void *data)
if (x_diff * x_diff + y_diff * y_diff > 25) return NULL; if (x_diff * x_diff + y_diff * y_diff > 25) return NULL;
/* crash both trains */ /* crash both trains */
tcc->num += TrainCrashed(tcc->v); tcc->num += TrainCrashed((Train *)tcc->v);
tcc->num += TrainCrashed(coll); tcc->num += TrainCrashed((Train *)coll);
/* Try to reserve all tiles directly under the crashed trains. /* Try to reserve all tiles directly under the crashed trains.
* As there might be more than two trains involved, we have to do that for all vehicles */ * As there might be more than two trains involved, we have to do that for all vehicles */
const Vehicle *u; const Vehicle *u;
FOR_ALL_VEHICLES(u) { FOR_ALL_VEHICLES(u) {
if (u->type == VEH_TRAIN && HASBITS(u->vehstatus, VS_CRASHED) && (u->u.rail.track & TRACK_BIT_DEPOT) == TRACK_BIT_NONE) { if (u->type == VEH_TRAIN && HASBITS(u->vehstatus, VS_CRASHED) && (((Train *)u)->u.rail.track & TRACK_BIT_DEPOT) == TRACK_BIT_NONE) {
TrackBits trackbits = u->u.rail.track; TrackBits trackbits = ((Train *)u)->u.rail.track;
if ((trackbits & TRACK_BIT_WORMHOLE) == TRACK_BIT_WORMHOLE) { if ((trackbits & TRACK_BIT_WORMHOLE) == TRACK_BIT_WORMHOLE) {
/* Vehicle is inside a wormhole, v->u.rail.track contains no useful value then. */ /* Vehicle is inside a wormhole, v->u.rail.track contains no useful value then. */
trackbits |= DiagDirToDiagTrackBits(GetTunnelBridgeDirection(u->tile)); trackbits |= DiagDirToDiagTrackBits(GetTunnelBridgeDirection(u->tile));
@ -3584,7 +3592,7 @@ static Vehicle *FindTrainCollideEnum(Vehicle *v, void *data)
* Reports the incident in a flashy news item, modifies station ratings and * Reports the incident in a flashy news item, modifies station ratings and
* plays a sound. * plays a sound.
*/ */
static bool CheckTrainCollision(Vehicle *v) static bool CheckTrainCollision(Train *v)
{ {
/* can't collide in depot */ /* can't collide in depot */
if (v->u.rail.track == TRACK_BIT_DEPOT) return false; if (v->u.rail.track == TRACK_BIT_DEPOT) return false;
@ -3623,16 +3631,16 @@ static Vehicle *CheckVehicleAtSignal(Vehicle *v, void *data)
DiagDirection exitdir = *(DiagDirection *)data; DiagDirection exitdir = *(DiagDirection *)data;
/* front engine of a train, not inside wormhole or depot, not crashed */ /* front engine of a train, not inside wormhole or depot, not crashed */
if (v->type == VEH_TRAIN && IsFrontEngine(v) && (v->u.rail.track & TRACK_BIT_MASK) != 0 && !(v->vehstatus & VS_CRASHED)) { if (v->type == VEH_TRAIN && IsFrontEngine(v) && (((Train *)v)->u.rail.track & TRACK_BIT_MASK) != 0 && !(v->vehstatus & VS_CRASHED)) {
if (v->cur_speed <= 5 && TrainExitDir(v->direction, v->u.rail.track) == exitdir) return v; if (v->cur_speed <= 5 && TrainExitDir(v->direction, ((Train *)v)->u.rail.track) == exitdir) return v;
} }
return NULL; return NULL;
} }
static void TrainController(Vehicle *v, Vehicle *nomove) static void TrainController(Train *v, Vehicle *nomove)
{ {
Vehicle *prev; Train *prev;
/* For every vehicle after and including the given vehicle */ /* For every vehicle after and including the given vehicle */
for (prev = v->Previous(); v != nomove; prev = v, v = v->Next()) { for (prev = v->Previous(); v != nomove; prev = v, v = v->Next()) {
@ -3922,11 +3930,11 @@ static Vehicle *CollectTrackbitsFromCrashedVehiclesEnum(Vehicle *v, void *data)
TrackBits *trackbits = (TrackBits *)data; TrackBits *trackbits = (TrackBits *)data;
if (v->type == VEH_TRAIN && (v->vehstatus & VS_CRASHED) != 0) { if (v->type == VEH_TRAIN && (v->vehstatus & VS_CRASHED) != 0) {
if ((v->u.rail.track & TRACK_BIT_WORMHOLE) == TRACK_BIT_WORMHOLE) { if ((((Train *)v)->u.rail.track & TRACK_BIT_WORMHOLE) == TRACK_BIT_WORMHOLE) {
/* Vehicle is inside a wormhole, v->u.rail.track contains no useful value then. */ /* Vehicle is inside a wormhole, v->u.rail.track contains no useful value then. */
*trackbits |= DiagDirToDiagTrackBits(GetTunnelBridgeDirection(v->tile)); *trackbits |= DiagDirToDiagTrackBits(GetTunnelBridgeDirection(v->tile));
} else { } else {
*trackbits |= v->u.rail.track; *trackbits |= ((Train *)v)->u.rail.track;
} }
} }
@ -3940,14 +3948,14 @@ static Vehicle *CollectTrackbitsFromCrashedVehiclesEnum(Vehicle *v, void *data)
* or inside a tunnel/bridge, recalculate the signals as they might need updating * or inside a tunnel/bridge, recalculate the signals as they might need updating
* @param v the Vehicle of which last wagon is to be removed * @param v the Vehicle of which last wagon is to be removed
*/ */
static void DeleteLastWagon(Vehicle *v) static void DeleteLastWagon(Train *v)
{ {
Vehicle *first = v->First(); Train *first = v->First();
/* Go to the last wagon and delete the link pointing there /* Go to the last wagon and delete the link pointing there
* *u is then the one-before-last wagon, and *v the last * *u is then the one-before-last wagon, and *v the last
* one which will physicially be removed */ * one which will physicially be removed */
Vehicle *u = v; Train *u = v;
for (; v->Next() != NULL; v = v->Next()) u = v; for (; v->Next() != NULL; v = v->Next()) u = v;
u->SetNext(NULL); u->SetNext(NULL);
@ -4002,7 +4010,7 @@ static void DeleteLastWagon(Vehicle *v)
} }
} }
static void ChangeTrainDirRandomly(Vehicle *v) static void ChangeTrainDirRandomly(Train *v)
{ {
static const DirDiff delta[] = { static const DirDiff delta[] = {
DIRDIFF_45LEFT, DIRDIFF_SAME, DIRDIFF_SAME, DIRDIFF_45RIGHT DIRDIFF_45LEFT, DIRDIFF_SAME, DIRDIFF_SAME, DIRDIFF_45RIGHT
@ -4022,7 +4030,7 @@ static void ChangeTrainDirRandomly(Vehicle *v)
} while ((v = v->Next()) != NULL); } while ((v = v->Next()) != NULL);
} }
static bool HandleCrashedTrain(Vehicle *v) static bool HandleCrashedTrain(Train *v)
{ {
int state = ++v->u.rail.crash_anim_pos; int state = ++v->u.rail.crash_anim_pos;
@ -4061,7 +4069,7 @@ static bool HandleCrashedTrain(Vehicle *v)
return true; return true;
} }
static void HandleBrokenTrain(Vehicle *v) static void HandleBrokenTrain(Train *v)
{ {
if (v->breakdown_ctr != 1) { if (v->breakdown_ctr != 1) {
v->breakdown_ctr = 1; v->breakdown_ctr = 1;
@ -4105,7 +4113,7 @@ static const uint16 _breakdown_speeds[16] = {
* @param signal not line end, just a red signal * @param signal not line end, just a red signal
* @return true iff we did NOT have to reverse * @return true iff we did NOT have to reverse
*/ */
static bool TrainApproachingLineEnd(Vehicle *v, bool signal) static bool TrainApproachingLineEnd(Train *v, bool signal)
{ {
/* Calc position within the current tile */ /* Calc position within the current tile */
uint x = v->x_pos & 0xF; uint x = v->x_pos & 0xF;
@ -4146,7 +4154,7 @@ static bool TrainApproachingLineEnd(Vehicle *v, bool signal)
* @param v train to test * @param v train to test
* @return true iff vehicle is NOT entering or inside a depot or tunnel/bridge * @return true iff vehicle is NOT entering or inside a depot or tunnel/bridge
*/ */
static bool TrainCanLeaveTile(const Vehicle *v) static bool TrainCanLeaveTile(const Train *v)
{ {
/* Exit if inside a tunnel/bridge or a depot */ /* Exit if inside a tunnel/bridge or a depot */
if (v->u.rail.track == TRACK_BIT_WORMHOLE || v->u.rail.track == TRACK_BIT_DEPOT) return false; if (v->u.rail.track == TRACK_BIT_WORMHOLE || v->u.rail.track == TRACK_BIT_DEPOT) return false;
@ -4176,7 +4184,7 @@ static bool TrainCanLeaveTile(const Vehicle *v)
* @return TileIndex of crossing the train is approaching, else INVALID_TILE * @return TileIndex of crossing the train is approaching, else INVALID_TILE
* @pre v in non-crashed front engine * @pre v in non-crashed front engine
*/ */
static TileIndex TrainApproachingCrossingTile(const Vehicle *v) static TileIndex TrainApproachingCrossingTile(const Train *v)
{ {
assert(IsFrontEngine(v)); assert(IsFrontEngine(v));
assert(!(v->vehstatus & VS_CRASHED)); assert(!(v->vehstatus & VS_CRASHED));
@ -4202,7 +4210,7 @@ static TileIndex TrainApproachingCrossingTile(const Vehicle *v)
* @param v vehicle we are checking * @param v vehicle we are checking
* @return true iff we did NOT have to reverse * @return true iff we did NOT have to reverse
*/ */
static bool TrainCheckIfLineEnds(Vehicle *v) static bool TrainCheckIfLineEnds(Train *v)
{ {
/* First, handle broken down train */ /* First, handle broken down train */
@ -4253,7 +4261,7 @@ static bool TrainCheckIfLineEnds(Vehicle *v)
} }
static bool TrainLocoHandler(Vehicle *v, bool mode) static bool TrainLocoHandler(Train *v, bool mode)
{ {
/* train has crashed? */ /* train has crashed? */
if (v->vehstatus & VS_CRASHED) { if (v->vehstatus & VS_CRASHED) {
@ -4381,7 +4389,7 @@ static bool TrainLocoHandler(Vehicle *v, bool mode)
SetLastSpeed(v, v->cur_speed); SetLastSpeed(v, v->cur_speed);
} }
for (Vehicle *u = v; u != NULL; u = u->Next()) { for (Train *u = v; u != NULL; u = u->Next()) {
if ((u->vehstatus & VS_HIDDEN) != 0) continue; if ((u->vehstatus & VS_HIDDEN) != 0) continue;
uint16 old_image = u->cur_image; uint16 old_image = u->cur_image;
@ -4399,7 +4407,7 @@ static bool TrainLocoHandler(Vehicle *v, bool mode)
Money Train::GetRunningCost() const Money Train::GetRunningCost() const
{ {
Money cost = 0; Money cost = 0;
const Vehicle *v = this; const Train *v = this;
do { do {
const RailVehicleInfo *rvi = RailVehInfo(v->engine_type); const RailVehicleInfo *rvi = RailVehInfo(v->engine_type);
@ -4448,7 +4456,7 @@ bool Train::Tick()
return true; return true;
} }
static void CheckIfTrainNeedsService(Vehicle *v) static void CheckIfTrainNeedsService(Train *v)
{ {
static const uint MAX_ACCEPTABLE_DEPOT_DIST = 16; static const uint MAX_ACCEPTABLE_DEPOT_DIST = 16;

View File

@ -28,7 +28,7 @@ void CcBuildWagon(bool success, TileIndex tile, uint32 p1, uint32 p2)
FOR_ALL_VEHICLES(v) { FOR_ALL_VEHICLES(v) {
if (v->type == VEH_TRAIN && IsFrontEngine(v) && if (v->type == VEH_TRAIN && IsFrontEngine(v) &&
v->tile == tile && v->tile == tile &&
v->u.rail.track == TRACK_BIT_DEPOT) { ((Train *)v)->u.rail.track == TRACK_BIT_DEPOT) {
if (found != NULL) return; // must be exactly one. if (found != NULL) return; // must be exactly one.
found = v; found = v;
} }

View File

@ -647,7 +647,7 @@ static CommandCost DoClearTunnel(TileIndex tile, DoCommandFlag flags)
Track track = DiagDirToDiagTrack(dir); Track track = DiagDirToDiagTrack(dir);
Owner owner = GetTileOwner(tile); Owner owner = GetTileOwner(tile);
Vehicle *v = NULL; Train *v = NULL;
if (GetTunnelBridgeReservation(tile)) { if (GetTunnelBridgeReservation(tile)) {
v = GetTrainForReservation(tile, track); v = GetTrainForReservation(tile, track);
if (v != NULL) FreeTrainTrackReservation(v); if (v != NULL) FreeTrainTrackReservation(v);
@ -711,7 +711,7 @@ static CommandCost DoClearBridge(TileIndex tile, DoCommandFlag flags)
bool rail = GetTunnelBridgeTransportType(tile) == TRANSPORT_RAIL; bool rail = GetTunnelBridgeTransportType(tile) == TRANSPORT_RAIL;
Owner owner = GetTileOwner(tile); Owner owner = GetTileOwner(tile);
uint height = GetBridgeHeight(tile); uint height = GetBridgeHeight(tile);
Vehicle *v = NULL; Train *v = NULL;
if (rail && GetTunnelBridgeReservation(tile)) { if (rail && GetTunnelBridgeReservation(tile)) {
v = GetTrainForReservation(tile, DiagDirToDiagTrack(direction)); v = GetTrainForReservation(tile, DiagDirToDiagTrack(direction));
@ -1385,31 +1385,32 @@ static VehicleEnterTileStatus VehicleEnter_TunnelBridge(Vehicle *v, TileIndex ti
DiagDirection vdir; DiagDirection vdir;
if (v->type == VEH_TRAIN) { if (v->type == VEH_TRAIN) {
Train *t = (Train *)v;
fc = (x & 0xF) + (y << 4); fc = (x & 0xF) + (y << 4);
vdir = DirToDiagDir(v->direction); vdir = DirToDiagDir(t->direction);
if (v->u.rail.track != TRACK_BIT_WORMHOLE && dir == vdir) { if (t->u.rail.track != TRACK_BIT_WORMHOLE && dir == vdir) {
if (IsFrontEngine(v) && fc == _tunnel_fractcoord_1[dir]) { if (IsFrontEngine(t) && fc == _tunnel_fractcoord_1[dir]) {
if (!PlayVehicleSound(v, VSE_TUNNEL) && RailVehInfo(v->engine_type)->engclass == 0) { if (!PlayVehicleSound(t, VSE_TUNNEL) && RailVehInfo(t->engine_type)->engclass == 0) {
SndPlayVehicleFx(SND_05_TRAIN_THROUGH_TUNNEL, v); SndPlayVehicleFx(SND_05_TRAIN_THROUGH_TUNNEL, v);
} }
return VETSB_CONTINUE; return VETSB_CONTINUE;
} }
if (fc == _tunnel_fractcoord_2[dir]) { if (fc == _tunnel_fractcoord_2[dir]) {
v->tile = tile; t->tile = tile;
v->u.rail.track = TRACK_BIT_WORMHOLE; t->u.rail.track = TRACK_BIT_WORMHOLE;
v->vehstatus |= VS_HIDDEN; t->vehstatus |= VS_HIDDEN;
return VETSB_ENTERED_WORMHOLE; return VETSB_ENTERED_WORMHOLE;
} }
} }
if (dir == ReverseDiagDir(vdir) && fc == _tunnel_fractcoord_3[dir] && z == 0) { if (dir == ReverseDiagDir(vdir) && fc == _tunnel_fractcoord_3[dir] && z == 0) {
/* We're at the tunnel exit ?? */ /* We're at the tunnel exit ?? */
v->tile = tile; t->tile = tile;
v->u.rail.track = (TrackBits)_exit_tunnel_track[dir]; t->u.rail.track = (TrackBits)_exit_tunnel_track[dir];
assert(v->u.rail.track); assert(t->u.rail.track);
v->vehstatus &= ~VS_HIDDEN; t->vehstatus &= ~VS_HIDDEN;
return VETSB_ENTERED_WORMHOLE; return VETSB_ENTERED_WORMHOLE;
} }
} else if (v->type == VEH_ROAD) { } else if (v->type == VEH_ROAD) {
@ -1462,11 +1463,12 @@ static VehicleEnterTileStatus VehicleEnter_TunnelBridge(Vehicle *v, TileIndex ti
case DIAGDIR_NW: if ((y & 0xF) != 0) return VETSB_CONTINUE; break; case DIAGDIR_NW: if ((y & 0xF) != 0) return VETSB_CONTINUE; break;
} }
switch (v->type) { switch (v->type) {
case VEH_TRAIN: case VEH_TRAIN: {
v->u.rail.track = TRACK_BIT_WORMHOLE; Train *t = (Train *)v;
ClrBit(v->u.rail.flags, VRF_GOINGUP); t->u.rail.track = TRACK_BIT_WORMHOLE;
ClrBit(v->u.rail.flags, VRF_GOINGDOWN); ClrBit(t->u.rail.flags, VRF_GOINGUP);
break; ClrBit(t->u.rail.flags, VRF_GOINGDOWN);
} break;
case VEH_ROAD: case VEH_ROAD:
((RoadVehicle *)v)->state = RVSB_WORMHOLE; ((RoadVehicle *)v)->state = RVSB_WORMHOLE;
@ -1482,12 +1484,13 @@ static VehicleEnterTileStatus VehicleEnter_TunnelBridge(Vehicle *v, TileIndex ti
} else if (DirToDiagDir(v->direction) == ReverseDiagDir(dir)) { } else if (DirToDiagDir(v->direction) == ReverseDiagDir(dir)) {
v->tile = tile; v->tile = tile;
switch (v->type) { switch (v->type) {
case VEH_TRAIN: case VEH_TRAIN: {
if (v->u.rail.track == TRACK_BIT_WORMHOLE) { Train *t = (Train *)v;
v->u.rail.track = (DiagDirToAxis(dir) == AXIS_X ? TRACK_BIT_X : TRACK_BIT_Y); if (t->u.rail.track == TRACK_BIT_WORMHOLE) {
t->u.rail.track = (DiagDirToAxis(dir) == AXIS_X ? TRACK_BIT_X : TRACK_BIT_Y);
return VETSB_ENTERED_WORMHOLE; return VETSB_ENTERED_WORMHOLE;
} }
break; } break;
case VEH_ROAD: { case VEH_ROAD: {
RoadVehicle *rv = (RoadVehicle *)v; RoadVehicle *rv = (RoadVehicle *)v;

View File

@ -982,8 +982,8 @@ void VehicleEnterDepot(Vehicle *v)
if (!IsFrontEngine(v)) v = v->First(); if (!IsFrontEngine(v)) v = v->First();
UpdateSignalsOnSegment(v->tile, INVALID_DIAGDIR, v->owner); UpdateSignalsOnSegment(v->tile, INVALID_DIAGDIR, v->owner);
v->load_unload_time_rem = 0; v->load_unload_time_rem = 0;
ClrBit(v->u.rail.flags, VRF_TOGGLE_REVERSE); ClrBit(((Train *)v)->u.rail.flags, VRF_TOGGLE_REVERSE);
TrainConsistChanged(v, true); TrainConsistChanged((Train *)v, true);
break; break;
case VEH_ROAD: case VEH_ROAD:
@ -1488,7 +1488,7 @@ void Vehicle::LeaveStation()
* might not be marked as wanting a reservation, e.g. * might not be marked as wanting a reservation, e.g.
* when an overlength train gets turned around in a station. */ * when an overlength train gets turned around in a station. */
if (UpdateSignalsOnSegment(this->tile, TrackdirToExitdir(this->GetVehicleTrackdir()), this->owner) == SIGSEG_PBS || _settings_game.pf.reserve_paths) { if (UpdateSignalsOnSegment(this->tile, TrackdirToExitdir(this->GetVehicleTrackdir()), this->owner) == SIGSEG_PBS || _settings_game.pf.reserve_paths) {
TryPathReserve(this, true, true); TryPathReserve((Train *)this, true, true);
} }
} }
} }

View File

@ -46,7 +46,7 @@ enum VehicleFlags {
struct VehicleRail { struct VehicleRail {
/* Link between the two ends of a multiheaded engine */ /* Link between the two ends of a multiheaded engine */
Vehicle *other_multiheaded_part; Train *other_multiheaded_part;
/* Cached wagon override spritegroup */ /* Cached wagon override spritegroup */
const struct SpriteGroup *cached_override; const struct SpriteGroup *cached_override;

View File

@ -152,7 +152,7 @@ CommandCost CmdMassStartStopVehicle(TileIndex tile, DoCommandFlag flags, uint32
if (!vehicle_list_window) { if (!vehicle_list_window) {
if (vehicle_type == VEH_TRAIN) { if (vehicle_type == VEH_TRAIN) {
if (CheckTrainInDepot(v, false) == -1) continue; if (CheckTrainInDepot((Train *)v, false) == -1) continue;
} else { } else {
if (!(v->vehstatus & VS_HIDDEN)) continue; if (!(v->vehstatus & VS_HIDDEN)) continue;
} }
@ -381,8 +381,8 @@ CommandCost CmdCloneVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
w = Vehicle::Get(_new_vehicle_id); w = Vehicle::Get(_new_vehicle_id);
if (v->type == VEH_TRAIN && HasBit(v->u.rail.flags, VRF_REVERSE_DIRECTION)) { if (v->type == VEH_TRAIN && HasBit(((Train *)v)->u.rail.flags, VRF_REVERSE_DIRECTION)) {
SetBit(w->u.rail.flags, VRF_REVERSE_DIRECTION); SetBit(((Train *)w)->u.rail.flags, VRF_REVERSE_DIRECTION);
} }
if (v->type == VEH_TRAIN && !IsFrontEngine(v)) { if (v->type == VEH_TRAIN && !IsFrontEngine(v)) {
@ -403,7 +403,7 @@ CommandCost CmdCloneVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint
} }
w_rear = w; // trains needs to know the last car in the train, so they can add more in next loop w_rear = w; // trains needs to know the last car in the train, so they can add more in next loop
} }
} while (v->type == VEH_TRAIN && (v = GetNextVehicle(v)) != NULL); } while (v->type == VEH_TRAIN && (v = GetNextVehicle((Train *)v)) != NULL);
if (flags & DC_EXEC && v_front->type == VEH_TRAIN) { if (flags & DC_EXEC && v_front->type == VEH_TRAIN) {
/* for trains this needs to be the front engine due to the callback function */ /* for trains this needs to be the front engine due to the callback function */
@ -437,7 +437,7 @@ CommandCost CmdCloneVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint
} }
if (w->type == VEH_TRAIN && EngineHasArticPart(w)) { if (w->type == VEH_TRAIN && EngineHasArticPart(w)) {
w = GetNextArticPart(w); w = GetNextArticPart((Train *)w);
} else if (w->type == VEH_ROAD && RoadVehHasArticPart(w)) { } else if (w->type == VEH_ROAD && RoadVehHasArticPart(w)) {
w = w->Next(); w = w->Next();
} else { } else {
@ -453,7 +453,7 @@ CommandCost CmdCloneVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint
} }
if (v->type == VEH_TRAIN && EngineHasArticPart(v)) { if (v->type == VEH_TRAIN && EngineHasArticPart(v)) {
v = GetNextArticPart(v); v = GetNextArticPart((Train *)v);
} else if (v->type == VEH_ROAD && RoadVehHasArticPart(v)) { } else if (v->type == VEH_ROAD && RoadVehHasArticPart(v)) {
v = v->Next(); v = v->Next();
} else { } else {
@ -461,8 +461,8 @@ CommandCost CmdCloneVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint
} }
} while (v != NULL); } while (v != NULL);
if ((flags & DC_EXEC) && v->type == VEH_TRAIN) w = GetNextVehicle(w); if ((flags & DC_EXEC) && v->type == VEH_TRAIN) w = GetNextVehicle((Train *)w);
} while (v->type == VEH_TRAIN && (v = GetNextVehicle(v)) != NULL); } while (v->type == VEH_TRAIN && (v = GetNextVehicle((Train *)v)) != NULL);
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
/* /*

View File

@ -59,10 +59,6 @@ void MarkSingleVehicleDirty(const Vehicle *v);
UnitID GetFreeUnitNumber(VehicleType type); UnitID GetFreeUnitNumber(VehicleType type);
void TrainConsistChanged(Vehicle *v, bool same_length);
void TrainPowerChanged(Vehicle *v);
Money GetTrainRunningCost(const Vehicle *v);
CommandCost SendAllVehiclesToDepot(VehicleType type, DoCommandFlag flags, bool service, Owner owner, uint16 vlw_flag, uint32 id); CommandCost SendAllVehiclesToDepot(VehicleType type, DoCommandFlag flags, bool service, Owner owner, uint16 vlw_flag, uint32 id);
void VehicleEnterDepot(Vehicle *v); void VehicleEnterDepot(Vehicle *v);

View File

@ -18,6 +18,7 @@
#include "newgrf_text.h" #include "newgrf_text.h"
#include "station_map.h" #include "station_map.h"
#include "roadveh.h" #include "roadveh.h"
#include "train.h"
#include "depot_base.h" #include "depot_base.h"
#include "group_gui.h" #include "group_gui.h"
#include "strings_func.h" #include "strings_func.h"
@ -1468,7 +1469,7 @@ struct VehicleDetailsWindow : Window {
SetDParam(1, v->u.rail.cached_power); SetDParam(1, v->u.rail.cached_power);
SetDParam(0, v->u.rail.cached_weight); SetDParam(0, v->u.rail.cached_weight);
SetDParam(3, v->u.rail.cached_max_te / 1000); SetDParam(3, v->u.rail.cached_max_te / 1000);
DrawString(2, this->width - 2, 25, (_settings_game.vehicle.train_acceleration_model != TAM_ORIGINAL && v->u.rail.railtype != RAILTYPE_MAGLEV) ? DrawString(2, this->width - 2, 25, (_settings_game.vehicle.train_acceleration_model != TAM_ORIGINAL && ((Train *)v)->u.rail.railtype != RAILTYPE_MAGLEV) ?
STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE : STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :
STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED); STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED);
break; break;
@ -1948,7 +1949,7 @@ struct VehicleViewWindow : Window {
} else { // no train } else { // no train
str = STR_VEHICLE_STATUS_STOPPED; str = STR_VEHICLE_STATUS_STOPPED;
} }
} else if (v->type == VEH_TRAIN && HasBit(v->u.rail.flags, VRF_TRAIN_STUCK)) { } else if (v->type == VEH_TRAIN && HasBit(((Train *)v)->u.rail.flags, VRF_TRAIN_STUCK)) {
str = STR_TRAIN_STUCK; str = STR_TRAIN_STUCK;
} else { // vehicle is in a "normal" state, show current order } else { // vehicle is in a "normal" state, show current order
switch (v->current_order.GetType()) { switch (v->current_order.GetType()) {

View File

@ -24,6 +24,10 @@ template <> struct EnumPropsT<VehicleType> : MakeEnumPropsT<VehicleType, byte, V
typedef TinyEnumT<VehicleType> VehicleTypeByte; typedef TinyEnumT<VehicleType> VehicleTypeByte;
struct Vehicle; struct Vehicle;
struct Train;
struct RoadVehicle;
struct Ship;
struct Aircraft;
struct BaseVehicle struct BaseVehicle
{ {

View File

@ -29,7 +29,7 @@ void BuildDepotVehicleList(VehicleType type, TileIndex tile, VehicleList *engine
switch (type) { switch (type) {
case VEH_TRAIN: case VEH_TRAIN:
if (IsArticulatedPart(v) || IsRearDualheaded(v)) continue; if (IsArticulatedPart(v) || IsRearDualheaded(v)) continue;
if (v->u.rail.track != TRACK_BIT_DEPOT) continue; if (((Train *)v)->u.rail.track != TRACK_BIT_DEPOT) continue;
if (wagons != NULL && IsFreeWagon(v->First())) { if (wagons != NULL && IsFreeWagon(v->First())) {
if (individual_wagons || IsFreeWagon(v)) *wagons->Append() = v; if (individual_wagons || IsFreeWagon(v)) *wagons->Append() = v;
continue; continue;

View File

@ -813,7 +813,7 @@ static void FloodVehicle(Vehicle *v)
/* FreeTrainTrackReservation() calls GetVehicleTrackdir() that doesn't like crashed vehicles. /* FreeTrainTrackReservation() calls GetVehicleTrackdir() that doesn't like crashed vehicles.
* In this case, v->direction matches v->u.rail.track, so we can do this (it wasn't crashed before) */ * In this case, v->direction matches v->u.rail.track, so we can do this (it wasn't crashed before) */
v->vehstatus &= ~VS_CRASHED; v->vehstatus &= ~VS_CRASHED;
FreeTrainTrackReservation(v); FreeTrainTrackReservation((Train *)v);
v->vehstatus |= VS_CRASHED; v->vehstatus |= VS_CRASHED;
} }
v->u.rail.crash_anim_pos = 4000; // max 4440, disappear pretty fast v->u.rail.crash_anim_pos = 4000; // max 4440, disappear pretty fast

View File

@ -258,7 +258,7 @@ CommandCost RemoveTrainWaypoint(TileIndex tile, DoCommandFlag flags, bool justre
wp->deleted = 30; // let it live for this many days before we do the actual deletion. wp->deleted = 30; // let it live for this many days before we do the actual deletion.
RedrawWaypointSign(wp); RedrawWaypointSign(wp);
Vehicle *v = NULL; Train *v = NULL;
if (justremove) { if (justremove) {
TrackBits tracks = GetRailWaypointBits(tile); TrackBits tracks = GetRailWaypointBits(tile);
bool reserved = GetDepotWaypointReservation(tile); bool reserved = GetDepotWaypointReservation(tile);

View File

@ -8,6 +8,7 @@
#include "yapf.hpp" #include "yapf.hpp"
#include "../depot_map.h" #include "../depot_map.h"
#include "../roadveh.h" #include "../roadveh.h"
#include "../train.h"
/** Track follower helper template class (can serve pathfinders and vehicle /** Track follower helper template class (can serve pathfinders and vehicle
* controllers). See 6 different typedefs below for 3 different transport * controllers). See 6 different typedefs below for 3 different transport
@ -54,7 +55,7 @@ struct CFollowTrackT
{ {
assert(!IsRailTT() || (v != NULL && v->type == VEH_TRAIN)); assert(!IsRailTT() || (v != NULL && v->type == VEH_TRAIN));
m_veh = v; m_veh = v;
Init(v != NULL ? v->owner : INVALID_OWNER, railtype_override == INVALID_RAILTYPES ? v->u.rail.compatible_railtypes : railtype_override, pPerf); Init(v != NULL ? v->owner : INVALID_OWNER, railtype_override == INVALID_RAILTYPES ? ((Train *)v)->u.rail.compatible_railtypes : railtype_override, pPerf);
} }
FORCEINLINE void Init(Owner o, RailTypes railtype_override, CPerformanceTimer *pPerf) FORCEINLINE void Init(Owner o, RailTypes railtype_override, CPerformanceTimer *pPerf)
@ -105,7 +106,7 @@ struct CFollowTrackT
m_old_tile = old_tile; m_old_tile = old_tile;
m_old_td = old_td; m_old_td = old_td;
m_err = EC_NONE; m_err = EC_NONE;
assert(((TrackStatusToTrackdirBits(GetTileTrackStatus(m_old_tile, TT(), m_veh ? m_veh->u.road.compatible_roadtypes : 0)) & TrackdirToTrackdirBits(m_old_td)) != 0) || assert(((TrackStatusToTrackdirBits(GetTileTrackStatus(m_old_tile, TT(), m_veh ? ((RoadVehicle *)m_veh)->compatible_roadtypes : 0)) & TrackdirToTrackdirBits(m_old_td)) != 0) ||
(IsTram() && GetSingleTramBit(m_old_tile) != INVALID_DIAGDIR)); // Disable the assertion for single tram bits (IsTram() && GetSingleTramBit(m_old_tile) != INVALID_DIAGDIR)); // Disable the assertion for single tram bits
m_exitdir = TrackdirToExitdir(m_old_td); m_exitdir = TrackdirToExitdir(m_old_td);
if (ForcedReverse()) return true; if (ForcedReverse()) return true;

View File

@ -91,8 +91,8 @@ public:
FORCEINLINE bool PfDetectDestination(TileIndex tile, Trackdir td) FORCEINLINE bool PfDetectDestination(TileIndex tile, Trackdir td)
{ {
return return
IsSafeWaitingPosition(Yapf().GetVehicle(), tile, td, true, !TrackFollower::Allow90degTurns()) && IsSafeWaitingPosition((Train *)Yapf().GetVehicle(), tile, td, true, !TrackFollower::Allow90degTurns()) &&
IsWaitingPositionFree(Yapf().GetVehicle(), tile, td, !TrackFollower::Allow90degTurns()); IsWaitingPositionFree((Train *)Yapf().GetVehicle(), tile, td, !TrackFollower::Allow90degTurns());
} }
/** Called by YAPF to calculate cost estimate. Calculates distance to the destination /** Called by YAPF to calculate cost estimate. Calculates distance to the destination

View File

@ -54,7 +54,7 @@ private:
bool FindSafePositionProc(TileIndex tile, Trackdir td) bool FindSafePositionProc(TileIndex tile, Trackdir td)
{ {
if (IsSafeWaitingPosition(Yapf().GetVehicle(), tile, td, true, !TrackFollower::Allow90degTurns())) { if (IsSafeWaitingPosition((Train *)Yapf().GetVehicle(), tile, td, true, !TrackFollower::Allow90degTurns())) {
m_res_dest = tile; m_res_dest = tile;
m_res_dest_td = td; m_res_dest_td = td;
return false; // Stop iterating segment return false; // Stop iterating segment
@ -149,7 +149,7 @@ public:
} }
/* Don't bother if the target is reserved. */ /* Don't bother if the target is reserved. */
if (!IsWaitingPositionFree(Yapf().GetVehicle(), m_res_dest, m_res_dest_td)) return false; if (!IsWaitingPositionFree((Train *)Yapf().GetVehicle(), m_res_dest, m_res_dest_td)) return false;
for (Node *node = m_res_node; node->m_parent != NULL; node = node->m_parent) { for (Node *node = m_res_node; node->m_parent != NULL; node = node->m_parent) {
node->IterateTiles(Yapf().GetVehicle(), Yapf(), *this, &CYapfReserveTrack<Types>::ReserveSingleTrack); node->IterateTiles(Yapf().GetVehicle(), Yapf(), *this, &CYapfReserveTrack<Types>::ReserveSingleTrack);
@ -411,7 +411,7 @@ public:
if (target != NULL) target->tile = INVALID_TILE; if (target != NULL) target->tile = INVALID_TILE;
/* set origin and destination nodes */ /* set origin and destination nodes */
PBSTileInfo origin = FollowTrainReservation(v); PBSTileInfo origin = FollowTrainReservation((Train *)v);
Yapf().SetOrigin(origin.tile, origin.trackdir, INVALID_TILE, INVALID_TRACKDIR, 1, true); Yapf().SetOrigin(origin.tile, origin.trackdir, INVALID_TILE, INVALID_TRACKDIR, 1, true);
Yapf().SetDestination(v); Yapf().SetDestination(v);
@ -534,10 +534,11 @@ Trackdir YapfChooseRailTrack(const Vehicle *v, TileIndex tile, DiagDirection ent
return td_ret; return td_ret;
} }
bool YapfCheckReverseTrain(const Vehicle *v) bool YapfCheckReverseTrain(const Vehicle *vt)
{ {
Train *v = (Train *)vt;
/* last wagon */ /* last wagon */
const Vehicle *last_veh = GetLastVehicleInChain(v); const Train *last_veh = (Train *)GetLastVehicleInChain(v);
/* get trackdirs of both ends */ /* get trackdirs of both ends */
Trackdir td = v->GetVehicleTrackdir(); Trackdir td = v->GetVehicleTrackdir();
@ -601,7 +602,7 @@ bool YapfFindNearestRailDepotTwoWay(const Vehicle *v, int max_distance, int reve
const Vehicle *last_veh = GetLastVehicleInChain(v); const Vehicle *last_veh = GetLastVehicleInChain(v);
PBSTileInfo origin = FollowTrainReservation(v); PBSTileInfo origin = FollowTrainReservation((Train *)v);
TileIndex last_tile = last_veh->tile; TileIndex last_tile = last_veh->tile;
Trackdir td_rev = ReverseTrackdir(last_veh->GetVehicleTrackdir()); Trackdir td_rev = ReverseTrackdir(last_veh->GetVehicleTrackdir());