From 6adb6940772d128c850a5fcc16d948dcda1c74ac Mon Sep 17 00:00:00 2001 From: ZioPao Date: Wed, 15 Nov 2023 02:52:02 +0100 Subject: [PATCH] equipping weapons working with prosts --- .../client/TOC/Handlers/ModDataHandler.lua | 18 +++----- .../lua/client/TOC/Handlers/PlayerHandler.lua | 45 ++++++++++++++----- .../client/TOC/Handlers/ProsthesisHandler.lua | 27 ++++++++--- media/lua/shared/TOC/BodyLocations.lua | 25 +++++------ media/lua/shared/TOC/StaticData.lua | 21 ++++++--- 5 files changed, 90 insertions(+), 46 deletions(-) diff --git a/media/lua/client/TOC/Handlers/ModDataHandler.lua b/media/lua/client/TOC/Handlers/ModDataHandler.lua index 8abeb39..31a6ec4 100644 --- a/media/lua/client/TOC/Handlers/ModDataHandler.lua +++ b/media/lua/client/TOC/Handlers/ModDataHandler.lua @@ -58,7 +58,6 @@ function ModDataHandler:setup(key) isCauterized = false, isVisible = false } - -- Initialize limbs for i=1, #StaticData.LIMBS_STR do local limbName = StaticData.LIMBS_STR[i] @@ -67,12 +66,10 @@ function ModDataHandler:setup(key) end -- Initialize prostheses stuff - -- TODO This is shit - local groups = {"top", "bottom"} - for i=1, #groups do - local group = groups[i] + for i=1, #StaticData.PROSTHESES_GROUPS_STR do + local group = StaticData.PROSTHESES_GROUPS_STR[i] self.tocData.prostheses[group] = { - isEquipped = false, + isProstEquipped = false, prostFactor = 0, } end @@ -80,7 +77,6 @@ function ModDataHandler:setup(key) -- Add it to global mod data ModData.add(key, self.tocData) - end @@ -115,9 +111,9 @@ end ---Set isProstEquipped ---@param group string ----@param isEquipped boolean -function ModDataHandler:setIsProstEquipped(group, isEquipped) - self.tocData.prostheses[group].isEquipped = isEquipped +---@param isProstEquipped boolean +function ModDataHandler:setIsProstEquipped(group, isProstEquipped) + self.tocData.prostheses[group].isProstEquipped = isProstEquipped end ---Set prostFactor @@ -167,7 +163,7 @@ end ---@param group string ---@return number function ModDataHandler:getProstFactor(group) - return self.tocData.prostheses[group].getProstFactor + return self.tocData.prostheses[group].prostFactor end --* Limbs data handling *-- diff --git a/media/lua/client/TOC/Handlers/PlayerHandler.lua b/media/lua/client/TOC/Handlers/PlayerHandler.lua index bf320e5..288b589 100644 --- a/media/lua/client/TOC/Handlers/PlayerHandler.lua +++ b/media/lua/client/TOC/Handlers/PlayerHandler.lua @@ -82,8 +82,8 @@ function PlayerHandler.CheckInfection(character) -- 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 ModDataHandler.GetInstance():getIsIgnoredPartInfected() then return end - for i=1, #StaticData.IGNORED_BODYLOCS_IND_BPT do - local bodyPartType = StaticData.IGNORED_BODYLOCS_IND_BPT[i] + for i=1, #StaticData.IGNORED_BODYLOCS_BPT do + local bodyPartType = StaticData.IGNORED_BODYLOCS_BPT[i] local bodyPart = bd:getBodyPart(bodyPartType) if bodyPart and (bodyPart:bitten() or bodyPart:IsInfected()) then ModDataHandler.GetInstance():setIsIgnoredPartInfected(true) @@ -155,6 +155,9 @@ local equipSecondaryText = getText("ContextMenu_Equip_Secondary") local primaryHand = StaticData.PARTS_IND_STR.Hand .. "_" .. StaticData.SIDES_IND_STR.R local secondaryHand = StaticData.PARTS_IND_STR.Hand .. "_" .. StaticData.SIDES_IND_STR.L +local prostTopR = StaticData.PROSTHESES_GROUPS_IND_STR.Top_R +local prostTopL = StaticData.PROSTHESES_GROUPS_IND_STR.Top_L + local og_ISEquipWeaponAction_isValid = ISEquipWeaponAction.isValid ---Add a condition to check the feasibility of having 2 handed weapons or if both arms are cut off ---@return boolean @@ -165,21 +168,30 @@ function ISEquipWeaponAction:isValid() if isValid and modDataHandler:getIsAnyLimbCut() then -- TODO We need to consider amputating legs, this won't be correct anymore - -- TODO Consider prosthesis + -- TODO Cache this! + local isPrimaryHandValid = not modDataHandler:getIsCut(primaryHand) or modDataHandler:getIsProstEquipped(prostTopR) + local isSecondaryHandValid = not modDataHandler:getIsCut(secondaryHand) or modDataHandler:getIsProstEquipped(prostTopL) + -- Check prosthesis before anything else. If we have them, then we're gucci + --if modDataHandler:getIsProstEquipped(StaticData.PROSTHESES_GROUPS.top) + + + TOC_DEBUG.print("isPrimaryHandValid: " .. tostring(isPrimaryHandValid)) + TOC_DEBUG.print("isSecondaryHandValid: " .. tostring(isSecondaryHandValid)) + -- Both hands are cut off - if modDataHandler:getIsCut(primaryHand) and modDataHandler:getIsCut(secondaryHand) then + if not(isPrimaryHandValid and isSecondaryHandValid) then return false end - -- Equip primary and no right hand - if self.jobType:contains(equipPrimaryText) and modDataHandler:getIsCut(primaryHand) then + -- Equip primary and no right hand (with no prost) + if self.jobType:contains(equipPrimaryText) and not isPrimaryHandValid then TOC_DEBUG.print("Equip primary, no right hand, not valid") return false end - -- Equip secondary and no left hand - if self.jobType:contains(equipSecondaryText) and modDataHandler:getIsCut(secondaryHand) then + -- Equip secondary and no left hand (with no prost) + if self.jobType:contains(equipSecondaryText) and not isSecondaryHandValid then TOC_DEBUG.print("Equip secondary, no left hand, not valid") return false end @@ -194,8 +206,12 @@ end ---A recreation of the original method, but with amputations in mind ---@param modDataHandler ModDataHandler function ISEquipWeaponAction:performWithAmputation(modDataHandler) + + -- TODO Simplify this local hand = nil + local prostGroup = nil local otherHand = nil + local otherProstGroup = nil local getMethodFirst = nil local setMethodFirst = nil @@ -204,14 +220,18 @@ function ISEquipWeaponAction:performWithAmputation(modDataHandler) if self.primary then hand = "Hand_R" + prostGroup = "Top_R" otherHand = "Hand_L" + otherProstGroup = "Top_L" getMethodFirst = self.character.getSecondaryHandItem setMethodFirst = self.character.setSecondaryHandItem getMethodSecond = self.character.getPrimaryHandItem setMethodSecond = self.character.setPrimaryHandItem else hand = "Hand_L" + prostGroup = "Top_L" otherHand = "Hand_R" + otherProstGroup = "Top_R" getMethodFirst = self.character.getPrimaryHandItem setMethodFirst = self.character.setPrimaryHandItem getMethodSecond = self.character.getSecondaryHandItem @@ -248,11 +268,16 @@ function ISEquipWeaponAction:performWithAmputation(modDataHandler) setMethodFirst(self.character, nil) setMethodSecond(self.character, nil) - if not modDataHandler:getIsCut(hand) then + + local isFirstValid = not modDataHandler:getIsCut(hand) or modDataHandler:getIsProstEquipped(prostGroup) + local isSecondValid = not modDataHandler:getIsCut(otherHand) or modDataHandler:getIsProstEquipped(otherProstGroup) + + + if isFirstValid then setMethodSecond(self.character, self.item) end - if not modDataHandler:getIsCut(otherHand) then + if isSecondValid then setMethodFirst(self.character, self.item) end end diff --git a/media/lua/client/TOC/Handlers/ProsthesisHandler.lua b/media/lua/client/TOC/Handlers/ProsthesisHandler.lua index 8e1b522..05ac69a 100644 --- a/media/lua/client/TOC/Handlers/ProsthesisHandler.lua +++ b/media/lua/client/TOC/Handlers/ProsthesisHandler.lua @@ -20,11 +20,19 @@ end ---@param item InventoryItem ---@return string function ProsthesisHandler.GetGroup(item) - if item:getBodyLocation():contains(bodyLocArmProst) then - return StaticData.PROSTHESES_GROUPS.top + + local bodyLocation = item:getBodyLocation() + local side = CommonMethods.GetSide(bodyLocation) + local index + + if bodyLocation:contains(bodyLocArmProst) then + index = "Top_" .. side else - return StaticData.PROSTHESES_GROUPS.bottom + index = "Bottom_" .. side end + + local group = StaticData.PROSTHESES_GROUPS_IND_STR[index] + return group end ---Cache the correct texture for the Health Panel for the currently equipped prosthesis @@ -38,11 +46,13 @@ end function ProsthesisHandler.CheckIfEquippable(bodyLocation) TOC_DEBUG.print("current item is a prosthesis") local side = CommonMethods.GetSide(bodyLocation) + TOC_DEBUG.print("checking side: " .. tostring(side)) local amputatedLimbs = CachedDataHandler.GetAmputatedLimbs(getPlayer():getUsername()) for i = 1, #amputatedLimbs do local limbName = amputatedLimbs[i] if string.contains(limbName, side) and not string.contains(limbName, "UpperArm") then + TOC_DEBUG.print("found acceptable limb to use prosthesis") return true end end @@ -62,6 +72,7 @@ end ---@diagnostic disable-next-line: duplicate-set-field function ISWearClothing:isValid() + TOC_DEBUG.print("ISWearClothing:isValid") local bodyLocation = self.item:getBodyLocation() if not string.contains(bodyLocation, bodyLocArmProst) then return true @@ -73,9 +84,13 @@ end local og_ISClothingExtraAction_isValid = ISClothingExtraAction.isValid ---@diagnostic disable-next-line: duplicate-set-field function ISClothingExtraAction:isValid() - local bodyLocation = self.item:getBodyLocation() - local isEquippable = false - if og_ISClothingExtraAction_isValid(self) and not string.contains(bodyLocation, bodyLocArmProst) then + + --the item that we gets is the OG one, so if we're coming from the left one and wanna switch to the right one we're still gonna get the Left bodylocation + -- TODO Figure out why it runs 2 times + local testItem = InventoryItemFactory.CreateItem(self.extra) + local bodyLocation = testItem:getBodyLocation() + local isEquippable = og_ISClothingExtraAction_isValid(self) + if isEquippable and not string.contains(bodyLocation, bodyLocArmProst) then isEquippable = true else isEquippable = ProsthesisHandler.CheckIfEquippable(bodyLocation) diff --git a/media/lua/shared/TOC/BodyLocations.lua b/media/lua/shared/TOC/BodyLocations.lua index dce76b1..a39b797 100644 --- a/media/lua/shared/TOC/BodyLocations.lua +++ b/media/lua/shared/TOC/BodyLocations.lua @@ -1,21 +1,18 @@ -- TODO This part is still one of the weakest and we don't have a better solution yet require("TOC/Debug") -local function AddBodyLocationBefore(newLocation, moveToLocation) - local group = BodyLocations.getGroup("Human") - local list = getClassFieldVal(group, getClassField(group, 1)) - group:getOrCreateLocation(newLocation) - local newItem = list:get(list:size()-1) - TOC_DEBUG.print("created new body location" .. newItem:getId()) - list:remove(newItem) -- We can't use the Index, it works if we pass the item though! - local i = group:indexOf(moveToLocation) - list:add(i, newItem) -end +-- AddBodyLocationBefore("TOC_Arm_R", "Shoes") +-- AddBodyLocationBefore("TOC_Arm_L", "Shoes") +-- AddBodyLocationBefore("TOC_ArmProst_R", "TOC_Arm_R") +-- AddBodyLocationBefore("TOC_ArmProst_L", "TOC_Arm_L") -AddBodyLocationBefore("TOC_Arm_R", "Shoes") -AddBodyLocationBefore("TOC_Arm_L", "Shoes") +-- Locations must be declared in render-order. +-- Location IDs must match BodyLocation= and CanBeEquipped= values in items.txt. +local group = BodyLocations.getGroup("Human") -AddBodyLocationBefore("TOC_ArmProst_R", "Shoes") -AddBodyLocationBefore("TOC_ArmProst_L", "Shoes") +group:getOrCreateLocation("TOC_Arm_R") +group:getOrCreateLocation("TOC_ArmProst_R") +group:getOrCreateLocation("TOC_Arm_L") +group:getOrCreateLocation("TOC_ArmProst_L") diff --git a/media/lua/shared/TOC/StaticData.lua b/media/lua/shared/TOC/StaticData.lua index f88f6cd..c0ccf23 100644 --- a/media/lua/shared/TOC/StaticData.lua +++ b/media/lua/shared/TOC/StaticData.lua @@ -1,6 +1,6 @@ ---@alias partData { isCut : boolean?, isInfected : boolean?, isOperated : boolean?, isCicatrized : boolean?, isCauterized : boolean?, isVisible : boolean?, cicatrizationTime : number } ---@alias limbsTable {Hand_L : partData, ForeArm_L : partData, UpperArm_L : partData, Hand_R : partData, ForeArm_R : partData, UpperArm_R : partData } ----@alias prosthesisData {isEquipped : boolean, prostFactor : number } +---@alias prosthesisData {isProstEquipped : boolean, prostFactor : number } ---@alias prosthesesTable {top : prosthesisData, bottom : prosthesisData } ---@alias tocModData { limbs : limbsTable, prostheses : prosthesesTable, isIgnoredPartInfected : boolean, isAnyLimbCut : boolean } --------------------------- @@ -39,7 +39,7 @@ StaticData.MOD_BODYLOCS_BASE_IND_STR = { } -- No "MAX" here. -StaticData.IGNORED_BODYLOCS_IND_BPT = { +StaticData.IGNORED_BODYLOCS_BPT = { BodyPartType.Foot_L, BodyPartType.Foot_R, BodyPartType.Groin, BodyPartType.Head, BodyPartType.LowerLeg_L, BodyPartType.LowerLeg_R, BodyPartType.Neck, BodyPartType.Torso_Lower, BodyPartType.Torso_Upper, BodyPartType.UpperLeg_L, BodyPartType.UpperLeg_R @@ -98,11 +98,22 @@ end ----------------- --* Prostheses -StaticData.PROSTHESES_GROUPS = { - top = "top", - bottom = "bottom" +StaticData.PROSTHESE_GROUPS_BASE_IND_STR = { + Top = "Top", + Bottom = "Bottom" } +StaticData.PROSTHESES_GROUPS_IND_STR = {} +StaticData.PROSTHESES_GROUPS_STR = {} + +for side, _ in pairs(StaticData.SIDES_IND_STR) do + for group, _ in pairs(StaticData.PROSTHESE_GROUPS_BASE_IND_STR) do + local sidedGroup = group .. "_" .. side + StaticData.PROSTHESES_GROUPS_IND_STR[sidedGroup] = sidedGroup + table.insert(StaticData.PROSTHESES_GROUPS_STR, sidedGroup) + end +end + ----------------- --* Traits