skyrim-item-roulette/build.ps1

305 lines
No EOL
10 KiB
PowerShell

<#
.SYNOPSIS
Builds the plugin and optionally reloads it in Vortex.
.PARAMETER InstallDependencies
Installs script dependencies with Chocolatey, except Papyrus, and quit
.PARAMETER Scripts
Build Papyrus scripts
.PARAMETER Models
Build Blender models
.PARAMETER Textures
Build GIMP textures
.PARAMETER Zip
Build the ZIP AND NOTHING ELSE. You probably don't want this option.
.PARAMETER KickVortex
Syncs the plugin with Vortex. This option requires Node.js and pnpm to
communicate with Vortex. Keep in mind that this only half works if Vortex
wasn't already started, so if it fails just run the script again.
If there are file conflicts, take changes from the game directory! This will
have changes from the ESP that were made in Creation Kit! You need to
symlink the /plugin directory into the mod staging area, preferably using
setup-dev.ps1 script.
.PARAMETER KickPort
The port for Vortex to listen on.
.PARAMETER Reload
Kills Skyrim before and loads it after building. It completely kills the game
because I had trouble getting hlp and reloadscript commands to work.
#>
param (
[Parameter(Mandatory = $False)]
[Switch]
$InstallDependencies,
[Parameter(Mandatory = $False)]
[Switch]
$Scripts,
[Parameter(Mandatory = $False)]
[Switch]
$Models,
[Parameter(Mandatory = $False)]
[Switch]
$Textures,
[Parameter(Mandatory = $False)]
[Switch]
$Zip,
[Parameter(Mandatory = $False)]
[Switch]
$KickVortex,
[Parameter(Mandatory = $False)]
[int]
$KickPort = 6969,
[Parameter(Mandatory = $False)]
[Switch]
$Reload
)
if($InstallDependencies) {
# Chocolatey
Set-ExecutionPolicy Bypass -Scope Process -Force
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072
Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
choco install blender gimp 7zip autohotkey
}
if(-not $Scripts -and -not $Models -and -not $Textures -and -not $Zip) {
$Scripts = $true
$Textures = $true
$Models = $true
$Zip = $true
}
New-Item -ItemType Directory "$PSScriptRoot/build" -ErrorAction SilentlyContinue
Add-Type -Path "$PSScriptRoot/Gameloop.Vdf.dll" -ErrorAction SilentlyContinue
$Proc = Get-Process Skyrim*
# Use the running instance
if($Proc) {
$Wmi = Get-WmiObject -Class win32_process -filter "ProcessId=$($Proc.Id)"
$SkyrimBase = Split-Path $Wmi.ExecutablePath
}
# Check for Steam version
if(-not $SkyrimBase) {
if ($env:PROCESSOR_ARCHITECTURE -eq "AMD64") {
$steamInstallPath = "${env:ProgramFiles(x86)}/Steam"
}
else {
$steamInstallPath = "$env:ProgramFiles/Steam"
}
$libraryFolders = [Gameloop.Vdf.VdfConvert]::Deserialize((Get-Content "$steamInstallPath/steamapps/libraryfolders.vdf") -join "`n")
$steamLibraries = @()
$steamLibraries += @($steamInstallPath)
$steamLibraries += Get-Member -InputObject $libraryFolders.Value -MemberType Dynamic | where-object -Property Name -Match "[0-9]+" | ForEach-Object { $libraryFolders.Value[$_.Name].ToString() }
$manifestPath = $None
foreach($steamLibrary in $steamLibraries) {
$manifestPath = Get-Item -Path @(
"$steamLibrary/steamapps/appmanifest_611670.acf",
"$steamLibrary/steamapps/appmanifest_489930.acf",
"$steamLibrary/steamapps/appmanifest_72850.acf"
) -ErrorAction SilentlyContinue | Select-Object -First 1
if($manifestPath) {
Write-Host "Manifest found at $($manifestPath.FullName)"
break
}
}
if($manifestPath) {
$appManifest = [Gameloop.Vdf.VdfConvert]::Deserialize((Get-Content $manifestPath) -join "`n")
$installDir = $appManifest.Value["installdir"].ToString()
$SkyrimBase = "$(Split-Path $manifestPath)/common/$installDir"
}
}
# Default to non-Steam version
if(-not $SkyrimBase) {
$SkyrimBase = (Get-Item -Path @(
"$env:ProgramFiles/Bethesda*/*Skyrim*"
"${env:ProgramFiles(x86)}/Bethesda*/*Skyrim*"
)).FullName
}
if($Reload) {
if($Proc) {
Stop-Process $Proc
}
}
if($Scripts) {
# Compile the scripts
& "$SkyrimBase/Papyrus Compiler/PapyrusCompiler.exe" `
"$PsScriptRoot/Source/Scripts" `
"-f=$SkyrimBase/Data/Source/Scripts/TESV_Papyrus_Flags.flg" `
"-i=$SkyrimBase/Data/Source/Scripts;$PsScriptRoot/Source/Scripts" `
"-o=$PsScriptRoot/plugin/Data/Scripts" `
"-all"
if($LastExitCode -ne 0) {
return $LastExitCode
}
}
if($Textures) {
Push-Location "$PSScriptRoot"
$Gimp = (Get-Item -Path @("$Env:ProgramFiles/GIMP*/bin/gimp-console*.exe", "${env:ProgramFiles(x86)}/GIMP*/bin/gimp-console*.exe")).FullName
& $Gimp -n -i --batch-interpreter python-fu-eval -b "import export_gimp_textures"
if($LastExitCode -ne 0) {
return $LastExitCode
}
Pop-Location
}
if($Models) {
$Blender = (Get-Item -Path @("${env:ProgramFiles(x86)}/blender*/blender*/blender.exe", "$env:ProgramFiles/blender*/blender*/blender.exe")).FullName
& $Blender --background --python "$PSScriptRoot/export_blender_models.py"
if($LastExitCode -ne 0) {
return $LastExitCode
}
$ChunkmergeBase = "$PSScriptRoot/build/ChunkMerge"
$MeshSourceDir = "$PSScriptRoot/Source/Meshes/_EQ_ItemRoulette"
$MeshDestDir = "$PSScriptRoot/plugin/Data/Meshes/_EQ_ItemRoulette"
$ChunkMergeZip = "$PSScriptRoot/build/chunkmerge.7z"
if(-not (Test-Path $ChunkmergeBase)) {
Invoke-WebRequest -Uri "https://github.com/downloads/skyfox69/NifUtils/ChunkMerge0155.7z" -OutFile $ChunkMergeZip
7z x "-o$PSScriptRoot/build" $ChunkMergeZip
}
$ChunkMergeConfig = @"
<Config>
<PathSkyrim>$SkyrimBase</PathSkyrim>
<PathNifXML>$PSScriptRoot/nif.xml</PathNifXML>
<PathTemplate>$MeshSourceDir</PathTemplate>
<LastTexture></LastTexture>
<LastTemplate></LastTemplate>
<DirSource></DirSource>
<DirDestination></DirDestination>
<DirCollision></DirCollision>
<MatHandling>0</MatHandling>
<VertexColorHandling>0</VertexColorHandling>
<UpdateTangentSpace>1</UpdateTangentSpace>
<ReorderProperties>1</ReorderProperties>
<CollTypeHandling>1</CollTypeHandling>
<CollMaterial>-553455049</CollMaterial>
<MaterialScan>
<MatScanTag>SkyrimHavokMaterial</MatScanTag>
<MatScanName>SKY_HAV_</MatScanName>
<MatScanPrefixList>
<MatScanPrefix>Material</MatScanPrefix>
</MatScanPrefixList>
<MatScanIgnoreList>
<MatScanIgnore>Unknown</MatScanIgnore>
</MatScanIgnoreList>
</MaterialScan>
<DirectXView>
<ShowTexture>1</ShowTexture>
<ShowWireframe>0</ShowWireframe>
<ShowColorWire>0</ShowColorWire>
<ForceDDS>0</ForceDDS>
<ColorWireframe>ffffffff</ColorWireframe>
<ColorWireCollision>ffffff00</ColorWireCollision>
<ColorBackground>ff200020</ColorBackground>
<ColorSelected>ffff00ff</ColorSelected>
<TexturePathList>
</TexturePathList>
</DirectXView>
</Config>
"@
Out-File -Encoding ascii -FilePath "$ChunkmergeBase/ChunkMerge.xml" -InputObject $ChunkMergeConfig
$ChunkMerge = "$ChunkmergeBase/ChunkMerge.exe"
& $ChunkMerge
# FIXME This path is not recursive because ChunkMerge can't handle it
foreach($ChunkTemplate in (Get-Item "$MeshSourceDir/*_template.nif")) {
$env:ChunkMerge_NifFile = Join-Path $MeshDestDir ($ChunkTemplate.Name -replace "_template.", ".")
$env:ChunkMerge_CollisionFile = Join-Path $MeshDestDir ($ChunkTemplate.Name -replace "_template.", "_collision.")
$env:ChunkMerge_TemplateFile = $ChunkTemplate.Name
Start-Process -Wait -FilePath AutoHotkey -ArgumentList @("$PSScriptRoot/ChunkMerge.ahk")
if($LastExitCode -ne 0) {
return $LastExitCode
}
}
}
if($Zip) {
# ZIP up the deployment package
$ZipPath = "$PSScriptRoot/build/Item Roulette for VRIK.zip"
Remove-Item $ZipPath -ErrorAction SilentlyContinue
Compress-Archive -Path $PSScriptRoot/plugin/* -DestinationPath $ZipPath
}
if($KickVortex) {
# Restart Vortex and kick off deploy-mods event via Chrome Debug Protocol.
$VortexRunningWithDebuggingPortActive = `
(Get-NetTCPConnection -State Listen -LocalPort $KickPort -ErrorAction SilentlyContinue) `
| Where-Object {
$tcpConn = $_
Get-Process -Name Vortex | Where-Object { $tcpConn.OwningProcess -eq $_.Id }
}
$env:KICK_PORT=$KickPort
if (-not $VortexRunningWithDebuggingPortActive) {
Stop-Process -Name Vortex -ErrorAction SilentlyContinue
$VortexPath = (Get-ItemProperty HKLM:\SOFTWARE\57979c68-f490-55b8-8fed-8b017a5af2fe).InstallLocation
$GameId = (Get-Item "$env:APPDATA/Vortex/skyrim*").BaseName
& "$VortexPath/Vortex.exe" --remote-debugging-port=$KickPort --game=$GameId
}
pnpm install -C "$PSScriptRoot"
node "$PSScriptRoot/kick-vortex.js"
}
if($Reload) {
# Prefer SKSE loader if we have it installed
$SkyrimExe = Get-Item -Path @(
"$SkyrimBase/skse*_loader.exe",
"$SkyrimBase/Skyrim*.exe"
) | Select-Object -First 1
Start-Process -WorkingDirectory $SkyrimExe.DirectoryName -FilePath $SkyrimExe
# Send JSON command to load first autosave. Doesn't currently work.
do {
$wrFail = $None
Start-Sleep -Seconds 1
Invoke-WebRequest -Uri "http://localhost:8558/api/command" `
-Method Post `
-ErrorVariable $wrFail `
-ContentType 'application/json' `
-Headers @{ Accept = 'application/json' } `
-Body @"
{ "command": "load \"autosave1\" " }
"@
} while ($wrFail)
}
return 0