From e155c8597add7962464dc951720e339ef177fc49 Mon Sep 17 00:00:00 2001 From: frosch Date: Thu, 30 Jul 2015 18:45:29 +0000 Subject: [PATCH] (svn r27348) [1.5] -Backport from trunk: - Fix: Password window layout with GUI zoom [FS#6321] (r27304, r27303) - Fix: Speed-only timetables got assigned times in stations [FS#6313] (r27302, r27301) - Fix: Enforce the company's default service intervals when purchasing another company [FS#6254] (r27282, r27281) - Fix: Cloning/autoreplace/autorenew did not copy custom service intervals (r27280) --- src/base_consist.cpp | 4 +++ src/economy.cpp | 31 ++++++++++++++++++-- src/network/network_gui.cpp | 2 +- src/timetable_cmd.cpp | 58 +++++++++++++++++++++++++------------ src/widget.cpp | 2 +- 5 files changed, 75 insertions(+), 22 deletions(-) diff --git a/src/base_consist.cpp b/src/base_consist.cpp index c7fcdec217..200512786c 100644 --- a/src/base_consist.cpp +++ b/src/base_consist.cpp @@ -44,4 +44,8 @@ void BaseConsist::CopyConsistPropertiesFrom(const BaseConsist *src) if (HasBit(src->vehicle_flags, VF_TIMETABLE_STARTED)) SetBit(this->vehicle_flags, VF_TIMETABLE_STARTED); if (HasBit(src->vehicle_flags, VF_AUTOFILL_TIMETABLE)) SetBit(this->vehicle_flags, VF_AUTOFILL_TIMETABLE); if (HasBit(src->vehicle_flags, VF_AUTOFILL_PRES_WAIT_TIME)) SetBit(this->vehicle_flags, VF_AUTOFILL_PRES_WAIT_TIME); + if (HasBit(src->vehicle_flags, VF_SERVINT_IS_PERCENT) != HasBit(this->vehicle_flags, VF_SERVINT_IS_PERCENT)) { + ToggleBit(this->vehicle_flags, VF_SERVINT_IS_PERCENT); + } + if (HasBit(src->vehicle_flags, VF_SERVINT_IS_CUSTOM)) SetBit(this->vehicle_flags, VF_SERVINT_IS_CUSTOM); } diff --git a/src/economy.cpp b/src/economy.cpp index 37a89b3f25..d78d2cccec 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -300,7 +300,7 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner) /* Single player cheated to AI company. * There are no spectators in single player, so we must pick some other company. */ assert(!_networking); - Backup cur_company(_current_company, FILE_LINE); + Backup cur_company2(_current_company, FILE_LINE); Company *c; FOR_ALL_COMPANIES(c) { if (c->index != old_owner) { @@ -308,7 +308,7 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner) break; } } - cur_company.Restore(); + cur_company2.Restore(); assert(old_owner != _local_company); } @@ -431,11 +431,38 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner) FreeUnitIDGenerator(VEH_SHIP, new_owner), FreeUnitIDGenerator(VEH_AIRCRAFT, new_owner) }; + /* Override company settings to new company defaults in case we need to convert them. + * This is required as the CmdChangeServiceInt doesn't copy the supplied value when it is non-custom + */ + if (new_owner != INVALID_OWNER) { + Company *old_company = Company::Get(old_owner); + Company *new_company = Company::Get(new_owner); + + old_company->settings.vehicle.servint_aircraft = new_company->settings.vehicle.servint_aircraft; + old_company->settings.vehicle.servint_trains = new_company->settings.vehicle.servint_trains; + old_company->settings.vehicle.servint_roadveh = new_company->settings.vehicle.servint_roadveh; + old_company->settings.vehicle.servint_ships = new_company->settings.vehicle.servint_ships; + old_company->settings.vehicle.servint_ispercent = new_company->settings.vehicle.servint_ispercent; + } + Vehicle *v; FOR_ALL_VEHICLES(v) { if (v->owner == old_owner && IsCompanyBuildableVehicleType(v->type)) { assert(new_owner != INVALID_OWNER); + /* Correct default values of interval settings while maintaining custom set ones. + * This prevents invalid values on mismatching company defaults being accepted. + */ + if (!v->ServiceIntervalIsCustom()) { + Company *new_company = Company::Get(new_owner); + + /* Technically, passing the interval is not needed as the command will query the default value itself. + * However, do not rely on that behaviour. + */ + int interval = CompanyServiceInterval(new_company, v->type); + DoCommand(v->tile, v->index, interval | (new_company->settings.vehicle.servint_ispercent << 17), DC_EXEC | DC_BANKRUPT, CMD_CHANGE_SERVICE_INT); + } + v->owner = new_owner; /* Owner changes, clear cache */ diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp index 3a36f146c9..013b375bda 100644 --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -2200,7 +2200,7 @@ static const NWidgetPart _nested_network_company_password_window_widgets[] = { NWidget(NWID_VERTICAL), SetPIP(5, 5, 5), NWidget(NWID_HORIZONTAL), SetPIP(5, 5, 5), NWidget(WWT_TEXT, COLOUR_GREY, WID_NCP_LABEL), SetDataTip(STR_COMPANY_VIEW_PASSWORD, STR_NULL), - NWidget(WWT_EDITBOX, COLOUR_GREY, WID_NCP_PASSWORD), SetMinimalSize(194, 12), SetDataTip(STR_COMPANY_VIEW_SET_PASSWORD, STR_NULL), + NWidget(WWT_EDITBOX, COLOUR_GREY, WID_NCP_PASSWORD), SetFill(1, 0), SetMinimalSize(194, 12), SetDataTip(STR_COMPANY_VIEW_SET_PASSWORD, STR_NULL), EndContainer(), NWidget(NWID_HORIZONTAL), SetPIP(5, 0, 5), NWidget(NWID_SPACER), SetFill(1, 0), diff --git a/src/timetable_cmd.cpp b/src/timetable_cmd.cpp index c6eaf3da81..29986c353d 100644 --- a/src/timetable_cmd.cpp +++ b/src/timetable_cmd.cpp @@ -96,6 +96,7 @@ static void ChangeTimetable(Vehicle *v, VehicleOrderID order_number, uint16 val, * - p1 = (bit 28-29) - Timetable data to change (@see ModifyTimetableFlags) * @param p2 The amount of time to wait. * - p2 = (bit 0-15) - The data to modify as specified by p1 bits 28-29. + * 0 to clear times, UINT16_MAX to clear speed limit. * @param text unused * @return the cost of this operation or an error */ @@ -154,14 +155,29 @@ CommandCost CmdChangeTimetable(TileIndex tile, DoCommandFlag flags, uint32 p1, u if (max_speed != order->GetMaxSpeed() && (order->IsType(OT_CONDITIONAL) || v->type == VEH_AIRCRAFT)) return CMD_ERROR; if (flags & DC_EXEC) { - if (wait_time != order->GetWaitTime() || (wait_time > 0 && !order->IsWaitTimetabled())) { - ChangeTimetable(v, order_number, wait_time, MTF_WAIT_TIME, wait_time > 0); - } - if (travel_time != order->GetTravelTime() || (travel_time > 0 && !order->IsTravelTimetabled())) { - ChangeTimetable(v, order_number, travel_time, MTF_TRAVEL_TIME, travel_time > 0); - } - if (max_speed != order->GetMaxSpeed()) { - ChangeTimetable(v, order_number, max_speed, MTF_TRAVEL_SPEED, max_speed != UINT16_MAX); + switch (mtf) { + case MTF_WAIT_TIME: + /* Set time if changing the value or confirming an estimated time as timetabled. */ + if (wait_time != order->GetWaitTime() || (wait_time > 0 && !order->IsWaitTimetabled())) { + ChangeTimetable(v, order_number, wait_time, MTF_WAIT_TIME, wait_time > 0); + } + break; + + case MTF_TRAVEL_TIME: + /* Set time if changing the value or confirming an estimated time as timetabled. */ + if (travel_time != order->GetTravelTime() || (travel_time > 0 && !order->IsTravelTimetabled())) { + ChangeTimetable(v, order_number, travel_time, MTF_TRAVEL_TIME, travel_time > 0); + } + break; + + case MTF_TRAVEL_SPEED: + if (max_speed != order->GetMaxSpeed()) { + ChangeTimetable(v, order_number, max_speed, MTF_TRAVEL_SPEED, max_speed != UINT16_MAX); + } + break; + + default: + break; } } @@ -368,6 +384,9 @@ void UpdateVehicleTimetable(Vehicle *v, bool travelling) if (v->current_order.IsType(OT_IMPLICIT)) return; // no timetabling of auto orders + if (v->cur_real_order_index >= v->GetNumOrders()) return; + Order *real_current_order = v->GetOrder(v->cur_real_order_index); + VehicleOrderID first_manual_order = 0; for (Order *o = v->GetFirstOrder(); o != NULL && o->IsType(OT_IMPLICIT); o = o->next) { ++first_manual_order; @@ -395,17 +414,20 @@ void UpdateVehicleTimetable(Vehicle *v, bool travelling) if (!HasBit(v->vehicle_flags, VF_TIMETABLE_STARTED)) return; bool autofilling = HasBit(v->vehicle_flags, VF_AUTOFILL_TIMETABLE); - if (travelling && (!v->current_order.IsWaitTimetabled() || - (autofilling && !HasBit(v->vehicle_flags, VF_AUTOFILL_PRES_WAIT_TIME)))) { - /* Need to clear that now as otherwise we are not able to reduce the wait time */ + bool remeasure_wait_time = !real_current_order->IsWaitTimetabled() || + (autofilling && !HasBit(v->vehicle_flags, VF_AUTOFILL_PRES_WAIT_TIME)); + + if (travelling && remeasure_wait_time) { + /* We just finished travelling and want to remeasure the loading time, + * so do not apply any restrictions for the loading to finish. */ v->current_order.SetWaitTime(0); } if (just_started) return; - /* Modify station waiting time only if our new value is larger (this is - * always the case when we cleared the timetable). */ - if (!v->current_order.IsType(OT_CONDITIONAL) && (travelling || time_taken > v->current_order.GetWaitTime())) { + /* Before modifying waiting times, check whether we want to preserve bigger ones. */ + if (!real_current_order->IsType(OT_CONDITIONAL) && + (travelling || time_taken > real_current_order->GetWaitTime() || remeasure_wait_time)) { /* Round the time taken up to the nearest day, as this will avoid * confusion for people who are timetabling in days, and can be * adjusted later by people who aren't. @@ -417,9 +439,9 @@ void UpdateVehicleTimetable(Vehicle *v, bool travelling) * processing of different orders when filling the timetable. */ uint time_to_set = CeilDiv(max(time_taken, 1U), DAY_TICKS) * DAY_TICKS; - if (travelling && (autofilling || !v->current_order.IsTravelTimetabled())) { + if (travelling && (autofilling || !real_current_order->IsTravelTimetabled())) { ChangeTimetable(v, v->cur_real_order_index, time_to_set, MTF_TRAVEL_TIME, autofilling); - } else if (!travelling && (autofilling || !v->current_order.IsWaitTimetabled())) { + } else if (!travelling && (autofilling || !real_current_order->IsWaitTimetabled())) { ChangeTimetable(v, v->cur_real_order_index, time_to_set, MTF_WAIT_TIME, autofilling); } } @@ -434,8 +456,8 @@ void UpdateVehicleTimetable(Vehicle *v, bool travelling) if (autofilling) return; - uint timetabled = travelling ? v->current_order.GetTimetabledTravel() : - v->current_order.GetTimetabledWait(); + uint timetabled = travelling ? real_current_order->GetTimetabledTravel() : + real_current_order->GetTimetabledWait(); /* Vehicles will wait at stations if they arrive early even if they are not * timetabled to wait there, so make sure the lateness counter is updated diff --git a/src/widget.cpp b/src/widget.cpp index a6176bd31f..350db9d141 100644 --- a/src/widget.cpp +++ b/src/widget.cpp @@ -2284,7 +2284,7 @@ void NWidgetLeaf::SetupSmallestSize(Window *w, bool init_array) } case WWT_EDITBOX: { Dimension sprite_size = GetSpriteSize(_current_text_dir == TD_RTL ? SPR_IMG_DELETE_RIGHT : SPR_IMG_DELETE_LEFT); - size.width = 30 + sprite_size.width; + size.width = max(size.width, 30 + sprite_size.width); size.height = max(sprite_size.height, GetStringBoundingBox("_").height + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM); /* FALL THROUGH */ }