Chunnel: Adjust z position of vehicles in chunnels to go "under" the water.
This commit is contained in:
@@ -13,6 +13,8 @@
|
|||||||
#include "train.h"
|
#include "train.h"
|
||||||
#include "roadveh.h"
|
#include "roadveh.h"
|
||||||
#include "depot_map.h"
|
#include "depot_map.h"
|
||||||
|
#include "tunnel_base.h"
|
||||||
|
#include "slope_type.h"
|
||||||
|
|
||||||
#include "safeguards.h"
|
#include "safeguards.h"
|
||||||
|
|
||||||
@@ -280,6 +282,66 @@ bool GroundVehicle<T, Type>::IsChainInDepot() const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates vehicle's Z inclination inside a wormhole, where applicable.
|
||||||
|
*/
|
||||||
|
template <class T, VehicleType Type>
|
||||||
|
void GroundVehicle<T, Type>::UpdateZPositionInWormhole()
|
||||||
|
{
|
||||||
|
if (!IsTunnel(this->tile)) return;
|
||||||
|
|
||||||
|
const Tunnel *t = Tunnel::GetByTile(this->tile);
|
||||||
|
if (!t->is_chunnel) return;
|
||||||
|
|
||||||
|
TileIndex pos_tile = TileVirtXY(this->x_pos, this->y_pos);
|
||||||
|
|
||||||
|
ClrBit(this->gv_flags, GVF_GOINGUP_BIT);
|
||||||
|
ClrBit(this->gv_flags, GVF_GOINGDOWN_BIT);
|
||||||
|
|
||||||
|
if (pos_tile == t->tile_n || pos_tile == t->tile_s) {
|
||||||
|
this->z_pos = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int north_coord, south_coord, pos_coord;
|
||||||
|
bool going_north;
|
||||||
|
Slope slope_north;
|
||||||
|
if (t->tile_s - t->tile_n > MapMaxX()) {
|
||||||
|
// tunnel extends along Y axis (DIAGDIR_SE from north end), has same X values
|
||||||
|
north_coord = TileY(t->tile_n);
|
||||||
|
south_coord = TileY(t->tile_s);
|
||||||
|
pos_coord = TileY(pos_tile);
|
||||||
|
going_north = (this->direction == DIR_NW);
|
||||||
|
slope_north = SLOPE_NW;
|
||||||
|
} else {
|
||||||
|
// tunnel extends along X axis (DIAGDIR_SW from north end), has same Y values
|
||||||
|
north_coord = TileX(t->tile_n);
|
||||||
|
south_coord = TileX(t->tile_s);
|
||||||
|
pos_coord = TileX(pos_tile);
|
||||||
|
going_north = (this->direction == DIR_NE);
|
||||||
|
slope_north = SLOPE_NE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Slope slope = SLOPE_FLAT;
|
||||||
|
|
||||||
|
int delta;
|
||||||
|
if ((delta = pos_coord - north_coord) <= 3) {
|
||||||
|
this->z_pos = TILE_HEIGHT * (delta == 3 ? -2 : -1);
|
||||||
|
if (delta != 2) {
|
||||||
|
slope = slope_north;
|
||||||
|
SetBit(this->gv_flags, going_north ? GVF_GOINGUP_BIT : GVF_GOINGDOWN_BIT);
|
||||||
|
}
|
||||||
|
} else if ((delta = south_coord - pos_coord) <= 3) {
|
||||||
|
this->z_pos = TILE_HEIGHT * (delta == 3 ? -2 : -1);
|
||||||
|
if (delta != 2) {
|
||||||
|
slope = SLOPE_ELEVATED ^ slope_north;
|
||||||
|
SetBit(this->gv_flags, going_north ? GVF_GOINGDOWN_BIT : GVF_GOINGUP_BIT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (slope != SLOPE_FLAT) this->z_pos += GetPartialPixelZ(this->x_pos & 0xF, this->y_pos & 0xF, slope);
|
||||||
|
}
|
||||||
|
|
||||||
/* Instantiation for Train */
|
/* Instantiation for Train */
|
||||||
template struct GroundVehicle<Train, VEH_TRAIN>;
|
template struct GroundVehicle<Train, VEH_TRAIN>;
|
||||||
/* Instantiation for RoadVehicle */
|
/* Instantiation for RoadVehicle */
|
||||||
|
@@ -228,17 +228,21 @@ struct GroundVehicle : public SpecializedVehicle<T, Type> {
|
|||||||
assert(this->z_pos == GetSlopePixelZ(this->x_pos, this->y_pos));
|
assert(this->z_pos == GetSlopePixelZ(this->x_pos, this->y_pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UpdateZPositionInWormhole();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the vehicle is in a slope and sets the required flags in that case.
|
* Checks if the vehicle is in a slope and sets the required flags in that case.
|
||||||
* @param new_tile True if the vehicle reached a new tile.
|
* @param new_tile True if the vehicle reached a new tile.
|
||||||
* @param update_delta Indicates to also update the delta.
|
* @param update_delta Indicates to also update the delta.
|
||||||
* @return Old height of the vehicle.
|
* @return Old height of the vehicle.
|
||||||
*/
|
*/
|
||||||
inline int UpdateInclination(bool new_tile, bool update_delta)
|
inline int UpdateInclination(bool new_tile, bool update_delta, bool in_wormhole = false)
|
||||||
{
|
{
|
||||||
int old_z = this->z_pos;
|
int old_z = this->z_pos;
|
||||||
|
|
||||||
if (new_tile) {
|
if (in_wormhole) {
|
||||||
|
this->UpdateZPositionInWormhole();
|
||||||
|
} else if (new_tile) {
|
||||||
this->UpdateZPositionAndInclination();
|
this->UpdateZPositionAndInclination();
|
||||||
} else {
|
} else {
|
||||||
this->UpdateZPosition();
|
this->UpdateZPosition();
|
||||||
|
@@ -1184,6 +1184,7 @@ bool IndividualRoadVehicleController(RoadVehicle *v, const RoadVehicle *prev)
|
|||||||
v->x_pos = gp.x;
|
v->x_pos = gp.x;
|
||||||
v->y_pos = gp.y;
|
v->y_pos = gp.y;
|
||||||
v->UpdatePosition();
|
v->UpdatePosition();
|
||||||
|
RoadZPosAffectSpeed(v, v->UpdateInclination(false, false, true));
|
||||||
if (v->IsDrawn()) v->Vehicle::UpdateViewport(true);
|
if (v->IsDrawn()) v->Vehicle::UpdateViewport(true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1555,7 +1556,7 @@ again:
|
|||||||
v->x_pos = x;
|
v->x_pos = x;
|
||||||
v->y_pos = y;
|
v->y_pos = y;
|
||||||
v->UpdatePosition();
|
v->UpdatePosition();
|
||||||
RoadZPosAffectSpeed(v, v->UpdateInclination(false, true));
|
RoadZPosAffectSpeed(v, v->UpdateInclination(false, true, v->state == RVSB_WORMHOLE));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1685,6 +1685,7 @@ static void UpdateStatusAfterSwap(Train *v)
|
|||||||
}
|
}
|
||||||
|
|
||||||
v->UpdatePosition();
|
v->UpdatePosition();
|
||||||
|
if (v->track == TRACK_BIT_WORMHOLE) v->UpdateInclination(false, false, true);
|
||||||
v->UpdateViewport(true, true);
|
v->UpdateViewport(true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3903,6 +3904,15 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse)
|
|||||||
v->x_pos = gp.x;
|
v->x_pos = gp.x;
|
||||||
v->y_pos = gp.y;
|
v->y_pos = gp.y;
|
||||||
v->UpdatePosition();
|
v->UpdatePosition();
|
||||||
|
if (v->track == TRACK_BIT_WORMHOLE) {
|
||||||
|
/* update the Z position of the vehicle */
|
||||||
|
int old_z = v->UpdateInclination(false, false, true);
|
||||||
|
|
||||||
|
if (prev == NULL) {
|
||||||
|
/* This is the first vehicle in the train */
|
||||||
|
AffectSpeedByZChange(v, old_z);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (v->IsDrawn()) v->Vehicle::UpdateViewport(true);
|
if (v->IsDrawn()) v->Vehicle::UpdateViewport(true);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -3919,7 +3929,7 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* update the Z position of the vehicle */
|
/* update the Z position of the vehicle */
|
||||||
int old_z = v->UpdateInclination(gp.new_tile != gp.old_tile, false);
|
int old_z = v->UpdateInclination(gp.new_tile != gp.old_tile, false, v->track == TRACK_BIT_WORMHOLE);
|
||||||
|
|
||||||
if (prev == NULL) {
|
if (prev == NULL) {
|
||||||
/* This is the first vehicle in the train */
|
/* This is the first vehicle in the train */
|
||||||
|
Reference in New Issue
Block a user