/** * Return if the tile is a valid tile for a crossing. * * @param tile the curent tile * @param ax the axis of the road over the rail * @return true if it is a valid tile */ static bool IsPossibleCrossing(const TileIndex tile, Axis ax) { return (IsTileType(tile, MP_RAILWAY) && GetRailTileType(tile) == RAIL_TILE_NORMAL && GetTrackBits(tile) == (ax == AXIS_X ? TRACK_BIT_Y : TRACK_BIT_X) && GetFoundationSlope(tile) == SLOPE_FLAT); }
/** * Get the axis for a new waypoint. This means that if it is a valid * tile to build a waypoint on it returns a valid Axis, otherwise an * invalid one. * @param tile the tile to look at. * @return the axis for the to-be-build waypoint. */ Axis GetAxisForNewWaypoint(TileIndex tile) { /* The axis for rail waypoints is easy. */ if (IsRailWaypointTile(tile)) return GetRailStationAxis(tile); /* Non-plain rail type, no valid axis for waypoints. */ if (!IsTileType(tile, MP_RAILWAY) || GetRailTileType(tile) != RAIL_TILE_NORMAL) return INVALID_AXIS; switch (GetTrackBits(tile)) { case TRACK_BIT_X: return AXIS_X; case TRACK_BIT_Y: return AXIS_Y; default: return INVALID_AXIS; } }
/** * Perform all steps to upgrade from the old waypoints to the new version * that uses station. This includes some old saveload mechanics. */ void MoveWaypointsToBaseStations() { /* In version 17, ground type is moved from m2 to m4 for depots and * waypoints to make way for storing the index in m2. The custom graphics * id which was stored in m4 is now saved as a grf/id reference in the * waypoint struct. */ if (IsSavegameVersionBefore(17)) { for (OldWaypoint *wp = _old_waypoints.Begin(); wp != _old_waypoints.End(); wp++) { if (wp->delete_ctr != 0) continue; // The waypoint was deleted /* Waypoint indices were not added to the map prior to this. */ _m[wp->xy].m2 = (StationID)wp->index; if (HasBit(_m[wp->xy].m3, 4)) { wp->spec = StationClass::Get(STAT_CLASS_WAYP, _m[wp->xy].m4 + 1); } } } else { /* As of version 17, we recalculate the custom graphic ID of waypoints * from the GRF ID / station index. */ for (OldWaypoint *wp = _old_waypoints.Begin(); wp != _old_waypoints.End(); wp++) { for (uint i = 0; i < StationClass::GetCount(STAT_CLASS_WAYP); i++) { const StationSpec *statspec = StationClass::Get(STAT_CLASS_WAYP, i); if (statspec != NULL && statspec->grf_prop.grffile->grfid == wp->grfid && statspec->grf_prop.local_id == wp->localidx) { wp->spec = statspec; break; } } } } if (!Waypoint::CanAllocateItem(_old_waypoints.Length())) SlError(STR_ERROR_TOO_MANY_STATIONS_LOADING); /* All saveload conversions have been done. Create the new waypoints! */ for (OldWaypoint *wp = _old_waypoints.Begin(); wp != _old_waypoints.End(); wp++) { Waypoint *new_wp = new Waypoint(wp->xy); new_wp->town = wp->town; new_wp->town_cn = wp->town_cn; new_wp->name = wp->name; new_wp->delete_ctr = 0; // Just reset delete counter for once. new_wp->build_date = wp->build_date; new_wp->owner = wp->owner; new_wp->string_id = STR_SV_STNAME_WAYPOINT; TileIndex t = wp->xy; if (IsTileType(t, MP_RAILWAY) && GetRailTileType(t) == 2 /* RAIL_TILE_WAYPOINT */ && _m[t].m2 == wp->index) { /* The tile might've been reserved! */ bool reserved = !IsSavegameVersionBefore(100) && HasBit(_m[t].m5, 4); /* The tile really has our waypoint, so reassign the map array */ MakeRailWaypoint(t, GetTileOwner(t), new_wp->index, (Axis)GB(_m[t].m5, 0, 1), 0, GetRailType(t)); new_wp->facilities |= FACIL_TRAIN; new_wp->owner = GetTileOwner(t); SetRailStationReservation(t, reserved); if (wp->spec != NULL) { SetCustomStationSpecIndex(t, AllocateSpecToStation(wp->spec, new_wp, true)); } new_wp->rect.BeforeAddTile(t, StationRect::ADD_FORCE); } wp->new_index = new_wp->index; } /* Update the orders of vehicles */ OrderList *ol; FOR_ALL_ORDER_LISTS(ol) { if (ol->GetFirstSharedVehicle()->type != VEH_TRAIN) continue; for (Order *o = ol->GetFirstOrder(); o != NULL; o = o->next) UpdateWaypointOrder(o); } Vehicle *v; FOR_ALL_VEHICLES(v) { if (v->type != VEH_TRAIN) continue; UpdateWaypointOrder(&v->current_order); } _old_waypoints.Reset(); }