This is related to move previous topic: Unable to assign property Text. string expected, got nil - #12 by Master1794
Hello, developers! I have an issue where my loop is skipping by two or more increments. What should happen is the loop should run once, then repeatedly wait until a condition (bool) is true. I’ve tried debugging by printing the bool value in the loop and it always printed false.
--//variables
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RemoteEvents = ReplicatedStorage:WaitForChild("RemoteEvents")
local Frame = script.Parent.Frame
local ChoicesFrame = script.Parent.choices.Frame
local ChatStarted = false
local canContinue = true
local currentChatIndex = 0 --//this is used for which number of messages we're at
local choiceIndex = 0 --//this is used for which index choice the player has chosen
local maxChoices = 0 --//this is used to determine how many choices the player is given (disregarding the GoodbyeTxt choice)
local oldChoiceIndex = 0 --//this is used to get the old choice index value
local GoodbyeTxt = "Goodbye!"
local choiceSelected
local choices
local responses
local currentChoice
local chatModes = {
Friendly = Color3.fromRGB(13, 228, 68),
Enemy = Color3.fromRGB(233, 0, 0),
Help = Color3.fromRGB(0, 118, 255),
None = Frame.UIStroke.Color
}
local typewriteMod = require(ReplicatedStorage:WaitForChild("typewrite"))
--//functions
local function getTableItems(array)
local totalItems = 0 --//total items in array
for _, element in ipairs(array) do
if typeof(element) == "table" then
totalItems += getTableItems(element)
else
totalItems += 1
end
end
return totalItems
end
local function tweenChoicesFrame(open: boolean)
if open == true then
ChoicesFrame.Parent:TweenPosition(
UDim2.new(
0.125,
0,
0.725,
0
),
Enum.EasingDirection.InOut,
Enum.EasingStyle.Quad,
0.5
)
else
ChoicesFrame.Parent:TweenPosition(
UDim2.new(
0.125,
0,
1.25,
0
),
Enum.EasingDirection.InOut,
Enum.EasingStyle.Quad,
0.5
)
end
end
local function getResponse()
for _, response in ipairs(responses) do
if ChatStarted == false then
break
end
currentChatIndex += 1
if typeof(responses[currentChatIndex]) == "string" then
Frame.speech_.Text = responses[currentChatIndex]
elseif typeof(responses[currentChatIndex]) == "table" then
local multiResps = responses[currentChatIndex]
--print(multiResps[oldChoiceIndex])
--Frame.speech_.Text = multiResps[oldChoiceIndex]
if choiceSelected ~= GoodbyeTxt then
Frame.speech_.Text = multiResps[choiceSelected]
else
break
end
end
typewriteMod.typewrite(Frame.speech_, 0.025)
print("Current chat index:", currentChatIndex)
repeat wait()
until canContinue == true
end
end
local function getChoice()
for index, choiceT in ipairs(choices) do
if ChatStarted == false or currentChatIndex == getTableItems(responses) - 1 or currentChoice == GoodbyeTxt then
break
end
if currentChoice == GoodbyeTxt then
print("wow, this should loop be broken by now!")
end
currentChoice = choices[currentChatIndex]
local currentIndex = 0 --//used to be added to for the table loop below
maxChoices = getTableItems(currentChoice)
for _, choice in ipairs(currentChoice) do
currentIndex += 1
if maxChoices == 1 then
ChoicesFrame["3"].Visible = false
ChoicesFrame["2"].Text = GoodbyeTxt
elseif maxChoices == 2 then
ChoicesFrame["3"].Visible = true
end
ChoicesFrame[currentIndex].Text = choice
--oldChoiceIndex = table.find(currentChoice, choiceSelected)
--print("old choice index:", oldChoiceIndex)
end
repeat wait()
until canContinue == true
end
end
RemoteEvents.StartChat.OnClientEvent:Connect(function(chatTree, speakerName, chatMode)
local Lresponses = chatTree["resps"]
local Lchoices = chatTree["choices"]
ChatStarted = true
responses = Lresponses
choices = Lchoices
Frame.name_.Text = speakerName .. ":"
Frame.speech_.Text = "..."
for modeName, modeColor in pairs(chatModes) do
if modeName == chatMode then
Frame.UIStroke.Color = modeColor
ChoicesFrame.Parent.UIStroke.Color = modeColor
end
end
Frame:TweenPosition(
UDim2.new(
0.5,
0,
0.909,
0
),
Enum.EasingDirection.InOut,
Enum.EasingStyle.Quad,
0.5
)
wait(1)
while canContinue == true do
canContinue = false
local coroGetResps = coroutine.create(getResponse)
local coroGetChoice = coroutine.create(getChoice)
if choiceSelected == GoodbyeTxt then
ChatStarted = false
Frame.speech_.Text = GoodbyeTxt
typewriteMod.typewrite(Frame.speech_, 0.025)
ReplicatedStorage:WaitForChild("typewrite").isFinished.Value = false
coroutine.close(coroGetResps)
coroutine.close(coroGetChoice)
break
end
if coroutine.status(coroGetResps) ~= "dead" or coroutine.status(coroGetChoice) ~= "dead" then
coroutine.resume(coroGetResps)
coroutine.resume(coroGetChoice)
repeat wait()
until typewriteMod.isFinished() == true
if currentChatIndex >= getTableItems(responses) - 1 then
ChatStarted = false
Frame.speech_.Text = GoodbyeTxt
typewriteMod.typewrite(Frame.speech_, 0.025)
ReplicatedStorage:WaitForChild("typewrite").isFinished.Value = false
coroutine.close(coroGetResps)
coroutine.close(coroGetChoice)
break
end
wait(1)
if typewriteMod.isFinished() == true then
coroutine.wrap(tweenChoicesFrame)(true)
end
end
repeat wait()
until canContinue == true
end
wait(2)
RemoteEvents.ChatEnded:FireServer()
Frame:TweenPosition(
UDim2.new(
0.5,
0,
1.25,
0
)
)
local dialogueScript = script:Clone()
dialogueScript.Parent = script.Parent
script:Destroy()
end)
for _, choiceBtn in ipairs(ChoicesFrame:GetChildren()) do
if choiceBtn:IsA("TextButton") then
local UIStroke = ChoicesFrame:WaitForChild("UIStroke")
choiceBtn.MouseButton1Click:Connect(function()
if canContinue == false then
canContinue = true
choiceSelected = table.find(currentChoice, choiceBtn.Text)
if choiceSelected == nil and choiceBtn.Text == GoodbyeTxt then
choiceSelected = GoodbyeTxt
end
coroutine.wrap(tweenChoicesFrame)(false)
end
end)
choiceBtn.MouseEnter:Connect(function()
UIStroke.Parent = choiceBtn
UIStroke.Enabled = true
end)
choiceBtn.MouseLeave:Connect(function()
UIStroke.Parent = ChoicesFrame
UIStroke.Enabled = false
end)
end
end