Current Status (Research Findings)
- Group data structure:
src/group.hGroup(name/owner/vehicle_type/flags/livery/statistics/parent/number),GroupID,DEFAULT_GROUP; - Existing commands (
src/group_cmd.h/group_cmd.cpp):CmdCreateGroup,CmdDeleteGroup,CmdAlterGroup(rename/set parent group)CmdAddVehicleGroup(single vehicle into group)CmdAddSharedVehicleGroup(adds vehicles sharing orders with a given vehicle to an existing group)CmdCreateGroupFromList(create group from a vehicle list, supportsVL_SHARED_ORDERSlist type; auto-naming)
- Auto-naming helper:
GenerateAutoNameForVehicleGroup()(group_cmd.cpp:899, by route start/end townSTR_VEHICLE_AUTO_GROUP_ROUTE/_LOCAL_ROUTE) — jgrpp already has the "name by route" infrastructure; - Command registration mechanism:
command_type.henum class Commands+DEF_CMD_TUPLE_NT(macro that simultaneously declares the handler and registersCommandTraits); - Vehicle↔Group:
vehicle_base.hVehicle::group_id; shared order chainFirstShared()/NextShared();OrderList *orders.
Conclusion: Missing a single command that "iterates all company vehicles, auto-creates groups by shared orders, and assigns vehicles to them."
This Feature Implementation
New Command Commands::AutoGroupSharedOrders (CmdAutoGroupSharedOrders)
Flow (src/group_cmd.cpp):
- Iterate all primary vehicles of the specified type for the company (
Vehicle::IterateTypeFrontOnly(type)), skip vehicles not owned by this company, without orders, or already in a custom group; - Count each shared order chain; when ≥2 vehicles share the same order list:
- Use
GenerateAutoNameForVehicleGroup(v)to generate a group name (e.g., "Town A ↔ Town B"); - Construct
VehicleListIdentifier(VL_SHARED_ORDERS, ...), nest a call toCommand<Commands::CreateGroupFromList>::Do(flags, ...)to create the group and move all shared vehicles into it; - After completion, vehicles in that group have a
group_iddifferent from the default group, so the loop automatically skips them (only one group per order list);
- Use
GroupChangeDeferredUpdateScopedefers group statistics updates uniformly.
Three Entry Points
| Entry Point | Location | Description |
|---|---|---|
| Group window button | src/group_gui.cpp new WID_GL_AUTOGROUP_SHARED (toolbar near LIVERY), OnClick sends command | Reuses SPR_GROUP_CREATE_TRAIN + vtype sprite |
| Console command | src/console_cmds.cpp autogroup [train|road|ship|aircraft] (no argument = execute for all four types) | IConsole::CmdRegister |
| Script/Other | Any code can call Command<Commands::AutoGroupSharedOrders>::Post(...) | Command goes through network sync, safe for multiplayer servers |
Involved Files
src/command_type.h:Commandsenum addsAutoGroupSharedOrders(Note: inserting in the middle shifts subsequent command IDs, causing inconsistency between old and new version multiplayer — this is normal within a fork)src/group_cmd.h/group_cmd.cpp: command declaration and implementationsrc/widgets/group_widget.h: new widget IDsrc/group_gui.cpp: toolbar button (NWidget + OnPaint sprite + OnClick)src/console_cmds.cpp: console commandsrc/lang/english.txt:STR_GROUP_AUTOGROUP_SHARED_TOOLTIP
Verification Points
- Two or more vehicles sharing the same order list → clicking the button /
autogroupcreates a "route name" group with all vehicles assigned; - Already grouped vehicles are not moved again; different order lists each form their own group;
- Group vehicle statistics (count/profit) are correctly refreshed (depends on
GroupChangeDeferredUpdateScope).