Trying to make stuff work in MP

This commit is contained in:
ZioPao
2023-11-12 05:35:54 +01:00
parent a691a729cf
commit 3443198edb
5 changed files with 104 additions and 73 deletions

View File

@@ -1,64 +1,36 @@
local StaticData = require("TOC/StaticData")
----------------
--This class should handle all the stuff related to the mod data
--- Handle all mod data related stuff
---@class ModDataHandler
---@field playerObj IsoPlayer
---@field tocData tocModData
local ModDataHandler = {}
ModDataHandler.instances = {}
---@param playerObj IsoPlayer
function ModDataHandler.AddExternalTocData(username, tocData)
end
---@param username string
---@param tocData tocModData
---@return ModDataHandler
function ModDataHandler:new(playerObj)
function ModDataHandler:new(username, tocData)
local o = {}
setmetatable(o, self)
self.__index = self
-- TODO Instead of requiring a player, to make it compatible in a MP env, we should require the table containing the modData for the init
-- Instead of requiring a player, to make it compatible in a MP env, we should require the table containing the modData for the init
o.playerObj = playerObj
o.tocData = playerObj:getModData()[StaticData.MOD_NAME]
ModDataHandler.instance = o
o.tocData = tocData
ModDataHandler.instances[username] = o
return o
end
---Setup a newly instanced ModDataHandler
---@param force boolean?
function ModDataHandler:setup(force)
local tocData = self.playerObj:getModData()[StaticData.MOD_NAME]
if force or tocData == nil or tocData.Hand_L == nil or tocData.Hand_L.isCut == nil then
self:createData()
end
-- TODO Check compatibility or do we just skip it at this point?
end
function ModDataHandler:createData()
print("TOC: createData")
local modData = self.playerObj:getModData()
modData[StaticData.MOD_NAME] = {
-- Generic stuff that does not belong anywhere else
isIgnoredPartInfected = false,
isAnyLimbCut = false
}
-- Set a reference to TOC data in ModData
self.tocData = self.playerObj:getModData()[StaticData.MOD_NAME]
---@type partData
local defaultParams = {isCut = false, isInfected = false, isOperated = false, isCicatrized = false, isCauterized = false, isVisible = false}
-- Initialize limbs
for i=1, #StaticData.LIMBS_STRINGS do
local limbName = StaticData.LIMBS_STRINGS[i]
modData[StaticData.MOD_NAME][limbName] = {}
self:setLimbParams(StaticData.LIMBS_STRINGS[i], defaultParams, 0)
end
end
-----------------
--* Setters *--
@@ -148,11 +120,10 @@ function ModDataHandler:setCutLimb(limbName, isOperated, isCicatrized, isCauteri
end
---Internal use only, set a limb data
---Set a limb data
---@param limbName string
---@param ampStatus partData {isCut, isInfected, isOperated, isCicatrized, isCauterized, isVisible}
---@param cicatrizationTime integer?
---@private
function ModDataHandler:setLimbParams(limbName, ampStatus, cicatrizationTime)
local limbData = self.tocData[limbName]
if ampStatus.isCut ~= nil then limbData.isCut = ampStatus.isCut end
@@ -165,12 +136,18 @@ function ModDataHandler:setLimbParams(limbName, ampStatus, cicatrizationTime)
if cicatrizationTime ~= nil then limbData.cicatrizationTime = cicatrizationTime end
end
---@return ModDataHandler
function ModDataHandler.GetInstance()
if ModDataHandler.instance ~= nil then
return ModDataHandler.instance
---@param username string?
---@return ModDataHandler?
function ModDataHandler.GetInstance(username)
if username == nil then username = getPlayer():getUsername() end
if ModDataHandler.instances[username] ~= nil then
return ModDataHandler.instances[username]
else
return ModDataHandler:new(getPlayer())
return nil -- TODO This isn't exactly good
--return ModDataHandler:new(getPlayer())
end
end

View File

@@ -15,13 +15,12 @@ local StaticData = require("TOC/StaticData")
---@field playerObj IsoPlayer
local PlayerHandler = {}
---Setup player modData
---Setup the Player Handler and modData
---@param _ nil
---@param playerObj IsoPlayer
---@param isForced boolean?
function PlayerHandler.InitializePlayer(_, playerObj, isForced)
PlayerHandler.modDataHandler = ModDataHandler:new(playerObj) -- TODO This isn't gonna work for MP purposes
PlayerHandler.modDataHandler:setup(isForced)
PlayerHandler.SetupModData(playerObj, isForced)
PlayerHandler.playerObj = playerObj
-- Calculate amputated limbs at startup
@@ -29,7 +28,7 @@ function PlayerHandler.InitializePlayer(_, playerObj, isForced)
for i=1, #StaticData.LIMBS_STRINGS do
local limbName = StaticData.LIMBS_STRINGS[i]
if PlayerHandler.modDataHandler:getIsCut(limbName) then
if ModDataHandler.GetInstance():getIsCut(limbName) then
PlayerHandler.AddLocalAmputatedLimb(limbName)
end
end
@@ -42,6 +41,35 @@ function PlayerHandler.InitializePlayer(_, playerObj, isForced)
end
end
---Setup TOC mod data to a local client
---@param playerObj IsoPlayer
---@param isForced boolean?
function PlayerHandler.SetupModData(playerObj, isForced)
local tocData = playerObj:getModData()[StaticData.MOD_NAME]
if isForced or tocData == nil or tocData.Hand_L == nil or tocData.Hand_L.isCut == nil then
local modData = playerObj:getModData()
modData[StaticData.MOD_NAME] = {
-- Generic stuff that does not belong anywhere else
isIgnoredPartInfected = false,
isAnyLimbCut = false
}
---@type partData
local defaultParams = {isCut = false, isInfected = false, isOperated = false, isCicatrized = false, isCauterized = false, isVisible = false}
-- We're gonna make a instance of ModDataHandler to setup this player
local plUsername = playerObj:getUsername()
local dataHandler = ModDataHandler:new(plUsername, modData[StaticData.MOD_NAME])
-- Initialize limbs
for i=1, #StaticData.LIMBS_STRINGS do
local limbName = StaticData.LIMBS_STRINGS[i]
modData[StaticData.MOD_NAME][limbName] = {}
dataHandler:setLimbParams(StaticData.LIMBS_STRINGS[i], defaultParams, 0)
end
end
end
---Handles the traits
---@param playerObj IsoPlayer
function PlayerHandler.ManageTraits(playerObj)
@@ -57,7 +85,6 @@ function PlayerHandler.ManageTraits(playerObj)
end
end
---Cache the currently amputated limbs
---@param limbName string
function PlayerHandler.AddLocalAmputatedLimb(limbName)
@@ -87,23 +114,23 @@ function PlayerHandler.CheckInfection(character)
local bodyPart = bd:getBodyPart(bptEnum)
if bodyPart:bitten() or bodyPart:IsInfected() then
if PlayerHandler.modDataHandler:getIsCut(limbName) then
if ModDataHandler.GetInstance():getIsCut(limbName) then
bodyPart:SetBitten(false)
else
PlayerHandler.modDataHandler:setIsInfected(limbName, true)
ModDataHandler.GetInstance():setIsInfected(limbName, 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 PlayerHandler.modDataHandler:getIsIgnoredPartInfected() then return end
if ModDataHandler.GetInstance():getIsIgnoredPartInfected() then return end
for i=1, #StaticData.IGNORED_PARTS_STRINGS do
local bodyPartType = BodyPartType[StaticData.IGNORED_PARTS_STRINGS[i]]
local bodyPart = bd:getBodyPart(bodyPartType)
if bodyPart and (bodyPart:bitten() or bodyPart:IsInfected()) then
PlayerHandler.modDataHandler:setIsIgnoredPartInfected(true)
ModDataHandler.GetInstance():setIsIgnoredPartInfected(true)
end
end
end
@@ -140,7 +167,7 @@ local og_ISBaseTimedAction_perform = ISBaseTimedAction.perform
function ISBaseTimedAction:perform()
og_ISBaseTimedAction_perform(self)
if PlayerHandler.modDataHandler:getIsAnyLimbCut() then
if ModDataHandler.GetInstance():getIsAnyLimbCut() then
for side, _ in pairs(StaticData.SIDES_STRINGS) do
local limbName = "Hand_" .. side
if ModDataHandler.GetInstance():getIsCut(limbName) then

View File

@@ -4,6 +4,7 @@ local TestUtils = require("TestFramework/TestUtils")
local PlayerHandler = require("TOC/Handlers/PlayerHandler")
local AmputationHandler = require("TOC/Handlers/AmputationHandler")
local ModDataHandler = require("TOC/Handlers/ModDataHandler")
TestFramework.registerTestModule("Functionality", "PlayerHandler", function()
@@ -46,37 +47,37 @@ TestFramework.registerTestModule("Functionality", "Amputation", function()
function Tests.CutLeftHand()
local handler = AmputationHandler:new("Hand_L")
handler:execute()
TestUtils.assert(PlayerHandler.modDataHandler:getIsCut("Hand_L"))
TestUtils.assert(ModDataHandler.GetInstance():getIsCut("Hand_L"))
end
function Tests.CutLeftForearm()
local handler = AmputationHandler:new("ForeArm_L")
handler:execute()
TestUtils.assert(PlayerHandler.modDataHandler:getIsCut("ForeArm_L") and PlayerHandler.modDataHandler:getIsCut("Hand_L"))
TestUtils.assert(ModDataHandler.GetInstance():getIsCut("ForeArm_L") and ModDataHandler.GetInstance():getIsCut("Hand_L"))
end
function Tests.CutLeftUpperarm()
local handler = AmputationHandler:new("UpperArm_L")
handler:execute()
TestUtils.assert(PlayerHandler.modDataHandler:getIsCut("UpperArm_L") and PlayerHandler.modDataHandler:getIsCut("ForeArm_L") and PlayerHandler.modDataHandler:getIsCut("Hand_L"))
TestUtils.assert(ModDataHandler.GetInstance():getIsCut("UpperArm_L") and ModDataHandler.GetInstance():getIsCut("ForeArm_L") and ModDataHandler.GetInstance():getIsCut("Hand_L"))
end
function Tests.CutRightHand()
local handler = AmputationHandler:new("Hand_R")
handler:execute()
TestUtils.assert(PlayerHandler.modDataHandler:getIsCut("Hand_R"))
TestUtils.assert(ModDataHandler.GetInstance():getIsCut("Hand_R"))
end
function Tests.CutRightForearm()
local handler = AmputationHandler:new("ForeArm_R")
handler:execute()
TestUtils.assert(PlayerHandler.modDataHandler:getIsCut("ForeArm_R") and PlayerHandler.modDataHandler:getIsCut("Hand_R"))
TestUtils.assert(ModDataHandler.GetInstance():getIsCut("ForeArm_R") and ModDataHandler.GetInstance():getIsCut("Hand_R"))
end
function Tests.CutRightUpperarm()
local handler = AmputationHandler:new("UpperArm_R")
handler:execute()
TestUtils.assert(PlayerHandler.modDataHandler:getIsCut("UpperArm_R") and PlayerHandler.modDataHandler:getIsCut("ForeArm_R") and PlayerHandler.modDataHandler:getIsCut("Hand_R"))
TestUtils.assert(ModDataHandler.GetInstance():getIsCut("UpperArm_R") and ModDataHandler.GetInstance():getIsCut("ForeArm_R") and ModDataHandler.GetInstance():getIsCut("Hand_R"))
end
return Tests

View File

@@ -1,6 +1,7 @@
local PlayerHandler = require("TOC/Handlers/PlayerHandler")
local StaticData = require("TOC/StaticData")
local CommonMethods = require("TOC/CommonMethods")
local ModDataHandler = require("TOC/Handlers/ModDataHandler")
---@diagnostic disable: duplicate-set-field
local CutLimbHandler = require("TOC/UI/CutLimbInteractions")
@@ -43,18 +44,27 @@ end
--* Modification to handle visible amputation on the health menu *--
function ISHealthPanel.GetHighestAmputation()
ISHealthPanel.highestAmputations = {}
function ISHealthPanel:setHighestAmputation()
if self.otherPlayer ~= nil then
self.tocUsername = self.otherPlayer:getUsername()
else
self.tocUsername = self.character:getUsername()
end
ISHealthPanel.highestAmputations[self.tocUsername] = {}
local modDataHandler = ModDataHandler.GetInstance(self.tocUsername)
if modDataHandler == nil then return end -- TODO Test this
for i=1, #PlayerHandler.amputatedLimbs do
local limbName = PlayerHandler.amputatedLimbs[i]
local index = CommonMethods.GetSide(limbName)
if PlayerHandler.modDataHandler:getIsCut(limbName) and PlayerHandler.modDataHandler:getIsVisible(limbName) then
if modDataHandler:getIsCut(limbName) and modDataHandler:getIsVisible(limbName) then
ISHealthPanel.highestAmputations[index] = limbName
end
end
end
local og_ISHealthPanel_initialise = ISHealthPanel.initialise
function ISHealthPanel:initialise()
if self.character:isFemale() then
@@ -62,29 +72,41 @@ function ISHealthPanel:initialise()
else
self.sexPl = "Male"
end
self:setHighestAmputation()
og_ISHealthPanel_initialise(self)
end
local og_ISHealthPanel_setOtherPlayer = ISHealthPanel.setOtherPlayer
---comment
---@param playerObj IsoPlayer
function ISHealthPanel:setOtherPlayer(playerObj)
og_ISHealthPanel_setOtherPlayer(self, playerObj)
self:setHighestAmputation()
end
local og_ISHealthPanel_render = ISHealthPanel.render
function ISHealthPanel:render()
og_ISHealthPanel_render(self)
-- TODO Handle another player health panel
if ISHealthPanel.highestAmputations then
if ISHealthPanel.highestAmputations[self.tocUsername] then
-- Left Texture
if ISHealthPanel.highestAmputations["L"] then
if ISHealthPanel.highestAmputations[self.tocUsername]["L"] then
local textureL = StaticData.HEALTH_PANEL_TEXTURES[self.sexPl][ISHealthPanel.highestAmputations["L"]]
self:drawTexture(textureL, self.healthPanel.x/2 - 2, self.healthPanel.y/2, 1, 1, 0, 0)
end
-- Right Texture
if ISHealthPanel.highestAmputations["R"] then
if ISHealthPanel.highestAmputations[self.tocUsername]["R"] then
local textureR = StaticData.HEALTH_PANEL_TEXTURES[self.sexPl][ISHealthPanel.highestAmputations["R"]]
self:drawTexture(textureR, self.healthPanel.x/2 + 2, self.healthPanel.y/2, 1, 1, 0, 0)
end
else
ISHealthPanel.GetHighestAmputation()
ISHealthPanel.GetHighestAmputation(self.tocUsername)
end
end

View File

@@ -4,6 +4,10 @@ local moduleName = CommandsData.modules.TOC_SYNC
------------------------------
-- TODO This is gonna be impossible to manage. We need Global Mod Data to keep track of this kind of stuff at this point
---A client has asked the server to ask another client to send its toc mod data
---@param surgeonPl IsoPlayer
---@param args {patientNum : number}