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 GetCustomVehicleIcon(engine,
DIR_W, image_type, result);
85 assert(IsValidImageIndex<VEH_SHIP>(spritenum));
86 result->
Set(
DIR_W + _ship_sprites[spritenum]);
92 GetShipIcon(engine, image_type, &seq);
96 preferred_x =
Clamp(preferred_x,
115 GetShipIcon(engine, image_type, &seq);
120 width =
UnScaleGUI(rect.right - rect.left + 1);
121 height =
UnScaleGUI(rect.bottom - rect.top + 1);
130 if (is_custom_sprite(spritenum)) {
131 GetCustomVehicleSprite(
this, direction, image_type, result);
137 assert(IsValidImageIndex<VEH_SHIP>(spritenum));
138 result->
Set(_ship_sprites[spritenum] + direction);
141 static const Depot *FindClosestShipDepot(
const Vehicle *v, uint max_distance)
145 const Depot *best_depot = NULL;
151 uint best_dist = max_distance == 0 ? UINT_MAX : max_distance + 1;
153 FOR_ALL_DEPOTS(depot) {
157 if (dist < best_dist) {
167 static void CheckIfShipNeedsService(
Vehicle *v)
177 case VPF_OPF: max_distance = 12;
break;
180 default: NOT_REACHED();
183 const Depot *depot = FindClosestShipDepot(v, max_distance);
229 CheckVehicleBreakdown(
this);
231 CheckIfShipNeedsService(
this);
273 static void PlayShipSound(
const Vehicle *v)
276 SndPlayVehicleFx(ShipVehInfo(v->
engine_type)->sfx, v);
300 static const int8 _delta_xy_table[8][4] = {
312 const int8 *bb = _delta_xy_table[
direction];
325 static bool CheckShipLeaveDepot(
Ship *v)
346 if (north_tracks && south_tracks) {
348 bool reverse =
false;
354 default: NOT_REACHED();
362 }
else if (south_tracks) {
385 static bool ShipAccelerate(
Vehicle *v)
402 if (spd == 0)
return false;
403 if ((byte)++spd == 0)
return true;
407 return (t < v->progress);
418 if (!(st->had_vehicle_of_type &
HVOT_SHIP)) {
423 STR_NEWS_FIRST_SHIP_ARRIVAL,
446 bool path_found =
true;
452 default: NOT_REACHED();
459 static const Direction _new_vehicle_direction_table[] = {
467 uint offs = (
TileY(new_tile) -
TileY(old_tile) + 1) * 4 +
469 assert(offs < 11 && offs != 3 && offs != 7);
470 return _new_vehicle_direction_table[offs];
475 uint offs = (y - v->
y_pos + 1) * 4 + (x - v->
x_pos + 1);
476 assert(offs < 11 && offs != 3 && offs != 7);
477 return _new_vehicle_direction_table[offs];
485 static const byte _ship_subcoord[4][6][3] = {
520 static void ShipController(
Ship *v)
540 if (CheckShipLeaveDepot(v))
return;
544 if (!ShipAccelerate(v))
return;
577 if ((gp.x & 0xF) == 8 && (gp.
y & 0xF) == 8) {
605 tracks = GetAvailShipTracks(gp.
new_tile, diagdir);
612 b = _ship_subcoord[diagdir][track];
614 gp.x = (gp.x & ~0xF) | b[0];
615 gp.
y = (gp.
y & ~0xF) | b[1];
645 dir = ShipGetNewDirection(v, gp.x, gp.
y);
648 v->
z_pos = GetSlopePixelZ(gp.x, gp.
y);
665 ShipController(
this);
697 v->
z_pos = GetSlopePixelZ(x, y);
714 _new_vehicle_id = v->
index;
743 const Depot *depot = FindClosestShipDepot(
this, 0);
745 if (depot == NULL)
return false;
747 if (location != NULL) *location = depot->xy;
748 if (destination != NULL) *destination = depot->
index;