feat: add customizations dump (data and icons)
This commit is contained in:
@@ -44,6 +44,15 @@ struct DLCInfo
|
|||||||
public Dictionary<string, string> dlcIds;
|
public Dictionary<string, string> dlcIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct CustomizationItemInfo
|
||||||
|
{
|
||||||
|
public string id;
|
||||||
|
public string name;
|
||||||
|
public string iconFilePath;
|
||||||
|
public int associatedCharacter;
|
||||||
|
public ECustomizationCategory category;
|
||||||
|
}
|
||||||
|
|
||||||
class Dumper
|
class Dumper
|
||||||
{
|
{
|
||||||
private DefaultFileProvider? _provider;
|
private DefaultFileProvider? _provider;
|
||||||
@@ -55,6 +64,7 @@ class Dumper
|
|||||||
private readonly Dictionary<int, CharacterInfo> _characterMap = new();
|
private readonly Dictionary<int, CharacterInfo> _characterMap = new();
|
||||||
private readonly Dictionary<string, ItemInfo> _itemMap = new();
|
private readonly Dictionary<string, ItemInfo> _itemMap = new();
|
||||||
private readonly Dictionary<string, OfferingInfo> _offeringMap = new();
|
private readonly Dictionary<string, OfferingInfo> _offeringMap = new();
|
||||||
|
private readonly Dictionary<string, CustomizationItemInfo> _customizationItemMap = new();
|
||||||
|
|
||||||
public Dumper(string outDir)
|
public Dumper(string outDir)
|
||||||
{
|
{
|
||||||
@@ -245,9 +255,117 @@ class Dumper
|
|||||||
WriteJson("dlcs", dlcList.ToArray());
|
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 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 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 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
|
* bulk functions for dumping
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ var dumpTasks = new (string Name, Action Execute)[]
|
|||||||
("character", () => { dumper.DumpCharacters(); dumper.DumpCharacterIcons(); }),
|
("character", () => { dumper.DumpCharacters(); dumper.DumpCharacterIcons(); }),
|
||||||
("item", () => { dumper.DumpItems(); dumper.DumpItemIcons(); }),
|
("item", () => { dumper.DumpItems(); dumper.DumpItemIcons(); }),
|
||||||
("offering", () => { dumper.DumpOfferings(); dumper.DumpOfferingIcons(); }),
|
("offering", () => { dumper.DumpOfferings(); dumper.DumpOfferingIcons(); }),
|
||||||
|
("customizations", () => { dumper.DumpCustomizations(); dumper.DumpCustomizationIcons(); }),
|
||||||
("dlc", () => { dumper.DumpDLCs(); })
|
("dlc", () => { dumper.DumpDLCs(); })
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user