45 Order UnpackOldOrder(uint16 packed) |
45 Order UnpackOldOrder(uint16 packed) |
46 { |
46 { |
47 Order order; |
47 Order order; |
48 order.type = GB(packed, 0, 4); |
48 order.type = GB(packed, 0, 4); |
49 order.flags = GB(packed, 4, 4); |
49 order.flags = GB(packed, 4, 4); |
50 order.station = GB(packed, 8, 8); |
50 order.dest.station = GB(packed, 8, 8); |
51 order.next = NULL; |
51 order.next = NULL; |
52 |
52 |
53 // Sanity check |
53 // Sanity check |
54 // TTD stores invalid orders as OT_NOTHING with non-zero flags/station |
54 // TTD stores invalid orders as OT_NOTHING with non-zero flags/station |
55 if (order.type == OT_NOTHING && (order.flags != 0 || order.station != 0)) { |
55 if (order.type == OT_NOTHING && (order.flags != 0 || order.dest.station != 0)) { |
56 order.type = OT_DUMMY; |
56 order.type = OT_DUMMY; |
57 order.flags = 0; |
57 order.flags = 0; |
58 } |
58 } |
59 |
59 |
60 return order; |
60 return order; |
68 static Order UnpackVersion4Order(uint16 packed) |
68 static Order UnpackVersion4Order(uint16 packed) |
69 { |
69 { |
70 Order order; |
70 Order order; |
71 order.type = GB(packed, 0, 4); |
71 order.type = GB(packed, 0, 4); |
72 order.flags = GB(packed, 4, 4); |
72 order.flags = GB(packed, 4, 4); |
73 order.station = GB(packed, 8, 8); |
73 order.dest.station = GB(packed, 8, 8); |
74 order.next = NULL; |
74 order.next = NULL; |
75 order.index = 0; // avoid compiler warning |
75 order.index = 0; // avoid compiler warning |
76 return order; |
76 return order; |
77 } |
77 } |
78 |
78 |
189 * and has the correct flags if any */ |
189 * and has the correct flags if any */ |
190 switch (new_order.type) { |
190 switch (new_order.type) { |
191 case OT_GOTO_STATION: { |
191 case OT_GOTO_STATION: { |
192 const Station *st; |
192 const Station *st; |
193 |
193 |
194 if (!IsValidStationID(new_order.station)) return CMD_ERROR; |
194 if (!IsValidStationID(new_order.dest.station)) return CMD_ERROR; |
195 st = GetStation(new_order.station); |
195 st = GetStation(new_order.dest.station); |
196 |
196 |
197 if (st->airport_type != AT_OILRIG && !IsBuoy(st) && !CheckOwnership(st->owner)) { |
197 if (st->airport_type != AT_OILRIG && !IsBuoy(st) && !CheckOwnership(st->owner)) { |
198 return CMD_ERROR; |
198 return CMD_ERROR; |
199 } |
199 } |
200 |
200 |
250 |
250 |
251 case OT_GOTO_DEPOT: { |
251 case OT_GOTO_DEPOT: { |
252 if (v->type == VEH_Aircraft) { |
252 if (v->type == VEH_Aircraft) { |
253 const Station* st; |
253 const Station* st; |
254 |
254 |
255 if (!IsValidStationID(new_order.station)) return CMD_ERROR; |
255 if (!IsValidStationID(new_order.dest.station)) return CMD_ERROR; |
256 st = GetStation(new_order.station); |
256 st = GetStation(new_order.dest.station); |
257 |
257 |
258 if ((st->airport_type != AT_OILRIG && !CheckOwnership(st->owner)) || |
258 if ((st->airport_type != AT_OILRIG && !CheckOwnership(st->owner)) || |
259 !(st->facilities & FACIL_AIRPORT) || |
259 !(st->facilities & FACIL_AIRPORT) || |
260 GetAirport(st->airport_type)->nof_depots == 0) { |
260 GetAirport(st->airport_type)->nof_depots == 0) { |
261 return CMD_ERROR; |
261 return CMD_ERROR; |
262 } |
262 } |
263 } else { |
263 } else { |
264 const Depot* dp; |
264 const Depot* dp; |
265 |
265 |
266 if (!IsValidDepotID(new_order.station)) return CMD_ERROR; |
266 if (!IsValidDepotID(new_order.dest.depot)) return CMD_ERROR; |
267 dp = GetDepot(new_order.station); |
267 dp = GetDepot(new_order.dest.depot); |
268 |
268 |
269 if (!CheckOwnership(GetTileOwner(dp->xy))) return CMD_ERROR; |
269 if (!CheckOwnership(GetTileOwner(dp->xy))) return CMD_ERROR; |
270 |
270 |
271 switch (v->type) { |
271 switch (v->type) { |
272 case VEH_Train: |
272 case VEH_Train: |
306 case OT_GOTO_WAYPOINT: { |
306 case OT_GOTO_WAYPOINT: { |
307 const Waypoint* wp; |
307 const Waypoint* wp; |
308 |
308 |
309 if (v->type != VEH_Train) return CMD_ERROR; |
309 if (v->type != VEH_Train) return CMD_ERROR; |
310 |
310 |
311 if (!IsValidWaypointID(new_order.station)) return CMD_ERROR; |
311 if (!IsValidWaypointID(new_order.dest.waypoint)) return CMD_ERROR; |
312 wp = GetWaypoint(new_order.station); |
312 wp = GetWaypoint(new_order.dest.waypoint); |
313 |
313 |
314 if (!CheckOwnership(GetTileOwner(wp->xy))) return CMD_ERROR; |
314 if (!CheckOwnership(GetTileOwner(wp->xy))) return CMD_ERROR; |
315 |
315 |
316 /* Order flags can be any of the following for waypoints: |
316 /* Order flags can be any of the following for waypoints: |
317 * [non-stop] |
317 * [non-stop] |
344 if (v->type == VEH_Ship && IS_HUMAN_PLAYER(v->owner) && |
344 if (v->type == VEH_Ship && IS_HUMAN_PLAYER(v->owner) && |
345 sel_ord != 0 && GetVehicleOrder(v, sel_ord - 1)->type == OT_GOTO_STATION |
345 sel_ord != 0 && GetVehicleOrder(v, sel_ord - 1)->type == OT_GOTO_STATION |
346 && !_patches.new_pathfinding_all) { |
346 && !_patches.new_pathfinding_all) { |
347 |
347 |
348 int dist = DistanceManhattan( |
348 int dist = DistanceManhattan( |
349 GetStation(GetVehicleOrder(v, sel_ord - 1)->station)->xy, |
349 GetStation(GetVehicleOrder(v, sel_ord - 1)->dest.station)->xy, |
350 GetStation(new_order.station)->xy // XXX type != OT_GOTO_STATION? |
350 GetStation(new_order.dest.station)->xy // XXX type != OT_GOTO_STATION? |
351 ); |
351 ); |
352 if (dist >= 130) |
352 if (dist >= 130) |
353 return_cmd_error(STR_0210_TOO_FAR_FROM_PREVIOUS_DESTINATIO); |
353 return_cmd_error(STR_0210_TOO_FAR_FROM_PREVIOUS_DESTINATIO); |
354 } |
354 } |
355 |
355 |
702 const Order *order; |
702 const Order *order; |
703 TileIndex required_dst = INVALID_TILE; |
703 TileIndex required_dst = INVALID_TILE; |
704 |
704 |
705 FOR_VEHICLE_ORDERS(src, order) { |
705 FOR_VEHICLE_ORDERS(src, order) { |
706 if (order->type == OT_GOTO_STATION) { |
706 if (order->type == OT_GOTO_STATION) { |
707 const Station *st = GetStation(order->station); |
707 const Station *st = GetStation(order->dest.station); |
708 if (dst->cargo_type == CT_PASSENGERS) { |
708 if (dst->cargo_type == CT_PASSENGERS) { |
709 if (st->bus_stops != NULL) required_dst = st->bus_stops->xy; |
709 if (st->bus_stops != NULL) required_dst = st->bus_stops->xy; |
710 } else { |
710 } else { |
711 if (st->truck_stops != NULL) required_dst = st->truck_stops->xy; |
711 if (st->truck_stops != NULL) required_dst = st->truck_stops->xy; |
712 } |
712 } |
917 problem_type = 1; |
917 problem_type = 1; |
918 break; |
918 break; |
919 } |
919 } |
920 /* Does station have a load-bay for this vehicle? */ |
920 /* Does station have a load-bay for this vehicle? */ |
921 if (order->type == OT_GOTO_STATION) { |
921 if (order->type == OT_GOTO_STATION) { |
922 const Station* st = GetStation(order->station); |
922 const Station* st = GetStation(order->dest.station); |
923 TileIndex required_tile = GetStationTileForVehicle(v, st); |
923 TileIndex required_tile = GetStationTileForVehicle(v, st); |
924 |
924 |
925 n_st++; |
925 n_st++; |
926 if (required_tile == 0) problem_type = 3; |
926 if (required_tile == 0) problem_type = 3; |
927 } |
927 } |
931 if (v->num_orders > 1) { |
931 if (v->num_orders > 1) { |
932 const Order* last = GetLastVehicleOrder(v); |
932 const Order* last = GetLastVehicleOrder(v); |
933 |
933 |
934 if (v->orders->type == last->type && |
934 if (v->orders->type == last->type && |
935 v->orders->flags == last->flags && |
935 v->orders->flags == last->flags && |
936 v->orders->station == last->station) { |
936 v->orders->dest.station == last->dest.station) { |
937 problem_type = 2; |
937 problem_type = 2; |
938 } |
938 } |
939 } |
939 } |
940 |
940 |
941 /* Do we only have 1 station in our order list? */ |
941 /* Do we only have 1 station in our order list? */ |
960 /** |
960 /** |
961 * Removes an order from all vehicles. Triggers when, say, a station is removed. |
961 * Removes an order from all vehicles. Triggers when, say, a station is removed. |
962 * @param type The type of the order (OT_GOTO_[STATION|DEPOT|WAYPOINT]). |
962 * @param type The type of the order (OT_GOTO_[STATION|DEPOT|WAYPOINT]). |
963 * @param destination The destination. Can be a StationID, DepotID or WaypointID. |
963 * @param destination The destination. Can be a StationID, DepotID or WaypointID. |
964 */ |
964 */ |
965 void RemoveOrderFromAllVehicles(OrderType type, StationID destination) |
965 void RemoveOrderFromAllVehicles(OrderType type, DestinationID destination) |
966 { |
966 { |
967 Vehicle *v; |
967 Vehicle *v; |
968 Order *order; |
968 Order *order; |
969 bool need_invalidate; |
969 bool need_invalidate; |
970 |
970 |
971 /* Go through all vehicles */ |
971 /* Go through all vehicles */ |
972 FOR_ALL_VEHICLES(v) { |
972 FOR_ALL_VEHICLES(v) { |
973 if (v->orders == NULL) continue; |
973 if (v->orders == NULL) continue; |
974 |
974 |
975 /* Forget about this station if this station is removed */ |
975 /* Forget about this station if this station is removed */ |
976 if (v->last_station_visited == destination && type == OT_GOTO_STATION) |
976 if (v->last_station_visited == destination.station && type == OT_GOTO_STATION) |
977 v->last_station_visited = INVALID_STATION; |
977 v->last_station_visited = INVALID_STATION; |
978 |
978 |
979 /* Check the current order */ |
979 /* Check the current order */ |
980 if (v->current_order.type == type && v->current_order.station == destination) { |
980 if (v->current_order.type == type && v->current_order.dest.station == destination.station) { |
981 /* Mark the order as DUMMY */ |
981 /* Mark the order as DUMMY */ |
982 v->current_order.type = OT_DUMMY; |
982 v->current_order.type = OT_DUMMY; |
983 v->current_order.flags = 0; |
983 v->current_order.flags = 0; |
984 InvalidateWindow(WC_VEHICLE_VIEW, v->index); |
984 InvalidateWindow(WC_VEHICLE_VIEW, v->index); |
985 } |
985 } |
986 |
986 |
987 /* Clear the order from the order-list */ |
987 /* Clear the order from the order-list */ |
988 need_invalidate = false; |
988 need_invalidate = false; |
989 FOR_VEHICLE_ORDERS(v, order) { |
989 FOR_VEHICLE_ORDERS(v, order) { |
990 if (order->type == type && order->station == destination) { |
990 if (order->type == type && order->dest.station == destination.station) { |
991 /* Mark the order as DUMMY */ |
991 /* Mark the order as DUMMY */ |
992 order->type = OT_DUMMY; |
992 order->type = OT_DUMMY; |
993 order->flags = 0; |
993 order->flags = 0; |
994 |
994 |
995 need_invalidate = true; |
995 need_invalidate = true; |
1110 } |
1110 } |
1111 |
1111 |
1112 static const SaveLoad _order_desc[] = { |
1112 static const SaveLoad _order_desc[] = { |
1113 SLE_VAR(Order, type, SLE_UINT8), |
1113 SLE_VAR(Order, type, SLE_UINT8), |
1114 SLE_VAR(Order, flags, SLE_UINT8), |
1114 SLE_VAR(Order, flags, SLE_UINT8), |
1115 SLE_VAR(Order, station, SLE_UINT16), |
1115 SLE_VAR(Order, dest.station, SLE_UINT16), // Saving one of the union is enough, they all share the same memory |
1116 SLE_REF(Order, next, REF_ORDER), |
1116 SLE_REF(Order, next, REF_ORDER), |
1117 |
1117 |
1118 // reserve extra space in savegame here. (currently 10 bytes) |
1118 // reserve extra space in savegame here. (currently 10 bytes) |
1119 SLE_CONDNULL(10, 5, SL_MAX_VERSION), |
1119 SLE_CONDNULL(10, 5, SL_MAX_VERSION), |
1120 SLE_END() |
1120 SLE_END() |