I have a character ability system that works for the most part, however, for some reason I can't get my head around, this won't work. The RemoteEvent I have set up is only supposed to execute once, and then check that the ability that it's linked to is disabled, yet after the first time it completely breaks, especially if you spam it. Obviously hints towards something not being reset properly, but it is? Idk but here's the code:
-----------------------
-- General Variables --
-----------------------
local player = game:GetService("Players"):WaitForChild(script.Parent.Name)
local character = workspace:WaitForChild(player.Name)
local humanoid = character:WaitForChild("Humanoid")
local RunService = game:GetService("RunService")
local ServerStorage = game:GetService("ServerStorage")
local Events = game:GetService("ReplicatedStorage").RemoteEventsAndFunctions
local SetHUDProgressBar = Events.SetHUDProgressBar
local AbilityEvents = Events.Abilities
local disableActions = script.DisableActions
local ability1 = script.Ability1
local ability2 = script.Ability2
local ability3 = script.Ability3
local abilitySlots = {ability1, ability2, ability3}
local activateAbility1Cooldown = false
local activateAbility2Cooldown = false
local activateAbility3Cooldown = false
local ability1Cooldown = 0
local ability2Cooldown = 0
local ability3Cooldown = 0
local ability1Disabled = false
local ability2Disabled = false
local ability3Disabled = false
----------------------------------
-- Character specific variables --
----------------------------------
local SlamEvent = AbilityEvents.Slam
local ChargeEvent = AbilityEvents.Charge
local PunchEvent = AbilityEvents.Punch
local slamFolder = script.BruteMoveset.Slam
local slamAttackTime = slamFolder.AttackTime.Value
local slamRecoveryTime = slamFolder.RecoveryTime.Value
local slamAnim = slamFolder.Animations.Slam
local slamRecovery = slamFolder.Animations.SlamRecovery
local slamAnimTrack = humanoid:LoadAnimation(slamAnim)
local slamAnimRecoveryTrack = humanoid:LoadAnimation(slamRecovery)
--------------------
-- Base functions --
--------------------
local function GetAbilitySlot(abilityFolder)
for i, v in ipairs(abilitySlots) do
if v.Value == abilityFolder then
return i
else
return -1
end
end
end
local function ActivateCooldown(slotIndex)
if slotIndex == 0 then
ability1Cooldown = abilitySlots[0].Value.Cooldown.Value
activateAbility1Cooldown = true
elseif slotIndex == 1 then
ability2Cooldown = abilitySlots[1].Value.Cooldown.Value
activateAbility2Cooldown = true
elseif slotIndex == 2 then
ability3Cooldown = abilitySlots[2].Value.Cooldown.Value
activateAbility3Cooldown = true
end
end
local function GetAbilityDisabled(slotIndex)
if slotIndex == 0 then
return ability1Disabled
elseif slotIndex == 1 then
return ability2Disabled
elseif slotIndex == 2 then
return ability3Disabled
end
end
local function SetAbilityDisabled(slotIndex, value)
if slotIndex == 0 then
ability1Disabled = value
elseif slotIndex == 1 then
ability2Disabled = value
elseif slotIndex == 2 then
ability3Disabled = value
end
end
local function SpawnAOE(size, cframe)
local newAOE = ServerStorage.GameplayObjects.DestructiveAOE:Clone()
newAOE.Instigator.Value = player.Character
newAOE.Size = Vector3.new(size, size, size)
newAOE.Parent = workspace
newAOE.CFrame = cframe
newAOE.BreakWelds.Disabled = false
end
----------------------------------
-- Character specific functions --
----------------------------------
SlamEvent.OnServerEvent:Connect(function(_player)
local slotIndex = GetAbilitySlot(slamFolder)
local abilityDisabled = GetAbilityDisabled(slotIndex)
if _player == player and slotIndex ~= -1 and abilityDisabled == false then
SetAbilityDisabled(slotIndex, true)
disableActions.Value = true
SetHUDProgressBar:FireClient(_player, slotIndex, 1, false, 0)
slamAnimTrack:Play()
slamAnimTrack:AdjustSpeed(1/slamAttackTime - (1/slamAttackTime) * 0.2)
slamAnimTrack:GetMarkerReachedSignal("AboutToSlam"):Connect(function(stringParam)
slamAnimTrack:AdjustSpeed(1)
end)
slamAnimTrack.Stopped:Connect(function()
SpawnAOE(slamFolder.AOESize.Value, character.HumanoidRootPart.CFrame * CFrame.new(0,-9,-10))
slamAnimRecoveryTrack:Play()
slamAnimRecoveryTrack:AdjustSpeed(1/slamRecoveryTime)
slamAnimRecoveryTrack.Stopped:Connect(function()
disableActions.Value = false
ActivateCooldown(slotIndex)
SetHUDProgressBar:FireClient(_player, slotIndex, 0, true, abilitySlots[slotIndex].Value.Cooldown.Value)
end)
end)
end
end)
RunService.Stepped:Connect(function(_time, step)
if activateAbility1Cooldown == true and ability1Disabled == true then
ability1Cooldown = ability1Cooldown - step
if ability1Cooldown <= 0 then
activateAbility1Cooldown = false
ability1Disabled = false
end
end
if activateAbility2Cooldown == true and ability2Disabled == true then
ability2Cooldown = ability2Cooldown - step
if ability2Cooldown <= 0 then
activateAbility2Cooldown = false
ability2Disabled = false
end
end
if activateAbility3Cooldown == true and ability3Disabled == true then
ability3Cooldown = ability3Cooldown - step
if ability3Cooldown <= 0 then
activateAbility3Cooldown = false
ability3Disabled = false
end
end
end)

1 comment
"pairs" is used for things like the GetChildren() function. But "ipairs" are used to loop through tables efficiently.