38 TRACK_BIT_Y | TRACK_BIT_LOWER | TRACK_BIT_RIGHT, // 0x2A, // DIAGDIR_NW |
41 TRACK_BIT_Y | TRACK_BIT_LOWER | TRACK_BIT_RIGHT, // 0x2A, // DIAGDIR_NW |
39 }; |
42 }; |
40 |
43 |
41 static TrackBits GetTileShipTrackStatus(TileIndex tile) |
44 static TrackBits GetTileShipTrackStatus(TileIndex tile) |
42 { |
45 { |
43 uint32 r = GetTileTrackStatus(tile, TRANSPORT_WATER); |
46 uint32 r = GetTileTrackStatus(tile, TRANSPORT_WATER, 0); |
44 return TrackdirBitsToTrackBits((TrackdirBits)(TRACKDIR_BIT_MASK & (r | r >> 8))); |
47 return TrackdirBitsToTrackBits((TrackdirBits)(TRACKDIR_BIT_MASK & (r | r >> 8))); |
45 } |
48 } |
46 |
49 |
47 void DrawShipEngine(int x, int y, EngineID engine, SpriteID pal) |
50 void DrawShipEngine(int x, int y, EngineID engine, SpriteID pal) |
48 { |
51 { |
60 DrawSprite(6 + _ship_sprites[spritenum], pal, x, y); |
63 DrawSprite(6 + _ship_sprites[spritenum], pal, x, y); |
61 } |
64 } |
62 |
65 |
63 /** Get the size of the sprite of a ship sprite heading west (used for lists) |
66 /** Get the size of the sprite of a ship sprite heading west (used for lists) |
64 * @param engine The engine to get the sprite from |
67 * @param engine The engine to get the sprite from |
65 * @param &width The width of the sprite |
68 * @param width The width of the sprite |
66 * @param &height The height of the sprite |
69 * @param height The height of the sprite |
67 */ |
70 */ |
68 void GetShipSpriteSize(EngineID engine, uint &width, uint &height) |
71 void GetShipSpriteSize(EngineID engine, uint &width, uint &height) |
69 { |
72 { |
70 SpriteID spritenum = ShipVehInfo(engine)->image_index; |
73 SpriteID spritenum = ShipVehInfo(engine)->image_index; |
71 SpriteID custom_sprite = 0; |
74 SpriteID custom_sprite = 0; |
109 TileIndex tile2 = v->tile; |
112 TileIndex tile2 = v->tile; |
110 |
113 |
111 if (_patches.new_pathfinding_all) { |
114 if (_patches.new_pathfinding_all) { |
112 NPFFoundTargetData ftd; |
115 NPFFoundTargetData ftd; |
113 Trackdir trackdir = GetVehicleTrackdir(v); |
116 Trackdir trackdir = GetVehicleTrackdir(v); |
114 ftd = NPFRouteToDepotTrialError(v->tile, trackdir, TRANSPORT_WATER, v->owner, INVALID_RAILTYPE); |
117 ftd = NPFRouteToDepotTrialError(v->tile, trackdir, TRANSPORT_WATER, 0, v->owner, INVALID_RAILTYPE); |
115 if (ftd.best_bird_dist == 0) { |
118 if (ftd.best_bird_dist == 0) { |
116 best_depot = GetDepotByTile(ftd.node.tile); /* Found target */ |
119 best_depot = GetDepotByTile(ftd.node.tile); /* Found target */ |
117 } else { |
120 } else { |
118 best_depot = NULL; /* Did not find target */ |
121 best_depot = NULL; /* Did not find target */ |
119 } |
122 } |
160 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); |
163 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); |
161 } |
164 } |
162 return; |
165 return; |
163 } |
166 } |
164 |
167 |
|
168 if (v->current_order.type == OT_LOADING) v->LeaveStation(); |
165 v->current_order.type = OT_GOTO_DEPOT; |
169 v->current_order.type = OT_GOTO_DEPOT; |
166 v->current_order.flags = OF_NON_STOP; |
170 v->current_order.flags = OF_NON_STOP; |
167 v->current_order.dest = depot->index; |
171 v->current_order.dest = depot->index; |
168 v->dest_tile = depot->xy; |
172 v->dest_tile = depot->xy; |
169 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); |
173 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); |
182 |
186 |
183 CheckOrders(v); |
187 CheckOrders(v); |
184 |
188 |
185 if (v->vehstatus & VS_STOPPED) return; |
189 if (v->vehstatus & VS_STOPPED) return; |
186 |
190 |
187 cost = ShipVehInfo(v->engine_type)->running_cost * _price.ship_running / 364; |
191 cost = GetVehicleProperty(v, 0x0F, ShipVehInfo(v->engine_type)->running_cost) * _price.ship_running / 364; |
188 v->profit_this_year -= cost >> 8; |
192 v->profit_this_year -= cost >> 8; |
189 |
193 |
190 SET_EXPENSES_TYPE(EXPENSES_SHIP_RUN); |
194 SET_EXPENSES_TYPE(EXPENSES_SHIP_RUN); |
191 SubtractMoneyFromPlayerFract(v->owner, cost); |
195 SubtractMoneyFromPlayerFract(v->owner, cost); |
192 |
196 |
193 InvalidateWindow(WC_VEHICLE_DETAILS, v->index); |
197 InvalidateWindow(WC_VEHICLE_DETAILS, v->index); |
194 //we need this for the profit |
198 /* we need this for the profit */ |
195 InvalidateWindowClasses(WC_SHIPS_LIST); |
199 InvalidateWindowClasses(WC_SHIPS_LIST); |
196 } |
200 } |
197 |
201 |
198 static void HandleBrokenShip(Vehicle *v) |
202 static void HandleBrokenShip(Vehicle *v) |
199 { |
203 { |
224 InvalidateWindow(WC_VEHICLE_VIEW, v->index); |
228 InvalidateWindow(WC_VEHICLE_VIEW, v->index); |
225 } |
229 } |
226 } |
230 } |
227 } |
231 } |
228 |
232 |
229 static void MarkShipDirty(Vehicle *v) |
233 void Ship::MarkDirty() |
230 { |
234 { |
231 v->cur_image = GetShipImage(v, v->direction); |
235 this->cur_image = GetShipImage(this, this->direction); |
232 MarkAllViewportsDirty(v->left_coord, v->top_coord, v->right_coord + 1, v->bottom_coord + 1); |
236 MarkAllViewportsDirty(this->left_coord, this->top_coord, this->right_coord + 1, this->bottom_coord + 1); |
233 } |
237 } |
234 |
238 |
235 static void PlayShipSound(Vehicle *v) |
239 static void PlayShipSound(const Vehicle *v) |
236 { |
240 { |
237 if (!PlayVehicleSound(v, VSE_START)) { |
241 if (!PlayVehicleSound(v, VSE_START)) { |
238 SndPlayVehicleFx(ShipVehInfo(v->engine_type)->sfx, v); |
242 SndPlayVehicleFx(ShipVehInfo(v->engine_type)->sfx, v); |
239 } |
243 } |
|
244 } |
|
245 |
|
246 void Ship::PlayLeaveStationSound() const |
|
247 { |
|
248 PlayShipSound(this); |
240 } |
249 } |
241 |
250 |
242 static void ProcessShipOrder(Vehicle *v) |
251 static void ProcessShipOrder(Vehicle *v) |
243 { |
252 { |
244 const Order *order; |
253 const Order *order; |
295 InvalidateVehicleOrder(v); |
304 InvalidateVehicleOrder(v); |
296 |
305 |
297 InvalidateWindowClasses(WC_SHIPS_LIST); |
306 InvalidateWindowClasses(WC_SHIPS_LIST); |
298 } |
307 } |
299 |
308 |
300 static void HandleShipLoading(Vehicle *v) |
309 void Ship::UpdateDeltaXY(Direction direction) |
301 { |
310 { |
302 switch (v->current_order.type) { |
311 #define MKIT(a, b, c, d) ((a & 0xFF) << 24) | ((b & 0xFF) << 16) | ((c & 0xFF) << 8) | ((d & 0xFF) << 0) |
303 case OT_LOADING: { |
|
304 if (--v->load_unload_time_rem) return; |
|
305 |
|
306 if (CanFillVehicle(v) && ( |
|
307 v->current_order.flags & OF_FULL_LOAD || |
|
308 (_patches.gradual_loading && !HASBIT(v->vehicle_flags, VF_LOADING_FINISHED)) |
|
309 )) { |
|
310 SET_EXPENSES_TYPE(EXPENSES_SHIP_INC); |
|
311 if (LoadUnloadVehicle(v, false)) { |
|
312 InvalidateWindow(WC_SHIPS_LIST, v->owner); |
|
313 MarkShipDirty(v); |
|
314 } |
|
315 return; |
|
316 } |
|
317 PlayShipSound(v); |
|
318 |
|
319 Order b = v->current_order; |
|
320 v->LeaveStation(); |
|
321 if (!(b.flags & OF_NON_STOP)) return; |
|
322 break; |
|
323 } |
|
324 |
|
325 case OT_DUMMY: break; |
|
326 |
|
327 default: return; |
|
328 } |
|
329 |
|
330 v->cur_order_index++; |
|
331 InvalidateVehicleOrder(v); |
|
332 } |
|
333 |
|
334 static void UpdateShipDeltaXY(Vehicle *v, int dir) |
|
335 { |
|
336 #define MKIT(d,c,b,a) ((a&0xFF)<<24) | ((b&0xFF)<<16) | ((c&0xFF)<<8) | ((d&0xFF)<<0) |
|
337 static const uint32 _delta_xy_table[8] = { |
312 static const uint32 _delta_xy_table[8] = { |
338 MKIT( -3, -3, 6, 6), |
313 MKIT( 6, 6, -3, -3), |
339 MKIT(-16, -3, 32, 6), |
314 MKIT( 6, 32, -3, -16), |
340 MKIT( -3, -3, 6, 6), |
315 MKIT( 6, 6, -3, -3), |
341 MKIT( -3, -16, 6, 32), |
316 MKIT(32, 6, -16, -3), |
342 MKIT( -3, -3, 6, 6), |
317 MKIT( 6, 6, -3, -3), |
343 MKIT(-16, -3, 32, 6), |
318 MKIT( 6, 32, -3, -16), |
344 MKIT( -3, -3, 6, 6), |
319 MKIT( 6, 6, -3, -3), |
345 MKIT( -3, -16, 6, 32), |
320 MKIT(32, 6, -16, -3), |
346 }; |
321 }; |
347 #undef MKIT |
322 #undef MKIT |
348 uint32 x = _delta_xy_table[dir]; |
323 |
349 v->x_offs = GB(x, 0, 8); |
324 uint32 x = _delta_xy_table[direction]; |
350 v->y_offs = GB(x, 8, 8); |
325 this->x_offs = GB(x, 0, 8); |
351 v->sprite_width = GB(x, 16, 8); |
326 this->y_offs = GB(x, 8, 8); |
352 v->sprite_height = GB(x, 24, 8); |
327 this->sprite_width = GB(x, 16, 8); |
|
328 this->sprite_height = GB(x, 24, 8); |
|
329 this->z_height = 6; |
353 } |
330 } |
354 |
331 |
355 void RecalcShipStuff(Vehicle *v) |
332 void RecalcShipStuff(Vehicle *v) |
356 { |
333 { |
357 UpdateShipDeltaXY(v, v->direction); |
334 v->UpdateDeltaXY(v->direction); |
358 v->cur_image = GetShipImage(v, v->direction); |
335 v->cur_image = GetShipImage(v, v->direction); |
359 MarkShipDirty(v); |
336 v->MarkDirty(); |
360 InvalidateWindow(WC_VEHICLE_DEPOT, v->tile); |
337 InvalidateWindow(WC_VEHICLE_DEPOT, v->tile); |
361 } |
338 } |
362 |
339 |
363 static const TileIndexDiffC _ship_leave_depot_offs[] = { |
340 static const TileIndexDiffC _ship_leave_depot_offs[] = { |
364 {-1, 0}, |
341 {-1, 0}, |
374 if (!IsShipInDepot(v)) return; |
351 if (!IsShipInDepot(v)) return; |
375 |
352 |
376 tile = v->tile; |
353 tile = v->tile; |
377 axis = GetShipDepotAxis(tile); |
354 axis = GetShipDepotAxis(tile); |
378 |
355 |
379 // Check first side |
356 /* Check first side */ |
380 if (_ship_sometracks[axis] & GetTileShipTrackStatus(TILE_ADD(tile, ToTileIndexDiff(_ship_leave_depot_offs[axis])))) { |
357 if (_ship_sometracks[axis] & GetTileShipTrackStatus(TILE_ADD(tile, ToTileIndexDiff(_ship_leave_depot_offs[axis])))) { |
381 m = (axis == AXIS_X) ? 0x101 : 0x207; |
358 m = (axis == AXIS_X) ? 0x101 : 0x207; |
382 // Check second side |
359 /* Check second side */ |
383 } else if (_ship_sometracks[axis + 2] & GetTileShipTrackStatus(TILE_ADD(tile, -2 * ToTileIndexDiff(_ship_leave_depot_offs[axis])))) { |
360 } else if (_ship_sometracks[axis + 2] & GetTileShipTrackStatus(TILE_ADD(tile, -2 * ToTileIndexDiff(_ship_leave_depot_offs[axis])))) { |
384 m = (axis == AXIS_X) ? 0x105 : 0x203; |
361 m = (axis == AXIS_X) ? 0x105 : 0x203; |
385 } else { |
362 } else { |
386 return; |
363 return; |
387 } |
364 } |
401 static bool ShipAccelerate(Vehicle *v) |
378 static bool ShipAccelerate(Vehicle *v) |
402 { |
379 { |
403 uint spd; |
380 uint spd; |
404 byte t; |
381 byte t; |
405 |
382 |
406 spd = min(v->cur_speed + 1, v->max_speed); |
383 spd = min(v->cur_speed + 1, GetVehicleProperty(v, 0x0B, v->max_speed)); |
407 |
384 |
408 //updates statusbar only if speed have changed to save CPU time |
385 /*updates statusbar only if speed have changed to save CPU time */ |
409 if (spd != v->cur_speed) { |
386 if (spd != v->cur_speed) { |
410 v->cur_speed = spd; |
387 v->cur_speed = spd; |
411 if (_patches.vehicle_speed) |
388 if (_patches.vehicle_speed) |
412 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); |
389 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); |
413 } |
390 } |
414 |
391 |
415 // Decrease somewhat when turning |
392 /* Decrease somewhat when turning */ |
416 if (!(v->direction & 1)) spd = spd * 3 / 4; |
393 if (!(v->direction & 1)) spd = spd * 3 / 4; |
417 |
394 |
418 if (spd == 0) return false; |
395 if (spd == 0) return false; |
419 if ((byte)++spd == 0) return true; |
396 if ((byte)++spd == 0) return true; |
420 |
397 |
453 uint best_length; |
430 uint best_length; |
454 }; |
431 }; |
455 |
432 |
456 static bool ShipTrackFollower(TileIndex tile, PathFindShip *pfs, int track, uint length, byte *state) |
433 static bool ShipTrackFollower(TileIndex tile, PathFindShip *pfs, int track, uint length, byte *state) |
457 { |
434 { |
458 // Found dest? |
435 /* Found dest? */ |
459 if (tile == pfs->dest_coords) { |
436 if (tile == pfs->dest_coords) { |
460 pfs->best_bird_dist = 0; |
437 pfs->best_bird_dist = 0; |
461 |
438 |
462 pfs->best_length = minu(pfs->best_length, length); |
439 pfs->best_length = minu(pfs->best_length, length); |
463 return true; |
440 return true; |
464 } |
441 } |
465 |
442 |
466 // Skip this tile in the calculation |
443 /* Skip this tile in the calculation */ |
467 if (tile != pfs->skiptile) { |
444 if (tile != pfs->skiptile) { |
468 pfs->best_bird_dist = minu(pfs->best_bird_dist, DistanceMaxPlusManhattan(pfs->dest_coords, tile)); |
445 pfs->best_bird_dist = minu(pfs->best_bird_dist, DistanceMaxPlusManhattan(pfs->dest_coords, tile)); |
469 } |
446 } |
470 |
447 |
471 return false; |
448 return false; |
500 i = RemoveFirstTrack(&bits); |
477 i = RemoveFirstTrack(&bits); |
501 |
478 |
502 pfs.best_bird_dist = (uint)-1; |
479 pfs.best_bird_dist = (uint)-1; |
503 pfs.best_length = (uint)-1; |
480 pfs.best_length = (uint)-1; |
504 |
481 |
505 FollowTrack(tile, 0x3800 | TRANSPORT_WATER, (DiagDirection)_ship_search_directions[i][dir], (TPFEnumProc*)ShipTrackFollower, NULL, &pfs); |
482 FollowTrack(tile, 0x3800 | TRANSPORT_WATER, 0, (DiagDirection)_ship_search_directions[i][dir], (TPFEnumProc*)ShipTrackFollower, NULL, &pfs); |
506 |
483 |
507 if (best_track != INVALID_TRACK) { |
484 if (best_track != INVALID_TRACK) { |
508 if (pfs.best_bird_dist != 0) { |
485 if (pfs.best_bird_dist != 0) { |
509 /* neither reached the destination, pick the one with the smallest bird dist */ |
486 /* neither reached the destination, pick the one with the smallest bird dist */ |
510 if (pfs.best_bird_dist > best_bird_dist) goto bad; |
487 if (pfs.best_bird_dist > best_bird_dist) goto bad; |
535 |
512 |
536 static inline NPFFoundTargetData PerfNPFRouteToStationOrTile(TileIndex tile, Trackdir trackdir, NPFFindStationOrTileData* target, TransportType type, Owner owner, RailTypeMask railtypes) |
513 static inline NPFFoundTargetData PerfNPFRouteToStationOrTile(TileIndex tile, Trackdir trackdir, NPFFindStationOrTileData* target, TransportType type, Owner owner, RailTypeMask railtypes) |
537 { |
514 { |
538 |
515 |
539 void* perf = NpfBeginInterval(); |
516 void* perf = NpfBeginInterval(); |
540 NPFFoundTargetData ret = NPFRouteToStationOrTile(tile, trackdir, target, type, owner, railtypes); |
517 NPFFoundTargetData ret = NPFRouteToStationOrTile(tile, trackdir, target, type, 0, owner, railtypes); |
541 int t = NpfEndInterval(perf); |
518 int t = NpfEndInterval(perf); |
542 DEBUG(yapf, 4, "[NPFW] %d us - %d rounds - %d open - %d closed -- ", t, 0, _aystar_stats_open_size, _aystar_stats_closed_size); |
519 DEBUG(yapf, 4, "[NPFW] %d us - %d rounds - %d open - %d closed -- ", t, 0, _aystar_stats_open_size, _aystar_stats_closed_size); |
543 return ret; |
520 return ret; |
544 } |
521 } |
545 |
522 |
546 /* returns the track to choose on the next tile, or -1 when it's better to |
523 /** returns the track to choose on the next tile, or -1 when it's better to |
547 * reverse. The tile given is the tile we are about to enter, enterdir is the |
524 * reverse. The tile given is the tile we are about to enter, enterdir is the |
548 * direction in which we are entering the tile */ |
525 * direction in which we are entering the tile */ |
549 static Track ChooseShipTrack(Vehicle *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks) |
526 static Track ChooseShipTrack(Vehicle *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks) |
550 { |
527 { |
551 assert(enterdir>=0 && enterdir<=3); |
528 assert(enterdir >= 0 && enterdir <= 3); |
552 |
529 |
553 if (_patches.yapf.ship_use_yapf) { |
530 if (_patches.yapf.ship_use_yapf) { |
554 Trackdir trackdir = YapfChooseShipTrack(v, tile, enterdir, tracks); |
531 Trackdir trackdir = YapfChooseShipTrack(v, tile, enterdir, tracks); |
555 return (trackdir != INVALID_TRACKDIR) ? TrackdirToTrack(trackdir) : INVALID_TRACK; |
532 return (trackdir != INVALID_TRACKDIR) ? TrackdirToTrack(trackdir) : INVALID_TRACK; |
556 } else if (_patches.new_pathfinding_all) { |
533 } else if (_patches.new_pathfinding_all) { |
557 NPFFindStationOrTileData fstd; |
534 NPFFindStationOrTileData fstd; |
558 NPFFoundTargetData ftd; |
535 NPFFoundTargetData ftd; |
559 TileIndex src_tile = TILE_ADD(tile, TileOffsByDiagDir(ReverseDiagDir(enterdir))); |
536 TileIndex src_tile = TILE_ADD(tile, TileOffsByDiagDir(ReverseDiagDir(enterdir))); |
560 Trackdir trackdir = GetVehicleTrackdir(v); |
537 Trackdir trackdir = GetVehicleTrackdir(v); |
561 assert(trackdir != INVALID_TRACKDIR); /* Check that we are not in a depot */ |
538 assert(trackdir != INVALID_TRACKDIR); // Check that we are not in a depot |
562 |
539 |
563 NPFFillWithOrderData(&fstd, v); |
540 NPFFillWithOrderData(&fstd, v); |
564 |
541 |
565 ftd = PerfNPFRouteToStationOrTile(src_tile, trackdir, &fstd, TRANSPORT_WATER, v->owner, INVALID_RAILTYPE); |
542 ftd = PerfNPFRouteToStationOrTile(src_tile, trackdir, &fstd, TRANSPORT_WATER, v->owner, INVALID_RAILTYPE); |
566 |
543 |
729 |
706 |
730 v->last_station_visited = v->current_order.dest; |
707 v->last_station_visited = v->current_order.dest; |
731 |
708 |
732 /* Process station in the orderlist. */ |
709 /* Process station in the orderlist. */ |
733 st = GetStation(v->current_order.dest); |
710 st = GetStation(v->current_order.dest); |
734 if (st->facilities & FACIL_DOCK) { /* ugly, ugly workaround for problem with ships able to drop off cargo at wrong stations */ |
711 if (st->facilities & FACIL_DOCK) { // ugly, ugly workaround for problem with ships able to drop off cargo at wrong stations |
|
712 ShipArrivesAt(v, st); |
735 v->BeginLoading(); |
713 v->BeginLoading(); |
736 v->current_order.flags &= OF_FULL_LOAD | OF_UNLOAD | OF_TRANSFER; |
714 } else { // leave stations without docks right aways |
737 v->current_order.flags |= OF_NON_STOP; |
|
738 ShipArrivesAt(v, st); |
|
739 |
|
740 SET_EXPENSES_TYPE(EXPENSES_SHIP_INC); |
|
741 if (LoadUnloadVehicle(v, true)) { |
|
742 InvalidateWindow(WC_SHIPS_LIST, v->owner); |
|
743 MarkShipDirty(v); |
|
744 } |
|
745 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); |
|
746 } else { /* leave stations without docks right aways */ |
|
747 v->current_order.type = OT_LEAVESTATION; |
715 v->current_order.type = OT_LEAVESTATION; |
748 v->cur_order_index++; |
716 v->cur_order_index++; |
749 InvalidateVehicleOrder(v); |
717 InvalidateVehicleOrder(v); |
750 } |
718 } |
751 } |
719 } |
832 } |
800 } |
833 } |
801 } |
834 |
802 |
835 /** Build a ship. |
803 /** Build a ship. |
836 * @param tile tile of depot where ship is built |
804 * @param tile tile of depot where ship is built |
|
805 * @param flags type of operation |
837 * @param p1 ship type being built (engine) |
806 * @param p1 ship type being built (engine) |
838 * @param p2 bit 0 when set, the unitnumber will be 0, otherwise it will be a free number |
807 * @param p2 bit 0 when set, the unitnumber will be 0, otherwise it will be a free number |
839 */ |
808 */ |
840 int32 CmdBuildShip(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
809 int32 CmdBuildShip(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
841 { |
810 { |
842 int32 value; |
811 int32 value; |
843 Vehicle *v; |
812 Vehicle *v; |
844 UnitID unit_num; |
813 UnitID unit_num; |
845 Engine *e; |
814 Engine *e; |
846 |
815 |
847 if (!IsEngineBuildable(p1, VEH_SHIP, _current_player)) return_cmd_error(STR_ENGINE_NOT_BUILDABLE); |
816 if (!IsEngineBuildable(p1, VEH_SHIP, _current_player)) return_cmd_error(STR_SHIP_NOT_AVAILABLE); |
848 |
817 |
849 SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES); |
818 SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES); |
850 |
819 |
851 value = EstimateShipCost(p1); |
820 value = EstimateShipCost(p1); |
852 if (flags & DC_QUERY_COST) return value; |
821 if (flags & DC_QUERY_COST) return value; |
874 v->tile = tile; |
843 v->tile = tile; |
875 x = TileX(tile) * TILE_SIZE + TILE_SIZE / 2; |
844 x = TileX(tile) * TILE_SIZE + TILE_SIZE / 2; |
876 y = TileY(tile) * TILE_SIZE + TILE_SIZE / 2; |
845 y = TileY(tile) * TILE_SIZE + TILE_SIZE / 2; |
877 v->x_pos = x; |
846 v->x_pos = x; |
878 v->y_pos = y; |
847 v->y_pos = y; |
879 v->z_pos = GetSlopeZ(x,y); |
848 v->z_pos = GetSlopeZ(x, y); |
880 |
849 |
881 v->z_height = 6; |
850 v->UpdateDeltaXY(v->direction); |
882 v->sprite_width = 6; |
|
883 v->sprite_height = 6; |
|
884 v->x_offs = -3; |
|
885 v->y_offs = -3; |
|
886 v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL; |
851 v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL; |
887 |
852 |
888 v->spritenum = svi->image_index; |
853 v->spritenum = svi->image_index; |
889 v->cargo_type = svi->cargo_type; |
854 v->cargo_type = svi->cargo_type; |
890 v->cargo_subtype = 0; |
855 v->cargo_subtype = 0; |
906 |
871 |
907 v->service_interval = _patches.servint_ships; |
872 v->service_interval = _patches.servint_ships; |
908 v->date_of_last_service = _date; |
873 v->date_of_last_service = _date; |
909 v->build_year = _cur_year; |
874 v->build_year = _cur_year; |
910 v->cur_image = 0x0E5E; |
875 v->cur_image = 0x0E5E; |
911 v->type = VEH_SHIP; |
876 v = new (v) Ship(); |
912 v->random_bits = VehicleRandomBits(); |
877 v->random_bits = VehicleRandomBits(); |
913 |
878 |
914 v->vehicle_flags = 0; |
879 v->vehicle_flags = 0; |
915 if (e->flags & ENGINE_EXCLUSIVE_PREVIEW) SETBIT(v->vehicle_flags, VF_BUILT_AS_PROTOTYPE); |
880 if (e->flags & ENGINE_EXCLUSIVE_PREVIEW) SETBIT(v->vehicle_flags, VF_BUILT_AS_PROTOTYPE); |
|
881 |
|
882 v->cargo_cap = GetVehicleProperty(v, 0x0D, svi->capacity); |
916 |
883 |
917 VehiclePositionChanged(v); |
884 VehiclePositionChanged(v); |
918 |
885 |
919 InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile); |
886 InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile); |
920 RebuildVehicleLists(); |
887 RebuildVehicleLists(); |
1056 |
1026 |
1057 dep = FindClosestShipDepot(v); |
1027 dep = FindClosestShipDepot(v); |
1058 if (dep == NULL) return_cmd_error(STR_981A_UNABLE_TO_FIND_LOCAL_DEPOT); |
1028 if (dep == NULL) return_cmd_error(STR_981A_UNABLE_TO_FIND_LOCAL_DEPOT); |
1059 |
1029 |
1060 if (flags & DC_EXEC) { |
1030 if (flags & DC_EXEC) { |
|
1031 if (v->current_order.type == OT_LOADING) v->LeaveStation(); |
|
1032 |
1061 v->dest_tile = dep->xy; |
1033 v->dest_tile = dep->xy; |
1062 v->current_order.type = OT_GOTO_DEPOT; |
1034 v->current_order.type = OT_GOTO_DEPOT; |
1063 v->current_order.flags = OF_NON_STOP; |
1035 v->current_order.flags = OF_NON_STOP; |
1064 if (!(p2 & DEPOT_SERVICE)) SETBIT(v->current_order.flags, OFB_HALT_IN_DEPOT); |
1036 if (!(p2 & DEPOT_SERVICE)) SETBIT(v->current_order.flags, OFB_HALT_IN_DEPOT); |
1065 v->current_order.refit_cargo = CT_INVALID; |
1037 v->current_order.refit_cargo = CT_INVALID; |
1071 } |
1043 } |
1072 |
1044 |
1073 |
1045 |
1074 /** Refits a ship to the specified cargo type. |
1046 /** Refits a ship to the specified cargo type. |
1075 * @param tile unused |
1047 * @param tile unused |
|
1048 * @param flags type of operation |
1076 * @param p1 vehicle ID of the ship to refit |
1049 * @param p1 vehicle ID of the ship to refit |
1077 * @param p2 various bitstuffed elements |
1050 * @param p2 various bitstuffed elements |
1078 * - p2 = (bit 0-7) - the new cargo type to refit to (p2 & 0xFF) |
1051 * - p2 = (bit 0-7) - the new cargo type to refit to (p2 & 0xFF) |
1079 * - p2 = (bit 8-15) - the new cargo subtype to refit to |
1052 * - p2 = (bit 8-15) - the new cargo subtype to refit to |
|
1053 * - p2 = (bit 16) - refit only this vehicle (ignored) |
|
1054 * @return cost of refit or error |
1080 */ |
1055 */ |
1081 int32 CmdRefitShip(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
1056 int32 CmdRefitShip(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
1082 { |
1057 { |
1083 Vehicle *v; |
1058 Vehicle *v; |
1084 int32 cost; |
1059 int32 cost; |