Add several NewGRF variables to vehicle image callback whitelist
Add vehicle flags to control cached image invalidation Various refactorings
This commit is contained in:
@@ -235,6 +235,7 @@ add_files(
|
|||||||
newgrf_airporttiles.h
|
newgrf_airporttiles.h
|
||||||
newgrf_animation_base.h
|
newgrf_animation_base.h
|
||||||
newgrf_animation_type.h
|
newgrf_animation_type.h
|
||||||
|
newgrf_cache_check.h
|
||||||
newgrf_callbacks.h
|
newgrf_callbacks.h
|
||||||
newgrf_canal.cpp
|
newgrf_canal.cpp
|
||||||
newgrf_canal.h
|
newgrf_canal.h
|
||||||
|
@@ -67,6 +67,7 @@ int GetAircraftFlightLevel(T *v, bool takeoff = false);
|
|||||||
struct AircraftCache {
|
struct AircraftCache {
|
||||||
uint32 cached_max_range_sqr; ///< Cached squared maximum range.
|
uint32 cached_max_range_sqr; ///< Cached squared maximum range.
|
||||||
uint16 cached_max_range; ///< Cached maximum range.
|
uint16 cached_max_range; ///< Cached maximum range.
|
||||||
|
byte image_movement_state; ///< Cached image aircraft movement state
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -1276,6 +1276,7 @@ static void HandleAircraftSmoke(Aircraft *v, bool mode)
|
|||||||
if (v->state != FLYING && v->state != LANDING && v->breakdown_type == BREAKDOWN_AIRCRAFT_SPEED) {
|
if (v->state != FLYING && v->state != LANDING && v->breakdown_type == BREAKDOWN_AIRCRAFT_SPEED) {
|
||||||
v->vehstatus &= ~VS_AIRCRAFT_BROKEN;
|
v->vehstatus &= ~VS_AIRCRAFT_BROKEN;
|
||||||
v->breakdown_ctr = 0;
|
v->breakdown_ctr = 0;
|
||||||
|
v->InvalidateImageCacheOfChain();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1334,7 +1335,7 @@ TileIndex Aircraft::GetOrderStationLocation(StationID station)
|
|||||||
void Aircraft::MarkDirty()
|
void Aircraft::MarkDirty()
|
||||||
{
|
{
|
||||||
this->colourmap = PAL_NONE;
|
this->colourmap = PAL_NONE;
|
||||||
this->cur_image_valid_dir = INVALID_DIR;
|
this->InvalidateImageCache();
|
||||||
this->UpdateViewport(true, false);
|
this->UpdateViewport(true, false);
|
||||||
if (this->subtype == AIR_HELICOPTER) {
|
if (this->subtype == AIR_HELICOPTER) {
|
||||||
Aircraft *rotor = this->Next()->Next();
|
Aircraft *rotor = this->Next()->Next();
|
||||||
@@ -2161,6 +2162,15 @@ bool Aircraft::Tick()
|
|||||||
if (!AircraftEventHandler(this, i)) return false;
|
if (!AircraftEventHandler(this, i)) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (HasBit(this->vcache.cached_veh_flags, VCF_REDRAW_ON_SPEED_CHANGE)) {
|
||||||
|
extern byte MapAircraftMovementState(const Aircraft *v);
|
||||||
|
byte state = MapAircraftMovementState(this);
|
||||||
|
if (state != this->acache.image_movement_state) {
|
||||||
|
this->InvalidateImageCacheOfChain();
|
||||||
|
this->acache.image_movement_state = state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1045,7 +1045,10 @@ CommandCost CmdSetCompanyColour(TileIndex tile, DoCommandFlag flags, uint32 p1,
|
|||||||
|
|
||||||
/* Company colour data is indirectly cached. */
|
/* Company colour data is indirectly cached. */
|
||||||
for (Vehicle *v : Vehicle::Iterate()) {
|
for (Vehicle *v : Vehicle::Iterate()) {
|
||||||
if (v->owner == _current_company) v->InvalidateNewGRFCache();
|
if (v->owner == _current_company) {
|
||||||
|
v->InvalidateNewGRFCache();
|
||||||
|
v->InvalidateImageCache();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void UpdateObjectColours(const Company *c);
|
extern void UpdateObjectColours(const Company *c);
|
||||||
|
@@ -204,7 +204,7 @@ void DisasterVehicle::UpdatePosition(int x, int y, int z)
|
|||||||
this->z_pos = z;
|
this->z_pos = z;
|
||||||
this->tile = TileVirtXY(x, y);
|
this->tile = TileVirtXY(x, y);
|
||||||
|
|
||||||
this->cur_image_valid_dir = INVALID_DIR;
|
this->InvalidateImageCache();
|
||||||
this->UpdateImage();
|
this->UpdateImage();
|
||||||
this->UpdatePositionAndViewport();
|
this->UpdatePositionAndViewport();
|
||||||
|
|
||||||
@@ -218,7 +218,7 @@ void DisasterVehicle::UpdatePosition(int x, int y, int z)
|
|||||||
safe_y = Clamp(u->y_pos, 0, MapMaxY() * TILE_SIZE);
|
safe_y = Clamp(u->y_pos, 0, MapMaxY() * TILE_SIZE);
|
||||||
u->z_pos = GetSlopePixelZ(safe_x, safe_y);
|
u->z_pos = GetSlopePixelZ(safe_x, safe_y);
|
||||||
u->direction = this->direction;
|
u->direction = this->direction;
|
||||||
u->cur_image_valid_dir = INVALID_DIR;
|
u->InvalidateImageCache();
|
||||||
|
|
||||||
u->UpdateImage();
|
u->UpdateImage();
|
||||||
u->UpdatePositionAndViewport();
|
u->UpdatePositionAndViewport();
|
||||||
|
@@ -466,6 +466,7 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner)
|
|||||||
/* Owner changes, clear cache */
|
/* Owner changes, clear cache */
|
||||||
v->colourmap = PAL_NONE;
|
v->colourmap = PAL_NONE;
|
||||||
v->InvalidateNewGRFCache();
|
v->InvalidateNewGRFCache();
|
||||||
|
v->InvalidateImageCache();
|
||||||
|
|
||||||
if (v->IsEngineCountable()) {
|
if (v->IsEngineCountable()) {
|
||||||
GroupStatistics::CountEngine(v, 1);
|
GroupStatistics::CountEngine(v, 1);
|
||||||
|
@@ -108,7 +108,7 @@ void GroundVehicle<T, Type>::CargoChanged()
|
|||||||
weight += current_weight;
|
weight += current_weight;
|
||||||
/* Slope steepness is in percent, result in N. */
|
/* Slope steepness is in percent, result in N. */
|
||||||
u->gcache.cached_slope_resistance = current_weight * u->GetSlopeSteepness() * 100;
|
u->gcache.cached_slope_resistance = current_weight * u->GetSlopeSteepness() * 100;
|
||||||
u->cur_image_valid_dir = INVALID_DIR;
|
u->InvalidateImageCache();
|
||||||
}
|
}
|
||||||
ClrBit(this->vcache.cached_veh_flags, VCF_GV_ZERO_SLOPE_RESIST);
|
ClrBit(this->vcache.cached_veh_flags, VCF_GV_ZERO_SLOPE_RESIST);
|
||||||
|
|
||||||
|
@@ -398,6 +398,9 @@ struct GroundVehicle : public SpecializedVehicle<T, Type> {
|
|||||||
if (this->cur_speed != this->gcache.last_speed) {
|
if (this->cur_speed != this->gcache.last_speed) {
|
||||||
SetWindowWidgetDirty(WC_VEHICLE_VIEW, this->index, WID_VV_START_STOP);
|
SetWindowWidgetDirty(WC_VEHICLE_VIEW, this->index, WID_VV_START_STOP);
|
||||||
this->gcache.last_speed = this->cur_speed;
|
this->gcache.last_speed = this->cur_speed;
|
||||||
|
if (HasBit(this->vcache.cached_veh_flags, VCF_REDRAW_ON_SPEED_CHANGE)) {
|
||||||
|
this->InvalidateImageCacheOfChain();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -278,6 +278,7 @@ void PropagateChildLivery(const Group *g)
|
|||||||
for (Vehicle *u = v; u != nullptr; u = u->Next()) {
|
for (Vehicle *u = v; u != nullptr; u = u->Next()) {
|
||||||
u->colourmap = PAL_NONE;
|
u->colourmap = PAL_NONE;
|
||||||
u->InvalidateNewGRFCache();
|
u->InvalidateNewGRFCache();
|
||||||
|
u->InvalidateImageCache();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -544,6 +545,7 @@ static void AddVehicleToGroup(Vehicle *v, GroupID new_g)
|
|||||||
for (Vehicle *u = v; u != nullptr; u = u->Next()) {
|
for (Vehicle *u = v; u != nullptr; u = u->Next()) {
|
||||||
u->colourmap = PAL_NONE;
|
u->colourmap = PAL_NONE;
|
||||||
u->InvalidateNewGRFCache();
|
u->InvalidateNewGRFCache();
|
||||||
|
u->InvalidateImageCache();
|
||||||
u->UpdateViewport(true);
|
u->UpdateViewport(true);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -794,6 +796,7 @@ void SetTrainGroupID(Train *v, GroupID new_g)
|
|||||||
u->group_id = new_g;
|
u->group_id = new_g;
|
||||||
u->colourmap = PAL_NONE;
|
u->colourmap = PAL_NONE;
|
||||||
u->InvalidateNewGRFCache();
|
u->InvalidateNewGRFCache();
|
||||||
|
u->InvalidateImageCache();
|
||||||
u->UpdateViewport(true);
|
u->UpdateViewport(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -821,6 +824,7 @@ void UpdateTrainGroupID(Train *v)
|
|||||||
u->group_id = new_g;
|
u->group_id = new_g;
|
||||||
u->colourmap = PAL_NONE;
|
u->colourmap = PAL_NONE;
|
||||||
u->InvalidateNewGRFCache();
|
u->InvalidateNewGRFCache();
|
||||||
|
u->InvalidateImageCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update the Replace Vehicle Windows */
|
/* Update the Replace Vehicle Windows */
|
||||||
|
@@ -6354,6 +6354,19 @@ static void SkipAct5(ByteReader *buf)
|
|||||||
*/
|
*/
|
||||||
bool GetGlobalVariable(byte param, uint32 *value, const GRFFile *grffile)
|
bool GetGlobalVariable(byte param, uint32 *value, const GRFFile *grffile)
|
||||||
{
|
{
|
||||||
|
if (_sprite_group_resolve_check_veh_check) {
|
||||||
|
switch (param) {
|
||||||
|
case 0x00:
|
||||||
|
case 0x02:
|
||||||
|
case 0x09:
|
||||||
|
case 0x0A:
|
||||||
|
case 0x20:
|
||||||
|
case 0x23:
|
||||||
|
_sprite_group_resolve_check_veh_check = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (param) {
|
switch (param) {
|
||||||
case 0x00: // current date
|
case 0x00: // current date
|
||||||
*value = max(_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0);
|
*value = max(_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0);
|
||||||
|
@@ -38,7 +38,7 @@ struct AirportScopeResolver : public ScopeResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32 GetRandomBits() const override;
|
uint32 GetRandomBits() const override;
|
||||||
uint32 GetVariable(byte variable, uint32 parameter, bool *available) const override;
|
uint32 GetVariable(byte variable, uint32 parameter, GetVariableExtra *extra) const override;
|
||||||
void StorePSA(uint pos, int32 value) override;
|
void StorePSA(uint pos, int32 value) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -197,14 +197,14 @@ void AirportOverrideManager::SetEntitySpec(AirportSpec *as)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* virtual */ uint32 AirportScopeResolver::GetVariable(byte variable, uint32 parameter, bool *available) const
|
/* virtual */ uint32 AirportScopeResolver::GetVariable(byte variable, uint32 parameter, GetVariableExtra *extra) const
|
||||||
{
|
{
|
||||||
switch (variable) {
|
switch (variable) {
|
||||||
case 0x40: return this->layout;
|
case 0x40: return this->layout;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->st == nullptr) {
|
if (this->st == nullptr) {
|
||||||
*available = false;
|
extra->available = false;
|
||||||
return UINT_MAX;
|
return UINT_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,7 +216,7 @@ void AirportOverrideManager::SetEntitySpec(AirportSpec *as)
|
|||||||
case 0xFA: return Clamp(this->st->build_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0, 65535);
|
case 0xFA: return Clamp(this->st->build_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0, 65535);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this->st->GetNewGRFVariable(this->ro, variable, parameter, available);
|
return this->st->GetNewGRFVariable(this->ro, variable, parameter, &(extra->available));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* virtual */ const SpriteGroup *AirportResolverObject::ResolveReal(const RealSpriteGroup *group) const
|
/* virtual */ const SpriteGroup *AirportResolverObject::ResolveReal(const RealSpriteGroup *group) const
|
||||||
|
@@ -158,7 +158,7 @@ static uint32 GetAirportTileIDAtOffset(TileIndex tile, const Station *st, uint32
|
|||||||
return 0xFF << 8 | ats->grf_prop.subst_id; // so just give him the substitute
|
return 0xFF << 8 | ats->grf_prop.subst_id; // so just give him the substitute
|
||||||
}
|
}
|
||||||
|
|
||||||
/* virtual */ uint32 AirportTileScopeResolver::GetVariable(byte variable, uint32 parameter, bool *available) const
|
/* virtual */ uint32 AirportTileScopeResolver::GetVariable(byte variable, uint32 parameter, GetVariableExtra *extra) const
|
||||||
{
|
{
|
||||||
assert(this->st != nullptr);
|
assert(this->st != nullptr);
|
||||||
|
|
||||||
@@ -195,7 +195,7 @@ static uint32 GetAirportTileIDAtOffset(TileIndex tile, const Station *st, uint32
|
|||||||
|
|
||||||
DEBUG(grf, 1, "Unhandled airport tile variable 0x%X", variable);
|
DEBUG(grf, 1, "Unhandled airport tile variable 0x%X", variable);
|
||||||
|
|
||||||
*available = false;
|
extra->available = false;
|
||||||
return UINT_MAX;
|
return UINT_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -38,7 +38,7 @@ struct AirportTileScopeResolver : public ScopeResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32 GetRandomBits() const override;
|
uint32 GetRandomBits() const override;
|
||||||
uint32 GetVariable(byte variable, uint32 parameter, bool *available) const override;
|
uint32 GetVariable(byte variable, uint32 parameter, GetVariableExtra *extra) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Resolver for tiles of an airport. */
|
/** Resolver for tiles of an airport. */
|
||||||
|
15
src/newgrf_cache_check.h
Normal file
15
src/newgrf_cache_check.h
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of OpenTTD.
|
||||||
|
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
||||||
|
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @file newgrf_cache_check.h NewGRF caching checks. */
|
||||||
|
|
||||||
|
#ifndef NEWGRF_CACHE_CHECK_H
|
||||||
|
#define NEWGRF_CACHE_CHECK_H
|
||||||
|
|
||||||
|
extern bool _sprite_group_resolve_check_veh_check;
|
||||||
|
|
||||||
|
#endif /* NEWGRF_CACHE_CHECK_H */
|
@@ -30,7 +30,7 @@ struct CanalScopeResolver : public ScopeResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32 GetRandomBits() const override;
|
uint32 GetRandomBits() const override;
|
||||||
uint32 GetVariable(byte variable, uint32 parameter, bool *available) const override;
|
uint32 GetVariable(byte variable, uint32 parameter, GetVariableExtra *extra) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Resolver object for canals. */
|
/** Resolver object for canals. */
|
||||||
@@ -61,7 +61,7 @@ struct CanalResolverObject : public ResolverObject {
|
|||||||
return IsTileType(this->tile, MP_WATER) ? GetWaterTileRandomBits(this->tile) : 0;
|
return IsTileType(this->tile, MP_WATER) ? GetWaterTileRandomBits(this->tile) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* virtual */ uint32 CanalScopeResolver::GetVariable(byte variable, uint32 parameter, bool *available) const
|
/* virtual */ uint32 CanalScopeResolver::GetVariable(byte variable, uint32 parameter, GetVariableExtra *extra) const
|
||||||
{
|
{
|
||||||
switch (variable) {
|
switch (variable) {
|
||||||
/* Height of tile */
|
/* Height of tile */
|
||||||
@@ -104,7 +104,7 @@ struct CanalResolverObject : public ResolverObject {
|
|||||||
|
|
||||||
DEBUG(grf, 1, "Unhandled canal variable 0x%02X", variable);
|
DEBUG(grf, 1, "Unhandled canal variable 0x%02X", variable);
|
||||||
|
|
||||||
*available = false;
|
extra->available = false;
|
||||||
return UINT_MAX;
|
return UINT_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -167,7 +167,7 @@ public:
|
|||||||
* @param avail Return whether the variable is available.
|
* @param avail Return whether the variable is available.
|
||||||
* @return The resolved variable's value.
|
* @return The resolved variable's value.
|
||||||
*/
|
*/
|
||||||
virtual uint Resolve(uint index, uint var, uint param, bool *avail) const = 0;
|
virtual uint Resolve(uint index, uint var, uint param, GetVariableExtra *extra) const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to decide if the PSA needs a parameter or not.
|
* Used to decide if the PSA needs a parameter or not.
|
||||||
@@ -492,11 +492,11 @@ struct NewGRFInspectWindow : Window {
|
|||||||
if (nif->variables != nullptr) {
|
if (nif->variables != nullptr) {
|
||||||
this->DrawString(r, i++, "Variables:");
|
this->DrawString(r, i++, "Variables:");
|
||||||
for (const NIVariable *niv = nif->variables; niv->name != nullptr; niv++) {
|
for (const NIVariable *niv = nif->variables; niv->name != nullptr; niv++) {
|
||||||
bool avail = true;
|
GetVariableExtra extra;
|
||||||
uint param = HasVariableParameter(niv->var) ? NewGRFInspectWindow::var60params[GetFeatureNum(this->window_number)][niv->var - 0x60] : 0;
|
uint param = HasVariableParameter(niv->var) ? NewGRFInspectWindow::var60params[GetFeatureNum(this->window_number)][niv->var - 0x60] : 0;
|
||||||
uint value = nih->Resolve(index, niv->var, param, &avail);
|
uint value = nih->Resolve(index, niv->var, param, &extra);
|
||||||
|
|
||||||
if (!avail) continue;
|
if (!extra.available) continue;
|
||||||
|
|
||||||
if (HasVariableParameter(niv->var)) {
|
if (HasVariableParameter(niv->var)) {
|
||||||
this->DrawString(r, i++, " %02x[%02x]: %08x (%s)", niv->var, param, value, niv->name);
|
this->DrawString(r, i++, " %02x[%02x]: %08x (%s)", niv->var, param, value, niv->name);
|
||||||
|
@@ -22,10 +22,13 @@
|
|||||||
#include "company_base.h"
|
#include "company_base.h"
|
||||||
#include "newgrf_railtype.h"
|
#include "newgrf_railtype.h"
|
||||||
#include "newgrf_roadtype.h"
|
#include "newgrf_roadtype.h"
|
||||||
|
#include "newgrf_cache_check.h"
|
||||||
#include "ship.h"
|
#include "ship.h"
|
||||||
|
|
||||||
#include "safeguards.h"
|
#include "safeguards.h"
|
||||||
|
|
||||||
|
bool _sprite_group_resolve_check_veh_check = false;
|
||||||
|
|
||||||
struct WagonOverride {
|
struct WagonOverride {
|
||||||
EngineID *train_id;
|
EngineID *train_id;
|
||||||
uint trains;
|
uint trains;
|
||||||
@@ -162,7 +165,7 @@ enum TTDPAircraftMovementStates {
|
|||||||
* Map OTTD aircraft movement states to TTDPatch style movement states
|
* Map OTTD aircraft movement states to TTDPatch style movement states
|
||||||
* (VarAction 2 Variable 0xE2)
|
* (VarAction 2 Variable 0xE2)
|
||||||
*/
|
*/
|
||||||
static byte MapAircraftMovementState(const Aircraft *v)
|
byte MapAircraftMovementState(const Aircraft *v)
|
||||||
{
|
{
|
||||||
const Station *st = GetTargetAirportIfValid(v);
|
const Station *st = GetTargetAirportIfValid(v);
|
||||||
if (st == nullptr) return AMS_TTDP_FLIGHT_TO_TOWER;
|
if (st == nullptr) return AMS_TTDP_FLIGHT_TO_TOWER;
|
||||||
@@ -343,6 +346,14 @@ static byte MapAircraftMovementAction(const Aircraft *v)
|
|||||||
|
|
||||||
/* virtual */ uint32 VehicleScopeResolver::GetTriggers() const
|
/* virtual */ uint32 VehicleScopeResolver::GetTriggers() const
|
||||||
{
|
{
|
||||||
|
if (this->v == nullptr) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
if (_sprite_group_resolve_check_veh_check) {
|
||||||
|
SetBit(const_cast<Vehicle*>(this->v->First())->vcache.cached_veh_flags, VCF_REDRAW_ON_TRIGGER);
|
||||||
|
}
|
||||||
|
return this->v->waiting_triggers;
|
||||||
|
}
|
||||||
return this->v == nullptr ? 0 : this->v->waiting_triggers;
|
return this->v == nullptr ? 0 : this->v->waiting_triggers;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -444,8 +455,118 @@ static uint32 PositionHelper(const Vehicle *v, bool consecutive)
|
|||||||
return chain_before | chain_after << 8 | (chain_before + chain_after + consecutive) << 16;
|
return chain_before | chain_after << 8 | (chain_before + chain_after + consecutive) << 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32 VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *object, byte variable, uint32 parameter, bool *available)
|
static uint32 VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *object, byte variable, uint32 parameter, GetVariableExtra *extra)
|
||||||
{
|
{
|
||||||
|
if (_sprite_group_resolve_check_veh_check) {
|
||||||
|
switch (variable) {
|
||||||
|
case 0xC:
|
||||||
|
case 0x10:
|
||||||
|
case 0x18:
|
||||||
|
case 0x1A:
|
||||||
|
case 0x1C:
|
||||||
|
case 0x25:
|
||||||
|
case 0x40:
|
||||||
|
case 0x41:
|
||||||
|
case 0x42:
|
||||||
|
case 0x43:
|
||||||
|
case 0x47:
|
||||||
|
case 0x48:
|
||||||
|
case 0x49:
|
||||||
|
case 0x4A:
|
||||||
|
case 0x4B:
|
||||||
|
case 0x4D:
|
||||||
|
case 0x60:
|
||||||
|
case 0x61:
|
||||||
|
case 0x7D:
|
||||||
|
case 0x7F:
|
||||||
|
case 0x80 + 0x0:
|
||||||
|
case 0x80 + 0x1:
|
||||||
|
case 0x80 + 0x4:
|
||||||
|
case 0x80 + 0x5:
|
||||||
|
case 0x80 + 0xA: // dubious
|
||||||
|
case 0x80 + 0xB: // dubious
|
||||||
|
case 0x80 + 0x39:
|
||||||
|
case 0x80 + 0x3A:
|
||||||
|
case 0x80 + 0x3B:
|
||||||
|
case 0x80 + 0x3C:
|
||||||
|
case 0x80 + 0x3D:
|
||||||
|
case 0x80 + 0x44:
|
||||||
|
case 0x80 + 0x45:
|
||||||
|
case 0x80 + 0x46:
|
||||||
|
case 0x80 + 0x47:
|
||||||
|
case 0x80 + 0x5A:
|
||||||
|
case 0x80 + 0x72:
|
||||||
|
case 0x80 + 0x7A:
|
||||||
|
case 0xFF:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x80 + 0x32:
|
||||||
|
if (extra->mask & (VS_HIDDEN | VS_TRAIN_SLOWING)) {
|
||||||
|
_sprite_group_resolve_check_veh_check = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x80 + 0x34:
|
||||||
|
case 0x80 + 0x35:
|
||||||
|
if (v->type == VEH_AIRCRAFT) {
|
||||||
|
_sprite_group_resolve_check_veh_check = false;
|
||||||
|
} else {
|
||||||
|
SetBit(v->First()->vcache.cached_veh_flags, VCF_REDRAW_ON_SPEED_CHANGE);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x5F:
|
||||||
|
case 0x80 + 0x7B:
|
||||||
|
SetBit(v->First()->vcache.cached_veh_flags, VCF_REDRAW_ON_TRIGGER);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x80 + 0x48:
|
||||||
|
// VRF_REVERSE_DIRECTION
|
||||||
|
if (v->type != VEH_TRAIN) {
|
||||||
|
_sprite_group_resolve_check_veh_check = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x80 + 0x62:
|
||||||
|
switch (v->type) {
|
||||||
|
case VEH_TRAIN:
|
||||||
|
case VEH_SHIP:
|
||||||
|
if (extra->mask & 0x7F) {
|
||||||
|
_sprite_group_resolve_check_veh_check = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VEH_ROAD:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VEH_AIRCRAFT:
|
||||||
|
if (v == v->First()) {
|
||||||
|
SetBit(v->First()->vcache.cached_veh_flags, VCF_REDRAW_ON_SPEED_CHANGE);
|
||||||
|
} else {
|
||||||
|
_sprite_group_resolve_check_veh_check = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
_sprite_group_resolve_check_veh_check = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0xFE:
|
||||||
|
// vehicle is unloading, VF_CARGO_UNLOADING may disappear without the vehicle being marked dirty
|
||||||
|
// the vehicle is always marked dirty when VF_CARGO_UNLOADING is set
|
||||||
|
if (HasBit(v->vehicle_flags, VF_CARGO_UNLOADING)) {
|
||||||
|
_sprite_group_resolve_check_veh_check = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
_sprite_group_resolve_check_veh_check = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Calculated vehicle parameters */
|
/* Calculated vehicle parameters */
|
||||||
switch (variable) {
|
switch (variable) {
|
||||||
case 0x25: // Get engine GRF ID
|
case 0x25: // Get engine GRF ID
|
||||||
@@ -667,9 +788,12 @@ static uint32 VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *object,
|
|||||||
|
|
||||||
if (parameter == 0x5F) {
|
if (parameter == 0x5F) {
|
||||||
/* This seems to be the only variable that makes sense to access via var 61, but is not handled by VehicleGetVariable */
|
/* This seems to be the only variable that makes sense to access via var 61, but is not handled by VehicleGetVariable */
|
||||||
|
if (_sprite_group_resolve_check_veh_check) {
|
||||||
|
SetBit(u->First()->vcache.cached_veh_flags, VCF_REDRAW_ON_TRIGGER);
|
||||||
|
}
|
||||||
return (u->random_bits << 8) | u->waiting_triggers;
|
return (u->random_bits << 8) | u->waiting_triggers;
|
||||||
} else {
|
} else {
|
||||||
return VehicleGetVariable(u, object, parameter, GetRegister(0x10E), available);
|
return VehicleGetVariable(u, object, parameter, GetRegister(0x10E), extra);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Not available */
|
/* Not available */
|
||||||
@@ -891,11 +1015,11 @@ static uint32 VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *object,
|
|||||||
|
|
||||||
DEBUG(grf, 1, "Unhandled vehicle variable 0x%X, type 0x%X", variable, (uint)v->type);
|
DEBUG(grf, 1, "Unhandled vehicle variable 0x%X, type 0x%X", variable, (uint)v->type);
|
||||||
|
|
||||||
*available = false;
|
extra->available = false;
|
||||||
return UINT_MAX;
|
return UINT_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* virtual */ uint32 VehicleScopeResolver::GetVariable(byte variable, uint32 parameter, bool *available) const
|
/* virtual */ uint32 VehicleScopeResolver::GetVariable(byte variable, uint32 parameter, GetVariableExtra *extra) const
|
||||||
{
|
{
|
||||||
if (this->v == nullptr) {
|
if (this->v == nullptr) {
|
||||||
/* Vehicle does not exist, so we're in a purchase list */
|
/* Vehicle does not exist, so we're in a purchase list */
|
||||||
@@ -922,11 +1046,11 @@ static uint32 VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *object,
|
|||||||
case 0xF2: return 0; // Cargo subtype
|
case 0xF2: return 0; // Cargo subtype
|
||||||
}
|
}
|
||||||
|
|
||||||
*available = false;
|
extra->available = false;
|
||||||
return UINT_MAX;
|
return UINT_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
return VehicleGetVariable(const_cast<Vehicle*>(this->v), this, variable, parameter, available);
|
return VehicleGetVariable(const_cast<Vehicle*>(this->v), this, variable, parameter, extra);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1206,6 +1330,9 @@ void TriggerVehicle(Vehicle *v, VehicleTrigger trigger)
|
|||||||
|
|
||||||
v->InvalidateNewGRFCacheOfChain();
|
v->InvalidateNewGRFCacheOfChain();
|
||||||
DoTriggerVehicle(v, trigger, 0, true);
|
DoTriggerVehicle(v, trigger, 0, true);
|
||||||
|
if (HasBit(v->First()->vcache.cached_veh_flags, VCF_REDRAW_ON_TRIGGER)) {
|
||||||
|
v->First()->InvalidateImageCacheOfChain();
|
||||||
|
}
|
||||||
v->InvalidateNewGRFCacheOfChain();
|
v->InvalidateNewGRFCacheOfChain();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1325,8 +1452,8 @@ void FillNewGRFVehicleCache(const Vehicle *v)
|
|||||||
for (size_t i = 0; i < lengthof(cache_entries); i++) {
|
for (size_t i = 0; i < lengthof(cache_entries); i++) {
|
||||||
/* Only resolve when the cache isn't valid. */
|
/* Only resolve when the cache isn't valid. */
|
||||||
if (HasBit(v->grf_cache.cache_valid, cache_entries[i][1])) continue;
|
if (HasBit(v->grf_cache.cache_valid, cache_entries[i][1])) continue;
|
||||||
bool stub;
|
GetVariableExtra extra;
|
||||||
ro.GetScope(VSG_SCOPE_SELF)->GetVariable(cache_entries[i][0], 0, &stub);
|
ro.GetScope(VSG_SCOPE_SELF)->GetVariable(cache_entries[i][0], 0, &extra);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make sure really all bits are set. */
|
/* Make sure really all bits are set. */
|
||||||
|
@@ -39,7 +39,7 @@ struct VehicleScopeResolver : public ScopeResolver {
|
|||||||
void SetVehicle(const Vehicle *v) { this->v = v; }
|
void SetVehicle(const Vehicle *v) { this->v = v; }
|
||||||
|
|
||||||
uint32 GetRandomBits() const override;
|
uint32 GetRandomBits() const override;
|
||||||
uint32 GetVariable(byte variable, uint32 parameter, bool *available) const override;
|
uint32 GetVariable(byte variable, uint32 parameter, GetVariableExtra *extra) const override;
|
||||||
uint32 GetTriggers() const override;
|
uint32 GetTriggers() const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -42,7 +42,7 @@ struct GenericScopeResolver : public ScopeResolver {
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 GetVariable(byte variable, uint32 parameter, bool *available) const override;
|
uint32 GetVariable(byte variable, uint32 parameter, GetVariableExtra *extra) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool ai_callback; ///< Callback comes from the AI.
|
bool ai_callback; ///< Callback comes from the AI.
|
||||||
@@ -121,7 +121,7 @@ void AddGenericCallback(uint8 feature, const GRFFile *file, const SpriteGroup *g
|
|||||||
_gcl[feature].push_front(GenericCallback(file, group));
|
_gcl[feature].push_front(GenericCallback(file, group));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* virtual */ uint32 GenericScopeResolver::GetVariable(byte variable, uint32 parameter, bool *available) const
|
/* virtual */ uint32 GenericScopeResolver::GetVariable(byte variable, uint32 parameter, GetVariableExtra *extra) const
|
||||||
{
|
{
|
||||||
if (this->ai_callback) {
|
if (this->ai_callback) {
|
||||||
switch (variable) {
|
switch (variable) {
|
||||||
@@ -143,7 +143,7 @@ void AddGenericCallback(uint8 feature, const GRFFile *file, const SpriteGroup *g
|
|||||||
|
|
||||||
DEBUG(grf, 1, "Unhandled generic feature variable 0x%02X", variable);
|
DEBUG(grf, 1, "Unhandled generic feature variable 0x%02X", variable);
|
||||||
|
|
||||||
*available = false;
|
extra->available = false;
|
||||||
return UINT_MAX;
|
return UINT_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -322,7 +322,7 @@ static uint32 GetDistanceFromNearbyHouse(uint8 parameter, TileIndex tile, HouseI
|
|||||||
/**
|
/**
|
||||||
* @note Used by the resolver to get values for feature 07 deterministic spritegroups.
|
* @note Used by the resolver to get values for feature 07 deterministic spritegroups.
|
||||||
*/
|
*/
|
||||||
/* virtual */ uint32 HouseScopeResolver::GetVariable(byte variable, uint32 parameter, bool *available) const
|
/* virtual */ uint32 HouseScopeResolver::GetVariable(byte variable, uint32 parameter, GetVariableExtra *extra) const
|
||||||
{
|
{
|
||||||
switch (variable) {
|
switch (variable) {
|
||||||
/* Construction stage. */
|
/* Construction stage. */
|
||||||
@@ -438,7 +438,7 @@ static uint32 GetDistanceFromNearbyHouse(uint8 parameter, TileIndex tile, HouseI
|
|||||||
|
|
||||||
DEBUG(grf, 1, "Unhandled house variable 0x%X", variable);
|
DEBUG(grf, 1, "Unhandled house variable 0x%X", variable);
|
||||||
|
|
||||||
*available = false;
|
extra->available = false;
|
||||||
return UINT_MAX;
|
return UINT_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -446,7 +446,7 @@ static uint32 GetDistanceFromNearbyHouse(uint8 parameter, TileIndex tile, HouseI
|
|||||||
/**
|
/**
|
||||||
* @note Used by the resolver to get values for feature 07 deterministic spritegroups.
|
* @note Used by the resolver to get values for feature 07 deterministic spritegroups.
|
||||||
*/
|
*/
|
||||||
/* virtual */ uint32 FakeHouseScopeResolver::GetVariable(byte variable, uint32 parameter, bool *available) const
|
/* virtual */ uint32 FakeHouseScopeResolver::GetVariable(byte variable, uint32 parameter, GetVariableExtra *extra) const
|
||||||
{
|
{
|
||||||
switch (variable) {
|
switch (variable) {
|
||||||
/* Construction stage. */
|
/* Construction stage. */
|
||||||
@@ -500,7 +500,7 @@ static uint32 GetDistanceFromNearbyHouse(uint8 parameter, TileIndex tile, HouseI
|
|||||||
|
|
||||||
DEBUG(grf, 1, "Unhandled house variable 0x%X", variable);
|
DEBUG(grf, 1, "Unhandled house variable 0x%X", variable);
|
||||||
|
|
||||||
*available = false;
|
extra->available = false;
|
||||||
return UINT_MAX;
|
return UINT_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -50,7 +50,7 @@ struct HouseScopeResolver : public CommonHouseScopeResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32 GetRandomBits() const override;
|
uint32 GetRandomBits() const override;
|
||||||
uint32 GetVariable(byte variable, uint32 parameter, bool *available) const override;
|
uint32 GetVariable(byte variable, uint32 parameter, GetVariableExtra *extra) const override;
|
||||||
uint32 GetTriggers() const override;
|
uint32 GetTriggers() const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -70,7 +70,7 @@ struct FakeHouseScopeResolver : public CommonHouseScopeResolver {
|
|||||||
: CommonHouseScopeResolver(ro, house_id)
|
: CommonHouseScopeResolver(ro, house_id)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
/* virtual */ uint32 GetVariable(byte variable, uint32 parameter, bool *available) const;
|
/* virtual */ uint32 GetVariable(byte variable, uint32 parameter, GetVariableExtra *extra) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Resolver object to be used for houses (feature 07 spritegroups). */
|
/** Resolver object to be used for houses (feature 07 spritegroups). */
|
||||||
|
@@ -155,7 +155,7 @@ static uint32 GetCountAndDistanceOfClosestInstance(byte param_setID, byte layout
|
|||||||
return count << 16 | GB(closest_dist, 0, 16);
|
return count << 16 | GB(closest_dist, 0, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* virtual */ uint32 IndustriesScopeResolver::GetVariable(byte variable, uint32 parameter, bool *available) const
|
/* virtual */ uint32 IndustriesScopeResolver::GetVariable(byte variable, uint32 parameter, GetVariableExtra *extra) const
|
||||||
{
|
{
|
||||||
if (this->ro.callback == CBID_INDUSTRY_LOCATION) {
|
if (this->ro.callback == CBID_INDUSTRY_LOCATION) {
|
||||||
/* Variables available during construction check. */
|
/* Variables available during construction check. */
|
||||||
@@ -201,7 +201,7 @@ static uint32 GetCountAndDistanceOfClosestInstance(byte param_setID, byte layout
|
|||||||
if (this->industry == nullptr) {
|
if (this->industry == nullptr) {
|
||||||
DEBUG(grf, 1, "Unhandled variable 0x%X (no available industry) in callback 0x%x", variable, this->ro.callback);
|
DEBUG(grf, 1, "Unhandled variable 0x%X (no available industry) in callback 0x%x", variable, this->ro.callback);
|
||||||
|
|
||||||
*available = false;
|
extra->available = false;
|
||||||
return UINT_MAX;
|
return UINT_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -401,7 +401,7 @@ static uint32 GetCountAndDistanceOfClosestInstance(byte param_setID, byte layout
|
|||||||
|
|
||||||
DEBUG(grf, 1, "Unhandled industry variable 0x%X", variable);
|
DEBUG(grf, 1, "Unhandled industry variable 0x%X", variable);
|
||||||
|
|
||||||
*available = false;
|
extra->available = false;
|
||||||
return UINT_MAX;
|
return UINT_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -33,7 +33,7 @@ struct IndustriesScopeResolver : public ScopeResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32 GetRandomBits() const override;
|
uint32 GetRandomBits() const override;
|
||||||
uint32 GetVariable(byte variable, uint32 parameter, bool *available) const override;
|
uint32 GetVariable(byte variable, uint32 parameter, GetVariableExtra *extra) const override;
|
||||||
uint32 GetTriggers() const override;
|
uint32 GetTriggers() const override;
|
||||||
void StorePSA(uint pos, int32 value) override;
|
void StorePSA(uint pos, int32 value) override;
|
||||||
};
|
};
|
||||||
|
@@ -58,7 +58,7 @@ uint32 GetRelativePosition(TileIndex tile, TileIndex ind_tile)
|
|||||||
return ((y & 0xF) << 20) | ((x & 0xF) << 16) | (y << 8) | x;
|
return ((y & 0xF) << 20) | ((x & 0xF) << 16) | (y << 8) | x;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* virtual */ uint32 IndustryTileScopeResolver::GetVariable(byte variable, uint32 parameter, bool *available) const
|
/* virtual */ uint32 IndustryTileScopeResolver::GetVariable(byte variable, uint32 parameter, GetVariableExtra *extra) const
|
||||||
{
|
{
|
||||||
switch (variable) {
|
switch (variable) {
|
||||||
/* Construction state of the tile: a value between 0 and 3 */
|
/* Construction state of the tile: a value between 0 and 3 */
|
||||||
@@ -95,7 +95,7 @@ uint32 GetRelativePosition(TileIndex tile, TileIndex ind_tile)
|
|||||||
|
|
||||||
DEBUG(grf, 1, "Unhandled industry tile variable 0x%X", variable);
|
DEBUG(grf, 1, "Unhandled industry tile variable 0x%X", variable);
|
||||||
|
|
||||||
*available = false;
|
extra->available = false;
|
||||||
return UINT_MAX;
|
return UINT_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -31,7 +31,7 @@ struct IndustryTileScopeResolver : public ScopeResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32 GetRandomBits() const override;
|
uint32 GetRandomBits() const override;
|
||||||
uint32 GetVariable(byte variable, uint32 parameter, bool *available) const override;
|
uint32 GetVariable(byte variable, uint32 parameter, GetVariableExtra *extra) const override;
|
||||||
uint32 GetTriggers() const override;
|
uint32 GetTriggers() const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -230,7 +230,7 @@ static uint32 GetCountAndDistanceOfClosestInstance(byte local_id, uint32 grfid,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Used by the resolver to get values for feature 0F deterministic spritegroups. */
|
/** Used by the resolver to get values for feature 0F deterministic spritegroups. */
|
||||||
/* virtual */ uint32 ObjectScopeResolver::GetVariable(byte variable, uint32 parameter, bool *available) const
|
/* virtual */ uint32 ObjectScopeResolver::GetVariable(byte variable, uint32 parameter, GetVariableExtra *extra) const
|
||||||
{
|
{
|
||||||
/* We get the town from the object, or we calculate the closest
|
/* We get the town from the object, or we calculate the closest
|
||||||
* town if we need to when there's no object. */
|
* town if we need to when there's no object. */
|
||||||
@@ -337,7 +337,7 @@ static uint32 GetCountAndDistanceOfClosestInstance(byte local_id, uint32 grfid,
|
|||||||
unhandled:
|
unhandled:
|
||||||
DEBUG(grf, 1, "Unhandled object variable 0x%X", variable);
|
DEBUG(grf, 1, "Unhandled object variable 0x%X", variable);
|
||||||
|
|
||||||
*available = false;
|
extra->available = false;
|
||||||
return UINT_MAX;
|
return UINT_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -116,7 +116,7 @@ struct ObjectScopeResolver : public ScopeResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32 GetRandomBits() const override;
|
uint32 GetRandomBits() const override;
|
||||||
uint32 GetVariable(byte variable, uint32 parameter, bool *available) const override;
|
uint32 GetVariable(byte variable, uint32 parameter, GetVariableExtra *extra) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A resolver object to be used with feature 0F spritegroups. */
|
/** A resolver object to be used with feature 0F spritegroups. */
|
||||||
|
@@ -22,7 +22,7 @@
|
|||||||
return GB(tmp, 0, 2);
|
return GB(tmp, 0, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* virtual */ uint32 RailTypeScopeResolver::GetVariable(byte variable, uint32 parameter, bool *available) const
|
/* virtual */ uint32 RailTypeScopeResolver::GetVariable(byte variable, uint32 parameter, GetVariableExtra *extra) const
|
||||||
{
|
{
|
||||||
if (this->tile == INVALID_TILE) {
|
if (this->tile == INVALID_TILE) {
|
||||||
switch (variable) {
|
switch (variable) {
|
||||||
@@ -54,7 +54,7 @@
|
|||||||
|
|
||||||
DEBUG(grf, 1, "Unhandled rail type tile variable 0x%X", variable);
|
DEBUG(grf, 1, "Unhandled rail type tile variable 0x%X", variable);
|
||||||
|
|
||||||
*available = false;
|
extra->available = false;
|
||||||
return UINT_MAX;
|
return UINT_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -32,7 +32,7 @@ struct RailTypeScopeResolver : public ScopeResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32 GetRandomBits() const override;
|
uint32 GetRandomBits() const override;
|
||||||
uint32 GetVariable(byte variable, uint32 parameter, bool *available) const override;
|
uint32 GetVariable(byte variable, uint32 parameter, GetVariableExtra *extra) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Resolver object for rail types. */
|
/** Resolver object for rail types. */
|
||||||
|
@@ -22,7 +22,7 @@
|
|||||||
return GB(tmp, 0, 2);
|
return GB(tmp, 0, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* virtual */ uint32 RoadTypeScopeResolver::GetVariable(byte variable, uint32 parameter, bool *available) const
|
/* virtual */ uint32 RoadTypeScopeResolver::GetVariable(byte variable, uint32 parameter, GetVariableExtra *extra) const
|
||||||
{
|
{
|
||||||
if (this->tile == INVALID_TILE) {
|
if (this->tile == INVALID_TILE) {
|
||||||
switch (variable) {
|
switch (variable) {
|
||||||
@@ -54,7 +54,7 @@
|
|||||||
|
|
||||||
DEBUG(grf, 1, "Unhandled road type tile variable 0x%X", variable);
|
DEBUG(grf, 1, "Unhandled road type tile variable 0x%X", variable);
|
||||||
|
|
||||||
*available = false;
|
extra->available = false;
|
||||||
return UINT_MAX;
|
return UINT_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -23,7 +23,7 @@ struct RoadTypeScopeResolver : public ScopeResolver {
|
|||||||
RoadTypeScopeResolver(ResolverObject &ro, const RoadTypeInfo *rti, TileIndex tile, TileContext context);
|
RoadTypeScopeResolver(ResolverObject &ro, const RoadTypeInfo *rti, TileIndex tile, TileContext context);
|
||||||
|
|
||||||
/* virtual */ uint32 GetRandomBits() const;
|
/* virtual */ uint32 GetRandomBits() const;
|
||||||
/* virtual */ uint32 GetVariable(byte variable, uint32 parameter, bool *available) const;
|
/* virtual */ uint32 GetVariable(byte variable, uint32 parameter, GetVariableExtra *extra) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Resolver object for road types. */
|
/** Resolver object for road types. */
|
||||||
|
@@ -14,6 +14,8 @@
|
|||||||
#include "newgrf_profiling.h"
|
#include "newgrf_profiling.h"
|
||||||
#include "core/pool_func.hpp"
|
#include "core/pool_func.hpp"
|
||||||
#include "vehicle_type.h"
|
#include "vehicle_type.h"
|
||||||
|
#include "newgrf_cache_check.h"
|
||||||
|
#include "scope_info.h"
|
||||||
|
|
||||||
#include "safeguards.h"
|
#include "safeguards.h"
|
||||||
|
|
||||||
@@ -72,7 +74,7 @@ RandomizedSpriteGroup::~RandomizedSpriteGroup()
|
|||||||
free(this->groups);
|
free(this->groups);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32 GetVariable(const ResolverObject &object, ScopeResolver *scope, byte variable, uint32 parameter, bool *available)
|
static inline uint32 GetVariable(const ResolverObject &object, ScopeResolver *scope, byte variable, uint32 parameter, GetVariableExtra *extra)
|
||||||
{
|
{
|
||||||
uint32 value;
|
uint32 value;
|
||||||
switch (variable) {
|
switch (variable) {
|
||||||
@@ -93,7 +95,7 @@ static inline uint32 GetVariable(const ResolverObject &object, ScopeResolver *sc
|
|||||||
/* First handle variables common with Action7/9/D */
|
/* First handle variables common with Action7/9/D */
|
||||||
if (variable < 0x40 && GetGlobalVariable(variable, &value, object.grffile)) return value;
|
if (variable < 0x40 && GetGlobalVariable(variable, &value, object.grffile)) return value;
|
||||||
/* Not a common variable, so evaluate the feature specific variables */
|
/* Not a common variable, so evaluate the feature specific variables */
|
||||||
return scope->GetVariable(variable, parameter, available);
|
return scope->GetVariable(variable, parameter, extra);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,10 +124,10 @@ static inline uint32 GetVariable(const ResolverObject &object, ScopeResolver *sc
|
|||||||
* @param[out] available Set to false, in case the variable does not exist.
|
* @param[out] available Set to false, in case the variable does not exist.
|
||||||
* @return Value
|
* @return Value
|
||||||
*/
|
*/
|
||||||
/* virtual */ uint32 ScopeResolver::GetVariable(byte variable, uint32 parameter, bool *available) const
|
/* virtual */ uint32 ScopeResolver::GetVariable(byte variable, uint32 parameter, GetVariableExtra *extra) const
|
||||||
{
|
{
|
||||||
DEBUG(grf, 1, "Unhandled scope variable 0x%X", variable);
|
DEBUG(grf, 1, "Unhandled scope variable 0x%X", variable);
|
||||||
*available = false;
|
extra->available = false;
|
||||||
return UINT_MAX;
|
return UINT_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,9 +201,6 @@ static U EvalAdjustT(const DeterministicSpriteGroupAdjust *adjust, ScopeResolver
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _sprite_group_resolve_check_veh_check = false;
|
|
||||||
VehicleType _sprite_group_resolve_check_veh_type;
|
|
||||||
|
|
||||||
static bool RangeHighComparator(const DeterministicSpriteGroupRange& range, uint32 value)
|
static bool RangeHighComparator(const DeterministicSpriteGroupRange& range, uint32 value)
|
||||||
{
|
{
|
||||||
return range.high < value;
|
return range.high < value;
|
||||||
@@ -219,9 +218,8 @@ const SpriteGroup *DeterministicSpriteGroup::Resolve(ResolverObject &object) con
|
|||||||
DeterministicSpriteGroupAdjust *adjust = &this->adjusts[i];
|
DeterministicSpriteGroupAdjust *adjust = &this->adjusts[i];
|
||||||
|
|
||||||
/* Try to get the variable. We shall assume it is available, unless told otherwise. */
|
/* Try to get the variable. We shall assume it is available, unless told otherwise. */
|
||||||
bool available = true;
|
GetVariableExtra extra(adjust->and_mask << adjust->shift_num);
|
||||||
if (adjust->variable == 0x7E) {
|
if (adjust->variable == 0x7E) {
|
||||||
_sprite_group_resolve_check_veh_check = false;
|
|
||||||
const SpriteGroup *subgroup = SpriteGroup::Resolve(adjust->subroutine, object, false);
|
const SpriteGroup *subgroup = SpriteGroup::Resolve(adjust->subroutine, object, false);
|
||||||
if (subgroup == nullptr) {
|
if (subgroup == nullptr) {
|
||||||
value = CALLBACK_FAILED;
|
value = CALLBACK_FAILED;
|
||||||
@@ -232,59 +230,12 @@ const SpriteGroup *DeterministicSpriteGroup::Resolve(ResolverObject &object) con
|
|||||||
/* Note: 'last_value' and 'reseed' are shared between the main chain and the procedure */
|
/* Note: 'last_value' and 'reseed' are shared between the main chain and the procedure */
|
||||||
} else if (adjust->variable == 0x7B) {
|
} else if (adjust->variable == 0x7B) {
|
||||||
_sprite_group_resolve_check_veh_check = false;
|
_sprite_group_resolve_check_veh_check = false;
|
||||||
value = GetVariable(object, scope, adjust->parameter, last_value, &available);
|
value = GetVariable(object, scope, adjust->parameter, last_value, &extra);
|
||||||
} else {
|
} else {
|
||||||
if (_sprite_group_resolve_check_veh_check) {
|
value = GetVariable(object, scope, adjust->variable, adjust->parameter, &extra);
|
||||||
switch (adjust->variable) {
|
|
||||||
// whitelist of variables which can be checked without requiring an immediate re-check on the next tick
|
|
||||||
case 0xC:
|
|
||||||
case 0x1A:
|
|
||||||
case 0x1C:
|
|
||||||
case 0x25:
|
|
||||||
case 0x40:
|
|
||||||
case 0x41:
|
|
||||||
case 0x42:
|
|
||||||
case 0x47:
|
|
||||||
case 0x49:
|
|
||||||
case 0x4B:
|
|
||||||
case 0x4D:
|
|
||||||
case 0x60:
|
|
||||||
case 0x7D:
|
|
||||||
case 0x7F:
|
|
||||||
case 0x80 + 0x0:
|
|
||||||
case 0x80 + 0x1:
|
|
||||||
case 0x80 + 0x4:
|
|
||||||
case 0x80 + 0x5:
|
|
||||||
case 0x80 + 0x39:
|
|
||||||
case 0x80 + 0x3A:
|
|
||||||
case 0x80 + 0x3B:
|
|
||||||
case 0x80 + 0x3C:
|
|
||||||
case 0x80 + 0x3D:
|
|
||||||
case 0x80 + 0x44:
|
|
||||||
case 0x80 + 0x45:
|
|
||||||
case 0x80 + 0x46:
|
|
||||||
case 0x80 + 0x47:
|
|
||||||
case 0x80 + 0x5A:
|
|
||||||
case 0x80 + 0x72:
|
|
||||||
case 0x80 + 0x7A:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x80 + 0x62:
|
|
||||||
// RoadVehicle::state
|
|
||||||
if (_sprite_group_resolve_check_veh_type != VEH_ROAD) {
|
|
||||||
_sprite_group_resolve_check_veh_check = false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
_sprite_group_resolve_check_veh_check = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
value = GetVariable(object, scope, adjust->variable, adjust->parameter, &available);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!available) {
|
if (!extra.available) {
|
||||||
/* Unsupported variable: skip further processing and return either
|
/* Unsupported variable: skip further processing and return either
|
||||||
* the group from the first range or the default group. */
|
* the group from the first range or the default group. */
|
||||||
return SpriteGroup::Resolve(this->error_group, object, false);
|
return SpriteGroup::Resolve(this->error_group, object, false);
|
||||||
|
@@ -287,6 +287,14 @@ struct IndustryProductionSpriteGroup : SpriteGroup {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct GetVariableExtra {
|
||||||
|
bool available;
|
||||||
|
uint32 mask;
|
||||||
|
|
||||||
|
GetVariableExtra(uint32 mask_ = 0xFFFFFFFF)
|
||||||
|
: available(true), mask(mask_) {}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface to query and set values specific to a single #VarSpriteGroupScope (action 2 scope).
|
* Interface to query and set values specific to a single #VarSpriteGroupScope (action 2 scope).
|
||||||
*
|
*
|
||||||
@@ -302,7 +310,7 @@ struct ScopeResolver {
|
|||||||
virtual uint32 GetRandomBits() const;
|
virtual uint32 GetRandomBits() const;
|
||||||
virtual uint32 GetTriggers() const;
|
virtual uint32 GetTriggers() const;
|
||||||
|
|
||||||
virtual uint32 GetVariable(byte variable, uint32 parameter, bool *available) const;
|
virtual uint32 GetVariable(byte variable, uint32 parameter, GetVariableExtra *extra) const;
|
||||||
virtual void StorePSA(uint reg, int32 value);
|
virtual void StorePSA(uint reg, int32 value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -268,7 +268,7 @@ TownScopeResolver *StationResolverObject::GetTown()
|
|||||||
return this->town_scope;
|
return this->town_scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* virtual */ uint32 StationScopeResolver::GetVariable(byte variable, uint32 parameter, bool *available) const
|
/* virtual */ uint32 StationScopeResolver::GetVariable(byte variable, uint32 parameter, GetVariableExtra *extra) const
|
||||||
{
|
{
|
||||||
if (this->st == nullptr) {
|
if (this->st == nullptr) {
|
||||||
/* Station does not exist, so we're in a purchase list or the land slope check callback. */
|
/* Station does not exist, so we're in a purchase list or the land slope check callback. */
|
||||||
@@ -296,7 +296,7 @@ TownScopeResolver *StationResolverObject::GetTown()
|
|||||||
case 0xFA: return Clamp(_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0, 65535); // Build date, clamped to a 16 bit value
|
case 0xFA: return Clamp(_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0, 65535); // Build date, clamped to a 16 bit value
|
||||||
}
|
}
|
||||||
|
|
||||||
*available = false;
|
extra->available = false;
|
||||||
return UINT_MAX;
|
return UINT_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -386,7 +386,7 @@ TownScopeResolver *StationResolverObject::GetTown()
|
|||||||
case 0xFA: return Clamp(this->st->build_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0, 65535);
|
case 0xFA: return Clamp(this->st->build_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0, 65535);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this->st->GetNewGRFVariable(this->ro, variable, parameter, available);
|
return this->st->GetNewGRFVariable(this->ro, variable, parameter, &(extra->available));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 Station::GetNewGRFVariable(const ResolverObject &object, byte variable, byte parameter, bool *available) const
|
uint32 Station::GetNewGRFVariable(const ResolverObject &object, byte variable, byte parameter, bool *available) const
|
||||||
|
@@ -45,7 +45,7 @@ struct StationScopeResolver : public ScopeResolver {
|
|||||||
uint32 GetRandomBits() const override;
|
uint32 GetRandomBits() const override;
|
||||||
uint32 GetTriggers() const override;
|
uint32 GetTriggers() const override;
|
||||||
|
|
||||||
uint32 GetVariable(byte variable, uint32 parameter, bool *available) const override;
|
uint32 GetVariable(byte variable, uint32 parameter, GetVariableExtra *extra) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Station resolver. */
|
/** Station resolver. */
|
||||||
|
@@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
#include "safeguards.h"
|
#include "safeguards.h"
|
||||||
|
|
||||||
/* virtual */ uint32 TownScopeResolver::GetVariable(byte variable, uint32 parameter, bool *available) const
|
/* virtual */ uint32 TownScopeResolver::GetVariable(byte variable, uint32 parameter, GetVariableExtra *extra) const
|
||||||
{
|
{
|
||||||
switch (variable) {
|
switch (variable) {
|
||||||
/* Larger towns */
|
/* Larger towns */
|
||||||
@@ -113,7 +113,7 @@
|
|||||||
|
|
||||||
DEBUG(grf, 1, "Unhandled town variable 0x%X", variable);
|
DEBUG(grf, 1, "Unhandled town variable 0x%X", variable);
|
||||||
|
|
||||||
*available = false;
|
extra->available = false;
|
||||||
return UINT_MAX;
|
return UINT_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,7 +148,7 @@
|
|||||||
t->psa_list.push_back(psa);
|
t->psa_list.push_back(psa);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* virtual */ uint32 FakeTownScopeResolver::GetVariable(byte variable, uint32 parameter, bool *available) const
|
/* virtual */ uint32 FakeTownScopeResolver::GetVariable(byte variable, uint32 parameter, GetVariableExtra *extra) const
|
||||||
{
|
{
|
||||||
switch (variable) {
|
switch (variable) {
|
||||||
/* Town index */
|
/* Town index */
|
||||||
@@ -168,7 +168,7 @@
|
|||||||
|
|
||||||
DEBUG(grf, 1, "Unhandled town variable 0x%X", variable);
|
DEBUG(grf, 1, "Unhandled town variable 0x%X", variable);
|
||||||
|
|
||||||
*available = false;
|
extra->available = false;
|
||||||
return UINT_MAX;
|
return UINT_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -34,7 +34,7 @@ struct TownScopeResolver : public ScopeResolver {
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual uint32 GetVariable(byte variable, uint32 parameter, bool *available) const;
|
virtual uint32 GetVariable(byte variable, uint32 parameter, GetVariableExtra *extra) const;
|
||||||
virtual void StorePSA(uint reg, int32 value);
|
virtual void StorePSA(uint reg, int32 value);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -53,7 +53,7 @@ struct FakeTownScopeResolver : public ScopeResolver {
|
|||||||
FakeTownScopeResolver(ResolverObject &ro) : ScopeResolver(ro)
|
FakeTownScopeResolver(ResolverObject &ro) : ScopeResolver(ro)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
virtual uint32 GetVariable(byte variable, uint32 parameter, bool *available) const;
|
virtual uint32 GetVariable(byte variable, uint32 parameter, GetVariableExtra *extra) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Resolver of town properties. */
|
/** Resolver of town properties. */
|
||||||
|
@@ -2362,7 +2362,7 @@ static VehicleEnterTileStatus VehicleEnter_Road(Vehicle *v, TileIndex tile, int
|
|||||||
RoadVehicle *rv = RoadVehicle::From(v);
|
RoadVehicle *rv = RoadVehicle::From(v);
|
||||||
if (rv->frame == RVC_DEPOT_STOP_FRAME &&
|
if (rv->frame == RVC_DEPOT_STOP_FRAME &&
|
||||||
_roadveh_enter_depot_dir[GetRoadDepotDirection(tile)] == rv->state) {
|
_roadveh_enter_depot_dir[GetRoadDepotDirection(tile)] == rv->state) {
|
||||||
rv->cur_image_valid_dir = INVALID_DIR;
|
rv->InvalidateImageCache();
|
||||||
rv->state = RVSB_IN_DEPOT;
|
rv->state = RVSB_IN_DEPOT;
|
||||||
rv->vehstatus |= VS_HIDDEN;
|
rv->vehstatus |= VS_HIDDEN;
|
||||||
rv->direction = ReverseDir(rv->direction);
|
rv->direction = ReverseDir(rv->direction);
|
||||||
|
@@ -415,7 +415,7 @@ void RoadVehicle::MarkDirty()
|
|||||||
{
|
{
|
||||||
for (RoadVehicle *v = this; v != nullptr; v = v->Next()) {
|
for (RoadVehicle *v = this; v != nullptr; v = v->Next()) {
|
||||||
v->colourmap = PAL_NONE;
|
v->colourmap = PAL_NONE;
|
||||||
v->cur_image_valid_dir = INVALID_DIR;
|
v->InvalidateImageCache();
|
||||||
v->UpdateViewport(true, false);
|
v->UpdateViewport(true, false);
|
||||||
}
|
}
|
||||||
this->CargoChanged();
|
this->CargoChanged();
|
||||||
@@ -1119,7 +1119,7 @@ static bool RoadVehLeaveDepot(RoadVehicle *v, bool first)
|
|||||||
}
|
}
|
||||||
|
|
||||||
v->vehstatus &= ~VS_HIDDEN;
|
v->vehstatus &= ~VS_HIDDEN;
|
||||||
v->cur_image_valid_dir = INVALID_DIR;
|
v->InvalidateImageCache();
|
||||||
v->state = tdir;
|
v->state = tdir;
|
||||||
v->frame = RVC_DEPOT_START_FRAME;
|
v->frame = RVC_DEPOT_START_FRAME;
|
||||||
v->UpdateIsDrawn();
|
v->UpdateIsDrawn();
|
||||||
@@ -1437,7 +1437,7 @@ again:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!HasBit(r, VETS_ENTERED_WORMHOLE)) {
|
if (!HasBit(r, VETS_ENTERED_WORMHOLE)) {
|
||||||
v->cur_image_valid_dir = INVALID_DIR;
|
v->InvalidateImageCache();
|
||||||
TileIndex old_tile = v->tile;
|
TileIndex old_tile = v->tile;
|
||||||
|
|
||||||
v->tile = tile;
|
v->tile = tile;
|
||||||
@@ -1513,7 +1513,7 @@ again:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
v->cur_image_valid_dir = INVALID_DIR;
|
v->InvalidateImageCache();
|
||||||
v->state = dir;
|
v->state = dir;
|
||||||
v->frame = turn_around_start_frame;
|
v->frame = turn_around_start_frame;
|
||||||
|
|
||||||
|
@@ -277,7 +277,7 @@ Trackdir Ship::GetVehicleTrackdir() const
|
|||||||
void Ship::MarkDirty()
|
void Ship::MarkDirty()
|
||||||
{
|
{
|
||||||
this->colourmap = PAL_NONE;
|
this->colourmap = PAL_NONE;
|
||||||
this->cur_image_valid_dir = INVALID_DIR;
|
this->InvalidateImageCache();
|
||||||
this->UpdateViewport(true, false);
|
this->UpdateViewport(true, false);
|
||||||
this->UpdateCache();
|
this->UpdateCache();
|
||||||
}
|
}
|
||||||
|
@@ -78,11 +78,11 @@ class NIHVehicle : public NIHelper {
|
|||||||
void SetStringParameters(uint index) const override { this->SetSimpleStringParameters(STR_VEHICLE_NAME, index); }
|
void SetStringParameters(uint index) const override { this->SetSimpleStringParameters(STR_VEHICLE_NAME, index); }
|
||||||
uint32 GetGRFID(uint index) const override { return Vehicle::Get(index)->GetGRFID(); }
|
uint32 GetGRFID(uint index) const override { return Vehicle::Get(index)->GetGRFID(); }
|
||||||
|
|
||||||
uint Resolve(uint index, uint var, uint param, bool *avail) const override
|
uint Resolve(uint index, uint var, uint param, GetVariableExtra *extra) const override
|
||||||
{
|
{
|
||||||
Vehicle *v = Vehicle::Get(index);
|
Vehicle *v = Vehicle::Get(index);
|
||||||
VehicleResolverObject ro(v->engine_type, v, VehicleResolverObject::WO_CACHED);
|
VehicleResolverObject ro(v->engine_type, v, VehicleResolverObject::WO_CACHED);
|
||||||
return ro.GetScope(VSG_SCOPE_SELF)->GetVariable(var, param, avail);
|
return ro.GetScope(VSG_SCOPE_SELF)->GetVariable(var, param, extra);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* virtual */ void ExtraInfo(uint index, std::function<void(const char *)> print) const override
|
/* virtual */ void ExtraInfo(uint index, std::function<void(const char *)> print) const override
|
||||||
@@ -170,6 +170,9 @@ class NIHVehicle : public NIHelper {
|
|||||||
e->duration_phase_1 + e->duration_phase_2 + e->duration_phase_3);
|
e->duration_phase_1 + e->duration_phase_2 + e->duration_phase_3);
|
||||||
print(buffer);
|
print(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
seprintf(buffer, lastof(buffer), " Current image cacheable: %s", v->cur_image_valid_dir != INVALID_DIR ? "yes" : "no");
|
||||||
|
print(buffer);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -229,10 +232,10 @@ class NIHStation : public NIHelper {
|
|||||||
void SetStringParameters(uint index) const override { this->SetObjectAtStringParameters(STR_STATION_NAME, GetStationIndex(index), index); }
|
void SetStringParameters(uint index) const override { this->SetObjectAtStringParameters(STR_STATION_NAME, GetStationIndex(index), index); }
|
||||||
uint32 GetGRFID(uint index) const override { return (this->IsInspectable(index)) ? GetStationSpec(index)->grf_prop.grffile->grfid : 0; }
|
uint32 GetGRFID(uint index) const override { return (this->IsInspectable(index)) ? GetStationSpec(index)->grf_prop.grffile->grfid : 0; }
|
||||||
|
|
||||||
uint Resolve(uint index, uint var, uint param, bool *avail) const override
|
uint Resolve(uint index, uint var, uint param, GetVariableExtra *extra) const override
|
||||||
{
|
{
|
||||||
StationResolverObject ro(GetStationSpec(index), Station::GetByTile(index), index, INVALID_RAILTYPE);
|
StationResolverObject ro(GetStationSpec(index), Station::GetByTile(index), index, INVALID_RAILTYPE);
|
||||||
return ro.GetScope(VSG_SCOPE_SELF)->GetVariable(var, param, avail);
|
return ro.GetScope(VSG_SCOPE_SELF)->GetVariable(var, param, extra);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -294,10 +297,10 @@ class NIHHouse : public NIHelper {
|
|||||||
void SetStringParameters(uint index) const override { this->SetObjectAtStringParameters(STR_TOWN_NAME, GetTownIndex(index), index); }
|
void SetStringParameters(uint index) const override { this->SetObjectAtStringParameters(STR_TOWN_NAME, GetTownIndex(index), index); }
|
||||||
uint32 GetGRFID(uint index) const override { return (this->IsInspectable(index)) ? HouseSpec::Get(GetHouseType(index))->grf_prop.grffile->grfid : 0; }
|
uint32 GetGRFID(uint index) const override { return (this->IsInspectable(index)) ? HouseSpec::Get(GetHouseType(index))->grf_prop.grffile->grfid : 0; }
|
||||||
|
|
||||||
uint Resolve(uint index, uint var, uint param, bool *avail) const override
|
uint Resolve(uint index, uint var, uint param, GetVariableExtra *extra) const override
|
||||||
{
|
{
|
||||||
HouseResolverObject ro(GetHouseType(index), index, Town::GetByTile(index));
|
HouseResolverObject ro(GetHouseType(index), index, Town::GetByTile(index));
|
||||||
return ro.GetScope(VSG_SCOPE_SELF)->GetVariable(var, param, avail);
|
return ro.GetScope(VSG_SCOPE_SELF)->GetVariable(var, param, extra);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExtraInfo(uint index, std::function<void(const char *)> print) const override
|
void ExtraInfo(uint index, std::function<void(const char *)> print) const override
|
||||||
@@ -359,10 +362,10 @@ class NIHIndustryTile : public NIHelper {
|
|||||||
void SetStringParameters(uint index) const override { this->SetObjectAtStringParameters(STR_INDUSTRY_NAME, GetIndustryIndex(index), index); }
|
void SetStringParameters(uint index) const override { this->SetObjectAtStringParameters(STR_INDUSTRY_NAME, GetIndustryIndex(index), index); }
|
||||||
uint32 GetGRFID(uint index) const override { return (this->IsInspectable(index)) ? GetIndustryTileSpec(GetIndustryGfx(index))->grf_prop.grffile->grfid : 0; }
|
uint32 GetGRFID(uint index) const override { return (this->IsInspectable(index)) ? GetIndustryTileSpec(GetIndustryGfx(index))->grf_prop.grffile->grfid : 0; }
|
||||||
|
|
||||||
uint Resolve(uint index, uint var, uint param, bool *avail) const override
|
uint Resolve(uint index, uint var, uint param, GetVariableExtra *extra) const override
|
||||||
{
|
{
|
||||||
IndustryTileResolverObject ro(GetIndustryGfx(index), index, Industry::GetByTile(index));
|
IndustryTileResolverObject ro(GetIndustryGfx(index), index, Industry::GetByTile(index));
|
||||||
return ro.GetScope(VSG_SCOPE_SELF)->GetVariable(var, param, avail);
|
return ro.GetScope(VSG_SCOPE_SELF)->GetVariable(var, param, extra);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -458,11 +461,11 @@ class NIHIndustry : public NIHelper {
|
|||||||
void SetStringParameters(uint index) const override { this->SetSimpleStringParameters(STR_INDUSTRY_NAME, index); }
|
void SetStringParameters(uint index) const override { this->SetSimpleStringParameters(STR_INDUSTRY_NAME, index); }
|
||||||
uint32 GetGRFID(uint index) const override { return (this->IsInspectable(index)) ? GetIndustrySpec(Industry::Get(index)->type)->grf_prop.grffile->grfid : 0; }
|
uint32 GetGRFID(uint index) const override { return (this->IsInspectable(index)) ? GetIndustrySpec(Industry::Get(index)->type)->grf_prop.grffile->grfid : 0; }
|
||||||
|
|
||||||
uint Resolve(uint index, uint var, uint param, bool *avail) const override
|
uint Resolve(uint index, uint var, uint param, GetVariableExtra *extra) const override
|
||||||
{
|
{
|
||||||
Industry *i = Industry::Get(index);
|
Industry *i = Industry::Get(index);
|
||||||
IndustriesResolverObject ro(i->location.tile, i, i->type);
|
IndustriesResolverObject ro(i->location.tile, i, i->type);
|
||||||
return ro.GetScope(VSG_SCOPE_SELF)->GetVariable(var, param, avail);
|
return ro.GetScope(VSG_SCOPE_SELF)->GetVariable(var, param, extra);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint GetPSASize(uint index, uint32 grfid) const override { return cpp_lengthof(PersistentStorage, storage); }
|
uint GetPSASize(uint index, uint32 grfid) const override { return cpp_lengthof(PersistentStorage, storage); }
|
||||||
@@ -546,10 +549,10 @@ class NIHObject : public NIHelper {
|
|||||||
void SetStringParameters(uint index) const override { this->SetObjectAtStringParameters(STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT_OBJECT, INVALID_STRING_ID, index); }
|
void SetStringParameters(uint index) const override { this->SetObjectAtStringParameters(STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT_OBJECT, INVALID_STRING_ID, index); }
|
||||||
uint32 GetGRFID(uint index) const override { return (this->IsInspectable(index)) ? ObjectSpec::GetByTile(index)->grf_prop.grffile->grfid : 0; }
|
uint32 GetGRFID(uint index) const override { return (this->IsInspectable(index)) ? ObjectSpec::GetByTile(index)->grf_prop.grffile->grfid : 0; }
|
||||||
|
|
||||||
uint Resolve(uint index, uint var, uint param, bool *avail) const override
|
uint Resolve(uint index, uint var, uint param, GetVariableExtra *extra) const override
|
||||||
{
|
{
|
||||||
ObjectResolverObject ro(ObjectSpec::GetByTile(index), Object::GetByTile(index), index);
|
ObjectResolverObject ro(ObjectSpec::GetByTile(index), Object::GetByTile(index), index);
|
||||||
return ro.GetScope(VSG_SCOPE_SELF)->GetVariable(var, param, avail);
|
return ro.GetScope(VSG_SCOPE_SELF)->GetVariable(var, param, extra);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -580,12 +583,12 @@ class NIHRailType : public NIHelper {
|
|||||||
void SetStringParameters(uint index) const override { this->SetObjectAtStringParameters(STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT_RAIL_TYPE, INVALID_STRING_ID, index); }
|
void SetStringParameters(uint index) const override { this->SetObjectAtStringParameters(STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT_RAIL_TYPE, INVALID_STRING_ID, index); }
|
||||||
uint32 GetGRFID(uint index) const override { return 0; }
|
uint32 GetGRFID(uint index) const override { return 0; }
|
||||||
|
|
||||||
uint Resolve(uint index, uint var, uint param, bool *avail) const override
|
uint Resolve(uint index, uint var, uint param, GetVariableExtra *extra) const override
|
||||||
{
|
{
|
||||||
/* There is no unique GRFFile for the tile. Multiple GRFs can define different parts of the railtype.
|
/* There is no unique GRFFile for the tile. Multiple GRFs can define different parts of the railtype.
|
||||||
* However, currently the NewGRF Debug GUI does not display variables depending on the GRF (like 0x7F) anyway. */
|
* However, currently the NewGRF Debug GUI does not display variables depending on the GRF (like 0x7F) anyway. */
|
||||||
RailTypeResolverObject ro(nullptr, index, TCX_NORMAL, RTSG_END);
|
RailTypeResolverObject ro(nullptr, index, TCX_NORMAL, RTSG_END);
|
||||||
return ro.GetScope(VSG_SCOPE_SELF)->GetVariable(var, param, avail);
|
return ro.GetScope(VSG_SCOPE_SELF)->GetVariable(var, param, extra);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExtraInfo(uint index, std::function<void(const char *)> print) const override
|
void ExtraInfo(uint index, std::function<void(const char *)> print) const override
|
||||||
@@ -644,10 +647,10 @@ class NIHAirportTile : public NIHelper {
|
|||||||
void SetStringParameters(uint index) const override { this->SetObjectAtStringParameters(STR_STATION_NAME, GetStationIndex(index), index); }
|
void SetStringParameters(uint index) const override { this->SetObjectAtStringParameters(STR_STATION_NAME, GetStationIndex(index), index); }
|
||||||
uint32 GetGRFID(uint index) const override { return (this->IsInspectable(index)) ? AirportTileSpec::Get(GetAirportGfx(index))->grf_prop.grffile->grfid : 0; }
|
uint32 GetGRFID(uint index) const override { return (this->IsInspectable(index)) ? AirportTileSpec::Get(GetAirportGfx(index))->grf_prop.grffile->grfid : 0; }
|
||||||
|
|
||||||
uint Resolve(uint index, uint var, uint param, bool *avail) const override
|
uint Resolve(uint index, uint var, uint param, GetVariableExtra *extra) const override
|
||||||
{
|
{
|
||||||
AirportTileResolverObject ro(AirportTileSpec::GetByTile(index), index, Station::GetByTile(index));
|
AirportTileResolverObject ro(AirportTileSpec::GetByTile(index), index, Station::GetByTile(index));
|
||||||
return ro.GetScope(VSG_SCOPE_SELF)->GetVariable(var, param, avail);
|
return ro.GetScope(VSG_SCOPE_SELF)->GetVariable(var, param, extra);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -684,10 +687,10 @@ class NIHTown : public NIHelper {
|
|||||||
bool PSAWithParameter() const override { return true; }
|
bool PSAWithParameter() const override { return true; }
|
||||||
uint GetPSASize(uint index, uint32 grfid) const override { return cpp_lengthof(PersistentStorage, storage); }
|
uint GetPSASize(uint index, uint32 grfid) const override { return cpp_lengthof(PersistentStorage, storage); }
|
||||||
|
|
||||||
uint Resolve(uint index, uint var, uint param, bool *avail) const override
|
uint Resolve(uint index, uint var, uint param, GetVariableExtra *extra) const override
|
||||||
{
|
{
|
||||||
TownResolverObject ro(nullptr, Town::Get(index), true);
|
TownResolverObject ro(nullptr, Town::Get(index), true);
|
||||||
return ro.GetScope(VSG_SCOPE_SELF)->GetVariable(var, param, avail);
|
return ro.GetScope(VSG_SCOPE_SELF)->GetVariable(var, param, extra);
|
||||||
}
|
}
|
||||||
|
|
||||||
const int32 *GetPSAFirstPosition(uint index, uint32 grfid) const override
|
const int32 *GetPSAFirstPosition(uint index, uint32 grfid) const override
|
||||||
@@ -738,7 +741,7 @@ class NIHStationStruct : public NIHelper {
|
|||||||
void SetStringParameters(uint index) const override { this->SetSimpleStringParameters(STR_STATION_NAME, index); }
|
void SetStringParameters(uint index) const override { this->SetSimpleStringParameters(STR_STATION_NAME, index); }
|
||||||
uint32 GetGRFID(uint index) const override { return 0; }
|
uint32 GetGRFID(uint index) const override { return 0; }
|
||||||
|
|
||||||
uint Resolve(uint index, uint var, uint param, bool *avail) const override
|
uint Resolve(uint index, uint var, uint param, GetVariableExtra *extra) const override
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -803,12 +806,12 @@ class NIHRoadType : public NIHelper {
|
|||||||
void SetStringParameters(uint index) const override { this->SetObjectAtStringParameters(STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT_RAIL_TYPE, INVALID_STRING_ID, index); }
|
void SetStringParameters(uint index) const override { this->SetObjectAtStringParameters(STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT_RAIL_TYPE, INVALID_STRING_ID, index); }
|
||||||
uint32 GetGRFID(uint index) const override { return 0; }
|
uint32 GetGRFID(uint index) const override { return 0; }
|
||||||
|
|
||||||
uint Resolve(uint index, uint var, uint param, bool *avail) const override
|
uint Resolve(uint index, uint var, uint param, GetVariableExtra *extra) const override
|
||||||
{
|
{
|
||||||
/* There is no unique GRFFile for the tile. Multiple GRFs can define different parts of the railtype.
|
/* There is no unique GRFFile for the tile. Multiple GRFs can define different parts of the railtype.
|
||||||
* However, currently the NewGRF Debug GUI does not display variables depending on the GRF (like 0x7F) anyway. */
|
* However, currently the NewGRF Debug GUI does not display variables depending on the GRF (like 0x7F) anyway. */
|
||||||
RoadTypeResolverObject ro(nullptr, index, TCX_NORMAL, ROTSG_END);
|
RoadTypeResolverObject ro(nullptr, index, TCX_NORMAL, ROTSG_END);
|
||||||
return ro.GetScope(VSG_SCOPE_SELF)->GetVariable(var, param, avail);
|
return ro.GetScope(VSG_SCOPE_SELF)->GetVariable(var, param, extra);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -1832,7 +1832,7 @@ static void SwapTrainFlags(uint16 *swap_flag1, uint16 *swap_flag2)
|
|||||||
*/
|
*/
|
||||||
static void UpdateStatusAfterSwap(Train *v)
|
static void UpdateStatusAfterSwap(Train *v)
|
||||||
{
|
{
|
||||||
v->cur_image_valid_dir = INVALID_DIR;
|
v->InvalidateImageCache();
|
||||||
|
|
||||||
/* Reverse the direction. */
|
/* Reverse the direction. */
|
||||||
if (v->track != TRACK_BIT_DEPOT) v->direction = ReverseDir(v->direction);
|
if (v->track != TRACK_BIT_DEPOT) v->direction = ReverseDir(v->direction);
|
||||||
@@ -3418,7 +3418,7 @@ void Train::MarkDirty()
|
|||||||
Train *v = this;
|
Train *v = this;
|
||||||
do {
|
do {
|
||||||
v->colourmap = PAL_NONE;
|
v->colourmap = PAL_NONE;
|
||||||
v->cur_image_valid_dir = INVALID_DIR;
|
v->InvalidateImageCache();
|
||||||
v->UpdateViewport(true, false);
|
v->UpdateViewport(true, false);
|
||||||
} while ((v = v->Next()) != nullptr);
|
} while ((v = v->Next()) != nullptr);
|
||||||
|
|
||||||
|
@@ -2695,7 +2695,7 @@ static VehicleEnterTileStatus VehicleEnter_TunnelBridge(Vehicle *v, TileIndex ti
|
|||||||
assert_msg(frame == rv->frame + 1 || rv->frame == _tunnel_turnaround_pre_visibility_frame[dir],
|
assert_msg(frame == rv->frame + 1 || rv->frame == _tunnel_turnaround_pre_visibility_frame[dir],
|
||||||
"frame: %u, rv->frame: %u, dir: %u, _tunnel_turnaround_pre_visibility_frame[dir]: %u", frame, rv->frame, dir, _tunnel_turnaround_pre_visibility_frame[dir]);
|
"frame: %u, rv->frame: %u, dir: %u, _tunnel_turnaround_pre_visibility_frame[dir]: %u", frame, rv->frame, dir, _tunnel_turnaround_pre_visibility_frame[dir]);
|
||||||
rv->tile = tile;
|
rv->tile = tile;
|
||||||
rv->cur_image_valid_dir = INVALID_DIR;
|
rv->InvalidateImageCache();
|
||||||
rv->state = RVSB_WORMHOLE;
|
rv->state = RVSB_WORMHOLE;
|
||||||
if (Tunnel::GetByTile(tile)->is_chunnel) SetBit(rv->gv_flags, GVF_CHUNNEL_BIT);
|
if (Tunnel::GetByTile(tile)->is_chunnel) SetBit(rv->gv_flags, GVF_CHUNNEL_BIT);
|
||||||
rv->vehstatus |= VS_HIDDEN;
|
rv->vehstatus |= VS_HIDDEN;
|
||||||
@@ -2710,7 +2710,7 @@ static VehicleEnterTileStatus VehicleEnter_TunnelBridge(Vehicle *v, TileIndex ti
|
|||||||
if (dir == ReverseDiagDir(vdir) && frame == (int) (_tunnel_visibility_frame[dir] - 1) && z == 0) {
|
if (dir == ReverseDiagDir(vdir) && frame == (int) (_tunnel_visibility_frame[dir] - 1) && z == 0) {
|
||||||
if (rv->tile != tile && GetOtherTunnelEnd(rv->tile) != tile) return VETSB_CONTINUE; // In chunnel
|
if (rv->tile != tile && GetOtherTunnelEnd(rv->tile) != tile) return VETSB_CONTINUE; // In chunnel
|
||||||
rv->tile = tile;
|
rv->tile = tile;
|
||||||
rv->cur_image_valid_dir = INVALID_DIR;
|
rv->InvalidateImageCache();
|
||||||
rv->state = DiagDirToDiagTrackdir(vdir);
|
rv->state = DiagDirToDiagTrackdir(vdir);
|
||||||
rv->frame = TILE_SIZE - (frame + 1);
|
rv->frame = TILE_SIZE - (frame + 1);
|
||||||
rv->vehstatus &= ~VS_HIDDEN;
|
rv->vehstatus &= ~VS_HIDDEN;
|
||||||
@@ -2753,7 +2753,7 @@ static VehicleEnterTileStatus VehicleEnter_TunnelBridge(Vehicle *v, TileIndex ti
|
|||||||
if (HasRoadTypeTram(tile) && HasBit(rv->compatible_roadtypes, GetRoadTypeTram(tile))) bits |= GetCustomBridgeHeadRoadBits(tile, RTT_TRAM);
|
if (HasRoadTypeTram(tile) && HasBit(rv->compatible_roadtypes, GetRoadTypeTram(tile))) bits |= GetCustomBridgeHeadRoadBits(tile, RTT_TRAM);
|
||||||
if (!(bits & DiagDirToRoadBits(GetTunnelBridgeDirection(tile)))) return VETSB_CONTINUE;
|
if (!(bits & DiagDirToRoadBits(GetTunnelBridgeDirection(tile)))) return VETSB_CONTINUE;
|
||||||
}
|
}
|
||||||
rv->cur_image_valid_dir = INVALID_DIR;
|
rv->InvalidateImageCache();
|
||||||
rv->state = RVSB_WORMHOLE;
|
rv->state = RVSB_WORMHOLE;
|
||||||
/* There are no slopes inside bridges / tunnels. */
|
/* There are no slopes inside bridges / tunnels. */
|
||||||
ClrBit(rv->gv_flags, GVF_GOINGUP_BIT);
|
ClrBit(rv->gv_flags, GVF_GOINGUP_BIT);
|
||||||
@@ -2790,7 +2790,7 @@ static VehicleEnterTileStatus VehicleEnter_TunnelBridge(Vehicle *v, TileIndex ti
|
|||||||
v->tile = tile;
|
v->tile = tile;
|
||||||
RoadVehicle *rv = RoadVehicle::From(v);
|
RoadVehicle *rv = RoadVehicle::From(v);
|
||||||
if (rv->state == RVSB_WORMHOLE) {
|
if (rv->state == RVSB_WORMHOLE) {
|
||||||
rv->cur_image_valid_dir = INVALID_DIR;
|
rv->InvalidateImageCache();
|
||||||
rv->state = DiagDirToDiagTrackdir(DirToDiagDir(v->direction));
|
rv->state = DiagDirToDiagTrackdir(DirToDiagDir(v->direction));
|
||||||
rv->frame = 0;
|
rv->frame = 0;
|
||||||
return VETSB_ENTERED_WORMHOLE;
|
return VETSB_ENTERED_WORMHOLE;
|
||||||
|
@@ -340,6 +340,7 @@ uint Vehicle::Crash(bool flooded)
|
|||||||
if (IsCargoInClass(v->cargo_type, CC_PASSENGERS)) pass += v->cargo.TotalCount();
|
if (IsCargoInClass(v->cargo_type, CC_PASSENGERS)) pass += v->cargo.TotalCount();
|
||||||
v->vehstatus |= VS_CRASHED;
|
v->vehstatus |= VS_CRASHED;
|
||||||
v->MarkAllViewportsDirty();
|
v->MarkAllViewportsDirty();
|
||||||
|
v->InvalidateImageCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
this->ClearSeparation();
|
this->ClearSeparation();
|
||||||
@@ -3757,6 +3758,8 @@ char *Vehicle::DumpVehicleFlags(char *b, const char *last, bool include_tile) co
|
|||||||
dump('l', HasBit(this->vcache.cached_veh_flags, VCF_LAST_VISUAL_EFFECT));
|
dump('l', HasBit(this->vcache.cached_veh_flags, VCF_LAST_VISUAL_EFFECT));
|
||||||
dump('z', HasBit(this->vcache.cached_veh_flags, VCF_GV_ZERO_SLOPE_RESIST));
|
dump('z', HasBit(this->vcache.cached_veh_flags, VCF_GV_ZERO_SLOPE_RESIST));
|
||||||
dump('d', HasBit(this->vcache.cached_veh_flags, VCF_IS_DRAWN));
|
dump('d', HasBit(this->vcache.cached_veh_flags, VCF_IS_DRAWN));
|
||||||
|
dump('t', HasBit(this->vcache.cached_veh_flags, VCF_REDRAW_ON_TRIGGER));
|
||||||
|
dump('s', HasBit(this->vcache.cached_veh_flags, VCF_REDRAW_ON_SPEED_CHANGE));
|
||||||
if (this->IsGroundVehicle()) {
|
if (this->IsGroundVehicle()) {
|
||||||
uint16 gv_flags = this->GetGroundVehicleFlags();
|
uint16 gv_flags = this->GetGroundVehicleFlags();
|
||||||
b += seprintf(b, last, ", gvf:");
|
b += seprintf(b, last, ", gvf:");
|
||||||
|
@@ -22,6 +22,7 @@
|
|||||||
#include "group_type.h"
|
#include "group_type.h"
|
||||||
#include "timetable.h"
|
#include "timetable.h"
|
||||||
#include "base_consist.h"
|
#include "base_consist.h"
|
||||||
|
#include "newgrf_cache_check.h"
|
||||||
#include "network/network.h"
|
#include "network/network.h"
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <map>
|
#include <map>
|
||||||
@@ -137,6 +138,8 @@ enum VehicleCacheFlags {
|
|||||||
VCF_LAST_VISUAL_EFFECT = 0, ///< Last vehicle in the consist with a visual effect.
|
VCF_LAST_VISUAL_EFFECT = 0, ///< Last vehicle in the consist with a visual effect.
|
||||||
VCF_GV_ZERO_SLOPE_RESIST = 1, ///< GroundVehicle: Consist has zero slope resistance (valid only for the first engine), may be false negative.
|
VCF_GV_ZERO_SLOPE_RESIST = 1, ///< GroundVehicle: Consist has zero slope resistance (valid only for the first engine), may be false negative.
|
||||||
VCF_IS_DRAWN = 2, ///< Vehicle is currently drawn
|
VCF_IS_DRAWN = 2, ///< Vehicle is currently drawn
|
||||||
|
VCF_REDRAW_ON_TRIGGER = 3, ///< Clear cur_image_valid_dir on changes to waiting_triggers (valid only for the first engine)
|
||||||
|
VCF_REDRAW_ON_SPEED_CHANGE = 4, ///< Clear cur_image_valid_dir on changes to cur_speed (ground vehicles) or aircraft movement state (aircraft) (valid only for the first engine)
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Cached often queried values common to all vehicles. */
|
/** Cached often queried values common to all vehicles. */
|
||||||
@@ -502,6 +505,28 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invalidates cached image
|
||||||
|
* @see InvalidateNewGRFCacheOfChain
|
||||||
|
*/
|
||||||
|
inline void InvalidateImageCache()
|
||||||
|
{
|
||||||
|
this->cur_image_valid_dir = INVALID_DIR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invalidates cached image of all vehicles in the chain (after the current vehicle)
|
||||||
|
* @see InvalidateImageCache
|
||||||
|
*/
|
||||||
|
inline void InvalidateImageCacheOfChain()
|
||||||
|
{
|
||||||
|
ClrBit(this->vcache.cached_veh_flags, VCF_REDRAW_ON_SPEED_CHANGE);
|
||||||
|
ClrBit(this->vcache.cached_veh_flags, VCF_REDRAW_ON_TRIGGER);
|
||||||
|
for (Vehicle *u = this; u != nullptr; u = u->Next()) {
|
||||||
|
u->InvalidateImageCache();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the vehicle is a ground vehicle.
|
* Check if the vehicle is a ground vehicle.
|
||||||
* @return True iff the vehicle is a train or a road vehicle.
|
* @return True iff the vehicle is a train or a road vehicle.
|
||||||
@@ -1242,16 +1267,12 @@ struct SpecializedVehicle : public Vehicle {
|
|||||||
/* Skip updating sprites on dedicated servers without screen */
|
/* Skip updating sprites on dedicated servers without screen */
|
||||||
if (_network_dedicated) return;
|
if (_network_dedicated) return;
|
||||||
|
|
||||||
extern bool _sprite_group_resolve_check_veh_check;
|
|
||||||
extern VehicleType _sprite_group_resolve_check_veh_type;
|
|
||||||
|
|
||||||
/* Explicitly choose method to call to prevent vtable dereference -
|
/* Explicitly choose method to call to prevent vtable dereference -
|
||||||
* it gives ~3% runtime improvements in games with many vehicles */
|
* it gives ~3% runtime improvements in games with many vehicles */
|
||||||
if (update_delta) ((T *)this)->T::UpdateDeltaXY();
|
if (update_delta) ((T *)this)->T::UpdateDeltaXY();
|
||||||
const Direction current_direction = ((T *)this)->GetMapImageDirection();
|
const Direction current_direction = ((T *)this)->GetMapImageDirection();
|
||||||
if (this->cur_image_valid_dir != current_direction) {
|
if (this->cur_image_valid_dir != current_direction) {
|
||||||
_sprite_group_resolve_check_veh_check = true;
|
_sprite_group_resolve_check_veh_check = true;
|
||||||
_sprite_group_resolve_check_veh_type = EXPECTED_TYPE;
|
|
||||||
VehicleSpriteSeq seq;
|
VehicleSpriteSeq seq;
|
||||||
((T *)this)->T::GetImage(current_direction, EIT_ON_MAP, &seq);
|
((T *)this)->T::GetImage(current_direction, EIT_ON_MAP, &seq);
|
||||||
this->cur_image_valid_dir = _sprite_group_resolve_check_veh_check ? current_direction : INVALID_DIR;
|
this->cur_image_valid_dir = _sprite_group_resolve_check_veh_check ? current_direction : INVALID_DIR;
|
||||||
|
Reference in New Issue
Block a user