diff --git a/media/lua/client/TOC/CommonMethods.lua b/media/lua/client/TOC/CommonMethods.lua index 99edc03..03c5b57 100644 --- a/media/lua/client/TOC/CommonMethods.lua +++ b/media/lua/client/TOC/CommonMethods.lua @@ -1,3 +1,6 @@ +local StaticData = require("TOC/StaticData") +----------------------------------- + local CommonMethods = {} ---@param val number @@ -9,6 +12,11 @@ function CommonMethods.Normalize(val, min, max) end +function CommonMethods.GetLimbNameFromBodyPart(bodyPart) + local bodyPartTypeStr = BodyPartType.ToString(bodyPart:getType()) + return StaticData.LIMBS_IND_STR[bodyPartTypeStr] +end + ---Returns the side for a certain limb or prosthesis ---@param name string ---@return string "L" or "R" diff --git a/media/lua/client/TOC/Handlers/ModDataHandler.lua b/media/lua/client/TOC/Handlers/ModDataHandler.lua index f2221ca..552df5c 100644 --- a/media/lua/client/TOC/Handlers/ModDataHandler.lua +++ b/media/lua/client/TOC/Handlers/ModDataHandler.lua @@ -62,8 +62,9 @@ function ModDataHandler:setup(key) ---@type partData local defaultParams = { - isCut = false, isInfected = false, isOperated = false, isCicatrized = false, - isCauterized = false, isVisible = false + isCut = false, isInfected = false, isOperated = false, isCicatrized = false, isCauterized = false, + woundDirtyness = -1, cicatrizationTime = -1, + isVisible = false } -- Initialize limbs @@ -138,6 +139,14 @@ function ModDataHandler:setIsCauterized(limbName, isCauterized) self.tocData.limbs[limbName].isCauterized = isCauterized end +---Set woundDirtyness +---@param limbName string +---@param woundDirtyness number +function ModDataHandler:setWoundDirtyness(limbName, woundDirtyness) + self.tocData.limbs[limbName].woundDirtyness = woundDirtyness +end + + ---Set cicatrizationTime ---@param limbName string ---@param cicatrizationTime number @@ -206,6 +215,14 @@ function ModDataHandler:getIsCauterized(limbName) return self.tocData.limbs[limbName].isCauterized end +---Get woundDirtyness +---@param limbName string +---@return number +function ModDataHandler:getWoundDirtyness(limbName) + return self.tocData.limbs[limbName].woundDirtyness +end + + ---Get cicatrizationTime ---@param limbName string ---@return number @@ -241,8 +258,10 @@ function ModDataHandler:setCutLimb(limbName, isOperated, isCicatrized, isCauteri cicatrizationTime = StaticData.LIMBS_CICATRIZATION_TIME_IND_NUM[limbName] - surgeonFactor end + -- TODO Set WoundDirtyness here! For now it's just 0 + ---@type partData - local params = {isCut = true, isInfected = false, isOperated = isOperated, isCicatrized = isCicatrized, isCauterized = isCauterized, isVisible = true} + local params = {isCut = true, isInfected = false, isOperated = isOperated, isCicatrized = isCicatrized, isCauterized = isCauterized, woundDirtyness = 0, isVisible = true} self:setLimbParams(limbName, params, cicatrizationTime) for i=1, #StaticData.LIMBS_DEPENDENCIES_IND_STR[limbName] do @@ -271,6 +290,7 @@ function ModDataHandler:setLimbParams(limbName, ampStatus, cicatrizationTime) if ampStatus.isOperated ~= nil then limbData.isOperated = ampStatus.isOperated end if ampStatus.isCicatrized ~= nil then limbData.isCicatrized = ampStatus.isCicatrized end if ampStatus.isCauterized ~= nil then limbData.isCauterized = ampStatus.isCauterized end + if ampStatus.woundDirtyness ~= nil then limbData.woundDirtyness = ampStatus.woundDirtyness end if ampStatus.isVisible ~= nil then limbData.isVisible = ampStatus.isVisible end if cicatrizationTime ~= nil then limbData.cicatrizationTime = cicatrizationTime end diff --git a/media/lua/client/TOC/Handlers/PlayerHandler.lua b/media/lua/client/TOC/Handlers/PlayerHandler.lua index 787a990..3145cca 100644 --- a/media/lua/client/TOC/Handlers/PlayerHandler.lua +++ b/media/lua/client/TOC/Handlers/PlayerHandler.lua @@ -210,6 +210,8 @@ function PlayerHandler.UpdateCicatrization() end local pl = PlayerHandler.playerObj + local bd = pl:getBodyDamage() + local visual = pl:getHumanVisual() local amputatedLimbs = CachedDataHandler.GetAmputatedLimbs(pl:getUsername()) local needsUpdate = false @@ -222,6 +224,24 @@ function PlayerHandler.UpdateCicatrization() local cicTime = modDataHandler:getCicatrizationTime(limbName) TOC_DEBUG.print("updating cicatrization for " .. tostring(limbName)) + -- TODO Check if bandaged, sutured, whatever + + -- TODO Clean + + -- TODO Check dirtyness of zone and add to it + + --local bptEnum = StaticData.BODYLOCS_IND_BPT[limbName] + + -- TODO Workaround + local bbptEnum = BloodBodyPartType[limbName] + --local bodyPart = bd:getBodyPart(bptEnum) + + local dirtyness = visual:getDirt(bbptEnum) + visual:getBlood(bbptEnum) + modDataHandler:getWoundDirtyness(limbName) + modDataHandler:setWoundDirtyness(limbName, dirtyness) + + TOC_DEBUG.print("dirtyness for this zone: " .. tostring(dirtyness)) + + cicTime = cicTime - SandboxVars.TOC.CicatrizationSpeed modDataHandler:setCicatrizationTime(limbName, cicTime) TOC_DEBUG.print("new cicatrization time: " .. tostring(cicTime)) diff --git a/media/lua/client/TOC/TimedActions/CleanWoundAction.lua b/media/lua/client/TOC/TimedActions/CleanWoundAction.lua new file mode 100644 index 0000000..7ef004f --- /dev/null +++ b/media/lua/client/TOC/TimedActions/CleanWoundAction.lua @@ -0,0 +1,102 @@ +local ModDataHandler = require("TOC/Handlers/ModDataHandler") +local CommonMethods = require("TOC/CommonMethods") +---- + +---@class CleanWoundAction : ISBaseTimedAction +local CleanWoundAction = ISBaseTimedAction:derive("CleanWoundAction") + +function CleanWoundAction:isValid() + if ISHealthPanel.DidPatientMove(self.character, self.otherPlayer, self.bandagedPlayerX, self.bandagedPlayerY) then + return false + end + return true +end + +function CleanWoundAction:waitToStart() + if self.character == self.otherPlayer then + return false + end + self.character:faceThisObject(self.otherPlayer) + return self.character:shouldBeTurning() +end + +function CleanWoundAction:update() + if self.character ~= self.otherPlayer then + self.character:faceThisObject(self.otherPlayer) + end + local jobType = getText("ContextMenu_CleanWound") + ISHealthPanel.setBodyPartActionForPlayer(self.otherPlayer, self.bodyPart, self, jobType, { cleanBurn = true }) + self.character:setMetabolicTarget(Metabolics.LightDomestic) +end + +function CleanWoundAction:start() + if self.character == self.otherPlayer then + self:setActionAnim(CharacterActionAnims.Bandage) + self:setAnimVariable("BandageType", ISHealthPanel.getBandageType(self.bodyPart)) + self.character:reportEvent("EventBandage") + else + self:setActionAnim("Loot") + self.character:SetVariable("LootPosition", "Mid") + self.character:reportEvent("EventLootItem") + end + self:setOverrideHandModels(nil, nil) +end + +function CleanWoundAction:stop() + ISHealthPanel.setBodyPartActionForPlayer(self.otherPlayer, self.bodyPart, nil, nil, nil) + ISBaseTimedAction.stop(self) +end + +function CleanWoundAction:perform() + -- needed to remove from queue / start next. + ISBaseTimedAction.perform(self) + + if self.character:HasTrait("Hemophobic") then + self.character:getStats():setPanic(self.character:getStats():getPanic() + 50) + end + + self.character:getXp():AddXP(Perks.Doctor, 10) + local addPain = (60 - (self.doctorLevel * 1)) + self.bodyPart:setAdditionalPain(self.bodyPart:getAdditionalPain() + addPain) + --self.bodyPart:setNeedBurnWash(false) + self.bandage:Use() + + if isClient() then + local limbName = CommonMethods.GetLimbNameFromBodyPart(self.bodyPart) + + -- TODO CHeck if correct in MP + local modDataHandler = ModDataHandler.GetInstance(self.character:getUsername()) + + modDataHandler:setWoundDirtyness(limbName, 0) + --sendCleanBurn(self.character, self.otherPlayer, self.bodyPart, self.bandage) + end + + ISHealthPanel.setBodyPartActionForPlayer(self.otherPlayer, self.bodyPart, nil, nil, nil) +end + +---@return CleanWoundAction +function CleanWoundAction:new(doctor, otherPlayer, bandage, bodyPart) + local o = {} + setmetatable(o, self) + self.__index = self + o.character = doctor + o.otherPlayer = otherPlayer + o.doctorLevel = doctor:getPerkLevel(Perks.Doctor) + o.bodyPart = bodyPart + o.bandage = bandage + o.stopOnWalk = true + o.stopOnRun = true + o.bandagedPlayerX = otherPlayer:getX() + o.bandagedPlayerY = otherPlayer:getY() + o.maxTime = 250 - (o.doctorLevel * 6) + if doctor:isTimedActionInstant() then + o.maxTime = 1 + end + if doctor:getAccessLevel() ~= "None" then + o.doctorLevel = 10 + end + return o +end + + +return CleanWoundAction \ No newline at end of file diff --git a/media/lua/client/TOC/UI/HealthPanel.lua b/media/lua/client/TOC/UI/HealthPanel.lua index 94d1c98..4174854 100644 --- a/media/lua/client/TOC/UI/HealthPanel.lua +++ b/media/lua/client/TOC/UI/HealthPanel.lua @@ -2,6 +2,7 @@ local StaticData = require("TOC/StaticData") local ModDataHandler = require("TOC/Handlers/ModDataHandler") local CachedDataHandler = require("TOC/Handlers/CachedDataHandler") local CutLimbHandler = require("TOC/UI/CutLimbInteractions") +local WoundCleaningHandler = require("TOC/UI/WoundCleaningInteraction") --------------------------------- -- We're overriding ISHealthPanel to add custom textures to the body panel. @@ -36,11 +37,14 @@ function ISHealthPanel:doBodyPartContextMenu(bodyPart, x, y) -- To not recreate it but reuse the one that has been created in the original method local context = getPlayerContextMenu(playerNum) + local cutLimbHandler = CutLimbHandler:new(self, bodyPart) - self:checkItems({cutLimbHandler}) - cutLimbHandler:addToMenu(context) + + local woundCleaningHandler = WoundCleaningHandler:new(self, bodyPart, self.character:getUsername()) + self:checkItems({woundCleaningHandler}) + woundCleaningHandler:addToMenu(context) end @@ -183,14 +187,12 @@ function ISHealthBodyPartListBox:doDrawItem(y, item, alt) if limbName then local modDataHandler = ModDataHandler.GetInstance(username) if modDataHandler:getIsCut(limbName) and modDataHandler:getIsVisible(limbName) then - if modDataHandler:getIsCicatrized(limbName) then if modDataHandler:getIsCauterized(limbName) then self:drawText("- " .. getText("IGUI_HealthPanel_Cauterized"), x, y, 0.58, 0.75, 0.28, 1, UIFont.Small) else self:drawText("- " .. getText("IGUI_HealthPanel_Cicatrized"), x, y, 0.28, 0.89, 0.28, 1, UIFont.Small) end - else local cicaTime = modDataHandler:getCicatrizationTime(limbName) diff --git a/media/lua/client/TOC/UI/SurgeryInteractions.lua b/media/lua/client/TOC/UI/SurgeryInteractions.lua index 7f722f4..b9d63d6 100644 --- a/media/lua/client/TOC/UI/SurgeryInteractions.lua +++ b/media/lua/client/TOC/UI/SurgeryInteractions.lua @@ -1,8 +1,9 @@ local CachedDataHandler = require("TOC/Handlers/CachedDataHandler") -local StaticData = require("TOC/StaticData") local ModDataHandler = require("TOC/Handlers/ModDataHandler") --------------- + + -- TODO Surgery Kits local function AddInventorySurgeryMenu(playerNum, context, items) diff --git a/media/lua/client/TOC/UI/WoundCleaningInteraction.lua b/media/lua/client/TOC/UI/WoundCleaningInteraction.lua new file mode 100644 index 0000000..790735c --- /dev/null +++ b/media/lua/client/TOC/UI/WoundCleaningInteraction.lua @@ -0,0 +1,80 @@ + +local BaseHandler = require("TOC/UI/HealthPanelBaseHandler") +local CommonMethods = require("TOC/CommonMethods") +local ModDataHandler = require("TOC/Handlers/ModDataHandler") + +local CleanWoundAction = require("TOC/TimedActions/CleanWoundAction") +------------------------- +---@class WoundCleaningHandler : BaseHandler +---@field username string +---@field limbName string +local WoundCleaningHandler = BaseHandler:derive("WoundCleaningHandler") + +---comment +---@param panel any +---@param bodyPart any +---@param username string +---@return table +function WoundCleaningHandler:new(panel, bodyPart, username) + local o = BaseHandler.new(self, panel, bodyPart) + o.items.ITEMS = {} + o.username = username + + o.limbName = CommonMethods.GetLimbNameFromBodyPart(bodyPart) + + + return o +end + +function WoundCleaningHandler:checkItem(item) + if item:getBandagePower() >= 2 then + self:addItem(self.items.ITEMS, item) + end +end + +function WoundCleaningHandler:addToMenu(context) + local types = self:getAllItemTypes(self.items.ITEMS) + if #types > 0 and self:isValid() then + local option = context:addOption("Clean Wound", nil) + local subMenu = context:getNew(context) + context:addSubMenu(option, subMenu) + for i=1,#types do + local item = self:getItemOfType(self.items.ITEMS, types[i]) + subMenu:addOption(item:getName(), self, self.onMenuOptionSelected, item:getFullType()) + end + end +end + +function WoundCleaningHandler:dropItems(items) + local types = self:getAllItemTypes(items) + if #self.items.ITEMS > 0 and #types == 1 and self:isInjured() and self.bodyPart:isNeedBurnWash() then + -- FIXME: A bandage can be used to clean a burn or bandage it + self:onMenuOptionSelected(types[1]) + return true + end + return false +end + +function WoundCleaningHandler:isValid() + -- TODO Check if cut and not cicatrized and dirty + + -- todo get username + if self.limbName == nil then return false end + + local modDataHandler = ModDataHandler.GetInstance(self.username) + + --and modDataHandler:getWoundDirtyness(self.limbName) > 0.1 + + return modDataHandler:getIsCut(self.limbName) and not modDataHandler:getIsCicatrized(self.limbName) + --return self:getItemOfType(self.items.ITEMS, itemType) +end + +function WoundCleaningHandler:perform(previousAction, itemType) + local item = self:getItemOfType(self.items.ITEMS, itemType) + previousAction = self:toPlayerInventory(item, previousAction) + local action = CleanWoundAction :new(self:getDoctor(), self:getPatient(), item, self.bodyPart) + ISTimedActionQueue.addAfter(previousAction, action) +end + + +return WoundCleaningHandler \ No newline at end of file diff --git a/media/lua/shared/TOC/StaticData.lua b/media/lua/shared/TOC/StaticData.lua index 741ee8e..06f50a3 100644 --- a/media/lua/shared/TOC/StaticData.lua +++ b/media/lua/shared/TOC/StaticData.lua @@ -1,4 +1,4 @@ ----@alias partData { isCut : boolean?, isInfected : boolean?, isOperated : boolean?, isCicatrized : boolean?, isCauterized : boolean?, isVisible : boolean?, cicatrizationTime : number } +---@alias partData { isCut : boolean?, isInfected : boolean?, isOperated : boolean?, isCicatrized : boolean?, isCauterized : boolean?, isVisible : boolean?, woundDirtyness : number, cicatrizationTime : number } ---@alias limbsTable {Hand_L : partData, ForeArm_L : partData, UpperArm_L : partData, Hand_R : partData, ForeArm_R : partData, UpperArm_R : partData } ---@alias prosthesisData {isProstEquipped : boolean, prostFactor : number } ---@alias prosthesesTable {Top_L : prosthesisData, Top_R : prosthesisData } -- TODO add Bottom_L and Bottom_R diff --git a/media/lua/shared/Translate/EN/ContextMenu_EN.txt b/media/lua/shared/Translate/EN/ContextMenu_EN.txt index 30a46f9..14a6d45 100644 --- a/media/lua/shared/Translate/EN/ContextMenu_EN.txt +++ b/media/lua/shared/Translate/EN/ContextMenu_EN.txt @@ -17,6 +17,8 @@ ContextMenu_EN = { ContextMenu_InstallProstRight = "Install prosthesis on right arm", ContextMenu_InstallProstLeft = "Install prosthesis on left arm", + + ContextMenu_CleanWound = "Clean Wound", }