(svn r6291) -Feature: Vehicle lists from the station window now also got the goto depot button

-Codechange: unified the code for mass goto depot to avoid duplicated code
-Fix: Vehicles already on the way to depots will not be cancelled by mass goto depot (made it really hard to send all vehicles at once)
This commit is contained in:
bjarni 2006-09-01 10:24:15 +00:00
parent 7d3685a8ad
commit d7e1d08d53
12 changed files with 91 additions and 125 deletions

View File

@ -492,30 +492,28 @@ int32 CmdStartStopAircraft(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
* @param tile unused
* @param p1 vehicle ID to send to the hangar
* @param p2 various bitmasked elements
* - p2 bit 0 - aircraft will try to goto a hangar, but not stop there (service only)
* - p2 bit 1 - send all of shared orders to depot
* - p2 bit 2 - aircraft will try to locate another airport with a hangar if the target airport lacks one (used by helicopters for autorenew and autoreplace)
* - p2 bit 0-3 - DEPOT_ flags (see vehicle.h)
* - p2 bit 8-10 - VLW flag (for mass goto depot)
*/
int32 CmdSendAircraftToHangar(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
{
Vehicle *v;
const int32 return_value = HASBIT(p2, 1) ? 0 : CMD_ERROR;
if (HASBIT(p2, 1) && (p2 & VLW_FLAGS) == VLW_STANDARD) {
return SendAllVehiclesToDepot(VEH_Aircraft, flags, HASBIT(p2, 0), _current_player);
if (p2 & DEPOT_MASS_SEND) {
/* Mass goto depot requested */
if (!ValidVLWFlags(p2 & VLW_FLAGS)) return CMD_ERROR;
return SendAllVehiclesToDepot(VEH_Aircraft, flags, p2 & DEPOT_SERVICE, _current_player, (p2 & VLW_FLAGS), p1);
}
if (!IsValidVehicleID(p1)) return return_value;
if (!IsValidVehicleID(p1)) return CMD_ERROR;
v = GetVehicle(p1);
if (v->type != VEH_Aircraft || !CheckOwnership(v->owner)) return return_value;
if (v->type != VEH_Aircraft || !CheckOwnership(v->owner)) return CMD_ERROR;
if (HASBIT(p2, 1) && v->next_shared != NULL) CmdSendAircraftToHangar(tile, flags, v->next_shared->index, p2);
if (v->current_order.type == OT_GOTO_DEPOT && p2 == 0) {
if (v->current_order.type == OT_GOTO_DEPOT && !(p2 & DEPOT_LOCATE_HANGAR)) {
if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of hangar orders
if (flags & DC_EXEC) {
if (HASBIT(p2, 1)) return 0; // Mass ordering goto depot should not turn goto hangar orders off
if (v->current_order.flags & OF_UNLOAD) v->cur_order_index++;
v->current_order.type = OT_DUMMY;
v->current_order.flags = 0;
@ -530,12 +528,12 @@ int32 CmdSendAircraftToHangar(TileIndex tile, uint32 flags, uint32 p1, uint32 p2
if (!IsValidStation(st) || st->airport_tile == 0 || GetAirport(st->airport_type)->nof_depots == 0) {
StationID station;
if (!HASBIT(p2, 2)) return return_value;
if (!(p2 & DEPOT_LOCATE_HANGAR)) return CMD_ERROR;
// the aircraft has to search for a hangar on its own
station = FindNearestHangar(v);
next_airport_has_hangar = false;
if (station == INVALID_STATION) return return_value;
if (station == INVALID_STATION) return CMD_ERROR;
st = GetStation(station);
next_airport_index = station;
@ -544,11 +542,11 @@ int32 CmdSendAircraftToHangar(TileIndex tile, uint32 flags, uint32 p1, uint32 p2
if (flags & DC_EXEC) {
v->current_order.type = OT_GOTO_DEPOT;
v->current_order.flags = OF_NON_STOP;
if (!HASBIT(p2,0)) SETBIT(v->current_order.flags, OFB_HALT_IN_DEPOT);
if (!(p1 & DEPOT_SERVICE)) SETBIT(v->current_order.flags, OFB_HALT_IN_DEPOT);
v->current_order.dest.station = next_airport_index;
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
if (HASBIT(p2, 2) || (p2 == 0 && v->u.air.state == FLYING && !next_airport_has_hangar)) {
// the aircraft is now heading for a different hangar than the next in the orders
if (p2 & DEPOT_LOCATE_HANGAR || (p2 & DEPOT_SERVICE && v->u.air.state == FLYING && !next_airport_has_hangar)) {
/* The aircraft is now heading for a different hangar than the next in the orders */
AircraftNextAirportPos_and_Order(v);
v->u.air.targetairport = next_airport_index;
}
@ -1601,7 +1599,7 @@ static void AircraftEventHandler_HeliTakeOff(Vehicle *v, const AirportFTAClass *
HASBIT(GetEngine(v->engine_type)->player_avail, _local_player))
)) {
_current_player = _local_player;
DoCommandP(v->tile, v->index, (1|(1 << 2)), NULL, CMD_SEND_AIRCRAFT_TO_HANGAR | CMD_SHOW_NO_ERROR);
DoCommandP(v->tile, v->index, DEPOT_SERVICE | DEPOT_LOCATE_HANGAR, NULL, CMD_SEND_AIRCRAFT_TO_HANGAR | CMD_SHOW_NO_ERROR);
_current_player = OWNER_NONE;
}
}
@ -1665,7 +1663,7 @@ static void AircraftEventHandler_Landing(Vehicle *v, const AirportFTAClass *Airp
(p->engine_renew && v->age - v->max_age > (p->engine_renew_months * 30))) {
// send the aircraft to the hangar at next airport
_current_player = _local_player;
DoCommandP(v->tile, v->index, 1, NULL, CMD_SEND_AIRCRAFT_TO_HANGAR | CMD_SHOW_NO_ERROR);
DoCommandP(v->tile, v->index, DEPOT_SERVICE, NULL, CMD_SEND_AIRCRAFT_TO_HANGAR | CMD_SHOW_NO_ERROR);
_current_player = OWNER_NONE;
}
}

View File

@ -596,7 +596,7 @@ static void AircraftViewWndProc(Window *w, WindowEvent *e)
ScrollMainWindowTo(v->x_pos, v->y_pos);
break;
case 7: /* goto hangar */
DoCommandP(v->tile, v->index, _ctrl_pressed ? 1 : 0, NULL, CMD_SEND_AIRCRAFT_TO_HANGAR | CMD_MSG(STR_A012_CAN_T_SEND_AIRCRAFT_TO));
DoCommandP(v->tile, v->index, _ctrl_pressed ? DEPOT_SERVICE : 0, NULL, CMD_SEND_AIRCRAFT_TO_HANGAR | CMD_MSG(STR_A012_CAN_T_SEND_AIRCRAFT_TO));
break;
case 8: /* refit */
ShowAircraftRefitWindow(v);
@ -985,7 +985,7 @@ static const Widget _player_aircraft_widgets[] = {
{ WWT_PANEL, RESIZE_RIGHT, 14, 248, 259, 14, 25, 0x0, STR_NULL },
{ WWT_MATRIX, RESIZE_RB, 14, 0, 247, 26, 169, 0x401, STR_A01F_AIRCRAFT_CLICK_ON_AIRCRAFT },
{ WWT_SCROLLBAR, RESIZE_LRB, 14, 248, 259, 26, 169, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST },
{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 0, 124, 170, 181, STR_A003_NEW_AIRCRAFT, STR_A020_BUILD_NEW_AIRCRAFT_REQUIRES },
{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 0, 124, 170, 181, STR_SEND_TO_HANGARS, STR_SEND_TO_HANGARS_TIP },
{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 125, 247, 170, 181, STR_REPLACE_VEHICLES, STR_REPLACE_HELP },
{ WWT_PANEL, RESIZE_RTB, 14, 248, 247, 170, 181, 0x0, STR_NULL },
{ WWT_RESIZEBOX, RESIZE_LRTB, 14, 248, 259, 170, 181, 0x0, STR_RESIZE_BUTTON },

View File

@ -358,33 +358,32 @@ static const Depot* FindClosestRoadDepot(const Vehicle* v)
* @param tile unused
* @param p1 vehicle ID to send to the depot
* @param p2 various bitmasked elements
* - p2 bit 0 - if bit 0 is set, then the road vehicle will only service at the depot. 0 Makes it stop inside
* - p2 bit 1 - send all of shared orders to depot
* - p2 bit 0-3 - DEPOT_ flags (see vehicle.h)
* - p2 bit 8-10 - VLW flag (for mass goto depot)
*/
int32 CmdSendRoadVehToDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
{
Vehicle *v;
const Depot *dep;
const int32 return_value = HASBIT(p2, 1) ? 0 : CMD_ERROR;
if (HASBIT(p2, 1) && (p2 & VLW_FLAGS) == VLW_STANDARD) {
return SendAllVehiclesToDepot(VEH_Road, flags, HASBIT(p2, 0), _current_player);
if (p2 & DEPOT_MASS_SEND) {
/* Mass goto depot requested */
if (!ValidVLWFlags(p2 & VLW_FLAGS)) return CMD_ERROR;
return SendAllVehiclesToDepot(VEH_Road, flags, p2 & DEPOT_SERVICE, _current_player, (p2 & VLW_FLAGS), p1);
}
if (!IsValidVehicleID(p1)) return return_value;
if (!IsValidVehicleID(p1)) return CMD_ERROR;
v = GetVehicle(p1);
if (v->type != VEH_Road || !CheckOwnership(v->owner)) return return_value;
if (v->type != VEH_Road || !CheckOwnership(v->owner)) return CMD_ERROR;
if (HASBIT(p2, 1) && v->next_shared != NULL) CmdSendRoadVehToDepot(tile, flags, v->next_shared->index, p2);
if (v->vehstatus & VS_CRASHED) return return_value;
if (v->vehstatus & VS_CRASHED) return CMD_ERROR;
/* If the current orders are already goto-depot */
if (v->current_order.type == OT_GOTO_DEPOT) {
if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of depot orders
if (flags & DC_EXEC) {
if (HASBIT(p2, 1)) return 0; // Mass ordering goto depot should not turn goto depot orders off
/* If the orders to 'goto depot' are in the orders list (forced servicing),
* then skip to the next order; effectively cancelling this forced service */
if (HASBIT(v->current_order.flags, OFB_PART_OF_ORDERS))
@ -398,16 +397,13 @@ int32 CmdSendRoadVehToDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
}
dep = FindClosestRoadDepot(v);
if (dep == NULL) {
if (HASBIT(p2, 1)) return 0; // Mass ordering goto depot should not return error
return_cmd_error(STR_9019_UNABLE_TO_FIND_LOCAL_DEPOT);
}
if (dep == NULL) return_cmd_error(STR_9019_UNABLE_TO_FIND_LOCAL_DEPOT);
if (flags & DC_EXEC) {
ClearSlot(v);
v->current_order.type = OT_GOTO_DEPOT;
v->current_order.flags = OF_NON_STOP;
if (!HASBIT(p2,0)) SETBIT(v->current_order.flags, OFB_HALT_IN_DEPOT);
if (!(p2 & DEPOT_SERVICE)) SETBIT(v->current_order.flags, OFB_HALT_IN_DEPOT);
v->current_order.dest.depot = dep->index;
v->dest_tile = dep->xy;
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);

View File

@ -383,7 +383,7 @@ static void RoadVehViewWndProc(Window *w, WindowEvent *e)
ScrollMainWindowTo(v->x_pos, v->y_pos);
break;
case 7: /* goto depot */
DoCommandP(v->tile, v->index, _ctrl_pressed ? 1 : 0, NULL, CMD_SEND_ROADVEH_TO_DEPOT | CMD_MSG(STR_9018_CAN_T_SEND_VEHICLE_TO_DEPOT));
DoCommandP(v->tile, v->index, _ctrl_pressed ? DEPOT_SERVICE : 0, NULL, CMD_SEND_ROADVEH_TO_DEPOT | CMD_MSG(STR_9018_CAN_T_SEND_VEHICLE_TO_DEPOT));
break;
case 8: /* turn around */
DoCommandP(v->tile, v->index, 0, NULL, CMD_TURN_ROADVEH | CMD_MSG(STR_9033_CAN_T_MAKE_VEHICLE_TURN));
@ -913,8 +913,7 @@ static const Widget _player_roadveh_widgets[] = {
{ WWT_PANEL, RESIZE_RIGHT, 14, 248, 259, 14, 25, 0x0, STR_NULL},
{ WWT_MATRIX, RESIZE_RB, 14, 0, 247, 26, 207, 0x701, STR_901A_ROAD_VEHICLES_CLICK_ON},
{ WWT_SCROLLBAR, RESIZE_LRB, 14, 248, 259, 26, 207, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST},
/* only for our road list, a 'Build Vehicle' button that opens the depot of the last built depot */
{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 0, 124, 208, 219, STR_8815_NEW_VEHICLES, STR_901B_BUILD_NEW_ROAD_VEHICLES},
{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 0, 124, 208, 219, STR_SEND_TO_DEPOTS, STR_SEND_TO_DEPOTS_TIP},
{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 125, 247, 208, 219, STR_REPLACE_VEHICLES, STR_REPLACE_HELP},
{ WWT_PANEL, RESIZE_RTB, 14, 248, 247, 208, 219, 0x0, STR_NULL},
{ WWT_RESIZEBOX, RESIZE_LRTB, 14, 248, 259, 208, 219, 0x0, STR_RESIZE_BUTTON},

View File

@ -996,33 +996,32 @@ int32 CmdStartStopShip(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
* @param tile unused
* @param p1 vehicle ID to send to the depot
* @param p2 various bitmasked elements
* - p2 bit 0 - if bit 0 is set, then the ship will only service at the depot. 0 Makes it stop inside
* - p2 bit 1 - send all of shared orders to depot
* - p2 bit 0-3 - DEPOT_ flags (see vehicle.h)
* - p2 bit 8-10 - VLW flag (for mass goto depot)
*/
int32 CmdSendShipToDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
{
Vehicle *v;
const Depot *dep;
const int32 return_value = HASBIT(p2, 1) ? 0 : CMD_ERROR;
if (HASBIT(p2, 1) && (p2 & VLW_FLAGS) == VLW_STANDARD) {
return SendAllVehiclesToDepot(VEH_Ship, flags, HASBIT(p2, 0), _current_player);
if (p2 & DEPOT_MASS_SEND) {
/* Mass goto depot requested */
if (!ValidVLWFlags(p2 & VLW_FLAGS)) return CMD_ERROR;
return SendAllVehiclesToDepot(VEH_Ship, flags, p2 & DEPOT_SERVICE, _current_player, (p2 & VLW_FLAGS), p1);
}
if (!IsValidVehicleID(p1)) return return_value;
if (!IsValidVehicleID(p1)) return CMD_ERROR;
v = GetVehicle(p1);
if (v->type != VEH_Ship || !CheckOwnership(v->owner)) return return_value;
if (v->type != VEH_Ship || !CheckOwnership(v->owner)) return CMD_ERROR;
if (HASBIT(p2, 1) && v->next_shared != NULL) CmdSendShipToDepot(tile, flags, v->next_shared->index, p2);
if (v->vehstatus & VS_CRASHED) return return_value;
if (v->vehstatus & VS_CRASHED) return CMD_ERROR;
/* If the current orders are already goto-depot */
if (v->current_order.type == OT_GOTO_DEPOT) {
if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of depot orders
if (flags & DC_EXEC) {
if (HASBIT(p2, 1)) return 0; // Mass ordering goto depot should not turn goto depot orders off
/* If the orders to 'goto depot' are in the orders list (forced servicing),
* then skip to the next order; effectively cancelling this forced service */
if (HASBIT(v->current_order.flags, OFB_PART_OF_ORDERS))
@ -1036,16 +1035,13 @@ int32 CmdSendShipToDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
}
dep = FindClosestShipDepot(v);
if (dep == NULL) {
if (HASBIT(p2, 1)) return 0; // Mass ordering goto depot should not return error
return_cmd_error(STR_981A_UNABLE_TO_FIND_LOCAL_DEPOT);
}
if (dep == NULL) return_cmd_error(STR_981A_UNABLE_TO_FIND_LOCAL_DEPOT);
if (flags & DC_EXEC) {
v->dest_tile = dep->xy;
v->current_order.type = OT_GOTO_DEPOT;
v->current_order.flags = OF_NON_STOP;
if (!HASBIT(p2,0)) SETBIT(v->current_order.flags, OFB_HALT_IN_DEPOT);
if (!(p2 & DEPOT_SERVICE)) SETBIT(v->current_order.flags, OFB_HALT_IN_DEPOT);
v->current_order.dest.depot = dep->index;
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
}

View File

@ -524,7 +524,7 @@ static void ShipViewWndProc(Window *w, WindowEvent *e)
ScrollMainWindowTo(v->x_pos, v->y_pos);
break;
case 7: /* goto hangar */
DoCommandP(v->tile, v->index, _ctrl_pressed ? 1 : 0, NULL, CMD_SEND_SHIP_TO_DEPOT | CMD_MSG(STR_9819_CAN_T_SEND_SHIP_TO_DEPOT));
DoCommandP(v->tile, v->index, _ctrl_pressed ? DEPOT_SERVICE : 0, NULL, CMD_SEND_SHIP_TO_DEPOT | CMD_MSG(STR_9819_CAN_T_SEND_SHIP_TO_DEPOT));
break;
case 8: /* refit */
ShowShipRefitWindow(v);
@ -926,7 +926,7 @@ static const Widget _player_ships_widgets[] = {
{ WWT_PANEL, RESIZE_RIGHT, 14, 248, 259, 14, 25, 0x0, STR_NULL},
{ WWT_MATRIX, RESIZE_RB, 14, 0, 247, 26, 169, 0x401, STR_9823_SHIPS_CLICK_ON_SHIP_FOR},
{ WWT_SCROLLBAR, RESIZE_LRB, 14, 248, 259, 26, 169, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST},
{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 0, 124, 170, 181, STR_9804_NEW_SHIPS, STR_9824_BUILD_NEW_SHIPS_REQUIRES},
{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 0, 124, 170, 181, STR_SEND_TO_DEPOTS, STR_SEND_TO_DEPOTS_TIP},
{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 125, 247, 170, 181, STR_REPLACE_VEHICLES, STR_REPLACE_HELP},
{ WWT_PANEL, RESIZE_RTB, 14, 248, 247, 170, 181, 0x0, STR_NULL},
{ WWT_RESIZEBOX, RESIZE_LRTB, 14, 248, 259, 170, 181, 0x0, STR_RESIZE_BUTTON},

View File

@ -1925,32 +1925,31 @@ static TrainFindDepotData FindClosestTrainDepot(Vehicle *v, int max_distance)
* @param tile unused
* @param p1 train to send to the depot
* @param p2 various bitmasked elements
* - p2 bit 0 - if bit 0 is set, then the train will only service at the depot. 0 Makes it stop inside
* - p2 bit 1 - send all of shared orders to depot
* - p2 bit 0-3 - DEPOT_ flags (see vehicle.h)
* - p2 bit 8-10 - VLW flag (for mass goto depot)
*/
int32 CmdSendTrainToDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
{
Vehicle *v;
TrainFindDepotData tfdd;
const int32 return_value = HASBIT(p2, 1) ? 0 : CMD_ERROR;
if (HASBIT(p2, 1) && (p2 & VLW_FLAGS) == VLW_STANDARD) {
return SendAllVehiclesToDepot(VEH_Train, flags, HASBIT(p2, 0), _current_player);
if (p2 & DEPOT_MASS_SEND) {
/* Mass goto depot requested */
if (!ValidVLWFlags(p2 & VLW_FLAGS)) return CMD_ERROR;
return SendAllVehiclesToDepot(VEH_Train, flags, p2 & DEPOT_SERVICE, _current_player, (p2 & VLW_FLAGS), p1);
}
if (!IsValidVehicleID(p1)) return return_value;
if (!IsValidVehicleID(p1)) return CMD_ERROR;
v = GetVehicle(p1);
if (v->type != VEH_Train || !CheckOwnership(v->owner)) return return_value;
if (v->type != VEH_Train || !CheckOwnership(v->owner)) return CMD_ERROR;
if (HASBIT(p2, 1) && v->next_shared != NULL) CmdSendTrainToDepot(tile, flags, v->next_shared->index, p2);
if (v->vehstatus & VS_CRASHED) return return_value;
if (v->vehstatus & VS_CRASHED) return CMD_ERROR;
if (v->current_order.type == OT_GOTO_DEPOT) {
if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of depot orders
if (flags & DC_EXEC) {
if (HASBIT(p2, 1)) return 0; // Mass ordering goto depot should not turn goto depot orders off
if (HASBIT(v->current_order.flags, OFB_PART_OF_ORDERS)) {
v->u.rail.days_since_order_progr = 0;
v->cur_order_index++;
@ -1964,16 +1963,13 @@ int32 CmdSendTrainToDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
}
tfdd = FindClosestTrainDepot(v, 0);
if (tfdd.best_length == (uint)-1) {
if (HASBIT(p2, 1)) return 0; // Mass ordering goto depot should not return error
return_cmd_error(STR_883A_UNABLE_TO_FIND_ROUTE_TO);
}
if (tfdd.best_length == (uint)-1) return_cmd_error(STR_883A_UNABLE_TO_FIND_ROUTE_TO);
if (flags & DC_EXEC) {
v->dest_tile = tfdd.tile;
v->current_order.type = OT_GOTO_DEPOT;
v->current_order.flags = OF_NON_STOP;
if (!HASBIT(p2,0)) SETBIT(v->current_order.flags, OFB_HALT_IN_DEPOT);
if (!(p2 & DEPOT_SERVICE)) SETBIT(v->current_order.flags, OFB_HALT_IN_DEPOT);
v->current_order.dest.depot = GetDepotByTile(tfdd.tile)->index;
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
/* If there is no depot in front, reverse automatically */

View File

@ -1025,7 +1025,7 @@ static void TrainViewWndProc(Window *w, WindowEvent *e)
break;
case 7: /* goto depot */
/* TrainGotoDepot has a nice randomizer in the pathfinder, which causes desyncs... */
DoCommandP(v->tile, v->index, _ctrl_pressed ? 1 : 0, NULL, CMD_SEND_TRAIN_TO_DEPOT | CMD_NO_TEST_IF_IN_NETWORK | CMD_MSG(STR_8830_CAN_T_SEND_TRAIN_TO_DEPOT));
DoCommandP(v->tile, v->index, _ctrl_pressed ? DEPOT_SERVICE : 0, NULL, CMD_SEND_TRAIN_TO_DEPOT | CMD_NO_TEST_IF_IN_NETWORK | CMD_MSG(STR_8830_CAN_T_SEND_TRAIN_TO_DEPOT));
break;
case 8: /* force proceed */
DoCommandP(v->tile, v->index, 0, NULL, CMD_FORCE_TRAIN_PROCEED | CMD_MSG(STR_8862_CAN_T_MAKE_TRAIN_PASS_SIGNAL));
@ -1383,7 +1383,7 @@ static const Widget _player_trains_widgets[] = {
{ WWT_PANEL, RESIZE_RIGHT, 14, 248, 324, 14, 25, 0x0, STR_NULL},
{ WWT_MATRIX, RESIZE_RB, 14, 0, 312, 26, 207, 0x701, STR_883D_TRAINS_CLICK_ON_TRAIN_FOR},
{ WWT_SCROLLBAR, RESIZE_LRB, 14, 313, 324, 26, 207, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST},
{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 0, 156, 208, 219, STR_8815_NEW_VEHICLES, STR_883E_BUILD_NEW_TRAINS_REQUIRES},
{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 0, 156, 208, 219, STR_SEND_TO_DEPOTS, STR_SEND_TO_DEPOTS_TIP},
{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 157, 312, 208, 219, STR_REPLACE_VEHICLES, STR_REPLACE_HELP},
{ WWT_PANEL, RESIZE_RTB, 14, 313, 312, 208, 219, 0x0, STR_NULL},
{ WWT_RESIZEBOX, RESIZE_LRTB, 14, 313, 324, 208, 219, 0x0, STR_RESIZE_BUTTON},

View File

@ -1969,24 +1969,26 @@ uint GenerateVehicleSortList(const Vehicle** sort_list, byte type, PlayerID owne
* @param flags the flags used for DoCommand()
* @param service should the vehicles only get service in the depots
* @param owner PlayerID of owner of the vehicles to send
* @param VLW_flag tells what kind of list requested the goto depot
* @return 0 for success and CMD_ERROR if no vehicle is able to go to depot
*/
int32 SendAllVehiclesToDepot(byte type, uint32 flags, bool service, PlayerID owner)
int32 SendAllVehiclesToDepot(byte type, uint32 flags, bool service, PlayerID owner, uint16 vlw_flag, uint32 id)
{
const Vehicle** sort_list;
uint n, i;
sort_list = malloc(GetVehicleArraySize() * sizeof(sort_list[0]));
if (sort_list == NULL) {
error("Could not allocate memory for the vehicle-sorting-list");
error("Could not allocate memory for the vehicle-goto-depot-list");
}
n = GenerateVehicleSortList(sort_list, type, owner, INVALID_STATION, INVALID_ORDER, VLW_STANDARD);
n = GenerateVehicleSortList(sort_list, type, owner, (vlw_flag == VLW_STATION_LIST) ? id : INVALID_STATION, (vlw_flag == VLW_SHARED_ORDERS) ? id : INVALID_ORDER, vlw_flag);
/* Send all the vehicles to a depot */
for (i = 0; i < n; i++) {
const Vehicle *v = sort_list[i];
if (!DoCommand(v->tile, v->index, service, flags, CMD_SEND_TO_DEPOT(type)) && !(flags & DC_EXEC)) {
if (!DoCommand(v->tile, v->index, service | DEPOT_DONT_CANCEL, flags, CMD_SEND_TO_DEPOT(type)) && !(flags & DC_EXEC)) {
/* At least one vehicle is valid to send the command to, so the mass goto depot is valid. No need to check the rest */
free((void*)sort_list);
return 0;
}

View File

@ -315,7 +315,16 @@ int CheckTrainStoppedInDepot(const Vehicle *v);
bool VehicleNeedsService(const Vehicle *v);
uint GenerateVehicleSortList(const Vehicle** sort_list, byte type, PlayerID owner, StationID station, OrderID order, uint16 window_type);
int32 SendAllVehiclesToDepot(byte type, uint32 flags, bool service, PlayerID owner);
int32 SendAllVehiclesToDepot(byte type, uint32 flags, bool service, PlayerID owner, uint16 vlw_flag, uint32 id);
/* Flags to add to p2 for goto depot commands */
/* Note: bits 8-10 are used for VLW flags */
enum {
DEPOT_SERVICE = (1 << 0), // The vehicle will leave the depot right after arrival (serivce only)
DEPOT_MASS_SEND = (1 << 1), // Tells that it's a mass send to depot command (type in VLW flag)
DEPOT_DONT_CANCEL = (1 << 2), // Don't cancel current goto depot command if any
DEPOT_LOCATE_HANGAR = (1 << 3), // Find another airport if the target one lacks a hangar
};
typedef struct GetNewVehiclePosResult {
int x,y;

View File

@ -1188,17 +1188,9 @@ void PlayerVehWndProc(Window *w, WindowEvent *e)
SetDParam(0, w->vscroll.count);
w->widget[1].unkA = STR_VEH_WITH_SHARED_ORDERS_LIST;
if (owner != _local_player) break; // only set up buttons for local player
if (owner != _local_player) break; // only set up buttons for local player
w->widget[10].unkA = STR_EMPTY;
SETBIT(w->disabled_state, 10);
if (vehicle_type == VEH_Aircraft) {
w->widget[9].unkA = STR_SEND_TO_HANGARS;
w->widget[9].tooltips = STR_SEND_TO_HANGARS_TIP;
} else {
w->widget[9].unkA = STR_SEND_TO_DEPOTS;
w->widget[9].tooltips = STR_SEND_TO_DEPOTS_TIP;
}
break;
case VLW_STANDARD:
@ -1215,15 +1207,8 @@ void PlayerVehWndProc(Window *w, WindowEvent *e)
default: NOT_REACHED(); break;
}
if (owner != _local_player) break; // only set up buttons for local player
if (owner != _local_player) break; // only set up buttons for local player
if (vl->list_length == 0) SETBIT(w->disabled_state, 9);
if (vehicle_type == VEH_Aircraft) {
w->widget[9].unkA = STR_SEND_TO_HANGARS;
w->widget[9].tooltips = STR_SEND_TO_HANGARS_TIP;
} else {
w->widget[9].unkA = STR_SEND_TO_DEPOTS;
w->widget[9].tooltips = STR_SEND_TO_DEPOTS_TIP;
}
break;
case VLW_STATION_LIST:
@ -1237,6 +1222,8 @@ void PlayerVehWndProc(Window *w, WindowEvent *e)
case VEH_Aircraft: w->widget[1].unkA = STR_SCHEDULED_AIRCRAFT; break;
default: NOT_REACHED(); break;
}
if (owner != _local_player) break; // only set up buttons for local player
if (vl->list_length == 0) SETBIT(w->disabled_state, 9);
break;
default: NOT_REACHED(); break;
@ -1345,36 +1332,14 @@ void PlayerVehWndProc(Window *w, WindowEvent *e)
}
} break;
case 9: { /* Left button */
uint16 window_type = w->window_number & VLW_FLAGS;
case 9: // Left button
if (GB(w->window_number, 0, 8) /* OwnerID */ != _local_player) break;
switch (window_type) {
case VLW_STANDARD:
case VLW_SHARED_ORDERS: {
/* Send to depot */
const Vehicle *v;
assert(vl->list_length != 0);
v = vl->sort_list[0];
DoCommandP(v->tile, v->index, window_type | _ctrl_pressed ? 3 : 2, NULL, CMD_SEND_TO_DEPOT(vehicle_type));
break;
}
case VLW_STATION_LIST:
/* Build new Vehicle */
switch (vehicle_type) {
case VEH_Train: ShowBuildTrainWindow(0); break;
case VEH_Road: ShowBuildRoadVehWindow(0); break;
case VEH_Ship: ShowBuildShipWindow(0); break;
case VEH_Aircraft: ShowBuildAircraftWindow(0); break;
default: NOT_REACHED(); break;
}
break;
default: NOT_REACHED(); break;
}
assert(vl->list_length != 0);
DoCommandP(0, GB(w->window_number, 16, 16) /* StationID or OrderID (depending on VLW). Nomatter which one it is, it's needed here */,
(w->window_number & VLW_FLAGS) | DEPOT_MASS_SEND | (_ctrl_pressed ? DEPOT_SERVICE : 0), NULL, CMD_SEND_TO_DEPOT(vehicle_type));
break;
}
case 10: /* Right button */
case 10: // Right button
ShowReplaceVehicleWindow(vehicle_type);
break;
}

View File

@ -47,6 +47,11 @@ enum {
VLW_STATION_LIST = 2 << 8,
};
static inline bool ValidVLWFlags(uint16 flags)
{
return (flags == VLW_STANDARD || flags == VLW_SHARED_ORDERS || flags == VLW_STATION_LIST);
}
void PlayerVehWndProc(Window *w, WindowEvent *e);
void ShowReplaceVehicleWindow(byte vehicletype);