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>
133 lines
3.7 KiB
C#
133 lines
3.7 KiB
C#
using System.Collections.Generic;
|
|
using System.Xml;
|
|
|
|
namespace TeslaConsole.BattleTech;
|
|
|
|
/// <summary>
|
|
/// A BattleTech scenario (game mode). Mirrors the Red Planet
|
|
/// <c>Scenario</c>/<c>DeathRaceScenario</c> pattern: it inherits the shared
|
|
/// map/vehicle/time/weather catalogs from <see cref="BTConfig" /> (minus any
|
|
/// <c><invalid></c> exclusions) and adds the BT-specific option lists
|
|
/// (experience, camo, patch, emblem, role).
|
|
/// </summary>
|
|
public class BTScenario
|
|
{
|
|
private readonly string mKey;
|
|
|
|
private readonly string mName;
|
|
|
|
private readonly Dictionary<string, BTMap> mMaps = new Dictionary<string, BTMap>();
|
|
|
|
private readonly Dictionary<string, BTVehicle> mVehicles = new Dictionary<string, BTVehicle>();
|
|
|
|
private readonly Dictionary<string, string> mTimesOfDay = new Dictionary<string, string>();
|
|
|
|
private readonly Dictionary<string, BTWeather> mWeather = new Dictionary<string, BTWeather>();
|
|
|
|
private readonly Dictionary<string, string> mExperiences = new Dictionary<string, string>();
|
|
|
|
private readonly Dictionary<string, string> mColors = new Dictionary<string, string>();
|
|
|
|
private readonly Dictionary<string, string> mPatches = new Dictionary<string, string>();
|
|
|
|
private readonly Dictionary<string, string> mBadges = new Dictionary<string, string>();
|
|
|
|
private readonly Dictionary<string, BTRole> mRoles = new Dictionary<string, BTRole>();
|
|
|
|
public string Key => mKey;
|
|
|
|
public string Name => mName;
|
|
|
|
public Dictionary<string, BTMap> Maps => mMaps;
|
|
|
|
public Dictionary<string, BTVehicle> Vehicles => mVehicles;
|
|
|
|
public Dictionary<string, string> TimesOfDay => mTimesOfDay;
|
|
|
|
public Dictionary<string, BTWeather> Weather => mWeather;
|
|
|
|
public Dictionary<string, string> Experiences => mExperiences;
|
|
|
|
public Dictionary<string, string> Colors => mColors;
|
|
|
|
public Dictionary<string, string> Patches => mPatches;
|
|
|
|
public Dictionary<string, string> Badges => mBadges;
|
|
|
|
public Dictionary<string, BTRole> Roles => mRoles;
|
|
|
|
internal BTScenario(XmlNode scenarioNode)
|
|
{
|
|
mKey = scenarioNode.Name;
|
|
mName = scenarioNode.Attributes["name"].InnerText;
|
|
List<KeyValuePair<string, string>> invalid = new List<KeyValuePair<string, string>>();
|
|
foreach (XmlNode childNode in scenarioNode.ChildNodes)
|
|
{
|
|
switch (childNode.Name)
|
|
{
|
|
case "invalid":
|
|
invalid.Add(new KeyValuePair<string, string>(childNode.Attributes["type"].InnerText, childNode.Attributes["key"].InnerText));
|
|
break;
|
|
case "experience":
|
|
BTConfig.AddKeyNameNode(childNode, mExperiences);
|
|
break;
|
|
case "color":
|
|
BTConfig.AddKeyNameNode(childNode, mColors);
|
|
break;
|
|
case "patch":
|
|
BTConfig.AddKeyNameNode(childNode, mPatches);
|
|
break;
|
|
case "badge":
|
|
BTConfig.AddKeyNameNode(childNode, mBadges);
|
|
break;
|
|
case "role":
|
|
{
|
|
BTRole role = new BTRole(childNode);
|
|
mRoles.Add(role.Key, role);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
foreach (BTMap value in BTConfig.Maps.Values)
|
|
{
|
|
if (!IsInvalid("map", value.Key, invalid))
|
|
{
|
|
mMaps.Add(value.Key, value);
|
|
}
|
|
}
|
|
foreach (BTVehicle value2 in BTConfig.Vehicles.Values)
|
|
{
|
|
if (!IsInvalid("vehicle", value2.Key, invalid))
|
|
{
|
|
mVehicles.Add(value2.Key, value2);
|
|
}
|
|
}
|
|
foreach (KeyValuePair<string, string> item in BTConfig.TimesOfDay)
|
|
{
|
|
if (!IsInvalid("time", item.Key, invalid))
|
|
{
|
|
mTimesOfDay.Add(item.Key, item.Value);
|
|
}
|
|
}
|
|
foreach (BTWeather value3 in BTConfig.Weather.Values)
|
|
{
|
|
if (!IsInvalid("weather", value3.Key, invalid))
|
|
{
|
|
mWeather.Add(value3.Key, value3);
|
|
}
|
|
}
|
|
}
|
|
|
|
private static bool IsInvalid(string type, string value, List<KeyValuePair<string, string>> invalid)
|
|
{
|
|
foreach (KeyValuePair<string, string> item in invalid)
|
|
{
|
|
if (item.Key == type && item.Value == value)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
}
|