67 Commits

Author SHA1 Message Date
ZioPao
839ce002a3 More tests 2025-10-04 15:05:33 +02:00
ZioPao
49eee7ce84 fix: 42.12 new bodyloc 2025-10-04 04:23:12 +02:00
ZioPao
1c72647d40 fix: fix for cheat prevention with both hands feasibility to false 2025-10-04 04:22:26 +02:00
ZioPao
a9a7063287 fix: override for both hands interaction for b42 and cheat prevention 2025-10-04 04:22:04 +02:00
ZioPao
a511ac777a refactor: reorganized settings for cd 2025-07-14 02:46:43 +02:00
ZioPao
04c7172d82 refactor: removed old code 2025-07-14 01:15:39 +02:00
ZioPao
522c49b40c chore: cleaning and setting up stuff 2025-04-17 18:23:18 +02:00
ZioPao
8c8aa8351b mod version 2025-04-17 15:53:49 +02:00
ZioPao
3eeb9d1000 fix: hotfix to IgnoredActions 2025-04-17 15:46:22 +02:00
ZioPao
c60a2c56ec fix: fixed (once and for all, hopefully) hotbar handling 2025-04-17 12:54:50 +02:00
ZioPao
69025c8262 fix: disabled ISDetachItemHotbar override, broken and unneccesary 2025-04-17 12:52:23 +02:00
ZioPao
80e9391db5 fix: fixed ignored actions that should ignore toc calculations 2025-04-17 12:42:35 +02:00
ZioPao
d7bdee1d26 fix: broken skipTOC check for timed actions 2025-04-17 12:18:27 +02:00
ZioPao
8234abd5e2 refactor: changed check for version 2025-04-17 11:26:58 +02:00
ZioPao
9011579f08 chore: changes to structure 2025-04-17 11:01:03 +02:00
ZioPao
be6466976c add: added known incompatibilies to mod.info for B42 2025-04-17 11:00:46 +02:00
ZioPao
9ab584d977 chore: fix to some stupid config issues 2025-04-17 03:38:02 +02:00
ZioPao
b0d3520173 fix: #174 2025-04-15 03:07:20 +02:00
ZioPao
bbd36f7dc2 chore: changes to vscode config and updated gitignore for symink 2025-04-15 03:02:38 +02:00
ZioPao
3fc37f56d6 refactor: cleaning dev stuff 2025-04-13 03:21:34 +02:00
ZioPao
d5fd735de8 refactor: cleaning code 2025-04-13 03:21:06 +02:00
ZioPao
253c5717a9 refactor: removed unused code 2025-04-13 03:16:06 +02:00
ZioPao
d850691053 Chore: changes to vscode config 2025-04-13 03:08:49 +02:00
ZioPao
f728520f9e Chore: fixed config for umbrella 2025-04-12 15:16:02 +02:00
ZioPao
67f51ca845 Change: unified perks into one single parent, added translations for perk tooltips (b42) 2025-04-03 00:37:18 +02:00
ZioPao
e07af54d27 Fix: moved UI files for b42 to correct location 2025-04-03 00:16:21 +02:00
ZioPao
6e47f945c5 Add: #180 2025-04-03 00:00:53 +02:00
ZioPao
644376cea0 Fix: #186 2025-04-02 23:57:17 +02:00
ZioPao
6a3fa76e00 Fix: added more checks in DataController to prevent issues, thanks PhysiksTV 2025-04-02 18:12:45 +02:00
ZioPao
6e674959ab UI: Fixed color for Health panel female covers (b41 only) 2025-04-02 02:04:44 +02:00
ZioPao
d52f3f6bf2 UI: Moved specific b42 health panel files to 42 folder, restored old files for b41 2025-04-02 01:59:58 +02:00
ZioPao
5acab111f2 git: Modified gitignore 2025-04-02 01:57:35 +02:00
ZioPao
61f505fa8e Dev: modified tasks and settings (vscode) 2025-04-02 01:36:37 +02:00
ZioPao
6abd89cea7 UI: Fixed male Health Panel 2025-04-02 01:32:30 +02:00
ZioPao
768a0dbdab UI: Better test pattern for Health Panel debugging 2025-04-02 01:16:51 +02:00
ZioPao
d96c26d099 UI: fixed health panel for Female chars 2025-04-02 00:42:58 +02:00
ZioPao
f93c0503f8 Fix unequip prosthesis for b42 2025-03-31 22:46:12 +02:00
ZioPao
671bf133e3 Fixes for overriden methods, compat with b41 2025-03-31 22:22:17 +02:00
ZioPao
1e754895a0 Re-added lua timers 2025-03-31 20:56:23 +02:00
ZioPao
9a11047e3c Fix to Traits 2025-03-31 19:57:38 +02:00
ZioPao
db6f315f89 Readded translations, finalized folder struct 2025-03-31 19:57:27 +02:00
ZioPao
729e3b62e7 Reverted common for B41 2025-03-31 06:45:44 +02:00
ZioPao
7c8cfb0fcc Added mod.info for b41 2025-03-31 06:43:19 +02:00
ZioPao
bb19da2b4b Removed icon and poster from versioned folder, added dynamically 2025-03-31 02:47:26 +02:00
ZioPao
471608f9ba minVersion=42.6 2025-03-31 02:40:13 +02:00
ZioPao
71b854efe2 Moved everything to common. 2025-03-31 02:36:15 +02:00
ZioPao
e919c8c01b Bump to mod version and changed folder for specific game version 2025-03-31 02:17:40 +02:00
ZioPao
b6b61b872f Bump to mod version 2025-03-31 02:15:49 +02:00
ZioPao
58d5c8e13d Moved TR translation to correct folder 2025-03-31 02:00:19 +02:00
ZioPao
cc5e67aceb Moved Translations to common folder, merged pgmbru changes manually 2025-03-31 01:59:27 +02:00
ZioPao
f77a357dab Updated to current unstable version and fixed Healthpanel again 2025-03-31 01:46:49 +02:00
Pao
499db8cd78 Merge pull request #193 from ZioPao/dev-b42
Dev b42
2025-03-31 00:40:24 +02:00
Pao
ffce5fac2e Merge pull request #182 from VVentos0/main
Turkish Translation Added
2025-02-26 01:51:43 +01:00
VVentos0
81842f7020 Turkish Translate Added
I made Turkish Translate for your mod. This Translate only for B41 because the encode is ANSI (Windows-1254)

If you going to update your mod to B42 .txt files should be UTF-08 I'll post B42 files too. Please don't forget to add B42 Translation after B42 Update <3
2025-01-11 10:17:03 +03:00
ZioPao
d846b853ff Fix for ISHealthPanel 2025-01-04 21:21:05 +01:00
ZioPao
0f4117cd34 moved common files 2025-01-04 21:07:34 +01:00
ZioPao
736d527a13 Fix instanceItem, oops 2025-01-04 21:00:39 +01:00
ZioPao
1ded7f976c Replaced InventoryItemFactory with instanceItem 2025-01-04 20:46:11 +01:00
ZioPao
6635cc19b2 moved folders 2025-01-04 20:44:12 +01:00
ZioPao
5d8e60a2e4 Updated tasks for b42 dev 2025-01-04 20:25:22 +01:00
Pao
5515b6bd4f Merge pull request #157 from ZioPao/dev
v2.1.5
2024-10-22 01:12:27 +02:00
ZioPao
ba267cb900 I should stop trying to fix stuff while I'm falling asleep 2024-10-22 01:09:41 +02:00
Pao
90ca2edbce Merge pull request #155 from ZioPao/dev
v2.1.5
2024-10-22 00:11:35 +02:00
ZioPao
00d5d83ea2 Bump to mod version 2024-10-22 00:10:49 +02:00
ZioPao
849c17051a Fixed broken checks for admin menu 2024-10-22 00:10:40 +02:00
Pao
0071d2ac3f Merge pull request #148 from ZioPao/dev
v2.1.4
2024-10-19 18:42:08 +02:00
ZioPao
68605ddb35 Bump to mod version 2024-10-19 18:37:02 +02:00
322 changed files with 1223 additions and 2103 deletions

3
.gitignore vendored
View File

@@ -1 +1,2 @@
.vscode dev_stuff/gen_amp_textures/.venv
dev_stuff/gen_amp_textures/output

37
.vscode/settings.json vendored
View File

@@ -1,16 +1,27 @@
{ {
"todo-tree.tree.scanMode": "workspace", "Lua.workspace.library": [
"mod_id": "3236152598", "${addons}/umbrella-unstable/module/library"
"zomboid_user_folder": "C:/Users/picch/Zomboid",
"zomboid_folder": "E:\\Steam\\steamapps\\common\\ProjectZomboid",
"zomboid_server_folder": "E:\\Steam\\steamapps\\common\\Project Zomboid Dedicated Server",
"Lua.diagnostics.globals": [
"ModOptions",
"zombie",
"_"
], ],
"Lua.format.defaultConfig": { "Lua.runtime.version": "Lua 5.1",
"indent_style": "space", "Lua.runtime.path": [
"indent_size": "2" "?.lua",
} "?/init.lua",
"server/?.lua"
],
"Lua.completion.requireSeparator": "/",
"Lua.runtime.builtin": {
"debug": "disable",
"io": "disable",
"package": "disable"
},
"Lua.workspace.checkThirdParty": false,
"Lua.workspace.ignoreDir": [
".vscode",
"dev_stuff",
"workshop_files"
],
"Lua.diagnostics.globals": [
"FHSwapHandsAction",
"timer"
]
} }

128
.vscode/tasks.json vendored
View File

@@ -6,74 +6,110 @@
{ {
"label": "Create Workshop folder", "label": "Create Workshop folder",
"type": "shell", "type": "shell",
"options": {"statusbar": {"label": "$(combine) Assemble Mod"}}, "options": {"statusbar": {"label": "$(combine) Assemble Mod - B42"}},
"command": "python ${config:zomboid_user_folder}/PaosCrap/make_workshop_pack.py picch ${workspaceFolderBasename}", "command": "python ${config:zomboid_user_folder}/PaosCrap/make_workshop_pack.py \"42\" \"picch\" \"${workspaceFolderBasename}\" \"\"",
},
{
"label": "Create Workshop folder",
"type": "shell",
"options": {"statusbar": {"label": "$(combine) Assemble Mod - B41"}},
"command": "python ${config:zomboid_user_folder}/PaosCrap/make_workshop_pack.py \"41\" \"picch\" \"${workspaceFolderBasename}\" \"\"",
},
{
"label": "Create Workshop folder",
"type": "shell",
"options": {"statusbar": {"label": "$(combine) Assemble Mod (Test)"}},
"command": "python ${config:zomboid_user_folder}/PaosCrap/make_workshop_pack.py \"picch\" \"${workspaceFolderBasename}\" \"test\"",
}, },
{ {
"label": "Bump Mod Version", "label": "Bump Mod Version",
"type": "shell", "type": "shell",
"options": {"statusbar": {"label": "$(arrow-up) Bump Mod Version"}}, "options": {"statusbar": {"label": "$(arrow-up) Bump Mod Version"}},
"command": "python ${config:zomboid_user_folder}/PaosCrap/bump_version.py media/lua/client/TOC/Main.lua", "command": "python ${config:zomboid_user_folder}/PaosCrap/bump_version.py common/media/lua/client/TOC/Main.lua",
}, },
{ {
"label": "Run Zomboid Debug No Steam", "label": "Run Zomboid Debug No Steam (42)",
"type": "shell", "type": "shell",
"presentation": { "presentation": {
"group": "groupZomboid" "group": "groupZomboid"
}, },
"command": "\"${config:zomboid_folder}\\ProjectZomboid64 - nosteam-debug.bat\"", "command": "\"${config:zomboid_folder_b42}\\ProjectZomboid64 - nosteam-debug 42.bat\"",
"options": {"statusbar": {"label": "$(run) Zomboid client"}}, "options": {"statusbar": {"label": "$(run) Zomboid client (42)"}},
"problemMatcher": [ "problemMatcher": [
"$eslint-stylish" "$eslint-stylish"
] ]
}, },
{ {
"label": "Run Zomboid Debug No Steam 2", "label": "Run Zomboid Debug No Steam (41)",
"type": "shell", "type": "shell",
"command": "\"${config:zomboid_folder}\\ProjectZomboid64 - nosteam-debug.bat\"",
"options": {"statusbar": {"hide": true}},
"problemMatcher": [
"$eslint-stylish"
]
},
{
"label": "Run two instances of Zomboid Debug No Steam",
"options": {"statusbar": {"label": "$(run-all) Two Zomboid Clients"}},
"presentation": { "presentation": {
"reveal": "always", "group": "groupZomboid"
"panel": "new"
}, },
"dependsOn": [ "command": "\"${config:zomboid_folder_b41}\\ProjectZomboid64 - nosteam-debug.bat\"",
"Run Zomboid Debug No Steam", "Run Zomboid Debug No Steam 2"], "options": {"statusbar": {"label": "$(run) Zomboid client (41)"}},
"problemMatcher": []
},
{
"label": "Run Zomboid Test Server",
"options": {"statusbar": {"label": "$(run) Zomboid Server (TOC)"}},
"type": "shell",
"command":"\"${config:zomboid_server_folder}\\StartServer64_nosteam_custom.bat\" TOC",
"problemMatcher": [ "problemMatcher": [
"$eslint-stylish" "$eslint-stylish"
] ]
}, },
{ // {
"label": "Run Zomboid Test Server 2", // "label": "Run Zomboid Debug No Steam",
"options": {"statusbar": {"label": "$(run) Zomboid Server (TOC+FH+BH)"}}, // "type": "shell",
"type": "shell", // "presentation": {
"command":"\"${config:zomboid_server_folder}\\StartServer64_nosteam_custom.bat\" TOC_FH_BH", // "group": "groupZomboid"
"problemMatcher": [ // },
"$eslint-stylish" // "command": "\"${config:zomboid_folder}\\ProjectZomboid64 - nosteam-debug.bat\"",
] // "options": {"statusbar": {"label": "$(run) Zomboid client"}},
}, // "problemMatcher": [
{ // "$eslint-stylish"
"label": "Run Zomboid Test Server 3", // ]
"options": {"statusbar": {"label": "$(run) Zomboid Server (TOC+FH+BH+iMedsFixed)"}}, // },
"type": "shell", // {
"command":"\"${config:zomboid_server_folder}\\StartServer64_nosteam_custom.bat\" TOC_FH_BH_imeds", // "label": "Run Zomboid Debug No Steam 2",
"problemMatcher": [ // "type": "shell",
"$eslint-stylish" // "command": "\"${config:zomboid_folder}\\ProjectZomboid64 - nosteam-debug.bat\"",
] // "options": {"statusbar": {"hide": true}},
}
// "problemMatcher": [
// "$eslint-stylish"
// ]
// },
// {
// "label": "Run two instances of Zomboid Debug No Steam",
// "options": {"statusbar": {"label": "$(run-all) Two Zomboid Clients"}},
// "presentation": {
// "reveal": "always",
// "panel": "new"
// },
// "dependsOn": [
// "Run Zomboid Debug No Steam", "Run Zomboid Debug No Steam 2"],
// "problemMatcher": []
// },
// {
// "label": "Run Zomboid Test Server",
// "options": {"statusbar": {"label": "$(run) Zomboid Server (TOC)"}},
// "type": "shell",
// "command":"\"${config:zomboid_server_folder}\\StartServer64_nosteam_custom.bat\" TOC",
// "problemMatcher": [
// "$eslint-stylish"
// ]
// },
// {
// "label": "Run Zomboid Test Server 2",
// "options": {"statusbar": {"label": "$(run) Zomboid Server (TOC+FH+BH)"}},
// "type": "shell",
// "command":"\"${config:zomboid_server_folder}\\StartServer64_nosteam_custom.bat\" TOC_FH_BH",
// "problemMatcher": [
// "$eslint-stylish"
// ]
// },
// {
// "label": "Run Zomboid Test Server 3",
// "options": {"statusbar": {"label": "$(run) Zomboid Server (TOC+FH+BH+iMedsFixed)"}},
// "type": "shell",
// "command":"\"${config:zomboid_server_folder}\\StartServer64_nosteam_custom.bat\" TOC_FH_BH_imeds",
// "problemMatcher": [
// "$eslint-stylish"
// ]
// }
] ]
} }

View File

@@ -0,0 +1,10 @@
local LimitActionsController = require("TOC/Controllers/LimitActionsController") -- declared in common
local OverridenMethodsArchive = require("TOC/OverridenMethodsArchive")
local og_ISClothingExtraAction_isValid = OverridenMethodsArchive.Get("ISClothingExtraAction_isValid")
---@diagnostic disable-next-line: duplicate-set-field
function ISClothingExtraAction:isValid()
-- TOC_DEBUG.print("Inside ISClothingExtraAction:isValid 42")
-- TOC_DEBUG.print(OverridenMethodsArchive.Get("ISClothingExtraAction_isValid"))
return LimitActionsController.WrapClothingAction(self, og_ISClothingExtraAction_isValid, instanceItem(self.extra))
end

View File

@@ -0,0 +1,40 @@
local ProsthesisHandler = require("TOC/Handlers/ProsthesisHandler") -- declared in common
local OverridenMethodsArchive = require("TOC/OverridenMethodsArchive")
local og_ISClothingExtraAction_isValid = OverridenMethodsArchive.Get("ISClothingExtraAction_isValid")
---@diagnostic disable-next-line: duplicate-set-field
function ISClothingExtraAction:isValid()
local isEquippable = og_ISClothingExtraAction_isValid(self)
-- self.extra is a string, not the item
local testItem = instanceItem(self.extra)
return ProsthesisHandler.Validate(testItem, isEquippable)
end
local og_ISClothingExtraAction_perform = OverridenMethodsArchive.Get("ISClothingExtraAction_perform")
function ISClothingExtraAction:perform()
local extraItem = instanceItem(self.extra)
ProsthesisHandler.SearchAndSetupProsthesis(extraItem, true)
og_ISClothingExtraAction_perform(self)
end
local og_ISUnequipAction_complete = ISUnequipAction.complete
function ISUnequipAction:complete()
-- Horrendous workaround. For B42, as of now, it will basically happen two times, once with :perform and once with :complete. Shouldn't
-- matter for performance but it's really ugly.
local isProst = ProsthesisHandler.SearchAndSetupProsthesis(self.item, false)
local group
if isProst then
group = BodyLocations.getGroup("Human")
group:setMultiItem("TOC_ArmProst", false)
end
og_ISUnequipAction_complete(self)
if isProst then
group:setMultiItem("TOC_ArmProst", true)
end
end

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
42/media/ui/Male/Hand_L.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

BIN
42/media/ui/Male/Hand_R.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

11
42/mod.info Normal file
View File

@@ -0,0 +1,11 @@
name=The Only Cure
poster=poster.png
description=You've been bitten. You have only two choices.
id=TheOnlyCure
icon=icon.png
url=https://github.com/ZioPao/The-Only-Cure
modversion=2.2
versionMin=42.6
loadModAfter=\FancyHandwork,\BrutalHandwork,\TwoWeaponsOnBackRework
incompatible=\BB_FirstAidOverhaul

View File

@@ -1,8 +0,0 @@
{
"folders": [
{
"path": "."
}
],
"settings": {}
}

View File

@@ -1,14 +1,16 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<clothingItem> <clothingItem>
<m_MaleModel>Amputation\Amputation_Left_LowerArm_Male</m_MaleModel> <m_MaleModel>Amputation\Amputation_FA_LR</m_MaleModel>
<m_FemaleModel>Amputation\Amputation_Left_LowerArm_Female</m_FemaleModel> <m_FemaleModel>Amputation\Amputation_Left_LowerArm_Female</m_FemaleModel>
<m_GUID>d3816fe0-48e1-4cf5-a8e4-48c72595edb4</m_GUID> <m_GUID>d3816fe0-48e1-4cf5-a8e4-48c72595edb4</m_GUID>
<m_Static>false</m_Static> <m_Static>false</m_Static>
<m_AllowRandomHue>false</m_AllowRandomHue> <m_AllowRandomHue>false</m_AllowRandomHue>
<m_AllowRandomTint>false</m_AllowRandomTint> <m_AllowRandomTint>false</m_AllowRandomTint>
<m_Masks>3</m_Masks> <m_UnderlayMasksFolder>media/textures/Amputations/Masks/TestDouble</m_UnderlayMasksFolder>
<m_Masks>4</m_Masks> <m_Masks>4</m_Masks>
<m_Masks>6</m_Masks>

View File

@@ -0,0 +1,61 @@
<?xml version="1.0" encoding="utf-8"?>
<clothingItem>
<m_MaleModel>Amputation\Amputation_FA_LR</m_MaleModel>
<m_FemaleModel>Amputation\Amputation_FA_LR</m_FemaleModel>
<m_GUID>8e5bc1b4-d79b-4a17-b86b-71dab6ace816</m_GUID>
<m_Static>false</m_Static>
<m_AllowRandomHue>false</m_AllowRandomHue>
<m_AllowRandomTint>false</m_AllowRandomTint>
<m_Masks>4</m_Masks>
<m_Masks>6</m_Masks>
<!-- HUMAN -->
<textureChoices>Amputations\Human\Forearm\skin01_b</textureChoices>
<textureChoices>Amputations\Human\Forearm\skin02_b</textureChoices>
<textureChoices>Amputations\Human\Forearm\skin03_b</textureChoices>
<textureChoices>Amputations\Human\Forearm\skin04_b</textureChoices>
<textureChoices>Amputations\Human\Forearm\skin05_b</textureChoices>
<textureChoices>Amputations\Human\Forearm\skin01_hairy_b</textureChoices>
<textureChoices>Amputations\Human\Forearm\skin02_hairy_b</textureChoices>
<textureChoices>Amputations\Human\Forearm\skin03_hairy_b</textureChoices>
<textureChoices>Amputations\Human\Forearm\skin04_hairy_b</textureChoices>
<textureChoices>Amputations\Human\Forearm\skin05_hairy_b</textureChoices>
<!-- HUMAN AFTER CICATRIZATION -->
<textureChoices>Body\MaleBody01</textureChoices>
<textureChoices>Body\MaleBody02</textureChoices>
<textureChoices>Body\MaleBody03</textureChoices>
<textureChoices>Body\MaleBody04</textureChoices>
<textureChoices>Body\MaleBody05</textureChoices>
<textureChoices>Body\MaleBody01a</textureChoices>
<textureChoices>Body\MaleBody02a</textureChoices>
<textureChoices>Body\MaleBody03a</textureChoices>
<textureChoices>Body\MaleBody04</textureChoices>
<textureChoices>Body\MaleBody05a</textureChoices>
<!-- ZOMBIE -->
<textureChoices>Amputations\Zombie\Forearm\z_skin01_l1</textureChoices>
<textureChoices>Amputations\Zombie\Forearm\z_skin01_l2</textureChoices>
<textureChoices>Amputations\Zombie\Forearm\z_skin01_l3</textureChoices>
<textureChoices>Amputations\Zombie\Forearm\z_skin02_l1</textureChoices>
<textureChoices>Amputations\Zombie\Forearm\z_skin02_l2</textureChoices>
<textureChoices>Amputations\Zombie\Forearm\z_skin02_l3</textureChoices>
<textureChoices>Amputations\Zombie\Forearm\z_skin03_l1</textureChoices>
<textureChoices>Amputations\Zombie\Forearm\z_skin03_l2</textureChoices>
<textureChoices>Amputations\Zombie\Forearm\z_skin03_l3</textureChoices>
<textureChoices>Amputations\Zombie\Forearm\z_skin04_l1</textureChoices>
<textureChoices>Amputations\Zombie\Forearm\z_skin04_l2</textureChoices>
<textureChoices>Amputations\Zombie\Forearm\z_skin04_l3</textureChoices>
</clothingItem>

View File

@@ -57,5 +57,11 @@
<guid>9a5fe063-63c7-4e6f-81ca-ee77c6678e0d</guid> <guid>9a5fe063-63c7-4e6f-81ca-ee77c6678e0d</guid>
</files> </files>
<!-- TEST -->
<files>
<path>media/clothing/clothingItems/Amputation_ForeArm_LR.xml</path>
<guid>8e5bc1b4-d79b-4a17-b86b-71dab6ace816</guid>
</files>
</fileGuidTable> </fileGuidTable>

View File

@@ -8,8 +8,7 @@ local DataController = require("TOC/Controllers/DataController")
---@param context ISContextMenu ---@param context ISContextMenu
---@param worldobjects table ---@param worldobjects table
local function AddAdminTocOptions(playerNum, context, worldobjects) local function AddAdminTocOptions(playerNum, context, worldobjects)
if not(isClient() and isAdmin() or isDebugEnabled()) then return end
if (isClient() and not isDebugEnabled()) or isAdmin() then return end
local players = {} local players = {}
for _, v in ipairs(worldobjects) do for _, v in ipairs(worldobjects) do
@@ -32,6 +31,7 @@ local function AddAdminTocOptions(playerNum, context, worldobjects)
end end
-- ugly This whole section should be done better
for _, pl in pairs(players) do for _, pl in pairs(players) do
---@cast pl IsoPlayer ---@cast pl IsoPlayer
@@ -46,7 +46,6 @@ local function AddAdminTocOptions(playerNum, context, worldobjects)
sendClientCommand(CommandsData.modules.TOC_RELAY, CommandsData.server.Relay.RelayExecuteInitialization, sendClientCommand(CommandsData.modules.TOC_RELAY, CommandsData.server.Relay.RelayExecuteInitialization,
{ patientNum = clickedPlayerNum }) { patientNum = clickedPlayerNum })
else else
-- TODO ugly
ClientRelayCommands.ReceiveExecuteInitialization() ClientRelayCommands.ReceiveExecuteInitialization()
end end
end) end)
@@ -66,12 +65,13 @@ local function AddAdminTocOptions(playerNum, context, worldobjects)
{ patientNum = clickedPlayerNum, limbName = limbName }) { patientNum = clickedPlayerNum, limbName = limbName })
else else
ClientRelayCommands.ReceiveExecuteAmputationAction({surgeonNum=clickedPlayerNum, limbName=limbName, damagePlayer=false}) ClientRelayCommands.ReceiveExecuteAmputationAction({surgeonNum=clickedPlayerNum, limbName=limbName, damagePlayer=false})
-- todo ugly
end end
end) end)
end end
end end
end end
Events.OnFillWorldObjectContextMenu.Add(AddAdminTocOptions) Events.OnFillWorldObjectContextMenu.Add(AddAdminTocOptions)

View File

@@ -50,6 +50,10 @@ Compat.handlers = {
['iMedsFixed'] = { ['iMedsFixed'] = {
fun = Compat.iMeds, fun = Compat.iMeds,
isActive = false} isActive = false}
-- TODO Check if FirstAidOverhaul can be made compatible
} }

View File

@@ -5,7 +5,7 @@ local StaticData = require("TOC/StaticData")
---------------- ----------------
--- An instance will be abbreviated with dcInst --- An instance will be abbreviated with dcInst
-- https://github.com/ZioPao/The-Only-Cure/issues/187
--- Handle all TOC mod data related stuff --- Handle all TOC mod data related stuff
---@class DataController ---@class DataController
@@ -57,7 +57,6 @@ function DataController:setup(key)
---@type tocModDataType ---@type tocModDataType
self.tocData = { self.tocData = {
-- Generic stuff that does not belong anywhere else -- Generic stuff that does not belong anywhere else
isInitializing = true,
isIgnoredPartInfected = false, isIgnoredPartInfected = false,
isAnyLimbCut = false, isAnyLimbCut = false,
limbs = {}, limbs = {},
@@ -93,16 +92,16 @@ function DataController:setup(key)
-- Sync with the server -- Sync with the server
self:apply() self:apply()
-- -- Disable lock
-- self.tocData.isInitializing = false
-- ModData.add(key, self.tocData)
triggerEvent("OnSetupTocData") triggerEvent("OnSetupTocData")
end end
---In case of desync between the table on ModData and the table here ---In case of desync between the table on ModData and the table here
---@param tocData tocModDataType ---@param tocData tocModDataType
function DataController:applyOnlineData(tocData) function DataController:applyOnlineData(tocData)
if not tocData or not tocData.limbs then
TOC_DEBUG.print("Received invalid tocData")
return
end
local key = CommandsData.GetKey(self.username) local key = CommandsData.GetKey(self.username)
ModData.add(key, tocData) ModData.add(key, tocData)
self.tocData = ModData.get(key) self.tocData = ModData.get(key)
@@ -229,12 +228,8 @@ end
---@param limbName string ---@param limbName string
---@return boolean ---@return boolean
function DataController:getIsCut(limbName) function DataController:getIsCut(limbName)
if not self.isDataReady then return false end if not self.isDataReady or not self.tocData or not self.tocData.limbs then return false end
if self.tocData.limbs[limbName] then return self.tocData.limbs[limbName] and self.tocData.limbs[limbName].isCut or false
return self.tocData.limbs[limbName].isCut
else
return false
end
end end
---Get isVisible ---Get isVisible
@@ -339,14 +334,11 @@ end
---@param cicatrizationTime integer? ---@param cicatrizationTime integer?
function DataController:setLimbParams(limbName, ampStatus, cicatrizationTime) function DataController:setLimbParams(limbName, ampStatus, cicatrizationTime)
local limbData = self.tocData.limbs[limbName] local limbData = self.tocData.limbs[limbName]
if ampStatus.isCut ~= nil then limbData.isCut = ampStatus.isCut end for k, v in pairs(ampStatus) do
if ampStatus.isInfected ~= nil then limbData.isInfected = ampStatus.isInfected end if v ~= nil then
if ampStatus.isOperated ~= nil then limbData.isOperated = ampStatus.isOperated end limbData[k] = v
if ampStatus.isCicatrized ~= nil then limbData.isCicatrized = ampStatus.isCicatrized end end
if ampStatus.isCauterized ~= nil then limbData.isCauterized = ampStatus.isCauterized end end
if ampStatus.woundDirtyness ~= nil then limbData.woundDirtyness = ampStatus.woundDirtyness end
if ampStatus.isVisible ~= nil then limbData.isVisible = ampStatus.isVisible end
if cicatrizationTime ~= nil then limbData.cicatrizationTime = cicatrizationTime end if cicatrizationTime ~= nil then limbData.cicatrizationTime = cicatrizationTime end
end end
@@ -403,9 +395,6 @@ function DataController.ReceiveData(key, data)
handler:setup(key) handler:setup(key)
elseif data and data.limbs then elseif data and data.limbs then
-- Let's validate that the data structure is actually valid to prevent issues -- Let's validate that the data structure is actually valid to prevent issues
if data.isUpdateFromServer then
TOC_DEBUG.print("Update from the server")
end
handler:applyOnlineData(data) handler:applyOnlineData(data)
elseif username == getPlayer():getUsername() then elseif username == getPlayer():getUsername() then
TOC_DEBUG.print("Trying to load local data or no data is available") TOC_DEBUG.print("Trying to load local data or no data is available")

View File

@@ -17,7 +17,7 @@ ItemsController.Player = {}
---@return number ---@return number
---@private ---@private
function ItemsController.Player.GetAmputationTexturesIndex(playerObj, isCicatrized) function ItemsController.Player.GetAmputationTexturesIndex(playerObj, isCicatrized)
-- FIX Broken -- todo
local textureString = playerObj:getHumanVisual():getSkinTexture() local textureString = playerObj:getHumanVisual():getSkinTexture()
local isHairy = textureString:sub(-1) == "a" local isHairy = textureString:sub(-1) == "a"
@@ -79,13 +79,16 @@ end
---Deletes all the old amputation items, used for resets ---Deletes all the old amputation items, used for resets
---@param playerObj IsoPlayer ---@param playerObj IsoPlayer
function ItemsController.Player.DeleteAllOldAmputationItems(playerObj) function ItemsController.Player.DeleteAllOldAmputationItems(playerObj)
-- TODO Fix visual bug
-- This part is a workaround for a pretty shitty implementation on the java side. Check ProsthesisHandler for more infos -- This part is a workaround for a pretty shitty implementation on the java side. Check ProsthesisHandler for more infos
local group = BodyLocations.getGroup("Human") -- local group = BodyLocations.getGroup("Human")
group:setMultiItem("TOC_Arm", false) -- group:setMultiItem("TOC_Arm", false)
group:setMultiItem("TOC_ArmProst", false) -- group:setMultiItem("TOC_ArmProst", false)
for i = 1, #StaticData.LIMBS_STR do for i = 1, #StaticData.LIMBS_STR do
local limbName = StaticData.LIMBS_STR[i] local limbName = StaticData.LIMBS_STR[i]
-- TODO Won't work with dedicated clothingItems for multi amps
local clothItemName = StaticData.AMPUTATION_CLOTHING_ITEM_BASE .. limbName local clothItemName = StaticData.AMPUTATION_CLOTHING_ITEM_BASE .. limbName
local clothItem = playerObj:getInventory():FindAndReturn(clothItemName) local clothItem = playerObj:getInventory():FindAndReturn(clothItemName)
---@cast clothItem InventoryItem ---@cast clothItem InventoryItem
@@ -94,8 +97,8 @@ function ItemsController.Player.DeleteAllOldAmputationItems(playerObj)
-- Reset model just in case -- Reset model just in case
playerObj:resetModel() playerObj:resetModel()
group:setMultiItem("TOC_Arm", true) -- group:setMultiItem("TOC_Arm", true)
group:setMultiItem("TOC_ArmProst", true) -- group:setMultiItem("TOC_ArmProst", true)
end end
---Spawns and equips the correct amputation item to the player. ---Spawns and equips the correct amputation item to the player.

View File

@@ -5,14 +5,51 @@ local CachedDataHandler = require("TOC/Handlers/CachedDataHandler")
local CommonMethods = require("TOC/CommonMethods") local CommonMethods = require("TOC/CommonMethods")
local StaticData = require("TOC/StaticData") local StaticData = require("TOC/StaticData")
local OverridenMethodsArchive = require("TOC/OverridenMethodsArchive")
----------------- -----------------
---@class LimitActionsController
local LimitActionsController = {}
--* TIMED ACTIONS *-- --* DISABLE WEARING CERTAIN ITEMS WHEN NO LIMB
-- We want to be able to modify how long actions are gonna take,
-- depending on amputation status and kind of action. Also, when the function LimitActionsController.CheckLimbFeasibility(limbName)
-- player has not completely cicatrized their own wounds, and try to do any action with local dcInst = DataController.GetInstance()
-- a prosthesis on, that can trigger random bleeds. local isFeasible = not dcInst:getIsCut(limbName) or dcInst:getIsProstEquipped(limbName)
--TOC_DEBUG.print("isFeasible="..tostring(isFeasible))
return isFeasible
end
---@param obj any
---@param wrappedFunc function
---@param item InventoryItem
---@return boolean
function LimitActionsController.WrapClothingAction(obj, wrappedFunc, item)
local isEquippable = wrappedFunc(obj)
if not isEquippable then return isEquippable end
local itemBodyLoc = item:getBodyLocation()
local limbToCheck = StaticData.AFFECTED_BODYLOCS_TO_LIMBS_IND_STR[itemBodyLoc]
if LimitActionsController.CheckLimbFeasibility(limbToCheck) then return isEquippable else return false end
end
-- We need to override when the player changes key binds manually to be sure that TOC changes are re-applied
local og_MainOptions_apply = MainOptions.apply
function MainOptions:apply(closeAfter)
og_MainOptions_apply(self, closeAfter)
CachedDataHandler.OverrideBothHandsFeasibility()
end
--------------------------------------------
--* TIMED ACTIONS
--* We want to be able to modify how long actions are gonna take,
--* depending on amputation status and kind of action. Also, when the
--* player has not completely cicatrized their own wounds, and try to do any action with
--* a prosthesis on, that can trigger random bleeds.
local function CheckHandFeasibility(limbName) local function CheckHandFeasibility(limbName)
TOC_DEBUG.print("Checking hand feasibility: " .. limbName) TOC_DEBUG.print("Checking hand feasibility: " .. limbName)
@@ -24,18 +61,18 @@ local function CheckHandFeasibility(limbName)
end end
--* Time to perform actions overrides *-- --* Time to perform actions overrides
local og_ISBaseTimedAction_adjustMaxTime = ISBaseTimedAction.adjustMaxTime local og_ISBaseTimedAction_adjustMaxTime = ISBaseTimedAction.adjustMaxTime
--- Adjust time --- Adjust time
---@diagnostic disable-next-line: duplicate-set-field ---@diagnostic disable-next-line: duplicate-set-field
function ISBaseTimedAction:adjustMaxTime(maxTime) function ISBaseTimedAction:adjustMaxTime(maxTime)
local time = og_ISBaseTimedAction_adjustMaxTime(self, maxTime) local time = og_ISBaseTimedAction_adjustMaxTime(self, maxTime)
--TOC_DEBUG.print("Running override for adjustMaxTime")
-- Exceptions handling, if we find that parameter then we just use the original time -- Exceptions handling, if we find that parameter then we just use the original time
local actionsQueue = ISTimedActionQueue.getTimedActionQueue(getPlayer()) local actionsQueue = ISTimedActionQueue.getTimedActionQueue(getPlayer())
if actionsQueue and actionsQueue.current and actionsQueue.skipTOC then if actionsQueue and actionsQueue.current and actionsQueue.current.skipTOC then
--TOC_DEBUG.print("Should skip TOC stuff") TOC_DEBUG.print("Should skip TOC stuff")
return time return time
end end
@@ -78,37 +115,58 @@ function ISBaseTimedAction:adjustMaxTime(maxTime)
return time return time
end end
--* Random bleeding during cicatrization + Perks leveling override *-- --* Random bleeding during cicatrization + Perks leveling override
local og_ISBaseTimedAction_perform = ISBaseTimedAction.perform local og_ISBaseTimedAction_perform = ISBaseTimedAction.perform
--- After each action, level up perks --- After each action, level up perks
---@diagnostic disable-next-line: duplicate-set-field ---@diagnostic disable-next-line: duplicate-set-field
function ISBaseTimedAction:perform() function ISBaseTimedAction:perform()
og_ISBaseTimedAction_perform(self) og_ISBaseTimedAction_perform(self)
TOC_DEBUG.print("Running ISBaseTimedAction.perform override")
TOC_DEBUG.print("max time: " .. tostring(self.maxTime)) --TOC_DEBUG.print("Running ISBaseTimedAction.perform override")
--TOC_DEBUG.print("max time: " .. tostring(self.maxTime))
local dcInst = DataController.GetInstance() local dcInst = DataController.GetInstance()
if not dcInst:getIsAnyLimbCut() then return end if not dcInst:getIsAnyLimbCut() or self.noExp then return end
--* LEVELING
-- First check level of perks. if already at max, skip
local amputatedLimbs = CachedDataHandler.GetAmputatedLimbs(LocalPlayerController.username) local amputatedLimbs = CachedDataHandler.GetAmputatedLimbs(LocalPlayerController.username)
local xp = self.maxTime / 100 local xp = self.maxTime / 100
-- TODO Exp should be added while doing the action, not after it's done
-- Prevent xp from being negative and decreasing perks
if xp < 0 then xp = 0 end
for k, _ in pairs(amputatedLimbs) do for k, _ in pairs(amputatedLimbs) do
local limbName = k local limbName = k
-- We're checking for only "visible" amputations to prevent from having bleeds everywhere -- We're checking for only "visible" amputations to prevent from having bleeds everywhere
if dcInst:getIsCut(limbName) and dcInst:getIsVisible(limbName) then if dcInst:getIsCut(limbName) and dcInst:getIsVisible(limbName) then
local side = CommonMethods.GetSide(limbName) local side = CommonMethods.GetSide(limbName)
LocalPlayerController.playerObj:getXp():AddXP(Perks["Side_" .. side], xp)
if not dcInst:getIsCicatrized(limbName) and dcInst:getIsProstEquipped(limbName) then local ampPerk = Perks["Side_" .. side]
TOC_DEBUG.print("Trying for bleed, player met the criteria") local ampPerkLevel = LocalPlayerController.playerObj:getPerkLevel(ampPerk)
LocalPlayerController.TryRandomBleed(self.character, limbName)
if ampPerkLevel < 10 then
--TOC_DEBUG.print("Levelling")
LocalPlayerController.playerObj:getXp():AddXP(ampPerk, xp)
end end
-- Level up prosthesis perk -- Level up prosthesis perk
if dcInst:getIsProstEquipped(limbName) then if dcInst:getIsProstEquipped(limbName) then
LocalPlayerController.playerObj:getXp():AddXP(Perks["ProstFamiliarity"], xp) local prostPerk = Perks["ProstFamiliarity"]
local prostPerkLevel = LocalPlayerController.playerObj:getPerkLevel(prostPerk)
if prostPerkLevel < 10 then
LocalPlayerController.playerObj:getXp():AddXP(prostPerk, xp)
end
end
-- Bleeding when not cicatrized
if not dcInst:getIsCicatrized(limbName) and dcInst:getIsProstEquipped(limbName) then
--TOC_DEBUG.print("Trying for bleed, player met the criteria")
LocalPlayerController.TryRandomBleed(self.character, limbName)
end end
end end
end end
@@ -124,7 +182,7 @@ end
--* Equipping items overrides *-- --* Equipping items overrides *--
local og_ISEquipWeaponAction_isValid = ISEquipWeaponAction.isValid local og_ISEquipWeaponAction_isValid = ISEquipWeaponAction.isValid
---Add a condition to check the feasibility of having 2 handed weapons or if both arms are cut off ---Add a condition to check the feasibility of having 2 handed weapons or if both arms are cut off
---@return boolean ---@return boolean?
---@diagnostic disable-next-line: duplicate-set-field ---@diagnostic disable-next-line: duplicate-set-field
function ISEquipWeaponAction:isValid() function ISEquipWeaponAction:isValid()
local isValid = og_ISEquipWeaponAction_isValid(self) local isValid = og_ISEquipWeaponAction_isValid(self)
@@ -291,6 +349,12 @@ function ISWorldObjectContextMenu.createMenu(player, worldobjects, x, y, test)
---@type ISContextMenu ---@type ISContextMenu
local ogContext = og_ISWorldObjectContextMenu_createMenu(player, worldobjects, x, y, test) local ogContext = og_ISWorldObjectContextMenu_createMenu(player, worldobjects, x, y, test)
-- goddamn it, zomboid devs. ogContext could be a boolean...
-- TBH, I don't really care about gamepad support, but all this method can break stuff. Let's just disable thisfor gamepad users.
if type(ogContext) == "boolean" or type(ogContext) == "string" then
return ogContext
end
-- The vanilla game doesn't count an item in the off hand as "equipped" for picking up glass. Let's fix that here -- The vanilla game doesn't count an item in the off hand as "equipped" for picking up glass. Let's fix that here
local brokenGlassOption = ogContext:getOptionFromName(getText("ContextMenu_RemoveBrokenGlass")) local brokenGlassOption = ogContext:getOptionFromName(getText("ContextMenu_RemoveBrokenGlass"))
@@ -322,42 +386,30 @@ function ISWorldObjectContextMenu.createMenu(player, worldobjects, x, y, test)
return ogContext return ogContext
end end
--* DISABLE WEARING CERTAIN ITEMS WHEN NO LIMB
local function CheckLimbFeasibility(limbName)
local dcInst = DataController.GetInstance()
local isFeasible = not dcInst:getIsCut(limbName) or dcInst:getIsProstEquipped(limbName)
--TOC_DEBUG.print("isFeasible="..tostring(isFeasible))
return isFeasible
end
---@param obj any
---@param wrappedFunc function
---@param item InventoryItem
---@return boolean
local function WrapClothingAction(obj, wrappedFunc, item)
local isEquippable = wrappedFunc(obj)
if not isEquippable then return isEquippable end
local itemBodyLoc = item:getBodyLocation()
local limbToCheck = StaticData.AFFECTED_BODYLOCS_TO_LIMBS_IND_STR[itemBodyLoc]
if CheckLimbFeasibility(limbToCheck) then return isEquippable else return false end
end
---@diagnostic disable-next-line: duplicate-set-field ---@diagnostic disable-next-line: duplicate-set-field
local og_ISWearClothing_isValid = ISWearClothing.isValid local og_ISWearClothing_isValid = ISWearClothing.isValid
function ISWearClothing:isValid() function ISWearClothing:isValid()
return WrapClothingAction(self, og_ISWearClothing_isValid, self.item) return LimitActionsController.WrapClothingAction(self, og_ISWearClothing_isValid, self.item)
end end
local og_ISClothingExtraAction_isValid = ISClothingExtraAction.isValid
local og_ISClothingExtraAction_isValid = OverridenMethodsArchive.Save("ISClothingExtraAction_isValid", ISClothingExtraAction.isValid)
---@diagnostic disable-next-line: duplicate-set-field ---@diagnostic disable-next-line: duplicate-set-field
function ISClothingExtraAction:isValid() function ISClothingExtraAction:isValid()
return WrapClothingAction(self, og_ISClothingExtraAction_isValid, InventoryItemFactory.CreateItem(self.extra)) return LimitActionsController.WrapClothingAction(self, og_ISClothingExtraAction_isValid, InventoryItemFactory.CreateItem(self.extra))
end end
--* Book exception for exp
local og_ISReadABook_perform = ISReadABook.perform
function ISReadABook:perform()
self.noExp = true
og_ISReadABook_perform(self)
end
return LimitActionsController

View File

@@ -94,16 +94,19 @@ end
local og_ISClothingExtraAction_perform = ISClothingExtraAction.perform local og_ISClothingExtraAction_perform = ISClothingExtraAction.perform
---@diagnostic disable-next-line: duplicate-set-field
function ISClothingExtraAction:perform() function ISClothingExtraAction:perform()
TourniquetController.WrapClothingAction(self, og_ISClothingExtraAction_perform) TourniquetController.WrapClothingAction(self, og_ISClothingExtraAction_perform)
end end
local og_ISWearClothing_isValid = ISWearClothing.isValid local og_ISWearClothing_isValid = ISWearClothing.isValid
---@diagnostic disable-next-line: duplicate-set-field
function ISWearClothing:isValid() function ISWearClothing:isValid()
return TourniquetController.WrapClothingAction(self, og_ISWearClothing_isValid) return TourniquetController.WrapClothingAction(self, og_ISWearClothing_isValid)
end end
local og_ISUnequipAction_perform = ISUnequipAction.perform local og_ISUnequipAction_perform = ISUnequipAction.perform
---@diagnostic disable-next-line: duplicate-set-field
function ISUnequipAction:perform() function ISUnequipAction:perform()
return TourniquetController.WrapClothingAction(self, og_ISUnequipAction_perform) return TourniquetController.WrapClothingAction(self, og_ISUnequipAction_perform)
end end

View File

@@ -23,7 +23,7 @@ end
function CachedDataHandler.CalculateCacheableValues(username) function CachedDataHandler.CalculateCacheableValues(username)
CachedDataHandler.CalculateHighestAmputatedLimbs(username) CachedDataHandler.CalculateHighestAmputatedLimbs(username)
if getPlayer():getUsername() == username then if getPlayer():getUsername() == username then
CachedDataHandler.CalculateBothHandsFeasibility() CachedDataHandler.OverrideBothHandsFeasibility()
end end
end end
@@ -130,14 +130,13 @@ function CachedDataHandler.GetHandFeasibility(side)
-- FIX horrendous workaround, but with a forced init we run the caching too early and it breaks this, setting it to nil. -- FIX horrendous workaround, but with a forced init we run the caching too early and it breaks this, setting it to nil.
if CachedDataHandler.handFeasibility[side] == nil then if CachedDataHandler.handFeasibility[side] == nil then
CachedDataHandler.CalculateBothHandsFeasibility() CachedDataHandler.OverrideBothHandsFeasibility()
end end
return CachedDataHandler.handFeasibility[side] return CachedDataHandler.handFeasibility[side]
end end
function CachedDataHandler.OverrideBothHandsFeasibility()
function CachedDataHandler.CalculateBothHandsFeasibility()
CachedDataHandler.CalculateHandFeasibility("Hand_L") CachedDataHandler.CalculateHandFeasibility("Hand_L")
CachedDataHandler.CalculateHandFeasibility("Hand_R") CachedDataHandler.CalculateHandFeasibility("Hand_R")
local interactStr = "Interact" local interactStr = "Interact"
@@ -151,13 +150,23 @@ function CachedDataHandler.CalculateBothHandsFeasibility()
if not CachedDataHandler.GetBothHandsFeasibility() then if not CachedDataHandler.GetBothHandsFeasibility() then
TOC_DEBUG.print("Disabling interact key") TOC_DEBUG.print("Disabling interact key")
TOC_DEBUG.print("Cached current key for interact: " .. tostring(CachedDataHandler.interactKey)) TOC_DEBUG.print("Cached current key for interact: " .. tostring(CachedDataHandler.interactKey))
getCore():addKeyBinding(interactStr, Keyboard.KEY_NONE)
else
TOC_DEBUG.print("Re-enabling interact key")
TOC_DEBUG.print("Cached current key for interact: " .. tostring(CachedDataHandler.interactKey))
if StaticData.COMPAT_42 then
getCore():addKeyBinding(interactStr, Keyboard.KEY_NONE, 0, false, false, false)
else
getCore():addKeyBinding(interactStr, Keyboard.KEY_NONE)
end
else
--TOC_DEBUG.print("Re-enabling interact key")
--TOC_DEBUG.print("Cached current key for interact: " .. tostring(CachedDataHandler.interactKey))
if StaticData.COMPAT_42 then
getCore():addKeyBinding(interactStr, CachedDataHandler.interactKey, 0, false, false, false)
else
getCore():addKeyBinding(interactStr, CachedDataHandler.interactKey) getCore():addKeyBinding(interactStr, CachedDataHandler.interactKey)
end end
end
end end
function CachedDataHandler.GetBothHandsFeasibility() function CachedDataHandler.GetBothHandsFeasibility()
@@ -165,3 +174,4 @@ function CachedDataHandler.GetBothHandsFeasibility()
end end
return CachedDataHandler return CachedDataHandler

View File

@@ -2,6 +2,8 @@ local CommonMethods = require("TOC/CommonMethods")
local StaticData = require("TOC/StaticData") local StaticData = require("TOC/StaticData")
local DataController = require("TOC/Controllers/DataController") local DataController = require("TOC/Controllers/DataController")
local CachedDataHandler = require("TOC/Handlers/CachedDataHandler") local CachedDataHandler = require("TOC/Handlers/CachedDataHandler")
local OverridenMethodsArchive = require("TOC/OverridenMethodsArchive")
------------------------- -------------------------
---@class ProsthesisHandler ---@class ProsthesisHandler
@@ -84,18 +86,11 @@ function ProsthesisHandler.SearchAndSetupProsthesis(item, isEquipping)
dcInst:apply() dcInst:apply()
-- Calculates hands feasibility once again -- Calculates hands feasibility once again
CachedDataHandler.CalculateBothHandsFeasibility() CachedDataHandler.OverrideBothHandsFeasibility()
return true return true
end end
------------------------- function ProsthesisHandler.Validate(item, isEquippable)
--* Overrides *--
---@param item InventoryItem
---@param isEquippable boolean
---@return unknown
local function HandleProsthesisValidation(item, isEquippable)
local isProst = ProsthesisHandler.CheckIfProst(item) local isProst = ProsthesisHandler.CheckIfProst(item)
if not isProst then return isEquippable end if not isProst then return isEquippable end
@@ -110,37 +105,56 @@ local function HandleProsthesisValidation(item, isEquippable)
end end
---@diagnostic disable-next-line: duplicate-set-field
-------------------------
--* Overrides *--
local og_ISWearClothing_isValid = ISWearClothing.isValid local og_ISWearClothing_isValid = ISWearClothing.isValid
---@diagnostic disable-next-line: duplicate-set-field
function ISWearClothing:isValid() function ISWearClothing:isValid()
local isEquippable = og_ISWearClothing_isValid(self) local isEquippable = og_ISWearClothing_isValid(self)
return HandleProsthesisValidation(self.item, isEquippable) return ProsthesisHandler.Validate(self.item, isEquippable)
end end
local og_ISWearClothing_perform = ISWearClothing.perform local og_ISWearClothing_perform = ISWearClothing.perform
---@diagnostic disable-next-line: duplicate-set-field
function ISWearClothing:perform() function ISWearClothing:perform()
ProsthesisHandler.SearchAndSetupProsthesis(self.item, true) ProsthesisHandler.SearchAndSetupProsthesis(self.item, true)
og_ISWearClothing_perform(self) og_ISWearClothing_perform(self)
end end
local og_ISClothingExtraAction_isValid = ISClothingExtraAction.isValid
local og_ISClothingExtraAction_isValid = OverridenMethodsArchive.Save("ISClothingExtraAction_isValid", ISClothingExtraAction.isValid)
---@diagnostic disable-next-line: duplicate-set-field ---@diagnostic disable-next-line: duplicate-set-field
function ISClothingExtraAction:isValid() function ISClothingExtraAction:isValid()
local isEquippable = og_ISClothingExtraAction_isValid(self) local isEquippable = og_ISClothingExtraAction_isValid(self)
-- self.extra is a string, not the item -- self.extra is a string, not the item
-- B42 Compatibility to add
local testItem = InventoryItemFactory.CreateItem(self.extra) local testItem = InventoryItemFactory.CreateItem(self.extra)
return HandleProsthesisValidation(testItem, isEquippable) return ProsthesisHandler.Validate(testItem, isEquippable)
end end
local og_ISClothingExtraAction_perform = OverridenMethodsArchive.Save("ISClothingExtraAction_perform", ISClothingExtraAction.perform)
local og_ISClothingExtraAction_perform = ISClothingExtraAction.perform ---@diagnostic disable-next-line: duplicate-set-field
function ISClothingExtraAction:perform() function ISClothingExtraAction:perform()
-- B42 Compatibility to add
local extraItem = InventoryItemFactory.CreateItem(self.extra) local extraItem = InventoryItemFactory.CreateItem(self.extra)
ProsthesisHandler.SearchAndSetupProsthesis(extraItem, true) ProsthesisHandler.SearchAndSetupProsthesis(extraItem, true)
og_ISClothingExtraAction_perform(self) og_ISClothingExtraAction_perform(self)
end end
local og_ISUnequipAction_perform = ISUnequipAction.perform local og_ISUnequipAction_perform = ISUnequipAction.perform
---@diagnostic disable-next-line: duplicate-set-field
function ISUnequipAction:perform() function ISUnequipAction:perform()
--[[ --[[
@@ -172,7 +186,6 @@ function ISUnequipAction:perform()
-- This could break if amputated limbs aren't cached for some reason -- This could break if amputated limbs aren't cached for some reason
triggerEvent("OnProsthesisUnequipped", hal) triggerEvent("OnProsthesisUnequipped", hal)
end end
end end
end end
end end

View File

@@ -6,7 +6,7 @@ require("TOC/Events")
---@class Main ---@class Main
local Main = { local Main = {
_version = "2.1.3" _version = "2.1.6"
} }
function Main.Start() function Main.Start()

View File

@@ -160,7 +160,6 @@ TestFramework.registerTestModule("Various", "Player", function()
return Tests return Tests
end) end)
TestFramework.registerTestModule("Various", "Visuals", function() TestFramework.registerTestModule("Various", "Visuals", function()
local Tests = {} local Tests = {}

View File

@@ -7,6 +7,9 @@ local CommonMethods = require("TOC/CommonMethods")
---@field otherPlayer IsoPlayer ---@field otherPlayer IsoPlayer
---@field bandage InventoryItem ---@field bandage InventoryItem
---@field bodyPart any ---@field bodyPart any
---@field doctorLevel number
---@field bandagedPlayerX number
---@field bandagedPlayerY number
local CleanWoundAction = ISBaseTimedAction:derive("CleanWoundAction") local CleanWoundAction = ISBaseTimedAction:derive("CleanWoundAction")
---@param doctor IsoPlayer ---@param doctor IsoPlayer
@@ -33,7 +36,7 @@ function CleanWoundAction:new(doctor, otherPlayer, bandage, bodyPart)
if doctor:isTimedActionInstant() then if doctor:isTimedActionInstant() then
o.maxTime = 1 o.maxTime = 1
end end
if doctor:getAccessLevel() ~= "None" then if doctor:getAccessLevel() ~= "None" then -- B42 Deprecated
o.doctorLevel = 10 o.doctorLevel = 10
end end
return o return o

View File

@@ -0,0 +1,139 @@
-- TODO This section must be overhauled
local DataController = require("TOC/Controllers/DataController")
local StaticData = require("TOC/StaticData")
---@diagnostic disable: duplicate-set-field
-- Bunch of actions shouldn't be modified by the adjusted time
-----------------------------------------------
---* Some actions have specific maxTime calculations and we must account for that
---ISAttachItemHotbar
---ISDetachItemHotbar
---ISEquipWeaponAction
---ISUnequipAction
--- We're forced to re-run this crap to fix it
---@param action ISBaseTimedAction
local function OverrideAction(action, maxTime)
-- TODO Add forced debuff instead of just relying on the vanilla values?
action.skipTOC = true
action.maxTime = maxTime
action.animSpeed = 1.0
end
local og_ISAttachItemHotbar_new = ISAttachItemHotbar.new
function ISAttachItemHotbar:new(character, item, slot, slotIndex, slotDef)
local action = og_ISAttachItemHotbar_new(self, character, item, slot, slotIndex, slotDef)
OverrideAction(action, 30) -- Default time for this action
return action
end
local og_ISDetachItemHotbar_new = ISDetachItemHotbar.new
function ISDetachItemHotbar:new(character, item)
local action = og_ISDetachItemHotbar_new(self, character, item)
OverrideAction(action, 25) -- Default time for this action
return action
end
local og_ISEquipWeaponAction_new = ISEquipWeaponAction.new
function ISEquipWeaponAction:new(character, item, time, primary, twoHands)
local action = og_ISEquipWeaponAction_new(self, character, item, time, primary, twoHands)
TOC_DEBUG.print("Override ISEquipWeaponAction New")
-- check if right arm is cut off or not. if it is, penality shall apply
-- if we got here, the action is valid, so we know that we have a prosthesis.
local dcInst = DataController.GetInstance()
-- Brutal Handwork should be considered. Use the twohands thing
if not (dcInst:getIsAnyLimbCut() and twoHands) then
OverrideAction(action, time)
end
return action
end
local og_ISUnequipAction_new = ISUnequipAction.new
function ISUnequipAction:new(character, item, time)
local action = og_ISUnequipAction_new(self, character, item, time)
---@cast item InventoryItem
-- TODO Consider other cases where unequipping something should skip TOC.
if instanceof(item, 'HandWeapon') then
OverrideAction(action, time)
end
return action
end
------------------------------------------------------
--- Normal cases
local og_ISEatFoodAction_new = ISEatFoodAction.new
function ISEatFoodAction:new(character, item, percentage)
local action = og_ISEatFoodAction_new(self, character, item, percentage)
--TOC_DEBUG.print("Override ISEatFoodAction")
action.skipTOC = true
return action
end
local og_ISReadABook_new = ISReadABook.new
function ISReadABook:new(character, item, time)
local action = og_ISReadABook_new(self, character, item, time)
--TOC_DEBUG.print("Override ISReadABook")
action.skipTOC = true
return action
end
local og_ISTakePillAction_new = ISTakePillAction.new
function ISTakePillAction:new(character, item, time)
local action = og_ISTakePillAction_new(self, character, item, time)
--TOC_DEBUG.print("Override ISTakePillAction")
action.skipTOC = true
return action
end
local og_ISTakeWaterAction_new = ISTakeWaterAction.new
function ISTakeWaterAction:new(character, item, waterUnit, waterObject, time, oldItem)
local action = og_ISTakeWaterAction_new(self, character, item, waterUnit, waterObject, time, oldItem)
--TOC_DEBUG.print("Override ISTakeWaterAction")
action.skipTOC = true
return action
end
local og_ISDrinkFromBottle_new = ISDrinkFromBottle.new
function ISDrinkFromBottle:new(character, item, uses)
local action = og_ISDrinkFromBottle_new(self, character, item, uses)
--TOC_DEBUG.print("Override ISDrinkFromBottle")
action.skipTOC = true
return action
end
if StaticData.COMPAT_42 == false then
-- TODO confirm that this doesn't exist anymore in B42
-- B42 nenen
local og_ISFinalizeDealAction_new = ISFinalizeDealAction.new
function ISFinalizeDealAction:new(player, otherPlayer, itemsToGive, itemsToReceive, time)
local action = og_ISFinalizeDealAction_new(self, player, otherPlayer, itemsToGive, itemsToReceive, time)
--TOC_DEBUG.print("Override ISFinalizeDealAction")
action.skipTOC = true
return action
end
end
local og_ISCampingInfoAction_new = ISCampingInfoAction.new
function ISCampingInfoAction:new(character, campfireObject, campfire)
local action = og_ISCampingInfoAction_new(self, character, campfireObject, campfire)
--TOC_DEBUG.print("Override ISCampingInfoAction")
action.skipTOC = true
return action
end

View File

@@ -53,14 +53,14 @@ function ConfirmationPanel:createChildren()
local yButton = self:getHeight() - yPadding - btnHeight local yButton = self:getHeight() - yPadding - btnHeight
self.btnYes = ISButton:new(xPadding, yButton, btnWidth, btnHeight, "Yes", self, self.onClick) self.btnYes = ISButton:new(xPadding, yButton, btnWidth, btnHeight, getText("IGUI_Yes"), self, self.onClick)
self.btnYes.internal = "YES" self.btnYes.internal = "YES"
self.btnYes:initialise() self.btnYes:initialise()
self.btnYes.borderColor = { r = 1, g = 0, b = 0, a = 1 } self.btnYes.borderColor = { r = 1, g = 0, b = 0, a = 1 }
self.btnYes:setEnable(true) self.btnYes:setEnable(true)
self:addChild(self.btnYes) self:addChild(self.btnYes)
self.btnNo = ISButton:new(self:getWidth() - xPadding - btnWidth, yButton, btnWidth, btnHeight, "No", self, self.btnNo = ISButton:new(self:getWidth() - xPadding - btnWidth, yButton, btnWidth, btnHeight, getText("IGUI_No"), self,
self.onClick) self.onClick)
self.btnNo.internal = "NO" self.btnNo.internal = "NO"
self.btnNo:initialise() self.btnNo:initialise()

View File

@@ -10,10 +10,22 @@ local WoundCleaningInteractionHandler = require("TOC/UI/Interactions/WoundCleani
local isReady = false local isReady = false
local xMod, yMod
if StaticData.COMPAT_42 then
-- B42 For some reason (I didn't investigate), when applying stuff to the health panel there is an un-accounted shift in B42.
xMod = 5
yMod = 13
else
xMod = 0
yMod = 0
end
function SetHealthPanelTOC() function SetHealthPanelTOC()
-- depending on compatibility -- depending on compatibility
isReady = true isReady = true
end end
@@ -101,14 +113,14 @@ function ISHealthPanel:tryDrawAmputation(highestAmputations, side, username)
local sexPl = self.character:isFemale() and "Female" or "Male" local sexPl = self.character:isFemale() and "Female" or "Male"
texture = StaticData.HEALTH_PANEL_TEXTURES[sexPl][limbName] texture = StaticData.HEALTH_PANEL_TEXTURES[sexPl][limbName]
end end
-- B42, for some reason the positioning of the texture changed. Realigned it manually with those fixed values
self:drawTexture(texture, self.healthPanel.x, self.healthPanel.y, 1, redColor, 0, 0) self:drawTexture(texture, self.healthPanel.x - xMod, self.healthPanel.y - yMod, 1, redColor, 0, 0)
end end
function ISHealthPanel:tryDrawProsthesis(highestAmputations, side, username) function ISHealthPanel:tryDrawProsthesis(highestAmputations, side, username)
local dc = DataController.GetInstance(username) -- TODO CACHE PROSTHESIS!!! Don't use DC here local dc = DataController.GetInstance(username) -- TODO CACHE PROSTHESIS!!! Don't use DC here
local limbName = highestAmputations[side] local limbName = highestAmputations[side]
if limbName and dc:getIsProstEquipped(limbName) then if limbName and dc:getIsProstEquipped(limbName) then
self:drawTexture(StaticData.HEALTH_PANEL_TEXTURES.ProstArm[side], self.healthPanel.x, self.healthPanel.y, 1, 1, 1, 1) self:drawTexture(StaticData.HEALTH_PANEL_TEXTURES.ProstArm[side], self.healthPanel.x - xMod, self.healthPanel.y - yMod, 1, 1, 1, 1)
end end
end end

View File

@@ -118,7 +118,7 @@ function BaseHandler:toPlayerInventory(item, previousAction)
if item:getContainer() ~= self:getDoctor():getInventory() then if item:getContainer() ~= self:getDoctor():getInventory() then
local action = ISInventoryTransferAction:new(self:getDoctor(), item, item:getContainer(), self:getDoctor():getInventory()) local action = ISInventoryTransferAction:new(self:getDoctor(), item, item:getContainer(), self:getDoctor():getInventory())
ISTimedActionQueue.addAfter(previousAction, action) ISTimedActionQueue.addAfter(previousAction, action)
-- FIXME: ISHealthPanel.actions never gets cleared -- FIX: ISHealthPanel.actions never gets cleared
self.panel.actions = self.panel.actions or {} self.panel.actions = self.panel.actions or {}
self.panel.actions[action] = self.bodyPart self.panel.actions[action] = self.bodyPart
return action return action

View File

@@ -68,7 +68,7 @@ local function AddStoveContextMenu(playerNum, context, worldObjects, test)
-- Notifications, in case the player can't do the action -- Notifications, in case the player can't do the action
local isPlayerCourageous = pl:HasTrait("Brave") or pl:getPerkLevel(Perks.Strength) > 5 local isPlayerCourageous = pl:HasTrait("Brave") or pl:HasTrait("Desensitized") or pl:getPerkLevel(Perks.Strength) > 5
local isTempHighEnough = stoveObj:getCurrentTemperature() >= 250 local isTempHighEnough = stoveObj:getCurrentTemperature() >= 250
local isLimbFree = not dcInst:getIsProstEquipped(limbName) local isLimbFree = not dcInst:getIsProstEquipped(limbName)

View File

@@ -0,0 +1,171 @@
-- Made by Vyshnia
-- Workshop ID: 2875394066
-- Mod ID: LuaTimers
local os_time = os.time
local table_insert = table.insert
local table_remove = table.remove
local assert = assert
local type = type
local pairs = pairs
timer = {
Timers = {},
SimpleTimers = {}
}
function timer:Simple(delay, func)
assert(type(delay) == "number", "Delay of timer should be a number type")
assert(type(func) == "function", "Func of timer should be a function type (lol)")
table_insert(self.SimpleTimers, {
EndTime = os_time() + delay,
Func = func
})
end
function timer:Create(name, delay, repetitions, func)
assert(type(name) == "string", "ID of timer should be a string type")
assert(type(delay) == "number", "Delay of timer should be a number type")
assert(type(repetitions) == "number", "Repetitions of timer should be a number type")
assert(type(func) == "function", "Func of timer should be a function type (lol)")
self.Timers[name] = {
Delay = delay,
StartRepetitions = repetitions,
Repetitions = repetitions,
Infinity = repetitions == 0,
LastFuncTime = os_time(),
Func = func,
Paused = false,
}
end
local function timerUpdate()
local cur_time = os_time()
for k, v in pairs(timer.Timers) do
if not v.Paused then
if cur_time >= v.LastFuncTime + v.Delay then
v.Func()
v.LastFuncTime = cur_time
if not v.Infinity then
v.Repetitions = v.Repetitions - 1
if v.Repetitions <= 0 then
timer.Timers[k] = nil
end
end
end
end
end
local simple_timers = timer.SimpleTimers
for i = #simple_timers, 1, -1 do
local t = simple_timers[i]
if t.EndTime <= cur_time then
t.Func()
table_remove(simple_timers, i)
end
end
end
Events.OnTickEvenPaused.Add(timerUpdate)
function timer:Remove(name)
local t = self.Timers[name]
if not t then return false end
self.Timers[name] = nil
return true
end
function timer:Exists(name)
return self.Timers[name] and true or false
end
function timer:Start(name)
local t = self.Timers[name]
if not t then return false end
t.Repetitions = t.StartRepetitions
t.LastFuncTime = os_time()
t.Paused = false
t.PausedTime = nil
return true
end
function timer:Pause(name)
local t = self.Timers[name]
if not t then return false end
if t.Paused then return false end
t.Paused = true
t.PausedTime = os_time()
return true
end
function timer:UnPause(name)
local t = self.Timers[name]
if not t then return false end
if not t.Paused then return false end
t.Paused = false
return true
end
timer.Resume = timer.UnPause
function timer:Toggle(name)
local t = self.Timers[name]
if not t then return false end
t.Paused = not t.Paused
return true
end
function timer:TimeLeft(name)
local t = self.Timers[name]
if not t then return end
if t.Paused then
return (t.Repetitions - 1) * t.Delay + (t.LastFuncTime + t.Delay - t.PausedTime)
else
return (t.Repetitions - 1) * t.Delay + (t.LastFuncTime + t.Delay - os_time())
end
end
function timer:NextTimeLeft(name)
local t = self.Timers[name]
if not t then return end
if t.Paused then
return t.LastFuncTime + t.Delay - t.PausedTime
else
return t.LastFuncTime + t.Delay - os_time()
end
end
function timer:RepsLeft(name)
local t = self.Timers[name]
return t and t.Repetitions
end

View File

@@ -24,8 +24,6 @@ function ServerDataHandler.AddTable(key, table)
--TOC_DEBUG.printTable(table) --TOC_DEBUG.printTable(table)
-- Set that the data has been modified and it's updated on the server -- Set that the data has been modified and it's updated on the server
table.isUpdateFromServer = true -- FIX this is useless as of now
ModData.add(key, table) -- Add it to the server mod data ModData.add(key, table) -- Add it to the server mod data
ServerDataHandler.modData[key] = table ServerDataHandler.modData[key] = table

View File

@@ -1,5 +1,6 @@
require("TOC/Debug") require("TOC/Debug")
require("NPCs/BodyLocations") require("NPCs/BodyLocations")
local StaticData = require("TOC/StaticData")
local BodyLocationsAPI = {} local BodyLocationsAPI = {}
local function customGetVal(obj, int) return getClassFieldVal(obj, getClassField(obj, int)) end local function customGetVal(obj, int) return getClassFieldVal(obj, getClassField(obj, int)) end
@@ -8,6 +9,8 @@ local group = BodyLocations.getGroup("Human")
---@type ArrayList ---@type ArrayList
local list = customGetVal(group, 1) local list = customGetVal(group, 1)
-- TODO Not sure if this method actually works as intende with b42, but for our use case it's fine...
---@param toRelocateOrCreate string ---@param toRelocateOrCreate string
---@param locationElement string ---@param locationElement string
---@param afterBoolean boolean ---@param afterBoolean boolean
@@ -19,7 +22,15 @@ function BodyLocationsAPI.MoveOrCreateBeforeOrAfter(toRelocateOrCreate, location
if itemToMoveTo ~= nil then if itemToMoveTo ~= nil then
-- Check type of arg 1 == string - if not, error out. -- Check type of arg 1 == string - if not, error out.
if type(toRelocateOrCreate) ~= "string" then error("Argument 1 is not of type string. Please re-check!", 2) end if type(toRelocateOrCreate) ~= "string" then error("Argument 1 is not of type string. Please re-check!", 2) end
local curItem = group:getOrCreateLocation(toRelocateOrCreate) -- get current item - or create
local curItem
if StaticData.COMPAT_42 then
curItem = BodyLocation.new(group, toRelocateOrCreate) -- create new item
group:getAllLocations():add(curItem) -- add to the list
else
curItem = group:getOrCreateLocation(toRelocateOrCreate) -- get current item - or create
end
list:remove(curItem) -- remove from the list list:remove(curItem) -- remove from the list
local index = group:indexOf(locationElement) -- get current index after removal of the location to move to local index = group:indexOf(locationElement) -- get current index after removal of the location to move to
if afterBoolean then index = index + 1 end -- if we want it after it, we increase the index to move to by one if afterBoolean then index = index + 1 end -- if we want it after it, we increase the index to move to by one
@@ -43,13 +54,15 @@ function TestBodyLocations()
print(bl:getId()) print(bl:getId())
end end
end end
-- MultiItem causes a ton of issues... fucking hell -- MultiItem causes a ton of issues... fucking hell
BodyLocationsAPI.MoveOrCreateBeforeOrAfter("TOC_Arm", "FullTop", true) -- BodyLocationsAPI.MoveOrCreateBeforeOrAfter("TOC_Arm", "Shirt", true)
group:setMultiItem("TOC_Arm", true) -- group:setMultiItem("TOC_Arm", true)
local curItem = BodyLocation.new(group, "TOC_Arm") -- create new item
group:getAllLocations():add(curItem) -- add to the list
BodyLocationsAPI.MoveOrCreateBeforeOrAfter("TOC_ArmProst", "TOC_Arm", true) BodyLocationsAPI.MoveOrCreateBeforeOrAfter("TOC_ArmProst", "TOC_Arm", true)
group:setMultiItem("TOC_ArmProst", true) group:setMultiItem("TOC_ArmProst", true)

View File

@@ -0,0 +1,31 @@
-- instead of relying on local to save og methods, we save them in a table here that we can use later.
---@class OverridenMethodsArchive
local OverridenMethodsArchive = {}
OverridenMethodsArchive.methods = {}
-- Save an original method, if it wasn't already saved and returns it to be used in common
function OverridenMethodsArchive.Save(methodName, method)
if not OverridenMethodsArchive.methods[methodName] then
OverridenMethodsArchive.methods[methodName] = method
TOC_DEBUG.print("Saved method " .. methodName)
end
return method
end
-- Get the original method
function OverridenMethodsArchive.Get(methodName)
--TOC_DEBUG.print("Getting og method " .. methodName)
--TOC_DEBUG.print("OverridenMethodsArchive.list[methodName] = " .. tostring(OverridenMethodsArchive.methods[methodName]))
--TOC_DEBUG.print(methodName)
--TOC_DEBUG.print(OverridenMethodsArchive.methods[methodName])
return OverridenMethodsArchive.methods[methodName]
end
return OverridenMethodsArchive

View File

@@ -2,7 +2,7 @@
---@alias limbsTable {Hand_L : partDataType, ForeArm_L : partDataType, UpperArm_L : partDataType, Hand_R : partDataType, ForeArm_R : partDataType, UpperArm_R : partDataType } ---@alias limbsTable {Hand_L : partDataType, ForeArm_L : partDataType, UpperArm_L : partDataType, Hand_R : partDataType, ForeArm_R : partDataType, UpperArm_R : partDataType }
---@alias prosthesisData {isProstEquipped : boolean, prostFactor : number } ---@alias prosthesisData {isProstEquipped : boolean, prostFactor : number }
---@alias prosthesesTable {Top_L : prosthesisData, Top_R : prosthesisData } -- TODO add Bottom_L and Bottom_R ---@alias prosthesesTable {Top_L : prosthesisData, Top_R : prosthesisData } -- TODO add Bottom_L and Bottom_R
---@alias tocModDataType { limbs : limbsTable, prostheses : prosthesesTable, isIgnoredPartInfected : boolean, isAnyLimbCut : boolean, isUpdateFromServer : boolean, isInitializing : boolean} ---@alias tocModDataType { limbs : limbsTable, prostheses : prosthesesTable, isIgnoredPartInfected : boolean, isAnyLimbCut : boolean}
--------------------------- ---------------------------
@@ -21,6 +21,10 @@ local StaticData = {}
---Mod name, used to setup Global Mod Data and various stuff ---Mod name, used to setup Global Mod Data and various stuff
StaticData.MOD_NAME = "TOC" StaticData.MOD_NAME = "TOC"
-- Game version, used to correct some stuff instead of relying on versioned folders
StaticData.COMPAT_42 = luautils.stringStarts(getGameVersion(), "42")
------------------------- -------------------------
--* Base --* Base
@@ -276,8 +280,17 @@ StaticData.AMPUTATION_CLOTHING_ITEM_BASE = "TOC.Amputation_"
------------------ ------------------
--* Items check --* Items check
local sawObj = InventoryItemFactory.CreateItem("Base.Saw") local sawObj
local gardenSawObj = InventoryItemFactory.CreateItem("Base.GardenSaw") local gardenSawObj
if StaticData.COMPAT_42 then
sawObj = instanceItem("Base.Saw")
gardenSawObj = instanceItem("Base.GardenSaw")
else
sawObj = InventoryItemFactory.CreateItem("Base.Saw")
gardenSawObj = InventoryItemFactory.CreateItem("Base.GardenSaw")
end
StaticData.SAWS_NAMES_IND_STR = { StaticData.SAWS_NAMES_IND_STR = {
saw = sawObj:getName(), saw = sawObj:getName(),

View File

@@ -19,8 +19,6 @@ end
local function SetupTraits() local function SetupTraits()
-- Perks.Left_Hand is defined in perks.txt
local traitsTable = { local traitsTable = {
[1] = TraitFactory.addTrait(TRAITS.Amputee_Hand, GetTraitText(TRAITS.Amputee_Hand), -8, GetTraitDesc(TRAITS.Amputee_Hand), false, false), [1] = TraitFactory.addTrait(TRAITS.Amputee_Hand, GetTraitText(TRAITS.Amputee_Hand), -8, GetTraitDesc(TRAITS.Amputee_Hand), false, false),
[2] = TraitFactory.addTrait(TRAITS.Amputee_ForeArm, GetTraitText(TRAITS.Amputee_ForeArm), -10, GetTraitDesc(TRAITS.Amputee_ForeArm), false, false), [2] = TraitFactory.addTrait(TRAITS.Amputee_ForeArm, GetTraitText(TRAITS.Amputee_ForeArm), -10, GetTraitDesc(TRAITS.Amputee_ForeArm), false, false),
@@ -32,7 +30,7 @@ local function SetupTraits()
---@type Trait ---@type Trait
local t = traitsTable[i] local t = traitsTable[i]
---@diagnostic disable-next-line: undefined-field ---@diagnostic disable-next-line: undefined-field
t:addXPBoost(Perks.Left_Hand, 4) t:addXPBoost(Perks.Side_L, 4)
t:addXPBoost(Perks.Fitness, -1) t:addXPBoost(Perks.Fitness, -1)
t:addXPBoost(Perks.Strength, -1) t:addXPBoost(Perks.Strength, -1)
end end

View File

@@ -1,4 +1,7 @@
IG_UI_DE = { IG_UI_DE = {
IGUI_Yes = "Ja",
IGUI_No = "Nein",
IGUI_perks_Amputations = "Amputationen", IGUI_perks_Amputations = "Amputationen",
IGUI_perks_Side_R = "Rechte Seite", IGUI_perks_Side_R = "Rechte Seite",
IGUI_perks_Side_L = "Linke Seite", IGUI_perks_Side_L = "Linke Seite",

View File

@@ -1,9 +1,14 @@
IG_UI_EN = { IG_UI_EN = {
IGUI_Yes = "Yes",
IGUI_No = "No",
IGUI_perks_Amputations = "Amputations", IGUI_perks_Amputations = "Amputations",
IGUI_perks_Side_R = "Right Side", IGUI_perks_Side_R = "Right Side",
IGUI_perks_Right Side_Description = "Familiarity with amputations on the right side of your body",
IGUI_perks_Side_L = "Left Side", IGUI_perks_Side_L = "Left Side",
IGUI_perks_Prosthesis = "Prosthesis", IGUI_perks_Left Side_Description = "Familiarity with amputations on the left side of your body",
IGUI_perks_ProstFamiliarity= "Familiarity", IGUI_perks_Prosthesis = "Prosthesis Familiarity",
IGUI_perks_Prosthesis Familiarity_Description = "Familiarity with prosthetic limbs",
IGUI_ItemCat_Prosthesis = "Prosthesis", IGUI_ItemCat_Prosthesis = "Prosthesis",
IGUI_ItemCat_Surgery = "Surgery", IGUI_ItemCat_Surgery = "Surgery",

View File

@@ -0,0 +1,21 @@
IG_UI_FR = {
IGUI_Yes = "Oui",
IGUI_No = "Non",
IGUI_perks_Amputations = "Amputations",
IGUI_perks_Side_R = "C<>t<EFBFBD> droit",
IGUI_perks_Side_L = "C<>t<EFBFBD> gauche",
IGUI_perks_Prosthesis = "Proth<74>se",
IGUI_perks_ProstFamiliarity = "Familiarit<69>",
IGUI_ItemCat_Prosthesis = "Proth<74>se",
IGUI_ItemCat_Surgery = "Chirurgie",
IGUI_ItemCat_Amputation = "Amputation",
IGUI_HealthPanel_Cicatrization = "Cicatrisation",
IGUI_HealthPanel_Cicatrized = "Cicatris<69>",
IGUI_HealthPanel_Cauterized = "Caut<75>ris<69>",
IGUI_HealthPanel_WoundDirtyness = "Salet<65> de la plaie",
IGUI_HealthPanel_ProstEquipped = "Proth<74>se <20>quip<69>e",
}

View File

@@ -1,4 +1,7 @@
IG_UI_IT = { IG_UI_IT = {
IGUI_Yes = "Si",
IGUI_No = "No",
IGUI_perks_Amputations = "Amputazioni", IGUI_perks_Amputations = "Amputazioni",
IGUI_perks_Side_R = "Parte destra", IGUI_perks_Side_R = "Parte destra",
IGUI_perks_Side_L = "Parte sinistra", IGUI_perks_Side_L = "Parte sinistra",

Some files were not shown because too many files have changed in this diff Show More