using System.Collections.Generic; using NUnit.Framework; using UnityEngine; using YachtDice.Categories; using YachtDice.Dice; using YachtDice.Economy; using YachtDice.Events; using YachtDice.Modifiers.Core; using YachtDice.Modifiers.Definition; using YachtDice.Modifiers.Effects; using YachtDice.Modifiers.Pipeline; using YachtDice.Modifiers.Runtime; using YachtDice.Scoring; namespace YachtDice.Tests { public class LimitedUseModifierFlowTests { private readonly List _createdAssets = new(); private CategoryDefinition _onesCategory; private CategoryDefinition _twosCategory; private CategoryDefinition _chanceCategory; private DiceDefinition _standardDice; private CategoryCatalog _catalog; private CurrencyBank _currencyBank; private ModifierRegistry _registry; private ScoringSystem _scoringSystem; private ModifierInstance _instance; [SetUp] public void SetUp() { _standardDice = DiceDefinition.CreateForTest("d6", "d6"); _onesCategory = SumOfValueCategory.CreateForTest("ones", "Единицы", 1); _twosCategory = SumOfValueCategory.CreateForTest("twos", "Двойки", 2); _chanceCategory = SumAllCategory.CreateForTest("chance", "Шанс"); _catalog = CategoryCatalog.CreateForTest(new List { _onesCategory, _twosCategory, _chanceCategory, }); _createdAssets.Add(_standardDice); _createdAssets.Add(_onesCategory); _createdAssets.Add(_twosCategory); _createdAssets.Add(_chanceCategory); _createdAssets.Add(_catalog); var bankGo = new GameObject("CurrencyBank"); _currencyBank = bankGo.AddComponent(); _currencyBank.SetBalance(100); _registry = new ModifierRegistry(5); var pipeline = new ModifierPipeline(_registry) { TracingEnabled = false, }; var eventBus = new GameEventBus(pipeline); var scoringGo = new GameObject("ScoringSystem"); _scoringSystem = scoringGo.AddComponent(); _scoringSystem.Construct(eventBus, _registry, _catalog, _currencyBank); var multiply = AddCreatedAsset(MultiplyScoreEffect.CreateForTest(2f, ModifierPhase.Multiplicative)); var consume = AddCreatedAsset(ConsumeChargeEffect.CreateForTest(1, ModifierPhase.SideEffect)); var behavior = AddCreatedAsset(ModifierBehavior.CreateForTest( TriggerType.OnCategoryScored, null, new List { multiply, consume })); var definition = AddCreatedAsset(ModifierDefinition.CreateForTest( "mod_multiplier_2x_limited", new List { behavior }, hasLimitedUses: true, maxUses: 3)); _instance = _registry.Add(definition); _registry.TryActivate(_instance); } [TearDown] public void TearDown() { foreach (var scoring in Object.FindObjectsByType(FindObjectsSortMode.None)) Object.DestroyImmediate(scoring.gameObject); foreach (var bank in Object.FindObjectsByType(FindObjectsSortMode.None)) Object.DestroyImmediate(bank.gameObject); for (var i = 0; i < _createdAssets.Count; i++) { if (_createdAssets[i] != null) Object.DestroyImmediate(_createdAssets[i]); } _createdAssets.Clear(); } /// /// Предпросмотр очков не расходует заряды ограниченного модификатора. /// [Test] public void PreviewScore_DoesNotConsumeCharges() { _scoringSystem.PreviewScore(CreateDice(1, 1, 2, 3, 4), _onesCategory); _scoringSystem.PreviewScore(CreateDice(2, 2, 2, 3, 4), _twosCategory); Assert.AreEqual(3, _instance.RemainingUses); Assert.AreEqual(1, _registry.All.Count); Assert.IsTrue(_instance.IsActive); } /// /// Подтверждение категории расходует ровно один заряд модификатора. /// [Test] public void ScoreCategory_ConsumesExactlyOneCharge() { _scoringSystem.ScoreCategory(CreateDice(1, 1, 2, 3, 4), _onesCategory); Assert.AreEqual(2, _instance.RemainingUses); Assert.AreEqual(1, _registry.All.Count); } /// /// Модификатор удаляется из реестра после полного исчерпания зарядов. /// [Test] public void ScoreCategory_RemovesModifier_WhenChargesExhausted() { _scoringSystem.ScoreCategory(CreateDice(1, 1, 2, 3, 4), _onesCategory); _scoringSystem.ScoreCategory(CreateDice(2, 2, 2, 3, 4), _twosCategory); _scoringSystem.ScoreCategory(CreateDice(1, 2, 3, 4, 5), _chanceCategory); Assert.AreEqual(0, _registry.All.Count); Assert.AreEqual(0, _registry.ActiveCount); } private IReadOnlyList CreateDice(params int[] values) { var dice = new DiceInstance[values.Length]; for (var i = 0; i < values.Length; i++) dice[i] = new DiceInstance(_standardDice, values[i]); return dice; } private T AddCreatedAsset(T asset) where T : Object { _createdAssets.Add(asset); return asset; } } }