diff --git a/Tools/CheckSuwakoAttackGroundAgain.ps1 b/Tools/CheckSuwakoAttackGroundAgain.ps1 new file mode 100644 index 000000000..cf2603f1f --- /dev/null +++ b/Tools/CheckSuwakoAttackGroundAgain.ps1 @@ -0,0 +1,51 @@ +param() + +$ErrorActionPreference = "Stop" + +$repoRoot = Resolve-Path (Join-Path $PSScriptRoot "..") +$failures = @() + +function Add-Failure { + param([string]$Message) + $script:failures += $Message +} + +function Read-RepoText { + param([string]$RelativePath) + $path = Join-Path $repoRoot $RelativePath + if (-not (Test-Path -LiteralPath $path)) { + Add-Failure "Missing file: $RelativePath" + return "" + } + return Get-Content -LiteralPath $path -Raw +} + +$actionLogic = Read-RepoText "Unity/Assets/Scripts/TH1_Logic/Action/ActionLogic.cs" +$attackGetAttackPointSkill = Read-RepoText "Unity/Assets/Scripts/TH1_Logic/Skill/AllSkill/AttackGetAttackPointSkill.cs" + +if ($attackGetAttackPointSkill -notmatch "public bool TryConsumeAndGrantAttackPoint\(MapData mapData, UnitData self\)") { + Add-Failure "AttackGetAttackPointSkill must expose a reusable consume-and-grant helper for non-damage attack-ground actions." +} + +if ($attackGetAttackPointSkill -notmatch "_level--;\s*self\.AddActionPoint\(ActionPointType\.Attack\);") { + Add-Failure "AttackGetAttackPointSkill must decrement its layer before granting an attack action point." +} + +if ($attackGetAttackPointSkill -notmatch "AfterActiveAttackOther[\s\S]*?TryConsumeAndGrantAttackPoint\(mapData, attackInfo\.DamageOrigin\)") { + Add-Failure "Normal active attacks must still use the same consume-and-grant helper." +} + +$suwakoSummonPattern = "unit1\.ClearActionPoint\(\)[\s\S]*?actionParams\.MapData\.AddUnitData\(targetGrid\.Id, city1\.Id, fullType, out suwakoUnit, 0\.2f\)[\s\S]*?TryConsumeAndGrantAttackPoint\(actionParams\.MapData, unit1\)" +if ($actionLogic -notmatch $suwakoSummonPattern) { + Add-Failure "Suwako empty-grid AttackGround summon must consume AttackGetAttackPoint and restore an Attack action point after ClearActionPoint." +} + +if ($failures.Count -gt 0) { + Write-Host "Suwako AttackGround again check failed:" -ForegroundColor Red + foreach ($failure in $failures) { + Write-Host " - $failure" -ForegroundColor Red + } + exit 1 +} + +Write-Host "Suwako AttackGround again checks passed." diff --git a/Tools/GitCheckpoint.ps1 b/Tools/GitCheckpoint.ps1 index 13f380d49..d1879f3dd 100644 --- a/Tools/GitCheckpoint.ps1 +++ b/Tools/GitCheckpoint.ps1 @@ -154,6 +154,11 @@ $touchedAttackGroundPeaceSemantics = @($paths | Where-Object { $_ -like 'Unity/Assets/Scripts/TH1_Logic/Skill/AllSkill/*.cs' -or $_ -eq 'Tools/CheckAttackGroundPeaceSemantics.ps1' }) +$touchedSuwakoAttackGroundAgain = @($paths | Where-Object { + $_ -eq 'Unity/Assets/Scripts/TH1_Logic/Action/ActionLogic.cs' -or + $_ -eq 'Unity/Assets/Scripts/TH1_Logic/Skill/AllSkill/AttackGetAttackPointSkill.cs' -or + $_ -eq 'Tools/CheckSuwakoAttackGroundAgain.ps1' +}) $touchedPeaceWonderHostileActionSemantics = @($paths | Where-Object { $_ -eq 'Unity/Assets/Scripts/TH1_Logic/Action/ActionLogic.cs' -or $_ -eq 'Unity/Assets/Scripts/TH1_Logic/Action/UnitActionLogic.cs' -or @@ -295,6 +300,19 @@ if ($touchedAttackGroundPeaceSemantics.Count -gt 0) { } } +if ($touchedSuwakoAttackGroundAgain.Count -gt 0) { + Write-Host "" + Write-Host "Suwako AttackGround again check:" + $suwakoAttackGroundAgainCheckPath = Join-Path $repoRoot "Tools/CheckSuwakoAttackGroundAgain.ps1" + try { + & $suwakoAttackGroundAgainCheckPath + } catch { + $hasBlockingIssue = $true + Write-Host " WARNING: Suwako AttackGround again guardrail failed:" + Write-Host " $($_.Exception.Message)" + } +} + if ($touchedPeaceWonderHostileActionSemantics.Count -gt 0) { Write-Host "" Write-Host "Peace wonder hostile-action semantics check:" @@ -415,6 +433,9 @@ if ($touchedSuikaFallingSplashAnimation.Count -gt 0) { if ($touchedAttackGroundPeaceSemantics.Count -gt 0) { Write-Host " Tools/CheckAttackGroundPeaceSemantics.ps1" } +if ($touchedSuwakoAttackGroundAgain.Count -gt 0) { + Write-Host " Tools/CheckSuwakoAttackGroundAgain.ps1" +} if ($touchedPeaceWonderHostileActionSemantics.Count -gt 0) { Write-Host " Tools/CheckPeaceWonderHostileActionSemantics.ps1" } diff --git a/Unity/Assets/Scripts/TH1_Logic/Action/ActionLogic.cs b/Unity/Assets/Scripts/TH1_Logic/Action/ActionLogic.cs index 6055069eb..69f3e7c76 100644 --- a/Unity/Assets/Scripts/TH1_Logic/Action/ActionLogic.cs +++ b/Unity/Assets/Scripts/TH1_Logic/Action/ActionLogic.cs @@ -3067,6 +3067,9 @@ namespace Logic.Action // TODO 这里的延迟产生单位形象,后续要加入presentationlist if (!actionParams.MapData.AddUnitData(targetGrid.Id, city1.Id, fullType, out suwakoUnit, 0.2f)) return false; + if (unit1.HasEffectiveSkill(SkillType.AttackGetAttackPoint, out var attackPointSkill) && + attackPointSkill is AttackGetAttackPointSkill attackGetAttackPointSkill) + attackGetAttackPointSkill.TryConsumeAndGrantAttackPoint(actionParams.MapData, unit1); } else if (!handledBySkillAttackGround) { diff --git a/Unity/Assets/Scripts/TH1_Logic/Skill/AllSkill/AttackGetAttackPointSkill.cs b/Unity/Assets/Scripts/TH1_Logic/Skill/AllSkill/AttackGetAttackPointSkill.cs index dce34db9f..ec111417f 100644 --- a/Unity/Assets/Scripts/TH1_Logic/Skill/AllSkill/AttackGetAttackPointSkill.cs +++ b/Unity/Assets/Scripts/TH1_Logic/Skill/AllSkill/AttackGetAttackPointSkill.cs @@ -1,12 +1,4 @@ -/* - * @Author: Claude - * @Description: 攻击获得攻击点 - 叠层永久技能,主动攻击后消耗1层获得1颗AttackActionPoint,0层自动消失(无回合时限) - * @Date: 2026年04月20日 - * @Modify: - */ - using RuntimeData; -using MemoryPack; namespace Logic.Skill { @@ -49,17 +41,22 @@ namespace Logic.Skill origin.HeroTask(map)?.OnAddSkillLevels(map, GetSkillType(), 1); } - public override void AfterActiveAttackOther(MapData mapData, AttackInfo attackInfo) + public bool TryConsumeAndGrantAttackPoint(MapData mapData, UnitData self) { if (_level > 1) _level = 1; - if (_level <= 0) return; + if (_level <= 0) return false; + if (self == null) return false; + + _level--; + self.AddActionPoint(ActionPointType.Attack); + return true; + } + + public override void AfterActiveAttackOther(MapData mapData, AttackInfo attackInfo) + { if (attackInfo?.DamageOrigin == null) return; - // 消耗1层 - _level--; - - // 获得1颗AttackActionPoint - attackInfo.DamageOrigin.AddActionPoint(ActionPointType.Attack); + TryConsumeAndGrantAttackPoint(mapData, attackInfo.DamageOrigin); } } }