Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
013f852e7e | ||
|
|
a7a064119d | ||
|
|
9b1876b235 | ||
|
|
0d9ee4203c | ||
|
|
2ea03601f5 | ||
|
|
3d4a54418c | ||
|
|
17718cbbca | ||
|
|
f9ad597d2b | ||
|
|
c8b6a8c5ed | ||
|
|
9478e0faa1 | ||
|
|
d512f0ba81 | ||
|
|
31995965f9 | ||
|
|
d35840d825 | ||
|
|
e270b4f73b | ||
|
|
4757d9dfa8 | ||
|
|
1b235ebaa4 | ||
|
|
44d486dfeb | ||
|
|
5cc982188a | ||
|
|
aadbe02df4 |
@@ -6,9 +6,9 @@ Wait until you succumb to the virus or take matters into your hands. Cut off tha
|
|||||||
|
|
||||||
This version of [b]The Only Cure[/b] has been rebuilt from scratch to support future additions and to feel as close as possible as a vanilla mechanic.
|
This version of [b]The Only Cure[/b] has been rebuilt from scratch to support future additions and to feel as close as possible as a vanilla mechanic.
|
||||||
|
|
||||||
|
[b]If you're using an older version of The Only Cure and want to switch with this, you're gonna need to create a new character\save to prevent issues.[/b]
|
||||||
[b]The older version will be delisted shortly and it will not be supported anymore.[/b]
|
[b]The older version will be delisted shortly and it will not be supported anymore.[/b]
|
||||||
|
[h1]Supports [b]Single Player[/b] and [b]Multiplayer[/b]. Host Mode is currently [b]UNSUPPORTED![/b][/h1]
|
||||||
Supports [b]Single Player[/b] and [b]Multiplayer[/b]!
|
|
||||||
|
|
||||||
[h1]Setup[/h1]
|
[h1]Setup[/h1]
|
||||||
Use it with the following mods for the intended experience:
|
Use it with the following mods for the intended experience:
|
||||||
@@ -17,6 +17,8 @@ Use it with the following mods for the intended experience:
|
|||||||
[*] [url=https://steamcommunity.com/sharedfiles/filedetails/?id=2934621024]Brutal Handwork[/url]
|
[*] [url=https://steamcommunity.com/sharedfiles/filedetails/?id=2934621024]Brutal Handwork[/url]
|
||||||
[/list]
|
[/list]
|
||||||
|
|
||||||
|
Place them [b]BEFORE[/b] The Only Cure in your mod list!
|
||||||
|
|
||||||
[hr][/hr]
|
[hr][/hr]
|
||||||
|
|
||||||
[h1]Quick guide[/h1]
|
[h1]Quick guide[/h1]
|
||||||
@@ -74,6 +76,10 @@ Got any issues or found some pesky bugs? Report them on GitHub!
|
|||||||
[th]dhert[/th]
|
[th]dhert[/th]
|
||||||
[th]Compatibility API[/th]
|
[th]Compatibility API[/th]
|
||||||
[/tr]
|
[/tr]
|
||||||
|
[tr]
|
||||||
|
[th]JCloudJalix[/th]
|
||||||
|
[th]German translation[/th]
|
||||||
|
[/tr]
|
||||||
[/table]
|
[/table]
|
||||||
|
|
||||||
[hr][/hr]
|
[hr][/hr]
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ function DataController:setup(key)
|
|||||||
---@type tocModDataType
|
---@type tocModDataType
|
||||||
self.tocData = {
|
self.tocData = {
|
||||||
-- Generic stuff that does not belong anywhere else
|
-- Generic stuff that does not belong anywhere else
|
||||||
|
isInitializing = true,
|
||||||
isIgnoredPartInfected = false,
|
isIgnoredPartInfected = false,
|
||||||
isAnyLimbCut = false,
|
isAnyLimbCut = false,
|
||||||
limbs = {},
|
limbs = {},
|
||||||
@@ -86,9 +87,16 @@ function DataController:setup(key)
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Add it to global mod data
|
-- Add it to client global mod data
|
||||||
ModData.add(key, self.tocData)
|
ModData.add(key, self.tocData)
|
||||||
|
|
||||||
|
-- Sync with the server
|
||||||
|
self:apply()
|
||||||
|
|
||||||
|
-- -- Disable lock
|
||||||
|
-- self.tocData.isInitializing = false
|
||||||
|
-- ModData.add(key, self.tocData)
|
||||||
|
|
||||||
end
|
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
|
||||||
@@ -100,7 +108,7 @@ function DataController:applyOnlineData(tocData)
|
|||||||
end
|
end
|
||||||
|
|
||||||
---@param key string
|
---@param key string
|
||||||
function DataController:loadLocalData(key)
|
function DataController:tryLoadLocalData(key)
|
||||||
self.tocData = ModData.get(key)
|
self.tocData = ModData.get(key)
|
||||||
|
|
||||||
--TOC_DEBUG.printTable(self.tocData)
|
--TOC_DEBUG.printTable(self.tocData)
|
||||||
@@ -372,8 +380,9 @@ function DataController.ReceiveData(key, data)
|
|||||||
|
|
||||||
|
|
||||||
TOC_DEBUG.print("ReceiveData for " .. key)
|
TOC_DEBUG.print("ReceiveData for " .. key)
|
||||||
if data == {} or data == nil then
|
|
||||||
error("Data is nil, new character or something is wrong")
|
if data == nil or data.limbs == nil then
|
||||||
|
TOC_DEBUG.print("Data is nil, new character or something is wrong")
|
||||||
end
|
end
|
||||||
|
|
||||||
-- 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
|
||||||
@@ -389,14 +398,17 @@ function DataController.ReceiveData(key, data)
|
|||||||
-- TODO Add update from server scenario
|
-- TODO Add update from server scenario
|
||||||
|
|
||||||
if handler.isResetForced then
|
if handler.isResetForced then
|
||||||
|
TOC_DEBUG.print("Forced reset")
|
||||||
handler:setup(key)
|
handler:setup(key)
|
||||||
elseif data then
|
elseif data and data.limbs then
|
||||||
|
-- Let's validate that the data structure is actually valid to prevent issues
|
||||||
if data.isUpdateFromServer then
|
if data.isUpdateFromServer then
|
||||||
TOC_DEBUG.print("Update from the server")
|
TOC_DEBUG.print("Update from the server")
|
||||||
end
|
end
|
||||||
handler:applyOnlineData(data)
|
handler:applyOnlineData(data)
|
||||||
elseif username == getPlayer():getUsername() then
|
elseif username == getPlayer():getUsername() then
|
||||||
handler:loadLocalData(key)
|
TOC_DEBUG.print("loading local data")
|
||||||
|
handler:tryLoadLocalData(key)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@@ -436,7 +448,7 @@ Events.OnReceiveGlobalModData.Add(DataController.ReceiveData)
|
|||||||
--- SP Only initialization
|
--- SP Only initialization
|
||||||
---@param key string
|
---@param key string
|
||||||
function DataController:initSinglePlayer(key)
|
function DataController:initSinglePlayer(key)
|
||||||
self:loadLocalData(key)
|
self:tryLoadLocalData(key)
|
||||||
if self.tocData == nil or self.isResetForced then
|
if self.tocData == nil or self.isResetForced then
|
||||||
self:setup(key)
|
self:setup(key)
|
||||||
end
|
end
|
||||||
@@ -464,4 +476,12 @@ function DataController.GetInstance(username)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function DataController.DestroyInstance(username)
|
||||||
|
if DataController.instances[username] ~= nil then
|
||||||
|
DataController.instances[username] = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
return DataController
|
return DataController
|
||||||
@@ -15,8 +15,12 @@ local StaticData = require("TOC/StaticData")
|
|||||||
-- a prosthesis on, that can trigger random bleeds.
|
-- a prosthesis on, that can trigger random bleeds.
|
||||||
|
|
||||||
local function CheckHandFeasibility(limbName)
|
local function CheckHandFeasibility(limbName)
|
||||||
|
TOC_DEBUG.print("Checking hand feasibility: " .. limbName)
|
||||||
local dcInst = DataController.GetInstance()
|
local dcInst = DataController.GetInstance()
|
||||||
return not dcInst:getIsCut(limbName) or dcInst:getIsProstEquipped(limbName)
|
|
||||||
|
local isFeasible = not dcInst:getIsCut(limbName) or dcInst:getIsProstEquipped(limbName)
|
||||||
|
TOC_DEBUG.print("isFeasible: " .. tostring(isFeasible))
|
||||||
|
return isFeasible
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@@ -39,13 +43,18 @@ function ISBaseTimedAction:adjustMaxTime(maxTime)
|
|||||||
|
|
||||||
for k, _ in pairs(amputatedLimbs) do
|
for k, _ in pairs(amputatedLimbs) do
|
||||||
local limbName = k
|
local limbName = k
|
||||||
--if dcInst:getIsCut(limbName) then
|
local perkAmp = Perks["Side_" .. CommonMethods.GetSide(limbName)]
|
||||||
local perk = Perks["Side_" .. CommonMethods.GetSide(limbName)]
|
local perkLevel = pl:getPerkLevel(perkAmp)
|
||||||
local perkLevel = pl:getPerkLevel(perk)
|
|
||||||
|
if dcInst:getIsProstEquipped(limbName) then
|
||||||
|
-- TODO We should separate this in multiple perks, since this is gonna be a generic familiarity and could make no actual sense
|
||||||
|
local perkProst = Perks["ProstFamiliarity"]
|
||||||
|
perkLevel = perkLevel + pl:getPerkLevel(perkProst)
|
||||||
|
end
|
||||||
|
|
||||||
local perkLevelScaled
|
local perkLevelScaled
|
||||||
if perkLevel ~= 0 then perkLevelScaled = perkLevel / 10 else perkLevelScaled = 0 end
|
if perkLevel ~= 0 then perkLevelScaled = perkLevel / 10 else perkLevelScaled = 0 end
|
||||||
time = time * (StaticData.LIMBS_TIME_MULTIPLIER_IND_NUM[limbName] - perkLevelScaled)
|
time = time * (StaticData.LIMBS_TIME_MULTIPLIER_IND_NUM[limbName] - perkLevelScaled)
|
||||||
--end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return time
|
return time
|
||||||
@@ -59,22 +68,31 @@ function ISBaseTimedAction:perform()
|
|||||||
og_ISBaseTimedAction_perform(self)
|
og_ISBaseTimedAction_perform(self)
|
||||||
|
|
||||||
TOC_DEBUG.print("Running ISBaseTimedAction.perform override")
|
TOC_DEBUG.print("Running ISBaseTimedAction.perform override")
|
||||||
|
TOC_DEBUG.print("max time: " .. tostring(self.maxTime))
|
||||||
|
|
||||||
local dcInst = DataController.GetInstance()
|
local dcInst = DataController.GetInstance()
|
||||||
if not dcInst:getIsAnyLimbCut() then return end
|
if not dcInst:getIsAnyLimbCut() then return end
|
||||||
|
|
||||||
local amputatedLimbs = CachedDataHandler.GetAmputatedLimbs(LocalPlayerController.username)
|
local amputatedLimbs = CachedDataHandler.GetAmputatedLimbs(LocalPlayerController.username)
|
||||||
|
local xp = self.maxTime/100
|
||||||
for k, _ in pairs(amputatedLimbs) do
|
for k, _ in pairs(amputatedLimbs) do
|
||||||
local limbName = k
|
local limbName = k
|
||||||
|
|
||||||
-- We're checking for only "visible" amputations to prevent from having bleeds everywhere
|
-- We're checking for only "visible" amputations to prevent from having bleeds everywhere
|
||||||
if dcInst:getIsCut(limbName) and dcInst:getIsVisible(limbName) then
|
if dcInst:getIsCut(limbName) and dcInst:getIsVisible(limbName) then
|
||||||
local side = CommonMethods.GetSide(limbName)
|
local side = CommonMethods.GetSide(limbName)
|
||||||
LocalPlayerController.playerObj:getXp():AddXP(Perks["Side_" .. side], 1) -- TODO Make it dynamic
|
LocalPlayerController.playerObj:getXp():AddXP(Perks["Side_" .. side], xp)
|
||||||
if not dcInst:getIsCicatrized(limbName) and dcInst:getIsProstEquipped(limbName) then
|
if not dcInst:getIsCicatrized(limbName) and dcInst:getIsProstEquipped(limbName) then
|
||||||
TOC_DEBUG.print("Trying for bleed, player met the criteria")
|
TOC_DEBUG.print("Trying for bleed, player met the criteria")
|
||||||
LocalPlayerController.TryRandomBleed(self.character, limbName)
|
LocalPlayerController.TryRandomBleed(self.character, limbName)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- Level up prosthesis perk
|
||||||
|
if dcInst:getIsProstEquipped(limbName) then
|
||||||
|
LocalPlayerController.playerObj:getXp():AddXP(Perks["ProstFamiliarity"], xp)
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -107,6 +125,8 @@ end
|
|||||||
---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)
|
||||||
|
|
||||||
|
TOC_DEBUG.print("running ISEquipWeaponAction performWithAmputation")
|
||||||
local hand = nil
|
local hand = nil
|
||||||
local otherHand = nil
|
local otherHand = nil
|
||||||
local getMethodFirst = nil
|
local getMethodFirst = nil
|
||||||
@@ -130,6 +150,10 @@ function ISEquipWeaponAction:performWithAmputation(dcInst)
|
|||||||
setMethodSecond = self.character.setSecondaryHandItem
|
setMethodSecond = self.character.setSecondaryHandItem
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local isFirstValid = CheckHandFeasibility(hand)
|
||||||
|
local isSecondValid = CheckHandFeasibility(otherHand)
|
||||||
|
|
||||||
|
|
||||||
if not self.twoHands then
|
if not self.twoHands then
|
||||||
if getMethodFirst(self.character) and getMethodFirst(self.character):isRequiresEquippedBothHands() then
|
if getMethodFirst(self.character) and getMethodFirst(self.character):isRequiresEquippedBothHands() then
|
||||||
setMethodFirst(self.character, nil)
|
setMethodFirst(self.character, nil)
|
||||||
@@ -145,10 +169,10 @@ function ISEquipWeaponAction:performWithAmputation(dcInst)
|
|||||||
setMethodSecond(self.character, nil)
|
setMethodSecond(self.character, nil)
|
||||||
-- TODO We should use the CachedData indexable instead of dcInst
|
-- TODO We should use the CachedData indexable instead of dcInst
|
||||||
|
|
||||||
if not dcInst:getIsCut(hand) then
|
if isFirstValid then
|
||||||
setMethodSecond(self.character, self.item)
|
setMethodSecond(self.character, self.item)
|
||||||
-- Check other HAND!
|
-- Check other HAND!
|
||||||
elseif not dcInst:getIsCut(otherHand) then
|
elseif isSecondValid then
|
||||||
setMethodFirst(self.character, self.item)
|
setMethodFirst(self.character, self.item)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -156,13 +180,10 @@ function ISEquipWeaponAction:performWithAmputation(dcInst)
|
|||||||
setMethodFirst(self.character, nil)
|
setMethodFirst(self.character, nil)
|
||||||
setMethodSecond(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("First Hand: " .. tostring(hand))
|
||||||
-- TOC_DEBUG.print("Prost Group: " .. tostring(prostGroup))
|
-- --TOC_DEBUG.print("Prost Group: " .. tostring(prostGroup))
|
||||||
-- TOC_DEBUG.print("Other Hand: " .. tostring(otherHand))
|
-- TOC_DEBUG.print("Other Hand: " .. tostring(otherHand))
|
||||||
-- TOC_DEBUG.print("Other Prost Group: " .. tostring(otherProstGroup))
|
-- --TOC_DEBUG.print("Other Prost Group: " .. tostring(otherProstGroup))
|
||||||
|
|
||||||
-- TOC_DEBUG.print("isPrimaryHandValid: " .. tostring(isFirstValid))
|
-- TOC_DEBUG.print("isPrimaryHandValid: " .. tostring(isFirstValid))
|
||||||
-- TOC_DEBUG.print("isSecondaryHandValid: " .. tostring(isSecondValid))
|
-- TOC_DEBUG.print("isSecondaryHandValid: " .. tostring(isSecondValid))
|
||||||
|
|||||||
@@ -354,10 +354,20 @@ function LocalPlayerController.DropItemsAfterAmputation(limbName)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- TODO Consider 2 handed weapons too
|
||||||
|
|
||||||
|
-- equipped items too
|
||||||
|
if side == "R" then
|
||||||
|
pl:setPrimaryHandItem(nil)
|
||||||
|
elseif side == "L" then
|
||||||
|
pl:setSecondaryHandItem(nil)
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
Events.OnAmputatedLimb.Add(LocalPlayerController.DropItemsAfterAmputation)
|
Events.OnAmputatedLimb.Add(LocalPlayerController.DropItemsAfterAmputation)
|
||||||
|
Events.OnProsthesisUnequipped.Add(LocalPlayerController.DropItemsAfterAmputation)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
--* Setup Events *--
|
--* Setup Events *--
|
||||||
LuaEventManager.AddEvent("OnAmputatedLimb") --Triggered when a limb has been amputated
|
LuaEventManager.AddEvent("OnAmputatedLimb") --Triggered when a limb has been amputated
|
||||||
|
LuaEventManager.AddEvent("OnProsthesisUnequipped")
|
||||||
LuaEventManager.AddEvent("OnReceivedTocData") -- Triggered when TOC data is ready
|
LuaEventManager.AddEvent("OnReceivedTocData") -- Triggered when TOC data is ready
|
||||||
|
|||||||
@@ -111,6 +111,8 @@ end
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--* Hand feasibility caching *--
|
--* Hand feasibility caching *--
|
||||||
CachedDataHandler.handFeasibility = {}
|
CachedDataHandler.handFeasibility = {}
|
||||||
|
|
||||||
|
|||||||
@@ -70,7 +70,6 @@ function ProsthesisHandler.CheckIfEquippable(fullType)
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
---Handle equipping or unequipping prosthetics
|
---Handle equipping or unequipping prosthetics
|
||||||
---@param item InventoryItem
|
---@param item InventoryItem
|
||||||
---@param isEquipping boolean
|
---@param isEquipping boolean
|
||||||
@@ -133,8 +132,6 @@ function ISClothingExtraAction:isValid()
|
|||||||
return HandleProsthesisValidation(testItem, isEquippable)
|
return HandleProsthesisValidation(testItem, isEquippable)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--[[
|
--[[
|
||||||
Horrendous workaround
|
Horrendous workaround
|
||||||
|
|
||||||
@@ -148,8 +145,8 @@ end
|
|||||||
|
|
||||||
local og_ISClothingExtraAction_perform = ISClothingExtraAction.perform
|
local og_ISClothingExtraAction_perform = ISClothingExtraAction.perform
|
||||||
function ISClothingExtraAction:perform()
|
function ISClothingExtraAction:perform()
|
||||||
--local extraItem = InventoryItemFactory.CreateItem(self.extra)
|
local extraItem = InventoryItemFactory.CreateItem(self.extra)
|
||||||
local isProst = ProsthesisHandler.SearchAndSetupProsthesis(self.item, true)
|
local isProst = ProsthesisHandler.SearchAndSetupProsthesis(extraItem, true)
|
||||||
local group
|
local group
|
||||||
if isProst then
|
if isProst then
|
||||||
group = BodyLocations.getGroup("Human")
|
group = BodyLocations.getGroup("Human")
|
||||||
@@ -161,7 +158,6 @@ function ISClothingExtraAction:perform()
|
|||||||
if isProst then
|
if isProst then
|
||||||
group:setMultiItem("TOC_ArmProst", true)
|
group:setMultiItem("TOC_ArmProst", true)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local og_ISUnequipAction_perform = ISUnequipAction.perform
|
local og_ISUnequipAction_perform = ISUnequipAction.perform
|
||||||
@@ -176,8 +172,15 @@ function ISUnequipAction:perform()
|
|||||||
|
|
||||||
if isProst then
|
if isProst then
|
||||||
group:setMultiItem("TOC_ArmProst", true)
|
group:setMultiItem("TOC_ArmProst", true)
|
||||||
|
|
||||||
|
-- we need to fetch the limbname associated to the prosthesis
|
||||||
|
local side = CommonMethods.GetSide(self.item:getFullType())
|
||||||
|
local highestAmputatedLimbs = CachedDataHandler.GetHighestAmputatedLimbs(getPlayer():getUsername())
|
||||||
|
if highestAmputatedLimbs then
|
||||||
|
local hal = highestAmputatedLimbs[side]
|
||||||
|
triggerEvent("OnProsthesisUnequipped", hal)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
return ProsthesisHandler
|
return ProsthesisHandler
|
||||||
|
|||||||
@@ -6,12 +6,11 @@ require("TOC/Events")
|
|||||||
|
|
||||||
---@class Main
|
---@class Main
|
||||||
local Main = {
|
local Main = {
|
||||||
_version = "2.0.2"
|
_version = "2.0.7"
|
||||||
}
|
}
|
||||||
|
|
||||||
function Main.Start()
|
function Main.Start()
|
||||||
TOC_DEBUG.print("Starting The Only Cure version " .. tostring(Main._version))
|
TOC_DEBUG.print("Starting The Only Cure version " .. tostring(Main._version))
|
||||||
--Main.SetupTraits()
|
|
||||||
Main.SetupEvents()
|
Main.SetupEvents()
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -37,16 +36,15 @@ function Main.InitializePlayer()
|
|||||||
CommonMethods.SafeStartEvent("OnTick", TryToInitialize)
|
CommonMethods.SafeStartEvent("OnTick", TryToInitialize)
|
||||||
end
|
end
|
||||||
|
|
||||||
---Clean the TOC table for that SP player, to prevent from clogging it up
|
---Clean the TOC table for that SP player, to prevent it from clogging ModData up
|
||||||
---@param player IsoPlayer
|
---@param player IsoPlayer
|
||||||
function Main.WipeData(player)
|
function Main.WipeData(player)
|
||||||
TOC_DEBUG.print("Wiping data after death")
|
local username = player:getUsername()
|
||||||
local key = CommandsData.GetKey(player:getUsername())
|
TOC_DEBUG.print("Wiping data after death: " .. username)
|
||||||
|
local key = CommandsData.GetKey(username)
|
||||||
|
|
||||||
--ModData.remove(key)
|
--ModData.remove(key)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if not isClient() then
|
if not isClient() then
|
||||||
-- For SP, it's enough just removing the data this way
|
-- For SP, it's enough just removing the data this way
|
||||||
ModData.remove(key)
|
ModData.remove(key)
|
||||||
@@ -55,7 +53,14 @@ function Main.WipeData(player)
|
|||||||
-- at the next character by passing an empty mod data
|
-- at the next character by passing an empty mod data
|
||||||
ModData.add(key, {})
|
ModData.add(key, {})
|
||||||
ModData.transmit(key)
|
ModData.transmit(key)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- Let's wipe the instance too just to be sure
|
||||||
|
local DataController = require("TOC/Controllers/DataController")
|
||||||
|
DataController.DestroyInstance(username)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--* Events *--
|
--* Events *--
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ local StaticData = require("TOC/StaticData")
|
|||||||
TestFramework.registerTestModule("LocalPlayerController", "Setup", function()
|
TestFramework.registerTestModule("LocalPlayerController", "Setup", function()
|
||||||
local Tests = {}
|
local Tests = {}
|
||||||
function Tests.InitializePlayer()
|
function Tests.InitializePlayer()
|
||||||
local pl = getPlayer()
|
|
||||||
LocalPlayerController.InitializePlayer(true)
|
LocalPlayerController.InitializePlayer(true)
|
||||||
end
|
end
|
||||||
return Tests
|
return Tests
|
||||||
@@ -154,6 +153,38 @@ TestFramework.registerTestModule("Various", "Player", function()
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
|
|
||||||
|
TestFramework.registerTestModule("Various", "Visuals", function()
|
||||||
|
local Tests = {}
|
||||||
|
|
||||||
|
function Tests.AddBloodLeftForearm()
|
||||||
|
local playerObj = getPlayer()
|
||||||
|
local limbName = "ForeArm_L"
|
||||||
|
local fullType = StaticData.AMPUTATION_CLOTHING_ITEM_BASE .. limbName
|
||||||
|
|
||||||
|
|
||||||
|
local item = playerObj:getInventory():FindAndReturn(fullType)
|
||||||
|
if instanceof(item, "Clothing") then
|
||||||
|
|
||||||
|
---@cast item Clothing
|
||||||
|
|
||||||
|
print("Found limb to add blood onto")
|
||||||
|
item:setBloodLevel(100)
|
||||||
|
local coveredParts = BloodClothingType.getCoveredParts(item:getBloodClothingType())
|
||||||
|
if coveredParts then
|
||||||
|
for j=0,coveredParts:size()-1 do
|
||||||
|
item:setBlood(coveredParts:get(j), 100)
|
||||||
|
item:setDirt(coveredParts:get(j), 100)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
playerObj:resetModelNextFrame()
|
||||||
|
end
|
||||||
|
|
||||||
|
return Tests
|
||||||
|
end)
|
||||||
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------------
|
||||||
if not getActivatedMods():contains("PerfTestFramework") or not isDebugEnabled() then return end
|
if not getActivatedMods():contains("PerfTestFramework") or not isDebugEnabled() then return end
|
||||||
|
|||||||
80
media/lua/client/TOC/TimedActions/WashYourselfOverride.lua
Normal file
80
media/lua/client/TOC/TimedActions/WashYourselfOverride.lua
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
local CachedDataHandler = require("TOC/Handlers/CachedDataHandler")
|
||||||
|
local StaticData = require("TOC/StaticData")
|
||||||
|
|
||||||
|
-- Since amputations are actually clothing items, we need to override ISWashYourself to account for that
|
||||||
|
|
||||||
|
-- TODO Clean this up
|
||||||
|
|
||||||
|
local og_ISWashYourself_perform = ISWashYourself.perform
|
||||||
|
function ISWashYourself:perform()
|
||||||
|
|
||||||
|
TOC_DEBUG.print("ISWashYourself override")
|
||||||
|
|
||||||
|
---@type IsoPlayer
|
||||||
|
local pl = self.character
|
||||||
|
local plInv = pl:getInventory()
|
||||||
|
-- Search for amputations and clean them here
|
||||||
|
local amputatedLimbs = CachedDataHandler.GetAmputatedLimbs(pl:getUsername())
|
||||||
|
for limbName, _ in pairs(amputatedLimbs) do
|
||||||
|
|
||||||
|
TOC_DEBUG.print("Checking if " .. limbName .. " is in inventory and washing it")
|
||||||
|
|
||||||
|
-- get clothing item
|
||||||
|
local foundItem = plInv:FindAndReturn(StaticData.AMPUTATION_CLOTHING_ITEM_BASE .. limbName)
|
||||||
|
if foundItem and instanceof(foundItem, "Clothing") then
|
||||||
|
|
||||||
|
TOC_DEBUG.print("Washing " .. limbName)
|
||||||
|
|
||||||
|
---@cast foundItem Clothing
|
||||||
|
foundItem:setWetness(100)
|
||||||
|
foundItem:setBloodLevel(0)
|
||||||
|
foundItem:setDirtyness(0) -- TODO Integrate with other dirtyness
|
||||||
|
|
||||||
|
local coveredParts = BloodClothingType.getCoveredParts(foundItem:getBloodClothingType())
|
||||||
|
for j=0, coveredParts:size() - 1 do
|
||||||
|
foundItem:setBlood(coveredParts:get(j), 0)
|
||||||
|
foundItem:setDirt(coveredParts:get(j), 0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
og_ISWashYourself_perform(self)
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local og_ISWashYourself_GetRequiredWater = ISWashYourself.GetRequiredWater
|
||||||
|
|
||||||
|
|
||||||
|
---@param character IsoPlayer
|
||||||
|
---@return integer
|
||||||
|
function ISWashYourself.GetRequiredWater(character)
|
||||||
|
|
||||||
|
local units = og_ISWashYourself_GetRequiredWater(character)
|
||||||
|
local amputatedLimbs = CachedDataHandler.GetAmputatedLimbs(character:getUsername())
|
||||||
|
local plInv = character:getInventory()
|
||||||
|
for limbName, _ in pairs(amputatedLimbs) do
|
||||||
|
|
||||||
|
TOC_DEBUG.print("Checking if " .. limbName .. " is in inventory and washing it")
|
||||||
|
|
||||||
|
-- get clothing item
|
||||||
|
local item = plInv:FindAndReturn(StaticData.AMPUTATION_CLOTHING_ITEM_BASE .. limbName)
|
||||||
|
if item and instanceof(item, "Clothing") then
|
||||||
|
local coveredParts = BloodClothingType.getCoveredParts(item:getBloodClothingType())
|
||||||
|
if coveredParts then
|
||||||
|
for i=1,coveredParts:size() do
|
||||||
|
local part = coveredParts:get(i-1)
|
||||||
|
if item:getBlood(part) > 0 then
|
||||||
|
units = units + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return units
|
||||||
|
end
|
||||||
@@ -29,12 +29,15 @@ function ServerDataHandler.AddTable(key, table)
|
|||||||
--TOC_DEBUG.printTable(table)
|
--TOC_DEBUG.printTable(table)
|
||||||
|
|
||||||
-- Set that the data has been modified and it's updated on the server
|
-- Set that the data has been modified and it's updated on the server
|
||||||
table.isUpdateFromServer = true
|
table.isUpdateFromServer = true -- FIX this is useless as of now
|
||||||
|
|
||||||
ModData.add(key, table) -- Add it to the server mod data
|
ModData.add(key, table) -- Add it to the server mod data
|
||||||
ServerDataHandler.modData[key] = table
|
ServerDataHandler.modData[key] = table
|
||||||
|
|
||||||
|
|
||||||
|
-- Check integrity of table. if it doesn't contains toc data, it means that we received a reset
|
||||||
|
if table.limbs == nil then return end
|
||||||
|
|
||||||
-- Since this could be triggered by a different client than the one referenced in the key, we're gonna
|
-- Since this could be triggered by a different client than the one referenced in the key, we're gonna
|
||||||
-- apply the changes back to the key client again to be sure that everything is in sync
|
-- apply the changes back to the key client again to be sure that everything is in sync
|
||||||
local username = CommandsData.GetUsername(key)
|
local username = CommandsData.GetUsername(key)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
---@alias limbsTable {Hand_L : partDataType, ForeArm_L : partDataType, UpperArm_L : partDataType, Hand_R : partDataType, ForeArm_R : partDataType, UpperArm_R : partDataType }
|
---@alias limbsTable {Hand_L : partDataType, ForeArm_L : partDataType, UpperArm_L : partDataType, Hand_R : partDataType, ForeArm_R : partDataType, UpperArm_R : partDataType }
|
||||||
---@alias prosthesisData {isProstEquipped : boolean, prostFactor : number }
|
---@alias prosthesisData {isProstEquipped : boolean, prostFactor : number }
|
||||||
---@alias prosthesesTable {Top_L : prosthesisData, Top_R : prosthesisData } -- TODO add Bottom_L and Bottom_R
|
---@alias prosthesesTable {Top_L : prosthesisData, Top_R : prosthesisData } -- TODO add Bottom_L and Bottom_R
|
||||||
---@alias tocModDataType { limbs : limbsTable, prostheses : prosthesesTable, isIgnoredPartInfected : boolean, isAnyLimbCut : boolean, isUpdateFromServer : boolean }
|
---@alias tocModDataType { limbs : limbsTable, prostheses : prosthesesTable, isIgnoredPartInfected : boolean, isAnyLimbCut : boolean, isUpdateFromServer : boolean, isInitializing : boolean}
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
2
mod.info
2
mod.info
@@ -4,5 +4,5 @@ description=You've been bitten. You have only two choices.
|
|||||||
id=TheOnlyCure
|
id=TheOnlyCure
|
||||||
icon=icon.png
|
icon=icon.png
|
||||||
url=https://github.com/ZioPao/The-Only-Cure
|
url=https://github.com/ZioPao/The-Only-Cure
|
||||||
modversion=2.0.2
|
modversion=2.0.7
|
||||||
pzversion=41.65
|
pzversion=41.65
|
||||||
|
|||||||
Reference in New Issue
Block a user