Implemented stitching + bandages after amputations

This commit is contained in:
ZioPao
2023-11-15 19:23:23 +01:00
parent f7c9047457
commit c4f6890dd0
5 changed files with 147 additions and 28 deletions

View File

@@ -8,4 +8,5 @@ function CommonMethods.GetSide(name)
end end
return CommonMethods return CommonMethods

View File

@@ -56,12 +56,38 @@ function AmputationHandler.ApplyDamageDuringAmputation(player, limbName)
bodyDamagePart:setBleedingTime(ZombRand(10, 20)) bodyDamagePart:setBleedingTime(ZombRand(10, 20))
end end
function AmputationHandler.HandleBandages(prevAction, limbName, surgeonPl, patientPl, bandageItem) ---comment
---@param prevAction ISBaseTimedAction
---@param limbName string
---@param surgeonPl IsoPlayer
---@param patientPl IsoPlayer
---@param stitchesItem InventoryItem
---@return ISStitch
function AmputationHandler.PrepareStitchesAction(prevAction, limbName, surgeonPl, patientPl, stitchesItem)
local bptEnum = StaticData.BODYLOCS_IND_BPT[limbName]
local bd = patientPl:getBodyDamage()
local bodyPart = bd:getBodyPart(bptEnum)
local stitchesAction = ISStitch:new(surgeonPl, patientPl, stitchesItem, bodyPart, true)
ISTimedActionQueue.addAfter(prevAction, stitchesAction)
return stitchesAction
end
---Setup the ISApplyBandage action that will trigger after the amputation
---@param prevAction ISBaseTimedAction
---@param limbName string
---@param surgeonPl IsoPlayer
---@param patientPl IsoPlayer
---@param bandageItem InventoryItem
---@return ISApplyBandage
function AmputationHandler.PrepareBandagesAction(prevAction, limbName, surgeonPl, patientPl, bandageItem)
local bptEnum = StaticData.BODYLOCS_IND_BPT[limbName] local bptEnum = StaticData.BODYLOCS_IND_BPT[limbName]
local bd = patientPl:getBodyDamage() local bd = patientPl:getBodyDamage()
local bodyPart = bd:getBodyPart(bptEnum) local bodyPart = bd:getBodyPart(bptEnum)
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)
return bandageAction
end end
--* Main methods *-- --* Main methods *--

View File

@@ -1,7 +1,8 @@
require "TimedActions/ISBaseTimedAction" require "TimedActions/ISBaseTimedAction"
local AmputationHandler = require("TOC/Handlers/AmputationHandler") local AmputationHandler = require("TOC/Handlers/AmputationHandler")
local CommandsData = require("TOC/CommandsData") local CommandsData = require("TOC/CommandsData")
local StaticData = require("TOC/StaticData") local CommonMethods = require("TOC/CommonMethods")
----------------------------- -----------------------------
---@class CutLimbAction : ISBaseTimedAction ---@class CutLimbAction : ISBaseTimedAction
@@ -9,15 +10,19 @@ local StaticData = require("TOC/StaticData")
---@field character IsoPlayer ---@field character IsoPlayer
---@field limbName string ---@field limbName string
---@field item InventoryItem ---@field item InventoryItem
---@field stitchesItem InventoryItem?
---@field bandageItem InventoryItem?
local CutLimbAction = ISBaseTimedAction:derive("CutLimbAction") local CutLimbAction = ISBaseTimedAction:derive("CutLimbAction")
---Starts CutLimbAction ---Starts CutLimbAction
---@param surgeon IsoPlayer This is gonna be self.character to have working animations
---@param patient IsoPlayer ---@param patient IsoPlayer
---@param surgeon IsoPlayer
---@param limbName string ---@param limbName string
---@param item InventoryItem ---@param item InventoryItem This is gonna be the saw, following ISBaseTimedAction
---@param stitchesItem InventoryItem?
---@param bandageItem InventoryItem?
---@return CutLimbAction ---@return CutLimbAction
function CutLimbAction:new(surgeon, patient, limbName, item) function CutLimbAction:new(surgeon, patient, limbName, item, stitchesItem, bandageItem)
local o = {} local o = {}
setmetatable(o, self) setmetatable(o, self)
self.__index = self self.__index = self
@@ -28,6 +33,9 @@ function CutLimbAction:new(surgeon, patient, limbName, item)
o.limbName = limbName o.limbName = limbName
o.item = item o.item = item
o.stitchesItem = stitchesItem or nil
o.bandageItem = bandageItem or nil
o.stopOnWalk = true o.stopOnWalk = true
o.stopOnRun = true o.stopOnRun = true
@@ -53,19 +61,19 @@ function CutLimbAction:start()
sendClientCommand(CommandsData.modules.TOC_RELAY, CommandsData.server.Relay.RelayDamageDuringAmputation, params ) sendClientCommand(CommandsData.modules.TOC_RELAY, CommandsData.server.Relay.RelayDamageDuringAmputation, params )
end end
---@type ISBaseTimedAction
local prevAction = self
-- TODO Check bandages, if there are init a bandage process -- Handle stitching
if self.stitchesItem then
--AmputationHandler.HandleBandages(self, self.limbName, self.character, self.patient, ) TOC_DEBUG.print("Stitches...")
local bandageItem = InventoryItemFactory.CreateItem("Base.Bandage") prevAction = AmputationHandler.PrepareStitchesAction(prevAction, self.limbName, self.character, self.patient, self.stitchesItem)
self.character:getInventory():addItem(bandageItem) end
local bptEnum = StaticData.BODYLOCS_IND_BPT[self.limbName]
local bd = self.character:getBodyDamage()
local bodyPart = bd:getBodyPart(bptEnum)
local bandageAction = ISApplyBandage:new(self.character, self.patient, bandageItem, bodyPart, 100)
ISTimedActionQueue.addAfter(self, bandageAction)
-- Handle bandages
if self.bandageItem then
prevAction = AmputationHandler.PrepareBandagesAction(prevAction, self.limbName, self.character, self.patient, self.bandageItem)
end
-- Setup cosmetic stuff -- Setup cosmetic stuff
self:setActionAnim("SawLog") self:setActionAnim("SawLog")
@@ -81,6 +89,16 @@ function CutLimbAction:waitToStart()
return self.character:shouldBeTurning() return self.character:shouldBeTurning()
end end
function CutLimbAction:update()
self.character:setMetabolicTarget(Metabolics.HeavyWork)
-- TODO Apply it too on the patient! check if it works online
if self.character ~= self.patient then
self.patient:setMetabolicTarget(Metabolics.HeavyWork)
end
end
function CutLimbAction:perform() function CutLimbAction:perform()
if self.patient == self.character then if self.patient == self.character then
TOC_DEBUG.print("patient and surgeon are the same, executing on the client") TOC_DEBUG.print("patient and surgeon are the same, executing on the client")

View File

@@ -4,8 +4,10 @@ local StaticData = require("TOC/StaticData")
local ModDataHandler = require("TOC/Handlers/ModDataHandler") local ModDataHandler = require("TOC/Handlers/ModDataHandler")
--------------------- ---------------------
-- TODO Add interaction to cut and bandage!
--* Various functions to help during these pesky checks
---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
@@ -14,37 +16,96 @@ local function CheckIfSaw(itemType)
end end
---Return a compatible bandage
---@param player IsoPlayer
---@return InventoryItem?
local function GetBandageItem(player)
local plInv = player:getInventory()
-- TODO Add other options, like ripped sheets and such items
local bandageItem = plInv:FindAndReturn("Base.Bandage") or plInv:FindAndReturn("Base.RippedSheets")
return bandageItem -- TODO check this warning
end
---Return a suture needle or thread (only if the player has a needle too)
---@param player IsoPlayer
---@return InventoryItem?
local function GetStitchesItem(player)
-- TODO Search for thread
local plInv = player:getInventory()
local needleItem = plInv:FindAndReturn("Base.SutureNeedle")
if needleItem ~= nil then return needleItem end
-- Didn't find the suture one, so let's search for the normal one + thread
needleItem = plInv:FindAndReturn("Base.Needle")
if needleItem == nil then return nil end
-- Found the normal one, searching for thread
local threadItem = plInv:FindAndReturn("Base.Thread")
if threadItem then return threadItem end
end
---Add the action to the queue ---Add the action to the queue
---@param limbName string ---@param limbName string
---@param surgeon IsoPlayer ---@param surgeon IsoPlayer
---@param patient IsoPlayer ---@param patient IsoPlayer
local function PerformAction(surgeon, patient, limbName, item) ---@param sawItem InventoryItem
ISTimedActionQueue.add(CutLimbAction:new(surgeon, patient, limbName, item)) ---@param stitchesItem InventoryItem?
---@param bandageItem InventoryItem?
local function PerformAction(surgeon, patient, limbName, sawItem, stitchesItem, bandageItem)
ISTimedActionQueue.add(CutLimbAction:new(surgeon, patient, limbName, sawItem, stitchesItem, bandageItem))
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 surgeonNum number ---@param player IsoPlayer
---@param context ISContextMenu ---@param context ISContextMenu
---@param item InventoryItem ---@param sawItem InventoryItem
local function AddInventoryAmputationOptions(surgeonNum, context, item) ---@param stitchesItem InventoryItem?
local surgeonObj = getSpecificPlayer(surgeonNum) ---@param bandageItem InventoryItem?
local option = context:addOption(getText("ContextMenu_Amputate"), nil) local function AddInvAmputationOptions(player, context, sawItem, stitchesItem, bandageItem)
local text
-- Set the correct text option
if stitchesItem and bandageItem then
text = textAmpStitchBandage
elseif stitchesItem and not bandageItem then
text = textAmpStitch
elseif bandageItem and not stitchesItem then
text = textAmpBandage
else
text = textAmp
end
local option = context:addOption(text, nil)
local subMenu = context:getNew(context) local subMenu = context:getNew(context)
context:addSubMenu(option, subMenu) context:addSubMenu(option, subMenu)
for i = 1, #StaticData.LIMBS_STR do for i = 1, #StaticData.LIMBS_STR do
local limbName = StaticData.LIMBS_STR[i] local limbName = StaticData.LIMBS_STR[i]
if not ModDataHandler.GetInstance():getIsCut(limbName) then if not ModDataHandler.GetInstance():getIsCut(limbName) then
local limbTranslatedName = getText("ContextMenu_Limb_" .. limbName) local limbTranslatedName = getText("ContextMenu_Limb_" .. limbName)
subMenu:addOption(limbTranslatedName, surgeonObj, PerformAction, surgeonObj, limbName, item) -- TODO Should be patient, not surgeon subMenu:addOption(limbTranslatedName, player, PerformAction, player, limbName, sawItem, stitchesItem, bandageItem) -- TODO Should be patient, not surgeon
end end
end end
end end
---Handler for OnFillInventoryObjectContextMenu ---Handler for OnFillInventoryObjectContextMenu
---@param player number ---@param playerNum number
---@param context ISContextMenu ---@param context ISContextMenu
---@param items table ---@param items table
local function AddInventoryAmputationMenu(player, context, items) local function AddInventoryAmputationMenu(playerNum, context, items)
local item local item
-- We can't access the item if we don't create the loop and start ipairs. -- We can't access the item if we don't create the loop and start ipairs.
@@ -58,7 +119,17 @@ local function AddInventoryAmputationMenu(player, context, items)
local itemType = item:getType() local itemType = item:getType()
if CheckIfSaw(itemType) then if CheckIfSaw(itemType) then
AddInventoryAmputationOptions(player, context, item) local player = getSpecificPlayer(playerNum)
local sawItem = item
--AddInvAmputationOptions(player, context, sawItem)
local stitchesItem = GetStitchesItem(player)
local bandageItem = GetBandageItem(player)
--if bandageItem then
AddInvAmputationOptions(player, context, sawItem, stitchesItem, bandageItem)
--end
-- TODO Add stitches option and mixes
end end
end end

View File

@@ -1,5 +1,8 @@
ContextMenu_EN = { ContextMenu_EN = {
ContextMenu_Amputate = "Amputate", ContextMenu_Amputate = "Amputate",
ContextMenu_Amputate_Bandage = "Amputate and bandage",
ContextMenu_Amputate_Stitch_Bandage = "Amputate and stitches",
ContextMenu_Amputate_Stitch_Bandage = "Amputate, stitches and bandage",
ContextMenu_Cauterize = "Cauterize", ContextMenu_Cauterize = "Cauterize",
ContextMenu_Cauterize_TempTooLow_tooltip = "Temperature too low", ContextMenu_Cauterize_TempTooLow_tooltip = "Temperature too low",