Rethinking structure a bit
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
local ModDataHandler = require("TOC/Handlers/ModDataHandler")
|
||||
local ItemsHandler = require("TOC/Handlers/ItemsHandler")
|
||||
local DataController = require("TOC/Controllers/DataController")
|
||||
local ItemsController = require("TOC/Handlers/ItemsController")
|
||||
local CachedDataHandler = require("TOC/Handlers/CachedDataHandler")
|
||||
local PlayerHandler = require("TOC/Handlers/PlayerHandler")
|
||||
local LocalPlayerController = require("TOC/Controllers/LocalPlayerController")
|
||||
local StaticData = require("TOC/StaticData")
|
||||
---------------------------
|
||||
|
||||
@@ -132,9 +132,9 @@ function AmputationHandler:execute(damagePlayer)
|
||||
local surgeonFactor = self.surgeonPl:getPerkLevel(Perks.Doctor) * SandboxVars.TOC.SurgeonAbilityImportance
|
||||
|
||||
-- Set the data in modData
|
||||
local modDataHandler = ModDataHandler.GetInstance()
|
||||
modDataHandler:setCutLimb(self.limbName, false, false, false, surgeonFactor)
|
||||
modDataHandler:apply() -- This will force rechecking the cached amputated limbs on the other client
|
||||
local dcInst = DataController.GetInstance()
|
||||
dcInst:setCutLimb(self.limbName, false, false, false, surgeonFactor)
|
||||
dcInst:apply() -- This will force rechecking the cached amputated limbs on the other client
|
||||
|
||||
-- Heal the area, we're gonna re-set the damage after (if it's enabled)
|
||||
local bd = self.patientPl:getBodyDamage()
|
||||
@@ -142,8 +142,8 @@ function AmputationHandler:execute(damagePlayer)
|
||||
PlayerHandler.HealArea(bodyPart)
|
||||
|
||||
-- Give the player the correct amputation item
|
||||
ItemsHandler.Player.DeleteOldAmputationItem(self.patientPl, self.limbName)
|
||||
ItemsHandler.Player.SpawnAmputationItem(self.patientPl, self.limbName)
|
||||
ItemsController.Player.DeleteOldAmputationItem(self.patientPl, self.limbName)
|
||||
ItemsController.Player.SpawnAmputationItem(self.patientPl, self.limbName)
|
||||
|
||||
-- Add it to the list of cut limbs on this local client
|
||||
local username = self.patientPl:getUsername()
|
||||
@@ -158,8 +158,8 @@ function AmputationHandler:execute(damagePlayer)
|
||||
CachedDataHandler.CalculateHighestAmputatedLimbs(username)
|
||||
|
||||
-- If the part was actually infected, heal the player, if they were in time (infectionLevel < 20)
|
||||
if bd:getInfectionLevel() < 20 and bodyPart:IsInfected() and not modDataHandler:getIsIgnoredPartInfected() then
|
||||
PlayerHandler.HealZombieInfection(bd, bodyPart, self.limbName, modDataHandler)
|
||||
if bd:getInfectionLevel() < 20 and bodyPart:IsInfected() and not dcInst:getIsIgnoredPartInfected() then
|
||||
PlayerHandler.HealZombieInfection(bd, bodyPart, self.limbName, dcInst)
|
||||
end
|
||||
|
||||
-- The last part is to handle the damage that the player will receive after the amputation
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
local StaticData = require("TOC/StaticData")
|
||||
local ModDataHandler = require("TOC/Handlers/ModDataHandler")
|
||||
local DataController = require("TOC/Controllers/DataController")
|
||||
local CommonMethods = require("TOC/CommonMethods")
|
||||
---------------------------
|
||||
|
||||
@@ -21,12 +21,12 @@ CachedDataHandler.amputatedLimbs = {}
|
||||
function CachedDataHandler.CalculateAmputatedLimbs(username)
|
||||
TOC_DEBUG.print("[CachedDataHandler] Calculating amputated limbs for " .. username)
|
||||
CachedDataHandler.amputatedLimbs[username] = {}
|
||||
local modDataHandler = ModDataHandler.GetInstance(username)
|
||||
local dcInst = DataController.GetInstance(username)
|
||||
|
||||
-- TODO If the data hasn't arrived, this won't work
|
||||
for i=1, #StaticData.LIMBS_STR do
|
||||
local limbName = StaticData.LIMBS_STR[i]
|
||||
if modDataHandler:getIsCut(limbName) then
|
||||
if dcInst:getIsCut(limbName) then
|
||||
CachedDataHandler.AddAmputatedLimb(username, limbName)
|
||||
end
|
||||
end
|
||||
@@ -58,9 +58,9 @@ CachedDataHandler.highestAmputatedLimbs = {}
|
||||
---@param username string
|
||||
function CachedDataHandler.CalculateHighestAmputatedLimbs(username)
|
||||
TOC_DEBUG.print("[CachedDataHandler] Triggered CalculateHighestAmputatedLimbs")
|
||||
local modDataHandler = ModDataHandler.GetInstance(username)
|
||||
if modDataHandler == nil then
|
||||
TOC_DEBUG.print("ModDataHandler not found for " .. username)
|
||||
local dcInst = DataController.GetInstance(username)
|
||||
if dcInst == nil then
|
||||
TOC_DEBUG.print("DataController not found for " .. username)
|
||||
return
|
||||
end
|
||||
|
||||
@@ -83,7 +83,7 @@ function CachedDataHandler.CalculateHighestAmputatedLimbs(username)
|
||||
for k, _ in pairs(amputatedLimbs) do
|
||||
local limbName = k
|
||||
local index = CommonMethods.GetSide(limbName)
|
||||
if modDataHandler:getIsCut(limbName) and modDataHandler:getIsVisible(limbName) then
|
||||
if dcInst:getIsCut(limbName) and dcInst:getIsVisible(limbName) then
|
||||
TOC_DEBUG.print("[CachedDataHandler] Added Highest Amputation: " .. limbName)
|
||||
CachedDataHandler.highestAmputatedLimbs[username][index] = limbName
|
||||
end
|
||||
|
||||
@@ -1,167 +0,0 @@
|
||||
local StaticData = require("TOC/StaticData")
|
||||
local CommonMethods = require("TOC/CommonMethods")
|
||||
---------------------------
|
||||
|
||||
--- Submodule to handle spawning the correct items after certain actions (ie: cutting a hand). LOCAL ONLY!
|
||||
---@class ItemsHandler
|
||||
local ItemsHandler = {}
|
||||
|
||||
|
||||
|
||||
--* Player Methods *--
|
||||
---@class ItemsHandler.Player
|
||||
ItemsHandler.Player = {}
|
||||
|
||||
---Returns the correct index for the textures of the amputation
|
||||
---@param playerObj IsoPlayer
|
||||
---@param isCicatrized boolean
|
||||
---@return number
|
||||
---@private
|
||||
function ItemsHandler.Player.GetAmputationTexturesIndex(playerObj, isCicatrized)
|
||||
local textureString = playerObj:getHumanVisual():getSkinTexture()
|
||||
local isHairy = textureString:sub(-1) == "a"
|
||||
|
||||
local matchedIndex = tonumber(textureString:match("%d$")) or 0
|
||||
|
||||
if isHairy then
|
||||
matchedIndex = matchedIndex + 5
|
||||
end
|
||||
|
||||
if isCicatrized then
|
||||
matchedIndex = matchedIndex + (isHairy and 5 or 10) -- We add 5 is it's the texture texture, else 10
|
||||
end
|
||||
|
||||
return matchedIndex - 1
|
||||
end
|
||||
|
||||
---Main function to delete a clothing item
|
||||
---@param playerObj IsoPlayer
|
||||
---@param clothingItem InventoryItem?
|
||||
---@return boolean
|
||||
---@private
|
||||
function ItemsHandler.Player.RemoveClothingItem(playerObj, clothingItem)
|
||||
if clothingItem and instanceof(clothingItem, "InventoryItem") then
|
||||
playerObj:removeWornItem(clothingItem)
|
||||
|
||||
playerObj:getInventory():Remove(clothingItem) -- Can be a InventoryItem too.. I guess? todo check it
|
||||
TOC_DEBUG.print("found and deleted" .. tostring(clothingItem))
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
---Search and deletes an old amputation clothing item on the same side
|
||||
---@param playerObj IsoPlayer
|
||||
---@param limbName string
|
||||
function ItemsHandler.Player.DeleteOldAmputationItem(playerObj, limbName)
|
||||
local side = CommonMethods.GetSide(limbName)
|
||||
for partName, _ in pairs(StaticData.PARTS_IND_STR) do
|
||||
local othLimbName = partName .. "_" .. side
|
||||
local othClothingItemName = StaticData.AMPUTATION_CLOTHING_ITEM_BASE .. othLimbName
|
||||
|
||||
-- TODO FindAndReturn could return an ArrayList. We need to check for that
|
||||
local othClothingItem = playerObj:getInventory():FindAndReturn(othClothingItemName)
|
||||
|
||||
|
||||
-- If we manage to find and remove an item, then we should stop this function.
|
||||
---@cast othClothingItem InventoryItem
|
||||
if ItemsHandler.Player.RemoveClothingItem(playerObj, othClothingItem) then return end
|
||||
end
|
||||
end
|
||||
|
||||
---Deletes all the old amputation items, used for resets
|
||||
---@param playerObj IsoPlayer
|
||||
function ItemsHandler.Player.DeleteAllOldAmputationItems(playerObj)
|
||||
|
||||
for i=1, #StaticData.LIMBS_STR do
|
||||
local limbName = StaticData.LIMBS_STR[i]
|
||||
local clothItemName = StaticData.AMPUTATION_CLOTHING_ITEM_BASE .. limbName
|
||||
local clothItem = playerObj:getInventory():FindAndReturn(clothItemName)
|
||||
---@cast clothItem InventoryItem
|
||||
ItemsHandler.Player.RemoveClothingItem(playerObj, clothItem)
|
||||
end
|
||||
end
|
||||
|
||||
---Spawns and equips the correct amputation item to the player.
|
||||
---@param playerObj IsoPlayer
|
||||
---@param limbName string
|
||||
function ItemsHandler.Player.SpawnAmputationItem(playerObj, limbName)
|
||||
TOC_DEBUG.print("clothing name " .. StaticData.AMPUTATION_CLOTHING_ITEM_BASE .. limbName)
|
||||
local clothingItem = playerObj:getInventory():AddItem(StaticData.AMPUTATION_CLOTHING_ITEM_BASE .. limbName)
|
||||
local texId = ItemsHandler.Player.GetAmputationTexturesIndex(playerObj, false)
|
||||
|
||||
---@cast clothingItem InventoryItem
|
||||
clothingItem:getVisual():setTextureChoice(texId) -- it counts from 0, so we have to subtract 1
|
||||
playerObj:setWornItem(clothingItem:getBodyLocation(), clothingItem)
|
||||
end
|
||||
|
||||
|
||||
|
||||
--* Zombie Methods *--
|
||||
---@class ItemsHandler.Zombie
|
||||
ItemsHandler.Zombie = {}
|
||||
|
||||
---Set an amputation to a zombie
|
||||
---@param zombie IsoZombie
|
||||
function ItemsHandler.Zombie.SpawnAmputationItem(zombie)
|
||||
-- TODO Set texture ID
|
||||
local itemVisualsList = zombie:getItemVisuals()
|
||||
local ignoredLimbs = {}
|
||||
|
||||
if itemVisualsList == nil then return end
|
||||
|
||||
for i=0, itemVisualsList:size() - 1 do
|
||||
local itemVisual = itemVisualsList:get(i)
|
||||
|
||||
-- TODO Check body location of item and deletes potential amputation to apply
|
||||
local clothingName = itemVisual:getClothingItemName()
|
||||
--print(clothingName)
|
||||
|
||||
if clothingName and luautils.stringStarts(clothingName, StaticData.AMPUTATION_CLOTHING_ITEM_BASE) then
|
||||
TOC_DEBUG.print("added " .. clothingName .. " to ignoredLimbs")
|
||||
ignoredLimbs[clothingName] = clothingName
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
-- TODO Consider highest amputation
|
||||
local usableClothingAmputations = {}
|
||||
|
||||
for i=1, #StaticData.LIMBS_STR do
|
||||
local limbName = StaticData.LIMBS_STR[i]
|
||||
local clothingName = StaticData.AMPUTATION_CLOTHING_ITEM_BASE .. limbName
|
||||
if ignoredLimbs[clothingName] == nil then
|
||||
table.insert(usableClothingAmputations, clothingName)
|
||||
end
|
||||
end
|
||||
|
||||
-- TODO Random index
|
||||
local index = ZombRand(1, #usableClothingAmputations)
|
||||
|
||||
local itemVisual = ItemVisual:new()
|
||||
itemVisual:setItemType(usableClothingAmputations[index])
|
||||
zombie:getItemVisuals():add(itemVisual)
|
||||
zombie:resetModelNextFrame()
|
||||
end
|
||||
|
||||
|
||||
--------------------------
|
||||
--* Overrides *--
|
||||
|
||||
local og_ISInventoryPane_refreshContainer = ISInventoryPane.refreshContainer
|
||||
|
||||
---Get the list of items for the container and remove the reference to the amputation items
|
||||
---@diagnostic disable-next-line: duplicate-set-field
|
||||
function ISInventoryPane:refreshContainer()
|
||||
og_ISInventoryPane_refreshContainer(self)
|
||||
if TOC_DEBUG.disablePaneMod then return end
|
||||
for i=1, #self.itemslist do
|
||||
local cItem = self.itemslist[i]
|
||||
if cItem and cItem.cat == "Amputation" then
|
||||
TOC_DEBUG.print("Refreshing container - current item is an amputation, removing it from the list of the container")
|
||||
table.remove(self.itemslist, i)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return ItemsHandler
|
||||
@@ -1,387 +0,0 @@
|
||||
local CommandsData = require("TOC/CommandsData")
|
||||
local StaticData = require("TOC/StaticData")
|
||||
----------------
|
||||
|
||||
--- Handle all mod data related stuff
|
||||
---@class ModDataHandler
|
||||
---@field username string
|
||||
---@field tocData tocModData
|
||||
---@field isDataReady boolean
|
||||
---@field isResetForced boolean
|
||||
local ModDataHandler = {}
|
||||
ModDataHandler.instances = {}
|
||||
|
||||
---Setup a new Mod Data Handler
|
||||
---@param username string
|
||||
---@param isResetForced boolean?
|
||||
---@return ModDataHandler
|
||||
function ModDataHandler:new(username, isResetForced)
|
||||
TOC_DEBUG.print("[ModDataHandler] NEW for " .. username)
|
||||
--error("TEST TRIGGER")
|
||||
local o = {}
|
||||
setmetatable(o, self)
|
||||
self.__index = self
|
||||
|
||||
o.username = username
|
||||
local key = CommandsData.GetKey(username)
|
||||
|
||||
-- We don't want to request ModData if we're in SP, or if we're forcing a reset
|
||||
if isClient() and not isResetForced then
|
||||
ModData.request(key)
|
||||
o.isResetForced = isResetForced
|
||||
o.isDataReady = false
|
||||
elseif isResetForced then
|
||||
self:setup(key)
|
||||
o.isResetForced = false
|
||||
o.isDataReady = true
|
||||
end
|
||||
|
||||
ModDataHandler.instances[username] = o
|
||||
|
||||
return o
|
||||
end
|
||||
|
||||
---Setup a new toc mod data data class
|
||||
---@param key string
|
||||
function ModDataHandler:setup(key)
|
||||
TOC_DEBUG.print("[ModDataHandler] Running setup")
|
||||
|
||||
---@type tocModData
|
||||
self.tocData = {
|
||||
-- Generic stuff that does not belong anywhere else
|
||||
isIgnoredPartInfected = false,
|
||||
isAnyLimbCut = false,
|
||||
limbs = {},
|
||||
prostheses = {}
|
||||
}
|
||||
|
||||
---@type partData
|
||||
local defaultParams = {
|
||||
isCut = false, isInfected = false, isOperated = false, isCicatrized = false, isCauterized = false,
|
||||
woundDirtyness = -1, cicatrizationTime = -1,
|
||||
isVisible = false
|
||||
}
|
||||
|
||||
-- Initialize limbs
|
||||
for i=1, #StaticData.LIMBS_STR do
|
||||
local limbName = StaticData.LIMBS_STR[i]
|
||||
self.tocData.limbs[limbName] = {}
|
||||
self:setLimbParams(StaticData.LIMBS_STR[i], defaultParams, 0)
|
||||
end
|
||||
|
||||
-- Initialize prostheses stuff
|
||||
for i=1, #StaticData.PROSTHESES_GROUPS_STR do
|
||||
local group = StaticData.PROSTHESES_GROUPS_STR[i]
|
||||
self.tocData.prostheses[group] = {
|
||||
isProstEquipped = false,
|
||||
prostFactor = 0,
|
||||
}
|
||||
end
|
||||
|
||||
-- Add it to global mod data
|
||||
ModData.add(key, self.tocData)
|
||||
|
||||
end
|
||||
|
||||
---In case of desync between the table on ModData and the table here
|
||||
---@param tocData tocModData
|
||||
function ModDataHandler:reapplyTocData(tocData)
|
||||
local key = CommandsData.GetKey(self.username)
|
||||
ModData.add(key, tocData)
|
||||
self.tocData = ModData.get(key)
|
||||
end
|
||||
|
||||
-----------------
|
||||
--* Setters *--
|
||||
|
||||
function ModDataHandler:setIsDataReady(isDataReady)
|
||||
self.isDataReady = isDataReady
|
||||
end
|
||||
|
||||
---Set a generic boolean that toggles varies function of the mod
|
||||
---@param isAnyLimbCut boolean
|
||||
function ModDataHandler:setIsAnyLimbCut(isAnyLimbCut)
|
||||
self.tocData.isAnyLimbCut = isAnyLimbCut
|
||||
end
|
||||
|
||||
---Set isIgnoredPartInfected
|
||||
---@param isIgnoredPartInfected boolean
|
||||
function ModDataHandler:setIsIgnoredPartInfected(isIgnoredPartInfected)
|
||||
self.tocData.isIgnoredPartInfected = isIgnoredPartInfected
|
||||
end
|
||||
|
||||
---Set isCut
|
||||
---@param limbName string
|
||||
---@param isCut boolean
|
||||
function ModDataHandler:setIsCut(limbName, isCut)
|
||||
self.tocData.limbs[limbName].isCut = isCut
|
||||
end
|
||||
|
||||
---Set isInfected
|
||||
---@param limbName string
|
||||
---@param isInfected boolean
|
||||
function ModDataHandler:setIsInfected(limbName, isInfected)
|
||||
self.tocData.limbs[limbName].isInfected = isInfected
|
||||
end
|
||||
|
||||
---Set isCicatrized
|
||||
---@param limbName string
|
||||
---@param isCicatrized boolean
|
||||
function ModDataHandler:setIsCicatrized(limbName, isCicatrized)
|
||||
self.tocData.limbs[limbName].isCicatrized = isCicatrized
|
||||
end
|
||||
|
||||
---Set isCauterized
|
||||
---@param limbName string
|
||||
---@param isCauterized boolean
|
||||
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
|
||||
function ModDataHandler:setCicatrizationTime(limbName, cicatrizationTime)
|
||||
self.tocData.limbs[limbName].cicatrizationTime = cicatrizationTime
|
||||
end
|
||||
|
||||
---Set isProstEquipped
|
||||
---@param group string
|
||||
---@param isProstEquipped boolean
|
||||
function ModDataHandler:setIsProstEquipped(group, isProstEquipped)
|
||||
self.tocData.prostheses[group].isProstEquipped = isProstEquipped
|
||||
end
|
||||
|
||||
---Set prostFactor
|
||||
---@param group string
|
||||
---@param prostFactor number
|
||||
function ModDataHandler:setProstFactor(group, prostFactor)
|
||||
self.tocData.prostheses[group].prostFactor = prostFactor
|
||||
end
|
||||
|
||||
-----------------
|
||||
--* Getters *--
|
||||
|
||||
---comment
|
||||
---@return boolean
|
||||
function ModDataHandler:getIsDataReady()
|
||||
return self.isDataReady
|
||||
end
|
||||
---Set a generic boolean that toggles varies function of the mod
|
||||
---@return boolean
|
||||
function ModDataHandler:getIsAnyLimbCut()
|
||||
--if self.isDataReady == false then return false end
|
||||
return self.tocData.isAnyLimbCut
|
||||
end
|
||||
|
||||
---Get isIgnoredPartInfected
|
||||
---@return boolean
|
||||
function ModDataHandler:getIsIgnoredPartInfected()
|
||||
return self.tocData.isIgnoredPartInfected
|
||||
end
|
||||
|
||||
---Get isCut
|
||||
---@param limbName string
|
||||
---@return boolean
|
||||
function ModDataHandler:getIsCut(limbName)
|
||||
if not self.isDataReady then return false end
|
||||
|
||||
if self.tocData.limbs[limbName] then
|
||||
return self.tocData.limbs[limbName].isCut
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
---Get isVisible
|
||||
---@param limbName string
|
||||
---@return boolean
|
||||
function ModDataHandler:getIsVisible(limbName)
|
||||
if not self.isDataReady then return false end
|
||||
|
||||
return self.tocData.limbs[limbName].isVisible
|
||||
end
|
||||
|
||||
---Get isCicatrized
|
||||
---@param limbName string
|
||||
---@return boolean
|
||||
function ModDataHandler:getIsCicatrized(limbName)
|
||||
return self.tocData.limbs[limbName].isCicatrized
|
||||
end
|
||||
|
||||
---Get isCauterized
|
||||
---@param limbName string
|
||||
---@return boolean
|
||||
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
|
||||
function ModDataHandler:getCicatrizationTime(limbName)
|
||||
return self.tocData.limbs[limbName].cicatrizationTime
|
||||
end
|
||||
|
||||
---Get isProstEquipped
|
||||
---@param group string
|
||||
---@return boolean
|
||||
function ModDataHandler:getIsProstEquipped(group)
|
||||
return self.tocData.prostheses[group].isProstEquipped
|
||||
end
|
||||
|
||||
---Get prostFactor
|
||||
---@param group string
|
||||
---@return number
|
||||
function ModDataHandler:getProstFactor(group)
|
||||
return self.tocData.prostheses[group].prostFactor
|
||||
end
|
||||
|
||||
--* Limbs data handling *--
|
||||
|
||||
---Set a limb and its dependend limbs as cut
|
||||
---@param limbName string
|
||||
---@param isOperated boolean
|
||||
---@param isCicatrized boolean
|
||||
---@param isCauterized boolean
|
||||
---@param surgeonFactor number?
|
||||
function ModDataHandler:setCutLimb(limbName, isOperated, isCicatrized, isCauterized, surgeonFactor)
|
||||
local cicatrizationTime = 0
|
||||
if isCicatrized == false or isCauterized == false then
|
||||
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, woundDirtyness = 0, isVisible = true}
|
||||
self:setLimbParams(limbName, params, cicatrizationTime)
|
||||
|
||||
for i=1, #StaticData.LIMBS_DEPENDENCIES_IND_STR[limbName] do
|
||||
local dependedLimbName = StaticData.LIMBS_DEPENDENCIES_IND_STR[limbName][i]
|
||||
|
||||
-- We don't care about isOperated, isCicatrized, isCauterized since this is depending on another limb
|
||||
-- Same story for cicatrizationTime, which will be 0
|
||||
-- isCicatrized is to true to prevent it from doing the cicatrization process
|
||||
self:setLimbParams(dependedLimbName, {isCut = true, isInfected = false, isVisible = false, isCicatrized = true}, 0)
|
||||
end
|
||||
|
||||
-- Set that a limb has been cut, to activate some functions without having to loop through the parts
|
||||
self:setIsAnyLimbCut(true)
|
||||
|
||||
-- TODO In theory we should cache data from here, not AmputationHandler
|
||||
end
|
||||
|
||||
---Set a limb data
|
||||
---@param limbName string
|
||||
---@param ampStatus partData {isCut, isInfected, isOperated, isCicatrized, isCauterized, isVisible}
|
||||
---@param cicatrizationTime integer?
|
||||
function ModDataHandler:setLimbParams(limbName, ampStatus, cicatrizationTime)
|
||||
local limbData = self.tocData.limbs[limbName]
|
||||
if ampStatus.isCut ~= nil then limbData.isCut = ampStatus.isCut end
|
||||
if ampStatus.isInfected ~= nil then limbData.isInfected = ampStatus.isInfected end
|
||||
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
|
||||
end
|
||||
|
||||
--* Update statuses of a limb *--
|
||||
|
||||
---Decreases the cicatrization time
|
||||
---@param limbName string
|
||||
function ModDataHandler:decreaseCicatrizationTime(limbName)
|
||||
self.tocData.limbs[limbName].cicatrizationTime = self.tocData.limbs[limbName].cicatrizationTime - 1
|
||||
end
|
||||
|
||||
--* Global Mod Data Handling *--
|
||||
|
||||
function ModDataHandler:apply()
|
||||
ModData.transmit(CommandsData.GetKey(self.username))
|
||||
end
|
||||
|
||||
function ModDataHandler.ReceiveData(key, data)
|
||||
if not isClient() then
|
||||
TOC_DEBUG.print("SP, skipping ModDataHandler.ReceiveData")
|
||||
end
|
||||
-- During startup the game can return Bob as the player username, adding a useless ModData table
|
||||
if key == "TOC_Bob" then return end
|
||||
|
||||
TOC_DEBUG.print("[ModDataHandler] ReceiveData for " .. key)
|
||||
if data == {} or data == nil then
|
||||
TOC_DEBUG.print("table is nil... returning")
|
||||
return
|
||||
end
|
||||
|
||||
-- Get ModDataHandler instance if there was none for that user and reapply the correct ModData table as a reference
|
||||
local username = key:sub(5)
|
||||
local handler = ModDataHandler.GetInstance(username)
|
||||
if handler.isResetForced or data == nil or data == {} or data == false then
|
||||
TOC_DEBUG.print("[ModDataHandler] Setup")
|
||||
handler:setup(key)
|
||||
handler.isResetForced = false
|
||||
else
|
||||
TOC_DEBUG.print("[ModDataHandler] Reapply")
|
||||
handler:reapplyTocData(data)
|
||||
end
|
||||
|
||||
|
||||
-- if handler.isResetForced or handler.tocData == nil or handler.tocData.limbs == nil or handler.tocData.limbs.Hand_L == nil or handler.tocData.limbs.Hand_L.isCut == nil then
|
||||
-- TOC_DEBUG.print("tocData in ModDataHandler for " .. handler.username .. " is nil, creating it now")
|
||||
-- handler:setup(key)
|
||||
-- handler.isResetForced = false
|
||||
-- elseif table then
|
||||
-- TOC_DEBUG.print("Reapply toc data for " .. handler.username)
|
||||
-- handler:reapplyTocData(table)
|
||||
-- end
|
||||
|
||||
handler:setIsDataReady(true)
|
||||
|
||||
-- Event
|
||||
triggerEvent("OnReceivedTocData", handler.username)
|
||||
|
||||
-- Transmit it to the server
|
||||
ModData.transmit(key)
|
||||
TOC_DEBUG.print("[ModDataHandler] Transmitting data after receiving it for: " .. handler.username)
|
||||
|
||||
end
|
||||
|
||||
Events.OnReceiveGlobalModData.Add(ModDataHandler.ReceiveData)
|
||||
|
||||
-------------------
|
||||
|
||||
---@param username string?
|
||||
---@return ModDataHandler
|
||||
function ModDataHandler.GetInstance(username)
|
||||
if username == nil or username == "Bob" then
|
||||
username = getPlayer():getUsername()
|
||||
end
|
||||
|
||||
if ModDataHandler.instances[username] == nil then
|
||||
TOC_DEBUG.print("[ModDataHandler] Creating NEW instance for " .. username)
|
||||
return ModDataHandler:new(username)
|
||||
else
|
||||
return ModDataHandler.instances[username]
|
||||
end
|
||||
end
|
||||
|
||||
return ModDataHandler
|
||||
@@ -1,534 +0,0 @@
|
||||
local ModDataHandler = require("TOC/Handlers/ModDataHandler")
|
||||
local CommonMethods = require("TOC/CommonMethods")
|
||||
local CachedDataHandler = require("TOC/Handlers/CachedDataHandler")
|
||||
local StaticData = require("TOC/StaticData")
|
||||
-----------
|
||||
|
||||
-- THIS SHOULD BE LOCAL ONLY! WE'RE MANAGING EVENTS AND INITIALIZATION STUFF!
|
||||
|
||||
-- LIST OF STUFF THAT THIS CLASS NEEDS TO DO
|
||||
-- Keep track of cut limbs so that we don't have to loop through all of them all the time
|
||||
-- Update current player status (infection checks)
|
||||
-- handle stats increase\decrease
|
||||
|
||||
---@class PlayerHandler
|
||||
---@field playerObj IsoPlayer
|
||||
---@field username string
|
||||
---@field hasBeenDamaged boolean
|
||||
local PlayerHandler = {}
|
||||
|
||||
---Setup the Player Handler and modData, only for local client
|
||||
---@param playerObj IsoPlayer
|
||||
---@param isForced boolean?
|
||||
function PlayerHandler.InitializePlayer(playerObj, isForced)
|
||||
local username = playerObj:getUsername()
|
||||
|
||||
TOC_DEBUG.print("[PlayerHandler] Initializing local player: " .. username)
|
||||
|
||||
ModDataHandler:new(username, isForced)
|
||||
PlayerHandler.playerObj = playerObj
|
||||
PlayerHandler.username = username
|
||||
|
||||
-- Calculate amputated limbs and highest point of amputations at startup
|
||||
--CachedDataHandler.CalculateAmputatedLimbs(username)
|
||||
--CachedDataHandler.CalculateHighestAmputatedLimbs(username)
|
||||
|
||||
--Setup the CicatrizationUpdate event and triggers it once
|
||||
Events.OnAmputatedLimb.Add(PlayerHandler.ToggleUpdateAmputations)
|
||||
PlayerHandler.ToggleUpdateAmputations()
|
||||
|
||||
-- Since isForced is used to reset an existing player data, we're gonna clean their ISHealthPanel table too
|
||||
if isForced then
|
||||
local ItemsHandler = require("TOC/Handlers/ItemsHandler")
|
||||
ItemsHandler.Player.DeleteAllOldAmputationItems(playerObj)
|
||||
CachedDataHandler.Reset(username)
|
||||
end
|
||||
|
||||
-- Set a bool to use an overriding GetDamagedParts
|
||||
SetHealthPanelTOC()
|
||||
|
||||
end
|
||||
|
||||
---Handles the traits
|
||||
---@param playerObj IsoPlayer
|
||||
function PlayerHandler.ManageTraits(playerObj)
|
||||
local AmputationHandler = require("Handlers/TOC_AmputationHandler")
|
||||
for k, v in pairs(StaticData.TRAITS_BP) do
|
||||
if playerObj:HasTrait(k) then
|
||||
-- Once we find one, we should be done.
|
||||
local tempHandler = AmputationHandler:new(v)
|
||||
tempHandler:execute(false) -- No damage
|
||||
tempHandler:close()
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--* Health management *--
|
||||
|
||||
---Used to heal an area that has been cut previously. There's an exception for bites, those are managed differently
|
||||
---@param bodyPart BodyPart
|
||||
function PlayerHandler.HealArea(bodyPart)
|
||||
bodyPart:setBleeding(false)
|
||||
bodyPart:setBleedingTime(0)
|
||||
|
||||
bodyPart:SetBitten(false)
|
||||
bodyPart:setBiteTime(0)
|
||||
|
||||
bodyPart:setCut(false)
|
||||
bodyPart:setCutTime(0)
|
||||
|
||||
bodyPart:setDeepWounded(false)
|
||||
bodyPart:setDeepWoundTime(0)
|
||||
|
||||
bodyPart:setHaveBullet(false, 0)
|
||||
bodyPart:setHaveGlass(false)
|
||||
bodyPart:setSplint(false, 0)
|
||||
end
|
||||
|
||||
---comment
|
||||
---@param bodyDamage BodyDamage
|
||||
---@param bodyPart BodyPart
|
||||
---@param limbName string
|
||||
---@param modDataHandler ModDataHandler
|
||||
function PlayerHandler.HealZombieInfection(bodyDamage, bodyPart, limbName, modDataHandler)
|
||||
if bodyDamage:isInfected() == false then return end
|
||||
|
||||
bodyDamage:setInfected(false)
|
||||
bodyDamage:setInfectionMortalityDuration(-1)
|
||||
bodyDamage:setInfectionTime(-1)
|
||||
bodyDamage:setInfectionLevel(-1)
|
||||
bodyPart:SetInfected(false)
|
||||
|
||||
modDataHandler:setIsInfected(limbName, false)
|
||||
modDataHandler:apply()
|
||||
end
|
||||
|
||||
---comment
|
||||
---@param character IsoPlayer
|
||||
---@param limbName string
|
||||
function PlayerHandler.TryRandomBleed(character, limbName)
|
||||
-- Chance should be determined by the cicatrization time
|
||||
local cicTime = ModDataHandler.GetInstance():getCicatrizationTime(limbName)
|
||||
if cicTime == 0 then return end
|
||||
-- TODO Sometimes we get cicTime = 0... Shouldn't really do it
|
||||
|
||||
-- TODO This is just a placeholder, we need to figure out a better way to calculate this chance
|
||||
local normCicTime = CommonMethods.Normalize(cicTime, 0, StaticData.LIMBS_CICATRIZATION_TIME_IND_NUM[limbName])/2
|
||||
TOC_DEBUG.print("OG cicTime: " .. tostring(cicTime))
|
||||
TOC_DEBUG.print("Normalized cic time : " .. tostring(normCicTime))
|
||||
|
||||
local chance = ZombRandFloat(0.0, 1.0)
|
||||
if chance > normCicTime then
|
||||
TOC_DEBUG.print("Triggered bleeding from non cicatrized wound")
|
||||
local adjacentBodyPartType = BodyPartType[StaticData.LIMBS_ADJACENT_IND_STR[limbName]]
|
||||
character:getBodyDamage():getBodyPart(adjacentBodyPartType):setBleeding(true)
|
||||
character:getBodyDamage():getBodyPart(adjacentBodyPartType):setBleedingTime(20)
|
||||
end
|
||||
end
|
||||
-------------------------
|
||||
--* Events *--
|
||||
--- Locks OnPlayerGetDamage event, to prevent it from getting spammed constantly
|
||||
PlayerHandler.hasBeenDamaged = false
|
||||
|
||||
|
||||
---Check if the player has in infected body part or if they have been hit in a cut area
|
||||
---@param character IsoPlayer
|
||||
function PlayerHandler.HandleDamage(character)
|
||||
-- TOC_DEBUG.print("Player got hit!")
|
||||
-- TOC_DEBUG.print(damageType)
|
||||
if character ~= getPlayer() then return end
|
||||
local bd = character:getBodyDamage()
|
||||
local modDataHandler = ModDataHandler.GetInstance()
|
||||
local modDataNeedsUpdate = false
|
||||
for i=1, #StaticData.LIMBS_STR do
|
||||
local limbName = StaticData.LIMBS_STR[i]
|
||||
local bptEnum = StaticData.BODYLOCS_IND_BPT[limbName]
|
||||
local bodyPart = bd:getBodyPart(bptEnum)
|
||||
if modDataHandler:getIsCut(limbName) then
|
||||
|
||||
-- Generic injury, let's heal it since they already cut the limb off
|
||||
if bodyPart:HasInjury() then
|
||||
PlayerHandler.HealArea(bodyPart)
|
||||
end
|
||||
|
||||
-- Special case for bites\zombie infections
|
||||
if bodyPart:IsInfected() then
|
||||
TOC_DEBUG.print("Healed from zombie infection " .. tostring(bodyPart))
|
||||
PlayerHandler.HealZombieInfection(bd, bodyPart, limbName, modDataHandler)
|
||||
end
|
||||
else
|
||||
if bodyPart:bitten() or bodyPart:IsInfected() then
|
||||
modDataHandler:setIsInfected(limbName, true)
|
||||
modDataNeedsUpdate = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- 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
|
||||
if modDataHandler:getIsIgnoredPartInfected() then return end
|
||||
|
||||
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:setIsIgnoredPartInfected(true)
|
||||
modDataNeedsUpdate = true
|
||||
end
|
||||
end
|
||||
|
||||
-- TODO in theory should sync modData, but it's gonna be expensive as fuck. Figure it out
|
||||
if modDataNeedsUpdate then
|
||||
modDataHandler:apply()
|
||||
end
|
||||
|
||||
-- Disable the lock
|
||||
PlayerHandler.hasBeenDamaged = false
|
||||
|
||||
end
|
||||
|
||||
---Setup HandleDamage, triggered by OnPlayerGetDamage
|
||||
---@param character IsoGameCharacter
|
||||
---@param damageType string
|
||||
---@param damageAmount number
|
||||
function PlayerHandler.OnGetDamage(character, damageType, damageAmount)
|
||||
|
||||
-- TODO Check if other players in the online triggers this
|
||||
|
||||
if PlayerHandler.hasBeenDamaged == false then
|
||||
-- Start checks
|
||||
|
||||
-- TODO Add a timer before we can re-enable this bool?
|
||||
PlayerHandler.hasBeenDamaged = true
|
||||
PlayerHandler.HandleDamage(character)
|
||||
end
|
||||
end
|
||||
|
||||
Events.OnPlayerGetDamage.Add(PlayerHandler.OnGetDamage)
|
||||
|
||||
---Updates the cicatrization process, run when a limb has been cut. Run it every 1 hour
|
||||
function PlayerHandler.UpdateAmputations()
|
||||
local modDataHandler = ModDataHandler.GetInstance()
|
||||
if modDataHandler:getIsAnyLimbCut() == false then
|
||||
Events.EveryHours.Remove(PlayerHandler.UpdateAmputations)
|
||||
end
|
||||
|
||||
local pl = PlayerHandler.playerObj
|
||||
local bd = pl:getBodyDamage()
|
||||
local visual = pl:getHumanVisual()
|
||||
local amputatedLimbs = CachedDataHandler.GetAmputatedLimbs(pl:getUsername())
|
||||
local needsUpdate = false
|
||||
|
||||
for k, _ in pairs(amputatedLimbs) do
|
||||
local limbName = k
|
||||
local isCicatrized = modDataHandler:getIsCicatrized(limbName)
|
||||
|
||||
if not isCicatrized then
|
||||
needsUpdate = true
|
||||
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 modifier = 0.01 * SandboxVars.TOC.WoundDirtynessMultiplier
|
||||
|
||||
--------------
|
||||
-- TEST SECTION
|
||||
|
||||
local dirtynessVis = visual:getDirt(bbptEnum) + visual:getBlood(bbptEnum)
|
||||
local dirtynessWound = modDataHandler:getWoundDirtyness(limbName) + modifier
|
||||
--------------
|
||||
|
||||
local dirtyness = dirtynessVis + dirtynessWound
|
||||
|
||||
if dirtyness > 1 then
|
||||
dirtyness = 1
|
||||
end
|
||||
|
||||
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))
|
||||
if cicTime <= 0 then
|
||||
TOC_DEBUG.print(tostring(limbName) .. " is cicatrized")
|
||||
modDataHandler:setIsCicatrized(limbName, true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if needsUpdate then
|
||||
TOC_DEBUG.print("updating modData from cicatrization loop")
|
||||
modDataHandler:apply() -- TODO This is gonna be heavy. Not entirely sure
|
||||
else
|
||||
TOC_DEBUG.print("Removing UpdateAmputations")
|
||||
Events.EveryHours.Remove(PlayerHandler.UpdateAmputations) -- We can remove it safely, no cicatrization happening here boys
|
||||
end
|
||||
TOC_DEBUG.print("updating cicatrization and wound dirtyness!")
|
||||
|
||||
end
|
||||
|
||||
---Starts safely the loop to update cicatrzation
|
||||
function PlayerHandler.ToggleUpdateAmputations()
|
||||
TOC_DEBUG.print("[PlayerHandler] Activating amputation handling loop (if it wasn't active before)")
|
||||
CommonMethods.SafeStartEvent("EveryHours", PlayerHandler.UpdateAmputations)
|
||||
end
|
||||
|
||||
|
||||
--* Helper functions for overrides *--
|
||||
|
||||
local function CheckHandFeasibility(limbName)
|
||||
local modDataHandler = ModDataHandler.GetInstance()
|
||||
|
||||
return not modDataHandler:getIsCut(limbName) or modDataHandler:getIsProstEquipped(StaticData.LIMBS_TO_PROST_GROUP_MATCH_IND_STR[limbName])
|
||||
end
|
||||
|
||||
------------------------------------------
|
||||
--* OVERRIDES *--
|
||||
|
||||
--* Time to perform actions overrides *--
|
||||
|
||||
local og_ISBaseTimedAction_adjustMaxTime = ISBaseTimedAction.adjustMaxTime
|
||||
--- Adjust time
|
||||
---@diagnostic disable-next-line: duplicate-set-field
|
||||
function ISBaseTimedAction:adjustMaxTime(maxTime)
|
||||
local time = og_ISBaseTimedAction_adjustMaxTime(self, maxTime)
|
||||
|
||||
-- Exceptions handling, if we find that parameter then we just use the original time
|
||||
local queue = ISTimedActionQueue.getTimedActionQueue(getPlayer())
|
||||
if queue and queue.current and queue.current.skipTOC then return time end
|
||||
|
||||
-- Action is valid, check if we have any cut limb and then modify maxTime
|
||||
local modDataHandler = ModDataHandler.GetInstance()
|
||||
if time ~= -1 and modDataHandler and modDataHandler:getIsAnyLimbCut() then
|
||||
local pl = getPlayer()
|
||||
local amputatedLimbs = CachedDataHandler.GetAmputatedLimbs(pl:getUsername())
|
||||
|
||||
for k, _ in pairs(amputatedLimbs) do
|
||||
local limbName = k
|
||||
--if modDataHandler:getIsCut(limbName) then
|
||||
local perk = Perks["Side_" .. CommonMethods.GetSide(limbName)]
|
||||
local perkLevel = pl:getPerkLevel(perk)
|
||||
local perkLevelScaled
|
||||
if perkLevel ~= 0 then perkLevelScaled = perkLevel / 10 else perkLevelScaled = 0 end
|
||||
time = time * (StaticData.LIMBS_TIME_MULTIPLIER_IND_NUM[limbName] - perkLevelScaled)
|
||||
--end
|
||||
end
|
||||
end
|
||||
return time
|
||||
end
|
||||
|
||||
|
||||
--* Random bleeding during cicatrization + Perks leveling override *--
|
||||
local og_ISBaseTimedAction_perform = ISBaseTimedAction.perform
|
||||
--- After each action, level up perks
|
||||
---@diagnostic disable-next-line: duplicate-set-field
|
||||
function ISBaseTimedAction:perform()
|
||||
og_ISBaseTimedAction_perform(self)
|
||||
|
||||
local modDataHandler = ModDataHandler.GetInstance()
|
||||
if not modDataHandler:getIsAnyLimbCut() then return end
|
||||
|
||||
local amputatedLimbs = CachedDataHandler.GetAmputatedLimbs(PlayerHandler.username)
|
||||
for k, _ in pairs(amputatedLimbs) do
|
||||
local limbName = k
|
||||
if modDataHandler:getIsCut(limbName) then
|
||||
local side = CommonMethods.GetSide(limbName)
|
||||
PlayerHandler.playerObj:getXp():AddXP(Perks["Side_" .. side], 1) -- TODO Make it dynamic
|
||||
local prostGroup = StaticData.LIMBS_TO_PROST_GROUP_MATCH_IND_STR[limbName]
|
||||
if not modDataHandler:getIsCicatrized(limbName) and modDataHandler:getIsProstEquipped(prostGroup) then
|
||||
TOC_DEBUG.print("Trying for bleed, player met the criteria")
|
||||
-- TODO If we have cut a forearm, it will try to check the hand too, with cicatrization time = 0. We should skip this
|
||||
PlayerHandler.TryRandomBleed(self.character, limbName)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--* Equipping items overrides *--
|
||||
|
||||
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 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
|
||||
---@diagnostic disable-next-line: duplicate-set-field
|
||||
function ISEquipWeaponAction:isValid()
|
||||
local isValid = og_ISEquipWeaponAction_isValid(self)
|
||||
local modDataHandler = ModDataHandler.GetInstance(self.character:getUsername())
|
||||
if isValid and modDataHandler:getIsAnyLimbCut() then
|
||||
local isPrimaryHandValid = CheckHandFeasibility(primaryHand)
|
||||
local isSecondaryHandValid = CheckHandFeasibility(secondaryHand)
|
||||
|
||||
--TOC_DEBUG.print("isPrimaryHandValid: " .. tostring(isPrimaryHandValid))
|
||||
--TOC_DEBUG.print("isSecondaryHandValid: " .. tostring(isSecondaryHandValid))
|
||||
|
||||
-- Both hands are cut off, so it's impossible to equip in any way
|
||||
if not isPrimaryHandValid and not isSecondaryHandValid then
|
||||
--TOC_DEBUG.print("Both hands invalid")
|
||||
isValid = false
|
||||
end
|
||||
end
|
||||
-- -- 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")
|
||||
-- isValid = false
|
||||
-- end
|
||||
|
||||
-- -- 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")
|
||||
-- isValid = false
|
||||
-- end
|
||||
-- end
|
||||
|
||||
--TOC_DEBUG.print("isValid to return -> " .. tostring(isValid))
|
||||
--print("_________________________________")
|
||||
return isValid
|
||||
end
|
||||
|
||||
|
||||
---@class ISEquipWeaponAction
|
||||
---@field character IsoPlayer
|
||||
|
||||
---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 otherHand = nil
|
||||
local getMethodFirst = nil
|
||||
local setMethodFirst = nil
|
||||
local getMethodSecond = nil
|
||||
local setMethodSecond = nil
|
||||
|
||||
if self.primary then
|
||||
hand = StaticData.LIMBS_IND_STR.Hand_R
|
||||
otherHand = StaticData.LIMBS_IND_STR.Hand_L
|
||||
getMethodFirst = self.character.getSecondaryHandItem
|
||||
setMethodFirst = self.character.setSecondaryHandItem
|
||||
getMethodSecond = self.character.getPrimaryHandItem
|
||||
setMethodSecond = self.character.setPrimaryHandItem
|
||||
else
|
||||
hand = StaticData.LIMBS_IND_STR.Hand_L
|
||||
otherHand = StaticData.LIMBS_IND_STR.Hand_R
|
||||
getMethodFirst = self.character.getPrimaryHandItem
|
||||
setMethodFirst = self.character.setPrimaryHandItem
|
||||
getMethodSecond = self.character.getSecondaryHandItem
|
||||
setMethodSecond = self.character.setSecondaryHandItem
|
||||
end
|
||||
|
||||
|
||||
if not self.twoHands then
|
||||
if getMethodFirst(self.character) and getMethodFirst(self.character):isRequiresEquippedBothHands() then
|
||||
setMethodFirst(self.character, nil)
|
||||
-- if this weapon is already equiped in the 2nd hand, we remove it
|
||||
elseif (getMethodFirst(self.character) == self.item or getMethodFirst(self.character) == getMethodSecond(self.character)) then
|
||||
setMethodFirst(self.character, nil)
|
||||
-- if we are equipping a handgun and there is a weapon in the secondary hand we remove it
|
||||
elseif instanceof(self.item, "HandWeapon") and self.item:getSwingAnim() and self.item:getSwingAnim() == "Handgun" then
|
||||
if getMethodFirst(self.character) and instanceof(getMethodFirst(self.character), "HandWeapon") then
|
||||
setMethodFirst(self.character, nil)
|
||||
end
|
||||
else
|
||||
setMethodSecond(self.character, nil)
|
||||
-- TODO We should use the CachedData indexable instead of modDataHandler
|
||||
|
||||
if not modDataHandler:getIsCut(hand) then
|
||||
setMethodSecond(self.character, self.item)
|
||||
-- Check other HAND!
|
||||
elseif not modDataHandler:getIsCut(otherHand) then
|
||||
setMethodFirst(self.character, self.item)
|
||||
end
|
||||
end
|
||||
|
||||
else
|
||||
setMethodFirst(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("Prost Group: " .. tostring(prostGroup))
|
||||
-- TOC_DEBUG.print("Other Hand: " .. tostring(otherHand))
|
||||
-- TOC_DEBUG.print("Other Prost Group: " .. tostring(otherProstGroup))
|
||||
|
||||
-- TOC_DEBUG.print("isPrimaryHandValid: " .. tostring(isFirstValid))
|
||||
-- TOC_DEBUG.print("isSecondaryHandValid: " .. tostring(isSecondValid))
|
||||
|
||||
|
||||
if isFirstValid then
|
||||
setMethodSecond(self.character, self.item)
|
||||
end
|
||||
|
||||
if isSecondValid then
|
||||
setMethodFirst(self.character, self.item)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local og_ISEquipWeaponAction_perform = ISEquipWeaponAction.perform
|
||||
---@diagnostic disable-next-line: duplicate-set-field
|
||||
function ISEquipWeaponAction:perform()
|
||||
|
||||
og_ISEquipWeaponAction_perform(self)
|
||||
|
||||
-- TODO Can we do it earlier?
|
||||
local modDataHandler = ModDataHandler.GetInstance(self.character:getUsername())
|
||||
-- Just check it any limb has been cut. If not, we can just return from here
|
||||
if modDataHandler:getIsAnyLimbCut() == true then
|
||||
self:performWithAmputation(modDataHandler)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function ISInventoryPaneContextMenu.doEquipOption(context, playerObj, isWeapon, items, player)
|
||||
|
||||
|
||||
-- check if hands if not heavy damaged
|
||||
if (not playerObj:isPrimaryHandItem(isWeapon) or (playerObj:isPrimaryHandItem(isWeapon) and playerObj:isSecondaryHandItem(isWeapon))) and not getSpecificPlayer(player):getBodyDamage():getBodyPart(BodyPartType.Hand_R):isDeepWounded() and (getSpecificPlayer(player):getBodyDamage():getBodyPart(BodyPartType.Hand_R):getFractureTime() == 0 or getSpecificPlayer(player):getBodyDamage():getBodyPart(BodyPartType.Hand_R):getSplintFactor() > 0) then
|
||||
-- forbid reequipping skinned items to avoid multiple problems for now
|
||||
local add = true
|
||||
if playerObj:getSecondaryHandItem() == isWeapon and isWeapon:getScriptItem():getReplaceWhenUnequip() then
|
||||
add = false
|
||||
end
|
||||
if add then
|
||||
local equipOption = context:addOption(getText("ContextMenu_Equip_Primary"), items, ISInventoryPaneContextMenu.OnPrimaryWeapon, player)
|
||||
equipOption.notAvailable = not CheckHandFeasibility(StaticData.LIMBS_IND_STR.Hand_R)
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
if (not playerObj:isSecondaryHandItem(isWeapon) or (playerObj:isPrimaryHandItem(isWeapon) and playerObj:isSecondaryHandItem(isWeapon))) and not getSpecificPlayer(player):getBodyDamage():getBodyPart(BodyPartType.Hand_L):isDeepWounded() and (getSpecificPlayer(player):getBodyDamage():getBodyPart(BodyPartType.Hand_L):getFractureTime() == 0 or getSpecificPlayer(player):getBodyDamage():getBodyPart(BodyPartType.Hand_L):getSplintFactor() > 0) then
|
||||
-- forbid reequipping skinned items to avoid multiple problems for now
|
||||
local add = true
|
||||
if playerObj:getPrimaryHandItem() == isWeapon and isWeapon:getScriptItem():getReplaceWhenUnequip() then
|
||||
add = false
|
||||
end
|
||||
if add then
|
||||
local equipOption = context:addOption(getText("ContextMenu_Equip_Secondary"), items, ISInventoryPaneContextMenu.OnSecondWeapon, player)
|
||||
|
||||
equipOption.notAvailable = not CheckHandFeasibility(StaticData.LIMBS_IND_STR.Hand_L)
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
return PlayerHandler
|
||||
@@ -1,6 +1,6 @@
|
||||
local CommonMethods = require("TOC/CommonMethods")
|
||||
local StaticData = require("TOC/StaticData")
|
||||
local ModDataHandler = require("TOC/Handlers/ModDataHandler")
|
||||
local DataController = require("TOC/Controllers/DataController")
|
||||
local CachedDataHandler = require("TOC/Handlers/CachedDataHandler")
|
||||
-------------------------
|
||||
|
||||
@@ -67,9 +67,9 @@ function ProsthesisHandler.SearchAndSetupProsthesis(item, isEquipping)
|
||||
|
||||
local group = ProsthesisHandler.GetGroup(item)
|
||||
TOC_DEBUG.print("applying prosthesis stuff for " .. group)
|
||||
local modDataHandler = ModDataHandler.GetInstance()
|
||||
modDataHandler:setIsProstEquipped(group, isEquipping)
|
||||
modDataHandler:apply()
|
||||
local dcInst = DataController.GetInstance()
|
||||
dcInst:setIsProstEquipped(group, isEquipping)
|
||||
dcInst:apply()
|
||||
|
||||
end
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
local ModDataHandler = require("TOC/Handlers/ModDataHandler")
|
||||
local DataController = require("TOC/Controllers/DataController")
|
||||
|
||||
---@class SurgeryHandler
|
||||
---@field type string
|
||||
@@ -28,7 +28,7 @@ function SurgeryHandler:execute()
|
||||
|
||||
|
||||
if self.type == "oven" then
|
||||
ModDataHandler.GetInstance():setIsCauterized(self.limbName, true)
|
||||
DataController.GetInstance():setIsCauterized(self.limbName, true)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user