Move equipped item projection into runtime
This commit is contained in:
parent
c2bbdff76e
commit
4eb5712e36
3 changed files with 584 additions and 309 deletions
|
|
@ -4289,8 +4289,8 @@ static void RequireInventoryCargoItemDetailsUseEveSurface(string root)
|
|||
|
||||
if (!source.Contains("ResolveInventorySurfaceStateRef", StringComparison.Ordinal) ||
|
||||
!source.Contains("AetheriaRuntimeDaemonItemStatQueries.TryReadItemStatRef(", StringComparison.Ordinal) ||
|
||||
!source.Contains("AetheriaRuntimeDaemonItemStatQueries.ItemStatRef(", StringComparison.Ordinal) ||
|
||||
!source.Contains("AetheriaRuntimeDaemonItemStatQueries.EvaluatePerformanceStat(", StringComparison.Ordinal) ||
|
||||
!cargoItemSurfaceBuilder.Contains("AetheriaRuntimeDaemonItemStatQueries.ItemStatRef(", StringComparison.Ordinal) ||
|
||||
source.Contains("private static bool TryReadItemStatRef(", StringComparison.Ordinal) ||
|
||||
source.Contains("DecodeRefToken", StringComparison.Ordinal) ||
|
||||
source.Contains("GameManager.ItemManager.GetTier", StringComparison.Ordinal) ||
|
||||
|
|
@ -4419,10 +4419,10 @@ static void RequireInventoryEquippedItemDetailsUseEveSurface(string root)
|
|||
"HandleEquippedItemDetailsSurfaceCommand(",
|
||||
"AetheriaEveUnitySurfaceHost.RenderRuntime(",
|
||||
"AetheriaEveUnitySurfaceHost.Hide(_equippedItemDetailsSurfaceDocument)",
|
||||
"AetheriaRuntimeEquippedItemDetailsSurfaceBuilder.Build(ProjectEquippedItemDetailsSurfaceState(",
|
||||
"ProjectEquippedItemDetailsSurfaceState(",
|
||||
"AetheriaRuntimeEquippedItemDetailsSurfaceBuilder.Build(ProjectEquippedItemDetailsSurface(",
|
||||
"AetheriaRuntimeEquippedItemDetailsSurfaceBuilder.Project(",
|
||||
"ProjectEquippedItemObservation(",
|
||||
"ProjectEquippedItemTemperatureControls(",
|
||||
"ProjectEquippedItemBehaviorSections(",
|
||||
"ProjectEquippedItemWeaponGroupControls(",
|
||||
"ProjectEquippedItemActionBarSlots(",
|
||||
"AetheriaRuntimeEquippedItemDetailsSurfaceCommands.TryRead(request, out var command)",
|
||||
|
|
@ -4464,6 +4464,12 @@ static void RequireInventoryEquippedItemDetailsUseEveSurface(string root)
|
|||
"ResolveEquippedItemDetailsSurfaceDocument(",
|
||||
"new EveUiToolkitSurfaceLowerer()",
|
||||
"host.AddComponent<UIDocument>",
|
||||
"new AetheriaRuntimeEquippedItemDetailsSurfaceState(",
|
||||
"ProjectEquippedItemDetailsSurfaceState(",
|
||||
"ProjectEquippedItemBehaviorSections(",
|
||||
"ProjectEquippedItemBehaviorMetric(",
|
||||
"new AetheriaRuntimeEquippedItemSection(",
|
||||
"new AetheriaRuntimeEquippedItemMetric(",
|
||||
"private static EveSurfaceComponent Card(",
|
||||
"private static EveSurfaceComponent Metric(",
|
||||
"private static EveSurfaceComponent Text(",
|
||||
|
|
@ -4516,6 +4522,7 @@ static void RequireInventoryEquippedItemDetailsUseEveSurface(string root)
|
|||
var requiredBuilderSymbols = new[]
|
||||
{
|
||||
"public sealed class AetheriaRuntimeEquippedItemDetailsSurfaceState",
|
||||
"public sealed class AetheriaRuntimeEquippedItemObservation",
|
||||
"public sealed class AetheriaRuntimeEquippedItemSection",
|
||||
"public sealed class AetheriaRuntimeEquippedItemMetric",
|
||||
"public sealed class AetheriaRuntimeEquippedItemControl",
|
||||
|
|
@ -4532,6 +4539,10 @@ static void RequireInventoryEquippedItemDetailsUseEveSurface(string root)
|
|||
"public const string ToggleWeaponGroup = \"aetheria.inventory.equipped_item_details.weapon_group.toggle\"",
|
||||
"public const string BindWeaponGroup = \"aetheria.inventory.equipped_item_details.weapon_group.bind\"",
|
||||
"public const string ClearActionBarBinding = \"aetheria.inventory.equipped_item_details.action_bar.clear\"",
|
||||
"public static AetheriaRuntimeEquippedItemDetailsSurfaceState Project(",
|
||||
"ProjectBehaviorSections(",
|
||||
"ProjectBehaviorMetric(",
|
||||
"AetheriaRuntimeDaemonItemStatQueries.ItemStatRef(",
|
||||
"public static AetheriaRuntimeSurfaceDocument Build(",
|
||||
"new AetheriaRuntimeSurfaceCommandTemplate(Close",
|
||||
"new AetheriaRuntimeSurfaceCommandTemplate(ToggleOverrideShutdown",
|
||||
|
|
@ -9505,6 +9516,33 @@ static void RequireTypedBehaviorMetadataCoverage(string root)
|
|||
var tradeMenu = File.Exists(tradeMenuPath)
|
||||
? File.ReadAllText(tradeMenuPath)
|
||||
: throw new InvalidOperationException("Cannot verify typed behavior metadata coverage; TradeMenu.cs is missing.");
|
||||
var cargoBuilderPath = Path.Combine(
|
||||
root,
|
||||
"Packages",
|
||||
"org.gamecult.aetheria.state",
|
||||
"Runtime",
|
||||
"AetheriaRuntimeCargoItemDetailsSurfaceBuilder.cs");
|
||||
var equippedBuilderPath = Path.Combine(
|
||||
root,
|
||||
"Packages",
|
||||
"org.gamecult.aetheria.state",
|
||||
"Runtime",
|
||||
"AetheriaRuntimeEquippedItemDetailsSurfaceBuilder.cs");
|
||||
var tradeItemBuilderPath = Path.Combine(
|
||||
root,
|
||||
"Packages",
|
||||
"org.gamecult.aetheria.state",
|
||||
"Runtime",
|
||||
"AetheriaRuntimeTradeItemDetailsSurfaceBuilder.cs");
|
||||
var cargoBuilder = File.Exists(cargoBuilderPath)
|
||||
? File.ReadAllText(cargoBuilderPath)
|
||||
: throw new InvalidOperationException("Cannot verify typed behavior metadata coverage; cargo item details builder is missing.");
|
||||
var equippedBuilder = File.Exists(equippedBuilderPath)
|
||||
? File.ReadAllText(equippedBuilderPath)
|
||||
: throw new InvalidOperationException("Cannot verify typed behavior metadata coverage; equipped item details builder is missing.");
|
||||
var tradeItemBuilder = File.Exists(tradeItemBuilderPath)
|
||||
? File.ReadAllText(tradeItemBuilderPath)
|
||||
: throw new InvalidOperationException("Cannot verify typed behavior metadata coverage; trade item details builder is missing.");
|
||||
|
||||
var requiredMetadataSymbols = new[]
|
||||
{
|
||||
|
|
@ -9534,25 +9572,34 @@ static void RequireTypedBehaviorMetadataCoverage(string root)
|
|||
"FormatTemperature"
|
||||
};
|
||||
|
||||
var inventoryBehaviorProjection = cargoBuilder + "\n" + equippedBuilder;
|
||||
var missingInventorySymbols = requiredUiSymbols
|
||||
.Where(symbol => !inventoryMenu.Contains(symbol, StringComparison.Ordinal))
|
||||
.Where(symbol => !inventoryBehaviorProjection.Contains(symbol, StringComparison.Ordinal))
|
||||
.ToArray();
|
||||
if (missingInventorySymbols.Length > 0)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"InventoryMenu no longer renders typed temperature-bearing behavior metadata: " +
|
||||
"Inventory item surface builders no longer render typed temperature-bearing behavior metadata: " +
|
||||
string.Join(", ", missingInventorySymbols));
|
||||
}
|
||||
|
||||
var missingTradeSymbols = requiredUiSymbols
|
||||
.Where(symbol => !tradeMenu.Contains(symbol, StringComparison.Ordinal))
|
||||
.Where(symbol => !tradeItemBuilder.Contains(symbol, StringComparison.Ordinal))
|
||||
.ToArray();
|
||||
if (missingTradeSymbols.Length > 0)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"TradeMenu no longer renders typed temperature-bearing behavior metadata: " +
|
||||
"Trade item surface builder no longer renders typed temperature-bearing behavior metadata: " +
|
||||
string.Join(", ", missingTradeSymbols));
|
||||
}
|
||||
|
||||
if (inventoryMenu.Contains("ProjectCargoItemBehaviorMetric(", StringComparison.Ordinal) ||
|
||||
inventoryMenu.Contains("ProjectEquippedItemBehaviorMetric(", StringComparison.Ordinal) ||
|
||||
tradeMenu.Contains("ProjectTradeItemBehaviorMetric(", StringComparison.Ordinal))
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"Unity menus must not own typed behavior metric projection after runtime surface builders take that role.");
|
||||
}
|
||||
}
|
||||
|
||||
static void RequireNameToolsUsesUiToolkit(string root)
|
||||
|
|
|
|||
|
|
@ -301,7 +301,7 @@ public class InventoryMenu : MonoBehaviour
|
|||
transform,
|
||||
_equippedItemDetailsSurfaceDocument,
|
||||
"Aetheria Inventory Equipped Item Details Surface",
|
||||
AetheriaRuntimeEquippedItemDetailsSurfaceBuilder.Build(ProjectEquippedItemDetailsSurfaceState(item, typedItem)),
|
||||
AetheriaRuntimeEquippedItemDetailsSurfaceBuilder.Build(ProjectEquippedItemDetailsSurface(item, typedItem)),
|
||||
HandleEquippedItemDetailsSurfaceCommand,
|
||||
_equippedItemDetailsSurfaceChrome,
|
||||
ResolveInventorySurfaceStateRef,
|
||||
|
|
@ -407,30 +407,33 @@ public class InventoryMenu : MonoBehaviour
|
|||
};
|
||||
}
|
||||
|
||||
private AetheriaRuntimeEquippedItemDetailsSurfaceState ProjectEquippedItemDetailsSurfaceState(
|
||||
private AetheriaRuntimeEquippedItemDetailsSurfaceState ProjectEquippedItemDetailsSurface(
|
||||
EquippedItem item,
|
||||
AetheriaRuntimeCatalogItem typedItem)
|
||||
{
|
||||
var durability = item.EquippableItem.Durability < .01f
|
||||
? "Item Destroyed!"
|
||||
: $"{(int)(item.EquippableItem.Durability / GetMaxDurability(typedItem, item.EquippableItem) * 100)}%";
|
||||
var hasWeapon = item.GetBehavior<Weapon>() != null;
|
||||
|
||||
return new AetheriaRuntimeEquippedItemDetailsSurfaceState(
|
||||
return AetheriaRuntimeEquippedItemDetailsSurfaceBuilder.Project(
|
||||
typedItem,
|
||||
ProjectEquippedItemObservation(item),
|
||||
BuildEquippedItemTitle(item, typedItem),
|
||||
typedItem.Description ?? "",
|
||||
ActionGameManager.RuntimeCatalog?.GetManufacturer(typedItem)?.Name ?? "GameCult",
|
||||
ActionGameManager.RuntimePlayerSettings.Format((float)typedItem.Mass),
|
||||
durability,
|
||||
ActionGameManager.RuntimePlayerSettings.FormatTemperature(item.Temperature),
|
||||
FormatTemperatureRange(typedItem),
|
||||
item.EquippableItem.OverrideShutdown ? "Enabled" : "Disabled",
|
||||
item.EquippableItem.OverrideShutdown ? "Disable Override" : "Enable Override",
|
||||
ActionGameManager.RuntimePlayerSettings.Format,
|
||||
ActionGameManager.RuntimePlayerSettings.FormatTemperature,
|
||||
ProjectEquippedItemTemperatureControls(item).ToArray(),
|
||||
ProjectEquippedItemBehaviorSections(typedItem, item.EquippableItem).ToArray(),
|
||||
hasWeapon ? ProjectEquippedItemWeaponGroupControls(item).ToArray() : Array.Empty<AetheriaRuntimeEquippedItemControl>(),
|
||||
hasWeapon ? ProjectEquippedItemActionBarSlots(item).ToArray() : Array.Empty<AetheriaRuntimeEquippedItemActionBarSlot>(),
|
||||
DateTime.UtcNow.ToString("O"));
|
||||
hasWeapon ? ProjectEquippedItemActionBarSlots(item).ToArray() : Array.Empty<AetheriaRuntimeEquippedItemActionBarSlot>());
|
||||
}
|
||||
|
||||
private static AetheriaRuntimeEquippedItemObservation ProjectEquippedItemObservation(EquippedItem item)
|
||||
{
|
||||
var equippableItem = item?.EquippableItem;
|
||||
return new AetheriaRuntimeEquippedItemObservation(
|
||||
equippableItem?.ItemKey ?? "",
|
||||
equippableItem?.Quality ?? 1,
|
||||
equippableItem?.Durability ?? 1,
|
||||
item?.Temperature ?? 0,
|
||||
equippableItem != null && equippableItem.OverrideShutdown);
|
||||
}
|
||||
|
||||
private IEnumerable<AetheriaRuntimeEquippedItemTemperatureControl> ProjectEquippedItemTemperatureControls(
|
||||
|
|
@ -520,98 +523,7 @@ public class InventoryMenu : MonoBehaviour
|
|||
equippableItem != null && equippableItem.OverrideShutdown);
|
||||
}
|
||||
|
||||
private IEnumerable<AetheriaRuntimeEquippedItemSection> ProjectEquippedItemBehaviorSections(
|
||||
AetheriaRuntimeCatalogItem typedItem,
|
||||
EquippableItem equippableItem)
|
||||
{
|
||||
foreach (var behavior in typedItem.BehaviorPayloads ?? Array.Empty<AetheriaRuntimeBehaviorPayload>())
|
||||
{
|
||||
if (string.Equals(behavior.Kind, AetheriaRuntimeBehaviorKinds.StatModifier, StringComparison.Ordinal))
|
||||
{
|
||||
var statReference = AetheriaRuntimeBehaviorValueReader.ReadStatReference(FindTypedBehaviorField(behavior, 1)?.Value);
|
||||
var modifier = AetheriaRuntimeBehaviorValueReader.ReadPerformanceStat(FindTypedBehaviorField(behavior, 2)?.Value);
|
||||
var modifierType = AetheriaRuntimeBehaviorValueReader.ReadEnum(
|
||||
FindTypedBehaviorField(behavior, 3)?.Value,
|
||||
StatModifierType.Constant);
|
||||
yield return new AetheriaRuntimeEquippedItemSection(
|
||||
$"{AetheriaRuntimeEquippedItemDetailsSurfaceBuilder.SurfaceId}.behavior.{behavior.Kind}.stat_modifier",
|
||||
"Stat Modifier",
|
||||
new[]
|
||||
{
|
||||
new AetheriaRuntimeEquippedItemMetric(
|
||||
$"{AetheriaRuntimeEquippedItemDetailsSurfaceBuilder.SurfaceId}.behavior.{behavior.Kind}.target",
|
||||
$"{statReference.Target.SplitCamelCase()}:{statReference.Stat.SplitCamelCase()}",
|
||||
$"{(modifierType == StatModifierType.Constant ? "+" : "x")}{FormatCurrentItemStat(modifier, equippableItem)}",
|
||||
AetheriaRuntimeDaemonItemStatQueries.ItemStatRef(
|
||||
equippableItem.ItemKey,
|
||||
behavior.Kind,
|
||||
behavior.Group,
|
||||
2))
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
var metadata = AetheriaRuntimeBehaviorMetadataCatalog.Get(behavior.Kind);
|
||||
if (metadata == null)
|
||||
continue;
|
||||
|
||||
var fields = metadata.DisplayFields
|
||||
.Select(field => ProjectEquippedItemBehaviorMetric(behavior, field, equippableItem))
|
||||
.Where(metric => metric != null)
|
||||
.ToArray();
|
||||
|
||||
if (fields.Length == 0)
|
||||
continue;
|
||||
|
||||
yield return new AetheriaRuntimeEquippedItemSection(
|
||||
$"{AetheriaRuntimeEquippedItemDetailsSurfaceBuilder.SurfaceId}.behavior.{behavior.Kind}",
|
||||
behavior.Kind.FormatTypeName(),
|
||||
fields);
|
||||
}
|
||||
}
|
||||
|
||||
private AetheriaRuntimeEquippedItemMetric ProjectEquippedItemBehaviorMetric(
|
||||
AetheriaRuntimeBehaviorPayload behavior,
|
||||
AetheriaRuntimeBehaviorFieldMetadata field,
|
||||
EquippableItem equippableItem)
|
||||
{
|
||||
var payloadField = FindTypedBehaviorField(behavior, field.Key);
|
||||
if (payloadField == null)
|
||||
return null;
|
||||
|
||||
string value;
|
||||
switch (field.ValueKind)
|
||||
{
|
||||
case AetheriaRuntimeBehaviorFieldValueKind.Number:
|
||||
value = ActionGameManager.RuntimePlayerSettings.Format((float)payloadField.Value.NumberValue);
|
||||
break;
|
||||
case AetheriaRuntimeBehaviorFieldValueKind.Temperature:
|
||||
value = ActionGameManager.RuntimePlayerSettings.FormatTemperature((float)payloadField.Value.NumberValue);
|
||||
break;
|
||||
case AetheriaRuntimeBehaviorFieldValueKind.Integer:
|
||||
value = ((int)payloadField.Value.NumberValue).ToString();
|
||||
break;
|
||||
case AetheriaRuntimeBehaviorFieldValueKind.PerformanceStat:
|
||||
value = FormatCurrentItemStat(payloadField.Value, equippableItem);
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
return new AetheriaRuntimeEquippedItemMetric(
|
||||
$"{AetheriaRuntimeEquippedItemDetailsSurfaceBuilder.SurfaceId}.behavior.{behavior.Kind}.{field.Key}",
|
||||
field.Name.SplitCamelCase(),
|
||||
value,
|
||||
field.ValueKind == AetheriaRuntimeBehaviorFieldValueKind.PerformanceStat
|
||||
? AetheriaRuntimeDaemonItemStatQueries.ItemStatRef(
|
||||
equippableItem.ItemKey,
|
||||
behavior.Kind,
|
||||
behavior.Group,
|
||||
field.Key)
|
||||
: "");
|
||||
}
|
||||
|
||||
private string BuildEquippedItemTitle(EquippedItem item, AetheriaRuntimeCatalogItem typedItem)
|
||||
private string BuildEquippedItemTitle(EquippedItem item, AetheriaRuntimeCatalogItem typedItem)
|
||||
{
|
||||
return $"{typedItem?.Name ?? "Unknown Item"} ({FormatItemTier(typedItem, item.EquippableItem)})";
|
||||
}
|
||||
|
|
@ -627,11 +539,6 @@ private string BuildEquippedItemTitle(EquippedItem item, AetheriaRuntimeCatalogI
|
|||
: "";
|
||||
}
|
||||
|
||||
private static string FormatCurrentItemStat(PerformanceStat stat, EquippableItem item)
|
||||
{
|
||||
return FormatCurrentItemStat(ToRuntimeBehaviorValue(stat), item);
|
||||
}
|
||||
|
||||
private static string FormatCurrentItemStat(AetheriaRuntimeBehaviorValue stat, EquippableItem item)
|
||||
{
|
||||
return ActionGameManager.RuntimePlayerSettings.Format(
|
||||
|
|
@ -696,157 +603,6 @@ private string BuildEquippedItemTitle(EquippedItem item, AetheriaRuntimeCatalogI
|
|||
string.Equals(item.ItemKey ?? "", itemKey ?? "", StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
private static AetheriaRuntimeBehaviorValue ToRuntimeBehaviorValue(PerformanceStat stat)
|
||||
{
|
||||
return new AetheriaRuntimeBehaviorValue(
|
||||
"performance-stat",
|
||||
"",
|
||||
0,
|
||||
false,
|
||||
"",
|
||||
"",
|
||||
new[]
|
||||
{
|
||||
Number(stat?.Min ?? 0),
|
||||
Number(stat?.Max ?? 0),
|
||||
Number(stat?.HeatExponentMultiplier ?? 0),
|
||||
Number(stat?.DurabilityExponentMultiplier ?? 0),
|
||||
Number(stat?.QualityExponent ?? 0),
|
||||
ToRuntimeStatRecipeValue(stat?.Recipe)
|
||||
},
|
||||
Array.Empty<AetheriaRuntimeBehaviorMapEntry>());
|
||||
}
|
||||
|
||||
private static AetheriaRuntimeBehaviorValue ToRuntimeStatRecipeValue(StatRecipe recipe)
|
||||
{
|
||||
if (recipe == null)
|
||||
return Number(0);
|
||||
|
||||
return new AetheriaRuntimeBehaviorValue(
|
||||
"stat-recipe",
|
||||
"",
|
||||
0,
|
||||
false,
|
||||
"",
|
||||
"",
|
||||
new[]
|
||||
{
|
||||
Number(recipe.BaseValue),
|
||||
new AetheriaRuntimeBehaviorValue(
|
||||
"stat-recipe-modifiers",
|
||||
"",
|
||||
0,
|
||||
false,
|
||||
"",
|
||||
"",
|
||||
(recipe.Modifiers ?? Array.Empty<StatRecipeModifier>())
|
||||
.Where(modifier => modifier != null)
|
||||
.Select(ToRuntimeStatRecipeModifierValue)
|
||||
.ToArray(),
|
||||
Array.Empty<AetheriaRuntimeBehaviorMapEntry>())
|
||||
},
|
||||
Array.Empty<AetheriaRuntimeBehaviorMapEntry>());
|
||||
}
|
||||
|
||||
private static AetheriaRuntimeBehaviorValue ToRuntimeStatRecipeModifierValue(StatRecipeModifier modifier)
|
||||
{
|
||||
return new AetheriaRuntimeBehaviorValue(
|
||||
"stat-recipe-modifier",
|
||||
"",
|
||||
0,
|
||||
false,
|
||||
"",
|
||||
"",
|
||||
new[]
|
||||
{
|
||||
Text(ConditionToken(modifier.Condition)),
|
||||
Text(OperationToken(modifier.Operation)),
|
||||
Number(modifier.Amount),
|
||||
Number(0),
|
||||
Bool(modifier.Enabled)
|
||||
},
|
||||
Array.Empty<AetheriaRuntimeBehaviorMapEntry>());
|
||||
}
|
||||
|
||||
private static string ConditionToken(StatConditionMask condition)
|
||||
{
|
||||
switch (condition)
|
||||
{
|
||||
case StatConditionMask.Quality:
|
||||
return AetheriaRuntimeStatRecipeConditions.Quality;
|
||||
case StatConditionMask.Durability:
|
||||
return AetheriaRuntimeStatRecipeConditions.Durability;
|
||||
case StatConditionMask.Heat:
|
||||
return AetheriaRuntimeStatRecipeConditions.Heat;
|
||||
case StatConditionMask.Charge:
|
||||
return AetheriaRuntimeStatRecipeConditions.Charge;
|
||||
case StatConditionMask.Ammo:
|
||||
return AetheriaRuntimeStatRecipeConditions.Ammo;
|
||||
case StatConditionMask.Range:
|
||||
return AetheriaRuntimeStatRecipeConditions.Range;
|
||||
case StatConditionMask.Integrity:
|
||||
return AetheriaRuntimeStatRecipeConditions.Integrity;
|
||||
case StatConditionMask.PilotSkill:
|
||||
return AetheriaRuntimeStatRecipeConditions.PilotSkill;
|
||||
case StatConditionMask.Environment:
|
||||
return AetheriaRuntimeStatRecipeConditions.Environment;
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private static string OperationToken(StatModifierOperation operation)
|
||||
{
|
||||
switch (operation)
|
||||
{
|
||||
case StatModifierOperation.Multiply:
|
||||
return AetheriaRuntimeStatRecipeOperations.Multiply;
|
||||
case StatModifierOperation.Override:
|
||||
return AetheriaRuntimeStatRecipeOperations.Override;
|
||||
default:
|
||||
return AetheriaRuntimeStatRecipeOperations.Add;
|
||||
}
|
||||
}
|
||||
|
||||
private static AetheriaRuntimeBehaviorValue Number(double value)
|
||||
{
|
||||
return new AetheriaRuntimeBehaviorValue(
|
||||
"number",
|
||||
"",
|
||||
value,
|
||||
false,
|
||||
"",
|
||||
"",
|
||||
Array.Empty<AetheriaRuntimeBehaviorValue>(),
|
||||
Array.Empty<AetheriaRuntimeBehaviorMapEntry>());
|
||||
}
|
||||
|
||||
private static AetheriaRuntimeBehaviorValue Text(string value)
|
||||
{
|
||||
return new AetheriaRuntimeBehaviorValue(
|
||||
"string",
|
||||
value ?? "",
|
||||
0,
|
||||
false,
|
||||
"",
|
||||
"",
|
||||
Array.Empty<AetheriaRuntimeBehaviorValue>(),
|
||||
Array.Empty<AetheriaRuntimeBehaviorMapEntry>());
|
||||
}
|
||||
|
||||
private static AetheriaRuntimeBehaviorValue Bool(bool value)
|
||||
{
|
||||
return new AetheriaRuntimeBehaviorValue(
|
||||
"bool",
|
||||
"",
|
||||
0,
|
||||
value,
|
||||
"",
|
||||
"",
|
||||
Array.Empty<AetheriaRuntimeBehaviorValue>(),
|
||||
Array.Empty<AetheriaRuntimeBehaviorMapEntry>());
|
||||
}
|
||||
|
||||
private static bool IsWeaponGroupAssigned(EquippedItem item, int groupIndex)
|
||||
{
|
||||
return item?.Entity?.WeaponGroups != null &&
|
||||
|
|
@ -935,43 +691,6 @@ private string BuildEquippedItemTitle(EquippedItem item, AetheriaRuntimeCatalogI
|
|||
return ActionGameManager.RuntimeCatalog?.FindItem(item?.ItemKey ?? "");
|
||||
}
|
||||
|
||||
private static float GetCargoItemMass(ItemInstance item, AetheriaRuntimeCatalogItem typedItem)
|
||||
{
|
||||
if (typedItem == null)
|
||||
return 0f;
|
||||
|
||||
return item is SimpleCommodity simpleCommodity
|
||||
? (float)typedItem.Mass * simpleCommodity.Quantity
|
||||
: (float)typedItem.Mass;
|
||||
}
|
||||
|
||||
private static float GetMaxDurability(AetheriaRuntimeCatalogItem typedItem, EquippableItem item)
|
||||
{
|
||||
if (typedItem != null && typedItem.Durability > 0)
|
||||
return (float)typedItem.Durability;
|
||||
|
||||
return Math.Max(item?.Durability ?? 1f, 1f);
|
||||
}
|
||||
|
||||
private static string FormatTemperatureRange(AetheriaRuntimeCatalogItem item)
|
||||
{
|
||||
if (item.MaximumTemperature > item.MinimumTemperature)
|
||||
{
|
||||
return
|
||||
$"{ActionGameManager.RuntimePlayerSettings.FormatTemperature((float)item.MinimumTemperature)} to " +
|
||||
$"{ActionGameManager.RuntimePlayerSettings.FormatTemperature((float)item.MaximumTemperature)}";
|
||||
}
|
||||
|
||||
return "No typed thermal range";
|
||||
}
|
||||
|
||||
private static AetheriaRuntimeBehaviorField FindTypedBehaviorField(AetheriaRuntimeBehaviorPayload behavior, int? key)
|
||||
{
|
||||
return key == null
|
||||
? null
|
||||
: behavior.Fields.FirstOrDefault(field => field.Key == key.Value);
|
||||
}
|
||||
|
||||
private static int2 RotateTypedShapeCell(
|
||||
AetheriaRuntimeShapeCell cell,
|
||||
AetheriaRuntimeCatalogItem item,
|
||||
|
|
|
|||
|
|
@ -156,6 +156,29 @@ namespace GameCult.Aetheria.State.Verse
|
|||
public bool HasWeaponControls => WeaponGroupControls.Count > 0;
|
||||
}
|
||||
|
||||
public sealed class AetheriaRuntimeEquippedItemObservation
|
||||
{
|
||||
public AetheriaRuntimeEquippedItemObservation(
|
||||
string itemKey,
|
||||
double quality,
|
||||
double durability,
|
||||
double temperature,
|
||||
bool overrideShutdown)
|
||||
{
|
||||
ItemKey = itemKey ?? "";
|
||||
Quality = quality;
|
||||
Durability = durability;
|
||||
Temperature = temperature;
|
||||
OverrideShutdown = overrideShutdown;
|
||||
}
|
||||
|
||||
public string ItemKey { get; }
|
||||
public double Quality { get; }
|
||||
public double Durability { get; }
|
||||
public double Temperature { get; }
|
||||
public bool OverrideShutdown { get; }
|
||||
}
|
||||
|
||||
public static class AetheriaRuntimeEquippedItemDetailsSurfaceBuilder
|
||||
{
|
||||
public const string SurfaceId = "aetheria.inventory.equipped_item_details";
|
||||
|
|
@ -166,6 +189,61 @@ namespace GameCult.Aetheria.State.Verse
|
|||
public const string BindWeaponGroup = "aetheria.inventory.equipped_item_details.weapon_group.bind";
|
||||
public const string ClearActionBarBinding = "aetheria.inventory.equipped_item_details.action_bar.clear";
|
||||
|
||||
public static AetheriaRuntimeEquippedItemDetailsSurfaceState Project(
|
||||
AetheriaRuntimeCatalogItem typedItem,
|
||||
AetheriaRuntimeEquippedItemObservation item,
|
||||
string title,
|
||||
string manufacturer,
|
||||
Func<float, string> formatValue,
|
||||
Func<float, string> formatTemperature,
|
||||
IReadOnlyList<AetheriaRuntimeEquippedItemTemperatureControl> temperatureControls,
|
||||
IReadOnlyList<AetheriaRuntimeEquippedItemControl> weaponGroupControls,
|
||||
IReadOnlyList<AetheriaRuntimeEquippedItemActionBarSlot> actionBarSlots,
|
||||
DateTime updatedAtUtc = default(DateTime))
|
||||
{
|
||||
if (updatedAtUtc == default(DateTime))
|
||||
updatedAtUtc = DateTime.UtcNow;
|
||||
|
||||
if (typedItem == null)
|
||||
{
|
||||
return new AetheriaRuntimeEquippedItemDetailsSurfaceState(
|
||||
title ?? "",
|
||||
"",
|
||||
manufacturer ?? "",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
temperatureControls ?? Array.Empty<AetheriaRuntimeEquippedItemTemperatureControl>(),
|
||||
Array.Empty<AetheriaRuntimeEquippedItemSection>(),
|
||||
weaponGroupControls ?? Array.Empty<AetheriaRuntimeEquippedItemControl>(),
|
||||
actionBarSlots ?? Array.Empty<AetheriaRuntimeEquippedItemActionBarSlot>(),
|
||||
updatedAtUtc.ToString("O", CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
var durability = item != null && item.Durability < .01
|
||||
? "Item Destroyed!"
|
||||
: $"{(int)((item?.Durability ?? 1) / MaxDurability(typedItem, item) * 100)}%";
|
||||
|
||||
return new AetheriaRuntimeEquippedItemDetailsSurfaceState(
|
||||
title ?? typedItem.Name,
|
||||
typedItem.Description ?? "",
|
||||
manufacturer ?? "",
|
||||
FormatValue(typedItem.Mass, formatValue),
|
||||
durability,
|
||||
FormatTemperature(item?.Temperature ?? 0, formatTemperature),
|
||||
FormatTemperatureRange(typedItem, formatTemperature),
|
||||
item != null && item.OverrideShutdown ? "Enabled" : "Disabled",
|
||||
item != null && item.OverrideShutdown ? "Disable Override" : "Enable Override",
|
||||
temperatureControls ?? Array.Empty<AetheriaRuntimeEquippedItemTemperatureControl>(),
|
||||
ProjectBehaviorSections(typedItem, item, formatValue, formatTemperature).ToArray(),
|
||||
weaponGroupControls ?? Array.Empty<AetheriaRuntimeEquippedItemControl>(),
|
||||
actionBarSlots ?? Array.Empty<AetheriaRuntimeEquippedItemActionBarSlot>(),
|
||||
updatedAtUtc.ToString("O", CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
public static AetheriaRuntimeSurfaceDocument Build(
|
||||
AetheriaRuntimeEquippedItemDetailsSurfaceState state,
|
||||
long version = 1)
|
||||
|
|
@ -329,6 +407,419 @@ namespace GameCult.Aetheria.State.Verse
|
|||
.ToArray()).Trim('-');
|
||||
}
|
||||
|
||||
private static IEnumerable<AetheriaRuntimeEquippedItemSection> ProjectBehaviorSections(
|
||||
AetheriaRuntimeCatalogItem typedItem,
|
||||
AetheriaRuntimeEquippedItemObservation item,
|
||||
Func<float, string> formatValue,
|
||||
Func<float, string> formatTemperature)
|
||||
{
|
||||
foreach (var behavior in typedItem.BehaviorPayloads ?? Array.Empty<AetheriaRuntimeBehaviorPayload>())
|
||||
{
|
||||
if (string.Equals(behavior.Kind, AetheriaRuntimeBehaviorKinds.StatModifier, StringComparison.Ordinal))
|
||||
{
|
||||
var statReference = ReadStatReference(FindTypedBehaviorField(behavior, 1)?.Value);
|
||||
var modifier = ReadPerformanceStat(FindTypedBehaviorField(behavior, 2)?.Value);
|
||||
var modifierType = ReadEnum(
|
||||
FindTypedBehaviorField(behavior, 3)?.Value,
|
||||
AetheriaRuntimeEquippedItemStatModifierType.Constant);
|
||||
yield return new AetheriaRuntimeEquippedItemSection(
|
||||
$"{SurfaceId}.behavior.{behavior.Kind}.stat_modifier",
|
||||
"Stat Modifier",
|
||||
new[]
|
||||
{
|
||||
new AetheriaRuntimeEquippedItemMetric(
|
||||
$"{SurfaceId}.behavior.{behavior.Kind}.target",
|
||||
$"{SplitCamelCase(statReference.Target)}:{SplitCamelCase(statReference.Stat)}",
|
||||
$"{(modifierType == AetheriaRuntimeEquippedItemStatModifierType.Constant ? "+" : "x")}{FormatCurrentItemStat(modifier, item, formatValue)}",
|
||||
AetheriaRuntimeDaemonItemStatQueries.ItemStatRef(
|
||||
item?.ItemKey ?? "",
|
||||
behavior.Kind,
|
||||
behavior.Group,
|
||||
2))
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
var metadata = AetheriaRuntimeBehaviorMetadataCatalog.Get(behavior.Kind);
|
||||
if (metadata == null)
|
||||
continue;
|
||||
|
||||
var fields = metadata.DisplayFields
|
||||
.Select(field => ProjectBehaviorMetric(behavior, field, item, formatValue, formatTemperature))
|
||||
.Where(metric => metric != null)
|
||||
.ToArray();
|
||||
|
||||
if (fields.Length == 0)
|
||||
continue;
|
||||
|
||||
yield return new AetheriaRuntimeEquippedItemSection(
|
||||
$"{SurfaceId}.behavior.{behavior.Kind}",
|
||||
FormatTypeName(behavior.Kind),
|
||||
fields);
|
||||
}
|
||||
}
|
||||
|
||||
private static AetheriaRuntimeEquippedItemMetric ProjectBehaviorMetric(
|
||||
AetheriaRuntimeBehaviorPayload behavior,
|
||||
AetheriaRuntimeBehaviorFieldMetadata field,
|
||||
AetheriaRuntimeEquippedItemObservation item,
|
||||
Func<float, string> formatValue,
|
||||
Func<float, string> formatTemperature)
|
||||
{
|
||||
var payloadField = FindTypedBehaviorField(behavior, field.Key);
|
||||
if (payloadField == null)
|
||||
return null;
|
||||
|
||||
string value;
|
||||
switch (field.ValueKind)
|
||||
{
|
||||
case AetheriaRuntimeBehaviorFieldValueKind.Number:
|
||||
value = FormatValue(payloadField.Value.NumberValue, formatValue);
|
||||
break;
|
||||
case AetheriaRuntimeBehaviorFieldValueKind.Temperature:
|
||||
value = FormatTemperature(payloadField.Value.NumberValue, formatTemperature);
|
||||
break;
|
||||
case AetheriaRuntimeBehaviorFieldValueKind.Integer:
|
||||
value = ((int)payloadField.Value.NumberValue).ToString(CultureInfo.InvariantCulture);
|
||||
break;
|
||||
case AetheriaRuntimeBehaviorFieldValueKind.PerformanceStat:
|
||||
value = FormatCurrentItemStat(payloadField.Value, item, formatValue);
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
return new AetheriaRuntimeEquippedItemMetric(
|
||||
$"{SurfaceId}.behavior.{behavior.Kind}.{field.Key}",
|
||||
SplitCamelCase(field.Name),
|
||||
value,
|
||||
field.ValueKind == AetheriaRuntimeBehaviorFieldValueKind.PerformanceStat
|
||||
? AetheriaRuntimeDaemonItemStatQueries.ItemStatRef(
|
||||
item?.ItemKey ?? "",
|
||||
behavior.Kind,
|
||||
behavior.Group,
|
||||
field.Key)
|
||||
: "");
|
||||
}
|
||||
|
||||
private static string FormatCurrentItemStat(
|
||||
AetheriaRuntimePerformanceStat stat,
|
||||
AetheriaRuntimeEquippedItemObservation item,
|
||||
Func<float, string> formatValue)
|
||||
{
|
||||
return FormatValue(
|
||||
AetheriaRuntimeDaemonItemStatQueries.EvaluatePerformanceStat(
|
||||
ToBehaviorValue(stat),
|
||||
ToLoadoutItem(item),
|
||||
item?.Temperature ?? 0),
|
||||
formatValue);
|
||||
}
|
||||
|
||||
private static string FormatCurrentItemStat(
|
||||
AetheriaRuntimeBehaviorValue stat,
|
||||
AetheriaRuntimeEquippedItemObservation item,
|
||||
Func<float, string> formatValue)
|
||||
{
|
||||
return FormatValue(
|
||||
AetheriaRuntimeDaemonItemStatQueries.EvaluatePerformanceStat(
|
||||
stat,
|
||||
ToLoadoutItem(item),
|
||||
item?.Temperature ?? 0),
|
||||
formatValue);
|
||||
}
|
||||
|
||||
private static AetheriaRuntimeLoadoutItemCommit ToLoadoutItem(AetheriaRuntimeEquippedItemObservation item)
|
||||
{
|
||||
return AetheriaRuntimeDaemonItemStatQueries.ItemCommit(
|
||||
item?.ItemKey ?? "",
|
||||
item?.Quality ?? 1,
|
||||
item?.Durability ?? 1,
|
||||
enabled: true,
|
||||
overrideShutdown: item != null && item.OverrideShutdown);
|
||||
}
|
||||
|
||||
private static double MaxDurability(
|
||||
AetheriaRuntimeCatalogItem typedItem,
|
||||
AetheriaRuntimeEquippedItemObservation item)
|
||||
{
|
||||
if (typedItem != null && typedItem.Durability > 0)
|
||||
return typedItem.Durability;
|
||||
|
||||
return Math.Max(item?.Durability ?? 1, 1);
|
||||
}
|
||||
|
||||
private static string FormatTemperatureRange(
|
||||
AetheriaRuntimeCatalogItem item,
|
||||
Func<float, string> formatTemperature)
|
||||
{
|
||||
if (item.MaximumTemperature > item.MinimumTemperature)
|
||||
{
|
||||
return
|
||||
$"{FormatTemperature(item.MinimumTemperature, formatTemperature)} to " +
|
||||
$"{FormatTemperature(item.MaximumTemperature, formatTemperature)}";
|
||||
}
|
||||
|
||||
return "No typed thermal range";
|
||||
}
|
||||
|
||||
private static AetheriaRuntimeBehaviorField FindTypedBehaviorField(
|
||||
AetheriaRuntimeBehaviorPayload behavior,
|
||||
int? key)
|
||||
{
|
||||
return key == null
|
||||
? null
|
||||
: behavior?.Fields?.FirstOrDefault(field => field.Key == key.Value);
|
||||
}
|
||||
|
||||
private static AetheriaRuntimePerformanceStat ReadPerformanceStat(AetheriaRuntimeBehaviorValue value)
|
||||
{
|
||||
return new AetheriaRuntimePerformanceStat(
|
||||
ChildNumber(value, 0),
|
||||
ChildNumber(value, 1),
|
||||
ChildNumber(value, 2),
|
||||
ChildNumber(value, 3),
|
||||
ChildNumber(value, 4),
|
||||
ReadStatRecipe(ChildValue(value, 5)));
|
||||
}
|
||||
|
||||
private static AetheriaRuntimeStatRecipe ReadStatRecipe(AetheriaRuntimeBehaviorValue value)
|
||||
{
|
||||
if (value == null || value.Children.Count == 0)
|
||||
return null;
|
||||
|
||||
var modifiers = ChildValue(value, 1)?.Children
|
||||
.Select(ReadStatRecipeModifier)
|
||||
.Where(modifier => modifier != null)
|
||||
.ToArray() ?? Array.Empty<AetheriaRuntimeStatRecipeModifier>();
|
||||
|
||||
return new AetheriaRuntimeStatRecipe(ChildNumber(value, 0), modifiers);
|
||||
}
|
||||
|
||||
private static AetheriaRuntimeStatRecipeModifier ReadStatRecipeModifier(AetheriaRuntimeBehaviorValue value)
|
||||
{
|
||||
if (value == null)
|
||||
return null;
|
||||
|
||||
return new AetheriaRuntimeStatRecipeModifier(
|
||||
ChildString(value, 0),
|
||||
ChildString(value, 1),
|
||||
ChildNumber(value, 2),
|
||||
ReadCurveKeys(ChildValue(value, 3)),
|
||||
value.Children.Count <= 4 || ChildValue(value, 4)?.BoolValue == true);
|
||||
}
|
||||
|
||||
private static IReadOnlyList<AetheriaRuntimeCurveKey> ReadCurveKeys(AetheriaRuntimeBehaviorValue value)
|
||||
{
|
||||
if (value?.Children == null || value.Children.Count == 0)
|
||||
return Array.Empty<AetheriaRuntimeCurveKey>();
|
||||
|
||||
return value.Children
|
||||
.Where(key => key.Children.Count >= 4)
|
||||
.Select(key => new AetheriaRuntimeCurveKey(
|
||||
ChildNumber(key, 0),
|
||||
ChildNumber(key, 1),
|
||||
ChildNumber(key, 2),
|
||||
ChildNumber(key, 3)))
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
private static AetheriaRuntimeEquippedItemStatReference ReadStatReference(AetheriaRuntimeBehaviorValue value)
|
||||
{
|
||||
return new AetheriaRuntimeEquippedItemStatReference(
|
||||
ChildString(value, 1),
|
||||
ChildString(value, 2));
|
||||
}
|
||||
|
||||
private static T ReadEnum<T>(AetheriaRuntimeBehaviorValue value, T fallback) where T : struct
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(value?.StringValue) && Enum.TryParse(value.StringValue, true, out T parsed))
|
||||
return parsed;
|
||||
|
||||
return value != null && Enum.IsDefined(typeof(T), (int)value.NumberValue)
|
||||
? (T)Enum.ToObject(typeof(T), (int)value.NumberValue)
|
||||
: fallback;
|
||||
}
|
||||
|
||||
private static AetheriaRuntimeBehaviorValue ToBehaviorValue(AetheriaRuntimePerformanceStat stat)
|
||||
{
|
||||
return new AetheriaRuntimeBehaviorValue(
|
||||
"performance-stat",
|
||||
"",
|
||||
0,
|
||||
false,
|
||||
"",
|
||||
"",
|
||||
new[]
|
||||
{
|
||||
Number(stat?.Min ?? 0),
|
||||
Number(stat?.Max ?? 0),
|
||||
Number(stat?.HeatExponentMultiplier ?? 0),
|
||||
Number(stat?.DurabilityExponentMultiplier ?? 0),
|
||||
Number(stat?.QualityExponent ?? 0),
|
||||
StatRecipeValue(stat?.Recipe)
|
||||
},
|
||||
EmptyMapEntries());
|
||||
}
|
||||
|
||||
private static AetheriaRuntimeBehaviorValue StatRecipeValue(AetheriaRuntimeStatRecipe recipe)
|
||||
{
|
||||
if (recipe == null)
|
||||
return EmptyValue("stat-recipe");
|
||||
|
||||
return new AetheriaRuntimeBehaviorValue(
|
||||
"stat-recipe",
|
||||
"",
|
||||
0,
|
||||
false,
|
||||
"",
|
||||
"",
|
||||
new[]
|
||||
{
|
||||
Number(recipe.BaseValue),
|
||||
new AetheriaRuntimeBehaviorValue(
|
||||
"stat-recipe-modifiers",
|
||||
"",
|
||||
0,
|
||||
false,
|
||||
"",
|
||||
"",
|
||||
(recipe.Modifiers ?? Array.Empty<AetheriaRuntimeStatRecipeModifier>())
|
||||
.Select(StatRecipeModifierValue)
|
||||
.ToArray(),
|
||||
EmptyMapEntries())
|
||||
},
|
||||
EmptyMapEntries());
|
||||
}
|
||||
|
||||
private static AetheriaRuntimeBehaviorValue StatRecipeModifierValue(AetheriaRuntimeStatRecipeModifier modifier)
|
||||
{
|
||||
if (modifier == null)
|
||||
return EmptyValue("stat-recipe-modifier");
|
||||
|
||||
return new AetheriaRuntimeBehaviorValue(
|
||||
"stat-recipe-modifier",
|
||||
"",
|
||||
0,
|
||||
false,
|
||||
"",
|
||||
"",
|
||||
new[]
|
||||
{
|
||||
TextValue(modifier.Condition),
|
||||
TextValue(modifier.Operation),
|
||||
Number(modifier.Amount),
|
||||
CurveValue(modifier.CurveKeys),
|
||||
BoolValue(modifier.Enabled)
|
||||
},
|
||||
EmptyMapEntries());
|
||||
}
|
||||
|
||||
private static AetheriaRuntimeBehaviorValue CurveValue(IReadOnlyList<AetheriaRuntimeCurveKey> keys)
|
||||
{
|
||||
return new AetheriaRuntimeBehaviorValue(
|
||||
"curve",
|
||||
"",
|
||||
0,
|
||||
false,
|
||||
"",
|
||||
"",
|
||||
(keys ?? Array.Empty<AetheriaRuntimeCurveKey>())
|
||||
.Select(key => new AetheriaRuntimeBehaviorValue(
|
||||
"curve-key",
|
||||
"",
|
||||
0,
|
||||
false,
|
||||
"",
|
||||
"",
|
||||
new[]
|
||||
{
|
||||
Number(key.Time),
|
||||
Number(key.Value),
|
||||
Number(key.InTangent),
|
||||
Number(key.OutTangent)
|
||||
},
|
||||
EmptyMapEntries()))
|
||||
.ToArray(),
|
||||
EmptyMapEntries());
|
||||
}
|
||||
|
||||
private static AetheriaRuntimeBehaviorValue Number(double value)
|
||||
{
|
||||
return new AetheriaRuntimeBehaviorValue("", "", value, false, "", "", Array.Empty<AetheriaRuntimeBehaviorValue>(), EmptyMapEntries());
|
||||
}
|
||||
|
||||
private static AetheriaRuntimeBehaviorValue TextValue(string value)
|
||||
{
|
||||
return new AetheriaRuntimeBehaviorValue("", value ?? "", 0, false, "", "", Array.Empty<AetheriaRuntimeBehaviorValue>(), EmptyMapEntries());
|
||||
}
|
||||
|
||||
private static AetheriaRuntimeBehaviorValue BoolValue(bool value)
|
||||
{
|
||||
return new AetheriaRuntimeBehaviorValue("", "", 0, value, "", "", Array.Empty<AetheriaRuntimeBehaviorValue>(), EmptyMapEntries());
|
||||
}
|
||||
|
||||
private static AetheriaRuntimeBehaviorValue EmptyValue(string kind)
|
||||
{
|
||||
return new AetheriaRuntimeBehaviorValue(kind ?? "", "", 0, false, "", "", Array.Empty<AetheriaRuntimeBehaviorValue>(), EmptyMapEntries());
|
||||
}
|
||||
|
||||
private static IReadOnlyList<AetheriaRuntimeBehaviorMapEntry> EmptyMapEntries()
|
||||
{
|
||||
return Array.Empty<AetheriaRuntimeBehaviorMapEntry>();
|
||||
}
|
||||
|
||||
private static double ChildNumber(AetheriaRuntimeBehaviorValue value, int index)
|
||||
{
|
||||
return value != null && value.Children.Count > index ? value.Children[index].NumberValue : 0;
|
||||
}
|
||||
|
||||
private static string ChildString(AetheriaRuntimeBehaviorValue value, int index)
|
||||
{
|
||||
return value != null && value.Children.Count > index ? value.Children[index].StringValue ?? "" : "";
|
||||
}
|
||||
|
||||
private static AetheriaRuntimeBehaviorValue ChildValue(AetheriaRuntimeBehaviorValue value, int index)
|
||||
{
|
||||
return value != null && value.Children.Count > index ? value.Children[index] : null;
|
||||
}
|
||||
|
||||
private static string FormatValue(
|
||||
double value,
|
||||
Func<float, string> formatValue)
|
||||
{
|
||||
return formatValue == null
|
||||
? value.ToString("0.###", CultureInfo.InvariantCulture)
|
||||
: formatValue((float)value);
|
||||
}
|
||||
|
||||
private static string FormatTemperature(
|
||||
double value,
|
||||
Func<float, string> formatTemperature)
|
||||
{
|
||||
return formatTemperature == null
|
||||
? value.ToString("0.###", CultureInfo.InvariantCulture)
|
||||
: formatTemperature((float)value);
|
||||
}
|
||||
|
||||
private static string FormatTypeName(string typeName)
|
||||
{
|
||||
if (string.IsNullOrEmpty(typeName))
|
||||
return "";
|
||||
|
||||
return SplitCamelCase(typeName.StartsWith("I", StringComparison.Ordinal) && typeName.Length > 1
|
||||
? typeName.Substring(1)
|
||||
: typeName);
|
||||
}
|
||||
|
||||
private static string SplitCamelCase(string value)
|
||||
{
|
||||
if (string.IsNullOrEmpty(value))
|
||||
return "";
|
||||
|
||||
return string.Concat(value.Select((character, index) =>
|
||||
index > 0 && char.IsUpper(character) ? " " + character : character.ToString()));
|
||||
}
|
||||
|
||||
private static AetheriaRuntimeSurfaceComponent Card(
|
||||
string id,
|
||||
string title,
|
||||
|
|
@ -441,6 +932,24 @@ namespace GameCult.Aetheria.State.Verse
|
|||
ClearActionBarBinding = 6
|
||||
}
|
||||
|
||||
internal enum AetheriaRuntimeEquippedItemStatModifierType
|
||||
{
|
||||
Constant = 0,
|
||||
Multiplier = 1
|
||||
}
|
||||
|
||||
internal readonly struct AetheriaRuntimeEquippedItemStatReference
|
||||
{
|
||||
public AetheriaRuntimeEquippedItemStatReference(string target, string stat)
|
||||
{
|
||||
Target = target ?? "";
|
||||
Stat = stat ?? "";
|
||||
}
|
||||
|
||||
public string Target { get; }
|
||||
public string Stat { get; }
|
||||
}
|
||||
|
||||
public readonly struct AetheriaRuntimeEquippedItemDetailsCommand
|
||||
{
|
||||
public AetheriaRuntimeEquippedItemDetailsCommand(
|
||||
|
|
|
|||
Loading…
Reference in a new issue