37 #include "table/strings.h"
60 static const uint16 _ship_sprites[] = {0x0E5D, 0x0E55, 0x0E65, 0x0E6D};
63 bool IsValidImageIndex<VEH_SHIP>(uint8 image_index)
65 return image_index <
lengthof(_ship_sprites);
76 uint8 spritenum = e->u.ship.image_index;
78 if (is_custom_sprite(spritenum)) {
79 SpriteID sprite = GetCustomVehicleIcon(engine,
DIR_W, image_type);
80 if (sprite != 0)
return sprite;
85 assert(IsValidImageIndex<VEH_SHIP>(spritenum));
86 return DIR_W + _ship_sprites[spritenum];
91 SpriteID sprite = GetShipIcon(engine, image_type);
108 const Sprite *spr = GetSprite(GetShipIcon(engine, image_type),
ST_NORMAL);
120 if (is_custom_sprite(spritenum)) {
121 SpriteID sprite = GetCustomVehicleSprite(
this, direction, image_type);
122 if (sprite != 0)
return sprite;
127 assert(IsValidImageIndex<VEH_SHIP>(spritenum));
131 static const Depot *FindClosestShipDepot(
const Vehicle *v, uint max_distance)
135 const Depot *best_depot = NULL;
141 uint best_dist = max_distance == 0 ? UINT_MAX : max_distance + 1;
143 FOR_ALL_DEPOTS(depot) {
147 if (dist < best_dist) {
157 static void CheckIfShipNeedsService(
Vehicle *v)
167 case VPF_OPF: max_distance = 12;
break;
170 default: NOT_REACHED();
173 const Depot *depot = FindClosestShipDepot(v, max_distance);
219 CheckVehicleBreakdown(
this);
221 CheckIfShipNeedsService(
this);
263 static void PlayShipSound(
const Vehicle *v)
266 SndPlayVehicleFx(ShipVehInfo(v->
engine_type)->sfx, v);
290 static const int8 _delta_xy_table[8][4] = {
302 const int8 *bb = _delta_xy_table[
direction];
315 static bool CheckShipLeaveDepot(
Ship *v)
336 if (north_tracks && south_tracks) {
338 bool reverse =
false;
344 default: NOT_REACHED();
352 }
else if (south_tracks) {
375 static bool ShipAccelerate(
Vehicle *v)
392 if (spd == 0)
return false;
393 if ((byte)++spd == 0)
return true;
397 return (t < v->progress);
408 if (!(st->had_vehicle_of_type &
HVOT_SHIP)) {
413 STR_NEWS_FIRST_SHIP_ARRIVAL,
436 bool path_found =
true;
442 default: NOT_REACHED();
449 static const Direction _new_vehicle_direction_table[] = {
457 uint offs = (
TileY(new_tile) -
TileY(old_tile) + 1) * 4 +
459 assert(offs < 11 && offs != 3 && offs != 7);
460 return _new_vehicle_direction_table[offs];
465 uint offs = (y - v->
y_pos + 1) * 4 + (x - v->
x_pos + 1);
466 assert(offs < 11 && offs != 3 && offs != 7);
467 return _new_vehicle_direction_table[offs];
475 static const byte _ship_subcoord[4][6][3] = {
510 static void ShipController(
Ship *v)
530 if (CheckShipLeaveDepot(v))
return;
534 if (!ShipAccelerate(v))
return;
567 if ((gp.x & 0xF) == 8 && (gp.
y & 0xF) == 8) {
595 tracks = GetAvailShipTracks(gp.
new_tile, diagdir);
602 b = _ship_subcoord[diagdir][track];
604 gp.x = (gp.x & ~0xF) | b[0];
605 gp.
y = (gp.
y & ~0xF) | b[1];
635 dir = ShipGetNewDirection(v, gp.x, gp.
y);
638 v->
z_pos = GetSlopePixelZ(gp.x, gp.
y);
655 ShipController(
this);
687 v->
z_pos = GetSlopePixelZ(x, y);
704 _new_vehicle_id = v->
index;
733 const Depot *depot = FindClosestShipDepot(
this, 0);
735 if (depot == NULL)
return false;
737 if (location != NULL) *location = depot->xy;
738 if (destination != NULL) *destination = depot->
index;