Workflow established for texturing and modeling.
This commit is contained in:
parent
fcd515095e
commit
5b116f357a
9 changed files with 199 additions and 34 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1,6 +1,9 @@
|
||||||
*.zip
|
*.zip
|
||||||
|
*.pyc
|
||||||
|
*.log
|
||||||
/plugin/Data/Scripts/
|
/plugin/Data/Scripts/
|
||||||
/plugin/Data/Meshes/
|
/plugin/Data/Meshes/
|
||||||
|
/plugin/Data/Textures/
|
||||||
/build/
|
/build/
|
||||||
node_modules/
|
node_modules/
|
||||||
*.blend[0-9]*
|
*.blend[0-9]*
|
15
.vscode/tasks.json
vendored
15
.vscode/tasks.json
vendored
|
@ -11,7 +11,20 @@
|
||||||
"kind": "build"
|
"kind": "build"
|
||||||
},
|
},
|
||||||
"command": "${workspaceFolder}/build.ps1",
|
"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": [
|
"problemMatcher": [
|
||||||
"$PapyrusCompiler"
|
"$PapyrusCompiler"
|
||||||
]
|
]
|
||||||
|
|
14
README.md
14
README.md
|
@ -1,3 +1,17 @@
|
||||||
# skyrim-item-roulette
|
# skyrim-item-roulette
|
||||||
|
|
||||||
Roulettes items
|
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.
|
Binary file not shown.
BIN
Source/Textures/_EQ_ItemRoulette/roulette_container.xcf
Normal file
BIN
Source/Textures/_EQ_ItemRoulette/roulette_container.xcf
Normal file
Binary file not shown.
82
build.ps1
82
build.ps1
|
@ -2,18 +2,57 @@
|
||||||
.SYNOPSIS
|
.SYNOPSIS
|
||||||
Builds the plugin and optionally reloads it in Vortex.
|
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
|
.PARAMETER Reload
|
||||||
Reloads Skyrim after building. Reloading assumes you have symlinked the mod
|
Reloads Skyrim after building. It completely kills and restarts the game
|
||||||
into Vortex's staging area using the method in setup-dev.ps1. It completely
|
as I had trouble getting hlp and reloadscript commands to work.
|
||||||
kills and restarts the game as I had trouble getting hlp and reloadscript
|
|
||||||
commands to work.
|
|
||||||
#>
|
#>
|
||||||
param (
|
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)]
|
[Parameter(Mandatory = $False)]
|
||||||
[Switch]
|
[Switch]
|
||||||
$Reload
|
$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
|
New-Item -ItemType Directory "$PSScriptRoot/build" -ErrorAction SilentlyContinue
|
||||||
|
|
||||||
Add-Type -Path "$PSScriptRoot/Gameloop.Vdf.dll" -ErrorAction SilentlyContinue
|
Add-Type -Path "$PSScriptRoot/Gameloop.Vdf.dll" -ErrorAction SilentlyContinue
|
||||||
|
@ -71,6 +110,7 @@ if(-not $SkyrimBase) {
|
||||||
)).FullName
|
)).FullName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if($Scripts) {
|
||||||
# Compile the scripts
|
# Compile the scripts
|
||||||
& "$SkyrimBase/Papyrus Compiler/PapyrusCompiler.exe" `
|
& "$SkyrimBase/Papyrus Compiler/PapyrusCompiler.exe" `
|
||||||
"$PsScriptRoot/Source/Scripts" `
|
"$PsScriptRoot/Source/Scripts" `
|
||||||
|
@ -82,25 +122,37 @@ if(-not $SkyrimBase) {
|
||||||
if($LastExitCode -ne 0) {
|
if($LastExitCode -ne 0) {
|
||||||
return $LastExitCode
|
return $LastExitCode
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# Build the models
|
if($Textures) {
|
||||||
blender.exe --background --python "$PSScriptRoot/export-blender-models.py"
|
Push-Location "$PSScriptRoot"
|
||||||
|
|
||||||
|
gimp-console -n -i --batch-interpreter python-fu-eval -b "import export_gimp_textures"
|
||||||
|
|
||||||
if($LastExitCode -ne 0) {
|
if($LastExitCode -ne 0) {
|
||||||
return $LastExitCode
|
return $LastExitCode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
# ZIP up the deployment package
|
||||||
$ZipPath = "$PSScriptRoot/build/Item Roulette for VRIK.zip"
|
$ZipPath = "$PSScriptRoot/build/Item Roulette for VRIK.zip"
|
||||||
|
|
||||||
Remove-Item $ZipPath -ErrorAction SilentlyContinue
|
Remove-Item $ZipPath -ErrorAction SilentlyContinue
|
||||||
Compress-Archive -Path $PSScriptRoot/plugin/* -DestinationPath $ZipPath
|
Compress-Archive -Path $PSScriptRoot/plugin/* -DestinationPath $ZipPath
|
||||||
|
|
||||||
if($Reload) {
|
|
||||||
if($Proc) {
|
|
||||||
Stop-Process $Proc
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if($KickVortex) {
|
||||||
# Restart Vortex and kick off deploy-mods event via Chrome Debug Protocol.
|
# Restart Vortex and kick off deploy-mods event via Chrome Debug Protocol.
|
||||||
Stop-Process -Name Vortex
|
Stop-Process -Name Vortex
|
||||||
$env:KICK_PORT=6969
|
$env:KICK_PORT=6969
|
||||||
|
@ -110,8 +162,14 @@ if($Reload) {
|
||||||
|
|
||||||
pnpm install -C "$PSScriptRoot"
|
pnpm install -C "$PSScriptRoot"
|
||||||
|
|
||||||
node.exe "$PSScriptRoot/kick-vortex.js"
|
node "$PSScriptRoot/kick-vortex.js"
|
||||||
Stop-Process -Name Vortex -ErrorAction SilentlyContinue
|
Stop-Process -Name Vortex -ErrorAction SilentlyContinue
|
||||||
|
}
|
||||||
|
|
||||||
|
if($Reload) {
|
||||||
|
if($Proc) {
|
||||||
|
Stop-Process $Proc
|
||||||
|
}
|
||||||
|
|
||||||
# Prefer SKSE loader if we have it installed
|
# Prefer SKSE loader if we have it installed
|
||||||
$SkyrimExe = Get-Item -Path @(
|
$SkyrimExe = Get-Item -Path @(
|
||||||
|
@ -135,3 +193,5 @@ if($Reload) {
|
||||||
"@
|
"@
|
||||||
} while ($wrFail)
|
} while ($wrFail)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0
|
|
@ -1,7 +1,7 @@
|
||||||
import bpy
|
import bpy
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
curdir = Path(__file__).parent
|
curdir = Path(__file__).parent
|
||||||
print("Current directory: " + str(curdir))
|
print("Current directory: " + str(curdir))
|
||||||
plugin_data_dir = curdir.joinpath("plugin/Data")
|
plugin_data_dir = curdir.joinpath("plugin/Data")
|
||||||
|
@ -16,9 +16,9 @@ for blend_path in blend_paths:
|
||||||
nif_parent = dest_blend_path.parent
|
nif_parent = dest_blend_path.parent
|
||||||
nif_path = nif_parent.joinpath(dest_blend_path.stem + '.nif')
|
nif_path = nif_parent.joinpath(dest_blend_path.stem + '.nif')
|
||||||
print(str(blend_path) + " -> " + str(nif_path))
|
print(str(blend_path) + " -> " + str(nif_path))
|
||||||
bpy.ops.wm.open_mainfile(filepath=str(blend_path))
|
|
||||||
try:
|
try:
|
||||||
nif_parent.mkdir(parents=True)
|
nif_parent.mkdir(parents=True)
|
||||||
except FileExistsError:
|
except FileExistsError:
|
||||||
pass
|
pass
|
||||||
|
bpy.ops.wm.open_mainfile(filepath=str(blend_path))
|
||||||
bpy.ops.export_scene.nif(filepath=str(nif_path))
|
bpy.ops.export_scene.nif(filepath=str(nif_path))
|
75
export_gimp_textures.py
Normal file
75
export_gimp_textures.py
Normal 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.
Loading…
Add table
Reference in a new issue