From 6a70abbd998ed5b54d52ddb44b4df8521413185c Mon Sep 17 00:00:00 2001 From: michi_cc Date: Tue, 17 Apr 2012 19:44:02 +0000 Subject: [PATCH] (svn r24136) -Feature [FS#4465]: Autoreplace vehicles only when they get old. (Vikthor) --- src/autoreplace.cpp | 8 ++- src/autoreplace_base.h | 1 + src/autoreplace_cmd.cpp | 14 +++-- src/autoreplace_func.h | 28 +++++++--- src/autoreplace_gui.cpp | 91 +++++++++++++++++++++++---------- src/lang/english.txt | 3 ++ src/saveload/autoreplace_sl.cpp | 1 + src/saveload/saveload.cpp | 3 +- src/vehicle.cpp | 10 ++-- src/vehicle_base.h | 2 +- src/widget.cpp | 7 ++- src/widget_type.h | 1 + src/widgets/dropdown.cpp | 4 +- src/window.cpp | 2 +- 14 files changed, 126 insertions(+), 49 deletions(-) diff --git a/src/autoreplace.cpp b/src/autoreplace.cpp index aed2c0e829..1ba64d7b80 100644 --- a/src/autoreplace.cpp +++ b/src/autoreplace.cpp @@ -57,16 +57,18 @@ void RemoveAllEngineReplacement(EngineRenewList *erl) * @param erl The renewlist to search in. * @param engine Engine type to be replaced. * @param group The group related to this replacement. + * @param[out] replace_when_old Set to true if the replacement should be done when old. * @return The engine type to replace with, or INVALID_ENGINE if no * replacement is in the list. */ -EngineID EngineReplacement(EngineRenewList erl, EngineID engine, GroupID group) +EngineID EngineReplacement(EngineRenewList erl, EngineID engine, GroupID group, bool *replace_when_old) { const EngineRenew *er = GetEngineReplacement(erl, engine, group); if (er == NULL && (group == DEFAULT_GROUP || (Group::IsValidID(group) && !Group::Get(group)->replace_protection))) { /* We didn't find anything useful in the vehicle's own group so we will try ALL_GROUP */ er = GetEngineReplacement(erl, engine, ALL_GROUP); } + if (replace_when_old != NULL) *replace_when_old = er == NULL ? false : er->replace_when_old; return er == NULL ? INVALID_ENGINE : er->to; } @@ -76,10 +78,11 @@ EngineID EngineReplacement(EngineRenewList erl, EngineID engine, GroupID group) * @param old_engine The original engine type. * @param new_engine The replacement engine type. * @param group The group related to this replacement. + * @param replace_when_old Replace when old or always? * @param flags The calling command flags. * @return 0 on success, CMD_ERROR on failure. */ -CommandCost AddEngineReplacement(EngineRenewList *erl, EngineID old_engine, EngineID new_engine, GroupID group, DoCommandFlag flags) +CommandCost AddEngineReplacement(EngineRenewList *erl, EngineID old_engine, EngineID new_engine, GroupID group, bool replace_when_old, DoCommandFlag flags) { /* Check if the old vehicle is already in the list */ EngineRenew *er = GetEngineReplacement(*erl, old_engine, group); @@ -93,6 +96,7 @@ CommandCost AddEngineReplacement(EngineRenewList *erl, EngineID old_engine, Engi if (flags & DC_EXEC) { er = new EngineRenew(old_engine, new_engine); er->group_id = group; + er->replace_when_old = replace_when_old; /* Insert before the first element */ er->next = (EngineRenew *)(*erl); diff --git a/src/autoreplace_base.h b/src/autoreplace_base.h index 77a31538ab..5d265866d8 100644 --- a/src/autoreplace_base.h +++ b/src/autoreplace_base.h @@ -37,6 +37,7 @@ struct EngineRenew : EngineRenewPool::PoolItem<&_enginerenew_pool> { EngineID to; EngineRenew *next; GroupID group_id; + bool replace_when_old; ///< Do replacement only when vehicle is old. EngineRenew(EngineID from = INVALID_ENGINE, EngineID to = INVALID_ENGINE) : from(from), to(to) {} ~EngineRenew() {} diff --git a/src/autoreplace_cmd.cpp b/src/autoreplace_cmd.cpp index 31bf75dee9..d208822206 100644 --- a/src/autoreplace_cmd.cpp +++ b/src/autoreplace_cmd.cpp @@ -225,10 +225,11 @@ static CargoID GetNewCargoTypeForReplace(Vehicle *v, EngineID engine_type, bool * Get the EngineID of the replacement for a vehicle * @param v The vehicle to find a replacement for * @param c The vehicle's owner (it's faster to forward the pointer than refinding it) + * @param always_replace Always replace, even if not old. * @param [out] e the EngineID of the replacement. INVALID_ENGINE if no replacement is found * @return Error if the engine to build is not available */ -static CommandCost GetNewEngineType(const Vehicle *v, const Company *c, EngineID &e) +static CommandCost GetNewEngineType(const Vehicle *v, const Company *c, bool always_replace, EngineID &e) { assert(v->type != VEH_TRAIN || !v->IsArticulatedPart()); @@ -239,7 +240,9 @@ static CommandCost GetNewEngineType(const Vehicle *v, const Company *c, EngineID return CommandCost(); } - e = EngineReplacementForCompany(c, v->engine_type, v->group_id); + bool replace_when_old; + e = EngineReplacementForCompany(c, v->engine_type, v->group_id, &replace_when_old); + if (!always_replace && replace_when_old && !v->NeedsAutorenewing(c, false)) e = INVALID_ENGINE; /* Autoreplace, if engine is available */ if (e != INVALID_ENGINE && IsEngineBuildable(e, v->type, _current_company)) { @@ -271,7 +274,7 @@ static CommandCost BuildReplacementVehicle(Vehicle *old_veh, Vehicle **new_vehic /* Shall the vehicle be replaced? */ const Company *c = Company::Get(_current_company); EngineID e; - CommandCost cost = GetNewEngineType(old_veh, c, e); + CommandCost cost = GetNewEngineType(old_veh, c, true, e); if (cost.Failed()) return cost; if (e == INVALID_ENGINE) return CommandCost(); // neither autoreplace is set, nor autorenew is triggered @@ -683,7 +686,7 @@ CommandCost CmdAutoreplaceVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1 bool any_replacements = false; while (w != NULL) { EngineID e; - CommandCost cost = GetNewEngineType(w, c, e); + CommandCost cost = GetNewEngineType(w, c, false, e); if (cost.Failed()) return cost; any_replacements |= (e != INVALID_ENGINE); w = (!free_wagon && w->type == VEH_TRAIN ? Train::From(w)->GetNextUnit() : NULL); @@ -736,6 +739,7 @@ CommandCost CmdAutoreplaceVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1 * @param tile unused * @param flags operation to perform * @param p1 packed data + * - bit 0 = replace when engine gets old? * - bits 16-31 = engine group * @param p2 packed data * - bits 0-15 = old engine type @@ -760,7 +764,7 @@ CommandCost CmdSetAutoReplace(TileIndex tile, DoCommandFlag flags, uint32 p1, ui if (!Engine::IsValidID(new_engine_type)) return CMD_ERROR; if (!CheckAutoreplaceValidity(old_engine_type, new_engine_type, _current_company)) return CMD_ERROR; - cost = AddEngineReplacementForCompany(c, old_engine_type, new_engine_type, id_g, flags); + cost = AddEngineReplacementForCompany(c, old_engine_type, new_engine_type, id_g, HasBit(p1, 0), flags); } else { cost = RemoveEngineReplacementForCompany(c, old_engine_type, id_g, flags); } diff --git a/src/autoreplace_func.h b/src/autoreplace_func.h index 7f2c96bf62..3a6fc83a81 100644 --- a/src/autoreplace_func.h +++ b/src/autoreplace_func.h @@ -16,8 +16,8 @@ #include "company_base.h" void RemoveAllEngineReplacement(EngineRenewList *erl); -EngineID EngineReplacement(EngineRenewList erl, EngineID engine, GroupID group); -CommandCost AddEngineReplacement(EngineRenewList *erl, EngineID old_engine, EngineID new_engine, GroupID group, DoCommandFlag flags); +EngineID EngineReplacement(EngineRenewList erl, EngineID engine, GroupID group, bool *replace_when_old = NULL); +CommandCost AddEngineReplacement(EngineRenewList *erl, EngineID old_engine, EngineID new_engine, GroupID group, bool replace_when_old, DoCommandFlag flags); CommandCost RemoveEngineReplacement(EngineRenewList *erl, EngineID engine, GroupID group, DoCommandFlag flags); /** @@ -34,12 +34,13 @@ static inline void RemoveAllEngineReplacementForCompany(Company *c) * @param c company. * @param engine Engine type. * @param group The group related to this replacement. + * @param[out] replace_when_old Set to true if the replacement should be done when old. * @return The engine type to replace with, or INVALID_ENGINE if no * replacement is in the list. */ -static inline EngineID EngineReplacementForCompany(const Company *c, EngineID engine, GroupID group) +static inline EngineID EngineReplacementForCompany(const Company *c, EngineID engine, GroupID group, bool *replace_when_old = NULL) { - return EngineReplacement(c->engine_renew_list, engine, group); + return EngineReplacement(c->engine_renew_list, engine, group, replace_when_old); } /** @@ -54,18 +55,33 @@ static inline bool EngineHasReplacementForCompany(const Company *c, EngineID eng return EngineReplacementForCompany(c, engine, group) != INVALID_ENGINE; } +/** + * Check if a company has a replacement set up for the given engine when it gets old. + * @param c Company. + * @param engine Engine type to be replaced. + * @param group The group related to this replacement. + * @return True if a replacement when old was set up, false otherwise. + */ +static inline bool EngineHasReplacementWhenOldForCompany(const Company *c, EngineID engine, GroupID group) +{ + bool replace_when_old; + EngineReplacement(c->engine_renew_list, engine, group, &replace_when_old); + return replace_when_old; +} + /** * Add an engine replacement for the company. * @param c Company. * @param old_engine The original engine type. * @param new_engine The replacement engine type. * @param group The group related to this replacement. + * @param replace_when_old Replace when old or always? * @param flags The calling command flags. * @return 0 on success, CMD_ERROR on failure. */ -static inline CommandCost AddEngineReplacementForCompany(Company *c, EngineID old_engine, EngineID new_engine, GroupID group, DoCommandFlag flags) +static inline CommandCost AddEngineReplacementForCompany(Company *c, EngineID old_engine, EngineID new_engine, GroupID group, bool replace_when_old, DoCommandFlag flags) { - return AddEngineReplacement(&c->engine_renew_list, old_engine, new_engine, group, flags); + return AddEngineReplacement(&c->engine_renew_list, old_engine, new_engine, group, replace_when_old, flags); } /** diff --git a/src/autoreplace_gui.cpp b/src/autoreplace_gui.cpp index 0a1b4686ca..ad39c8b28d 100644 --- a/src/autoreplace_gui.cpp +++ b/src/autoreplace_gui.cpp @@ -24,6 +24,7 @@ #include "settings_func.h" #include "core/geometry_func.hpp" #include "rail_gui.h" +#include "widgets/dropdown_func.h" #include "widgets/autoreplace_widget.h" @@ -67,6 +68,12 @@ void AddRemoveEngineFromAutoreplaceAndBuildWindows(VehicleType type) InvalidateWindowClassesData(WC_BUILD_VEHICLE); // The build windows needs updating as well } +static const StringID _start_replace_dropdown[] = { + STR_REPLACE_VEHICLES_NOW, + STR_REPLACE_VEHICLES_WHEN_OLD, + INVALID_STRING_ID +}; + /** * Window for the autoreplacing of vehicles. */ @@ -170,6 +177,18 @@ class ReplaceVehicleWindow : public Window { this->reset_sel_engine = false; } + /** + * Handle click on the start replace button. + * @param replace_when_old Replace now or only when old? + */ + void ReplaceClick_StartReplace(bool replace_when_old) + { + EngineID veh_from = this->sel_engine[0]; + EngineID veh_to = this->sel_engine[1]; + DoCommandP(0, (replace_when_old ? 1 : 0) | (this->sel_group << 16), veh_from + (veh_to << 16), CMD_SET_AUTOREPLACE); + this->SetDirty(); + } + public: ReplaceVehicleWindow(const WindowDesc *desc, VehicleType vehicletype, GroupID id_g) : Window() { @@ -270,6 +289,17 @@ public: *size = maxdim(*size, d); break; } + + case WID_RV_START_REPLACE: { + Dimension d = GetStringBoundingBox(STR_REPLACE_VEHICLES_START); + for (int i = 0; _start_replace_dropdown[i] != INVALID_STRING_ID; i++) { + d = maxdim(d, GetStringBoundingBox(_start_replace_dropdown[i])); + } + d.width += padding.width; + d.height += padding.height; + *size = maxdim(*size, d); + break; + } } } @@ -301,8 +331,10 @@ public: if (!EngineHasReplacementForCompany(c, this->sel_engine[0], this->sel_group)) { SetDParam(0, STR_REPLACE_NOT_REPLACING); } else { - SetDParam(0, STR_ENGINE_NAME); - SetDParam(1, EngineReplacementForCompany(c, this->sel_engine[0], this->sel_group)); + bool when_old = false; + EngineID e = EngineReplacementForCompany(c, this->sel_engine[0], this->sel_group, &when_old); + SetDParam(0, when_old ? STR_REPLACE_REPLACING_WHEN_OLD : STR_ENGINE_NAME); + SetDParam(1, e); } } else { SetDParam(0, STR_REPLACE_NOT_REPLACING_VEHICLE_SELECTED); @@ -334,13 +366,11 @@ public: /* Disable the "Start Replacing" button if: * Either engines list is empty - * or The selected replacement engine has a replacement (to prevent loops) - * or The right engines list (new replacement) has the existing replacement vehicle selected */ + * or The selected replacement engine has a replacement (to prevent loops). */ this->SetWidgetDisabledState(WID_RV_START_REPLACE, this->sel_engine[0] == INVALID_ENGINE || this->sel_engine[1] == INVALID_ENGINE || - EngineReplacementForCompany(c, this->sel_engine[1], this->sel_group) != INVALID_ENGINE || - EngineReplacementForCompany(c, this->sel_engine[0], this->sel_group) == this->sel_engine[1]); + EngineReplacementForCompany(c, this->sel_engine[1], this->sel_group) != INVALID_ENGINE); /* Disable the "Stop Replacing" button if: * The left engines list (existing vehicle) is empty @@ -349,9 +379,6 @@ public: this->sel_engine[0] == INVALID_ENGINE || !EngineHasReplacementForCompany(c, this->sel_engine[0], this->sel_group)); - /* now the actual drawing of the window itself takes place */ - SetDParam(0, STR_REPLACE_VEHICLE_TRAIN + this->window_number); - if (this->window_number == VEH_TRAIN) { /* sets the colour of that art thing */ this->GetWidget(WID_RV_TRAIN_FLUFF_LEFT)->colour = _company_colours[_local_company]; @@ -401,10 +428,13 @@ public: break; case WID_RV_START_REPLACE: { // Start replacing - EngineID veh_from = this->sel_engine[0]; - EngineID veh_to = this->sel_engine[1]; - DoCommandP(0, this->sel_group << 16, veh_from + (veh_to << 16), CMD_SET_AUTOREPLACE); - this->SetDirty(); + if (this->GetWidget(widget)->ButtonHit(pt)) { + this->HandleButtonClick(WID_RV_START_REPLACE); + ReplaceClick_StartReplace(false); + } else { + bool replacment_when_old = EngineHasReplacementWhenOldForCompany(Company::Get(_local_company), this->sel_engine[0], this->sel_group); + ShowDropDownMenu(this, _start_replace_dropdown, replacment_when_old ? 1 : 0, WID_RV_START_REPLACE, !this->replace_engines ? 1 << 1 : 0, 0); + } break; } @@ -441,17 +471,26 @@ public: virtual void OnDropdownSelect(int widget, int index) { - RailType temp = (RailType)index; - if (temp == sel_railtype) return; // we didn't select a new one. No need to change anything - sel_railtype = temp; - /* Reset scrollbar positions */ - this->vscroll[0]->SetPosition(0); - this->vscroll[1]->SetPosition(0); - /* Rebuild the lists */ - this->engines[0].ForceRebuild(); - this->engines[1].ForceRebuild(); - this->reset_sel_engine = true; - this->SetDirty(); + switch (widget) { + case WID_RV_TRAIN_RAILTYPE_DROPDOWN: { + RailType temp = (RailType)index; + if (temp == sel_railtype) return; // we didn't select a new one. No need to change anything + sel_railtype = temp; + /* Reset scrollbar positions */ + this->vscroll[0]->SetPosition(0); + this->vscroll[1]->SetPosition(0); + /* Rebuild the lists */ + this->engines[0].ForceRebuild(); + this->engines[1].ForceRebuild(); + this->reset_sel_engine = true; + this->SetDirty(); + break; + } + + case WID_RV_START_REPLACE: + this->ReplaceClick_StartReplace(index != 0); + break; + } } virtual void OnResize() @@ -497,7 +536,7 @@ static const NWidgetPart _nested_replace_rail_vehicle_widgets[] = { NWidget(WWT_PANEL, COLOUR_GREY, WID_RV_RIGHT_DETAILS), SetMinimalSize(228, 102), SetResize(1, 0), EndContainer(), EndContainer(), NWidget(NWID_HORIZONTAL), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_RV_START_REPLACE), SetMinimalSize(139, 12), SetDataTip(STR_REPLACE_VEHICLES_START, STR_REPLACE_HELP_START_BUTTON), + NWidget(NWID_PUSHBUTTON_DROPDOWN, COLOUR_GREY, WID_RV_START_REPLACE), SetMinimalSize(139, 12), SetDataTip(STR_REPLACE_VEHICLES_START, STR_REPLACE_HELP_START_BUTTON), NWidget(WWT_PANEL, COLOUR_GREY, WID_RV_INFO_TAB), SetMinimalSize(167, 12), SetDataTip(0x0, STR_REPLACE_HELP_REPLACE_INFO_TAB), SetResize(1, 0), EndContainer(), NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_RV_STOP_REPLACE), SetMinimalSize(150, 12), SetDataTip(STR_REPLACE_VEHICLES_STOP, STR_REPLACE_HELP_STOP_BUTTON), @@ -537,7 +576,7 @@ static const NWidgetPart _nested_replace_vehicle_widgets[] = { NWidget(WWT_PANEL, COLOUR_GREY, WID_RV_RIGHT_DETAILS), SetMinimalSize(228, 92), SetResize(1, 0), EndContainer(), EndContainer(), NWidget(NWID_HORIZONTAL), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_RV_START_REPLACE), SetMinimalSize(139, 12), SetDataTip(STR_REPLACE_VEHICLES_START, STR_REPLACE_HELP_START_BUTTON), + NWidget(NWID_PUSHBUTTON_DROPDOWN, COLOUR_GREY, WID_RV_START_REPLACE), SetMinimalSize(139, 12), SetDataTip(STR_REPLACE_VEHICLES_START, STR_REPLACE_HELP_START_BUTTON), NWidget(WWT_PANEL, COLOUR_GREY, WID_RV_INFO_TAB), SetMinimalSize(167, 12), SetDataTip(0x0, STR_REPLACE_HELP_REPLACE_INFO_TAB), SetResize(1, 0), EndContainer(), NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_RV_STOP_REPLACE), SetMinimalSize(138, 12), SetDataTip(STR_REPLACE_VEHICLES_STOP, STR_REPLACE_HELP_STOP_BUTTON), NWidget(WWT_RESIZEBOX, COLOUR_GREY), diff --git a/src/lang/english.txt b/src/lang/english.txt index 0cdfeb011e..bdbc08a84a 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -3112,9 +3112,12 @@ STR_REPLACE_HELP_LEFT_ARRAY :{BLACK}Select t STR_REPLACE_HELP_RIGHT_ARRAY :{BLACK}Select the new engine type you would like to use in place of the left selected engine type STR_REPLACE_VEHICLES_START :{BLACK}Start Replacing Vehicles +STR_REPLACE_VEHICLES_NOW :Replace all vehicles now +STR_REPLACE_VEHICLES_WHEN_OLD :Replace only old vehicles STR_REPLACE_HELP_START_BUTTON :{BLACK}Press to begin replacement of the left selected engine type with the right selected engine type STR_REPLACE_NOT_REPLACING :{BLACK}Not replacing STR_REPLACE_NOT_REPLACING_VEHICLE_SELECTED :{BLACK}No vehicle selected +STR_REPLACE_REPLACING_WHEN_OLD :{ENGINE} when old STR_REPLACE_VEHICLES_STOP :{BLACK}Stop Replacing Vehicles STR_REPLACE_HELP_STOP_BUTTON :{BLACK}Press to stop the replacement of the engine type selected on the left diff --git a/src/saveload/autoreplace_sl.cpp b/src/saveload/autoreplace_sl.cpp index 96fff77282..0cb9cca8d1 100644 --- a/src/saveload/autoreplace_sl.cpp +++ b/src/saveload/autoreplace_sl.cpp @@ -20,6 +20,7 @@ static const SaveLoad _engine_renew_desc[] = { SLE_REF(EngineRenew, next, REF_ENGINE_RENEWS), SLE_CONDVAR(EngineRenew, group_id, SLE_UINT16, 60, SL_MAX_VERSION), + SLE_CONDVAR(EngineRenew, replace_when_old, SLE_BOOL, 175, SL_MAX_VERSION), SLE_END() }; diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp index b834123355..f9e569680f 100644 --- a/src/saveload/saveload.cpp +++ b/src/saveload/saveload.cpp @@ -238,8 +238,9 @@ * 172 23947 * 173 23967 1.2.0-RC1 * 174 23973 1.2.x + * 175 24136 */ -extern const uint16 SAVEGAME_VERSION = 174; ///< Current savegame version of OpenTTD. +extern const uint16 SAVEGAME_VERSION = 175; ///< Current savegame version of OpenTTD. SavegameType _savegame_type; ///< type of savegame we are loading diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 8be891b2fd..1db865ef9d 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -67,9 +67,10 @@ INSTANTIATE_POOL_METHODS(Vehicle) /** * Function to tell if a vehicle needs to be autorenewed * @param *c The vehicle owner + * @param use_renew_setting Should the company renew setting be considered? * @return true if the vehicle is old enough for replacement */ -bool Vehicle::NeedsAutorenewing(const Company *c) const +bool Vehicle::NeedsAutorenewing(const Company *c, bool use_renew_setting) const { /* We can always generate the Company pointer when we have the vehicle. * However this takes time and since the Company pointer is often present @@ -77,7 +78,7 @@ bool Vehicle::NeedsAutorenewing(const Company *c) const * argument rather than finding it again. */ assert(c == Company::Get(this->owner)); - if (!c->settings.engine_renew) return false; + if (use_renew_setting && !c->settings.engine_renew) return false; if (this->age - this->max_age < (c->settings.engine_renew_months * 30)) return false; /* Only engines need renewing */ @@ -131,10 +132,13 @@ bool Vehicle::NeedsServicing() const if (needed_money > c->money) return false; for (const Vehicle *v = this; v != NULL; v = (v->type == VEH_TRAIN) ? Train::From(v)->GetNextUnit() : NULL) { - EngineID new_engine = EngineReplacementForCompany(c, v->engine_type, v->group_id); + bool replace_when_old = false; + EngineID new_engine = EngineReplacementForCompany(c, v->engine_type, v->group_id, &replace_when_old); /* Check engine availability */ if (new_engine == INVALID_ENGINE || !HasBit(Engine::Get(new_engine)->company_avail, v->owner)) continue; + /* Is the vehicle old if we are not always replacing? */ + if (replace_when_old && !v->NeedsAutorenewing(c, false)) continue; /* Check refittability */ uint32 available_cargo_types, union_mask; diff --git a/src/vehicle_base.h b/src/vehicle_base.h index 852442e2e7..a605e64ece 100644 --- a/src/vehicle_base.h +++ b/src/vehicle_base.h @@ -603,7 +603,7 @@ public: bool HandleBreakdown(); - bool NeedsAutorenewing(const Company *c) const; + bool NeedsAutorenewing(const Company *c, bool use_renew_setting = true) const; bool NeedsServicing() const; bool NeedsAutomaticServicing() const; diff --git a/src/widget.cpp b/src/widget.cpp index 705ee105be..c38a6fa2b3 100644 --- a/src/widget.cpp +++ b/src/widget.cpp @@ -2050,6 +2050,7 @@ NWidgetLeaf::NWidgetLeaf(WidgetType tp, Colours colour, int index, uint16 data, case WWT_TEXT: case WWT_MATRIX: case NWID_BUTTON_DROPDOWN: + case NWID_PUSHBUTTON_DROPDOWN: case WWT_ARROWBTN: case WWT_PUSHARROWBTN: this->SetFill(0, 0); @@ -2254,7 +2255,8 @@ void NWidgetLeaf::SetupSmallestSize(Window *w, bool init_array) break; } case WWT_DROPDOWN: - case NWID_BUTTON_DROPDOWN: { + case NWID_BUTTON_DROPDOWN: + case NWID_PUSHBUTTON_DROPDOWN: { static const Dimension extra = {WD_DROPDOWNTEXT_LEFT + WD_DROPDOWNTEXT_RIGHT, WD_DROPDOWNTEXT_TOP + WD_DROPDOWNTEXT_BOTTOM}; padding = &extra; if (this->index >= 0) w->SetStringParameters(this->index); @@ -2380,6 +2382,7 @@ void NWidgetLeaf::Draw(const Window *w) break; case NWID_BUTTON_DROPDOWN: + case NWID_PUSHBUTTON_DROPDOWN: if (this->index >= 0) w->SetStringParameters(this->index); DrawButtonDropdown(r, this->colour, clicked, (this->disp_flags & ND_DROPDOWN_ACTIVE) != 0, this->widget_data); break; @@ -2582,7 +2585,7 @@ static int MakeNWidget(const NWidgetPart *parts, int count, NWidgetBase **dest, default: if (*dest != NULL) return num_used; - assert((parts->type & WWT_MASK) < WWT_LAST || parts->type == NWID_BUTTON_DROPDOWN); + assert((parts->type & WWT_MASK) < WWT_LAST || (parts->type & WWT_MASK) == NWID_BUTTON_DROPDOWN); *dest = new NWidgetLeaf(parts->type, parts->u.widget.colour, parts->u.widget.index, 0x0, STR_NULL); *biggest_index = max(*biggest_index, (int)parts->u.widget.index); break; diff --git a/src/widget_type.h b/src/widget_type.h index e77a7a1318..be29a2a4c7 100644 --- a/src/widget_type.h +++ b/src/widget_type.h @@ -102,6 +102,7 @@ enum WidgetType { WWT_PUSHTXTBTN = WWT_TEXTBTN | WWB_PUSHBUTTON, WWT_PUSHIMGBTN = WWT_IMGBTN | WWB_PUSHBUTTON, WWT_PUSHARROWBTN = WWT_ARROWBTN | WWB_PUSHBUTTON, + NWID_PUSHBUTTON_DROPDOWN = NWID_BUTTON_DROPDOWN | WWB_PUSHBUTTON, }; /** Different forms of sizing nested widgets, using NWidgetBase::AssignSizePosition() */ diff --git a/src/widgets/dropdown.cpp b/src/widgets/dropdown.cpp index 6f982b5a0c..410ec62a40 100644 --- a/src/widgets/dropdown.cpp +++ b/src/widgets/dropdown.cpp @@ -172,7 +172,7 @@ struct DropdownWindow : Window { if (w2 != NULL) { if (w2->nested_array != NULL) { NWidgetCore *nwi2 = w2->GetWidget(this->parent_button); - if (nwi2->type == NWID_BUTTON_DROPDOWN) { + if ((nwi2->type & WWT_MASK) == NWID_BUTTON_DROPDOWN) { nwi2->disp_flags &= ~ND_DROPDOWN_ACTIVE; } else { w2->RaiseWidget(this->parent_button); @@ -358,7 +358,7 @@ void ShowDropDownList(Window *w, DropDownList *list, int selected, int button, u wi_rect.bottom = nwi->pos_y + nwi->current_y - 1; wi_colour = nwi->colour; - if (nwi->type == NWID_BUTTON_DROPDOWN) { + if ((nwi->type & WWT_MASK) == NWID_BUTTON_DROPDOWN) { nwi->disp_flags |= ND_DROPDOWN_ACTIVE; } else { w->LowerWidget(button); diff --git a/src/window.cpp b/src/window.cpp index 2ea83c9ff1..5511618828 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -305,7 +305,7 @@ void CDECL Window::SetWidgetsLoweredState(bool lowered_stat, int widgets, ...) void Window::RaiseButtons(bool autoraise) { for (uint i = 0; i < this->nested_array_size; i++) { - if (this->nested_array[i] != NULL && (this->nested_array[i]->type & ~WWB_PUSHBUTTON) < WWT_LAST && + if (this->nested_array[i] != NULL && ((this->nested_array[i]->type & ~WWB_PUSHBUTTON) < WWT_LAST || this->nested_array[i]->type == NWID_PUSHBUTTON_DROPDOWN) && (!autoraise || (this->nested_array[i]->type & WWB_PUSHBUTTON)) && this->IsWidgetLowered(i)) { this->RaiseWidget(i); this->SetWidgetDirty(i);