Workflow established for texturing and modeling.

This commit is contained in:
Empathic Qubit 2021-05-29 09:10:46 -04:00
parent fcd515095e
commit 5b116f357a
9 changed files with 199 additions and 34 deletions

3
.gitignore vendored
View file

@ -1,6 +1,9 @@
*.zip
*.pyc
*.log
/plugin/Data/Scripts/
/plugin/Data/Meshes/
/plugin/Data/Textures/
/build/
node_modules/
*.blend[0-9]*

15
.vscode/tasks.json vendored
View file

@ -11,7 +11,20 @@
"kind": "build"
},
"command": "${workspaceFolder}/build.ps1",
"args": ["-Reload"],
"args": ["-KickVortex"],
"problemMatcher": [
"$PapyrusCompiler"
]
},
{
"label": "Build and Reload",
"type": "shell",
"group": {
"isDefault": true,
"kind": "build"
},
"command": "${workspaceFolder}/build.ps1",
"args": ["-KickVortex", "-Reload"],
"problemMatcher": [
"$PapyrusCompiler"
]

View file

@ -1,3 +1,17 @@
# skyrim-item-roulette
Roulettes items
## Notes
* NIF export from Blender is perfectly fine if you're working from scratch.
Skyrim doesn't seem to care that the models are an old format.
* It should go without saying that if you change a model texture or any
resource other than the main plugin file, make sure you redeploy from Vortex
or you won't see the changes.
* Likewise, if you change the texture in GIMP, you must rebuild the textures
or you won't see them anywhere.
* If you include a texture it must be connected to the Color node of the Material
in the Shader node view, and the **node name** must be `Base`. The image path must
be the DDS in the /plugin folder. The NIF plugin is intelligent enough to relativize
the path when exporting.

104
build.ps1
View file

@ -2,18 +2,57 @@
.SYNOPSIS
Builds the plugin and optionally reloads it in Vortex.
.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. 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 staging area, preferably using setup-dev.ps1 script.
.PARAMETER Reload
Reloads Skyrim after building. Reloading assumes you have symlinked the mod
into Vortex's staging area using the method in setup-dev.ps1. It completely
kills and restarts the game as I had trouble getting hlp and reloadscript
commands to work.
Reloads Skyrim after building. It completely kills and restarts the game
as I had trouble getting hlp and reloadscript commands to work.
#>
param (
[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)]
[Switch]
$Reload
)
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
@ -71,36 +110,49 @@ if(-not $SkyrimBase) {
)).FullName
}
# Compile the scripts
& "$SkyrimBase/Papyrus Compiler/PapyrusCompiler.exe" `
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) {
if($LastExitCode -ne 0) {
return $LastExitCode
}
}
# Build the models
blender.exe --background --python "$PSScriptRoot/export-blender-models.py"
if($Textures) {
Push-Location "$PSScriptRoot"
if($LastExitCode -ne 0) {
gimp-console -n -i --batch-interpreter python-fu-eval -b "import export_gimp_textures"
if($LastExitCode -ne 0) {
return $LastExitCode
}
# 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($Reload) {
if($Proc) {
Stop-Process $Proc
}
Pop-Location
}
if($Models) {
blender --background --python "$PSScriptRoot/export_blender_models.py"
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.
Stop-Process -Name Vortex
$env:KICK_PORT=6969
@ -110,8 +162,14 @@ if($Reload) {
pnpm install -C "$PSScriptRoot"
node.exe "$PSScriptRoot/kick-vortex.js"
node "$PSScriptRoot/kick-vortex.js"
Stop-Process -Name Vortex -ErrorAction SilentlyContinue
}
if($Reload) {
if($Proc) {
Stop-Process $Proc
}
# Prefer SKSE loader if we have it installed
$SkyrimExe = Get-Item -Path @(
@ -135,3 +193,5 @@ if($Reload) {
"@
} while ($wrFail)
}
return 0

View file

@ -1,7 +1,7 @@
import bpy
import os
from pathlib import Path
curdir = Path(__file__).parent
print("Current directory: " + str(curdir))
plugin_data_dir = curdir.joinpath("plugin/Data")
@ -16,9 +16,9 @@ for blend_path in blend_paths:
nif_parent = dest_blend_path.parent
nif_path = nif_parent.joinpath(dest_blend_path.stem + '.nif')
print(str(blend_path) + " -> " + str(nif_path))
bpy.ops.wm.open_mainfile(filepath=str(blend_path))
try:
nif_parent.mkdir(parents=True)
except FileExistsError:
pass
bpy.ops.wm.open_mainfile(filepath=str(blend_path))
bpy.ops.export_scene.nif(filepath=str(nif_path))

75
export_gimp_textures.py Normal file
View file

@ -0,0 +1,75 @@
from gimpfu import pdb
import platform
import sys
pdb.gimp_message("Started exporting textures.")
pdb.gimp_message(platform.python_version())
try:
import glob
import os
import pydoc
curdir = os.path.dirname(os.path.abspath(__file__))
pdb.gimp_message("Current directory: " + curdir)
plugin_data_dir = os.path.join(curdir, "plugin/Data")
pdb.gimp_message("Plugin directory: " + plugin_data_dir)
texture_src_dir = os.path.join(curdir, "Source/Textures/_EQ_ItemRoulette")
pdb.gimp_message("Texture Source directory: " + texture_src_dir)
texture_dest_dir = os.path.join(plugin_data_dir, "Textures/_EQ_ItemRoulette")
pdb.gimp_message("Texture Dest directory: " + texture_dest_dir)
# FIXME This won't recurse
xcf_paths = glob.glob(texture_src_dir + "/*.xcf")
for xcf_path in xcf_paths:
dest_xcf_path = os.path.join(texture_dest_dir, os.path.relpath(path=xcf_path, start=texture_src_dir))
dds_parent = os.path.dirname(dest_xcf_path)
dds_path = os.path.join(os.path.splitext(dest_xcf_path)[0] + '.dds')
pdb.gimp_message(xcf_path + " -> " + dds_path)
try:
os.makedirs(dds_parent)
except:
pass
image = pdb.gimp_xcf_load(1, xcf_path, xcf_path)
#pdb.gimp_message(str(pdb.file_dds_save.params))
pdb.file_dds_save(
image,
# (13, 'image', 'Input image'),
image.flatten(),
# (16, 'drawable', 'Drawable to save'),
dds_path,
# (4, 'filename', 'The name of the file to save the image as'),
dds_path,
# (4, 'raw-filename', 'The name entered'),
0,
# (0, 'compression-format', 'Compression format # (0 = None, 1 = BC1/DXT1, 2 = BC2/DXT3, 3 = BC3/DXT5, 4 = BC3n/DXT5nm, 5 = BC4/ATI1N, 6 = BC5/ATI2N, 7 = RXGB # (DXT5), 8 = Alpha Exponent # (DXT5), 9 = YCoCg # (DXT5), 10 = YCoCg scaled # (DXT5))'),
1,
# (0, 'mipmaps', 'How to handle mipmaps # (0 = No mipmaps, 1 = Generate mipmaps, 2 = Use existing mipmaps # (layers)'),
0,
# (0, 'savetype', 'How to save the image # (0 = selected layer, 1 = cube map, 2 = volume map, 3 = texture array'),
0,
# (0, 'format', 'Custom pixel format # (0 = default, 1 = R5G6B5, 2 = RGBA4, 3 = RGB5A1, 4 = RGB10A2)'),
-1,
# (0, 'transparent-index', 'Index of transparent color or -1 to disable # (for indexed images only).'),
0,
# (0, 'mipmap-filter', 'Filtering to use when generating mipmaps # (0 = default, 1 = nearest, 2 = box, 3 = triangle, 4 = quadratic, 5 = bspline, 6 = mitchell, 7 = lanczos, 8 = kaiser)'),
0,
# (0, 'mipmap-wrap', 'Wrap mode to use when generating mipmaps # (0 = default, 1 = mirror, 2 = repeat, 3 = clamp)'),
0,
# (0, 'gamma-correct', 'Use gamma correct mipmap filtering'),
0,
# (0, 'srgb', 'Use sRGB colorspace for gamma correction'),
0,
# (3, 'gamma', 'Gamma value to use for gamma correction # (i.e. 2.2)'),
2.2,
# (0, 'perceptual-metric', 'Use a perceptual error metric during compression'),
0,
# (0, 'preserve-alpha-coverage', 'Preserve alpha test converage for alpha channel maps'),
0
# (3, 'alpha-test-threshold', 'Alpha test threshold value for which alpha test converage should be preserved')
)
pdb.gimp_image_delete(image)
except:
pdb.gimp_message("An unhandled error occurred: " + str(sys.exc_info()[0]) + ": " + str(sys.exc_info()[1]))
pdb.gimp_quit(0)

Binary file not shown.