diff --git a/src/ai/default/default.cpp b/src/ai/default/default.cpp --- a/src/ai/default/default.cpp +++ b/src/ai/default/default.cpp @@ -299,7 +299,7 @@ static EngineID AiChooseShipToReplaceWit static void AiHandleGotoDepot(Player *p, int cmd) { - if (_players_ai[p->index].cur_veh->current_order.type != OT_GOTO_DEPOT) + if (!_players_ai[p->index].cur_veh->current_order.IsType(OT_GOTO_DEPOT)) DoCommand(0, _players_ai[p->index].cur_veh->index, 0, DC_EXEC, cmd); if (++_players_ai[p->index].state_counter <= 1387) { @@ -307,9 +307,8 @@ static void AiHandleGotoDepot(Player *p, return; } - if (_players_ai[p->index].cur_veh->current_order.type == OT_GOTO_DEPOT) { - _players_ai[p->index].cur_veh->current_order.type = OT_DUMMY; - _players_ai[p->index].cur_veh->current_order.flags = 0; + if (_players_ai[p->index].cur_veh->current_order.IsType(OT_GOTO_DEPOT)) { + _players_ai[p->index].cur_veh->current_order.MakeDummy(); InvalidateWindow(WC_VEHICLE_VIEW, _players_ai[p->index].cur_veh->index); } } @@ -318,7 +317,7 @@ static void AiRestoreVehicleOrders(Vehic { if (bak->order == NULL) return; - for (uint i = 0; bak->order[i].type != OT_NOTHING; i++) { + for (uint i = 0; !bak->order[i].IsType(OT_NOTHING); i++) { if (!DoCommandP(0, v->index + (i << 16), PackOrder(&bak->order[i]), NULL, CMD_INSERT_ORDER | CMD_NO_TEST_IF_IN_NETWORK)) break; } @@ -2553,9 +2552,7 @@ handle_nocash: ); Order order; - order.type = OT_GOTO_STATION; - order.flags = 0; - order.dest = AiGetStationIdByDef(aib->use_tile, aib->cur_building_rule); + order.MakeGoToStation(AiGetStationIdByDef(aib->use_tile, aib->cur_building_rule)); if (!is_pass && i == 1) order.flags |= OFB_UNLOAD; if (_players_ai[p->index].num_want_fullload != 0 && (is_pass || i == 0)) @@ -3290,9 +3287,7 @@ static void AiStateBuildRoadVehicles(Pla ); Order order; - order.type = OT_GOTO_STATION; - order.flags = 0; - order.dest = AiGetStationIdFromRoadBlock(aib->use_tile, aib->cur_building_rule); + order.MakeGoToStation(AiGetStationIdFromRoadBlock(aib->use_tile, aib->cur_building_rule)); if (!is_pass && i == 1) order.flags |= OFB_UNLOAD; if (_players_ai[p->index].num_want_fullload != 0 && (is_pass || i == 0)) @@ -3571,9 +3566,7 @@ static void AiStateBuildAircraftVehicles bool is_pass = (_players_ai[p->index].cargo_type == CT_PASSENGERS || _players_ai[p->index].cargo_type == CT_MAIL); Order order; - order.type = OT_GOTO_STATION; - order.flags = 0; - order.dest = AiGetStationIdFromAircraftBlock(aib->use_tile, aib->cur_building_rule); + order.MakeGoToStation(AiGetStationIdFromAircraftBlock(aib->use_tile, aib->cur_building_rule)); if (!is_pass && i == 1) order.flags |= OFB_UNLOAD; if (_players_ai[p->index].num_want_fullload != 0 && (is_pass || i == 0)) @@ -3614,7 +3607,7 @@ static void AiStateSellVeh(Player *p) if (v->type == VEH_TRAIN) { if (!IsTileDepotType(v->tile, TRANSPORT_RAIL) || v->u.rail.track != 0x80 || !(v->vehstatus&VS_STOPPED)) { - if (v->current_order.type != OT_GOTO_DEPOT) + if (!v->current_order.IsType(OT_GOTO_DEPOT)) DoCommand(0, v->index, 0, DC_EXEC, CMD_SEND_TRAIN_TO_DEPOT); goto going_to_depot; } @@ -3624,7 +3617,7 @@ static void AiStateSellVeh(Player *p) } else if (v->type == VEH_ROAD) { if (!v->IsStoppedInDepot()) { - if (v->current_order.type != OT_GOTO_DEPOT) + if (!v->current_order.IsType(OT_GOTO_DEPOT)) DoCommand(0, v->index, 0, DC_EXEC, CMD_SEND_ROADVEH_TO_DEPOT); goto going_to_depot; } @@ -3632,7 +3625,7 @@ static void AiStateSellVeh(Player *p) DoCommand(0, v->index, 0, DC_EXEC, CMD_SELL_ROAD_VEH); } else if (v->type == VEH_AIRCRAFT) { if (!v->IsStoppedInDepot()) { - if (v->current_order.type != OT_GOTO_DEPOT) + if (!v->current_order.IsType(OT_GOTO_DEPOT)) DoCommand(0, v->index, 0, DC_EXEC, CMD_SEND_AIRCRAFT_TO_HANGAR); goto going_to_depot; } @@ -3647,9 +3640,8 @@ static void AiStateSellVeh(Player *p) going_to_depot:; if (++_players_ai[p->index].state_counter <= 832) return; - if (v->current_order.type == OT_GOTO_DEPOT) { - v->current_order.type = OT_DUMMY; - v->current_order.flags = 0; + if (v->current_order.IsType(OT_GOTO_DEPOT)) { + v->current_order.MakeDummy(); InvalidateWindow(WC_VEHICLE_VIEW, v->index); } return_to_loop:; @@ -3670,7 +3662,7 @@ static void AiStateRemoveStation(Player byte *in_use = MallocT(GetMaxStationIndex() + 1); memset(in_use, 0, GetMaxStationIndex() + 1); FOR_ALL_ORDERS(ord) { - if (ord->type == OT_GOTO_STATION) in_use[ord->dest] = 1; + if (ord->IsType(OT_GOTO_STATION)) in_use[ord->dest] = 1; } // Go through all stations and delete those that aren't in use diff --git a/src/ai/trolly/trolly.cpp b/src/ai/trolly/trolly.cpp --- a/src/ai/trolly/trolly.cpp +++ b/src/ai/trolly/trolly.cpp @@ -553,7 +553,7 @@ static bool AiNew_CheckVehicleStation(Pl const Order *order; FOR_VEHICLE_ORDERS(v, order) { - if (order->type == OT_GOTO_STATION && GetStation(order->dest) == st) { + if (order->IsType(OT_GOTO_STATION) && GetStation(order->dest) == st) { // This vehicle has this city in its list count++; } @@ -1184,24 +1184,18 @@ static void AiNew_State_GiveOrders(Playe // Very handy for AI, goto depot.. but yeah, it needs to be activated ;) if (_patches.gotodepot) { idx = 0; - order.type = OT_GOTO_DEPOT; - order.flags = OFB_UNLOAD; - order.dest = GetDepotByTile(_players_ainew[p->index].depot_tile)->index; + order.MakeGoToDepot(GetDepotByTile(_players_ainew[p->index].depot_tile)->index, true); AI_DoCommand(0, _players_ainew[p->index].veh_id + (idx << 16), PackOrder(&order), DC_EXEC, CMD_INSERT_ORDER); } idx = 0; - order.type = OT_GOTO_STATION; - order.flags = 0; - order.dest = GetStationIndex(_players_ainew[p->index].to_tile); + order.MakeGoToStation(GetStationIndex(_players_ainew[p->index].to_tile)); if (_players_ainew[p->index].tbt == AI_TRUCK && _players_ainew[p->index].to_deliver) order.flags |= OFB_FULL_LOAD; AI_DoCommand(0, _players_ainew[p->index].veh_id + (idx << 16), PackOrder(&order), DC_EXEC, CMD_INSERT_ORDER); idx = 0; - order.type = OT_GOTO_STATION; - order.flags = 0; - order.dest = GetStationIndex(_players_ainew[p->index].from_tile); + order.MakeGoToStation(GetStationIndex(_players_ainew[p->index].from_tile)); if (_players_ainew[p->index].tbt == AI_TRUCK && _players_ainew[p->index].from_deliver) order.flags |= OFB_FULL_LOAD; AI_DoCommand(0, _players_ainew[p->index].veh_id + (idx << 16), PackOrder(&order), DC_EXEC, CMD_INSERT_ORDER); diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp --- a/src/aircraft_cmd.cpp +++ b/src/aircraft_cmd.cpp @@ -569,7 +569,7 @@ CommandCost CmdSendAircraftToHangar(Tile if (v->type != VEH_AIRCRAFT || !CheckOwnership(v->owner) || v->IsInDepot()) return CMD_ERROR; - if (v->current_order.type == OT_GOTO_DEPOT && !(p2 & DEPOT_LOCATE_HANGAR)) { + if (v->current_order.IsType(OT_GOTO_DEPOT) && !(p2 & DEPOT_LOCATE_HANGAR)) { if (!!(p2 & DEPOT_SERVICE) == HasBit(v->current_order.flags, OF_HALT_IN_DEPOT)) { /* We called with a different DEPOT_SERVICE setting. * Now we change the setting to apply the new one and let the vehicle head for the same hangar. @@ -585,8 +585,7 @@ CommandCost CmdSendAircraftToHangar(Tile if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of hangar orders if (flags & DC_EXEC) { if (v->current_order.flags & OFB_UNLOAD) v->cur_order_index++; - v->current_order.type = OT_DUMMY; - v->current_order.flags = 0; + v->current_order.MakeDummy(); InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH); } } else { @@ -604,13 +603,10 @@ CommandCost CmdSendAircraftToHangar(Tile } if (flags & DC_EXEC) { - if (v->current_order.type == OT_LOADING) v->LeaveStation(); + if (v->current_order.IsType(OT_LOADING)) v->LeaveStation(); - v->current_order.type = OT_GOTO_DEPOT; - v->current_order.flags = OFB_NON_STOP; + v->current_order.MakeGoToDepot(next_airport_index, false); if (!(p2 & DEPOT_SERVICE)) SetBit(v->current_order.flags, OF_HALT_IN_DEPOT); - v->current_order.refit_cargo = CT_INVALID; - v->current_order.dest = next_airport_index; InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH); if (v->u.air.state == FLYING && !next_airport_has_hangar) { /* The aircraft is now heading for a different hangar than the next in the orders */ @@ -714,12 +710,10 @@ static void CheckIfAircraftNeedsService( if (st->IsValid() && st->airport_tile != 0 && st->Airport()->terminals != NULL) { // printf("targetairport = %d, st->index = %d\n", v->u.air.targetairport, st->index); // v->u.air.targetairport = st->index; - v->current_order.type = OT_GOTO_DEPOT; - v->current_order.flags = OFB_NON_STOP; + v->current_order.MakeGoToDepot(INVALID_STATION, false); InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH); - } else if (v->current_order.type == OT_GOTO_DEPOT) { - v->current_order.type = OT_DUMMY; - v->current_order.flags = 0; + } else if (v->current_order.IsType(OT_GOTO_DEPOT)) { + v->current_order.MakeDummy(); InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH); } } @@ -780,7 +774,7 @@ static void HelicopterTickHandler(Vehicl /* if true, helicopter rotors do not rotate. This should only be the case if a helicopter is * loading/unloading at a terminal or stopped */ - if (v->current_order.type == OT_LOADING || (v->vehstatus & VS_STOPPED)) { + if (v->current_order.IsType(OT_LOADING) || (v->vehstatus & VS_STOPPED)) { if (u->cur_speed != 0) { u->cur_speed++; if (u->cur_speed >= 0x80 && u->u.air.state == HRS_ROTOR_MOVING_3) { @@ -1388,7 +1382,7 @@ void HandleMissingAircraftOrders(Vehicle _current_player = old_player; if (CmdFailed(ret)) CrashAirplane(v); - } else if (v->current_order.type != OT_GOTO_DEPOT) { + } else if (!v->current_order.IsType(OT_GOTO_DEPOT)) { v->current_order.Free(); } } @@ -1471,7 +1465,7 @@ static void MaybeCrashAirplane(Vehicle * /** we've landed and just arrived at a terminal */ static void AircraftEntersTerminal(Vehicle *v) { - if (v->current_order.type == OT_GOTO_DEPOT) return; + if (v->current_order.IsType(OT_GOTO_DEPOT)) return; Station *st = GetStation(v->u.air.targetairport); v->last_station_visited = v->u.air.targetairport; @@ -1505,8 +1499,8 @@ static void AircraftLandAirplane(Vehicle /** set the right pos when heading to other airports after takeoff */ static void AircraftNextAirportPos_and_Order(Vehicle *v) { - if (v->current_order.type == OT_GOTO_STATION || - v->current_order.type == OT_GOTO_DEPOT) + if (v->current_order.IsType(OT_GOTO_STATION) || + v->current_order.IsType(OT_GOTO_DEPOT)) v->u.air.targetairport = v->current_order.dest; const AirportFTAClass *apc = GetStation(v->u.air.targetairport)->Airport(); @@ -1603,13 +1597,13 @@ static void AircraftEventHandler_InHanga } /* if we were sent to the depot, stay there */ - if (v->current_order.type == OT_GOTO_DEPOT && (v->vehstatus & VS_STOPPED)) { + if (v->current_order.IsType(OT_GOTO_DEPOT) && (v->vehstatus & VS_STOPPED)) { v->current_order.Free(); return; } - if (v->current_order.type != OT_GOTO_STATION && - v->current_order.type != OT_GOTO_DEPOT) + if (!v->current_order.IsType(OT_GOTO_STATION) && + !v->current_order.IsType(OT_GOTO_DEPOT)) return; /* if the block of the next position is busy, stay put */ @@ -1660,7 +1654,7 @@ static void AircraftEventHandler_AtTermi /* airport-road is free. We either have to go to another airport, or to the hangar * ---> start moving */ - switch (v->current_order.type) { + switch (v->current_order.GetType()) { case OT_GOTO_STATION: // ready to fly to another airport /* airplane goto state takeoff, helicopter to helitakeoff */ v->u.air.state = (v->subtype == AIR_HELICOPTER) ? HELITAKEOFF : TAKEOFF; @@ -1786,7 +1780,7 @@ static void AircraftEventHandler_EndLand * 1. in case all terminals are busy AirportFindFreeTerminal() returns false or * 2. not going for terminal (but depot, no order), * --> get out of the way to the hangar. */ - if (v->current_order.type == OT_GOTO_STATION) { + if (v->current_order.IsType(OT_GOTO_STATION)) { if (AirportFindFreeTerminal(v, apc)) return; } v->u.air.state = HANGAR; @@ -1805,7 +1799,7 @@ static void AircraftEventHandler_HeliEnd * --> else TAKEOFF * the reason behind this is that if an airport has a terminal, it also has a hangar. Airplanes * must go to a hangar. */ - if (v->current_order.type == OT_GOTO_STATION) { + if (v->current_order.IsType(OT_GOTO_STATION)) { if (AirportFindFreeHelipad(v, apc)) return; } v->u.air.state = (apc->nof_depots != 0) ? HANGAR : HELITAKEOFF; @@ -2126,7 +2120,7 @@ static void AircraftEventHandler(Vehicle ProcessOrders(v); v->HandleLoading(loop != 0); - if (v->current_order.type >= OT_LOADING) return; + if (v->current_order.IsType(OT_LOADING) || v->current_order.IsType(OT_LEAVESTATION)) return; AirportGoToNextPosition(v); } diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp --- a/src/industry_cmd.cpp +++ b/src/industry_cmd.cpp @@ -1967,7 +1967,7 @@ int WhoCanServiceIndustry(Industry* ind) */ const Order *o; FOR_VEHICLE_ORDERS(v, o) { - if (o->type == OT_GOTO_STATION && !HasBit(o->flags, OF_TRANSFER)) { + if (o->IsType(OT_GOTO_STATION) && !HasBit(o->flags, OF_TRANSFER)) { /* Vehicle visits a station to load or unload */ Station *st = GetStation(o->dest); if (!st->IsValid()) continue; diff --git a/src/newgrf_engine.cpp b/src/newgrf_engine.cpp --- a/src/newgrf_engine.cpp +++ b/src/newgrf_engine.cpp @@ -348,11 +348,11 @@ static byte MapAircraftMovementAction(co case TERM1: case HELIPAD1: - return (v->current_order.type == OT_LOADING) ? AMA_TTDP_ON_PAD1 : AMA_TTDP_LANDING_TO_PAD1; + return (v->current_order.IsType(OT_LOADING)) ? AMA_TTDP_ON_PAD1 : AMA_TTDP_LANDING_TO_PAD1; case TERM2: case HELIPAD2: - return (v->current_order.type == OT_LOADING) ? AMA_TTDP_ON_PAD2 : AMA_TTDP_LANDING_TO_PAD2; + return (v->current_order.IsType(OT_LOADING)) ? AMA_TTDP_ON_PAD2 : AMA_TTDP_LANDING_TO_PAD2; case TERM3: case TERM4: @@ -362,7 +362,7 @@ static byte MapAircraftMovementAction(co case TERM8: case HELIPAD3: case HELIPAD4: - return (v->current_order.type == OT_LOADING) ? AMA_TTDP_ON_PAD3 : AMA_TTDP_LANDING_TO_PAD3; + return (v->current_order.IsType(OT_LOADING)) ? AMA_TTDP_ON_PAD3 : AMA_TTDP_LANDING_TO_PAD3; case TAKEOFF: // Moving to takeoff position case STARTTAKEOFF: // Accelerating down runway @@ -379,7 +379,7 @@ static byte MapAircraftMovementAction(co case HELILANDING: case HELIENDLANDING: /* @todo Need to check terminal we're landing to. Is it known yet? */ - return (v->current_order.type == OT_GOTO_DEPOT) ? + return (v->current_order.IsType(OT_GOTO_DEPOT)) ? AMA_TTDP_LANDING_TO_HANGAR : AMA_TTDP_LANDING_TO_PAD1; default: @@ -811,7 +811,7 @@ static const SpriteGroup *VehicleResolve return NULL; } - bool in_motion = v->First()->current_order.type != OT_LOADING; + bool in_motion = !v->First()->current_order.IsType(OT_LOADING); totalsets = in_motion ? group->g.real.num_loaded : group->g.real.num_loading; diff --git a/src/npf.cpp b/src/npf.cpp --- a/src/npf.cpp +++ b/src/npf.cpp @@ -980,7 +980,7 @@ void NPFFillWithOrderData(NPFFindStation * dest_tile, not just any stop of that station. * So only for train orders to stations we fill fstd->station_index, for all * others only dest_coords */ - if (v->current_order.type == OT_GOTO_STATION && v->type == VEH_TRAIN) { + if (v->current_order.IsType(OT_GOTO_STATION) && v->type == VEH_TRAIN) { fstd->station_index = v->current_order.dest; /* Let's take the closest tile of the station as our target for trains */ fstd->dest_coords = CalcClosestStationTile(v->current_order.dest, v->tile); diff --git a/src/oldloader.cpp b/src/oldloader.cpp --- a/src/oldloader.cpp +++ b/src/oldloader.cpp @@ -345,8 +345,8 @@ static void FixOldVehicles() * (loading) order which causes assertions and the like later on. */ if (!IsPlayerBuildableVehicleType(v) || - (v->IsPrimaryVehicle() && v->current_order.type == OT_NOTHING)) { - v->current_order.type = OT_DUMMY; + (v->IsPrimaryVehicle() && v->current_order.IsType(OT_NOTHING))) { + v->current_order.MakeDummy(); } FOR_ALL_VEHICLES_FROM(u, v->index + 1) { diff --git a/src/openttd.cpp b/src/openttd.cpp --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -2178,7 +2178,7 @@ bool AfterLoadGame() FOR_ALL_VEHICLES(v) { if ((v->type != VEH_TRAIN || IsFrontEngine(v)) && // for all locs !(v->vehstatus & (VS_STOPPED | VS_CRASHED)) && // not stopped or crashed - v->current_order.type == OT_LOADING) { // loading + v->current_order.IsType(OT_LOADING)) { // loading GetStation(v->last_station_visited)->loading_vehicles.push_back(v); /* The loading finished flag is *only* set when actually completely @@ -2195,7 +2195,7 @@ bool AfterLoadGame() for (iter = st->loading_vehicles.begin(); iter != st->loading_vehicles.end();) { Vehicle *v = *iter; iter++; - if (v->current_order.type != OT_LOADING) st->loading_vehicles.remove(v); + if (!v->current_order.IsType(OT_LOADING)) st->loading_vehicles.remove(v); } } } @@ -2307,7 +2307,7 @@ bool AfterLoadGame() /* Update go to buoy orders because they are just waypoints */ Order *order; FOR_ALL_ORDERS(order) { - if (order->type == OT_GOTO_STATION && GetStation(order->dest)->IsBuoy()) { + if (order->IsType(OT_GOTO_STATION) && GetStation(order->dest)->IsBuoy()) { order->flags = 0; } } diff --git a/src/order_base.h b/src/order_base.h --- a/src/order_base.h +++ b/src/order_base.h @@ -9,8 +9,10 @@ #include "oldpool.h" #include "core/bitmath_func.hpp" #include "cargo_type.h" +#include "depot_type.h" #include "station_type.h" #include "vehicle_type.h" +#include "waypoint_type.h" DECLARE_OLD_POOL(Order, Order, 6, 1000) @@ -20,9 +22,20 @@ DECLARE_OLD_POOL(Order, Order, 6, 1000) * - REF_ORDER (all REFs are currently limited to 16 bits!!) */ struct Order : PoolItem { +private: + friend const struct SaveLoad *GetVehicleDescription(VehicleType vt); ///< Saving and loading the current order of vehicles. + friend void Load_VEHS(); ///< Loading of ancient vehicles. + friend const struct SaveLoad *GetOrderDescription(); ///< Saving and loading of orders. + friend uint32 PackOrder(const Order *order); ///< 'Compressing' an order. + friend Order UnpackOrder(uint32 packed); ///< 'Uncompressing' an order. + friend Order UnpackOldOrder(uint16 packed); ///< 'Uncompressing' a loaded old order. + friend Order UnpackVersion4Order(uint16 packed); ///< 'Uncompressing' a loaded ancient order. + + OrderTypeByte type; + +public: Order *next; ///< Pointer to next order. If NULL, end of list - OrderTypeByte type; uint8 flags; DestinationID dest; ///< The destionation of the order. @@ -37,16 +50,64 @@ struct Order : PoolItemtype != OT_NOTHING; } /** + * Check whether this order is of the given type. + * @param type the type to check against. + * @return true if the order matches. + */ + inline bool IsType(OrderType type) const { return this->type == type; } + + /** + * Get the type of order of this order. + * @return the order type. + */ + inline OrderType GetType() const { return this->type; } + + /** * 'Free' the order * @note ONLY use on "current_order" vehicle orders! */ void Free(); /** + * Makes this order a Go To Station order. + * @param destsination the station to go to. + */ + void MakeGoToStation(StationID destination); + + /** + * Makes this order a Go To Depot order. + * @param destination the depot to go to. + * @param order is this order a 'default' order, or an overriden vehicle order? + */ + void MakeGoToDepot(DepotID destination, bool order); + + /** + * Makes this order a Go To Waypoint order. + * @param destination the waypoint to go to. + */ + void MakeGoToWaypoint(WaypointID destination); + + /** + * Makes this order a Loading order. + */ + void MakeLoading(); + + /** + * Makes this order a Leave Station order. + */ + void MakeLeaveStation(); + + /** + * Makes this order a Dummy order. + */ + void MakeDummy(); + + /** * Free a complete order chain. * @note do not use on "current_order" vehicle orders! */ diff --git a/src/order_cmd.cpp b/src/order_cmd.cpp --- a/src/order_cmd.cpp +++ b/src/order_cmd.cpp @@ -48,6 +48,46 @@ void Order::Free() this->next = NULL; } +void Order::MakeGoToStation(StationID destination) +{ + this->type = OT_GOTO_STATION; + this->flags = 0; + this->dest = destination; +} + +void Order::MakeGoToDepot(DepotID destination, bool order) +{ + this->type = OT_GOTO_DEPOT; + this->flags = order ? OFB_PART_OF_ORDERS : OFB_NON_STOP; + this->dest = destination; + this->refit_cargo = CT_NO_REFIT; + this->refit_subtype = 0; +} + +void Order::MakeGoToWaypoint(WaypointID destination) +{ + this->type = OT_GOTO_WAYPOINT; + this->flags = 0; + this->dest = destination; +} + +void Order::MakeLoading() +{ + this->type = OT_LOADING; +} + +void Order::MakeLeaveStation() +{ + this->type = OT_LEAVESTATION; + this->flags = 0; +} + +void Order::MakeDummy() +{ + this->type = OT_DUMMY; + this->flags = 0; +} + void Order::FreeChain() { if (next != NULL) next->FreeChain(); @@ -128,7 +168,7 @@ Order UnpackOldOrder(uint16 packed) * Unpacks a order from savegames with version 4 and lower * */ -static Order UnpackVersion4Order(uint16 packed) +Order UnpackVersion4Order(uint16 packed) { Order order; order.type = (OrderType)GB(packed, 0, 4); @@ -208,7 +248,7 @@ static void DeleteOrderWarnings(const Ve static TileIndex GetOrderLocation(const Order& o) { - switch (o.type) { + switch (o.GetType()) { default: NOT_REACHED(); case OT_GOTO_STATION: return GetStation(o.dest)->xy; case OT_GOTO_DEPOT: return GetDepot(o.dest)->xy; @@ -241,7 +281,7 @@ CommandCost CmdInsertOrder(TileIndex til /* Check if the inserted order is to the correct destination (owner, type), * and has the correct flags if any */ - switch (new_order.type) { + switch (new_order.GetType()) { case OT_GOTO_STATION: { const Station *st; @@ -401,7 +441,7 @@ CommandCost CmdInsertOrder(TileIndex til * If the order is to be inserted at the beginning of the order list this * finds the last order in the list. */ for (const Order *o = v->orders; o != NULL; o = o->next) { - if (o->type == OT_GOTO_STATION || o->type == OT_GOTO_DEPOT) prev = o; + if (o->IsType(OT_GOTO_STATION) || o->IsType(OT_GOTO_DEPOT)) prev = o; if (++n == sel_ord && prev != NULL) break; } if (prev != NULL) { @@ -575,7 +615,7 @@ CommandCost CmdDeleteOrder(TileIndex til /* NON-stop flag is misused to see if a train is in a station that is * on his order list or not */ - if (sel_ord == u->cur_order_index && u->current_order.type == OT_LOADING && + if (sel_ord == u->cur_order_index && u->current_order.IsType(OT_LOADING) && HasBit(u->current_order.flags, OF_NON_STOP)) { u->current_order.flags = 0; } @@ -614,7 +654,7 @@ CommandCost CmdSkipToOrder(TileIndex til if (v->type == VEH_ROAD) ClearSlot(v); - if (v->current_order.type == OT_LOADING) { + if (v->current_order.IsType(OT_LOADING)) { v->LeaveStation(); /* NON-stop flag is misused to see if a train is in a station that is * on his order list or not */ @@ -745,9 +785,9 @@ CommandCost CmdModifyOrder(TileIndex til if (sel_ord >= v->num_orders) return CMD_ERROR; order = GetVehicleOrder(v, sel_ord); - if ((order->type != OT_GOTO_STATION || GetStation(order->dest)->IsBuoy()) && - (order->type != OT_GOTO_DEPOT || p2 == OF_UNLOAD) && - (order->type != OT_GOTO_WAYPOINT || p2 != OF_NON_STOP)) { + if ((!order->IsType(OT_GOTO_STATION) || GetStation(order->dest)->IsBuoy()) && + (!order->IsType(OT_GOTO_DEPOT) || p2 == OF_UNLOAD) && + (!order->IsType(OT_GOTO_WAYPOINT) || p2 != OF_NON_STOP)) { return CMD_ERROR; } @@ -755,7 +795,7 @@ CommandCost CmdModifyOrder(TileIndex til switch (p2) { case OF_FULL_LOAD: ToggleBit(order->flags, OF_FULL_LOAD); - if (order->type != OT_GOTO_DEPOT) ClrBit(order->flags, OF_UNLOAD); + if (!order->IsType(OT_GOTO_DEPOT)) ClrBit(order->flags, OF_UNLOAD); break; case OF_UNLOAD: ToggleBit(order->flags, OF_UNLOAD); @@ -787,7 +827,7 @@ CommandCost CmdModifyOrder(TileIndex til * when this function is called. */ if (sel_ord == u->cur_order_index && - u->current_order.type != OT_GOTO_DEPOT && + !u->current_order.IsType(OT_GOTO_DEPOT) && HasBit(u->current_order.flags, OF_FULL_LOAD) != HasBit(order->flags, OF_FULL_LOAD)) { ToggleBit(u->current_order.flags, OF_FULL_LOAD); } @@ -884,7 +924,7 @@ CommandCost CmdCloneOrder(TileIndex tile TileIndex required_dst = INVALID_TILE; FOR_VEHICLE_ORDERS(src, order) { - if (order->type == OT_GOTO_STATION) { + if (order->IsType(OT_GOTO_STATION)) { const Station *st = GetStation(order->dest); if (IsCargoInClass(dst->cargo_type, CC_PASSENGERS)) { if (st->bus_stops != NULL) required_dst = st->bus_stops->xy; @@ -1162,12 +1202,12 @@ void CheckOrders(const Vehicle* v) FOR_VEHICLE_ORDERS(v, order) { /* Dummy order? */ - if (order->type == OT_DUMMY) { + if (order->IsType(OT_DUMMY)) { problem_type = 1; break; } /* Does station have a load-bay for this vehicle? */ - if (order->type == OT_GOTO_STATION) { + if (order->IsType(OT_GOTO_STATION)) { const Station* st = GetStation(order->dest); TileIndex required_tile = GetStationTileForVehicle(v, st); @@ -1228,20 +1268,18 @@ void RemoveOrderFromAllVehicles(OrderTyp } order = &v->current_order; - if ((v->type == VEH_AIRCRAFT && order->type == OT_GOTO_DEPOT ? OT_GOTO_STATION : order->type) == type && + if ((v->type == VEH_AIRCRAFT && order->IsType(OT_GOTO_DEPOT) ? OT_GOTO_STATION : order->GetType()) == type && v->current_order.dest == destination) { - order->type = OT_DUMMY; - order->flags = 0; + order->MakeDummy(); InvalidateWindow(WC_VEHICLE_VIEW, v->index); } /* Clear the order from the order-list */ invalidate = false; FOR_VEHICLE_ORDERS(v, order) { - if ((v->type == VEH_AIRCRAFT && order->type == OT_GOTO_DEPOT ? OT_GOTO_STATION : order->type) == type && + if ((v->type == VEH_AIRCRAFT && order->IsType(OT_GOTO_DEPOT) ? OT_GOTO_STATION : order->GetType()) == type && order->dest == destination) { - order->type = OT_DUMMY; - order->flags = 0; + order->MakeDummy(); invalidate = true; } } @@ -1263,7 +1301,7 @@ bool VehicleHasDepotOrders(const Vehicle const Order *order; FOR_VEHICLE_ORDERS(v, order) { - if (order->type == OT_GOTO_DEPOT) + if (order->IsType(OT_GOTO_DEPOT)) return true; } @@ -1340,7 +1378,7 @@ static bool CheckForValidOrders(const Ve { const Order *order; - FOR_VEHICLE_ORDERS(v, order) if (order->type != OT_DUMMY) return true; + FOR_VEHICLE_ORDERS(v, order) if (!order->IsType(OT_DUMMY)) return true; return false; } @@ -1354,7 +1392,7 @@ static bool CheckForValidOrders(const Ve */ bool ProcessOrders(Vehicle *v) { - switch (v->current_order.type) { + switch (v->current_order.GetType()) { case OT_GOTO_DEPOT: /* Let a depot order in the orderlist interrupt. */ if (!(v->current_order.flags & OFB_PART_OF_ORDERS)) return false; @@ -1382,10 +1420,10 @@ bool ProcessOrders(Vehicle *v) * will be reset to nothing. (That also happens if no order, but in that case * it won't hit the point in code where may_reverse is checked) */ - bool may_reverse = v->current_order.type == OT_NOTHING; + bool may_reverse = v->current_order.IsType(OT_NOTHING); /* Check if we've reached the waypoint? */ - if (v->current_order.type == OT_GOTO_WAYPOINT && v->tile == v->dest_tile) { + if (v->current_order.IsType(OT_GOTO_WAYPOINT) && v->tile == v->dest_tile) { UpdateVehicleTimetable(v, true); v->cur_order_index++; } @@ -1406,7 +1444,7 @@ bool ProcessOrders(Vehicle *v) const Order *order = GetVehicleOrder(v, v->cur_order_index); /* If no order, do nothing. */ - if (order == NULL || (v->type == VEH_AIRCRAFT && order->type == OT_DUMMY && !CheckForValidOrders(v))) { + if (order == NULL || (v->type == VEH_AIRCRAFT && order->IsType(OT_DUMMY) && !CheckForValidOrders(v))) { if (v->type == VEH_AIRCRAFT) { /* Aircraft do something vastly different here, so handle separately */ extern void HandleMissingAircraftOrders(Vehicle *v); @@ -1422,7 +1460,7 @@ bool ProcessOrders(Vehicle *v) /* If it is unchanged, keep it. */ if (order->Equals(v->current_order) && - (v->type != VEH_SHIP || order->type != OT_GOTO_STATION || GetStation(order->dest)->dock_tile != 0)) { + (v->type != VEH_SHIP || !order->IsType(OT_GOTO_STATION) || GetStation(order->dest)->dock_tile != 0)) { return false; } @@ -1444,7 +1482,7 @@ bool ProcessOrders(Vehicle *v) break; } - switch (order->type) { + switch (order->GetType()) { case OT_GOTO_STATION: v->dest_tile = v->GetOrderStationLocation(order->dest); break; @@ -1490,6 +1528,7 @@ void InitializeOrders() _backup_orders_tile = 0; } +const SaveLoad *GetOrderDescription() { static const SaveLoad _order_desc[] = { SLE_VAR(Order, type, SLE_UINT8), SLE_VAR(Order, flags, SLE_UINT8), @@ -1505,6 +1544,8 @@ static const SaveLoad _order_desc[] = { SLE_CONDNULL(10, 5, 35), SLE_END() }; + return _order_desc; +} static void Save_ORDR() { @@ -1512,7 +1553,7 @@ static void Save_ORDR() FOR_ALL_ORDERS(order) { SlSetArrayIndex(order->index); - SlObject(order, _order_desc); + SlObject(order, GetOrderDescription()); } } @@ -1565,7 +1606,7 @@ static void Load_ORDR() while ((index = SlIterateArray()) != -1) { Order *order = new (index) Order(); - SlObject(order, _order_desc); + SlObject(order, GetOrderDescription()); } } } diff --git a/src/order_gui.cpp b/src/order_gui.cpp --- a/src/order_gui.cpp +++ b/src/order_gui.cpp @@ -153,7 +153,7 @@ static void DrawOrdersWindow(Window *w) w->ShowWidget(ORDER_WIDGET_UNLOAD); // Unload if (order != NULL) { - switch (order->type) { + switch (order->GetType()) { case OT_GOTO_STATION: if (!GetStation(order->dest)->IsBuoy()) break; /* Fall-through */ @@ -194,7 +194,7 @@ static void DrawOrdersWindow(Window *w) if (i - w->vscroll.pos < w->vscroll.cap) { SetDParam(1, 6); - switch (order->type) { + switch (order->GetType()) { case OT_DUMMY: SetDParam(1, STR_INVALID_ORDER); SetDParam(2, order->dest); @@ -272,9 +272,7 @@ static Order GetOrderCmdFromTile(const V case MP_RAILWAY: if (v->type == VEH_TRAIN && IsTileOwner(tile, _local_player)) { if (IsRailDepot(tile)) { - order.type = OT_GOTO_DEPOT; - order.flags = OFB_PART_OF_ORDERS; - order.dest = GetDepotByTile(tile)->index; + order.MakeGoToDepot(GetDepotByTile(tile)->index, true); return order; } } @@ -282,9 +280,7 @@ static Order GetOrderCmdFromTile(const V case MP_ROAD: if (IsRoadDepot(tile) && v->type == VEH_ROAD && IsTileOwner(tile, _local_player)) { - order.type = OT_GOTO_DEPOT; - order.flags = OFB_PART_OF_ORDERS; - order.dest = GetDepotByTile(tile)->index; + order.MakeGoToDepot(GetDepotByTile(tile)->index, true); return order; } break; @@ -292,9 +288,7 @@ static Order GetOrderCmdFromTile(const V case MP_STATION: if (v->type != VEH_AIRCRAFT) break; if (IsHangar(tile) && IsTileOwner(tile, _local_player)) { - order.type = OT_GOTO_DEPOT; - order.flags = OFB_PART_OF_ORDERS; - order.dest = GetStationIndex(tile); + order.MakeGoToDepot(GetStationIndex(tile), true); return order; } break; @@ -305,9 +299,7 @@ static Order GetOrderCmdFromTile(const V IsTileOwner(tile, _local_player)) { TileIndex tile2 = GetOtherShipDepotTile(tile); - order.type = OT_GOTO_DEPOT; - order.flags = OFB_PART_OF_ORDERS; - order.dest = GetDepotByTile(tile < tile2 ? tile : tile2)->index; + order.MakeGoToDepot(GetDepotByTile(tile < tile2 ? tile : tile2)->index, true); return order; } @@ -321,9 +313,7 @@ static Order GetOrderCmdFromTile(const V v->type == VEH_TRAIN && IsTileOwner(tile, _local_player) && IsRailWaypoint(tile)) { - order.type = OT_GOTO_WAYPOINT; - order.flags = 0; - order.dest = GetWaypointByTile(tile)->index; + order.MakeGoToWaypoint(GetWaypointByTile(tile)->index); return order; } @@ -339,9 +329,7 @@ static Order GetOrderCmdFromTile(const V (facil=FACIL_BUS_STOP, v->type == VEH_ROAD && IsCargoInClass(v->cargo_type, CC_PASSENGERS)) || (facil=FACIL_TRUCK_STOP, 1); if (st->facilities & facil) { - order.type = OT_GOTO_STATION; - order.flags = 0; - order.dest = st_index; + order.MakeGoToStation(st_index); return order; } } @@ -576,7 +564,7 @@ static void OrdersWndProc(Window *w, Win const Order *ord = GetVehicleOrder(v, sel); TileIndex xy; - switch (ord->type) { + switch (ord->GetType()) { case OT_GOTO_STATION: xy = GetStation(ord->dest)->xy ; break; case OT_GOTO_DEPOT: xy = (v->type == VEH_AIRCRAFT) ? GetStation(ord->dest)->xy : GetDepot(ord->dest)->xy; break; case OT_GOTO_WAYPOINT: xy = GetWaypoint(ord->dest)->xy; break; @@ -691,7 +679,7 @@ static void OrdersWndProc(Window *w, Win int s = OrderGetSel(w); if (e->we.click.widget != ORDER_WIDGET_FULL_LOAD) break; - if (s == v->num_orders || GetVehicleOrder(v, s)->type != OT_GOTO_DEPOT) { + if (s == v->num_orders || !GetVehicleOrder(v, s)->IsType(OT_GOTO_DEPOT)) { GuiShowTooltips(STR_8857_MAKE_THE_HIGHLIGHTED_ORDER); } else { GuiShowTooltips(STR_SERVICE_HINT); diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp --- a/src/roadveh_cmd.cpp +++ b/src/roadveh_cmd.cpp @@ -476,7 +476,7 @@ CommandCost CmdSendRoadVehToDepot(TileIn if (v->IsInDepot()) return CMD_ERROR; /* If the current orders are already goto-depot */ - if (v->current_order.type == OT_GOTO_DEPOT) { + if (v->current_order.IsType(OT_GOTO_DEPOT)) { if (!!(p2 & DEPOT_SERVICE) == HasBit(v->current_order.flags, OF_HALT_IN_DEPOT)) { /* We called with a different DEPOT_SERVICE setting. * Now we change the setting to apply the new one and let the vehicle head for the same depot. @@ -496,8 +496,7 @@ CommandCost CmdSendRoadVehToDepot(TileIn if (HasBit(v->current_order.flags, OF_PART_OF_ORDERS)) v->cur_order_index++; - v->current_order.type = OT_DUMMY; - v->current_order.flags = 0; + v->current_order.MakeDummy(); InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH); } return CommandCost(); @@ -507,14 +506,11 @@ CommandCost CmdSendRoadVehToDepot(TileIn if (dep == NULL) return_cmd_error(STR_9019_UNABLE_TO_FIND_LOCAL_DEPOT); if (flags & DC_EXEC) { - if (v->current_order.type == OT_LOADING) v->LeaveStation(); + if (v->current_order.IsType(OT_LOADING)) v->LeaveStation(); ClearSlot(v); - v->current_order.type = OT_GOTO_DEPOT; - v->current_order.flags = OFB_NON_STOP; + v->current_order.MakeGoToDepot(dep->index, false); if (!(p2 & DEPOT_SERVICE)) SetBit(v->current_order.flags, OF_HALT_IN_DEPOT); - v->current_order.refit_cargo = CT_INVALID; - v->current_order.dest = dep->index; v->dest_tile = dep->xy; InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH); } @@ -1757,8 +1753,8 @@ again: /* Vehicle is at the stop position (at a bay) in a road stop. * Note, if vehicle is loading/unloading it has already been handled, * so if we get here the vehicle has just arrived or is just ready to leave. */ - if (v->current_order.type != OT_LEAVESTATION && - v->current_order.type != OT_GOTO_DEPOT) { + if (!v->current_order.IsType(OT_LEAVESTATION) && + !v->current_order.IsType(OT_GOTO_DEPOT)) { /* Vehicle has arrived at a bay in a road stop */ if (IsDriveThroughStopTile(v->tile)) { @@ -1795,7 +1791,7 @@ again: } /* Vehicle is ready to leave a bay in a road stop */ - if (v->current_order.type != OT_GOTO_DEPOT) { + if (!v->current_order.IsType(OT_GOTO_DEPOT)) { if (rs->IsEntranceBusy()) { /* Road stop entrance is busy, so wait as there is nowhere else to go */ v->cur_speed = 0; @@ -1821,8 +1817,8 @@ again: if (v->dest_tile != v->u.road.slot->xy) { DEBUG(ms, 2, " stop tile 0x%X is not destination tile 0x%X. Multistop desync", v->u.road.slot->xy, v->dest_tile); } - if (v->current_order.type != OT_GOTO_STATION) { - DEBUG(ms, 2, " current order type (%d) is not OT_GOTO_STATION", v->current_order.type); + if (!v->current_order.IsType(OT_GOTO_STATION)) { + DEBUG(ms, 2, " current order type (%d) is not OT_GOTO_STATION", v->current_order.GetType()); } else { if (v->current_order.dest != st->index) DEBUG(ms, 2, " current station %d is not target station in current_order.station (%d)", @@ -1884,7 +1880,7 @@ static void RoadVehController(Vehicle *v ProcessOrders(v); v->HandleLoading(); - if (v->current_order.type == OT_LOADING) return; + if (v->current_order.IsType(OT_LOADING)) return; if (v->IsInDepot() && RoadVehLeaveDepot(v, true)) return; @@ -1925,26 +1921,23 @@ static void CheckIfRoadVehNeedsService(V const Depot *depot = FindClosestRoadDepot(v); if (depot == NULL || DistanceManhattan(v->tile, depot->xy) > 12) { - if (v->current_order.type == OT_GOTO_DEPOT) { - v->current_order.type = OT_DUMMY; - v->current_order.flags = 0; + if (v->current_order.IsType(OT_GOTO_DEPOT)) { + v->current_order.MakeDummy(); InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH); } return; } - if (v->current_order.type == OT_GOTO_DEPOT && + if (v->current_order.IsType(OT_GOTO_DEPOT) && v->current_order.flags & OFB_NON_STOP && !Chance16(1, 20)) { return; } - if (v->current_order.type == OT_LOADING) v->LeaveStation(); + if (v->current_order.IsType(OT_LOADING)) v->LeaveStation(); ClearSlot(v); - v->current_order.type = OT_GOTO_DEPOT; - v->current_order.flags = OFB_NON_STOP; - v->current_order.dest = depot->index; + v->current_order.MakeGoToDepot(depot->index, false); v->dest_tile = depot->xy; InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH); } @@ -1962,14 +1955,14 @@ void RoadVehicle::OnNewDay() CheckOrders(this); /* Current slot has expired */ - if (this->current_order.type == OT_GOTO_STATION && this->u.road.slot != NULL && this->u.road.slot_age-- == 0) { + if (this->current_order.IsType(OT_GOTO_STATION) && this->u.road.slot != NULL && this->u.road.slot_age-- == 0) { DEBUG(ms, 3, "Slot expired for vehicle %d (index %d) at stop 0x%X", this->unitnumber, this->index, this->u.road.slot->xy); ClearSlot(this); } /* update destination */ - if (!(this->vehstatus & VS_STOPPED) && this->current_order.type == OT_GOTO_STATION && this->u.road.slot == NULL && !(this->vehstatus & VS_CRASHED)) { + if (!(this->vehstatus & VS_STOPPED) && this->current_order.IsType(OT_GOTO_STATION) && this->u.road.slot == NULL && !(this->vehstatus & VS_CRASHED)) { Station *st = GetStation(this->current_order.dest); RoadStop *rs = st->GetPrimaryRoadStop(this); RoadStop *best = NULL; diff --git a/src/ship_cmd.cpp b/src/ship_cmd.cpp --- a/src/ship_cmd.cpp +++ b/src/ship_cmd.cpp @@ -153,17 +153,14 @@ static void CheckIfShipNeedsService(Vehi const Depot *depot = FindClosestShipDepot(v); if (depot == NULL || DistanceManhattan(v->tile, depot->xy) > 12) { - if (v->current_order.type == OT_GOTO_DEPOT) { - v->current_order.type = OT_DUMMY; - v->current_order.flags = 0; + if (v->current_order.IsType(OT_GOTO_DEPOT)) { + v->current_order.MakeDummy(); InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH); } return; } - v->current_order.type = OT_GOTO_DEPOT; - v->current_order.flags = OFB_NON_STOP; - v->current_order.dest = depot->index; + v->current_order.MakeGoToDepot(depot->index, false); v->dest_tile = depot->xy; InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH); } @@ -604,7 +601,7 @@ static void ShipController(Vehicle *v) ProcessOrders(v); v->HandleLoading(); - if (v->current_order.type == OT_LOADING) return; + if (v->current_order.IsType(OT_LOADING)) return; CheckShipLeaveDepot(v); @@ -625,40 +622,38 @@ static void ShipController(Vehicle *v) /* A leave station order only needs one tick to get processed, so we can * always skip ahead. */ - if (v->current_order.type == OT_LEAVESTATION) { + if (v->current_order.IsType(OT_LEAVESTATION)) { v->current_order.Free(); InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH); } else if (v->dest_tile != 0) { /* We have a target, let's see if we reached it... */ - if (v->current_order.type == OT_GOTO_STATION && + if (v->current_order.IsType(OT_GOTO_STATION) && IsBuoyTile(v->dest_tile) && DistanceManhattan(v->dest_tile, gp.new_tile) <= 3) { /* We got within 3 tiles of our target buoy, so let's skip to our * next order */ UpdateVehicleTimetable(v, true); v->cur_order_index++; - v->current_order.type = OT_DUMMY; + v->current_order.MakeDummy(); InvalidateVehicleOrder(v); } else { /* Non-buoy orders really need to reach the tile */ if (v->dest_tile == gp.new_tile) { - if (v->current_order.type == OT_GOTO_DEPOT) { + if (v->current_order.IsType(OT_GOTO_DEPOT)) { if ((gp.x & 0xF) == 8 && (gp.y & 0xF) == 8) { VehicleEnterDepot(v); return; } - } else if (v->current_order.type == OT_GOTO_STATION) { - Station *st; - + } else if (v->current_order.IsType(OT_GOTO_STATION)) { v->last_station_visited = v->current_order.dest; /* Process station in the orderlist. */ - st = GetStation(v->current_order.dest); + Station *st = GetStation(v->current_order.dest); if (st->facilities & FACIL_DOCK) { // ugly, ugly workaround for problem with ships able to drop off cargo at wrong stations ShipArrivesAt(v, st); v->BeginLoading(); } else { // leave stations without docks right aways - v->current_order.type = OT_LEAVESTATION; + v->current_order.MakeLeaveStation(); v->cur_order_index++; InvalidateVehicleOrder(v); } @@ -947,7 +942,7 @@ CommandCost CmdSendShipToDepot(TileIndex if (v->IsInDepot()) return CMD_ERROR; /* If the current orders are already goto-depot */ - if (v->current_order.type == OT_GOTO_DEPOT) { + if (v->current_order.IsType(OT_GOTO_DEPOT)) { if (!!(p2 & DEPOT_SERVICE) == HasBit(v->current_order.flags, OF_HALT_IN_DEPOT)) { /* We called with a different DEPOT_SERVICE setting. * Now we change the setting to apply the new one and let the vehicle head for the same depot. @@ -967,8 +962,7 @@ CommandCost CmdSendShipToDepot(TileIndex if (HasBit(v->current_order.flags, OF_PART_OF_ORDERS)) v->cur_order_index++; - v->current_order.type = OT_DUMMY; - v->current_order.flags = 0; + v->current_order.MakeDummy(); InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH); } return CommandCost(); @@ -978,14 +972,11 @@ CommandCost CmdSendShipToDepot(TileIndex if (dep == NULL) return_cmd_error(STR_981A_UNABLE_TO_FIND_LOCAL_DEPOT); if (flags & DC_EXEC) { - if (v->current_order.type == OT_LOADING) v->LeaveStation(); + if (v->current_order.IsType(OT_LOADING)) v->LeaveStation(); v->dest_tile = dep->xy; - v->current_order.type = OT_GOTO_DEPOT; - v->current_order.flags = OFB_NON_STOP; + v->current_order.MakeGoToDepot(dep->index, false); if (!(p2 & DEPOT_SERVICE)) SetBit(v->current_order.flags, OF_HALT_IN_DEPOT); - v->current_order.refit_cargo = CT_INVALID; - v->current_order.dest = dep->index; InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH); } diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -1898,7 +1898,7 @@ bool HasStationInUse(StationID station, if (player == INVALID_PLAYER || v->owner == player) { const Order *order; FOR_VEHICLE_ORDERS(v, order) { - if (order->type == OT_GOTO_STATION && order->dest == station) { + if (order->IsType(OT_GOTO_STATION) && order->dest == station) { return true; } } diff --git a/src/timetable_cmd.cpp b/src/timetable_cmd.cpp --- a/src/timetable_cmd.cpp +++ b/src/timetable_cmd.cpp @@ -69,7 +69,7 @@ CommandCost CmdChangeTimetable(TileIndex bool packed_time = HasBit(p1, 25); bool is_journey = HasBit(p1, 24) || packed_time; if (!is_journey) { - if (order->type != OT_GOTO_STATION) return_cmd_error(STR_TIMETABLE_ONLY_WAIT_AT_STATIONS); + if (!order->IsType(OT_GOTO_STATION)) return_cmd_error(STR_TIMETABLE_ONLY_WAIT_AT_STATIONS); if (_patches.new_nonstop && (order->flags & OFB_NON_STOP)) return_cmd_error(STR_TIMETABLE_NOT_STOPPING_HERE); } diff --git a/src/timetable_gui.cpp b/src/timetable_gui.cpp --- a/src/timetable_gui.cpp +++ b/src/timetable_gui.cpp @@ -79,7 +79,7 @@ static void DrawTimetableWindow(Window * w->EnableWidget(TTV_CLEAR_TIME); } else { const Order *order = GetVehicleOrder(v, (selected + 1) / 2); - bool disable = order == NULL || order->type != OT_GOTO_STATION || (_patches.new_nonstop && (order->flags & OFB_NON_STOP)); + bool disable = order == NULL || !order->IsType(OT_GOTO_STATION) || (_patches.new_nonstop && (order->flags & OFB_NON_STOP)); w->SetWidgetDisabledState(TTV_CHANGE_TIME, disable); w->SetWidgetDisabledState(TTV_CLEAR_TIME, disable); @@ -113,7 +113,7 @@ static void DrawTimetableWindow(Window * if (i % 2 == 0) { SetDParam(2, STR_EMPTY); - switch (order->type) { + switch (order->GetType()) { case OT_DUMMY: SetDParam(0, STR_INVALID_ORDER); break; @@ -197,7 +197,7 @@ static void DrawTimetableWindow(Window * for (const Order *order = GetVehicleOrder(v, 0); order != NULL; order = order->next) { total_time += order->travel_time + order->wait_time; if (order->travel_time == 0) complete = false; - if (order->wait_time == 0 && order->type == OT_GOTO_STATION && !(_patches.new_nonstop && (order->flags & OFB_NON_STOP))) complete = false; + if (order->wait_time == 0 && order->IsType(OT_GOTO_STATION) && !(_patches.new_nonstop && (order->flags & OFB_NON_STOP))) complete = false; } if (total_time != 0) { diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -2107,7 +2107,7 @@ CommandCost CmdSendTrainToDepot(TileInde if (v->vehstatus & VS_CRASHED) return CMD_ERROR; - if (v->current_order.type == OT_GOTO_DEPOT) { + if (v->current_order.IsType(OT_GOTO_DEPOT)) { if (!!(p2 & DEPOT_SERVICE) == HasBit(v->current_order.flags, OF_HALT_IN_DEPOT)) { /* We called with a different DEPOT_SERVICE setting. * Now we change the setting to apply the new one and let the vehicle head for the same depot. @@ -2126,8 +2126,7 @@ CommandCost CmdSendTrainToDepot(TileInde v->cur_order_index++; } - v->current_order.type = OT_DUMMY; - v->current_order.flags = 0; + v->current_order.MakeDummy(); InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH); } return CommandCost(); @@ -2141,14 +2140,11 @@ CommandCost CmdSendTrainToDepot(TileInde if (tfdd.best_length == (uint)-1) return_cmd_error(STR_883A_UNABLE_TO_FIND_ROUTE_TO); if (flags & DC_EXEC) { - if (v->current_order.type == OT_LOADING) v->LeaveStation(); + if (v->current_order.IsType(OT_LOADING)) v->LeaveStation(); v->dest_tile = tfdd.tile; - v->current_order.type = OT_GOTO_DEPOT; - v->current_order.flags = OFB_NON_STOP; + v->current_order.MakeGoToDepot(GetDepotByTile(tfdd.tile)->index, false); if (!(p2 & DEPOT_SERVICE)) SetBit(v->current_order.flags, OF_HALT_IN_DEPOT); - v->current_order.dest = GetDepotByTile(tfdd.tile)->index; - v->current_order.refit_cargo = CT_INVALID; InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH); /* If there is no depot in front, reverse automatically */ if (tfdd.reverse) DoCommand(v->tile, v->index, 0, DC_EXEC, CMD_REVERSE_TRAIN_DIRECTION); @@ -2346,11 +2342,7 @@ static bool NtpCallbFindStation(TileInde static void FillWithStationData(TrainTrackFollowerData* fd, const Vehicle* v) { fd->dest_coords = v->dest_tile; - if (v->current_order.type == OT_GOTO_STATION) { - fd->station_index = v->current_order.dest; - } else { - fd->station_index = INVALID_STATION; - } + fd->station_index = v->current_order.IsType(OT_GOTO_STATION) ? v->current_order.dest : INVALID_STATION; } static const byte _initial_tile_subcoord[6][4][3] = { @@ -2958,7 +2950,7 @@ static void TrainController(Vehicle *v, return; } - if (v->current_order.type == OT_LEAVESTATION) { + if (v->current_order.IsType(OT_LEAVESTATION)) { v->current_order.Free(); InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH); } @@ -3470,7 +3462,7 @@ static void TrainLocoHandler(Vehicle *v, v->HandleLoading(mode); - if (v->current_order.type == OT_LOADING) return; + if (v->current_order.IsType(OT_LOADING)) return; if (CheckTrainStayInDepot(v)) return; @@ -3554,12 +3546,11 @@ static void CheckIfTrainNeedsService(Veh TrainFindDepotData tfdd = FindClosestTrainDepot(v, MAX_ACCEPTABLE_DEPOT_DIST); /* Only go to the depot if it is not too far out of our way. */ if (tfdd.best_length == (uint)-1 || tfdd.best_length > MAX_ACCEPTABLE_DEPOT_DIST) { - if (v->current_order.type == OT_GOTO_DEPOT) { + if (v->current_order.IsType(OT_GOTO_DEPOT)) { /* If we were already heading for a depot but it has * suddenly moved farther away, we continue our normal * schedule? */ - v->current_order.type = OT_DUMMY; - v->current_order.flags = 0; + v->current_order.MakeDummy(); InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH); } return; @@ -3567,15 +3558,13 @@ static void CheckIfTrainNeedsService(Veh const Depot* depot = GetDepotByTile(tfdd.tile); - if (v->current_order.type == OT_GOTO_DEPOT && + if (v->current_order.IsType(OT_GOTO_DEPOT) && v->current_order.dest != depot->index && !Chance16(3, 16)) { return; } - v->current_order.type = OT_GOTO_DEPOT; - v->current_order.flags = OFB_NON_STOP; - v->current_order.dest = depot->index; + v->current_order.MakeGoToDepot(depot->index, false); v->dest_tile = tfdd.tile; InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH); } @@ -3593,7 +3582,7 @@ void Train::OnNewDay() CheckOrders(this); /* update destination */ - if (this->current_order.type == OT_GOTO_STATION) { + if (this->current_order.IsType(OT_GOTO_STATION)) { TileIndex tile = GetStation(this->current_order.dest)->train_tile; if (tile != 0) this->dest_tile = tile; } diff --git a/src/vehicle.cpp b/src/vehicle.cpp --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -120,10 +120,10 @@ void VehicleServiceInDepot(Vehicle *v) bool VehicleNeedsService(const Vehicle *v) { if (v->vehstatus & (VS_STOPPED | VS_CRASHED)) return false; - if (v->current_order.type != OT_GOTO_DEPOT || !(v->current_order.flags & OFB_PART_OF_ORDERS)) { // Don't interfere with a depot visit by the order list + if (!v->current_order.IsType(OT_GOTO_DEPOT) || !(v->current_order.flags & OFB_PART_OF_ORDERS)) { // Don't interfere with a depot visit by the order list if (_patches.gotodepot && VehicleHasDepotOrders(v)) return false; - if (v->current_order.type == OT_LOADING) return false; - if (v->current_order.type == OT_GOTO_DEPOT && v->current_order.flags & OFB_HALT_IN_DEPOT) return false; + if (v->current_order.IsType(OT_LOADING)) return false; + if (v->current_order.IsType(OT_GOTO_DEPOT) && v->current_order.flags & OFB_HALT_IN_DEPOT) return false; } if (_patches.no_servicing_if_no_breakdowns && _opt.diff.vehicle_breakdowns == 0) { @@ -631,7 +631,7 @@ void VehicleEnteredDepotThisTick(Vehicle { /* We need to set v->leave_depot_instantly as we have no control of it's contents at this time. * Vehicle should stop in the depot if it was in 'stopping' state - train intered depot while slowing down. */ - if ((HasBit(v->current_order.flags, OF_HALT_IN_DEPOT) && !HasBit(v->current_order.flags, OF_PART_OF_ORDERS) && v->current_order.type == OT_GOTO_DEPOT) || + if ((HasBit(v->current_order.flags, OF_HALT_IN_DEPOT) && !HasBit(v->current_order.flags, OF_PART_OF_ORDERS) && v->current_order.IsType(OT_GOTO_DEPOT)) || (v->vehstatus & VS_STOPPED)) { /* we keep the vehicle in the depot since the user ordered it to stay */ v->leave_depot_instantly = false; @@ -2033,7 +2033,7 @@ uint GenerateVehicleSortList(const Vehic const Order *order; FOR_VEHICLE_ORDERS(v, order) { - if (order->type == OT_GOTO_STATION && order->dest == index) { + if (order->IsType(OT_GOTO_STATION) && order->dest == index) { if (n == *length_of_array) ExtendVehicleListSize(sort_list, length_of_array, 50); (*sort_list)[n++] = v; break; @@ -2077,7 +2077,7 @@ uint GenerateVehicleSortList(const Vehic const Order *order; FOR_VEHICLE_ORDERS(v, order) { - if (order->type == OT_GOTO_DEPOT && order->dest == index) { + if (order->IsType(OT_GOTO_DEPOT) && order->dest == index) { if (n == *length_of_array) ExtendVehicleListSize(sort_list, length_of_array, 25); (*sort_list)[n++] = v; break; @@ -2235,14 +2235,13 @@ void VehicleEnterDepot(Vehicle *v) TriggerVehicle(v, VEHICLE_TRIGGER_DEPOT); - if (v->current_order.type == OT_GOTO_DEPOT) { + if (v->current_order.IsType(OT_GOTO_DEPOT)) { Order t; InvalidateWindow(WC_VEHICLE_VIEW, v->index); t = v->current_order; - v->current_order.type = OT_DUMMY; - v->current_order.flags = 0; + v->current_order.MakeDummy(); if (t.refit_cargo < NUM_CARGO) { CommandCost cost; @@ -3054,7 +3053,7 @@ static void Save_VEHS() } /** Will be called when vehicles need to be loaded. */ -static void Load_VEHS() +void Load_VEHS() { int index; Vehicle *v; @@ -3097,7 +3096,7 @@ static void Load_VEHS() if (CheckSavegameVersion(5)) { /* Convert the current_order.type (which is a mix of type and flags, because * in those versions, they both were 4 bits big) to type and flags */ - v->current_order.flags = (v->current_order.type & 0xF0) >> 4; + v->current_order.flags = GB(v->current_order.type, 4, 4); v->current_order.type.m_val &= 0x0F; } @@ -3131,7 +3130,7 @@ void Vehicle::BeginLoading() { assert(IsTileType(tile, MP_STATION) || type == VEH_SHIP); - if (this->current_order.type == OT_GOTO_STATION && + if (this->current_order.IsType(OT_GOTO_STATION) && this->current_order.dest == this->last_station_visited) { /* Arriving at the ordered station. * Keep the load/unload flags, as we (obviously) still need them. */ @@ -3149,7 +3148,7 @@ void Vehicle::BeginLoading() this->current_order.flags = 0; } - current_order.type = OT_LOADING; + current_order.MakeLoading(); GetStation(this->last_station_visited)->loading_vehicles.push_back(this); VehiclePayment(this); @@ -3170,8 +3169,7 @@ void Vehicle::LeaveStation() /* Only update the timetable if the vehicle was supposed to stop here. */ if (current_order.flags & OFB_NON_STOP) UpdateVehicleTimetable(this, false); - current_order.type = OT_LEAVESTATION; - current_order.flags = 0; + current_order.MakeLeaveStation(); GetStation(this->last_station_visited)->loading_vehicles.remove(this); HideFillingPercent(this->fill_percent_te_id); @@ -3181,7 +3179,7 @@ void Vehicle::LeaveStation() void Vehicle::HandleLoading(bool mode) { - switch (this->current_order.type) { + switch (this->current_order.GetType()) { case OT_LOADING: { uint wait_time = max(this->current_order.wait_time - this->lateness_counter, 0); diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -917,7 +917,7 @@ void DrawSmallOrderList(const Vehicle *v if (sel == 0) DrawString(x - 6, y, STR_SMALL_RIGHT_ARROW, TC_BLACK); sel--; - if (order->type == OT_GOTO_STATION) { + if (order->IsType(OT_GOTO_STATION)) { if (v->type == VEH_SHIP && GetStation(order->dest)->IsBuoy()) continue; SetDParam(0, order->dest); @@ -1952,7 +1952,7 @@ static void DrawVehicleViewWindow(Window str = STR_8861_STOPPED; } } else { // vehicle is in a "normal" state, show current order - switch (v->current_order.type) { + switch (v->current_order.GetType()) { case OT_GOTO_STATION: { SetDParam(0, v->current_order.dest); SetDParam(1, v->GetDisplaySpeed()); diff --git a/src/waypoint.cpp b/src/waypoint.cpp --- a/src/waypoint.cpp +++ b/src/waypoint.cpp @@ -236,7 +236,7 @@ CommandCost CmdBuildTrainWaypoint(TileIn FOR_ALL_VEHICLES(v) { if (v->type == VEH_TRAIN && v->First() == v && - v->current_order.type == OT_GOTO_WAYPOINT && + v->current_order.IsType(OT_GOTO_WAYPOINT) && v->dest_tile == wp->xy) { v->dest_tile = tile; } diff --git a/src/yapf/yapf_destrail.hpp b/src/yapf/yapf_destrail.hpp --- a/src/yapf/yapf_destrail.hpp +++ b/src/yapf/yapf_destrail.hpp @@ -86,7 +86,7 @@ protected: public: void SetDestination(Vehicle* v) { - switch (v->current_order.type) { + switch (v->current_order.GetType()) { case OT_GOTO_STATION: m_destTile = CalcStationCenterTile(v->current_order.dest); m_dest_station_id = v->current_order.dest; diff --git a/src/yapf/yapf_road.cpp b/src/yapf/yapf_road.cpp --- a/src/yapf/yapf_road.cpp +++ b/src/yapf/yapf_road.cpp @@ -84,7 +84,7 @@ public: const Vehicle* v = Yapf().GetVehicle(); // we have reached the vehicle's destination - segment should end here to avoid target skipping - if (v->current_order.type == OT_GOTO_STATION && tile == v->dest_tile) break; + if (v->current_order.IsType(OT_GOTO_STATION) && tile == v->dest_tile) break; // stop if we have just entered the depot if (IsTileDepotType(tile, TRANSPORT_ROAD) && trackdir == DiagdirToDiagTrackdir(ReverseDiagDir(GetRoadDepotDirection(tile)))) {