diff --git a/src/newgrf.cpp b/src/newgrf.cpp index 7fa56609d4..86086dddb4 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -186,6 +186,7 @@ enum { struct GRFTempEngineData { uint16 cargo_allowed; uint16 cargo_disallowed; + RailTypeLabel railtypelabel; bool refitmask_valid; ///< Did the newgrf set any refittability property? If not, default refittability will be applied. uint8 rv_max_speed; ///< Temporary storage of RV prop 15, maximum speed in mph/0.8 }; @@ -527,20 +528,14 @@ static ChangeInfoResult RailVehicleChangeInfo(uint engine, int numinfo, int prop uint8 tracktype = buf->ReadByte(); if (tracktype < _cur_grffile->railtype_max) { - RailType railtype = GetRailTypeByLabel(_cur_grffile->railtype_list[tracktype]); - if (railtype == INVALID_RAILTYPE) { - /* Rail type is not available, so disable this engine */ - ei[i].climates = 0x80; - } else { - rvi[i].railtype = railtype; - } + _gted[e->index].railtypelabel = _cur_grffile->railtype_list[tracktype]; break; } switch (tracktype) { - case 0: rvi->railtype = rvi->engclass >= 2 ? RAILTYPE_ELECTRIC : RAILTYPE_RAIL; break; - case 1: rvi->railtype = RAILTYPE_MONO; break; - case 2: rvi->railtype = RAILTYPE_MAGLEV; break; + case 0: _gted[e->index].railtypelabel = rvi->engclass >= 2 ? RAILTYPE_ELECTRIC_LABEL : RAILTYPE_RAIL_LABEL; break; + case 1: _gted[e->index].railtypelabel = RAILTYPE_MONO_LABEL; break; + case 2: _gted[e->index].railtypelabel = RAILTYPE_MAGLEV_LABEL; break; default: grfmsg(1, "RailVehicleChangeInfo: Invalid track type %d specified, ignoring", tracktype); break; @@ -661,8 +656,8 @@ static ChangeInfoResult RailVehicleChangeInfo(uint engine, int numinfo, int prop if (_cur_grffile->railtype_max == 0) { /* Use traction type to select between normal and electrified * rail only when no translation list is in place. */ - if (rvi->railtype == RAILTYPE_RAIL && engclass >= EC_ELECTRIC) rvi->railtype = RAILTYPE_ELECTRIC; - if (rvi->railtype == RAILTYPE_ELECTRIC && engclass < EC_ELECTRIC) rvi->railtype = RAILTYPE_RAIL; + if (rvi->railtype == RAILTYPE_RAIL && engclass >= EC_ELECTRIC) _gted[e->index].railtypelabel = RAILTYPE_ELECTRIC_LABEL; + if (rvi->railtype == RAILTYPE_ELECTRIC && engclass < EC_ELECTRIC) _gted[e->index].railtypelabel = RAILTYPE_RAIL_LABEL; } rvi->engclass = engclass; @@ -5732,6 +5727,12 @@ static void ResetNewGRFData() /* Allocate temporary refit/cargo class data */ _gted = CallocT(Engine::GetPoolSize()); + /* Fill rail type label temporary data for default trains */ + Engine *e; + FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) { + _gted[e->index].railtypelabel = GetRailTypeInfo(e->u.rail.railtype)->label; + } + /* Reset GRM reservations */ memset(&_grm_engines, 0, sizeof(_grm_engines)); memset(&_grm_cargos, 0, sizeof(_grm_cargos)); @@ -6477,6 +6478,16 @@ static void AfterLoadGRFs() } } + FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) { + RailType railtype = GetRailTypeByLabel(_gted[e->index].railtypelabel); + if (railtype == INVALID_RAILTYPE) { + /* Rail type is not available, so disable this engine */ + e->info.climates = 0x80; + } else { + e->u.rail.railtype = railtype; + } + } + SetYearEngineAgingStops(); FinalisePriceBaseMultipliers(); diff --git a/src/rail_type.h b/src/rail_type.h index 18a7698418..1ad5d96986 100644 --- a/src/rail_type.h +++ b/src/rail_type.h @@ -16,6 +16,11 @@ typedef uint32 RailTypeLabel; +static const RailTypeLabel RAILTYPE_RAIL_LABEL = 'RAIL'; +static const RailTypeLabel RAILTYPE_ELECTRIC_LABEL = 'ELRL'; +static const RailTypeLabel RAILTYPE_MONO_LABEL = 'MONO'; +static const RailTypeLabel RAILTYPE_MAGLEV_LABEL = 'MGLV'; + /** * Enumeration for all possible railtypes. * diff --git a/src/road_func.h b/src/road_func.h index 151ae4e9fe..7303ebff30 100644 --- a/src/road_func.h +++ b/src/road_func.h @@ -28,16 +28,6 @@ static inline bool IsValidRoadType(RoadType rt) return rt == ROADTYPE_ROAD || rt == ROADTYPE_TRAM; } -/** - * Are the given bits pointing to valid roadtypes? - * @param rts the roadtypes to check for validness - * @return true if and only if valid - */ -static inline bool AreValidRoadTypes(RoadTypes rts) -{ - return HasBit(rts, ROADTYPE_ROAD) || HasBit(rts, ROADTYPE_TRAM); -} - /** * Maps a RoadType to the corresponding RoadTypes value * diff --git a/src/smallmap_gui.cpp b/src/smallmap_gui.cpp index 40d238c9b0..77784e0480 100644 --- a/src/smallmap_gui.cpp +++ b/src/smallmap_gui.cpp @@ -392,8 +392,8 @@ static inline uint32 GetSmallMapIndustriesPixels(TileIndex tile, TileType t) if (_legend_from_industries[_industry_to_list_pos[Industry::GetByTile(tile)->type]].show_on_map) { return GetIndustrySpec(Industry::GetByTile(tile)->type)->map_colour * 0x01010101; } else { - /* Otherwise, return the colour of the clear tiles, which will make it disappear */ - t = MP_CLEAR; + /* Otherwise, return the colour which will make it disappear */ + t = (GetWaterClass(tile) == WATER_CLASS_INVALID) ? MP_CLEAR : MP_WATER; } } diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 32ad4fd957..8618f254c6 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -1534,7 +1534,7 @@ CommandCost CmdBuildRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, uin if (distant_join && (!_settings_game.station.distant_join_stations || !Station::IsValidID(station_to_join))) return CMD_ERROR; - if (!AreValidRoadTypes(rts) || !HasRoadTypesAvail(_current_company, rts)) return CMD_ERROR; + if (!HasExactlyOneBit(rts) || !HasRoadTypesAvail(_current_company, rts)) return CMD_ERROR; /* Trams only have drive through stops */ if (!is_drive_through && HasBit(rts, ROADTYPE_TRAM)) return CMD_ERROR; diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp index f8bf9d2a6f..149e1cc436 100644 --- a/src/tunnelbridge_cmd.cpp +++ b/src/tunnelbridge_cmd.cpp @@ -206,7 +206,7 @@ CommandCost CmdBuildBridge(TileIndex end_tile, DoCommandFlag flags, uint32 p1, u switch (transport_type) { case TRANSPORT_ROAD: roadtypes = (RoadTypes)GB(p2, 8, 2); - if (!AreValidRoadTypes(roadtypes) || !HasRoadTypesAvail(_current_company, roadtypes)) return CMD_ERROR; + if (!HasExactlyOneBit(roadtypes) || !HasRoadTypesAvail(_current_company, roadtypes)) return CMD_ERROR; break; case TRANSPORT_RAIL: @@ -485,7 +485,7 @@ CommandCost CmdBuildTunnel(TileIndex start_tile, DoCommandFlag flags, uint32 p1, if (!ValParamRailtype((RailType)p1)) return CMD_ERROR; } else { const RoadTypes rts = (RoadTypes)GB(p1, 0, 2); - if (!AreValidRoadTypes(rts) || !HasRoadTypesAvail(_current_company, rts)) return CMD_ERROR; + if (!HasExactlyOneBit(rts) || !HasRoadTypesAvail(_current_company, rts)) return CMD_ERROR; } uint start_z; diff --git a/src/vehicle_cmd.cpp b/src/vehicle_cmd.cpp index 2999816636..12b6e8c63f 100644 --- a/src/vehicle_cmd.cpp +++ b/src/vehicle_cmd.cpp @@ -350,6 +350,7 @@ static void CloneVehicleName(const Vehicle *src, Vehicle *dst) /* Format buffer and determine starting number. */ int num; + byte padding = 0; if (number_position == strlen(src->name)) { /* No digit at the end, so start at number 2. */ strecpy(buf, src->name, lastof(buf)); @@ -360,13 +361,15 @@ static void CloneVehicleName(const Vehicle *src, Vehicle *dst) /* Found digits, parse them and start at the next number. */ strecpy(buf, src->name, lastof(buf)); buf[number_position] = '\0'; - num = strtol(&src->name[number_position], NULL, 10) + 1; + char *endptr; + num = strtol(&src->name[number_position], &endptr, 10) + 1; + padding = endptr - &src->name[number_position]; } /* Check if this name is already taken. */ for (int max_iterations = 1000; max_iterations > 0; max_iterations--, num++) { /* Attach the number to the temporary name. */ - seprintf(&buf[number_position], lastof(buf), "%d", num); + seprintf(&buf[number_position], lastof(buf), "%0*d", padding, num); /* Check the name is unique. */ if (IsUniqueVehicleName(buf)) {