@@ -684,17 +684,15 @@ static void HelicopterTickHandler(Aircra
void SetAircraftPosition(Aircraft *v, int x, int y, int z)
{
v->x_pos = x;
v->y_pos = y;
v->z_pos = z;
v->cur_image = v->GetImage(v->direction);
v->UpdateViewport(true, false);
if (v->subtype == AIR_HELICOPTER) v->Next()->Next()->cur_image = GetRotorImage(v);
VehicleMove(v, true);
Aircraft *u = v->Next();
int safe_x = Clamp(x, 0, MapMaxX() * TILE_SIZE);
int safe_y = Clamp(y - 1, 0, MapMaxY() * TILE_SIZE);
u->x_pos = x;
u->y_pos = y - ((v->z_pos - GetSlopeZ(safe_x, safe_y)) >> 3);;
@@ -1275,15 +1273,14 @@ TileIndex Aircraft::GetOrderStationLocat
/* Aircraft do not use dest-tile */
return 0;
}
void Aircraft::MarkDirty()
this->cur_image = this->GetImage(this->direction);
this->UpdateViewport(false, false);
if (this->subtype == AIR_HELICOPTER) this->Next()->Next()->cur_image = GetRotorImage(this);
MarkSingleVehicleDirty(this);
static void CrashAirplane(Aircraft *v)
v->vehstatus |= VS_CRASHED;
v->crashed_counter = 0;
@@ -479,14 +479,13 @@ CommandCost CmdTurnRoadVeh(TileIndex til
void RoadVehicle::MarkDirty()
for (Vehicle *v = this; v != NULL; v = v->Next()) {
MarkSingleVehicleDirty(v);
v->UpdateViewport(false, false);
void RoadVehicle::UpdateDeltaXY(Direction direction)
#define MKIT(a, b, c, d) ((a & 0xFF) << 24) | ((b & 0xFF) << 16) | ((c & 0xFF) << 8) | ((d & 0xFF) << 0)
@@ -529,25 +528,25 @@ static void DeleteLastRoadVeh(RoadVehicl
if (IsTileType(v->tile, MP_STATION)) ClearCrashedStation(v);
delete v;
static byte SetRoadVehPosition(RoadVehicle *v, int x, int y)
static byte SetRoadVehPosition(RoadVehicle *v, int x, int y, bool turned)
byte new_z, old_z;
/* need this hint so it returns the right z coordinate on bridges. */
new_z = GetSlopeZ(x, y);
old_z = v->z_pos;
v->z_pos = new_z;
v->UpdateViewport(true, turned);
return old_z;
static void RoadVehSetRandomDirection(RoadVehicle *v)
static const DirDiff delta[] = {
@@ -555,15 +554,13 @@ static void RoadVehSetRandomDirection(Ro
};
do {
uint32 r = Random();
v->direction = ChangeDir(v->direction, delta[r & 3]);
v->UpdateDeltaXY(v->direction);
SetRoadVehPosition(v, v->x_pos, v->y_pos);
SetRoadVehPosition(v, v->x_pos, v->y_pos, true);
} while ((v = v->Next()) != NULL);
static bool RoadVehIsCrashed(RoadVehicle *v)
v->crashed_ctr++;
@@ -1252,14 +1249,13 @@ static bool RoadVehLeaveDepot(RoadVehicl
v->vehstatus &= ~VS_HIDDEN;
v->state = tdir;
v->frame = RVC_DEPOT_START_FRAME;
SetRoadVehPosition(v, x, y);
SetRoadVehPosition(v, x, y, true);
InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
return true;
@@ -1380,14 +1376,13 @@ static bool IndividualRoadVehicleControl
return false;
if (IsTileType(gp.new_tile, MP_TUNNELBRIDGE) && HasBit(VehicleEnterTile(v, gp.new_tile, gp.x, gp.y), VETS_ENTERED_WORMHOLE)) {
/* Vehicle has just entered a bridge or tunnel */
SetRoadVehPosition(v, gp.x, gp.y);
SetRoadVehPosition(v, gp.x, gp.y, true);
v->x_pos = gp.x;
v->y_pos = gp.y;
VehicleMove(v, !(v->vehstatus & VS_HIDDEN));
@@ -1526,14 +1521,13 @@ again:
if (new_dir != v->direction) {
v->direction = new_dir;
v->cur_speed -= v->cur_speed >> 2;
RoadZPosAffectSpeed(v, SetRoadVehPosition(v, x, y));
RoadZPosAffectSpeed(v, SetRoadVehPosition(v, x, y, true));
if (rd.x & RDE_TURNED) {
/* Vehicle has finished turning around, it will now head back onto the same tile */
Trackdir dir;
@@ -1591,14 +1585,13 @@ again:
/* This vehicle is not in a wormhole and it hasn't entered a new tile. If
* it's on a depot tile, check if it's time to activate the next vehicle in
* the chain yet. */
@@ -1631,14 +1624,13 @@ again:
Direction old_dir = v->direction;
if (new_dir != old_dir) {
v->cur_speed -= (v->cur_speed >> 2);
if (old_dir != v->state) {
/* The vehicle is in a road stop */
/* Note, return here means that the frame counter is not incremented
* for vehicles changing direction in a road stop. This causes frames to
* be repeated. (XXX) Is this intended? */
@@ -1679,13 +1671,13 @@ again:
rs_n->num_vehicles++;
v->slot = rs_n;
v->dest_tile = rs_n->xy;
v->slot_age = 14;
v->frame++;
RoadZPosAffectSpeed(v, SetRoadVehPosition(v, x, y, false));
rs->SetEntranceBusy(false);
@@ -1754,14 +1746,13 @@ again:
/* Move to next frame unless vehicle arrived at a stop position
* in a depot or entered a tunnel/bridge */
if (!HasBit(r, VETS_ENTERED_WORMHOLE)) v->frame++;
static bool RoadVehController(RoadVehicle *v)
/* decrease counters */
@@ -1813,15 +1804,13 @@ static bool RoadVehController(RoadVehicl
if (j >= adv_spd && RoadVehCheckTrainCrash(v)) break;
for (RoadVehicle *u = v; u != NULL; u = u->Next()) {
if ((u->vehstatus & VS_HIDDEN) != 0) continue;
uint16 old_image = u->cur_image;
u->cur_image = u->GetImage(u->direction);
if (old_image != u->cur_image) VehicleMove(u, true);
u->UpdateViewport(false, false);
if (v->progress == 0) v->progress = j;
@@ -226,14 +226,13 @@ static void HandleBrokenShip(Vehicle *v)
void Ship::MarkDirty()
static void PlayShipSound(const Vehicle *v)
if (!PlayVehicleSound(v, VSE_START)) {
SndPlayVehicleFx(ShipVehInfo(v->engine_type)->sfx, v);
@@ -280,15 +279,13 @@ void Ship::UpdateDeltaXY(Direction direc
this->y_extent = GB(x, 24, 8);
this->z_extent = 6;
void RecalcShipStuff(Vehicle *v)
v->MarkDirty();
v->UpdateViewport(false, true);
InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
static const TileIndexDiffC _ship_leave_depot_offs[] = {
{-1, 0},
{ 0, -1}
@@ -705,15 +702,13 @@ static void ShipController(Ship *v)
dir = ShipGetNewDirection(v, gp.x, gp.y);
v->z_pos = GetSlopeZ(gp.x, gp.y);
getout:
v->UpdateDeltaXY(dir);
v->cur_image = v->GetImage(dir);
v->UpdateViewport(true, true);
return;
reverse_direction:
dir = ReverseDir(v->direction);
v->direction = dir;
goto getout;
@@ -1617,19 +1617,12 @@ void Train::UpdateDeltaXY(Direction dire
this->y_offs = GB(x, 8, 8);
this->x_extent = GB(x, 16, 8);
static void UpdateVarsAfterSwap(Train *v)
static inline void SetLastSpeed(Train *v, int spd)
int old = v->tcache.last_speed;
if (spd != old) {
v->tcache.last_speed = spd;
if (_settings_client.gui.vehicle_speed || (old == 0) != (spd == 0)) {
@@ -1711,21 +1704,21 @@ static void ReverseTrainSwapVeh(Train *v
Swap(a->tile, b->tile);
Swap(a->z_pos, b->z_pos);
SwapTrainFlags(&a->flags, &b->flags);
/* update other vars */
UpdateVarsAfterSwap(a);
UpdateVarsAfterSwap(b);
a->UpdateViewport(true, true);
b->UpdateViewport(true, true);
/* call the proper EnterTile function unless we are in a wormhole */
if (a->track != TRACK_BIT_WORMHOLE) VehicleEnterTile(a, a->tile, a->x_pos, a->y_pos);
if (b->track != TRACK_BIT_WORMHOLE) VehicleEnterTile(b, b->tile, b->x_pos, b->y_pos);
} else {
if (a->track != TRACK_BIT_DEPOT) a->direction = ReverseDir(a->direction);
/* Update train's power incase tiles were different rail type */
TrainPowerChanged(v);
@@ -1945,13 +1938,13 @@ static void ReverseTrainDirection(Train
ClrBit(v->flags, VRF_REVERSING);
/* recalculate cached data */
TrainConsistChanged(v, true);
/* update all images */
for (Vehicle *u = v; u != NULL; u = u->Next()) u->cur_image = u->GetImage(u->direction);
for (Vehicle *u = v; u != NULL; u = u->Next()) u->UpdateViewport(false, false);
/* update crossing we were approaching */
if (crossing != INVALID_TILE) UpdateLevelCrossing(crossing);
/* maybe we are approaching crossing now, after reversal */
crossing = TrainApproachingCrossingTile(v);
@@ -3321,14 +3314,13 @@ TileIndex Train::GetOrderStationLocation
void Train::MarkDirty()
Vehicle *v = this;
/* need to update acceleration and cached values since the goods on the train changed. */
TrainCargoChanged(this);
UpdateTrainAcceleration(this);
@@ -4447,15 +4439,13 @@ static bool TrainLocoHandler(Train *v, b
SetLastSpeed(v, v->cur_speed);
for (Train *u = v; u != NULL; u = u->Next()) {
if (v->progress == 0) v->progress = j; // Save unused spd for next time, if TrainController didn't set progress
@@ -306,12 +306,27 @@ public:
/**
* Calls the new day handler of the vehicle
*/
virtual void OnNewDay() {};
* Update vehicle sprite- and position caches
* @param moved Was the vehicle moved?
* @param turned Did the vehicle direction change?
inline void UpdateViewport(bool moved, bool turned)
extern void VehicleMove(Vehicle *v, bool update_viewport);
if (turned) this->UpdateDeltaXY(this->direction);
SpriteID old_image = this->cur_image;
if (moved || this->cur_image != old_image) VehicleMove(this, true);
* Returns the Trackdir on which the vehicle is currently located.
* Works for trains and ships.
* Currently works only sortof for road vehicles, since they have a fuzzy
* concept of being "on" a trackdir. Dunno really what it returns for a road
* vehicle that is halfway a tile, never really understood that part. For road
* vehicles that are at the beginning or end of the tile, should just return
Status change: