BattleTech egg builder, catalog, and golden-egg DiffTests (BT port phases 1-2)
New TeslaConsole.BattleTech namespace mirroring TeslaConsole.RedPlanet's mission layer: BTMission/BTFreeForAllMission (egg serializer; RP wire framing and ordinal bitmaps reused verbatim), BTParticipant/BTPlayer/BTCamera (BT participant fields: advancedDamage, experience, vehicleValue, patch, role), and the BTConfig/BTScenario/BTMap/BTVehicle/BTWeather/BTRole catalog loaded from BattleTech\BTConfig.xml (reconstructed from the Mac Console 4.10 ini BT tree). Free For All and No Return share one mission class - both send scenario=freeforall; the mode is the role assigned to each pilot. BTGoldenEggTests (7 tests, recovered-only) diff the generated egg field-by-field against two eggs captured from the original consoles (cavern.egg, TESTARN.EGG): order-independent per-section compare with font-rendered bitmap pixel rows excluded, ordinal art byte-exact vs TESTARN.EGG, EggFileMessage framing reassembly, role de-dup, No Return role semantics, and shipped-catalog contents. Invoker gains BTEggString/ BTEggFraming reflection cases. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
using System.Xml;
|
||||
|
||||
namespace TeslaConsole.BattleTech;
|
||||
|
||||
/// <summary>
|
||||
/// Loads and exposes the BattleTech data catalog (BattleTech\BTConfig.xml),
|
||||
/// mirroring <c>TeslaConsole.RedPlanet.RPConfig</c>. The single BT scenario is
|
||||
/// "Free For All"; No Return reuses the same catalog and differs only by role.
|
||||
/// </summary>
|
||||
public static class BTConfig
|
||||
{
|
||||
private static readonly BTScenario mFreeForAll;
|
||||
|
||||
private static readonly Dictionary<string, BTMap> mMaps;
|
||||
|
||||
private static readonly Dictionary<string, BTVehicle> mVehicles;
|
||||
|
||||
private static readonly Dictionary<string, string> mTimesOfDay;
|
||||
|
||||
private static readonly Dictionary<string, BTWeather> mWeather;
|
||||
|
||||
public static BTScenario FreeForAll => mFreeForAll;
|
||||
|
||||
public static Dictionary<string, BTMap> Maps => mMaps;
|
||||
|
||||
public static Dictionary<string, BTVehicle> Vehicles => mVehicles;
|
||||
|
||||
public static Dictionary<string, string> TimesOfDay => mTimesOfDay;
|
||||
|
||||
public static Dictionary<string, BTWeather> Weather => mWeather;
|
||||
|
||||
static BTConfig()
|
||||
{
|
||||
mMaps = new Dictionary<string, BTMap>();
|
||||
mVehicles = new Dictionary<string, BTVehicle>();
|
||||
mTimesOfDay = new Dictionary<string, string>();
|
||||
mWeather = new Dictionary<string, BTWeather>();
|
||||
XmlNode freeForAllNode = null;
|
||||
XmlDocument xmlDocument = new XmlDocument();
|
||||
xmlDocument.Load(Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "BattleTech\\BTConfig.xml"));
|
||||
foreach (XmlNode childNode in xmlDocument.DocumentElement.ChildNodes)
|
||||
{
|
||||
switch (childNode.Name)
|
||||
{
|
||||
case "freeforall":
|
||||
freeForAllNode = childNode;
|
||||
break;
|
||||
case "map":
|
||||
{
|
||||
BTMap bTMap = new BTMap(childNode);
|
||||
mMaps.Add(bTMap.Key, bTMap);
|
||||
break;
|
||||
}
|
||||
case "vehicle":
|
||||
{
|
||||
BTVehicle bTVehicle = new BTVehicle(childNode);
|
||||
mVehicles.Add(bTVehicle.Key, bTVehicle);
|
||||
break;
|
||||
}
|
||||
case "time":
|
||||
AddKeyNameNode(childNode, mTimesOfDay);
|
||||
break;
|
||||
case "weather":
|
||||
{
|
||||
BTWeather bTWeather = new BTWeather(childNode);
|
||||
mWeather.Add(bTWeather.Key, bTWeather);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
mFreeForAll = new BTScenario(freeForAllNode);
|
||||
}
|
||||
|
||||
internal static void AddKeyNameNode(XmlNode node, Dictionary<string, string> list)
|
||||
{
|
||||
list.Add(node.Attributes["key"].InnerText, node.Attributes["name"].InnerText);
|
||||
}
|
||||
|
||||
public static string MapNameOrKey(string mapKey)
|
||||
{
|
||||
if (!mMaps.ContainsKey(mapKey))
|
||||
{
|
||||
return mapKey;
|
||||
}
|
||||
return mMaps[mapKey].Name;
|
||||
}
|
||||
|
||||
public static string VehicleNameOrKey(string vehicleKey)
|
||||
{
|
||||
if (!mVehicles.ContainsKey(vehicleKey))
|
||||
{
|
||||
return vehicleKey;
|
||||
}
|
||||
return mVehicles[vehicleKey].Name;
|
||||
}
|
||||
|
||||
public static string TimeOfDayNameOrKey(string timeOfDayKey)
|
||||
{
|
||||
if (!mTimesOfDay.ContainsKey(timeOfDayKey))
|
||||
{
|
||||
return timeOfDayKey;
|
||||
}
|
||||
return mTimesOfDay[timeOfDayKey];
|
||||
}
|
||||
|
||||
public static string WeatherNameOrKey(string weatherKey)
|
||||
{
|
||||
if (!mWeather.ContainsKey(weatherKey))
|
||||
{
|
||||
return weatherKey;
|
||||
}
|
||||
return mWeather[weatherKey].Name;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user