For some reason whenever I get to like really high numbers of stat gain it’s just 0 but I don’t think its a capcity bug because when I’m in training zones which gives way more I gain the stat but when I’m not it just gives me 0 heres my helper functions module
local ClientModules = RS.Modules
local BigNum = require(ClientModules.BigNum)
local Helpers = {}
--// Helpers To Our Helpers
-- Check if the current time has exceeded the cooldown period
function Helpers.CheckDebounceTime(debounce, cooldown)
return debounce < os.time() - cooldown
end
-- Add amount to a BigNum stat
function Helpers.BigNumAdd(stat, amount)
local bNum = BigNum.new(stat.Value)
local res = BigNum.mt.add(bNum, BigNum.new(amount))
stat.Value = BigNum.mt.tostring(res)
end
-- Subtract amount from a BigNum stat
function Helpers.BigNumSub(stat, amount)
local bNum = BigNum.new(stat.Value)
local res = BigNum.mt.sub(bNum, BigNum.new(amount))
stat.Value = BigNum.mt.tostring(res)
end
function Helpers.BigNumMul(a, b)
return BigNum.mt.tostring(BigNum.mt.mul(BigNum.new(a), BigNum.new(b)))
end
-- Calculate and update player's health based on their endurance
function Helpers.CalculateHealth(Player, Endurance)
local Char = Player.Character
if not Char then
warn("[CalculateHealth] No character for", Player.Name)
return
end
local Humanoid = Char:FindFirstChildOfClass("Humanoid")
if not Humanoid then
warn("[CalculateHealth] No Humanoid found for", Player.Name)
return
end
local Endu = tonumber(Endurance.Value)
if not Endu then
warn("[CalculateHealth] Invalid Endurance.Value for", Player.Name, "Value:", Endurance.Value)
return
end
local EnduBigNum = BigNum.new(Endu)
local rawHealth = BigNum.mt.add(BigNum.mt.mul(EnduBigNum, 10), BigNum.new(100))
local healthNum = tonumber(BigNum.mt.tostring(rawHealth))
if not healthNum then
warn("[CalculateHealth] Failed to convert BigNum to number for", Player.Name)
return
end
local oldMax = Humanoid.MaxHealth
Humanoid.MaxHealth = healthNum
-- Heal to full (optional, comment if not wanted)
Humanoid.Health = healthNum
end
function Helpers.Train(Player, StatName, isAutoTraining)
local Char = Player.Character
if not Char then return end
-- Retry to find PhysicalStats
local physicalStats
for i = 1, 5 do
physicalStats = Player:FindFirstChild("PhysicalStats")
if physicalStats then break end
wait(0.2)
end
if not physicalStats then
warn("PhysicalStats not found for player " .. Player.Name)
return
end
local Stat = physicalStats:FindFirstChild(StatName)
if not Stat then
warn("Stat " .. StatName .. " not found in PhysicalStats!")
return
end
local Multi = Player:FindFirstChild("Multipliers") and Player.Multipliers:FindFirstChild(StatName .. "Multi")
local GemMulti = Player:FindFirstChild("GemMultipliers") and Player.GemMultipliers:FindFirstChild("Gem" .. StatName .. "Multi")
local PowerMultiplier = Player:FindFirstChild("Stats") and Player.Stats:FindFirstChild("PowerMultiplier")
local GeneticsPowerMulti = Player:FindFirstChild("Stats") and Player.Stats:FindFirstChild("GeneticsPowerMulti")
local DoublePowerMulti = Player:FindFirstChild("Stats") and Player.Stats:FindFirstChild("DoublePowerMulti")
local BoostdoublePowerMulti = Player:FindFirstChild("Stats") and Player.Stats:FindFirstChild("BoostdoublePowerMulti")
local Tool = Char:FindFirstChildOfClass("Tool")
local IsPushUpTool = Tool and Tool.Name == "PushUpTool"
local multiplier = Multi and Multi.Value or 1
if not IsPushUpTool then
local ZoneMulti = Helpers.IsInUsableZone(Player, StatName, isAutoTraining)
multiplier = multiplier * ZoneMulti
end
-- Helper function to safely multiply and debug multipliers
local function debugMultiplier(name, value)
local num = tonumber(value)
print("[Multiplier Debug] " .. name .. " = " .. tostring(value))
if not num or num <= 0 then
print("[Warning] Multiplier '" .. name .. "' is invalid or zero. Using 1 instead.")
return 1
end
return num
end
multiplier = multiplier * debugMultiplier("PowerMultiplier", PowerMultiplier and PowerMultiplier.Value)
multiplier = multiplier * debugMultiplier("GeneticsPowerMulti", GeneticsPowerMulti and GeneticsPowerMulti.Value)
multiplier = multiplier * debugMultiplier("DoublePowerMulti", DoublePowerMulti and DoublePowerMulti.Value)
multiplier = multiplier * debugMultiplier("BoostdoublePowerMulti", BoostdoublePowerMulti and BoostdoublePowerMulti.Value)
if GemMulti then
multiplier = multiplier * debugMultiplier("GemMulti", GemMulti.Value)
end
print("[Final Multiplier] For stat '" .. StatName .. "' multiplier is: " .. multiplier)
-- Final training addition
Helpers.BigNumAdd(Stat, Helpers.BigNumMul("1", multiplier))
if StatName == "Endurance" then
Helpers.CalculateHealth(Player, Stat)
end
end
function Helpers.IsInUsableZone(Player, StatName, isAutoTraining)
local Char = Player.Character
if not Char then return 1, false end
local HRP = Char.PrimaryPart
if not HRP then return 1, false end
-- Retry to find PhysicalStats up to 5 times with small wait
local physicalStats
for i = 1, 5 do
physicalStats = Player:FindFirstChild("PhysicalStats")
if physicalStats then break end
wait(0.75) -- Wait for 0.2 seconds before trying again
end
if not physicalStats then
warn("PhysicalStats not found for player " .. Player.Name)
return 1, false
end
local Stat = physicalStats:FindFirstChild(StatName)
if not Stat then
warn("Stat " .. StatName .. " not found in PhysicalStats!")
return 1, false
end
local ZoneMulti = 1
local hitAZone = false
-- Check if the player is auto-training push-ups (endurance) and skip zone multiplier calculation
if isAutoTraining and StatName == "Endurance" then
-- If auto-training endurance, just return no zone multiplier
return 1, false
end
-- Only check zone multipliers for auto-training if the stat is "Strength" (for punching)
if isAutoTraining and StatName == "Strength" then
local origin = HRP.Position
local Range = -30
local Dir = Vector3.new(0, Range, 0)
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {game.Workspace.TrainingZones}
raycastParams.FilterType = Enum.RaycastFilterType.Include
local ZoneRay = Ray.new(origin, Dir)
local Zone = workspace:FindPartOnRayWithWhitelist(ZoneRay, workspace.TrainingZones:GetDescendants())
if Zone and string.split(Zone.Name, ' ')[1] == StatName and BigNum.mt.ge(Stat.Value, Zone.Req.Value) then
ZoneMulti = Zone.Multiplier.Value
hitAZone = true
end
else
-- If not auto-training, perform the normal zone check
local origin = HRP.Position
local Range = -30
local Dir = Vector3.new(0, Range, 0)
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {game.Workspace.TrainingZones}
raycastParams.FilterType = Enum.RaycastFilterType.Include
local ZoneRay = Ray.new(origin, Dir)
local Zone = workspace:FindPartOnRayWithWhitelist(ZoneRay, workspace.TrainingZones:GetDescendants())
if Zone and string.split(Zone.Name, ' ')[1] == StatName and BigNum.mt.ge(Stat.Value, Zone.Req.Value) then
ZoneMulti = Zone.Multiplier.Value
hitAZone = true
end
end
return ZoneMulti, hitAZone
end
return Helpers