File diff r27420:b37b70eb3169 → r27421:e8c2cdc1e8e6
src/newgrf.cpp
Show inline comments
 
@@ -941,13 +941,13 @@ static bool ReadSpriteLayout(ByteReader 
 
 */
 
static CargoTypes TranslateRefitMask(uint32 refit_mask)
 
{
 
	CargoTypes result = 0;
 
	for (uint8 bit : SetBitIterator(refit_mask)) {
 
		CargoID cargo = GetCargoTranslation(bit, _cur.grffile, true);
 
		if (cargo != CT_INVALID) SetBit(result, cargo);
 
		if (IsValidCargoID(cargo)) SetBit(result, cargo);
 
	}
 
	return result;
 
}
 

	
 
/**
 
 * Converts TTD(P) Base Price pointers into the enum used by OTTD
 
@@ -1303,14 +1303,13 @@ static ChangeInfoResult RailVehicleChang
 
				_gted[e->index].UpdateRefittability(prop == 0x2C && count != 0);
 
				if (prop == 0x2C) _gted[e->index].defaultcargo_grf = _cur.grffile;
 
				CargoTypes &ctt = prop == 0x2C ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
 
				ctt = 0;
 
				while (count--) {
 
					CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
 
					if (ctype == CT_INVALID) continue;
 
					SetBit(ctt, ctype);
 
					if (IsValidCargoID(ctype)) SetBit(ctt, ctype);
 
				}
 
				break;
 
			}
 

	
 
			case PROP_TRAIN_CURVE_SPEED_MOD: // 0x2E Curve speed modifier
 
				rvi->curve_speed_mod = buf->ReadWord();
 
@@ -1513,14 +1512,13 @@ static ChangeInfoResult RoadVehicleChang
 
				_gted[e->index].UpdateRefittability(prop == 0x24 && count != 0);
 
				if (prop == 0x24) _gted[e->index].defaultcargo_grf = _cur.grffile;
 
				CargoTypes &ctt = prop == 0x24 ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
 
				ctt = 0;
 
				while (count--) {
 
					CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
 
					if (ctype == CT_INVALID) continue;
 
					SetBit(ctt, ctype);
 
					if (IsValidCargoID(ctype)) SetBit(ctt, ctype);
 
				}
 
				break;
 
			}
 

	
 
			case 0x26: // Engine variant
 
				ei->variant_id = buf->ReadWord();
 
@@ -1697,14 +1695,13 @@ static ChangeInfoResult ShipVehicleChang
 
				_gted[e->index].UpdateRefittability(prop == 0x1E && count != 0);
 
				if (prop == 0x1E) _gted[e->index].defaultcargo_grf = _cur.grffile;
 
				CargoTypes &ctt = prop == 0x1E ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
 
				ctt = 0;
 
				while (count--) {
 
					CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
 
					if (ctype == CT_INVALID) continue;
 
					SetBit(ctt, ctype);
 
					if (IsValidCargoID(ctype)) SetBit(ctt, ctype);
 
				}
 
				break;
 
			}
 

	
 
			case 0x20: // Engine variant
 
				ei->variant_id = buf->ReadWord();
 
@@ -1859,14 +1856,13 @@ static ChangeInfoResult AircraftVehicleC
 
				_gted[e->index].UpdateRefittability(prop == 0x1D && count != 0);
 
				if (prop == 0x1D) _gted[e->index].defaultcargo_grf = _cur.grffile;
 
				CargoTypes &ctt = prop == 0x1D ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
 
				ctt = 0;
 
				while (count--) {
 
					CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
 
					if (ctype == CT_INVALID) continue;
 
					SetBit(ctt, ctype);
 
					if (IsValidCargoID(ctype)) SetBit(ctt, ctype);
 
				}
 
				break;
 
			}
 

	
 
			case PROP_AIRCRAFT_RANGE: // 0x1F Max aircraft range
 
				avi->max_range = buf->ReadWord();
 
@@ -2544,13 +2540,13 @@ static ChangeInfoResult TownHouseChangeI
 

	
 
				for (uint j = 0; j < 3; j++) {
 
					/* Get the cargo number from the 'list' */
 
					uint8 cargo_part = GB(cargotypes, 8 * j, 8);
 
					CargoID cargo = GetCargoTranslation(cargo_part, _cur.grffile);
 

	
 
					if (cargo == CT_INVALID) {
 
					if (!IsValidCargoID(cargo)) {
 
						/* Disable acceptance of invalid cargo type */
 
						housespec->cargo_acceptance[j] = 0;
 
					} else {
 
						housespec->accepts_cargo[j] = cargo;
 
					}
 
				}
 
@@ -2562,13 +2558,13 @@ static ChangeInfoResult TownHouseChangeI
 
				break;
 

	
 
			case 0x20: { // Cargo acceptance watch list
 
				byte count = buf->ReadByte();
 
				for (byte j = 0; j < count; j++) {
 
					CargoID cargo = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
 
					if (cargo != CT_INVALID) SetBit(housespec->watched_cargoes, cargo);
 
					if (IsValidCargoID(cargo)) SetBit(housespec->watched_cargoes, cargo);
 
				}
 
				break;
 
			}
 

	
 
			case 0x21: // long introduction year
 
				housespec->min_year = buf->ReadWord();
 
@@ -5454,13 +5450,13 @@ static void NewSpriteGroup(ByteReader *b
 
							error->data = "too many inputs (max 16)";
 
							return;
 
						}
 
						for (uint i = 0; i < group->num_input; i++) {
 
							byte rawcargo = buf->ReadByte();
 
							CargoID cargo = GetCargoTranslation(rawcargo, _cur.grffile);
 
							if (cargo == CT_INVALID) {
 
							if (!IsValidCargoID(cargo)) {
 
								/* The mapped cargo is invalid. This is permitted at this point,
 
								 * as long as the result is not used. Mark it invalid so this
 
								 * can be tested later. */
 
								group->version = 0xFF;
 
							} else if (std::find(group->cargo_input, group->cargo_input + i, cargo) != group->cargo_input + i) {
 
								GRFError *error = DisableGrf(STR_NEWGRF_ERROR_INDPROD_CALLBACK);
 
@@ -5476,13 +5472,13 @@ static void NewSpriteGroup(ByteReader *b
 
							error->data = "too many outputs (max 16)";
 
							return;
 
						}
 
						for (uint i = 0; i < group->num_output; i++) {
 
							byte rawcargo = buf->ReadByte();
 
							CargoID cargo = GetCargoTranslation(rawcargo, _cur.grffile);
 
							if (cargo == CT_INVALID) {
 
							if (!IsValidCargoID(cargo)) {
 
								/* Mark this result as invalid to use */
 
								group->version = 0xFF;
 
							} else if (std::find(group->cargo_output, group->cargo_output + i, cargo) != group->cargo_output + i) {
 
								GRFError *error = DisableGrf(STR_NEWGRF_ERROR_INDPROD_CALLBACK);
 
								error->data = "duplicate output cargo";
 
								return;
 
@@ -5550,13 +5546,13 @@ static CargoID TranslateCargo(uint8 feat
 
	if (cl == 0) {
 
		GrfMsg(5, "TranslateCargo: Cargo type {} not available in this climate, skipping.", ctype);
 
		return CT_INVALID;
 
	}
 

	
 
	ctype = GetCargoIDByLabel(cl);
 
	if (ctype == CT_INVALID) {
 
	if (!IsValidCargoID(ctype)) {
 
		GrfMsg(5, "TranslateCargo: Cargo '{:c}{:c}{:c}{:c}' unsupported, skipping.", GB(cl, 24, 8), GB(cl, 16, 8), GB(cl, 8, 8), GB(cl, 0, 8));
 
		return CT_INVALID;
 
	}
 

	
 
	GrfMsg(6, "TranslateCargo: Cargo '{:c}{:c}{:c}{:c}' mapped to cargo type {}.", GB(cl, 24, 8), GB(cl, 16, 8), GB(cl, 8, 8), GB(cl, 0, 8), ctype);
 
	return ctype;
 
@@ -5620,13 +5616,13 @@ static void VehicleMapSpriteGroup(ByteRe
 
		uint16 groupid = buf->ReadWord();
 
		if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) continue;
 

	
 
		GrfMsg(8, "VehicleMapSpriteGroup: * [{}] Cargo type 0x{:X}, group id 0x{:02X}", c, ctype, groupid);
 

	
 
		ctype = TranslateCargo(feature, ctype);
 
		if (ctype == CT_INVALID) continue;
 
		if (!IsValidCargoID(ctype)) continue;
 

	
 
		for (uint i = 0; i < idcount; i++) {
 
			EngineID engine = engines[i];
 

	
 
			GrfMsg(7, "VehicleMapSpriteGroup: [{}] Engine {}...", i, engine);
 

	
 
@@ -5699,13 +5695,13 @@ static void StationMapSpriteGroup(ByteRe
 
	for (uint c = 0; c < cidcount; c++) {
 
		uint8 ctype = buf->ReadByte();
 
		uint16 groupid = buf->ReadWord();
 
		if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) continue;
 

	
 
		ctype = TranslateCargo(GSF_STATIONS, ctype);
 
		if (ctype == CT_INVALID) continue;
 
		if (!IsValidCargoID(ctype)) continue;
 

	
 
		for (auto &station : stations) {
 
			StationSpec *statspec = station >= _cur.grffile->stations.size() ? nullptr : _cur.grffile->stations[station].get();
 

	
 
			if (statspec == nullptr) {
 
				GrfMsg(1, "StationMapSpriteGroup: Station {} undefined, skipping", station);
 
@@ -5880,13 +5876,13 @@ static void ObjectMapSpriteGroup(ByteRea
 
	for (uint c = 0; c < cidcount; c++) {
 
		uint8 ctype = buf->ReadByte();
 
		uint16 groupid = buf->ReadWord();
 
		if (!IsValidGroupID(groupid, "ObjectMapSpriteGroup")) continue;
 

	
 
		ctype = TranslateCargo(GSF_OBJECTS, ctype);
 
		if (ctype == CT_INVALID) continue;
 
		if (!IsValidCargoID(ctype)) continue;
 

	
 
		for (auto &object : objects) {
 
			ObjectSpec *spec = object >= _cur.grffile->objectspec.size() ? nullptr : _cur.grffile->objectspec[object].get();
 

	
 
			if (spec == nullptr) {
 
				GrfMsg(1, "ObjectMapSpriteGroup: Object {} undefined, skipping", object);
 
@@ -6066,13 +6062,13 @@ static void RoadStopMapSpriteGroup(ByteR
 
	for (uint c = 0; c < cidcount; c++) {
 
		uint8 ctype = buf->ReadByte();
 
		uint16 groupid = buf->ReadWord();
 
		if (!IsValidGroupID(groupid, "RoadStopMapSpriteGroup")) continue;
 

	
 
		ctype = TranslateCargo(GSF_ROADSTOPS, ctype);
 
		if (ctype == CT_INVALID) continue;
 
		if (!IsValidCargoID(ctype)) continue;
 

	
 
		for (auto &roadstop : roadstops) {
 
			RoadStopSpec *roadstopspec = roadstop >= _cur.grffile->roadstops.size() ? nullptr : _cur.grffile->roadstops[roadstop].get();
 

	
 
			if (roadstopspec == nullptr) {
 
				GrfMsg(1, "RoadStopMapSpriteGroup: Road stop {} undefined, skipping", roadstop);
 
@@ -6841,15 +6837,15 @@ static void SkipIf(ByteReader *buf)
 
	/* condtypes that do not use 'param' are always valid.
 
	 * condtypes that use 'param' are either not valid for param 0x88, or they are only valid for param 0x88.
 
	 */
 
	if (condtype >= 0x0B) {
 
		/* Tests that ignore 'param' */
 
		switch (condtype) {
 
			case 0x0B: result = GetCargoIDByLabel(BSWAP32(cond_val)) == CT_INVALID;
 
				break;
 
			case 0x0C: result = GetCargoIDByLabel(BSWAP32(cond_val)) != CT_INVALID;
 
			case 0x0B: result = !IsValidCargoID(GetCargoIDByLabel(BSWAP32(cond_val)));
 
				break;
 
			case 0x0C: result = IsValidCargoID(GetCargoIDByLabel(BSWAP32(cond_val)));
 
				break;
 
			case 0x0D: result = GetRailTypeByLabel(BSWAP32(cond_val)) == INVALID_RAILTYPE;
 
				break;
 
			case 0x0E: result = GetRailTypeByLabel(BSWAP32(cond_val)) != INVALID_RAILTYPE;
 
				break;
 
			case 0x0F: {
 
@@ -8942,13 +8938,13 @@ GRFFile::~GRFFile()
 
 */
 
static void CalculateRefitMasks()
 
{
 
	CargoTypes original_known_cargoes = 0;
 
	for (int ct = 0; ct != NUM_ORIGINAL_CARGO; ++ct) {
 
		CargoID cid = GetDefaultCargoID(_settings_game.game_creation.landscape, static_cast<CargoType>(ct));
 
		if (cid != CT_INVALID) SetBit(original_known_cargoes, cid);
 
		if (IsValidCargoID(cid)) SetBit(original_known_cargoes, cid);
 
	}
 

	
 
	for (Engine *e : Engine::Iterate()) {
 
		EngineID engine = e->index;
 
		EngineInfo *ei = &e->info;
 
		bool only_defaultcargo; ///< Set if the vehicle shall carry only the default cargo
 
@@ -9032,13 +9028,13 @@ static void CalculateRefitMasks()
 
				}
 
			}
 
			_gted[engine].UpdateRefittability(_gted[engine].cargo_allowed != 0);
 

	
 
			/* Translate cargo_type using the original climate-specific cargo table. */
 
			ei->cargo_type = GetDefaultCargoID(_settings_game.game_creation.landscape, static_cast<CargoType>(ei->cargo_type));
 
			if (ei->cargo_type != CT_INVALID) ClrBit(_gted[engine].ctt_exclude_mask, ei->cargo_type);
 
			if (IsValidCargoID(ei->cargo_type)) ClrBit(_gted[engine].ctt_exclude_mask, ei->cargo_type);
 
		}
 

	
 
		/* Compute refittability */
 
		{
 
			CargoTypes mask = 0;
 
			CargoTypes not_mask = 0;
 
@@ -9061,23 +9057,23 @@ static void CalculateRefitMasks()
 
			/* Apply explicit refit includes/excludes. */
 
			ei->refit_mask |= _gted[engine].ctt_include_mask;
 
			ei->refit_mask &= ~_gted[engine].ctt_exclude_mask;
 
		}
 

	
 
		/* Clear invalid cargoslots (from default vehicles or pre-NewCargo GRFs) */
 
		if (ei->cargo_type != CT_INVALID && !HasBit(_cargo_mask, ei->cargo_type)) ei->cargo_type = CT_INVALID;
 
		if (IsValidCargoID(ei->cargo_type) && !HasBit(_cargo_mask, ei->cargo_type)) ei->cargo_type = CT_INVALID;
 

	
 
		/* Ensure that the vehicle is either not refittable, or that the default cargo is one of the refittable cargoes.
 
		 * Note: Vehicles refittable to no cargo are handle differently to vehicle refittable to a single cargo. The latter might have subtypes. */
 
		if (!only_defaultcargo && (e->type != VEH_SHIP || e->u.ship.old_refittable) && ei->cargo_type != CT_INVALID && !HasBit(ei->refit_mask, ei->cargo_type)) {
 
		if (!only_defaultcargo && (e->type != VEH_SHIP || e->u.ship.old_refittable) && IsValidCargoID(ei->cargo_type) && !HasBit(ei->refit_mask, ei->cargo_type)) {
 
			ei->cargo_type = CT_INVALID;
 
		}
 

	
 
		/* Check if this engine's cargo type is valid. If not, set to the first refittable
 
		 * cargo type. Finally disable the vehicle, if there is still no cargo. */
 
		if (ei->cargo_type == CT_INVALID && ei->refit_mask != 0) {
 
		if (!IsValidCargoID(ei->cargo_type) && ei->refit_mask != 0) {
 
			/* Figure out which CTT to use for the default cargo, if it is 'first refittable'. */
 
			const uint8 *cargo_map_for_first_refittable = nullptr;
 
			{
 
				const GRFFile *file = _gted[engine].defaultcargo_grf;
 
				if (file == nullptr) file = e->GetGRF();
 
				if (file != nullptr && file->grf_version >= 8 && file->cargo_list.size() != 0) {
 
@@ -9094,18 +9090,18 @@ static void CalculateRefitMasks()
 
						best_local_slot = local_slot;
 
						ei->cargo_type = cargo_type;
 
					}
 
				}
 
			}
 

	
 
			if (ei->cargo_type == CT_INVALID) {
 
			if (!IsValidCargoID(ei->cargo_type)) {
 
				/* Use first refittable cargo slot */
 
				ei->cargo_type = (CargoID)FindFirstBit(ei->refit_mask);
 
			}
 
		}
 
		if (ei->cargo_type == CT_INVALID) ei->climates = 0;
 
		if (!IsValidCargoID(ei->cargo_type)) ei->climates = 0;
 

	
 
		/* Clear refit_mask for not refittable ships */
 
		if (e->type == VEH_SHIP && !e->u.ship.old_refittable) {
 
			ei->refit_mask = 0;
 
		}
 
	}