Reworked initialization logic for local client
This commit is contained in:
@@ -25,24 +25,18 @@ function DataController:new(username, isResetForced)
|
|||||||
self.__index = self
|
self.__index = self
|
||||||
|
|
||||||
o.username = username
|
o.username = username
|
||||||
local key = CommandsData.GetKey(username)
|
o.isResetForced = isResetForced
|
||||||
|
o.isDataReady = false
|
||||||
|
|
||||||
-- We don't want to request ModData if we're in SP, or if we're forcing a reset
|
local key = CommandsData.GetKey(username)
|
||||||
if isClient() and not isResetForced then
|
ModData.request(key)
|
||||||
ModData.request(key)
|
|
||||||
o.isResetForced = isResetForced
|
|
||||||
o.isDataReady = false
|
|
||||||
elseif isResetForced then
|
|
||||||
self:setup(key)
|
|
||||||
o.isResetForced = false
|
|
||||||
o.isDataReady = true
|
|
||||||
end
|
|
||||||
|
|
||||||
DataController.instances[username] = o
|
DataController.instances[username] = o
|
||||||
|
|
||||||
return o
|
return o
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
---Setup a new toc mod data data class
|
---Setup a new toc mod data data class
|
||||||
---@param key string
|
---@param key string
|
||||||
function DataController:setup(key)
|
function DataController:setup(key)
|
||||||
@@ -87,19 +81,34 @@ end
|
|||||||
|
|
||||||
---In case of desync between the table on ModData and the table here
|
---In case of desync between the table on ModData and the table here
|
||||||
---@param tocData tocModDataType
|
---@param tocData tocModDataType
|
||||||
function DataController:reapplyTocData(tocData)
|
function DataController:applyOnlineData(tocData)
|
||||||
local key = CommandsData.GetKey(self.username)
|
local key = CommandsData.GetKey(self.username)
|
||||||
ModData.add(key, tocData)
|
ModData.add(key, tocData)
|
||||||
self.tocData = ModData.get(key)
|
self.tocData = ModData.get(key)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---@param key string
|
||||||
|
function DataController:loadLocalData(key)
|
||||||
|
self.tocData = ModData.get(key)
|
||||||
|
if self.tocData ~= nil and self.tocData ~= {} then
|
||||||
|
TOC_DEBUG.print("Found and loaded local data")
|
||||||
|
else
|
||||||
|
error("Local data failed to load!")
|
||||||
|
end
|
||||||
|
end
|
||||||
-----------------
|
-----------------
|
||||||
--* Setters *--
|
--* Setters *--
|
||||||
|
|
||||||
|
---@param isDataReady boolean
|
||||||
function DataController:setIsDataReady(isDataReady)
|
function DataController:setIsDataReady(isDataReady)
|
||||||
self.isDataReady = isDataReady
|
self.isDataReady = isDataReady
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---@param isResetForced boolean
|
||||||
|
function DataController:setIsResetForced(isResetForced)
|
||||||
|
self.isResetForced = isResetForced
|
||||||
|
end
|
||||||
|
|
||||||
---Set a generic boolean that toggles varies function of the mod
|
---Set a generic boolean that toggles varies function of the mod
|
||||||
---@param isAnyLimbCut boolean
|
---@param isAnyLimbCut boolean
|
||||||
function DataController:setIsAnyLimbCut(isAnyLimbCut)
|
function DataController:setIsAnyLimbCut(isAnyLimbCut)
|
||||||
@@ -320,9 +329,6 @@ function DataController:apply()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function DataController.ReceiveData(key, data)
|
function DataController.ReceiveData(key, data)
|
||||||
if not isClient() then
|
|
||||||
TOC_DEBUG.print("SP, skipping DataController.ReceiveData")
|
|
||||||
end
|
|
||||||
-- During startup the game can return Bob as the player username, adding a useless ModData table
|
-- During startup the game can return Bob as the player username, adding a useless ModData table
|
||||||
if key == "TOC_Bob" then return end
|
if key == "TOC_Bob" then return end
|
||||||
|
|
||||||
@@ -335,31 +341,30 @@ function DataController.ReceiveData(key, data)
|
|||||||
-- Get DataController instance if there was none for that user and reapply the correct ModData table as a reference
|
-- Get DataController instance if there was none for that user and reapply the correct ModData table as a reference
|
||||||
local username = key:sub(5)
|
local username = key:sub(5)
|
||||||
local handler = DataController.GetInstance(username)
|
local handler = DataController.GetInstance(username)
|
||||||
if handler.isResetForced or data == nil or data == {} or data == false then
|
|
||||||
TOC_DEBUG.print("Setup")
|
-- Bit of a workaround, but in a perfect world, I'd use the server to get the data and that would be it.
|
||||||
handler:setup(key)
|
-- but Zomboid Mod Data handling is too finnicky at best to be that reliable, in case of an unwanted disconnection and what not,
|
||||||
handler.isResetForced = false
|
-- so for now, I'm gonna assume that the local data (for the local client) is the
|
||||||
|
-- most recent (and correct) one instead of trying to fetch it from the server every single time
|
||||||
|
if isClient() then
|
||||||
|
if handler.isResetForced or data == nil or data == {} or data == false then
|
||||||
|
handler:setup(key)
|
||||||
|
elseif username == getPlayer():getUsername() then
|
||||||
|
handler:loadLocalData(key)
|
||||||
|
else
|
||||||
|
handler:applyOnlineData(data)
|
||||||
|
end
|
||||||
else
|
else
|
||||||
TOC_DEBUG.print("Reapply")
|
handler:loadLocalData(key)
|
||||||
handler:reapplyTocData(data)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
handler.isResetForced = false -- TODO Add a setter
|
||||||
-- 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 DataController 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)
|
handler:setIsDataReady(true)
|
||||||
|
|
||||||
-- Event
|
-- Event
|
||||||
triggerEvent("OnReceivedTocData", handler.username)
|
triggerEvent("OnReceivedTocData", handler.username)
|
||||||
|
|
||||||
-- Transmit it to the server
|
-- Transmit it back to the server
|
||||||
ModData.transmit(key)
|
ModData.transmit(key)
|
||||||
TOC_DEBUG.print("Transmitting data after receiving it for: " .. handler.username)
|
TOC_DEBUG.print("Transmitting data after receiving it for: " .. handler.username)
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +1,26 @@
|
|||||||
|
local LocalPlayerController = require("TOC/Controllers/LocalPlayerController")
|
||||||
local DataController = require("TOC/Controllers/DataController")
|
local DataController = require("TOC/Controllers/DataController")
|
||||||
|
|
||||||
local CachedDataHandler = require("TOC/Handlers/CachedDataHandler")
|
local CachedDataHandler = require("TOC/Handlers/CachedDataHandler")
|
||||||
local CommonMethods = require("TOC/CommonMethods")
|
local CommonMethods = require("TOC/CommonMethods")
|
||||||
local StaticData = require("TOC/StaticData")
|
local StaticData = require("TOC/StaticData")
|
||||||
|
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
|
||||||
|
--* TIMED ACTIONS *--
|
||||||
|
-- We want to be able to modify how long actions are gonna take,
|
||||||
|
-- depending on amputation status and kind of action. Also, when the
|
||||||
|
-- player has not completely cicatrized their own wounds, and try to do any action with
|
||||||
|
-- a prosthesis on, that can trigger random bleeds.
|
||||||
|
|
||||||
local function CheckHandFeasibility(limbName)
|
local function CheckHandFeasibility(limbName)
|
||||||
local dcInst = DataController.GetInstance()
|
local dcInst = DataController.GetInstance()
|
||||||
|
|
||||||
return not dcInst:getIsCut(limbName) or dcInst:getIsProstEquipped(StaticData.LIMBS_TO_PROST_GROUP_MATCH_IND_STR[limbName])
|
return not dcInst:getIsCut(limbName) or dcInst:getIsProstEquipped(StaticData.LIMBS_TO_PROST_GROUP_MATCH_IND_STR[limbName])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--* Time to perform actions overrides *--
|
--* Time to perform actions overrides *--
|
||||||
|
|
||||||
local og_ISBaseTimedAction_adjustMaxTime = ISBaseTimedAction.adjustMaxTime
|
local og_ISBaseTimedAction_adjustMaxTime = ISBaseTimedAction.adjustMaxTime
|
||||||
--- Adjust time
|
--- Adjust time
|
||||||
---@diagnostic disable-next-line: duplicate-set-field
|
---@diagnostic disable-next-line: duplicate-set-field
|
||||||
@@ -71,12 +77,17 @@ function ISBaseTimedAction:perform()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--* Equipping items overrides *--
|
--* EQUIPPING ITEMS *--
|
||||||
|
-- Check wheter the player can equip items or not, for example dual wielding when you only have one
|
||||||
|
-- hand (and no prosthesis) should be disabled. Same thing for some werable items, like watches.
|
||||||
|
|
||||||
|
---@class ISEquipWeaponAction
|
||||||
|
---@field character IsoPlayer
|
||||||
|
|
||||||
local primaryHand = StaticData.PARTS_IND_STR.Hand .. "_" .. StaticData.SIDES_IND_STR.R
|
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 secondaryHand = StaticData.PARTS_IND_STR.Hand .. "_" .. StaticData.SIDES_IND_STR.L
|
||||||
|
|
||||||
|
--* Equipping items overrides *--
|
||||||
local og_ISEquipWeaponAction_isValid = ISEquipWeaponAction.isValid
|
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
|
---Add a condition to check the feasibility of having 2 handed weapons or if both arms are cut off
|
||||||
---@return boolean
|
---@return boolean
|
||||||
@@ -95,9 +106,6 @@ function ISEquipWeaponAction:isValid()
|
|||||||
return isValid
|
return isValid
|
||||||
end
|
end
|
||||||
|
|
||||||
---@class ISEquipWeaponAction
|
|
||||||
---@field character IsoPlayer
|
|
||||||
|
|
||||||
---A recreation of the original method, but with amputations in mind
|
---A recreation of the original method, but with amputations in mind
|
||||||
---@param dcInst DataController
|
---@param dcInst DataController
|
||||||
function ISEquipWeaponAction:performWithAmputation(dcInst)
|
function ISEquipWeaponAction:performWithAmputation(dcInst)
|
||||||
@@ -173,7 +181,6 @@ function ISEquipWeaponAction:performWithAmputation(dcInst)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
local og_ISEquipWeaponAction_perform = ISEquipWeaponAction.perform
|
local og_ISEquipWeaponAction_perform = ISEquipWeaponAction.perform
|
||||||
---@diagnostic disable-next-line: duplicate-set-field
|
---@diagnostic disable-next-line: duplicate-set-field
|
||||||
function ISEquipWeaponAction:perform()
|
function ISEquipWeaponAction:perform()
|
||||||
@@ -188,7 +195,6 @@ function ISEquipWeaponAction:perform()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function ISInventoryPaneContextMenu.doEquipOption(context, playerObj, isWeapon, items, player)
|
function ISInventoryPaneContextMenu.doEquipOption(context, playerObj, isWeapon, items, player)
|
||||||
-- check if hands if not heavy damaged
|
-- 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
|
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
|
||||||
|
|||||||
@@ -5,15 +5,8 @@ local StaticData = require("TOC/StaticData")
|
|||||||
require("TOC/Events")
|
require("TOC/Events")
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
-- TODO Separate this in more classes, it's getting too big
|
|
||||||
|
|
||||||
|
-- Handle ONLY stuff for the local client
|
||||||
-- 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 LocalPlayerController
|
---@class LocalPlayerController
|
||||||
---@field playerObj IsoPlayer
|
---@field playerObj IsoPlayer
|
||||||
@@ -21,6 +14,9 @@ require("TOC/Events")
|
|||||||
---@field hasBeenDamaged boolean
|
---@field hasBeenDamaged boolean
|
||||||
local LocalPlayerController = {}
|
local LocalPlayerController = {}
|
||||||
|
|
||||||
|
|
||||||
|
--* Initialization
|
||||||
|
|
||||||
---Setup the Player Handler and modData, only for local client
|
---Setup the Player Handler and modData, only for local client
|
||||||
---@param isForced boolean?
|
---@param isForced boolean?
|
||||||
function LocalPlayerController.InitializePlayer(isForced)
|
function LocalPlayerController.InitializePlayer(isForced)
|
||||||
@@ -33,10 +29,6 @@ function LocalPlayerController.InitializePlayer(isForced)
|
|||||||
LocalPlayerController.playerObj = playerObj
|
LocalPlayerController.playerObj = playerObj
|
||||||
LocalPlayerController.username = username
|
LocalPlayerController.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
|
--Setup the CicatrizationUpdate event and triggers it once
|
||||||
Events.OnAmputatedLimb.Add(LocalPlayerController.ToggleUpdateAmputations)
|
Events.OnAmputatedLimb.Add(LocalPlayerController.ToggleUpdateAmputations)
|
||||||
LocalPlayerController.ToggleUpdateAmputations()
|
LocalPlayerController.ToggleUpdateAmputations()
|
||||||
@@ -68,7 +60,9 @@ function LocalPlayerController.ManageTraits(playerObj)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--* Health management *--
|
----------------------------------------------------------
|
||||||
|
|
||||||
|
--* Health *--
|
||||||
|
|
||||||
---Used to heal an area that has been cut previously. There's an exception for bites, those are managed differently
|
---Used to heal an area that has been cut previously. There's an exception for bites, those are managed differently
|
||||||
---@param bodyPart BodyPart
|
---@param bodyPart BodyPart
|
||||||
@@ -96,7 +90,6 @@ function LocalPlayerController.HealArea(bodyPart)
|
|||||||
bodyPart:setSplint(false, 0)
|
bodyPart:setSplint(false, 0)
|
||||||
end
|
end
|
||||||
|
|
||||||
---comment
|
|
||||||
---@param bodyDamage BodyDamage
|
---@param bodyDamage BodyDamage
|
||||||
---@param bodyPart BodyPart
|
---@param bodyPart BodyPart
|
||||||
---@param limbName string
|
---@param limbName string
|
||||||
@@ -114,7 +107,6 @@ function LocalPlayerController.HealZombieInfection(bodyDamage, bodyPart, limbNam
|
|||||||
dcInst:apply()
|
dcInst:apply()
|
||||||
end
|
end
|
||||||
|
|
||||||
---comment
|
|
||||||
---@param character IsoPlayer
|
---@param character IsoPlayer
|
||||||
---@param limbName string
|
---@param limbName string
|
||||||
function LocalPlayerController.TryRandomBleed(character, limbName)
|
function LocalPlayerController.TryRandomBleed(character, limbName)
|
||||||
@@ -135,6 +127,8 @@ function LocalPlayerController.TryRandomBleed(character, limbName)
|
|||||||
character:getBodyDamage():getBodyPart(adjacentBodyPartType):setBleedingTime(20)
|
character:getBodyDamage():getBodyPart(adjacentBodyPartType):setBleedingTime(20)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-------------------------
|
-------------------------
|
||||||
--* Damage handling *--
|
--* Damage handling *--
|
||||||
--- Locks OnPlayerGetDamage event, to prevent it from getting spammed constantly
|
--- Locks OnPlayerGetDamage event, to prevent it from getting spammed constantly
|
||||||
@@ -291,8 +285,6 @@ function LocalPlayerController.ToggleUpdateAmputations()
|
|||||||
CommonMethods.SafeStartEvent("EveryHours", LocalPlayerController.UpdateAmputations)
|
CommonMethods.SafeStartEvent("EveryHours", LocalPlayerController.UpdateAmputations)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--* Tourniquet handling
|
--* Tourniquet handling
|
||||||
function LocalPlayerController.HandleTourniquet()
|
function LocalPlayerController.HandleTourniquet()
|
||||||
print("test")
|
print("test")
|
||||||
@@ -301,5 +293,4 @@ end
|
|||||||
Events.OnPuttingTourniquet.Add(LocalPlayerController.HandleTourniquet)
|
Events.OnPuttingTourniquet.Add(LocalPlayerController.HandleTourniquet)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return LocalPlayerController
|
return LocalPlayerController
|
||||||
@@ -74,7 +74,7 @@ end
|
|||||||
|
|
||||||
--* Events *--
|
--* Events *--
|
||||||
|
|
||||||
Events.OnGameBoot.Add(Main.Start)
|
Events.OnGameBoot.Add(Main.Start) -- TODO Does this apply after death?
|
||||||
|
|
||||||
if not isClient() and not isServer() then
|
if not isClient() and not isServer() then
|
||||||
Events.OnPlayerDeath.Add(Main.WipeSinglePlayerData)
|
Events.OnPlayerDeath.Add(Main.WipeSinglePlayerData)
|
||||||
|
|||||||
Reference in New Issue
Block a user