Mining 6 fix: pickup reports the whole stack (read Quantity before TryStore); pin sell-ore Origin and Collected hold fill

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Nibu 2026-11-13 05:58:28 +00:00
commit b5cfa3cbea
3 changed files with 42 additions and 2 deletions

View file

@ -443,12 +443,15 @@ public class Zone
{
var floating = FloatingItems.FirstOrDefault(f => f.Id.Equals(id));
if (floating == null || (floating.Holder != null && !ReferenceEquals(floating.Holder, taker))) return false;
// The quantity is read before the store: a store that merges into a part-filled stack and spills the rest into a
// new cell rewrites the item's Quantity.
var stored = floating.Item is SimpleCommodity stack ? stack.Quantity : 1;
if (!taker.CargoBays.Any(bay => bay.TryStore(floating.Item))) return false;
FloatingItems.Remove(floating);
CargoGained.OnNext(new CargoGain
{
Taker = taker, Design = floating.Item.Data, Lot = floating.Item.Lot, Kind = GainKind.Collected,
Stored = floating.Item is SimpleCommodity stack ? stack.Quantity : 1
Stored = stored
});
return true;
}

View file

@ -143,6 +143,23 @@ public sealed class HaulFeedTests : IDisposable
Assert.Same(taker, gain.Taker);
}
[Fact]
public void APickupThatMergesAndSpillsReportsTheWholeStack()
{
var grit = MiningCut5aTests.Commodity("Grit", maxStack: 4);
var (rig, _, gains) = Mining(1, 1, (grit, 1f));
var taker = new Ship(rig.Scene.Items, rig.Zone, MiningCut3Tests.Mint(rig.Scene, rig.Scene.Hull), new EntitySettings());
rig.Zone.Admit(taker, piloted: false);
var bay = MiningCut5aTests.Bay(rig.Scene, taker, 2, 1, "Taker");
var design = rig.Scene.Cache.RefOf<ItemData>(grit);
Assert.True(bay.TryStore(new SimpleCommodity { Data = design, Lot = 7, Quantity = 3 }));
gains.Clear();
var floating = rig.Zone.Release(new SimpleCommodity { Data = design, Lot = 7, Quantity = 4 }, new float2(0, 0), new float2(0, 0));
Assert.True(rig.Zone.TryPickUp(taker, floating.Id));
Assert.Equal(7, MiningCut5aTests.Units(bay, "Grit", rig.Scene));
Assert.Equal((GainKind.Collected, 4, 0), (Assert.Single(gains).Kind, gains[0].Stored, gains[0].Adrift));
}
[Fact]
public void TheLineNamesWhatWasTakenAndWhatFloated()
{
@ -161,7 +178,10 @@ public sealed class HaulFeedTests : IDisposable
var spill = HaulFeed.Line(new CargoGain { Taker = rig.Shooter, Design = design, Stored = 1, Adrift = 2, Kind = GainKind.Mined }, items);
Assert.Contains("2 adrift", spill);
Assert.Contains("Rock", spill);
Assert.DoesNotContain("adrift", HaulFeed.Line(new CargoGain { Taker = rig.Shooter, Design = design, Stored = 2, Kind = GainKind.Collected }, items));
var collected = HaulFeed.Line(new CargoGain { Taker = rig.Shooter, Design = design, Stored = 2, Kind = GainKind.Collected }, items);
Assert.DoesNotContain("adrift", collected);
Assert.Contains("Collected 2", collected);
Assert.Contains(hold, collected);
}
[Fact]

View file

@ -536,6 +536,23 @@ public sealed class StationServicesTests : IDisposable
Assert.Contains(gun, bay.Cargo.Keys);
}
[Fact]
public void SellOreLeavesALottedCommodityThatWasNotExtracted()
{
var ship = Ship();
var bay = ship.CargoBays.Single();
var data = _cache.GetByName<SimpleCommodityData>("Ore");
var lot = _items.Lots.Add(new Lot { Design = _cache.RefOf<ItemData>(data), Origin = new Attributed(), Quality = 1 });
Assert.NotEqual(0, lot);
var traded = new SimpleCommodity { Data = _cache.RefOf<ItemData>(data), Quantity = 6, Lot = lot };
Assert.True(bay.TryStore(traded));
var credits = 100;
Assert.Equal(0, StationServices.OreValue(_items, ship.CargoBays));
Assert.Equal(0, StationServices.TrySellOre(ship.CargoBays, Station(), ref credits));
Assert.Equal(100, credits);
Assert.Contains(traded, bay.Cargo.Keys);
}
[Fact]
public void SellOreAcrossBaysAndShips()
{