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;