Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

Why does this coroutine crash Studio?

Asked by
drew1017 330 Moderation Voter
9 years ago
function InfiniteDamageOverTime(victim, dps)
                if victim and victim.Parent and victim.Parent.Torso and victim.Parent.Head then
                    if victim and victim.Parent and victim.Parent:FindFirstChild('Humanoid') then
                        for i=1, math.huge do
                            if victim and victim.Parent and victim.Parent.Head and victim.Parent.Torso and victim.Parent:FindFirstChild('Humanoid') then
                                if victim.Parent:FindFirstChild('Type') then
                                    if victim.Parent.Type.Value == 'Miniboss' or victim.Parent.Type.Value == 'Boss' then
                                        victim.Parent.Humanoid:TakeDamage((dps / 10) * 0.8)
                                    else
                                        victim.Parent.Humanoid:TakeDamage(dps / 10)
                                    end
                                else
                                    victim.Parent.Humanoid:TakeDamage(dps / 10)
                                end
                                wait(.1)
                            end
                        end
                    end
                end
            end             

This is my damage over time coroutine adapted from my one that has a duration / wears off. For my new shotgun, I needed a version of it with infinite duration which is seen here. It works as expected (continuously drains the enemy's health), but if the enemy is killed Studio crashes. Why would that happen?

2 answers

Log in to vote
1
Answered by
MunimR 125
9 years ago

The solution is simple, the problem is that you are placing the wait(.1)inside the if statement's scope which is causing it to not wait if the statement is False. So place it outside of the if statement's scope into the for loop's scope.

function InfiniteDamageOverTime(victim, dps)
                if victim and victim.Parent and victim.Parent.Torso and victim.Parent.Head then
                    if victim and victim.Parent and victim.Parent:FindFirstChild('Humanoid') then
                        for i=1, math.huge do
                            if victim and victim.Parent and victim.Parent.Head and victim.Parent.Torso and victim.Parent:FindFirstChild('Humanoid') then
                                if victim.Parent:FindFirstChild('Type') then
                                    if victim.Parent.Type.Value == 'Miniboss' or victim.Parent.Type.Value == 'Boss' then
                                        victim.Parent.Humanoid:TakeDamage((dps / 10) * 0.8)
                                    else
                                        victim.Parent.Humanoid:TakeDamage(dps / 10)
                                    end
                                else
                                    victim.Parent.Humanoid:TakeDamage(dps / 10)
                                end   
                            end
                            wait(.1)
                        end
                    end
                end
            end             

Line 15 was changed and moved down to line 16

Ad
Log in to vote
1
Answered by
Redbullusa 1580 Moderation Voter
9 years ago

This looks like the same situation as a "while" loop with no "wait()" function.

-- A part of your script, regarding the "for" loop
for i=1, math.huge do
    if victim and victim.Parent then
        -- Etcetera
        wait(.1)
    end
end

Once victim dies, victim.Parent becomes nil, which means the "if" statement's condition is not met. Therefore, no more wait() statements to run, which crashes studio.

I'd either use a "while" loop instead, or add a break.

-- Tab your code!
function InfiniteDamageOverTime(victim, dps)
    if victim and victim.Parent and victim.Parent.Torso and victim.Parent.Head then
        while victim and victim.Parent and victim.Parent:FindFirstChild("Humanoid") do
            if victim.Parent:FindFirstChild("Head") and victim.Parent:FindFirstChild("Torso") and victim.Parent:FindFirstChild('Humanoid') then
                if victim.Parent:FindFirstChild('Type') then
                    if victim.Parent.Type.Value == 'Miniboss' or victim.Parent.Type.Value == 'Boss' then
                        victim.Parent.Humanoid:TakeDamage((dps / 10) * 0.8)
                    else
                        victim.Parent.Humanoid:TakeDamage(dps / 10)
                    end
                else
                    victim.Parent.Humanoid:TakeDamage(dps / 10)
                end
            end
            wait(.1) -- I also repositioned the "wait()" function.
        end
    end
end

Answer this question