Skip to content

Commit 1502a85

Browse files
Validate airdrop item, grenade and storage IDs at load to prevent phantom items
Items whose IDs don't resolve to a loaded asset (e.g. missing workshop mod) are now filtered at load with a warning listing the bad IDs, so airdrops no longer fill with phantom items that render as Work Jeans. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent e373e87 commit 1502a85

3 files changed

Lines changed: 57 additions & 1 deletion

File tree

AirdropManager3/AirdropManager3.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<TargetFramework>net48</TargetFramework>
55
<LangVersion>latest</LangVersion>
66
<RootNamespace>RestoreMonarchy.AirdropManager3</RootNamespace>
7-
<Version>3.1.2</Version>
7+
<Version>3.1.3</Version>
88
</PropertyGroup>
99

1010
<ItemGroup>

AirdropManager3/AirdropManager3Plugin.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,11 @@ internal void LogError(string message)
163163
Logger.Log($"Error >> {message}", ConsoleColor.Red);
164164
}
165165

166+
internal void LogWarning(string message)
167+
{
168+
Logger.Log($"Warning >> {message}", ConsoleColor.Yellow);
169+
}
170+
166171
internal bool DisableInfoLog { get; set; }
167172

168173
internal void LogInfo(string message)

AirdropManager3/Configurations/AirdropsXmlConfiguration.cs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,57 @@ public void Load()
3333
Save();
3434
pluginInstance.LogInfo($"Generated {fileName} with {Instance.Airdrops.Count} airdrops.");
3535
}
36+
37+
Validate();
38+
}
39+
40+
private void Validate()
41+
{
42+
if (Instance?.Airdrops == null)
43+
{
44+
return;
45+
}
46+
47+
foreach (Airdrop airdrop in Instance.Airdrops)
48+
{
49+
if (airdrop.Items != null && airdrop.Items.Count > 0)
50+
{
51+
List<ushort> invalidItemIds = new();
52+
airdrop.Items.RemoveAll(item =>
53+
{
54+
if (Assets.find(EAssetType.ITEM, item.Id) is not ItemAsset)
55+
{
56+
invalidItemIds.Add(item.Id);
57+
return true;
58+
}
59+
return false;
60+
});
61+
62+
if (invalidItemIds.Count > 0)
63+
{
64+
pluginInstance.LogWarning($"Airdrop '{airdrop.DisplayName()}': removed {invalidItemIds.Count} item(s) with unresolved IDs: {string.Join(", ", invalidItemIds)}. Check that the workshop mods providing these items are loaded correctly.");
65+
}
66+
}
67+
68+
if (airdrop.Grenade != null && airdrop.Grenade.Id != 0
69+
&& Assets.find(EAssetType.ITEM, airdrop.Grenade.Id) is not ItemAsset)
70+
{
71+
pluginInstance.LogWarning($"Airdrop '{airdrop.DisplayName()}': grenade ID {airdrop.Grenade.Id} doesn't resolve to a valid item. Grenade binding disabled for this airdrop.");
72+
airdrop.Grenade = null;
73+
}
74+
75+
if (airdrop.Storage != null && airdrop.Storage.BarricadeId != 0
76+
&& Assets.find(EAssetType.ITEM, airdrop.Storage.BarricadeId) is not ItemBarricadeAsset)
77+
{
78+
pluginInstance.LogWarning($"Airdrop '{airdrop.DisplayName()}': storage barricade ID {airdrop.Storage.BarricadeId} doesn't resolve to a valid barricade. Falling back to default storage.");
79+
airdrop.Storage.BarricadeId = 0;
80+
}
81+
82+
if (airdrop.Items == null || airdrop.Items.Count == 0)
83+
{
84+
pluginInstance.LogError($"Airdrop '{airdrop.DisplayName()}' has no valid items. Airdrops of this type will spawn empty.");
85+
}
86+
}
3687
}
3788

3889
public void Save()

0 commit comments

Comments
 (0)