feat: add customizations dump (data and icons)
This commit is contained in:
+120
-2
@@ -44,6 +44,15 @@ struct DLCInfo
|
||||
public Dictionary<string, string> dlcIds;
|
||||
}
|
||||
|
||||
struct CustomizationItemInfo
|
||||
{
|
||||
public string id;
|
||||
public string name;
|
||||
public string iconFilePath;
|
||||
public int associatedCharacter;
|
||||
public ECustomizationCategory category;
|
||||
}
|
||||
|
||||
class Dumper
|
||||
{
|
||||
private DefaultFileProvider? _provider;
|
||||
@@ -55,6 +64,7 @@ class Dumper
|
||||
private readonly Dictionary<int, CharacterInfo> _characterMap = new();
|
||||
private readonly Dictionary<string, ItemInfo> _itemMap = new();
|
||||
private readonly Dictionary<string, OfferingInfo> _offeringMap = new();
|
||||
private readonly Dictionary<string, CustomizationItemInfo> _customizationItemMap = new();
|
||||
|
||||
public Dumper(string outDir)
|
||||
{
|
||||
@@ -228,9 +238,9 @@ class Dumper
|
||||
|
||||
|
||||
string? displayName = null;
|
||||
if (TryGetStringProp<FText>(props, "DisplayName", out string foundName) && !string.IsNullOrWhiteSpace(foundName))
|
||||
if (TryGetStringProp<FText>(props, "DisplayName", out string foundName) && !string.IsNullOrWhiteSpace(foundName))
|
||||
displayName = foundName;
|
||||
|
||||
|
||||
DLCInfo info = new DLCInfo
|
||||
{
|
||||
id = rowKey,
|
||||
@@ -245,9 +255,117 @@ class Dumper
|
||||
WriteJson("dlcs", dlcList.ToArray());
|
||||
}
|
||||
|
||||
public void DumpCustomizations()
|
||||
{
|
||||
ProcessDataTables("/CustomizationItemDB.uasset", "customization items", (rowKey, props) =>
|
||||
{
|
||||
if (!TryGetProp(props, "Category", out ECustomizationCategory category)
|
||||
|| !TryGetProp(props, "Availability", out FStructFallback availabilityFb)
|
||||
|| !TryGetProp(props, "UIData", out FStructFallback uiDataFb)
|
||||
|| !TryGetProp(props, "AssociatedCharacter", out int associatedCharacter))
|
||||
throw new KeyNotFoundException($"Required properties missing for CustomizationItem: {rowKey}");
|
||||
|
||||
AvailabilityStruct availability = availabilityFb.MapToStruct<AvailabilityStruct>();
|
||||
UIDataStruct uiData = uiDataFb.MapToStruct<UIDataStruct>();
|
||||
|
||||
if (availability.DLCId == "development") return; // skip development dlc items just in case
|
||||
|
||||
if (uiData.IconAssetList.Length == 0)
|
||||
throw new InvalidDataException("CustomizationItem's UIData had no icons");
|
||||
|
||||
string iconPathStr = uiData.IconAssetList[0].ToString();
|
||||
|
||||
_customizationItemMap[rowKey] = new CustomizationItemInfo
|
||||
{
|
||||
id = rowKey,
|
||||
name = uiData.DisplayName.ToString(),
|
||||
associatedCharacter = associatedCharacter,
|
||||
category = category,
|
||||
iconFilePath = iconPathStr,
|
||||
};
|
||||
});
|
||||
|
||||
_log.Info("Dumped {0} customization items", _customizationItemMap.Count);
|
||||
WriteJson("customization_items", _customizationItemMap.Values);
|
||||
}
|
||||
|
||||
public void DumpCharacterIcons() => ExportIcons(_characterMap.Values.Select(x => x.iconFilePath), "character", "/character-icons/");
|
||||
public void DumpItemIcons() => ExportIcons(_itemMap.Values.Select(x => x.iconFilePath), "item", "/item-icons/");
|
||||
public void DumpOfferingIcons() => ExportIcons(_offeringMap.Values.Select(x => x.iconFilePath), "offering", "/offering-icons/");
|
||||
public void DumpCustomizationIcons()
|
||||
{
|
||||
_log.Info("Dumping customization item icons");
|
||||
|
||||
foreach (var item in _customizationItemMap.Values)
|
||||
{
|
||||
string outPath = "customization/";
|
||||
|
||||
if (item.category == ECustomizationCategory.Charm ||
|
||||
item.category == ECustomizationCategory.Badge ||
|
||||
item.category == ECustomizationCategory.Banner ||
|
||||
item.category == ECustomizationCategory.PortraitBackground)
|
||||
{
|
||||
switch (item.category)
|
||||
{
|
||||
case ECustomizationCategory.Charm:
|
||||
outPath += "charms/";
|
||||
break;
|
||||
case ECustomizationCategory.Badge:
|
||||
outPath += "badges/";
|
||||
break;
|
||||
case ECustomizationCategory.Banner:
|
||||
outPath += "banners/";
|
||||
break;
|
||||
case ECustomizationCategory.PortraitBackground:
|
||||
outPath += "portrait-backgrounds/";
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (item.associatedCharacter > -1)
|
||||
{
|
||||
string charFolderName = item.associatedCharacter.ToString();
|
||||
|
||||
if (_characterMap.TryGetValue(item.associatedCharacter, out CharacterInfo charInfo) && !string.IsNullOrWhiteSpace(charInfo.name))
|
||||
charFolderName = string.Join("_", charInfo.name.Split(Path.GetInvalidFileNameChars()));
|
||||
|
||||
outPath += $"characters/{charFolderName}/";
|
||||
|
||||
switch (item.category)
|
||||
{
|
||||
case ECustomizationCategory.SurvivorHead:
|
||||
case ECustomizationCategory.KillerHead:
|
||||
outPath += "heads/";
|
||||
break;
|
||||
case ECustomizationCategory.SurvivorTorso:
|
||||
outPath += "torsos/";
|
||||
break;
|
||||
case ECustomizationCategory.SurvivorLegs:
|
||||
outPath += "legs/";
|
||||
break;
|
||||
case ECustomizationCategory.KillerBody:
|
||||
outPath += "bodys/";
|
||||
break;
|
||||
case ECustomizationCategory.KillerWeapon:
|
||||
outPath += "weapons/";
|
||||
break;
|
||||
case ECustomizationCategory.Outfits:
|
||||
outPath += "outfits/";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ExportIcon(item.iconFilePath, outPath);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_log.Error($"Failed to export icon for {item.id}: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
_log.Info("Dumped all customization item icons");
|
||||
}
|
||||
|
||||
/*
|
||||
* bulk functions for dumping
|
||||
|
||||
@@ -15,6 +15,7 @@ var dumpTasks = new (string Name, Action Execute)[]
|
||||
("character", () => { dumper.DumpCharacters(); dumper.DumpCharacterIcons(); }),
|
||||
("item", () => { dumper.DumpItems(); dumper.DumpItemIcons(); }),
|
||||
("offering", () => { dumper.DumpOfferings(); dumper.DumpOfferingIcons(); }),
|
||||
("customizations", () => { dumper.DumpCustomizations(); dumper.DumpCustomizationIcons(); }),
|
||||
("dlc", () => { dumper.DumpDLCs(); })
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user