Merge branch 'dev-42.13' of https://github.com/ZioPao/The-Only-Cure into dev-42.13-merge

This commit is contained in:
ZioPao
2026-01-08 01:39:40 +01:00
249 changed files with 241 additions and 220 deletions

View File

@@ -1,10 +0,0 @@
local LimitActionsController = require("TOC/Controllers/LimitActionsController") -- declared in common
local OverridenMethodsArchive = require("TOC/OverridenMethodsArchive")
local og_ISClothingExtraAction_isValid = OverridenMethodsArchive.Get("ISClothingExtraAction_isValid")
---@diagnostic disable-next-line: duplicate-set-field
function ISClothingExtraAction:isValid()
-- TOC_DEBUG.print("Inside ISClothingExtraAction:isValid 42")
-- TOC_DEBUG.print(OverridenMethodsArchive.Get("ISClothingExtraAction_isValid"))
return LimitActionsController.WrapClothingAction(self, og_ISClothingExtraAction_isValid, instanceItem(self.extra))
end

View File

@@ -1,40 +0,0 @@
local ProsthesisHandler = require("TOC/Handlers/ProsthesisHandler") -- declared in common
local OverridenMethodsArchive = require("TOC/OverridenMethodsArchive")
local og_ISClothingExtraAction_isValid = OverridenMethodsArchive.Get("ISClothingExtraAction_isValid")
---@diagnostic disable-next-line: duplicate-set-field
function ISClothingExtraAction:isValid()
local isEquippable = og_ISClothingExtraAction_isValid(self)
-- self.extra is a string, not the item
local testItem = instanceItem(self.extra)
return ProsthesisHandler.Validate(testItem, isEquippable)
end
local og_ISClothingExtraAction_perform = OverridenMethodsArchive.Get("ISClothingExtraAction_perform")
function ISClothingExtraAction:perform()
local extraItem = instanceItem(self.extra)
ProsthesisHandler.SearchAndSetupProsthesis(extraItem, true)
og_ISClothingExtraAction_perform(self)
end
local og_ISUnequipAction_complete = ISUnequipAction.complete
function ISUnequipAction:complete()
-- Horrendous workaround. For B42, as of now, it will basically happen two times, once with :perform and once with :complete. Shouldn't
-- matter for performance but it's really ugly.
-- local isProst = ProsthesisHandler.SearchAndSetupProsthesis(self.item, false)
-- local group
-- if isProst then
-- group = BodyLocations.getGroup("Human")
-- group:setMultiItem("TOC_ArmProst", false)
-- end
og_ISUnequipAction_complete(self)
-- if isProst then
-- group:setMultiItem("TOC_ArmProst", true)
-- end
end

View File

@@ -397,7 +397,7 @@ end
local og_ISClothingExtraAction_isValid = OverridenMethodsArchive.Save("ISClothingExtraAction_isValid", ISClothingExtraAction.isValid) local og_ISClothingExtraAction_isValid = OverridenMethodsArchive.Save("ISClothingExtraAction_isValid", ISClothingExtraAction.isValid)
---@diagnostic disable-next-line: duplicate-set-field ---@diagnostic disable-next-line: duplicate-set-field
function ISClothingExtraAction:isValid() function ISClothingExtraAction:isValid()
return LimitActionsController.WrapClothingAction(self, og_ISClothingExtraAction_isValid, InventoryItemFactory.CreateItem(self.extra)) return LimitActionsController.WrapClothingAction(self, og_ISClothingExtraAction_isValid, instanceItem(self.extra))
end end

View File

@@ -3,6 +3,7 @@ local CommonMethods = require("TOC/CommonMethods")
local CachedDataHandler = require("TOC/Handlers/CachedDataHandler") local CachedDataHandler = require("TOC/Handlers/CachedDataHandler")
local StaticData = require("TOC/StaticData") local StaticData = require("TOC/StaticData")
require("TOC/Events") require("TOC/Events")
local TOC = require("TOC/Registries")
----------- -----------
@@ -56,7 +57,7 @@ function LocalPlayerController.ManageTraits()
local AmputationHandler = require("TOC/Handlers/AmputationHandler") local AmputationHandler = require("TOC/Handlers/AmputationHandler")
for k, v in pairs(StaticData.TRAITS_BP) do for k, v in pairs(StaticData.TRAITS_BP) do
if playerObj:HasTrait(k) then if playerObj:hasTrait(TOC.traits[k]) then
-- Once we find one, we should be done since they're exclusive -- Once we find one, we should be done since they're exclusive
TOC_DEBUG.print("Player has amputation trait " .. k .. ", executing it") TOC_DEBUG.print("Player has amputation trait " .. k .. ", executing it")
local tempHandler = AmputationHandler:new(v, playerObj) local tempHandler = AmputationHandler:new(v, playerObj)
@@ -93,7 +94,8 @@ function LocalPlayerController.HealArea(bodyPart)
bodyPart:setBleedingTime(0) bodyPart:setBleedingTime(0)
bodyPart:SetBitten(false) bodyPart:SetBitten(false)
bodyPart:setBiteTime(0) --bodyPart:setBiteTime(0)
bodyPart:SetInfected(false)
bodyPart:setCut(false) bodyPart:setCut(false)
bodyPart:setCutTime(0) bodyPart:setCutTime(0)
@@ -110,14 +112,14 @@ end
---@param bodyPart BodyPart ---@param bodyPart BodyPart
---@param limbName string ---@param limbName string
---@param dcInst DataController ---@param dcInst DataController
function LocalPlayerController.HealZombieInfection(bodyDamage, bodyPart, limbName, dcInst) function LocalPlayerController.HealZombieInfection(bodyDamage, limbName, dcInst)
-- FIX Different in B42.13, to be set with stats?
if bodyDamage:isInfected() == false then return end if bodyDamage:isInfected() == false then return end
bodyDamage:setInfected(false) bodyDamage:setInfected(false)
bodyDamage:setInfectionMortalityDuration(-1) bodyDamage:setInfectionMortalityDuration(-1)
bodyDamage:setInfectionTime(-1) bodyDamage:setInfectionTime(-1)
bodyDamage:setInfectionLevel(-1) --bodyPart:SetInfected(false)
bodyPart:SetInfected(false)
dcInst:setIsInfected(limbName, false) dcInst:setIsInfected(limbName, false)
dcInst:apply() dcInst:apply()
@@ -183,7 +185,7 @@ function LocalPlayerController.HandleDamage(character)
-- Special case for bites\zombie infections -- Special case for bites\zombie infections
if bodyPart:IsInfected() then if bodyPart:IsInfected() then
TOC_DEBUG.print("Healed from zombie infection - " .. limbName) TOC_DEBUG.print("Healed from zombie infection - " .. limbName)
LocalPlayerController.HealZombieInfection(bd, bodyPart, limbName, dcInst) LocalPlayerController.HealZombieInfection(bd, limbName, dcInst)
end end
else else
if (bodyPart:bitten() or bodyPart:IsInfected()) and not dcInst:getIsInfected(limbName) then if (bodyPart:bitten() or bodyPart:IsInfected()) and not dcInst:getIsInfected(limbName) then

View File

@@ -152,8 +152,8 @@ function AmputationHandler:damageAfterAmputation(surgeonFactor)
bodyPart:setBleedingTime(baseDamage - surgeonFactor) bodyPart:setBleedingTime(baseDamage - surgeonFactor)
bodyPart:setDeepWounded(true) bodyPart:setDeepWounded(true)
bodyPart:setDeepWoundTime(baseDamage - surgeonFactor) bodyPart:setDeepWoundTime(baseDamage - surgeonFactor)
patientStats:setEndurance(surgeonFactor) patientStats:set(CharacterStat.ENDURANCE, surgeonFactor)
patientStats:setStress(baseDamage - surgeonFactor) patientStats:set(CharacterStat.STRESS, baseDamage - surgeonFactor)
end end
---Execute the amputation. This method doesn't check if the upper limb has been amputated or not, so if ---Execute the amputation. This method doesn't check if the upper limb has been amputated or not, so if
@@ -190,8 +190,10 @@ function AmputationHandler:execute(damagePlayer)
-- Cache highest amputation and hand feasibility -- Cache highest amputation and hand feasibility
CachedDataHandler.CalculateCacheableValues(username) CachedDataHandler.CalculateCacheableValues(username)
-- TODO Test this again for 42.13
-- If the part was actually infected, heal the player, if they were in time (infectionLevel < 20) -- 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 dcInst:getIsIgnoredPartInfected() then local infectionLevel = self.patientPl:getStats():get(CharacterStat.ZOMBIE_INFECTION)
if infectionLevel < 20 and bodyPart:isInfected() and not dcInst:getIsIgnoredPartInfected() then
LocalPlayerController.HealZombieInfection(bd, bodyPart, self.limbName, dcInst) LocalPlayerController.HealZombieInfection(bd, bodyPart, self.limbName, dcInst)
end end

View File

@@ -9,7 +9,7 @@ local OverridenMethodsArchive = require("TOC/OverridenMethodsArchive")
---@class ProsthesisHandler ---@class ProsthesisHandler
local ProsthesisHandler = {} local ProsthesisHandler = {}
local bodylocArmProstBaseline = "TOC_ArmProst" local bodylocArmProstBaseline = "toc:toc_armprost"
--local bodyLocLegProst = "TOC_LegProst" --local bodyLocLegProst = "TOC_LegProst"
---Check if the following item is a prosthesis or not ---Check if the following item is a prosthesis or not
@@ -17,13 +17,12 @@ local bodylocArmProstBaseline = "TOC_ArmProst"
---@return boolean ---@return boolean
function ProsthesisHandler.CheckIfProst(item) function ProsthesisHandler.CheckIfProst(item)
-- TODO Won't be correct when prost for legs are gonna be in -- TODO Won't be correct when prost for legs are gonna be in
--TOC_DEBUG.print("Checking if item is prost")
if item == nil then if item == nil then
--TOC_DEBUG.print("Not prost") TOC_DEBUG.print("Not prost")
return false return false
end end
return item:getBodyLocation():contains(bodylocArmProstBaseline) return item:getBodyLocation():toString():contains(bodylocArmProstBaseline)
end end
---Get the grouping for the prosthesis ---Get the grouping for the prosthesis
@@ -35,7 +34,7 @@ function ProsthesisHandler.GetGroup(item)
local bodyLocation = item:getBodyLocation() local bodyLocation = item:getBodyLocation()
local position local position
if bodyLocation:contains(bodylocArmProstBaseline) then if bodyLocation:toString():contains(bodylocArmProstBaseline) then
position = "Top_" position = "Top_"
else else
TOC_DEBUG.print("Something is wrong, no position in this item") TOC_DEBUG.print("Something is wrong, no position in this item")

View File

@@ -6,7 +6,7 @@ require("TOC/Events")
---@class Main ---@class Main
local Main = { local Main = {
_version = "2.2.2" _version = "2.3"
} }
function Main.Start() function Main.Start()

View File

@@ -87,7 +87,7 @@ function CleanWoundAction:perform()
TOC_DEBUG.print("CleanWound for " .. self.otherPlayer:getUsername()) TOC_DEBUG.print("CleanWound for " .. self.otherPlayer:getUsername())
if self.character:HasTrait("Hemophobic") then if self.character:hasTrait("Hemophobic") then
self.character:getStats():setPanic(self.character:getStats():getPanic() + 15) self.character:getStats():setPanic(self.character:getStats():getPanic() + 15)
end end

View File

@@ -68,9 +68,10 @@ local function AddStoveContextMenu(playerNum, context, worldObjects, test)
-- Notifications, in case the player can't do the action -- Notifications, in case the player can't do the action
local isPlayerCourageous = pl:HasTrait("Brave") or pl:HasTrait("Desensitized") or pl:getPerkLevel(Perks.Strength) > 5 local isPlayerCourageous = pl:hasTrait(CharacterTrait.BRAVE) or pl:hasTrait(CharacterTrait.DESENSITIZED) or pl:getPerkLevel(Perks.Strength) > 5
local isTempHighEnough = stoveObj:getCurrentTemperature() >= 250 local isTempHighEnough = stoveObj:getCurrentTemperature()-1 >= 2.50
local isLimbFree = not dcInst:getIsProstEquipped(limbName) local isLimbFree = not dcInst:getIsProstEquipped(limbName)
TOC_DEBUG.print(stoveObj:getCurrentTemperature())
option.notAvailable = not(isPlayerCourageous and isTempHighEnough and isLimbFree) option.notAvailable = not(isPlayerCourageous and isTempHighEnough and isLimbFree)
if not isTempHighEnough then if not isTempHighEnough then

View File

@@ -0,0 +1,109 @@
--Based on RabenRabo's bodylocation solution from their mod "Fantasy Bodyparts" and "Fantasy Legs" sub-mod.
--Modified by GanydeBielovzki with permission for batch use for the Frockin' Splendor franchise and spin-offs.
--To copy, further modify or otherwise use this code the original creator and the modifier must be credited.
local function copyBodyLocationProperties(oldGroup, oldLocID, newGroup)
for k = 0, oldGroup:size()-1 do
local otherLocID = oldGroup:getLocationByIndex(k):getId()
if oldGroup:isExclusive(oldLocID, otherLocID)
then
newGroup:setExclusive(oldLocID, otherLocID)
end
if oldGroup:isHideModel(oldLocID, otherLocID)
then
newGroup:setHideModel(oldLocID, otherLocID)
end
if oldGroup:isAltModel(oldLocID, otherLocID)
then
newGroup:setAltModel(oldLocID, otherLocID)
end
end
end
local function addBodyLocationsAt(groupName, locationList)
local results = {}
-- get list (!!actually a view!!) of all groups and copy to array (BodyLocations.reset() will also clear the view)
local allGroupsList = BodyLocations.getAllGroups()
local allGroups = {}
for i = 0, allGroupsList:size()-1 do
allGroups[i + 1] = allGroupsList:get(i)
end
BodyLocations.reset()
-- recreate all groups/bodylocations and insert new bodylocations
for i = 1, #allGroups do
local oldGroup = allGroups[i]
local newGroup = BodyLocations.getGroup(oldGroup:getId())
-- FIRST: Process all original locations AND insert new ones at correct positions
for j = 0, oldGroup:size()-1 do
local oldLoc = oldGroup:getLocationByIndex(j)
local oldLocID = oldLoc:getId()
-- For each location definition, check if it should be inserted here
for _, locDef in ipairs(locationList) do
if oldGroup:getId() == groupName then
local newLocID = type(locDef.name) ~= "string" and locDef.name or
ItemBodyLocation.get(ResourceLocation.of(locDef.name))
local refLocID = type(locDef.reference) ~= "string" and locDef.reference or
ResourceLocation.of(locDef.reference)
local isTargetGroupAndLoc = refLocID == oldLocID
if isTargetGroupAndLoc and locDef.before then
results[locDef.name] = newGroup:getOrCreateLocation(newLocID)
end
end
end
-- Add the original location
newGroup:getOrCreateLocation(oldLocID)
-- Check for "after" insertions
for _, locDef in ipairs(locationList) do
if oldGroup:getId() == groupName then
local newLocID = type(locDef.name) ~= "string" and locDef.name or
ItemBodyLocation.get(ResourceLocation.of(locDef.name))
local refLocID = type(locDef.reference) ~= "string" and locDef.reference or
ResourceLocation.of(locDef.reference)
local isTargetGroupAndLoc = refLocID == oldLocID
if isTargetGroupAndLoc and not locDef.before then
results[locDef.name] = newGroup:getOrCreateLocation(newLocID)
end
end
end
end
-- SECOND: copy bodylocation properties from old groups to new groups
for j = 0, oldGroup:size()-1 do
local oldLocID = oldGroup:getLocationByIndex(j):getId()
newGroup:setMultiItem(oldLocID, oldGroup:isMultiItem(oldLocID))
copyBodyLocationProperties(oldGroup, oldLocID, newGroup)
end
end
return results
end
local results = addBodyLocationsAt("Human", {
{name = "toc:Arm_L", reference = ItemBodyLocation.FULL_TOP, before = false},
{name = "toc:Arm_R", reference = ItemBodyLocation.FULL_TOP, before = false},
{name = "toc:ArmProst_L", reference = ItemBodyLocation.FULL_TOP, before = false},
{name = "toc:ArmProst_R", reference = ItemBodyLocation.FULL_TOP, before = false},
{name = "toc:ArmAccessory_L", reference = ItemBodyLocation.FULL_TOP, before = false},
{name = "toc:ArmAccessory_R", reference = ItemBodyLocation.FULL_TOP, before = false},
})
results['toc:Arm_L']:setMultiItem(true)
results['toc:Arm_R']:setMultiItem(true)
results['toc:ArmProst_L']:setMultiItem(true)
results['toc:ArmProst_R']:setMultiItem(true)
results['toc:ArmAccessory_L']:setMultiItem(true)
results['toc:ArmAccessory_R']:setMultiItem(true)

View File

@@ -0,0 +1 @@
return _TOCRegistries

View File

@@ -5,7 +5,6 @@
---@alias tocModDataType { limbs : limbsTable, prostheses : prosthesesTable, isIgnoredPartInfected : boolean, isAnyLimbCut : boolean} ---@alias tocModDataType { limbs : limbsTable, prostheses : prosthesesTable, isIgnoredPartInfected : boolean, isAnyLimbCut : boolean}
--------------------------- ---------------------------
-- _STR = Only strings, no index -- _STR = Only strings, no index
-- _IND_STR = indexed Strings -- _IND_STR = indexed Strings
-- _IND_BPT = Indexed BodyPartType -- _IND_BPT = Indexed BodyPartType
@@ -49,15 +48,6 @@ StaticData.PARTS_STR = {
"UpperArm" "UpperArm"
} }
-- TODO make it a bit more elegant
StaticData.MOD_BODYLOCS_BASE_IND_STR = {
TOC_ArmProst_L = "TOC_ArmProst_L",
TOC_ArmProst_R = "TOC_ArmProst_R",
TOC_Arm_L = "TOC_Arm_L",
TOC_Arm_R = "TOC_Arm_R",
--TOC_LegProst = "TOC_LegProst",
}
-- No "MAX" here. -- No "MAX" here.
StaticData.IGNORED_BODYLOCS_BPT = { StaticData.IGNORED_BODYLOCS_BPT = {
@@ -193,8 +183,8 @@ end
StaticData.TOURNIQUET_BODYLOCS_TO_GROUPS_IND_STR = { StaticData.TOURNIQUET_BODYLOCS_TO_GROUPS_IND_STR = {
["HandsLeft"] = StaticData.AMP_GROUPS_IND_STR.Top_L, [ItemBodyLocation.HANDS_LEFT] = StaticData.AMP_GROUPS_IND_STR.Top_L,
["HandsRight"] = StaticData.AMP_GROUPS_IND_STR.Top_R [ItemBodyLocation.HANDS_RIGHT] = StaticData.AMP_GROUPS_IND_STR.Top_R
} }
@@ -242,7 +232,7 @@ end
StaticData.TRAITS_BP = { StaticData.TRAITS_BP = {
Amputee_Hand = "Hand_L", Amputee_Hand = "Hand_L",
Amputee_ForeArm = "ForeArm_L", Amputee_ForeArm = "ForeArm_L",
Amputee_UpperArm = "UpperArm_L" Amputee_UpperArm = "UpperArm_L",
} }
----------------- -----------------

Some files were not shown because too many files have changed in this diff Show More