using System.Collections.Generic; using BumpCombat.Constants; using BumpCombat.Core; using BumpCombat.Defense; using BumpCombat.Defense.Comparison; using BumpCombat.Progression; using NUnit.Framework; using UnityEngine; namespace BumpCombat.PlayModeTests { public sealed class Defense25DProgressionPlayModeTests { [Test] public void KillExperienceUsesActualActorModifiersAndQueuesOneLevelChoice() { GameObject actorObject = new("Progression Actor"); Defense25DActor actor = actorObject.AddComponent(); ModifierDefinition experienceModifier = Modifier( "experience-gain", CharacterStat.ExperienceGain, 0.5f, 1); ModifierDefinition rewardModifier = Modifier( "move-speed", CharacterStat.MoveSpeed, 0.2f, 2); Defense25DRewardConstants rewardConstants = ScriptableObject.CreateInstance(); Defense25DTowerModifiers towerModifiers = new(rewardConstants); int oldRequiredExperience = GameplayConstants.Current.LevelUp.BaseExperienceToNextLevel; try { GameplayConstants.Current.LevelUp.BaseExperienceToNextLevel = 5; Assert.That(experienceModifier.TryApplyToModel(actor, null), Is.True); Defense25DProgression progression = new(); List requestedTokens = new(); progression.ChoiceRequested += (_, token) => requestedTokens.Add(token); progression.Bind( actor, rewardConstants, new[] { rewardModifier }, towerModifiers, _ => false); progression.GrantKillExperience(3); Assert.That(progression.CurrentExperience, Is.EqualTo(4)); Assert.That(progression.Level, Is.EqualTo(1)); Assert.That(progression.HasPendingLevelChoice, Is.False); progression.GrantKillExperience(1); Assert.That(progression.Level, Is.EqualTo(2)); Assert.That(progression.CurrentExperience, Is.EqualTo(1)); Assert.That(progression.HasPendingLevelChoice, Is.True); Assert.That(requestedTokens, Is.EqualTo(new[] { "run:1:level:2" })); Assert.That(progression.CurrentChoices, Has.Count.EqualTo(1)); Assert.That(progression.CurrentChoices[0].TargetKind, Is.EqualTo(Defense25DRewardTargetKind.PlayerModifier)); Assert.That(progression.TryChooseModifier(0), Is.True); Assert.That(actor.GetStackCount( rewardModifier.ModifierId, CharacterStat.MoveSpeed), Is.EqualTo(1)); Assert.That(progression.HasPendingLevelChoice, Is.False); Defense25DTowerModifierDefinition fireAttack = System.Array.Find( rewardConstants.TowerModifierCatalog, definition => definition.DefinitionId == "fire.attack.common"); Assert.That(fireAttack, Is.Not.Null); Assert.That(towerModifiers.Apply( Defense25DRewardChoice.CreateTowerModifier(fireAttack)), Is.True); Assert.That(towerModifiers.AppliedChoiceCount, Is.EqualTo(1)); progression.ResetProgression(); Assert.That(progression.Level, Is.EqualTo(1)); Assert.That(progression.CurrentExperience, Is.Zero); Assert.That(progression.RequiredExperience, Is.EqualTo(5)); Assert.That(progression.CurrentChoices, Is.Empty); Assert.That(towerModifiers.AppliedChoiceCount, Is.Zero, "Restart clears the run's tower modifier stacks as well as XP and choices."); } finally { GameplayConstants.Current.LevelUp.BaseExperienceToNextLevel = oldRequiredExperience; Object.DestroyImmediate(experienceModifier); Object.DestroyImmediate(rewardModifier); Object.DestroyImmediate(rewardConstants); Object.DestroyImmediate(actorObject); } } private static ModifierDefinition Modifier( string id, CharacterStat stat, float value, int maximumStacks) { ModifierDefinition definition = ScriptableObject.CreateInstance(); definition.Configure( $"progression-test.{id}", id, stat, ModifierOperation.Increased, value, maximumStacks); return definition; } } }