-
What do you want to achieve? Keep it simple and clear!
Each tool (potion) has a timer embedded into their respective function on the server script which is run when the event is triggered from a local script, this timer is used to determine how long a potion’s effect should last for and after the time is up, follow-up code is run to remove player’s boosts from this potion. [note: potion gets DELETED from the player’s backpack when they use it]
When a player uses a tool (potion) and die during it’s effect period, the effect will not persist after death (for example, if it was a speed potion, player loses that speed boost when they respawn) which is intended and it’s wait period gets removed as well so it doesn’t tamper with the next potion’s effect period.
-
What is the issue? Include screenshots / videos if possible!
When a player uses a tool (potion) and die during it’s effect, the effect will not persist after death (which is intended) but the follow-up code AFTER the wait period is up will run and mess up the player statistics (only if another tool (potion) is used during the last tool’s wait period). -
What solutions have you tried so far? Did you look for solutions on the Developer Hub?
I have been looking for ways to incorporate wait periods on tools as it seems the wait periods currently in place are conflicting with one another, but since the tools are 1-time use only and get removed after use, I can’t think of a way of checking which tool has been used and is currently in cooldown (so it could be cancelled after death). Please let me know of any ways and I’ll review them.
I am 100% sure that the wait statements are the core issue here, I’ll present a scenario where it would cause an issue:
- Player drinks a defence potion with 60 seconds of effect and cooldown and provides 15% of immunity to any damage taken (for this example, let’s assume player will use potion of the same type and size (boost))
- Player dies within the first 30 seconds of gameplay, after they respawn the initial effect of the potion is cancelled by another script which handles player statistics to ensure that the statistics are correct based on levels which ignores any boosts, which is all intended, but the wait statement continues to wait for another 30 seconds because the potion’s effect/wait period was 60, if a player doesn’t drink the same potion of this type for the last 30 seconds, the follow-up code will remove the boost correctly and everything will work fine (in this case, player had 20% defence immunity with boost, now has 5%) but if a player Drinks another potion of this type within the last potion’s wait period, the last potion’s wait period will take priority and remove player’s statistics based on the boost of the last potion (which is 20% - 15% = 5%) AND THEN after this current potion’s wait period is done, it’ll remove ANOTHER 15% (which is 5% - 15% = -10%)
Please note that potions are divided into different categories which is used to determine which potion ‘type’ is being used in order to allocate the right statistics boost to the player.
game.Players.PlayerAdded:Connect(function(player)
player.CharacterAdded:Connect(function(character)
local levelSelection = player:WaitForChild("levelSelection")
local defenceStatValue = levelSelection:WaitForChild("DefenceValue")
local hum = character:FindFirstChild("Humanoid")
local healthCooldownValue = levelSelection:FindFirstChild("HealthCooldown")
local speedCooldownValue = levelSelection:FindFirstChild("SpeedCooldown")
local defenceCooldownValue = levelSelection:FindFirstChild("DefenceCooldown")
local replicatedStorage = game:GetService("ReplicatedStorage")
local smallHealthCooldownEvent = replicatedStorage:WaitForChild("PotionEvents").SmallHealthEvent
local smallSpeedCooldownEvent = replicatedStorage:WaitForChild("PotionEvents").SmallSpeedEvent
local smallDefenceCooldownEvent = replicatedStorage:WaitForChild("PotionEvents").SmallDefenceEvent
local mediumHealthCooldownEvent = replicatedStorage:WaitForChild("PotionEvents").MediumHealthEvent
local mediumSpeedCooldownEvent = replicatedStorage:WaitForChild("PotionEvents").MediumSpeedEvent
local mediumDefenceCooldownEvent = replicatedStorage:WaitForChild("PotionEvents").MediumDefenceEvent
local LargeHealthCooldownEvent = replicatedStorage:WaitForChild("PotionEvents").LargeHealthEvent
local LargeSpeedCooldownEvent = replicatedStorage:WaitForChild("PotionEvents").LargeSpeedEvent
local LargeDefenceCooldownEvent = replicatedStorage:WaitForChild("PotionEvents").LargeDefenceEvent
---events for each potion so that the right name can be found in the character and remove the tool after it's used
local healthLevel = levelSelection:FindFirstChild("HealthLevel")
local speedLevel = levelSelection:FindFirstChild("SpeedLevel")
local defenceLevel = levelSelection:FindFirstChild("DefenceLevel")
local baseHealth = 150
local baseSpeed = 20
local baseDefence = 0
local incrementSpeed = 2
local incrementDefence = 0.05
-- finding the base stats and their equivalent after calculations of levels, this is used to bring back the right stats to play after potion effect expires
local function calculateHealth(boost, cooldownType)
hum.MaxHealth = baseHealth * healthLevel.Value
if hum.Health <= boost and cooldownType.Value == true then
hum.Health = 1
elseif hum.Health > boost and cooldownType.Value == true then
hum.Health -= boost
elseif cooldownType.Value == false then
return -- player drink debounce is false, don't do anything
end
end
local function calculateSpeed(boost, cooldownType)
local speedBoost = incrementSpeed * speedLevel.Value
if cooldownType.Value == true then
hum.WalkSpeed = baseSpeed + speedBoost
else
return -- player drink debounce is false, don't do anything
end
end
local function calculateDefence(boost, cooldownType)
local defenceBoost = incrementDefence * defenceLevel.Value
if cooldownType.Value == true then
defenceStatValue.Value -= boost
else
defenceStatValue.Value = baseDefence + defenceBoost
end
end
healthCooldownValue.Value = false
speedCooldownValue.Value = false
defenceCooldownValue.Value = false
---when player joins, the values reset and the player can drink a potion
-- this Round function is for rounding up the result of the 0.05 + 0.05, for whatever reason the float points glitch creates up to 10 decimal place number outcomes
-- and with this function, it gets converted to 3 decimal places for correct calculation
local function Round(Number, Digits, Multiples)
local Num = math.round(Number * 10^Digits) / 10^Digits
if Multiples then Num = math.round(Num / Multiples) * Multiples end
print("worked, and the value is", Num)
return Num
end
local function potionConsumed(cooldownType, boost, toolName, cooldownPeriod)
local hum = character:FindFirstChild("Humanoid")
local tools = character:GetChildren()
for _, tool in pairs(tools) do
if tool:IsA("Tool") then
if tool.Name == toolName then
if cooldownType.Value == false then
cooldownType.Value = true
if cooldownType == defenceCooldownValue then
local calculation = tonumber(defenceStatValue.Value) + tonumber(boost)
local trueValue = Round(calculation, 3)
defenceStatValue.Value = trueValue
task.wait(1.5)
tool:Destroy()
task.wait(cooldownPeriod)
calculateDefence(boost, cooldownType)
cooldownType.Value = false
elseif cooldownType == speedCooldownValue then
hum.WalkSpeed = hum.WalkSpeed + boost
task.wait(1.5)
tool:Destroy()
task.wait(cooldownPeriod)
calculateSpeed(boost, cooldownType)
cooldownType.Value = false
elseif cooldownType == healthCooldownValue then
hum.MaxHealth = hum.MaxHealth + boost
if toolName == "Small Health Potion" then
local humanoidHealth = hum.MaxHealth
local healthToAdd = humanoidHealth * 0.25
if hum.Health + healthToAdd >= humanoidHealth then
hum.Health = humanoidHealth
else
hum.Health += healthToAdd
end
elseif toolName == "Medium Health Potion" then
local humanoidHealth = hum.MaxHealth
local healthToAdd = humanoidHealth * 0.5
if hum.Health + healthToAdd >= humanoidHealth then
hum.Health = humanoidHealth
else
hum.Health += healthToAdd
end
elseif toolName == "Large Health Potion" then
local humanoidHealth = hum.MaxHealth
local healthToAdd = humanoidHealth * 0.75
if hum.Health + healthToAdd >= humanoidHealth then
hum.Health = humanoidHealth
else
hum.Health += healthToAdd
end
end
task.wait(1.5)
tool:Destroy()
task.wait(cooldownPeriod)
calculateHealth(boost, cooldownType)
cooldownType.Value = false
end
end
end
end --FIX SO THAT TOOLS GET CHECKED FIRST, AND IF PLAYER DOESN'T HAVE THE TOOL, THE LOOP STOPS TO AVOID EXPLOITERS EXPLOITING THIS
end
end
smallHealthCooldownEvent.OnServerEvent:Connect(function()
potionConsumed(healthCooldownValue, 100, "Small Health Potion", 30) -- put in the cooldown type, the boost and the name of the tool and the function will handle the rest
end)
smallSpeedCooldownEvent.OnServerEvent:Connect(function()
potionConsumed(speedCooldownValue, 3, "Small Speed Potion", 30) -- put in the cooldown type, the boost and the name of the tool and the function will handle the rest
end)
smallDefenceCooldownEvent.OnServerEvent:Connect(function()
potionConsumed(defenceCooldownValue, 0.05, "Small Defence Potion", 30) -- put in the cooldown type, the boost and the name of the tool and the function will handle the rest
end)
mediumHealthCooldownEvent.OnServerEvent:Connect(function()
potionConsumed(healthCooldownValue, 200, "Medium Health Potion", 45) -- put in the cooldown type, the boost and the name of the tool and the function will handle the rest
end)
mediumSpeedCooldownEvent.OnServerEvent:Connect(function()
potionConsumed(speedCooldownValue, 7, "Medium Speed Potion", 45) -- put in the cooldown type, the boost and the name of the tool and the function will handle the rest
end)
mediumDefenceCooldownEvent.OnServerEvent:Connect(function()
potionConsumed(defenceCooldownValue, 0.1, "Medium Defence Potion", 45) -- put in the cooldown type, the boost and the name of the tool and the function will handle the rest
end)
LargeHealthCooldownEvent.OnServerEvent:Connect(function()
potionConsumed(healthCooldownValue, 300, "Large Health Potion", 60) -- put in the cooldown type, the boost and the name of the tool and the function will handle the rest
end)
LargeSpeedCooldownEvent.OnServerEvent:Connect(function()
potionConsumed(speedCooldownValue, 12, "Large Speed Potion", 60) -- put in the cooldown type, the boost and the name of the tool and the function will handle the rest
end)
LargeDefenceCooldownEvent.OnServerEvent:Connect(function()
potionConsumed(defenceCooldownValue, 0.15, "Large Defence Potion", 60) -- put in the cooldown type, the boost and the name of the tool and the function will handle the rest
-- last number in the function is the length of cooldown and effect that the potion is going to have on the player
end)
end)
end)