93 return; |
93 return; |
94 |
94 |
95 if (v->vehstatus & VS_STOPPED) |
95 if (v->vehstatus & VS_STOPPED) |
96 return; |
96 return; |
97 |
97 |
98 if ((v->next_order & (OT_MASK | OF_FULL_LOAD)) == (OT_GOTO_DEPOT | OF_FULL_LOAD)) |
98 if (v->current_order.type == OT_GOTO_DEPOT && |
|
99 v->current_order.flags & OF_FULL_LOAD) |
99 return; |
100 return; |
100 |
101 |
101 if (_patches.gotodepot && ScheduleHasDepotOrders(v->schedule_ptr)) |
102 if (_patches.gotodepot && ScheduleHasDepotOrders(v->schedule_ptr)) |
102 return; |
103 return; |
103 |
104 |
104 i = FindClosestShipDepot(v); |
105 i = FindClosestShipDepot(v); |
105 |
106 |
106 if (i < 0 || GetTileDist(v->tile, (&_depots[i])->xy) > 12) { |
107 if (i < 0 || GetTileDist(v->tile, (&_depots[i])->xy) > 12) { |
107 if ((v->next_order & OT_MASK) == OT_GOTO_DEPOT) { |
108 if (v->current_order.type == OT_GOTO_DEPOT) { |
108 v->next_order = OT_DUMMY; |
109 v->current_order.type = OT_DUMMY; |
|
110 v->current_order.flags = 0; |
109 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4); |
111 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4); |
110 } |
112 } |
111 return; |
113 return; |
112 } |
114 } |
113 |
115 |
114 v->next_order = OT_GOTO_DEPOT | OF_NON_STOP; |
116 v->current_order.type = OT_GOTO_DEPOT; |
115 v->next_order_param = (byte)i; |
117 v->current_order.flags = OF_NON_STOP; |
|
118 v->current_order.station = (byte)i; |
116 v->dest_tile = (&_depots[i])->xy; |
119 v->dest_tile = (&_depots[i])->xy; |
117 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4); |
120 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4); |
118 } |
121 } |
119 |
122 |
120 void OnNewDay_Ship(Vehicle *v) |
123 void OnNewDay_Ship(Vehicle *v) |
197 TILE_XY(0,0), |
200 TILE_XY(0,0), |
198 }; |
201 }; |
199 |
202 |
200 static void ProcessShipOrder(Vehicle *v) |
203 static void ProcessShipOrder(Vehicle *v) |
201 { |
204 { |
202 uint order; |
205 Order order; |
203 Station *st; |
206 Station *st; |
204 |
207 |
205 if ((v->next_order & OT_MASK) >= OT_GOTO_DEPOT && (v->next_order & OT_MASK) <= OT_LEAVESTATION) { |
208 if (v->current_order.type >= OT_GOTO_DEPOT && |
206 if ((v->next_order & (OT_MASK|OF_UNLOAD)) != (OT_GOTO_DEPOT|OF_UNLOAD)) |
209 v->current_order.type <= OT_LEAVESTATION) { |
|
210 if (v->current_order.type != OT_GOTO_DEPOT || |
|
211 !(v->current_order.flags & OF_UNLOAD)) |
207 return; |
212 return; |
208 } |
213 } |
209 |
214 |
210 if ((v->next_order & (OT_MASK|OF_UNLOAD|OF_FULL_LOAD)) == (OT_GOTO_DEPOT|OF_UNLOAD|OF_FULL_LOAD) && |
215 if (v->current_order.type == OT_GOTO_DEPOT && |
|
216 (v->current_order.flags & (OF_UNLOAD | OF_FULL_LOAD)) == (OF_UNLOAD | OF_FULL_LOAD) && |
211 SERVICE_INTERVAL) { |
217 SERVICE_INTERVAL) { |
212 v->cur_order_index++; |
218 v->cur_order_index++; |
213 } |
219 } |
214 |
220 |
215 |
221 |
216 if (v->cur_order_index >= v->num_orders) |
222 if (v->cur_order_index >= v->num_orders) |
217 v->cur_order_index = 0; |
223 v->cur_order_index = 0; |
218 |
224 |
219 order = v->schedule_ptr[v->cur_order_index]; |
225 order = v->schedule_ptr[v->cur_order_index]; |
220 |
226 |
221 if (order == 0) { |
227 if (order.type == OT_NOTHING) { |
222 v->next_order = OT_NOTHING; |
228 v->current_order.type = OT_NOTHING; |
|
229 v->current_order.flags = 0; |
223 v->dest_tile = 0; |
230 v->dest_tile = 0; |
224 return; |
231 return; |
225 } |
232 } |
226 |
233 |
227 if (order == (uint)((v->next_order | (v->next_order_param<<8)))) |
234 if (order.type == v->current_order.type && |
228 return; |
235 order.flags == v->current_order.flags && |
229 |
236 order.station == v->current_order.station) |
230 v->next_order = (byte)order; |
237 return; |
231 v->next_order_param = (byte)(order >> 8); |
238 |
232 |
239 v->current_order = order; |
233 if ((order & OT_MASK) == OT_GOTO_STATION) { |
240 |
234 if ( (byte)(order >> 8) == v->last_station_visited) |
241 if (order.type == OT_GOTO_STATION) { |
|
242 if (order.station == v->last_station_visited) |
235 v->last_station_visited = 0xFF; |
243 v->last_station_visited = 0xFF; |
236 |
244 |
237 st = DEREF_STATION(order >> 8); |
245 st = DEREF_STATION(order.station); |
238 if (st->dock_tile != 0) { |
246 if (st->dock_tile != 0) { |
239 v->dest_tile = TILE_ADD(st->dock_tile, _dock_offs[_map5[st->dock_tile]-0x4B]); |
247 v->dest_tile = TILE_ADD(st->dock_tile, _dock_offs[_map5[st->dock_tile]-0x4B]); |
240 } |
248 } |
241 } else if ((order & OT_MASK) == OT_GOTO_DEPOT) { |
249 } else if (order.type == OT_GOTO_DEPOT) { |
242 v->dest_tile = _depots[order >> 8].xy; |
250 v->dest_tile = _depots[order.station].xy; |
243 } else { |
251 } else { |
244 v->dest_tile = 0; |
252 v->dest_tile = 0; |
245 } |
253 } |
246 InvalidateVehicleOrderWidget(v); |
254 InvalidateVehicleOrderWidget(v); |
247 } |
255 } |
248 |
256 |
249 static void HandleShipLoading(Vehicle *v) |
257 static void HandleShipLoading(Vehicle *v) |
250 { |
258 { |
251 if (v->next_order == OT_NOTHING) |
259 if (v->current_order.type == OT_NOTHING) |
252 return; |
260 return; |
253 |
261 |
254 if (v->next_order != OT_DUMMY) { |
262 if (v->current_order.type != OT_DUMMY) { |
255 if ((v->next_order&OT_MASK) != OT_LOADING) |
263 if (v->current_order.type != OT_LOADING) |
256 return; |
264 return; |
257 |
265 |
258 if (--v->load_unload_time_rem) |
266 if (--v->load_unload_time_rem) |
259 return; |
267 return; |
260 |
268 |
261 if (v->next_order&OF_FULL_LOAD && CanFillVehicle(v)) { |
269 if (v->current_order.flags & OF_FULL_LOAD && CanFillVehicle(v)) { |
262 SET_EXPENSES_TYPE(EXPENSES_SHIP_INC); |
270 SET_EXPENSES_TYPE(EXPENSES_SHIP_INC); |
263 if (LoadUnloadVehicle(v)) { |
271 if (LoadUnloadVehicle(v)) { |
264 InvalidateWindow(WC_SHIPS_LIST, v->owner); |
272 InvalidateWindow(WC_SHIPS_LIST, v->owner); |
265 MarkShipDirty(v); |
273 MarkShipDirty(v); |
266 } |
274 } |
267 return; |
275 return; |
268 } |
276 } |
269 PlayShipSound(v); |
277 PlayShipSound(v); |
270 |
278 |
271 { |
279 { |
272 byte b = v->next_order; |
280 Order b = v->current_order; |
273 v->next_order = OT_LEAVESTATION; |
281 v->current_order.type = OT_LEAVESTATION; |
274 if (!(b & OF_NON_STOP)) |
282 v->current_order.flags = 0; |
|
283 if (!(b.flags & OF_NON_STOP)) |
275 return; |
284 return; |
276 } |
285 } |
277 } |
286 } |
278 |
287 |
279 v->cur_order_index++; |
288 v->cur_order_index++; |
394 |
401 |
395 MaybeRenewVehicle(v, EstimateShipCost(v->engine_type)); |
402 MaybeRenewVehicle(v, EstimateShipCost(v->engine_type)); |
396 |
403 |
397 TriggerVehicle(v, VEHICLE_TRIGGER_DEPOT); |
404 TriggerVehicle(v, VEHICLE_TRIGGER_DEPOT); |
398 |
405 |
399 if ((v->next_order&OT_MASK) == OT_GOTO_DEPOT) { |
406 if (v->current_order.type == OT_GOTO_DEPOT) { |
|
407 Order t; |
|
408 |
400 InvalidateWindow(WC_VEHICLE_VIEW, v->index); |
409 InvalidateWindow(WC_VEHICLE_VIEW, v->index); |
401 |
410 |
402 t = v->next_order; |
411 t = v->current_order; |
403 v->next_order = OT_DUMMY; |
412 v->current_order.type = OT_DUMMY; |
404 |
413 v->current_order.flags = 0; |
405 if (t&OF_UNLOAD) { v->cur_order_index++; } |
414 |
406 |
415 if (t.flags & OF_UNLOAD) { |
407 else if (t & 0x40) { |
416 v->cur_order_index++; |
|
417 } else if (t.flags & OF_FULL_LOAD) { |
408 v->vehstatus |= VS_STOPPED; |
418 v->vehstatus |= VS_STOPPED; |
409 if (v->owner == _local_player) { |
419 if (v->owner == _local_player) { |
410 SetDParam(0, v->unitnumber); |
420 SetDParam(0, v->unitnumber); |
411 AddNewsItem( |
421 AddNewsItem( |
412 STR_981C_SHIP_IS_WAITING_IN_DEPOT, |
422 STR_981C_SHIP_IS_WAITING_IN_DEPOT, |
655 /* isnot inside depot */ |
665 /* isnot inside depot */ |
656 r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y); |
666 r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y); |
657 if (r & 0x8) goto reverse_direction; |
667 if (r & 0x8) goto reverse_direction; |
658 |
668 |
659 if (v->dest_tile != 0 && v->dest_tile == gp.new_tile) { |
669 if (v->dest_tile != 0 && v->dest_tile == gp.new_tile) { |
660 if ((v->next_order & OT_MASK) == OT_GOTO_DEPOT) { |
670 if (v->current_order.type == OT_GOTO_DEPOT) { |
661 if ((gp.x&0xF)==8 && (gp.y&0xF)==8) { |
671 if ((gp.x&0xF)==8 && (gp.y&0xF)==8) { |
662 ShipEnterDepot(v); |
672 ShipEnterDepot(v); |
663 return; |
673 return; |
664 } |
674 } |
665 } else if ((v->next_order & OT_MASK) == OT_GOTO_STATION) { |
675 } else if (v->current_order.type == OT_GOTO_STATION) { |
666 Station *st; |
676 Station *st; |
667 |
677 |
668 v->last_station_visited = v->next_order_param; |
678 v->last_station_visited = v->current_order.station; |
669 |
679 |
670 /* Process station in the schedule. Don't do that for buoys (HVOT_BUOY) */ |
680 /* Process station in the schedule. Don't do that for buoys (HVOT_BUOY) */ |
671 st = DEREF_STATION(v->next_order_param); |
681 st = DEREF_STATION(v->current_order.station); |
672 if (!(st->had_vehicle_of_type & HVOT_BUOY) |
682 if (!(st->had_vehicle_of_type & HVOT_BUOY) |
673 && (st->facilities & FACIL_DOCK)) { /* ugly, ugly workaround for problem with ships able to drop off cargo at wrong stations */ |
683 && (st->facilities & FACIL_DOCK)) { /* ugly, ugly workaround for problem with ships able to drop off cargo at wrong stations */ |
674 v->next_order = (v->next_order & (OF_FULL_LOAD|OF_UNLOAD)) | OF_NON_STOP | OT_LOADING; |
684 v->current_order.type = OT_LOADING; |
|
685 v->current_order.flags &= OF_FULL_LOAD | OF_UNLOAD; |
|
686 v->current_order.flags |= OF_NON_STOP; |
675 ShipArrivesAt(v, st); |
687 ShipArrivesAt(v, st); |
676 |
688 |
677 SET_EXPENSES_TYPE(EXPENSES_SHIP_INC); |
689 SET_EXPENSES_TYPE(EXPENSES_SHIP_INC); |
678 if (LoadUnloadVehicle(v)) { |
690 if (LoadUnloadVehicle(v)) { |
679 InvalidateWindow(WC_SHIPS_LIST, v->owner); |
691 InvalidateWindow(WC_SHIPS_LIST, v->owner); |
680 MarkShipDirty(v); |
692 MarkShipDirty(v); |
681 } |
693 } |
682 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4); |
694 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4); |
683 } else { /* leave buoys right aways */ |
695 } else { /* leave buoys right aways */ |
684 v->next_order = OT_LEAVESTATION; |
696 v->current_order.type = OT_LEAVESTATION; |
|
697 v->current_order.flags = 0; |
685 v->cur_order_index++; |
698 v->cur_order_index++; |
686 InvalidateVehicleOrderWidget(v); |
699 InvalidateVehicleOrderWidget(v); |
687 } |
700 } |
688 goto else_end; |
701 goto else_end; |
689 } |
702 } |
690 } |
703 } |
691 |
704 |
692 if (v->next_order == OT_LEAVESTATION) { |
705 if (v->current_order.type == OT_LEAVESTATION) { |
693 v->next_order = OT_NOTHING; |
706 v->current_order.type = OT_NOTHING; |
|
707 v->current_order.flags = 0; |
694 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4); |
708 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4); |
695 } |
709 } |
696 } |
710 } |
697 } else { |
711 } else { |
698 // new tile |
712 // new tile |
841 v->max_age = e->lifelength * 366; |
855 v->max_age = e->lifelength * 366; |
842 _new_ship_id = v->index; |
856 _new_ship_id = v->index; |
843 |
857 |
844 v->string_id = STR_SV_SHIP_NAME; |
858 v->string_id = STR_SV_SHIP_NAME; |
845 v->u.ship.state = 0x80; |
859 v->u.ship.state = 0x80; |
846 *(v->schedule_ptr = _ptr_to_next_order++) = 0; |
860 _ptr_to_next_order->type = OT_NOTHING; |
|
861 _ptr_to_next_order->flags = 0; |
|
862 v->schedule_ptr = _ptr_to_next_order++; |
847 |
863 |
848 v->service_interval = _patches.servint_ships; |
864 v->service_interval = _patches.servint_ships; |
849 v->date_of_last_service = _date; |
865 v->date_of_last_service = _date; |
850 v->build_year = _cur_year; |
866 v->build_year = _cur_year; |
851 v->cur_image = 0x0E5E; |
867 v->cur_image = 0x0E5E; |
915 v = &_vehicles[p1]; |
931 v = &_vehicles[p1]; |
916 |
932 |
917 if (!CheckOwnership(v->owner)) |
933 if (!CheckOwnership(v->owner)) |
918 return CMD_ERROR; |
934 return CMD_ERROR; |
919 |
935 |
920 if ((v->next_order&OT_MASK) == OT_GOTO_DEPOT) { |
936 if (v->current_order.type == OT_GOTO_DEPOT) { |
921 if (flags & DC_EXEC) { |
937 if (flags & DC_EXEC) { |
922 if (v->next_order&OF_UNLOAD) {v->cur_order_index++;} |
938 if (v->current_order.flags & OF_UNLOAD) v->cur_order_index++; |
923 v->next_order = OT_DUMMY; |
939 v->current_order.type = OT_DUMMY; |
|
940 v->current_order.flags = 0; |
924 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4); |
941 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4); |
925 } |
942 } |
926 } else { |
943 } else { |
927 depot = FindClosestShipDepot(v); |
944 depot = FindClosestShipDepot(v); |
928 if (depot < 0) |
945 if (depot < 0) |
929 return_cmd_error(STR_981A_UNABLE_TO_FIND_LOCAL_DEPOT); |
946 return_cmd_error(STR_981A_UNABLE_TO_FIND_LOCAL_DEPOT); |
930 |
947 |
931 if (flags & DC_EXEC) { |
948 if (flags & DC_EXEC) { |
932 v->dest_tile = _depots[depot].xy; |
949 v->dest_tile = _depots[depot].xy; |
933 v->next_order = OF_NON_STOP | OF_FULL_LOAD | OT_GOTO_DEPOT; |
950 v->current_order.type = OT_GOTO_DEPOT; |
934 v->next_order_param = depot; |
951 v->current_order.flags = OF_NON_STOP | OF_FULL_LOAD; |
|
952 v->current_order.station = depot; |
935 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4); |
953 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4); |
936 } |
954 } |
937 } |
955 } |
938 |
956 |
939 return 0; |
957 return 0; |