From feae643dfef5a0003bd7dd7772ea06fb937f1f0d Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Sun, 14 Jun 2026 06:52:29 +0100 Subject: [PATCH] Use typed thermal curves for equipped items --- .voidbot/state/aetheria.cc | Bin 70057 -> 70070 bytes Assets/Scripts/ServerShared/Entity.cs | 39 +++++++++++++++++++++++--- docs/aetheria-perfect-machine-map.md | 12 +++++--- 3 files changed, 43 insertions(+), 8 deletions(-) diff --git a/.voidbot/state/aetheria.cc b/.voidbot/state/aetheria.cc index b693bbe532c0d543078786b8e05dc3471417799a..7150282c1d701dc2f302ffba382b417d75b0c329 100644 GIT binary patch delta 1249 zcmZWpO=uHA6n5J*Z52I;+Mm<2P_SZSQ(Lh?L~RvCq_tMW-X^<~WbE$Fc4oFQJs8EK zC)q=99;`oz6beDTDISzcMetZDB3=Z+LocEr=$lP8KkX$O-n{+Z_kHi%dAb;Tu^3x^ z+_Zf-nHoHnNDd~a?-_f8w@r7em7`&WH_u0vBLiWjEe1xR)E6_~Uq5$d)@Pnat@DaH zpmJ0=#0HOw499=2Nx|iLpmW6biJ}rz0eeCCu3`=a(-(6TW@tes9+@^_&S&F51E5LF z9KOYrgkWQ0Uod{FUjCGO2=U?bA0EpLvH9NpcGUC|oRa6|cC(bRYze=Oq-V3TB`0DLy#sYfphzGSeUS zM4>T#q#|?Nw-F}v%6kwUB@5=HH#|ZPEJ+vvH$4x>$yW^u@C9p~ZMzEsa!e kpZLOZ+~84pcrffd(Q4d|poW8u=8l(NT8%gD)vl50|G7=c`2YX_ delta 1166 zcmY*ZJ7^S96m^r0G3%!g%_@l8MpSS&Yh1G`s6;nn6n|(6)4iR!yYp~%-uOPdMvGu; z5QHgGi$Cmy1uZOsg@uS>s|aG_x3W{P@V{(L z6A{Er2MQw5hJdvY80du}4OGT19xlI@Fs^M|WY9V&PCQHx`kUEg4Fw#Z16d=q|y#j=U1FGV}K{b|c7_ti!g zi)bQX(vJm?G}M`gS{32Ak&wXi`axrqo1sN%P;Z>G}Y+# zReYo|Qk3%k>v0h&(@fd1fz0-`y&!8qu+pPEKWO(5``Pg|4;SKP?C- zARCeEs2*8K@mkoq_3qHxlNZjgm0D?1$C2F8qfQd^tss!9M5y*&73y3nZRhSA>kVsm3vz~Cs}idk4=K_)`(@W~ zCZ9Y%e7lqVv3)}_^g5rs`MqOfcLS6w^Y=AtsE@0Tbh3YNxU=+k{aEkfmuWqWWVZG` v54dfy{C*^}(u*D3Yj;C`dmJpMt77@|Xy#`Bh)a9+b2Rf}Ea&Q$OQrdLa7&`5 diff --git a/Assets/Scripts/ServerShared/Entity.cs b/Assets/Scripts/ServerShared/Entity.cs index 952663500..4744bf3b7 100644 --- a/Assets/Scripts/ServerShared/Entity.cs +++ b/Assets/Scripts/ServerShared/Entity.cs @@ -1271,6 +1271,7 @@ public class EquippedItem public Shape InsetShape { get; } public Entity Entity { get; } public EquippableItemData Data { get; } + public AetheriaRuntimeCatalogItem RuntimeItem { get; } public ReactiveProperty ThermalOnline { get; } = new ReactiveProperty(false); public ReactiveProperty DurabilityOnline { get; } = new ReactiveProperty(false); @@ -1283,6 +1284,7 @@ public class EquippedItem public Subject<(uint id, float v)> AudioParameters { get; } = new Subject<(uint id, float v)>(); public Dictionary AudioParameterValues { get; } = new Dictionary(); + private readonly BezierCurve _thermalPerformanceCurve; private float oldTemperature; public float Temperature { @@ -1372,9 +1374,10 @@ public class EquippedItem Entity = entity; EquippableItem = item; Position = position; - var typedItem = ItemManager.GetRuntimeItem(item); - Conductivity = typedItem != null ? (float)typedItem.Conductivity : Data.Conductivity; - MaxDurability = typedItem?.Durability > 0 ? (float)typedItem.Durability : Math.Max(item.Durability, 1f); + RuntimeItem = ItemManager.GetRuntimeItem(item); + Conductivity = RuntimeItem != null ? (float)RuntimeItem.Conductivity : Data.Conductivity; + MaxDurability = RuntimeItem?.Durability > 0 ? (float)RuntimeItem.Durability : Math.Max(item.Durability, 1f); + _thermalPerformanceCurve = CreateThermalPerformanceCurve(RuntimeItem); ThermalExponent = lerp( ItemManager.GameplaySettings.ThermalQualityMin, ItemManager.GameplaySettings.ThermalQualityMax, @@ -1443,7 +1446,7 @@ public class EquippedItem public void UpdatePerformance() { var temp = Temperature; - ThermalPerformance = Data.Performance(temp); + ThermalPerformance = EvaluateThermalPerformance(temp); var deltaTemp = math.abs(temp - oldTemperature); DurabilityPerformance = EquippableItem.Durability / MaxDurability; var performanceThreshold = Entity.Settings.ShutdownPerformance; @@ -1457,6 +1460,34 @@ public class EquippedItem oldTemperature = temp; } + private float EvaluateThermalPerformance(float temperature) + { + if (_thermalPerformanceCurve == null || + RuntimeItem == null || + RuntimeItem.MaximumTemperature <= RuntimeItem.MinimumTemperature) + { + return Data.Performance(temperature); + } + + var t = unlerp((float)RuntimeItem.MinimumTemperature, (float)RuntimeItem.MaximumTemperature, temperature); + return saturate(_thermalPerformanceCurve.Evaluate(t)); + } + + private static BezierCurve CreateThermalPerformanceCurve(AetheriaRuntimeCatalogItem item) + { + if (item?.ThermalPerformanceCurveKeys == null || item.ThermalPerformanceCurveKeys.Count == 0) + { + return null; + } + + return new BezierCurve + { + Keys = item.ThermalPerformanceCurveKeys + .Select(key => new float4((float)key.Time, (float)key.Value, (float)key.InTangent, (float)key.OutTangent)) + .ToArray() + }; + } + public void Update(float delta) { foreach (var audioStat in Data.AudioStats) diff --git a/docs/aetheria-perfect-machine-map.md b/docs/aetheria-perfect-machine-map.md index e493cac82..1eb82f879 100644 --- a/docs/aetheria-perfect-machine-map.md +++ b/docs/aetheria-perfect-machine-map.md @@ -233,10 +233,11 @@ legacy catalog cache, and legacy UI paths should be migration-only or deleted. performance stats. `ItemManager.CreateInstance(CraftedItemData, float)` initializes new equippable runtime durability from the typed runtime item row; `EquippableItemData.Durability` is only an incomplete-row fallback. - `EquippedItem` also takes conductivity and max durability from the typed - runtime item row for heat conduction, durability performance, and wear - scaling; the legacy equippable DTO still owns thermal curve, thermal - resilience, and audio-stat residue until those surfaces are imported. + `EquippedItem` also takes conductivity, max durability, thermal bounds, and + thermal performance curve keys from the typed runtime item row for heat + conduction, durability performance, thermal performance, and wear scaling; + the legacy equippable DTO still owns thermal resilience and audio-stat + residue until those surfaces are imported. Inventory drag preview occupancy now projects typed item shape cells only into the local `Shape` grid, and final fit/equip acceptance shares the typed runtime catalog geometry path in `Entity.ItemFits` and `TryEquip`. @@ -774,6 +775,9 @@ First Aetheria surfaces to publish: - Done: move `EquippedItem` conductivity and max-durability performance/wear inputs onto typed runtime item rows; legacy thermal resilience and audio stats remain explicit DTO residues. + - Done: move `EquippedItem` thermal performance evaluation onto typed + runtime item thermal bounds and curve keys; legacy `Data.Performance` + remains only as an incomplete-row fallback. - Done: import action-bar icon resource paths into typed item definitions and move `ActionBarSlot` custom gear icon lookup onto typed runtime item rows. - Done: move `Ship` drag, combat/turret predicted shot height, and thruster