diff --git a/src/group.h b/src/group.h index f296ee844f..5de8dd4e96 100644 --- a/src/group.h +++ b/src/group.h @@ -117,6 +117,8 @@ void RemoveVehicleFromGroup(const Vehicle *v); void RemoveAllGroupsForCompany(const CompanyID company); bool GroupIsInGroup(GroupID search, GroupID group); +std::string GenerateAutoNameForVehicleGroup(const Vehicle *v); + extern GroupID _new_group_id; #endif /* GROUP_H */ diff --git a/src/group_cmd.cpp b/src/group_cmd.cpp index 5fc8688de4..7d888dabbc 100644 --- a/src/group_cmd.cpp +++ b/src/group_cmd.cpp @@ -15,6 +15,7 @@ #include "vehicle_func.h" #include "autoreplace_base.h" #include "autoreplace_func.h" +#include "base_station_base.h" #include "string_func.h" #include "company_func.h" #include "core/pool_func.hpp" @@ -25,6 +26,9 @@ #include "table/strings.h" #include "safeguards.h" +#include "strings_func.h" +#include "town.h" +#include "townname_func.h" GroupID _new_group_id; @@ -645,6 +649,86 @@ CommandCost CmdAddVehicleGroup(TileIndex tile, DoCommandFlag flags, uint32 p1, u return CommandCost(); } +static Town* GetTownFromDestination(const DestinationID destination) +{ + Town* town = nullptr; + + BaseStation *st = BaseStation::GetIfValid(destination); + if (st != nullptr) { + town = st->town; + } + + return town; +} + +static void GetAutoGroupMostRelevantTowns(const Vehicle *vehicle, Town* &from, Town* &to) +{ + std::vector unique_destinations; + + const int num = vehicle->GetNumOrders(); + + for (int x = 0; x < num; x++) + { + Order *order = vehicle->GetOrder(x); + + if (order->GetType() != OT_GOTO_STATION) continue; + + const DestinationID dest = order->GetDestination(); + Town *town = GetTownFromDestination(dest); + + if (town != nullptr && unique_destinations.end() == std::find(unique_destinations.begin(), unique_destinations.end(), town)) + { + unique_destinations.push_back(town); + } + } + + if (unique_destinations.empty()) return; + + from = unique_destinations[0]; + + if (unique_destinations.size() > 1) { + to = unique_destinations[unique_destinations.size() - 1]; + } +} + +static CargoTypes GetVehicleCargoList(const Vehicle *vehicle) +{ + CargoTypes cargoes = 0; + + for (const Vehicle *u = vehicle; u != nullptr; u = u->Next()) { + if (u->cargo_cap == 0) continue; + + SetBit(cargoes, u->cargo_type); + } + return cargoes; +} + +std::string GenerateAutoNameForVehicleGroup(const Vehicle *v) +{ + Town *town_from = nullptr; + Town *town_to = nullptr; + + GetAutoGroupMostRelevantTowns(v, town_from, town_to); + if (town_from == nullptr) return ""; + + CargoTypes cargoes = GetVehicleCargoList(v); + + char group_name[512]; + if (town_from == town_to || town_to == nullptr) { + SetDParam(0, town_from->index); + SetDParam(1, (cargoes != 0) ? STR_VEHICLE_AUTO_GROUP_CARGO_LIST : STR_EMPTY); + SetDParam(2, cargoes); + GetString(group_name, STR_VEHICLE_AUTO_GROUP_LOCAL_ROUTE, lastof(group_name)); + } else { + SetDParam(0, town_from->index); + SetDParam(1, town_to->index); + SetDParam(2, (cargoes != 0) ? STR_VEHICLE_AUTO_GROUP_CARGO_LIST : STR_EMPTY); + SetDParam(3, cargoes); + GetString(group_name, STR_VEHICLE_AUTO_GROUP_ROUTE, lastof(group_name)); + } + return std::string(group_name); +} + /** * Add all shared vehicles of all vehicles from a group * @param tile unused diff --git a/src/group_gui.cpp b/src/group_gui.cpp index 5da1d41934..0b4f4e2cd8 100644 --- a/src/group_gui.cpp +++ b/src/group_gui.cpp @@ -999,6 +999,19 @@ public: } break; } + + case WID_GL_CREATE_GROUP: { // make new group with auto generated vehicle specific name and add vehicle + const Vehicle *v = Vehicle::Get(vehicle_sel); + this->vehicle_sel = INVALID_VEHICLE; + this->group_over = INVALID_GROUP; + this->SetDirty(); + + std::string name = GenerateAutoNameForVehicleGroup(v); + + DoCommandP(0, VehicleListIdentifier(_ctrl_pressed ? VL_SHARED_ORDERS : VL_SINGLE_VEH, v->type, v->owner, v->index).Pack(), 0, CMD_CREATE_GROUP_FROM_LIST | CMD_MSG(STR_ERROR_GROUP_CAN_T_CREATE), nullptr, name.c_str()); + + break; + } } } @@ -1110,6 +1123,21 @@ public: this->group_sel = INVALID_GROUP; this->group_over = INVALID_GROUP; this->SetWidgetDirty(WID_GL_LIST_VEHICLE); + this->SetVehicleDraggedOverCreateGroupButton(false); + } + + void SetVehicleDraggedOverCreateGroupButton(bool dragged) + { + NWidgetCore *create_group = this->GetWidget(WID_GL_CREATE_GROUP); + if (dragged && (create_group->type & WWB_PUSHBUTTON)) { + create_group->type = static_cast(create_group->type & ~WWB_PUSHBUTTON); + create_group->SetLowered(true); + create_group->SetDirty(this); + } else if (!dragged && !(create_group->type & WWB_PUSHBUTTON)) { + create_group->type = static_cast(create_group->type | WWB_PUSHBUTTON); + create_group->SetLowered(false); + create_group->SetDirty(this); + } } void OnMouseDrag(Point pt, int widget) override @@ -1118,6 +1146,8 @@ public: /* A vehicle is dragged over... */ GroupID new_group_over = INVALID_GROUP; + + bool create_group_drag_over = false; switch (widget) { case WID_GL_DEFAULT_VEHICLES: // ... the 'default' group. new_group_over = DEFAULT_GROUP; @@ -1128,8 +1158,15 @@ public: new_group_over = id_g >= this->groups.size() ? NEW_GROUP : this->groups[id_g]->index; break; } + + case WID_GL_CREATE_GROUP: { + if (this->vehicle_sel != INVALID_VEHICLE) create_group_drag_over = true; + break; + } } + this->SetVehicleDraggedOverCreateGroupButton(create_group_drag_over); + /* Do not highlight when dragging over the current group */ if (this->vehicle_sel != INVALID_VEHICLE) { if (Vehicle::Get(vehicle_sel)->group_id == new_group_over) new_group_over = INVALID_GROUP; diff --git a/src/lang/english.txt b/src/lang/english.txt index cdb9746c78..bb5cb67212 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -4926,6 +4926,10 @@ STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS :{BLACK}Reliabil STR_VEHICLE_INFO_GROUP :{BLACK}Group: {LTBLUE}{GROUP} +STR_VEHICLE_AUTO_GROUP_ROUTE :{TOWN} to {TOWN}{STRING1} +STR_VEHICLE_AUTO_GROUP_LOCAL_ROUTE :{TOWN} Local{STRING1} +STR_VEHICLE_AUTO_GROUP_CARGO_LIST : ({CARGO_LIST}) + STR_VEHICLE_INFO_BUILT_VALUE :{LTBLUE}{ENGINE} {BLACK}Built: {LTBLUE}{NUM}{BLACK} Value: {LTBLUE}{CURRENCY_LONG} STR_VEHICLE_INFO_NO_CAPACITY :{BLACK}Capacity: {LTBLUE}None{STRING} STR_VEHICLE_INFO_CAPACITY :{BLACK}Capacity: {LTBLUE}{CARGO_LONG}{3:STRING} diff --git a/src/lang/german.txt b/src/lang/german.txt index 1561c796a8..884d0d0258 100644 --- a/src/lang/german.txt +++ b/src/lang/german.txt @@ -4782,6 +4782,8 @@ STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS :{BLACK}Zuverlä STR_VEHICLE_INFO_GROUP :{BLACK}Gruppe: {LTBLUE}{GROUP} +STR_VEHICLE_AUTO_GROUP_LOCAL_ROUTE :{TOWN} Ortsbereich {CARGO_LIST} + STR_VEHICLE_INFO_BUILT_VALUE :{LTBLUE}{ENGINE} {BLACK}Gebaut: {LTBLUE}{NUM}{BLACK} Wert: {LTBLUE}{CURRENCY_LONG} STR_VEHICLE_INFO_NO_CAPACITY :{BLACK}Kapazität: {LTBLUE}Keine{STRING} STR_VEHICLE_INFO_CAPACITY :{BLACK}Kapazität: {LTBLUE}{CARGO_LONG}{3:STRING}