Merge branch 'master' into infrastructure_sharing
Conflicts: src/aircraft_cmd.cpp src/economy.cpp src/lang/english.txt src/order_gui.cpp src/roadveh_cmd.cpp src/saveload/saveload.cpp src/settings.cpp src/settings_gui.cpp src/train_cmd.cpp
This commit is contained in:
140
src/ship_cmd.cpp
140
src/ship_cmd.cpp
@@ -37,6 +37,8 @@
|
||||
|
||||
#include "table/strings.h"
|
||||
|
||||
#include "safeguards.h"
|
||||
|
||||
/**
|
||||
* Determine the effective #WaterClass for a ship travelling on a tile.
|
||||
* @param tile Tile of interest
|
||||
@@ -58,6 +60,12 @@ WaterClass GetEffectiveWaterClass(TileIndex tile)
|
||||
|
||||
static const uint16 _ship_sprites[] = {0x0E5D, 0x0E55, 0x0E65, 0x0E6D};
|
||||
|
||||
template <>
|
||||
bool IsValidImageIndex<VEH_SHIP>(uint8 image_index)
|
||||
{
|
||||
return image_index < lengthof(_ship_sprites);
|
||||
}
|
||||
|
||||
static inline TrackBits GetTileShipTrackStatus(TileIndex tile)
|
||||
{
|
||||
return TrackStatusToTrackBits(GetTileTrackStatus(tile, TRANSPORT_WATER, 0));
|
||||
@@ -75,6 +83,7 @@ static SpriteID GetShipIcon(EngineID engine, EngineImageType image_type)
|
||||
spritenum = e->original_image_index;
|
||||
}
|
||||
|
||||
assert(IsValidImageIndex<VEH_SHIP>(spritenum));
|
||||
return DIR_W + _ship_sprites[spritenum];
|
||||
}
|
||||
|
||||
@@ -82,22 +91,29 @@ void DrawShipEngine(int left, int right, int preferred_x, int y, EngineID engine
|
||||
{
|
||||
SpriteID sprite = GetShipIcon(engine, image_type);
|
||||
const Sprite *real_sprite = GetSprite(sprite, ST_NORMAL);
|
||||
preferred_x = Clamp(preferred_x, left - UnScaleByZoom(real_sprite->x_offs, ZOOM_LVL_GUI), right - UnScaleByZoom(real_sprite->width, ZOOM_LVL_GUI) - UnScaleByZoom(real_sprite->x_offs, ZOOM_LVL_GUI));
|
||||
preferred_x = Clamp(preferred_x,
|
||||
left - UnScaleGUI(real_sprite->x_offs),
|
||||
right - UnScaleGUI(real_sprite->width) - UnScaleGUI(real_sprite->x_offs));
|
||||
DrawSprite(sprite, pal, preferred_x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the size of the sprite of a ship sprite heading west (used for lists)
|
||||
* @param engine The engine to get the sprite from
|
||||
* @param width The width of the sprite
|
||||
* @param height The height of the sprite
|
||||
* Get the size of the sprite of a ship sprite heading west (used for lists).
|
||||
* @param engine The engine to get the sprite from.
|
||||
* @param[out] width The width of the sprite.
|
||||
* @param[out] height The height of the sprite.
|
||||
* @param[out] xoffs Number of pixels to shift the sprite to the right.
|
||||
* @param[out] yoffs Number of pixels to shift the sprite downwards.
|
||||
* @param image_type Context the sprite is used in.
|
||||
*/
|
||||
void GetShipSpriteSize(EngineID engine, uint &width, uint &height, EngineImageType image_type)
|
||||
void GetShipSpriteSize(EngineID engine, uint &width, uint &height, int &xoffs, int &yoffs, EngineImageType image_type)
|
||||
{
|
||||
const Sprite *spr = GetSprite(GetShipIcon(engine, image_type), ST_NORMAL);
|
||||
|
||||
width = UnScaleByZoom(spr->width, ZOOM_LVL_GUI);
|
||||
height = UnScaleByZoom(spr->height, ZOOM_LVL_GUI);
|
||||
width = UnScaleGUI(spr->width);
|
||||
height = UnScaleGUI(spr->height);
|
||||
xoffs = UnScaleGUI(spr->x_offs);
|
||||
yoffs = UnScaleGUI(spr->y_offs);
|
||||
}
|
||||
|
||||
SpriteID Ship::GetImage(Direction direction, EngineImageType image_type) const
|
||||
@@ -111,6 +127,7 @@ SpriteID Ship::GetImage(Direction direction, EngineImageType image_type) const
|
||||
spritenum = this->GetEngine()->original_image_index;
|
||||
}
|
||||
|
||||
assert(IsValidImageIndex<VEH_SHIP>(spritenum));
|
||||
return _ship_sprites[spritenum] + direction;
|
||||
}
|
||||
|
||||
@@ -143,7 +160,7 @@ static const Depot *FindClosestShipDepot(const Vehicle *v, uint max_distance)
|
||||
static void CheckIfShipNeedsService(Vehicle *v)
|
||||
{
|
||||
if (Company::Get(v->owner)->settings.vehicle.servint_ships == 0 || !v->NeedsAutomaticServicing()) return;
|
||||
if (v->IsInDepot()) {
|
||||
if (v->IsChainInDepot()) {
|
||||
VehicleServiceInDepot(v);
|
||||
return;
|
||||
}
|
||||
@@ -241,7 +258,8 @@ Trackdir Ship::GetVehicleTrackdir() const
|
||||
|
||||
void Ship::MarkDirty()
|
||||
{
|
||||
this->UpdateViewport(false, false);
|
||||
this->colourmap = PAL_NONE;
|
||||
this->UpdateViewport(true, false);
|
||||
this->UpdateCache();
|
||||
}
|
||||
|
||||
@@ -272,24 +290,23 @@ TileIndex Ship::GetOrderStationLocation(StationID station)
|
||||
|
||||
void Ship::UpdateDeltaXY(Direction direction)
|
||||
{
|
||||
#define MKIT(a, b, c, d) ((a & 0xFF) << 24) | ((b & 0xFF) << 16) | ((c & 0xFF) << 8) | ((d & 0xFF) << 0)
|
||||
static const uint32 _delta_xy_table[8] = {
|
||||
MKIT( 6, 6, -3, -3),
|
||||
MKIT( 6, 32, -3, -16),
|
||||
MKIT( 6, 6, -3, -3),
|
||||
MKIT(32, 6, -16, -3),
|
||||
MKIT( 6, 6, -3, -3),
|
||||
MKIT( 6, 32, -3, -16),
|
||||
MKIT( 6, 6, -3, -3),
|
||||
MKIT(32, 6, -16, -3),
|
||||
static const int8 _delta_xy_table[8][4] = {
|
||||
/* y_extent, x_extent, y_offs, x_offs */
|
||||
{ 6, 6, -3, -3}, // N
|
||||
{ 6, 32, -3, -16}, // NE
|
||||
{ 6, 6, -3, -3}, // E
|
||||
{32, 6, -16, -3}, // SE
|
||||
{ 6, 6, -3, -3}, // S
|
||||
{ 6, 32, -3, -16}, // SW
|
||||
{ 6, 6, -3, -3}, // W
|
||||
{32, 6, -16, -3}, // NW
|
||||
};
|
||||
#undef MKIT
|
||||
|
||||
uint32 x = _delta_xy_table[direction];
|
||||
this->x_offs = GB(x, 0, 8);
|
||||
this->y_offs = GB(x, 8, 8);
|
||||
this->x_extent = GB(x, 16, 8);
|
||||
this->y_extent = GB(x, 24, 8);
|
||||
const int8 *bb = _delta_xy_table[direction];
|
||||
this->x_offs = bb[3];
|
||||
this->y_offs = bb[2];
|
||||
this->x_extent = bb[1];
|
||||
this->y_extent = bb[0];
|
||||
this->z_extent = 6;
|
||||
}
|
||||
|
||||
@@ -300,7 +317,7 @@ static const TileIndexDiffC _ship_leave_depot_offs[] = {
|
||||
|
||||
static bool CheckShipLeaveDepot(Ship *v)
|
||||
{
|
||||
if (!v->IsInDepot()) return false;
|
||||
if (!v->IsChainInDepot()) return false;
|
||||
|
||||
/* We are leaving a depot, but have to go to the exact same one; re-enter */
|
||||
if (v->current_order.IsType(OT_GOTO_DEPOT) &&
|
||||
@@ -312,13 +329,34 @@ static bool CheckShipLeaveDepot(Ship *v)
|
||||
TileIndex tile = v->tile;
|
||||
Axis axis = GetShipDepotAxis(tile);
|
||||
|
||||
/* Check first (north) side */
|
||||
if (DiagdirReachesTracks((DiagDirection)axis) & GetTileShipTrackStatus(TILE_ADD(tile, ToTileIndexDiff(_ship_leave_depot_offs[axis])))) {
|
||||
v->direction = ReverseDir(AxisToDirection(axis));
|
||||
/* Check second (south) side */
|
||||
} else if (DiagdirReachesTracks((DiagDirection)(axis + 2)) & GetTileShipTrackStatus(TILE_ADD(tile, -2 * ToTileIndexDiff(_ship_leave_depot_offs[axis])))) {
|
||||
v->direction = AxisToDirection(axis);
|
||||
DiagDirection north_dir = ReverseDiagDir(AxisToDiagDir(axis));
|
||||
TileIndex north_neighbour = TILE_ADD(tile, ToTileIndexDiff(_ship_leave_depot_offs[axis]));
|
||||
DiagDirection south_dir = AxisToDiagDir(axis);
|
||||
TileIndex south_neighbour = TILE_ADD(tile, -2 * ToTileIndexDiff(_ship_leave_depot_offs[axis]));
|
||||
|
||||
TrackBits north_tracks = DiagdirReachesTracks(north_dir) & GetTileShipTrackStatus(north_neighbour);
|
||||
TrackBits south_tracks = DiagdirReachesTracks(south_dir) & GetTileShipTrackStatus(south_neighbour);
|
||||
if (north_tracks && south_tracks) {
|
||||
/* Ask pathfinder for best direction */
|
||||
bool reverse = false;
|
||||
bool path_found;
|
||||
switch (_settings_game.pf.pathfinder_for_ships) {
|
||||
case VPF_OPF: reverse = OPFShipChooseTrack(v, north_neighbour, north_dir, north_tracks, path_found) == INVALID_TRACK; break; // OPF always allows reversing
|
||||
case VPF_NPF: reverse = NPFShipCheckReverse(v); break;
|
||||
case VPF_YAPF: reverse = YapfShipCheckReverse(v); break;
|
||||
default: NOT_REACHED();
|
||||
}
|
||||
if (reverse) north_tracks = TRACK_BIT_NONE;
|
||||
}
|
||||
|
||||
if (north_tracks) {
|
||||
/* Leave towards north */
|
||||
v->direction = DiagDirToDir(north_dir);
|
||||
} else if (south_tracks) {
|
||||
/* Leave towards south */
|
||||
v->direction = DiagDirToDir(south_dir);
|
||||
} else {
|
||||
/* Both ways blocked */
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -343,7 +381,7 @@ static bool ShipAccelerate(Vehicle *v)
|
||||
byte t;
|
||||
|
||||
spd = min(v->cur_speed + 1, v->vcache.cached_max_speed);
|
||||
spd = min(spd, v->current_order.max_speed * 2);
|
||||
spd = min(spd, v->current_order.GetMaxSpeed() * 2);
|
||||
|
||||
/* updates statusbar only if speed have changed to save CPU time */
|
||||
if (spd != v->cur_speed) {
|
||||
@@ -351,7 +389,7 @@ static bool ShipAccelerate(Vehicle *v)
|
||||
SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, WID_VV_START_STOP);
|
||||
}
|
||||
|
||||
/* Convert direction-indepenent speed into direction-dependent speed. (old movement method) */
|
||||
/* Convert direction-independent speed into direction-dependent speed. (old movement method) */
|
||||
spd = v->GetOldAdvanceSpeed(spd);
|
||||
|
||||
if (spd == 0) return false;
|
||||
@@ -376,7 +414,7 @@ static void ShipArrivesAt(const Vehicle *v, Station *st)
|
||||
SetDParam(0, st->index);
|
||||
AddVehicleNewsItem(
|
||||
STR_NEWS_FIRST_SHIP_ARRIVAL,
|
||||
(v->owner == _local_company) ? NS_ARRIVAL_COMPANY : NS_ARRIVAL_OTHER,
|
||||
(v->owner == _local_company) ? NT_ARRIVAL_COMPANY : NT_ARRIVAL_OTHER,
|
||||
v->index,
|
||||
st->index
|
||||
);
|
||||
@@ -386,9 +424,13 @@ static void ShipArrivesAt(const Vehicle *v, Station *st)
|
||||
|
||||
|
||||
/**
|
||||
* returns the track to choose on the next tile, or -1 when it's better to
|
||||
* reverse. The tile given is the tile we are about to enter, enterdir is the
|
||||
* direction in which we are entering the tile
|
||||
* Runs the pathfinder to choose a track to continue along.
|
||||
*
|
||||
* @param v Ship to navigate
|
||||
* @param tile Tile, the ship is about to enter
|
||||
* @param enterdir Direction of entering
|
||||
* @param tracks Available track choices on \a tile
|
||||
* @return Track to choose, or INVALID_TRACK when to reverse.
|
||||
*/
|
||||
static Track ChooseShipTrack(Ship *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks)
|
||||
{
|
||||
@@ -547,15 +589,12 @@ static void ShipController(Ship *v)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
DiagDirection diagdir;
|
||||
/* New tile */
|
||||
if (TileX(gp.new_tile) >= MapMaxX() || TileY(gp.new_tile) >= MapMaxY()) {
|
||||
goto reverse_direction;
|
||||
}
|
||||
if (!IsValidTile(gp.new_tile)) goto reverse_direction;
|
||||
|
||||
dir = ShipGetNewDirectionFromTiles(gp.new_tile, gp.old_tile);
|
||||
assert(dir == DIR_NE || dir == DIR_SE || dir == DIR_SW || dir == DIR_NW);
|
||||
diagdir = DirToDiagDir(dir);
|
||||
DiagDirection diagdir = DirToDiagDir(dir);
|
||||
tracks = GetAvailShipTracks(gp.new_tile, diagdir);
|
||||
if (tracks == TRACK_BIT_NONE) goto reverse_direction;
|
||||
|
||||
@@ -589,8 +628,8 @@ static void ShipController(Ship *v)
|
||||
if (!IsTileType(gp.new_tile, MP_TUNNELBRIDGE) || !HasBit(VehicleEnterTile(v, gp.new_tile, gp.x, gp.y), VETS_ENTERED_WORMHOLE)) {
|
||||
v->x_pos = gp.x;
|
||||
v->y_pos = gp.y;
|
||||
VehicleUpdatePosition(v);
|
||||
if ((v->vehstatus & VS_HIDDEN) == 0) VehicleUpdateViewport(v, true);
|
||||
v->UpdatePosition();
|
||||
if ((v->vehstatus & VS_HIDDEN) == 0) v->Vehicle::UpdateViewport(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -602,7 +641,7 @@ static void ShipController(Ship *v)
|
||||
v->z_pos = GetSlopePixelZ(gp.x, gp.y);
|
||||
|
||||
getout:
|
||||
VehicleUpdatePosition(v);
|
||||
v->UpdatePosition();
|
||||
v->UpdateViewport(true, true);
|
||||
return;
|
||||
|
||||
@@ -656,8 +695,10 @@ CommandCost CmdBuildShip(TileIndex tile, DoCommandFlag flags, const Engine *e, u
|
||||
v->spritenum = svi->image_index;
|
||||
v->cargo_type = e->GetDefaultCargoType();
|
||||
v->cargo_cap = svi->capacity;
|
||||
v->refit_cap = 0;
|
||||
|
||||
v->last_station_visited = INVALID_STATION;
|
||||
v->last_loading_station = INVALID_STATION;
|
||||
v->engine_type = e->index;
|
||||
|
||||
v->reliability = e->reliability;
|
||||
@@ -667,7 +708,7 @@ CommandCost CmdBuildShip(TileIndex tile, DoCommandFlag flags, const Engine *e, u
|
||||
|
||||
v->state = TRACK_BIT_DEPOT;
|
||||
|
||||
v->service_interval = Company::Get(_current_company)->settings.vehicle.servint_ships;
|
||||
v->SetServiceInterval(Company::Get(_current_company)->settings.vehicle.servint_ships);
|
||||
v->date_of_last_service = _date;
|
||||
v->build_year = _cur_year;
|
||||
v->cur_image = SPR_IMG_QUERY;
|
||||
@@ -676,6 +717,7 @@ CommandCost CmdBuildShip(TileIndex tile, DoCommandFlag flags, const Engine *e, u
|
||||
v->UpdateCache();
|
||||
|
||||
if (e->flags & ENGINE_EXCLUSIVE_PREVIEW) SetBit(v->vehicle_flags, VF_BUILT_AS_PROTOTYPE);
|
||||
v->SetServiceIntervalIsPercent(Company::Get(_current_company)->settings.vehicle.servint_ispercent);
|
||||
|
||||
v->InvalidateNewGRFCacheOfChain();
|
||||
|
||||
@@ -683,7 +725,7 @@ CommandCost CmdBuildShip(TileIndex tile, DoCommandFlag flags, const Engine *e, u
|
||||
|
||||
v->InvalidateNewGRFCacheOfChain();
|
||||
|
||||
VehicleUpdatePosition(v);
|
||||
v->UpdatePosition();
|
||||
}
|
||||
|
||||
return CommandCost();
|
||||
|
Reference in New Issue
Block a user