This commit is contained in:
2026-03-11 16:48:26 +08:00
parent 113decb414
commit 9c5871b518
21 changed files with 611 additions and 47 deletions
@@ -10,6 +10,8 @@ namespace GeometryTD.Procedure
{
public class ProcedureMain : ProcedureBase
{
private const int MaxParticipantTowerCount = 4;
public override bool UseNativeDialog => false;
private RepoFormUseCase _repoFormUseCase;
@@ -188,8 +190,23 @@ namespace GeometryTD.Procedure
snapshot = GameEntry.PlayerInventory.GetInventorySnapshot();
}
HandleRunAdvanceResult(
ProcedureMainRunFlowService.TryAdvanceRun(_currentRunState, args.CompletionStatus, snapshot));
ProcedureMainParticipantTowerCleanupResult cleanupResult =
ProcedureMainParticipantTowerCleanupService.RemoveBrokenParticipantTowers(
snapshot,
MaxParticipantTowerCount);
if (cleanupResult.HasAnyRemovedTower && GameEntry.PlayerInventory != null)
{
GameEntry.PlayerInventory.ReplaceInventorySnapshot(snapshot);
}
ProcedureMainRunAdvanceResult advanceResult =
ProcedureMainRunFlowService.TryAdvanceRun(_currentRunState, args.CompletionStatus, snapshot);
HandleRunAdvanceResult(advanceResult);
if (cleanupResult.HasAnyRemovedTower &&
advanceResult != ProcedureMainRunAdvanceResult.RunCompleted)
{
OpenRemovedParticipantTowerDialog(cleanupResult);
}
}
private void OnNodeMapNodeEnterRequested(object sender, GameEventArgs e)
@@ -404,6 +421,14 @@ namespace GeometryTD.Procedure
});
}
private void OpenRemovedParticipantTowerDialog(ProcedureMainParticipantTowerCleanupResult cleanupResult)
{
GameEntry.UIRouter.CloseUI(UIFormType.DialogForm);
GameEntry.UIRouter.OpenUI(
UIFormType.DialogForm,
ProcedureMainParticipantTowerCleanupService.BuildRemovedTowerDialogRawData(cleanupResult));
}
private void OnRunCompleteDialogConfirmed(object userData)
{
_ = userData;
@@ -423,4 +448,4 @@ namespace GeometryTD.Procedure
_isReturnToMenuPending = true;
}
}
}
}
@@ -114,33 +114,10 @@ namespace GeometryTD.Procedure
builder.Append("塔 #");
builder.Append(result.TowerInstanceId);
builder.Append(' ');
builder.Append(GetFailureReasonMessage(result.FailureReason));
builder.Append(CombatParticipantTowerValidationText.GetFailureReasonMessage(result.FailureReason));
}
return builder.ToString();
}
private static string GetFailureReasonMessage(CombatParticipantTowerValidationFailureReason failureReason)
{
switch (failureReason)
{
case CombatParticipantTowerValidationFailureReason.TowerMissing:
return "已不存在,无法参战。";
case CombatParticipantTowerValidationFailureReason.MissingMuzzleComponent:
return "缺少枪口组件。";
case CombatParticipantTowerValidationFailureReason.MissingBearingComponent:
return "缺少轴承组件。";
case CombatParticipantTowerValidationFailureReason.MissingBaseComponent:
return "缺少底座组件。";
case CombatParticipantTowerValidationFailureReason.BrokenMuzzleComponent:
return "枪口组件耐久为 0,无法参战。";
case CombatParticipantTowerValidationFailureReason.BrokenBearingComponent:
return "轴承组件耐久为 0,无法参战。";
case CombatParticipantTowerValidationFailureReason.BrokenBaseComponent:
return "底座组件耐久为 0,无法参战。";
default:
return "不满足当前参战条件。";
}
}
}
}
@@ -0,0 +1,106 @@
using System.Collections.Generic;
using GeometryTD.CustomUtility;
using GeometryTD.Definition;
using GeometryTD.UI;
namespace GeometryTD.Procedure
{
public sealed class ProcedureMainParticipantTowerCleanupResult
{
public List<CombatParticipantTowerValidationResult> RemovedResults { get; } = new();
public bool HasAnyRemovedTower => RemovedResults.Count > 0;
}
public static class ProcedureMainParticipantTowerCleanupService
{
public static ProcedureMainParticipantTowerCleanupResult RemoveBrokenParticipantTowers(
BackpackInventoryData inventory,
int maxParticipantCount)
{
ProcedureMainParticipantTowerCleanupResult result = new ProcedureMainParticipantTowerCleanupResult();
if (inventory == null)
{
return result;
}
CombatParticipantTowerValidationSummary summary =
CombatParticipantTowerValidationService.ValidateParticipantTowers(inventory);
if (summary.InvalidResults == null || summary.InvalidResults.Count <= 0)
{
return result;
}
HashSet<long> removedTowerIds = new HashSet<long>();
for (int i = 0; i < summary.InvalidResults.Count; i++)
{
CombatParticipantTowerValidationResult invalidResult = summary.InvalidResults[i];
if (invalidResult == null ||
invalidResult.TowerInstanceId <= 0 ||
!IsBrokenFailureReason(invalidResult.FailureReason) ||
!removedTowerIds.Add(invalidResult.TowerInstanceId))
{
continue;
}
if (InventoryParticipantUtility.TryRemoveParticipantTower(
inventory,
invalidResult.TowerInstanceId,
maxParticipantCount))
{
result.RemovedResults.Add(invalidResult);
}
}
return result;
}
public static DialogFormRawData BuildRemovedTowerDialogRawData(
ProcedureMainParticipantTowerCleanupResult cleanupResult)
{
return new DialogFormRawData
{
Mode = 1,
Title = "出战塔已损坏",
Message = BuildRemovedTowerDialogMessage(cleanupResult),
PauseGame = false,
ConfirmText = "知道了"
};
}
private static string BuildRemovedTowerDialogMessage(
ProcedureMainParticipantTowerCleanupResult cleanupResult)
{
if (cleanupResult == null || !cleanupResult.HasAnyRemovedTower)
{
return "当前没有需要移出参战区的损坏防御塔。";
}
System.Text.StringBuilder builder = new System.Text.StringBuilder();
builder.Append("以下防御塔已损坏,已自动移出参战区:");
for (int i = 0; i < cleanupResult.RemovedResults.Count; i++)
{
CombatParticipantTowerValidationResult removedResult = cleanupResult.RemovedResults[i];
if (removedResult == null)
{
continue;
}
builder.Append('\n');
builder.Append("塔 #");
builder.Append(removedResult.TowerInstanceId);
builder.Append(' ');
builder.Append(CombatParticipantTowerValidationText.GetFailureReasonMessage(removedResult.FailureReason));
}
return builder.ToString();
}
private static bool IsBrokenFailureReason(CombatParticipantTowerValidationFailureReason failureReason)
{
return failureReason == CombatParticipantTowerValidationFailureReason.BrokenMuzzleComponent ||
failureReason == CombatParticipantTowerValidationFailureReason.BrokenBearingComponent ||
failureReason == CombatParticipantTowerValidationFailureReason.BrokenBaseComponent;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 597a543063e14117a16e3530f9cb4949
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: