S5-04
This commit is contained in:
parent
113decb414
commit
9c5871b518
|
|
@ -1,6 +1,6 @@
|
||||||
# Id 列1 Title Description Options
|
# Id 列1 Title Description Options
|
||||||
# int string string string
|
# int string string string
|
||||||
# 事件编号 策划备注 事件题目 事件描述 事件选项
|
# 事件编号 策划备注 事件题目 事件描述 事件选项
|
||||||
1 赌马 一名商人邀请你下注。赢了就能赚一笔。 [{\"optionText\":\"下注 100(金)- 稳健:70% 赢 150\",\"requirements\":[{\"type\":\"GoldAtLeast\",\"param\":{\"Count\":100}}],\"costEffects\":[{\"type\":\"AddGold\",\"param\":{\"Count\":-100}}],\"rewardEffects\":[{\"type\":\"AddGold\",\"param\":{\"Count\":150}}],\"probability\":0.7},{\"optionText\":\"下注 100(金)- 激进:30% 赢 250\",\"requirements\":[{\"type\":\"GoldAtLeast\",\"param\":{\"Count\":100}}],\"costEffects\":[{\"type\":\"AddGold\",\"param\":{\"Count\":-100}}],\"rewardEffects\":[{\"type\":\"AddGold\",\"param\":{\"Count\":250}}],\"probability\":0.3}]
|
1 赌马 一名商人邀请你下注。赢了就能赚一笔。 [{"optionText":"下注 100(金)- 稳健:70% 赢 150","requirements":[{"type":"GoldAtLeast","param":{"Count":100}}],"costEffects":[{"type":"AddGold","param":{"Count":-100}}],"rewardEffects":[{"type":"AddGold","param":{"Count":150}}],"probability":0.7},{"optionText":"下注 100(金)- 激进:30% 赢 250","requirements":[{"type":"GoldAtLeast","param":{"Count":100}}],"costEffects":[{"type":"AddGold","param":{"Count":-100}}],"rewardEffects":[{"type":"AddGold","param":{"Count":250}}],"probability":0.3}]
|
||||||
2 工匠的熔炉 工匠以金币交换防御塔组件。 [{\"optionText\":\"交出 3 个白色组件,获得 50 金币\",\"requirements\":[{\"type\":\"CompCountAtLeast\",\"param\":{\"Count\":3,\"Rarity\":\"White\"}}],\"costEffects\":[{\"type\":\"RemoveRandomComps\",\"param\":{\"Count\":3,\"Rarity\":\"White\"}}],\"rewardEffects\":[{\"type\":\"AddGold\",\"param\":{\"Count\":50}}]},{\"optionText\":\"交出 2 个绿色组件,获得 70 金币\",\"requirements\":[{\"type\":\"CompCountAtLeast\",\"param\":{\"Count\":2,\"Rarity\":\"Green\"}}],\"costEffects\":[{\"type\":\"RemoveRandomComps\",\"param\":{\"Count\":2,\"Rarity\":\"Green\"}}],\"rewardEffects\":[{\"type\":\"AddGold\",\"param\":{\"Count\":70}}]},{\"optionText\":\"交出 1 个蓝色组件,获得 80 金币\",\"requirements\":[{\"type\":\"CompCountAtLeast\",\"param\":{\"Count\":1,\"Rarity\":\"Blue\"}}],\"costEffects\":[{\"type\":\"RemoveRandomComps\",\"param\":{\"Count\":1,\"Rarity\":\"Blue\"}}],\"rewardEffects\":[{\"type\":\"AddGold\",\"param\":{\"Count\":80}}]},{\"optionText\":\"拒绝\",\"rewardEffects\":[]}]
|
2 工匠的熔炉 工匠以金币交换防御塔组件。 [{"optionText":"交出 3 个白色组件,获得 50 金币","requirements":[{"type":"CompCountAtLeast","param":{"Count":3,"Rarity":"White"}}],"costEffects":[{"type":"RemoveRandomComps","param":{"Count":3,"Rarity":"White"}}],"rewardEffects":[{"type":"AddGold","param":{"Count":50}}]},{"optionText":"交出 2 个绿色组件,获得 70 金币","requirements":[{"type":"CompCountAtLeast","param":{"Count":2,"Rarity":"Green"}}],"costEffects":[{"type":"RemoveRandomComps","param":{"Count":2,"Rarity":"Green"}}],"rewardEffects":[{"type":"AddGold","param":{"Count":70}}]},{"optionText":"交出 1 个蓝色组件,获得 80 金币","requirements":[{"type":"CompCountAtLeast","param":{"Count":1,"Rarity":"Blue"}}],"costEffects":[{"type":"RemoveRandomComps","param":{"Count":1,"Rarity":"Blue"}}],"rewardEffects":[{"type":"AddGold","param":{"Count":80}}]},{"optionText":"拒绝","rewardEffects":[]}]
|
||||||
3 代价与回报 某种黑暗力量向你索取代价。 [{\"optionText\":\"展示你的防御塔\",\"requirements\":[{\"type\":\"TowerCountAtLeast\",\"param\":{\"Count\":2}}],\"rewardEffects\":[{\"type\":\"AddGold\",\"param\":{\"Count\":50}}]},{\"optionText\":\"离开\",\"rewardEffects\":[]}]
|
3 代价与回报 某种黑暗力量向你索取代价。 [{"optionText":"展示你的防御塔","requirements":[{"type":"TowerCountAtLeast","param":{"Count":2}}],"rewardEffects":[{"type":"AddGold","param":{"Count":50}}]},{"optionText":"离开","rewardEffects":[]}]
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,15 @@
|
||||||
# Id 列1 TagType TriggerPhase Description Param
|
# Id 列1 TagType TriggerPhase Description Param
|
||||||
# int TagType TagTriggerPhase string string
|
# int TagType TagTriggerPhase string string
|
||||||
# Tag配置编号 策划备注 所属Tag类型 触发阶段 描述 参数Json
|
# Tag配置编号 策划备注 所属Tag类型 触发阶段 描述 参数Json
|
||||||
1 元素 Fire OnAfterHit 持续对敌人造成<color=red>火</color>伤害 {\"BurnDurationSeconds\":3,\"BurnDamagePerSecondPerStack\":20,\"MaxEffectiveStack\":5}
|
1 元素 Fire OnAfterHit 持续对敌人造成<color=red>火</color>伤害 {"BurnDurationSeconds":3,"BurnDamagePerSecondPerStack":20,"MaxEffectiveStack":5}
|
||||||
2 元素 BurnSpread None 燃烧向邻近敌人传播 {\"SpreadRadius\":2,\"SpreadDamageRate\":1}
|
2 元素 BurnSpread None 燃烧向邻近敌人传播 {"SpreadRadius":2,"SpreadDamageRate":1}
|
||||||
3 元素 IgniteBurst None 燃烧结束或击杀时爆炸 {\"BurstRadius\":1,\"BurstDamageRate\":0.5}
|
3 元素 IgniteBurst None 燃烧结束或击杀时爆炸 {"BurstRadius":1,"BurstDamageRate":0.5}
|
||||||
4 元素 Inferno OnAfterHit 强化燃烧伤害或持续时间 {\"BonusBurnDurationSeconds\":0.1,\"BonusBurnDamagePerSecondPerStack\":0.1}
|
4 元素 Inferno OnAfterHit 强化燃烧伤害或持续时间 {"BonusBurnDurationSeconds":0.1,"BonusBurnDamagePerSecondPerStack":0.1}
|
||||||
5 控制 Ice OnAfterHit 命中附加减速 {\"SlowDurationSeconds\":2,\"SlowRatioPerStack\":0.2,\"MinMoveSpeedMultiplier\":0.4}
|
5 控制 Ice OnAfterHit 命中附加减速 {"SlowDurationSeconds":2,"SlowRatioPerStack":0.2,"MinMoveSpeedMultiplier":0.4}
|
||||||
6 控制 FreezeMask None 冻结积累条 / 冻结面具机制 {\"FreezeBuildUpPerStack\":0.1}
|
6 控制 FreezeMask None 冻结积累条 / 冻结面具机制 {"FreezeBuildUpPerStack":0.1}
|
||||||
7 控制 Shatter OnBeforeHit 对已减速 / 已冻结目标增伤 {\"RequiresSlowedTarget\":true,\"DamageBonusPerStack\":0.1}
|
7 控制 Shatter OnBeforeHit 对已减速 / 已冻结目标增伤 {"RequiresSlowedTarget":true,"DamageBonusPerStack":0.1}
|
||||||
8 控制 AbsoluteZero OnAfterHit 强化减速,或提高冻结触发速度 {\"BonusSlowDurationSeconds\":0.1,\"BonusSlowRatioPerStack\":0.2}
|
8 控制 AbsoluteZero OnAfterHit 强化减速,或提高冻结触发速度 {"BonusSlowDurationSeconds":0.1,"BonusSlowRatioPerStack":0.2}
|
||||||
9 穿透 Pierce None 子弹贯穿多个目标 {\"ExtraPierceCount\":2}
|
9 穿透 Pierce None 子弹贯穿多个目标 {"ExtraPierceCount":2}
|
||||||
10 穿透 Crit OnBeforeHit 命中前按概率暴击 {\"CritChancePerStack\":0.1,\"CritDamageMultiplier\":1.5}
|
10 穿透 Crit OnBeforeHit 命中前按概率暴击 {"CritChancePerStack":0.1,"CritDamageMultiplier":1.5}
|
||||||
11 穿透 Overpenetrate None 贯穿后保留部分伤害继续飞行 {\"ExtraPenetrationCount\":0.1,\"RemainingDamageRate\":0.2}
|
11 穿透 Overpenetrate None 贯穿后保留部分伤害继续飞行 {"ExtraPenetrationCount":0.1,"RemainingDamageRate":0.2}
|
||||||
12 穿透 Execution OnBeforeHit 对低血量目标增伤或直接处决 {\"TargetHealthThreshold\":0.3,\"DamageBonusPerStack\":0.5}
|
12 穿透 Execution OnBeforeHit 对低血量目标增伤或直接处决 {"TargetHealthThreshold":0.3,"DamageBonusPerStack":0.5}
|
||||||
|
|
|
||||||
|
|
@ -38,4 +38,4 @@ namespace GeometryTD.DataTable
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
namespace GeometryTD.Definition
|
||||||
|
{
|
||||||
|
public static class CombatParticipantTowerValidationText
|
||||||
|
{
|
||||||
|
public 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,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d7cba7cf0b7a4bfe96f172620db8d30d
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -10,6 +10,8 @@ namespace GeometryTD.Procedure
|
||||||
{
|
{
|
||||||
public class ProcedureMain : ProcedureBase
|
public class ProcedureMain : ProcedureBase
|
||||||
{
|
{
|
||||||
|
private const int MaxParticipantTowerCount = 4;
|
||||||
|
|
||||||
public override bool UseNativeDialog => false;
|
public override bool UseNativeDialog => false;
|
||||||
|
|
||||||
private RepoFormUseCase _repoFormUseCase;
|
private RepoFormUseCase _repoFormUseCase;
|
||||||
|
|
@ -188,8 +190,23 @@ namespace GeometryTD.Procedure
|
||||||
snapshot = GameEntry.PlayerInventory.GetInventorySnapshot();
|
snapshot = GameEntry.PlayerInventory.GetInventorySnapshot();
|
||||||
}
|
}
|
||||||
|
|
||||||
HandleRunAdvanceResult(
|
ProcedureMainParticipantTowerCleanupResult cleanupResult =
|
||||||
ProcedureMainRunFlowService.TryAdvanceRun(_currentRunState, args.CompletionStatus, snapshot));
|
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)
|
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)
|
private void OnRunCompleteDialogConfirmed(object userData)
|
||||||
{
|
{
|
||||||
_ = userData;
|
_ = userData;
|
||||||
|
|
@ -423,4 +448,4 @@ namespace GeometryTD.Procedure
|
||||||
_isReturnToMenuPending = true;
|
_isReturnToMenuPending = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -114,33 +114,10 @@ namespace GeometryTD.Procedure
|
||||||
builder.Append("塔 #");
|
builder.Append("塔 #");
|
||||||
builder.Append(result.TowerInstanceId);
|
builder.Append(result.TowerInstanceId);
|
||||||
builder.Append(' ');
|
builder.Append(' ');
|
||||||
builder.Append(GetFailureReasonMessage(result.FailureReason));
|
builder.Append(CombatParticipantTowerValidationText.GetFailureReasonMessage(result.FailureReason));
|
||||||
}
|
}
|
||||||
|
|
||||||
return builder.ToString();
|
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:
|
||||||
|
|
@ -185,7 +185,10 @@ namespace GeometryTD.UI
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Form.SetRepoItemSelected(args.ItemId, args.Assigned);
|
bool isSelected = _compAreaTowerIds.Contains(args.ItemId)
|
||||||
|
? _participantTowerIds.Contains(args.ItemId)
|
||||||
|
: args.Assigned;
|
||||||
|
Form.SetRepoItemSelected(args.ItemId, isSelected);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnCombineSlotClicked(object sender, GameEventArgs e)
|
private void OnCombineSlotClicked(object sender, GameEventArgs e)
|
||||||
|
|
@ -284,6 +287,9 @@ namespace GeometryTD.UI
|
||||||
result.TowerInstanceId,
|
result.TowerInstanceId,
|
||||||
result.FailureReason,
|
result.FailureReason,
|
||||||
result.ValidationFailureReason);
|
result.ValidationFailureReason);
|
||||||
|
GameEntry.UIRouter.OpenUI(
|
||||||
|
UIFormType.DialogForm,
|
||||||
|
RepoParticipantAssignDialogUtility.BuildDialog(result, MaxParticipantCount));
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
using GeometryTD.Definition;
|
||||||
|
|
||||||
|
namespace GeometryTD.UI
|
||||||
|
{
|
||||||
|
public static class RepoParticipantAssignDialogUtility
|
||||||
|
{
|
||||||
|
public static DialogFormRawData BuildDialog(
|
||||||
|
ParticipantTowerAssignResult result,
|
||||||
|
int maxParticipantCount)
|
||||||
|
{
|
||||||
|
return new DialogFormRawData
|
||||||
|
{
|
||||||
|
Mode = 1,
|
||||||
|
Title = "无法加入参战区",
|
||||||
|
Message = BuildMessage(result, maxParticipantCount),
|
||||||
|
PauseGame = false,
|
||||||
|
ConfirmText = "知道了"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string BuildMessage(
|
||||||
|
ParticipantTowerAssignResult result,
|
||||||
|
int maxParticipantCount)
|
||||||
|
{
|
||||||
|
if (result == null)
|
||||||
|
{
|
||||||
|
return "当前无法加入参战区,请稍后重试。";
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (result.FailureReason)
|
||||||
|
{
|
||||||
|
case ParticipantTowerAssignFailureReason.TowerMissing:
|
||||||
|
return $"塔 #{result.TowerInstanceId} 已不存在,无法加入参战区。";
|
||||||
|
case ParticipantTowerAssignFailureReason.InvalidTower:
|
||||||
|
return $"塔 #{result.TowerInstanceId} {CombatParticipantTowerValidationText.GetFailureReasonMessage(result.ValidationFailureReason)}";
|
||||||
|
case ParticipantTowerAssignFailureReason.AlreadyAssigned:
|
||||||
|
return $"塔 #{result.TowerInstanceId} 已在参战区中。";
|
||||||
|
case ParticipantTowerAssignFailureReason.ParticipantAreaFull:
|
||||||
|
return $"参战区已满,最多只能放入 {maxParticipantCount} 座塔。";
|
||||||
|
default:
|
||||||
|
return "当前无法加入参战区,请稍后重试。";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 6e6500e5312e4f2cb788f03f0aa8ab0c
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -117,7 +117,7 @@ namespace GeometryTD.CustomUtility
|
||||||
ConfigId = 3,
|
ConfigId = 3,
|
||||||
Name = "穿透枪口",
|
Name = "穿透枪口",
|
||||||
Rarity = InventoryRarityRuleService.NormalizeComponentRarity(RarityType.Purple),
|
Rarity = InventoryRarityRuleService.NormalizeComponentRarity(RarityType.Purple),
|
||||||
Endurance = 97f,
|
Endurance = 1f,
|
||||||
IsAssembledIntoTower = false,
|
IsAssembledIntoTower = false,
|
||||||
AttackDamage = new[] { 50, 55, 60, 80, 90 },
|
AttackDamage = new[] { 50, 55, 60, 80, 90 },
|
||||||
DamageRandomRate = 0.02f,
|
DamageRandomRate = 0.02f,
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,14 @@ namespace GeometryTD.CustomUtility
|
||||||
sb.Append(BuildTowerDesc(tower.Stats ?? new TowerStatsData()));
|
sb.Append(BuildTowerDesc(tower.Stats ?? new TowerStatsData()));
|
||||||
float enduranceRate = ResolveTowerEnduranceRate(tower, muzzleMap, bearingMap, baseMap);
|
float enduranceRate = ResolveTowerEnduranceRate(tower, muzzleMap, bearingMap, baseMap);
|
||||||
sb.AppendLine($"平均耐久: {enduranceRate * 100f:0.#}");
|
sb.AppendLine($"平均耐久: {enduranceRate * 100f:0.#}");
|
||||||
|
CombatParticipantTowerValidationFailureReason failureReason =
|
||||||
|
ResolveTowerValidationFailureReason(tower, muzzleMap, bearingMap, baseMap);
|
||||||
|
if (failureReason != CombatParticipantTowerValidationFailureReason.None)
|
||||||
|
{
|
||||||
|
sb.AppendLine("状态:已损坏");
|
||||||
|
sb.Append($"参战限制:{CombatParticipantTowerValidationText.GetFailureReasonMessage(failureReason)}");
|
||||||
|
}
|
||||||
|
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -139,6 +147,7 @@ namespace GeometryTD.CustomUtility
|
||||||
sb.AppendLine($"攻击方式:{ConvertAttackMethod(muzzleData.AttackMethodType)}");
|
sb.AppendLine($"攻击方式:{ConvertAttackMethod(muzzleData.AttackMethodType)}");
|
||||||
|
|
||||||
sb.AppendLine($"当前耐久:{muzzleData.Endurance}");
|
sb.AppendLine($"当前耐久:{muzzleData.Endurance}");
|
||||||
|
AppendComponentBrokenStatus(sb, muzzleData);
|
||||||
|
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
|
@ -164,6 +173,7 @@ namespace GeometryTD.CustomUtility
|
||||||
sb.Append('\n');
|
sb.Append('\n');
|
||||||
|
|
||||||
sb.AppendLine($"当前耐久:{bearingData.Endurance}");
|
sb.AppendLine($"当前耐久:{bearingData.Endurance}");
|
||||||
|
AppendComponentBrokenStatus(sb, bearingData);
|
||||||
|
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
|
@ -183,10 +193,65 @@ namespace GeometryTD.CustomUtility
|
||||||
sb.AppendLine($"伤害属性:{ConvertAttackProperty(baseData.AttackPropertyType)}");
|
sb.AppendLine($"伤害属性:{ConvertAttackProperty(baseData.AttackPropertyType)}");
|
||||||
|
|
||||||
sb.AppendLine($"当前耐久:{baseData.Endurance}");
|
sb.AppendLine($"当前耐久:{baseData.Endurance}");
|
||||||
|
AppendComponentBrokenStatus(sb, baseData);
|
||||||
|
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void AppendComponentBrokenStatus(StringBuilder sb, TowerCompItemData component)
|
||||||
|
{
|
||||||
|
if (sb == null || component == null || component.Endurance > 0f)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.AppendLine("状态:已损坏,无法参战。");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static CombatParticipantTowerValidationFailureReason ResolveTowerValidationFailureReason(
|
||||||
|
TowerItemData tower,
|
||||||
|
IReadOnlyDictionary<long, MuzzleCompItemData> muzzleMap,
|
||||||
|
IReadOnlyDictionary<long, BearingCompItemData> bearingMap,
|
||||||
|
IReadOnlyDictionary<long, BaseCompItemData> baseMap)
|
||||||
|
{
|
||||||
|
if (tower == null)
|
||||||
|
{
|
||||||
|
return CombatParticipantTowerValidationFailureReason.TowerMissing;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (muzzleMap == null || !muzzleMap.TryGetValue(tower.MuzzleComponentInstanceId, out MuzzleCompItemData muzzle))
|
||||||
|
{
|
||||||
|
return CombatParticipantTowerValidationFailureReason.MissingMuzzleComponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (muzzle.Endurance <= 0f)
|
||||||
|
{
|
||||||
|
return CombatParticipantTowerValidationFailureReason.BrokenMuzzleComponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bearingMap == null || !bearingMap.TryGetValue(tower.BearingComponentInstanceId, out BearingCompItemData bearing))
|
||||||
|
{
|
||||||
|
return CombatParticipantTowerValidationFailureReason.MissingBearingComponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bearing.Endurance <= 0f)
|
||||||
|
{
|
||||||
|
return CombatParticipantTowerValidationFailureReason.BrokenBearingComponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (baseMap == null || !baseMap.TryGetValue(tower.BaseComponentInstanceId, out BaseCompItemData baseComp))
|
||||||
|
{
|
||||||
|
return CombatParticipantTowerValidationFailureReason.MissingBaseComponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (baseComp.Endurance <= 0f)
|
||||||
|
{
|
||||||
|
return CombatParticipantTowerValidationFailureReason.BrokenBaseComponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CombatParticipantTowerValidationFailureReason.None;
|
||||||
|
}
|
||||||
|
|
||||||
public static string ConvertAttackMethod(AttackMethodType type)
|
public static string ConvertAttackMethod(AttackMethodType type)
|
||||||
{
|
{
|
||||||
return type switch
|
return type switch
|
||||||
|
|
@ -215,4 +280,3 @@ namespace GeometryTD.CustomUtility
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,92 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using GeometryTD.CustomUtility;
|
||||||
|
using GeometryTD.Definition;
|
||||||
|
using NUnit.Framework;
|
||||||
|
|
||||||
|
namespace GeometryTD.Tests.EditMode
|
||||||
|
{
|
||||||
|
public sealed class ItemDescUtilityTests
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void BuildMuzzleDesc_Appends_Broken_Status_When_Endurance_Is_Zero()
|
||||||
|
{
|
||||||
|
string description = ItemDescUtility.BuildMuzzleDesc(new MuzzleCompItemData
|
||||||
|
{
|
||||||
|
AttackDamage = new[] { 10 },
|
||||||
|
DamageRandomRate = 0.1f,
|
||||||
|
AttackMethodType = AttackMethodType.NormalBullet,
|
||||||
|
Endurance = 0f
|
||||||
|
});
|
||||||
|
|
||||||
|
StringAssert.Contains("当前耐久:0", description);
|
||||||
|
StringAssert.Contains("状态:已损坏,无法参战。", description);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void BuildTowerDesc_Appends_Broken_Status_And_Restriction_When_Component_Is_Broken()
|
||||||
|
{
|
||||||
|
TowerItemData tower = CreateTower();
|
||||||
|
Dictionary<long, MuzzleCompItemData> muzzleMap = new Dictionary<long, MuzzleCompItemData>
|
||||||
|
{
|
||||||
|
[10001] = new MuzzleCompItemData { InstanceId = 10001, Endurance = 0f }
|
||||||
|
};
|
||||||
|
Dictionary<long, BearingCompItemData> bearingMap = new Dictionary<long, BearingCompItemData>
|
||||||
|
{
|
||||||
|
[20001] = new BearingCompItemData { InstanceId = 20001, Endurance = 100f }
|
||||||
|
};
|
||||||
|
Dictionary<long, BaseCompItemData> baseMap = new Dictionary<long, BaseCompItemData>
|
||||||
|
{
|
||||||
|
[30001] = new BaseCompItemData { InstanceId = 30001, Endurance = 100f }
|
||||||
|
};
|
||||||
|
|
||||||
|
string description = ItemDescUtility.BuildTowerDesc(tower, muzzleMap, bearingMap, baseMap);
|
||||||
|
|
||||||
|
StringAssert.Contains("状态:已损坏", description);
|
||||||
|
StringAssert.Contains("参战限制:枪口组件耐久为 0,无法参战。", description);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void BuildTowerDesc_Does_Not_Append_Broken_Status_When_Tower_Is_Valid()
|
||||||
|
{
|
||||||
|
TowerItemData tower = CreateTower();
|
||||||
|
Dictionary<long, MuzzleCompItemData> muzzleMap = new Dictionary<long, MuzzleCompItemData>
|
||||||
|
{
|
||||||
|
[10001] = new MuzzleCompItemData { InstanceId = 10001, Endurance = 100f }
|
||||||
|
};
|
||||||
|
Dictionary<long, BearingCompItemData> bearingMap = new Dictionary<long, BearingCompItemData>
|
||||||
|
{
|
||||||
|
[20001] = new BearingCompItemData { InstanceId = 20001, Endurance = 100f }
|
||||||
|
};
|
||||||
|
Dictionary<long, BaseCompItemData> baseMap = new Dictionary<long, BaseCompItemData>
|
||||||
|
{
|
||||||
|
[30001] = new BaseCompItemData { InstanceId = 30001, Endurance = 100f }
|
||||||
|
};
|
||||||
|
|
||||||
|
string description = ItemDescUtility.BuildTowerDesc(tower, muzzleMap, bearingMap, baseMap);
|
||||||
|
|
||||||
|
StringAssert.DoesNotContain("状态:已损坏", description);
|
||||||
|
StringAssert.DoesNotContain("参战限制:", description);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TowerItemData CreateTower()
|
||||||
|
{
|
||||||
|
return new TowerItemData
|
||||||
|
{
|
||||||
|
InstanceId = 90001,
|
||||||
|
MuzzleComponentInstanceId = 10001,
|
||||||
|
BearingComponentInstanceId = 20001,
|
||||||
|
BaseComponentInstanceId = 30001,
|
||||||
|
Stats = new TowerStatsData
|
||||||
|
{
|
||||||
|
AttackDamage = new[] { 10 },
|
||||||
|
DamageRandomRate = 0.1f,
|
||||||
|
AttackMethodType = AttackMethodType.NormalBullet,
|
||||||
|
RotateSpeed = new[] { 1f },
|
||||||
|
AttackRange = new[] { 2f },
|
||||||
|
AttackSpeed = new[] { 1f },
|
||||||
|
AttackPropertyType = AttackPropertyType.Physics
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 128f16fc0aa2493f9ffeb226f76d2661
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,85 @@
|
||||||
|
using GeometryTD.Definition;
|
||||||
|
using GeometryTD.Procedure;
|
||||||
|
using GeometryTD.UI;
|
||||||
|
using NUnit.Framework;
|
||||||
|
|
||||||
|
namespace GeometryTD.Tests.EditMode
|
||||||
|
{
|
||||||
|
public sealed class ProcedureMainParticipantTowerCleanupServiceTests
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void RemoveBrokenParticipantTowers_Removes_Only_Broken_Participant_Towers()
|
||||||
|
{
|
||||||
|
BackpackInventoryData inventory = CreateInventory();
|
||||||
|
inventory.MuzzleComponents[0].Endurance = 0f;
|
||||||
|
inventory.ParticipantTowerInstanceIds.Add(90002);
|
||||||
|
|
||||||
|
ProcedureMainParticipantTowerCleanupResult result =
|
||||||
|
ProcedureMainParticipantTowerCleanupService.RemoveBrokenParticipantTowers(inventory, 4);
|
||||||
|
|
||||||
|
Assert.That(result.HasAnyRemovedTower, Is.True);
|
||||||
|
Assert.That(result.RemovedResults.Count, Is.EqualTo(1));
|
||||||
|
Assert.That(result.RemovedResults[0].TowerInstanceId, Is.EqualTo(90001));
|
||||||
|
CollectionAssert.AreEqual(new long[] { 90002 }, inventory.ParticipantTowerInstanceIds);
|
||||||
|
Assert.That(inventory.Towers[0].IsParticipatingInCombat, Is.False);
|
||||||
|
Assert.That(inventory.Towers[1].IsParticipatingInCombat, Is.True);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void BuildRemovedTowerDialogRawData_Lists_Removed_Broken_Towers()
|
||||||
|
{
|
||||||
|
ProcedureMainParticipantTowerCleanupResult cleanupResult = new ProcedureMainParticipantTowerCleanupResult();
|
||||||
|
cleanupResult.RemovedResults.Add(new CombatParticipantTowerValidationResult
|
||||||
|
{
|
||||||
|
TowerInstanceId = 90001,
|
||||||
|
FailureReason = CombatParticipantTowerValidationFailureReason.BrokenMuzzleComponent
|
||||||
|
});
|
||||||
|
cleanupResult.RemovedResults.Add(new CombatParticipantTowerValidationResult
|
||||||
|
{
|
||||||
|
TowerInstanceId = 90002,
|
||||||
|
FailureReason = CombatParticipantTowerValidationFailureReason.BrokenBaseComponent
|
||||||
|
});
|
||||||
|
|
||||||
|
DialogFormRawData rawData =
|
||||||
|
ProcedureMainParticipantTowerCleanupService.BuildRemovedTowerDialogRawData(cleanupResult);
|
||||||
|
|
||||||
|
Assert.That(rawData.Title, Is.EqualTo("出战塔已损坏"));
|
||||||
|
Assert.That(
|
||||||
|
rawData.Message,
|
||||||
|
Is.EqualTo("以下防御塔已损坏,已自动移出参战区:\n塔 #90001 枪口组件耐久为 0,无法参战。\n塔 #90002 底座组件耐久为 0,无法参战。"));
|
||||||
|
Assert.That(rawData.ConfirmText, Is.EqualTo("知道了"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static BackpackInventoryData CreateInventory()
|
||||||
|
{
|
||||||
|
BackpackInventoryData inventory = new BackpackInventoryData();
|
||||||
|
AddTower(inventory, 90001, 10001, 20001, 30001);
|
||||||
|
AddTower(inventory, 90002, 10002, 20002, 30002);
|
||||||
|
inventory.ParticipantTowerInstanceIds.Add(90001);
|
||||||
|
inventory.ParticipantTowerInstanceIds.Add(90002);
|
||||||
|
inventory.Towers[0].IsParticipatingInCombat = true;
|
||||||
|
inventory.Towers[1].IsParticipatingInCombat = true;
|
||||||
|
return inventory;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void AddTower(
|
||||||
|
BackpackInventoryData inventory,
|
||||||
|
long towerId,
|
||||||
|
long muzzleId,
|
||||||
|
long bearingId,
|
||||||
|
long baseId)
|
||||||
|
{
|
||||||
|
inventory.MuzzleComponents.Add(new MuzzleCompItemData { InstanceId = muzzleId, Endurance = 100f });
|
||||||
|
inventory.BearingComponents.Add(new BearingCompItemData { InstanceId = bearingId, Endurance = 100f });
|
||||||
|
inventory.BaseComponents.Add(new BaseCompItemData { InstanceId = baseId, Endurance = 100f });
|
||||||
|
inventory.Towers.Add(new TowerItemData
|
||||||
|
{
|
||||||
|
InstanceId = towerId,
|
||||||
|
MuzzleComponentInstanceId = muzzleId,
|
||||||
|
BearingComponentInstanceId = bearingId,
|
||||||
|
BaseComponentInstanceId = baseId,
|
||||||
|
Stats = new TowerStatsData()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 7e9f19d3160e4ba2b966d46feae1e8ee
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
using GeometryTD.Definition;
|
||||||
|
using GeometryTD.UI;
|
||||||
|
using NUnit.Framework;
|
||||||
|
|
||||||
|
namespace GeometryTD.Tests.EditMode
|
||||||
|
{
|
||||||
|
public sealed class RepoParticipantAssignDialogUtilityTests
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void BuildDialog_Returns_InvalidTower_Message_For_Broken_Component()
|
||||||
|
{
|
||||||
|
DialogFormRawData rawData = RepoParticipantAssignDialogUtility.BuildDialog(
|
||||||
|
new ParticipantTowerAssignResult
|
||||||
|
{
|
||||||
|
TowerInstanceId = 90001,
|
||||||
|
FailureReason = ParticipantTowerAssignFailureReason.InvalidTower,
|
||||||
|
ValidationFailureReason = CombatParticipantTowerValidationFailureReason.BrokenMuzzleComponent
|
||||||
|
},
|
||||||
|
4);
|
||||||
|
|
||||||
|
Assert.That(rawData.Title, Is.EqualTo("无法加入参战区"));
|
||||||
|
Assert.That(rawData.Message, Is.EqualTo("塔 #90001 枪口组件耐久为 0,无法参战。"));
|
||||||
|
Assert.That(rawData.ConfirmText, Is.EqualTo("知道了"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void BuildDialog_Returns_InvalidTower_Message_For_Missing_Component()
|
||||||
|
{
|
||||||
|
DialogFormRawData rawData = RepoParticipantAssignDialogUtility.BuildDialog(
|
||||||
|
new ParticipantTowerAssignResult
|
||||||
|
{
|
||||||
|
TowerInstanceId = 90002,
|
||||||
|
FailureReason = ParticipantTowerAssignFailureReason.InvalidTower,
|
||||||
|
ValidationFailureReason = CombatParticipantTowerValidationFailureReason.MissingBaseComponent
|
||||||
|
},
|
||||||
|
4);
|
||||||
|
|
||||||
|
Assert.That(rawData.Message, Is.EqualTo("塔 #90002 缺少底座组件。"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void BuildDialog_Returns_ParticipantAreaFull_Message()
|
||||||
|
{
|
||||||
|
DialogFormRawData rawData = RepoParticipantAssignDialogUtility.BuildDialog(
|
||||||
|
new ParticipantTowerAssignResult
|
||||||
|
{
|
||||||
|
TowerInstanceId = 90003,
|
||||||
|
FailureReason = ParticipantTowerAssignFailureReason.ParticipantAreaFull
|
||||||
|
},
|
||||||
|
4);
|
||||||
|
|
||||||
|
Assert.That(rawData.Message, Is.EqualTo("参战区已满,最多只能放入 4 座塔。"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void BuildDialog_Returns_AlreadyAssigned_Message()
|
||||||
|
{
|
||||||
|
DialogFormRawData rawData = RepoParticipantAssignDialogUtility.BuildDialog(
|
||||||
|
new ParticipantTowerAssignResult
|
||||||
|
{
|
||||||
|
TowerInstanceId = 90004,
|
||||||
|
FailureReason = ParticipantTowerAssignFailureReason.AlreadyAssigned
|
||||||
|
},
|
||||||
|
4);
|
||||||
|
|
||||||
|
Assert.That(rawData.Message, Is.EqualTo("塔 #90004 已在参战区中。"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: dcce8297c0fb4a539e4ab8db1a20e165
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -60,7 +60,7 @@ def convert_excel_to_txt(folder_path='.'):
|
||||||
|
|
||||||
# 导出设置:
|
# 导出设置:
|
||||||
# 1. sep='\t' : 使用制表符分隔
|
# 1. sep='\t' : 使用制表符分隔
|
||||||
# 2. quoting=csv.QUOTE_NONE : 不使用引号包裹字段,也不会把 " 变成 ""
|
# 2. quoting=csv.QUOTE_NONE + quotechar='\x00' : 不使用引号包裹字段,且 " 按原样输出
|
||||||
# 3. escapechar='\\' : 如果单元格内恰好有 Tab 键,会用反斜杠转义,防止数据列错位
|
# 3. escapechar='\\' : 如果单元格内恰好有 Tab 键,会用反斜杠转义,防止数据列错位
|
||||||
df.to_csv(
|
df.to_csv(
|
||||||
output_file,
|
output_file,
|
||||||
|
|
@ -69,6 +69,7 @@ def convert_excel_to_txt(folder_path='.'):
|
||||||
header=False,
|
header=False,
|
||||||
encoding='utf-8',
|
encoding='utf-8',
|
||||||
quoting=csv.QUOTE_NONE,
|
quoting=csv.QUOTE_NONE,
|
||||||
|
quotechar='\x00',
|
||||||
escapechar='\\'
|
escapechar='\\'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue