diff options
author | peter1138 <peter1138@openttd.org> | 2014-04-08 21:09:06 +0000 |
---|---|---|
committer | peter1138 <peter1138@openttd.org> | 2014-04-08 21:09:06 +0000 |
commit | 567d0ff3a7286fe830bf188c2911e3d10d70eb8c (patch) | |
tree | f61a570d4fb3a9bb1419b0eee818692686d75462 /src | |
parent | 3e9c10f9e11935a82d33fd5c66592d795c279777 (diff) | |
download | openttd-567d0ff3a7286fe830bf188c2911e3d10d70eb8c.tar.xz |
(svn r26450) -Feature: Hierarchical vehicle subgroups.
Diffstat (limited to 'src')
-rw-r--r-- | src/autoreplace.cpp | 2 | ||||
-rw-r--r-- | src/command.cpp | 4 | ||||
-rw-r--r-- | src/command_type.h | 2 | ||||
-rw-r--r-- | src/group.h | 3 | ||||
-rw-r--r-- | src/group_cmd.cpp | 106 | ||||
-rw-r--r-- | src/group_gui.cpp | 138 | ||||
-rw-r--r-- | src/lang/english.txt | 3 | ||||
-rw-r--r-- | src/saveload/group_sl.cpp | 3 | ||||
-rw-r--r-- | src/saveload/saveload.cpp | 3 | ||||
-rw-r--r-- | src/script/api/script_group.cpp | 2 | ||||
-rw-r--r-- | src/vehiclelist.cpp | 3 |
11 files changed, 218 insertions, 51 deletions
diff --git a/src/autoreplace.cpp b/src/autoreplace.cpp index 0cb8d997f..0788fccb3 100644 --- a/src/autoreplace.cpp +++ b/src/autoreplace.cpp @@ -28,7 +28,7 @@ static EngineRenew *GetEngineReplacement(EngineRenewList erl, EngineID engine, G EngineRenew *er = (EngineRenew *)erl; while (er != NULL) { - if (er->from == engine && er->group_id == group) return er; + if (er->from == engine && GroupIsInGroup(group, er->group_id)) return er; er = er->next; } return NULL; diff --git a/src/command.cpp b/src/command.cpp index 2891a06af..34d5ab61e 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -180,7 +180,7 @@ CommandProc CmdDepotSellAllVehicles; CommandProc CmdDepotMassAutoReplace; CommandProc CmdCreateGroup; -CommandProc CmdRenameGroup; +CommandProc CmdAlterGroup; CommandProc CmdDeleteGroup; CommandProc CmdAddVehicleGroup; CommandProc CmdAddSharedVehicleGroup; @@ -338,7 +338,7 @@ static const Command _command_proc_table[] = { DEF_CMD(CmdDepotMassAutoReplace, 0, CMDT_VEHICLE_CONSTRUCTION ), // CMD_DEPOT_MASS_AUTOREPLACE DEF_CMD(CmdCreateGroup, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_CREATE_GROUP DEF_CMD(CmdDeleteGroup, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_DELETE_GROUP - DEF_CMD(CmdRenameGroup, 0, CMDT_OTHER_MANAGEMENT ), // CMD_RENAME_GROUP + DEF_CMD(CmdAlterGroup, 0, CMDT_OTHER_MANAGEMENT ), // CMD_ALTER_GROUP DEF_CMD(CmdAddVehicleGroup, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_ADD_VEHICLE_GROUP DEF_CMD(CmdAddSharedVehicleGroup, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_ADD_SHARE_VEHICLE_GROUP DEF_CMD(CmdRemoveAllVehiclesGroup, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_REMOVE_ALL_VEHICLES_GROUP diff --git a/src/command_type.h b/src/command_type.h index b4a49bd9f..a369be665 100644 --- a/src/command_type.h +++ b/src/command_type.h @@ -314,7 +314,7 @@ enum Commands { CMD_CREATE_GROUP, ///< create a new group CMD_DELETE_GROUP, ///< delete a group - CMD_RENAME_GROUP, ///< rename a group + CMD_ALTER_GROUP, ///< alter a group CMD_ADD_VEHICLE_GROUP, ///< add a vehicle to a group CMD_ADD_SHARED_VEHICLE_GROUP, ///< add all other shared vehicles to a group which are missing CMD_REMOVE_ALL_VEHICLES_GROUP, ///< remove all vehicles from a group diff --git a/src/group.h b/src/group.h index d8680c294..91ee77e60 100644 --- a/src/group.h +++ b/src/group.h @@ -71,6 +71,8 @@ struct Group : GroupPool::PoolItem<&_group_pool> { bool replace_protection; ///< If set to true, the global autoreplace have no effect on the group GroupStatistics statistics; ///< NOSAVE: Statistics and caches on the vehicles in the group. + GroupID parent; ///< Parent group + Group(CompanyID owner = INVALID_COMPANY); ~Group(); }; @@ -101,6 +103,7 @@ void SetTrainGroupID(Train *v, GroupID grp); void UpdateTrainGroupID(Train *v); void RemoveVehicleFromGroup(const Vehicle *v); void RemoveAllGroupsForCompany(const CompanyID company); +bool GroupIsInGroup(GroupID search, GroupID group); extern GroupID _new_group_id; diff --git a/src/group_cmd.cpp b/src/group_cmd.cpp index e86b9de28..77e0b0d38 100644 --- a/src/group_cmd.cpp +++ b/src/group_cmd.cpp @@ -285,6 +285,7 @@ CommandCost CmdCreateGroup(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 Group *g = new Group(_current_company); g->replace_protection = false; g->vehicle_type = vt; + g->parent = INVALID_GROUP; _new_group_id = g->index; @@ -313,6 +314,14 @@ CommandCost CmdDeleteGroup(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 /* Remove all vehicles from the group */ DoCommand(0, p1, 0, flags, CMD_REMOVE_ALL_VEHICLES_GROUP); + /* Delete sub-groups */ + Group *gp; + FOR_ALL_GROUPS(gp) { + if (gp->parent == g->index) { + DoCommand(0, gp->index, 0, flags, CMD_DELETE_GROUP); + } + } + if (flags & DC_EXEC) { /* Update backupped orders if needed */ OrderBackup::ClearGroup(g->index); @@ -352,33 +361,60 @@ static bool IsUniqueGroupNameForVehicleType(const char *name, VehicleType type) } /** - * Rename a group + * Alter a group * @param tile unused * @param flags type of operation * @param p1 index of array group * - p1 bit 0-15 : GroupID - * @param p2 unused + * - p1 bit 16: 0 - Rename grouop + * 1 - Set group parent + * @param p2 parent group index * @param text the new name or an empty string when resetting to the default * @return the cost of this operation or an error */ -CommandCost CmdRenameGroup(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) +CommandCost CmdAlterGroup(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { - Group *g = Group::GetIfValid(p1); + Group *g = Group::GetIfValid(GB(p1, 0, 16)); if (g == NULL || g->owner != _current_company) return CMD_ERROR; - bool reset = StrEmpty(text); + if (!HasBit(p1, 16)) { + /* Rename group */ + bool reset = StrEmpty(text); + + if (!reset) { + if (Utf8StringLength(text) >= MAX_LENGTH_GROUP_NAME_CHARS) return CMD_ERROR; + if (!IsUniqueGroupNameForVehicleType(text, g->vehicle_type)) return_cmd_error(STR_ERROR_NAME_MUST_BE_UNIQUE); + } - if (!reset) { - if (Utf8StringLength(text) >= MAX_LENGTH_GROUP_NAME_CHARS) return CMD_ERROR; - if (!IsUniqueGroupNameForVehicleType(text, g->vehicle_type)) return_cmd_error(STR_ERROR_NAME_MUST_BE_UNIQUE); + if (flags & DC_EXEC) { + /* Delete the old name */ + free(g->name); + /* Assign the new one */ + g->name = reset ? NULL : strdup(text); + } + } else { + /* Set group parent */ + const Group *pg = Group::GetIfValid(GB(p2, 0, 16)); + + if (pg != NULL) { + if (pg->owner != _current_company) return CMD_ERROR; + if (pg->vehicle_type != g->vehicle_type) return CMD_ERROR; + + /* Ensure request parent isn't child of group. + * This is the only place that infinite loops are prevented. */ + const Group *looptest = pg; + while (looptest->parent != INVALID_GROUP) { + if (looptest->parent == g->index) return CMD_ERROR; + looptest = Group::Get(looptest->parent); + } + } + + if (flags & DC_EXEC) { + g->parent = (pg == NULL) ? INVALID_GROUP : pg->index; + } } if (flags & DC_EXEC) { - /* Delete the old name */ - free(g->name); - /* Assign the new one */ - g->name = reset ? NULL : strdup(text); - SetWindowDirty(WC_REPLACE_VEHICLE, g->vehicle_type); InvalidateWindowData(GetWindowClassForVehicleType(g->vehicle_type), VehicleListIdentifier(VL_GROUP_LIST, g->vehicle_type, _current_company).Pack()); } @@ -542,6 +578,20 @@ CommandCost CmdRemoveAllVehiclesGroup(TileIndex tile, DoCommandFlag flags, uint3 return CommandCost(); } +/** + * Set replace protection for a group and its sub-groups. + * @param g initial group. + * @param protect 1 to set or 0 to clear protection. + */ +static void SetGroupReplaceProtection(Group *g, bool protect) +{ + g->replace_protection = protect; + + Group *pg; + FOR_ALL_GROUPS(pg) { + if (pg->parent == g->index) SetGroupReplaceProtection(pg, protect); + } +} /** * (Un)set global replace protection from a group @@ -551,6 +601,7 @@ CommandCost CmdRemoveAllVehiclesGroup(TileIndex tile, DoCommandFlag flags, uint3 * - p1 bit 0-15 : GroupID * @param p2 * - p2 bit 0 : 1 to set or 0 to clear protection. + * - p2 bit 1 : 1 to apply to sub-groups. * @param text unused * @return the cost of this operation or an error */ @@ -560,7 +611,11 @@ CommandCost CmdSetGroupReplaceProtection(TileIndex tile, DoCommandFlag flags, ui if (g == NULL || g->owner != _current_company) return CMD_ERROR; if (flags & DC_EXEC) { - g->replace_protection = HasBit(p2, 0); + if (HasBit(p2, 1)) { + SetGroupReplaceProtection(g, HasBit(p2, 0)); + } else { + g->replace_protection = HasBit(p2, 0); + } SetWindowDirty(GetWindowClassForVehicleType(g->vehicle_type), VehicleListIdentifier(VL_GROUP_LIST, g->vehicle_type, _current_company).Pack()); InvalidateWindowData(WC_REPLACE_VEHICLE, g->vehicle_type); @@ -639,8 +694,13 @@ void UpdateTrainGroupID(Train *v) */ uint GetGroupNumEngines(CompanyID company, GroupID id_g, EngineID id_e) { + uint count = 0; const Engine *e = Engine::Get(id_e); - return GroupStatistics::Get(company, id_g, e->type).num_engines[id_e]; + const Group *g; + FOR_ALL_GROUPS(g) { + if (g->parent == id_g) count += GetGroupNumEngines(company, g->index, id_e); + } + return count + GroupStatistics::Get(company, id_g, e->type).num_engines[id_e]; } void RemoveAllGroupsForCompany(const CompanyID company) @@ -651,3 +711,19 @@ void RemoveAllGroupsForCompany(const CompanyID company) if (company == g->owner) delete g; } } + + +bool GroupIsInGroup(GroupID search, GroupID group) +{ + if (search == NEW_GROUP || + search == ALL_GROUP || + search == DEFAULT_GROUP || + search == INVALID_GROUP) return search == group; + + do { + if (search == group) return true; + search = Group::Get(search)->parent; + } while (search != INVALID_GROUP); + + return false; +} diff --git a/src/group_gui.cpp b/src/group_gui.cpp index ed3176e27..698f9a71f 100644 --- a/src/group_gui.cpp +++ b/src/group_gui.cpp @@ -30,6 +30,8 @@ #include "table/sprites.h" +static const int LEVEL_WIDTH = 10; ///< Indenting width of a sub-group in pixels + typedef GUIList<const Group*> GUIGroupList; static const NWidgetPart _nested_group_widgets[] = { @@ -105,34 +107,26 @@ private: }; VehicleID vehicle_sel; ///< Selected vehicle + GroupID group_sel; ///< Selected group (for drag/drop) GroupID group_rename; ///< Group being renamed, INVALID_GROUP if none GroupID group_over; ///< Group over which a vehicle is dragged, INVALID_GROUP if none GUIGroupList groups; ///< List of groups uint tiny_step_height; ///< Step height for the group list Scrollbar *group_sb; + SmallVector<int, 16> indents; ///< Indentation levels + Dimension column_size[VGC_END]; ///< Size of the columns in the group list. - /** - * (Re)Build the group list. - * - * @param owner The owner of the window - */ - void BuildGroupList(Owner owner) + void AddParents(GUIGroupList *source, GroupID parent, int indent) { - if (!this->groups.NeedRebuild()) return; - - this->groups.Clear(); - - const Group *g; - FOR_ALL_GROUPS(g) { - if (g->owner == owner && g->vehicle_type == this->vli.vtype) { - *this->groups.Append() = g; + for (const Group **g = source->Begin(); g != source->End(); g++) { + if ((*g)->parent == parent) { + *this->groups.Append() = *g; + *this->indents.Append() = indent; + AddParents(source, (*g)->index, indent + 1); } } - - this->groups.Compact(); - this->groups.RebuildDone(); } /** Sort the groups by their name */ @@ -159,6 +153,36 @@ private: } /** + * (Re)Build the group list. + * + * @param owner The owner of the window + */ + void BuildGroupList(Owner owner) + { + if (!this->groups.NeedRebuild()) return; + + this->groups.Clear(); + this->indents.Clear(); + + GUIGroupList list; + + const Group *g; + FOR_ALL_GROUPS(g) { + if (g->owner == owner && g->vehicle_type == this->vli.vtype) { + *list.Append() = g; + } + } + + list.ForceResort(); + list.Sort(&GroupNameSorter); + + AddParents(&list, INVALID_GROUP, 0); + + this->groups.Compact(); + this->groups.RebuildDone(); + } + + /** * Compute tiny_step_height and column_size * @return Total width required for the group list. */ @@ -204,9 +228,10 @@ private: * @param left Left of the row. * @param right Right of the row. * @param g_id Group to list. + * @param indent Indentation level. * @param protection Whether autoreplace protection is set. */ - void DrawGroupInfo(int y, int left, int right, GroupID g_id, bool protection = false) const + void DrawGroupInfo(int y, int left, int right, GroupID g_id, int indent = 0, bool protection = false) const { /* Highlight the group if a vehicle is dragged over it */ if (g_id == this->group_over) { @@ -231,7 +256,7 @@ private: str = STR_GROUP_NAME; } int x = rtl ? right - WD_FRAMERECT_RIGHT - 8 - this->column_size[VGC_NAME].width + 1 : left + WD_FRAMERECT_LEFT + 8; - DrawString(x, x + this->column_size[VGC_NAME].width - 1, y + (this->tiny_step_height - this->column_size[VGC_NAME].height) / 2, str, colour); + DrawString(x + indent * LEVEL_WIDTH, x + this->column_size[VGC_NAME].width - 1, y + (this->tiny_step_height - this->column_size[VGC_NAME].height) / 2, str, colour); /* draw autoreplace protection */ x = rtl ? x - 8 - this->column_size[VGC_PROTECT].width : x + 8 + this->column_size[VGC_NAME].width; @@ -295,6 +320,7 @@ public: this->vli.index = ALL_GROUP; this->vehicle_sel = INVALID_VEHICLE; + this->group_sel = INVALID_GROUP; this->group_rename = INVALID_GROUP; this->group_over = INVALID_GROUP; @@ -308,7 +334,6 @@ public: this->groups.ForceRebuild(); this->groups.NeedResort(); this->BuildGroupList(vli.company); - this->groups.Sort(&GroupNameSorter); this->GetWidget<NWidgetCore>(WID_GL_CAPTION)->widget_data = STR_VEHICLE_LIST_TRAIN_CAPTION + this->vli.vtype; this->GetWidget<NWidgetCore>(WID_GL_LIST_VEHICLE)->tool_tip = STR_VEHICLE_LIST_TRAIN_LIST_TOOLTIP + this->vli.vtype; @@ -442,7 +467,6 @@ public: this->SortVehicleList(); this->BuildGroupList(this->owner); - this->groups.Sort(&GroupNameSorter); this->group_sb->SetCount(this->groups.Length()); this->vscroll->SetCount(this->vehicles.Length()); @@ -508,7 +532,7 @@ public: assert(g->owner == this->owner); - DrawGroupInfo(y1, r.left, r.right, g->index, g->replace_protection); + DrawGroupInfo(y1, r.left, r.right, g->index, this->indents[i], g->replace_protection); y1 += this->tiny_step_height; } @@ -523,6 +547,19 @@ public: break; case WID_GL_LIST_VEHICLE: + if (this->vli.index != ALL_GROUP) { + /* Mark vehicles which are in sub-groups */ + int y = r.top; + uint max = min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), this->vehicles.Length()); + for (uint i = this->vscroll->GetPosition(); i < max; ++i) { + const Vehicle *v = this->vehicles[i]; + if (v->group_id != this->vli.index) { + GfxFillRect(r.left + 1, y + 1, r.right - 1, y + this->resize.step_height - 2, _colour_gradient[COLOUR_GREY][3], FILLRECT_CHECKER); + } + y += this->resize.step_height; + } + } + this->DrawVehicleListItems(this->vehicle_sel, this->resize.step_height, r); break; } @@ -560,7 +597,9 @@ public: uint id_g = this->group_sb->GetScrolledRowFromWidget(pt.y, this, WID_GL_LIST_GROUP, 0, this->tiny_step_height); if (id_g >= this->groups.Length()) return; - this->vli.index = this->groups[id_g]->index; + this->group_sel = this->vli.index = this->groups[id_g]->index; + + SetObjectToPlaceWnd(SPR_CURSOR_MOUSE, PAL_NONE, HT_DRAG, this); this->vehicles.ForceRebuild(); this->SetDirty(); @@ -620,14 +659,46 @@ public: case WID_GL_REPLACE_PROTECTION: { const Group *g = Group::GetIfValid(this->vli.index); if (g != NULL) { - DoCommandP(0, this->vli.index, !g->replace_protection, CMD_SET_GROUP_REPLACE_PROTECTION); + DoCommandP(0, this->vli.index, !g->replace_protection | (_ctrl_pressed << 1), CMD_SET_GROUP_REPLACE_PROTECTION); } break; } } } - virtual void OnDragDrop(Point pt, int widget) + void OnDragDrop_Group(Point pt, int widget) + { + const Group *g = Group::Get(this->group_sel); + + switch (widget) { + case WID_GL_ALL_VEHICLES: // All vehicles + case WID_GL_DEFAULT_VEHICLES: // Ungroupd vehicles + if (g->parent != INVALID_GROUP) { + DoCommandP(0, this->group_sel | (1 << 16), INVALID_GROUP, CMD_ALTER_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_SET_PARENT)); + } + + this->group_sel = INVALID_GROUP; + this->group_over = INVALID_GROUP; + this->SetDirty(); + break; + + case WID_GL_LIST_GROUP: { // Matrix group + uint id_g = this->group_sb->GetScrolledRowFromWidget(pt.y, this, WID_GL_LIST_GROUP, 0, this->tiny_step_height); + GroupID new_g = id_g >= this->groups.Length() ? INVALID_GROUP : this->groups[id_g]->index; + + if (this->group_sel != new_g && g->parent != new_g) { + DoCommandP(0, this->group_sel | (1 << 16), new_g, CMD_ALTER_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_SET_PARENT)); + } + + this->group_sel = INVALID_GROUP; + this->group_over = INVALID_GROUP; + this->SetDirty(); + break; + } + } + } + + void OnDragDrop_Vehicle(Point pt, int widget) { switch (widget) { case WID_GL_DEFAULT_VEHICLES: // Ungrouped vehicles @@ -668,12 +739,19 @@ public: break; } } + } + + virtual void OnDragDrop(Point pt, int widget) + { + if (this->vehicle_sel != INVALID_VEHICLE) OnDragDrop_Vehicle(pt, widget); + if (this->group_sel != INVALID_GROUP) OnDragDrop_Group(pt, widget); + _cursor.vehchain = false; } virtual void OnQueryTextFinished(char *str) { - if (str != NULL) DoCommandP(0, this->group_rename, 0, CMD_RENAME_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_RENAME), NULL, str); + if (str != NULL) DoCommandP(0, this->group_rename, 0, CMD_ALTER_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_RENAME), NULL, str); this->group_rename = INVALID_GROUP; } @@ -742,7 +820,7 @@ public: virtual void OnMouseDrag(Point pt, int widget) { - if (this->vehicle_sel == INVALID_VEHICLE) return; + if (this->vehicle_sel == INVALID_VEHICLE && this->group_sel == INVALID_GROUP) return; /* A vehicle is dragged over... */ GroupID new_group_over = INVALID_GROUP; @@ -759,7 +837,11 @@ public: } /* Do not highlight when dragging over the current group */ - if (Vehicle::Get(vehicle_sel)->group_id == new_group_over) new_group_over = INVALID_GROUP; + if (this->vehicle_sel != INVALID_VEHICLE) { + if (Vehicle::Get(vehicle_sel)->group_id == new_group_over) new_group_over = INVALID_GROUP; + } else if (this->group_sel != INVALID_GROUP) { + if (this->group_sel == new_group_over || Group::Get(this->group_sel)->parent == new_group_over) new_group_over = INVALID_GROUP; + } /* Mark widgets as dirty if the group changed. */ if (new_group_over != this->group_over) { diff --git a/src/lang/english.txt b/src/lang/english.txt index 198515a34..7bf97aaa3 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -3297,7 +3297,7 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :Ungrouped road STR_GROUP_DEFAULT_SHIPS :Ungrouped ships STR_GROUP_DEFAULT_AIRCRAFTS :Ungrouped aircraft -STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Groups - click on a group to list all vehicles of this group +STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Groups - click on a group to list all vehicles of this group. Drag and drop groups to arrange hierarchy. STR_GROUP_CREATE_TOOLTIP :{BLACK}Click to create a group STR_GROUP_DELETE_TOOLTIP :{BLACK}Delete the selected group STR_GROUP_RENAME_TOOLTIP :{BLACK}Rename the selected group @@ -4276,6 +4276,7 @@ STR_ERROR_YOU_ALREADY_OWN_IT :{WHITE}... you STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Can't create group... STR_ERROR_GROUP_CAN_T_DELETE :{WHITE}Can't delete this group... STR_ERROR_GROUP_CAN_T_RENAME :{WHITE}Can't rename group... +STR_ERROR_GROUP_CAN_T_SET_PARENT :{WHITE}Can't set parent group... STR_ERROR_GROUP_CAN_T_REMOVE_ALL_VEHICLES :{WHITE}Can't remove all vehicles from this group... STR_ERROR_GROUP_CAN_T_ADD_VEHICLE :{WHITE}Can't add the vehicle to this group... STR_ERROR_GROUP_CAN_T_ADD_SHARED_VEHICLE :{WHITE}Can't add shared vehicles to group... diff --git a/src/saveload/group_sl.cpp b/src/saveload/group_sl.cpp index 1e006a218..891d6ea6f 100644 --- a/src/saveload/group_sl.cpp +++ b/src/saveload/group_sl.cpp @@ -21,6 +21,7 @@ static const SaveLoad _group_desc[] = { SLE_VAR(Group, owner, SLE_UINT8), SLE_VAR(Group, vehicle_type, SLE_UINT8), SLE_VAR(Group, replace_protection, SLE_BOOL), + SLE_CONDVAR(Group, parent, SLE_UINT16, 189, SL_MAX_VERSION), SLE_END() }; @@ -42,6 +43,8 @@ static void Load_GRPS() while ((index = SlIterateArray()) != -1) { Group *g = new (index) Group(); SlObject(g, _group_desc); + + if (IsSavegameVersionBefore(189)) g->parent = INVALID_GROUP; } } diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp index e1daaf405..ab3e4a290 100644 --- a/src/saveload/saveload.cpp +++ b/src/saveload/saveload.cpp @@ -254,8 +254,9 @@ * 186 25833 * 187 25899 * 188 26169 1.4.x + * 189 26450 */ -extern const uint16 SAVEGAME_VERSION = 188; ///< Current savegame version of OpenTTD. +extern const uint16 SAVEGAME_VERSION = 189; ///< Current savegame version of OpenTTD. SavegameType _savegame_type; ///< type of savegame we are loading diff --git a/src/script/api/script_group.cpp b/src/script/api/script_group.cpp index 01569d824..89cbf2c71 100644 --- a/src/script/api/script_group.cpp +++ b/src/script/api/script_group.cpp @@ -57,7 +57,7 @@ EnforcePreconditionEncodedText(false, text); EnforcePreconditionCustomError(false, ::Utf8StringLength(text) < MAX_LENGTH_GROUP_NAME_CHARS, ScriptError::ERR_PRECONDITION_STRING_TOO_LONG); - return ScriptObject::DoCommand(0, group_id, 0, CMD_RENAME_GROUP, text); + return ScriptObject::DoCommand(0, group_id, 0, CMD_ALTER_GROUP, text); } /* static */ char *ScriptGroup::GetName(GroupID group_id) diff --git a/src/vehiclelist.cpp b/src/vehiclelist.cpp index e74f28f0f..fca9c5e46 100644 --- a/src/vehiclelist.cpp +++ b/src/vehiclelist.cpp @@ -12,6 +12,7 @@ #include "stdafx.h" #include "train.h" #include "vehiclelist.h" +#include "group.h" /** * Pack a VehicleListIdentifier in a single uint32. @@ -145,7 +146,7 @@ bool GenerateVehicleSortList(VehicleList *list, const VehicleListIdentifier &vli if (vli.index != ALL_GROUP) { FOR_ALL_VEHICLES(v) { if (v->type == vli.vtype && v->IsPrimaryVehicle() && - v->owner == vli.company && v->group_id == vli.index) { + v->owner == vli.company && GroupIsInGroup(v->group_id, vli.index)) { *list->Append() = v; } } |