diff --git a/.vscode/settings.json b/.vscode/settings.json index 1bc0fbf..87aed1a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -9,4 +9,8 @@ "zombie", "_" ], + "Lua.format.defaultConfig": { + "indent_style": "space", + "indent_size": "2" + } } \ No newline at end of file diff --git a/media/lua/client/TOC/Admin.lua b/media/lua/client/TOC/Admin.lua index 9ba62b3..2fd6797 100644 --- a/media/lua/client/TOC/Admin.lua +++ b/media/lua/client/TOC/Admin.lua @@ -43,6 +43,21 @@ local function AddAdminTocOptions(playerNum, context, worldobjects) sendClientCommand(CommandsData.modules.TOC_RELAY, CommandsData.server.Relay.RelayExecuteInitialization, { patientNum = clickedPlayerNum }) 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() + sendClientCommand(CommandsData.modules.TOC_RELAY, CommandsData.server.Relay.RelayForcedAmputation, + { patientNum = clickedPlayerNum, limbName = limbName }) + end) + end end end Events.OnFillWorldObjectContextMenu.Add(AddAdminTocOptions) diff --git a/media/lua/client/TOC/ClientRelayCommands.lua b/media/lua/client/TOC/ClientRelayCommands.lua index 35b2f49..ae5b3b9 100644 --- a/media/lua/client/TOC/ClientRelayCommands.lua +++ b/media/lua/client/TOC/ClientRelayCommands.lua @@ -1,5 +1,6 @@ local CommandsData = require("TOC/CommandsData") local AmputationHandler = require("TOC/Handlers/AmputationHandler") +local DataController = require("TOC/Controllers/DataController") -------------------------------------------- local ClientRelayCommands = {} @@ -25,8 +26,14 @@ end ---Creates a new handler and execute the amputation function on this client ---@param args receiveExecuteAmputationActionParams 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) - handler:execute(true) + handler:execute(args.damagePlayer) end @@ -46,6 +53,15 @@ function ClientRelayCommands.ReceiveExecuteInitialization() LocalPlayerController.InitializePlayer(true) 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) diff --git a/media/lua/client/TOC/Handlers/AmputationHandler.lua b/media/lua/client/TOC/Handlers/AmputationHandler.lua index 837168f..8061a11 100644 --- a/media/lua/client/TOC/Handlers/AmputationHandler.lua +++ b/media/lua/client/TOC/Handlers/AmputationHandler.lua @@ -156,7 +156,9 @@ function AmputationHandler:damageAfterAmputation(surgeonFactor) patientStats:setStress(baseDamage - surgeonFactor) 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 function AmputationHandler:execute(damagePlayer) local surgeonFactor = self.surgeonPl:getPerkLevel(Perks.Doctor) * SandboxVars.TOC.SurgeonAbilityImportance diff --git a/media/lua/client/TOC/Main.lua b/media/lua/client/TOC/Main.lua index 8b540bc..4f53a7e 100644 --- a/media/lua/client/TOC/Main.lua +++ b/media/lua/client/TOC/Main.lua @@ -6,7 +6,7 @@ require("TOC/Events") ---@class Main local Main = { - _version = "2.1.1" + _version = "2.1.2" } function Main.Start() diff --git a/media/lua/client/TOC/Zombies/ZombiesAmputation.lua b/media/lua/client/TOC/Zombies/ZombiesAmputation.lua index 56adbd4..0a7a01c 100644 --- a/media/lua/client/TOC/Zombies/ZombiesAmputation.lua +++ b/media/lua/client/TOC/Zombies/ZombiesAmputation.lua @@ -61,8 +61,6 @@ end ------------------------------- - - local bloodAmount = 10 @@ -84,13 +82,22 @@ local function HandleZombiesAmputations(player, zombie, handWeapon, damage) 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 - if not zombieInv:containsEval(PredicateAmputationItemLeft) then - SpawnAmputation(zombie, "L") - elseif not zombieInv:containsEval(PredicateAmputationItemRight) then - SpawnAmputation(zombie, "R") + 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) diff --git a/media/lua/server/TOC/ServerRelayCommands.lua b/media/lua/server/TOC/ServerRelayCommands.lua index 890c5be..863c440 100644 --- a/media/lua/server/TOC/ServerRelayCommands.lua +++ b/media/lua/server/TOC/ServerRelayCommands.lua @@ -24,7 +24,7 @@ function ServerRelayCommands.RelayExecuteAmputationAction(surgeonPl, args) local surgeonNum = surgeonPl:getOnlineID() ---@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) end @@ -38,6 +38,21 @@ function ServerRelayCommands.RelayExecuteInitialization(adminObj, args) 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 + ------------------------- diff --git a/media/lua/shared/TOC/CommandsData.lua b/media/lua/shared/TOC/CommandsData.lua index e937d48..569ecde 100644 --- a/media/lua/shared/TOC/CommandsData.lua +++ b/media/lua/shared/TOC/CommandsData.lua @@ -11,14 +11,14 @@ CommandsData.modules = { CommandsData.client = { Relay = { 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 *-- ReceiveApplyFromServer = "ReceiveApplyFromServer", --* ADMIN ONLY --* - ReceiveExecuteInitialization = "ReceiveExecuteInitialization" - + ReceiveExecuteInitialization = "ReceiveExecuteInitialization", + ReceiveForcedCicatrization = "ReceiveForcedCicatrization" ---@alias receiveForcedCicatrizationParams {limbName : string} } } @@ -31,8 +31,10 @@ CommandsData.server = { Relay = { RelayDamageDuringAmputation = "RelayDamageDuringAmputation", ---@alias relayDamageDuringAmputationParams {patientNum : number, limbName : string} RelayExecuteAmputationAction = "RelayExecuteAmputationAction", ---@alias relayExecuteAmputationActionParams {patientNum : number, limbName : string} + --* ADMIN ONLY *-- - RelayExecuteInitialization = "RelayExecuteInitialization" ---@alias relayExecuteInitializationParams {patientNum : number} + RelayExecuteInitialization = "RelayExecuteInitialization", ---@alias relayExecuteInitializationParams {patientNum : number} + RelayForcedAmputation = "RelayForcedAmputation" ---@alias relayForcedAmputationParams {patientNum : number, limbName : string} } } diff --git a/mod.info b/mod.info index 3ba4d94..871e831 100644 --- a/mod.info +++ b/mod.info @@ -4,5 +4,5 @@ description=You've been bitten. You have only two choices. id=TheOnlyCure icon=icon.png url=https://github.com/ZioPao/The-Only-Cure -modversion=2.1.1 +modversion=2.1.2 pzversion=41.65