I wish my cat wouldn't lick so loudly

This commit is contained in:
Empathic Qubit 2021-05-28 16:30:20 -04:00
commit 0bb2a6be23
18 changed files with 510 additions and 0 deletions

6
.gitignore vendored Normal file
View file

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

14
.vscode/launch.json vendored Normal file
View file

@ -0,0 +1,14 @@
{
// Verwendet IntelliSense zum Ermitteln möglicher Attribute.
// Zeigen Sie auf vorhandene Attribute, um die zugehörigen Beschreibungen anzuzeigen.
// Weitere Informationen finden Sie unter https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "papyrus",
"name": "Skyrim",
"request": "attach",
"game": "skyrimSpecialEdition"
}
]
}

20
.vscode/tasks.json vendored Normal file
View file

@ -0,0 +1,20 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "Build",
"type": "shell",
"group": {
"isDefault": true,
"kind": "build"
},
"command": "${workspaceFolder}/build.ps1",
"args": ["-Reload"],
"problemMatcher": [
"$PapyrusCompiler"
]
}
]
}

BIN
Gameloop.Vdf.dll Normal file

Binary file not shown.

3
README.md Normal file
View file

@ -0,0 +1,3 @@
# skyrim-item-roulette
Roulettes items

View file

@ -0,0 +1,5 @@
Scriptname _EQ_ItemRoulette_Main extends ReferenceAlias
Event OnPlayerLoadGame()
(GetOwningQuest() as _EQ_ItemRoulette_Quest).Main()
EndEvent

View file

@ -0,0 +1,54 @@
Scriptname _EQ_ItemRoulette_Quest extends Quest
Actor Property PlayerRef Auto
Static Property _EQ_ItemRoulette_Roulette Auto
ObjectReference[] DisplayItems
Int MAX_ITEMS = 6
Int CIRCLE_RADIUS = 16
Event OnInit()
DisplayItems = New ObjectReference[127]
int index = 0
While index < MAX_ITEMS
DisplayItems[index] = None
index += 1
EndWhile
Main()
EndEvent
Function Main()
Debug.Trace("Item Roulette loaded")
RegisterForModEvent("_EQ_ItemRoulette_Activate", "OnMyAction")
VRIK.VrikAddGestureAction("_EQ_ItemRoulette_Activate", "Activate Item Roulette")
RegisterForSingleUpdate(0.01)
EndFunction
Event OnUpdate()
Int index = 0
While index < MAX_ITEMS && DisplayItems[index] != None
DisplayItems[index].SetPosition(VRIK.VrikGetHandX(true) + CIRCLE_RADIUS * Math.sin(60 * index), VRIK.VrikGetHandY(true), VRIK.VrikGetHandZ(true) + CIRCLE_RADIUS * Math.cos(60 * index))
index += 1
EndWhile
RegisterForSingleUpdate(0.01)
EndEvent
Event OnMyAction(string eventName, string strArg, float numArg, Form sender)
Debug.Trace("VRIK activated me!")
PlayerRef.PlaceAtMe(_EQ_ItemRoulette_Roulette)
Int numItems = PlayerRef.getNumItems()
Int formIndex = numItems
Int count = 0
While formIndex > 0 && formIndex > numItems - MAX_ITEMS
formIndex -= 1
count = numItems - formIndex
Form invItem = PlayerRef.GetNthForm(formIndex)
ObjectReference invItemInst = PlayerRef.DropObject(invItem)
invItemInst.SetScale(0.1)
invItemInst.SetMotionType(invItemInst.Motion_Keyframed)
DisplayItems[count - 1] = invItemInst
EndWhile
EndEvent

137
build.ps1 Normal file
View file

@ -0,0 +1,137 @@
<#
.SYNOPSIS
Builds the plugin and optionally reloads it in Vortex.
.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.
#>
param (
[Parameter(Mandatory = $False)]
[Switch]
$Reload
)
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 { $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
}
# 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
}
# Build the models
blender.exe --background --python "$PSScriptRoot/export-blender-models.py"
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
}
# Restart Vortex and kick off deploy-mods event via Chrome Debug Protocol.
Stop-Process -Name Vortex
$env:KICK_PORT=6969
$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=$env:KICK_PORT --game=$GameId
pnpm install -C "$PSScriptRoot"
node.exe "$PSScriptRoot/kick-vortex.js"
Stop-Process -Name Vortex -ErrorAction SilentlyContinue
# 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)
}

24
export-blender-models.py Normal file
View file

@ -0,0 +1,24 @@
import bpy
import os
from pathlib import Path
curdir = Path(__file__).parent
print("Current directory: " + str(curdir))
plugin_data_dir = curdir.joinpath("plugin/Data")
print("Plugin directory: " + str(plugin_data_dir))
mesh_src_dir = curdir.joinpath("Source/Meshes")
print("Mesh Source directory: " + str(mesh_src_dir))
mesh_dest_dir = plugin_data_dir.joinpath("Meshes")
print("Mesh Dest directory: " + str(mesh_dest_dir))
blend_paths = Path(mesh_src_dir).rglob("*.blend")
for blend_path in blend_paths:
dest_blend_path = mesh_dest_dir.joinpath(blend_path.relative_to(mesh_src_dir))
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.export_scene.nif(filepath=str(nif_path))

58
kick-vortex.js Normal file
View file

@ -0,0 +1,58 @@
const CDP = require('chrome-remote-interface');
const waitPort = require('wait-port')
const util = require('util')
const main = async() => {
const port = parseInt(process.env.KICK_PORT);
await waitPort({
host: '127.0.0.1',
port: port,
})
let client;
while(!client) {
try {
client = await CDP({
host: '127.0.0.1',
port: port,
});
}
catch(e) {
console.error(e);
}
}
console.log('Connected to CDP')
let target;
while(!target || splash) {
await new Promise(res => setTimeout(res, 100))
const targets = await client.Target.getTargets();
splash = targets.targetInfos.find(y => y.url.endsWith('splash.html'))
target = targets.targetInfos.find(y => y.url.endsWith('index.html'))
}
console.log('Found target!')
await new Promise(res => client.close(res));
client = await CDP({
host: '127.0.0.1',
port: port,
});
await client.Runtime.evaluate({
awaitPromise: true,
expression: '(' + (async function() {
await new Promise(function(res, rej) {
async function handler() {
if(_API && _API.events && _API.events.emit) {
await _API.awaitUI();
_API.events.emit("deploy-mods", res);
}
else {
setTimeout(handler, 100);
}
}
handler();
});
}).toString() + ')()'
})
client.close();
console.log('Finished everything!')
};
main().catch(console.error)

15
package.json Normal file
View file

@ -0,0 +1,15 @@
{
"name": "skyrim-item-roulette",
"version": "1.0.0",
"description": "Roulettes items",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "MIT",
"devDependencies": {
"chrome-remote-interface": "^0.30.0",
"wait-port": "^0.2.9"
}
}

Binary file not shown.

View file

@ -0,0 +1 @@
This is a placeholder file for development purposes.

View file

@ -0,0 +1,14 @@
<!-- FOMod Creation Tool [http://www.nexusmods.com/fallout4/mods/6821] -->
<!-- FOMod Quick Guide [https://media.readthedocs.org/pdf/fomod-docs/latest/fomod-docs.pdf] -->
<!-- FOMod Reference Manual [https://fomod-designer.readthedocs.io/en/stable/] -->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://qconsulting.ca/fo3/ModConfig5.0.xsd">
<moduleName>Item Roulette Selector for VRIK</moduleName>
<moduleDependencies operator="And">
<fileDependency file="vrik.esp" state="Active" />
</moduleDependencies>
<requiredInstallFiles>
<folder source="Data" priority="0"/>
</requiredInstallFiles>
</config>

6
plugin/fomod/info.xml Normal file
View file

@ -0,0 +1,6 @@
<!-- Created with FOMOD Creation Tool 1.7.0.37 [http://www.nexusmods.com/fallout4/mods/6821] -->
<!-- FOMod Document [https://media.readthedocs.org/pdf/fomod-docs/latest/fomod-docs.pdf] -->
<fomod>
<Name>Item Roulette Selector for VRIK</Name>
<Website>https://www.nexusmods.com/skyrimspecialedition/mods/FIXME</Website>
</fomod>

114
pnpm-lock.yaml generated Normal file
View file

@ -0,0 +1,114 @@
lockfileVersion: 5.3
specifiers:
chrome-remote-interface: ^0.30.0
wait-port: ^0.2.9
devDependencies:
chrome-remote-interface: 0.30.0
wait-port: 0.2.9
packages:
/ansi-styles/3.2.1:
resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==}
engines: {node: '>=4'}
dependencies:
color-convert: 1.9.3
dev: true
/chalk/2.4.2:
resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==}
engines: {node: '>=4'}
dependencies:
ansi-styles: 3.2.1
escape-string-regexp: 1.0.5
supports-color: 5.5.0
dev: true
/chrome-remote-interface/0.30.0:
resolution: {integrity: sha512-krIHiWQCRvlLhHmjWuGgHJfqhj2Jcj3mtVebq3c/Pwv4RF7P0A2eSy6YRqrBPwcziYJrtsPGR0rm7uCe4987rQ==}
hasBin: true
dependencies:
commander: 2.11.0
ws: 7.4.6
transitivePeerDependencies:
- bufferutil
- utf-8-validate
dev: true
/color-convert/1.9.3:
resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
dependencies:
color-name: 1.1.3
dev: true
/color-name/1.1.3:
resolution: {integrity: sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=}
dev: true
/commander/2.11.0:
resolution: {integrity: sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==}
dev: true
/commander/3.0.2:
resolution: {integrity: sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==}
dev: true
/debug/4.3.1:
resolution: {integrity: sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==}
engines: {node: '>=6.0'}
peerDependencies:
supports-color: '*'
peerDependenciesMeta:
supports-color:
optional: true
dependencies:
ms: 2.1.2
dev: true
/escape-string-regexp/1.0.5:
resolution: {integrity: sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=}
engines: {node: '>=0.8.0'}
dev: true
/has-flag/3.0.0:
resolution: {integrity: sha1-tdRU3CGZriJWmfNGfloH87lVuv0=}
engines: {node: '>=4'}
dev: true
/ms/2.1.2:
resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
dev: true
/supports-color/5.5.0:
resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==}
engines: {node: '>=4'}
dependencies:
has-flag: 3.0.0
dev: true
/wait-port/0.2.9:
resolution: {integrity: sha512-hQ/cVKsNqGZ/UbZB/oakOGFqic00YAMM5/PEj3Bt4vKarv2jWIWzDbqlwT94qMs/exAQAsvMOq99sZblV92zxQ==}
engines: {node: '>=8'}
hasBin: true
dependencies:
chalk: 2.4.2
commander: 3.0.2
debug: 4.3.1
transitivePeerDependencies:
- supports-color
dev: true
/ws/7.4.6:
resolution: {integrity: sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==}
engines: {node: '>=8.3.0'}
peerDependencies:
bufferutil: ^4.0.1
utf-8-validate: ^5.0.2
peerDependenciesMeta:
bufferutil:
optional: true
utf-8-validate:
optional: true
dev: true

39
setup-dev.ps1 Normal file
View file

@ -0,0 +1,39 @@
mkdir "$PSScriptRoot/build" -ErrorAction SilentlyContinue
pnpm install -C $PSScriptRoot
$ZipName = "EmpathicQubit-ItemRoulette-Dev.zip"
$ModPath = (Get-Item "$env:APPDATA/Vortex/skyrim*/mods").FullName+"/"+[IO.Path]::GetFileNameWithoutExtension($ZipName)
if((Get-Item $ModPath).Attributes.HasFlag([IO.FileAttributes]::ReparsePoint)) {
Write-Host "Already setup."
return
}
$ZipPath = "$PSScriptRoot/build/$ZipName"
Compress-Archive -Update -Path "$PSScriptRoot/plugin/Data/_EQ_ItemRoulette_Placeholder.md" -DestinationPath $ZipPath
$VortexPath = (Get-ItemProperty HKLM:\SOFTWARE\57979c68-f490-55b8-8fed-8b017a5af2fe).InstallLocation
Invoke-WebRequest -Uri http://nginx.org/download/nginx-1.21.0.zip -OutFile "$PSScriptRoot/build/nginx.zip"
Expand-Archive -Path "$PSScriptRoot/build/nginx.zip" -DestinationPath "$PSScriptRoot/build"
$NginxPath = "$PSScriptRoot/build/nginx-1.21.0"
Move-Item "$NginxPath/conf/nginx.conf" "$NginxPath/conf/nginx.conf.old"
(Get-Content "$NginxPath/conf/nginx.conf.old") `
-replace '^([^#]*root).*$', "`$1 $PSScriptRoot/build;" `
-replace '^([^#]*listen).*$', '$1 8998;' `
| Out-File -Encoding ascii "$NginxPath/conf/nginx.conf"
$job = Start-Job { & "$NginxPath/nginx.exe" -g 'daemon off;' }
Start-Sleep -Seconds 1
& "$VortexPath/Vortex.exe" -i "http://localhost:8998/$ZipName"
Start-Sleep -Seconds 10
Stop-Job $job
Remove-Item -Recurse $ModPath
New-Item -Path $ModPath -ItemType SymbolicLink -Value "$PSScriptRoot/plugin/Data"