diff --git a/Assets/Scripts/ServerShared/ZoneData.cs b/Assets/Scripts/ServerShared/ZoneData.cs index 634b6f9cc..890b2dfef 100644 --- a/Assets/Scripts/ServerShared/ZoneData.cs +++ b/Assets/Scripts/ServerShared/ZoneData.cs @@ -226,8 +226,9 @@ public static class FieldKinds .Select(kind => { var key = catalog.RefOf(kind).Key; - return (Key: key, Weight: kind.GenerationWeight * Factor( - type?.Kinds.Where(entry => entry.Kind.Key.Equals(key)).Select(entry => (double) entry.Weight), 1.0)); + var factor = Factor(type?.Kinds.Where(entry => entry.Kind.Key.Equals(key)).Select(entry => (double) entry.Weight), 1.0); + // Both must be positive: two negatives do not multiply into a weight. + return (Key: key, Weight: kind.GenerationWeight > 0f && factor > 0.0 ? kind.GenerationWeight * factor : 0.0); }) .Where(kind => kind.Weight > 0.0) .OrderBy(kind => kind.Key.Value, StringComparer.Ordinal) diff --git a/tests/Aetheria.Shared.Tests/OreGeographyTests.cs b/tests/Aetheria.Shared.Tests/OreGeographyTests.cs index 2b4097322..582b5d65e 100644 --- a/tests/Aetheria.Shared.Tests/OreGeographyTests.cs +++ b/tests/Aetheria.Shared.Tests/OreGeographyTests.cs @@ -238,6 +238,25 @@ public sealed class OreGeographyTests : IDisposable Assert.False(FieldKinds.Assign("belt-0", Empty(), default).IsSet()); } + [Fact] + public void AKindWhoseCombinedWeightIsNotPositiveIsNeverDrawn() + { + var cache = Empty(); + var negative = Kind(cache, "negative", -1f); + Kind(cache, "positive", 1f); + var flipped = Province(cache, "flipped", 1, new[] {KindFactor(negative, -1f)}); + for (var i = 0; i < 500; i++) + { + Assert.Equal("field-kind:positive", FieldKinds.Assign($"belt-{i}", cache, default).Key.Value); + Assert.Equal("field-kind:positive", FieldKinds.Assign($"belt-{i}", cache, flipped).Key.Value); + } + + // With nothing positive left the belt has no kind, rather than the negative one. + var only = Empty(); + var lone = Kind(only, "negative", -1f); + Assert.False(FieldKinds.Assign("belt-0", only, Province(only, "flipped", 1, new[] {KindFactor(lone, -1f)})).IsSet()); + } + [Fact] public void ProvinceWeightsTheKindDraw() {