Codechange: Use EnumBitSet for DoCommandFlags

This commit is contained in:
Rubidium
2025-02-13 23:35:52 +01:00
committed by rubidium42
parent f309b90a1d
commit c3d5e6d2a0
95 changed files with 871 additions and 873 deletions

View File

@@ -318,7 +318,7 @@ static CommandCost GetNewEngineType(const Vehicle *v, const Company *c, bool alw
* @param flags The calling command flags.
* @return cost or error
*/
static CommandCost BuildReplacementVehicle(Vehicle *old_veh, Vehicle **new_vehicle, bool part_of_chain, DoCommandFlag flags)
static CommandCost BuildReplacementVehicle(Vehicle *old_veh, Vehicle **new_vehicle, bool part_of_chain, DoCommandFlags flags)
{
*new_vehicle = nullptr;
@@ -332,7 +332,7 @@ static CommandCost BuildReplacementVehicle(Vehicle *old_veh, Vehicle **new_vehic
/* Does it need to be refitted */
CargoType refit_cargo = GetNewCargoTypeForReplace(old_veh, e, part_of_chain);
if (!IsValidCargoType(refit_cargo)) {
if (!IsLocalCompany() || (flags & DC_EXEC) == 0) return CommandCost();
if (!IsLocalCompany() || !flags.Test(DoCommandFlag::Execute)) return CommandCost();
VehicleID old_veh_id = (old_veh->type == VEH_TRAIN) ? Train::From(old_veh)->First()->index : old_veh->index;
SetDParam(0, old_veh_id);
@@ -354,7 +354,7 @@ static CommandCost BuildReplacementVehicle(Vehicle *old_veh, Vehicle **new_vehic
/* Build the new vehicle */
VehicleID new_veh_id;
std::tie(cost, new_veh_id, std::ignore, std::ignore, std::ignore) = Command<CMD_BUILD_VEHICLE>::Do(DC_EXEC | DC_AUTOREPLACE, old_veh->tile, e, true, INVALID_CARGO, INVALID_CLIENT_ID);
std::tie(cost, new_veh_id, std::ignore, std::ignore, std::ignore) = Command<CMD_BUILD_VEHICLE>::Do({DoCommandFlag::Execute, DoCommandFlag::AutoReplace}, old_veh->tile, e, true, INVALID_CARGO, INVALID_CLIENT_ID);
if (cost.Failed()) return cost;
Vehicle *new_veh = Vehicle::Get(new_veh_id);
@@ -364,13 +364,13 @@ static CommandCost BuildReplacementVehicle(Vehicle *old_veh, Vehicle **new_vehic
if (refit_cargo != CARGO_NO_REFIT) {
uint8_t subtype = GetBestFittingSubType(old_veh, new_veh, refit_cargo);
cost.AddCost(std::get<0>(Command<CMD_REFIT_VEHICLE>::Do(DC_EXEC, new_veh->index, refit_cargo, subtype, false, false, 0)));
cost.AddCost(std::get<0>(Command<CMD_REFIT_VEHICLE>::Do(DoCommandFlag::Execute, new_veh->index, refit_cargo, subtype, false, false, 0)));
assert(cost.Succeeded()); // This should be ensured by GetNewCargoTypeForReplace()
}
/* Try to reverse the vehicle, but do not care if it fails as the new type might not be reversible */
if (new_veh->type == VEH_TRAIN && HasBit(Train::From(old_veh)->flags, VRF_REVERSE_DIRECTION)) {
Command<CMD_REVERSE_TRAIN_DIRECTION>::Do(DC_EXEC, new_veh->index, true);
Command<CMD_REVERSE_TRAIN_DIRECTION>::Do(DoCommandFlag::Execute, new_veh->index, true);
}
return cost;
@@ -384,7 +384,7 @@ static CommandCost BuildReplacementVehicle(Vehicle *old_veh, Vehicle **new_vehic
*/
static inline CommandCost DoCmdStartStopVehicle(const Vehicle *v, bool evaluate_callback)
{
return Command<CMD_START_STOP_VEHICLE>::Do(DC_EXEC | DC_AUTOREPLACE, v->index, evaluate_callback);
return Command<CMD_START_STOP_VEHICLE>::Do({DoCommandFlag::Execute, DoCommandFlag::AutoReplace}, v->index, evaluate_callback);
}
/**
@@ -395,9 +395,9 @@ static inline CommandCost DoCmdStartStopVehicle(const Vehicle *v, bool evaluate_
* @param whole_chain move all vehicles following 'v' (true), or only 'v' (false)
* @return success or error
*/
static inline CommandCost CmdMoveVehicle(const Vehicle *v, const Vehicle *after, DoCommandFlag flags, bool whole_chain)
static inline CommandCost CmdMoveVehicle(const Vehicle *v, const Vehicle *after, DoCommandFlags flags, bool whole_chain)
{
return Command<CMD_MOVE_RAIL_VEHICLE>::Do(flags | DC_NO_CARGO_CAP_CHECK, v->index, after != nullptr ? after->index : INVALID_VEHICLE, whole_chain);
return Command<CMD_MOVE_RAIL_VEHICLE>::Do(flags.Set(DoCommandFlag::NoCargoCapacityCheck), v->index, after != nullptr ? after->index : INVALID_VEHICLE, whole_chain);
}
/**
@@ -406,15 +406,15 @@ static inline CommandCost CmdMoveVehicle(const Vehicle *v, const Vehicle *after,
* @param new_head The new head of the completely replaced vehicle chain
* @param flags the command flags to use
*/
static CommandCost CopyHeadSpecificThings(Vehicle *old_head, Vehicle *new_head, DoCommandFlag flags)
static CommandCost CopyHeadSpecificThings(Vehicle *old_head, Vehicle *new_head, DoCommandFlags flags)
{
CommandCost cost = CommandCost();
/* Share orders */
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(DoCommandFlag::Execute, CO_SHARE, new_head->index, old_head->index));
/* Copy group membership */
if (cost.Succeeded() && old_head != new_head) cost.AddCost(std::get<0>(Command<CMD_ADD_VEHICLE_GROUP>::Do(DC_EXEC, old_head->group_id, new_head->index, false, VehicleListIdentifier{})));
if (cost.Succeeded() && old_head != new_head) cost.AddCost(std::get<0>(Command<CMD_ADD_VEHICLE_GROUP>::Do(DoCommandFlag::Execute, old_head->group_id, new_head->index, false, VehicleListIdentifier{})));
/* Perform start/stop check whether the new vehicle suits newgrf restrictions etc. */
if (cost.Succeeded()) {
@@ -427,7 +427,7 @@ static CommandCost CopyHeadSpecificThings(Vehicle *old_head, Vehicle *new_head,
}
/* Last do those things which do never fail (resp. we do not care about), but which are not undo-able */
if (cost.Succeeded() && old_head != new_head && (flags & DC_EXEC) != 0) {
if (cost.Succeeded() && old_head != new_head && flags.Test(DoCommandFlag::Execute)) {
/* Copy other things which cannot be copied by a command and which shall not stay resetted from the build vehicle command */
new_head->CopyVehicleConfigAndStatistics(old_head);
GroupStatistics::AddProfitLastYear(new_head);
@@ -448,7 +448,7 @@ static CommandCost CopyHeadSpecificThings(Vehicle *old_head, Vehicle *new_head,
* @param nothing_to_do is set to 'false' when something was done (only valid when not failed)
* @return cost or error
*/
static CommandCost ReplaceFreeUnit(Vehicle **single_unit, DoCommandFlag flags, bool *nothing_to_do)
static CommandCost ReplaceFreeUnit(Vehicle **single_unit, DoCommandFlags flags, bool *nothing_to_do)
{
Train *old_v = Train::From(*single_unit);
assert(!old_v->IsArticulatedPart() && !old_v->IsRearDualheaded());
@@ -463,9 +463,9 @@ static CommandCost ReplaceFreeUnit(Vehicle **single_unit, DoCommandFlag flags, b
if (cost.Succeeded() && new_v != nullptr) {
*nothing_to_do = false;
if ((flags & DC_EXEC) != 0) {
if (flags.Test(DoCommandFlag::Execute)) {
/* Move the new vehicle behind the old */
CmdMoveVehicle(new_v, old_v, DC_EXEC, false);
CmdMoveVehicle(new_v, old_v, DoCommandFlag::Execute, false);
/* Take over cargo
* Note: We do only transfer cargo from the old to the new vehicle.
@@ -483,9 +483,9 @@ static CommandCost ReplaceFreeUnit(Vehicle **single_unit, DoCommandFlag flags, b
/* Sell the old vehicle */
cost.AddCost(Command<CMD_SELL_VEHICLE>::Do(flags, old_v->index, false, false, INVALID_CLIENT_ID));
/* If we are not in DC_EXEC undo everything */
if ((flags & DC_EXEC) == 0) {
Command<CMD_SELL_VEHICLE>::Do(DC_EXEC, new_v->index, false, false, INVALID_CLIENT_ID);
/* If we are not in DoCommandFlag::Execute undo everything */
if (!flags.Test(DoCommandFlag::Execute)) {
Command<CMD_SELL_VEHICLE>::Do(DoCommandFlag::Execute, new_v->index, false, false, INVALID_CLIENT_ID);
}
}
@@ -515,7 +515,7 @@ struct ReplaceChainItem {
* @param nothing_to_do is set to 'false' when something was done (only valid when not failed)
* @return cost or error
*/
static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon_removal, bool *nothing_to_do)
static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlags flags, bool wagon_removal, bool *nothing_to_do)
{
Vehicle *old_head = *chain;
assert(old_head->IsPrimaryVehicle());
@@ -546,7 +546,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
if (cost.Succeeded()) {
/* Separate the head, so we can start constructing the new chain */
Train *second = Train::From(old_head)->GetNextUnit();
if (second != nullptr) cost.AddCost(CmdMoveVehicle(second, nullptr, DC_EXEC | DC_AUTOREPLACE, true));
if (second != nullptr) cost.AddCost(CmdMoveVehicle(second, nullptr, {DoCommandFlag::Execute, DoCommandFlag::AutoReplace}, true));
assert(Train::From(new_head)->GetNextUnit() == nullptr);
@@ -562,14 +562,14 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
if (RailVehInfo(append->engine_type)->railveh_type == RAILVEH_WAGON) continue;
if (it->new_veh != nullptr) {
/* Move the old engine to a separate row with DC_AUTOREPLACE. Else
/* Move the old engine to a separate row with DoCommandFlag::AutoReplace. Else
* moving the wagon in front may fail later due to unitnumber limit.
* (We have to attach wagons without DC_AUTOREPLACE.) */
CmdMoveVehicle(it->old_veh, nullptr, DC_EXEC | DC_AUTOREPLACE, false);
* (We have to attach wagons without DoCommandFlag::AutoReplace.) */
CmdMoveVehicle(it->old_veh, nullptr, {DoCommandFlag::Execute, DoCommandFlag::AutoReplace}, false);
}
if (last_engine == nullptr) last_engine = append;
cost.AddCost(CmdMoveVehicle(append, new_head, DC_EXEC, false));
cost.AddCost(CmdMoveVehicle(append, new_head, DoCommandFlag::Execute, false));
if (cost.Failed()) break;
}
if (last_engine == nullptr) last_engine = new_head;
@@ -588,13 +588,13 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
if (RailVehInfo(append->engine_type)->railveh_type == RAILVEH_WAGON) {
/* Insert wagon after 'last_engine' */
CommandCost res = CmdMoveVehicle(append, last_engine, DC_EXEC, false);
CommandCost res = CmdMoveVehicle(append, last_engine, DoCommandFlag::Execute, false);
/* When we allow removal of wagons, either the move failing due
* to the train becoming too long, or the train becoming longer
* would move the vehicle to the empty vehicle chain. */
if (wagon_removal && (res.Failed() ? res.GetErrorMessage() == STR_ERROR_TRAIN_TOO_LONG : Train::From(new_head)->gcache.cached_total_length > old_total_length)) {
CmdMoveVehicle(append, nullptr, DC_EXEC | DC_AUTOREPLACE, false);
CmdMoveVehicle(append, nullptr, {DoCommandFlag::Execute, DoCommandFlag::AutoReplace}, false);
break;
}
@@ -619,7 +619,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
assert(RailVehInfo(wagon->engine_type)->railveh_type == RAILVEH_WAGON);
/* Sell wagon */
[[maybe_unused]] CommandCost ret = Command<CMD_SELL_VEHICLE>::Do(DC_EXEC, wagon->index, false, false, INVALID_CLIENT_ID);
[[maybe_unused]] CommandCost ret = Command<CMD_SELL_VEHICLE>::Do(DoCommandFlag::Execute, wagon->index, false, false, INVALID_CLIENT_ID);
assert(ret.Succeeded());
it->new_veh = nullptr;
@@ -634,7 +634,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
if (cost.Succeeded()) {
/* Success ! */
if ((flags & DC_EXEC) != 0 && new_head != old_head) {
if (flags.Test(DoCommandFlag::Execute) && new_head != old_head) {
*chain = new_head;
AI::NewEvent(old_head->owner, new ScriptEventVehicleAutoReplaced(old_head->index, new_head->index));
}
@@ -646,43 +646,43 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
* Note: We cannot test 'new_vehs[i] != nullptr' as wagon removal might cause to remove both */
if (w->First() == new_head) continue;
if ((flags & DC_EXEC) != 0) TransferCargo(w, new_head, true);
if (flags.Test(DoCommandFlag::Execute)) TransferCargo(w, new_head, true);
/* Sell the vehicle.
* Note: This might temporarily construct new trains, so use DC_AUTOREPLACE to prevent
* Note: This might temporarily construct new trains, so use DoCommandFlag::AutoReplace to prevent
* it from failing due to engine limits. */
cost.AddCost(Command<CMD_SELL_VEHICLE>::Do(flags | DC_AUTOREPLACE, w->index, false, false, INVALID_CLIENT_ID));
if ((flags & DC_EXEC) != 0) {
cost.AddCost(Command<CMD_SELL_VEHICLE>::Do(DoCommandFlags{flags}.Set(DoCommandFlag::AutoReplace), w->index, false, false, INVALID_CLIENT_ID));
if (flags.Test(DoCommandFlag::Execute)) {
it->old_veh = nullptr;
if (it == std::begin(replacements)) old_head = nullptr;
}
}
if ((flags & DC_EXEC) != 0) CheckCargoCapacity(new_head);
if (flags.Test(DoCommandFlag::Execute)) CheckCargoCapacity(new_head);
}
/* If we are not in DC_EXEC undo everything, i.e. rearrange old vehicles.
/* If we are not in DoCommandFlag::Execute undo everything, i.e. rearrange old vehicles.
* We do this from back to front, so that the head of the temporary vehicle chain does not change all the time.
* Note: The vehicle attach callback is disabled here :) */
if ((flags & DC_EXEC) == 0) {
if (!flags.Test(DoCommandFlag::Execute)) {
/* Separate the head, so we can reattach the old vehicles */
Train *second = Train::From(old_head)->GetNextUnit();
if (second != nullptr) CmdMoveVehicle(second, nullptr, DC_EXEC | DC_AUTOREPLACE, true);
if (second != nullptr) CmdMoveVehicle(second, nullptr, {DoCommandFlag::Execute, DoCommandFlag::AutoReplace}, true);
assert(Train::From(old_head)->GetNextUnit() == nullptr);
for (auto it = std::rbegin(replacements); it != std::rend(replacements); ++it) {
[[maybe_unused]] CommandCost ret = CmdMoveVehicle(it->old_veh, old_head, DC_EXEC | DC_AUTOREPLACE, false);
[[maybe_unused]] CommandCost ret = CmdMoveVehicle(it->old_veh, old_head, {DoCommandFlag::Execute, DoCommandFlag::AutoReplace}, false);
assert(ret.Succeeded());
}
}
}
/* Finally undo buying of new vehicles */
if ((flags & DC_EXEC) == 0) {
if (!flags.Test(DoCommandFlag::Execute)) {
for (auto it = std::rbegin(replacements); it != std::rend(replacements); ++it) {
if (it->new_veh != nullptr) {
Command<CMD_SELL_VEHICLE>::Do(DC_EXEC, it->new_veh->index, false, false, INVALID_CLIENT_ID);
Command<CMD_SELL_VEHICLE>::Do(DoCommandFlag::Execute, it->new_veh->index, false, false, INVALID_CLIENT_ID);
it->new_veh = nullptr;
}
}
@@ -701,7 +701,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
if (cost.Succeeded()) {
/* The new vehicle is constructed, now take over cargo */
if ((flags & DC_EXEC) != 0) {
if (flags.Test(DoCommandFlag::Execute)) {
TransferCargo(old_head, new_head, true);
*chain = new_head;
@@ -712,9 +712,9 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
cost.AddCost(Command<CMD_SELL_VEHICLE>::Do(flags, old_head->index, false, false, INVALID_CLIENT_ID));
}
/* If we are not in DC_EXEC undo everything */
if ((flags & DC_EXEC) == 0) {
Command<CMD_SELL_VEHICLE>::Do(DC_EXEC, new_head->index, false, false, INVALID_CLIENT_ID);
/* If we are not in DoCommandFlag::Execute undo everything */
if (!flags.Test(DoCommandFlag::Execute)) {
Command<CMD_SELL_VEHICLE>::Do(DoCommandFlag::Execute, new_head->index, false, false, INVALID_CLIENT_ID);
}
}
}
@@ -729,7 +729,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
* @param veh_id Index of vehicle
* @return the cost of this operation or an error
*/
CommandCost CmdAutoreplaceVehicle(DoCommandFlag flags, VehicleID veh_id)
CommandCost CmdAutoreplaceVehicle(DoCommandFlags flags, VehicleID veh_id)
{
Vehicle *v = Vehicle::GetIfValid(veh_id);
if (v == nullptr) return CMD_ERROR;
@@ -781,17 +781,17 @@ CommandCost CmdAutoreplaceVehicle(DoCommandFlag flags, VehicleID veh_id)
/* We have to construct the new vehicle chain to test whether it is valid.
* Vehicle construction needs random bits, so we have to save the random seeds
* to prevent desyncs and to replay newgrf callbacks during DC_EXEC */
* to prevent desyncs and to replay newgrf callbacks during DoCommandFlag::Execute */
SavedRandomSeeds saved_seeds;
SaveRandomSeeds(&saved_seeds);
if (free_wagon) {
cost.AddCost(ReplaceFreeUnit(&v, flags & ~DC_EXEC, &nothing_to_do));
cost.AddCost(ReplaceFreeUnit(&v, DoCommandFlags{flags}.Reset(DoCommandFlag::Execute), &nothing_to_do));
} else {
cost.AddCost(ReplaceChain(&v, flags & ~DC_EXEC, wagon_removal, &nothing_to_do));
cost.AddCost(ReplaceChain(&v, DoCommandFlags{flags}.Reset(DoCommandFlag::Execute), wagon_removal, &nothing_to_do));
}
RestoreRandomSeeds(saved_seeds);
if (cost.Succeeded() && (flags & DC_EXEC) != 0) {
if (cost.Succeeded() && flags.Test(DoCommandFlag::Execute)) {
if (free_wagon) {
ret = ReplaceFreeUnit(&v, flags, &nothing_to_do);
} else {
@@ -817,7 +817,7 @@ CommandCost CmdAutoreplaceVehicle(DoCommandFlag flags, VehicleID veh_id)
* @param when_old replace when engine gets old?
* @return the cost of this operation or an error
*/
CommandCost CmdSetAutoReplace(DoCommandFlag flags, GroupID id_g, EngineID old_engine_type, EngineID new_engine_type, bool when_old)
CommandCost CmdSetAutoReplace(DoCommandFlags flags, GroupID id_g, EngineID old_engine_type, EngineID new_engine_type, bool when_old)
{
Company *c = Company::GetIfValid(_current_company);
if (c == nullptr) return CMD_ERROR;
@@ -837,14 +837,14 @@ CommandCost CmdSetAutoReplace(DoCommandFlag flags, GroupID id_g, EngineID old_en
cost = RemoveEngineReplacementForCompany(c, old_engine_type, id_g, flags);
}
if (flags & DC_EXEC) {
if (flags.Test(DoCommandFlag::Execute)) {
GroupStatistics::UpdateAutoreplace(_current_company);
if (IsLocalCompany()) SetWindowDirty(WC_REPLACE_VEHICLE, Engine::Get(old_engine_type)->type);
const VehicleType vt = Engine::Get(old_engine_type)->type;
SetWindowDirty(GetWindowClassForVehicleType(vt), VehicleListIdentifier(VL_GROUP_LIST, vt, _current_company).ToWindowNumber());
}
if ((flags & DC_EXEC) && IsLocalCompany()) InvalidateAutoreplaceWindow(old_engine_type, id_g);
if (flags.Test(DoCommandFlag::Execute) && IsLocalCompany()) InvalidateAutoreplaceWindow(old_engine_type, id_g);
return cost;
}