2082 } |
2082 } |
2083 |
2083 |
2084 return tfdd; |
2084 return tfdd; |
2085 } |
2085 } |
2086 |
2086 |
|
2087 bool Train::FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse) |
|
2088 { |
|
2089 TrainFindDepotData tfdd = FindClosestTrainDepot(this, 0); |
|
2090 if (tfdd.best_length == (uint)-1) return false; |
|
2091 |
|
2092 if (location != NULL) *location = tfdd.tile; |
|
2093 if (destination != NULL) *destination = GetDepotByTile(tfdd.tile)->index; |
|
2094 if (reverse != NULL) *reverse = tfdd.reverse; |
|
2095 |
|
2096 return true; |
|
2097 } |
|
2098 |
2087 /** Send a train to a depot |
2099 /** Send a train to a depot |
2088 * @param tile unused |
2100 * @param tile unused |
2089 * @param flags type of operation |
2101 * @param flags type of operation |
2090 * @param p1 train to send to the depot |
2102 * @param p1 train to send to the depot |
2091 * @param p2 various bitmasked elements |
2103 * @param p2 various bitmasked elements |
2102 |
2114 |
2103 if (!IsValidVehicleID(p1)) return CMD_ERROR; |
2115 if (!IsValidVehicleID(p1)) return CMD_ERROR; |
2104 |
2116 |
2105 Vehicle *v = GetVehicle(p1); |
2117 Vehicle *v = GetVehicle(p1); |
2106 |
2118 |
2107 if (v->type != VEH_TRAIN || !CheckOwnership(v->owner)) return CMD_ERROR; |
2119 if (v->type != VEH_TRAIN) return CMD_ERROR; |
2108 |
2120 |
2109 if (v->vehstatus & VS_CRASHED) return CMD_ERROR; |
2121 return v->SendToDepot(flags, (DepotCommand)(p2 & DEPOT_COMMAND_MASK)); |
2110 |
|
2111 if (v->current_order.IsType(OT_GOTO_DEPOT)) { |
|
2112 bool halt_in_depot = v->current_order.GetDepotActionType() & ODATFB_HALT; |
|
2113 if (!!(p2 & DEPOT_SERVICE) == halt_in_depot) { |
|
2114 /* We called with a different DEPOT_SERVICE setting. |
|
2115 * Now we change the setting to apply the new one and let the vehicle head for the same depot. |
|
2116 * Note: the if is (true for requesting service == true for ordered to stop in depot) */ |
|
2117 if (flags & DC_EXEC) { |
|
2118 v->current_order.SetDepotOrderType(ODTF_MANUAL); |
|
2119 v->current_order.SetDepotActionType(halt_in_depot ? ODATF_SERVICE_ONLY : ODATFB_HALT); |
|
2120 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH); |
|
2121 } |
|
2122 return CommandCost(); |
|
2123 } |
|
2124 |
|
2125 if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of depot orders |
|
2126 if (flags & DC_EXEC) { |
|
2127 /* If the orders to 'goto depot' are in the orders list (forced servicing), |
|
2128 * then skip to the next order; effectively cancelling this forced service */ |
|
2129 if (v->current_order.GetDepotOrderType() & ODTFB_PART_OF_ORDERS) v->cur_order_index++; |
|
2130 |
|
2131 v->current_order.MakeDummy(); |
|
2132 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH); |
|
2133 } |
|
2134 return CommandCost(); |
|
2135 } |
|
2136 |
|
2137 /* check if at a standstill (not stopped only) in a depot |
|
2138 * the check is down here to make it possible to alter stop/service for trains entering the depot */ |
|
2139 if (IsTileDepotType(v->tile, TRANSPORT_RAIL) && v->cur_speed == 0) return CMD_ERROR; |
|
2140 |
|
2141 TrainFindDepotData tfdd = FindClosestTrainDepot(v, 0); |
|
2142 if (tfdd.best_length == (uint)-1) return_cmd_error(STR_883A_UNABLE_TO_FIND_ROUTE_TO); |
|
2143 |
|
2144 if (flags & DC_EXEC) { |
|
2145 if (v->current_order.IsType(OT_LOADING)) v->LeaveStation(); |
|
2146 |
|
2147 v->dest_tile = tfdd.tile; |
|
2148 v->current_order.MakeGoToDepot(GetDepotByTile(tfdd.tile)->index, ODTF_MANUAL); |
|
2149 if (!(p2 & DEPOT_SERVICE)) v->current_order.SetDepotActionType(ODATFB_HALT); |
|
2150 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH); |
|
2151 /* If there is no depot in front, reverse automatically */ |
|
2152 if (tfdd.reverse) DoCommand(v->tile, v->index, 0, DC_EXEC, CMD_REVERSE_TRAIN_DIRECTION); |
|
2153 } |
|
2154 |
|
2155 return CommandCost(); |
|
2156 } |
2122 } |
2157 |
2123 |
2158 |
2124 |
2159 void OnTick_Train() |
2125 void OnTick_Train() |
2160 { |
2126 { |