summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorfrosch <frosch@openttd.org>2012-02-07 22:03:03 +0000
committerfrosch <frosch@openttd.org>2012-02-07 22:03:03 +0000
commit306a0967d0825af5a3d982da306ddb7164983563 (patch)
treeedb6ef094937378a7371af42e77a7b4e52620d48 /src
parentcc3cbc652fc4c57b64a321f771dc91104b4d488e (diff)
downloadopenttd-306a0967d0825af5a3d982da306ddb7164983563.tar.xz
(svn r23912) -Fix: When testing whether a engine shall only carry the default cargo, check ctt_include_mask for being empty before applying cargo translation.
Diffstat (limited to 'src')
-rw-r--r--src/newgrf.cpp58
1 files changed, 39 insertions, 19 deletions
diff --git a/src/newgrf.cpp b/src/newgrf.cpp
index 1a4894044..6365d86f9 100644
--- a/src/newgrf.cpp
+++ b/src/newgrf.cpp
@@ -284,15 +284,35 @@ static const uint MAX_STATIONS = 256;
/** Temporary engine data used when loading only */
struct GRFTempEngineData {
+ /** Summary state of refitability properties */
+ enum Refittability {
+ UNSET = 0, ///< No properties assigned. Default refit masks shall be activated.
+ EMPTY, ///< GRF defined vehicle as not-refittable. The vehicle shall only carry the default cargo.
+ NONEMPTY, ///< GRF defined the vehicle as refittable. If the refitmask is empty after translation (cargotypes not available), disable the vehicle.
+ };
+
uint16 cargo_allowed;
uint16 cargo_disallowed;
RailTypeLabel railtypelabel;
const GRFFile *refitmask_grf; ///< GRF providing the cargo translation table for the refitmask.
- bool refitmask_valid; ///< Did the newgrf set any refittability property? If not, default refittability will be applied.
+ Refittability refittability; ///< Did the newgrf set any refittability property? If not, default refittability will be applied. bool prop27_set; ///< Did the NewGRF set property 27 (misc flags)?
bool prop27_set; ///< Did the NewGRF set property 27 (misc flags)?
uint8 rv_max_speed; ///< Temporary storage of RV prop 15, maximum speed in mph/0.8
uint32 ctt_include_mask; ///< Cargo types always included in the refit mask.
uint32 ctt_exclude_mask; ///< Cargo types always excluded from the refit mask.
+
+ /**
+ * Update the summary refittability on setting a refittability property.
+ * @param non_empty true if the GRF sets the vehicle to be refittable.
+ */
+ void UpdateRefittability(bool non_empty)
+ {
+ if (non_empty) {
+ this->refittability = NONEMPTY;
+ } else if (this->refittability == UNSET) {
+ this->refittability = EMPTY;
+ }
+ }
};
static GRFTempEngineData *_gted; ///< Temporary engine data used during NewGRF loading
@@ -1079,7 +1099,7 @@ static ChangeInfoResult RailVehicleChangeInfo(uint engine, int numinfo, int prop
case 0x1D: // Refit cargo
ei->refit_mask = buf->ReadDWord();
- _gted[e->index].refitmask_valid = true;
+ _gted[e->index].UpdateRefittability(ei->refit_mask != 0);
_gted[e->index].refitmask_grf = _cur.grffile;
break;
@@ -1140,12 +1160,12 @@ static ChangeInfoResult RailVehicleChangeInfo(uint engine, int numinfo, int prop
case 0x28: // Cargo classes allowed
_gted[e->index].cargo_allowed = buf->ReadWord();
- _gted[e->index].refitmask_valid = true;
+ _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
break;
case 0x29: // Cargo classes disallowed
_gted[e->index].cargo_disallowed = buf->ReadWord();
- _gted[e->index].refitmask_valid = true;
+ _gted[e->index].UpdateRefittability(false);
break;
case 0x2A: // Long format introduction date (days since year 0)
@@ -1159,12 +1179,12 @@ static ChangeInfoResult RailVehicleChangeInfo(uint engine, int numinfo, int prop
case 0x2C: // CTT refit include list
case 0x2D: { // CTT refit exclude list
uint8 count = buf->ReadByte();
+ _gted[e->index].UpdateRefittability(prop == 0x2C && count != 0);
while (count--) {
CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
if (ctype == CT_INVALID) continue;
SetBit(prop == 0x2C ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask, ctype);
}
- _gted[e->index].refitmask_valid = true;
break;
}
@@ -1266,7 +1286,7 @@ static ChangeInfoResult RoadVehicleChangeInfo(uint engine, int numinfo, int prop
case 0x16: // Cargoes available for refitting
ei->refit_mask = buf->ReadDWord();
- _gted[e->index].refitmask_valid = true;
+ _gted[e->index].UpdateRefittability(ei->refit_mask != 0);
_gted[e->index].refitmask_grf = _cur.grffile;
break;
@@ -1297,12 +1317,12 @@ static ChangeInfoResult RoadVehicleChangeInfo(uint engine, int numinfo, int prop
case 0x1D: // Cargo classes allowed
_gted[e->index].cargo_allowed = buf->ReadWord();
- _gted[e->index].refitmask_valid = true;
+ _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
break;
case 0x1E: // Cargo classes disallowed
_gted[e->index].cargo_disallowed = buf->ReadWord();
- _gted[e->index].refitmask_valid = true;
+ _gted[e->index].UpdateRefittability(false);
break;
case 0x1F: // Long format introduction date (days since year 0)
@@ -1334,12 +1354,12 @@ static ChangeInfoResult RoadVehicleChangeInfo(uint engine, int numinfo, int prop
case 0x24: // CTT refit include list
case 0x25: { // CTT refit exclude list
uint8 count = buf->ReadByte();
+ _gted[e->index].UpdateRefittability(prop == 0x24 && count != 0);
while (count--) {
CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
if (ctype == CT_INVALID) continue;
SetBit(prop == 0x24 ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask, ctype);
}
- _gted[e->index].refitmask_valid = true;
break;
}
@@ -1429,7 +1449,7 @@ static ChangeInfoResult ShipVehicleChangeInfo(uint engine, int numinfo, int prop
case 0x11: // Cargoes available for refitting
ei->refit_mask = buf->ReadDWord();
- _gted[e->index].refitmask_valid = true;
+ _gted[e->index].UpdateRefittability(ei->refit_mask != 0);
_gted[e->index].refitmask_grf = _cur.grffile;
break;
@@ -1460,12 +1480,12 @@ static ChangeInfoResult ShipVehicleChangeInfo(uint engine, int numinfo, int prop
case 0x18: // Cargo classes allowed
_gted[e->index].cargo_allowed = buf->ReadWord();
- _gted[e->index].refitmask_valid = true;
+ _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
break;
case 0x19: // Cargo classes disallowed
_gted[e->index].cargo_disallowed = buf->ReadWord();
- _gted[e->index].refitmask_valid = true;
+ _gted[e->index].UpdateRefittability(false);
break;
case 0x1A: // Long format introduction date (days since year 0)
@@ -1493,12 +1513,12 @@ static ChangeInfoResult ShipVehicleChangeInfo(uint engine, int numinfo, int prop
case 0x1E: // CTT refit include list
case 0x1F: { // CTT refit exclude list
uint8 count = buf->ReadByte();
+ _gted[e->index].UpdateRefittability(prop == 0x1E && count != 0);
while (count--) {
CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
if (ctype == CT_INVALID) continue;
SetBit(prop == 0x1E ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask, ctype);
}
- _gted[e->index].refitmask_valid = true;
break;
}
@@ -1585,7 +1605,7 @@ static ChangeInfoResult AircraftVehicleChangeInfo(uint engine, int numinfo, int
case 0x13: // Cargoes available for refitting
ei->refit_mask = buf->ReadDWord();
- _gted[e->index].refitmask_valid = true;
+ _gted[e->index].UpdateRefittability(ei->refit_mask != 0);
_gted[e->index].refitmask_grf = _cur.grffile;
break;
@@ -1608,12 +1628,12 @@ static ChangeInfoResult AircraftVehicleChangeInfo(uint engine, int numinfo, int
case 0x18: // Cargo classes allowed
_gted[e->index].cargo_allowed = buf->ReadWord();
- _gted[e->index].refitmask_valid = true;
+ _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
break;
case 0x19: // Cargo classes disallowed
_gted[e->index].cargo_disallowed = buf->ReadWord();
- _gted[e->index].refitmask_valid = true;
+ _gted[e->index].UpdateRefittability(false);
break;
case 0x1A: // Long format introduction date (days since year 0)
@@ -1631,12 +1651,12 @@ static ChangeInfoResult AircraftVehicleChangeInfo(uint engine, int numinfo, int
case 0x1D: // CTT refit include list
case 0x1E: { // CTT refit exclude list
uint8 count = buf->ReadByte();
+ _gted[e->index].UpdateRefittability(prop == 0x1D && count != 0);
while (count--) {
CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
if (ctype == CT_INVALID) continue;
SetBit(prop == 0x1D ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask, ctype);
}
- _gted[e->index].refitmask_valid = true;
break;
}
@@ -8046,14 +8066,14 @@ static void CalculateRefitMasks()
const uint8 *cargo_map_for_first_refittable = NULL;
/* Did the newgrf specify any refitting? If not, use defaults. */
- if (_gted[engine].refitmask_valid) {
+ if (_gted[engine].refittability != GRFTempEngineData::UNSET) {
uint32 mask = 0;
uint32 not_mask = 0;
uint32 xor_mask = 0;
/* If the original masks set by the grf are zero, the vehicle shall only carry the default cargo.
* Note: After applying the translations, the vehicle may end up carrying no defined cargo. It becomes unavailable in that case. */
- only_defaultcargo = (ei->refit_mask == 0 && _gted[engine].cargo_allowed == 0 && _gted[engine].ctt_include_mask == 0);
+ only_defaultcargo = _gted[engine].refittability == GRFTempEngineData::EMPTY;
const GRFFile *file = _gted[engine].refitmask_grf;
if (file == NULL) file = e->GetGRF();