From a9163d05034a2f6cdddaee8b083d8ee74f26bbde Mon Sep 17 00:00:00 2001 From: rubidium Date: Sat, 3 Apr 2010 19:57:23 +0000 Subject: [PATCH] (svn r19552) [1.0] -Backport from trunk: - Fix: Prevent drawing industries disabled at the smallmap as land tiles when they are built on water (r19523) - Fix: Tunnels, bridges and roadstops are build with only one roadtype (r19506) - Fix: [NewGRF] During NewGRF loading, store rail type labels in temporary data and process after loading has finished. This avoids deactivated rail vehicles being reactivated if the climate property is set after the rail type property (r19502) - Fix: Keep number padding intact when cloning vehicle names [FS#3710] (r19498) --- src/newgrf.cpp | 35 +++++++++++++++++++++++------------ src/rail_type.h | 5 +++++ src/road_func.h | 10 ---------- src/smallmap_gui.cpp | 4 ++-- src/station_cmd.cpp | 2 +- src/tunnelbridge_cmd.cpp | 4 ++-- src/vehicle_cmd.cpp | 7 +++++-- 7 files changed, 38 insertions(+), 29 deletions(-) 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)) {