Codechange: Un-bitstuff group and autoreplace commands.

This commit is contained in:
Michael Lutz 2021-11-17 00:40:06 +01:00
parent 46bd2f1ced
commit e08b3abe7f
12 changed files with 118 additions and 147 deletions

View File

@ -405,7 +405,7 @@ static CommandCost CopyHeadSpecificThings(Vehicle *old_head, Vehicle *new_head,
if (cost.Succeeded() && old_head != new_head) cost.AddCost(Command<CMD_CLONE_ORDER>::Do(DC_EXEC, CO_SHARE, new_head->index, old_head->index)); if (cost.Succeeded() && old_head != new_head) cost.AddCost(Command<CMD_CLONE_ORDER>::Do(DC_EXEC, CO_SHARE, new_head->index, old_head->index));
/* Copy group membership */ /* Copy group membership */
if (cost.Succeeded() && old_head != new_head) cost.AddCost(Command<CMD_ADD_VEHICLE_GROUP>::Do(DC_EXEC, 0, old_head->group_id, new_head->index, {})); if (cost.Succeeded() && old_head != new_head) cost.AddCost(Command<CMD_ADD_VEHICLE_GROUP>::Do(DC_EXEC, old_head->group_id, new_head->index, false));
/* Perform start/stop check whether the new vehicle suits newgrf restrictions etc. */ /* Perform start/stop check whether the new vehicle suits newgrf restrictions etc. */
if (cost.Succeeded()) { if (cost.Succeeded()) {
@ -713,15 +713,12 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
* Autoreplaces a vehicle * Autoreplaces a vehicle
* Trains are replaced as a whole chain, free wagons in depot are replaced on their own * Trains are replaced as a whole chain, free wagons in depot are replaced on their own
* @param flags type of operation * @param flags type of operation
* @param tile not used * @param veh_id Index of vehicle
* @param p1 Index of vehicle
* @param p2 not used
* @param text unused
* @return the cost of this operation or an error * @return the cost of this operation or an error
*/ */
CommandCost CmdAutoreplaceVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) CommandCost CmdAutoreplaceVehicle(DoCommandFlag flags, VehicleID veh_id)
{ {
Vehicle *v = Vehicle::GetIfValid(p1); Vehicle *v = Vehicle::GetIfValid(veh_id);
if (v == nullptr) return CMD_ERROR; if (v == nullptr) return CMD_ERROR;
CommandCost ret = CheckOwnership(v->owner); CommandCost ret = CheckOwnership(v->owner);
@ -802,24 +799,17 @@ CommandCost CmdAutoreplaceVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1
/** /**
* Change engine renewal parameters * Change engine renewal parameters
* @param flags operation to perform * @param flags operation to perform
* @param tile unused * @param id_g engine group
* @param p1 packed data * @param old_engine_type old engine type
* - bit 0 = replace when engine gets old? * @param new_engine_type new engine type
* - bits 16-31 = engine group * @param when_old replace when engine gets old?
* @param p2 packed data
* - bits 0-15 = old engine type
* - bits 16-31 = new engine type
* @param text unused
* @return the cost of this operation or an error * @return the cost of this operation or an error
*/ */
CommandCost CmdSetAutoReplace(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) CommandCost CmdSetAutoReplace(DoCommandFlag flags, GroupID id_g, EngineID old_engine_type, EngineID new_engine_type, bool when_old)
{ {
Company *c = Company::GetIfValid(_current_company); Company *c = Company::GetIfValid(_current_company);
if (c == nullptr) return CMD_ERROR; if (c == nullptr) return CMD_ERROR;
EngineID old_engine_type = GB(p2, 0, 16);
EngineID new_engine_type = GB(p2, 16, 16);
GroupID id_g = GB(p1, 16, 16);
CommandCost cost; CommandCost cost;
if (Group::IsValidID(id_g) ? Group::Get(id_g)->owner != _current_company : !IsAllGroupID(id_g) && !IsDefaultGroupID(id_g)) return CMD_ERROR; if (Group::IsValidID(id_g) ? Group::Get(id_g)->owner != _current_company : !IsAllGroupID(id_g) && !IsDefaultGroupID(id_g)) return CMD_ERROR;
@ -829,7 +819,7 @@ CommandCost CmdSetAutoReplace(DoCommandFlag flags, TileIndex tile, uint32 p1, ui
if (!Engine::IsValidID(new_engine_type)) return CMD_ERROR; if (!Engine::IsValidID(new_engine_type)) return CMD_ERROR;
if (!CheckAutoreplaceValidity(old_engine_type, new_engine_type, _current_company)) 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, HasBit(p1, 0), flags); cost = AddEngineReplacementForCompany(c, old_engine_type, new_engine_type, id_g, when_old, flags);
} else { } else {
cost = RemoveEngineReplacementForCompany(c, old_engine_type, id_g, flags); cost = RemoveEngineReplacementForCompany(c, old_engine_type, id_g, flags);
} }

View File

@ -11,9 +11,12 @@
#define AUTOREPLACE_CMD_H #define AUTOREPLACE_CMD_H
#include "command_type.h" #include "command_type.h"
#include "vehicle_type.h"
#include "engine_type.h"
#include "group_type.h"
CommandProc CmdAutoreplaceVehicle; CommandCost CmdAutoreplaceVehicle(DoCommandFlag flags, VehicleID veh_id);
CommandProc CmdSetAutoReplace; CommandCost CmdSetAutoReplace(DoCommandFlag flags, GroupID id_g, EngineID old_engine_type, EngineID new_engine_type, bool when_old);
DEF_CMD_TRAIT(CMD_AUTOREPLACE_VEHICLE, CmdAutoreplaceVehicle, 0, CMDT_VEHICLE_MANAGEMENT) DEF_CMD_TRAIT(CMD_AUTOREPLACE_VEHICLE, CmdAutoreplaceVehicle, 0, CMDT_VEHICLE_MANAGEMENT)
DEF_CMD_TRAIT(CMD_SET_AUTOREPLACE, CmdSetAutoReplace, 0, CMDT_VEHICLE_MANAGEMENT) DEF_CMD_TRAIT(CMD_SET_AUTOREPLACE, CmdSetAutoReplace, 0, CMDT_VEHICLE_MANAGEMENT)

View File

@ -220,7 +220,7 @@ class ReplaceVehicleWindow : public Window {
{ {
EngineID veh_from = this->sel_engine[0]; EngineID veh_from = this->sel_engine[0];
EngineID veh_to = this->sel_engine[1]; EngineID veh_to = this->sel_engine[1];
Command<CMD_SET_AUTOREPLACE>::Post(0, (replace_when_old ? 1 : 0) | (this->sel_group << 16), veh_from + (veh_to << 16), {}); Command<CMD_SET_AUTOREPLACE>::Post(this->sel_group, veh_from, veh_to, replace_when_old);
} }
public: public:
@ -544,7 +544,7 @@ public:
case WID_RV_TRAIN_WAGONREMOVE_TOGGLE: { case WID_RV_TRAIN_WAGONREMOVE_TOGGLE: {
const Group *g = Group::GetIfValid(this->sel_group); const Group *g = Group::GetIfValid(this->sel_group);
if (g != nullptr) { if (g != nullptr) {
Command<CMD_SET_GROUP_FLAG>::Post(0, this->sel_group | (GroupFlags::GF_REPLACE_WAGON_REMOVAL << 16), (HasBit(g->flags, GroupFlags::GF_REPLACE_WAGON_REMOVAL) ? 0 : 1) | (_ctrl_pressed << 1), {}); Command<CMD_SET_GROUP_FLAG>::Post(this->sel_group, GroupFlags::GF_REPLACE_WAGON_REMOVAL, !HasBit(g->flags, GroupFlags::GF_REPLACE_WAGON_REMOVAL), _ctrl_pressed);
} else { } else {
// toggle renew_keep_length // toggle renew_keep_length
Command<CMD_CHANGE_COMPANY_SETTING>::Post(0, 0, Company::Get(_local_company)->settings.renew_keep_length ? 0 : 1, "company.renew_keep_length"); Command<CMD_CHANGE_COMPANY_SETTING>::Post(0, 0, Company::Get(_local_company)->settings.renew_keep_length ? 0 : 1, "company.renew_keep_length");
@ -565,7 +565,7 @@ public:
case WID_RV_STOP_REPLACE: { // Stop replacing case WID_RV_STOP_REPLACE: { // Stop replacing
EngineID veh_from = this->sel_engine[0]; EngineID veh_from = this->sel_engine[0];
Command<CMD_SET_AUTOREPLACE>::Post(0, this->sel_group << 16, veh_from + (INVALID_ENGINE << 16), {}); Command<CMD_SET_AUTOREPLACE>::Post(this->sel_group, veh_from, INVALID_ENGINE, false);
break; break;
} }
@ -587,7 +587,7 @@ public:
if (click_side == 0 && _ctrl_pressed && e != INVALID_ENGINE && if (click_side == 0 && _ctrl_pressed && e != INVALID_ENGINE &&
(GetGroupNumEngines(_local_company, sel_group, e) == 0 || GetGroupNumEngines(_local_company, ALL_GROUP, e) == 0)) { (GetGroupNumEngines(_local_company, sel_group, e) == 0 || GetGroupNumEngines(_local_company, ALL_GROUP, e) == 0)) {
EngineID veh_from = e; EngineID veh_from = e;
Command<CMD_SET_AUTOREPLACE>::Post(0, this->sel_group << 16, veh_from + (INVALID_ENGINE << 16), {}); Command<CMD_SET_AUTOREPLACE>::Post(this->sel_group, veh_from, INVALID_ENGINE, false);
break; break;
} }

View File

@ -1005,7 +1005,7 @@ public:
} }
} else { } else {
/* Setting group livery */ /* Setting group livery */
Command<CMD_SET_GROUP_LIVERY>::Post(0, this->sel, (widget == WID_SCL_PRI_COL_DROPDOWN ? 0 : 256) | (index << 16), {}); Command<CMD_SET_GROUP_LIVERY>::Post(this->sel, widget == WID_SCL_PRI_COL_DROPDOWN, (Colours)index);
} }
} }

View File

@ -223,7 +223,7 @@ struct SubSprite {
int left, top, right, bottom; int left, top, right, bottom;
}; };
enum Colours { enum Colours : byte {
COLOUR_BEGIN, COLOUR_BEGIN,
COLOUR_DARK_BLUE = COLOUR_BEGIN, COLOUR_DARK_BLUE = COLOUR_BEGIN,
COLOUR_PALE_GREEN, COLOUR_PALE_GREEN,

View File

@ -295,20 +295,17 @@ Group::Group(Owner owner)
/** /**
* Create a new vehicle group. * Create a new vehicle group.
* @param flags type of operation * @param flags type of operation
* @param tile unused * @param vt vehicle type
* @param p1 vehicle type * @param parent_group parent groupid
* @param p2 parent groupid
* @param text unused
* @return the cost of this operation or an error * @return the cost of this operation or an error
*/ */
CommandCost CmdCreateGroup(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) CommandCost CmdCreateGroup(DoCommandFlag flags, VehicleType vt, GroupID parent_group)
{ {
VehicleType vt = Extract<VehicleType, 0, 3>(p1);
if (!IsCompanyBuildableVehicleType(vt)) return CMD_ERROR; if (!IsCompanyBuildableVehicleType(vt)) return CMD_ERROR;
if (!Group::CanAllocateItem()) return CMD_ERROR; if (!Group::CanAllocateItem()) return CMD_ERROR;
const Group *pg = Group::GetIfValid(GB(p2, 0, 16)); const Group *pg = Group::GetIfValid(parent_group);
if (pg != nullptr) { if (pg != nullptr) {
if (pg->owner != _current_company) return CMD_ERROR; if (pg->owner != _current_company) return CMD_ERROR;
if (pg->vehicle_type != vt) return CMD_ERROR; if (pg->vehicle_type != vt) return CMD_ERROR;
@ -344,25 +341,21 @@ CommandCost CmdCreateGroup(DoCommandFlag flags, TileIndex tile, uint32 p1, uint3
/** /**
* Add all vehicles in the given group to the default group and then deletes the group. * Add all vehicles in the given group to the default group and then deletes the group.
* @param flags type of operation * @param flags type of operation
* @param tile unused * @param group_id index of group
* @param p1 index of array group
* - p1 bit 0-15 : GroupID
* @param p2 unused
* @param text unused
* @return the cost of this operation or an error * @return the cost of this operation or an error
*/ */
CommandCost CmdDeleteGroup(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) CommandCost CmdDeleteGroup(DoCommandFlag flags, GroupID group_id)
{ {
Group *g = Group::GetIfValid(p1); Group *g = Group::GetIfValid(group_id);
if (g == nullptr || g->owner != _current_company) return CMD_ERROR; if (g == nullptr || g->owner != _current_company) return CMD_ERROR;
/* Remove all vehicles from the group */ /* Remove all vehicles from the group */
Command<CMD_REMOVE_ALL_VEHICLES_GROUP>::Do(flags, 0, p1, 0, {}); Command<CMD_REMOVE_ALL_VEHICLES_GROUP>::Do(flags, group_id);
/* Delete sub-groups */ /* Delete sub-groups */
for (const Group *gp : Group::Iterate()) { for (const Group *gp : Group::Iterate()) {
if (gp->parent == g->index) { if (gp->parent == g->index) {
Command<CMD_DELETE_GROUP>::Do(flags, 0, gp->index, 0, {}); Command<CMD_DELETE_GROUP>::Do(flags, gp->index);
} }
} }
@ -396,21 +389,18 @@ CommandCost CmdDeleteGroup(DoCommandFlag flags, TileIndex tile, uint32 p1, uint3
/** /**
* Alter a group * Alter a group
* @param flags type of operation * @param flags type of operation
* @param tile unused * @param mode Operation to perform.
* @param p1 index of array group * @param group_id GroupID
* - p1 bit 0-15 : GroupID * @param parent_id parent group index
* - 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 * @param text the new name or an empty string when resetting to the default
* @return the cost of this operation or an error * @return the cost of this operation or an error
*/ */
CommandCost CmdAlterGroup(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) CommandCost CmdAlterGroup(DoCommandFlag flags, AlterGroupMode mode, GroupID group_id, GroupID parent_id, const std::string &text)
{ {
Group *g = Group::GetIfValid(GB(p1, 0, 16)); Group *g = Group::GetIfValid(group_id);
if (g == nullptr || g->owner != _current_company) return CMD_ERROR; if (g == nullptr || g->owner != _current_company) return CMD_ERROR;
if (!HasBit(p1, 16)) { if (mode == AlterGroupMode::Rename) {
/* Rename group */ /* Rename group */
bool reset = text.empty(); bool reset = text.empty();
@ -426,9 +416,9 @@ CommandCost CmdAlterGroup(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32
g->name = text; g->name = text;
} }
} }
} else { } else if (mode == AlterGroupMode::SetParent) {
/* Set group parent */ /* Set group parent */
const Group *pg = Group::GetIfValid(GB(p2, 0, 16)); const Group *pg = Group::GetIfValid(parent_id);
if (pg != nullptr) { if (pg != nullptr) {
if (pg->owner != _current_company) return CMD_ERROR; if (pg->owner != _current_company) return CMD_ERROR;
@ -452,6 +442,8 @@ CommandCost CmdAlterGroup(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32
MarkWholeScreenDirty(); MarkWholeScreenDirty();
} }
} }
} else {
return CMD_ERROR;
} }
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
@ -500,19 +492,15 @@ static void AddVehicleToGroup(Vehicle *v, GroupID new_g)
/** /**
* Add a vehicle to a group * Add a vehicle to a group
* @param flags type of operation * @param flags type of operation
* @param tile unused * @param group_id index of group
* @param p1 index of array group * @param veh_id vehicle to add to a group
* - p1 bit 0-15 : GroupID * @param add_shared Add shared vehicles as well.
* @param p2 vehicle to add to a group
* - p2 bit 0-19 : VehicleID
* - p2 bit 31 : Add shared vehicles as well.
* @param text unused
* @return the cost of this operation or an error * @return the cost of this operation or an error
*/ */
CommandCost CmdAddVehicleGroup(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) CommandCost CmdAddVehicleGroup(DoCommandFlag flags, GroupID group_id, VehicleID veh_id, bool add_shared)
{ {
Vehicle *v = Vehicle::GetIfValid(GB(p2, 0, 20)); Vehicle *v = Vehicle::GetIfValid(veh_id);
GroupID new_g = p1; GroupID new_g = group_id;
if (v == nullptr || (!Group::IsValidID(new_g) && !IsDefaultGroupID(new_g) && new_g != NEW_GROUP)) return CMD_ERROR; if (v == nullptr || (!Group::IsValidID(new_g) && !IsDefaultGroupID(new_g) && new_g != NEW_GROUP)) return CMD_ERROR;
@ -525,7 +513,7 @@ CommandCost CmdAddVehicleGroup(DoCommandFlag flags, TileIndex tile, uint32 p1, u
if (new_g == NEW_GROUP) { if (new_g == NEW_GROUP) {
/* Create new group. */ /* Create new group. */
CommandCost ret = CmdCreateGroup(flags, 0, v->type, INVALID_GROUP, {}); CommandCost ret = CmdCreateGroup(flags, v->type, INVALID_GROUP);
if (ret.Failed()) return ret; if (ret.Failed()) return ret;
new_g = _new_group_id; new_g = _new_group_id;
@ -534,7 +522,7 @@ CommandCost CmdAddVehicleGroup(DoCommandFlag flags, TileIndex tile, uint32 p1, u
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
AddVehicleToGroup(v, new_g); AddVehicleToGroup(v, new_g);
if (HasBit(p2, 31)) { if (add_shared) {
/* Add vehicles in the shared order list as well. */ /* Add vehicles in the shared order list as well. */
for (Vehicle *v2 = v->FirstShared(); v2 != nullptr; v2 = v2->NextShared()) { for (Vehicle *v2 = v->FirstShared(); v2 != nullptr; v2 = v2->NextShared()) {
if (v2->group_id != new_g) AddVehicleToGroup(v2, new_g); if (v2->group_id != new_g) AddVehicleToGroup(v2, new_g);
@ -559,17 +547,12 @@ CommandCost CmdAddVehicleGroup(DoCommandFlag flags, TileIndex tile, uint32 p1, u
/** /**
* Add all shared vehicles of all vehicles from a group * Add all shared vehicles of all vehicles from a group
* @param flags type of operation * @param flags type of operation
* @param tile unused * @param id_g index of group
* @param p1 index of group array * @param type type of vehicles
* - p1 bit 0-15 : GroupID
* @param p2 type of vehicles
* @param text unused
* @return the cost of this operation or an error * @return the cost of this operation or an error
*/ */
CommandCost CmdAddSharedVehicleGroup(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) CommandCost CmdAddSharedVehicleGroup(DoCommandFlag flags, GroupID id_g, VehicleType type)
{ {
VehicleType type = Extract<VehicleType, 0, 3>(p2);
GroupID id_g = p1;
if (!Group::IsValidID(id_g) || !IsCompanyBuildableVehicleType(type)) return CMD_ERROR; if (!Group::IsValidID(id_g) || !IsCompanyBuildableVehicleType(type)) return CMD_ERROR;
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
@ -581,7 +564,7 @@ CommandCost CmdAddSharedVehicleGroup(DoCommandFlag flags, TileIndex tile, uint32
/* For each shared vehicles add it to the group */ /* For each shared vehicles add it to the group */
for (Vehicle *v2 = v->FirstShared(); v2 != nullptr; v2 = v2->NextShared()) { for (Vehicle *v2 = v->FirstShared(); v2 != nullptr; v2 = v2->NextShared()) {
if (v2->group_id != id_g) Command<CMD_ADD_VEHICLE_GROUP>::Do(flags, tile, id_g, v2->index, text); if (v2->group_id != id_g) Command<CMD_ADD_VEHICLE_GROUP>::Do(flags, id_g, v2->index, false);
} }
} }
} }
@ -596,17 +579,12 @@ CommandCost CmdAddSharedVehicleGroup(DoCommandFlag flags, TileIndex tile, uint32
/** /**
* Remove all vehicles from a group * Remove all vehicles from a group
* @param flags type of operation * @param flags type of operation
* @param tile unused * @param group_id index of group
* @param p1 index of group array
* - p1 bit 0-15 : GroupID
* @param p2 unused
* @param text unused
* @return the cost of this operation or an error * @return the cost of this operation or an error
*/ */
CommandCost CmdRemoveAllVehiclesGroup(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) CommandCost CmdRemoveAllVehiclesGroup(DoCommandFlag flags, GroupID group_id)
{ {
GroupID old_g = p1; Group *g = Group::GetIfValid(group_id);
Group *g = Group::GetIfValid(old_g);
if (g == nullptr || g->owner != _current_company) return CMD_ERROR; if (g == nullptr || g->owner != _current_company) return CMD_ERROR;
@ -614,10 +592,10 @@ CommandCost CmdRemoveAllVehiclesGroup(DoCommandFlag flags, TileIndex tile, uint3
/* Find each Vehicle that belongs to the group old_g and add it to the default group */ /* Find each Vehicle that belongs to the group old_g and add it to the default group */
for (const Vehicle *v : Vehicle::Iterate()) { for (const Vehicle *v : Vehicle::Iterate()) {
if (v->IsPrimaryVehicle()) { if (v->IsPrimaryVehicle()) {
if (v->group_id != old_g) continue; if (v->group_id != group_id) continue;
/* Add The Vehicle to the default group */ /* Add The Vehicle to the default group */
Command<CMD_ADD_VEHICLE_GROUP>::Do(flags,tile, DEFAULT_GROUP, v->index, text); Command<CMD_ADD_VEHICLE_GROUP>::Do(flags, DEFAULT_GROUP, v->index, false);
} }
} }
@ -630,18 +608,13 @@ CommandCost CmdRemoveAllVehiclesGroup(DoCommandFlag flags, TileIndex tile, uint3
/** /**
* Set the livery for a vehicle group. * Set the livery for a vehicle group.
* @param flags Command flags. * @param flags Command flags.
* @param tile Unused. * @param group_id Group ID.
* @param p1 * @param primary Set primary instead of secondary colour
* - p1 bit 0-15 Group ID. * @param colour Colour.
* @param p2
* - p2 bit 8 Set secondary instead of primary colour
* - p2 bit 16-23 Colour.
*/ */
CommandCost CmdSetGroupLivery(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) CommandCost CmdSetGroupLivery(DoCommandFlag flags, GroupID group_id, bool primary, Colours colour)
{ {
Group *g = Group::GetIfValid(p1); Group *g = Group::GetIfValid(group_id);
bool primary = !HasBit(p2, 8);
Colours colour = Extract<Colours, 16, 8>(p2);
if (g == nullptr || g->owner != _current_company) return CMD_ERROR; if (g == nullptr || g->owner != _current_company) return CMD_ERROR;
@ -689,27 +662,21 @@ static void SetGroupFlag(Group *g, GroupFlags flag, bool set, bool children)
* (Un)set group flag from a group * (Un)set group flag from a group
* @param flags type of operation * @param flags type of operation
* @param tile unused * @param tile unused
* @param p1 index of group array * @param group_id index of group array
* - p1 bit 0-15 : GroupID * @param flag flag to set, by value not bit.
* - p1 bit 16-18 : Flag to set, by value not bit. * @param value value to set the flag to.
* @param p2 * @param recursive to apply to sub-groups.
* - 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 * @return the cost of this operation or an error
*/ */
CommandCost CmdSetGroupFlag(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) CommandCost CmdSetGroupFlag(DoCommandFlag flags, GroupID group_id, GroupFlags flag, bool value, bool recursive)
{ {
Group *g = Group::GetIfValid(GB(p1, 0, 16)); Group *g = Group::GetIfValid(group_id);
if (g == nullptr || g->owner != _current_company) return CMD_ERROR; if (g == nullptr || g->owner != _current_company) return CMD_ERROR;
/* GroupFlags are stored in as an 8 bit bitfield but passed here by value,
* so 3 bits is sufficient to cover each possible value. */
GroupFlags flag = (GroupFlags)GB(p1, 16, 3);
if (flag >= GroupFlags::GF_END) return CMD_ERROR; if (flag >= GroupFlags::GF_END) return CMD_ERROR;
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
SetGroupFlag(g, flag, HasBit(p2, 0), HasBit(p2, 1)); SetGroupFlag(g, flag, value, recursive);
SetWindowDirty(GetWindowClassForVehicleType(g->vehicle_type), VehicleListIdentifier(VL_GROUP_LIST, g->vehicle_type, _current_company).Pack()); SetWindowDirty(GetWindowClassForVehicleType(g->vehicle_type), VehicleListIdentifier(VL_GROUP_LIST, g->vehicle_type, _current_company).Pack());
InvalidateWindowData(WC_REPLACE_VEHICLE, g->vehicle_type); InvalidateWindowData(WC_REPLACE_VEHICLE, g->vehicle_type);

View File

@ -11,15 +11,26 @@
#define GROUP_CMD_H #define GROUP_CMD_H
#include "command_type.h" #include "command_type.h"
#include "group_type.h"
#include "vehicle_type.h"
CommandProc CmdCreateGroup; enum Colours : byte;
CommandProc CmdAlterGroup; enum GroupFlags : uint8;
CommandProc CmdDeleteGroup;
CommandProc CmdAddVehicleGroup; /** Action for \c CmdAlterGroup. */
CommandProc CmdAddSharedVehicleGroup; enum class AlterGroupMode : byte {
CommandProc CmdRemoveAllVehiclesGroup; Rename, ///< Change group name.
CommandProc CmdSetGroupFlag; SetParent, ///< Change group parent.
CommandProc CmdSetGroupLivery; };
CommandCost CmdCreateGroup(DoCommandFlag flags, VehicleType vt, GroupID parent_group);
CommandCost CmdAlterGroup(DoCommandFlag flags, AlterGroupMode mode, GroupID group_id, GroupID parent_id, const std::string &text);
CommandCost CmdDeleteGroup(DoCommandFlag flags, GroupID group_id);
CommandCost CmdAddVehicleGroup(DoCommandFlag flags, GroupID group_id, VehicleID veh_id, bool add_shared);
CommandCost CmdAddSharedVehicleGroup(DoCommandFlag flags, GroupID id_g, VehicleType type);
CommandCost CmdRemoveAllVehiclesGroup(DoCommandFlag flags, GroupID group_id);
CommandCost CmdSetGroupFlag(DoCommandFlag flags, GroupID group_id, GroupFlags flag, bool value, bool recursive);
CommandCost CmdSetGroupLivery(DoCommandFlag flags, GroupID group_id, bool primary, Colours colour);
DEF_CMD_TRAIT(CMD_CREATE_GROUP, CmdCreateGroup, 0, CMDT_ROUTE_MANAGEMENT) DEF_CMD_TRAIT(CMD_CREATE_GROUP, CmdCreateGroup, 0, CMDT_ROUTE_MANAGEMENT)
DEF_CMD_TRAIT(CMD_DELETE_GROUP, CmdDeleteGroup, 0, CMDT_ROUTE_MANAGEMENT) DEF_CMD_TRAIT(CMD_DELETE_GROUP, CmdDeleteGroup, 0, CMDT_ROUTE_MANAGEMENT)

View File

@ -642,7 +642,7 @@ public:
if (confirmed) { if (confirmed) {
VehicleGroupWindow *w = (VehicleGroupWindow*)win; VehicleGroupWindow *w = (VehicleGroupWindow*)win;
w->vli.index = ALL_GROUP; w->vli.index = ALL_GROUP;
Command<CMD_DELETE_GROUP>::Post(STR_ERROR_GROUP_CAN_T_DELETE, 0, w->group_confirm, 0, {}); Command<CMD_DELETE_GROUP>::Post(STR_ERROR_GROUP_CAN_T_DELETE, w->group_confirm);
} }
} }
@ -773,7 +773,7 @@ public:
} }
case WID_GL_CREATE_GROUP: { // Create a new group case WID_GL_CREATE_GROUP: { // Create a new group
Command<CMD_CREATE_GROUP>::Post(STR_ERROR_GROUP_CAN_T_CREATE, CcCreateGroup, 0, this->vli.vtype, this->vli.index, {}); Command<CMD_CREATE_GROUP>::Post(STR_ERROR_GROUP_CAN_T_CREATE, CcCreateGroup, this->vli.vtype, this->vli.index);
break; break;
} }
@ -809,7 +809,7 @@ public:
case WID_GL_REPLACE_PROTECTION: { case WID_GL_REPLACE_PROTECTION: {
const Group *g = Group::GetIfValid(this->vli.index); const Group *g = Group::GetIfValid(this->vli.index);
if (g != nullptr) { if (g != nullptr) {
Command<CMD_SET_GROUP_FLAG>::Post(0, this->vli.index | (GroupFlags::GF_REPLACE_PROTECTION << 16), (HasBit(g->flags, GroupFlags::GF_REPLACE_PROTECTION) ? 0 : 1) | (_ctrl_pressed << 1), {}); Command<CMD_SET_GROUP_FLAG>::Post(this->vli.index, GroupFlags::GF_REPLACE_PROTECTION, !HasBit(g->flags, GroupFlags::GF_REPLACE_PROTECTION), _ctrl_pressed);
} }
break; break;
} }
@ -824,7 +824,7 @@ public:
case WID_GL_ALL_VEHICLES: // All vehicles case WID_GL_ALL_VEHICLES: // All vehicles
case WID_GL_DEFAULT_VEHICLES: // Ungrouped vehicles case WID_GL_DEFAULT_VEHICLES: // Ungrouped vehicles
if (g->parent != INVALID_GROUP) { if (g->parent != INVALID_GROUP) {
Command<CMD_ALTER_GROUP>::Post(STR_ERROR_GROUP_CAN_T_SET_PARENT, 0, this->group_sel | (1 << 16), INVALID_GROUP, {}); Command<CMD_ALTER_GROUP>::Post(STR_ERROR_GROUP_CAN_T_SET_PARENT, AlterGroupMode::SetParent, this->group_sel, INVALID_GROUP, {});
} }
this->group_sel = INVALID_GROUP; this->group_sel = INVALID_GROUP;
@ -837,7 +837,7 @@ public:
GroupID new_g = id_g >= this->groups.size() ? INVALID_GROUP : this->groups[id_g]->index; GroupID new_g = id_g >= this->groups.size() ? INVALID_GROUP : this->groups[id_g]->index;
if (this->group_sel != new_g && g->parent != new_g) { if (this->group_sel != new_g && g->parent != new_g) {
Command<CMD_ALTER_GROUP>::Post(STR_ERROR_GROUP_CAN_T_SET_PARENT, 0, this->group_sel | (1 << 16), new_g, {}); Command<CMD_ALTER_GROUP>::Post(STR_ERROR_GROUP_CAN_T_SET_PARENT, AlterGroupMode::SetParent, this->group_sel, new_g, {});
} }
this->group_sel = INVALID_GROUP; this->group_sel = INVALID_GROUP;
@ -852,7 +852,7 @@ public:
{ {
switch (widget) { switch (widget) {
case WID_GL_DEFAULT_VEHICLES: // Ungrouped vehicles case WID_GL_DEFAULT_VEHICLES: // Ungrouped vehicles
Command<CMD_ADD_VEHICLE_GROUP>::Post(STR_ERROR_GROUP_CAN_T_ADD_VEHICLE, 0, DEFAULT_GROUP, this->vehicle_sel | (_ctrl_pressed || this->grouping == GB_SHARED_ORDERS ? 1 << 31 : 0), {}); Command<CMD_ADD_VEHICLE_GROUP>::Post(STR_ERROR_GROUP_CAN_T_ADD_VEHICLE, DEFAULT_GROUP, this->vehicle_sel, _ctrl_pressed || this->grouping == GB_SHARED_ORDERS);
this->vehicle_sel = INVALID_VEHICLE; this->vehicle_sel = INVALID_VEHICLE;
this->group_over = INVALID_GROUP; this->group_over = INVALID_GROUP;
@ -869,7 +869,7 @@ public:
uint id_g = this->group_sb->GetScrolledRowFromWidget(pt.y, this, WID_GL_LIST_GROUP); uint id_g = this->group_sb->GetScrolledRowFromWidget(pt.y, this, WID_GL_LIST_GROUP);
GroupID new_g = id_g >= this->groups.size() ? NEW_GROUP : this->groups[id_g]->index; GroupID new_g = id_g >= this->groups.size() ? NEW_GROUP : this->groups[id_g]->index;
Command<CMD_ADD_VEHICLE_GROUP>::Post(STR_ERROR_GROUP_CAN_T_ADD_VEHICLE, new_g == NEW_GROUP ? CcAddVehicleNewGroup : nullptr, 0, new_g, vindex | (_ctrl_pressed || this->grouping == GB_SHARED_ORDERS ? 1 << 31 : 0), {}); Command<CMD_ADD_VEHICLE_GROUP>::Post(STR_ERROR_GROUP_CAN_T_ADD_VEHICLE, new_g == NEW_GROUP ? CcAddVehicleNewGroup : nullptr, 0, new_g, vindex, _ctrl_pressed || this->grouping == GB_SHARED_ORDERS);
break; break;
} }
@ -924,7 +924,7 @@ public:
void OnQueryTextFinished(char *str) override void OnQueryTextFinished(char *str) override
{ {
if (str != nullptr) Command<CMD_ALTER_GROUP>::Post(STR_ERROR_GROUP_CAN_T_RENAME, 0, this->group_rename, 0, str); if (str != nullptr) Command<CMD_ALTER_GROUP>::Post(STR_ERROR_GROUP_CAN_T_RENAME, AlterGroupMode::Rename, this->group_rename, 0, str);
this->group_rename = INVALID_GROUP; this->group_rename = INVALID_GROUP;
} }
@ -961,12 +961,12 @@ public:
case ADI_ADD_SHARED: // Add shared Vehicles case ADI_ADD_SHARED: // Add shared Vehicles
assert(Group::IsValidID(this->vli.index)); assert(Group::IsValidID(this->vli.index));
Command<CMD_ADD_SHARED_VEHICLE_GROUP>::Post(STR_ERROR_GROUP_CAN_T_ADD_SHARED_VEHICLE, 0, this->vli.index, this->vli.vtype, {}); Command<CMD_ADD_SHARED_VEHICLE_GROUP>::Post(STR_ERROR_GROUP_CAN_T_ADD_SHARED_VEHICLE, this->vli.index, this->vli.vtype);
break; break;
case ADI_REMOVE_ALL: // Remove all Vehicles from the selected group case ADI_REMOVE_ALL: // Remove all Vehicles from the selected group
assert(Group::IsValidID(this->vli.index)); assert(Group::IsValidID(this->vli.index));
Command<CMD_REMOVE_ALL_VEHICLES_GROUP>::Post(STR_ERROR_GROUP_CAN_T_REMOVE_ALL_VEHICLES, 0, this->vli.index, 0, {}); Command<CMD_REMOVE_ALL_VEHICLES_GROUP>::Post(STR_ERROR_GROUP_CAN_T_REMOVE_ALL_VEHICLES, this->vli.index);
break; break;
default: NOT_REACHED(); default: NOT_REACHED();
} }
@ -1161,10 +1161,10 @@ void CcCreateGroup(Commands cmd, const CommandCost &result, TileIndex tile, cons
{ {
if (result.Failed()) return; if (result.Failed()) return;
auto [tile_, p1, p2, text] = EndianBufferReader::ToValue<CommandTraits<CMD_CREATE_GROUP>::Args>(data); auto [vt, parent_group] = EndianBufferReader::ToValue<CommandTraits<CMD_CREATE_GROUP>::Args>(data);
assert(p1 <= VEH_AIRCRAFT); assert(vt <= VEH_AIRCRAFT);
CcCreateGroup((VehicleType)p1); CcCreateGroup(vt);
} }
/** /**
@ -1178,10 +1178,10 @@ void CcAddVehicleNewGroup(Commands cmd, const CommandCost &result, TileIndex til
{ {
if (result.Failed()) return; if (result.Failed()) return;
auto [tile_, p1, p2, text] = EndianBufferReader::ToValue<CommandTraits<CMD_ADD_VEHICLE_GROUP>::Args>(data); auto [group_id, veh_id, shared] = EndianBufferReader::ToValue<CommandTraits<CMD_ADD_VEHICLE_GROUP>::Args>(data);
assert(Vehicle::IsValidID(GB(p2, 0, 20))); assert(Vehicle::IsValidID(veh_id));
CcCreateGroup(Vehicle::Get(GB(p2, 0, 20))->type); CcCreateGroup(Vehicle::Get(veh_id)->type);
} }
/** /**

View File

@ -90,7 +90,7 @@ void OrderBackup::DoRestore(Vehicle *v)
if (v->cur_implicit_order_index >= v->GetNumOrders()) v->cur_implicit_order_index = v->cur_real_order_index; if (v->cur_implicit_order_index >= v->GetNumOrders()) v->cur_implicit_order_index = v->cur_real_order_index;
/* Restore vehicle group */ /* Restore vehicle group */
Command<CMD_ADD_VEHICLE_GROUP>::Do(DC_EXEC, 0, this->group, v->index, {}); Command<CMD_ADD_VEHICLE_GROUP>::Do(DC_EXEC, this->group, v->index, false);
} }
/** /**

View File

@ -31,7 +31,7 @@
/* static */ ScriptGroup::GroupID ScriptGroup::CreateGroup(ScriptVehicle::VehicleType vehicle_type, GroupID parent_group_id) /* static */ ScriptGroup::GroupID ScriptGroup::CreateGroup(ScriptVehicle::VehicleType vehicle_type, GroupID parent_group_id)
{ {
if (!ScriptObject::Command<CMD_CREATE_GROUP>::Do(&ScriptInstance::DoCommandReturnGroupID, 0, (::VehicleType)vehicle_type, parent_group_id, {})) return GROUP_INVALID; if (!ScriptObject::Command<CMD_CREATE_GROUP>::Do(&ScriptInstance::DoCommandReturnGroupID, (::VehicleType)vehicle_type, parent_group_id)) return GROUP_INVALID;
/* In case of test-mode, we return GroupID 0 */ /* In case of test-mode, we return GroupID 0 */
return (ScriptGroup::GroupID)0; return (ScriptGroup::GroupID)0;
@ -41,7 +41,7 @@
{ {
EnforcePrecondition(false, IsValidGroup(group_id)); EnforcePrecondition(false, IsValidGroup(group_id));
return ScriptObject::Command<CMD_DELETE_GROUP>::Do(0, group_id, 0, {}); return ScriptObject::Command<CMD_DELETE_GROUP>::Do(group_id);
} }
/* static */ ScriptVehicle::VehicleType ScriptGroup::GetVehicleType(GroupID group_id) /* static */ ScriptVehicle::VehicleType ScriptGroup::GetVehicleType(GroupID group_id)
@ -61,7 +61,7 @@
EnforcePreconditionEncodedText(false, text); EnforcePreconditionEncodedText(false, text);
EnforcePreconditionCustomError(false, ::Utf8StringLength(text) < MAX_LENGTH_GROUP_NAME_CHARS, ScriptError::ERR_PRECONDITION_STRING_TOO_LONG); EnforcePreconditionCustomError(false, ::Utf8StringLength(text) < MAX_LENGTH_GROUP_NAME_CHARS, ScriptError::ERR_PRECONDITION_STRING_TOO_LONG);
return ScriptObject::Command<CMD_ALTER_GROUP>::Do(0, group_id, 0, text); return ScriptObject::Command<CMD_ALTER_GROUP>::Do(AlterGroupMode::Rename, group_id, 0, text);
} }
/* static */ char *ScriptGroup::GetName(GroupID group_id) /* static */ char *ScriptGroup::GetName(GroupID group_id)
@ -77,7 +77,7 @@
EnforcePrecondition(false, IsValidGroup(group_id)); EnforcePrecondition(false, IsValidGroup(group_id));
EnforcePrecondition(false, IsValidGroup(parent_group_id)); EnforcePrecondition(false, IsValidGroup(parent_group_id));
return ScriptObject::Command<CMD_ALTER_GROUP>::Do(0, group_id | 1 << 16, parent_group_id, {}); return ScriptObject::Command<CMD_ALTER_GROUP>::Do(AlterGroupMode::SetParent, group_id, parent_group_id, {});
} }
/* static */ ScriptGroup::GroupID ScriptGroup::GetParent(GroupID group_id) /* static */ ScriptGroup::GroupID ScriptGroup::GetParent(GroupID group_id)
@ -92,7 +92,7 @@
{ {
EnforcePrecondition(false, IsValidGroup(group_id)); EnforcePrecondition(false, IsValidGroup(group_id));
return ScriptObject::Command<CMD_SET_GROUP_FLAG>::Do(0, group_id | GroupFlags::GF_REPLACE_PROTECTION, enable ? 1 : 0, {}); return ScriptObject::Command<CMD_SET_GROUP_FLAG>::Do(group_id, GroupFlags::GF_REPLACE_PROTECTION, enable, false);
} }
/* static */ bool ScriptGroup::GetAutoReplaceProtection(GroupID group_id) /* static */ bool ScriptGroup::GetAutoReplaceProtection(GroupID group_id)
@ -123,7 +123,7 @@
EnforcePrecondition(false, IsValidGroup(group_id) || group_id == GROUP_DEFAULT); EnforcePrecondition(false, IsValidGroup(group_id) || group_id == GROUP_DEFAULT);
EnforcePrecondition(false, ScriptVehicle::IsValidVehicle(vehicle_id)); EnforcePrecondition(false, ScriptVehicle::IsValidVehicle(vehicle_id));
return ScriptObject::Command<CMD_ADD_VEHICLE_GROUP>::Do(0, group_id, vehicle_id, {}); return ScriptObject::Command<CMD_ADD_VEHICLE_GROUP>::Do(group_id, vehicle_id, false);
} }
/* static */ bool ScriptGroup::EnableWagonRemoval(bool enable_removal) /* static */ bool ScriptGroup::EnableWagonRemoval(bool enable_removal)
@ -143,7 +143,7 @@
EnforcePrecondition(false, IsValidGroup(group_id) || group_id == GROUP_DEFAULT || group_id == GROUP_ALL); EnforcePrecondition(false, IsValidGroup(group_id) || group_id == GROUP_DEFAULT || group_id == GROUP_ALL);
EnforcePrecondition(false, ScriptEngine::IsBuildable(engine_id_new)); EnforcePrecondition(false, ScriptEngine::IsBuildable(engine_id_new));
return ScriptObject::Command<CMD_SET_AUTOREPLACE>::Do(0, group_id << 16, (engine_id_new << 16) | engine_id_old, {}); return ScriptObject::Command<CMD_SET_AUTOREPLACE>::Do(group_id, engine_id_old, engine_id_new, false);
} }
/* static */ EngineID ScriptGroup::GetEngineReplacement(GroupID group_id, EngineID engine_id) /* static */ EngineID ScriptGroup::GetEngineReplacement(GroupID group_id, EngineID engine_id)
@ -157,7 +157,7 @@
{ {
EnforcePrecondition(false, IsValidGroup(group_id) || group_id == GROUP_DEFAULT || group_id == GROUP_ALL); EnforcePrecondition(false, IsValidGroup(group_id) || group_id == GROUP_DEFAULT || group_id == GROUP_ALL);
return ScriptObject::Command<CMD_SET_AUTOREPLACE>::Do(0, group_id << 16, (::INVALID_ENGINE << 16) | engine_id, {}); return ScriptObject::Command<CMD_SET_AUTOREPLACE>::Do(group_id, engine_id, ::INVALID_ENGINE, false);
} }
/* static */ Money ScriptGroup::GetProfitThisYear(GroupID group_id) /* static */ Money ScriptGroup::GetProfitThisYear(GroupID group_id)
@ -207,14 +207,14 @@
{ {
EnforcePrecondition(false, IsValidGroup(group_id)); EnforcePrecondition(false, IsValidGroup(group_id));
return ScriptObject::Command<CMD_SET_GROUP_LIVERY>::Do(0, group_id, colour << 16, {}); return ScriptObject::Command<CMD_SET_GROUP_LIVERY>::Do(group_id, true, (::Colours)colour);
} }
/* static */ bool ScriptGroup::SetSecondaryColour(GroupID group_id, ScriptCompany::Colours colour) /* static */ bool ScriptGroup::SetSecondaryColour(GroupID group_id, ScriptCompany::Colours colour)
{ {
EnforcePrecondition(false, IsValidGroup(group_id)); EnforcePrecondition(false, IsValidGroup(group_id));
return ScriptObject::Command<CMD_SET_GROUP_LIVERY>::Do(0, group_id, (1 << 8) | (colour << 16), {}); return ScriptObject::Command<CMD_SET_GROUP_LIVERY>::Do(group_id, false, (::Colours)colour);
} }
/* static */ ScriptCompany::Colours ScriptGroup::GetPrimaryColour(GroupID group_id) /* static */ ScriptCompany::Colours ScriptGroup::GetPrimaryColour(GroupID group_id)

View File

@ -1059,7 +1059,7 @@ void CallVehicleTicks()
const Company *c = Company::Get(_current_company); const Company *c = Company::Get(_current_company);
SubtractMoneyFromCompany(CommandCost(EXPENSES_NEW_VEHICLES, (Money)c->settings.engine_renew_money)); SubtractMoneyFromCompany(CommandCost(EXPENSES_NEW_VEHICLES, (Money)c->settings.engine_renew_money));
CommandCost res = Command<CMD_AUTOREPLACE_VEHICLE>::Do(DC_EXEC, 0, v->index, 0, {}); CommandCost res = Command<CMD_AUTOREPLACE_VEHICLE>::Do(DC_EXEC, v->index);
SubtractMoneyFromCompany(CommandCost(EXPENSES_NEW_VEHICLES, -(Money)c->settings.engine_renew_money)); SubtractMoneyFromCompany(CommandCost(EXPENSES_NEW_VEHICLES, -(Money)c->settings.engine_renew_money));
if (!IsLocalCompany()) continue; if (!IsLocalCompany()) continue;

View File

@ -707,7 +707,7 @@ CommandCost CmdDepotMassAutoReplace(DoCommandFlag flags, TileIndex tile, Vehicle
/* Ensure that the vehicle completely in the depot */ /* Ensure that the vehicle completely in the depot */
if (!v->IsChainInDepot()) continue; if (!v->IsChainInDepot()) continue;
CommandCost ret = Command<CMD_AUTOREPLACE_VEHICLE>::Do(flags, 0, v->index, 0, {}); CommandCost ret = Command<CMD_AUTOREPLACE_VEHICLE>::Do(flags, v->index);
if (ret.Succeeded()) cost.AddCost(ret); if (ret.Succeeded()) cost.AddCost(ret);
} }
@ -891,7 +891,7 @@ CommandCost CmdCloneVehicle(DoCommandFlag flags, TileIndex tile, VehicleID veh_i
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
/* Cloned vehicles belong to the same group */ /* Cloned vehicles belong to the same group */
Command<CMD_ADD_VEHICLE_GROUP>::Do(flags, 0, v_front->group_id, w_front->index, {}); Command<CMD_ADD_VEHICLE_GROUP>::Do(flags, v_front->group_id, w_front->index, false);
} }