Use typed item mass and thermal facts

This commit is contained in:
Meta Vens 2026-06-14 04:35:51 +01:00
commit a8f6df5bb1
160 changed files with 344 additions and 275 deletions

Binary file not shown.

View file

@ -387,6 +387,7 @@ internal static class LegacyCatalogReader
LegacyId = legacyId,
Description = description,
Mass = GetDouble(payload, 4),
SpecificHeat = GetPositiveDoubleOrDefault(payload, 6, 1),
Volume = shape.OccupiedCells,
ManufacturerLegacyId = GetOptionalGuid(payload, 3),
Price = GetInt(payload, 8),
@ -588,6 +589,12 @@ internal static class LegacyCatalogReader
};
}
private static double GetPositiveDoubleOrDefault(IReadOnlyDictionary<int, object?> payload, int key, double fallback)
{
var value = GetDouble(payload, key);
return value > 0 ? value : fallback;
}
private static int GetInt(IReadOnlyDictionary<int, object?> payload, int key)
{
if (!payload.TryGetValue(key, out var value) || value == null)

View file

@ -23,6 +23,7 @@ internal static class AetheriaRuntimeCatalogSnapshotMapper
item.ManufacturerLegacyId,
item.Price,
item.Mass,
item.SpecificHeat,
item.Volume,
item.ShapeWidth,
item.ShapeHeight,

View file

@ -47,6 +47,7 @@ if (nameFiles.Any(nameFile => nameFile.Names.Length == 0 || nameFile.Names.Lengt
var pricedItems = items.Count(item => item.Price > 0);
var manufacturedItems = items.Count(item => !string.IsNullOrWhiteSpace(item.ManufacturerLegacyId));
var specificHeatItems = items.Count(item => item.SpecificHeat > 0);
var shapedItems = items.Count(item => item.ShapeWidth > 0 && item.ShapeHeight > 0 && item.OccupiedCells > 0);
var shapedMaskItems = items.Count(item => item.ShapeCells.Length > 0);
var interiorShapeItems = items.Count(item => item.InteriorShapeCells.Length > 0);
@ -89,6 +90,12 @@ if (manufacturedItems == 0)
throw new InvalidOperationException("Typed item definitions did not import any manufacturer legacy IDs.");
}
if (specificHeatItems != items.Length)
{
throw new InvalidOperationException(
$"Typed item definitions did not import positive specific heat for every item: {specificHeatItems}/{items.Length}.");
}
if (shapedItems == 0)
{
throw new InvalidOperationException("Typed item definitions did not import any shape dimensions.");
@ -346,7 +353,7 @@ if (string.IsNullOrWhiteSpace(quarantine.CatalogFingerprint))
Console.WriteLine($"Aetheria typed state verify passed: {statePath}");
Console.WriteLine($"Catalog fingerprint: {quarantine.CatalogFingerprint}");
Console.WriteLine($"Item definitions: {items.Length}");
Console.WriteLine($"Priced/manufactured/shaped items: {pricedItems}/{manufacturedItems}/{shapedItems}");
Console.WriteLine($"Priced/manufactured/specific-heat/shaped items: {pricedItems}/{manufacturedItems}/{specificHeatItems}/{shapedItems}");
Console.WriteLine($"Shape masks: {shapedMaskItems}");
Console.WriteLine($"Interior masks/hardpoint hosts/hardpoints: {interiorShapeItems}/{hardpointHostItems}/{hardpointCount}");
Console.WriteLine($"Behavior payload items/payloads/fields/legacy refs: {behaviorPayloadItems}/{behaviorPayloadCount}/{behaviorFieldCount}/{behaviorLegacyRefCount}");

View file

@ -126,6 +126,9 @@ public sealed class AetheriaItemDefinition
[Key(37)]
public string CompoundCommodityCategory { get; set; } = "";
[Key(38)]
public double SpecificHeat { get; set; } = 1;
}
[MessagePackObject]

View file

@ -8,12 +8,14 @@ using Unity.Mathematics;
public interface IRuntimeItemProjectionReader
{
AetheriaRuntimeCatalogItem GetRuntimeItem(Guid guid);
ItemData Get(Guid guid);
T Get<T>(Guid guid) where T : ItemData;
}
public sealed class AetheriaRuntimeItemCatalog : IRuntimeItemProjectionReader
{
private readonly Dictionary<Guid, AetheriaRuntimeCatalogItem> _typedItems;
private readonly Dictionary<Guid, ItemData> _items;
private static readonly IReadOnlyDictionary<int, Type> BehaviorTypesByUnionKey = new Dictionary<int, Type>
{
@ -54,12 +56,22 @@ public sealed class AetheriaRuntimeItemCatalog : IRuntimeItemProjectionReader
{
if (catalog == null) throw new ArgumentNullException(nameof(catalog));
_typedItems = catalog.Items
.Where(item => Guid.TryParse(item.LegacyId, out _))
.ToDictionary(item => Guid.Parse(item.LegacyId), item => item);
_items = catalog.Items
.Select(ProjectItem)
.Where(item => item != null)
.ToDictionary(item => item.ID, item => item);
}
public AetheriaRuntimeCatalogItem GetRuntimeItem(Guid guid)
{
_typedItems.TryGetValue(guid, out var item);
return item;
}
public ItemData Get(Guid guid)
{
ItemData item;
@ -90,6 +102,7 @@ public sealed class AetheriaRuntimeItemCatalog : IRuntimeItemProjectionReader
projected.Description = item.Description;
projected.Manufacturer = ParseGuid(item.ManufacturerLegacyId);
projected.Mass = (float)item.Mass;
projected.SpecificHeat = (float)item.SpecificHeat;
projected.Shape = ProjectShape(item.ShapeWidth, item.ShapeHeight, item.ShapeCells);
projected.Price = item.Price;

View file

@ -6,6 +6,7 @@ using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using GameCult.Aetheria.State.Unity;
using Unity.Mathematics;
using static Unity.Mathematics.math;
using float2 = Unity.Mathematics.float2;
@ -57,6 +58,12 @@ public class ItemManager
return _itemProjections.Get<T>(id);
}
public AetheriaRuntimeCatalogItem GetRuntimeItem(ItemInstance item)
{
var itemId = item?.Data?.ItemId ?? Guid.Empty;
return itemId == Guid.Empty ? null : _itemProjections.GetRuntimeItem(itemId);
}
public RuntimeItemReference CreateReference(ItemData item)
{
return new RuntimeItemReference(item);
@ -107,21 +114,32 @@ public class ItemManager
public float GetMass(ItemInstance item)
{
var typedItem = GetRuntimeItem(item);
if (typedItem == null)
{
return 0;
}
return item switch
{
CraftedItemInstance _ => GetData(item).Mass,
SimpleCommodity commodity => GetData(item).Mass * commodity.Quantity,
CraftedItemInstance _ => (float)typedItem.Mass,
SimpleCommodity commodity => (float)typedItem.Mass * commodity.Quantity,
_ => 0
};
}
public float GetThermalMass(ItemInstance item)
{
var data = GetData(item);
var typedItem = GetRuntimeItem(item);
if (typedItem == null)
{
return 0;
}
return item switch
{
CraftedItemInstance _ => data.Mass * data.SpecificHeat,
SimpleCommodity commodity => data.Mass * data.SpecificHeat * commodity.Quantity,
CraftedItemInstance _ => (float)(typedItem.Mass * typedItem.SpecificHeat),
SimpleCommodity commodity => (float)(typedItem.Mass * typedItem.SpecificHeat * commodity.Quantity),
_ => 0
};
}
@ -145,8 +163,10 @@ public class ItemManager
public int GetPrice(CraftedItemInstance item)
{
var data = GetData(item);
return (int) (GameplaySettings.QualityPriceModifier.Evaluate(item.Quality) * data.Price);
var typedItem = GetRuntimeItem(item);
return typedItem == null
? 0
: (int) (GameplaySettings.QualityPriceModifier.Evaluate(item.Quality) * typedItem.Price);
}
public SimpleCommodity CreateInstance(SimpleCommodityData item, int count)

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show more