Ingot spawn count issue

Put simply, I want the ingots to pass under the press, and when pressed turn into a formed ingot and move on.

It works fine the first time. The issue I’m having is I can press it again, even after the old glowing part (v in the loop) is destroyed, I can still use the press.
While this may seem like a simple fix, this means since the script seems to think v is still there it will create 2 copper ingots, and 3 the next time, and then 4, etc.

Ive tried to instead use waits that wait for a value to be true, in an attempt to simply pause the script until there is user input, but that simply results in more issues.

My best guess is the script still seems to think something is there even though its not?
(no errors)

Code:
https://pastebin.com/cUAJkzY1

Video (it explains the issue step by step):
https://streamable.com/t0jgt5

1 Like

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.

image

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)
2 Likes

Hello!

first of all I want to thank you for this help, this is extremely impressive.

Im trying to implement your code, but im getting an error here.
Im not sure exactly what the issue is, ive tried a few things but I think it has to do with hit not being named a number, so its trying to find node “7”, which does not exist


image

1 Like

Yeah, if there’s more than 5 unpressed ingots then it will try to find a holding position no. that doesn’t exist, so the FindFirstChild call evals to nil, and nil.Position gives the “attempt to index nil with ‘Position’” error.

AFAICT it shouldn’t add any unpressed ingots beyond 5, so I’m not sure why this even happens?

2 Likes

I ran a test, it adds more than 5. It goes into 6. But not 7.

I found that you had
<= UNPRESSED_CONVEYOR_CAPACITY
meaning if it was at 5, it could go to 6.

I changed it to
< UNPRESSED_CONVEYOR_CAPACITY

Now I dont get the error, but its preventing me from pressing it again and allowing the furthest ingot from moving into the press.

2 Likes

Alright I tried using some if statements and such with no luck.

I think the issue is if it goes over 5, it moves on but errors, and If I dont let it go over 5, no errors but it wont move on.

Not really sure the solution to this, this code is out of my knowledge complexity wise.

1 Like

Hmm can’t tell what the problem is just from looking at the code. If you’re comfortable sending the place file over I’ll take a look at it in Studio

1 Like

Yeah sure, ill message it to you. One moment.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.