refactor 1: 新增/重命名类定义

- 将资源服务类型从 CombatResourceManager 重命名为 CombatInRunResourceManager,并同步更新现有引用。
    - CombatScheduler.cs:28
    - CombatInRunResourceManager.cs:11
    - CombatFinishFormState.cs:22
- 新增掉落解析骨架:
    - EnemyDropResolveContext.cs:6
    - EnemyDropResolveResult.cs:3
    - EnemyDropResolver.cs:7
- 新增 phase end condition 骨架:
    - IPhaseEndCondition.cs:5
    - PhaseEndConditionContext.cs:5
    - PhaseEndConditionFactory.cs:5
    - 以及 4 个实现类:
        - NonePhaseEndCondition
        - TimeElapsedPhaseEndCondition
        - EnemiesClearedPhaseEndCondition
        - BossDeadPhaseEndCondition
This commit is contained in:
SepComet
2026-03-07 11:30:44 +08:00
parent 0ff04f02f4
commit 1d7c5b80d9
25 changed files with 361 additions and 14 deletions
@@ -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;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 69d0ce2f2c3ee424985fa9775c6291d1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -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;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9a9d79f496dab39479265367593921f8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,11 @@
using GeometryTD.Definition;
namespace GeometryTD.CustomComponent
{
internal interface IPhaseEndCondition
{
PhaseEndType EndType { get; }
bool ShouldExit(in PhaseEndConditionContext context);
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 15e7750c40dbb6449bc1bc93370734cb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -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;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 27a6e6b0635d41d4d8ba336e05927bab
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -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; }
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d4ce36bacd2ae574dbd77a9441cbbecb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -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
};
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 35a7aac328337414dbae929053176177
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -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;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 39315af578eed09408c2a088fb83d409
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: