diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatResourceManager.cs b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatInRunResourceManager.cs similarity index 99% rename from Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatResourceManager.cs rename to Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatInRunResourceManager.cs index b77e002..f11fd8c 100644 --- a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatResourceManager.cs +++ b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatInRunResourceManager.cs @@ -8,7 +8,7 @@ using Random = UnityEngine.Random; namespace GeometryTD.CustomComponent { - internal sealed class CombatResourceManager + internal sealed class CombatInRunResourceManager { // 每次击杀敌人后,进入“掉组件判定”的概率: // chance = clamp(DropChanceBase + (phaseIndex - 1) * DropChancePerPhase, 0, DropChanceCap) diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatResourceManager.cs.meta b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatInRunResourceManager.cs.meta similarity index 100% rename from Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatResourceManager.cs.meta rename to Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatInRunResourceManager.cs.meta diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatScheduler.cs b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatScheduler.cs index 2e6d8a9..4cca942 100644 --- a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatScheduler.cs +++ b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatScheduler.cs @@ -25,7 +25,7 @@ namespace GeometryTD.CustomComponent private readonly PhaseLoopRuntime _phaseLoopRuntime = new(); private readonly CombatLoadSession _loadSession = new(); private readonly CombatEventBridge _eventBridge = new(); - private readonly CombatResourceManager _combatResourceManager = new(); + private readonly CombatInRunResourceManager _combatInRunResourceManager = new(); private EntityComponent _entity; private DRLevel _currentLevel; @@ -49,8 +49,8 @@ namespace GeometryTD.CustomComponent public int PhaseCount => _phaseLoopRuntime.PhaseCount; public bool CanEndCombat => _phaseLoopRuntime.CanEndCombat; public int DefeatedEnemyCount => _enemyManager.DefeatedEnemyCount; - public int GainedCoin => _combatResourceManager.GainedCoin; - public int GainedGold => _combatResourceManager.GainedGold; + public int GainedCoin => _combatInRunResourceManager.GainedCoin; + public int GainedGold => _combatInRunResourceManager.GainedGold; public void OnInit() { @@ -95,7 +95,7 @@ namespace GeometryTD.CustomComponent _enemyManager.EndPhase(); _enemyManager.ResetCombatStats(); ResetRuntime(); - _combatResourceManager.Reset(); + _combatInRunResourceManager.Reset(); _isFinishAsVictory = true; _currentLevel = level; @@ -192,14 +192,14 @@ namespace GeometryTD.CustomComponent public void OnEnemyDefeatedRewardResolved(int gainedCoin, int gainedGold) { - _combatResourceManager.AddEnemyDefeatedReward(gainedCoin, gainedGold); + _combatInRunResourceManager.AddEnemyDefeatedReward(gainedCoin, gainedGold); if (!IsRunning) { return; } - _combatResourceManager.TryRollOutGameItemDrop( + _combatInRunResourceManager.TryRollOutGameItemDrop( _phaseLoopRuntime.DisplayPhaseIndex, ResolveCurrentThemeType()); } @@ -222,7 +222,7 @@ namespace GeometryTD.CustomComponent _spawnEntriesByPhaseId.Clear(); _phaseLoopRuntime.Reset(); _loadSession.Reset(); - _combatResourceManager.Reset(); + _combatInRunResourceManager.Reset(); _settlementContext = null; _currentLevel = null; _isFinishAsVictory = true; @@ -337,8 +337,8 @@ namespace GeometryTD.CustomComponent SettlementContext settlementContext = new SettlementContext { DefeatedEnemyCount = Mathf.Max(0, defeatedEnemyCount), - GainedGold = Mathf.Max(0, _combatResourceManager.GainedGold), - RewardInventory = _combatResourceManager.GetRewardInventorySnapshot(), + GainedGold = Mathf.Max(0, _combatInRunResourceManager.GainedGold), + RewardInventory = _combatInRunResourceManager.GetRewardInventorySnapshot(), ShouldOpenRewardSelection = shouldOpenFullBaseHpRewardSelect, Reason = reason }; @@ -397,10 +397,10 @@ namespace GeometryTD.CustomComponent } } - int goldForBonusCalculation = Mathf.Max(0, _combatResourceManager.GainedGold) + levelRewardGold; + int goldForBonusCalculation = Mathf.Max(0, _combatInRunResourceManager.GainedGold) + levelRewardGold; int bonusGold = bonusRate > 0f ? Mathf.FloorToInt(goldForBonusCalculation * bonusRate) : 0; int settlementGold = levelRewardGold + bonusGold; - _combatResourceManager.AddSettlementGold(settlementGold); + _combatInRunResourceManager.AddSettlementGold(settlementGold); Log.Info( "Combat settlement resolved. BaseHp={0}/{1}, LevelReward={2}, BonusRate={3:P0}, BonusGold={4}, FullHpRewardSelect={5}, LowHpPenalty={6}.", @@ -437,7 +437,7 @@ namespace GeometryTD.CustomComponent private bool TryPrepareRewardSelection(SettlementContext settlementContext) { - IReadOnlyList candidateItems = _combatResourceManager.RollSettlementRewardCandidates( + IReadOnlyList candidateItems = _combatInRunResourceManager.RollSettlementRewardCandidates( _phaseLoopRuntime.DisplayPhaseIndex, ResolveCurrentThemeType(), RewardSelectDisplayCount); diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/EnemyDropResolveContext.cs b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/EnemyDropResolveContext.cs new file mode 100644 index 0000000..705385f --- /dev/null +++ b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/EnemyDropResolveContext.cs @@ -0,0 +1,21 @@ +using GeometryTD.DataTable; +using GeometryTD.Definition; + +namespace GeometryTD.CustomComponent +{ + internal readonly struct EnemyDropResolveContext + { + public EnemyDropResolveContext(DREnemy enemy, int displayPhaseIndex, LevelThemeType themeType) + { + Enemy = enemy; + DisplayPhaseIndex = displayPhaseIndex; + ThemeType = themeType; + } + + public DREnemy Enemy { get; } + + public int DisplayPhaseIndex { get; } + + public LevelThemeType ThemeType { get; } + } +} diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/EnemyDropResolveContext.cs.meta b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/EnemyDropResolveContext.cs.meta new file mode 100644 index 0000000..a6990e0 --- /dev/null +++ b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/EnemyDropResolveContext.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cc1fe871193e2594189cac3af541f354 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/EnemyDropResolveResult.cs b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/EnemyDropResolveResult.cs new file mode 100644 index 0000000..853fc84 --- /dev/null +++ b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/EnemyDropResolveResult.cs @@ -0,0 +1,20 @@ +namespace GeometryTD.CustomComponent +{ + internal readonly struct EnemyDropResolveResult + { + public static EnemyDropResolveResult Empty => new(0, 0, false); + + public EnemyDropResolveResult(int coin, int gold, bool shouldRollOutGameItem) + { + Coin = coin; + Gold = gold; + ShouldRollOutGameItem = shouldRollOutGameItem; + } + + public int Coin { get; } + + public int Gold { get; } + + public bool ShouldRollOutGameItem { get; } + } +} diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/EnemyDropResolveResult.cs.meta b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/EnemyDropResolveResult.cs.meta new file mode 100644 index 0000000..f0dbff9 --- /dev/null +++ b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/EnemyDropResolveResult.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 754c09edf691f354aa918c4a730a9cc5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/EnemyDropResolver.cs b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/EnemyDropResolver.cs new file mode 100644 index 0000000..30ffb13 --- /dev/null +++ b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/EnemyDropResolver.cs @@ -0,0 +1,32 @@ +using GeometryTD.DataTable; +using UnityEngine; +using Random = UnityEngine.Random; + +namespace GeometryTD.CustomComponent +{ + internal sealed class EnemyDropResolver + { + public EnemyDropResolveResult Resolve(in EnemyDropResolveContext context) + { + DREnemy enemy = context.Enemy; + if (enemy == null) + { + return EnemyDropResolveResult.Empty; + } + + int coin = Mathf.Max(0, enemy.DropCoin); + int gold = 0; + + float dropRate = enemy.DropPercent > 1f + ? Mathf.Clamp01(enemy.DropPercent * 0.01f) + : Mathf.Clamp01(enemy.DropPercent); + + if (enemy.DropGold > 0 && dropRate > 0f && Random.value <= dropRate) + { + gold = Mathf.Max(0, enemy.DropGold); + } + + return new EnemyDropResolveResult(coin, gold, shouldRollOutGameItem: true); + } + } +} diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/EnemyDropResolver.cs.meta b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/EnemyDropResolver.cs.meta new file mode 100644 index 0000000..31c6478 --- /dev/null +++ b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/EnemyDropResolver.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b7dc48b97505d0242bf5846ba835f3b3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/PhaseEndConditions.meta b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/PhaseEndConditions.meta new file mode 100644 index 0000000..dd21fe9 --- /dev/null +++ b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/PhaseEndConditions.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 9e3f30abcd9a85642b7fe0e9a73254ce +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/PhaseEndConditions/BossDeadPhaseEndCondition.cs b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/PhaseEndConditions/BossDeadPhaseEndCondition.cs new file mode 100644 index 0000000..f4990d7 --- /dev/null +++ b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/PhaseEndConditions/BossDeadPhaseEndCondition.cs @@ -0,0 +1,14 @@ +using GeometryTD.Definition; + +namespace GeometryTD.CustomComponent +{ + internal sealed class BossDeadPhaseEndCondition : IPhaseEndCondition + { + public PhaseEndType EndType => PhaseEndType.BossDead; + + public bool ShouldExit(in PhaseEndConditionContext context) + { + return context.IsPhaseSpawnCompleted && !context.HasAliveBoss; + } + } +} diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/PhaseEndConditions/BossDeadPhaseEndCondition.cs.meta b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/PhaseEndConditions/BossDeadPhaseEndCondition.cs.meta new file mode 100644 index 0000000..28a6bb5 --- /dev/null +++ b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/PhaseEndConditions/BossDeadPhaseEndCondition.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 69d0ce2f2c3ee424985fa9775c6291d1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/PhaseEndConditions/EnemiesClearedPhaseEndCondition.cs b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/PhaseEndConditions/EnemiesClearedPhaseEndCondition.cs new file mode 100644 index 0000000..aeeb420 --- /dev/null +++ b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/PhaseEndConditions/EnemiesClearedPhaseEndCondition.cs @@ -0,0 +1,14 @@ +using GeometryTD.Definition; + +namespace GeometryTD.CustomComponent +{ + internal sealed class EnemiesClearedPhaseEndCondition : IPhaseEndCondition + { + public PhaseEndType EndType => PhaseEndType.EnemiesCleared; + + public bool ShouldExit(in PhaseEndConditionContext context) + { + return context.IsPhaseSpawnCompleted && context.AliveEnemyCount <= 0; + } + } +} diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/PhaseEndConditions/EnemiesClearedPhaseEndCondition.cs.meta b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/PhaseEndConditions/EnemiesClearedPhaseEndCondition.cs.meta new file mode 100644 index 0000000..3675ef7 --- /dev/null +++ b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/PhaseEndConditions/EnemiesClearedPhaseEndCondition.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9a9d79f496dab39479265367593921f8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/PhaseEndConditions/IPhaseEndCondition.cs b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/PhaseEndConditions/IPhaseEndCondition.cs new file mode 100644 index 0000000..eeba254 --- /dev/null +++ b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/PhaseEndConditions/IPhaseEndCondition.cs @@ -0,0 +1,11 @@ +using GeometryTD.Definition; + +namespace GeometryTD.CustomComponent +{ + internal interface IPhaseEndCondition + { + PhaseEndType EndType { get; } + + bool ShouldExit(in PhaseEndConditionContext context); + } +} diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/PhaseEndConditions/IPhaseEndCondition.cs.meta b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/PhaseEndConditions/IPhaseEndCondition.cs.meta new file mode 100644 index 0000000..ea05c69 --- /dev/null +++ b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/PhaseEndConditions/IPhaseEndCondition.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 15e7750c40dbb6449bc1bc93370734cb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/PhaseEndConditions/NonePhaseEndCondition.cs b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/PhaseEndConditions/NonePhaseEndCondition.cs new file mode 100644 index 0000000..3c05abf --- /dev/null +++ b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/PhaseEndConditions/NonePhaseEndCondition.cs @@ -0,0 +1,25 @@ +using GeometryTD.Definition; + +namespace GeometryTD.CustomComponent +{ + internal sealed class NonePhaseEndCondition : IPhaseEndCondition + { + public PhaseEndType EndType => PhaseEndType.None; + + public bool ShouldExit(in PhaseEndConditionContext context) + { + if (context.Phase == null) + { + return false; + } + + if (context.Phase.DurationSeconds > 0 && + context.PhaseElapsedSeconds >= context.Phase.DurationSeconds) + { + return true; + } + + return context.IsPhaseSpawnCompleted && context.AliveEnemyCount <= 0; + } + } +} diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/PhaseEndConditions/NonePhaseEndCondition.cs.meta b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/PhaseEndConditions/NonePhaseEndCondition.cs.meta new file mode 100644 index 0000000..5cf9a5f --- /dev/null +++ b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/PhaseEndConditions/NonePhaseEndCondition.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 27a6e6b0635d41d4d8ba336e05927bab +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/PhaseEndConditions/PhaseEndConditionContext.cs b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/PhaseEndConditions/PhaseEndConditionContext.cs new file mode 100644 index 0000000..49dc8d1 --- /dev/null +++ b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/PhaseEndConditions/PhaseEndConditionContext.cs @@ -0,0 +1,31 @@ +using GeometryTD.DataTable; + +namespace GeometryTD.CustomComponent +{ + internal readonly struct PhaseEndConditionContext + { + public PhaseEndConditionContext( + DRLevelPhase phase, + float phaseElapsedSeconds, + bool isPhaseSpawnCompleted, + int aliveEnemyCount, + bool hasAliveBoss) + { + Phase = phase; + PhaseElapsedSeconds = phaseElapsedSeconds; + IsPhaseSpawnCompleted = isPhaseSpawnCompleted; + AliveEnemyCount = aliveEnemyCount; + HasAliveBoss = hasAliveBoss; + } + + public DRLevelPhase Phase { get; } + + public float PhaseElapsedSeconds { get; } + + public bool IsPhaseSpawnCompleted { get; } + + public int AliveEnemyCount { get; } + + public bool HasAliveBoss { get; } + } +} diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/PhaseEndConditions/PhaseEndConditionContext.cs.meta b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/PhaseEndConditions/PhaseEndConditionContext.cs.meta new file mode 100644 index 0000000..18f939f --- /dev/null +++ b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/PhaseEndConditions/PhaseEndConditionContext.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d4ce36bacd2ae574dbd77a9441cbbecb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/PhaseEndConditions/PhaseEndConditionFactory.cs b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/PhaseEndConditions/PhaseEndConditionFactory.cs new file mode 100644 index 0000000..1690324 --- /dev/null +++ b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/PhaseEndConditions/PhaseEndConditionFactory.cs @@ -0,0 +1,24 @@ +using GeometryTD.Definition; + +namespace GeometryTD.CustomComponent +{ + internal static class PhaseEndConditionFactory + { + private static readonly IPhaseEndCondition None = new NonePhaseEndCondition(); + private static readonly IPhaseEndCondition TimeElapsed = new TimeElapsedPhaseEndCondition(); + private static readonly IPhaseEndCondition EnemiesCleared = new EnemiesClearedPhaseEndCondition(); + private static readonly IPhaseEndCondition BossDead = new BossDeadPhaseEndCondition(); + + public static IPhaseEndCondition Create(PhaseEndType endType) + { + return endType switch + { + PhaseEndType.TimeElapsed => TimeElapsed, + PhaseEndType.EnemiesCleared => EnemiesCleared, + PhaseEndType.BossDead => BossDead, + PhaseEndType.None => None, + _ => None + }; + } + } +} diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/PhaseEndConditions/PhaseEndConditionFactory.cs.meta b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/PhaseEndConditions/PhaseEndConditionFactory.cs.meta new file mode 100644 index 0000000..f3a3269 --- /dev/null +++ b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/PhaseEndConditions/PhaseEndConditionFactory.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 35a7aac328337414dbae929053176177 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/PhaseEndConditions/TimeElapsedPhaseEndCondition.cs b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/PhaseEndConditions/TimeElapsedPhaseEndCondition.cs new file mode 100644 index 0000000..165c0e5 --- /dev/null +++ b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/PhaseEndConditions/TimeElapsedPhaseEndCondition.cs @@ -0,0 +1,37 @@ +using System.Globalization; +using GeometryTD.DataTable; +using GeometryTD.Definition; + +namespace GeometryTD.CustomComponent +{ + internal sealed class TimeElapsedPhaseEndCondition : IPhaseEndCondition + { + public PhaseEndType EndType => PhaseEndType.TimeElapsed; + + public bool ShouldExit(in PhaseEndConditionContext context) + { + if (context.Phase == null) + { + return false; + } + + return context.PhaseElapsedSeconds >= ResolveTimeElapsedThreshold(context.Phase); + } + + private static float ResolveTimeElapsedThreshold(DRLevelPhase phase) + { + if (!string.IsNullOrWhiteSpace(phase.EndParam) && + float.TryParse(phase.EndParam, NumberStyles.Float, CultureInfo.InvariantCulture, out float parsed)) + { + return parsed; + } + + if (phase.DurationSeconds > 0) + { + return phase.DurationSeconds; + } + + return 0f; + } + } +} diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/PhaseEndConditions/TimeElapsedPhaseEndCondition.cs.meta b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/PhaseEndConditions/TimeElapsedPhaseEndCondition.cs.meta new file mode 100644 index 0000000..1b76de4 --- /dev/null +++ b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/PhaseEndConditions/TimeElapsedPhaseEndCondition.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 39315af578eed09408c2a088fb83d409 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatStates/CombatFinishFormState.cs b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatStates/CombatFinishFormState.cs index 4a6aa1e..9f37927 100644 --- a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatStates/CombatFinishFormState.cs +++ b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatStates/CombatFinishFormState.cs @@ -19,7 +19,7 @@ namespace GeometryTD.CustomComponent } Scheduler.CommitSettlementInventory(Scheduler._settlementContext); - Scheduler._settlementContext.GainedGold = Mathf.Max(0, Scheduler._combatResourceManager.GainedGold); + Scheduler._settlementContext.GainedGold = Mathf.Max(0, Scheduler._combatInRunResourceManager.GainedGold); Scheduler.OpenCombatFinishForm(Scheduler._settlementContext); Scheduler.ChangeState(new CombatWaitingForReturnState(Scheduler)); }