38 #include "table/strings.h"
61 static const uint16 _ship_sprites[] = {0x0E5D, 0x0E55, 0x0E65, 0x0E6D};
64 bool IsValidImageIndex<VEH_SHIP>(uint8 image_index)
66 return image_index <
lengthof(_ship_sprites);
77 uint8 spritenum = e->u.ship.image_index;
79 if (is_custom_sprite(spritenum)) {
80 GetCustomVehicleIcon(engine,
DIR_W, image_type, result);
86 assert(IsValidImageIndex<VEH_SHIP>(spritenum));
87 result->
Set(
DIR_W + _ship_sprites[spritenum]);
93 GetShipIcon(engine, image_type, &seq);
97 preferred_x =
Clamp(preferred_x,
116 GetShipIcon(engine, image_type, &seq);
121 width =
UnScaleGUI(rect.right - rect.left + 1);
122 height =
UnScaleGUI(rect.bottom - rect.top + 1);
131 if (is_custom_sprite(spritenum)) {
132 GetCustomVehicleSprite(
this, direction, image_type, result);
138 assert(IsValidImageIndex<VEH_SHIP>(spritenum));
139 result->
Set(_ship_sprites[spritenum] + direction);
142 static const Depot *FindClosestShipDepot(
const Vehicle *v, uint max_distance)
146 const Depot *best_depot = NULL;
152 uint best_dist = max_distance == 0 ? UINT_MAX : max_distance + 1;
154 FOR_ALL_DEPOTS(depot) {
158 if (dist < best_dist) {
168 static void CheckIfShipNeedsService(
Vehicle *v)
178 case VPF_OPF: max_distance = 12;
break;
181 default: NOT_REACHED();
184 const Depot *depot = FindClosestShipDepot(v, max_distance);
230 CheckVehicleBreakdown(
this);
232 CheckIfShipNeedsService(
this);
274 static void PlayShipSound(
const Vehicle *v)
277 SndPlayVehicleFx(ShipVehInfo(v->
engine_type)->sfx, v);
301 static const int8 _delta_xy_table[8][4] = {
313 const int8 *bb = _delta_xy_table[
direction];
321 static bool CheckShipLeaveDepot(
Ship *v)
342 if (north_tracks && south_tracks) {
344 bool reverse =
false;
350 default: NOT_REACHED();
358 }
else if (south_tracks) {
381 static bool ShipAccelerate(
Vehicle *v)
398 if (spd == 0)
return false;
399 if ((byte)++spd == 0)
return true;
403 return (t < v->progress);
414 if (!(st->had_vehicle_of_type &
HVOT_SHIP)) {
419 STR_NEWS_FIRST_SHIP_ARRIVAL,
443 bool path_found =
true;
449 default: NOT_REACHED();
461 static const byte _ship_subcoord[4][6][3] = {
496 static void ShipController(
Ship *v)
516 if (CheckShipLeaveDepot(v))
return;
520 if (!ShipAccelerate(v))
return;
553 if ((gp.x & 0xF) == 8 && (gp.
y & 0xF) == 8) {
580 tracks = GetAvailShipTracks(gp.
new_tile, diagdir);
587 b = _ship_subcoord[diagdir][track];
589 gp.x = (gp.x & ~0xF) | b[0];
590 gp.
y = (gp.
y & ~0xF) | b[1];
622 v->
z_pos = GetSlopePixelZ(gp.x, gp.
y);
639 ShipController(
this);
671 v->
z_pos = GetSlopePixelZ(x, y);
688 _new_vehicle_id = v->
index;
717 const Depot *depot = FindClosestShipDepot(
this, 0);
719 if (depot == NULL)
return false;
721 if (location != NULL) *location = depot->xy;
722 if (destination != NULL) *destination = depot->
index;