using BumpCombat.Constants; using BumpCombat.Combat; using BumpCombat.Core; using BumpCombat.Enemies; using BumpCombat.Player; using BumpCombat.Progression; using BumpCombat.Spawning; using NUnit.Framework; using System.Reflection; using UnityEditor; using UnityEngine; namespace BumpCombat.Tests { public sealed class GameplayConstantsConsumptionTests { private static readonly BindingFlags NonPublicInstance = BindingFlags.Instance | BindingFlags.NonPublic; [Test] public void ExperienceAndMissionRules_ReadChangedLevelUpSettings() { LevelUpConstants constants = GameplayConstants.Current.LevelUp; int originalBaseExperience = constants.BaseExperienceToNextLevel; int originalAdditionalExperience = constants.AdditionalExperiencePerLevel; float originalRampageWindow = constants.RampageWindowSeconds; MissionTuning[] originalMissions = constants.Missions; try { constants.BaseExperienceToNextLevel = 19; constants.AdditionalExperiencePerLevel = 8; MissionTuning[] changedMissions = (MissionTuning[])originalMissions.Clone(); changedMissions[0].Target = 7; changedMissions[0].ConditionFormat = "Defeat {0} units"; changedMissions[0].ExperienceReward = 23; changedMissions[10].Target = 9; changedMissions[10].ConditionFormat = "Within {1}s defeat {0}"; constants.Missions = changedMissions; constants.RampageWindowSeconds = 4f; Assert.That( ExperienceSystem.RequiredExperienceForLevel(3), Is.EqualTo(35)); RunMissionDefinition mission = RunMissionTracker.GetDefinition(0); Assert.That(mission.Target, Is.EqualTo(7)); Assert.That(mission.ExperienceReward, Is.EqualTo(23)); Assert.That(mission.Condition, Is.EqualTo("Defeat 7 units")); Assert.That(RunMissionTracker.RampageKillTarget, Is.EqualTo(9)); Assert.That( RunMissionTracker.GetDefinition(10).Condition, Is.EqualTo("Within 4s defeat 9")); } finally { constants.BaseExperienceToNextLevel = originalBaseExperience; constants.AdditionalExperiencePerLevel = originalAdditionalExperience; constants.Missions = originalMissions; constants.RampageWindowSeconds = originalRampageWindow; } } [Test] public void SpawnDensityRules_ReadChangedRunSettings() { RunConstants constants = GameplayConstants.Current.Run; SpawnDensityPhase[] originalPhases = constants.SpawnDensity; try { SpawnDensityPhase[] changedPhases = (SpawnDensityPhase[])originalPhases.Clone(); changedPhases[0] = new SpawnDensityPhase(60f, 9, 8); constants.SpawnDensity = changedPhases; Assert.That(SpawnDirector.TargetCrowdAliveCountAt(0f), Is.EqualTo(9)); Assert.That(SpawnDirector.TargetNormalAliveCountAt(0f), Is.EqualTo(8)); } finally { constants.SpawnDensity = originalPhases; } } [Test] public void PlayerAndBumpRules_ReadChangedSettings() { PlayerConstants player = GameplayConstants.Current.Player; CombatConstants combat = GameplayConstants.Current.Combat; float originalSpeed = player.BaseMoveSpeed; float originalPositionMultiplier = combat.PositionDamageMultiplier; GameObject owner = new("Gameplay Constants Player Consumer Test"); try { PlayerStats stats = owner.AddComponent(); player.BaseMoveSpeed = 6.25f; combat.PositionDamageMultiplier = 1.7f; Assert.That(stats.MoveSpeed, Is.EqualTo(6.25f)); Assert.That( BumpCombatMath.ApplySideMultiplier(10f, HitSide.Side), Is.EqualTo(17f).Within(0.0001f)); } finally { player.BaseMoveSpeed = originalSpeed; combat.PositionDamageMultiplier = originalPositionMultiplier; Object.DestroyImmediate(owner); } } [Test] public void ArtifactGaugeRule_ReadsChangedArtifactSettings() { ArtifactConstants artifacts = GameplayConstants.Current.Artifacts; float originalGaugeGain = artifacts.NormalBumpGaugeGain; GameObject playerObject = new("Gameplay Constants Artifact Consumer Test"); try { playerObject.AddComponent(); playerObject.AddComponent(); ActiveArtifactController controller = playerObject.AddComponent(); InvokePrivate(controller, "Awake"); artifacts.NormalBumpGaugeGain = 9f; controller.AddNormalHitCharge(); Assert.That(controller.CurrentGauge, Is.EqualTo(9f)); } finally { artifacts.NormalBumpGaugeGain = originalGaugeGain; Object.DestroyImmediate(playerObject); } } [Test] public void ImportedCatalog_ReferencesEveryCategoryAndPreservesRunArrays() { GameplayConstants catalog = AssetDatabase.LoadAssetAtPath( "Assets/_Project/Constants/Resources/GameplayConstants.asset"); Assert.That(catalog, Is.Not.Null); Assert.That(catalog.Player, Is.SameAs(AssetDatabase.LoadAssetAtPath( "Assets/_Project/Constants/Player/PlayerConstants.asset"))); Assert.That(catalog.Combat, Is.SameAs(AssetDatabase.LoadAssetAtPath( "Assets/_Project/Constants/Combat/CombatConstants.asset"))); Assert.That(catalog.Enemies, Is.SameAs(AssetDatabase.LoadAssetAtPath( "Assets/_Project/Constants/Enemies/EnemyConstants.asset"))); Assert.That(catalog.Items, Is.SameAs(AssetDatabase.LoadAssetAtPath( "Assets/_Project/Constants/Items/ItemConstants.asset"))); Assert.That(catalog.LevelUp, Is.SameAs(AssetDatabase.LoadAssetAtPath( "Assets/_Project/Constants/LevelUp/LevelUpConstants.asset"))); Assert.That(catalog.Artifacts, Is.SameAs(AssetDatabase.LoadAssetAtPath( "Assets/_Project/Constants/Artifacts/ArtifactConstants.asset"))); Assert.That(catalog.Run, Is.SameAs(AssetDatabase.LoadAssetAtPath( "Assets/_Project/Constants/Run/RunConstants.asset"))); Assert.That(catalog.CombatFeedback, Is.SameAs(AssetDatabase.LoadAssetAtPath( "Assets/_Project/Constants/Combat/CombatFeedback.asset"))); Assert.That(catalog.Run.MidBossKinds, Is.EqualTo(new[] { EnemyKind.GreatswordSkeleton, EnemyKind.NecroGolem, })); Assert.That(catalog.Run.ProductionEliteAttacksPerSequence, Is.EqualTo(new[] { 1, 2, 3, 2 })); Assert.That(catalog.Run.DevelopmentEliteEventTimes, Is.EqualTo(new[] { 36f, 72f, 108f, 144f, 180f, 216f })); Assert.That(catalog.Run.ProductionEliteEventTimes, Is.EqualTo(new[] { 180f, 360f, 540f, 720f })); } private static void InvokePrivate(object target, string methodName) { MethodInfo method = target.GetType().GetMethod(methodName, NonPublicInstance); Assert.That(method, Is.Not.Null, methodName); method.Invoke(target, null); } } }