241 lines
7.0 KiB
PowerShell
241 lines
7.0 KiB
PowerShell
param(
|
|
[string]$AssetPath = "Unity/Assets/BundleResources/DataAssets/UnitTypeDataAssets.asset",
|
|
[string]$ExportPath = "Unity/Assets/BundleResources/Export/UnitTypeDataAssets.asset",
|
|
[switch]$CheckExport
|
|
)
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
$repoRoot = git rev-parse --show-toplevel 2>$null
|
|
if (-not $repoRoot) {
|
|
throw "Not inside a git repository."
|
|
}
|
|
$repoRoot = [System.IO.Path]::GetFullPath($repoRoot.Trim())
|
|
|
|
$prepareOfficerSkillHex = @(
|
|
"b6000000", # SkillType.OFFICER
|
|
"b3000000" # SkillType.JUNKEROFFICER
|
|
)
|
|
|
|
$cultureUpgradeChessTypes = @{
|
|
6 = "PawnWarrior"
|
|
7 = "PawnArcher"
|
|
8 = "PawnDefender"
|
|
9 = "PawnRider"
|
|
10 = "PawnKnight"
|
|
12 = "PawnCatapult"
|
|
13 = "PawnSword"
|
|
}
|
|
|
|
$explicitExemptions = @{
|
|
"20/0/0" = "KaguyaFrenchAnimalWarrior is an animal-resource conversion unit, not a normal Feudal Fief upgrade target."
|
|
}
|
|
|
|
function Resolve-RepoPath([string]$Path) {
|
|
if ([System.IO.Path]::IsPathRooted($Path)) {
|
|
return [System.IO.Path]::GetFullPath($Path)
|
|
}
|
|
return [System.IO.Path]::GetFullPath((Join-Path $repoRoot $Path))
|
|
}
|
|
|
|
function Get-UnitKey($Unit) {
|
|
return "$($Unit.UnitType)/$($Unit.GiantType)/$($Unit.UnitLevel)"
|
|
}
|
|
|
|
function Read-UnitTypeEntries([string]$Path) {
|
|
$fullPath = Resolve-RepoPath $Path
|
|
if (-not (Test-Path -LiteralPath $fullPath)) {
|
|
throw "UnitTypeDataAssets file not found: $fullPath"
|
|
}
|
|
|
|
$lines = Get-Content -LiteralPath $fullPath
|
|
$entries = @()
|
|
$current = $null
|
|
|
|
for ($i = 0; $i -lt $lines.Count; $i++) {
|
|
$line = $lines[$i]
|
|
if ($line -match '^ - UnitType: (\d+)') {
|
|
if ($current) {
|
|
$entries += [pscustomobject]$current
|
|
}
|
|
$current = [ordered]@{
|
|
SourcePath = $Path
|
|
Line = $i + 1
|
|
UnitType = [int]$Matches[1]
|
|
GiantType = $null
|
|
UnitLevel = $null
|
|
ChessType = $null
|
|
Civ = $null
|
|
Force = $null
|
|
Name = ""
|
|
LandType = $null
|
|
Cost = $null
|
|
Skills = ""
|
|
}
|
|
continue
|
|
}
|
|
|
|
if (-not $current) {
|
|
continue
|
|
}
|
|
|
|
if ($line -match '^ GiantType: (\d+)') {
|
|
$current.GiantType = [int]$Matches[1]
|
|
continue
|
|
}
|
|
if ($line -match '^ UnitLevel: (\d+)') {
|
|
$current.UnitLevel = [int]$Matches[1]
|
|
continue
|
|
}
|
|
if ($line -match '^ ChessType: (\d+)') {
|
|
$current.ChessType = [int]$Matches[1]
|
|
continue
|
|
}
|
|
if ($line -match '^ Civ: (\d+)') {
|
|
$current.Civ = [int]$Matches[1]
|
|
continue
|
|
}
|
|
if ($line -match '^ Force: (\d+)') {
|
|
$current.Force = [int]$Matches[1]
|
|
continue
|
|
}
|
|
if ($line -match '^ Name: (.*)$') {
|
|
$current.Name = $Matches[1]
|
|
continue
|
|
}
|
|
if ($line -match '^ LandType: (\d+)') {
|
|
$current.LandType = [int]$Matches[1]
|
|
continue
|
|
}
|
|
if ($line -match '^ Cost: ([\d\.]+)') {
|
|
$current.Cost = [double]$Matches[1]
|
|
continue
|
|
}
|
|
if ($line -match '^ Skills: ?(.*)$') {
|
|
$current.Skills = $Matches[1].ToLowerInvariant()
|
|
continue
|
|
}
|
|
}
|
|
|
|
if ($current) {
|
|
$entries += [pscustomobject]$current
|
|
}
|
|
|
|
return $entries
|
|
}
|
|
|
|
function Test-HasPrepareOfficerSkill($Unit) {
|
|
foreach ($skillHex in $prepareOfficerSkillHex) {
|
|
if ($Unit.Skills -match $skillHex) {
|
|
return $true
|
|
}
|
|
}
|
|
return $false
|
|
}
|
|
|
|
function Test-IsExpectedCultureUpgradeTarget($Unit) {
|
|
if ($null -eq $Unit.GiantType -or $Unit.GiantType -ne 0) {
|
|
return $false
|
|
}
|
|
if ($null -eq $Unit.UnitLevel -or $Unit.UnitLevel -ne 0) {
|
|
return $false
|
|
}
|
|
if ($null -eq $Unit.Cost -or $Unit.Cost -le 0) {
|
|
return $false
|
|
}
|
|
if ($null -eq $Unit.LandType -or $Unit.LandType -ne 1) {
|
|
return $false
|
|
}
|
|
if ($null -eq $Unit.ChessType -or -not $cultureUpgradeChessTypes.ContainsKey([int]$Unit.ChessType)) {
|
|
return $false
|
|
}
|
|
if ($explicitExemptions.ContainsKey((Get-UnitKey $Unit))) {
|
|
return $false
|
|
}
|
|
return $true
|
|
}
|
|
|
|
function Get-MissingPrepareOfficerUnits($Units) {
|
|
foreach ($unit in $Units) {
|
|
if (-not (Test-IsExpectedCultureUpgradeTarget $unit)) {
|
|
continue
|
|
}
|
|
if (Test-HasPrepareOfficerSkill $unit) {
|
|
continue
|
|
}
|
|
|
|
[pscustomobject]@{
|
|
Path = $unit.SourcePath
|
|
Line = $unit.Line
|
|
UnitKey = Get-UnitKey $unit
|
|
Name = $unit.Name
|
|
ChessType = $cultureUpgradeChessTypes[[int]$unit.ChessType]
|
|
Skills = $unit.Skills
|
|
}
|
|
}
|
|
}
|
|
|
|
function Assert-NoMissingPrepareOfficer([string]$Label, $Units) {
|
|
$expected = @($Units | Where-Object { Test-IsExpectedCultureUpgradeTarget $_ })
|
|
$missing = @(Get-MissingPrepareOfficerUnits $Units)
|
|
if ($missing.Count -gt 0) {
|
|
Write-Host "$Label culture upgrade config errors:"
|
|
$missing | Format-Table -AutoSize
|
|
throw "$Label has $($missing.Count) ordinary culture-upgrade unit(s) missing prepare-officer skill."
|
|
}
|
|
|
|
Write-Host "$Label culture upgrade config OK: checked $($expected.Count) ordinary culture-upgrade unit(s)."
|
|
}
|
|
|
|
$sourceUnits = Read-UnitTypeEntries $AssetPath
|
|
Assert-NoMissingPrepareOfficer "Source" $sourceUnits
|
|
|
|
if ($CheckExport) {
|
|
$exportUnits = Read-UnitTypeEntries $ExportPath
|
|
Assert-NoMissingPrepareOfficer "Export" $exportUnits
|
|
|
|
$exportByKey = @{}
|
|
foreach ($unit in $exportUnits) {
|
|
$exportByKey[(Get-UnitKey $unit)] = $unit
|
|
}
|
|
|
|
$staleExportUnits = @()
|
|
foreach ($sourceUnit in $sourceUnits) {
|
|
if (-not (Test-IsExpectedCultureUpgradeTarget $sourceUnit)) {
|
|
continue
|
|
}
|
|
if (-not (Test-HasPrepareOfficerSkill $sourceUnit)) {
|
|
continue
|
|
}
|
|
|
|
$key = Get-UnitKey $sourceUnit
|
|
if (-not $exportByKey.ContainsKey($key)) {
|
|
$staleExportUnits += [pscustomobject]@{
|
|
UnitKey = $key
|
|
SourceLine = $sourceUnit.Line
|
|
ExportLine = ""
|
|
Problem = "missing in export"
|
|
}
|
|
continue
|
|
}
|
|
|
|
$exportUnit = $exportByKey[$key]
|
|
if (-not (Test-HasPrepareOfficerSkill $exportUnit)) {
|
|
$staleExportUnits += [pscustomobject]@{
|
|
UnitKey = $key
|
|
SourceLine = $sourceUnit.Line
|
|
ExportLine = $exportUnit.Line
|
|
Problem = "export lacks prepare-officer skill"
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($staleExportUnits.Count -gt 0) {
|
|
Write-Host "Export culture upgrade sync errors:"
|
|
$staleExportUnits | Format-Table -AutoSize
|
|
throw "Export UnitTypeDataAssets is stale for $($staleExportUnits.Count) culture-upgrade unit(s). Refresh export through the normal Unity workflow."
|
|
}
|
|
|
|
Write-Host "Export culture upgrade config is in sync with source."
|
|
}
|