using Sandbox.Definitions;
using System.Text.RegularExpressions;
using VRage.Game;
namespace SpaceEngineersBlueprintEditor.SpaceEngineersCore.BlueprintEditing;
public enum BlueprintArmorType
{
Light,
Heavy
}
public sealed class BlueprintTransformResult
{
public int ConvertedBlocks { get; internal set; }
public int AlreadyTargetBlocks { get; internal set; }
public int UnsupportedBlocks { get; internal set; }
public int ChangedGrids { get; internal set; }
}
/// <summary>
/// Converts blueprint blocks by using the definitions loaded from the installed game.
/// This keeps the conversion table in sync with game and DLC updates.
/// </summary>
public static class BlueprintTransformService
{
private static readonly Regex ArmorWeightRegex = new(
"(?:Light|Heavy)",
RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Compiled);
public static BlueprintTransformResult ConvertGridSize(
MyObjectBuilder_ShipBlueprintDefinition blueprint,
MyCubeSize targetSize)
{
if (blueprint is null)
{
throw new ArgumentNullException(nameof(blueprint));
}
var result = new BlueprintTransformResult();
foreach (var grid in blueprint.CubeGrids ?? [])
{
if (grid.GridSizeEnum != targetSize)
{
grid.GridSizeEnum = targetSize;
result.ChangedGrids++;
}
foreach (var block in grid.CubeBlocks ?? [])
{
var sourceDefinition = TryGetDefinition(block);
if (sourceDefinition is null)
{
result.UnsupportedBlocks++;
continue;
}
if (sourceDefinition.CubeSize == targetSize)
{
result.AlreadyTargetBlocks++;
continue;
}
var group = MyDefinitionManager.Static.TryGetDefinitionGroup(sourceDefinition.BlockPairName);
var targetDefinition = targetSize == MyCubeSize.Small ? group?.Small : group?.Large;
if (targetDefinition is null || targetDefinition.Id.TypeId != block.TypeId)
{
result.UnsupportedBlocks++;
continue;
}
block.SubtypeName = targetDefinition.Id.SubtypeName;
result.ConvertedBlocks++;
}
}
return result;
}
public static BlueprintTransformResult ConvertArmor(
MyObjectBuilder_ShipBlueprintDefinition blueprint,
BlueprintArmorType targetArmor)
{
if (blueprint is null)
{
throw new ArgumentNullException(nameof(blueprint));
}
var targetIsHeavy = targetArmor == BlueprintArmorType.Heavy;
var candidates = MyDefinitionManager.Static.GetAllDefinitions()
.OfType<MyCubeBlockDefinition>()
.Where(IsArmorDefinition)
.GroupBy(definition => CreateArmorKey(
definition.BlockPairName,
definition.CubeSize,
IsHeavyArmor(definition)))
.ToDictionary(group => group.Key, group => group.First());
var result = new BlueprintTransformResult();
foreach (var grid in blueprint.CubeGrids ?? [])
{
foreach (var block in grid.CubeBlocks ?? [])
{
var sourceDefinition = TryGetDefinition(block);
if (sourceDefinition is null || !IsArmorDefinition(sourceDefinition))
{
continue;
}
if (IsHeavyArmor(sourceDefinition) == targetIsHeavy)
{
result.AlreadyTargetBlocks++;
continue;
}
var key = CreateArmorKey(
sourceDefinition.BlockPairName,
sourceDefinition.CubeSize,
targetIsHeavy);
if (!candidates.TryGetValue(key, out var targetDefinition) ||
targetDefinition.Id.TypeId != block.TypeId)
{
result.UnsupportedBlocks++;
continue;
}
block.SubtypeName = targetDefinition.Id.SubtypeName;
result.ConvertedBlocks++;
}
}
return result;
}
private static MyCubeBlockDefinition? TryGetDefinition(MyObjectBuilder_CubeBlock block)
{
try
{
return MyDefinitionManager.Static.GetCubeBlockDefinition(block);
}
catch
{
return null;
}
}
private static bool IsArmorDefinition(MyCubeBlockDefinition definition)
{
return definition.BlockPairName.IndexOf("Armor", StringComparison.OrdinalIgnoreCase) >= 0 ||
definition.Id.SubtypeName.IndexOf("Armor", StringComparison.OrdinalIgnoreCase) >= 0;
}
private static bool IsHeavyArmor(MyCubeBlockDefinition definition)
{
return definition.BlockPairName.IndexOf("Heavy", StringComparison.OrdinalIgnoreCase) >= 0 ||
definition.Id.SubtypeName.IndexOf("Heavy", StringComparison.OrdinalIgnoreCase) >= 0;
}
private static string NormalizeArmorName(string name)
{
return ArmorWeightRegex.Replace(name ?? string.Empty, string.Empty);
}
private static string CreateArmorKey(string pairName, MyCubeSize cubeSize, bool isHeavy)
{
return $"{NormalizeArmorName(pairName)}|{(int)cubeSize}|{isHeavy}";
}
}
using Sandbox.Definitions;
using System.Text.RegularExpressions;
using VRage.Game;
namespace SpaceEngineersBlueprintEditor.SpaceEngineersCore.BlueprintEditing;
public enum BlueprintArmorType
{
Light,
Heavy
}
public sealed class BlueprintTransformResult
{
public int ConvertedBlocks { get; internal set; }
public int AlreadyTargetBlocks { get; internal set; }
public int UnsupportedBlocks { get; internal set; }
public int ChangedGrids { get; internal set; }
}
/// <summary>
/// Converts blueprint blocks by using the definitions loaded from the installed game.
/// This keeps the conversion table in sync with game and DLC updates.
/// </summary>
public static class BlueprintTransformService
{
private static readonly Regex ArmorWeightRegex = new(
"(?:Light|Heavy)",
RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Compiled);
public static BlueprintTransformResult ConvertGridSize(
MyObjectBuilder_ShipBlueprintDefinition blueprint,
MyCubeSize targetSize)
{
if (blueprint is null)
{
throw new ArgumentNullException(nameof(blueprint));
}
var result = new BlueprintTransformResult();
foreach (var grid in blueprint.CubeGrids ?? [])
{
if (grid.GridSizeEnum != targetSize)
{
grid.GridSizeEnum = targetSize;
result.ChangedGrids++;
}
foreach (var block in grid.CubeBlocks ?? [])
{
var sourceDefinition = TryGetDefinition(block);
if (sourceDefinition is null)
{
result.UnsupportedBlocks++;
continue;
}
if (sourceDefinition.CubeSize == targetSize)
{
result.AlreadyTargetBlocks++;
continue;
}
var group = MyDefinitionManager.Static.TryGetDefinitionGroup(sourceDefinition.BlockPairName);
var targetDefinition = targetSize == MyCubeSize.Small ? group?.Small : group?.Large;
if (targetDefinition is null || targetDefinition.Id.TypeId != block.TypeId)
{
result.UnsupportedBlocks++;
continue;
}
block.SubtypeName = targetDefinition.Id.SubtypeName;
result.ConvertedBlocks++;
}
}
return result;
}
public static BlueprintTransformResult ConvertArmor(
MyObjectBuilder_ShipBlueprintDefinition blueprint,
BlueprintArmorType targetArmor)
{
if (blueprint is null)
{
throw new ArgumentNullException(nameof(blueprint));
}
var targetIsHeavy = targetArmor == BlueprintArmorType.Heavy;
var candidates = MyDefinitionManager.Static.GetAllDefinitions()
.OfType<MyCubeBlockDefinition>()
.Where(IsArmorDefinition)
.GroupBy(definition => CreateArmorKey(
definition.BlockPairName,
definition.CubeSize,
IsHeavyArmor(definition)))
.ToDictionary(group => group.Key, group => group.First());
var result = new BlueprintTransformResult();
foreach (var grid in blueprint.CubeGrids ?? [])
{
foreach (var block in grid.CubeBlocks ?? [])
{
var sourceDefinition = TryGetDefinition(block);
if (sourceDefinition is null || !IsArmorDefinition(sourceDefinition))
{
continue;
}
if (IsHeavyArmor(sourceDefinition) == targetIsHeavy)
{
result.AlreadyTargetBlocks++;
continue;
}
var key = CreateArmorKey(
sourceDefinition.BlockPairName,
sourceDefinition.CubeSize,
targetIsHeavy);
if (!candidates.TryGetValue(key, out var targetDefinition) ||
targetDefinition.Id.TypeId != block.TypeId)
{
result.UnsupportedBlocks++;
continue;
}
block.SubtypeName = targetDefinition.Id.SubtypeName;
result.ConvertedBlocks++;
}
}
return result;
}
private static MyCubeBlockDefinition? TryGetDefinition(MyObjectBuilder_CubeBlock block)
{
try
{
return MyDefinitionManager.Static.GetCubeBlockDefinition(block);
}
catch
{
return null;
}
}
private static bool IsArmorDefinition(MyCubeBlockDefinition definition)
{
return definition.BlockPairName.IndexOf("Armor", StringComparison.OrdinalIgnoreCase) >= 0 ||
definition.Id.SubtypeName.IndexOf("Armor", StringComparison.OrdinalIgnoreCase) >= 0;
}
private static bool IsHeavyArmor(MyCubeBlockDefinition definition)
{
return definition.BlockPairName.IndexOf("Heavy", StringComparison.OrdinalIgnoreCase) >= 0 ||
definition.Id.SubtypeName.IndexOf("Heavy", StringComparison.OrdinalIgnoreCase) >= 0;
}
private static string NormalizeArmorName(string name)
{
return ArmorWeightRegex.Replace(name ?? string.Empty, string.Empty);
}
private static string CreateArmorKey(string pairName, MyCubeSize cubeSize, bool isHeavy)
{
return $"{NormalizeArmorName(pairName)}|{(int)cubeSize}|{isHeavy}";
}
}