mirror of
https://github.com/JGRennison/OpenTTD-patches.git
synced 2024-11-11 13:10:45 +00:00
Refactor CallVehicleTicks vehicle loop
This commit is contained in:
parent
5995e825bc
commit
e5b61e0b6c
@ -380,6 +380,8 @@ CommandCost CmdBuildAircraft(TileIndex tile, DoCommandFlag flags, const Engine *
|
||||
u->SetNext(w);
|
||||
w->UpdatePosition();
|
||||
}
|
||||
|
||||
InvalidateVehicleTickCaches();
|
||||
}
|
||||
|
||||
return CommandCost();
|
||||
@ -2131,8 +2133,6 @@ bool Aircraft::Tick()
|
||||
{
|
||||
if (!this->IsNormalAircraft()) return true;
|
||||
|
||||
PerformanceAccumulator framerate(PFE_GL_AIRCRAFT);
|
||||
|
||||
this->tick_counter++;
|
||||
|
||||
if (!(this->vehstatus & VS_STOPPED)) this->running_ticks++;
|
||||
|
@ -568,6 +568,7 @@ static bool DisasterTick_Big_Ufo(DisasterVehicle *v)
|
||||
DisasterVehicle *u = new DisasterVehicle(-6 * (int)TILE_SIZE, v->y_pos, DIR_SW, ST_BIG_UFO_DESTROYER, v->index);
|
||||
DisasterVehicle *w = new DisasterVehicle(-6 * (int)TILE_SIZE, v->y_pos, DIR_SW, ST_BIG_UFO_DESTROYER_SHADOW);
|
||||
u->SetNext(w);
|
||||
InvalidateVehicleTickCaches();
|
||||
} else if (v->current_order.GetDestination() == 0) {
|
||||
int x = TileX(v->dest_tile) * TILE_SIZE;
|
||||
int y = TileY(v->dest_tile) * TILE_SIZE;
|
||||
@ -727,6 +728,8 @@ static void Disaster_Zeppeliner_Init()
|
||||
/* Allocate shadow */
|
||||
DisasterVehicle *u = new DisasterVehicle(x, 0, DIR_SE, ST_ZEPPELINER_SHADOW);
|
||||
v->SetNext(u);
|
||||
|
||||
InvalidateVehicleTickCaches();
|
||||
}
|
||||
|
||||
|
||||
@ -745,6 +748,8 @@ static void Disaster_Small_Ufo_Init()
|
||||
/* Allocate shadow */
|
||||
DisasterVehicle *u = new DisasterVehicle(x, 0, DIR_SE, ST_SMALL_UFO_SHADOW);
|
||||
v->SetNext(u);
|
||||
|
||||
InvalidateVehicleTickCaches();
|
||||
}
|
||||
|
||||
|
||||
@ -771,6 +776,8 @@ static void Disaster_Airplane_Init()
|
||||
DisasterVehicle *v = new DisasterVehicle(x, y, DIR_NE, ST_AIRPLANE);
|
||||
DisasterVehicle *u = new DisasterVehicle(x, y, DIR_NE, ST_AIRPLANE_SHADOW);
|
||||
v->SetNext(u);
|
||||
|
||||
InvalidateVehicleTickCaches();
|
||||
}
|
||||
|
||||
|
||||
@ -799,6 +806,8 @@ static void Disaster_Helicopter_Init()
|
||||
|
||||
DisasterVehicle *w = new DisasterVehicle(x, y, DIR_SW, ST_HELICOPTER_ROTORS);
|
||||
u->SetNext(w);
|
||||
|
||||
InvalidateVehicleTickCaches();
|
||||
}
|
||||
|
||||
|
||||
@ -817,6 +826,8 @@ static void Disaster_Big_Ufo_Init()
|
||||
/* Allocate shadow */
|
||||
DisasterVehicle *u = new DisasterVehicle(x, y, DIR_NW, ST_BIG_UFO_SHADOW);
|
||||
v->SetNext(u);
|
||||
|
||||
InvalidateVehicleTickCaches();
|
||||
}
|
||||
|
||||
|
||||
@ -840,6 +851,8 @@ static void Disaster_Submarine_Init(DisasterSubType subtype)
|
||||
if (!IsWaterTile(TileVirtXY(x, y))) return;
|
||||
|
||||
new DisasterVehicle(x, y, dir, subtype);
|
||||
|
||||
InvalidateVehicleTickCaches();
|
||||
}
|
||||
|
||||
/* Curious submarine #1, just floats around */
|
||||
|
@ -19,6 +19,8 @@
|
||||
#include "effectvehicle_func.h"
|
||||
#include "effectvehicle_base.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "safeguards.h"
|
||||
|
||||
|
||||
@ -632,6 +634,8 @@ EffectVehicle *CreateEffectVehicle(int x, int y, int z, EffectVehicleType type)
|
||||
|
||||
v->UpdatePositionAndViewport();
|
||||
|
||||
v->AddEffectVehicleToTickCache();
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
@ -686,3 +690,23 @@ TransparencyOption EffectVehicle::GetTransparencyOption() const
|
||||
{
|
||||
return _effect_transparency_options[this->subtype];
|
||||
}
|
||||
|
||||
extern std::vector<Vehicle *> _tick_other_veh_cache;
|
||||
extern bool _tick_caches_valid;
|
||||
|
||||
void EffectVehicle::AddEffectVehicleToTickCache()
|
||||
{
|
||||
if (!_tick_caches_valid) return;
|
||||
_tick_other_veh_cache.erase(std::remove(_tick_other_veh_cache.begin(), _tick_other_veh_cache.end(), nullptr), _tick_other_veh_cache.end());
|
||||
_tick_other_veh_cache.insert(std::upper_bound(_tick_other_veh_cache.begin(), _tick_other_veh_cache.end(), this, [&](const Vehicle *a, const Vehicle *b) {
|
||||
return a->index < b->index;
|
||||
}), this);
|
||||
}
|
||||
|
||||
void EffectVehicle::RemoveEffectVehicleFromTickCache()
|
||||
{
|
||||
if (!_tick_caches_valid) return;
|
||||
for (auto &v : _tick_other_veh_cache) {
|
||||
if (v == this) v = nullptr;
|
||||
}
|
||||
}
|
||||
|
@ -30,11 +30,13 @@ struct EffectVehicle FINAL : public SpecializedVehicle<EffectVehicle, VEH_EFFECT
|
||||
/** We don't want GCC to zero our struct! It already is zeroed and has an index! */
|
||||
EffectVehicle() : SpecializedVehicleBase() {}
|
||||
/** We want to 'destruct' the right class. */
|
||||
virtual ~EffectVehicle() {}
|
||||
virtual ~EffectVehicle() { this->RemoveEffectVehicleFromTickCache(); }
|
||||
|
||||
void UpdateDeltaXY();
|
||||
bool Tick();
|
||||
TransparencyOption GetTransparencyOption() const;
|
||||
void AddEffectVehicleToTickCache();
|
||||
void RemoveEffectVehicleFromTickCache();
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -252,6 +252,8 @@ int GroundVehicle<T, Type>::GetAcceleration()
|
||||
!(Train::From(this)->flags & (VRF_IS_BROKEN | (1 << VRF_TRAIN_STUCK))) &&
|
||||
this->cur_speed < 3 && accel < 5) {
|
||||
SetBit(Train::From(this)->flags, VRF_TOO_HEAVY);
|
||||
extern std::vector<Train *> _tick_train_too_heavy_cache;
|
||||
_tick_train_too_heavy_cache.push_back(Train::From(this));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -366,6 +366,24 @@ struct GroundVehicle : public SpecializedVehicle<T, Type> {
|
||||
*/
|
||||
inline bool IsRearDualheaded() const { return this->IsMultiheaded() && !this->IsEngine(); }
|
||||
|
||||
/**
|
||||
* Check if the vehicle is a front engine.
|
||||
* @return Returns true if the vehicle is a front engine.
|
||||
*/
|
||||
inline bool IsFrontEngine() const
|
||||
{
|
||||
return HasBit(this->subtype, GVSF_FRONT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the vehicle is an articulated part of an engine.
|
||||
* @return Returns true if the vehicle is an articulated part.
|
||||
*/
|
||||
inline bool IsArticulatedPart() const
|
||||
{
|
||||
return HasBit(this->subtype, GVSF_ARTICULATED_PART);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the GUI variant of the current speed of the vehicle.
|
||||
* Also mark the widget dirty when that is needed, i.e. when
|
||||
|
@ -131,6 +131,9 @@ void InitializeGame(uint size_x, uint size_y, bool reset_date, bool reset_settin
|
||||
|
||||
InitializeEconomy();
|
||||
|
||||
InvalidateVehicleTickCaches();
|
||||
ClearVehicleTickCaches();
|
||||
|
||||
ResetObjectToPlace();
|
||||
ResetRailPlacementSnapping();
|
||||
|
||||
|
@ -374,6 +374,8 @@ static void ShutdownGame()
|
||||
|
||||
ViewportMapClearTunnelCache();
|
||||
ViewportClearStationSignCache();
|
||||
InvalidateVehicleTickCaches();
|
||||
ClearVehicleTickCaches();
|
||||
ClearCommandLog();
|
||||
}
|
||||
|
||||
|
@ -332,6 +332,8 @@ CommandCost CmdBuildRoadVehicle(TileIndex tile, DoCommandFlag flags, const Engin
|
||||
v->UpdatePosition();
|
||||
|
||||
CheckConsistencyOfArticulatedVehicle(v);
|
||||
|
||||
InvalidateVehicleTickCaches();
|
||||
}
|
||||
|
||||
return CommandCost();
|
||||
@ -1665,10 +1667,6 @@ Money RoadVehicle::GetRunningCost() const
|
||||
|
||||
bool RoadVehicle::Tick()
|
||||
{
|
||||
PerformanceAccumulator framerate(PFE_GL_ROADVEHS);
|
||||
|
||||
this->tick_counter++;
|
||||
|
||||
if (this->IsFrontEngine()) {
|
||||
if (!(this->IsRoadVehicleStopped())) this->running_ticks++;
|
||||
return RoadVehController(this);
|
||||
|
@ -3620,6 +3620,9 @@ bool AfterLoadGame()
|
||||
AfterLoadTraceRestrict();
|
||||
AfterLoadTemplateVehiclesUpdateImage();
|
||||
|
||||
InvalidateVehicleTickCaches();
|
||||
ClearVehicleTickCaches();
|
||||
|
||||
/* Show this message last to avoid covering up an error message if we bail out part way */
|
||||
switch (gcf_res) {
|
||||
case GLC_COMPATIBLE: ShowErrorMessage(STR_NEWGRF_COMPATIBLE_LOAD_WARNING, INVALID_STRING_ID, WL_CRITICAL); break;
|
||||
|
@ -839,8 +839,6 @@ reverse_direction:
|
||||
|
||||
bool Ship::Tick()
|
||||
{
|
||||
PerformanceAccumulator framerate(PFE_GL_SHIPS);
|
||||
|
||||
if (!(this->vehstatus & VS_STOPPED)) this->running_ticks++;
|
||||
|
||||
ShipController(this);
|
||||
@ -924,6 +922,7 @@ CommandCost CmdBuildShip(TileIndex tile, DoCommandFlag flags, const Engine *e, u
|
||||
v->InvalidateNewGRFCacheOfChain();
|
||||
|
||||
v->UpdatePosition();
|
||||
InvalidateVehicleTickCaches();
|
||||
}
|
||||
|
||||
return CommandCost();
|
||||
|
@ -172,6 +172,8 @@ void Train::ConsistChanged(ConsistChangeFlags allowed_changes)
|
||||
|
||||
assert(this->IsFrontEngine() || this->IsFreeWagon());
|
||||
|
||||
InvalidateVehicleTickCaches();
|
||||
|
||||
const RailVehicleInfo *rvi_v = RailVehInfo(this->engine_type);
|
||||
EngineID first_engine = this->IsFrontEngine() ? this->engine_type : INVALID_ENGINE;
|
||||
this->gcache.cached_total_length = 0;
|
||||
@ -4941,10 +4943,6 @@ Money Train::GetRunningCost() const
|
||||
*/
|
||||
bool Train::Tick()
|
||||
{
|
||||
PerformanceAccumulator framerate(PFE_GL_TRAINS);
|
||||
|
||||
this->tick_counter++;
|
||||
|
||||
if (this->IsFrontEngine()) {
|
||||
if (!(this->vehstatus & VS_STOPPED) || this->cur_speed > 0) this->running_ticks++;
|
||||
|
||||
|
233
src/vehicle.cpp
233
src/vehicle.cpp
@ -1019,6 +1019,8 @@ Vehicle::~Vehicle()
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->type != VEH_EFFECT) InvalidateVehicleTickCaches();
|
||||
|
||||
if (this->breakdowns_since_last_service) _vehicles_to_pay_repair.erase(this);
|
||||
|
||||
if (this->type < VEH_BEGIN || this->type >= VEH_COMPANY_END) {
|
||||
@ -1122,6 +1124,91 @@ static void ShowAutoReplaceAdviceMessage(const CommandCost &res, const Vehicle *
|
||||
AddVehicleAdviceNewsItem(message, v->index);
|
||||
}
|
||||
|
||||
bool _tick_caches_valid = false;
|
||||
std::vector<Train *> _tick_train_too_heavy_cache;
|
||||
std::vector<Train *> _tick_train_front_cache;
|
||||
std::vector<RoadVehicle *> _tick_road_veh_front_cache;
|
||||
std::vector<Aircraft *> _tick_aircraft_front_cache;
|
||||
std::vector<Ship *> _tick_ship_cache;
|
||||
std::vector<Vehicle *> _tick_other_veh_cache;
|
||||
|
||||
void ClearVehicleTickCaches()
|
||||
{
|
||||
_tick_train_too_heavy_cache.clear();
|
||||
_tick_train_front_cache.clear();
|
||||
_tick_road_veh_front_cache.clear();
|
||||
_tick_aircraft_front_cache.clear();
|
||||
_tick_ship_cache.clear();
|
||||
_tick_other_veh_cache.clear();
|
||||
}
|
||||
|
||||
void RebuildVehicleTickCaches()
|
||||
{
|
||||
Vehicle *v = NULL;
|
||||
SCOPE_INFO_FMT([&v], "RebuildVehicleTickCaches: %s", scope_dumper().VehicleInfo(v));
|
||||
|
||||
ClearVehicleTickCaches();
|
||||
|
||||
FOR_ALL_VEHICLES(v) {
|
||||
switch (v->type) {
|
||||
default:
|
||||
_tick_other_veh_cache.push_back(v);
|
||||
break;
|
||||
|
||||
case VEH_TRAIN:
|
||||
if (HasBit(Train::From(v)->flags, VRF_TOO_HEAVY)) _tick_train_too_heavy_cache.push_back(Train::From(v));
|
||||
if (v->Previous() == nullptr) _tick_train_front_cache.push_back(Train::From(v));
|
||||
break;
|
||||
|
||||
case VEH_ROAD:
|
||||
if (v->Previous() == nullptr) _tick_road_veh_front_cache.push_back(RoadVehicle::From(v));
|
||||
break;
|
||||
|
||||
case VEH_AIRCRAFT:
|
||||
if (v->Previous() == nullptr) _tick_aircraft_front_cache.push_back(Aircraft::From(v));
|
||||
break;
|
||||
|
||||
case VEH_SHIP:
|
||||
_tick_ship_cache.push_back(Ship::From(v));
|
||||
break;
|
||||
}
|
||||
}
|
||||
_tick_caches_valid = true;
|
||||
}
|
||||
|
||||
void VehicleTickCargoAging(Vehicle *v)
|
||||
{
|
||||
if (v->vcache.cached_cargo_age_period != 0) {
|
||||
v->cargo_age_counter = min(v->cargo_age_counter, v->vcache.cached_cargo_age_period);
|
||||
if (--v->cargo_age_counter == 0) {
|
||||
v->cargo.AgeCargo();
|
||||
v->cargo_age_counter = v->vcache.cached_cargo_age_period;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VehicleTickMotion(Vehicle *v, Vehicle *front)
|
||||
{
|
||||
/* Do not play any sound when crashed */
|
||||
if (front->vehstatus & VS_CRASHED) return;
|
||||
|
||||
/* Do not play any sound when in depot or tunnel */
|
||||
if (v->vehstatus & VS_HIDDEN) return;
|
||||
|
||||
v->motion_counter += front->cur_speed;
|
||||
if (_settings_client.sound.vehicle) {
|
||||
/* Play a running sound if the motion counter passes 256 (Do we not skip sounds?) */
|
||||
if (GB(v->motion_counter, 0, 8) < front->cur_speed) PlayVehicleSound(v, VSE_RUNNING);
|
||||
|
||||
/* Play an alternating running sound every 16 ticks */
|
||||
if (GB(v->tick_counter, 0, 4) == 0) {
|
||||
/* Play running sound when speed > 0 and not braking */
|
||||
bool running = (front->cur_speed > 0) && !(front->vehstatus & (VS_STOPPED | VS_TRAIN_SLOWING));
|
||||
PlayVehicleSound(v, running ? VSE_RUNNING_16 : VSE_STOPPED_16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CallVehicleTicks()
|
||||
{
|
||||
_vehicles_to_autoreplace.Clear();
|
||||
@ -1137,98 +1224,72 @@ void CallVehicleTicks()
|
||||
SCOPE_INFO_FMT([&st], "CallVehicleTicks: LoadUnloadStation: %s", scope_dumper().StationInfo(st));
|
||||
FOR_ALL_STATIONS(st) LoadUnloadStation(st);
|
||||
}
|
||||
PerformanceAccumulator::Reset(PFE_GL_TRAINS);
|
||||
PerformanceAccumulator::Reset(PFE_GL_ROADVEHS);
|
||||
PerformanceAccumulator::Reset(PFE_GL_SHIPS);
|
||||
PerformanceAccumulator::Reset(PFE_GL_AIRCRAFT);
|
||||
|
||||
if (!_tick_caches_valid) RebuildVehicleTickCaches();
|
||||
|
||||
Vehicle *v = NULL;
|
||||
SCOPE_INFO_FMT([&v], "CallVehicleTicks: %s", scope_dumper().VehicleInfo(v));
|
||||
FOR_ALL_VEHICLES(v) {
|
||||
/* Vehicle could be deleted in this tick */
|
||||
auto tick = [](Vehicle *v) -> bool {
|
||||
/* De-virtualise most common cases */
|
||||
if (v->type == VEH_TRAIN) return Train::From(v)->Train::Tick();
|
||||
if (v->type == VEH_ROAD) return RoadVehicle::From(v)->RoadVehicle::Tick();
|
||||
if (v->type == VEH_AIRCRAFT) return Aircraft::From(v)->Aircraft::Tick();
|
||||
return v->Tick();
|
||||
};
|
||||
if (!tick(v)) {
|
||||
assert(Vehicle::Get(vehicle_index) == NULL);
|
||||
continue;
|
||||
}
|
||||
|
||||
assert(Vehicle::Get(vehicle_index) == v);
|
||||
|
||||
switch (v->type) {
|
||||
default: break;
|
||||
|
||||
case VEH_TRAIN:
|
||||
if (HasBit(Train::From(v)->flags, VRF_TOO_HEAVY)) {
|
||||
if (v->owner == _local_company) {
|
||||
SetDParam(0, v->index);
|
||||
SetDParam(1, STR_ERROR_TRAIN_TOO_HEAVY);
|
||||
AddVehicleNewsItem(STR_ERROR_TRAIN_TOO_HEAVY, NT_ADVICE, v->index);
|
||||
}
|
||||
ClrBit(Train::From(v)->flags, VRF_TOO_HEAVY);
|
||||
{
|
||||
PerformanceMeasurer framerate(PFE_GL_TRAINS);
|
||||
for (Train *t : _tick_train_too_heavy_cache) {
|
||||
if (HasBit(t->flags, VRF_TOO_HEAVY)) {
|
||||
if (t->owner == _local_company) {
|
||||
SetDParam(0, t->index);
|
||||
SetDParam(1, STR_ERROR_TRAIN_TOO_HEAVY);
|
||||
AddVehicleNewsItem(STR_ERROR_TRAIN_TOO_HEAVY, NT_ADVICE, t->index);
|
||||
}
|
||||
/* FALL THROUGH */
|
||||
case VEH_ROAD:
|
||||
case VEH_AIRCRAFT:
|
||||
case VEH_SHIP: {
|
||||
Vehicle *front = v->First();
|
||||
|
||||
if (v->vcache.cached_cargo_age_period != 0) {
|
||||
v->cargo_age_counter = min(v->cargo_age_counter, v->vcache.cached_cargo_age_period);
|
||||
if (--v->cargo_age_counter == 0) {
|
||||
v->cargo.AgeCargo();
|
||||
v->cargo_age_counter = v->vcache.cached_cargo_age_period;
|
||||
}
|
||||
}
|
||||
|
||||
/* Do not play any sound when crashed */
|
||||
if (front->vehstatus & VS_CRASHED) continue;
|
||||
|
||||
/* Do not play any sound when in depot or tunnel */
|
||||
if (v->vehstatus & VS_HIDDEN) continue;
|
||||
|
||||
/* Do not play any sound when stopped */
|
||||
if ((front->vehstatus & VS_STOPPED) && (front->type != VEH_TRAIN || front->cur_speed == 0)) continue;
|
||||
|
||||
/* Check vehicle type specifics */
|
||||
switch (v->type) {
|
||||
case VEH_TRAIN:
|
||||
if (Train::From(v)->IsWagon()) continue;
|
||||
break;
|
||||
|
||||
case VEH_ROAD:
|
||||
if (!RoadVehicle::From(v)->IsFrontEngine()) continue;
|
||||
break;
|
||||
|
||||
case VEH_AIRCRAFT:
|
||||
if (!Aircraft::From(v)->IsNormalAircraft()) continue;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
v->motion_counter += front->cur_speed;
|
||||
if (_settings_client.sound.vehicle) {
|
||||
/* Play a running sound if the motion counter passes 256 (Do we not skip sounds?) */
|
||||
if (GB(v->motion_counter, 0, 8) < front->cur_speed) PlayVehicleSound(v, VSE_RUNNING);
|
||||
|
||||
/* Play an alternating running sound every 16 ticks */
|
||||
if (GB(v->tick_counter, 0, 4) == 0) {
|
||||
/* Play running sound when speed > 0 and not braking */
|
||||
bool running = (front->cur_speed > 0) && !(front->vehstatus & (VS_STOPPED | VS_TRAIN_SLOWING));
|
||||
PlayVehicleSound(v, running ? VSE_RUNNING_16 : VSE_STOPPED_16);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
ClrBit(t->flags, VRF_TOO_HEAVY);
|
||||
}
|
||||
}
|
||||
_tick_train_too_heavy_cache.clear();
|
||||
for (Train *front : _tick_train_front_cache) {
|
||||
v = front;
|
||||
if (!front->Train::Tick()) continue;
|
||||
for (Train *u = front; u != nullptr; u = u->Next()) {
|
||||
u->tick_counter++;
|
||||
VehicleTickCargoAging(u);
|
||||
if (!u->IsWagon() && !((front->vehstatus & VS_STOPPED) && front->cur_speed == 0)) VehicleTickMotion(u, front);
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
PerformanceMeasurer framerate(PFE_GL_ROADVEHS);
|
||||
for (RoadVehicle *front : _tick_road_veh_front_cache) {
|
||||
v = front;
|
||||
if (!front->RoadVehicle::Tick()) continue;
|
||||
for (RoadVehicle *u = front; u != nullptr; u = u->Next()) {
|
||||
u->tick_counter++;
|
||||
VehicleTickCargoAging(u);
|
||||
}
|
||||
if (!(front->vehstatus & VS_STOPPED)) VehicleTickMotion(front, front);
|
||||
}
|
||||
}
|
||||
{
|
||||
PerformanceMeasurer framerate(PFE_GL_AIRCRAFT);
|
||||
for (Aircraft *front : _tick_aircraft_front_cache) {
|
||||
v = front;
|
||||
if (!front->Aircraft::Tick()) continue;
|
||||
for (Aircraft *u = front; u != nullptr; u = u->Next()) {
|
||||
VehicleTickCargoAging(u);
|
||||
}
|
||||
if (!(front->vehstatus & VS_STOPPED)) VehicleTickMotion(front, front);
|
||||
}
|
||||
}
|
||||
{
|
||||
PerformanceMeasurer framerate(PFE_GL_SHIPS);
|
||||
for (Ship *s : _tick_ship_cache) {
|
||||
v = s;
|
||||
if (!s->Ship::Tick()) continue;
|
||||
VehicleTickCargoAging(s);
|
||||
if (!(s->vehstatus & VS_STOPPED)) VehicleTickMotion(s, s);
|
||||
}
|
||||
}
|
||||
{
|
||||
for (Vehicle *u : _tick_other_veh_cache) {
|
||||
if (!u) continue;
|
||||
v = u;
|
||||
u->Tick();
|
||||
}
|
||||
}
|
||||
v = NULL;
|
||||
|
||||
|
@ -1280,4 +1280,12 @@ struct FreeUnitIDGenerator {
|
||||
/** Sentinel for an invalid coordinate. */
|
||||
static const int32 INVALID_COORD = 0x7fffffff;
|
||||
|
||||
inline void InvalidateVehicleTickCaches()
|
||||
{
|
||||
extern bool _tick_caches_valid;
|
||||
_tick_caches_valid = false;
|
||||
}
|
||||
|
||||
void ClearVehicleTickCaches();
|
||||
|
||||
#endif /* VEHICLE_BASE_H */
|
||||
|
Loading…
Reference in New Issue
Block a user