Files
blitzkit/src/BlitzKit.CLI/Functions/Mangler.cs
T

164 lines
5.0 KiB
C#
Raw Normal View History

2025-01-29 19:14:46 -06:00
using Blitzkit;
2025-01-28 12:59:59 -06:00
using BlitzKit.CLI.Models;
2025-01-28 19:52:49 -06:00
using BlitzKit.CLI.Utils;
using CUE4Parse.FileProvider.Objects;
2025-01-29 19:14:46 -06:00
using Google.Protobuf;
2025-01-30 12:49:15 -06:00
using Google.Protobuf.Collections;
2025-01-29 19:14:46 -06:00
using Newtonsoft.Json.Linq;
2025-01-27 22:17:13 -06:00
2025-01-28 12:59:59 -06:00
namespace BlitzKit.CLI.Functions
2025-01-26 21:17:25 -06:00
{
public static class Mangler
{
2025-01-27 22:17:13 -06:00
public static void Mangle()
{
2025-01-29 19:14:46 -06:00
Tanks tanks = new();
2025-01-27 22:17:13 -06:00
BlitzProvider provider = new();
2025-01-30 11:31:55 -06:00
foreach (
var nationDir in provider.RootDirectory.GetDirectory("Blitz/Content/Tanks").Directories
)
2025-01-27 22:17:13 -06:00
{
2025-01-30 11:31:55 -06:00
if (nationDir.Key == "TankStub")
2025-01-27 22:17:13 -06:00
continue;
2025-01-30 11:31:55 -06:00
foreach (var tankDir in nationDir.Value.Directories)
2025-01-27 22:17:13 -06:00
{
2025-01-30 11:31:55 -06:00
if (tankDir.Key != "R90_IS_4")
2025-01-28 19:52:49 -06:00
continue;
2025-01-30 11:31:55 -06:00
var attributeFileName = $"DA_{tankDir.Key}_Attributes.uasset";
var hasAttributesFile = tankDir.Value.HasFile(attributeFileName);
2025-01-29 19:14:46 -06:00
GameFile? attributesFile = null;
2025-01-28 19:52:49 -06:00
if (hasAttributesFile)
2025-01-28 12:55:02 -06:00
{
2025-01-30 11:31:55 -06:00
attributesFile = tankDir.Value.GetFile(attributeFileName);
2025-01-28 19:52:49 -06:00
}
else
{
PrettyLog.Warn(
2025-01-30 11:31:55 -06:00
$"No attributes file found for {nationDir.Key}/{tankDir.Key}, it may be misspelled; finding any attributes file..."
2025-01-28 19:52:49 -06:00
);
2025-01-30 11:31:55 -06:00
foreach (var file in tankDir.Value.Files)
2025-01-28 19:52:49 -06:00
{
if (file.Key.EndsWith("_Attributes.uasset"))
{
2025-01-29 19:14:46 -06:00
attributesFile = file.Value;
2025-01-28 19:52:49 -06:00
break;
}
}
2025-01-29 19:14:46 -06:00
if (attributesFile == null)
2025-01-28 19:52:49 -06:00
{
PrettyLog.Error(
2025-01-30 11:31:55 -06:00
$"No suffixed attributes file found for {nationDir.Key}/{tankDir.Key}; skipping..."
2025-01-28 19:52:49 -06:00
);
continue;
}
}
2025-01-29 19:14:46 -06:00
var exports = provider.LoadAllObjects(attributesFile.Path);
2025-01-28 19:52:49 -06:00
2025-01-29 19:14:46 -06:00
var tankAttributesDataAsset =
exports.First((export) => export.ExportType == "TankAttributesDataAsset")
?? throw new Exception("TankAttributesDataAsset not found");
var attr = JObject.FromObject(tankAttributesDataAsset);
2025-01-30 11:31:55 -06:00
var props = attr.GetValue("Properties");
2025-01-28 19:52:49 -06:00
2025-01-30 11:31:55 -06:00
if (props == null || props["MaxHealth"] == null)
{
PrettyLog.Warn(
$"{nationDir.Key}/{tankDir.Key} has not migrated to Reforged; skipping..."
);
continue;
}
Tank tank = new()
{
Id = tankDir.Key,
// TODO: Name
// TODO: Set
// TODO: Class
// TODO: Faction
TurretRotatorHealth = MangleModuleHealth((props["TurretRotatorHealth"] as JObject)!),
SurveyingDeviceHealth = MangleModuleHealth(
(props["SurveyingDeviceHealth"] as JObject)!
),
GunHealth = MangleModuleHealth((props["GunHealth"] as JObject)!),
ChassisHealth = MangleModuleHealth((props["ChassisHealth"] as JObject)!),
AmmoBayHealth = MangleModuleHealth((props["AmmoBayHealth"] as JObject)!),
EngineHealth = MangleModuleHealth((props["EngineHealth"] as JObject)!),
FuelTankHealth = MangleModuleHealth((props["FuelTankHealth"] as JObject)!),
};
2025-01-30 12:49:15 -06:00
MangleCrewHealth(tank.CrewHealth, (props["CrewHealth"] as JArray)!);
2025-01-30 11:31:55 -06:00
tanks.Tanks_.Add(tank.Id);
var tankBytes = tank.ToByteArray();
Console.WriteLine($"Mangled {nationDir.Key}/{tankDir.Key}");
2025-01-27 22:17:13 -06:00
}
}
2025-01-29 19:14:46 -06:00
var tanksBytes = tanks.ToByteArray();
2025-01-26 21:17:25 -06:00
}
2025-01-30 11:31:55 -06:00
2025-01-30 12:49:15 -06:00
public static Dictionary<string, CrewType> CrewTypes = new()
{
{ "EModuleOrTankmen::Commander", CrewType.Commander },
{ "EModuleOrTankmen::Driver", CrewType.Driver },
{ "EModuleOrTankmen::Gunner1", CrewType.Gunner1 },
{ "EModuleOrTankmen::Gunner2", CrewType.Gunner2 },
{ "EModuleOrTankmen::Loader1", CrewType.Loader1 },
{ "EModuleOrTankmen::Loader2", CrewType.Loader2 },
};
public static void MangleCrewHealth(RepeatedField<CrewHealth> map, JArray array)
{
foreach (var member in array.Cast<JObject>())
{
var key = member["Key"]!.Value<string>()!;
if (CrewTypes.TryGetValue(key, out var crewType))
{
CrewHealth crewHealth = new()
{
Type = crewType,
MaxHealth = member["Value"]!["MaxHealth"]!.Value<float>(),
};
map.Add(crewHealth);
}
else
{
throw new Exception($"Unrecognized CrewType: {key}");
}
}
}
2025-01-30 11:31:55 -06:00
public static ModuleHealth MangleModuleHealth(JObject obj)
{
ModuleHealth moduleHealth = new()
{
MaxHealth = obj["MaxHealth"]!.Value<float>(),
MaxRegenHealth = obj["MaxRegenHealth"]!.Value<float>(),
HealthRegenPerSec = obj["HealthRegenPerSec"]!.Value<float>(),
};
if (obj.TryGetValue("HysteresisHealth", out var hysteresis))
{
moduleHealth.HysteresisHealth = hysteresis.Value<float>();
}
if (obj.TryGetValue("HealthBurnPerSec", out var burn))
{
moduleHealth.HealthBurnPerSec = burn.Value<float>();
}
return moduleHealth;
}
2025-01-26 21:17:25 -06:00
}
}