From e4b45169c1cc740862d9bca8706c179fb931676f Mon Sep 17 00:00:00 2001 From: frosch Date: Sat, 7 Nov 2009 16:37:48 +0000 Subject: [PATCH] (svn r17996) [0.7] -Backport from trunk: - Fix: [NewGRF] 'last_value' and 'reseed' are shared between procedure and main chain, 'scope' and 'count' are not (r17672) - Change: [NewGRF] Apply default refitmasks only when the NewGRF did not set any of the three refittability properties (xor mask, positive classes, negative classes) (r17663) --- src/newgrf.cpp | 68 +++++++++++++++++++++++--------------- src/newgrf_spritegroup.cpp | 8 +++-- src/newgrf_spritegroup.h | 3 -- 3 files changed, 47 insertions(+), 32 deletions(-) diff --git a/src/newgrf.cpp b/src/newgrf.cpp index 9bf1b30d58..1e90f66c00 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -93,6 +93,7 @@ enum { struct GRFTempEngineData { uint16 cargo_allowed; uint16 cargo_disallowed; + bool refitmask_valid; ///< Did the newgrf set any refittability property? If not, default refittability will be applied. uint8 rv_max_speed; ///< Temporary storage of RV prop 15, maximum speed in mph/0.8 }; @@ -671,6 +672,7 @@ static ChangeInfoResult RailVehicleChangeInfo(uint engine, int numinfo, int prop case 0x1D: // Refit cargo ei->refit_mask = grf_load_dword(&buf); + _gted[e->index].refitmask_valid = true; break; case 0x1E: // Callback @@ -725,10 +727,12 @@ static ChangeInfoResult RailVehicleChangeInfo(uint engine, int numinfo, int prop case 0x28: // Cargo classes allowed _gted[e->index].cargo_allowed = grf_load_word(&buf); + _gted[e->index].refitmask_valid = true; break; case 0x29: // Cargo classes disallowed _gted[e->index].cargo_disallowed = grf_load_word(&buf); + _gted[e->index].refitmask_valid = true; break; case 0x2A: // Long format introduction date (days since year 0) @@ -832,6 +836,7 @@ static ChangeInfoResult RoadVehicleChangeInfo(uint engine, int numinfo, int prop case 0x16: // Cargos available for refitting ei->refit_mask = grf_load_dword(&buf); + _gted[e->index].refitmask_valid = true; break; case 0x17: // Callback mask @@ -861,10 +866,12 @@ static ChangeInfoResult RoadVehicleChangeInfo(uint engine, int numinfo, int prop case 0x1D: // Cargo classes allowed _gted[e->index].cargo_allowed = grf_load_word(&buf); + _gted[e->index].refitmask_valid = true; break; case 0x1E: // Cargo classes disallowed _gted[e->index].cargo_disallowed = grf_load_word(&buf); + _gted[e->index].refitmask_valid = true; break; case 0x1F: // Long format introduction date (days since year 0) @@ -946,6 +953,7 @@ static ChangeInfoResult ShipVehicleChangeInfo(uint engine, int numinfo, int prop case 0x11: // Cargos available for refitting ei->refit_mask = grf_load_dword(&buf); + _gted[e->index].refitmask_valid = true; break; case 0x12: // Callback mask @@ -974,10 +982,12 @@ static ChangeInfoResult ShipVehicleChangeInfo(uint engine, int numinfo, int prop case 0x18: // Cargo classes allowed _gted[e->index].cargo_allowed = grf_load_word(&buf); + _gted[e->index].refitmask_valid = true; break; case 0x19: // Cargo classes disallowed _gted[e->index].cargo_disallowed = grf_load_word(&buf); + _gted[e->index].refitmask_valid = true; break; case 0x1A: // Long format introduction date (days since year 0) @@ -1062,6 +1072,7 @@ static ChangeInfoResult AircraftVehicleChangeInfo(uint engine, int numinfo, int case 0x13: // Cargos available for refitting ei->refit_mask = grf_load_dword(&buf); + _gted[e->index].refitmask_valid = true; break; case 0x14: // Callback mask @@ -1083,10 +1094,12 @@ static ChangeInfoResult AircraftVehicleChangeInfo(uint engine, int numinfo, int case 0x18: // Cargo classes allowed _gted[e->index].cargo_allowed = grf_load_word(&buf); + _gted[e->index].refitmask_valid = true; break; case 0x19: // Cargo classes disallowed _gted[e->index].cargo_disallowed = grf_load_word(&buf); + _gted[e->index].refitmask_valid = true; break; case 0x1A: // Long format introduction date (days since year 0) @@ -5765,39 +5778,42 @@ static void CalculateRefitMasks() uint32 not_mask = 0; uint32 xor_mask = 0; - if (ei->refit_mask != 0) { - const GRFFile *file = e->grffile; - if (file != NULL && file->cargo_max != 0) { - /* Apply cargo translation table to the refit mask */ - uint num_cargo = min(32, file->cargo_max); - for (uint i = 0; i < num_cargo; i++) { - if (!HasBit(ei->refit_mask, i)) continue; + /* Did the newgrf specify any refitting? If not, use defaults. */ + if (_gted[engine].refitmask_valid) { + if (ei->refit_mask != 0) { + const GRFFile *file = e->grffile; + if (file != NULL && file->cargo_max != 0) { + /* Apply cargo translation table to the refit mask */ + uint num_cargo = min(32, file->cargo_max); + for (uint i = 0; i < num_cargo; i++) { + if (!HasBit(ei->refit_mask, i)) continue; - CargoID c = GetCargoIDByLabel(file->cargo_list[i]); - if (c == CT_INVALID) continue; + CargoID c = GetCargoIDByLabel(file->cargo_list[i]); + if (c == CT_INVALID) continue; - SetBit(xor_mask, c); - } - } else { - /* No cargo table, so use the cargo bitnum values */ - for (CargoID c = 0; c < NUM_CARGO; c++) { - const CargoSpec *cs = GetCargo(c); - if (!cs->IsValid()) continue; + SetBit(xor_mask, c); + } + } else { + /* No cargo table, so use the cargo bitnum values */ + for (CargoID c = 0; c < NUM_CARGO; c++) { + const CargoSpec *cs = GetCargo(c); + if (!cs->IsValid()) continue; - if (HasBit(ei->refit_mask, cs->bitnum)) SetBit(xor_mask, c); + if (HasBit(ei->refit_mask, cs->bitnum)) SetBit(xor_mask, c); + } } } - } - if (_gted[engine].cargo_allowed != 0) { - /* Build up the list of cargo types from the set cargo classes. */ - for (CargoID i = 0; i < NUM_CARGO; i++) { - const CargoSpec *cs = GetCargo(i); - if (_gted[engine].cargo_allowed & cs->classes) SetBit(mask, i); - if (_gted[engine].cargo_disallowed & cs->classes) SetBit(not_mask, i); + if (_gted[engine].cargo_allowed != 0) { + /* Build up the list of cargo types from the set cargo classes. */ + for (CargoID i = 0; i < NUM_CARGO; i++) { + const CargoSpec *cs = GetCargo(i); + if (_gted[engine].cargo_allowed & cs->classes) SetBit(mask, i); + if (_gted[engine].cargo_disallowed & cs->classes) SetBit(not_mask, i); + } } - } else if (xor_mask == 0) { - /* Don't apply default refit mask to wagons or engines with no capacity */ + } else { + /* Don't apply default refit mask to wagons nor engines with no capacity */ if (e->type != VEH_TRAIN || (e->u.rail.capacity != 0 && e->u.rail.railveh_type != RAILVEH_WAGON)) { const CargoLabel *cl = _default_refitmasks[e->type]; for (uint i = 0;; i++) { diff --git a/src/newgrf_spritegroup.cpp b/src/newgrf_spritegroup.cpp index 511a6be2c1..9626275f55 100644 --- a/src/newgrf_spritegroup.cpp +++ b/src/newgrf_spritegroup.cpp @@ -173,14 +173,16 @@ static inline const SpriteGroup *ResolveVariable(const SpriteGroup *group, Resol /* Try to get the variable. We shall assume it is available, unless told otherwise. */ bool available = true; if (adjust->variable == 0x7E) { - ResolverObject subobject = *object; - subobject.procedure_call = true; - const SpriteGroup *subgroup = Resolve(adjust->subroutine, &subobject); + const SpriteGroup *subgroup = Resolve(adjust->subroutine, object); if (subgroup == NULL || subgroup->type != SGT_CALLBACK) { value = CALLBACK_FAILED; } else { value = subgroup->g.callback.result; } + + /* Reset values to current scope. + * Note: 'last_value' and 'reseed' are shared between the main chain and the procedure */ + object->scope = group->g.determ.var_scope; } else { value = GetVariable(object, adjust->variable, adjust->parameter, &available); } diff --git a/src/newgrf_spritegroup.h b/src/newgrf_spritegroup.h index bc078808f2..c569ac942a 100644 --- a/src/newgrf_spritegroup.h +++ b/src/newgrf_spritegroup.h @@ -206,7 +206,6 @@ struct ResolverObject { CallbackID callback; uint32 callback_param1; uint32 callback_param2; - bool procedure_call; ///< true if we are currently resolving a var 0x7E procedure result. byte trigger; byte count; @@ -266,8 +265,6 @@ struct ResolverObject { void (*SetTriggers)(const struct ResolverObject*, int); uint32 (*GetVariable)(const struct ResolverObject*, byte, byte, bool*); const SpriteGroup *(*ResolveReal)(const struct ResolverObject*, const SpriteGroup*); - - ResolverObject() : procedure_call(false) { } };