Compare commits
120 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
68605ddb35 | ||
|
|
132ce24328 | ||
|
|
4af127196c | ||
|
|
39bccaf895 | ||
|
|
54c5958715 | ||
|
|
6b79ebf003 | ||
|
|
75d5cb180d | ||
|
|
245f81be26 | ||
|
|
1f950e0663 | ||
|
|
aecb5448ea | ||
|
|
c02ac7dacc | ||
|
|
332e02d9fd | ||
|
|
a2b3db6793 | ||
|
|
6883c81322 | ||
|
|
600c55f5f8 | ||
|
|
bf20aec94f | ||
|
|
26c269e8ba | ||
|
|
db42feed35 | ||
|
|
10f97cffa1 | ||
|
|
22e6621300 | ||
|
|
4d2b62e4a1 | ||
|
|
dd0d48cd08 | ||
|
|
2de512b447 | ||
|
|
1765d82ad9 | ||
|
|
c52cca09f1 | ||
|
|
545d5c7573 | ||
|
|
99d0847caa | ||
|
|
3b7fe2ec58 | ||
|
|
92fc80095d | ||
|
|
751e36cba7 | ||
|
|
487e616801 | ||
|
|
d5915cd287 | ||
|
|
d1f63ab55f | ||
|
|
857515576e | ||
|
|
69c6177be5 | ||
|
|
38fa63324c | ||
|
|
940f5486aa | ||
|
|
11622795e1 | ||
|
|
cb7603feea | ||
|
|
7b5e8e15d5 | ||
|
|
9a74710c1e | ||
|
|
3f7bf56be2 | ||
|
|
501c2fbabd | ||
|
|
3dad820014 | ||
|
|
2f82021b5d | ||
|
|
a3287bb2bc | ||
|
|
6c82f1a96f | ||
|
|
f2446c0781 | ||
|
|
4d6ee68054 | ||
|
|
854238ef98 | ||
|
|
2b41745a05 | ||
|
|
c2e15151a6 | ||
|
|
b25f52a40d | ||
|
|
145ec33620 | ||
|
|
307e19fd52 | ||
|
|
9eb9ea0263 | ||
|
|
f8fc8e7f60 | ||
|
|
3d1cfba85c | ||
|
|
1f6fc63f46 | ||
|
|
3931c0ed4d | ||
|
|
74eb7763cf | ||
|
|
e0e65c022f | ||
|
|
574526aca0 | ||
|
|
29f21decb4 | ||
|
|
b70dd619a4 | ||
|
|
0d5814dad1 | ||
|
|
5f64ead354 | ||
|
|
80c8b22faa | ||
|
|
696edc1f1d | ||
|
|
a1336c8d2e | ||
|
|
1187f1a1b6 | ||
|
|
dc921e4c04 | ||
|
|
bff6a2d4d6 | ||
|
|
36c3418a3e | ||
|
|
a7e32bc69b | ||
|
|
139ad5828a | ||
|
|
1636ca7e13 | ||
|
|
46a8ddc207 | ||
|
|
26e0324f4a | ||
|
|
c1faeeaabf | ||
|
|
a93c8a56bb | ||
|
|
b33cee7271 | ||
|
|
6e68e12b60 | ||
|
|
013f852e7e | ||
|
|
99dbaea143 | ||
|
|
a09a1520a1 | ||
|
|
a7a064119d | ||
|
|
6458988cc8 | ||
|
|
9b1876b235 | ||
|
|
0d9ee4203c | ||
|
|
2ea03601f5 | ||
|
|
3d4a54418c | ||
|
|
ba4f161122 | ||
|
|
17718cbbca | ||
|
|
f9ad597d2b | ||
|
|
c8b6a8c5ed | ||
|
|
df8591b1ef | ||
|
|
9478e0faa1 | ||
|
|
91a6eb7763 | ||
|
|
d512f0ba81 | ||
|
|
31995965f9 | ||
|
|
d35840d825 | ||
|
|
e270b4f73b | ||
|
|
1a754f4012 | ||
|
|
4757d9dfa8 | ||
|
|
74bb34bbc8 | ||
|
|
1b235ebaa4 | ||
|
|
44d486dfeb | ||
|
|
5cc982188a | ||
|
|
aadbe02df4 | ||
|
|
20bed84910 | ||
|
|
fc3113f243 | ||
|
|
be368738ba | ||
|
|
4209f690a8 | ||
|
|
a3a2614124 | ||
|
|
50f6db9344 | ||
|
|
17d554d269 | ||
|
|
1bef713de5 | ||
|
|
beee6f409c | ||
|
|
540f510eb0 |
24
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
24
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
---
|
||||||
|
name: Bug report
|
||||||
|
about: Create a report to help us improve
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: ZioPao
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Describe the bug**
|
||||||
|
A clear and concise description of what the bug is.
|
||||||
|
|
||||||
|
**To Reproduce**
|
||||||
|
Steps to reproduce the behavior:
|
||||||
|
1. Go to '...'
|
||||||
|
2. Click on '....'
|
||||||
|
3. Scroll down to '....'
|
||||||
|
4. See error
|
||||||
|
|
||||||
|
**Logs**
|
||||||
|
Please upload your game logs too. Server logs are useful too.
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context about the problem here.
|
||||||
5
.vscode/settings.json
vendored
5
.vscode/settings.json
vendored
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"todo-tree.tree.scanMode": "workspace",
|
"todo-tree.tree.scanMode": "workspace",
|
||||||
|
"mod_id": "3236152598",
|
||||||
"zomboid_user_folder": "C:/Users/picch/Zomboid",
|
"zomboid_user_folder": "C:/Users/picch/Zomboid",
|
||||||
"zomboid_folder": "E:\\Steam\\steamapps\\common\\ProjectZomboid",
|
"zomboid_folder": "E:\\Steam\\steamapps\\common\\ProjectZomboid",
|
||||||
"zomboid_server_folder": "E:\\Steam\\steamapps\\common\\Project Zomboid Dedicated Server",
|
"zomboid_server_folder": "E:\\Steam\\steamapps\\common\\Project Zomboid Dedicated Server",
|
||||||
@@ -8,4 +9,8 @@
|
|||||||
"zombie",
|
"zombie",
|
||||||
"_"
|
"_"
|
||||||
],
|
],
|
||||||
|
"Lua.format.defaultConfig": {
|
||||||
|
"indent_style": "space",
|
||||||
|
"indent_size": "2"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
15
.vscode/tasks.json
vendored
15
.vscode/tasks.json
vendored
@@ -9,6 +9,12 @@
|
|||||||
"options": {"statusbar": {"label": "$(combine) Assemble Mod"}},
|
"options": {"statusbar": {"label": "$(combine) Assemble Mod"}},
|
||||||
"command": "python ${config:zomboid_user_folder}/PaosCrap/make_workshop_pack.py picch ${workspaceFolderBasename}",
|
"command": "python ${config:zomboid_user_folder}/PaosCrap/make_workshop_pack.py picch ${workspaceFolderBasename}",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"label": "Bump Mod Version",
|
||||||
|
"type": "shell",
|
||||||
|
"options": {"statusbar": {"label": "$(arrow-up) Bump Mod Version"}},
|
||||||
|
"command": "python ${config:zomboid_user_folder}/PaosCrap/bump_version.py media/lua/client/TOC/Main.lua",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"label": "Run Zomboid Debug No Steam",
|
"label": "Run Zomboid Debug No Steam",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
@@ -59,6 +65,15 @@
|
|||||||
"problemMatcher": [
|
"problemMatcher": [
|
||||||
"$eslint-stylish"
|
"$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"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -12,8 +12,6 @@ Wait until you succumb to the virus or take matters into your hands. Cut off tha
|
|||||||
|
|
||||||
This version of **The Only Cure** has been rebuilt from scratch to support future additions and to feel as close as possible as a vanilla mechanic.
|
This version of **The Only Cure** has been rebuilt from scratch to support future additions and to feel as close as possible as a vanilla mechanic.
|
||||||
|
|
||||||
**The older version will be delisted shortly and it will not be supported anymore.**
|
|
||||||
|
|
||||||
Supports **Single Player** and **Multiplayer**!
|
Supports **Single Player** and **Multiplayer**!
|
||||||
|
|
||||||
# Setup
|
# Setup
|
||||||
|
|||||||
@@ -1,56 +0,0 @@
|
|||||||
0.9.15
|
|
||||||
- Hotfix to sound not stopping when performing an amputation on another player
|
|
||||||
|
|
||||||
0.9.14
|
|
||||||
- Optimizations
|
|
||||||
- New icon for the mod
|
|
||||||
- Added a dirtyness malus for cicatrization, you'll have to keep your wound clean while it's healing (wash it you animal)
|
|
||||||
- When trying to equip a prosthesis from the inventory you'll get a message to let you know that you're doing it wrong
|
|
||||||
- Added explicit support to Left Is Right, making it work a lot better when you've got an amputated right limb
|
|
||||||
|
|
||||||
|
|
||||||
0.9.13
|
|
||||||
- Some little optimizations
|
|
||||||
- Fixed a bug that made Fancy Handwork compat not work as intended
|
|
||||||
|
|
||||||
0.9.12
|
|
||||||
- Fixed traits icons
|
|
||||||
- Some cleaning to the code
|
|
||||||
|
|
||||||
0.9.11
|
|
||||||
- Hotfix to cicatrization visuals
|
|
||||||
|
|
||||||
0.9.10
|
|
||||||
- Modified textures once again
|
|
||||||
|
|
||||||
|
|
||||||
0.9.9
|
|
||||||
- Modified textures for amputations
|
|
||||||
- Fixed a bug that caused some problems when amputating an already amputated limb
|
|
||||||
|
|
||||||
0.9.8
|
|
||||||
- New textures for amputations
|
|
||||||
- When cicatrized, an amputation will not be bloody anymore (visual thing only)
|
|
||||||
|
|
||||||
0.9.7
|
|
||||||
- Now amputations should spawn in every case, damn hairs. Thanks Dev for the tip!
|
|
||||||
|
|
||||||
|
|
||||||
0.9.6
|
|
||||||
- Fixed a bug when handling zombie hitting amputated limbs
|
|
||||||
- Fixed sound looping incessantly after amputating a limb
|
|
||||||
- Changed how phantom pain occurs
|
|
||||||
- Fixes to new hook models
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
0.9.5
|
|
||||||
- No more Right Click menu. You'll have to use the TOC Menu from the Medical Check, except for Cheats
|
|
||||||
- Fixes to how amputations are handled
|
|
||||||
before and after
|
|
||||||
- Compatibility fixes with older versions
|
|
||||||
- Various fixes to Traits
|
|
||||||
- New heavily WIP models for metal and wooden hooks
|
|
||||||
- Readded sounds during amputations
|
|
||||||
- Fixed banages not getting applied after an amputation when they were in the player's inventory
|
|
||||||
32
dev_stuff/ci/bump_minor_version.sh
Normal file
32
dev_stuff/ci/bump_minor_version.sh
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Open the Main.lua file in read mode
|
||||||
|
while IFS= read -r line; do
|
||||||
|
# Check if the current line contains _version
|
||||||
|
if [[ $line == *_version* ]]; then
|
||||||
|
# Get the current version number from the line
|
||||||
|
current_version=$(echo $line | cut -d '"' -f 2)
|
||||||
|
|
||||||
|
# Increment the version number by 1
|
||||||
|
new_version=$((current_version + 1))
|
||||||
|
|
||||||
|
# Replace the old version number with the new one in the file
|
||||||
|
echo "$line" | sed "s/$current_version/$new_version/g" > media/lua/client/Main.lua
|
||||||
|
fi
|
||||||
|
done < media/lua/client/Main.lua
|
||||||
|
|
||||||
|
|
||||||
|
# Open the mod.info file in read mode
|
||||||
|
while IFS= read -r line; do
|
||||||
|
# Check if the current line contains modversion
|
||||||
|
if [[ $line == *modversion* ]]; then
|
||||||
|
# Get the current version number from the line
|
||||||
|
current_version=$(echo $line | cut -d '"' -f 2)
|
||||||
|
|
||||||
|
# Increment the version number by 1
|
||||||
|
new_version=$((current_version + 1))
|
||||||
|
|
||||||
|
# Replace the old version number with the new one in the file
|
||||||
|
echo "$line" | sed "s/$current_version/$new_version/g" > mod.info
|
||||||
|
fi
|
||||||
|
done < mod.info
|
||||||
BIN
dev_stuff/logos/TOC_LOGOv2_ByChuck_169_with_title.png
Normal file
BIN
dev_stuff/logos/TOC_LOGOv2_ByChuck_169_with_title.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 540 KiB |
@@ -6,9 +6,9 @@ Wait until you succumb to the virus or take matters into your hands. Cut off tha
|
|||||||
|
|
||||||
This version of [b]The Only Cure[/b] has been rebuilt from scratch to support future additions and to feel as close as possible as a vanilla mechanic.
|
This version of [b]The Only Cure[/b] has been rebuilt from scratch to support future additions and to feel as close as possible as a vanilla mechanic.
|
||||||
|
|
||||||
|
[b]If you're using an older version of The Only Cure and want to switch with this, you're gonna need to create a new character\save to prevent issues.[/b]
|
||||||
[b]The older version will be delisted shortly and it will not be supported anymore.[/b]
|
[b]The older version will be delisted shortly and it will not be supported anymore.[/b]
|
||||||
|
[h1]Supports [b]Single Player[/b] and [b]Multiplayer[/b]. Host Mode is currently [b]UNSUPPORTED![/b][/h1]
|
||||||
Supports [b]Single Player[/b] and [b]Multiplayer[/b]!
|
|
||||||
|
|
||||||
[h1]Setup[/h1]
|
[h1]Setup[/h1]
|
||||||
Use it with the following mods for the intended experience:
|
Use it with the following mods for the intended experience:
|
||||||
@@ -17,6 +17,8 @@ Use it with the following mods for the intended experience:
|
|||||||
[*] [url=https://steamcommunity.com/sharedfiles/filedetails/?id=2934621024]Brutal Handwork[/url]
|
[*] [url=https://steamcommunity.com/sharedfiles/filedetails/?id=2934621024]Brutal Handwork[/url]
|
||||||
[/list]
|
[/list]
|
||||||
|
|
||||||
|
Place them [b]BEFORE[/b] The Only Cure in your mod list!
|
||||||
|
|
||||||
[hr][/hr]
|
[hr][/hr]
|
||||||
|
|
||||||
[h1]Quick guide[/h1]
|
[h1]Quick guide[/h1]
|
||||||
@@ -74,6 +76,10 @@ Got any issues or found some pesky bugs? Report them on GitHub!
|
|||||||
[th]dhert[/th]
|
[th]dhert[/th]
|
||||||
[th]Compatibility API[/th]
|
[th]Compatibility API[/th]
|
||||||
[/tr]
|
[/tr]
|
||||||
|
[tr]
|
||||||
|
[th]JCloudJalix[/th]
|
||||||
|
[th]German translation[/th]
|
||||||
|
[/tr]
|
||||||
[/table]
|
[/table]
|
||||||
|
|
||||||
[hr][/hr]
|
[hr][/hr]
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
local CommandsData = require("TOC/CommandsData")
|
local CommandsData = require("TOC/CommandsData")
|
||||||
|
local ClientRelayCommands = require("TOC/ClientRelayCommands")
|
||||||
local StaticData = require("TOC/StaticData")
|
local StaticData = require("TOC/StaticData")
|
||||||
local DataController = require("TOC/Controllers/DataController")
|
local DataController = require("TOC/Controllers/DataController")
|
||||||
-------------------
|
-------------------
|
||||||
@@ -7,7 +8,8 @@ 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 isAdmin() 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
|
||||||
@@ -40,9 +42,35 @@ local function AddAdminTocOptions(playerNum, context, worldobjects)
|
|||||||
context:addSubMenu(option, subMenu)
|
context:addSubMenu(option, subMenu)
|
||||||
|
|
||||||
subMenu:addOption(getText("ContextMenu_Admin_ResetTOC"), nil, function()
|
subMenu:addOption(getText("ContextMenu_Admin_ResetTOC"), nil, function()
|
||||||
|
if isClient() then
|
||||||
sendClientCommand(CommandsData.modules.TOC_RELAY, CommandsData.server.Relay.RelayExecuteInitialization,
|
sendClientCommand(CommandsData.modules.TOC_RELAY, CommandsData.server.Relay.RelayExecuteInitialization,
|
||||||
{ patientNum = clickedPlayerNum })
|
{ patientNum = clickedPlayerNum })
|
||||||
|
else
|
||||||
|
-- TODO ugly
|
||||||
|
ClientRelayCommands.ReceiveExecuteInitialization()
|
||||||
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
-- Force amputation
|
||||||
|
local forceAmpOption = subMenu:addOption(getText("ContextMenu_Admin_ForceAmputation"), nil, nil)
|
||||||
|
local forceAmpSubMenu = ISContextMenu:getNew(subMenu)
|
||||||
|
context:addSubMenu(forceAmpOption, forceAmpSubMenu)
|
||||||
|
|
||||||
|
for i = 1, #StaticData.LIMBS_STR do
|
||||||
|
local limbName = StaticData.LIMBS_STR[i]
|
||||||
|
local limbTranslatedName = getText("ContextMenu_Limb_" .. limbName)
|
||||||
|
|
||||||
|
forceAmpSubMenu:addOption(limbTranslatedName, nil, function()
|
||||||
|
if isClient() then
|
||||||
|
sendClientCommand(CommandsData.modules.TOC_RELAY, CommandsData.server.Relay.RelayForcedAmputation,
|
||||||
|
{ patientNum = clickedPlayerNum, limbName = limbName })
|
||||||
|
else
|
||||||
|
ClientRelayCommands.ReceiveExecuteAmputationAction({surgeonNum=clickedPlayerNum, limbName=limbName, damagePlayer=false})
|
||||||
|
-- todo ugly
|
||||||
|
end
|
||||||
|
|
||||||
|
end)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
Events.OnFillWorldObjectContextMenu.Add(AddAdminTocOptions)
|
Events.OnFillWorldObjectContextMenu.Add(AddAdminTocOptions)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
local CommandsData = require("TOC/CommandsData")
|
local CommandsData = require("TOC/CommandsData")
|
||||||
local AmputationHandler = require("TOC/Handlers/AmputationHandler")
|
local AmputationHandler = require("TOC/Handlers/AmputationHandler")
|
||||||
|
local DataController = require("TOC/Controllers/DataController")
|
||||||
--------------------------------------------
|
--------------------------------------------
|
||||||
|
|
||||||
local ClientRelayCommands = {}
|
local ClientRelayCommands = {}
|
||||||
@@ -25,8 +26,14 @@ end
|
|||||||
---Creates a new handler and execute the amputation function on this client
|
---Creates a new handler and execute the amputation function on this client
|
||||||
---@param args receiveExecuteAmputationActionParams
|
---@param args receiveExecuteAmputationActionParams
|
||||||
function ClientRelayCommands.ReceiveExecuteAmputationAction(args)
|
function ClientRelayCommands.ReceiveExecuteAmputationAction(args)
|
||||||
|
|
||||||
|
-- Check if player already doesn't have that limb or it's a dependant limb.
|
||||||
|
-- Mostly a check for admin forced amputations more than anything else, since this case is handled in the GUI already.
|
||||||
|
local dcInst = DataController.GetInstance()
|
||||||
|
if dcInst:getIsCut(args.limbName) then return end
|
||||||
|
|
||||||
local handler = InitAmputationHandler(args.limbName, args.surgeonNum)
|
local handler = InitAmputationHandler(args.limbName, args.surgeonNum)
|
||||||
handler:execute(true)
|
handler:execute(args.damagePlayer)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@@ -46,6 +53,15 @@ function ClientRelayCommands.ReceiveExecuteInitialization()
|
|||||||
LocalPlayerController.InitializePlayer(true)
|
LocalPlayerController.InitializePlayer(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---Creates a new handler and execute the amputation function on this client
|
||||||
|
---@param args receiveForcedCicatrizationParams
|
||||||
|
function ClientRelayCommands.ReceiveForcedCicatrization(args)
|
||||||
|
local dcInst = DataController.GetInstance()
|
||||||
|
--dcInst:setCicatrizationTime(args.limbName, 1)
|
||||||
|
dcInst:setIsCicatrized(args.limbName, true)
|
||||||
|
dcInst:apply()
|
||||||
|
end
|
||||||
|
|
||||||
-------------------------
|
-------------------------
|
||||||
|
|
||||||
local function OnServerRelayCommand(module, command, args)
|
local function OnServerRelayCommand(module, command, args)
|
||||||
@@ -56,3 +72,6 @@ local function OnServerRelayCommand(module, command, args)
|
|||||||
end
|
end
|
||||||
|
|
||||||
Events.OnServerCommand.Add(OnServerRelayCommand)
|
Events.OnServerCommand.Add(OnServerRelayCommand)
|
||||||
|
|
||||||
|
-- TODO temporary
|
||||||
|
return ClientRelayCommands
|
||||||
@@ -26,7 +26,7 @@ end
|
|||||||
|
|
||||||
---Returns full name for the side, to be used with BodyLocations
|
---Returns full name for the side, to be used with BodyLocations
|
||||||
---@param side string
|
---@param side string
|
||||||
---@return string
|
---@return string?
|
||||||
function CommonMethods.GetSideFull(side)
|
function CommonMethods.GetSideFull(side)
|
||||||
if side == 'R' then
|
if side == 'R' then
|
||||||
return "Right"
|
return "Right"
|
||||||
|
|||||||
@@ -1,27 +1,19 @@
|
|||||||
|
|
||||||
|
---@class Compat
|
||||||
|
---@field handlers table<string, {fun : function, isActive : boolean}>
|
||||||
|
local Compat = {
|
||||||
|
handlers = {}
|
||||||
|
}
|
||||||
|
|
||||||
local function HandleModCompatibility()
|
--- Brutal hands has a TOC_COMPAT but its check is wrong and uses an old API.
|
||||||
|
function Compat.BrutalHandwork()
|
||||||
|
|
||||||
|
|
||||||
local activatedMods = getActivatedMods()
|
|
||||||
TOC_DEBUG.print("Checking for mods compatibility")
|
|
||||||
|
|
||||||
--[[
|
|
||||||
Brutal hands has a TOC_COMPAT but its check is wrong and uses an old API.
|
|
||||||
]]
|
|
||||||
if activatedMods:contains('BrutalHandwork') then
|
|
||||||
TOC_DEBUG.print("found BrutalHandwork, activating compat module")
|
|
||||||
BrutalHands = BrutalHands or {}
|
BrutalHands = BrutalHands or {}
|
||||||
BrutalHands.TOC = require("TOC/API")
|
BrutalHands.TOC = require("TOC/API")
|
||||||
end
|
|
||||||
|
|
||||||
--[[
|
end
|
||||||
Was handled inside old TOC
|
|
||||||
]]
|
|
||||||
if activatedMods:contains('FancyHandwork') then
|
|
||||||
TOC_DEBUG.print("found FancyHandwork, activating compat module")
|
|
||||||
|
|
||||||
|
--- Was handled inside old TOC
|
||||||
|
function Compat.FancyHandwork()
|
||||||
require("TimedActions/FHSwapHandsAction")
|
require("TimedActions/FHSwapHandsAction")
|
||||||
local og_FHSwapHandsAction_isValid = FHSwapHandsAction.isValid
|
local og_FHSwapHandsAction_isValid = FHSwapHandsAction.isValid
|
||||||
function FHSwapHandsAction:isValid()
|
function FHSwapHandsAction:isValid()
|
||||||
@@ -32,8 +24,52 @@ local function HandleModCompatibility()
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
Events.OnGameStart.Add(HandleModCompatibility)
|
|
||||||
|
|
||||||
|
function Compat.iMeds()
|
||||||
|
require("Component/Interface/Service/ContextMenu/Menu/HealthPanel/HealthPanelMenuInitializer")
|
||||||
|
-- placeholder, in case we need to do something more drastic with it.
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------
|
||||||
|
|
||||||
|
Compat.handlers = {
|
||||||
|
["BrutalHandwork"] = {
|
||||||
|
fun = Compat.BrutalHandwork,
|
||||||
|
isActive = false},
|
||||||
|
["FancyHandwork"] = {
|
||||||
|
fun = Compat.FancyHandwork,
|
||||||
|
isActive = false},
|
||||||
|
|
||||||
|
-- either or
|
||||||
|
['iMeds'] = {
|
||||||
|
fun = Compat.iMeds,
|
||||||
|
isActive = false},
|
||||||
|
['iMedsFixed'] = {
|
||||||
|
fun = Compat.iMeds,
|
||||||
|
isActive = false}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function Compat.RunModCompatibility()
|
||||||
|
local activatedMods = getActivatedMods()
|
||||||
|
TOC_DEBUG.print("Checking for mods compatibility")
|
||||||
|
|
||||||
|
for k, modCompatHandler in pairs(Compat.handlers) do
|
||||||
|
if activatedMods:contains(k) then
|
||||||
|
TOC_DEBUG.print("Found " .. k .. ", running compatibility handler")
|
||||||
|
modCompatHandler.fun()
|
||||||
|
modCompatHandler.isActive = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
Events.OnGameStart.Add(Compat.RunModCompatibility)
|
||||||
|
|
||||||
|
return Compat
|
||||||
@@ -57,6 +57,7 @@ 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 = {},
|
||||||
@@ -86,9 +87,17 @@ function DataController:setup(key)
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Add it to global mod data
|
-- Add it to client global mod data
|
||||||
ModData.add(key, self.tocData)
|
ModData.add(key, self.tocData)
|
||||||
|
|
||||||
|
-- Sync with the server
|
||||||
|
self:apply()
|
||||||
|
|
||||||
|
-- -- Disable lock
|
||||||
|
-- self.tocData.isInitializing = false
|
||||||
|
-- ModData.add(key, self.tocData)
|
||||||
|
|
||||||
|
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
|
||||||
@@ -100,7 +109,7 @@ function DataController:applyOnlineData(tocData)
|
|||||||
end
|
end
|
||||||
|
|
||||||
---@param key string
|
---@param key string
|
||||||
function DataController:loadLocalData(key)
|
function DataController:tryLoadLocalData(key)
|
||||||
self.tocData = ModData.get(key)
|
self.tocData = ModData.get(key)
|
||||||
|
|
||||||
--TOC_DEBUG.printTable(self.tocData)
|
--TOC_DEBUG.printTable(self.tocData)
|
||||||
@@ -368,11 +377,14 @@ end
|
|||||||
function DataController.ReceiveData(key, data)
|
function DataController.ReceiveData(key, data)
|
||||||
-- During startup the game can return Bob as the player username, adding a useless ModData table
|
-- During startup the game can return Bob as the player username, adding a useless ModData table
|
||||||
if key == "TOC_Bob" then return end
|
if key == "TOC_Bob" then return end
|
||||||
|
if not luautils.stringStarts(key, StaticData.MOD_NAME .. "_") then return end
|
||||||
|
|
||||||
|
|
||||||
TOC_DEBUG.print("ReceiveData for " .. key)
|
TOC_DEBUG.print("ReceiveData for " .. key)
|
||||||
if data == {} or data == nil then
|
|
||||||
error("Data is nil, new character or something is wrong")
|
-- if data == nil or data.limbs == nil then
|
||||||
end
|
-- TOC_DEBUG.print("Data is nil, new character or something is wrong")
|
||||||
|
-- end
|
||||||
|
|
||||||
-- Get DataController instance if there was none for that user and reapply the correct ModData table as a reference
|
-- Get DataController instance if there was none for that user and reapply the correct ModData table as a reference
|
||||||
local username = key:sub(5)
|
local username = key:sub(5)
|
||||||
@@ -387,22 +399,28 @@ function DataController.ReceiveData(key, data)
|
|||||||
-- TODO Add update from server scenario
|
-- TODO Add update from server scenario
|
||||||
|
|
||||||
if handler.isResetForced then
|
if handler.isResetForced then
|
||||||
|
TOC_DEBUG.print("Forced reset")
|
||||||
handler:setup(key)
|
handler:setup(key)
|
||||||
elseif data then
|
elseif data and data.limbs then
|
||||||
|
-- Let's validate that the data structure is actually valid to prevent issues
|
||||||
if data.isUpdateFromServer then
|
if data.isUpdateFromServer then
|
||||||
TOC_DEBUG.print("Update from the server")
|
TOC_DEBUG.print("Update from the server")
|
||||||
end
|
end
|
||||||
handler:applyOnlineData(data)
|
handler:applyOnlineData(data)
|
||||||
elseif username == getPlayer():getUsername() then
|
elseif username == getPlayer():getUsername() then
|
||||||
handler:loadLocalData(key)
|
TOC_DEBUG.print("Trying to load local data or no data is available")
|
||||||
|
handler:tryLoadLocalData(key)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
handler:setIsResetForced(false)
|
handler:setIsResetForced(false)
|
||||||
handler:setIsDataReady(true)
|
handler:setIsDataReady(true)
|
||||||
|
|
||||||
|
--TOC_DEBUG.print("Finished ReceiveData, triggering OnReceivedTocData")
|
||||||
triggerEvent("OnReceivedTocData", handler.username)
|
triggerEvent("OnReceivedTocData", handler.username)
|
||||||
|
|
||||||
|
-- TODO We need an event to track if initialization has been finalized
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- if username == getPlayer():getUsername() and not handler.isResetForced then
|
-- if username == getPlayer():getUsername() and not handler.isResetForced then
|
||||||
@@ -434,7 +452,7 @@ Events.OnReceiveGlobalModData.Add(DataController.ReceiveData)
|
|||||||
--- SP Only initialization
|
--- SP Only initialization
|
||||||
---@param key string
|
---@param key string
|
||||||
function DataController:initSinglePlayer(key)
|
function DataController:initSinglePlayer(key)
|
||||||
self:loadLocalData(key)
|
self:tryLoadLocalData(key)
|
||||||
if self.tocData == nil or self.isResetForced then
|
if self.tocData == nil or self.isResetForced then
|
||||||
self:setup(key)
|
self:setup(key)
|
||||||
end
|
end
|
||||||
@@ -462,4 +480,12 @@ function DataController.GetInstance(username)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function DataController.DestroyInstance(username)
|
||||||
|
if DataController.instances[username] ~= nil then
|
||||||
|
DataController.instances[username] = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
return DataController
|
return DataController
|
||||||
@@ -17,10 +17,12 @@ ItemsController.Player = {}
|
|||||||
---@return number
|
---@return number
|
||||||
---@private
|
---@private
|
||||||
function ItemsController.Player.GetAmputationTexturesIndex(playerObj, isCicatrized)
|
function ItemsController.Player.GetAmputationTexturesIndex(playerObj, isCicatrized)
|
||||||
|
-- FIX Broken
|
||||||
local textureString = playerObj:getHumanVisual():getSkinTexture()
|
local textureString = playerObj:getHumanVisual():getSkinTexture()
|
||||||
local isHairy = textureString:sub(-1) == "a"
|
local isHairy = textureString:sub(-1) == "a"
|
||||||
|
|
||||||
local matchedIndex = tonumber(textureString:match("%d$")) or 0
|
local matchedIndex = tonumber(textureString:match("%d%d")) -- it must always be at least 1
|
||||||
|
TOC_DEBUG.print("Texture string: " .. tostring(textureString))
|
||||||
|
|
||||||
if isHairy then
|
if isHairy then
|
||||||
matchedIndex = matchedIndex + 5
|
matchedIndex = matchedIndex + 5
|
||||||
@@ -30,7 +32,7 @@ function ItemsController.Player.GetAmputationTexturesIndex(playerObj, isCicatriz
|
|||||||
matchedIndex = matchedIndex + (isHairy and 5 or 10) -- We add 5 is it's the texture, else 10
|
matchedIndex = matchedIndex + (isHairy and 5 or 10) -- We add 5 is it's the texture, else 10
|
||||||
end
|
end
|
||||||
|
|
||||||
TOC_DEBUG.print("isCicatrized= " .. tostring(isCicatrized))
|
TOC_DEBUG.print("isCicatrized = " .. tostring(isCicatrized))
|
||||||
TOC_DEBUG.print("Amputation Texture Index: " .. tostring(matchedIndex))
|
TOC_DEBUG.print("Amputation Texture Index: " .. tostring(matchedIndex))
|
||||||
return matchedIndex - 1
|
return matchedIndex - 1
|
||||||
end
|
end
|
||||||
@@ -154,6 +156,9 @@ function ItemsController.Zombie.SpawnAmputationItem(zombie, amputationFullType)
|
|||||||
-- Spawn the item too in the inventory to keep track of stuff this way. It's gonna get deleted when we reload the game
|
-- Spawn the item too in the inventory to keep track of stuff this way. It's gonna get deleted when we reload the game
|
||||||
local zombieInv = zombie:getInventory()
|
local zombieInv = zombie:getInventory()
|
||||||
zombieInv:AddItem(amputationFullType)
|
zombieInv:AddItem(amputationFullType)
|
||||||
|
|
||||||
|
|
||||||
|
-- TODO Remove objects in that part of the body to prevent items floating in mid air
|
||||||
end
|
end
|
||||||
|
|
||||||
function ItemsController.Zombie.GetAmputationTexturesIndex(zombie)
|
function ItemsController.Zombie.GetAmputationTexturesIndex(zombie)
|
||||||
|
|||||||
@@ -15,8 +15,12 @@ local StaticData = require("TOC/StaticData")
|
|||||||
-- a prosthesis on, that can trigger random bleeds.
|
-- a prosthesis on, that can trigger random bleeds.
|
||||||
|
|
||||||
local function CheckHandFeasibility(limbName)
|
local function CheckHandFeasibility(limbName)
|
||||||
|
TOC_DEBUG.print("Checking hand feasibility: " .. limbName)
|
||||||
local dcInst = DataController.GetInstance()
|
local dcInst = DataController.GetInstance()
|
||||||
return not dcInst:getIsCut(limbName) or dcInst:getIsProstEquipped(limbName)
|
|
||||||
|
local isFeasible = not dcInst:getIsCut(limbName) or dcInst:getIsProstEquipped(limbName)
|
||||||
|
TOC_DEBUG.print("isFeasible: " .. tostring(isFeasible))
|
||||||
|
return isFeasible
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@@ -28,26 +32,49 @@ function ISBaseTimedAction:adjustMaxTime(maxTime)
|
|||||||
local time = og_ISBaseTimedAction_adjustMaxTime(self, maxTime)
|
local time = og_ISBaseTimedAction_adjustMaxTime(self, maxTime)
|
||||||
|
|
||||||
-- 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 queue = ISTimedActionQueue.getTimedActionQueue(getPlayer())
|
local actionsQueue = ISTimedActionQueue.getTimedActionQueue(getPlayer())
|
||||||
if queue and queue.current and queue.current.skipTOC then return time end
|
|
||||||
|
if actionsQueue and actionsQueue.current and actionsQueue.skipTOC then
|
||||||
|
--TOC_DEBUG.print("Should skip TOC stuff")
|
||||||
|
return time
|
||||||
|
end
|
||||||
|
|
||||||
-- Action is valid, check if we have any cut limb and then modify maxTime
|
-- Action is valid, check if we have any cut limb and then modify maxTime
|
||||||
local dcInst = DataController.GetInstance()
|
local dcInst = DataController.GetInstance()
|
||||||
if time ~= -1 and dcInst and dcInst:getIsAnyLimbCut() then
|
if time ~= -1 and dcInst and dcInst:getIsAnyLimbCut() then
|
||||||
|
--TOC_DEBUG.print("Overriding adjustMaxTime")
|
||||||
local pl = getPlayer()
|
local pl = getPlayer()
|
||||||
local amputatedLimbs = CachedDataHandler.GetAmputatedLimbs(pl:getUsername())
|
local amputatedLimbs = CachedDataHandler.GetAmputatedLimbs(pl:getUsername())
|
||||||
|
|
||||||
for k, _ in pairs(amputatedLimbs) do
|
for k, _ in pairs(amputatedLimbs) do
|
||||||
local limbName = k
|
local limbName = k
|
||||||
--if dcInst:getIsCut(limbName) then
|
local perkAmp = Perks["Side_" .. CommonMethods.GetSide(limbName)]
|
||||||
local perk = Perks["Side_" .. CommonMethods.GetSide(limbName)]
|
local perkLevel = pl:getPerkLevel(perkAmp)
|
||||||
local perkLevel = pl:getPerkLevel(perk)
|
|
||||||
|
if dcInst:getIsProstEquipped(limbName) then
|
||||||
|
-- TODO We should separate this in multiple perks, since this is gonna be a generic familiarity and could make no actual sense
|
||||||
|
local perkProst = Perks["ProstFamiliarity"]
|
||||||
|
perkLevel = perkLevel + pl:getPerkLevel(perkProst)
|
||||||
|
end
|
||||||
|
|
||||||
local perkLevelScaled
|
local perkLevelScaled
|
||||||
if perkLevel ~= 0 then perkLevelScaled = perkLevel / 10 else perkLevelScaled = 0 end
|
if perkLevel ~= 0 then perkLevelScaled = perkLevel / 10 else perkLevelScaled = 0 end
|
||||||
time = time * (StaticData.LIMBS_TIME_MULTIPLIER_IND_NUM[limbName] - perkLevelScaled)
|
TOC_DEBUG.print("Perk Level: " .. tostring(perkLevel))
|
||||||
--end
|
TOC_DEBUG.print("OG time: " .. tostring(time))
|
||||||
|
|
||||||
|
-- Modified Time shouldn't EVER be lower compared to the og one.
|
||||||
|
local modifiedTime = time * (StaticData.LIMBS_TIME_MULTIPLIER_IND_NUM[limbName] - perkLevelScaled)
|
||||||
|
|
||||||
|
if modifiedTime >= time then
|
||||||
|
time = modifiedTime
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--TOC_DEBUG.print("Modified time: " .. tostring(time))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
--TOC_DEBUG.print("New time with amputations: " .. tostring(time))
|
||||||
return time
|
return time
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -59,22 +86,30 @@ function ISBaseTimedAction:perform()
|
|||||||
og_ISBaseTimedAction_perform(self)
|
og_ISBaseTimedAction_perform(self)
|
||||||
|
|
||||||
TOC_DEBUG.print("Running ISBaseTimedAction.perform override")
|
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() then return end
|
||||||
|
|
||||||
local amputatedLimbs = CachedDataHandler.GetAmputatedLimbs(LocalPlayerController.username)
|
local amputatedLimbs = CachedDataHandler.GetAmputatedLimbs(LocalPlayerController.username)
|
||||||
|
local xp = self.maxTime / 100
|
||||||
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], 1) -- TODO Make it dynamic
|
LocalPlayerController.playerObj:getXp():AddXP(Perks["Side_" .. side], xp)
|
||||||
if not dcInst:getIsCicatrized(limbName) and dcInst:getIsProstEquipped(limbName) then
|
if not dcInst:getIsCicatrized(limbName) and dcInst:getIsProstEquipped(limbName) then
|
||||||
TOC_DEBUG.print("Trying for bleed, player met the criteria")
|
TOC_DEBUG.print("Trying for bleed, player met the criteria")
|
||||||
LocalPlayerController.TryRandomBleed(self.character, limbName)
|
LocalPlayerController.TryRandomBleed(self.character, limbName)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- Level up prosthesis perk
|
||||||
|
if dcInst:getIsProstEquipped(limbName) then
|
||||||
|
LocalPlayerController.playerObj:getXp():AddXP(Perks["ProstFamiliarity"], xp)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -97,6 +132,10 @@ function ISEquipWeaponAction:isValid()
|
|||||||
local isPrimaryHandValid = CachedDataHandler.GetHandFeasibility(StaticData.SIDES_IND_STR.R)
|
local isPrimaryHandValid = CachedDataHandler.GetHandFeasibility(StaticData.SIDES_IND_STR.R)
|
||||||
local isSecondaryHandValid = CachedDataHandler.GetHandFeasibility(StaticData.SIDES_IND_STR.L)
|
local isSecondaryHandValid = CachedDataHandler.GetHandFeasibility(StaticData.SIDES_IND_STR.L)
|
||||||
-- Both hands are cut off, so it's impossible to equip in any way
|
-- Both hands are cut off, so it's impossible to equip in any way
|
||||||
|
|
||||||
|
--TOC_DEBUG.print("isPrimaryHandValid : " .. tostring(isPrimaryHandValid))
|
||||||
|
--TOC_DEBUG.print("isSecondaryHandValid : " .. tostring(isSecondaryHandValid))
|
||||||
|
|
||||||
if not isPrimaryHandValid and not isSecondaryHandValid then
|
if not isPrimaryHandValid and not isSecondaryHandValid then
|
||||||
isValid = false
|
isValid = false
|
||||||
end
|
end
|
||||||
@@ -105,8 +144,8 @@ function ISEquipWeaponAction:isValid()
|
|||||||
end
|
end
|
||||||
|
|
||||||
---A recreation of the original method, but with amputations in mind
|
---A recreation of the original method, but with amputations in mind
|
||||||
---@param dcInst DataController
|
function ISEquipWeaponAction:performWithAmputation()
|
||||||
function ISEquipWeaponAction:performWithAmputation(dcInst)
|
TOC_DEBUG.print("running ISEquipWeaponAction performWithAmputation")
|
||||||
local hand = nil
|
local hand = nil
|
||||||
local otherHand = nil
|
local otherHand = nil
|
||||||
local getMethodFirst = nil
|
local getMethodFirst = nil
|
||||||
@@ -130,6 +169,10 @@ function ISEquipWeaponAction:performWithAmputation(dcInst)
|
|||||||
setMethodSecond = self.character.setSecondaryHandItem
|
setMethodSecond = self.character.setSecondaryHandItem
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local isFirstValid = CheckHandFeasibility(hand)
|
||||||
|
local isSecondValid = CheckHandFeasibility(otherHand)
|
||||||
|
|
||||||
|
|
||||||
if not self.twoHands then
|
if not self.twoHands then
|
||||||
if getMethodFirst(self.character) and getMethodFirst(self.character):isRequiresEquippedBothHands() then
|
if getMethodFirst(self.character) and getMethodFirst(self.character):isRequiresEquippedBothHands() then
|
||||||
setMethodFirst(self.character, nil)
|
setMethodFirst(self.character, nil)
|
||||||
@@ -145,10 +188,10 @@ function ISEquipWeaponAction:performWithAmputation(dcInst)
|
|||||||
setMethodSecond(self.character, nil)
|
setMethodSecond(self.character, nil)
|
||||||
-- TODO We should use the CachedData indexable instead of dcInst
|
-- TODO We should use the CachedData indexable instead of dcInst
|
||||||
|
|
||||||
if not dcInst:getIsCut(hand) then
|
if isFirstValid then
|
||||||
setMethodSecond(self.character, self.item)
|
setMethodSecond(self.character, self.item)
|
||||||
-- Check other HAND!
|
-- Check other HAND!
|
||||||
elseif not dcInst:getIsCut(otherHand) then
|
elseif isSecondValid then
|
||||||
setMethodFirst(self.character, self.item)
|
setMethodFirst(self.character, self.item)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -156,13 +199,10 @@ function ISEquipWeaponAction:performWithAmputation(dcInst)
|
|||||||
setMethodFirst(self.character, nil)
|
setMethodFirst(self.character, nil)
|
||||||
setMethodSecond(self.character, nil)
|
setMethodSecond(self.character, nil)
|
||||||
|
|
||||||
|
|
||||||
local isFirstValid = CheckHandFeasibility(hand)
|
|
||||||
local isSecondValid = CheckHandFeasibility(otherHand)
|
|
||||||
-- TOC_DEBUG.print("First Hand: " .. tostring(hand))
|
-- TOC_DEBUG.print("First Hand: " .. tostring(hand))
|
||||||
-- TOC_DEBUG.print("Prost Group: " .. tostring(prostGroup))
|
-- --TOC_DEBUG.print("Prost Group: " .. tostring(prostGroup))
|
||||||
-- TOC_DEBUG.print("Other Hand: " .. tostring(otherHand))
|
-- TOC_DEBUG.print("Other Hand: " .. tostring(otherHand))
|
||||||
-- TOC_DEBUG.print("Other Prost Group: " .. tostring(otherProstGroup))
|
-- --TOC_DEBUG.print("Other Prost Group: " .. tostring(otherProstGroup))
|
||||||
|
|
||||||
-- TOC_DEBUG.print("isPrimaryHandValid: " .. tostring(isFirstValid))
|
-- TOC_DEBUG.print("isPrimaryHandValid: " .. tostring(isFirstValid))
|
||||||
-- TOC_DEBUG.print("isSecondaryHandValid: " .. tostring(isSecondValid))
|
-- TOC_DEBUG.print("isSecondaryHandValid: " .. tostring(isSecondValid))
|
||||||
@@ -183,12 +223,15 @@ local og_ISEquipWeaponAction_perform = ISEquipWeaponAction.perform
|
|||||||
function ISEquipWeaponAction:perform()
|
function ISEquipWeaponAction:perform()
|
||||||
og_ISEquipWeaponAction_perform(self)
|
og_ISEquipWeaponAction_perform(self)
|
||||||
|
|
||||||
-- TODO Can we do it earlier?
|
|
||||||
|
--if self.character == getPlayer() then
|
||||||
local dcInst = DataController.GetInstance(self.character:getUsername())
|
local dcInst = DataController.GetInstance(self.character:getUsername())
|
||||||
-- Just check it any limb has been cut. If not, we can just return from here
|
-- Just check it any limb has been cut. If not, we can just return from here
|
||||||
if dcInst:getIsAnyLimbCut() == true then
|
if dcInst:getIsAnyLimbCut() then
|
||||||
self:performWithAmputation(dcInst)
|
self:performWithAmputation()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--end
|
||||||
end
|
end
|
||||||
|
|
||||||
function ISInventoryPaneContextMenu.doEquipOption(context, playerObj, isWeapon, items, player)
|
function ISInventoryPaneContextMenu.doEquipOption(context, playerObj, isWeapon, items, player)
|
||||||
@@ -248,6 +291,29 @@ 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
|
||||||
|
local brokenGlassOption = ogContext:getOptionFromName(getText("ContextMenu_RemoveBrokenGlass"))
|
||||||
|
|
||||||
|
if brokenGlassOption then
|
||||||
|
local playerObj = getSpecificPlayer(player)
|
||||||
|
if (CachedDataHandler.GetHandFeasibility(StaticData.SIDES_IND_STR.R) and playerObj:getPrimaryHandItem()) or
|
||||||
|
(CachedDataHandler.GetHandFeasibility(StaticData.SIDES_IND_STR.L) and playerObj:getSecondaryHandItem())
|
||||||
|
then
|
||||||
|
brokenGlassOption.notAvailable = false
|
||||||
|
brokenGlassOption.toolTip = nil -- This is active only when you can't do the action.
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- check if no hands, disable various interactions
|
-- check if no hands, disable various interactions
|
||||||
if not CachedDataHandler.GetBothHandsFeasibility() then
|
if not CachedDataHandler.GetBothHandsFeasibility() then
|
||||||
TOC_DEBUG.print("NO hands :((")
|
TOC_DEBUG.print("NO hands :((")
|
||||||
@@ -262,13 +328,12 @@ function ISWorldObjectContextMenu.createMenu(player, worldobjects, x, y, test)
|
|||||||
return ogContext
|
return ogContext
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--* DISABLE WEARING CERTAIN ITEMS WHEN NO LIMB
|
--* DISABLE WEARING CERTAIN ITEMS WHEN NO LIMB
|
||||||
|
|
||||||
local function CheckLimbFeasibility(limbName)
|
local function CheckLimbFeasibility(limbName)
|
||||||
local dcInst = DataController.GetInstance()
|
local dcInst = DataController.GetInstance()
|
||||||
local isFeasible = not dcInst:getIsCut(limbName) or dcInst:getIsProstEquipped(limbName)
|
local isFeasible = not dcInst:getIsCut(limbName) or dcInst:getIsProstEquipped(limbName)
|
||||||
TOC_DEBUG.print("isFeasible="..tostring(isFeasible))
|
--TOC_DEBUG.print("isFeasible="..tostring(isFeasible))
|
||||||
return isFeasible
|
return isFeasible
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ require("TOC/Events")
|
|||||||
-----------
|
-----------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- Handle ONLY stuff for the local client
|
-- Handle ONLY stuff for the local client
|
||||||
|
|
||||||
---@class LocalPlayerController
|
---@class LocalPlayerController
|
||||||
@@ -44,21 +46,37 @@ function LocalPlayerController.InitializePlayer(isForced)
|
|||||||
SetHealthPanelTOC()
|
SetHealthPanelTOC()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
---Handles the traits
|
---Handles the traits
|
||||||
---@param playerObj IsoPlayer
|
function LocalPlayerController.ManageTraits()
|
||||||
function LocalPlayerController.ManageTraits(playerObj)
|
|
||||||
local AmputationHandler = require("Handlers/TOC_AmputationHandler")
|
-- Local player
|
||||||
|
local playerObj = getPlayer()
|
||||||
|
|
||||||
|
local AmputationHandler = require("TOC/Handlers/AmputationHandler")
|
||||||
for k, v in pairs(StaticData.TRAITS_BP) do
|
for k, v in pairs(StaticData.TRAITS_BP) do
|
||||||
if playerObj:HasTrait(k) then
|
if playerObj:HasTrait(k) then
|
||||||
-- Once we find one, we should be done.
|
-- Once we find one, we should be done since they're exclusive
|
||||||
local tempHandler = AmputationHandler:new(v)
|
TOC_DEBUG.print("Player has amputation trait " .. k .. ", executing it")
|
||||||
|
local tempHandler = AmputationHandler:new(v, playerObj)
|
||||||
tempHandler:execute(false) -- No damage
|
tempHandler:execute(false) -- No damage
|
||||||
tempHandler:close()
|
tempHandler:close()
|
||||||
|
|
||||||
|
-- The wound should be already cicatrized
|
||||||
|
local dcInst = DataController.GetInstance()
|
||||||
|
LocalPlayerController.HandleSetCicatrization(DataController.GetInstance(), playerObj, v)
|
||||||
|
dcInst:apply()
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- We need to manage traits when we're done setupping everything
|
||||||
|
-- It shouldn't be done every single time we initialize the player, fetching data, etc.
|
||||||
|
Events.OnSetupTocData.Add(LocalPlayerController.ManageTraits)
|
||||||
|
|
||||||
|
|
||||||
----------------------------------------------------------
|
----------------------------------------------------------
|
||||||
|
|
||||||
--* Health *--
|
--* Health *--
|
||||||
@@ -121,8 +139,14 @@ function LocalPlayerController.TryRandomBleed(character, limbName)
|
|||||||
if chance > normCicTime then
|
if chance > normCicTime then
|
||||||
TOC_DEBUG.print("Triggered bleeding from non cicatrized wound")
|
TOC_DEBUG.print("Triggered bleeding from non cicatrized wound")
|
||||||
local adjacentBodyPartType = BodyPartType[StaticData.LIMBS_ADJACENT_IND_STR[limbName]]
|
local adjacentBodyPartType = BodyPartType[StaticData.LIMBS_ADJACENT_IND_STR[limbName]]
|
||||||
character:getBodyDamage():getBodyPart(adjacentBodyPartType):setBleeding(true)
|
|
||||||
character:getBodyDamage():getBodyPart(adjacentBodyPartType):setBleedingTime(20)
|
-- we need to check if the wound is already bleeding before doing anything else to prevent issues with bandages
|
||||||
|
local bp = character:getBodyDamage():getBodyPart(adjacentBodyPartType)
|
||||||
|
bp:setBleedingTime(20) -- TODO Should depend on cicatrization instead of a fixed time
|
||||||
|
-- ADD Could break bandages if bleeding is too much?
|
||||||
|
|
||||||
|
|
||||||
|
--character:getBodyDamage():getBodyPart(adjacentBodyPartType):setBleeding(true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -135,9 +159,13 @@ LocalPlayerController.hasBeenDamaged = false
|
|||||||
---Check if the player has in infected body part or if they have been hit in a cut area
|
---Check if the player has in infected body part or if they have been hit in a cut area
|
||||||
---@param character IsoPlayer|IsoGameCharacter
|
---@param character IsoPlayer|IsoGameCharacter
|
||||||
function LocalPlayerController.HandleDamage(character)
|
function LocalPlayerController.HandleDamage(character)
|
||||||
-- TOC_DEBUG.print("Player got hit!")
|
--TOC_DEBUG.print("Player got hit!")
|
||||||
-- TOC_DEBUG.print(damageType)
|
-- TOC_DEBUG.print(damageType)
|
||||||
if character ~= getPlayer() then return end
|
if character ~= getPlayer() then
|
||||||
|
-- Disable lock before doing anything else
|
||||||
|
LocalPlayerController.hasBeenDamaged = false
|
||||||
|
return
|
||||||
|
end
|
||||||
local bd = character:getBodyDamage()
|
local bd = character:getBodyDamage()
|
||||||
local dcInst = DataController.GetInstance()
|
local dcInst = DataController.GetInstance()
|
||||||
local modDataNeedsUpdate = false
|
local modDataNeedsUpdate = false
|
||||||
@@ -167,8 +195,7 @@ function LocalPlayerController.HandleDamage(character)
|
|||||||
|
|
||||||
-- Check other body parts that are not included in the mod, if there's a bite there then the player is fucked
|
-- Check other body parts that are not included in the mod, if there's a bite there then the player is fucked
|
||||||
-- We can skip this loop if the player has been infected. The one before we kinda need it to handle correctly the bites in case the player wanna cut stuff off anyway
|
-- We can skip this loop if the player has been infected. The one before we kinda need it to handle correctly the bites in case the player wanna cut stuff off anyway
|
||||||
if dcInst:getIsIgnoredPartInfected() then return end
|
if not dcInst:getIsIgnoredPartInfected() then
|
||||||
|
|
||||||
for i = 1, #StaticData.IGNORED_BODYLOCS_BPT do
|
for i = 1, #StaticData.IGNORED_BODYLOCS_BPT do
|
||||||
local bodyPartType = StaticData.IGNORED_BODYLOCS_BPT[i]
|
local bodyPartType = StaticData.IGNORED_BODYLOCS_BPT[i]
|
||||||
local bodyPart = bd:getBodyPart(bodyPartType)
|
local bodyPart = bd:getBodyPart(bodyPartType)
|
||||||
@@ -177,8 +204,8 @@ function LocalPlayerController.HandleDamage(character)
|
|||||||
modDataNeedsUpdate = true
|
modDataNeedsUpdate = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- TODO in theory should sync modData, but it's gonna be expensive as fuck. Figure it out
|
|
||||||
if modDataNeedsUpdate then
|
if modDataNeedsUpdate then
|
||||||
dcInst:apply()
|
dcInst:apply()
|
||||||
end
|
end
|
||||||
@@ -187,17 +214,13 @@ function LocalPlayerController.HandleDamage(character)
|
|||||||
LocalPlayerController.hasBeenDamaged = false
|
LocalPlayerController.hasBeenDamaged = false
|
||||||
end
|
end
|
||||||
|
|
||||||
---Setup HandleDamage, triggered by OnPlayerGetDamage
|
---Setup HandleDamage, triggered by OnPlayerGetDamage. To prevent a spam caused by this awful event, we use a bool lock
|
||||||
---@param character IsoPlayer|IsoGameCharacter
|
---@param character IsoPlayer|IsoGameCharacter
|
||||||
---@param damageType string
|
---@param damageType string
|
||||||
---@param damageAmount number
|
---@param damageAmount number
|
||||||
function LocalPlayerController.OnGetDamage(character, damageType, damageAmount)
|
function LocalPlayerController.OnGetDamage(character, damageType, damageAmount)
|
||||||
-- TODO Check if other players in the online triggers this
|
|
||||||
|
|
||||||
if LocalPlayerController.hasBeenDamaged == false then
|
if LocalPlayerController.hasBeenDamaged == false then
|
||||||
-- Start checks
|
-- Start checks
|
||||||
|
|
||||||
-- TODO Add a timer before we can re-enable this bool?
|
|
||||||
LocalPlayerController.hasBeenDamaged = true
|
LocalPlayerController.hasBeenDamaged = true
|
||||||
LocalPlayerController.HandleDamage(character)
|
LocalPlayerController.HandleDamage(character)
|
||||||
end
|
end
|
||||||
@@ -257,14 +280,11 @@ function LocalPlayerController.UpdateAmputations()
|
|||||||
cicTime = cicTime - cicDec
|
cicTime = cicTime - cicDec
|
||||||
|
|
||||||
|
|
||||||
dcInst:setCicatrizationTime(limbName, cicTime)
|
|
||||||
TOC_DEBUG.print("New cicatrization time: " .. tostring(cicTime))
|
TOC_DEBUG.print("New cicatrization time: " .. tostring(cicTime))
|
||||||
if cicTime <= 0 then
|
if cicTime <= 0 then
|
||||||
TOC_DEBUG.print(tostring(limbName) .. " is cicatrized")
|
LocalPlayerController.HandleSetCicatrization(dcInst, pl, limbName)
|
||||||
dcInst:setIsCicatrized(limbName, true)
|
else
|
||||||
-- Set visual
|
dcInst:setCicatrizationTime(limbName, cicTime)
|
||||||
local ItemsController = require("TOC/Controllers/ItemsController")
|
|
||||||
ItemsController.Player.OverrideAmputationItemVisuals(pl, limbName, true)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -285,6 +305,23 @@ function LocalPlayerController.ToggleUpdateAmputations()
|
|||||||
CommonMethods.SafeStartEvent("EveryHours", LocalPlayerController.UpdateAmputations)
|
CommonMethods.SafeStartEvent("EveryHours", LocalPlayerController.UpdateAmputations)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--* Cicatrization and cicatrization visuals *--
|
||||||
|
|
||||||
|
---Set the boolean and cicTime in DCINST and the visuals for the amputated limb
|
||||||
|
---@param dcInst DataController
|
||||||
|
---@param playerObj IsoPlayer
|
||||||
|
---@param limbName string
|
||||||
|
function LocalPlayerController.HandleSetCicatrization(dcInst, playerObj, limbName)
|
||||||
|
TOC_DEBUG.print("Setting cicatrization to " .. tostring(limbName))
|
||||||
|
dcInst:setIsCicatrized(limbName, true)
|
||||||
|
dcInst:setCicatrizationTime(limbName, 0)
|
||||||
|
|
||||||
|
-- Set visuals for the amputation
|
||||||
|
local ItemsController = require("TOC/Controllers/ItemsController")
|
||||||
|
ItemsController.Player.OverrideAmputationItemVisuals(playerObj, limbName, true)
|
||||||
|
end
|
||||||
|
|
||||||
--* Object drop handling when amputation occurs
|
--* Object drop handling when amputation occurs
|
||||||
|
|
||||||
|
|
||||||
@@ -334,10 +371,20 @@ function LocalPlayerController.DropItemsAfterAmputation(limbName)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- TODO Consider 2 handed weapons too
|
||||||
|
|
||||||
|
-- equipped items too
|
||||||
|
if side == "R" then
|
||||||
|
pl:setPrimaryHandItem(nil)
|
||||||
|
elseif side == "L" then
|
||||||
|
pl:setSecondaryHandItem(nil)
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
Events.OnAmputatedLimb.Add(LocalPlayerController.DropItemsAfterAmputation)
|
Events.OnAmputatedLimb.Add(LocalPlayerController.DropItemsAfterAmputation)
|
||||||
|
Events.OnProsthesisUnequipped.Add(LocalPlayerController.DropItemsAfterAmputation)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -71,11 +71,13 @@ function TourniquetController.WrapClothingAction(obj, wrappedFunc)
|
|||||||
group:setMultiItem(TourniquetController.bodyLoc, false)
|
group:setMultiItem(TourniquetController.bodyLoc, false)
|
||||||
end
|
end
|
||||||
|
|
||||||
wrappedFunc(obj)
|
local ogValue = wrappedFunc(obj)
|
||||||
|
|
||||||
if isTourniquet then
|
if isTourniquet then
|
||||||
group:setMultiItem(TourniquetController.bodyLoc, true)
|
group:setMultiItem(TourniquetController.bodyLoc, true)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
return ogValue -- Needed for isValid
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@@ -98,12 +100,12 @@ end
|
|||||||
|
|
||||||
local og_ISWearClothing_isValid = ISWearClothing.isValid
|
local og_ISWearClothing_isValid = ISWearClothing.isValid
|
||||||
function ISWearClothing:isValid()
|
function ISWearClothing:isValid()
|
||||||
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
|
||||||
function ISUnequipAction:perform()
|
function ISUnequipAction:perform()
|
||||||
TourniquetController.WrapClothingAction(self, og_ISUnequipAction_perform)
|
return TourniquetController.WrapClothingAction(self, og_ISUnequipAction_perform)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
--* Setup Events *--
|
--* Setup Events *--
|
||||||
LuaEventManager.AddEvent("OnAmputatedLimb") --Triggered when a limb has been amputated
|
LuaEventManager.AddEvent("OnAmputatedLimb") --Triggered when a limb has been amputated
|
||||||
|
LuaEventManager.AddEvent("OnProsthesisUnequipped")
|
||||||
LuaEventManager.AddEvent("OnReceivedTocData") -- Triggered when TOC data is ready
|
LuaEventManager.AddEvent("OnReceivedTocData") -- Triggered when TOC data is ready
|
||||||
|
LuaEventManager.AddEvent("OnSetupTocData") -- Triggered when TOC has been setupped
|
||||||
@@ -89,9 +89,12 @@ end
|
|||||||
---@param stitchesItem InventoryItem
|
---@param stitchesItem InventoryItem
|
||||||
---@return ISStitch
|
---@return ISStitch
|
||||||
function AmputationHandler.PrepareStitchesAction(prevAction, limbName, surgeonPl, patientPl, stitchesItem)
|
function AmputationHandler.PrepareStitchesAction(prevAction, limbName, surgeonPl, patientPl, stitchesItem)
|
||||||
local bptEnum = StaticData.LIMBS_TO_BODYLOCS_IND_BPT[limbName]
|
|
||||||
local bd = patientPl:getBodyDamage()
|
local bd = patientPl:getBodyDamage()
|
||||||
local bodyPart = bd:getBodyPart(bptEnum)
|
|
||||||
|
-- we need the adjacent one, not the actual one
|
||||||
|
local adjacentLimb = StaticData.LIMBS_ADJACENT_IND_STR[limbName]
|
||||||
|
local bodyPart = bd:getBodyPart(BodyPartType[adjacentLimb])
|
||||||
|
|
||||||
local stitchesAction = ISStitch:new(surgeonPl, patientPl, stitchesItem, bodyPart, true)
|
local stitchesAction = ISStitch:new(surgeonPl, patientPl, stitchesItem, bodyPart, true)
|
||||||
ISTimedActionQueue.addAfter(prevAction, stitchesAction)
|
ISTimedActionQueue.addAfter(prevAction, stitchesAction)
|
||||||
|
|
||||||
@@ -106,9 +109,11 @@ end
|
|||||||
---@param bandageItem InventoryItem
|
---@param bandageItem InventoryItem
|
||||||
---@return ISApplyBandage
|
---@return ISApplyBandage
|
||||||
function AmputationHandler.PrepareBandagesAction(prevAction, limbName, surgeonPl, patientPl, bandageItem)
|
function AmputationHandler.PrepareBandagesAction(prevAction, limbName, surgeonPl, patientPl, bandageItem)
|
||||||
local bptEnum = StaticData.LIMBS_TO_BODYLOCS_IND_BPT[limbName]
|
|
||||||
local bd = patientPl:getBodyDamage()
|
local bd = patientPl:getBodyDamage()
|
||||||
local bodyPart = bd:getBodyPart(bptEnum)
|
-- we need the adjacent one, not the actual one
|
||||||
|
local adjacentLimb = StaticData.LIMBS_ADJACENT_IND_STR[limbName]
|
||||||
|
local bodyPart = bd:getBodyPart(BodyPartType[adjacentLimb])
|
||||||
|
|
||||||
local bandageAction = ISApplyBandage:new(surgeonPl, patientPl, bandageItem, bodyPart, true)
|
local bandageAction = ISApplyBandage:new(surgeonPl, patientPl, bandageItem, bodyPart, true)
|
||||||
ISTimedActionQueue.addAfter(prevAction, bandageAction)
|
ISTimedActionQueue.addAfter(prevAction, bandageAction)
|
||||||
|
|
||||||
@@ -151,7 +156,9 @@ function AmputationHandler:damageAfterAmputation(surgeonFactor)
|
|||||||
patientStats:setStress(baseDamage - surgeonFactor)
|
patientStats:setStress(baseDamage - surgeonFactor)
|
||||||
end
|
end
|
||||||
|
|
||||||
---Execute the amputation
|
---Execute the amputation. This method doesn't check if the upper limb has been amputated or not, so if
|
||||||
|
--- somehow the method gets triggered and we're trying to cut off a part that doesn't really exist anymore,
|
||||||
|
--- it will still be executed. This is by design, additional checks must be made BEFORE running the AmputationHandler
|
||||||
---@param damagePlayer boolean
|
---@param damagePlayer boolean
|
||||||
function AmputationHandler:execute(damagePlayer)
|
function AmputationHandler:execute(damagePlayer)
|
||||||
local surgeonFactor = self.surgeonPl:getPerkLevel(Perks.Doctor) * SandboxVars.TOC.SurgeonAbilityImportance
|
local surgeonFactor = self.surgeonPl:getPerkLevel(Perks.Doctor) * SandboxVars.TOC.SurgeonAbilityImportance
|
||||||
|
|||||||
@@ -22,8 +22,6 @@ end
|
|||||||
---Will calculate all the values that we need
|
---Will calculate all the values that we need
|
||||||
function CachedDataHandler.CalculateCacheableValues(username)
|
function CachedDataHandler.CalculateCacheableValues(username)
|
||||||
CachedDataHandler.CalculateHighestAmputatedLimbs(username)
|
CachedDataHandler.CalculateHighestAmputatedLimbs(username)
|
||||||
|
|
||||||
-- FIX This should be run ONLY on the actual client, never on other clients. Just a placeholder fix for now
|
|
||||||
if getPlayer():getUsername() == username then
|
if getPlayer():getUsername() == username then
|
||||||
CachedDataHandler.CalculateBothHandsFeasibility()
|
CachedDataHandler.CalculateBothHandsFeasibility()
|
||||||
end
|
end
|
||||||
@@ -31,7 +29,6 @@ end
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--* Amputated Limbs caching *--
|
--* Amputated Limbs caching *--
|
||||||
CachedDataHandler.amputatedLimbs = {}
|
CachedDataHandler.amputatedLimbs = {}
|
||||||
|
|
||||||
@@ -111,6 +108,8 @@ end
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--* Hand feasibility caching *--
|
--* Hand feasibility caching *--
|
||||||
CachedDataHandler.handFeasibility = {}
|
CachedDataHandler.handFeasibility = {}
|
||||||
|
|
||||||
@@ -118,11 +117,22 @@ CachedDataHandler.handFeasibility = {}
|
|||||||
function CachedDataHandler.CalculateHandFeasibility(limbName)
|
function CachedDataHandler.CalculateHandFeasibility(limbName)
|
||||||
local dcInst = DataController.GetInstance()
|
local dcInst = DataController.GetInstance()
|
||||||
local side = CommonMethods.GetSide(limbName)
|
local side = CommonMethods.GetSide(limbName)
|
||||||
|
|
||||||
|
-- TODO if we re run this too early, it might break everything after a forced re-init
|
||||||
|
|
||||||
CachedDataHandler.handFeasibility[side] = not dcInst:getIsCut(limbName) or dcInst:getIsProstEquipped(limbName)
|
CachedDataHandler.handFeasibility[side] = not dcInst:getIsCut(limbName) or dcInst:getIsProstEquipped(limbName)
|
||||||
|
TOC_DEBUG.print("Calculated hand feasibility: " .. tostring(side))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---@param side string Either "L" or "R"
|
||||||
|
---@return boolean
|
||||||
function CachedDataHandler.GetHandFeasibility(side)
|
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.
|
||||||
|
if CachedDataHandler.handFeasibility[side] == nil then
|
||||||
|
CachedDataHandler.CalculateBothHandsFeasibility()
|
||||||
|
end
|
||||||
|
|
||||||
return CachedDataHandler.handFeasibility[side]
|
return CachedDataHandler.handFeasibility[side]
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -131,16 +141,21 @@ 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"
|
||||||
|
|
||||||
|
if CachedDataHandler.interactKey == nil or CachedDataHandler.interactKey == 0 then
|
||||||
|
CachedDataHandler.interactKey = getCore():getKey(interactStr)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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))
|
||||||
-- Cache the current key
|
|
||||||
CachedDataHandler.interactKey = getCore():getKey(interactStr)
|
|
||||||
getCore():addKeyBinding(interactStr, Keyboard.KEY_NONE)
|
getCore():addKeyBinding(interactStr, Keyboard.KEY_NONE)
|
||||||
else
|
else
|
||||||
TOC_DEBUG.print("Re-enabling interact key")
|
TOC_DEBUG.print("Re-enabling interact key")
|
||||||
|
TOC_DEBUG.print("Cached current key for interact: " .. tostring(CachedDataHandler.interactKey))
|
||||||
|
|
||||||
if not CachedDataHandler.interactKey then CachedDataHandler.interactKey = getCore():getKey(interactStr) end
|
|
||||||
getCore():addKeyBinding(interactStr, CachedDataHandler.interactKey)
|
getCore():addKeyBinding(interactStr, CachedDataHandler.interactKey)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -70,7 +70,6 @@ function ProsthesisHandler.CheckIfEquippable(fullType)
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
---Handle equipping or unequipping prosthetics
|
---Handle equipping or unequipping prosthetics
|
||||||
---@param item InventoryItem
|
---@param item InventoryItem
|
||||||
---@param isEquipping boolean
|
---@param isEquipping boolean
|
||||||
@@ -134,38 +133,25 @@ function ISClothingExtraAction:isValid()
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local og_ISClothingExtraAction_perform = ISClothingExtraAction.perform
|
||||||
|
function ISClothingExtraAction:perform()
|
||||||
|
local extraItem = InventoryItemFactory.CreateItem(self.extra)
|
||||||
|
ProsthesisHandler.SearchAndSetupProsthesis(extraItem, true)
|
||||||
|
og_ISClothingExtraAction_perform(self)
|
||||||
|
end
|
||||||
|
|
||||||
--[[
|
local og_ISUnequipAction_perform = ISUnequipAction.perform
|
||||||
|
function ISUnequipAction:perform()
|
||||||
|
|
||||||
|
--[[
|
||||||
Horrendous workaround
|
Horrendous workaround
|
||||||
|
|
||||||
To unequp items, the java side uses WornItems.setItem, which has
|
To unequp items, the java side uses WornItems.setItem, which has
|
||||||
a check for multiItem. Basically, if it's active, it won't actually remove the item,
|
a check for multiItem. Basically, if it's active, it won't actually remove the item,
|
||||||
fucking things up. So, to be 100% sure that we're removing the items, we're gonna
|
fucking things up. So, to be 100% sure that we're removing the items, we're gonna
|
||||||
disable and re-enable the multi-item bool for the Unequip Action.
|
disable and re-enable the multi-item bool for the Unequip Action.
|
||||||
]]
|
]]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
local og_ISClothingExtraAction_perform = ISClothingExtraAction.perform
|
|
||||||
function ISClothingExtraAction:perform()
|
|
||||||
--local extraItem = InventoryItemFactory.CreateItem(self.extra)
|
|
||||||
local isProst = ProsthesisHandler.SearchAndSetupProsthesis(self.item, true)
|
|
||||||
local group
|
|
||||||
if isProst then
|
|
||||||
group = BodyLocations.getGroup("Human")
|
|
||||||
group:setMultiItem("TOC_ArmProst", false)
|
|
||||||
end
|
|
||||||
|
|
||||||
og_ISClothingExtraAction_perform(self)
|
|
||||||
|
|
||||||
if isProst then
|
|
||||||
group:setMultiItem("TOC_ArmProst", true)
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
local og_ISUnequipAction_perform = ISUnequipAction.perform
|
|
||||||
function ISUnequipAction:perform()
|
|
||||||
local isProst = ProsthesisHandler.SearchAndSetupProsthesis(self.item, false)
|
local isProst = ProsthesisHandler.SearchAndSetupProsthesis(self.item, false)
|
||||||
local group
|
local group
|
||||||
if isProst then
|
if isProst then
|
||||||
@@ -176,8 +162,19 @@ function ISUnequipAction:perform()
|
|||||||
|
|
||||||
if isProst then
|
if isProst then
|
||||||
group:setMultiItem("TOC_ArmProst", true)
|
group:setMultiItem("TOC_ArmProst", true)
|
||||||
|
|
||||||
|
-- we need to fetch the limbname associated to the prosthesis
|
||||||
|
local side = CommonMethods.GetSide(self.item:getFullType())
|
||||||
|
local highestAmputatedLimbs = CachedDataHandler.GetHighestAmputatedLimbs(getPlayer():getUsername())
|
||||||
|
if highestAmputatedLimbs then
|
||||||
|
local hal = highestAmputatedLimbs[side]
|
||||||
|
if hal then
|
||||||
|
-- This could break if amputated limbs aren't cached for some reason
|
||||||
|
triggerEvent("OnProsthesisUnequipped", hal)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
return ProsthesisHandler
|
return ProsthesisHandler
|
||||||
|
|||||||
@@ -6,39 +6,11 @@ require("TOC/Events")
|
|||||||
|
|
||||||
---@class Main
|
---@class Main
|
||||||
local Main = {
|
local Main = {
|
||||||
_version = 2.0
|
_version = "2.1.4"
|
||||||
}
|
}
|
||||||
|
|
||||||
---Setups the custom traits
|
|
||||||
function Main.SetupTraits()
|
|
||||||
-- Perks.Left_Hand is defined in perks.txt
|
|
||||||
|
|
||||||
local traitsTable = {
|
|
||||||
[1] = TraitFactory.addTrait("Amputee_Hand", getText("UI_trait_Amputee_Hand"), -8, getText("UI_trait_Amputee_Hand_desc"), false, false),
|
|
||||||
[2] = TraitFactory.addTrait("Amputee_LowerArm", getText("UI_trait_Amputee_LowerArm"), -10, getText("UI_trait_Amputee_LowerArm_desc"), false, false),
|
|
||||||
[3] = TraitFactory.addTrait("Amputee_UpperArm", getText("UI_trait_Amputee_UpperArm"), -20, getText("UI_trait_Amputee_UpperArm_desc"), false, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i=1, #traitsTable do
|
|
||||||
|
|
||||||
---@type Trait
|
|
||||||
local t = traitsTable[i]
|
|
||||||
---@diagnostic disable-next-line: undefined-field
|
|
||||||
t:addXPBoost(Perks.Left_Hand, 4)
|
|
||||||
t:addXPBoost(Perks.Fitness, -1)
|
|
||||||
t:addXPBoost(Perks.Strength, -1)
|
|
||||||
end
|
|
||||||
|
|
||||||
TraitFactory.addTrait("Insensitive", getText("UI_trait_Insensitive"), 6, getText("UI_trait_Insensitive_desc"), false, false)
|
|
||||||
|
|
||||||
TraitFactory.setMutualExclusive("Amputee_Hand", "Amputee_LowerArm")
|
|
||||||
TraitFactory.setMutualExclusive("Amputee_Hand", "Amputee_UpperArm")
|
|
||||||
TraitFactory.setMutualExclusive("Amputee_LowerArm", "Amputee_UpperArm")
|
|
||||||
end
|
|
||||||
|
|
||||||
function Main.Start()
|
function Main.Start()
|
||||||
TOC_DEBUG.print("running Start method")
|
TOC_DEBUG.print("Starting The Only Cure version " .. tostring(Main._version))
|
||||||
Main.SetupTraits()
|
|
||||||
Main.SetupEvents()
|
Main.SetupEvents()
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -47,6 +19,7 @@ function Main.SetupEvents()
|
|||||||
Events.OnReceivedTocData.Add(CachedDataHandler.CalculateCacheableValues)
|
Events.OnReceivedTocData.Add(CachedDataHandler.CalculateCacheableValues)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function Main.InitializePlayer()
|
function Main.InitializePlayer()
|
||||||
---Looop until we've successfully initialized the mod
|
---Looop until we've successfully initialized the mod
|
||||||
local function TryToInitialize()
|
local function TryToInitialize()
|
||||||
@@ -63,16 +36,15 @@ function Main.InitializePlayer()
|
|||||||
CommonMethods.SafeStartEvent("OnTick", TryToInitialize)
|
CommonMethods.SafeStartEvent("OnTick", TryToInitialize)
|
||||||
end
|
end
|
||||||
|
|
||||||
---Clean the TOC table for that SP player, to prevent from clogging it up
|
---Clean the TOC table for that SP player, to prevent it from clogging ModData up
|
||||||
---@param player IsoPlayer
|
---@param player IsoPlayer
|
||||||
function Main.WipeData(player)
|
function Main.WipeData(player)
|
||||||
TOC_DEBUG.print("Wiping data after death")
|
local username = player:getUsername()
|
||||||
local key = CommandsData.GetKey(player:getUsername())
|
TOC_DEBUG.print("Wiping data after death: " .. username)
|
||||||
|
local key = CommandsData.GetKey(username)
|
||||||
|
|
||||||
--ModData.remove(key)
|
--ModData.remove(key)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if not isClient() then
|
if not isClient() then
|
||||||
-- For SP, it's enough just removing the data this way
|
-- For SP, it's enough just removing the data this way
|
||||||
ModData.remove(key)
|
ModData.remove(key)
|
||||||
@@ -81,7 +53,15 @@ function Main.WipeData(player)
|
|||||||
-- at the next character by passing an empty mod data
|
-- at the next character by passing an empty mod data
|
||||||
ModData.add(key, {})
|
ModData.add(key, {})
|
||||||
ModData.transmit(key)
|
ModData.transmit(key)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- Let's wipe the instance too just to be sure
|
||||||
|
-- TODO This can break things I guess
|
||||||
|
--local DataController = require("TOC/Controllers/DataController")
|
||||||
|
--DataController.DestroyInstance(username)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--* Events *--
|
--* Events *--
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ local StaticData = require("TOC/StaticData")
|
|||||||
TestFramework.registerTestModule("LocalPlayerController", "Setup", function()
|
TestFramework.registerTestModule("LocalPlayerController", "Setup", function()
|
||||||
local Tests = {}
|
local Tests = {}
|
||||||
function Tests.InitializePlayer()
|
function Tests.InitializePlayer()
|
||||||
local pl = getPlayer()
|
|
||||||
LocalPlayerController.InitializePlayer(true)
|
LocalPlayerController.InitializePlayer(true)
|
||||||
end
|
end
|
||||||
return Tests
|
return Tests
|
||||||
@@ -146,6 +145,14 @@ end)
|
|||||||
TestFramework.registerTestModule("Various", "Player", function()
|
TestFramework.registerTestModule("Various", "Player", function()
|
||||||
local Tests = {}
|
local Tests = {}
|
||||||
|
|
||||||
|
|
||||||
|
function Tests.BleedTest()
|
||||||
|
local pl = getPlayer()
|
||||||
|
|
||||||
|
--pl:getBodyDamage():getBodyPart(BodyPartType.ForeArm_R):setBleeding(true)
|
||||||
|
pl:getBodyDamage():getBodyPart(BodyPartType.ForeArm_R):setBleedingTime(20)
|
||||||
|
end
|
||||||
|
|
||||||
function Tests.Kill()
|
function Tests.Kill()
|
||||||
getPlayer():Kill(getPlayer())
|
getPlayer():Kill(getPlayer())
|
||||||
end
|
end
|
||||||
@@ -154,6 +161,38 @@ TestFramework.registerTestModule("Various", "Player", function()
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
|
|
||||||
|
TestFramework.registerTestModule("Various", "Visuals", function()
|
||||||
|
local Tests = {}
|
||||||
|
|
||||||
|
function Tests.AddBloodLeftForearm()
|
||||||
|
local playerObj = getPlayer()
|
||||||
|
local limbName = "ForeArm_L"
|
||||||
|
local fullType = StaticData.AMPUTATION_CLOTHING_ITEM_BASE .. limbName
|
||||||
|
|
||||||
|
|
||||||
|
local item = playerObj:getInventory():FindAndReturn(fullType)
|
||||||
|
if instanceof(item, "Clothing") then
|
||||||
|
|
||||||
|
---@cast item Clothing
|
||||||
|
|
||||||
|
print("Found limb to add blood onto")
|
||||||
|
item:setBloodLevel(100)
|
||||||
|
local coveredParts = BloodClothingType.getCoveredParts(item:getBloodClothingType())
|
||||||
|
if coveredParts then
|
||||||
|
for j=0,coveredParts:size()-1 do
|
||||||
|
item:setBlood(coveredParts:get(j), 100)
|
||||||
|
item:setDirt(coveredParts:get(j), 100)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
playerObj:resetModelNextFrame()
|
||||||
|
end
|
||||||
|
|
||||||
|
return Tests
|
||||||
|
end)
|
||||||
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------------
|
||||||
if not getActivatedMods():contains("PerfTestFramework") or not isDebugEnabled() then return end
|
if not getActivatedMods():contains("PerfTestFramework") or not isDebugEnabled() then return end
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
require "TimedActions/ISBaseTimedAction"
|
require "TimedActions/ISBaseTimedAction"
|
||||||
local DataController = require("TOC/Controllers/DataController")
|
local DataController = require("TOC/Controllers/DataController")
|
||||||
|
local LocalPlayerController = require("TOC/Controllers/LocalPlayerController")
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
---@class CauterizeAction : ISBaseTimedAction
|
---@class CauterizeAction : ISBaseTimedAction
|
||||||
@@ -72,11 +73,14 @@ function CauterizeAction:perform()
|
|||||||
|
|
||||||
local dcInst = DataController.GetInstance()
|
local dcInst = DataController.GetInstance()
|
||||||
dcInst:setCicatrizationTime(self.limbName, 0)
|
dcInst:setCicatrizationTime(self.limbName, 0)
|
||||||
dcInst:setIsCicatrized(self.limbName, true)
|
|
||||||
dcInst:setIsCauterized(self.limbName, true)
|
dcInst:setIsCauterized(self.limbName, true)
|
||||||
|
|
||||||
-- we don't care about the depended limbs, since they're alread "cicatrized"
|
-- Set isCicatrized and the visuals in one go, since this action is gonna be run only on a single client
|
||||||
|
LocalPlayerController.HandleSetCicatrization(dcInst, self.character, self.limbName)
|
||||||
|
|
||||||
|
-- TODO Add specific visuals for cauterization
|
||||||
|
|
||||||
|
-- we don't care about the depended limbs, since they're alread "cicatrized"
|
||||||
dcInst:apply()
|
dcInst:apply()
|
||||||
|
|
||||||
ISBaseTimedAction.perform(self)
|
ISBaseTimedAction.perform(self)
|
||||||
|
|||||||
@@ -1,10 +1,91 @@
|
|||||||
|
-- TODO This section must be overhauled
|
||||||
|
|
||||||
|
-- local DataController = require("TOC/Controllers/DataController")
|
||||||
|
-- local StaticData = require("TOC/StaticData")
|
||||||
|
|
||||||
---@diagnostic disable: duplicate-set-field
|
---@diagnostic disable: duplicate-set-field
|
||||||
-- Bunch of actions shouldn't be modified by the adjusted time
|
-- 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 HandleSpeedSpecificAction(action, time)
|
||||||
|
-- action.skipTOC = true
|
||||||
|
-- action.maxTime = time
|
||||||
|
-- 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)
|
||||||
|
-- HandleSpeedSpecificAction(action, -1)
|
||||||
|
-- return action
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- local og_ISDetachItemHotbar_new = ISDetachItemHotbar.new
|
||||||
|
-- function ISDetachItemHotbar:new(character, item)
|
||||||
|
-- local action = og_ISDetachItemHotbar_new(self, character, item)
|
||||||
|
-- HandleSpeedSpecificAction(action, -1)
|
||||||
|
-- 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()
|
||||||
|
|
||||||
|
-- if not dcInst:getIsCut(StaticData.LIMBS_IND_STR.Hand_R) then
|
||||||
|
-- action.skipTOC = true
|
||||||
|
-- action.maxTime = time
|
||||||
|
-- action.animSpeed = 1.0
|
||||||
|
-- TOC_DEBUG.print("Skipping TOC for ISEquipWeaponAction new")
|
||||||
|
-- end
|
||||||
|
|
||||||
|
|
||||||
|
-- -- if not twoHands then
|
||||||
|
-- -- TOC_DEBUG.print("Not a two handed action, re-adding skip TOC")
|
||||||
|
-- -- HandleSpeedSpecificAction(action)
|
||||||
|
-- -- 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
|
||||||
|
|
||||||
|
-- -- For some reason (I have no clue why), if we re-run the method it breaks basically every unequip clothing action. Not for weapons though.
|
||||||
|
-- if instanceof(item, 'HandWeapon') then
|
||||||
|
-- --print("Running handlespeedspecificaction")
|
||||||
|
-- HandleSpeedSpecificAction(action)
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- return action
|
||||||
|
-- end
|
||||||
|
|
||||||
|
------------------------------------------------------
|
||||||
|
--- Normal cases
|
||||||
|
|
||||||
|
|
||||||
local og_ISEatFoodAction_new = ISEatFoodAction.new
|
local og_ISEatFoodAction_new = ISEatFoodAction.new
|
||||||
function ISEatFoodAction:new(character, item, percentage)
|
function ISEatFoodAction:new(character, item, percentage)
|
||||||
local action = og_ISEatFoodAction_new(self, character, item, percentage)
|
local action = og_ISEatFoodAction_new(self, character, item, percentage)
|
||||||
TOC_DEBUG.print("Override ISEatFoodAction")
|
--TOC_DEBUG.print("Override ISEatFoodAction")
|
||||||
action.skipTOC = true
|
action.skipTOC = true
|
||||||
return action
|
return action
|
||||||
end
|
end
|
||||||
@@ -12,7 +93,7 @@ end
|
|||||||
local og_ISReadABook_new = ISReadABook.new
|
local og_ISReadABook_new = ISReadABook.new
|
||||||
function ISReadABook:new(character, item, time)
|
function ISReadABook:new(character, item, time)
|
||||||
local action = og_ISReadABook_new(self, character, item, time)
|
local action = og_ISReadABook_new(self, character, item, time)
|
||||||
TOC_DEBUG.print("Override ISReadABook")
|
--TOC_DEBUG.print("Override ISReadABook")
|
||||||
action.skipTOC = true
|
action.skipTOC = true
|
||||||
return action
|
return action
|
||||||
end
|
end
|
||||||
@@ -20,7 +101,7 @@ end
|
|||||||
local og_ISTakePillAction_new = ISTakePillAction.new
|
local og_ISTakePillAction_new = ISTakePillAction.new
|
||||||
function ISTakePillAction:new(character, item, time)
|
function ISTakePillAction:new(character, item, time)
|
||||||
local action = og_ISTakePillAction_new(self, character, item, time)
|
local action = og_ISTakePillAction_new(self, character, item, time)
|
||||||
TOC_DEBUG.print("Override ISTakePillAction")
|
--TOC_DEBUG.print("Override ISTakePillAction")
|
||||||
action.skipTOC = true
|
action.skipTOC = true
|
||||||
return action
|
return action
|
||||||
end
|
end
|
||||||
@@ -28,7 +109,7 @@ end
|
|||||||
local og_ISTakeWaterAction_new = ISTakeWaterAction.new
|
local og_ISTakeWaterAction_new = ISTakeWaterAction.new
|
||||||
function ISTakeWaterAction:new(character, item, waterUnit, waterObject, time, oldItem)
|
function ISTakeWaterAction:new(character, item, waterUnit, waterObject, time, oldItem)
|
||||||
local action = og_ISTakeWaterAction_new(self, character, item, waterUnit, waterObject, time, oldItem)
|
local action = og_ISTakeWaterAction_new(self, character, item, waterUnit, waterObject, time, oldItem)
|
||||||
TOC_DEBUG.print("Override ISTakeWaterAction")
|
--TOC_DEBUG.print("Override ISTakeWaterAction")
|
||||||
action.skipTOC = true
|
action.skipTOC = true
|
||||||
return action
|
return action
|
||||||
end
|
end
|
||||||
@@ -36,7 +117,7 @@ end
|
|||||||
local og_ISDrinkFromBottle_new = ISDrinkFromBottle.new
|
local og_ISDrinkFromBottle_new = ISDrinkFromBottle.new
|
||||||
function ISDrinkFromBottle:new(character, item, uses)
|
function ISDrinkFromBottle:new(character, item, uses)
|
||||||
local action = og_ISDrinkFromBottle_new(self, character, item, uses)
|
local action = og_ISDrinkFromBottle_new(self, character, item, uses)
|
||||||
TOC_DEBUG.print("Override ISDrinkFromBottle")
|
--TOC_DEBUG.print("Override ISDrinkFromBottle")
|
||||||
action.skipTOC = true
|
action.skipTOC = true
|
||||||
return action
|
return action
|
||||||
end
|
end
|
||||||
@@ -44,7 +125,7 @@ end
|
|||||||
local og_ISFinalizeDealAction_new = ISFinalizeDealAction.new
|
local og_ISFinalizeDealAction_new = ISFinalizeDealAction.new
|
||||||
function ISFinalizeDealAction:new(player, otherPlayer, itemsToGive, itemsToReceive, time)
|
function ISFinalizeDealAction:new(player, otherPlayer, itemsToGive, itemsToReceive, time)
|
||||||
local action = og_ISFinalizeDealAction_new(self, player, otherPlayer, itemsToGive, itemsToReceive, time)
|
local action = og_ISFinalizeDealAction_new(self, player, otherPlayer, itemsToGive, itemsToReceive, time)
|
||||||
TOC_DEBUG.print("Override ISFinalizeDealAction")
|
--TOC_DEBUG.print("Override ISFinalizeDealAction")
|
||||||
action.skipTOC = true
|
action.skipTOC = true
|
||||||
return action
|
return action
|
||||||
end
|
end
|
||||||
@@ -52,7 +133,7 @@ end
|
|||||||
local og_ISCampingInfoAction_new = ISCampingInfoAction.new
|
local og_ISCampingInfoAction_new = ISCampingInfoAction.new
|
||||||
function ISCampingInfoAction:new(character, campfireObject, campfire)
|
function ISCampingInfoAction:new(character, campfireObject, campfire)
|
||||||
local action = og_ISCampingInfoAction_new(self, character, campfireObject, campfire)
|
local action = og_ISCampingInfoAction_new(self, character, campfireObject, campfire)
|
||||||
TOC_DEBUG.print("Override ISCampingInfoAction")
|
--TOC_DEBUG.print("Override ISCampingInfoAction")
|
||||||
action.skipTOC = true
|
action.skipTOC = true
|
||||||
return action
|
return action
|
||||||
end
|
end
|
||||||
80
media/lua/client/TOC/TimedActions/WashYourselfOverride.lua
Normal file
80
media/lua/client/TOC/TimedActions/WashYourselfOverride.lua
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
local CachedDataHandler = require("TOC/Handlers/CachedDataHandler")
|
||||||
|
local StaticData = require("TOC/StaticData")
|
||||||
|
|
||||||
|
-- Since amputations are actually clothing items, we need to override ISWashYourself to account for that
|
||||||
|
|
||||||
|
-- TODO Clean this up
|
||||||
|
|
||||||
|
local og_ISWashYourself_perform = ISWashYourself.perform
|
||||||
|
function ISWashYourself:perform()
|
||||||
|
|
||||||
|
TOC_DEBUG.print("ISWashYourself override")
|
||||||
|
|
||||||
|
---@type IsoPlayer
|
||||||
|
local pl = self.character
|
||||||
|
local plInv = pl:getInventory()
|
||||||
|
-- Search for amputations and clean them here
|
||||||
|
local amputatedLimbs = CachedDataHandler.GetAmputatedLimbs(pl:getUsername())
|
||||||
|
for limbName, _ in pairs(amputatedLimbs) do
|
||||||
|
|
||||||
|
TOC_DEBUG.print("Checking if " .. limbName .. " is in inventory and washing it")
|
||||||
|
|
||||||
|
-- get clothing item
|
||||||
|
local foundItem = plInv:FindAndReturn(StaticData.AMPUTATION_CLOTHING_ITEM_BASE .. limbName)
|
||||||
|
if foundItem and instanceof(foundItem, "Clothing") then
|
||||||
|
|
||||||
|
TOC_DEBUG.print("Washing " .. limbName)
|
||||||
|
|
||||||
|
---@cast foundItem Clothing
|
||||||
|
foundItem:setWetness(100)
|
||||||
|
foundItem:setBloodLevel(0)
|
||||||
|
foundItem:setDirtyness(0) -- TODO Integrate with other dirtyness
|
||||||
|
|
||||||
|
local coveredParts = BloodClothingType.getCoveredParts(foundItem:getBloodClothingType())
|
||||||
|
for j=0, coveredParts:size() - 1 do
|
||||||
|
foundItem:setBlood(coveredParts:get(j), 0)
|
||||||
|
foundItem:setDirt(coveredParts:get(j), 0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
og_ISWashYourself_perform(self)
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local og_ISWashYourself_GetRequiredWater = ISWashYourself.GetRequiredWater
|
||||||
|
|
||||||
|
|
||||||
|
---@param character IsoPlayer
|
||||||
|
---@return integer
|
||||||
|
function ISWashYourself.GetRequiredWater(character)
|
||||||
|
|
||||||
|
local units = og_ISWashYourself_GetRequiredWater(character)
|
||||||
|
local amputatedLimbs = CachedDataHandler.GetAmputatedLimbs(character:getUsername())
|
||||||
|
local plInv = character:getInventory()
|
||||||
|
for limbName, _ in pairs(amputatedLimbs) do
|
||||||
|
|
||||||
|
TOC_DEBUG.print("Checking if " .. limbName .. " is in inventory and washing it")
|
||||||
|
|
||||||
|
-- get clothing item
|
||||||
|
local item = plInv:FindAndReturn(StaticData.AMPUTATION_CLOTHING_ITEM_BASE .. limbName)
|
||||||
|
if item and instanceof(item, "Clothing") then
|
||||||
|
local coveredParts = BloodClothingType.getCoveredParts(item:getBloodClothingType())
|
||||||
|
if coveredParts then
|
||||||
|
for i=1,coveredParts:size() do
|
||||||
|
local part = coveredParts:get(i-1)
|
||||||
|
if item:getBlood(part) > 0 then
|
||||||
|
units = units + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return units
|
||||||
|
end
|
||||||
116
media/lua/client/TOC/UI/ConfirmationPanel.lua
Normal file
116
media/lua/client/TOC/UI/ConfirmationPanel.lua
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
---@class ConfirmationPanel : ISPanel
|
||||||
|
local ConfirmationPanel = ISPanel:derive("ConfirmationPanel")
|
||||||
|
|
||||||
|
---Starts a new confirmation panel
|
||||||
|
---@param x number
|
||||||
|
---@param y number
|
||||||
|
---@param width number
|
||||||
|
---@param height number
|
||||||
|
---@param alertText string
|
||||||
|
---@param onConfirmFunc function
|
||||||
|
---@return ConfirmationPanel
|
||||||
|
function ConfirmationPanel:new(x, y, width, height, alertText, parentPanel, onConfirmFunc)
|
||||||
|
local o = ISPanel:new(x, y, width, height)
|
||||||
|
setmetatable(o, self)
|
||||||
|
self.__index = self
|
||||||
|
|
||||||
|
o:initialise()
|
||||||
|
o.alertText = alertText
|
||||||
|
o.onConfirmFunc = onConfirmFunc
|
||||||
|
o.parentPanel = parentPanel
|
||||||
|
ConfirmationPanel.instance = o
|
||||||
|
|
||||||
|
---@cast o ConfirmationPanel
|
||||||
|
return o
|
||||||
|
end
|
||||||
|
|
||||||
|
function ConfirmationPanel:createChildren()
|
||||||
|
ISPanel.createChildren(self)
|
||||||
|
self.borderColor = { r = 1, g = 0, b = 0, a = 1 }
|
||||||
|
|
||||||
|
self.textPanel = ISRichTextPanel:new(0, 0, self.width, self.height)
|
||||||
|
self.textPanel:initialise()
|
||||||
|
self:addChild(self.textPanel)
|
||||||
|
self.textPanel.defaultFont = UIFont.Medium
|
||||||
|
self.textPanel.anchorTop = true
|
||||||
|
self.textPanel.anchorLeft = false
|
||||||
|
self.textPanel.anchorBottom = true
|
||||||
|
self.textPanel.anchorRight = false
|
||||||
|
self.textPanel.marginLeft = 0
|
||||||
|
self.textPanel.marginTop = 10
|
||||||
|
self.textPanel.marginRight = 0
|
||||||
|
self.textPanel.marginBottom = 0
|
||||||
|
self.textPanel.autosetheight = false
|
||||||
|
self.textPanel.background = false
|
||||||
|
self.textPanel:setText(self.alertText)
|
||||||
|
self.textPanel:paginate()
|
||||||
|
|
||||||
|
local yPadding = 10
|
||||||
|
local xPadding = self:getWidth() / 4
|
||||||
|
local btnWidth = 100
|
||||||
|
local btnHeight = 25
|
||||||
|
|
||||||
|
|
||||||
|
local yButton = self:getHeight() - yPadding - btnHeight
|
||||||
|
|
||||||
|
self.btnYes = ISButton:new(xPadding, yButton, btnWidth, btnHeight, "Yes", self, self.onClick)
|
||||||
|
self.btnYes.internal = "YES"
|
||||||
|
self.btnYes:initialise()
|
||||||
|
self.btnYes.borderColor = { r = 1, g = 0, b = 0, a = 1 }
|
||||||
|
self.btnYes:setEnable(true)
|
||||||
|
self:addChild(self.btnYes)
|
||||||
|
|
||||||
|
self.btnNo = ISButton:new(self:getWidth() - xPadding - btnWidth, yButton, btnWidth, btnHeight, "No", self,
|
||||||
|
self.onClick)
|
||||||
|
self.btnNo.internal = "NO"
|
||||||
|
self.btnNo:initialise()
|
||||||
|
self.btnNo:setEnable(true)
|
||||||
|
self:addChild(self.btnNo)
|
||||||
|
end
|
||||||
|
|
||||||
|
function ConfirmationPanel:onClick(btn)
|
||||||
|
if btn.internal == 'YES' then
|
||||||
|
self.onConfirmFunc(self.parentPanel)
|
||||||
|
self:close()
|
||||||
|
elseif btn.internal == 'NO' then
|
||||||
|
self:close()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
---@param alertText string
|
||||||
|
---@param x any
|
||||||
|
---@param y any
|
||||||
|
---@param parentPanel any
|
||||||
|
---@param onConfirmFunc any
|
||||||
|
---@return ConfirmationPanel
|
||||||
|
function ConfirmationPanel.Open(alertText, x, y, parentPanel, onConfirmFunc)
|
||||||
|
local width = 500
|
||||||
|
local height = 120
|
||||||
|
|
||||||
|
|
||||||
|
local screenWidth = getCore():getScreenWidth()
|
||||||
|
local screenHeight = getCore():getScreenHeight()
|
||||||
|
|
||||||
|
-- Check for oversize
|
||||||
|
if x+width > screenWidth then
|
||||||
|
x = screenWidth - width
|
||||||
|
end
|
||||||
|
|
||||||
|
if y+height > screenHeight then
|
||||||
|
y = screenHeight - height
|
||||||
|
end
|
||||||
|
|
||||||
|
local panel = ConfirmationPanel:new(x, y, width, height, alertText, parentPanel, onConfirmFunc)
|
||||||
|
panel:initialise()
|
||||||
|
panel:addToUIManager()
|
||||||
|
panel:bringToTop()
|
||||||
|
return panel
|
||||||
|
end
|
||||||
|
|
||||||
|
function ConfirmationPanel.Close()
|
||||||
|
ConfirmationPanel.instance:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
return ConfirmationPanel
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
local StaticData = require("TOC/StaticData")
|
local StaticData = require("TOC/StaticData")
|
||||||
local CommandsData = require("TOC/CommandsData")
|
|
||||||
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 Compat = require("TOC/Compat")
|
||||||
|
|
||||||
local CutLimbInteractionHandler = require("TOC/UI/Interactions/CutLimbInteractionHandler")
|
local CutLimbInteractionHandler = require("TOC/UI/Interactions/CutLimbInteractionHandler")
|
||||||
local WoundCleaningInteractionHandler = require("TOC/UI/Interactions/WoundCleaningInteractionHandler")
|
local WoundCleaningInteractionHandler = require("TOC/UI/Interactions/WoundCleaningInteractionHandler")
|
||||||
@@ -11,6 +11,9 @@ local WoundCleaningInteractionHandler = require("TOC/UI/Interactions/WoundCleani
|
|||||||
local isReady = false
|
local isReady = false
|
||||||
|
|
||||||
function SetHealthPanelTOC()
|
function SetHealthPanelTOC()
|
||||||
|
|
||||||
|
-- depending on compatibility
|
||||||
|
|
||||||
isReady = true
|
isReady = true
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -128,23 +131,23 @@ function ISHealthPanel:render()
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
local og_ISHealthPanel_update = ISHealthPanel.update
|
-- local og_ISHealthPanel_update = ISHealthPanel.update
|
||||||
function ISHealthPanel:update()
|
-- function ISHealthPanel:update()
|
||||||
og_ISHealthPanel_update(self)
|
-- og_ISHealthPanel_update(self)
|
||||||
-- TODO Listen for changes on other player side instead of looping this
|
-- -- TODO Listen for changes on other player side instead of looping this
|
||||||
|
|
||||||
|
|
||||||
-- FIX Re-enable it, just for test
|
-- -- FIX Re-enable it, just for test
|
||||||
if self.character then
|
-- if self.character then
|
||||||
local locPlUsername = getPlayer():getUsername()
|
-- local locPlUsername = getPlayer():getUsername()
|
||||||
local remPlUsername = self.character:getUsername()
|
-- local remPlUsername = self.character:getUsername()
|
||||||
if locPlUsername ~= remPlUsername and self:isReallyVisible() then
|
-- if locPlUsername ~= remPlUsername and self:isReallyVisible() then
|
||||||
-- Request update for TOC DATA
|
-- -- Request update for TOC DATA
|
||||||
local key = CommandsData.GetKey(remPlUsername)
|
-- local key = CommandsData.GetKey(remPlUsername)
|
||||||
--ModData.request(key)
|
-- --ModData.request(key)
|
||||||
end
|
-- end
|
||||||
end
|
-- end
|
||||||
end
|
-- end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -252,10 +255,10 @@ end
|
|||||||
|
|
||||||
local og_ISHealthPanel_getDamagedParts = ISHealthPanel.getDamagedParts
|
local og_ISHealthPanel_getDamagedParts = ISHealthPanel.getDamagedParts
|
||||||
function ISHealthPanel:getDamagedParts()
|
function ISHealthPanel:getDamagedParts()
|
||||||
-- TODO Overriding it is a lot easier, but ew
|
-- check for imeds or if TOC is ready to display its stuff on the health panel
|
||||||
|
if isReady == false or Compat.handlers['iMeds'].isActive or Compat.handlers['iMedsFixed'].isActive then
|
||||||
if isReady then
|
return og_ISHealthPanel_getDamagedParts(self)
|
||||||
|
elseif isReady then
|
||||||
local result = {}
|
local result = {}
|
||||||
local bodyParts = self:getPatient():getBodyDamage():getBodyParts()
|
local bodyParts = self:getPatient():getBodyDamage():getBodyParts()
|
||||||
if isClient() and not self:getPatient():isLocalPlayer() then
|
if isClient() and not self:getPatient():isLocalPlayer() then
|
||||||
@@ -274,8 +277,5 @@ function ISHealthPanel:getDamagedParts()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
return result
|
return result
|
||||||
|
|
||||||
else
|
|
||||||
return og_ISHealthPanel_getDamagedParts(self)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -1,11 +1,12 @@
|
|||||||
local BaseHandler = require("TOC/UI/Interactions/HealthPanelBaseHandler")
|
local BaseHandler = require("TOC/UI/Interactions/HealthPanelBaseHandler")
|
||||||
local StaticData = require("TOC/StaticData")
|
local StaticData = require("TOC/StaticData")
|
||||||
local DataController = require("TOC/Controllers/DataController")
|
local DataController = require("TOC/Controllers/DataController")
|
||||||
|
local ConfirmationPanel = require("TOC/UI/ConfirmationPanel")
|
||||||
|
|
||||||
local CutLimbAction = require("TOC/TimedActions/CutLimbAction")
|
local CutLimbAction = require("TOC/TimedActions/CutLimbAction")
|
||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
-- TODO Add interaction to cut and bandage!
|
|
||||||
|
|
||||||
|
|
||||||
--* Various functions to help during these pesky checks
|
--* Various functions to help during these pesky checks
|
||||||
@@ -13,7 +14,8 @@ local CutLimbAction = require("TOC/TimedActions/CutLimbAction")
|
|||||||
---Check if the item type corresponds to a compatible saw
|
---Check if the item type corresponds to a compatible saw
|
||||||
---@param itemType string
|
---@param itemType string
|
||||||
local function CheckIfSaw(itemType)
|
local function CheckIfSaw(itemType)
|
||||||
return itemType:contains(StaticData.SAWS_TYPES_IND_STR.saw) or itemType:contains(StaticData.SAWS_TYPES_IND_STR.gardenSaw)
|
return itemType == StaticData.SAWS_TYPES_IND_STR.saw
|
||||||
|
or itemType == StaticData.SAWS_TYPES_IND_STR.gardenSaw
|
||||||
end
|
end
|
||||||
|
|
||||||
---Return a compatible bandage
|
---Return a compatible bandage
|
||||||
@@ -37,9 +39,8 @@ local function GetStitchesConsumableItem(player)
|
|||||||
-- Suture needle has priority
|
-- Suture needle has priority
|
||||||
|
|
||||||
local sutureNeedle = plInv:FindAndReturn("Base.SutureNeedle")
|
local sutureNeedle = plInv:FindAndReturn("Base.SutureNeedle")
|
||||||
---@cast sutureNeedle DrainableComboItem
|
|
||||||
|
|
||||||
if sutureNeedle and sutureNeedle:getUsedDelta() > 0 then
|
if sutureNeedle then
|
||||||
return sutureNeedle
|
return sutureNeedle
|
||||||
else
|
else
|
||||||
-- Didn't find the suture one, so let's search for the normal one + thread
|
-- Didn't find the suture one, so let's search for the normal one + thread
|
||||||
@@ -61,6 +62,12 @@ local function GetStitchesConsumableItem(player)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local textConfirmAmp = getText("IGUI_Confirmation_Amputate")
|
||||||
|
local textAmp = getText("ContextMenu_Amputate")
|
||||||
|
local textAmpBandage = getText("ContextMenu_Amputate_Bandage")
|
||||||
|
local textAmpStitch = getText("ContextMenu_Amputate_Stitch")
|
||||||
|
local textAmpStitchBandage = getText("ContextMenu_Amputate_Stitch_Bandage")
|
||||||
|
|
||||||
---Add the action to the queue
|
---Add the action to the queue
|
||||||
---@param limbName string
|
---@param limbName string
|
||||||
---@param surgeon IsoPlayer
|
---@param surgeon IsoPlayer
|
||||||
@@ -69,6 +76,14 @@ end
|
|||||||
---@param stitchesItem InventoryItem?
|
---@param stitchesItem InventoryItem?
|
||||||
---@param bandageItem InventoryItem?
|
---@param bandageItem InventoryItem?
|
||||||
local function PerformAction(surgeon, patient, limbName, sawItem, stitchesItem, bandageItem)
|
local function PerformAction(surgeon, patient, limbName, sawItem, stitchesItem, bandageItem)
|
||||||
|
|
||||||
|
|
||||||
|
local x = (getCore():getScreenWidth() - 500) / 2
|
||||||
|
local y = getCore():getScreenHeight() / 2
|
||||||
|
|
||||||
|
|
||||||
|
ConfirmationPanel.Open(textConfirmAmp, x, y, nil, function()
|
||||||
|
|
||||||
-- get saw in hand
|
-- get saw in hand
|
||||||
-- todo primary or secondary depending on amputation status of surgeon
|
-- todo primary or secondary depending on amputation status of surgeon
|
||||||
ISTimedActionQueue.add(ISEquipWeaponAction:new(surgeon, sawItem, 50, true, false))
|
ISTimedActionQueue.add(ISEquipWeaponAction:new(surgeon, sawItem, 50, true, false))
|
||||||
@@ -80,13 +95,13 @@ local function PerformAction(surgeon, patient, limbName, sawItem, stitchesItem,
|
|||||||
|
|
||||||
|
|
||||||
ISTimedActionQueue.add(CutLimbAction:new(surgeon, patient, limbName, sawItem, stitchesItem, bandageItem))
|
ISTimedActionQueue.add(CutLimbAction:new(surgeon, patient, limbName, sawItem, stitchesItem, bandageItem))
|
||||||
|
|
||||||
|
end)
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
local textAmp = getText("ContextMenu_Amputate")
|
|
||||||
local textAmpBandage = getText("ContextMenu_Amputate_Bandage")
|
|
||||||
local textAmpStitch = getText("ContextMenu_Amputate_Stitch")
|
|
||||||
local textAmpStitchBandage = getText("ContextMenu_Amputate_Stitch_Bandage")
|
|
||||||
|
|
||||||
---Adds the actions to the inventory context menu
|
---Adds the actions to the inventory context menu
|
||||||
---@param player IsoPlayer
|
---@param player IsoPlayer
|
||||||
@@ -214,6 +229,18 @@ function CutLimbInteractionHandler:checkItem(item)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
---@param x number
|
||||||
|
---@param y number
|
||||||
|
---@param type any
|
||||||
|
function CutLimbInteractionHandler:openConfirmation(x, y, type)
|
||||||
|
ConfirmationPanel.Open(textConfirmAmp, x, y, nil, function()
|
||||||
|
self.onMenuOptionSelected(self, type)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
---@param context ISContextMenu
|
---@param context ISContextMenu
|
||||||
function CutLimbInteractionHandler:addToMenu(context)
|
function CutLimbInteractionHandler:addToMenu(context)
|
||||||
--TOC_DEBUG.print("CutLimbInteractionHandler addToMenu")
|
--TOC_DEBUG.print("CutLimbInteractionHandler addToMenu")
|
||||||
@@ -221,8 +248,12 @@ function CutLimbInteractionHandler:addToMenu(context)
|
|||||||
local patientUsername = self:getPatient():getUsername()
|
local patientUsername = self:getPatient():getUsername()
|
||||||
if #types > 0 and StaticData.LIMBS_TO_BODYLOCS_IND_BPT[self.limbName] and not DataController.GetInstance(patientUsername):getIsCut(self.limbName) then
|
if #types > 0 and StaticData.LIMBS_TO_BODYLOCS_IND_BPT[self.limbName] and not DataController.GetInstance(patientUsername):getIsCut(self.limbName) then
|
||||||
TOC_DEBUG.print("addToMenu, types > 0")
|
TOC_DEBUG.print("addToMenu, types > 0")
|
||||||
|
|
||||||
|
local x = (getCore():getScreenWidth() - 500) / 2
|
||||||
|
local y = getCore():getScreenHeight() / 2
|
||||||
|
|
||||||
for i=1, #types do
|
for i=1, #types do
|
||||||
context:addOption(getText("ContextMenu_Amputate"), self, self.onMenuOptionSelected, types[i])
|
context:addOption(getText("ContextMenu_Amputate"), self, self.openConfirmation, x, y, types[i])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,151 +1,157 @@
|
|||||||
-- todo activate after some more testing
|
require "lua_timers"
|
||||||
|
|
||||||
|
local ItemsController = require("TOC/Controllers/ItemsController")
|
||||||
|
local StaticData = require("TOC/StaticData")
|
||||||
|
local CommandsData = require("TOC/CommandsData")
|
||||||
|
-------------------------------
|
||||||
|
|
||||||
|
---@param zombie IsoZombie|IsoGameCharacter|IsoMovingObject|IsoObject
|
||||||
|
---@return integer trueID
|
||||||
|
local function GetZombieID(zombie)
|
||||||
|
-- Big love to Chuck and Sir Doggy Jvla for this code
|
||||||
|
---@diagnostic disable-next-line: param-type-mismatch
|
||||||
|
local pID = zombie:getPersistentOutfitID()
|
||||||
|
local bits = string.split(string.reverse(Long.toUnsignedString(pID, 2)), "")
|
||||||
|
while #bits < 16 do bits[#bits + 1] = 0 end
|
||||||
|
|
||||||
|
-- trueID
|
||||||
|
bits[16] = 0
|
||||||
|
local trueID = Long.parseUnsignedLong(string.reverse(table.concat(bits, "")), 2)
|
||||||
|
|
||||||
|
return trueID
|
||||||
|
end
|
||||||
|
|
||||||
|
-------------------------------
|
||||||
|
|
||||||
|
|
||||||
-- local ItemsController = require("TOC/Controllers/ItemsController")
|
---@param item InventoryItem
|
||||||
-- local StaticData = require("TOC/StaticData")
|
local function PredicateAmputationItems(item)
|
||||||
-- local CommandsData = require("TOC/CommandsData")
|
return item:getType():contains("Amputation_")
|
||||||
-- -------------------------------
|
end
|
||||||
|
|
||||||
-- ---@param item InventoryItem
|
---@param item InventoryItem
|
||||||
-- local function PredicateAmputationItems(item)
|
local function PredicateAmputationItemLeft(item)
|
||||||
-- return item:getType():contains("Amputation_")
|
return item:getType():contains("Amputation_") and item:getType():contains("_L")
|
||||||
-- end
|
end
|
||||||
|
|
||||||
|
---@param item InventoryItem
|
||||||
|
local function PredicateAmputationItemRight(item)
|
||||||
|
return item:getType():contains("Amputation_") and item:getType():contains("_R")
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param zombie IsoZombie
|
||||||
|
local function SpawnAmputation(zombie, side)
|
||||||
|
local index = ZombRand(1, #StaticData.PARTS_STR)
|
||||||
|
local limb = StaticData.PARTS_STR[index] .. "_" .. side
|
||||||
|
local amputationFullType = StaticData.AMPUTATION_CLOTHING_ITEM_BASE .. limb
|
||||||
|
|
||||||
|
|
||||||
|
ItemsController.Zombie.SpawnAmputationItem(zombie, amputationFullType)
|
||||||
-- local function PredicateAmputationItemLeft(item)
|
|
||||||
-- return item:getType():contains("Amputation_") and item:getType():contains("_L")
|
|
||||||
-- end
|
|
||||||
|
|
||||||
-- local function PredicateAmputationItemRight(item)
|
|
||||||
-- return item:getType():contains("Amputation_") and item:getType():contains("_R")
|
|
||||||
-- end
|
|
||||||
|
|
||||||
-- ---@param zombie IsoZombie|IsoGameCharacter|IsoMovingObject|IsoObject
|
|
||||||
-- ---@return integer trueID
|
|
||||||
-- local function GetZombieID(zombie)
|
|
||||||
|
|
||||||
-- -- Big love to Chuck and Sir Doggy Jvla for this code
|
|
||||||
-- ---@diagnostic disable-next-line: param-type-mismatch
|
|
||||||
-- local pID = zombie:getPersistentOutfitID()
|
|
||||||
-- local bits = string.split(string.reverse(Long.toUnsignedString(pID, 2)), "")
|
|
||||||
-- while #bits < 16 do bits[#bits+1] = 0 end
|
|
||||||
|
|
||||||
-- -- trueID
|
|
||||||
-- bits[16] = 0
|
|
||||||
-- local trueID = Long.parseUnsignedLong(string.reverse(table.concat(bits, "")), 2)
|
|
||||||
|
|
||||||
-- return trueID
|
|
||||||
-- end
|
|
||||||
|
|
||||||
|
|
||||||
-- ---@param zombie IsoZombie
|
-- Add reference and transmit it to server
|
||||||
-- local function SpawnAmputation(zombie, side)
|
local pID = GetZombieID(zombie)
|
||||||
-- local index = ZombRand(1, #StaticData.PARTS_STR)
|
local zombieKey = CommandsData.GetZombieKey()
|
||||||
-- local limb = StaticData.PARTS_STR[index] .. "_" .. side
|
local zombiesMD = ModData.getOrCreate(zombieKey)
|
||||||
-- local amputationFullType = StaticData.AMPUTATION_CLOTHING_ITEM_BASE .. limb
|
if zombiesMD[pID] == nil then zombiesMD[pID] = {} end
|
||||||
|
zombiesMD[pID][side] = amputationFullType
|
||||||
|
ModData.add(zombieKey, zombiesMD)
|
||||||
|
ModData.transmit(zombieKey)
|
||||||
|
end
|
||||||
|
|
||||||
|
-------------------------------
|
||||||
|
|
||||||
|
local bloodAmount = 10
|
||||||
|
|
||||||
|
|
||||||
-- ItemsController.Zombie.SpawnAmputationItem(zombie, amputationFullType)
|
---@param player IsoGameCharacter
|
||||||
|
---@param zombie IsoZombie
|
||||||
|
---@param handWeapon HandWeapon
|
||||||
|
local function HandleZombiesAmputations(player, zombie, handWeapon, damage)
|
||||||
|
if not SandboxVars.TOC.EnableZombieAmputations then return end
|
||||||
|
|
||||||
|
if not instanceof(zombie, "IsoZombie") or not instanceof(player, "IsoPlayer") then return end
|
||||||
|
if player ~= getPlayer() then return end
|
||||||
|
|
||||||
|
-- Check type of weapon. No hands, only knifes or such
|
||||||
|
local weaponCategories = handWeapon:getScriptItem():getCategories()
|
||||||
|
if not (weaponCategories:contains("Axe") or weaponCategories:contains("LongBlade")) then return end
|
||||||
|
|
||||||
|
local isCrit = player:isCriticalHit()
|
||||||
|
local randomChance = ZombRand(0, 100) > (100 - SandboxVars.TOC.ZombieAmputationDamageChance)
|
||||||
|
if (damage > SandboxVars.TOC.ZombieAmputationDamageThreshold and randomChance) or isCrit then
|
||||||
|
TOC_DEBUG.print("Amputating zombie limbs - damage: " .. tostring(damage))
|
||||||
|
local zombieInv = zombie:getInventory()
|
||||||
|
|
||||||
|
-- Check left or right
|
||||||
|
local randSide = ZombRand(2) -- Random side
|
||||||
|
local preferredSide = randSide == 0 and "L" or "R"
|
||||||
|
local alternateSide = preferredSide == "L" and "R" or "L"
|
||||||
|
|
||||||
|
local predicatePreferred = preferredSide == "L" and PredicateAmputationItemLeft or PredicateAmputationItemRight
|
||||||
|
local predicateAlternate = alternateSide == "L" and PredicateAmputationItemLeft or PredicateAmputationItemRight
|
||||||
|
|
||||||
|
if not zombieInv:containsEval(predicatePreferred) then
|
||||||
|
SpawnAmputation(zombie, preferredSide)
|
||||||
|
elseif not zombieInv:containsEval(predicateAlternate) then
|
||||||
|
SpawnAmputation(zombie, alternateSide)
|
||||||
|
end
|
||||||
|
|
||||||
|
TOC_DEBUG.print("Amputating zombie limbs - damage: " .. tostring(damage) .. ", preferred limb side: " .. preferredSide)
|
||||||
|
|
||||||
|
-- add blood splat every couple of seconds for a while
|
||||||
|
addBloodSplat(getCell():getGridSquare(zombie:getX(), zombie:getY(), zombie:getZ()), bloodAmount)
|
||||||
|
local timerName = tostring(GetZombieID(zombie)) .. "_timer"
|
||||||
|
timer:Create(timerName, 1, 10, function()
|
||||||
|
addBloodSplat(getCell():getGridSquare(zombie:getX(), zombie:getY(), zombie:getZ()), bloodAmount)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Events.OnWeaponHitCharacter.Add(HandleZombiesAmputations)
|
||||||
|
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
local localOnlyZombiesMD
|
||||||
|
|
||||||
|
local function SetupZombiesModData()
|
||||||
|
if not SandboxVars.TOC.EnableZombieAmputations then return end
|
||||||
|
local zombieKey = CommandsData.GetZombieKey()
|
||||||
|
localOnlyZombiesMD = ModData.getOrCreate(zombieKey)
|
||||||
|
end
|
||||||
|
|
||||||
|
Events.OnInitGlobalModData.Add(SetupZombiesModData)
|
||||||
|
|
||||||
|
|
||||||
-- -- Add reference and transmit it to server
|
---@param zombie IsoZombie
|
||||||
-- local pID = GetZombieID(zombie)
|
local function ReapplyAmputation(zombie)
|
||||||
-- local zombieKey = CommandsData.GetZombieKey()
|
if not SandboxVars.TOC.EnableZombieAmputations then return end
|
||||||
-- local zombiesMD = ModData.getOrCreate(zombieKey)
|
|
||||||
-- if zombiesMD[pID] == nil then zombiesMD[pID] = {} end
|
|
||||||
-- zombiesMD[pID][side] = amputationFullType
|
|
||||||
-- ModData.add(zombieKey, zombiesMD)
|
|
||||||
-- ModData.transmit(zombieKey)
|
|
||||||
-- end
|
|
||||||
|
|
||||||
-- -------------------------------
|
local pID = GetZombieID(zombie)
|
||||||
|
|
||||||
-- ---@param player IsoGameCharacter
|
|
||||||
-- ---@param zombie IsoZombie
|
|
||||||
-- ---@param handWeapon HandWeapon
|
|
||||||
-- function HandleZombiesAmputations(player, zombie, handWeapon, damage)
|
|
||||||
-- if not instanceof(zombie, "IsoZombie") or not instanceof(player, "IsoPlayer") then return end
|
|
||||||
-- if player ~= getPlayer() then return end
|
|
||||||
|
|
||||||
-- -- TODO Check type of weapon. No hands, only knifes or such
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- if damage < 3 or ZombRand(0,100) < 25 then return end
|
|
||||||
|
|
||||||
-- TOC_DEBUG.print(handWeapon:getName())
|
|
||||||
|
|
||||||
|
|
||||||
-- local zombieInv = zombie:getInventory()
|
|
||||||
|
|
||||||
|
|
||||||
-- -- Check left or right
|
|
||||||
-- local leftItem = zombieInv:containsEval(PredicateAmputationItemLeft)
|
|
||||||
|
|
||||||
-- if not leftItem then
|
|
||||||
-- SpawnAmputation(zombie, "L")
|
|
||||||
-- return
|
|
||||||
-- end
|
|
||||||
|
|
||||||
|
|
||||||
-- local rightItem = zombieInv:containsEval(PredicateAmputationItemRight)
|
|
||||||
-- if not rightItem then
|
|
||||||
-- SpawnAmputation(zombie, "R")
|
|
||||||
-- return
|
|
||||||
-- end
|
|
||||||
-- end
|
|
||||||
|
|
||||||
|
|
||||||
-- Events.OnWeaponHitCharacter.Add(HandleZombiesAmputations)
|
|
||||||
|
|
||||||
-- -----------------------------
|
|
||||||
|
|
||||||
-- local localOnlyZombiesMD
|
|
||||||
|
|
||||||
-- local function SetupZombiesModData()
|
|
||||||
-- local zombieKey = CommandsData.GetZombieKey()
|
|
||||||
-- localOnlyZombiesMD = ModData.getOrCreate(zombieKey)
|
|
||||||
|
|
||||||
-- end
|
|
||||||
|
|
||||||
-- Events.OnInitGlobalModData.Add(SetupZombiesModData)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- ---@param zombie IsoZombie
|
|
||||||
-- local function ReapplyAmputation(zombie)
|
|
||||||
-- local pID = GetZombieID(zombie)
|
|
||||||
|
|
||||||
-- if localOnlyZombiesMD[pID] ~= nil then
|
|
||||||
-- -- check if zombie has amputation
|
|
||||||
-- local zombiesAmpData = localOnlyZombiesMD[pID]
|
|
||||||
-- local zombieInv = zombie:getInventory()
|
|
||||||
-- local foundItem = zombieInv:containsEvalRecurse(PredicateAmputationItems)
|
|
||||||
|
|
||||||
-- if foundItem then
|
|
||||||
-- return
|
|
||||||
-- else
|
|
||||||
-- local leftAmp = zombiesAmpData['L']
|
|
||||||
-- if leftAmp then
|
|
||||||
-- ItemsController.Zombie.SpawnAmputationItem(zombie, leftAmp)
|
|
||||||
-- end
|
|
||||||
|
|
||||||
-- local rightAmp = zombiesAmpData['R']
|
|
||||||
-- if rightAmp then
|
|
||||||
-- ItemsController.Zombie.SpawnAmputationItem(zombie, rightAmp)
|
|
||||||
-- end
|
|
||||||
|
|
||||||
-- -- Removes reference, local only
|
|
||||||
-- localOnlyZombiesMD[pID] = nil
|
|
||||||
-- end
|
|
||||||
-- end
|
|
||||||
-- end
|
|
||||||
|
|
||||||
-- Events.OnZombieUpdate.Add(ReapplyAmputation)
|
|
||||||
|
|
||||||
|
if localOnlyZombiesMD[pID] ~= nil then
|
||||||
|
-- check if zombie has amputation
|
||||||
|
local zombiesAmpData = localOnlyZombiesMD[pID]
|
||||||
|
local zombieInv = zombie:getInventory()
|
||||||
|
local foundItem = zombieInv:containsEvalRecurse(PredicateAmputationItems)
|
||||||
|
|
||||||
|
if foundItem then
|
||||||
|
return
|
||||||
|
else
|
||||||
|
local leftAmp = zombiesAmpData['L']
|
||||||
|
if leftAmp then
|
||||||
|
ItemsController.Zombie.SpawnAmputationItem(zombie, leftAmp)
|
||||||
|
end
|
||||||
|
|
||||||
|
local rightAmp = zombiesAmpData['R']
|
||||||
|
if rightAmp then
|
||||||
|
ItemsController.Zombie.SpawnAmputationItem(zombie, rightAmp)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Removes reference, local only
|
||||||
|
localOnlyZombiesMD[pID] = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Events.OnZombieUpdate.Add(ReapplyAmputation)
|
||||||
|
|||||||
216
media/lua/client/lua_timers.lua
Normal file
216
media/lua/client/lua_timers.lua
Normal file
@@ -0,0 +1,216 @@
|
|||||||
|
-- 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
|
||||||
@@ -3,14 +3,9 @@ local StaticData = require("TOC/StaticData")
|
|||||||
local CommandsData = require("TOC/CommandsData")
|
local CommandsData = require("TOC/CommandsData")
|
||||||
------------------------
|
------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
local ServerDataHandler = {}
|
local ServerDataHandler = {}
|
||||||
ServerDataHandler.modData = {}
|
ServerDataHandler.modData = {}
|
||||||
|
|
||||||
|
|
||||||
---Get the server mod data table containing that player TOC data
|
---Get the server mod data table containing that player TOC data
|
||||||
---@param key string
|
---@param key string
|
||||||
---@return tocModDataType
|
---@return tocModDataType
|
||||||
@@ -29,12 +24,15 @@ 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
|
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
|
||||||
|
|
||||||
|
|
||||||
|
-- Check integrity of table. if it doesn't contains toc data, it means that we received a reset
|
||||||
|
if table.limbs == nil then return end
|
||||||
|
|
||||||
-- Since this could be triggered by a different client than the one referenced in the key, we're gonna
|
-- Since this could be triggered by a different client than the one referenced in the key, we're gonna
|
||||||
-- apply the changes back to the key client again to be sure that everything is in sync
|
-- apply the changes back to the key client again to be sure that everything is in sync
|
||||||
local username = CommandsData.GetUsername(key)
|
local username = CommandsData.GetUsername(key)
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ function ServerRelayCommands.RelayExecuteAmputationAction(surgeonPl, args)
|
|||||||
local surgeonNum = surgeonPl:getOnlineID()
|
local surgeonNum = surgeonPl:getOnlineID()
|
||||||
|
|
||||||
---@type receiveDamageDuringAmputationParams
|
---@type receiveDamageDuringAmputationParams
|
||||||
local params = {surgeonNum = surgeonNum, limbName = args.limbName}
|
local params = {surgeonNum = surgeonNum, limbName = args.limbName, damagePlayer = true}
|
||||||
sendServerCommand(patientPl, CommandsData.modules.TOC_RELAY, CommandsData.client.Relay.ReceiveExecuteAmputationAction, params)
|
sendServerCommand(patientPl, CommandsData.modules.TOC_RELAY, CommandsData.client.Relay.ReceiveExecuteAmputationAction, params)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -38,6 +38,21 @@ function ServerRelayCommands.RelayExecuteInitialization(adminObj, args)
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---Relay a forced amputation to another client.
|
||||||
|
---@param adminObj IsoPlayer
|
||||||
|
---@param args relayForcedAmputationParams
|
||||||
|
function ServerRelayCommands.RelayForcedAmputation(adminObj, args)
|
||||||
|
local patientPl = getPlayerByOnlineID(args.patientNum)
|
||||||
|
local adminNum = adminObj:getOnlineID()
|
||||||
|
|
||||||
|
---@type receiveDamageDuringAmputationParams
|
||||||
|
local ampParams = {surgeonNum = adminNum, limbName = args.limbName, damagePlayer = false} -- the only difference between relayExecuteAmputationAction and this is the damage
|
||||||
|
sendServerCommand(patientPl, CommandsData.modules.TOC_RELAY, CommandsData.client.Relay.ReceiveExecuteAmputationAction, ampParams)
|
||||||
|
|
||||||
|
-- Automatic cicatrization
|
||||||
|
sendServerCommand(patientPl, CommandsData.modules.TOC_RELAY, CommandsData.client.Relay.ReceiveForcedCicatrization, {limbName = args.limbName})
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-------------------------
|
-------------------------
|
||||||
|
|||||||
@@ -11,14 +11,14 @@ CommandsData.modules = {
|
|||||||
CommandsData.client = {
|
CommandsData.client = {
|
||||||
Relay = {
|
Relay = {
|
||||||
ReceiveDamageDuringAmputation = "ReceiveDamageDuringAmputation", ---@alias receiveDamageDuringAmputationParams { limbName : string}
|
ReceiveDamageDuringAmputation = "ReceiveDamageDuringAmputation", ---@alias receiveDamageDuringAmputationParams { limbName : string}
|
||||||
ReceiveExecuteAmputationAction = "ReceiveExecuteAmputationAction", ---@alias receiveExecuteAmputationActionParams {surgeonNum : number, limbName : string}
|
ReceiveExecuteAmputationAction = "ReceiveExecuteAmputationAction", ---@alias receiveExecuteAmputationActionParams {surgeonNum : number, limbName : string, damagePlayer : boolean}
|
||||||
|
|
||||||
--* APPLY *--
|
--* APPLY *--
|
||||||
ReceiveApplyFromServer = "ReceiveApplyFromServer",
|
ReceiveApplyFromServer = "ReceiveApplyFromServer",
|
||||||
|
|
||||||
--* ADMIN ONLY --*
|
--* ADMIN ONLY --*
|
||||||
ReceiveExecuteInitialization = "ReceiveExecuteInitialization"
|
ReceiveExecuteInitialization = "ReceiveExecuteInitialization",
|
||||||
|
ReceiveForcedCicatrization = "ReceiveForcedCicatrization" ---@alias receiveForcedCicatrizationParams {limbName : string}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,8 +31,10 @@ CommandsData.server = {
|
|||||||
Relay = {
|
Relay = {
|
||||||
RelayDamageDuringAmputation = "RelayDamageDuringAmputation", ---@alias relayDamageDuringAmputationParams {patientNum : number, limbName : string}
|
RelayDamageDuringAmputation = "RelayDamageDuringAmputation", ---@alias relayDamageDuringAmputationParams {patientNum : number, limbName : string}
|
||||||
RelayExecuteAmputationAction = "RelayExecuteAmputationAction", ---@alias relayExecuteAmputationActionParams {patientNum : number, limbName : string}
|
RelayExecuteAmputationAction = "RelayExecuteAmputationAction", ---@alias relayExecuteAmputationActionParams {patientNum : number, limbName : string}
|
||||||
|
|
||||||
--* ADMIN ONLY *--
|
--* ADMIN ONLY *--
|
||||||
RelayExecuteInitialization = "RelayExecuteInitialization" ---@alias relayExecuteInitializationParams {patientNum : number}
|
RelayExecuteInitialization = "RelayExecuteInitialization", ---@alias relayExecuteInitializationParams {patientNum : number}
|
||||||
|
RelayForcedAmputation = "RelayForcedAmputation" ---@alias relayForcedAmputationParams {patientNum : number, limbName : string}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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 }
|
---@alias tocModDataType { limbs : limbsTable, prostheses : prosthesesTable, isIgnoredPartInfected : boolean, isAnyLimbCut : boolean, isUpdateFromServer : boolean, isInitializing : boolean}
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
|
|
||||||
@@ -232,9 +232,9 @@ end
|
|||||||
|
|
||||||
-- Link a trait to a specific body part
|
-- Link a trait to a specific body part
|
||||||
StaticData.TRAITS_BP = {
|
StaticData.TRAITS_BP = {
|
||||||
AmputeeHand = "Hand_L",
|
Amputee_Hand = "Hand_L",
|
||||||
AmputeeLowerArm = "ForeArm_L",
|
Amputee_ForeArm = "ForeArm_L",
|
||||||
AmputeeUpeerArm = "UpperArm_L"
|
Amputee_UpperArm = "UpperArm_L"
|
||||||
}
|
}
|
||||||
|
|
||||||
-----------------
|
-----------------
|
||||||
|
|||||||
49
media/lua/shared/TOC/Traits.lua
Normal file
49
media/lua/shared/TOC/Traits.lua
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
|
||||||
|
---Setups the custom TOC traits
|
||||||
|
|
||||||
|
local TRAITS = {
|
||||||
|
Amputee_Hand = "Amputee_Hand",
|
||||||
|
Amputee_ForeArm = "Amputee_ForeArm",
|
||||||
|
Amputee_UpperArm = "Amputee_UpperArm",
|
||||||
|
--Insensitive = "Insensitive" -- TODO Disabled for now, until we reintroduce it
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
local function GetTraitText(trait)
|
||||||
|
return getText("UI_trait_" .. trait)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function GetTraitDesc(trait)
|
||||||
|
return getText("UI_trait_" .. trait .. "_desc")
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local function SetupTraits()
|
||||||
|
-- Perks.Left_Hand is defined in perks.txt
|
||||||
|
|
||||||
|
local traitsTable = {
|
||||||
|
[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),
|
||||||
|
[3] = TraitFactory.addTrait(TRAITS.Amputee_UpperArm, GetTraitText(TRAITS.Amputee_UpperArm), -20, GetTraitDesc(TRAITS.Amputee_UpperArm), false, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
for i=1, #traitsTable do
|
||||||
|
|
||||||
|
---@type Trait
|
||||||
|
local t = traitsTable[i]
|
||||||
|
---@diagnostic disable-next-line: undefined-field
|
||||||
|
t:addXPBoost(Perks.Left_Hand, 4)
|
||||||
|
t:addXPBoost(Perks.Fitness, -1)
|
||||||
|
t:addXPBoost(Perks.Strength, -1)
|
||||||
|
end
|
||||||
|
|
||||||
|
--TraitFactory.addTrait(TRAITS.Insensitive, GetTraitText(TRAITS.Insensitive), 6, GetTraitDesc(TRAITS.Insensitive), false, false)
|
||||||
|
|
||||||
|
TraitFactory.setMutualExclusive(TRAITS.Amputee_Hand, TRAITS.Amputee_ForeArm)
|
||||||
|
TraitFactory.setMutualExclusive(TRAITS.Amputee_Hand, TRAITS.Amputee_UpperArm)
|
||||||
|
TraitFactory.setMutualExclusive(TRAITS.Amputee_ForeArm, TRAITS.Amputee_UpperArm)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Events.OnGameBoot.Add(SetupTraits)
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
UI_DE = {
|
UI_DE = {
|
||||||
UI_trait_Amputee_Hand = "Amputierte linke Hand",
|
UI_trait_Amputee_Hand = "Amputierte linke Hand",
|
||||||
UI_trait_Amputee_Hand_desc = "",
|
UI_trait_Amputee_Hand_desc = "",
|
||||||
UI_trait_Amputee_LowerArm = "Amputierter linker Unterarm",
|
UI_trait_Amputee_ForeArm = "Amputierter linker Unterarm",
|
||||||
UI_trait_Amputee_LowerArm_desc = "",
|
UI_trait_Amputee_ForeArm_desc = "",
|
||||||
UI_trait_Amputee_UpperArm = "Amputierter linker Oberarm",
|
UI_trait_Amputee_UpperArm = "Amputierter linker Oberarm",
|
||||||
UI_trait_Amputee_UpperArm_desc = "",
|
UI_trait_Amputee_UpperArm_desc = "",
|
||||||
UI_trait_Insensitive = "Unempfindlich",
|
UI_trait_Insensitive = "Unempfindlich",
|
||||||
|
|||||||
@@ -15,4 +15,6 @@ IG_UI_EN = {
|
|||||||
IGUI_HealthPanel_WoundDirtyness = "Wound Dirtyness",
|
IGUI_HealthPanel_WoundDirtyness = "Wound Dirtyness",
|
||||||
IGUI_HealthPanel_ProstEquipped = "Prosthesis Equipped",
|
IGUI_HealthPanel_ProstEquipped = "Prosthesis Equipped",
|
||||||
|
|
||||||
|
IGUI_Confirmation_Amputate = " <CENTRE> Do you really want to amputate that limb?"
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -3,5 +3,8 @@ Sandbox_EN = {
|
|||||||
Sandbox_TOC_CicatrizationSpeed = "Cicatrization Speed",
|
Sandbox_TOC_CicatrizationSpeed = "Cicatrization Speed",
|
||||||
Sandbox_TOC_WoundDirtynessMultiplier = "Wound Dirtyness Multiplier",
|
Sandbox_TOC_WoundDirtynessMultiplier = "Wound Dirtyness Multiplier",
|
||||||
Sandbox_TOC_SurgeonAbilityImportance = "Relevance of surgeon doctor ability",
|
Sandbox_TOC_SurgeonAbilityImportance = "Relevance of surgeon doctor ability",
|
||||||
|
Sandbox_TOC_EnableZombieAmputations = "Enable Zombie amputations",
|
||||||
|
Sandbox_TOC_ZombieAmputationDamageThreshold = "Zombie amputations damage treshold",
|
||||||
|
Sandbox_TOC_ZombieAmputationDamageChance = "Zombie amputations damage chance",
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -2,8 +2,8 @@ UI_EN = {
|
|||||||
UI_trait_Amputee_Hand = "Amputated Left Hand",
|
UI_trait_Amputee_Hand = "Amputated Left Hand",
|
||||||
UI_trait_Amputee_Hand_desc = "",
|
UI_trait_Amputee_Hand_desc = "",
|
||||||
|
|
||||||
UI_trait_Amputee_LowerArm = "Amputated Left Forearm",
|
UI_trait_Amputee_ForeArm = "Amputated Left Forearm",
|
||||||
UI_trait_Amputee_LowerArm_desc = "",
|
UI_trait_Amputee_ForeArm_desc = "",
|
||||||
|
|
||||||
UI_trait_Amputee_UpperArm = "Amputated Left Upper arm",
|
UI_trait_Amputee_UpperArm = "Amputated Left Upper arm",
|
||||||
UI_trait_Amputee_UpperArm_desc = "",
|
UI_trait_Amputee_UpperArm_desc = "",
|
||||||
|
|||||||
29
media/lua/shared/Translate/FR/ContextMenu_FR.txt
Normal file
29
media/lua/shared/Translate/FR/ContextMenu_FR.txt
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
ContextMenu_FR = {
|
||||||
|
ContextMenu_Amputate = "Amputer",
|
||||||
|
ContextMenu_Amputate_Bandage = "Amputer et bander",
|
||||||
|
ContextMenu_Amputate_Stitch = "Amputer et suturer",
|
||||||
|
ContextMenu_Amputate_Stitch_Bandage = "Amputer, suturer et bander",
|
||||||
|
|
||||||
|
ContextMenu_Cauterize = "Cautériser",
|
||||||
|
|
||||||
|
ContextMenu_Limb_Hand_L = "Main gauche",
|
||||||
|
ContextMenu_Limb_ForeArm_L = "Avant-bras gauche",
|
||||||
|
ContextMenu_Limb_UpperArm_L = "Bras supérieur gauche",
|
||||||
|
ContextMenu_Limb_Hand_R = "Main droite",
|
||||||
|
ContextMenu_Limb_ForeArm_R = "Avant-bras droit",
|
||||||
|
ContextMenu_Limb_UpperArm_R = "Bras supérieur droit",
|
||||||
|
|
||||||
|
ContextMenu_InstallProstRight = "Installer une prothèse sur le bras droit",
|
||||||
|
ContextMenu_InstallProstLeft = "Installer une prothèse sur le bras gauche",
|
||||||
|
|
||||||
|
ContextMenu_PutTourniquetArmLeft = "Mettre un garrot sur le bras gauche",
|
||||||
|
ContextMenu_PutTourniquetLegL = "Mettre un garrot sur la jambe gauche",
|
||||||
|
ContextMenu_PutTourniquetArmRight = "Mettre un garrot sur le bras droit",
|
||||||
|
ContextMenu_PutTourniquetLegR = "Mettre un garrot sur la jambe droite",
|
||||||
|
|
||||||
|
ContextMenu_CleanWound = "Nettoyer la plaie",
|
||||||
|
|
||||||
|
ContextMenu_Admin_TOC = "TOC",
|
||||||
|
ContextMenu_Admin_ResetTOC = "Réinitialiser les amputations",
|
||||||
|
ContextMenu_Admin_ForceAmputation = "Forcer l'amputation",
|
||||||
|
}
|
||||||
18
media/lua/shared/Translate/FR/IG_UI_FR.txt
Normal file
18
media/lua/shared/Translate/FR/IG_UI_FR.txt
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
IG_UI_FR = {
|
||||||
|
IGUI_perks_Amputations = "Amputations",
|
||||||
|
IGUI_perks_Side_R = "Côté droit",
|
||||||
|
IGUI_perks_Side_L = "Côté gauche",
|
||||||
|
IGUI_perks_Prosthesis = "Prothèse",
|
||||||
|
IGUI_perks_ProstFamiliarity = "Familiarité",
|
||||||
|
|
||||||
|
IGUI_ItemCat_Prosthesis = "Prothèse",
|
||||||
|
IGUI_ItemCat_Surgery = "Chirurgie",
|
||||||
|
IGUI_ItemCat_Amputation = "Amputation",
|
||||||
|
|
||||||
|
IGUI_HealthPanel_Cicatrization = "Cicatrisation",
|
||||||
|
IGUI_HealthPanel_Cicatrized = "Cicatrisé",
|
||||||
|
IGUI_HealthPanel_Cauterized = "Cautérisé",
|
||||||
|
IGUI_HealthPanel_WoundDirtyness = "Saleté de la plaie",
|
||||||
|
IGUI_HealthPanel_ProstEquipped = "Prothèse équipée",
|
||||||
|
|
||||||
|
}
|
||||||
11
media/lua/shared/Translate/FR/ItemName_FR.txt
Normal file
11
media/lua/shared/Translate/FR/ItemName_FR.txt
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
ItemName_FR = {
|
||||||
|
|
||||||
|
ItemName_TOC.Surg_Arm_Tourniquet_L = "Garrot",
|
||||||
|
ItemName_TOC.Surg_Arm_Tourniquet_R = "Garrot",
|
||||||
|
|
||||||
|
ItemName_TOC.Prost_NormalArm_L = "Bras prothétique",
|
||||||
|
ItemName_TOC.Prost_NormalArm_R = "Bras prothétique",
|
||||||
|
|
||||||
|
ItemName_TOC.Prost_HookArm_L = "Bras prothétique - Crochet",
|
||||||
|
ItemName_TOC.Prost_HookArm_R = "Bras prothétique - Crochet",
|
||||||
|
}
|
||||||
5
media/lua/shared/Translate/FR/Recipes_FR.txt
Normal file
5
media/lua/shared/Translate/FR/Recipes_FR.txt
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
Recipes_FR = {
|
||||||
|
Recipe_Craft_Prosthetic_Arm = "Fabriquer un bras prothétique",
|
||||||
|
Recipe_Craft_Prosthetic_Hook = "Fabriquer un crochet prothétique",
|
||||||
|
|
||||||
|
}
|
||||||
10
media/lua/shared/Translate/FR/Sandbox_FR.txt
Normal file
10
media/lua/shared/Translate/FR/Sandbox_FR.txt
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
Sandbox_FR = {
|
||||||
|
Sandbox_TOC = "Le Seul Remède",
|
||||||
|
Sandbox_TOC_CicatrizationSpeed = "Vitesse de cicatrisation",
|
||||||
|
Sandbox_TOC_WoundDirtynessMultiplier = "Multiplicateur de saleté de la plaie",
|
||||||
|
Sandbox_TOC_SurgeonAbilityImportance = "Importance de la compétence du chirurgien",
|
||||||
|
Sandbox_TOC_EnableZombieAmputations = "Activer les amputations de zombies",
|
||||||
|
Sandbox_TOC_ZombieAmputationDamageThreshold = "Seuil de dégâts pour amputations de zombies",
|
||||||
|
Sandbox_TOC_ZombieAmputationDamageChance = "Probabilité d'amputations de zombies",
|
||||||
|
|
||||||
|
}
|
||||||
10
media/lua/shared/Translate/FR/Tooltip_FR.txt
Normal file
10
media/lua/shared/Translate/FR/Tooltip_FR.txt
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
Tooltip_FR = {
|
||||||
|
|
||||||
|
Tooltip_Surgery_CantCauterize = "Vous ne pouvez pas cautériser la plaie",
|
||||||
|
|
||||||
|
Tooltip_Surgery_And = " et ",
|
||||||
|
Tooltip_Surgery_TempTooLow = "La température est encore trop basse",
|
||||||
|
Tooltip_Surgery_Coward = "Vous n'avez pas le courage de le faire",
|
||||||
|
Tooltip_Surgery_LimbNotFree = "Vous devez d'abord retirer la prothèse",
|
||||||
|
|
||||||
|
}
|
||||||
16
media/lua/shared/Translate/FR/UI_FR.txt
Normal file
16
media/lua/shared/Translate/FR/UI_FR.txt
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
UI_FR = {
|
||||||
|
UI_trait_Amputee_Hand = "Main gauche amputée",
|
||||||
|
UI_trait_Amputee_Hand_desc = "",
|
||||||
|
|
||||||
|
UI_trait_Amputee_ForeArm = "Avant-bras gauche amputé",
|
||||||
|
UI_trait_Amputee_ForeArm_desc = "",
|
||||||
|
|
||||||
|
UI_trait_Amputee_UpperArm = "Bras supérieur gauche amputé",
|
||||||
|
UI_trait_Amputee_UpperArm_desc = "",
|
||||||
|
|
||||||
|
UI_trait_Insensitive = "Insensible",
|
||||||
|
UI_trait_Insensitive_desc = "",
|
||||||
|
|
||||||
|
UI_Say_CantEquip = "Je ne peux pas l'équiper comme ça..."
|
||||||
|
|
||||||
|
}
|
||||||
33
media/lua/shared/Translate/IT/ContextMenu_IT.txt
Normal file
33
media/lua/shared/Translate/IT/ContextMenu_IT.txt
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
ContextMenu_IT = {
|
||||||
|
ContextMenu_Amputate = "Amputa",
|
||||||
|
ContextMenu_Amputate_Bandage = "Amputa e fascia",
|
||||||
|
ContextMenu_Amputate_Stitch = "Amputa e metti i punti",
|
||||||
|
ContextMenu_Amputate_Stitch_Bandage = "Amputate, metti i punti e fascia",
|
||||||
|
|
||||||
|
ContextMenu_Cauterize = "Cauterizza",
|
||||||
|
|
||||||
|
ContextMenu_Limb_Hand_L = "Mano Sinistra",
|
||||||
|
ContextMenu_Limb_ForeArm_L = "Avambraccio Sinistro",
|
||||||
|
ContextMenu_Limb_UpperArm_L = "Braccio Superiore Sinistro",
|
||||||
|
ContextMenu_Limb_Hand_R = "Mano Destra",
|
||||||
|
ContextMenu_Limb_ForeArm_R = "Avambraccio Destro",
|
||||||
|
ContextMenu_Limb_UpperArm_R = "Braccio Superiore Destro",
|
||||||
|
|
||||||
|
ContextMenu_InstallProstRight = "Installa protesi sul braccio destro",
|
||||||
|
ContextMenu_InstallProstLeft = "Installa protesi sul braccio sinistro",
|
||||||
|
|
||||||
|
ContextMenu_PutTourniquetArmLeft = "Metti laccio emostatico sul braccio sinistro",
|
||||||
|
ContextMenu_PutTourniquetLegL = "Metti laccio emostatico sulla gamba sinistra",
|
||||||
|
ContextMenu_PutTourniquetArmRight = "Metti laccio emostatico sul braccio destro",
|
||||||
|
ContextMenu_PutTourniquetLegR = "Metti laccio emostatico sulla gamba destra",
|
||||||
|
|
||||||
|
|
||||||
|
ContextMenu_CleanWound = "Pulisci ferita",
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ContextMenu_Admin_TOC = "TOC",
|
||||||
|
ContextMenu_Admin_ResetTOC = "Reset Amputations",
|
||||||
|
ContextMenu_Admin_ForceAmputation = "Force Amputation",
|
||||||
|
|
||||||
|
}
|
||||||
18
media/lua/shared/Translate/IT/IG_UI_IT.txt
Normal file
18
media/lua/shared/Translate/IT/IG_UI_IT.txt
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
IG_UI_IT = {
|
||||||
|
IGUI_perks_Amputations = "Amputazioni",
|
||||||
|
IGUI_perks_Side_R = "Parte destra",
|
||||||
|
IGUI_perks_Side_L = "Parte sinistra",
|
||||||
|
IGUI_perks_Prosthesis = "Protesi",
|
||||||
|
IGUI_perks_ProstFamiliarity= "Familiarità",
|
||||||
|
|
||||||
|
IGUI_ItemCat_Prosthesis = "Protesi",
|
||||||
|
IGUI_ItemCat_Surgery = "Operazioni mediche",
|
||||||
|
IGUI_ItemCat_Amputation = "Amputazione"
|
||||||
|
|
||||||
|
IGUI_HealthPanel_Cicatrization = "Cicatrizzazione",
|
||||||
|
IGUI_HealthPanel_Cicatrized = "Cicatrizzata",
|
||||||
|
IGUI_HealthPanel_Cauterized = "Cauterizzata",
|
||||||
|
IGUI_HealthPanel_WoundDirtyness = "Sporcizia della ferita",
|
||||||
|
IGUI_HealthPanel_ProstEquipped = "Protesi installata",
|
||||||
|
|
||||||
|
}
|
||||||
11
media/lua/shared/Translate/IT/ItemName_IT.txt
Normal file
11
media/lua/shared/Translate/IT/ItemName_IT.txt
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
ItemName_IT = {
|
||||||
|
|
||||||
|
ItemName_TOC.Surg_Arm_Tourniquet_L = "Laccio emostatico",
|
||||||
|
ItemName_TOC.Surg_Arm_Tourniquet_R = "Laccio emostatico",
|
||||||
|
|
||||||
|
ItemName_TOC.Prost_NormalArm_L = "Braccio Prostetico",
|
||||||
|
ItemName_TOC.Prost_NormalArm_R = "Braccio Prostetico",
|
||||||
|
|
||||||
|
ItemName_TOC.Prost_HookArm_L = "Braccio prostetico - Uncino",
|
||||||
|
ItemName_TOC.Prost_HookArm_R = "Braccio prostetico - Uncino",
|
||||||
|
}
|
||||||
4
media/lua/shared/Translate/IT/Recipes_IT.txt
Normal file
4
media/lua/shared/Translate/IT/Recipes_IT.txt
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
Recipes_IT = {
|
||||||
|
Recipe_Craft_Prosthetic_Arm = "Costruisci un braccio prostetico",
|
||||||
|
Recipe_Craft_Prosthetic_Hook = "Costruisci un braccio prostetico con uncino",
|
||||||
|
}
|
||||||
7
media/lua/shared/Translate/IT/Sandbox_IT.txt
Normal file
7
media/lua/shared/Translate/IT/Sandbox_IT.txt
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
Sandbox_IT = {
|
||||||
|
Sandbox_TOC = "The Only Cure",
|
||||||
|
Sandbox_TOC_CicatrizationSpeed = "Velocità cicatrizzazione",
|
||||||
|
Sandbox_TOC_WoundDirtynessMultiplier = "Moltiplicatore sporcizia ferita",
|
||||||
|
Sandbox_TOC_SurgeonAbilityImportance = "Importanza abilità medico",
|
||||||
|
|
||||||
|
}
|
||||||
10
media/lua/shared/Translate/IT/Tooltip_IT.txt
Normal file
10
media/lua/shared/Translate/IT/Tooltip_IT.txt
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
Tooltip_IT = {
|
||||||
|
|
||||||
|
Tooltip_Surgery_CantCauterize = "Non puoi cauterizzare la ferita",
|
||||||
|
|
||||||
|
Tooltip_Surgery_And = " e "
|
||||||
|
Tooltip_Surgery_TempTooLow = "La temperatura è troppo bassa",
|
||||||
|
Tooltip_Surgery_Coward = "Non sei abbastanza coraggioso",
|
||||||
|
Tooltip_Surgery_LimbNotFree = "Devi rimuovere la protesi",
|
||||||
|
|
||||||
|
}
|
||||||
16
media/lua/shared/Translate/IT/UI_IT.txt
Normal file
16
media/lua/shared/Translate/IT/UI_IT.txt
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
UI_IT = {
|
||||||
|
UI_trait_Amputee_Hand = "Mano Sinistra Amputata",
|
||||||
|
UI_trait_Amputee_Hand_desc = "",
|
||||||
|
|
||||||
|
UI_trait_Amputee_ForeArm = "Avambraccio Sinistro Amputato",
|
||||||
|
UI_trait_Amputee_ForeArm_desc = "",
|
||||||
|
|
||||||
|
UI_trait_Amputee_UpperArm = "Parte superiore del Braccio Sinistro Amputato",
|
||||||
|
UI_trait_Amputee_UpperArm_desc = "",
|
||||||
|
|
||||||
|
UI_trait_Insensitive = "Insensibile",
|
||||||
|
UI_trait_Insensitive_desc = "",
|
||||||
|
|
||||||
|
|
||||||
|
UI_Say_CantEquip = "Non posso equipaggiarlo..."
|
||||||
|
}
|
||||||
BIN
media/lua/shared/Translate/KO/ContextMenu_KO.txt
Normal file
BIN
media/lua/shared/Translate/KO/ContextMenu_KO.txt
Normal file
Binary file not shown.
BIN
media/lua/shared/Translate/KO/IG_UI_KO.txt
Normal file
BIN
media/lua/shared/Translate/KO/IG_UI_KO.txt
Normal file
Binary file not shown.
BIN
media/lua/shared/Translate/KO/ItemName_KO.txt
Normal file
BIN
media/lua/shared/Translate/KO/ItemName_KO.txt
Normal file
Binary file not shown.
BIN
media/lua/shared/Translate/KO/Recipes_KO.txt
Normal file
BIN
media/lua/shared/Translate/KO/Recipes_KO.txt
Normal file
Binary file not shown.
BIN
media/lua/shared/Translate/KO/Sandbox_KO.txt
Normal file
BIN
media/lua/shared/Translate/KO/Sandbox_KO.txt
Normal file
Binary file not shown.
BIN
media/lua/shared/Translate/KO/Tooltip_KO.txt
Normal file
BIN
media/lua/shared/Translate/KO/Tooltip_KO.txt
Normal file
Binary file not shown.
BIN
media/lua/shared/Translate/KO/UI_KO.txt
Normal file
BIN
media/lua/shared/Translate/KO/UI_KO.txt
Normal file
Binary file not shown.
33
media/lua/shared/Translate/RU/ContextMenu_RU.txt
Normal file
33
media/lua/shared/Translate/RU/ContextMenu_RU.txt
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
ContextMenu_RU = {
|
||||||
|
ContextMenu_Amputate = "Àìïóòèðîâàòü",
|
||||||
|
ContextMenu_Amputate_Bandage = "Àìïóòèðîâàòü è ïåðåâÿçàòü",
|
||||||
|
ContextMenu_Amputate_Stitch = "Àìïóòèðîâàòü è íàëîæèòü øâû",
|
||||||
|
ContextMenu_Amputate_Stitch_Bandage = "Àìïóòèðîâàòü, íàëîæèòü øâû è ïåðåâÿçàòü",
|
||||||
|
|
||||||
|
ContextMenu_Cauterize = "Ïðèæå÷ü",
|
||||||
|
|
||||||
|
ContextMenu_Limb_Hand_L = "Ëåâàÿ ðóêà",
|
||||||
|
ContextMenu_Limb_ForeArm_L = "Ëåâàÿ ïðåäïëå÷üå",
|
||||||
|
ContextMenu_Limb_UpperArm_L = "Ëåâîå ïëå÷î"
|
||||||
|
ContextMenu_Limb_Hand_R = "Ïðàâàÿ ðóêà",
|
||||||
|
ContextMenu_Limb_ForeArm_R = "Ïðàâàÿ ïðåäïëå÷üå",
|
||||||
|
ContextMenu_Limb_UpperArm_R = "Ïðàâàÿ ïëå÷î",
|
||||||
|
|
||||||
|
ContextMenu_InstallProstRight = "Óñòàíîâèòü ïðîòåç íà ïðàâóþ ðóêó",
|
||||||
|
ContextMenu_InstallProstLeft = "Óñòàíîâèòü ïðîòåç íà ëåâóþ ðóêó",
|
||||||
|
|
||||||
|
ContextMenu_PutTourniquetArmLeft = "Íàëîæèòü æãóò íà ëåâóþ ðóêó",
|
||||||
|
ContextMenu_PutTourniquetLegL = "Íàëîæèòü æãóò íà ëåâóþ íîãó",
|
||||||
|
ContextMenu_PutTourniquetArmRight = "Íàëîæèòü æãóò íà ïðàâóþ ðóêó",
|
||||||
|
ContextMenu_PutTourniquetLegR = "Íàëîæèòü æãóò íà ïðàâóþ íîãó",
|
||||||
|
|
||||||
|
|
||||||
|
ContextMenu_CleanWound = "Î÷èñòèòü ðàíó",
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ContextMenu_Admin_TOC = "TOC",
|
||||||
|
ContextMenu_Admin_ResetTOC = "Ñáðîñèòü àìïóòàöèè",
|
||||||
|
ContextMenu_Admin_ForceAmputation = "Ìîìåíòàëüíî àìïóòèðîâàòü",
|
||||||
|
|
||||||
|
}
|
||||||
18
media/lua/shared/Translate/RU/IG_UI_RU.txt
Normal file
18
media/lua/shared/Translate/RU/IG_UI_RU.txt
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
IG_UI_RU = {
|
||||||
|
IGUI_perks_Amputations = "Ампутации",
|
||||||
|
IGUI_perks_Side_R = "Правая сторона",
|
||||||
|
IGUI_perks_Side_L = "Левая сторона",
|
||||||
|
IGUI_perks_Prosthesis = "Протез",
|
||||||
|
IGUI_perks_ProstFamiliarity= "Приспособленность",
|
||||||
|
|
||||||
|
IGUI_ItemCat_Prosthesis = "Протез",
|
||||||
|
IGUI_ItemCat_Surgery = "Хирургия",
|
||||||
|
IGUI_ItemCat_Amputation = "Ампутация"
|
||||||
|
|
||||||
|
IGUI_HealthPanel_Cicatrization = "Заживление",
|
||||||
|
IGUI_HealthPanel_Cicatrized = "Заживлено",
|
||||||
|
IGUI_HealthPanel_Cauterized = "Прижженно",
|
||||||
|
IGUI_HealthPanel_WoundDirtyness = "Загрезнённая рана",
|
||||||
|
IGUI_HealthPanel_ProstEquipped = "Протез экипирован",
|
||||||
|
|
||||||
|
}
|
||||||
11
media/lua/shared/Translate/RU/ItemName_RU.txt
Normal file
11
media/lua/shared/Translate/RU/ItemName_RU.txt
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
ItemName_RU = {
|
||||||
|
|
||||||
|
ItemName_TOC.Surg_Arm_Tourniquet_L = "Æãóò",
|
||||||
|
ItemName_TOC.Surg_Arm_Tourniquet_R = "Æãóò",
|
||||||
|
|
||||||
|
ItemName_TOC.Prost_NormalArm_L = "Ïðîòåç ðóêè",
|
||||||
|
ItemName_TOC.Prost_NormalArm_R = "Ïðîòåç ðóêè",
|
||||||
|
|
||||||
|
ItemName_TOC.Prost_HookArm_L = "Ïðîòåç ðóêè - Êðþê",
|
||||||
|
ItemName_TOC.Prost_HookArm_R = "Ïðîòåç ðóêè - Êðþê",
|
||||||
|
}
|
||||||
4
media/lua/shared/Translate/RU/Recipes_RU.txt
Normal file
4
media/lua/shared/Translate/RU/Recipes_RU.txt
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
Recipes_RU = {
|
||||||
|
Recipe_Craft_Prosthetic_Arm = "如泐蝾忤螯 镳铗彗 痼觇",
|
||||||
|
Recipe_Craft_Prosthetic_Hook = "如泐蝾忤螯 镳铗彗 忖桎<E5BF96> 牮<>赅",
|
||||||
|
}
|
||||||
7
media/lua/shared/Translate/RU/Sandbox_RU.txt
Normal file
7
media/lua/shared/Translate/RU/Sandbox_RU.txt
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
Sandbox_RU = {
|
||||||
|
Sandbox_TOC = "The Only Cure",
|
||||||
|
Sandbox_TOC_CicatrizationSpeed = "Ñêîðîñòü çàæèâëåíèÿ",
|
||||||
|
Sandbox_TOC_WoundDirtynessMultiplier = "Ìíîæèòåëü çàãðÿçíåíèÿ ðàí",
|
||||||
|
Sandbox_TOC_SurgeonAbilityImportance = "Çíà÷èìîñòü ñïîñîáíîñòåé âðà÷à-õèðóðãà",
|
||||||
|
|
||||||
|
}
|
||||||
10
media/lua/shared/Translate/RU/Tooltip_RU.txt
Normal file
10
media/lua/shared/Translate/RU/Tooltip_RU.txt
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
Tooltip_RU = {
|
||||||
|
|
||||||
|
Tooltip_Surgery_CantCauterize = "Нельзя прижигать рану",
|
||||||
|
|
||||||
|
Tooltip_Surgery_And = " и "
|
||||||
|
Tooltip_Surgery_TempTooLow = "Температура все еще слишком низкая",
|
||||||
|
Tooltip_Surgery_Coward = "У тебя не хватит смелости сделать это",
|
||||||
|
Tooltip_Surgery_LimbNotFree = "Сначала нужно снять протез",
|
||||||
|
|
||||||
|
}
|
||||||
16
media/lua/shared/Translate/RU/UI_RU.txt
Normal file
16
media/lua/shared/Translate/RU/UI_RU.txt
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
UI_RU = {
|
||||||
|
UI_trait_Amputee_Hand = "Ампутированная левая рука",
|
||||||
|
UI_trait_Amputee_Hand_desc = "Вы начинаете с ампутированной левой рукой.",
|
||||||
|
|
||||||
|
UI_trait_Amputee_ForeArm = "Ампутированное левое предплечье",
|
||||||
|
UI_trait_Amputee_ForeArm_desc = "Вы начинаете с ампутированным левым предплечьем.",
|
||||||
|
|
||||||
|
UI_trait_Amputee_UpperArm = "Ампутированное левое плечо",
|
||||||
|
UI_trait_Amputee_UpperArm_desc = "Вы начинаете с ампутированнвм левым плечём.",
|
||||||
|
|
||||||
|
UI_trait_Insensitive = "Нечувствительный",
|
||||||
|
UI_trait_Insensitive_desc = "",
|
||||||
|
|
||||||
|
|
||||||
|
UI_Say_CantEquip = "Я не могу его так экипировать..."
|
||||||
|
}
|
||||||
33
media/lua/shared/Translate/UA/ContextMenu_UA.txt
Normal file
33
media/lua/shared/Translate/UA/ContextMenu_UA.txt
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
ContextMenu_UA = {
|
||||||
|
ContextMenu_Amputate = "Àìïóòóâàòè",
|
||||||
|
ContextMenu_Amputate_Bandage = "Àìïóòóâàòè òà ïåðåâ'ÿçàòè",
|
||||||
|
ContextMenu_Amputate_Stitch = "Àìïóòóâàòè òà íàêëàñòè øâè",
|
||||||
|
ContextMenu_Amputate_Stitch_Bandage = "Àìïóòóâàòè, íàêëàñòè øâè òà ïåðåâ'ÿçàòè",
|
||||||
|
|
||||||
|
ContextMenu_Cauterize = "Ïðèïåêòè",
|
||||||
|
|
||||||
|
ContextMenu_Limb_Hand_L = "˳âà Ðóêà",
|
||||||
|
ContextMenu_Limb_ForeArm_L = "˳âå Ïåðåäïë³÷÷ÿ",
|
||||||
|
ContextMenu_Limb_UpperArm_L = "˳âå Ïëå÷å"
|
||||||
|
ContextMenu_Limb_Hand_R = "Ïðàâà Ðóêà",
|
||||||
|
ContextMenu_Limb_ForeArm_R = "Ïðàâå Ïåðåäïë³÷÷ÿ",
|
||||||
|
ContextMenu_Limb_UpperArm_R = "Ïðàâå Ïëå÷å",
|
||||||
|
|
||||||
|
ContextMenu_InstallProstRight = "Óñòàíîâèòè ïðîòåç íà ïðàâó ðóêó",
|
||||||
|
ContextMenu_InstallProstLeft = "Óñòàíîâèòè ïðîòåç íà ë³âó ðóêó",
|
||||||
|
|
||||||
|
ContextMenu_PutTourniquetArmLeft = "Íàêëàñòè äæãóò íà ë³âó ðóêó",
|
||||||
|
ContextMenu_PutTourniquetLegL = "Íàêëàñòè äæãóò íà ë³âó íîãó",
|
||||||
|
ContextMenu_PutTourniquetArmRight = "Íàêëàñòè äæãóò íà ïðàâó ðóêó",
|
||||||
|
ContextMenu_PutTourniquetLegR = "Íàêëàñòè äæãóò íà ïðàâó íîãó",
|
||||||
|
|
||||||
|
|
||||||
|
ContextMenu_CleanWound = "Î÷èñòèòè ðàíó",
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ContextMenu_Admin_TOC = "TOC",
|
||||||
|
ContextMenu_Admin_ResetTOC = "Ñêèíóòè Àìïóòàö³¿",
|
||||||
|
ContextMenu_Admin_ForceAmputation = "Ïðèìóñîâî Àìïóòóâàòè",
|
||||||
|
|
||||||
|
}
|
||||||
18
media/lua/shared/Translate/UA/IG_UI_UA.txt
Normal file
18
media/lua/shared/Translate/UA/IG_UI_UA.txt
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
IG_UI_UA = {
|
||||||
|
IGUI_perks_Amputations = "Ŕěďóňŕöłż",
|
||||||
|
IGUI_perks_Side_R = "Ďđŕâŕ ńňîđîíŕ",
|
||||||
|
IGUI_perks_Side_L = "Ëłâŕ ńňîđîíŕ",
|
||||||
|
IGUI_perks_Prosthesis = "Ďđîňĺç",
|
||||||
|
IGUI_perks_ProstFamiliarity= "Ďđčńňîńîâŕíłńňü",
|
||||||
|
|
||||||
|
IGUI_ItemCat_Prosthesis = "Ďđîňĺç",
|
||||||
|
IGUI_ItemCat_Surgery = "Őłđóđăł˙",
|
||||||
|
IGUI_ItemCat_Amputation = "Ŕěďóňŕöł˙"
|
||||||
|
|
||||||
|
IGUI_HealthPanel_Cicatrization = "Đóáöţâŕíí˙",
|
||||||
|
IGUI_HealthPanel_Cicatrized = "Çŕđóáöüîâŕíŕ",
|
||||||
|
IGUI_HealthPanel_Cauterized = "Ďđčďĺ÷ĺíŕ",
|
||||||
|
IGUI_HealthPanel_WoundDirtyness = "Çŕáđóäíĺíŕ đŕíŕ",
|
||||||
|
IGUI_HealthPanel_ProstEquipped = "Ďđîňĺç óńňŕíîâëĺíî",
|
||||||
|
|
||||||
|
}
|
||||||
11
media/lua/shared/Translate/UA/ItemName_UA.txt
Normal file
11
media/lua/shared/Translate/UA/ItemName_UA.txt
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
ItemName_UA = {
|
||||||
|
|
||||||
|
ItemName_TOC.Surg_Arm_Tourniquet_L = "Äæãóò",
|
||||||
|
ItemName_TOC.Surg_Arm_Tourniquet_R = "Äæãóò",
|
||||||
|
|
||||||
|
ItemName_TOC.Prost_NormalArm_L = "Ïðîòåç Ðóêè",
|
||||||
|
ItemName_TOC.Prost_NormalArm_R = "Ïðîòåç Ðóêè",
|
||||||
|
|
||||||
|
ItemName_TOC.Prost_HookArm_L = "Ïðîòåç Ðóêè - Ãàê",
|
||||||
|
ItemName_TOC.Prost_HookArm_R = "Ïðîòåç Ðóêè - Ãàê",
|
||||||
|
}
|
||||||
4
media/lua/shared/Translate/UA/Recipes_UA.txt
Normal file
4
media/lua/shared/Translate/UA/Recipes_UA.txt
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
Recipes_UA = {
|
||||||
|
Recipe_Craft_Prosthetic_Arm = "Створити Протез Руки",
|
||||||
|
Recipe_Craft_Prosthetic_Hook = "Створити Протез Руки - Гак",
|
||||||
|
}
|
||||||
10
media/lua/shared/Translate/UA/Sandbox_UA.txt
Normal file
10
media/lua/shared/Translate/UA/Sandbox_UA.txt
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
Sandbox_UA = {
|
||||||
|
Sandbox_TOC = "The Only Cure",
|
||||||
|
Sandbox_TOC_CicatrizationSpeed = "Øâèäê³ñòü ðóáöþâàííÿ",
|
||||||
|
Sandbox_TOC_WoundDirtynessMultiplier = "Ìíîæíèê çàáðóäíåííÿ ðàíè",
|
||||||
|
Sandbox_TOC_SurgeonAbilityImportance = "Âàæëèâ³ñòü ìåäè÷íèõ íàâè÷îê ë³êàðÿ",
|
||||||
|
Sandbox_TOC_EnableZombieAmputations = "Óâ³ìêíóòè àìïóòàö³¿ çîìá³",
|
||||||
|
Sandbox_TOC_ZombieAmputationDamageThreshold = "Ïîð³ã øêîäè ïðè àìïóòàö³¿ çîìá³",
|
||||||
|
Sandbox_TOC_ZombieAmputationDamageChance = "Øàíñ íàíåñåííÿ øêîäè ïðè àìïóòàö³¿ çîìá³",
|
||||||
|
|
||||||
|
}
|
||||||
10
media/lua/shared/Translate/UA/Tooltip_UA.txt
Normal file
10
media/lua/shared/Translate/UA/Tooltip_UA.txt
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
Tooltip_UA = {
|
||||||
|
|
||||||
|
Tooltip_Surgery_CantCauterize = "Не можна припекти рану",
|
||||||
|
|
||||||
|
Tooltip_Surgery_And = " та "
|
||||||
|
Tooltip_Surgery_TempTooLow = "Температура занадто низька",
|
||||||
|
Tooltip_Surgery_Coward = "Вам не вистачає сміливості зробити це",
|
||||||
|
Tooltip_Surgery_LimbNotFree = "Спочатку необхідно зняти протез",
|
||||||
|
|
||||||
|
}
|
||||||
16
media/lua/shared/Translate/UA/UI_UA.txt
Normal file
16
media/lua/shared/Translate/UA/UI_UA.txt
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
UI_UA = {
|
||||||
|
UI_trait_Amputee_Hand = "Àìïóòîâàíà ˳âà Ðóêà",
|
||||||
|
UI_trait_Amputee_Hand_desc = "",
|
||||||
|
|
||||||
|
UI_trait_Amputee_ForeArm = "Àìïóòîâàíå ˳âå Ïåðåäïë³÷÷ÿ",
|
||||||
|
UI_trait_Amputee_ForeArm_desc = "",
|
||||||
|
|
||||||
|
UI_trait_Amputee_UpperArm = "Àìïóòîâàíå ˳âå Ïëå÷å",
|
||||||
|
UI_trait_Amputee_UpperArm_desc = "",
|
||||||
|
|
||||||
|
UI_trait_Insensitive = "Íå÷óòëèâèé",
|
||||||
|
UI_trait_Insensitive_desc = "",
|
||||||
|
|
||||||
|
|
||||||
|
UI_Say_CantEquip = "ß íå ìîæó âñòàíîâèòè öå òàêèì ÷èíîì..."
|
||||||
|
}
|
||||||
@@ -28,3 +28,31 @@ option TOC.SurgeonAbilityImportance
|
|||||||
translation = TOC_SurgeonAbilityImportance,
|
translation = TOC_SurgeonAbilityImportance,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
option TOC.EnableZombieAmputations
|
||||||
|
{
|
||||||
|
type = boolean,
|
||||||
|
default = false,
|
||||||
|
page = TOC,
|
||||||
|
translation= TOC_EnableZombieAmputations,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
option TOC.ZombieAmputationDamageThreshold
|
||||||
|
{
|
||||||
|
type = integer,
|
||||||
|
min = 0,
|
||||||
|
max = 10,
|
||||||
|
default = 4,
|
||||||
|
page = TOC,
|
||||||
|
translation = TOC_ZombieAmputationDamageThreshold,
|
||||||
|
}
|
||||||
|
|
||||||
|
option TOC.ZombieAmputationDamageChance
|
||||||
|
{
|
||||||
|
type = integer,
|
||||||
|
min = 0,
|
||||||
|
max = 100,
|
||||||
|
default = 25,
|
||||||
|
page = TOC,
|
||||||
|
translation = TOC_ZombieAmputationDamageChance,
|
||||||
|
}
|
||||||
BIN
media/ui/Traits/trait_Amputee_ForeArm.png
Normal file
BIN
media/ui/Traits/trait_Amputee_ForeArm.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
BIN
media/ui/Traits/trait_Amputee_Hand.png
Normal file
BIN
media/ui/Traits/trait_Amputee_Hand.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
BIN
media/ui/Traits/trait_Amputee_UpperArm.png
Normal file
BIN
media/ui/Traits/trait_Amputee_UpperArm.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
BIN
media/ui/Traits/trait_insensitive.png
Normal file
BIN
media/ui/Traits/trait_insensitive.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 237 B |
4
mod.info
4
mod.info
@@ -1,8 +1,8 @@
|
|||||||
name=The Only Cure
|
name=The Only Cure
|
||||||
poster=poster.png
|
poster=poster.png
|
||||||
description=Bitten? Not a problem!
|
description=You've been bitten. You have only two choices.
|
||||||
id=TheOnlyCure
|
id=TheOnlyCure
|
||||||
icon=icon.png
|
icon=icon.png
|
||||||
url=https://github.com/ZioPao/The-Only-Cure
|
url=https://github.com/ZioPao/The-Only-Cure
|
||||||
modversion=2.0
|
modversion=2.1.4
|
||||||
pzversion=41.65
|
pzversion=41.65
|
||||||
|
|||||||
@@ -5,17 +5,23 @@ description=[img]https://raw.githubusercontent.com/ZioPao/The-Only-Cure/551125bb
|
|||||||
|
|
||||||
description=
|
description=
|
||||||
|
|
||||||
|
description=
|
||||||
|
|
||||||
description=[h1]You're bitten. You have two choices.[/h1]
|
description=[h1]You're bitten. You have two choices.[/h1]
|
||||||
|
|
||||||
description=Wait until you succumb to the virus or take matters into your hands.
|
description=Wait until you succumb to the virus or take matters into your hands. Cut off that infected part and live to die another day.
|
||||||
|
|
||||||
description=
|
description=
|
||||||
|
|
||||||
description=This version of [b]The Only Cure[/b] has been rebuilt from scratch to support future additions.
|
description=This version of [b]The Only Cure[/b] has been rebuilt from scratch to support future additions and to feel as close as possible as a vanilla mechanic.
|
||||||
|
|
||||||
description=
|
description=
|
||||||
|
|
||||||
description=Supports [b]Single Player[/b] and [b]Multiplayer[/b]!
|
description=[b]If you're using an older version of The Only Cure and want to switch with this, you're gonna need to create a new character\save to prevent issues.[/b]
|
||||||
|
|
||||||
|
description=[b]The older version will be delisted shortly and it will not be supported anymore.[/b]
|
||||||
|
|
||||||
|
description=[h1]Supports [b]Single Player[/b] and [b]Multiplayer[/b]. Host Mode is currently [b]UNSUPPORTED![/b][/h1]
|
||||||
|
|
||||||
description=
|
description=
|
||||||
|
|
||||||
@@ -33,6 +39,14 @@ description=[/list]
|
|||||||
|
|
||||||
description=
|
description=
|
||||||
|
|
||||||
|
description=Place them [b]BEFORE[/b] The Only Cure in your mod list!
|
||||||
|
|
||||||
|
description=
|
||||||
|
|
||||||
|
description=[hr][/hr]
|
||||||
|
|
||||||
|
description=
|
||||||
|
|
||||||
description=[h1]Quick guide[/h1]
|
description=[h1]Quick guide[/h1]
|
||||||
|
|
||||||
description=[h2]Amputation[/h2]
|
description=[h2]Amputation[/h2]
|
||||||
@@ -41,11 +55,17 @@ description=Get a [i]Saw[/i] or a [i]Garden Saw[/i], right click on it, and choo
|
|||||||
|
|
||||||
description=
|
description=
|
||||||
|
|
||||||
description=If you have a tourniquet, place it on the correct side to dampen the amount of damage you will take after you're done amputating the limb.
|
description=If you have some [i]bandages[/i] and\or [i]stitches[/i] in your inventory you will automatically use them, multiplying the chances of your survival.
|
||||||
|
|
||||||
|
description=If you have a [i]tourniquet[/i], place it on the correct side to dampen the amount of damage you will take after you're done amputating the limb.
|
||||||
|
|
||||||
description=
|
description=
|
||||||
|
|
||||||
description=Keep in mind that if you amputate your upper arm, you won't be able to equip any prosthesis.
|
description=Keep in mind that if you amputate your [b]upper arm[/b], you won't be able to equip any prosthesis.
|
||||||
|
|
||||||
|
description=
|
||||||
|
|
||||||
|
description=After you've amputated a limb, you will gain [b]skill points[/b] for the amputated side, making timed actions faster in due time.
|
||||||
|
|
||||||
description=
|
description=
|
||||||
|
|
||||||
@@ -59,7 +79,7 @@ description=If your limb isn't completely cicatrized, you can still equip prosth
|
|||||||
|
|
||||||
description=
|
description=
|
||||||
|
|
||||||
description=[h2]Prosthesis[/h2]
|
description=[h2]Prosthetics[/h2]
|
||||||
|
|
||||||
description=If you're missing a hand, you won't be able to do a lot of things, such as equipping two-handed weapons. With prosthetics limbs, you can fix that.
|
description=If you're missing a hand, you won't be able to do a lot of things, such as equipping two-handed weapons. With prosthetics limbs, you can fix that.
|
||||||
|
|
||||||
@@ -77,22 +97,32 @@ description=
|
|||||||
|
|
||||||
description=The main difference between the twos is that your actions will take longer with the Hook Prosthesis.
|
description=The main difference between the twos is that your actions will take longer with the Hook Prosthesis.
|
||||||
|
|
||||||
|
description=When you equip a prosthetic limb, you will slowly gain skill points in the [b]Prosthesis Familiarity[/b] perk, making actions more speedy in due time.
|
||||||
|
|
||||||
description=
|
description=
|
||||||
|
|
||||||
description=[h1]Issues[/h1]
|
description=[h2]Admin tools[/h2]
|
||||||
|
|
||||||
description=Got any issues? Report them on GitHub!
|
description=If something strange happened, an admin can reset TOC mechanics on any player by right clicking on them and select [i]"Reset Amputations"[/i]. They could also do the opposite by clicking on [i]"Force Amputation"[/i] for each amputable limb.
|
||||||
|
|
||||||
|
description=
|
||||||
|
|
||||||
|
description=[hr][/hr]
|
||||||
|
|
||||||
|
description=
|
||||||
|
|
||||||
|
description=[h1]Issues and bugs?[/h1]
|
||||||
|
|
||||||
|
description=Got any issues or found some pesky bugs? Report them on GitHub!
|
||||||
|
|
||||||
|
description=
|
||||||
|
|
||||||
description=[url=https://github.com/ZioPao/The-Only-Cure][img]https://img.shields.io/badge/GitHub-100000?style=for-the-badge&logo=github&logoColor=white[/img][/url]
|
description=[url=https://github.com/ZioPao/The-Only-Cure][img]https://img.shields.io/badge/GitHub-100000?style=for-the-badge&logo=github&logoColor=white[/img][/url]
|
||||||
|
|
||||||
description=
|
description=
|
||||||
|
|
||||||
description=
|
|
||||||
|
|
||||||
description=[h1]Credits[/h1]
|
description=[h1]Credits[/h1]
|
||||||
|
|
||||||
description=
|
|
||||||
|
|
||||||
description=[table]
|
description=[table]
|
||||||
|
|
||||||
description= [tr]
|
description= [tr]
|
||||||
@@ -127,11 +157,19 @@ description= [th]Compatibility API[/th]
|
|||||||
|
|
||||||
description= [/tr]
|
description= [/tr]
|
||||||
|
|
||||||
|
description= [tr]
|
||||||
|
|
||||||
|
description= [th]JCloudJalix, Rinary1, pllq, ttaeo, pgmbru[/th]
|
||||||
|
|
||||||
|
description= [th]Translations[/th]
|
||||||
|
|
||||||
|
description= [/tr]
|
||||||
|
|
||||||
description=[/table]
|
description=[/table]
|
||||||
|
|
||||||
description=
|
description=
|
||||||
|
|
||||||
description=[hr]
|
description=[hr][/hr]
|
||||||
|
|
||||||
description=
|
description=
|
||||||
|
|
||||||
@@ -141,7 +179,7 @@ description=[url=https://ko-fi.com/M4M7IERNW][img]https://storage.ko-fi.com/cdn/
|
|||||||
|
|
||||||
description=
|
description=
|
||||||
|
|
||||||
description=[hr]
|
description=[hr][/hr]
|
||||||
|
|
||||||
tags=Build 41;Balance;Interface;Items;Misc;Multiplayer;Realistic;Textures
|
tags=Build 41;Balance;Interface;Items;Misc;Multiplayer;Realistic;Textures
|
||||||
visibility=private
|
visibility=public
|
||||||
Reference in New Issue
Block a user