You have Objectives. They stay open until they are somehow cleared.
Here's one way you can organize it.
There are two important functions:
function Add(objective, priority)
end
function ShowAll()
end
We'll need a list of all of the objectives currently open, and we'll need Add to put into it something that has (1) the objective data, (2) something saying it's still open, and (3) the priority.
You might also want to add, e.g., a Frame so that you can do animations when there are updates, instead of just erasing and updating everything in ShowAll. I'll show that here.
local objectives = {}
function Add(objective, priority)
local o = { data = objective, priority = priority }
o.gui = Instance.new("Frame", script.Parent)
o.gui.Position = UDim2.new(0.5, 0, 0.5, 0)
o.gui.Size = UDim2.new(0, 0, 0, 0)
local label = Instance.new("TextLabel", o.gui)
label.Text = objective
label.TextScaled = true
label.BackgroundTransparency = 1
ShowAll()
return o
end
We can also add a Complete function which gets rid of the o.gui:
function Complete(objective)
o.gui:TweenSize( UDim2.new(0,0,0,0), nil, nil, 1, true)
delay(1, function() o.gui:Destroy() end)
end
Now we need ShowAll to (1) clear solved objectives, (2) sort current objectives, and (3) display the objectives.
table.remove can remove something at a given index. The simplest way to make this work is a for loop that moves from back to front (since table.remove shifts all the indices down, going up doesn't work).
Sorting is easy with table.sort. We can give a function telling how to compare to objects, which puts larger .priority fields first:
function ShowAll()
for i = #objectives, 1, -1 do
if objectives[i].cleared then
Complete( table.remove(objectives, i) )
end
end
table.sort(objectives, function(a,b) return a.priority > b.priority end)
You then should choose to display either the first or all objectives. Here I'll display the first, and the rest separately:
if objectives[1] then
objectives[1].gui:TweenPosition(UDim2.new(0,0,0,0))
objectives[1].gui.TweenSize(UDim2.new(1, 0, 0, 72))
end
for i = 2, #objectives do
objectives[i].gui:TweenPosition(UDim2.new(1, -100, 0, 72+(i-2)*36), nil, nil, 1, true)
objectives[i].gui:TweenSize(UDim2.new(0, 100, 0, 36), nil, nil, 1, true)
end
end
To finish an objective, you should add cleared onto the thing that Add returns:
local objective = Add("Wait 10 seconds", 1)
wait(10)
objective.cleared = true
ShowAll()
It may be reasonable to simply ShowAll on a loop every one second instead. Note that if you interrupt Tweens, it will look a little strange, so if you have very frequent updates, you might run into some issues.
Also be aware that this is not fast. Sorting hundreds or thousands of elements when you add one thing isn't the fastest -- but if you have less than a few dozen it'll still be instant
3 comments
I'm thinking along the lines of an Array that is updated with announcements and GUI is made to match it?
What exactly do you mean by "queue"? Would it show the oldest, highest-priority message, then after a few seconds remove it from the queue and move onto the next one?
Yes, that the basic idea except messages would stay put until an objective is met and would re-order themselves according to their priority. One example could be a standard Quest system, or a list of calendar-events re-ordering themselves by date.