Changeset - r27119:18b3e09ea8be
[Not reviewed]
master
0 10 0
Rubidium - 14 months ago 2023-04-18 19:24:42
rubidium@openttd.org
Codechange: use string/fmt instead of printf for grfmsg
10 files changed with 287 insertions and 293 deletions:
0 comments (0 inline, 0 general)
src/newgrf.cpp
Show inline comments
 
@@ -276,7 +276,7 @@ public:
 
		if (string_length == Remaining()) {
 
			/* String was not NUL terminated, so make sure it is now. */
 
			string[string_length - 1] = '\0';
 
			grfmsg(7, "String was not terminated with a zero byte.");
 
			GrfMsg(7, "String was not terminated with a zero byte.");
 
		} else {
 
			/* Increase the string length to include the NUL byte. */
 
			string_length++;
 
@@ -383,22 +383,15 @@ static GRFLineToSpriteOverride _grf_line
 
 * Debug() function dedicated to newGRF debugging messages
 
 * Function is essentially the same as Debug(grf, severity, ...) with the
 
 * addition of file:line information when parsing grf files.
 
 * NOTE: for the above reason(s) grfmsg() should ONLY be used for
 
 * NOTE: for the above reason(s) GrfMsg() should ONLY be used for
 
 * loading/parsing grf files, not for runtime debug messages as there
 
 * is no file information available during that time.
 
 * @param severity debugging severity level, see debug.h
 
 * @param str message in printf() format
 
 * @param msg the message
 
 */
 
void CDECL grfmsg(int severity, const char *str, ...)
 
{
 
	char buf[1024];
 
	va_list va;
 

	
 
	va_start(va, str);
 
	vseprintf(buf, lastof(buf), str, va);
 
	va_end(va);
 

	
 
	Debug(grf, severity, "[{}:{}] {}", _cur.grfconfig->filename, _cur.nfo_line, buf);
 
void GrfMsgI(int severity, const std::string &msg)
 
{
 
	Debug(grf, severity, "[{}:{}] {}", _cur.grfconfig->filename, _cur.nfo_line, msg);
 
}
 

	
 
/**
 
@@ -592,7 +585,7 @@ static std::map<uint32, uint32> _grf_id_
 
static void SetNewGRFOverride(uint32 source_grfid, uint32 target_grfid)
 
{
 
	_grf_id_overrides[source_grfid] = target_grfid;
 
	grfmsg(5, "SetNewGRFOverride: Added override of 0x%X to 0x%X", BSWAP32(source_grfid), BSWAP32(target_grfid));
 
	GrfMsg(5, "SetNewGRFOverride: Added override of {:#X} to {:#X}", BSWAP32(source_grfid), BSWAP32(target_grfid));
 
}
 

	
 
/**
 
@@ -616,9 +609,9 @@ static Engine *GetNewEngine(const GRFFil
 
			scope_grfid = override;
 
			const GRFFile *grf_match = GetFileByGRFID(override);
 
			if (grf_match == nullptr) {
 
				grfmsg(5, "Tried mapping from GRFID %x to %x but target is not loaded", BSWAP32(file->grfid), BSWAP32(override));
 
				GrfMsg(5, "Tried mapping from GRFID {:x} to {:x} but target is not loaded", BSWAP32(file->grfid), BSWAP32(override));
 
			} else {
 
				grfmsg(5, "Mapping from GRFID %x to %x", BSWAP32(file->grfid), BSWAP32(override));
 
				GrfMsg(5, "Mapping from GRFID {:x} to {:x}", BSWAP32(file->grfid), BSWAP32(override));
 
			}
 
		}
 

	
 
@@ -638,7 +631,7 @@ static Engine *GetNewEngine(const GRFFil
 

	
 
		if (e->grf_prop.grffile == nullptr) {
 
			e->grf_prop.grffile = file;
 
			grfmsg(5, "Replaced engine at index %d for GRFID %x, type %d, index %d", e->index, BSWAP32(file->grfid), type, internal_id);
 
			GrfMsg(5, "Replaced engine at index {} for GRFID {:x}, type {}, index {}", e->index, BSWAP32(file->grfid), type, internal_id);
 
		}
 

	
 
		/* Reserve the engine slot */
 
@@ -653,7 +646,7 @@ static Engine *GetNewEngine(const GRFFil
 
	if (static_access) return nullptr;
 

	
 
	if (!Engine::CanAllocateItem()) {
 
		grfmsg(0, "Can't allocate any more engines");
 
		GrfMsg(0, "Can't allocate any more engines");
 
		return nullptr;
 
	}
 

	
 
@@ -684,7 +677,7 @@ static Engine *GetNewEngine(const GRFFil
 
		_gted[e->index].railtypelabel = GetRailTypeInfo(e->u.rail.railtype)->label;
 
	}
 

	
 
	grfmsg(5, "Created new engine at index %d for GRFID %x, type %d, index %d", e->index, BSWAP32(file->grfid), type, internal_id);
 
	GrfMsg(5, "Created new engine at index {} for GRFID {:x}, type {}, index {}", e->index, BSWAP32(file->grfid), type, internal_id);
 

	
 
	return e;
 
}
 
@@ -760,7 +753,7 @@ static TileLayoutFlags ReadSpriteLayoutS
 
		/* Use sprite from Action 1 */
 
		uint index = GB(grf_sprite->sprite, 0, 14);
 
		if (use_cur_spritesets && (!_cur.IsValidSpriteSet(feature, index) || _cur.GetNumEnts(feature, index) == 0)) {
 
			grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d", index);
 
			GrfMsg(1, "ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset {}", index);
 
			grf_sprite->sprite = SPR_IMG_QUERY;
 
			grf_sprite->pal = PAL_NONE;
 
		} else {
 
@@ -770,7 +763,7 @@ static TileLayoutFlags ReadSpriteLayoutS
 
			SetBit(grf_sprite->sprite, SPRITE_MODIFIER_CUSTOM_SPRITE);
 
		}
 
	} else if ((flags & TLF_SPRITE_VAR10) && !(flags & TLF_SPRITE_REG_FLAGS)) {
 
		grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout specifies var10 value for non-action-1 sprite");
 
		GrfMsg(1, "ReadSpriteLayoutSprite: Spritelayout specifies var10 value for non-action-1 sprite");
 
		DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
 
		return flags;
 
	}
 
@@ -779,7 +772,7 @@ static TileLayoutFlags ReadSpriteLayoutS
 
		/* Use palette from Action 1 */
 
		uint index = GB(grf_sprite->pal, 0, 14);
 
		if (use_cur_spritesets && (!_cur.IsValidSpriteSet(feature, index) || _cur.GetNumEnts(feature, index) == 0)) {
 
			grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d for 'palette'", index);
 
			GrfMsg(1, "ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset {} for 'palette'", index);
 
			grf_sprite->pal = PAL_NONE;
 
		} else {
 
			SpriteID sprite = use_cur_spritesets ? _cur.GetSprite(feature, index) : index;
 
@@ -788,7 +781,7 @@ static TileLayoutFlags ReadSpriteLayoutS
 
			SetBit(grf_sprite->pal, SPRITE_MODIFIER_CUSTOM_SPRITE);
 
		}
 
	} else if ((flags & TLF_PALETTE_VAR10) && !(flags & TLF_PALETTE_REG_FLAGS)) {
 
		grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 value for non-action-1 palette");
 
		GrfMsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 value for non-action-1 palette");
 
		DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
 
		return flags;
 
	}
 
@@ -830,7 +823,7 @@ static void ReadSpriteLayoutRegisters(By
 
	if (flags & TLF_SPRITE_VAR10) {
 
		regs.sprite_var10 = buf->ReadByte();
 
		if (regs.sprite_var10 > TLR_MAX_VAR10) {
 
			grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 (%d) exceeding the maximal allowed value %d", regs.sprite_var10, TLR_MAX_VAR10);
 
			GrfMsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 ({}) exceeding the maximal allowed value {}", regs.sprite_var10, TLR_MAX_VAR10);
 
			DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
 
			return;
 
		}
 
@@ -839,7 +832,7 @@ static void ReadSpriteLayoutRegisters(By
 
	if (flags & TLF_PALETTE_VAR10) {
 
		regs.palette_var10 = buf->ReadByte();
 
		if (regs.palette_var10 > TLR_MAX_VAR10) {
 
			grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 (%d) exceeding the maximal allowed value %d", regs.palette_var10, TLR_MAX_VAR10);
 
			GrfMsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 ({}) exceeding the maximal allowed value {}", regs.palette_var10, TLR_MAX_VAR10);
 
			DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
 
			return;
 
		}
 
@@ -873,7 +866,7 @@ static bool ReadSpriteLayout(ByteReader 
 
	if (_cur.skip_sprites < 0) return true;
 

	
 
	if (flags & ~(valid_flags & ~TLF_NON_GROUND_FLAGS)) {
 
		grfmsg(1, "ReadSpriteLayout: Spritelayout uses invalid flag 0x%x for ground sprite", flags & ~(valid_flags & ~TLF_NON_GROUND_FLAGS));
 
		GrfMsg(1, "ReadSpriteLayout: Spritelayout uses invalid flag {:#X} for ground sprite", flags & ~(valid_flags & ~TLF_NON_GROUND_FLAGS));
 
		DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
 
		return true;
 
	}
 
@@ -888,7 +881,7 @@ static bool ReadSpriteLayout(ByteReader 
 
		if (_cur.skip_sprites < 0) return true;
 

	
 
		if (flags & ~valid_flags) {
 
			grfmsg(1, "ReadSpriteLayout: Spritelayout uses unknown flag 0x%x", flags & ~valid_flags);
 
			GrfMsg(1, "ReadSpriteLayout: Spritelayout uses unknown flag {:#X}", flags & ~valid_flags);
 
			DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
 
			return true;
 
		}
 
@@ -979,7 +972,7 @@ static void ConvertTTDBasePrice(uint32 b
 
	static const uint32 size  = 6;      ///< Size of each base price record
 

	
 
	if (base_pointer < start || (base_pointer - start) % size != 0 || (base_pointer - start) / size >= PR_END) {
 
		grfmsg(1, "%s: Unsupported running cost base 0x%04X, ignoring", error_location, base_pointer);
 
		GrfMsg(1, "{}: Unsupported running cost base {:#04X}, ignoring", error_location, base_pointer);
 
		return;
 
	}
 

	
 
@@ -1072,7 +1065,7 @@ static ChangeInfoResult RailVehicleChang
 
					case 1: _gted[e->index].railtypelabel = RAILTYPE_MONO_LABEL; break;
 
					case 2: _gted[e->index].railtypelabel = RAILTYPE_MAGLEV_LABEL; break;
 
					default:
 
						grfmsg(1, "RailVehicleChangeInfo: Invalid track type %d specified, ignoring", tracktype);
 
						GrfMsg(1, "RailVehicleChangeInfo: Invalid track type {} specified, ignoring", tracktype);
 
						break;
 
				}
 
				break;
 
@@ -1124,7 +1117,7 @@ static ChangeInfoResult RailVehicleChang
 
				if (IsValidNewGRFImageIndex<VEH_TRAIN>(spriteid)) {
 
					rvi->image_index = spriteid;
 
				} else {
 
					grfmsg(1, "RailVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
 
					GrfMsg(1, "RailVehicleChangeInfo: Invalid Sprite {} specified, ignoring", orig_spriteid);
 
					rvi->image_index = 0;
 
				}
 
				break;
 
@@ -1161,7 +1154,7 @@ static ChangeInfoResult RailVehicleChang
 
					ei->cargo_type = ctype;
 
				} else {
 
					ei->cargo_type = CT_INVALID;
 
					grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
 
					GrfMsg(2, "RailVehicleChangeInfo: Invalid cargo type {}, using first refittable", ctype);
 
				}
 
				break;
 
			}
 
@@ -1175,7 +1168,7 @@ static ChangeInfoResult RailVehicleChang
 
				break;
 

	
 
			case 0x18: // AI rank
 
				grfmsg(2, "RailVehicleChangeInfo: Property 0x18 'AI rank' not used by NoAI, ignored.");
 
				GrfMsg(2, "RailVehicleChangeInfo: Property 0x18 'AI rank' not used by NoAI, ignored.");
 
				buf->ReadByte();
 
				break;
 

	
 
@@ -1269,7 +1262,7 @@ static ChangeInfoResult RailVehicleChang
 
				byte weight = buf->ReadByte();
 

	
 
				if (weight > 4) {
 
					grfmsg(2, "RailVehicleChangeInfo: Nonsensical weight of %d tons, ignoring", weight << 8);
 
					GrfMsg(2, "RailVehicleChangeInfo: Nonsensical weight of {} tons, ignoring", weight << 8);
 
				} else {
 
					SB(rvi->weight, 8, 8, weight);
 
				}
 
@@ -1398,7 +1391,7 @@ static ChangeInfoResult RoadVehicleChang
 
				if (IsValidNewGRFImageIndex<VEH_ROAD>(spriteid)) {
 
					rvi->image_index = spriteid;
 
				} else {
 
					grfmsg(1, "RoadVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
 
					GrfMsg(1, "RoadVehicleChangeInfo: Invalid Sprite {} specified, ignoring", orig_spriteid);
 
					rvi->image_index = 0;
 
				}
 
				break;
 
@@ -1423,7 +1416,7 @@ static ChangeInfoResult RoadVehicleChang
 
					ei->cargo_type = ctype;
 
				} else {
 
					ei->cargo_type = CT_INVALID;
 
					grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
 
					GrfMsg(2, "RailVehicleChangeInfo: Invalid cargo type {}, using first refittable", ctype);
 
				}
 
				break;
 
			}
 
@@ -1586,7 +1579,7 @@ static ChangeInfoResult ShipVehicleChang
 
				if (IsValidNewGRFImageIndex<VEH_SHIP>(spriteid)) {
 
					svi->image_index = spriteid;
 
				} else {
 
					grfmsg(1, "ShipVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
 
					GrfMsg(1, "ShipVehicleChangeInfo: Invalid Sprite {} specified, ignoring", orig_spriteid);
 
					svi->image_index = 0;
 
				}
 
				break;
 
@@ -1619,7 +1612,7 @@ static ChangeInfoResult ShipVehicleChang
 
					ei->cargo_type = ctype;
 
				} else {
 
					ei->cargo_type = CT_INVALID;
 
					grfmsg(2, "ShipVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
 
					GrfMsg(2, "ShipVehicleChangeInfo: Invalid cargo type {}, using first refittable", ctype);
 
				}
 
				break;
 
			}
 
@@ -1770,7 +1763,7 @@ static ChangeInfoResult AircraftVehicleC
 
				if (IsValidNewGRFImageIndex<VEH_AIRCRAFT>(spriteid)) {
 
					avi->image_index = spriteid;
 
				} else {
 
					grfmsg(1, "AircraftVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
 
					GrfMsg(1, "AircraftVehicleChangeInfo: Invalid Sprite {} specified, ignoring", orig_spriteid);
 
					avi->image_index = 0;
 
				}
 
				break;
 
@@ -1917,7 +1910,7 @@ static ChangeInfoResult StationChangeInf
 
	ChangeInfoResult ret = CIR_SUCCESS;
 

	
 
	if (stid + numinfo > NUM_STATIONS_PER_GRF) {
 
		grfmsg(1, "StationChangeInfo: Station %u is invalid, max %u, ignoring", stid + numinfo, NUM_STATIONS_PER_GRF);
 
		GrfMsg(1, "StationChangeInfo: Station {} is invalid, max {}, ignoring", stid + numinfo, NUM_STATIONS_PER_GRF);
 
		return CIR_INVALID_ID;
 
	}
 

	
 
@@ -1929,7 +1922,7 @@ static ChangeInfoResult StationChangeInf
 

	
 
		/* Check that the station we are modifying is defined. */
 
		if (statspec == nullptr && prop != 0x08) {
 
			grfmsg(2, "StationChangeInfo: Attempt to modify undefined station %u, ignoring", stid + i);
 
			GrfMsg(2, "StationChangeInfo: Attempt to modify undefined station {}, ignoring", stid + i);
 
			return CIR_INVALID_ID;
 
		}
 

	
 
@@ -1991,7 +1984,7 @@ static ChangeInfoResult StationChangeInf
 

	
 
				/* Number of layouts must be even, alternating X and Y */
 
				if (statspec->renderdata.size() & 1) {
 
					grfmsg(1, "StationChangeInfo: Station %u defines an odd number of sprite layouts, dropping the last item", stid + i);
 
					GrfMsg(1, "StationChangeInfo: Station {} defines an odd number of sprite layouts, dropping the last item", stid + i);
 
					statspec->renderdata.pop_back();
 
				}
 
				break;
 
@@ -2002,7 +1995,7 @@ static ChangeInfoResult StationChangeInf
 
				const StationSpec *srcstatspec = srcid >= _cur.grffile->stations.size() ? nullptr : _cur.grffile->stations[srcid].get();
 

	
 
				if (srcstatspec == nullptr) {
 
					grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy sprite layout to %u.", srcid, stid + i);
 
					GrfMsg(1, "StationChangeInfo: Station {} is not defined, cannot copy sprite layout to {}.", srcid, stid + i);
 
					continue;
 
				}
 

	
 
@@ -2044,7 +2037,7 @@ static ChangeInfoResult StationChangeInf
 
					/* Validate tile values are only the permitted 00, 02, 04 and 06. */
 
					for (auto &tile : statspec->layouts[length - 1][number - 1]) {
 
						if ((tile & 6) != tile) {
 
							grfmsg(1, "StationChangeInfo: Invalid tile %u in layout %ux%u", tile, length, number);
 
							GrfMsg(1, "StationChangeInfo: Invalid tile {} in layout {}x{}", tile, length, number);
 
							tile &= 6;
 
						}
 
					}
 
@@ -2056,7 +2049,7 @@ static ChangeInfoResult StationChangeInf
 
				const StationSpec *srcstatspec = srcid >= _cur.grffile->stations.size() ? nullptr : _cur.grffile->stations[srcid].get();
 

	
 
				if (srcstatspec == nullptr) {
 
					grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy tile layout to %u.", srcid, stid + i);
 
					GrfMsg(1, "StationChangeInfo: Station {} is not defined, cannot copy tile layout to {}.", srcid, stid + i);
 
					continue;
 
				}
 

	
 
@@ -2119,7 +2112,7 @@ static ChangeInfoResult StationChangeInf
 

	
 
				/* Number of layouts must be even, alternating X and Y */
 
				if (statspec->renderdata.size() & 1) {
 
					grfmsg(1, "StationChangeInfo: Station %u defines an odd number of sprite layouts, dropping the last item", stid + i);
 
					GrfMsg(1, "StationChangeInfo: Station {} defines an odd number of sprite layouts, dropping the last item", stid + i);
 
					statspec->renderdata.pop_back();
 
				}
 
				break;
 
@@ -2147,7 +2140,7 @@ static ChangeInfoResult CanalChangeInfo(
 
	ChangeInfoResult ret = CIR_SUCCESS;
 

	
 
	if (id + numinfo > CF_END) {
 
		grfmsg(1, "CanalChangeInfo: Canal feature 0x%02X is invalid, max %u, ignoring", id + numinfo, CF_END);
 
		GrfMsg(1, "CanalChangeInfo: Canal feature {:#02X} is invalid, max {}, ignoring", id + numinfo, CF_END);
 
		return CIR_INVALID_ID;
 
	}
 

	
 
@@ -2185,7 +2178,7 @@ static ChangeInfoResult BridgeChangeInfo
 
	ChangeInfoResult ret = CIR_SUCCESS;
 

	
 
	if (brid + numinfo > MAX_BRIDGES) {
 
		grfmsg(1, "BridgeChangeInfo: Bridge %u is invalid, max %u, ignoring", brid + numinfo, MAX_BRIDGES);
 
		GrfMsg(1, "BridgeChangeInfo: Bridge {} is invalid, max {}, ignoring", brid + numinfo, MAX_BRIDGES);
 
		return CIR_INVALID_ID;
 
	}
 

	
 
@@ -2229,7 +2222,7 @@ static ChangeInfoResult BridgeChangeInfo
 

	
 
				for (; numtables-- != 0; tableid++) {
 
					if (tableid >= 7) { // skip invalid data
 
						grfmsg(1, "BridgeChangeInfo: Table %d >= 7, skipping", tableid);
 
						GrfMsg(1, "BridgeChangeInfo: Table {} >= 7, skipping", tableid);
 
						for (byte sprite = 0; sprite < 32; sprite++) buf->ReadDWord();
 
						continue;
 
					}
 
@@ -2363,7 +2356,7 @@ static ChangeInfoResult TownHouseChangeI
 
	ChangeInfoResult ret = CIR_SUCCESS;
 

	
 
	if (hid + numinfo > NUM_HOUSES_PER_GRF) {
 
		grfmsg(1, "TownHouseChangeInfo: Too many houses loaded (%u), max (%u). Ignoring.", hid + numinfo, NUM_HOUSES_PER_GRF);
 
		GrfMsg(1, "TownHouseChangeInfo: Too many houses loaded ({}), max ({}). Ignoring.", hid + numinfo, NUM_HOUSES_PER_GRF);
 
		return CIR_INVALID_ID;
 
	}
 

	
 
@@ -2390,7 +2383,7 @@ static ChangeInfoResult TownHouseChangeI
 
					continue;
 
				} else if (subs_id >= NEW_HOUSE_OFFSET) {
 
					/* The substitute id must be one of the original houses. */
 
					grfmsg(2, "TownHouseChangeInfo: Attempt to use new house %u as substitute house for %u. Ignoring.", subs_id, hid + i);
 
					GrfMsg(2, "TownHouseChangeInfo: Attempt to use new house {} as substitute house for {}. Ignoring.", subs_id, hid + i);
 
					continue;
 
				}
 

	
 
@@ -2484,7 +2477,7 @@ static ChangeInfoResult TownHouseChangeI
 

	
 
				/* The house being overridden must be an original house. */
 
				if (override >= NEW_HOUSE_OFFSET) {
 
					grfmsg(2, "TownHouseChangeInfo: Attempt to override new house %u with house id %u. Ignoring.", override, hid + i);
 
					GrfMsg(2, "TownHouseChangeInfo: Attempt to override new house {} with house id {}. Ignoring.", override, hid + i);
 
					continue;
 
				}
 

	
 
@@ -2625,7 +2618,7 @@ template <typename T>
 
static ChangeInfoResult LoadTranslationTable(uint gvid, int numinfo, ByteReader *buf, T &translation_table, const char *name)
 
{
 
	if (gvid != 0) {
 
		grfmsg(1, "LoadTranslationTable: %s translation table must start at zero", name);
 
		GrfMsg(1, "LoadTranslationTable: {} translation table must start at zero", name);
 
		return CIR_INVALID_ID;
 
	}
 

	
 
@@ -2693,7 +2686,7 @@ static ChangeInfoResult GlobalVarChangeI
 
				if (price < PR_END) {
 
					_cur.grffile->price_base_multipliers[price] = std::min<int>(factor - 8, MAX_PRICE_MODIFIER);
 
				} else {
 
					grfmsg(1, "GlobalVarChangeInfo: Price %d out of range, ignoring", price);
 
					GrfMsg(1, "GlobalVarChangeInfo: Price {} out of range, ignoring", price);
 
				}
 
				break;
 
			}
 
@@ -2718,7 +2711,7 @@ static ChangeInfoResult GlobalVarChangeI
 
					 * to be compatible */
 
					_currency_specs[curidx].rate = rate / 1000;
 
				} else {
 
					grfmsg(1, "GlobalVarChangeInfo: Currency multipliers %d out of range, ignoring", curidx);
 
					GrfMsg(1, "GlobalVarChangeInfo: Currency multipliers {} out of range, ignoring", curidx);
 
				}
 
				break;
 
			}
 
@@ -2734,7 +2727,7 @@ static ChangeInfoResult GlobalVarChangeI
 
					 * since newgrf specs said that only 0 and 1 can be set for symbol_pos */
 
					_currency_specs[curidx].symbol_pos = GB(options, 8, 1);
 
				} else {
 
					grfmsg(1, "GlobalVarChangeInfo: Currency option %d out of range, ignoring", curidx);
 
					GrfMsg(1, "GlobalVarChangeInfo: Currency option {} out of range, ignoring", curidx);
 
				}
 
				break;
 
			}
 
@@ -2746,7 +2739,7 @@ static ChangeInfoResult GlobalVarChangeI
 
				if (curidx < CURRENCY_END) {
 
					_currency_specs[curidx].prefix = prefix;
 
				} else {
 
					grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
 
					GrfMsg(1, "GlobalVarChangeInfo: Currency symbol {} out of range, ignoring", curidx);
 
				}
 
				break;
 
			}
 
@@ -2758,7 +2751,7 @@ static ChangeInfoResult GlobalVarChangeI
 
				if (curidx < CURRENCY_END) {
 
					_currency_specs[curidx].suffix = suffix;
 
				} else {
 
					grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
 
					GrfMsg(1, "GlobalVarChangeInfo: Currency symbol {} out of range, ignoring", curidx);
 
				}
 
				break;
 
			}
 
@@ -2770,16 +2763,16 @@ static ChangeInfoResult GlobalVarChangeI
 
				if (curidx < CURRENCY_END) {
 
					_currency_specs[curidx].to_euro = year_euro;
 
				} else {
 
					grfmsg(1, "GlobalVarChangeInfo: Euro intro date %d out of range, ignoring", curidx);
 
					GrfMsg(1, "GlobalVarChangeInfo: Euro intro date {} out of range, ignoring", curidx);
 
				}
 
				break;
 
			}
 

	
 
			case 0x10: // Snow line height table
 
				if (numinfo > 1 || IsSnowLineSet()) {
 
					grfmsg(1, "GlobalVarChangeInfo: The snowline can only be set once (%d)", numinfo);
 
					GrfMsg(1, "GlobalVarChangeInfo: The snowline can only be set once ({})", numinfo);
 
				} else if (buf->Remaining() < SNOW_LINE_MONTHS * SNOW_LINE_DAYS) {
 
					grfmsg(1, "GlobalVarChangeInfo: Not enough entries set in the snowline table (" PRINTF_SIZE ")", buf->Remaining());
 
					GrfMsg(1, "GlobalVarChangeInfo: Not enough entries set in the snowline table ({})", buf->Remaining());
 
				} else {
 
					byte table[SNOW_LINE_MONTHS][SNOW_LINE_DAYS];
 

	
 
@@ -2814,7 +2807,7 @@ static ChangeInfoResult GlobalVarChangeI
 
				uint curidx = gvid + i; // The current index, i.e. language.
 
				const LanguageMetadata *lang = curidx < MAX_LANG ? GetLanguage(curidx) : nullptr;
 
				if (lang == nullptr) {
 
					grfmsg(1, "GlobalVarChangeInfo: Language %d is not known, ignoring", curidx);
 
					GrfMsg(1, "GlobalVarChangeInfo: Language {} is not known, ignoring", curidx);
 
					/* Skip over the data. */
 
					if (prop == 0x15) {
 
						buf->ReadByte();
 
@@ -2831,7 +2824,7 @@ static ChangeInfoResult GlobalVarChangeI
 
				if (prop == 0x15) {
 
					uint plural_form = buf->ReadByte();
 
					if (plural_form >= LANGUAGE_MAX_PLURAL) {
 
						grfmsg(1, "GlobalVarChanceInfo: Plural form %d is out of range, ignoring", plural_form);
 
						GrfMsg(1, "GlobalVarChanceInfo: Plural form {} is out of range, ignoring", plural_form);
 
					} else {
 
						_cur.grffile->language_map[curidx].plural_form = plural_form;
 
					}
 
@@ -2855,14 +2848,14 @@ static ChangeInfoResult GlobalVarChangeI
 
					if (prop == 0x13) {
 
						map.openttd_id = lang->GetGenderIndex(name);
 
						if (map.openttd_id >= MAX_NUM_GENDERS) {
 
							grfmsg(1, "GlobalVarChangeInfo: Gender name %s is not known, ignoring", name);
 
							GrfMsg(1, "GlobalVarChangeInfo: Gender name {} is not known, ignoring", name);
 
						} else {
 
							_cur.grffile->language_map[curidx].gender_map.push_back(map);
 
						}
 
					} else {
 
						map.openttd_id = lang->GetCaseIndex(name);
 
						if (map.openttd_id >= MAX_NUM_CASES) {
 
							grfmsg(1, "GlobalVarChangeInfo: Case name %s is not known, ignoring", name);
 
							GrfMsg(1, "GlobalVarChangeInfo: Case name {} is not known, ignoring", name);
 
						} else {
 
							_cur.grffile->language_map[curidx].case_map.push_back(map);
 
						}
 
@@ -2963,7 +2956,7 @@ static ChangeInfoResult CargoChangeInfo(
 
	ChangeInfoResult ret = CIR_SUCCESS;
 

	
 
	if (cid + numinfo > NUM_CARGO) {
 
		grfmsg(2, "CargoChangeInfo: Cargo type %d out of range (max %d)", cid + numinfo, NUM_CARGO - 1);
 
		GrfMsg(2, "CargoChangeInfo: Cargo type {} out of range (max {})", cid + numinfo, NUM_CARGO - 1);
 
		return CIR_INVALID_ID;
 
	}
 

	
 
@@ -3060,7 +3053,7 @@ static ChangeInfoResult CargoChangeInfo(
 
					case 0x09: cs->town_effect = TE_WATER; break;
 
					case 0x0B: cs->town_effect = TE_FOOD; break;
 
					default:
 
						grfmsg(1, "CargoChangeInfo: Unknown town growth substitute value %d, setting to none.", substitute_type);
 
						GrfMsg(1, "CargoChangeInfo: Unknown town growth substitute value {}, setting to none.", substitute_type);
 
						FALLTHROUGH;
 
					case 0xFF: cs->town_effect = TE_NONE; break;
 
				}
 
@@ -3102,12 +3095,12 @@ static ChangeInfoResult SoundEffectChang
 
	ChangeInfoResult ret = CIR_SUCCESS;
 

	
 
	if (_cur.grffile->sound_offset == 0) {
 
		grfmsg(1, "SoundEffectChangeInfo: No effects defined, skipping");
 
		GrfMsg(1, "SoundEffectChangeInfo: No effects defined, skipping");
 
		return CIR_INVALID_ID;
 
	}
 

	
 
	if (sid + numinfo - ORIGINAL_SAMPLE_COUNT > _cur.grffile->num_sounds) {
 
		grfmsg(1, "SoundEffectChangeInfo: Attempting to change undefined sound effect (%u), max (%u). Ignoring.", sid + numinfo, ORIGINAL_SAMPLE_COUNT + _cur.grffile->num_sounds);
 
		GrfMsg(1, "SoundEffectChangeInfo: Attempting to change undefined sound effect ({}), max ({}). Ignoring.", sid + numinfo, ORIGINAL_SAMPLE_COUNT + _cur.grffile->num_sounds);
 
		return CIR_INVALID_ID;
 
	}
 

	
 
@@ -3127,7 +3120,7 @@ static ChangeInfoResult SoundEffectChang
 
				SoundID orig_sound = buf->ReadByte();
 

	
 
				if (orig_sound >= ORIGINAL_SAMPLE_COUNT) {
 
					grfmsg(1, "SoundEffectChangeInfo: Original sound %d not defined (max %d)", orig_sound, ORIGINAL_SAMPLE_COUNT);
 
					GrfMsg(1, "SoundEffectChangeInfo: Original sound {} not defined (max {})", orig_sound, ORIGINAL_SAMPLE_COUNT);
 
				} else {
 
					SoundEntry *old_sound = GetSound(orig_sound);
 

	
 
@@ -3197,7 +3190,7 @@ static ChangeInfoResult IndustrytilesCha
 
	ChangeInfoResult ret = CIR_SUCCESS;
 

	
 
	if (indtid + numinfo > NUM_INDUSTRYTILES_PER_GRF) {
 
		grfmsg(1, "IndustryTilesChangeInfo: Too many industry tiles loaded (%u), max (%u). Ignoring.", indtid + numinfo, NUM_INDUSTRYTILES_PER_GRF);
 
		GrfMsg(1, "IndustryTilesChangeInfo: Too many industry tiles loaded ({}), max ({}). Ignoring.", indtid + numinfo, NUM_INDUSTRYTILES_PER_GRF);
 
		return CIR_INVALID_ID;
 
	}
 

	
 
@@ -3218,7 +3211,7 @@ static ChangeInfoResult IndustrytilesCha
 
				byte subs_id = buf->ReadByte();
 
				if (subs_id >= NEW_INDUSTRYTILEOFFSET) {
 
					/* The substitute id must be one of the original industry tile. */
 
					grfmsg(2, "IndustryTilesChangeInfo: Attempt to use new industry tile %u as substitute industry tile for %u. Ignoring.", subs_id, indtid + i);
 
					GrfMsg(2, "IndustryTilesChangeInfo: Attempt to use new industry tile {} as substitute industry tile for {}. Ignoring.", subs_id, indtid + i);
 
					continue;
 
				}
 

	
 
@@ -3248,7 +3241,7 @@ static ChangeInfoResult IndustrytilesCha
 

	
 
				/* The industry being overridden must be an original industry. */
 
				if (ovrid >= NEW_INDUSTRYTILEOFFSET) {
 
					grfmsg(2, "IndustryTilesChangeInfo: Attempt to override new industry tile %u with industry tile id %u. Ignoring.", ovrid, indtid + i);
 
					GrfMsg(2, "IndustryTilesChangeInfo: Attempt to override new industry tile {} with industry tile id {}. Ignoring.", ovrid, indtid + i);
 
					continue;
 
				}
 

	
 
@@ -3453,7 +3446,7 @@ static ChangeInfoResult IndustriesChange
 
	ChangeInfoResult ret = CIR_SUCCESS;
 

	
 
	if (indid + numinfo > NUM_INDUSTRYTYPES_PER_GRF) {
 
		grfmsg(1, "IndustriesChangeInfo: Too many industries loaded (%u), max (%u). Ignoring.", indid + numinfo, NUM_INDUSTRYTYPES_PER_GRF);
 
		GrfMsg(1, "IndustriesChangeInfo: Too many industries loaded ({}), max ({}). Ignoring.", indid + numinfo, NUM_INDUSTRYTYPES_PER_GRF);
 
		return CIR_INVALID_ID;
 
	}
 

	
 
@@ -3479,7 +3472,7 @@ static ChangeInfoResult IndustriesChange
 
					continue;
 
				} else if (subs_id >= NEW_INDUSTRYOFFSET) {
 
					/* The substitute id must be one of the original industry. */
 
					grfmsg(2, "_industry_specs: Attempt to use new industry %u as substitute industry for %u. Ignoring.", subs_id, indid + i);
 
					GrfMsg(2, "_industry_specs: Attempt to use new industry {} as substitute industry for {}. Ignoring.", subs_id, indid + i);
 
					continue;
 
				}
 

	
 
@@ -3506,7 +3499,7 @@ static ChangeInfoResult IndustriesChange
 

	
 
				/* The industry being overridden must be an original industry. */
 
				if (ovrid >= NEW_INDUSTRYOFFSET) {
 
					grfmsg(2, "IndustriesChangeInfo: Attempt to override new industry %u with industry id %u. Ignoring.", ovrid, indid + i);
 
					GrfMsg(2, "IndustriesChangeInfo: Attempt to override new industry {} with industry id {}. Ignoring.", ovrid, indid + i);
 
					continue;
 
				}
 
				indsp->grf_prop.override = ovrid;
 
@@ -3526,7 +3519,7 @@ static ChangeInfoResult IndustriesChange
 

	
 
					for (uint k = 0;; k++) {
 
						if (bytes_read >= definition_size) {
 
							grfmsg(3, "IndustriesChangeInfo: Incorrect size for industry tile layout definition for industry %u.", indid);
 
							GrfMsg(3, "IndustriesChangeInfo: Incorrect size for industry tile layout definition for industry {}.", indid);
 
							/* Avoid warning twice */
 
							definition_size = UINT32_MAX;
 
						}
 
@@ -3544,12 +3537,12 @@ static ChangeInfoResult IndustriesChange
 
							bytes_read += 2;
 

	
 
							if (type >= lengthof(_origin_industry_specs)) {
 
								grfmsg(1, "IndustriesChangeInfo: Invalid original industry number for layout import, industry %u", indid);
 
								GrfMsg(1, "IndustriesChangeInfo: Invalid original industry number for layout import, industry {}", indid);
 
								DisableGrf(STR_NEWGRF_ERROR_INVALID_ID);
 
								return CIR_DISABLED;
 
							}
 
							if (laynbr >= _origin_industry_specs[type].layouts.size()) {
 
								grfmsg(1, "IndustriesChangeInfo: Invalid original industry layout index for layout import, industry %u", indid);
 
								GrfMsg(1, "IndustriesChangeInfo: Invalid original industry layout index for layout import, industry {}", indid);
 
								DisableGrf(STR_NEWGRF_ERROR_INVALID_ID);
 
								return CIR_DISABLED;
 
							}
 
@@ -3578,7 +3571,7 @@ static ChangeInfoResult IndustriesChange
 
							int tempid = _industile_mngr.GetID(local_tile_id, _cur.grffile->grfid);
 

	
 
							if (tempid == INVALID_INDUSTRYTILE) {
 
								grfmsg(2, "IndustriesChangeInfo: Attempt to use industry tile %u with industry id %u, not yet defined. Ignoring.", local_tile_id, indid);
 
								GrfMsg(2, "IndustriesChangeInfo: Attempt to use industry tile {} with industry id {}, not yet defined. Ignoring.", local_tile_id, indid);
 
							} else {
 
								/* Declared as been valid, can be used */
 
								it.gfx = tempid;
 
@@ -3600,7 +3593,7 @@ static ChangeInfoResult IndustriesChange
 

	
 
					if (!ValidateIndustryLayout(layout)) {
 
						/* The industry layout was not valid, so skip this one. */
 
						grfmsg(1, "IndustriesChangeInfo: Invalid industry layout for industry id %u. Ignoring", indid);
 
						GrfMsg(1, "IndustriesChangeInfo: Invalid industry layout for industry id {}. Ignoring", indid);
 
						new_num_layouts--;
 
						j--;
 
					} else {
 
@@ -3857,7 +3850,7 @@ static ChangeInfoResult AirportChangeInf
 
	ChangeInfoResult ret = CIR_SUCCESS;
 

	
 
	if (airport + numinfo > NUM_AIRPORTS_PER_GRF) {
 
		grfmsg(1, "AirportChangeInfo: Too many airports, trying id (%u), max (%u). Ignoring.", airport + numinfo, NUM_AIRPORTS_PER_GRF);
 
		GrfMsg(1, "AirportChangeInfo: Too many airports, trying id ({}), max ({}). Ignoring.", airport + numinfo, NUM_AIRPORTS_PER_GRF);
 
		return CIR_INVALID_ID;
 
	}
 

	
 
@@ -3868,7 +3861,7 @@ static ChangeInfoResult AirportChangeInf
 
		AirportSpec *as = _cur.grffile->airportspec[airport + i].get();
 

	
 
		if (as == nullptr && prop != 0x08 && prop != 0x09) {
 
			grfmsg(2, "AirportChangeInfo: Attempt to modify undefined airport %u, ignoring", airport + i);
 
			GrfMsg(2, "AirportChangeInfo: Attempt to modify undefined airport {}, ignoring", airport + i);
 
			return CIR_INVALID_ID;
 
		}
 

	
 
@@ -3882,7 +3875,7 @@ static ChangeInfoResult AirportChangeInf
 
					continue;
 
				} else if (subs_id >= NEW_AIRPORT_OFFSET) {
 
					/* The substitute id must be one of the original airports. */
 
					grfmsg(2, "AirportChangeInfo: Attempt to use new airport %u as substitute airport for %u. Ignoring.", subs_id, airport + i);
 
					GrfMsg(2, "AirportChangeInfo: Attempt to use new airport {} as substitute airport for {}. Ignoring.", subs_id, airport + i);
 
					continue;
 
				}
 

	
 
@@ -3944,7 +3937,7 @@ static ChangeInfoResult AirportChangeInf
 
								uint16 tempid = _airporttile_mngr.GetID(local_tile_id, _cur.grffile->grfid);
 

	
 
								if (tempid == INVALID_AIRPORTTILE) {
 
									grfmsg(2, "AirportChangeInfo: Attempt to use airport tile %u with airport id %u, not yet defined. Ignoring.", local_tile_id, airport + i);
 
									GrfMsg(2, "AirportChangeInfo: Attempt to use airport tile {} with airport id {}, not yet defined. Ignoring.", local_tile_id, airport + i);
 
								} else {
 
									/* Declared as been valid, can be used */
 
									att[k].gfx = tempid;
 
@@ -4078,7 +4071,7 @@ static ChangeInfoResult ObjectChangeInfo
 
	ChangeInfoResult ret = CIR_SUCCESS;
 

	
 
	if (id + numinfo > NUM_OBJECTS_PER_GRF) {
 
		grfmsg(1, "ObjectChangeInfo: Too many objects loaded (%u), max (%u). Ignoring.", id + numinfo, NUM_OBJECTS_PER_GRF);
 
		GrfMsg(1, "ObjectChangeInfo: Too many objects loaded ({}), max ({}). Ignoring.", id + numinfo, NUM_OBJECTS_PER_GRF);
 
		return CIR_INVALID_ID;
 
	}
 

	
 
@@ -4128,7 +4121,7 @@ static ChangeInfoResult ObjectChangeInfo
 
			case 0x0C: // Size
 
				spec->size = buf->ReadByte();
 
				if (GB(spec->size, 0, 4) == 0 || GB(spec->size, 4, 4) == 0) {
 
					grfmsg(0, "ObjectChangeInfo: Invalid object size requested (0x%x) for object id %u. Ignoring.", spec->size, id + i);
 
					GrfMsg(0, "ObjectChangeInfo: Invalid object size requested ({:#X}) for object id {}. Ignoring.", spec->size, id + i);
 
					spec->size = OBJECT_SIZE_1X1;
 
				}
 
				break;
 
@@ -4179,7 +4172,7 @@ static ChangeInfoResult ObjectChangeInfo
 
			case 0x17: // Views
 
				spec->views = buf->ReadByte();
 
				if (spec->views != 1 && spec->views != 2 && spec->views != 4) {
 
					grfmsg(2, "ObjectChangeInfo: Invalid number of views (%u) for object id %u. Ignoring.", spec->views, id + i);
 
					GrfMsg(2, "ObjectChangeInfo: Invalid number of views ({}) for object id {}. Ignoring.", spec->views, id + i);
 
					spec->views = 1;
 
				}
 
				break;
 
@@ -4212,7 +4205,7 @@ static ChangeInfoResult RailTypeChangeIn
 
	extern RailtypeInfo _railtypes[RAILTYPE_END];
 

	
 
	if (id + numinfo > RAILTYPE_END) {
 
		grfmsg(1, "RailTypeChangeInfo: Rail type %u is invalid, max %u, ignoring", id + numinfo, RAILTYPE_END);
 
		GrfMsg(1, "RailTypeChangeInfo: Rail type {} is invalid, max {}, ignoring", id + numinfo, RAILTYPE_END);
 
		return CIR_INVALID_ID;
 
	}
 

	
 
@@ -4342,7 +4335,7 @@ static ChangeInfoResult RailTypeReserveI
 
	extern RailtypeInfo _railtypes[RAILTYPE_END];
 

	
 
	if (id + numinfo > RAILTYPE_END) {
 
		grfmsg(1, "RailTypeReserveInfo: Rail type %u is invalid, max %u, ignoring", id + numinfo, RAILTYPE_END);
 
		GrfMsg(1, "RailTypeReserveInfo: Rail type {} is invalid, max {}, ignoring", id + numinfo, RAILTYPE_END);
 
		return CIR_INVALID_ID;
 
	}
 

	
 
@@ -4383,7 +4376,7 @@ static ChangeInfoResult RailTypeReserveI
 
					}
 
					break;
 
				}
 
				grfmsg(1, "RailTypeReserveInfo: Ignoring property 1D for rail type %u because no label was set", id + i);
 
				GrfMsg(1, "RailTypeReserveInfo: Ignoring property 1D for rail type {} because no label was set", id + i);
 
				FALLTHROUGH;
 

	
 
			case 0x0E: // Compatible railtype list
 
@@ -4431,7 +4424,7 @@ static ChangeInfoResult RoadTypeChangeIn
 
	RoadType *type_map = (rtt == RTT_TRAM) ? _cur.grffile->tramtype_map : _cur.grffile->roadtype_map;
 

	
 
	if (id + numinfo > ROADTYPE_END) {
 
		grfmsg(1, "RoadTypeChangeInfo: Road type %u is invalid, max %u, ignoring", id + numinfo, ROADTYPE_END);
 
		GrfMsg(1, "RoadTypeChangeInfo: Road type {} is invalid, max {}, ignoring", id + numinfo, ROADTYPE_END);
 
		return CIR_INVALID_ID;
 
	}
 

	
 
@@ -4555,7 +4548,7 @@ static ChangeInfoResult RoadTypeReserveI
 
	RoadType *type_map = (rtt == RTT_TRAM) ? _cur.grffile->tramtype_map : _cur.grffile->roadtype_map;
 

	
 
	if (id + numinfo > ROADTYPE_END) {
 
		grfmsg(1, "RoadTypeReserveInfo: Road type %u is invalid, max %u, ignoring", id + numinfo, ROADTYPE_END);
 
		GrfMsg(1, "RoadTypeReserveInfo: Road type {} is invalid, max {}, ignoring", id + numinfo, ROADTYPE_END);
 
		return CIR_INVALID_ID;
 
	}
 

	
 
@@ -4570,7 +4563,7 @@ static ChangeInfoResult RoadTypeReserveI
 
					/* Set up new road type */
 
					rt = AllocateRoadType(rtl, rtt);
 
				} else if (GetRoadTramType(rt) != rtt) {
 
					grfmsg(1, "RoadTypeReserveInfo: Road type %u is invalid type (road/tram), ignoring", id + numinfo);
 
					GrfMsg(1, "RoadTypeReserveInfo: Road type {} is invalid type (road/tram), ignoring", id + numinfo);
 
					return CIR_INVALID_ID;
 
				}
 

	
 
@@ -4597,7 +4590,7 @@ static ChangeInfoResult RoadTypeReserveI
 
					}
 
					break;
 
				}
 
				grfmsg(1, "RoadTypeReserveInfo: Ignoring property 1D for road type %u because no label was set", id + i);
 
				GrfMsg(1, "RoadTypeReserveInfo: Ignoring property 1D for road type {} because no label was set", id + i);
 
				/* FALL THROUGH */
 

	
 
			case 0x0F: // Powered roadtype list
 
@@ -4640,7 +4633,7 @@ static ChangeInfoResult AirportTilesChan
 
	ChangeInfoResult ret = CIR_SUCCESS;
 

	
 
	if (airtid + numinfo > NUM_AIRPORTTILES_PER_GRF) {
 
		grfmsg(1, "AirportTileChangeInfo: Too many airport tiles loaded (%u), max (%u). Ignoring.", airtid + numinfo, NUM_AIRPORTTILES_PER_GRF);
 
		GrfMsg(1, "AirportTileChangeInfo: Too many airport tiles loaded ({}), max ({}). Ignoring.", airtid + numinfo, NUM_AIRPORTTILES_PER_GRF);
 
		return CIR_INVALID_ID;
 
	}
 

	
 
@@ -4651,7 +4644,7 @@ static ChangeInfoResult AirportTilesChan
 
		AirportTileSpec *tsp = _cur.grffile->airtspec[airtid + i].get();
 

	
 
		if (prop != 0x08 && tsp == nullptr) {
 
			grfmsg(2, "AirportTileChangeInfo: Attempt to modify undefined airport tile %u. Ignoring.", airtid + i);
 
			GrfMsg(2, "AirportTileChangeInfo: Attempt to modify undefined airport tile {}. Ignoring.", airtid + i);
 
			return CIR_INVALID_ID;
 
		}
 

	
 
@@ -4660,7 +4653,7 @@ static ChangeInfoResult AirportTilesChan
 
				byte subs_id = buf->ReadByte();
 
				if (subs_id >= NEW_AIRPORTTILE_OFFSET) {
 
					/* The substitute id must be one of the original airport tiles. */
 
					grfmsg(2, "AirportTileChangeInfo: Attempt to use new airport tile %u as substitute airport tile for %u. Ignoring.", subs_id, airtid + i);
 
					GrfMsg(2, "AirportTileChangeInfo: Attempt to use new airport tile {} as substitute airport tile for {}. Ignoring.", subs_id, airtid + i);
 
					continue;
 
				}
 

	
 
@@ -4686,7 +4679,7 @@ static ChangeInfoResult AirportTilesChan
 

	
 
				/* The airport tile being overridden must be an original airport tile. */
 
				if (override >= NEW_AIRPORTTILE_OFFSET) {
 
					grfmsg(2, "AirportTileChangeInfo: Attempt to override new airport tile %u with airport tile id %u. Ignoring.", override, airtid + i);
 
					GrfMsg(2, "AirportTileChangeInfo: Attempt to override new airport tile {} with airport tile id {}. Ignoring.", override, airtid + i);
 
					continue;
 
				}
 

	
 
@@ -4765,7 +4758,7 @@ static ChangeInfoResult RoadStopChangeIn
 
	ChangeInfoResult ret = CIR_SUCCESS;
 

	
 
	if (id + numinfo > NUM_ROADSTOPS_PER_GRF) {
 
		grfmsg(1, "RoadStopChangeInfo: RoadStop %u is invalid, max %u, ignoring", id + numinfo, NUM_ROADSTOPS_PER_GRF);
 
		GrfMsg(1, "RoadStopChangeInfo: RoadStop {} is invalid, max {}, ignoring", id + numinfo, NUM_ROADSTOPS_PER_GRF);
 
		return CIR_INVALID_ID;
 
	}
 

	
 
@@ -4775,7 +4768,7 @@ static ChangeInfoResult RoadStopChangeIn
 
		RoadStopSpec *rs = _cur.grffile->roadstops[id + i].get();
 

	
 
		if (rs == nullptr && prop != 0x08) {
 
			grfmsg(1, "RoadStopChangeInfo: Attempt to modify undefined road stop %u, ignoring", id + i);
 
			GrfMsg(1, "RoadStopChangeInfo: Attempt to modify undefined road stop {}, ignoring", id + i);
 
			ChangeInfoResult cir = IgnoreRoadStopProperty(prop, buf);
 
			if (cir > ret) ret = cir;
 
			continue;
 
@@ -4862,11 +4855,11 @@ static bool HandleChangeInfoResult(const
 
			return false;
 

	
 
		case CIR_UNHANDLED:
 
			grfmsg(1, "%s: Ignoring property 0x%02X of feature 0x%02X (not implemented)", caller, property, feature);
 
			GrfMsg(1, "{}: Ignoring property {:#02X} of feature {:#02X} (not implemented)", caller, property, feature);
 
			return false;
 

	
 
		case CIR_UNKNOWN:
 
			grfmsg(0, "%s: Unknown property 0x%02X of feature 0x%02X, disabling", caller, property, feature);
 
			GrfMsg(0, "{}: Unknown property {:#02X} of feature {:#02X}, disabling", caller, property, feature);
 
			FALLTHROUGH;
 

	
 
		case CIR_INVALID_ID: {
 
@@ -4923,15 +4916,15 @@ static void FeatureChangeInfo(ByteReader
 
	uint engine   = buf->ReadExtendedByte();
 

	
 
	if (feature >= GSF_END) {
 
		grfmsg(1, "FeatureChangeInfo: Unsupported feature 0x%02X, skipping", feature);
 
		GrfMsg(1, "FeatureChangeInfo: Unsupported feature {:#02X}, skipping", feature);
 
		return;
 
	}
 

	
 
	grfmsg(6, "FeatureChangeInfo: Feature 0x%02X, %d properties, to apply to %d+%d",
 
	GrfMsg(6, "FeatureChangeInfo: Feature {:#02X}, {} properties, to apply to {}+{}",
 
	               feature, numprops, engine, numinfo);
 

	
 
	if (handler[feature] == nullptr) {
 
		if (feature != GSF_CARGOES) grfmsg(1, "FeatureChangeInfo: Unsupported feature 0x%02X, skipping", feature);
 
		if (feature != GSF_CARGOES) GrfMsg(1, "FeatureChangeInfo: Unsupported feature {:#02X}, skipping", feature);
 
		return;
 
	}
 

	
 
@@ -5056,13 +5049,13 @@ static void NewSpriteSet(ByteReader *buf
 

	
 
	if (feature >= GSF_END) {
 
		_cur.skip_sprites = num_sets * num_ents;
 
		grfmsg(1, "NewSpriteSet: Unsupported feature 0x%02X, skipping %d sprites", feature, _cur.skip_sprites);
 
		GrfMsg(1, "NewSpriteSet: Unsupported feature {:#02X}, skipping {} sprites", feature, _cur.skip_sprites);
 
		return;
 
	}
 

	
 
	_cur.AddSpriteSets(feature, _cur.spriteid, first_set, num_sets, num_ents);
 

	
 
	grfmsg(7, "New sprite set at %d of feature 0x%02X, consisting of %d sets with %d views each (total %d)",
 
	GrfMsg(7, "New sprite set at {} of feature {:#02X}, consisting of {} sets with {} views each (total {})",
 
		_cur.spriteid, feature, num_sets, num_ents, num_sets * num_ents
 
	);
 

	
 
@@ -5088,7 +5081,7 @@ static void SkipAct1(ByteReader *buf)
 

	
 
	_cur.skip_sprites = num_sets * num_ents;
 

	
 
	grfmsg(3, "SkipAct1: Skipping %d sprites", _cur.skip_sprites);
 
	GrfMsg(3, "SkipAct1: Skipping {} sprites", _cur.skip_sprites);
 
}
 

	
 
/* Helper function to either create a callback or link to a previously
 
@@ -5101,7 +5094,7 @@ static const SpriteGroup *GetGroupFromGr
 
	}
 

	
 
	if (groupid > MAX_SPRITEGROUP || _cur.spritegroups[groupid] == nullptr) {
 
		grfmsg(1, "GetGroupFromGroupID(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty", setid, type, groupid);
 
		GrfMsg(1, "GetGroupFromGroupID({:#02X}:{:#02X}): Groupid {:#04X} does not exist, leaving empty", setid, type, groupid);
 
		return nullptr;
 
	}
 

	
 
@@ -5124,7 +5117,7 @@ static const SpriteGroup *CreateGroupFro
 
	}
 

	
 
	if (!_cur.IsValidSpriteSet(feature, spriteid)) {
 
		grfmsg(1, "CreateGroupFromGroupID(0x%02X:0x%02X): Sprite set %u invalid", setid, type, spriteid);
 
		GrfMsg(1, "CreateGroupFromGroupID({:#02X}:{:#02X}): Sprite set {} invalid", setid, type, spriteid);
 
		return nullptr;
 
	}
 

	
 
@@ -5155,7 +5148,7 @@ static void NewSpriteGroup(ByteReader *b
 

	
 
	uint8 feature = buf->ReadByte();
 
	if (feature >= GSF_END) {
 
		grfmsg(1, "NewSpriteGroup: Unsupported feature 0x%02X, skipping", feature);
 
		GrfMsg(1, "NewSpriteGroup: Unsupported feature {:#02X}, skipping", feature);
 
		return;
 
	}
 

	
 
@@ -5298,7 +5291,7 @@ static void NewSpriteGroup(ByteReader *b
 

	
 
			byte num_groups = buf->ReadByte();
 
			if (!HasExactlyOneBit(num_groups)) {
 
				grfmsg(1, "NewSpriteGroup: Random Action 2 nrand should be power of 2");
 
				GrfMsg(1, "NewSpriteGroup: Random Action 2 nrand should be power of 2");
 
			}
 

	
 
			for (uint i = 0; i < num_groups; i++) {
 
@@ -5328,15 +5321,15 @@ static void NewSpriteGroup(ByteReader *b
 
					byte num_loading = buf->ReadByte();
 

	
 
					if (!_cur.HasValidSpriteSets(feature)) {
 
						grfmsg(0, "NewSpriteGroup: No sprite set to work on! Skipping");
 
						GrfMsg(0, "NewSpriteGroup: No sprite set to work on! Skipping");
 
						return;
 
					}
 

	
 
					grfmsg(6, "NewSpriteGroup: New SpriteGroup 0x%02X, %u loaded, %u loading",
 
					GrfMsg(6, "NewSpriteGroup: New SpriteGroup {:#02X}, {} loaded, {} loading",
 
							setid, num_loaded, num_loading);
 

	
 
					if (num_loaded + num_loading == 0) {
 
						grfmsg(1, "NewSpriteGroup: no result, skipping invalid RealSpriteGroup");
 
						GrfMsg(1, "NewSpriteGroup: no result, skipping invalid RealSpriteGroup");
 
						break;
 
					}
 

	
 
@@ -5344,7 +5337,7 @@ static void NewSpriteGroup(ByteReader *b
 
						/* Avoid creating 'Real' sprite group if only one option. */
 
						uint16 spriteid = buf->ReadWord();
 
						act_group = CreateGroupFromGroupID(feature, setid, type, spriteid);
 
						grfmsg(8, "NewSpriteGroup: one result, skipping RealSpriteGroup = subset %u", spriteid);
 
						GrfMsg(8, "NewSpriteGroup: one result, skipping RealSpriteGroup = subset {}", spriteid);
 
						break;
 
					}
 

	
 
@@ -5353,12 +5346,12 @@ static void NewSpriteGroup(ByteReader *b
 

	
 
					for (uint i = 0; i < num_loaded; i++) {
 
						loaded.push_back(buf->ReadWord());
 
						grfmsg(8, "NewSpriteGroup: + rg->loaded[%i]  = subset %u", i, loaded[i]);
 
						GrfMsg(8, "NewSpriteGroup: + rg->loaded[{}]  = subset {}", i, loaded[i]);
 
					}
 

	
 
					for (uint i = 0; i < num_loading; i++) {
 
						loading.push_back(buf->ReadWord());
 
						grfmsg(8, "NewSpriteGroup: + rg->loading[%i] = subset %u", i, loading[i]);
 
						GrfMsg(8, "NewSpriteGroup: + rg->loading[{}] = subset {}", i, loading[i]);
 
					}
 

	
 
					if (std::adjacent_find(loaded.begin(),  loaded.end(),  std::not_equal_to<>()) == loaded.end() &&
 
@@ -5367,7 +5360,7 @@ static void NewSpriteGroup(ByteReader *b
 
					{
 
						/* Both lists only contain the same value, so don't create 'Real' sprite group */
 
						act_group = CreateGroupFromGroupID(feature, setid, type, loaded[0]);
 
						grfmsg(8, "NewSpriteGroup: same result, skipping RealSpriteGroup = subset %u", loaded[0]);
 
						GrfMsg(8, "NewSpriteGroup: same result, skipping RealSpriteGroup = subset {}", loaded[0]);
 
						break;
 
					}
 

	
 
@@ -5408,7 +5401,7 @@ static void NewSpriteGroup(ByteReader *b
 

	
 
				case GSF_INDUSTRIES: {
 
					if (type > 2) {
 
						grfmsg(1, "NewSpriteGroup: Unsupported industry production version %d, skipping", type);
 
						GrfMsg(1, "NewSpriteGroup: Unsupported industry production version {}, skipping", type);
 
						break;
 
					}
 

	
 
@@ -5488,7 +5481,7 @@ static void NewSpriteGroup(ByteReader *b
 
				}
 

	
 
				/* Loading of Tile Layout and Production Callback groups would happen here */
 
				default: grfmsg(1, "NewSpriteGroup: Unsupported feature 0x%02X, skipping", feature);
 
				default: GrfMsg(1, "NewSpriteGroup: Unsupported feature {:#02X}, skipping", feature);
 
			}
 
		}
 
	}
 
@@ -5503,7 +5496,7 @@ static CargoID TranslateCargo(uint8 feat
 
			case 0:    return 0;
 
			case 0xFF: return CT_PURCHASE_OBJECT;
 
			default:
 
				grfmsg(1, "TranslateCargo: Invalid cargo bitnum %d for objects, skipping.", ctype);
 
				GrfMsg(1, "TranslateCargo: Invalid cargo bitnum {} for objects, skipping.", ctype);
 
				return CT_INVALID;
 
		}
 
	}
 
@@ -5514,41 +5507,41 @@ static CargoID TranslateCargo(uint8 feat
 
	if (_cur.grffile->cargo_list.size() == 0) {
 
		/* No cargo table, so use bitnum values */
 
		if (ctype >= 32) {
 
			grfmsg(1, "TranslateCargo: Cargo bitnum %d out of range (max 31), skipping.", ctype);
 
			GrfMsg(1, "TranslateCargo: Cargo bitnum {} out of range (max 31), skipping.", ctype);
 
			return CT_INVALID;
 
		}
 

	
 
		for (const CargoSpec *cs : CargoSpec::Iterate()) {
 
			if (cs->bitnum == ctype) {
 
				grfmsg(6, "TranslateCargo: Cargo bitnum %d mapped to cargo type %d.", ctype, cs->Index());
 
				GrfMsg(6, "TranslateCargo: Cargo bitnum {} mapped to cargo type {}.", ctype, cs->Index());
 
				return cs->Index();
 
			}
 
		}
 

	
 
		grfmsg(5, "TranslateCargo: Cargo bitnum %d not available in this climate, skipping.", ctype);
 
		GrfMsg(5, "TranslateCargo: Cargo bitnum {} not available in this climate, skipping.", ctype);
 
		return CT_INVALID;
 
	}
 

	
 
	/* Check if the cargo type is out of bounds of the cargo translation table */
 
	if (ctype >= _cur.grffile->cargo_list.size()) {
 
		grfmsg(1, "TranslateCargo: Cargo type %d out of range (max %d), skipping.", ctype, (unsigned int)_cur.grffile->cargo_list.size() - 1);
 
		GrfMsg(1, "TranslateCargo: Cargo type {} out of range (max {}), skipping.", ctype, (unsigned int)_cur.grffile->cargo_list.size() - 1);
 
		return CT_INVALID;
 
	}
 

	
 
	/* Look up the cargo label from the translation table */
 
	CargoLabel cl = _cur.grffile->cargo_list[ctype];
 
	if (cl == 0) {
 
		grfmsg(5, "TranslateCargo: Cargo type %d not available in this climate, skipping.", ctype);
 
		GrfMsg(5, "TranslateCargo: Cargo type {} not available in this climate, skipping.", ctype);
 
		return CT_INVALID;
 
	}
 

	
 
	ctype = GetCargoIDByLabel(cl);
 
	if (ctype == CT_INVALID) {
 
		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));
 
		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 %d.", GB(cl, 24, 8), GB(cl, 16, 8), GB(cl, 8, 8), GB(cl, 0, 8), ctype);
 
	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;
 
}
 

	
 
@@ -5556,7 +5549,7 @@ static CargoID TranslateCargo(uint8 feat
 
static bool IsValidGroupID(uint16 groupid, const char *function)
 
{
 
	if (groupid > MAX_SPRITEGROUP || _cur.spritegroups[groupid] == nullptr) {
 
		grfmsg(1, "%s: Spritegroup 0x%04X out of range or empty, skipping.", function, groupid);
 
		GrfMsg(1, "{}: Spritegroup {:#04X} out of range or empty, skipping.", function, groupid);
 
		return false;
 
	}
 

	
 
@@ -5576,11 +5569,11 @@ static void VehicleMapSpriteGroup(ByteRe
 
		idcount = GB(idcount, 0, 7);
 

	
 
		if (last_engines_count == 0) {
 
			grfmsg(0, "VehicleMapSpriteGroup: WagonOverride: No engine to do override with");
 
			GrfMsg(0, "VehicleMapSpriteGroup: WagonOverride: No engine to do override with");
 
			return;
 
		}
 

	
 
		grfmsg(6, "VehicleMapSpriteGroup: WagonOverride: %u engines, %u wagons",
 
		GrfMsg(6, "VehicleMapSpriteGroup: WagonOverride: {} engines, {} wagons",
 
				last_engines_count, idcount);
 
	} else {
 
		if (last_engines_count != idcount) {
 
@@ -5610,7 +5603,7 @@ static void VehicleMapSpriteGroup(ByteRe
 
		uint16 groupid = buf->ReadWord();
 
		if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) continue;
 

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

	
 
		ctype = TranslateCargo(feature, ctype);
 
		if (ctype == CT_INVALID) continue;
 
@@ -5618,7 +5611,7 @@ static void VehicleMapSpriteGroup(ByteRe
 
		for (uint i = 0; i < idcount; i++) {
 
			EngineID engine = engines[i];
 

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

	
 
			if (wagover) {
 
				SetWagonOverrideSprites(engine, ctype, _cur.spritegroups[groupid], last_engines, last_engines_count);
 
@@ -5631,7 +5624,7 @@ static void VehicleMapSpriteGroup(ByteRe
 
	uint16 groupid = buf->ReadWord();
 
	if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) return;
 

	
 
	grfmsg(8, "-- Default group id 0x%04X", groupid);
 
	GrfMsg(8, "-- Default group id {:#04X}", groupid);
 

	
 
	for (uint i = 0; i < idcount; i++) {
 
		EngineID engine = engines[i];
 
@@ -5662,7 +5655,7 @@ static void CanalMapSpriteGroup(ByteRead
 

	
 
	for (auto &cf : cfs) {
 
		if (cf >= CF_END) {
 
			grfmsg(1, "CanalMapSpriteGroup: Canal subset %d out of range, skipping", cf);
 
			GrfMsg(1, "CanalMapSpriteGroup: Canal subset {} out of range, skipping", cf);
 
			continue;
 
		}
 

	
 
@@ -5675,7 +5668,7 @@ static void CanalMapSpriteGroup(ByteRead
 
static void StationMapSpriteGroup(ByteReader *buf, uint8 idcount)
 
{
 
	if (_cur.grffile->stations.empty()) {
 
		grfmsg(1, "StationMapSpriteGroup: No stations defined, skipping");
 
		GrfMsg(1, "StationMapSpriteGroup: No stations defined, skipping");
 
		return;
 
	}
 

	
 
@@ -5698,7 +5691,7 @@ static void StationMapSpriteGroup(ByteRe
 
			StationSpec *statspec = station >= _cur.grffile->stations.size() ? nullptr : _cur.grffile->stations[station].get();
 

	
 
			if (statspec == nullptr) {
 
				grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", station);
 
				GrfMsg(1, "StationMapSpriteGroup: Station with ID {:#02X} does not exist, skipping", station);
 
				continue;
 
			}
 

	
 
@@ -5713,12 +5706,12 @@ static void StationMapSpriteGroup(ByteRe
 
		StationSpec *statspec = station >= _cur.grffile->stations.size() ? nullptr : _cur.grffile->stations[station].get();
 

	
 
		if (statspec == nullptr) {
 
			grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", station);
 
			GrfMsg(1, "StationMapSpriteGroup: Station with ID {:#02X} does not exist, skipping", station);
 
			continue;
 
		}
 

	
 
		if (statspec->grf_prop.grffile != nullptr) {
 
			grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X mapped multiple times, skipping", station);
 
			GrfMsg(1, "StationMapSpriteGroup: Station with ID {:#02X} mapped multiple times, skipping", station);
 
			continue;
 
		}
 

	
 
@@ -5733,7 +5726,7 @@ static void StationMapSpriteGroup(ByteRe
 
static void TownHouseMapSpriteGroup(ByteReader *buf, uint8 idcount)
 
{
 
	if (_cur.grffile->housespec.empty()) {
 
		grfmsg(1, "TownHouseMapSpriteGroup: No houses defined, skipping");
 
		GrfMsg(1, "TownHouseMapSpriteGroup: No houses defined, skipping");
 
		return;
 
	}
 

	
 
@@ -5754,7 +5747,7 @@ static void TownHouseMapSpriteGroup(Byte
 
		HouseSpec *hs = house >= _cur.grffile->housespec.size() ? nullptr : _cur.grffile->housespec[house].get();
 

	
 
		if (hs == nullptr) {
 
			grfmsg(1, "TownHouseMapSpriteGroup: House %d undefined, skipping.", house);
 
			GrfMsg(1, "TownHouseMapSpriteGroup: House {} undefined, skipping.", house);
 
			continue;
 
		}
 

	
 
@@ -5765,7 +5758,7 @@ static void TownHouseMapSpriteGroup(Byte
 
static void IndustryMapSpriteGroup(ByteReader *buf, uint8 idcount)
 
{
 
	if (_cur.grffile->industryspec.empty()) {
 
		grfmsg(1, "IndustryMapSpriteGroup: No industries defined, skipping");
 
		GrfMsg(1, "IndustryMapSpriteGroup: No industries defined, skipping");
 
		return;
 
	}
 

	
 
@@ -5786,7 +5779,7 @@ static void IndustryMapSpriteGroup(ByteR
 
		IndustrySpec *indsp = industry >= _cur.grffile->industryspec.size() ? nullptr : _cur.grffile->industryspec[industry].get();
 

	
 
		if (indsp == nullptr) {
 
			grfmsg(1, "IndustryMapSpriteGroup: Industry %d undefined, skipping", industry);
 
			GrfMsg(1, "IndustryMapSpriteGroup: Industry {} undefined, skipping", industry);
 
			continue;
 
		}
 

	
 
@@ -5797,7 +5790,7 @@ static void IndustryMapSpriteGroup(ByteR
 
static void IndustrytileMapSpriteGroup(ByteReader *buf, uint8 idcount)
 
{
 
	if (_cur.grffile->indtspec.empty()) {
 
		grfmsg(1, "IndustrytileMapSpriteGroup: No industry tiles defined, skipping");
 
		GrfMsg(1, "IndustrytileMapSpriteGroup: No industry tiles defined, skipping");
 
		return;
 
	}
 

	
 
@@ -5818,7 +5811,7 @@ static void IndustrytileMapSpriteGroup(B
 
		IndustryTileSpec *indtsp = indtile >= _cur.grffile->indtspec.size() ? nullptr : _cur.grffile->indtspec[indtile].get();
 

	
 
		if (indtsp == nullptr) {
 
			grfmsg(1, "IndustrytileMapSpriteGroup: Industry tile %d undefined, skipping", indtile);
 
			GrfMsg(1, "IndustrytileMapSpriteGroup: Industry tile {} undefined, skipping", indtile);
 
			continue;
 
		}
 

	
 
@@ -5843,7 +5836,7 @@ static void CargoMapSpriteGroup(ByteRead
 

	
 
	for (auto &cid : cargoes) {
 
		if (cid >= NUM_CARGO) {
 
			grfmsg(1, "CargoMapSpriteGroup: Cargo ID %d out of range, skipping", cid);
 
			GrfMsg(1, "CargoMapSpriteGroup: Cargo ID {} out of range, skipping", cid);
 
			continue;
 
		}
 

	
 
@@ -5856,7 +5849,7 @@ static void CargoMapSpriteGroup(ByteRead
 
static void ObjectMapSpriteGroup(ByteReader *buf, uint8 idcount)
 
{
 
	if (_cur.grffile->objectspec.empty()) {
 
		grfmsg(1, "ObjectMapSpriteGroup: No object tiles defined, skipping");
 
		GrfMsg(1, "ObjectMapSpriteGroup: No object tiles defined, skipping");
 
		return;
 
	}
 

	
 
@@ -5879,7 +5872,7 @@ static void ObjectMapSpriteGroup(ByteRea
 
			ObjectSpec *spec = object >= _cur.grffile->objectspec.size() ? nullptr : _cur.grffile->objectspec[object].get();
 

	
 
			if (spec == nullptr) {
 
				grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", object);
 
				GrfMsg(1, "ObjectMapSpriteGroup: Object with ID {:#02X} undefined, skipping", object);
 
				continue;
 
			}
 

	
 
@@ -5894,12 +5887,12 @@ static void ObjectMapSpriteGroup(ByteRea
 
		ObjectSpec *spec = object >= _cur.grffile->objectspec.size() ? nullptr : _cur.grffile->objectspec[object].get();
 

	
 
		if (spec == nullptr) {
 
			grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", object);
 
			GrfMsg(1, "ObjectMapSpriteGroup: Object with ID {:#02X} undefined, skipping", object);
 
			continue;
 
		}
 

	
 
		if (spec->grf_prop.grffile != nullptr) {
 
			grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X mapped multiple times, skipping", object);
 
			GrfMsg(1, "ObjectMapSpriteGroup: Object with ID {:#02X} mapped multiple times, skipping", object);
 
			continue;
 
		}
 

	
 
@@ -5978,7 +5971,7 @@ static void RoadTypeMapSpriteGroup(ByteR
 
static void AirportMapSpriteGroup(ByteReader *buf, uint8 idcount)
 
{
 
	if (_cur.grffile->airportspec.empty()) {
 
		grfmsg(1, "AirportMapSpriteGroup: No airports defined, skipping");
 
		GrfMsg(1, "AirportMapSpriteGroup: No airports defined, skipping");
 
		return;
 
	}
 

	
 
@@ -5999,7 +5992,7 @@ static void AirportMapSpriteGroup(ByteRe
 
		AirportSpec *as = airport >= _cur.grffile->airportspec.size() ? nullptr : _cur.grffile->airportspec[airport].get();
 

	
 
		if (as == nullptr) {
 
			grfmsg(1, "AirportMapSpriteGroup: Airport %d undefined, skipping", airport);
 
			GrfMsg(1, "AirportMapSpriteGroup: Airport {} undefined, skipping", airport);
 
			continue;
 
		}
 

	
 
@@ -6010,7 +6003,7 @@ static void AirportMapSpriteGroup(ByteRe
 
static void AirportTileMapSpriteGroup(ByteReader *buf, uint8 idcount)
 
{
 
	if (_cur.grffile->airtspec.empty()) {
 
		grfmsg(1, "AirportTileMapSpriteGroup: No airport tiles defined, skipping");
 
		GrfMsg(1, "AirportTileMapSpriteGroup: No airport tiles defined, skipping");
 
		return;
 
	}
 

	
 
@@ -6031,7 +6024,7 @@ static void AirportTileMapSpriteGroup(By
 
		AirportTileSpec *airtsp = airptile >= _cur.grffile->airtspec.size() ? nullptr : _cur.grffile->airtspec[airptile].get();
 

	
 
		if (airtsp == nullptr) {
 
			grfmsg(1, "AirportTileMapSpriteGroup: Airport tile %d undefined, skipping", airptile);
 
			GrfMsg(1, "AirportTileMapSpriteGroup: Airport tile {} undefined, skipping", airptile);
 
			continue;
 
		}
 

	
 
@@ -6042,7 +6035,7 @@ static void AirportTileMapSpriteGroup(By
 
static void RoadStopMapSpriteGroup(ByteReader *buf, uint8 idcount)
 
{
 
	if (_cur.grffile->roadstops.empty()) {
 
		grfmsg(1, "RoadStopMapSpriteGroup: No roadstops defined, skipping");
 
		GrfMsg(1, "RoadStopMapSpriteGroup: No roadstops defined, skipping");
 
		return;
 
	}
 

	
 
@@ -6065,7 +6058,7 @@ static void RoadStopMapSpriteGroup(ByteR
 
			RoadStopSpec *roadstopspec = roadstop >= _cur.grffile->roadstops.size() ? nullptr : _cur.grffile->roadstops[roadstop].get();
 

	
 
			if (roadstopspec == nullptr) {
 
				grfmsg(1, "RoadStopMapSpriteGroup: Road stop with ID 0x%02X does not exist, skipping", roadstop);
 
				GrfMsg(1, "RoadStopMapSpriteGroup: Road stop with ID {:#02X} does not exist, skipping", roadstop);
 
				continue;
 
			}
 

	
 
@@ -6080,12 +6073,12 @@ static void RoadStopMapSpriteGroup(ByteR
 
		RoadStopSpec *roadstopspec = roadstop >= _cur.grffile->roadstops.size() ? nullptr : _cur.grffile->roadstops[roadstop].get();
 

	
 
		if (roadstopspec == nullptr) {
 
			grfmsg(1, "RoadStopMapSpriteGroup: Road stop with ID 0x%02X does not exist, skipping.", roadstop);
 
			GrfMsg(1, "RoadStopMapSpriteGroup: Road stop with ID {:#02X} does not exist, skipping.", roadstop);
 
			continue;
 
		}
 

	
 
		if (roadstopspec->grf_prop.grffile != nullptr) {
 
			grfmsg(1, "RoadStopMapSpriteGroup: Road stop with ID 0x%02X mapped multiple times, skipping", roadstop);
 
			GrfMsg(1, "RoadStopMapSpriteGroup: Road stop with ID {:#02X} mapped multiple times, skipping", roadstop);
 
			continue;
 
		}
 

	
 
@@ -6117,7 +6110,7 @@ static void FeatureMapSpriteGroup(ByteRe
 
	uint8 idcount = buf->ReadByte();
 

	
 
	if (feature >= GSF_END) {
 
		grfmsg(1, "FeatureMapSpriteGroup: Unsupported feature 0x%02X, skipping", feature);
 
		GrfMsg(1, "FeatureMapSpriteGroup: Unsupported feature {:#02X}, skipping", feature);
 
		return;
 
	}
 

	
 
@@ -6128,7 +6121,7 @@ static void FeatureMapSpriteGroup(ByteRe
 
		uint16 groupid = buf->ReadWord();
 
		if (!IsValidGroupID(groupid, "FeatureMapSpriteGroup")) return;
 

	
 
		grfmsg(6, "FeatureMapSpriteGroup: Adding generic feature callback for feature 0x%02X", feature);
 
		GrfMsg(6, "FeatureMapSpriteGroup: Adding generic feature callback for feature {:#02X}", feature);
 

	
 
		AddGenericCallback(feature, _cur.grffile, _cur.spritegroups[groupid]);
 
		return;
 
@@ -6137,7 +6130,7 @@ static void FeatureMapSpriteGroup(ByteRe
 
	/* Mark the feature as used by the grf (generic callbacks do not count) */
 
	SetBit(_cur.grffile->grf_features, feature);
 

	
 
	grfmsg(6, "FeatureMapSpriteGroup: Feature 0x%02X, %d ids", feature, idcount);
 
	GrfMsg(6, "FeatureMapSpriteGroup: Feature {:#02X}, {} ids", feature, idcount);
 

	
 
	switch (feature) {
 
		case GSF_TRAINS:
 
@@ -6200,7 +6193,7 @@ static void FeatureMapSpriteGroup(ByteRe
 
			return;
 

	
 
		default:
 
			grfmsg(1, "FeatureMapSpriteGroup: Unsupported feature 0x%02X, skipping", feature);
 
			GrfMsg(1, "FeatureMapSpriteGroup: Unsupported feature {:#02X}, skipping", feature);
 
			return;
 
	}
 
}
 
@@ -6228,7 +6221,7 @@ static void FeatureNewName(ByteReader *b
 

	
 
	uint8 feature  = buf->ReadByte();
 
	if (feature >= GSF_END && feature != 0x48) {
 
		grfmsg(1, "FeatureNewName: Unsupported feature 0x%02X, skipping", feature);
 
		GrfMsg(1, "FeatureNewName: Unsupported feature {:#02X}, skipping", feature);
 
		return;
 
	}
 

	
 
@@ -6248,12 +6241,12 @@ static void FeatureNewName(ByteReader *b
 

	
 
	uint16 endid = id + num;
 

	
 
	grfmsg(6, "FeatureNewName: About to rename engines %d..%d (feature 0x%02X) in language 0x%02X",
 
	GrfMsg(6, "FeatureNewName: About to rename engines {}..{} (feature {:#02X}) in language {:#02X}",
 
	               id, endid, feature, lang);
 

	
 
	for (; id < endid && buf->HasData(); id++) {
 
		const char *name = buf->ReadString();
 
		grfmsg(8, "FeatureNewName: 0x%04X <- %s", id, name);
 
		GrfMsg(8, "FeatureNewName: {:#04X} <- {}", id, name);
 

	
 
		switch (feature) {
 
			case GSF_TRAINS:
 
@@ -6279,7 +6272,7 @@ static void FeatureNewName(ByteReader *b
 
				switch (GB(id, 8, 8)) {
 
					case 0xC4: // Station class name
 
						if (GB(id, 0, 8) >= _cur.grffile->stations.size() || _cur.grffile->stations[GB(id, 0, 8)] == nullptr) {
 
							grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
 
							GrfMsg(1, "FeatureNewName: Attempt to name undefined station {:#X}, ignoring", GB(id, 0, 8));
 
						} else {
 
							StationClassID cls_id = _cur.grffile->stations[GB(id, 0, 8)]->cls_id;
 
							StationClass::Get(cls_id)->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
 
@@ -6288,7 +6281,7 @@ static void FeatureNewName(ByteReader *b
 

	
 
					case 0xC5: // Station name
 
						if (GB(id, 0, 8) >= _cur.grffile->stations.size() || _cur.grffile->stations[GB(id, 0, 8)] == nullptr) {
 
							grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
 
							GrfMsg(1, "FeatureNewName: Attempt to name undefined station {:#X}, ignoring", GB(id, 0, 8));
 
						} else {
 
							_cur.grffile->stations[GB(id, 0, 8)]->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
 
						}
 
@@ -6296,7 +6289,7 @@ static void FeatureNewName(ByteReader *b
 

	
 
					case 0xC7: // Airporttile name
 
						if (GB(id, 0, 8) >= _cur.grffile->airtspec.size() || _cur.grffile->airtspec[GB(id, 0, 8)] == nullptr) {
 
							grfmsg(1, "FeatureNewName: Attempt to name undefined airport tile 0x%X, ignoring", GB(id, 0, 8));
 
							GrfMsg(1, "FeatureNewName: Attempt to name undefined airport tile {:#X}, ignoring", GB(id, 0, 8));
 
						} else {
 
							_cur.grffile->airtspec[GB(id, 0, 8)]->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
 
						}
 
@@ -6304,14 +6297,14 @@ static void FeatureNewName(ByteReader *b
 

	
 
					case 0xC9: // House name
 
						if (GB(id, 0, 8) >= _cur.grffile->housespec.size() || _cur.grffile->housespec[GB(id, 0, 8)] == nullptr) {
 
							grfmsg(1, "FeatureNewName: Attempt to name undefined house 0x%X, ignoring.", GB(id, 0, 8));
 
							GrfMsg(1, "FeatureNewName: Attempt to name undefined house {:#X}, ignoring.", GB(id, 0, 8));
 
						} else {
 
							_cur.grffile->housespec[GB(id, 0, 8)]->building_name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
 
						}
 
						break;
 

	
 
					default:
 
						grfmsg(7, "FeatureNewName: Unsupported ID (0x%04X)", id);
 
						GrfMsg(7, "FeatureNewName: Unsupported ID ({:#04X})", id);
 
						break;
 
				}
 
				break;
 
@@ -6331,14 +6324,14 @@ static uint16 SanitizeSpriteOffset(uint1
 
{
 

	
 
	if (offset >= max_sprites) {
 
		grfmsg(1, "GraphicsNew: %s sprite offset must be less than %i, skipping", name, max_sprites);
 
		GrfMsg(1, "GraphicsNew: {} sprite offset must be less than {}, skipping", name, max_sprites);
 
		uint orig_num = num;
 
		num = 0;
 
		return orig_num;
 
	}
 

	
 
	if (offset + num > max_sprites) {
 
		grfmsg(4, "GraphicsNew: %s sprite overflow, truncating...", name);
 
		GrfMsg(4, "GraphicsNew: {} sprite overflow, truncating...", name);
 
		uint orig_num = num;
 
		num = std::max(max_sprites - offset, 0);
 
		return orig_num - num;
 
@@ -6410,7 +6403,7 @@ static void GraphicsNew(ByteReader *buf)
 
	if ((type == 0x0D) && (num == 10) && HasBit(_cur.grfconfig->flags, GCF_SYSTEM)) {
 
		/* Special not-TTDP-compatible case used in openttd.grf
 
		 * Missing shore sprites and initialisation of SPR_SHORE_BASE */
 
		grfmsg(2, "GraphicsNew: Loading 10 missing shore sprites from extra grf.");
 
		GrfMsg(2, "GraphicsNew: Loading 10 missing shore sprites from extra grf.");
 
		LoadNextSprite(SPR_SHORE_BASE +  0, *_cur.file, _cur.nfo_line++); // SLOPE_STEEP_S
 
		LoadNextSprite(SPR_SHORE_BASE +  5, *_cur.file, _cur.nfo_line++); // SLOPE_STEEP_W
 
		LoadNextSprite(SPR_SHORE_BASE +  7, *_cur.file, _cur.nfo_line++); // SLOPE_WSE
 
@@ -6427,7 +6420,7 @@ static void GraphicsNew(ByteReader *buf)
 

	
 
	/* Supported type? */
 
	if ((type >= lengthof(_action5_types)) || (_action5_types[type].block_type == A5BLOCK_INVALID)) {
 
		grfmsg(2, "GraphicsNew: Custom graphics (type 0x%02X) sprite block of length %u (unimplemented, ignoring)", type, num);
 
		GrfMsg(2, "GraphicsNew: Custom graphics (type {:#02X}) sprite block of length {} (unimplemented, ignoring)", type, num);
 
		_cur.skip_sprites = num;
 
		return;
 
	}
 
@@ -6438,14 +6431,14 @@ static void GraphicsNew(ByteReader *buf)
 
	 * except for the long version of the shore type:
 
	 * Ignore offset if not allowed */
 
	if ((action5_type->block_type != A5BLOCK_ALLOW_OFFSET) && (offset != 0)) {
 
		grfmsg(1, "GraphicsNew: %s (type 0x%02X) do not allow an <offset> field. Ignoring offset.", action5_type->name, type);
 
		GrfMsg(1, "GraphicsNew: {} (type {:#02X}) do not allow an <offset> field. Ignoring offset.", action5_type->name, type);
 
		offset = 0;
 
	}
 

	
 
	/* Ignore action5 if too few sprites are specified. (for TTDP compatibility)
 
	 * This does not make sense, if <offset> is allowed */
 
	if ((action5_type->block_type == A5BLOCK_FIXED) && (num < action5_type->min_sprites)) {
 
		grfmsg(1, "GraphicsNew: %s (type 0x%02X) count must be at least %d. Only %d were specified. Skipping.", action5_type->name, type, action5_type->min_sprites, num);
 
		GrfMsg(1, "GraphicsNew: {} (type {:#02X}) count must be at least {}. Only {} were specified. Skipping.", action5_type->name, type, action5_type->min_sprites, num);
 
		_cur.skip_sprites = num;
 
		return;
 
	}
 
@@ -6455,7 +6448,7 @@ static void GraphicsNew(ByteReader *buf)
 
	SpriteID replace = action5_type->sprite_base + offset;
 

	
 
	/* Load <num> sprites starting from <replace>, then skip <skip_num> sprites. */
 
	grfmsg(2, "GraphicsNew: Replacing sprites %d to %d of %s (type 0x%02X) at SpriteID 0x%04X", offset, offset + num - 1, action5_type->name, type, replace);
 
	GrfMsg(2, "GraphicsNew: Replacing sprites {} to {} of {} (type {:#02X}) at SpriteID {:#04X}", offset, offset + num - 1, action5_type->name, type, replace);
 

	
 
	if (type == 0x0D) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_5;
 

	
 
@@ -6491,7 +6484,7 @@ static void SkipAct5(ByteReader *buf)
 
	/* Skip the sprites of this action */
 
	_cur.skip_sprites = buf->ReadExtendedByte();
 

	
 
	grfmsg(3, "SkipAct5: Skipping %d sprites", _cur.skip_sprites);
 
	GrfMsg(3, "SkipAct5: Skipping {} sprites", _cur.skip_sprites);
 
}
 

	
 
/**
 
@@ -6675,7 +6668,7 @@ static uint32 GetParamVal(byte param, ui
 
			if (param < 0x80) return _cur.grffile->GetParam(param);
 

	
 
			/* In-game variable. */
 
			grfmsg(1, "Unsupported in-game variable 0x%02X", param);
 
			GrfMsg(1, "Unsupported in-game variable {:#02X}", param);
 
			return UINT_MAX;
 
	}
 
}
 
@@ -6711,7 +6704,7 @@ static void CfgApply(ByteReader *buf)
 
	file.SeekTo(pos, SEEK_SET);
 

	
 
	if (type != 0xFF) {
 
		grfmsg(2, "CfgApply: Ignoring (next sprite is real, unsupported)");
 
		GrfMsg(2, "CfgApply: Ignoring (next sprite is real, unsupported)");
 
		free(preload_sprite);
 
		return;
 
	}
 
@@ -6753,11 +6746,11 @@ static void CfgApply(ByteReader *buf)
 
		/* If the parameter is a GRF parameter (not an internal variable) check
 
		 * if it (and all further sequential parameters) has been defined. */
 
		if (param_num < 0x80 && (param_num + (param_size - 1) / 4) >= _cur.grffile->param_end) {
 
			grfmsg(2, "CfgApply: Ignoring (param %d not set)", (param_num + (param_size - 1) / 4));
 
			GrfMsg(2, "CfgApply: Ignoring (param {} not set)", (param_num + (param_size - 1) / 4));
 
			break;
 
		}
 

	
 
		grfmsg(8, "CfgApply: Applying %u bytes from parameter 0x%02X at offset 0x%04X", param_size, param_num, offset);
 
		GrfMsg(8, "CfgApply: Applying {} bytes from parameter {:#02X} at offset {:#04X}", param_size, param_num, offset);
 

	
 
		bool carry = false;
 
		for (i = 0; i < param_size && offset + i < num; i++) {
 
@@ -6826,11 +6819,11 @@ static void SkipIf(ByteReader *buf)
 
	}
 

	
 
	if (param < 0x80 && _cur.grffile->param_end <= param) {
 
		grfmsg(7, "SkipIf: Param %d undefined, skipping test", param);
 
		GrfMsg(7, "SkipIf: Param {} undefined, skipping test", param);
 
		return;
 
	}
 

	
 
	grfmsg(7, "SkipIf: Test condtype %d, param 0x%02X, condval 0x%08X", condtype, param, cond_val);
 
	GrfMsg(7, "SkipIf: Test condtype {}, param {:#02X}, condval {:#08X}", condtype, param, cond_val);
 

	
 
	/* 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.
 
@@ -6866,7 +6859,7 @@ static void SkipIf(ByteReader *buf)
 
				result = rt != INVALID_ROADTYPE && RoadTypeIsTram(rt);
 
				break;
 
			}
 
			default: grfmsg(1, "SkipIf: Unsupported condition type %02X. Ignoring", condtype); return;
 
			default: GrfMsg(1, "SkipIf: Unsupported condition type {:02X}. Ignoring", condtype); return;
 
		}
 
	} else if (param == 0x88) {
 
		/* GRF ID checks */
 
@@ -6879,7 +6872,7 @@ static void SkipIf(ByteReader *buf)
 
		}
 

	
 
		if (condtype != 10 && c == nullptr) {
 
			grfmsg(7, "SkipIf: GRFID 0x%08X unknown, skipping test", BSWAP32(cond_val));
 
			GrfMsg(7, "SkipIf: GRFID {:#08X} unknown, skipping test", BSWAP32(cond_val));
 
			return;
 
		}
 

	
 
@@ -6906,7 +6899,7 @@ static void SkipIf(ByteReader *buf)
 
				result = c == nullptr || c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND;
 
				break;
 

	
 
			default: grfmsg(1, "SkipIf: Unsupported GRF condition type %02X. Ignoring", condtype); return;
 
			default: GrfMsg(1, "SkipIf: Unsupported GRF condition type {:02X}. Ignoring", condtype); return;
 
		}
 
	} else {
 
		/* Tests that use 'param' and are not GRF ID checks.  */
 
@@ -6924,12 +6917,12 @@ static void SkipIf(ByteReader *buf)
 
				break;
 
			case 0x05: result = (param_val & mask) > cond_val;
 
				break;
 
			default: grfmsg(1, "SkipIf: Unsupported condition type %02X. Ignoring", condtype); return;
 
			default: GrfMsg(1, "SkipIf: Unsupported condition type {:02X}. Ignoring", condtype); return;
 
		}
 
	}
 

	
 
	if (!result) {
 
		grfmsg(2, "SkipIf: Not skipping sprites, test was false");
 
		GrfMsg(2, "SkipIf: Not skipping sprites, test was false");
 
		return;
 
	}
 

	
 
@@ -6953,13 +6946,13 @@ static void SkipIf(ByteReader *buf)
 
	}
 

	
 
	if (choice != nullptr) {
 
		grfmsg(2, "SkipIf: Jumping to label 0x%0X at line %d, test was true", choice->label, choice->nfo_line);
 
		GrfMsg(2, "SkipIf: Jumping to label {:#X} at line {}, test was true", choice->label, choice->nfo_line);
 
		_cur.file->SeekTo(choice->pos, SEEK_SET);
 
		_cur.nfo_line = choice->nfo_line;
 
		return;
 
	}
 

	
 
	grfmsg(2, "SkipIf: Skipping %d sprites, test was true", numsprites);
 
	GrfMsg(2, "SkipIf: Skipping {} sprites, test was true", numsprites);
 
	_cur.skip_sprites = numsprites;
 
	if (_cur.skip_sprites == 0) {
 
		/* Zero means there are no sprites to skip, so
 
@@ -7051,7 +7044,7 @@ static void SpriteReplace(ByteReader *bu
 
		uint8 num_sprites = buf->ReadByte();
 
		uint16 first_sprite = buf->ReadWord();
 

	
 
		grfmsg(2, "SpriteReplace: [Set %d] Changing %d sprites, beginning with %d",
 
		GrfMsg(2, "SpriteReplace: [Set {}] Changing {} sprites, beginning with {}",
 
			i, num_sprites, first_sprite
 
		);
 

	
 
@@ -7081,7 +7074,7 @@ static void SkipActA(ByteReader *buf)
 
		buf->ReadWord();
 
	}
 

	
 
	grfmsg(3, "SkipActA: Skipping %d sprites", _cur.skip_sprites);
 
	GrfMsg(3, "SkipActA: Skipping {} sprites", _cur.skip_sprites);
 
}
 

	
 
/* Action 0x0B */
 
@@ -7129,13 +7122,13 @@ static void GRFLoadError(ByteReader *buf
 
	/* Skip the error until the activation stage unless bit 7 of the severity
 
	 * is set. */
 
	if (!HasBit(severity, 7) && _cur.stage == GLS_INIT) {
 
		grfmsg(7, "GRFLoadError: Skipping non-fatal GRFLoadError in stage %d", _cur.stage);
 
		GrfMsg(7, "GRFLoadError: Skipping non-fatal GRFLoadError in stage {}", _cur.stage);
 
		return;
 
	}
 
	ClrBit(severity, 7);
 

	
 
	if (severity >= lengthof(sevstr)) {
 
		grfmsg(7, "GRFLoadError: Invalid severity id %d. Setting to 2 (non-fatal error).", severity);
 
		GrfMsg(7, "GRFLoadError: Invalid severity id {}. Setting to 2 (non-fatal error).", severity);
 
		severity = 2;
 
	} else if (severity == 3) {
 
		/* This is a fatal error, so make sure the GRF is deactivated and no
 
@@ -7148,12 +7141,12 @@ static void GRFLoadError(ByteReader *buf
 
	}
 

	
 
	if (message_id >= lengthof(msgstr) && message_id != 0xFF) {
 
		grfmsg(7, "GRFLoadError: Invalid message id.");
 
		GrfMsg(7, "GRFLoadError: Invalid message id.");
 
		return;
 
	}
 

	
 
	if (buf->Remaining() <= 1) {
 
		grfmsg(7, "GRFLoadError: No message data supplied.");
 
		GrfMsg(7, "GRFLoadError: No message data supplied.");
 
		return;
 
	}
 

	
 
@@ -7169,7 +7162,7 @@ static void GRFLoadError(ByteReader *buf
 

	
 
			error->custom_message = TranslateTTDPatchCodes(_cur.grffile->grfid, lang, true, message, SCC_RAW_STRING_POINTER);
 
		} else {
 
			grfmsg(7, "GRFLoadError: No custom message supplied.");
 
			GrfMsg(7, "GRFLoadError: No custom message supplied.");
 
			error->custom_message.clear();
 
		}
 
	} else {
 
@@ -7181,7 +7174,7 @@ static void GRFLoadError(ByteReader *buf
 

	
 
		error->data = TranslateTTDPatchCodes(_cur.grffile->grfid, lang, true, data);
 
	} else {
 
		grfmsg(7, "GRFLoadError: No message data supplied.");
 
		GrfMsg(7, "GRFLoadError: No message data supplied.");
 
		error->data.clear();
 
	}
 

	
 
@@ -7204,7 +7197,7 @@ static void GRFComment(ByteReader *buf)
 
	if (!buf->HasData()) return;
 

	
 
	const char *text = buf->ReadString();
 
	grfmsg(2, "GRFComment: %s", text);
 
	GrfMsg(2, "GRFComment: {}", text);
 
}
 

	
 
/* Action 0x0D (GLS_SAFETYSCAN) */
 
@@ -7299,7 +7292,7 @@ static uint32 GetPatchVariable(uint8 par
 
			return _settings_game.game_creation.generation_seed;
 

	
 
		default:
 
			grfmsg(2, "ParamSet: Unknown Patch variable 0x%02X.", param);
 
			GrfMsg(2, "ParamSet: Unknown Patch variable {:#02X}.", param);
 
			return 0;
 
	}
 
}
 
@@ -7333,7 +7326,7 @@ static uint32 PerformGRM(uint32 *grm, ui
 
	if (size == count) {
 
		/* Got the slot... */
 
		if (op == 0 || op == 3) {
 
			grfmsg(2, "ParamSet: GRM: Reserving %d %s at %d", count, type, start);
 
			GrfMsg(2, "ParamSet: GRM: Reserving {} {} at {}", count, type, start);
 
			for (uint i = 0; i < count; i++) grm[start + i] = _cur.grffile->grfid;
 
		}
 
		return start;
 
@@ -7342,12 +7335,12 @@ static uint32 PerformGRM(uint32 *grm, ui
 
	/* Unable to allocate */
 
	if (op != 4 && op != 5) {
 
		/* Deactivate GRF */
 
		grfmsg(0, "ParamSet: GRM: Unable to allocate %d %s, deactivating", count, type);
 
		GrfMsg(0, "ParamSet: GRM: Unable to allocate {} {}, deactivating", count, type);
 
		DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED);
 
		return UINT_MAX;
 
	}
 

	
 
	grfmsg(1, "ParamSet: GRM: Unable to allocate %d %s", count, type);
 
	GrfMsg(1, "ParamSet: GRM: Unable to allocate {} {}", count, type);
 
	return UINT_MAX;
 
}
 

	
 
@@ -7393,7 +7386,7 @@ static void ParamSet(ByteReader *buf)
 
	 *   an earlier action D */
 
	if (HasBit(oper, 7)) {
 
		if (target < 0x80 && target < _cur.grffile->param_end) {
 
			grfmsg(7, "ParamSet: Param %u already defined, skipping", target);
 
			GrfMsg(7, "ParamSet: Param {} already defined, skipping", target);
 
			return;
 
		}
 

	
 
@@ -7417,13 +7410,13 @@ static void ParamSet(ByteReader *buf)
 
						if (op == 0) {
 
							/* Check if the allocated sprites will fit below the original sprite limit */
 
							if (_cur.spriteid + count >= 16384) {
 
								grfmsg(0, "ParamSet: GRM: Unable to allocate %d sprites; try changing NewGRF order", count);
 
								GrfMsg(0, "ParamSet: GRM: Unable to allocate {} sprites; try changing NewGRF order", count);
 
								DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED);
 
								return;
 
							}
 

	
 
							/* Reserve space at the current sprite ID */
 
							grfmsg(4, "ParamSet: GRM: Allocated %d sprites at %d", count, _cur.spriteid);
 
							GrfMsg(4, "ParamSet: GRM: Allocated {} sprites at {}", count, _cur.spriteid);
 
							_grm_sprites[GRFLocation(_cur.grffile->grfid, _cur.nfo_line)] = _cur.spriteid;
 
							_cur.spriteid += count;
 
						}
 
@@ -7459,7 +7452,7 @@ static void ParamSet(ByteReader *buf)
 
								case 0:
 
									/* Return space reserved during reservation stage */
 
									src1 = _grm_sprites[GRFLocation(_cur.grffile->grfid, _cur.nfo_line)];
 
									grfmsg(4, "ParamSet: GRM: Using pre-allocated sprites at %d", src1);
 
									GrfMsg(4, "ParamSet: GRM: Using pre-allocated sprites at {}", src1);
 
									break;
 

	
 
								case 1:
 
@@ -7467,7 +7460,7 @@ static void ParamSet(ByteReader *buf)
 
									break;
 

	
 
								default:
 
									grfmsg(1, "ParamSet: GRM: Unsupported operation %d for general sprites", op);
 
									GrfMsg(1, "ParamSet: GRM: Unsupported operation {} for general sprites", op);
 
									return;
 
							}
 
							break;
 
@@ -7478,7 +7471,7 @@ static void ParamSet(ByteReader *buf)
 
							if (_cur.skip_sprites == -1) return;
 
							break;
 

	
 
						default: grfmsg(1, "ParamSet: GRM: Unsupported feature 0x%X", feature); return;
 
						default: GrfMsg(1, "ParamSet: GRM: Unsupported feature {:#X}", feature); return;
 
					}
 
				} else {
 
					/* Ignore GRM during initialization */
 
@@ -7589,7 +7582,7 @@ static void ParamSet(ByteReader *buf)
 
			}
 
			break;
 

	
 
		default: grfmsg(0, "ParamSet: Unknown operation %d, skipping", oper); return;
 
		default: GrfMsg(0, "ParamSet: Unknown operation {}, skipping", oper); return;
 
	}
 

	
 
	switch (target) {
 
@@ -7618,7 +7611,7 @@ static void ParamSet(ByteReader *buf)
 
		case 0x96: // Tile refresh offset downwards
 
		case 0x97: // Snow line height -- Better supported by feature 8 property 10h (snow line table) TODO: implement by filling the entire snow line table with the given value
 
		case 0x99: // Global ID offset -- Not necessary since IDs are remapped automatically
 
			grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
 
			GrfMsg(7, "ParamSet: Skipping unimplemented target {:#02X}", target);
 
			break;
 

	
 
		case 0x9E: // Miscellaneous GRF features
 
@@ -7639,7 +7632,7 @@ static void ParamSet(ByteReader *buf)
 
			break;
 

	
 
		case 0x9F: // locale-dependent settings
 
			grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
 
			GrfMsg(7, "ParamSet: Skipping unimplemented target {:#02X}", target);
 
			break;
 

	
 
		default:
 
@@ -7648,7 +7641,7 @@ static void ParamSet(ByteReader *buf)
 
				/* param is zeroed by default */
 
				if (target + 1U > _cur.grffile->param_end) _cur.grffile->param_end = target + 1;
 
			} else {
 
				grfmsg(7, "ParamSet: Skipping unknown target 0x%02X", target);
 
				GrfMsg(7, "ParamSet: Skipping unknown target {:#02X}", target);
 
			}
 
			break;
 
	}
 
@@ -7695,7 +7688,7 @@ static void GRFInhibit(ByteReader *buf)
 

	
 
		/* Unset activation flag */
 
		if (file != nullptr && file != _cur.grfconfig) {
 
			grfmsg(2, "GRFInhibit: Deactivating file '%s'", file->filename);
 
			GrfMsg(2, "GRFInhibit: Deactivating file '{}'", file->filename);
 
			GRFError *error = DisableGrf(STR_NEWGRF_ERROR_FORCEFULLY_DISABLED, file);
 
			error->data = _cur.grfconfig->GetName();
 
		}
 
@@ -7717,7 +7710,7 @@ static void FeatureTownName(ByteReader *
 
	GRFTownName *townname = AddGRFTownName(grfid);
 

	
 
	byte id = buf->ReadByte();
 
	grfmsg(6, "FeatureTownName: definition 0x%02X", id & 0x7F);
 
	GrfMsg(6, "FeatureTownName: definition {:#02X}", id & 0x7F);
 

	
 
	if (HasBit(id, 7)) {
 
		/* Final definition */
 
@@ -7733,7 +7726,7 @@ static void FeatureTownName(ByteReader *
 
			const char *name = buf->ReadString();
 

	
 
			std::string lang_name = TranslateTTDPatchCodes(grfid, lang, false, name);
 
			grfmsg(6, "FeatureTownName: lang 0x%X -> '%s'", lang, lang_name.c_str());
 
			GrfMsg(6, "FeatureTownName: lang {:#X} -> '{}'", lang, lang_name.c_str());
 

	
 
			style = AddGRFString(grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
 

	
 
@@ -7743,7 +7736,7 @@ static void FeatureTownName(ByteReader *
 
	}
 

	
 
	uint8 parts = buf->ReadByte();
 
	grfmsg(6, "FeatureTownName: %u parts", parts);
 
	GrfMsg(6, "FeatureTownName: {} parts", parts);
 

	
 
	townname->partlists[id].reserve(parts);
 
	for (uint partnum = 0; partnum < parts; partnum++) {
 
@@ -7752,7 +7745,7 @@ static void FeatureTownName(ByteReader *
 
		partlist.bitstart = buf->ReadByte();
 
		partlist.bitcount = buf->ReadByte();
 
		partlist.maxprob  = 0;
 
		grfmsg(6, "FeatureTownName: part %u contains %u texts and will use GB(seed, %u, %u)", partnum, texts, partlist.bitstart, partlist.bitcount);
 
		GrfMsg(6, "FeatureTownName: part {} contains {} texts and will use GB(seed, {}, {})", partnum, texts, partlist.bitstart, partlist.bitcount);
 

	
 
		partlist.parts.reserve(texts);
 
		for (uint textnum = 0; textnum < texts; textnum++) {
 
@@ -7762,21 +7755,21 @@ static void FeatureTownName(ByteReader *
 
			if (HasBit(part.prob, 7)) {
 
				byte ref_id = buf->ReadByte();
 
				if (ref_id >= GRFTownName::MAX_LISTS || townname->partlists[ref_id].empty()) {
 
					grfmsg(0, "FeatureTownName: definition 0x%02X doesn't exist, deactivating", ref_id);
 
					GrfMsg(0, "FeatureTownName: definition {:#02X} doesn't exist, deactivating", ref_id);
 
					DelGRFTownName(grfid);
 
					DisableGrf(STR_NEWGRF_ERROR_INVALID_ID);
 
					return;
 
				}
 
				part.id = ref_id;
 
				grfmsg(6, "FeatureTownName: part %u, text %u, uses intermediate definition 0x%02X (with probability %u)", partnum, textnum, ref_id, part.prob & 0x7F);
 
				GrfMsg(6, "FeatureTownName: part {}, text {}, uses intermediate definition {:#02X} (with probability {})", partnum, textnum, ref_id, part.prob & 0x7F);
 
			} else {
 
				const char *text = buf->ReadString();
 
				part.text = TranslateTTDPatchCodes(grfid, 0, false, text);
 
				grfmsg(6, "FeatureTownName: part %u, text %u, '%s' (with probability %u)", partnum, textnum, part.text.c_str(), part.prob);
 
				GrfMsg(6, "FeatureTownName: part {}, text {}, '{}' (with probability {})", partnum, textnum, part.text.c_str(), part.prob);
 
			}
 
			partlist.maxprob += GB(part.prob, 0, 7);
 
		}
 
		grfmsg(6, "FeatureTownName: part %u, total probability %u", partnum, partlist.maxprob);
 
		GrfMsg(6, "FeatureTownName: part {}, total probability {}", partnum, partlist.maxprob);
 
	}
 
}
 

	
 
@@ -7792,7 +7785,7 @@ static void DefineGotoLabel(ByteReader *
 

	
 
	_cur.grffile->labels.emplace_back(nfo_label, _cur.nfo_line, _cur.file->GetPos());
 

	
 
	grfmsg(2, "DefineGotoLabel: GOTO target with label 0x%02X", nfo_label);
 
	GrfMsg(2, "DefineGotoLabel: GOTO target with label {:#02X}", nfo_label);
 
}
 

	
 
/**
 
@@ -7807,16 +7800,16 @@ static void ImportGRFSound(SoundEntry *s
 

	
 
	file = GetFileByGRFID(grfid);
 
	if (file == nullptr || file->sound_offset == 0) {
 
		grfmsg(1, "ImportGRFSound: Source file not available");
 
		GrfMsg(1, "ImportGRFSound: Source file not available");
 
		return;
 
	}
 

	
 
	if (sound_id >= file->num_sounds) {
 
		grfmsg(1, "ImportGRFSound: Sound effect %d is invalid", sound_id);
 
		GrfMsg(1, "ImportGRFSound: Sound effect {} is invalid", sound_id);
 
		return;
 
	}
 

	
 
	grfmsg(2, "ImportGRFSound: Copying sound %d (%d) from file %X", sound_id, file->sound_offset + sound_id, grfid);
 
	GrfMsg(2, "ImportGRFSound: Copying sound {} ({}) from file {:x}", sound_id, file->sound_offset + sound_id, grfid);
 

	
 
	*sound = *GetSound(file->sound_offset + sound_id);
 

	
 
@@ -7880,10 +7873,10 @@ static void GRFSound(ByteReader *buf)
 
		if (grf_container_version >= 2 && type == 0xFD) {
 
			/* Reference to sprite section. */
 
			if (invalid) {
 
				grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
 
				GrfMsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
 
				file.SkipBytes(len);
 
			} else if (len != 4) {
 
				grfmsg(1, "GRFSound: Invalid sprite section import");
 
				GrfMsg(1, "GRFSound: Invalid sprite section import");
 
				file.SkipBytes(len);
 
			} else {
 
				uint32 id = file.ReadDword();
 
@@ -7893,14 +7886,14 @@ static void GRFSound(ByteReader *buf)
 
		}
 

	
 
		if (type != 0xFF) {
 
			grfmsg(1, "GRFSound: Unexpected RealSprite found, skipping");
 
			GrfMsg(1, "GRFSound: Unexpected RealSprite found, skipping");
 
			file.SkipBytes(7);
 
			SkipSpriteData(*_cur.file, type, len - 8);
 
			continue;
 
		}
 

	
 
		if (invalid) {
 
			grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
 
			GrfMsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
 
			file.SkipBytes(len);
 
		}
 

	
 
@@ -7910,7 +7903,7 @@ static void GRFSound(ByteReader *buf)
 
				/* Allocate sound only in init stage. */
 
				if (_cur.stage == GLS_INIT) {
 
					if (grf_container_version >= 2) {
 
						grfmsg(1, "GRFSound: Inline sounds are not supported for container version >= 2");
 
						GrfMsg(1, "GRFSound: Inline sounds are not supported for container version >= 2");
 
					} else {
 
						LoadGRFSound(offs, sound + i);
 
					}
 
@@ -7922,7 +7915,7 @@ static void GRFSound(ByteReader *buf)
 
				if (_cur.stage == GLS_ACTIVATION) {
 
					/* XXX 'Action 0xFE' isn't really specified. It is only mentioned for
 
					 * importing sounds, so this is probably all wrong... */
 
					if (file.ReadByte() != 0) grfmsg(1, "GRFSound: Import type mismatch");
 
					if (file.ReadByte() != 0) GrfMsg(1, "GRFSound: Import type mismatch");
 
					ImportGRFSound(sound + i);
 
				} else {
 
					file.SkipBytes(len - 1); // already read <action>
 
@@ -7930,7 +7923,7 @@ static void GRFSound(ByteReader *buf)
 
				break;
 

	
 
			default:
 
				grfmsg(1, "GRFSound: Unexpected Action %x found, skipping", action);
 
				GrfMsg(1, "GRFSound: Unexpected Action {:x} found, skipping", action);
 
				file.SkipBytes(len - 1); // already read <action>
 
				break;
 
		}
 
@@ -7946,7 +7939,7 @@ static void SkipAct11(ByteReader *buf)
 

	
 
	_cur.skip_sprites = buf->ReadWord();
 

	
 
	grfmsg(3, "SkipAct11: Skipping %d sprites", _cur.skip_sprites);
 
	GrfMsg(3, "SkipAct11: Skipping {} sprites", _cur.skip_sprites);
 
}
 

	
 
/** Action 0x12 */
 
@@ -7967,10 +7960,10 @@ static void LoadFontGlyph(ByteReader *bu
 
		uint16 base_char = buf->ReadWord();
 

	
 
		if (size >= FS_END) {
 
			grfmsg(1, "LoadFontGlyph: Size %u is not supported, ignoring", size);
 
		}
 

	
 
		grfmsg(7, "LoadFontGlyph: Loading %u glyph(s) at 0x%04X for size %u", num_char, base_char, size);
 
			GrfMsg(1, "LoadFontGlyph: Size {} is not supported, ignoring", size);
 
		}
 

	
 
		GrfMsg(7, "LoadFontGlyph: Loading {} glyph(s) at {:#04X} for size {}", num_char, base_char, size);
 

	
 
		for (uint c = 0; c < num_char; c++) {
 
			if (size < FS_END) SetUnicodeGlyph(size, base_char + c, _cur.spriteid);
 
@@ -8003,7 +7996,7 @@ static void SkipAct12(ByteReader *buf)
 
		buf->ReadWord();
 
	}
 

	
 
	grfmsg(3, "SkipAct12: Skipping %d sprites", _cur.skip_sprites);
 
	GrfMsg(3, "SkipAct12: Skipping {} sprites", _cur.skip_sprites);
 
}
 

	
 
/** Action 0x13 */
 
@@ -8019,7 +8012,7 @@ static void TranslateGRFStrings(ByteRead
 
	uint32 grfid = buf->ReadDWord();
 
	const GRFConfig *c = GetGRFConfig(grfid);
 
	if (c == nullptr || (c->status != GCS_INITIALISED && c->status != GCS_ACTIVATED)) {
 
		grfmsg(7, "TranslateGRFStrings: GRFID 0x%08x unknown, skipping action 13", BSWAP32(grfid));
 
		GrfMsg(7, "TranslateGRFStrings: GRFID {:#08X} unknown, skipping action 13", BSWAP32(grfid));
 
		return;
 
	}
 

	
 
@@ -8043,7 +8036,7 @@ static void TranslateGRFStrings(ByteRead
 
	uint16 first_id  = buf->ReadWord();
 

	
 
	if (!((first_id >= 0xD000 && first_id + num_strings <= 0xD400) || (first_id >= 0xD800 && first_id + num_strings <= 0xE000))) {
 
		grfmsg(7, "TranslateGRFStrings: Attempting to set out-of-range string IDs in action 13 (first: 0x%4X, number: 0x%2X)", first_id, num_strings);
 
		GrfMsg(7, "TranslateGRFStrings: Attempting to set out-of-range string IDs in action 13 (first: {:#04X}, number: {:#02X})", first_id, num_strings);
 
		return;
 
	}
 

	
 
@@ -8051,7 +8044,7 @@ static void TranslateGRFStrings(ByteRead
 
		const char *string = buf->ReadString();
 

	
 
		if (StrEmpty(string)) {
 
			grfmsg(7, "TranslateGRFString: Ignoring empty string.");
 
			GrfMsg(7, "TranslateGRFString: Ignoring empty string.");
 
			continue;
 
		}
 

	
 
@@ -8084,7 +8077,7 @@ static bool ChangeGRFURL(byte langid, co
 
static bool ChangeGRFNumUsedParams(size_t len, ByteReader *buf)
 
{
 
	if (len != 1) {
 
		grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'NPAR' but got " PRINTF_SIZE ", ignoring this field", len);
 
		GrfMsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'NPAR' but got {}, ignoring this field", len);
 
		buf->Skip(len);
 
	} else {
 
		_cur.grfconfig->num_valid_params = std::min<byte>(buf->ReadByte(), lengthof(_cur.grfconfig->param));
 
@@ -8096,7 +8089,7 @@ static bool ChangeGRFNumUsedParams(size_
 
static bool ChangeGRFPalette(size_t len, ByteReader *buf)
 
{
 
	if (len != 1) {
 
		grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'PALS' but got " PRINTF_SIZE ", ignoring this field", len);
 
		GrfMsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'PALS' but got {}, ignoring this field", len);
 
		buf->Skip(len);
 
	} else {
 
		char data = buf->ReadByte();
 
@@ -8107,7 +8100,7 @@ static bool ChangeGRFPalette(size_t len,
 
			case 'W': pal = GRFP_GRF_WINDOWS; break;
 
			case 'D': pal = GRFP_GRF_DOS;     break;
 
			default:
 
				grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'PALS', ignoring this field", data);
 
				GrfMsg(2, "StaticGRFInfo: unexpected value '{:02X}' for 'INFO'->'PALS', ignoring this field", data);
 
				break;
 
		}
 
		if (pal != GRFP_GRF_UNSET) {
 
@@ -8122,7 +8115,7 @@ static bool ChangeGRFPalette(size_t len,
 
static bool ChangeGRFBlitter(size_t len, ByteReader *buf)
 
{
 
	if (len != 1) {
 
		grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'BLTR' but got " PRINTF_SIZE ", ignoring this field", len);
 
		GrfMsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'BLTR' but got {}, ignoring this field", len);
 
		buf->Skip(len);
 
	} else {
 
		char data = buf->ReadByte();
 
@@ -8131,7 +8124,7 @@ static bool ChangeGRFBlitter(size_t len,
 
			case '8': pal = GRFP_BLT_UNSET; break;
 
			case '3': pal = GRFP_BLT_32BPP;  break;
 
			default:
 
				grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'BLTR', ignoring this field", data);
 
				GrfMsg(2, "StaticGRFInfo: unexpected value '{:02X}' for 'INFO'->'BLTR', ignoring this field", data);
 
				return true;
 
		}
 
		_cur.grfconfig->palette &= ~GRFP_BLT_MASK;
 
@@ -8144,7 +8137,7 @@ static bool ChangeGRFBlitter(size_t len,
 
static bool ChangeGRFVersion(size_t len, ByteReader *buf)
 
{
 
	if (len != 4) {
 
		grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'VRSN' but got " PRINTF_SIZE ", ignoring this field", len);
 
		GrfMsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'VRSN' but got {}, ignoring this field", len);
 
		buf->Skip(len);
 
	} else {
 
		/* Set min_loadable_version as well (default to minimal compatibility) */
 
@@ -8157,16 +8150,16 @@ static bool ChangeGRFVersion(size_t len,
 
static bool ChangeGRFMinVersion(size_t len, ByteReader *buf)
 
{
 
	if (len != 4) {
 
		grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'MINV' but got " PRINTF_SIZE ", ignoring this field", len);
 
		GrfMsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'MINV' but got {}, ignoring this field", len);
 
		buf->Skip(len);
 
	} else {
 
		_cur.grfconfig->min_loadable_version = buf->ReadDWord();
 
		if (_cur.grfconfig->version == 0) {
 
			grfmsg(2, "StaticGRFInfo: 'MINV' defined before 'VRSN' or 'VRSN' set to 0, ignoring this field");
 
			GrfMsg(2, "StaticGRFInfo: 'MINV' defined before 'VRSN' or 'VRSN' set to 0, ignoring this field");
 
			_cur.grfconfig->min_loadable_version = 0;
 
		}
 
		if (_cur.grfconfig->version < _cur.grfconfig->min_loadable_version) {
 
			grfmsg(2, "StaticGRFInfo: 'MINV' defined as %d, limiting it to 'VRSN'", _cur.grfconfig->min_loadable_version);
 
			GrfMsg(2, "StaticGRFInfo: 'MINV' defined as {}, limiting it to 'VRSN'", _cur.grfconfig->min_loadable_version);
 
			_cur.grfconfig->min_loadable_version = _cur.grfconfig->version;
 
		}
 
	}
 
@@ -8193,14 +8186,14 @@ static bool ChangeGRFParamDescription(by
 
static bool ChangeGRFParamType(size_t len, ByteReader *buf)
 
{
 
	if (len != 1) {
 
		grfmsg(2, "StaticGRFInfo: expected 1 byte for 'INFO'->'PARA'->'TYPE' but got " PRINTF_SIZE ", ignoring this field", len);
 
		GrfMsg(2, "StaticGRFInfo: expected 1 byte for 'INFO'->'PARA'->'TYPE' but got {}, ignoring this field", len);
 
		buf->Skip(len);
 
	} else {
 
		GRFParameterType type = (GRFParameterType)buf->ReadByte();
 
		if (type < PTYPE_END) {
 
			_cur_parameter->type = type;
 
		} else {
 
			grfmsg(3, "StaticGRFInfo: unknown parameter type %d, ignoring this field", type);
 
			GrfMsg(3, "StaticGRFInfo: unknown parameter type {}, ignoring this field", type);
 
		}
 
	}
 
	return true;
 
@@ -8210,10 +8203,10 @@ static bool ChangeGRFParamType(size_t le
 
static bool ChangeGRFParamLimits(size_t len, ByteReader *buf)
 
{
 
	if (_cur_parameter->type != PTYPE_UINT_ENUM) {
 
		grfmsg(2, "StaticGRFInfo: 'INFO'->'PARA'->'LIMI' is only valid for parameters with type uint/enum, ignoring this field");
 
		GrfMsg(2, "StaticGRFInfo: 'INFO'->'PARA'->'LIMI' is only valid for parameters with type uint/enum, ignoring this field");
 
		buf->Skip(len);
 
	} else if (len != 8) {
 
		grfmsg(2, "StaticGRFInfo: expected 8 bytes for 'INFO'->'PARA'->'LIMI' but got " PRINTF_SIZE ", ignoring this field", len);
 
		GrfMsg(2, "StaticGRFInfo: expected 8 bytes for 'INFO'->'PARA'->'LIMI' but got {}, ignoring this field", len);
 
		buf->Skip(len);
 
	} else {
 
		uint32 min_value = buf->ReadDWord();
 
@@ -8222,7 +8215,7 @@ static bool ChangeGRFParamLimits(size_t 
 
			_cur_parameter->min_value = min_value;
 
			_cur_parameter->max_value = max_value;
 
		} else {
 
			grfmsg(2, "StaticGRFInfo: 'INFO'->'PARA'->'LIMI' values are incoherent, ignoring this field");
 
			GrfMsg(2, "StaticGRFInfo: 'INFO'->'PARA'->'LIMI' values are incoherent, ignoring this field");
 
		}
 
	}
 
	return true;
 
@@ -8232,12 +8225,12 @@ static bool ChangeGRFParamLimits(size_t 
 
static bool ChangeGRFParamMask(size_t len, ByteReader *buf)
 
{
 
	if (len < 1 || len > 3) {
 
		grfmsg(2, "StaticGRFInfo: expected 1 to 3 bytes for 'INFO'->'PARA'->'MASK' but got " PRINTF_SIZE ", ignoring this field", len);
 
		GrfMsg(2, "StaticGRFInfo: expected 1 to 3 bytes for 'INFO'->'PARA'->'MASK' but got {}, ignoring this field", len);
 
		buf->Skip(len);
 
	} else {
 
		byte param_nr = buf->ReadByte();
 
		if (param_nr >= lengthof(_cur.grfconfig->param)) {
 
			grfmsg(2, "StaticGRFInfo: invalid parameter number in 'INFO'->'PARA'->'MASK', param %d, ignoring this field", param_nr);
 
			GrfMsg(2, "StaticGRFInfo: invalid parameter number in 'INFO'->'PARA'->'MASK', param {}, ignoring this field", param_nr);
 
			buf->Skip(len - 1);
 
		} else {
 
			_cur_parameter->param_nr = param_nr;
 
@@ -8253,7 +8246,7 @@ static bool ChangeGRFParamMask(size_t le
 
static bool ChangeGRFParamDefault(size_t len, ByteReader *buf)
 
{
 
	if (len != 4) {
 
		grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'PARA'->'DEFA' but got " PRINTF_SIZE ", ignoring this field", len);
 
		GrfMsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'PARA'->'DEFA' but got {}, ignoring this field", len);
 
		buf->Skip(len);
 
	} else {
 
		_cur_parameter->def_value = buf->ReadDWord();
 
@@ -8360,7 +8353,7 @@ static bool ChangeGRFParamValueNames(Byt
 
	while (type != 0) {
 
		uint32 id = buf->ReadDWord();
 
		if (type != 'T' || id > _cur_parameter->max_value) {
 
			grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA'->param_num->'VALU' should have type 't' and the value/bit number as id");
 
			GrfMsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA'->param_num->'VALU' should have type 't' and the value/bit number as id");
 
			if (!SkipUnknownInfo(buf, type)) return false;
 
			type = buf->ReadByte();
 
			continue;
 
@@ -8407,7 +8400,7 @@ static bool HandleParameterInfo(ByteRead
 
	while (type != 0) {
 
		uint32 id = buf->ReadDWord();
 
		if (type != 'C' || id >= _cur.grfconfig->num_valid_params) {
 
			grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA' should have type 'C' and their parameter number as id");
 
			GrfMsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA' should have type 'C' and their parameter number as id");
 
			if (!SkipUnknownInfo(buf, type)) return false;
 
			type = buf->ReadByte();
 
			continue;
 
@@ -8522,7 +8515,7 @@ static bool HandleNode(byte type, uint32
 
			}
 
		}
 
	}
 
	grfmsg(2, "StaticGRFInfo: unknown type/id combination found, type=%c, id=%x", type, id);
 
	GrfMsg(2, "StaticGRFInfo: unknown type/id combination found, type={:c}, id={:x}", type, id);
 
	return SkipUnknownInfo(buf, type);
 
}
 

	
 
@@ -9494,7 +9487,7 @@ static void DecodeSpecialSprite(byte *bu
 
	} else {
 
		/* Use the preloaded sprite data. */
 
		buf = _grf_line_to_action6_sprite_override[location];
 
		grfmsg(7, "DecodeSpecialSprite: Using preloaded pseudo sprite data");
 
		GrfMsg(7, "DecodeSpecialSprite: Using preloaded pseudo sprite data");
 

	
 
		/* Skip the real (original) content of this action. */
 
		_cur.file->SeekTo(num, SEEK_CUR);
 
@@ -9507,19 +9500,19 @@ static void DecodeSpecialSprite(byte *bu
 
		byte action = bufp->ReadByte();
 

	
 
		if (action == 0xFF) {
 
			grfmsg(2, "DecodeSpecialSprite: Unexpected data block, skipping");
 
			GrfMsg(2, "DecodeSpecialSprite: Unexpected data block, skipping");
 
		} else if (action == 0xFE) {
 
			grfmsg(2, "DecodeSpecialSprite: Unexpected import block, skipping");
 
			GrfMsg(2, "DecodeSpecialSprite: Unexpected import block, skipping");
 
		} else if (action >= lengthof(handlers)) {
 
			grfmsg(7, "DecodeSpecialSprite: Skipping unknown action 0x%02X", action);
 
			GrfMsg(7, "DecodeSpecialSprite: Skipping unknown action {:#02X}", action);
 
		} else if (handlers[action][stage] == nullptr) {
 
			grfmsg(7, "DecodeSpecialSprite: Skipping action 0x%02X in stage %d", action, stage);
 
			GrfMsg(7, "DecodeSpecialSprite: Skipping action {:#02X} in stage {}", action, stage);
 
		} else {
 
			grfmsg(7, "DecodeSpecialSprite: Handling action 0x%02X in stage %d", action, stage);
 
			GrfMsg(7, "DecodeSpecialSprite: Handling action {:#02X} in stage {}", action, stage);
 
			handlers[action][stage](bufp);
 
		}
 
	} catch (...) {
 
		grfmsg(1, "DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
 
		GrfMsg(1, "DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
 
		DisableGrf(STR_NEWGRF_ERROR_READ_BOUNDS);
 
	}
 
}
 
@@ -9593,7 +9586,7 @@ static void LoadNewGRFFileFromFile(GRFCo
 
			}
 
		} else {
 
			if (_cur.skip_sprites == 0) {
 
				grfmsg(0, "LoadNewGRFFile: Unexpected sprite, disabling");
 
				GrfMsg(0, "LoadNewGRFFile: Unexpected sprite, disabling");
 
				DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE);
 
				break;
 
			}
src/newgrf.h
Show inline comments
 
@@ -201,7 +201,8 @@ void ReloadNewGRFData(); // in saveload/
 
void ResetNewGRFData();
 
void ResetPersistentNewGRFData();
 

	
 
void CDECL grfmsg(int severity, const char *str, ...) WARN_FORMAT(2, 3);
 
void GrfMsgI(int severity, const std::string &msg);
 
#define GrfMsg(severity, format_string, ...) GrfMsgI(severity, fmt::format(FMT_STRING(format_string), ## __VA_ARGS__))
 

	
 
bool GetGlobalVariable(byte param, uint32 *value, const GRFFile *grffile);
 

	
src/newgrf_airport.cpp
Show inline comments
 
@@ -176,7 +176,7 @@ void AirportOverrideManager::SetEntitySp
 
	byte airport_id = this->AddEntityID(as->grf_prop.local_id, as->grf_prop.grffile->grfid, as->grf_prop.subst_id);
 

	
 
	if (airport_id == this->invalid_id) {
 
		grfmsg(1, "Airport.SetEntitySpec: Too many airports allocated. Ignoring.");
 
		GrfMsg(1, "Airport.SetEntitySpec: Too many airports allocated. Ignoring.");
 
		return;
 
	}
 

	
src/newgrf_airporttiles.cpp
Show inline comments
 
@@ -69,7 +69,7 @@ void AirportTileOverrideManager::SetEnti
 
	StationGfx airpt_id = this->AddEntityID(airpts->grf_prop.local_id, airpts->grf_prop.grffile->grfid, airpts->grf_prop.subst_id);
 

	
 
	if (airpt_id == this->invalid_id) {
 
		grfmsg(1, "AirportTile.SetEntitySpec: Too many airport tiles allocated. Ignoring.");
 
		GrfMsg(1, "AirportTile.SetEntitySpec: Too many airport tiles allocated. Ignoring.");
 
		return;
 
	}
 

	
src/newgrf_class_func.h
Show inline comments
 
@@ -63,7 +63,7 @@ DEFINE_NEWGRF_CLASS_METHOD(Tid)::Allocat
 
		}
 
	}
 

	
 
	grfmsg(2, "ClassAllocate: already allocated %d classes, using default", Tmax);
 
	GrfMsg(2, "ClassAllocate: already allocated {} classes, using default", Tmax);
 
	return (Tid)0;
 
}
 

	
src/newgrf_commons.cpp
Show inline comments
 
@@ -160,7 +160,7 @@ void HouseOverrideManager::SetEntitySpec
 
	HouseID house_id = this->AddEntityID(hs->grf_prop.local_id, hs->grf_prop.grffile->grfid, hs->grf_prop.subst_id);
 

	
 
	if (house_id == this->invalid_id) {
 
		grfmsg(1, "House.SetEntitySpec: Too many houses allocated. Ignoring.");
 
		GrfMsg(1, "House.SetEntitySpec: Too many houses allocated. Ignoring.");
 
		return;
 
	}
 

	
 
@@ -254,7 +254,7 @@ void IndustryOverrideManager::SetEntityS
 
	}
 

	
 
	if (ind_id == this->invalid_id) {
 
		grfmsg(1, "Industry.SetEntitySpec: Too many industries allocated. Ignoring.");
 
		GrfMsg(1, "Industry.SetEntitySpec: Too many industries allocated. Ignoring.");
 
		return;
 
	}
 

	
 
@@ -269,7 +269,7 @@ void IndustryTileOverrideManager::SetEnt
 
	IndustryGfx indt_id = this->AddEntityID(its->grf_prop.local_id, its->grf_prop.grffile->grfid, its->grf_prop.subst_id);
 

	
 
	if (indt_id == this->invalid_id) {
 
		grfmsg(1, "IndustryTile.SetEntitySpec: Too many industry tiles allocated. Ignoring.");
 
		GrfMsg(1, "IndustryTile.SetEntitySpec: Too many industry tiles allocated. Ignoring.");
 
		return;
 
	}
 

	
 
@@ -308,7 +308,7 @@ void ObjectOverrideManager::SetEntitySpe
 
	}
 

	
 
	if (type == this->invalid_id) {
 
		grfmsg(1, "Object.SetEntitySpec: Too many objects allocated. Ignoring.");
 
		GrfMsg(1, "Object.SetEntitySpec: Too many objects allocated. Ignoring.");
 
		return;
 
	}
 

	
src/newgrf_engine.cpp
Show inline comments
 
@@ -55,7 +55,7 @@ void SetCustomEngineSprites(EngineID eng
 
	assert(cargo < lengthof(e->grf_prop.spritegroup));
 

	
 
	if (e->grf_prop.spritegroup[cargo] != nullptr) {
 
		grfmsg(6, "SetCustomEngineSprites: engine %d cargo %d already has group -- replacing", engine, cargo);
 
		GrfMsg(6, "SetCustomEngineSprites: engine {} cargo {} already has group -- replacing", engine, cargo);
 
	}
 
	e->grf_prop.spritegroup[cargo] = group;
 
}
src/newgrf_generic.cpp
Show inline comments
 
@@ -109,7 +109,7 @@ void ResetGenericCallbacks()
 
void AddGenericCallback(uint8 feature, const GRFFile *file, const SpriteGroup *group)
 
{
 
	if (feature >= lengthof(_gcl)) {
 
		grfmsg(5, "AddGenericCallback: Unsupported feature 0x%02X", feature);
 
		GrfMsg(5, "AddGenericCallback: Unsupported feature {:#02X}", feature);
 
		return;
 
	}
 

	
src/newgrf_object.cpp
Show inline comments
 
@@ -12,8 +12,8 @@
 
#include "company_func.h"
 
#include "debug.h"
 
#include "genworld.h"
 
#include "newgrf_object.h"
 
#include "newgrf_class_func.h"
 
#include "newgrf_object.h"
 
#include "newgrf_sound.h"
 
#include "object_base.h"
 
#include "object_map.h"
src/newgrf_text.cpp
Show inline comments
 
@@ -137,7 +137,7 @@ struct UnmappedChoiceList {
 
		if (this->strings.find(0) == this->strings.end()) {
 
			/* In case of a (broken) NewGRF without a default,
 
			 * assume an empty string. */
 
			grfmsg(1, "choice list misses default value");
 
			GrfMsg(1, "choice list misses default value");
 
			this->strings[0] = std::stringstream();
 
		}
 

	
 
@@ -211,7 +211,7 @@ struct UnmappedChoiceList {
 
				int idx = (this->type == SCC_GENDER_LIST ? lm->GetReverseMapping(i, true) : i + 1);
 
				const auto &str = this->strings[this->strings.find(idx) != this->strings.end() ? idx : 0].str();
 
				size_t len = str.size() + 1;
 
				if (len > 0xFF) grfmsg(1, "choice list string is too long");
 
				if (len > 0xFF) GrfMsg(1, "choice list string is too long");
 
				*d++ = GB(len, 0, 8);
 
			}
 

	
 
@@ -290,7 +290,7 @@ std::string TranslateTTDPatchCodes(uint3
 
				if (allow_newlines) {
 
					*d++ = 0x0A;
 
				} else {
 
					grfmsg(1, "Detected newline in string that does not allow one");
 
					GrfMsg(1, "Detected newline in string that does not allow one");
 
				}
 
				break;
 
			case 0x0E: Utf8Encode(d, SCC_TINYFONT); break;
 
@@ -392,12 +392,12 @@ std::string TranslateTTDPatchCodes(uint3
 
						if (str[0] == '\0') goto string_end;
 
						if (mapping == nullptr) {
 
							if (code == 0x10) src++; // Skip the index
 
							grfmsg(1, "choice list %s marker found when not expected", code == 0x10 ? "next" : "default");
 
							GrfMsg(1, "choice list {} marker found when not expected", code == 0x10 ? "next" : "default");
 
							break;
 
						} else {
 
							int index = (code == 0x10 ? *src++ : 0);
 
							if (mapping->strings.find(index) != mapping->strings.end()) {
 
								grfmsg(1, "duplicate choice list string, ignoring");
 
								GrfMsg(1, "duplicate choice list string, ignoring");
 
							} else {
 
								d = std::ostreambuf_iterator<char>(mapping->strings[index]);
 
							}
 
@@ -406,7 +406,7 @@ std::string TranslateTTDPatchCodes(uint3
 

	
 
					case 0x12:
 
						if (mapping == nullptr) {
 
							grfmsg(1, "choice list end marker found when not expected");
 
							GrfMsg(1, "choice list end marker found when not expected");
 
						} else {
 
							/* Now we can start flushing everything and clean everything up. */
 
							mapping->Flush(LanguageMap::GetLanguageMap(grfid, language_id), dest);
 
@@ -422,7 +422,7 @@ std::string TranslateTTDPatchCodes(uint3
 
					case 0x15:
 
						if (src[0] == '\0') goto string_end;
 
						if (mapping != nullptr) {
 
							grfmsg(1, "choice lists can't be stacked, it's going to get messy now...");
 
							GrfMsg(1, "choice lists can't be stacked, it's going to get messy now...");
 
							if (code != 0x14) src++;
 
						} else {
 
							static const StringControlCode mp[] = { SCC_GENDER_LIST, SCC_SWITCH_CASE, SCC_PLURAL_LIST };
 
@@ -446,7 +446,7 @@ std::string TranslateTTDPatchCodes(uint3
 
					case 0x20: Utf8Encode(d, SCC_POP_COLOUR);  break;
 

	
 
					default:
 
						grfmsg(1, "missing handler for extended format code");
 
						GrfMsg(1, "missing handler for extended format code");
 
						break;
 
				}
 
				break;
 
@@ -477,7 +477,7 @@ std::string TranslateTTDPatchCodes(uint3
 

	
 
string_end:
 
	if (mapping != nullptr) {
 
		grfmsg(1, "choice list was incomplete, the whole list is ignored");
 
		GrfMsg(1, "choice list was incomplete, the whole list is ignored");
 
		delete mapping;
 
	}
 

	
 
@@ -590,7 +590,7 @@ StringID AddGRFString(uint32 grfid, uint
 
	}
 
	AddGRFTextToList(_grf_text[id].textholder, langid_to_add, newtext);
 

	
 
	grfmsg(3, "Added 0x%X: grfid %08X string 0x%X lang 0x%X string '%s' (%X)", id, grfid, stringid, langid_to_add, newtext.c_str(), MakeStringID(TEXT_TAB_NEWGRF_START, id));
 
	GrfMsg(3, "Added {:#X} grfid {:08X} string {:#X} lang {:#X} string '{}' ({:X})", id, grfid, stringid, langid_to_add, newtext.c_str(), MakeStringID(TEXT_TAB_NEWGRF_START, id));
 

	
 
	return MakeStringID(TEXT_TAB_NEWGRF_START, id);
 
}
0 comments (0 inline, 0 general)