Your code is pretty messy and that makes it harder for you or others to figure out what’s happening.
Anyway, your problem is probably due to connecting events inside loops inside other events… which is probably not what you want. For example, the function passed to CenterPress.Event:Connect runs every time…
CenterPress is fired… for each unpressed ingot… every time LeftPress is fired… every time a player joins.
I’m not sure if this exactly follows the logic of what you want to do, but it should be a lot closer:
local game = game
local TweenService = game:GetService("TweenService")
local BindableEvents = game.ReplicatedStorage.BindableEvents
local Assets = game.ReplicatedStorage.Assts
local Audio = Assets.Audio
local HoldingPositions = game.Workspace.Main.HoldingPositions
local UnpressedIngots = game.Workspace.UnpressedIngots
local PressedIngots = game.Workspace.PressedIngots
local UNPRESSED_CONVEYOR_CAPACITY = 5
local PressHead = game.Workspace.Conveyor.Press.Head
local PressBase = PressHead.BasePart
local ingotUnderPress
local t = {
isClass = function(v, className)
return v and typeof(v) == "Instance" and v.ClassName == className
end
}
function getStat(player, stat)
return player.leaderstats[stat].Value
end
function setStat(player, stat, value)
player.leaderstats[stat].Value = value
return value
end
function incrementStat(player, stat, amount)
return setStat(player, stat, getStat(player, stat) + (amount or 1))
end
function toCFrame(v: CFrame | Vector3 | PVInstance): CFrame
if typeof(v) == "CFrame" then
return v
elseif typeof(v) == "Vector3" then
return CFrame.new(v)
elseif typeof(v) == "PVInstance" then
return v:GetPivot()
else
error()
end
end
function tweenTo(obj: PVInstance, target: Vector3 | CFrame | PVInstance, tweenInfo: TweenInfo, autoplay: boolean): Tween
if autoplay == nil then autoplay = true end
if tweenInfo == nil then tweenInfo = TweenInfo.new(1) end
local tween = TweenService:Create(obj, tweenInfo, {CFrame = toCFrame(target)})
if autoplay then
tween:Play()
end
return tween
end
function playSound(sound): Sound
local sound = sound:Clone()
sound.Parent = game.Workspace
sound.Ended:Once(function()
sound:Destroy()
end)
sound:Play()
return sound
end
function sparkVFX()
task.spawn(function()
PressBase.Effect.Sparks.Enabled = true
task.wait(0.1)
PressBase.Effect.Sparks.Enabled = false
end)
end
function clankSFX()
return playSound(Audio.SFX.Clank)
end
function getIngotHoldingPosition(ingot: PVInstance): Vector3
return HoldingPositions:FindFirstChild(tostring(ingot.CurrentNode.Value)).Position --TODO: Probably replace tostring(ingot.CurrentNode.Value) with ingot.CurrentNode.Value.Name
end
function addIngotToUnpressedConveyor(ingot: PVInstance)
ingot.CurrentNode.Value = 1
ingot.Parent = UnpressedIngots
ingotUnderPress = nil
for _, ingot in UnpressedIngots:GetChildren() do
ingot.CurrentNode.Value += 1
tweenTo(ingot, getIngotHoldingPosition(ingot))
if ingot.CurrentNode.Value == UNPRESSED_CONVEYOR_CAPACITY then
ingotUnderPress = ingot
end
end
end
function addIngotToPressedConveyor(ingot: PVInstance)
ingot.Position = HoldingPositions.Hit.Position
ingot.Parent = PressedIngots
--Tween ingot to smelter (TODO: or whatever that is???)
local toSmelterTI = TweenInfo.new(1, Enum.EasingStyle.Linear, Enum.EasingDirection.In, 0, false, 0)
tweenTo(ingot, HoldingPositions.EndPos.Position, toSmelterTI).Completed:Wait()
--Clean up the pressed ingot and award player with silver
ingot:Destroy()
incrementStat(player, "Silver")
end
function runPress(ingot: PVInstance)
--Tween press down
local startCF = PressBase.CFrame
local pressDownTweenInfo = TweenInfo.new(0.5, Enum.EasingStyle.Exponential, Enum.EasingDirection.In, 0, false, 1)
tweenTo(PressBase, startCF + Vector3.new(0, -3.7, 0), pressDownTweenInfo).Completed:Wait()
--Replace unpressed with pressed
ingot:Destroy()
local pressedIngot = Assets.PressedIngot:Clone()
addIngotToPressedConveyor(pressedIngot)
--Effects
sparkVFX()
clankSFX()
--Tween press back up
local pressUpTweenInfo = TweenInfo.new(0.7, Enum.EasingStyle.Linear, Enum.EasingDirection.Out, 0, false, 1)
tweenTo(PressBase, startCF, pressUpTweenInfo).Completed:Wait()
end
BindableEvents.LeftButtonPressed.Event:Connect(function()
if #UnpressedIngots:GetChildren() <= UNPRESSED_CONVEYOR_CAPACITY then
addIngotToUnpressedConveyor(Assets.UnpressedIngot:Clone())
end
end)
BindableEvents.CenterButtonPressed.Event:Connect(function(player: Player)
assert(t.isClass(player, "Player"))
local ingot = ingotUnderPress()
if not ingot then return end
runPress(ingot)
end)