From 6c8c89ffce9efd71cbf6cf4e674b31ee0484e6db Mon Sep 17 00:00:00 2001 From: dafit Date: Tue, 25 Aug 2026 09:48:34 +0200 Subject: [PATCH] new service files - updates to ll-stack-architecture.md --- guides-stack/llama-alpha.service | 32 +++ guides-stack/llama-beta.service | 32 +++ guides-stack/llama-delta.service | 31 ++ guides-stack/llama-epsilon.service | 31 ++ guides-stack/llama-gamma.service | 31 ++ guides-stack/llama-zeta.service | 23 ++ guides-stack/llm-stack-architecture.md | 64 ++--- .../Edit Scripts/Export armor to CSV.pas | 270 ++++++++++++++++++ .../PS-Scripts/armor-by-keyword.ps1 | 6 + .../PS-Scripts/armor-by-slot.ps1 | 4 + .../PS-Scripts/armor-keywords-heavy.ps1 | 2 + .../PS-Scripts/armor-keywords-light.ps1 | 2 + .../PS-Scripts/armor-slot-count.ps1 | 3 + .../PS-Scripts/armoraddon-by-slot.ps1 | 3 + .../PS-Scripts/armoraddon-slot-count.ps1 | 3 + .../PS-Scripts/get-armor.ps1 | 51 ++++ .../PS-Scripts/get-armoraddon.ps1 | 88 ++++++ universal-translator/Nord.yaml | 2 +- 18 files changed, 644 insertions(+), 34 deletions(-) create mode 100644 guides-stack/llama-alpha.service create mode 100644 guides-stack/llama-beta.service create mode 100644 guides-stack/llama-delta.service create mode 100644 guides-stack/llama-epsilon.service create mode 100644 guides-stack/llama-gamma.service create mode 100644 guides-stack/llama-zeta.service create mode 100644 tools/SSedit/SSEEdit Export Armor Script-90522-1-0-1683004422/Edit Scripts/Export armor to CSV.pas create mode 100644 tools/SSedit/SSEEdit Export Armor Script-90522-1-0-1683004422/PS-Scripts/armor-by-keyword.ps1 create mode 100644 tools/SSedit/SSEEdit Export Armor Script-90522-1-0-1683004422/PS-Scripts/armor-by-slot.ps1 create mode 100644 tools/SSedit/SSEEdit Export Armor Script-90522-1-0-1683004422/PS-Scripts/armor-keywords-heavy.ps1 create mode 100644 tools/SSedit/SSEEdit Export Armor Script-90522-1-0-1683004422/PS-Scripts/armor-keywords-light.ps1 create mode 100644 tools/SSedit/SSEEdit Export Armor Script-90522-1-0-1683004422/PS-Scripts/armor-slot-count.ps1 create mode 100644 tools/SSedit/SSEEdit Export Armor Script-90522-1-0-1683004422/PS-Scripts/armoraddon-by-slot.ps1 create mode 100644 tools/SSedit/SSEEdit Export Armor Script-90522-1-0-1683004422/PS-Scripts/armoraddon-slot-count.ps1 create mode 100644 tools/SSedit/SSEEdit Export Armor Script-90522-1-0-1683004422/PS-Scripts/get-armor.ps1 create mode 100644 tools/SSedit/SSEEdit Export Armor Script-90522-1-0-1683004422/PS-Scripts/get-armoraddon.ps1 diff --git a/guides-stack/llama-alpha.service b/guides-stack/llama-alpha.service new file mode 100644 index 0000000..706af7d --- /dev/null +++ b/guides-stack/llama-alpha.service @@ -0,0 +1,32 @@ +[Unit] +Description=llama.cpp server - alpha (meta/combat/action_eval on Ada #1) +After=network-online.target + +[Service] +Type=simple +User=nyx-organs +Group=nimmerverse-agents +Environment="CUDA_VISIBLE_DEVICES=0" +Environment="PATH=/usr/local/cuda/bin:/data/venvs/llama/bin:/usr/local/bin:/usr/bin:/usr/sbin:/bin" +ExecStart=/data/llama.cpp/build/bin/llama-server \ + --model /data/models/prod/alpha/Gemma4-31B-QAT-Uncensored-HauhauCS-Balanced-Q4_K_M.gguf \ + --model-draft /data/models/prod/alpha/mtp-gemma-4-31B-it.gguf \ + --spec-type draft-mtp \ + -fa on \ + --alias alpha \ + --host 0.0.0.0 \ + --port 31001 \ + --n-gpu-layers 40 \ + --ctx-size 65536 \ + --cache-type-k q4_0 \ + --cache-type-v q4_0 \ + --batch-size 2048 \ + --ubatch-size 512 \ + --threads 8 \ + --cont-batching \ + --reasoning off +RestartSec=5 +WorkingDirectory=/data + +[Install] +WantedBy=multi-user.target diff --git a/guides-stack/llama-beta.service b/guides-stack/llama-beta.service new file mode 100644 index 0000000..df0b910 --- /dev/null +++ b/guides-stack/llama-beta.service @@ -0,0 +1,32 @@ +[Unit] +Description=llama.cpp server - beta (meta/combat/action_eval on Ada #1) +After=network-online.target + +[Service] +Type=simple +User=nyx-organs +Group=nimmerverse-agents +Environment="CUDA_VISIBLE_DEVICES=1" +Environment="PATH=/usr/local/cuda/bin:/data/venvs/llama/bin:/usr/local/bin:/usr/bin:/usr/sbin:/bin" +ExecStart=/data/llama.cpp/build/bin/llama-server \ + --model /data/models/prod/beta/Gemma4-31B-QAT-Uncensored-HauhauCS-Balanced-Q4_K_M.gguf \ + --model-draft /data/models/prod/beta/mtp-gemma-4-31B-it.gguf \ + --spec-type draft-mtp \ + -fa on \ + --alias beta \ + --host 0.0.0.0 \ + --port 31002 \ + --n-gpu-layers 40 \ + --ctx-size 65536 \ + --cache-type-k q4_0 \ + --cache-type-v q4_0 \ + --batch-size 2048 \ + --ubatch-size 512 \ + --threads 8 \ + --cont-batching \ + --reasoning off +RestartSec=5 +WorkingDirectory=/data + +[Install] +WantedBy=multi-user.target diff --git a/guides-stack/llama-delta.service b/guides-stack/llama-delta.service new file mode 100644 index 0000000..8318346 --- /dev/null +++ b/guides-stack/llama-delta.service @@ -0,0 +1,31 @@ +[Unit] +Description=llama.cpp server - delta +After=network-online.target + +[Service] +Type=simple +User=nyx-organs +Group=nimmerverse-agents +Environment="PATH=/usr/local/cuda/bin:/data/venvs/llama/bin:/usr/local/bin:/usr/bin:/usr/sbin:/bin" +ExecStart=/usr/local/bin/llama-server \ + --model /data/models/prod/delta/Gemma4-31B-QAT-Uncensored-HauhauCS-Balanced-Q4_K_M.gguf \ + --model-draft /data/models/prod/delta/mtp-gemma-4-31B-it.gguf \ + --spec-type draft-mtp \ + -fa on \ + --alias delta \ + --host 0.0.0.0 \ + --port 31001 \ + --n-gpu-layers 60 \ + --cache-type-k q4_0 \ + --cache-type-v q4_0 \ + --ctx-size 262144 \ + --batch-size 2048 \ + --ubatch-size 512 \ + --threads 8 \ + --cont-batching \ + --reasoning off +RestartSec=5 +WorkingDirectory=/data + +[Install] +WantedBy=multi-user.target diff --git a/guides-stack/llama-epsilon.service b/guides-stack/llama-epsilon.service new file mode 100644 index 0000000..0c20ec7 --- /dev/null +++ b/guides-stack/llama-epsilon.service @@ -0,0 +1,31 @@ +[Unit] +Description=llama.cpp server - epsilon +After=network-online.target + +[Service] +Type=simple +User=nyx-organs +Group=nimmerverse-agents +Environment="PATH=/usr/local/cuda/bin:/data/venvs/llama/bin:/usr/local/bin:/usr/bin:/usr/sbin:/bin" +ExecStart=/usr/local/bin/llama-server \ + --model /data/models/prod/epsilon/Gemma4-31B-QAT-Uncensored-HauhauCS-Balanced-Q4_K_M.gguf \ + --model-draft /data/models/prod/epsilon/mtp-gemma-4-31B-it.gguf \ + --spec-type draft-mtp \ + -fa on \ + --alias epsilon \ + --host 0.0.0.0 \ + --port 31002 \ + --n-gpu-layers 60 \ + --cache-type-k q4_0 \ + --cache-type-v q4_0 \ + --ctx-size 262144 \ + --batch-size 2048 \ + --ubatch-size 512 \ + --threads 8 \ + --cont-batching \ + --reasoning off +RestartSec=5 +WorkingDirectory=/data + +[Install] +WantedBy=multi-user.target diff --git a/guides-stack/llama-gamma.service b/guides-stack/llama-gamma.service new file mode 100644 index 0000000..3b3db06 --- /dev/null +++ b/guides-stack/llama-gamma.service @@ -0,0 +1,31 @@ +[Unit] +Description=llama.cpp server - gamma (memory/profile/vision/translator on RTX 3090) +After=network-online.target + +[Service] +Type=simple +User=nyx-organs +Group=nimmerverse-agents +Environment="PATH=/usr/local/cuda/bin:/data/venvs/llama/bin:/usr/local/bin:/usr/bin:/usr/sbin:/bin" +ExecStart=/data/llama.cpp/build/bin/llama-server \ + --model /data/models/prod/gamma/Gemma4-31B-QAT-Uncensored-HauhauCS-Balanced-Q4_K_M.gguf \ + --model-draft /data/models/prod/gamma/mtp-gemma-4-31B-it.gguf \ + --spec-type draft-mtp \ + -fa on \ + --alias gamma \ + --host 0.0.0.0 \ + --port 31003 \ + --n-gpu-layers 40 \ + --ctx-size 262144 \ + --cache-type-k q4_0 \ + --cache-type-v q4_0 \ + --batch-size 2048 \ + --ubatch-size 512 \ + --threads 8 \ + --cont-batching \ + --reasoning off +RestartSec=5 +WorkingDirectory=/data + +[Install] +WantedBy=multi-user.target diff --git a/guides-stack/llama-zeta.service b/guides-stack/llama-zeta.service new file mode 100644 index 0000000..0696d89 --- /dev/null +++ b/guides-stack/llama-zeta.service @@ -0,0 +1,23 @@ +[Unit] +Description=llama.cpp server - zeta +After=network-online.target + +[Service] +Type=simple +User=nyx-organs +Group=nimmerverse-agents +Environment="PATH=/usr/local/cuda/bin:/data/venvs/llama/bin:/usr/local/bin:/usr/bin:/usr/sbin:/bin" +ExecStart=llama-server \ + --model /data/models/prod/zeta/Huihui-Qwen3-VL-8B-Instruct-abliterated.Q8_0.gguf \ + --alias zeta \ + --mmproj /data/models/prod/zeta/zeta-mmproj-Q8_0.gguf \ + --host 0.0.0.0 \ + --port 31003 \ + --n-gpu-layers 9999 \ + --ctx-size 64000 \ + --chat-template-kwargs '{"enable_thinking": false}' +RestartSec=5 +WorkingDirectory=/data + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/guides-stack/llm-stack-architecture.md b/guides-stack/llm-stack-architecture.md index b993a74..590cabb 100644 --- a/guides-stack/llm-stack-architecture.md +++ b/guides-stack/llm-stack-architecture.md @@ -5,44 +5,42 @@ Chat endpoint: `/v1/chat/completions` with `{"chat_template_kwargs": {"enable_th ## Instances -| Instance | Node | GPU | Port | Model | Quant | VRAM | Vision | -|----------|------|-----|------|-------|-------|------|--------| -| **nyx** | theia | Blackwell 6000 | 31000 | self-trained ~41B | BF16 | ~84GB | ✅ | -| **alpha1** | dioscuri | Ada #1 | 31001 | Qwen3.6-27B-Fable-711 | IQ4_XS | 16.6GB | ❌ | -| **alpha2** | dioscuri | Ada #2 | 31002 | Qwen3.6-27B-Fable-711 | IQ4_XS | 16.6GB | ❌ | -| **gamma** | comfy-dev | RTX 3090 | 31003 | Qwen3.6-27B-Fable-711-MTP | Q4_K_S MTP | 19.9GB | ✅ | +| Instance | Node | GPU | Port | Model | Quant | Vision | +|----------|------|-----|------|-------|-------|------| +| **alpha** | dioscuri | Ada #1 | 31001 | Gemma4-31B-QAT-Uncensored-HauhauCS-Balanced-Q4_K_M.gguf-MTP | Q4_K_M MTP +| **beta** | dioscuri | Ada #2 | 31002 | Gemma4-31B-QAT-Uncensored-HauhauCS-Balanced-Q4_K_M.gguf-MTP | Q4_K_M MTP +| **gamma** | comfy-dev | RTX 3090 | 31003 | Gemma4-31B-QAT-Uncensored-HauhauCS-Balanced-Q4_K_M.gguf-MTP | Q4_K_M MTP +| **delta** | theia | Blackwell 6000 | 31001 | Gemma4-31B-QAT-Uncensored-HauhauCS-Balanced-Q4_K_M.gguf-MTP | Q4_K_M MTP +| **epsilon** | theia | Blackwell 6000 | 31002 | Gemma4-31B-QAT-Uncensored-HauhauCS-Balanced-Q4_K_M.gguf-MTP | Q4_K_M MTP +| **zeta** | theia | Blackwell 6000 | 31003 | Huihui-Qwen3-VL-8B-Instruct-abliterated.Q8_0.gguf | Q8_0 | mmproj-Q8_0.gguf -## Role Mapping +## Service Files under: +/nimmerverse/nimmersky/guides-stack/ -- **nyx (31000):** default dialogue, diary, agent_helper -- **alpha1 (31001):** meta, combat, action_evaluation -- **alpha2 (31002):** gamemaster, overflow -- **gamma (31003):** memory, character_profile, vision, universal_translator +llama-alpha.service +llama-beta.service +llama-delta.service +llama-epsilon.service +llama-gamma.service +llama-zeta.service +## +## Theia specific -## Endpoints for SkyrimNet + sudo nvidia-cuda-mps-control -d -```yaml -default: 10.0.40.21:31000/v1 -diary: 10.0.40.21:31000/v1 -agent_helper: 10.0.40.21:31000/v1 -meta: 10.0.40.22:31001/v1 -combat: 10.0.40.22:31001/v1 -action_evaluation: 10.0.40.22:31001/v1 -gamemaster: 10.0.40.22:31002/v1 -memory: 10.0.30.124:31003/v1 -character_profile: 10.0.30.124:31003/v1 -vision: 10.0.30.124:31003/v1 -universal_translator: 10.0.30.124:31003/v1 -``` +This command starts the CUDA Multi-Process Service (MPS) control daemon in the background. -## Notes +The control program used to manage the MPS server system.-d (Daemon mode): This flag launches the MPS control daemon in the background.What it does: Normally, if multiple Linux processes try to use the same GPU simultaneously, the GPU time-slices between them (hardware context switching), which adds overhead. MPS allows multiple different processes to share a single GPU context. This lets them execute kernels simultaneously on the same GPU, filling up underutilized GPU hardware and improving overall throughput. +## -- Throughput: gamma ~20 tok/s, alpha1 ~10 tok/s, alpha2 ~14 tok/s -- alpha1/alpha2 identical models (SHA256 confirmed) -- gamma has MTP quant; alpha1/alpha2 have non-MTP -- All llama.cpp services run as nyx-organs:nimmerverse-agents -- OStimNet: Fable-Fusion needs explicit x-rated vocabulary in system prompts + sudo nvidia-smi -i 0 -c EXCLUSIVE_PROCESS -## Service Files +This command changes the Compute Mode of a specific GPU so that only one process can attach to it at a time. -`~/tmp/skyrimnet-analysis/services/` — llama-gamma.service, llama-alpha1.service, llama-alpha2.service + nvidia-smi: The NVIDIA System Management Interface utility. + -i 0 (Index 0): Targets the specific GPU with an ID of 0. + -c EXCLUSIVE_PROCESS (Compute Mode): Sets the compute mode to "Exclusive Process" + +.What it does: It restricts the GPU so that only one single CUDA context (process) can access it at any given time. If a second process tries to use GPU 0 while the first is running, it will immediately throw an out-of-memory or initialization error. +## +💡 How They Work TogetherAt first glance, these two commands seem to contradict each other: one allows sharing (MPS), and the other forbids sharing (EXCLUSIVE_PROCESS).However, they are designed to be used together. When you set a GPU to EXCLUSIVE_PROCESS, the MPS server counts as that single allowed process.EXCLUSIVE_PROCESS blocks all regular user applications from touching GPU 0 directly.MPS daemon steps in as the sole owner of GPU 0.Your applications then talk to the MPS daemon, which safely multiplexes their workloads onto the GPU together.This specific combination is the recommended way to deploy MPS because it prevents rogue, non-MPS processes from accidentally hijacking the GPU and ruining performance. \ No newline at end of file diff --git a/tools/SSedit/SSEEdit Export Armor Script-90522-1-0-1683004422/Edit Scripts/Export armor to CSV.pas b/tools/SSedit/SSEEdit Export Armor Script-90522-1-0-1683004422/Edit Scripts/Export armor to CSV.pas new file mode 100644 index 0000000..7df326b --- /dev/null +++ b/tools/SSedit/SSEEdit Export Armor Script-90522-1-0-1683004422/Edit Scripts/Export armor to CSV.pas @@ -0,0 +1,270 @@ +unit ExportScripts; + +//version 1.0 + +// Global variables +var ArmoList : TStringList; +var ArmaList : TStringList; +var ArmoListSlot : TStringList; +var ArmaListSlot : TStringList; +var RetrieveAddRaces : Boolean; + +// Called when the script starts +function Initialize : integer; +var + csvHeaderArmo: string; + csvHeaderArma: string; +begin + csvHeaderArma := 'Plugin;RecordType;FormID;EditorID;Slot;Race;MaleModel;FemaleModel;MaleModel1stPerson;FemaleModel1stPerson;AdditionalRaces'; + csvHeaderArmo := 'Plugin;RecordType;FormID;EditorID;Slot;Race;Name;MaleModel;FemaleModel;Type;Enchantment;ArmorRating;Weight;Value;Keywords;ArmorAddon'; + + ArmoList := TStringList.Create; + ArmoList.Add(csvHeaderArmo); + + ArmaList := TStringList.Create; + ArmaList.Add(csvHeaderArma); + + ArmoListSlot := TStringList.Create; + ArmoListSlot.Add(csvHeaderArmo); + + ArmaListSlot := TStringList.Create; + ArmaListSlot.Add(csvHeaderArma); + + //don't retrieve 'Additional Races', takes too long + RetrieveAddRaces := False +end; + +// Called for each selected record in the TES5Edit tree +function Process(e: IInterface): integer; +var + i: integer; + slot: cardinal; + espName: string; + recordType: string; + itemName: string; + maleModel: string; + femaleModel: string; + armorType: string; + nArmorType: integer; + typesList: array[0..2] of string; + enchantment: string; + rating: float; + weight: float; + value: integer; + maleModel1st: string; + femaleModel1st: string; + keywords: string; + armature: string; + elKwda: IInterface; + elArma: IInterface; + elRaces: IInterface; + slotList: TStringList; + formId: string; + primaryRace: string; + additionalRaces: string; + +begin + if ((Signature(e) <> 'ARMO') and (Signature(e) <> 'ARMA')) then Exit; + + typesList[0] := 'Light'; + typesList[1] := 'Heavy'; + typesList[2] := 'None'; + + slotList := TStringList.Create; + itemName := ''; + armorType := ''; + maleModel := ''; + femaleModel := ''; + enchantment := ''; + maleModel1st := ''; + femaleModel1st := ''; + keywords := ''; + rating := 0.0; + weight := 0.0; + value := 0.0; + formId := IntToHex(GetLoadOrderFormID(e), 8); + slotList.Delimiter := ','; + primaryRace := ''; + + espName := '[' + IntToStr(GetLoadOrder(GetFile(e))) + '] ' + GetFileName(e); + if ElementExists(e,'FULL') then itemName := GetElementEditValues(e, 'FULL'); + if ElementExists(e,'EITM') then enchantment := GetElementEditValues(e, 'EITM'); + if ElementExists(e,'DNAM') then rating := GetElementNativeValues(e, 'DNAM'); + if ElementExists(e,'DATA\Value') then value := GetElementNativeValues(e, 'DATA\Value'); + if ElementExists(e,'DATA\Weight') then weight := GetElementNativeValues(e, 'DATA\Weight'); + if ElementExists(e,'RNAM') then primaryRace := GetElementEditValues(e, 'RNAM'); + + if ElementExists(e,'BODT\First Person Flags') then + begin + slot := GetElementNativeValues(e, 'BODT\First Person Flags'); + if ElementExists(e,'BODT\Armor Type') then + begin + nArmorType := GetElementNativeValues(e, 'BODT\Armor Type'); + armorType := typesList[nArmorType]; + end + end + else + begin + if ElementExists(e,'BOD2\First Person Flags') then + begin + slot := GetElementNativeValues(e, 'BOD2\First Person Flags'); + if ElementExists(e,'BOD2\Armor Type') then + begin + nArmorType := GetElementNativeValues(e, 'BOD2\Armor Type'); + armorType := typesList[nArmorType]; + end + end + else + begin + AddMessage('********* element doesnt have slot definition *********'); + Exit; + end + end; + + if Signature(e) = 'ARMA' then + begin + if ElementExists(e,'Male world model\MOD2') then maleModel := GetElementNativeValues(e, 'Male world model\MOD2'); + if ElementExists(e,'Female world model\MOD3') then femaleModel := GetElementNativeValues(e, 'Female world model\MOD3'); + if ElementExists(e,'Male 1st Person\MOD4') then maleModel1st := GetElementNativeValues(e, 'Male 1st Person\MOD4'); + if ElementExists(e,'Female 1st Person\MOD5') then femaleModel1st := GetElementNativeValues(e, 'Female 1st Person\MOD5'); + if RetrieveAddRaces and ElementExists(e,'Additional Races') then + begin + elRaces := ElementByName(e, 'Additional Races'); + for i := 0 to ElementCount(elRaces) - 1 do begin + additionalRaces := additionalRaces + GetElementEditValues(LinksTo(ElementByIndex(elRaces,i)), 'EDID'); + if(i < (ElementCount(elRaces) - 1)) then additionalRaces := additionalRaces + ','; + end; + end; + end + else + begin + if Signature(e) = 'ARMO' then + begin + if ElementExists(e,'Male world model\MOD2') then maleModel := GetElementNativeValues(e, 'Male world model\MOD2'); + if ElementExists(e,'Female world model\MOD4') then femaleModel := GetElementNativeValues(e, 'Female world model\MOD4'); + if ElementExists(e,'KWDA') then + begin + elKwda := ElementBySignature(e, 'KWDA'); + for i := 0 to ElementCount(elKwda) - 1 do begin + keywords := keywords + GetElementEditValues(LinksTo(ElementByIndex(elKwda,i)), 'EDID'); + if(i < (ElementCount(elKwda) - 1)) then keywords := keywords + ','; + end; + end; + if ElementExists(e,'Armature') then + begin + + elArma := ElementByName(e, 'Armature'); + for i := 0 to ElementCount(elArma) - 1 do begin + armature := armature + GetElementEditValues(LinksTo(ElementByIndex(elArma,i)), 'EDID'); + if(i < (ElementCount(elArma) - 1)) then armature := armature + ','; + end; + end; + end + end; + + //loop through the 32 slots + i := 1; + while(i <= 32) do + begin + i := i + 1; + //bitwise and + if ((slot and 1) = 1) then + begin + slotList.Add(IntToStr(i+28)); + AddMessage(espName + ';' + Signature(e) + ';' + formId +';'+ GetElementEditValues(e, 'EDID') + ';' + itemName + ';' + maleModel + ';' + femaleModel +';' + armorType +';' + enchantment + ';' + FloatToStr(rating/100) + ';' + FloatToStr(weight) + ';' + IntToStr(value) + ';' + IntToStr(i+28) + ';' + keywords); + if Signature(e) = 'ARMO' then + ArmoListSlot.Add(espName + ';' + + Signature(e) + ';' + + formId + ';' + + GetElementEditValues(e, 'EDID') + ';' + + IntToStr(i+28) + ';' + + primaryRace + ';' + + itemName + ';' + + maleModel + ';' + + femaleModel +';' + + armorType +';' + + enchantment + ';' + + FloatToStr(rating/100) + ';' + + FloatToStr(weight) + ';' + + IntToStr(value) + ';' + + keywords + ';' + + armature + ); + if Signature(e) = 'ARMA' then + ArmaListSlot.Add(espName + ';' + + Signature(e) + ';' + + formId + ';' + + GetElementEditValues(e, 'EDID') + ';' + + IntToStr(i+28) + ';' + + primaryRace + ';' + + maleModel + ';' + + femaleModel +';' + + maleModel1st + ';' + + femaleModel1st + ';' + + additionalRaces + ); + end + slot := slot shr 1; + end; + + if Signature(e) = 'ARMO' then + ArmoList.Add(espName + ';' + + Signature(e) + ';' + + formId + ';' + + GetElementEditValues(e, 'EDID') + ';' + + slotList.DelimitedText + ';' + + primaryRace + ';' + + itemName + ';' + + maleModel + ';' + + femaleModel +';' + + armorType +';' + + enchantment + ';' + + FloatToStr(rating/100) + ';' + + FloatToStr(weight) + ';' + + IntToStr(value) + ';' + + keywords + ';' + + armature + ); + if Signature(e) = 'ARMA' then + ArmaList.Add(espName + ';' + + Signature(e) + ';' + + formId + ';' + + GetElementEditValues(e, 'EDID') + ';' + + slotList.DelimitedText + ';' + + primaryRace + ';' + + maleModel + ';' + + femaleModel +';' + + maleModel1st + ';' + + femaleModel1st + ';' + + additionalRaces + ); + slotList.Free; +end; + +// Called after the script has finished processing every record +function Finalize : integer; +var filenameArmo : string; +var filenameArma : string; +var filenameArmoSlot : string; +var filenameArmaSlot : string; +begin + filenameArmo := ProgramPath + 'ArmorExport-Armor.csv'; + filenameArma := ProgramPath + 'ArmorExport-ArmorAddon.csv'; + filenameArmoSlot := ProgramPath + 'ArmorExport-Armor-Slot.csv'; + filenameArmaSlot := ProgramPath + 'ArmorExport-ArmorAddon-Slot.csv'; + + AddMessage('Saving Armor list to ' + filenameArmo); + AddMessage('Saving ArmorAddon list to ' + filenameArma); + AddMessage('Saving Armor-Slot list to ' + filenameArmoSlot); + AddMessage('Saving ArmorAddon-Slot list to ' + filenameArmaSlot); + ArmoList.SaveToFile(filenameArmo); + ArmoList.Free; + ArmaList.SaveToFile(filenameArma); + ArmaList.Free; + ArmoListSlot.SaveToFile(filenameArmoSlot); + ArmoListSlot.Free; + ArmaListSlot.SaveToFile(filenameArmaSlot); + ArmaListSlot.Free; +end; + +end. diff --git a/tools/SSedit/SSEEdit Export Armor Script-90522-1-0-1683004422/PS-Scripts/armor-by-keyword.ps1 b/tools/SSedit/SSEEdit Export Armor Script-90522-1-0-1683004422/PS-Scripts/armor-by-keyword.ps1 new file mode 100644 index 0000000..7b06571 --- /dev/null +++ b/tools/SSedit/SSEEdit Export Armor Script-90522-1-0-1683004422/PS-Scripts/armor-by-keyword.ps1 @@ -0,0 +1,6 @@ +param([Parameter(Mandatory=$true)][string[]]$keyword) +### keyword to filter +$csvDir=(Join-Path $PSScriptRoot ..) +Get-Content $csvDir\ArmorExport-Armor.csv|convertFrom-Csv -Delimiter ';' ` + |ForEach-Object { $_.Keywords = ($_.Keywords -split ','); $_ } ` + |where-object { $keyword -in $_.Keywords } \ No newline at end of file diff --git a/tools/SSedit/SSEEdit Export Armor Script-90522-1-0-1683004422/PS-Scripts/armor-by-slot.ps1 b/tools/SSedit/SSEEdit Export Armor Script-90522-1-0-1683004422/PS-Scripts/armor-by-slot.ps1 new file mode 100644 index 0000000..e7e54b3 --- /dev/null +++ b/tools/SSedit/SSEEdit Export Armor Script-90522-1-0-1683004422/PS-Scripts/armor-by-slot.ps1 @@ -0,0 +1,4 @@ +param([Parameter(Mandatory=$true)][int]$slot) +#slot to filter +$csvDir=(Join-Path $PSScriptRoot ..) +Get-Content $csvDir\ArmorExport-Armor-Slot.csv|ConvertFrom-Csv -Delimiter ';'|Sort-Object -Property FormID,Slot -Unique|Where-Object { $_.Slot -eq $slot } \ No newline at end of file diff --git a/tools/SSedit/SSEEdit Export Armor Script-90522-1-0-1683004422/PS-Scripts/armor-keywords-heavy.ps1 b/tools/SSedit/SSEEdit Export Armor Script-90522-1-0-1683004422/PS-Scripts/armor-keywords-heavy.ps1 new file mode 100644 index 0000000..7c2f6ca --- /dev/null +++ b/tools/SSedit/SSEEdit Export Armor Script-90522-1-0-1683004422/PS-Scripts/armor-keywords-heavy.ps1 @@ -0,0 +1,2 @@ +$csvDir=(Join-Path $PSScriptRoot ..) +Get-Content $csvDir\ArmorExport-Armor.csv|convertFrom-Csv -Delimiter ';'|ForEach-Object { $_.Keywords = ($_.Keywords -split ','); $_ }|where-object { $_.Keywords -contains 'ArmorHeavy' } \ No newline at end of file diff --git a/tools/SSedit/SSEEdit Export Armor Script-90522-1-0-1683004422/PS-Scripts/armor-keywords-light.ps1 b/tools/SSedit/SSEEdit Export Armor Script-90522-1-0-1683004422/PS-Scripts/armor-keywords-light.ps1 new file mode 100644 index 0000000..f3c1559 --- /dev/null +++ b/tools/SSedit/SSEEdit Export Armor Script-90522-1-0-1683004422/PS-Scripts/armor-keywords-light.ps1 @@ -0,0 +1,2 @@ +$csvDir=(Join-Path $PSScriptRoot ..) +Get-Content $csvDir\ArmorExport-Armor.csv|convertFrom-Csv -Delimiter ';'|ForEach-Object { $_.Keywords = ($_.Keywords -split ','); $_ }|where-object { $_.Keywords -contains 'ArmorLight' } \ No newline at end of file diff --git a/tools/SSedit/SSEEdit Export Armor Script-90522-1-0-1683004422/PS-Scripts/armor-slot-count.ps1 b/tools/SSedit/SSEEdit Export Armor Script-90522-1-0-1683004422/PS-Scripts/armor-slot-count.ps1 new file mode 100644 index 0000000..76d9153 --- /dev/null +++ b/tools/SSedit/SSEEdit Export Armor Script-90522-1-0-1683004422/PS-Scripts/armor-slot-count.ps1 @@ -0,0 +1,3 @@ +#show count of records by slot +$csvDir=(Join-Path $PSScriptRoot ..) +Get-Content $csvDir\ArmorExport-Armor-Slot.csv|ConvertFrom-Csv -Delimiter ';'|Sort-Object -Property FormID,Slot -Unique|Sort-Object Slot|Group-Object -NoElement -Property slot \ No newline at end of file diff --git a/tools/SSedit/SSEEdit Export Armor Script-90522-1-0-1683004422/PS-Scripts/armoraddon-by-slot.ps1 b/tools/SSedit/SSEEdit Export Armor Script-90522-1-0-1683004422/PS-Scripts/armoraddon-by-slot.ps1 new file mode 100644 index 0000000..31fb035 --- /dev/null +++ b/tools/SSedit/SSEEdit Export Armor Script-90522-1-0-1683004422/PS-Scripts/armoraddon-by-slot.ps1 @@ -0,0 +1,3 @@ +param([Parameter(Mandatory=$true)][int]$slot) +$csvDir=(Join-Path $PSScriptRoot ..) +Get-Content $csvDir\ArmorExport-ArmorAddon-Slot.csv|ConvertFrom-Csv -Delimiter ';'|Sort-Object -Property FormID,Slot -Unique|Where-Object { $_.Slot -eq $slot } \ No newline at end of file diff --git a/tools/SSedit/SSEEdit Export Armor Script-90522-1-0-1683004422/PS-Scripts/armoraddon-slot-count.ps1 b/tools/SSedit/SSEEdit Export Armor Script-90522-1-0-1683004422/PS-Scripts/armoraddon-slot-count.ps1 new file mode 100644 index 0000000..a327716 --- /dev/null +++ b/tools/SSedit/SSEEdit Export Armor Script-90522-1-0-1683004422/PS-Scripts/armoraddon-slot-count.ps1 @@ -0,0 +1,3 @@ +#show count of records by slot +$csvDir=(Join-Path $PSScriptRoot ..) +Get-Content $csvDir\ArmorExport-ArmorAddon-Slot.csv|ConvertFrom-Csv -Delimiter ';'|Sort-Object -Property FormID,Slot -Unique|Sort-Object Slot|Group-Object -NoElement -Property slot \ No newline at end of file diff --git a/tools/SSedit/SSEEdit Export Armor Script-90522-1-0-1683004422/PS-Scripts/get-armor.ps1 b/tools/SSedit/SSEEdit Export Armor Script-90522-1-0-1683004422/PS-Scripts/get-armor.ps1 new file mode 100644 index 0000000..8025438 --- /dev/null +++ b/tools/SSedit/SSEEdit Export Armor Script-90522-1-0-1683004422/PS-Scripts/get-armor.ps1 @@ -0,0 +1,51 @@ +<# + .PARAMETER editorId + to filter by editorId + + .PARAMETER formId + to filter by formId + + .PARAMETER all + to list all records + + .PARAMETER slotAsArray + convert slot field to array + + .PARAMETER splitBySlot + split records by slot + + .EXAMPLE + PS> .\get-armor.ps1 -editorId EnchArmorImperialLightGauntletsMarksman03 + + .EXAMPLE + PS> .\get-armor.ps1 -formId 000B9745 +#> +param([string]$editorId, [string]$formId, [switch]$slotAsArray, [switch]$splitBySlot) +#editorId or formId to filter + +#usage: +## .\get-armor.ps1 -editorId EnchArmorImperialLightGauntletsMarksman03 +## .\get-armor.ps1 -formId 000B9745 +$csvDir=(Join-Path $PSScriptRoot ..) +$csvFile="ArmorExport-Armor.csv" +if($splitBySlot) { + $csvFile="ArmorExport-Armor-Slot.csv" +} +if($editorId -or $formId) { + Get-Content (Join-Path $csvDir $csvFile)|ConvertFrom-Csv -Delimiter ';' ` + |where-object { ($editorId -and $_.EditorID -eq $editorId) -or ($formId -and $_.FormID -eq $formId)} ` + |foreach-object { + $_.Keywords = $_.Keywords -Split ','; + $_.ArmorAddon = $_.ArmorAddon -Split ','; + if($slotAsArray -and !$splitBySlot) { $_.Slot = ($_.Slot -Split ','); } + $_ + } +} else { + Get-Content (Join-Path $csvDir $csvFile)|ConvertFrom-Csv -Delimiter ';' ` + |foreach-object { + $_.Keywords = $_.Keywords -Split ','; + $_.ArmorAddon = $_.ArmorAddon -Split ','; + if($slotAsArray -and !$splitBySlot) { $_.Slot = ($_.Slot -Split ','); } + $_ + } +} diff --git a/tools/SSedit/SSEEdit Export Armor Script-90522-1-0-1683004422/PS-Scripts/get-armoraddon.ps1 b/tools/SSedit/SSEEdit Export Armor Script-90522-1-0-1683004422/PS-Scripts/get-armoraddon.ps1 new file mode 100644 index 0000000..445a38a --- /dev/null +++ b/tools/SSedit/SSEEdit Export Armor Script-90522-1-0-1683004422/PS-Scripts/get-armoraddon.ps1 @@ -0,0 +1,88 @@ +<# + .PARAMETER editorId + to filter by editorId + + .PARAMETER formId + to filter by formId + + .PARAMETER all + to list all records + + .PARAMETER slotAsArray + convert slot field to array + + .PARAMETER splitBySlot + split records by slot + + .EXAMPLE + PS> .\get-armor.ps1 | ?{ $_.FormID -in '00013939' } | .\get-armoraddon.ps1 + + .EXAMPLE + PS> .\get-armoraddon.ps1 -formId 0005DB82 + + .EXAMPLE + PS> .\get-armor.ps1 -editorId EnchArmorImperialLightGauntletsMarksman03|.\get-armoraddon.ps1 + + .EXAMPLE + PS> .\armor-by-keyword.ps1 ArmorHeavy|?{$_.Keywords -contains 'ArmorHelmet'}|.\get-armoraddon.ps1 +#> +param([string]$editorId, [string]$formId, [switch]$all, [switch]$slotAsArray, [switch]$splitBySlot) +# editorId or formId to filter +# -all to list all records + +#usage: +## .\get-armor.ps1 | ?{ $_.FormID -in '00013939' } | .\get-armoraddon.ps1 +## .\get-armoraddon.ps1 -formId 0005DB82 +## .\get-armor.ps1 -editorId EnchArmorImperialLightGauntletsMarksman03|.\get-armoraddon.ps1 +## .\armor-by-keyword.ps1 ArmorHeavy|?{$_.Keywords -contains 'ArmorHelmet'}|.\get-armoraddon.ps1 + +Set-StrictMode -Version 3.0 +$csvDir=(Join-Path $PSScriptRoot ..) + +$myInput = $input + +$ids=@() + +$inObjs=@{} +foreach($i in $myInput) { + foreach($a in $i.ArmorAddon) { + $ids+=$a; + if($inObjs.ContainsKey($a)) { + $inObjs[$a]=$i + } else { + $inObjs.Add($a, $i) + } + } +} + +$csvDir=(Join-Path $PSScriptRoot ..) +$csvFile="ArmorExport-ArmorAddon.csv" +if($splitBySlot) { + $csvFile="ArmorExport-ArmorAddon-Slot.csv" +} + +if($editorId -or $formId) { + Get-Content (Join-Path $csvDir $csvFile)|ConvertFrom-Csv -Delimiter ';' ` + |where-object { ($editorId -and $_.EditorID -eq $editorId) -or ($formId -and $_.FormID -eq $formId)} ` + |foreach-object { ` + if($slotAsArray -and !$splitBySlot) { $_.Slot = ($_.Slot -Split ','); } ` + $_.AdditionalRaces = ($_.AdditionalRaces -Split ','); ` + $_ ` + } +} elseif($ids.Length -gt 0) { + Get-Content (Join-Path $csvDir $csvFile)|ConvertFrom-Csv -Delimiter ';' ` + |where-object { $ids -contains $_.EditorID } ` + |foreach-object { ` + if($slotAsArray -and !$splitBySlot) { $_.Slot = ($_.Slot -Split ','); } ` + $_.AdditionalRaces = ($_.AdditionalRaces -Split ','); ` + $_ } ` + |foreach-object { Add-Member -InputObject $_ -MemberType NoteProperty -Name _ArmoRef ` + -Value "$($inObjs[$_.EditorID].EditorID) `"$($inObjs[$_.EditorID].Name)`" [$($inObjs[$_.EditorID].RecordType):$($inObjs[$_.EditorID].FormID)]"; ` + $_ } +} elseif($all) { + Get-Content (Join-Path $csvDir $csvFile)|ConvertFrom-Csv -Delimiter ';' ` + |foreach-object { ` + if($slotAsArray -and !$splitBySlot) { $_.Slot = ($_.Slot -Split ','); } ` + $_.AdditionalRaces = ($_.AdditionalRaces -Split ','); ` + $_ } +} diff --git a/universal-translator/Nord.yaml b/universal-translator/Nord.yaml index b58b294..964211b 100644 --- a/universal-translator/Nord.yaml +++ b/universal-translator/Nord.yaml @@ -1 +1 @@ -traits: direct - boisterous - patriarchal - revanchist - warm to kin, wary of outsiders +traits: direct - boisterous - patriarchal - revanchist - warm to kin, openly racist to outsiders