From 9931557d89fcd86169ba71f9909c5a63134e4148 Mon Sep 17 00:00:00 2001 From: rubidium Date: Tue, 16 Mar 2010 20:54:26 +0000 Subject: [PATCH] (svn r19439) [1.0] -Backport from trunk: - Fix: Custom group names are misaligned with default ones when using rtl languages [FS#3700] (r19438) - Fix: With certain game settings one could clear tiles for free when building long roads (r19436) - Fix: When loading a savegame created with a house NewGRF without that NewGRF available all houses became tall office blocks (r19435) - Fix: Limit rail clearance earnings to 3/4s of rail build cost, to avoid money making loophole when rail build cost is less than rail removal earnings (r19433) - Fix: Crash when the error message 'owned by ' was shown [FS#3696] (r19432) - Feature: Append rail type speed limit (if set) to rail type selection list, and toolbar title (r19431) --- src/group_gui.cpp | 2 +- src/lang/english.txt | 2 ++ src/misc_gui.cpp | 2 +- src/newgrf_commons.cpp | 2 +- src/newgrf_commons.h | 2 +- src/rail.h | 18 +++++++++++++++++- src/rail_cmd.cpp | 6 +++++- src/rail_gui.cpp | 14 +++++++++++++- src/road_cmd.cpp | 6 +++++- src/saveload/town_sl.cpp | 2 +- src/toolbar_gui.cpp | 7 ++++++- 11 files changed, 53 insertions(+), 10 deletions(-) diff --git a/src/group_gui.cpp b/src/group_gui.cpp index dd8c71747c..3ce991bee9 100644 --- a/src/group_gui.cpp +++ b/src/group_gui.cpp @@ -400,7 +400,7 @@ public: /* draw the selected group in white, else we draw it in black */ SetDParam(0, g->index); - DrawString(r.left + WD_FRAMERECT_LEFT + 8, r.right - WD_FRAMERECT_RIGHT, y1, STR_GROUP_NAME, (this->group_sel == g->index) ? TC_WHITE : TC_BLACK); + DrawString(r.left + WD_FRAMERECT_LEFT + 8, r.right - WD_FRAMERECT_RIGHT - 8, y1, STR_GROUP_NAME, (this->group_sel == g->index) ? TC_WHITE : TC_BLACK); /* draw the number of vehicles of the group */ SetDParam(0, g->num_vehicle); diff --git a/src/lang/english.txt b/src/lang/english.txt index 8051d4490f..afd07a89bb 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -4109,3 +4109,5 @@ STR_BUS :{BLACK}{BUS} STR_LORRY :{BLACK}{LORRY} STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} + +STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) diff --git a/src/misc_gui.cpp b/src/misc_gui.cpp index 77d5373c0d..cc326edea4 100644 --- a/src/misc_gui.cpp +++ b/src/misc_gui.cpp @@ -544,7 +544,7 @@ public: this->detailed_msg = detailed_msg; CompanyID company = (CompanyID)GetDParamX(this->decode_params, 2); - this->face = (this->detailed_msg == STR_ERROR_OWNED_BY && company <= MAX_COMPANIES) ? company : INVALID_COMPANY; + this->face = (this->detailed_msg == STR_ERROR_OWNED_BY && company < MAX_COMPANIES) ? company : INVALID_COMPANY; const WindowDesc *desc = (face == INVALID_COMPANY) ? &_errmsg_desc : &_errmsg_face_desc; assert(summary_msg != INVALID_STRING_ID); diff --git a/src/newgrf_commons.cpp b/src/newgrf_commons.cpp index cf86834980..f95ad985cb 100644 --- a/src/newgrf_commons.cpp +++ b/src/newgrf_commons.cpp @@ -136,7 +136,7 @@ uint16 OverrideManagerBase::AddEntityID(byte grf_local_id, uint32 grfid, byte su * @param entity_id of the entity being queried * @return mapped id */ -uint16 OverrideManagerBase::GetSubstituteID(byte entity_id) +uint16 OverrideManagerBase::GetSubstituteID(uint16 entity_id) { return mapping_ID[entity_id].substitute_id; } diff --git a/src/newgrf_commons.h b/src/newgrf_commons.h index 56a16aaeba..e58e7e6b04 100644 --- a/src/newgrf_commons.h +++ b/src/newgrf_commons.h @@ -57,7 +57,7 @@ public: void Add(uint8 local_id, uint32 grfid, uint entity_type); virtual uint16 AddEntityID(byte grf_local_id, uint32 grfid, byte substitute_id); - uint16 GetSubstituteID(byte entity_id); + uint16 GetSubstituteID(uint16 entity_id); virtual uint16 GetID(uint8 grf_local_id, uint32 grfid); inline uint16 GetMaxMapping() { return max_new_entities; } diff --git a/src/rail.h b/src/rail.h index aaa592da92..cf7b482f65 100644 --- a/src/rail.h +++ b/src/rail.h @@ -269,6 +269,22 @@ static inline Money RailBuildCost(RailType railtype) return (_price[PR_BUILD_RAIL] * GetRailTypeInfo(railtype)->cost_multiplier) >> 3; } +/** + * Returns the 'cost' of clearing the specified railtype. + * @param railtype The railtype being removed. + * @return The cost. + */ +static inline Money RailClearCost(RailType railtype) +{ + /* Clearing rail in fact earns money, but if the build cost is set + * very low then a loophole exists where money can be made. + * In this case we limit the removal earnings to 3/4s of the build + * cost. + */ + assert(railtype < RAILTYPE_END); + return max(_price[PR_CLEAR_RAIL], -RailBuildCost(railtype) * 3 / 4); +} + /** * Calculates the cost of rail conversion * @param from The railtype we are converting from @@ -296,7 +312,7 @@ static inline Money RailConvertCost(RailType from, RailType to) } /* make the price the same as remove + build new type */ - return RailBuildCost(to) + _price[PR_CLEAR_RAIL]; + return RailBuildCost(to) + RailClearCost(from); } void DrawTrainDepotSprite(int x, int y, int image, RailType railtype); diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index dd6e6c7da8..d8f7ceb2aa 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -510,7 +510,7 @@ CommandCost CmdBuildSingleRail(TileIndex tile, DoCommandFlag flags, uint32 p1, u CommandCost CmdRemoveSingleRail(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { Track track = (Track)p2; - CommandCost cost(EXPENSES_CONSTRUCTION, _price[PR_CLEAR_RAIL] ); + CommandCost cost(EXPENSES_CONSTRUCTION); bool crossing = false; if (!ValParamTrackOrientation((Track)p2)) return CMD_ERROR; @@ -533,6 +533,8 @@ CommandCost CmdRemoveSingleRail(TileIndex tile, DoCommandFlag flags, uint32 p1, return CMD_ERROR; } + cost.AddCost(RailClearCost(GetRailType(tile))); + if (flags & DC_EXEC) { if (HasReservedTracks(tile, trackbit)) { v = GetTrainForReservation(tile, track); @@ -557,6 +559,8 @@ CommandCost CmdRemoveSingleRail(TileIndex tile, DoCommandFlag flags, uint32 p1, if ((present & trackbit) == 0) return CMD_ERROR; if (present == (TRACK_BIT_X | TRACK_BIT_Y)) crossing = true; + cost.AddCost(RailClearCost(GetRailType(tile))); + /* Charge extra to remove signals on the track, if they are there */ if (HasSignalOnTrack(tile, track)) cost.AddCost(DoCommand(tile, track, 0, flags, CMD_REMOVE_SIGNALS)); diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index 753426fd0f..3ff64991fb 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -617,6 +617,8 @@ static const RailBuildingGUIButtonData _rail_build_button_data[] = { * @param clicked_widget Widget clicked in the toolbar */ struct BuildRailToolbarWindow : Window { + RailType railtype; + BuildRailToolbarWindow(const WindowDesc *desc, WindowNumber window_number, RailType railtype) : Window() { this->InitNested(desc); @@ -636,10 +638,11 @@ struct BuildRailToolbarWindow : Window { */ void SetupRailToolbar(RailType railtype) { + this->railtype = railtype; const RailtypeInfo *rti = GetRailTypeInfo(railtype); assert(railtype < RAILTYPE_END); - this->GetWidget(RTW_CAPTION)->widget_data = rti->strings.toolbar_caption; + this->GetWidget(RTW_CAPTION)->widget_data = rti->max_speed > 0 ? STR_TOOLBAR_RAILTYPE_VELOCITY : STR_JUST_STRING; this->GetWidget(RTW_BUILD_NS)->widget_data = rti->gui_sprites.build_ns_rail; this->GetWidget(RTW_BUILD_X)->widget_data = rti->gui_sprites.build_x_rail; this->GetWidget(RTW_BUILD_EW)->widget_data = rti->gui_sprites.build_ew_rail; @@ -689,6 +692,15 @@ struct BuildRailToolbarWindow : Window { } } + virtual void SetStringParameters(int widget) const + { + if (widget == RTW_CAPTION) { + const RailtypeInfo *rti = GetRailTypeInfo(this->railtype); + SetDParam(0, rti->strings.toolbar_caption); + SetDParam(1, rti->max_speed); + } + } + virtual void OnPaint() { this->DrawWidgets(); diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp index 9e9f9c1416..3cf8f84653 100644 --- a/src/road_cmd.cpp +++ b/src/road_cmd.cpp @@ -583,7 +583,7 @@ CommandCost CmdBuildRoad(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 default: { do_clear:; - CommandCost ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); + CommandCost ret = DoCommand(tile, 0, 0, flags & ~DC_EXEC, CMD_LANDSCAPE_CLEAR); if (ret.Failed()) return ret; cost.AddCost(ret); tile_cleared = true; @@ -632,6 +632,10 @@ do_clear:; } if (flags & DC_EXEC) { + /* CmdBuildLongRoad calls us directly with DC_EXEC, so we may only clear the tile after all + * fail/success tests have been done. */ + if (tile_cleared) DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); + switch (GetTileType(tile)) { case MP_ROAD: { RoadTileType rtt = GetRoadTileType(tile); diff --git a/src/saveload/town_sl.cpp b/src/saveload/town_sl.cpp index 47a7fb6c0d..d10a0c60e7 100644 --- a/src/saveload/town_sl.cpp +++ b/src/saveload/town_sl.cpp @@ -40,7 +40,7 @@ void UpdateHousesAndTowns() if (!IsTileType(t, MP_HOUSE)) continue; - house_id = GetHouseType(t); + house_id = GetCleanHouseType(t); if (!HouseSpec::Get(house_id)->enabled && house_id >= NEW_HOUSE_OFFSET) { /* The specs for this type of house are not available any more, so * replace it with the substitute original house type. */ diff --git a/src/toolbar_gui.cpp b/src/toolbar_gui.cpp index 5d0afdc88d..fbfe44bb92 100644 --- a/src/toolbar_gui.cpp +++ b/src/toolbar_gui.cpp @@ -649,7 +649,12 @@ static void ToolbarBuildRailClick(Window *w) const RailtypeInfo *rti = GetRailTypeInfo(rt); /* Skip rail type if it has no label */ if (rti->label == 0) continue; - list->push_back(new DropDownListStringItem(rti->strings.menu_text, rt, !HasBit(c->avail_railtypes, rt))); + + StringID str = rti->max_speed > 0 ? STR_TOOLBAR_RAILTYPE_VELOCITY : STR_JUST_STRING; + DropDownListParamStringItem *item = new DropDownListParamStringItem(str, rt, !HasBit(c->avail_railtypes, rt)); + item->SetParam(0, rti->strings.menu_text); + item->SetParam(1, rti->max_speed); + list->push_back(item); } ShowDropDownList(w, list, _last_built_railtype, TBN_RAILS, 140, true, true); SndPlayFx(SND_15_BEEP);