diff --git a/src/newgrf_spritegroup.cpp b/src/newgrf_spritegroup.cpp index 47cb718015..a4ce0cd731 100644 --- a/src/newgrf_spritegroup.cpp +++ b/src/newgrf_spritegroup.cpp @@ -13,6 +13,7 @@ #include "debug.h" #include "newgrf_spritegroup.h" #include "core/pool_func.hpp" +#include "vehicle_type.h" #include "safeguards.h" @@ -237,8 +238,8 @@ static U EvalAdjustT(const DeterministicSpriteGroupAdjust *adjust, ScopeResolver } } -bool _sprite_group_resolve_check_veh_enable = false; -bool _sprite_group_resolve_check_veh_result = false; +bool _sprite_group_resolve_check_veh_check = false; +VehicleType _sprite_group_resolve_check_veh_type; const SpriteGroup *DeterministicSpriteGroup::Resolve(ResolverObject &object) const { @@ -254,7 +255,7 @@ const SpriteGroup *DeterministicSpriteGroup::Resolve(ResolverObject &object) con /* Try to get the variable. We shall assume it is available, unless told otherwise. */ bool available = true; if (adjust->variable == 0x7E) { - _sprite_group_resolve_check_veh_result = false; + _sprite_group_resolve_check_veh_check = false; const SpriteGroup *subgroup = SpriteGroup::Resolve(adjust->subroutine, object, false); if (subgroup == NULL) { value = CALLBACK_FAILED; @@ -264,10 +265,10 @@ const SpriteGroup *DeterministicSpriteGroup::Resolve(ResolverObject &object) con /* Note: 'last_value' and 'reseed' are shared between the main chain and the procedure */ } else if (adjust->variable == 0x7B) { - _sprite_group_resolve_check_veh_result = false; + _sprite_group_resolve_check_veh_check = false; value = GetVariable(object, scope, adjust->parameter, last_value, &available); } else { - if (_sprite_group_resolve_check_veh_enable) { + if (_sprite_group_resolve_check_veh_check) { switch (adjust->variable) { // whitelist of variables which can be checked without requiring an immediate re-check on the next tick case 0xC: @@ -302,8 +303,15 @@ const SpriteGroup *DeterministicSpriteGroup::Resolve(ResolverObject &object) con 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_result = false; + _sprite_group_resolve_check_veh_check = false; break; } } diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp index 3668596be2..6564ea355e 100644 --- a/src/road_cmd.cpp +++ b/src/road_cmd.cpp @@ -1751,6 +1751,7 @@ static VehicleEnterTileStatus VehicleEnter_Road(Vehicle *v, TileIndex tile, int RoadVehicle *rv = RoadVehicle::From(v); if (rv->frame == RVC_DEPOT_STOP_FRAME && _roadveh_enter_depot_dir[GetRoadDepotDirection(tile)] == rv->state) { + rv->cur_image_valid_dir = INVALID_DIR; rv->state = RVSB_IN_DEPOT; rv->vehstatus |= VS_HIDDEN; rv->direction = ReverseDir(rv->direction); diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp index e16956c63f..d1cd0f7444 100644 --- a/src/roadveh_cmd.cpp +++ b/src/roadveh_cmd.cpp @@ -1025,6 +1025,7 @@ static bool RoadVehLeaveDepot(RoadVehicle *v, bool first) } v->vehstatus &= ~VS_HIDDEN; + v->cur_image_valid_dir = INVALID_DIR; v->state = tdir; v->frame = RVC_DEPOT_START_FRAME; @@ -1306,6 +1307,7 @@ again: } if (!HasBit(r, VETS_ENTERED_WORMHOLE)) { + v->cur_image_valid_dir = INVALID_DIR; v->tile = tile; v->state = (byte)dir; v->frame = start_frame; @@ -1372,6 +1374,7 @@ again: return false; } + v->cur_image_valid_dir = INVALID_DIR; v->state = dir; v->frame = turn_around_start_frame; diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp index 656db507ca..b7cf858be0 100644 --- a/src/tunnelbridge_cmd.cpp +++ b/src/tunnelbridge_cmd.cpp @@ -1949,6 +1949,7 @@ static VehicleEnterTileStatus VehicleEnter_TunnelBridge(Vehicle *v, TileIndex ti /* Frame should be equal to the next frame number in the RV's movement */ assert(frame == rv->frame + 1); rv->tile = tile; + rv->cur_image_valid_dir = INVALID_DIR; rv->state = RVSB_WORMHOLE; rv->vehstatus |= VS_HIDDEN; return VETSB_ENTERED_WORMHOLE; @@ -1960,6 +1961,7 @@ static VehicleEnterTileStatus VehicleEnter_TunnelBridge(Vehicle *v, TileIndex ti /* We're at the tunnel exit ?? */ if (dir == ReverseDiagDir(vdir) && frame == TILE_SIZE - _tunnel_visibility_frame[dir] && z == 0) { rv->tile = tile; + rv->cur_image_valid_dir = INVALID_DIR; rv->state = DiagDirToDiagTrackdir(vdir); rv->frame = frame; rv->vehstatus &= ~VS_HIDDEN; @@ -1990,6 +1992,7 @@ static VehicleEnterTileStatus VehicleEnter_TunnelBridge(Vehicle *v, TileIndex ti case VEH_ROAD: { RoadVehicle *rv = RoadVehicle::From(v); + rv->cur_image_valid_dir = INVALID_DIR; rv->state = RVSB_WORMHOLE; /* There are no slopes inside bridges / tunnels. */ ClrBit(rv->gv_flags, GVF_GOINGUP_BIT); @@ -2019,6 +2022,7 @@ static VehicleEnterTileStatus VehicleEnter_TunnelBridge(Vehicle *v, TileIndex ti case VEH_ROAD: { RoadVehicle *rv = RoadVehicle::From(v); if (rv->state == RVSB_WORMHOLE) { + rv->cur_image_valid_dir = INVALID_DIR; rv->state = DiagDirToDiagTrackdir(vdir); rv->frame = 0; return VETSB_ENTERED_WORMHOLE; diff --git a/src/vehicle_base.h b/src/vehicle_base.h index ff43189eff..fbe29794f7 100644 --- a/src/vehicle_base.h +++ b/src/vehicle_base.h @@ -1148,19 +1148,19 @@ struct SpecializedVehicle : public Vehicle { /* Skip updating sprites on dedicated servers without screen */ if (_network_dedicated) return; - extern bool _sprite_group_resolve_check_veh_enable; - extern bool _sprite_group_resolve_check_veh_result; + 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 - * it gives ~3% runtime improvements in games with many vehicles */ if (update_delta) ((T *)this)->T::UpdateDeltaXY(this->direction); SpriteID old_image = this->cur_image; if (this->cur_image_valid_dir != this->direction) { - _sprite_group_resolve_check_veh_enable = true; - _sprite_group_resolve_check_veh_result = true; + _sprite_group_resolve_check_veh_check = true; + _sprite_group_resolve_check_veh_type = EXPECTED_TYPE; this->cur_image = ((T *)this)->T::GetImage(this->direction, EIT_ON_MAP); - this->cur_image_valid_dir = _sprite_group_resolve_check_veh_result ? this->direction : INVALID_DIR; - _sprite_group_resolve_check_veh_enable = false; + this->cur_image_valid_dir = _sprite_group_resolve_check_veh_check ? this->direction : INVALID_DIR; + _sprite_group_resolve_check_veh_check = false; } if (force_update || this->cur_image != old_image) this->Vehicle::UpdateViewport(true); }