Paradox.Modding.Stellaris.psm1
function ConvertTo-PdsBuilding { <# .SYNOPSIS Converts building configuration files into building mod files. .DESCRIPTION Converts building configuration files into building mod files. This command is used to read psd1-based configuration files for buildings and convert them into the format Stellaris expects. Generally, this command needs not be called directly and happens automatically during Build-PdxMod. For more details on how to define buildings via configuration file, see: https://github.com/FriedrichWeinmann/Paradox.Modding.Stellaris/blob/master/docs/content/buildings.md .PARAMETER Path Path to the file(s) to build. .PARAMETER ModRoot Root path of the mod you are building. Defaults to the parent folder of the parent folder of the first file specified in -Path. .EXAMPLE PS C:\> ConvertTo-PdsBuilding -Path "$PSScriptRoot\common\buildings\*.psd1" Builds all .psd1 files in the common\buildings subfolder under the path the current script is placed. .LINK https://github.com/FriedrichWeinmann/Paradox.Modding.Stellaris/blob/master/docs/content/buildings.md #> [CmdletBinding()] param ( [Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [Alias('FullName')] [PSFFile] $Path, [string] $ModRoot ) begin { $commonProps = [ordered]@{ Capital = 'capital' CanBuild = 'can_build' CanDemolish = 'can_demolish' CanRuin = 'can_be_ruined' CanDisable = 'can_be_disabled' Position = 'position_priority' BuildTime = 'base_buildtime' EmpireLimit = 'empire_limit' CanBeRuined = 'can_be_ruined' Category = 'category' BuildingSets = 'building_sets' Prerequisites = 'prerequisites' UpgradeTo = 'upgrades' Upgrades = 'upgrades' Potential = 'potential' Allow = 'allow' PlanetModifier = 'planet_modifier' CountryModifier = 'country_modifier' } $localeMap = @{ Name = '{0}' Description = '{0}_desc' } $typeMap = @{ upgrades = 'array' prerequisites = 'array' building_sets = 'array' } } process { foreach ($filePath in $Path) { if (-not $ModRoot) { $ModRoot = Split-Path -Path (Split-Path -Path (Split-Path -Path $filePath)) } $strings = New-PdxLocalizedString $data = Import-PSFPowerShellDataFile -LiteralPath $filePath -Psd1Mode Unsafe $allBuildings = [ordered]@{} #region Build Edict Data foreach ($buildingName in $data.Buildings.Keys) { $buildingData = $data.Buildings.$buildingName $newBuilding = [ordered]@{} #region Cost & Upkeep $currentCost = $data.Core.Cost if ($buildingData.Cost) { $currentCost = $buildingData.Cost } $currentUpkeep = $data.Core.Upkeep if ($buildingData.Upkeep) { $currentUpkeep = $buildingData.Upkeep } if ($currentCost -or $currentUpkeep) { $resourceData = [ordered]@{ category = 'planet_buildings' } if ($currentCost) { if ($currentCost -is [int]) { $resourceData['cost'] = @{ minerals = $currentCost } } else { $resourceData['cost'] = $currentCost } } if ($currentUpkeep) { if ($currentUpkeep -is [int]) { $resourceData['upkeep'] = @{ energy = $currentUpkeep } } else { $resourceData['upkeep'] = $currentUpkeep } } $newBuilding['resources'] = $resourceData } #endregion Cost & Upkeep $allBuildings[$buildingName] = New-PdxConfigEntry -Entry $buildingData -Name $buildingName -Defaults $data.Core -Common $commonProps -Output $newBuilding -Strings $strings -LocalizationProperties $localeMap -Ignore Cost, Upkeep -TypeMap $typeMap } #endregion Build Edict Data # Write File $sourceFile = Get-Item -LiteralPath $filePath $exportFile = Join-Path -Path $sourceFile.DirectoryName -ChildPath "$($sourceFile.BaseName).txt" $allBuildings | ConvertTo-PdxConfigFormat -TopLevel | Set-Content -Path $exportFile # Write Localization Export-PdxLocalizedString -Strings $strings -ModRoot $ModRoot -Name "buildings_$($sourceFile.BaseName)" } } } function ConvertTo-PdsDistrict { <# .SYNOPSIS Converts district configuration files into district mod files. .DESCRIPTION Converts district configuration files into district mod files. This command is used to read psd1-based configuration files for districts and convert them into the format Stellaris expects. Generally, this command needs not be called directly and happens automatically during Build-PdxMod. For more details on how to define districts via configuration file, see: https://github.com/FriedrichWeinmann/Paradox.Modding.Stellaris/blob/master/docs/content/districts.md .PARAMETER Path Path to the file(s) to build. .PARAMETER ModRoot Root path of the mod you are building. Defaults to the parent folder of the parent folder of the first file specified in -Path. .EXAMPLE PS C:\> ConvertTo-PdsDistrict -Path "$PSScriptRoot\common\districts\*.psd1" Builds all .psd1 files in the common\districts subfolder under the path the current script is placed. .LINK https://github.com/FriedrichWeinmann/Paradox.Modding.Stellaris/blob/master/docs/content/districts.md #> [CmdletBinding()] param ( [Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [Alias('FullName')] [PSFFile] $Path, [string] $ModRoot ) begin { $commonProps = [ordered]@{ BuildTime = 'base_buildtime' MinDeposits = 'min_for_deposits_on_planet' MaxDeposits = 'max_for_deposits_on_planet' Capped = 'is_capped_by_modifier' Exempt = 'exempt_from_ai_planet_specialization' Default = 'default_starting_district' Slots = 'zone_slots' ShowOnUncolonized = 'show_on_uncolonized' Potential = 'potential' Allow = 'allow' ConversionRatio = 'conversion_ratio' # integer ConvertTo = 'convert_to' # array Resources = 'resources' PlanetModifier = 'planet_modifier' } $localeMap = @{ Name = '{0}' Description = '{0}_desc' } $typeMap = @{ zone_slots = 'array' convert_to = 'array' } } process { foreach ($filePath in $Path) { if (-not $ModRoot) { $ModRoot = Split-Path -Path (Split-Path -Path (Split-Path -Path $filePath)) } $strings = New-PdxLocalizedString $data = Import-PSFPowerShellDataFile -LiteralPath $filePath -Psd1Mode Unsafe $alldistricts = [ordered]@{} #region Build Edict Data foreach ($districtName in $data.districts.Keys) { $districtData = $data.districts.$districtName $newdistrict = [ordered]@{} #region Cost & Upkeep $currentCost = $data.Core.Cost if ($districtData.Cost) { $currentCost = $districtData.Cost } $currentUpkeep = $data.Core.Upkeep if ($districtData.Upkeep) { $currentUpkeep = $districtData.Upkeep } if ($currentCost -or $currentUpkeep) { $resourceData = [ordered]@{ category = 'planet_districts_cities' } if ($currentCost) { if ($currentCost -is [int]) { $resourceData['cost'] = @{ minerals = $currentCost } } else { $resourceData['cost'] = $currentCost } } if ($currentUpkeep) { if ($currentUpkeep -is [int]) { $resourceData['upkeep'] = @{ energy = $currentUpkeep } } else { $resourceData['upkeep'] = $currentUpkeep } } $newdistrict['resources'] = $resourceData } #endregion Cost & Upkeep $alldistricts[$districtName] = New-PdxConfigEntry -Entry $districtData -Name $districtName -Defaults $data.Core -Common $commonProps -Output $newdistrict -Strings $strings -LocalizationProperties $localeMap -Ignore Cost, Upkeep -TypeMap $typeMap } #endregion Build Edict Data # Write File $sourceFile = Get-Item -LiteralPath $filePath $exportFile = Join-Path -Path $sourceFile.DirectoryName -ChildPath "$($sourceFile.BaseName).txt" $alldistricts | ConvertTo-PdxConfigFormat -TopLevel | Set-Content -Path $exportFile # Write Localization Export-PdxLocalizedString -Strings $strings -ModRoot $ModRoot -Name "districts_$($sourceFile.BaseName)" } } } function ConvertTo-PdsEdict { <# .SYNOPSIS Converts edict configuration files into edict mod files. .DESCRIPTION Converts edict configuration files into edict mod files. This command is used to read psd1-based configuration files for edicts and convert them into the format Stellaris expects. Generally, this command needs not be called directly and happens automatically during Build-PdxMod. For more details on how to define edicts via configuration file, see: https://github.com/FriedrichWeinmann/Paradox.Modding.Stellaris/tree/master/docs/content/edicts.md .PARAMETER Path Path to the file(s) to build. .PARAMETER ModRoot Root path of the mod you are building. Defaults to the parent folder of the parent folder of the first file specified in -Path. .EXAMPLE PS C:\> ConvertTo-PdsEdict -Path "$PSScriptRoot\common\edicts\*.psd1" Builds all .psd1 files in the common\edicts subfolder under the path the current script is placed. .LINK https://github.com/FriedrichWeinmann/Paradox.Modding.Stellaris/tree/master/docs/content/edicts.md #> [CmdletBinding()] param ( [Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [Alias('FullName')] [PSFFile] $Path, [string] $ModRoot ) begin { $commonProps = [ordered]@{ Length = 'length' EdictCapUsage = 'edict_cap_usage' Potential = 'potential' Allow = 'allow' AIWeight = 'ai_weight' Modifier = 'modifier' } } process { foreach ($filePath in $Path) { if (-not $ModRoot) { $ModRoot = Split-Path -Path (Split-Path -Path (Split-Path -Path $filePath)) } $strings = New-PdxLocalizedString $data = Import-PSFPowerShellDataFile -LiteralPath $filePath -Psd1Mode Unsafe $allEdicts = [ordered]@{} #region Build Edict Data foreach ($edictName in $data.Edicts.Keys) { $edictData = $data.Edicts.$edictName $newEdict = [ordered]@{} #region Cost $currentCost = $data.Core.Cost if ($edictData.Cost) { $currentCost = $edictData.Cost } if (-not $currentCost) { $currentCost = 0 } $costHash = @{ influence = $currentCost } if ($currentCost -isnot [int]) { $costhash = $currentCost } $newEdict['resources'] = [ordered]@{ category = 'edicts' cost = $costHash } #endregion Cost $allEdicts[$edictName] = New-PdxConfigEntry -Entry $edictData -Name $edictName -Defaults $data.Core -Common $commonProps -Output $newEdict -Strings $strings -LocalizationProperties @{ Name = 'edict_{0}' Description = 'edict_{0}_desc' } -Ignore Cost } #endregion Build Edict Data # Write File $sourceFile = Get-Item -LiteralPath $filePath $exportFile = Join-Path -Path $sourceFile.DirectoryName -ChildPath "$($sourceFile.BaseName).txt" $allEdicts | ConvertTo-PdxConfigFormat -TopLevel | Set-Content -Path $exportFile # Write Localization Export-PdxLocalizedString -Strings $strings -ModRoot $ModRoot -Name "edicts_$($sourceFile.BaseName)" } } } function ConvertTo-PdsZone { <# .SYNOPSIS Converts zone configuration files into zone mod files. .DESCRIPTION Converts zone configuration files into zone mod files. This command is used to read psd1-based configuration files for zones and convert them into the format Stellaris expects. Generally, this command needs not be called directly and happens automatically during Build-PdxMod. For more details on how to define zones via configuration file, see: https://github.com/FriedrichWeinmann/Paradox.Modding.Stellaris/blob/master/docs/content/zones.md .PARAMETER Path Path to the file(s) to build. .PARAMETER ModRoot Root path of the mod you are building. Defaults to the parent folder of the parent folder of the first file specified in -Path. .EXAMPLE PS C:\> ConvertTo-PdsZone -Path "$PSScriptRoot\common\zones\*.psd1" Builds all .psd1 files in the common\zones subfolder under the path the current script is placed. .LINK https://github.com/FriedrichWeinmann/Paradox.Modding.Stellaris/blob/master/docs/content/zones.md #> [CmdletBinding()] param ( [Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [Alias('FullName')] [PSFFile] $Path, [string] $ModRoot ) begin { $commonProps = [ordered]@{ Icon = 'icon' BuildTime = 'base_buildtime' Potential = 'potential' Unlock = 'unlock' Include = 'include' Resources = 'resources' MaxBuildings = 'max_buildings' PlanetModifier = 'planet_modifier' } $localeMap = @{ Name = '{0}' Description = '{0}_desc' } $typeMap = @{ include = 'array' exclude = 'array' included_building_sets = 'array' excluded_building_sets = 'array' } } process { foreach ($filePath in $Path) { if (-not $ModRoot) { $ModRoot = Split-Path -Path (Split-Path -Path (Split-Path -Path $filePath)) } $strings = New-PdxLocalizedString $data = Import-PSFPowerShellDataFile -LiteralPath $filePath -Psd1Mode Unsafe $allzones = [ordered]@{} #region Build Edict Data foreach ($zoneName in $data.zones.Keys) { $zoneData = $data.zones.$zoneName $newzone = [ordered]@{} #region Cost & Upkeep $currentCost = $data.Core.Cost if ($zoneData.Cost) { $currentCost = $zoneData.Cost } if ($currentCost) { $resourceData = [ordered]@{ category = 'planet_zones' } if ($currentCost) { if ($currentCost -is [int]) { $resourceData['cost'] = @{ minerals = $currentCost } } else { $resourceData['cost'] = $currentCost } } $newzone['resources'] = $resourceData } #endregion Cost & Upkeep $allzones[$zoneName] = New-PdxConfigEntry -Entry $zoneData -Name $zoneName -Defaults $data.Core -Common $commonProps -Output $newzone -Strings $strings -LocalizationProperties $localeMap -Ignore Cost -TypeMap $typeMap } #endregion Build Edict Data # Write File $sourceFile = Get-Item -LiteralPath $filePath $exportFile = Join-Path -Path $sourceFile.DirectoryName -ChildPath "$($sourceFile.BaseName).txt" $allzones | ConvertTo-PdxConfigFormat -TopLevel | Set-Content -Path $exportFile # Write Localization Export-PdxLocalizedString -Strings $strings -ModRoot $ModRoot -Name "zones_$($sourceFile.BaseName)" } } } function ConvertTo-PdsZoneSlot { <# .SYNOPSIS Converts zoneslot configuration files into zoneslot mod files. .DESCRIPTION Converts zoneslot configuration files into zoneslot mod files. This command is used to read psd1-based configuration files for zoneslots and convert them into the format Stellaris expects. Generally, this command needs not be called directly and happens automatically during Build-PdxMod. For more details on how to define zoneslots via configuration file, see: https://github.com/FriedrichWeinmann/Paradox.Modding.Stellaris/blob/master/docs/content/zone_slots.md .PARAMETER Path Path to the file(s) to build. .PARAMETER ModRoot Root path of the mod you are building. Defaults to the parent folder of the parent folder of the first file specified in -Path. .EXAMPLE PS C:\> ConvertTo-PdsZoneSlot -Path "$PSScriptRoot\common\zone_slots\*.psd1" Builds all .psd1 files in the common\zone_slots subfolder under the path the current script is placed. .LINK https://github.com/FriedrichWeinmann/Paradox.Modding.Stellaris/blob/master/docs/content/zone_slots.md #> [CmdletBinding()] param ( [Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [Alias('FullName')] [PSFFile] $Path, [string] $ModRoot ) begin { $commonProps = [ordered]@{ Start = 'start' # A zone of this type is immediately placed in a new district slot. Include = 'include' # A list of zone types that are available to be built in the slot. The key 'all' can be used to include all existing zone types. Exclude = 'exclude' # A list of zone types that aren't available to be built in the slot. Potential = 'potential' # Trigger that defines whether the slot is available on the planet at all. Scope = Planet. Unlock = 'unlock' # Trigger that defines whether the slot is unlocked on the planet. Scope = Planet. } $typeMap = @{ include = 'array' exclude = 'array' } } process { foreach ($filePath in $Path) { if (-not $ModRoot) { $ModRoot = Split-Path -Path (Split-Path -Path (Split-Path -Path $filePath)) } $data = Import-PSFPowerShellDataFile -LiteralPath $filePath -Psd1Mode Unsafe $allzoneslots = [ordered]@{} #region Build Edict Data foreach ($zoneslotName in $data.ZoneSlots.Keys) { $zoneslotData = $data.ZoneSlots.$zoneslotName $newzoneslot = [ordered]@{} $allzoneslots[$zoneslotName] = New-PdxConfigEntry -Entry $zoneslotData -Name $zoneslotName -Defaults $data.Core -Common $commonProps -Strings @{} -LocalizationProperties @{} -Output $newzoneslot -TypeMap $typeMap } #endregion Build Edict Data # Write File $sourceFile = Get-Item -LiteralPath $filePath $exportFile = Join-Path -Path $sourceFile.DirectoryName -ChildPath "$($sourceFile.BaseName).txt" $allzoneslots | ConvertTo-PdxConfigFormat -TopLevel | Set-Content -Path $exportFile } } } function Get-PdsGameDirectory { <# .SYNOPSIS Returns the root path to the Stellaris game installation. .DESCRIPTION Returns the root path to the Stellaris game installation. Uses steam to figure it out the path. Define the 'Paradox.Modding.Stellaris.Installpath' configuration setting (using Set-PSFConfig) to override (and disable) autodetection. .EXAMPLE PS C:\> Get-PdsGameDirectory returns the path to where the game is installed. #> [OutputType([string])] [CmdletBinding()] param () process { # Configuration beats it all if (Get-PSFConfigValue -Fullname 'Paradox.Modding.Stellaris.Installpath') { return Get-PSFConfigValue -Fullname 'Paradox.Modding.Stellaris.Installpath' } # Once cached, do not resolve again. if ($script:_stellarisGamePath) { return $script:_stellarisGamePath } # Resolve using Steam configuration path. $steamLibraryCfgFile = "${env:ProgramFiles(x86)}\Steam\config\libraryfolders.vdf" $steamLibraries = Get-Content -Path $steamLibraryCfgFile | Where-Object { $_ -match '"path"' } | ForEach-Object { $_ -replace '^.+"path".+?"' -replace '".{0,}' -replace '\\\\', '\' } foreach ($path in $steamLibraries) { if (Test-Path -Path "$path\steamapps\common\Stellaris\stellaris.exe") { $script:_stellarisGamePath = "$path\steamapps\common\Stellaris" return "$path\steamapps\common\Stellaris" } } Stop-PSFFunction -Message "Stellaris installation path not found! Autodiscovery failed to detect it, use the following line to tell the module where to find the game:`nSet-PSFConfig -FullName 'Paradox.Modding.Stellaris.Installpath' -Value '<InsertPathhere>' -PassThru | Register-PSFConfig" -EnableException $true -Cmdlet $PSCmdlet } } Register-PdxBuildExtension -Name 'Stellaris.Edicts' -Tags 'stellaris','edicts' -Description 'Builds all edicts in a Stellaris mod' -Code { param ($Data) if (Test-Path "$($Data.Root)\common\edicts\*.psd1") { ConvertTo-PdsEdict -Path "$($Data.Root)\common\edicts\*.psd1" } } Register-PdxBuildExtension -Name 'Stellaris.Buildings' -Tags 'stellaris','buildings' -Description 'Builds all buildings in a Stellaris mod' -Code { param ($Data) if (Test-Path "$($Data.Root)\common\buildings\*.psd1") { ConvertTo-PdsBuilding -Path "$($Data.Root)\common\buildings\*.psd1" } } Register-PdxBuildExtension -Name 'Stellaris.Zones' -Tags 'stellaris','zones' -Description 'Builds all zones in a Stellaris mod' -Code { param ($Data) if (Test-Path "$($Data.Root)\common\zones\*.psd1") { ConvertTo-PdsZone -Path "$($Data.Root)\common\zones\*.psd1" } } Register-PdxBuildExtension -Name 'Stellaris.ZoneSlotss' -Tags 'stellaris','zoneslots' -Description 'Builds all zone slots in a Stellaris mod' -Code { param ($Data) if (Test-Path "$($Data.Root)\common\zone_slots\*.psd1") { ConvertTo-PdsZoneSlot -Path "$($Data.Root)\common\zone_slots\*.psd1" } } Register-PdxBuildExtension -Name 'Stellaris.Districts' -Tags 'stellaris','districts' -Description 'Builds all districts in a Stellaris mod' -Code { param ($Data) if (Test-Path "$($Data.Root)\common\districts\*.psd1") { ConvertTo-PdsDistrict -Path "$($Data.Root)\common\districts\*.psd1" } } Set-PSFConfig -Fullname 'Paradox.Modding.Stellaris.Installpath' -Value '' -Validation string -Initialize -Description 'Path where the game was installed. Overrides auto-detection.' |