railroader-setons-special-s.../dist/build-common.ps1
seton a4d3cd1621 feat(map): S3 v0.2.1 - in-game overlay, M/F10, popout restore
Replace the bare-bones stock map with a full Dear ImGui in-game overlay
(M key). The overlay shares the same toolbar and compass as the OS popout
window: Follow, Pop Out, Gear, rotation compass.

Pop Out button is now in the bottom toolbar where it is actually visible.
Pressing it (or F10) closes the overlay, waits 0.5 s for the camera to
release, then opens the OS popout window. Closing the popout restores the
overlay if it was running when the launch was triggered. Pressing M while
the popout is open closes the popout and reopens the overlay.

Harmony patches intercept MapWindow.Toggle and Show so base-game "Show on
map" links and the map hotkey both route through the S3 overlay. MapBypass
lets internal S3 calls through without triggering the patch recursively.

Camera ownership is enforced in LateUpdate so no base-game script can reset
targetTexture before the camera renders. Object.Destroy replaces Release()
on both RT teardown paths so the D3D address stays live until end-of-frame
and cannot be recycled into a new RT mid-frame.
2026-06-17 22:25:48 -04:00

88 lines
3.9 KiB
PowerShell

# Shared build helpers for S³ (dot-sourced by build-local.ps1 and build-release.ps1).
# Not run directly.
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
$script:RepoRoot = Split-Path $PSScriptRoot -Parent
$script:ModId = "S3"
function Get-ModVersion {
# Single source of truth: the Version field in Info.json.
$info = Get-Content (Join-Path $RepoRoot "Info.json") -Raw | ConvertFrom-Json
return $info.Version
}
function Invoke-ManagedBuild {
param([string]$Configuration = "Release", [string]$GameDir = "")
Write-Host "=== Building managed (S3.dll, $Configuration) ===" -ForegroundColor Cyan
$csproj = Join-Path $RepoRoot "src\S3.csproj"
$args = @($csproj, "-c", $Configuration, "--nologo", "-v", "minimal")
if ($GameDir) { $args += "/p:GameDir=$GameDir" }
dotnet build @args | Out-Host
if ($LASTEXITCODE -ne 0) { throw "Managed build failed." }
$dll = Join-Path $RepoRoot "src\bin\$Configuration\S3.dll"
if (-not (Test-Path $dll)) { throw "S3.dll not found at $dll" }
return $dll
}
function Invoke-NativeBuild {
param([string]$Configuration = "Release")
$cmakeLists = Join-Path $RepoRoot "native\CMakeLists.txt"
if (-not (Test-Path $cmakeLists)) {
Write-Host "=== No native/CMakeLists.txt — skipping native build ===" -ForegroundColor DarkYellow
return $null
}
Write-Host "=== Building native (S3Native.dll, $Configuration) ===" -ForegroundColor Cyan
$buildDir = Join-Path $RepoRoot "native\build"
if (-not (Test-Path $buildDir)) { cmake -B $buildDir -A x64 (Join-Path $RepoRoot "native") | Out-Host }
cmake --build $buildDir --config $Configuration | Out-Host
if ($LASTEXITCODE -ne 0) { throw "Native build failed." }
# MSVC multi-config generators place the DLL in a per-config subfolder.
$dll = Join-Path $buildDir "bin\$Configuration\S3Native.dll"
if (-not (Test-Path $dll)) { $dll = Join-Path $buildDir "bin\S3Native.dll" } # single-config fallback
if (-not (Test-Path $dll)) { throw "S3Native.dll not found under $buildDir\bin" }
return $dll
}
# Assembles the Mods\S3 layout into $DestModDir (the S3 folder itself).
#
# Overwrites in place rather than wiping the folder. A full wipe is dangerous: if
# the game is running, a loaded DLL is locked, so the wipe deletes Info.json and
# the managed DLL, then aborts on the locked native DLL — leaving the mod with no
# manifest, so it silently vanishes from the loader. Overwriting in place keeps
# the last-good install if a copy fails, and preserves the user's settings files.
function New-ModLayout {
param([Parameter(Mandatory)][string]$DestModDir,
[Parameter(Mandatory)][string]$ManagedDll,
[string]$NativeDll = $null)
New-Item -ItemType Directory -Force -Path $DestModDir | Out-Null
# Fail fast with a clear message if a DLL we're about to overwrite is locked
# (game still running) — before touching anything.
foreach ($name in @("S3.dll", "S3Native.dll")) {
$path = Join-Path $DestModDir $name
if (Test-Path $path) {
try { [System.IO.File]::Open($path, 'Open', 'ReadWrite', 'None').Close() }
catch { throw "$name is locked - close Railroader before installing." }
}
}
# Drop stale artifacts from older builds (the pre-rename native DLL, ngen
# caches) so they don't linger, but leave Info.json and settings intact.
$stale = Join-Path $DestModDir "RRPopout.dll"
if (Test-Path $stale) { Remove-Item $stale -Force }
Get-ChildItem $DestModDir -Filter "*.cache" -ErrorAction SilentlyContinue | Remove-Item -Force
Copy-Item (Join-Path $RepoRoot "Info.json") (Join-Path $DestModDir "Info.json") -Force
Copy-Item $ManagedDll (Join-Path $DestModDir "S3.dll") -Force
if ($NativeDll) {
Copy-Item $NativeDll (Join-Path $DestModDir "S3Native.dll") -Force
}
}