Merge origin/master (ace81719 product-titles) into eureka/aetheria-release-sim-mines

This commit is contained in:
Meta Vens 2026-10-08 17:02:10 +02:00
commit 8a98aef5c1
6 changed files with 110 additions and 9 deletions

View file

@ -1423,7 +1423,7 @@ public class ActionGameManager : MonoBehaviour
: $"base {d.PBase:P1}";
DebugInfoText.text =
$"FIRE CONTROL - {selectedItem.Data.Name}\n" +
$"FIRE CONTROL - {ItemManager.Title(selectedItem.EquippableItem)}\n" +
$"{gates}\n" +
$"range {d.Range:F0} [{d.MinRange:F0}..{d.MaxRange:F0}]\n" +
$"info {d.Info:F3}/{d.InfoDemandCeiling:F3} sensor {d.PSensor:F3}\n" +

View file

@ -221,6 +221,11 @@ public class ItemManager
return (ItemData.Get(maker), product);
}
// What the player reads an item as: its product's name when its lot's maker has a product of this design,
// otherwise the design's own name (unbranded, console-given and extracted lots, and commodities).
public string Title(ItemInstance item) =>
(item is CraftedItemInstance crafted ? Brand(crafted).Product?.Name : null) ?? GetData(item).Name;
public (RarityTier tier, int upgrades) GetTier(CraftedItemInstance item)
{
var quality = GetLot(item).Quality;

View file

@ -192,9 +192,9 @@ public class TradeMenu : MonoBehaviour
columns.Add(("Name", 3,
x => () => x.item is CraftedItemInstance craftedItemInstance ?
$"<color=#{ColorUtility.ToHtmlStringRGB(GameManager.ItemManager.GetTier(craftedItemInstance).tier.Color.ToColor())}>{x.data.Name}" :
x.data.Name,
x => x.data.Name));
$"<color=#{ColorUtility.ToHtmlStringRGB(GameManager.ItemManager.GetTier(craftedItemInstance).tier.Color.ToColor())}>{GameManager.ItemManager.Title(x.item)}" :
GameManager.ItemManager.Title(x.item),
x => GameManager.ItemManager.Title(x.item)));
if(_hardpointFilter.filter==null)
columns.Add(("Type", 2,
x => () =>
@ -352,7 +352,7 @@ public class TradeMenu : MonoBehaviour
{
int quantity = 1;
Dialog.Clear();
Dialog.Title.text = $"Buying {i.data.Name}";
Dialog.Title.text = $"Buying {GameManager.ItemManager.Title(i.item)}";
Dialog.AddField("Quantity",
() => quantity,
q => quantity = min(min(q, GameManager.Credits / StationServices.BuyPrice(GameManager.ItemManager, s)), s.Quantity));

View file

@ -376,7 +376,6 @@ public class PropertiesPanel : MonoBehaviour
sheet.AddStat("Manufacturer", () => maker.Name);
if (product != null)
{
AddProperty(product.Name);
AddProperty(product.Description);
}
}
@ -430,10 +429,9 @@ public class PropertiesPanel : MonoBehaviour
private string GetTitle(EquippableItem item)
{
var data = GameManager.ItemManager.GetData(item);
var (tier, upgrades) = GameManager.ItemManager.GetTier(item);
return
$"<color=#{ColorUtility.ToHtmlStringRGB(tier.Color.ToColor())}>{data.Name}</color><smallcaps><size=60%> ({tier.Name}{new string('+', upgrades)})";
$"<color=#{ColorUtility.ToHtmlStringRGB(tier.Color.ToColor())}>{GameManager.ItemManager.Title(item)}</color><smallcaps><size=60%> ({tier.Name}{new string('+', upgrades)})";
}
public void Inspect(EquippedItem item)

View file

@ -605,7 +605,7 @@ public class ZoneRenderer : MonoBehaviour
var itemPickup = gridObject.gameObject.GetComponent<ItemPickup>();
itemPickup.Item = item;
itemPickup.ZoneRenderer = this;
itemPickup.ScanLabel.text = ItemManager.GetData(item).Name;
itemPickup.ScanLabel.text = ItemManager.Title(item);
if (item is CraftedItemInstance craftedItemInstance)
{
var c = ItemManager.GetTier(craftedItemInstance).tier.Color.ToColor();

View file

@ -0,0 +1,98 @@
using System;
using System.Collections.Generic;
using System.IO;
using CultMath;
using GameCult.Caching;
using Xunit;
// Items are titled by their product (ruling catalog-grows-generic-designs-branded-products): ItemManager.Title reads
// Brand, so the lot's maker picks which of a design's products names the unit, and nothing else carries a name.
public sealed class ItemTitleTests : IDisposable
{
private readonly string _root = Path.Combine(Path.GetTempPath(), "aetheria-itemtitle-" + Guid.NewGuid().ToString("N"));
private readonly CultCache _cache;
private readonly ItemManager _items;
private readonly FactionProductData _panopticon, _clapBack, _spiceBlend;
private readonly CultRecordRef<Faction> _stranger;
private readonly CompoundCommodityData _spice;
private readonly GearData _array;
public ItemTitleTests()
{
Directory.CreateDirectory(_root);
_cache = AetheriaStores.Open(Path.Combine(_root, "Aetheria.cc"), catalogWritable: true);
_cache.Upsert(new TestCatalogGlobal { Name = "Temperament" });
_array = new GearData { Name = "Array", Hardpoint = HardpointType.Sensors, Shape = new Shape(), Price = 10, Durability = 5 };
_cache.Upsert(_array);
_cache.Upsert(new SimpleCommodityData { Name = "Ore", Shape = new Shape(), Price = 7, MaxStack = 100 });
var finch = _cache.Upsert(new Faction { Name = "Finch", ShortName = "FIN" });
var lucent = _cache.Upsert(new Faction { Name = "Lucent", ShortName = "LUC" });
_stranger = _cache.Upsert(new Faction { Name = "Stranger", ShortName = "STR" });
_spice = new CompoundCommodityData { Name = "Spice", Shape = new Shape(), Price = 3 };
_cache.Upsert(_spice);
var design = _cache.RefOf<CraftedItemData>(_cache.GetByName<GearData>("Array"));
_panopticon = new FactionProductData { Name = "Panopticon Prime", Design = design, Manufacturer = finch };
_clapBack = new FactionProductData { Name = "ClapBack Ultra", Design = design, Manufacturer = lucent };
_cache.Commit(batch => batch.Upsert(typeof(FactionProductData), _panopticon, new CultRecordKey("array-finch")));
_cache.Commit(batch => batch.Upsert(typeof(FactionProductData), _clapBack, new CultRecordKey("array-lucent")));
_spiceBlend = new FactionProductData { Name = "Finch Reserve", Design = _cache.RefOf<CraftedItemData>(_spice), Manufacturer = finch };
_cache.Commit(batch => batch.Upsert(typeof(FactionProductData), _spiceBlend, new CultRecordKey("spice-finch")));
_items = new ItemManager(_cache, new ProvenanceLedger(), RunSaveTests.TestSettings(), _ => { });
}
public void Dispose()
{
_cache.Dispose();
Directory.Delete(_root, true);
}
[Fact]
public void A_product_unit_is_titled_by_its_product()
{
var unit = _items.CreateInstance(_items.CreateLot(_panopticon));
Assert.Equal("Panopticon Prime", _items.Title(unit));
Assert.NotEqual("Panopticon Prime", _items.GetData(unit).Name);
}
[Fact]
public void Two_makers_title_their_own_units()
{
var finch = _items.CreateInstance(_items.CreateLot(_panopticon));
var lucent = _items.CreateInstance(_items.CreateLot(_clapBack));
Assert.Equal(_items.GetData(finch).Name, _items.GetData(lucent).Name);
Assert.Equal("Panopticon Prime", _items.Title(finch));
Assert.Equal("ClapBack Ultra", _items.Title(lucent));
}
[Fact]
public void Unbranded_units_are_titled_by_design()
{
var given = _items.CreateInstance(_items.CreateLot(_array, default, .5f));
Assert.Equal("Array", _items.Title(given));
var extractedLot = _items.Lots.Add(new Lot
{
Design = _cache.RefOf<ItemData>(_array), Origin = new Extracted(), Quality = .5f, Roles = new List<RoleFill>()
});
Assert.Equal("Array", _items.Title(_items.CreateInstance(extractedLot)));
var ore = new SimpleCommodity { Data = _cache.RefOf<ItemData>(_cache.GetByName<SimpleCommodityData>("Ore")), Quantity = 3 };
Assert.Equal("Ore", _items.Title(ore));
}
[Fact]
public void A_maker_without_a_product_of_the_design_is_titled_by_design()
{
var unit = _items.CreateInstance(_items.CreateLot(_array, _stranger, .5f));
Assert.Equal("Stranger", _items.Brand(unit).Maker.Name);
Assert.Equal("Array", _items.Title(unit));
}
[Fact]
public void A_crafted_commodity_with_a_product_is_titled_by_its_product()
{
var unit = _items.CreateInstance(_items.CreateLot(_spiceBlend));
Assert.IsType<CompoundCommodity>(unit);
Assert.Equal("Finch Reserve", _items.Title(unit));
}
}