mirror of https://github.com/OpenTTD/OpenTTD
(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)release/0.7
parent
d8c4ed5118
commit
e4b45169c1
|
@ -93,6 +93,7 @@ enum {
|
||||||
struct GRFTempEngineData {
|
struct GRFTempEngineData {
|
||||||
uint16 cargo_allowed;
|
uint16 cargo_allowed;
|
||||||
uint16 cargo_disallowed;
|
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
|
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
|
case 0x1D: // Refit cargo
|
||||||
ei->refit_mask = grf_load_dword(&buf);
|
ei->refit_mask = grf_load_dword(&buf);
|
||||||
|
_gted[e->index].refitmask_valid = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1E: // Callback
|
case 0x1E: // Callback
|
||||||
|
@ -725,10 +727,12 @@ static ChangeInfoResult RailVehicleChangeInfo(uint engine, int numinfo, int prop
|
||||||
|
|
||||||
case 0x28: // Cargo classes allowed
|
case 0x28: // Cargo classes allowed
|
||||||
_gted[e->index].cargo_allowed = grf_load_word(&buf);
|
_gted[e->index].cargo_allowed = grf_load_word(&buf);
|
||||||
|
_gted[e->index].refitmask_valid = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x29: // Cargo classes disallowed
|
case 0x29: // Cargo classes disallowed
|
||||||
_gted[e->index].cargo_disallowed = grf_load_word(&buf);
|
_gted[e->index].cargo_disallowed = grf_load_word(&buf);
|
||||||
|
_gted[e->index].refitmask_valid = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x2A: // Long format introduction date (days since year 0)
|
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
|
case 0x16: // Cargos available for refitting
|
||||||
ei->refit_mask = grf_load_dword(&buf);
|
ei->refit_mask = grf_load_dword(&buf);
|
||||||
|
_gted[e->index].refitmask_valid = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x17: // Callback mask
|
case 0x17: // Callback mask
|
||||||
|
@ -861,10 +866,12 @@ static ChangeInfoResult RoadVehicleChangeInfo(uint engine, int numinfo, int prop
|
||||||
|
|
||||||
case 0x1D: // Cargo classes allowed
|
case 0x1D: // Cargo classes allowed
|
||||||
_gted[e->index].cargo_allowed = grf_load_word(&buf);
|
_gted[e->index].cargo_allowed = grf_load_word(&buf);
|
||||||
|
_gted[e->index].refitmask_valid = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1E: // Cargo classes disallowed
|
case 0x1E: // Cargo classes disallowed
|
||||||
_gted[e->index].cargo_disallowed = grf_load_word(&buf);
|
_gted[e->index].cargo_disallowed = grf_load_word(&buf);
|
||||||
|
_gted[e->index].refitmask_valid = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1F: // Long format introduction date (days since year 0)
|
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
|
case 0x11: // Cargos available for refitting
|
||||||
ei->refit_mask = grf_load_dword(&buf);
|
ei->refit_mask = grf_load_dword(&buf);
|
||||||
|
_gted[e->index].refitmask_valid = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x12: // Callback mask
|
case 0x12: // Callback mask
|
||||||
|
@ -974,10 +982,12 @@ static ChangeInfoResult ShipVehicleChangeInfo(uint engine, int numinfo, int prop
|
||||||
|
|
||||||
case 0x18: // Cargo classes allowed
|
case 0x18: // Cargo classes allowed
|
||||||
_gted[e->index].cargo_allowed = grf_load_word(&buf);
|
_gted[e->index].cargo_allowed = grf_load_word(&buf);
|
||||||
|
_gted[e->index].refitmask_valid = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x19: // Cargo classes disallowed
|
case 0x19: // Cargo classes disallowed
|
||||||
_gted[e->index].cargo_disallowed = grf_load_word(&buf);
|
_gted[e->index].cargo_disallowed = grf_load_word(&buf);
|
||||||
|
_gted[e->index].refitmask_valid = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1A: // Long format introduction date (days since year 0)
|
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
|
case 0x13: // Cargos available for refitting
|
||||||
ei->refit_mask = grf_load_dword(&buf);
|
ei->refit_mask = grf_load_dword(&buf);
|
||||||
|
_gted[e->index].refitmask_valid = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x14: // Callback mask
|
case 0x14: // Callback mask
|
||||||
|
@ -1083,10 +1094,12 @@ static ChangeInfoResult AircraftVehicleChangeInfo(uint engine, int numinfo, int
|
||||||
|
|
||||||
case 0x18: // Cargo classes allowed
|
case 0x18: // Cargo classes allowed
|
||||||
_gted[e->index].cargo_allowed = grf_load_word(&buf);
|
_gted[e->index].cargo_allowed = grf_load_word(&buf);
|
||||||
|
_gted[e->index].refitmask_valid = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x19: // Cargo classes disallowed
|
case 0x19: // Cargo classes disallowed
|
||||||
_gted[e->index].cargo_disallowed = grf_load_word(&buf);
|
_gted[e->index].cargo_disallowed = grf_load_word(&buf);
|
||||||
|
_gted[e->index].refitmask_valid = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1A: // Long format introduction date (days since year 0)
|
case 0x1A: // Long format introduction date (days since year 0)
|
||||||
|
@ -5765,39 +5778,42 @@ static void CalculateRefitMasks()
|
||||||
uint32 not_mask = 0;
|
uint32 not_mask = 0;
|
||||||
uint32 xor_mask = 0;
|
uint32 xor_mask = 0;
|
||||||
|
|
||||||
if (ei->refit_mask != 0) {
|
/* Did the newgrf specify any refitting? If not, use defaults. */
|
||||||
const GRFFile *file = e->grffile;
|
if (_gted[engine].refitmask_valid) {
|
||||||
if (file != NULL && file->cargo_max != 0) {
|
if (ei->refit_mask != 0) {
|
||||||
/* Apply cargo translation table to the refit mask */
|
const GRFFile *file = e->grffile;
|
||||||
uint num_cargo = min(32, file->cargo_max);
|
if (file != NULL && file->cargo_max != 0) {
|
||||||
for (uint i = 0; i < num_cargo; i++) {
|
/* Apply cargo translation table to the refit mask */
|
||||||
if (!HasBit(ei->refit_mask, i)) continue;
|
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]);
|
CargoID c = GetCargoIDByLabel(file->cargo_list[i]);
|
||||||
if (c == CT_INVALID) continue;
|
if (c == CT_INVALID) continue;
|
||||||
|
|
||||||
SetBit(xor_mask, c);
|
SetBit(xor_mask, c);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* No cargo table, so use the cargo bitnum values */
|
/* No cargo table, so use the cargo bitnum values */
|
||||||
for (CargoID c = 0; c < NUM_CARGO; c++) {
|
for (CargoID c = 0; c < NUM_CARGO; c++) {
|
||||||
const CargoSpec *cs = GetCargo(c);
|
const CargoSpec *cs = GetCargo(c);
|
||||||
if (!cs->IsValid()) continue;
|
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) {
|
if (_gted[engine].cargo_allowed != 0) {
|
||||||
/* Build up the list of cargo types from the set cargo classes. */
|
/* Build up the list of cargo types from the set cargo classes. */
|
||||||
for (CargoID i = 0; i < NUM_CARGO; i++) {
|
for (CargoID i = 0; i < NUM_CARGO; i++) {
|
||||||
const CargoSpec *cs = GetCargo(i);
|
const CargoSpec *cs = GetCargo(i);
|
||||||
if (_gted[engine].cargo_allowed & cs->classes) SetBit(mask, 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_disallowed & cs->classes) SetBit(not_mask, i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (xor_mask == 0) {
|
} else {
|
||||||
/* Don't apply default refit mask to wagons or engines with no capacity */
|
/* 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)) {
|
if (e->type != VEH_TRAIN || (e->u.rail.capacity != 0 && e->u.rail.railveh_type != RAILVEH_WAGON)) {
|
||||||
const CargoLabel *cl = _default_refitmasks[e->type];
|
const CargoLabel *cl = _default_refitmasks[e->type];
|
||||||
for (uint i = 0;; i++) {
|
for (uint i = 0;; i++) {
|
||||||
|
|
|
@ -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. */
|
/* Try to get the variable. We shall assume it is available, unless told otherwise. */
|
||||||
bool available = true;
|
bool available = true;
|
||||||
if (adjust->variable == 0x7E) {
|
if (adjust->variable == 0x7E) {
|
||||||
ResolverObject subobject = *object;
|
const SpriteGroup *subgroup = Resolve(adjust->subroutine, object);
|
||||||
subobject.procedure_call = true;
|
|
||||||
const SpriteGroup *subgroup = Resolve(adjust->subroutine, &subobject);
|
|
||||||
if (subgroup == NULL || subgroup->type != SGT_CALLBACK) {
|
if (subgroup == NULL || subgroup->type != SGT_CALLBACK) {
|
||||||
value = CALLBACK_FAILED;
|
value = CALLBACK_FAILED;
|
||||||
} else {
|
} else {
|
||||||
value = subgroup->g.callback.result;
|
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 {
|
} else {
|
||||||
value = GetVariable(object, adjust->variable, adjust->parameter, &available);
|
value = GetVariable(object, adjust->variable, adjust->parameter, &available);
|
||||||
}
|
}
|
||||||
|
|
|
@ -206,7 +206,6 @@ struct ResolverObject {
|
||||||
CallbackID callback;
|
CallbackID callback;
|
||||||
uint32 callback_param1;
|
uint32 callback_param1;
|
||||||
uint32 callback_param2;
|
uint32 callback_param2;
|
||||||
bool procedure_call; ///< true if we are currently resolving a var 0x7E procedure result.
|
|
||||||
|
|
||||||
byte trigger;
|
byte trigger;
|
||||||
byte count;
|
byte count;
|
||||||
|
@ -266,8 +265,6 @@ struct ResolverObject {
|
||||||
void (*SetTriggers)(const struct ResolverObject*, int);
|
void (*SetTriggers)(const struct ResolverObject*, int);
|
||||||
uint32 (*GetVariable)(const struct ResolverObject*, byte, byte, bool*);
|
uint32 (*GetVariable)(const struct ResolverObject*, byte, byte, bool*);
|
||||||
const SpriteGroup *(*ResolveReal)(const struct ResolverObject*, const SpriteGroup*);
|
const SpriteGroup *(*ResolveReal)(const struct ResolverObject*, const SpriteGroup*);
|
||||||
|
|
||||||
ResolverObject() : procedure_call(false) { }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue