Queuing Announcements


I recently downloaded an addon to create server-side achievements (http://code.google.com/p/gmodsachievements/)

The addon itself works fine in testing, however I’m wanting to add this to my TTT server, and as you can imagine, any traitor specific achievement that is earned mid-game is basically announcing that said person is a traitor to everyone else.

I was wondering, how could I go about queuing up the achievement announcements until the end of the round? Achievement announcements are sent to clients via usermessages like so:

if (type == “announce_achievement”) then
s_achievements.Announcement( um:ReadString(), um:ReadString(), um:ReadString() )

function s_achievements.Announcement( name, color, achievement )
s_achievements.CallHook( “c_achievement_announce”, { name, color, achievement } )
local ecolor = string.Explode( “,”, color )
local name_color = Color( ecolor[1], ecolor[2], ecolor[3], 255 )
chat.AddText( name_color, name, s_achievements.color_offwhite, " has earned the achievement ", s_achievements.color_green, achievement )

As well as the clientside hook above, there’s a serverside hook for when the achievement is actually earned.

Not looking to be spoonfed here, just I’m a bit out of my depth here and dont know anyone good enough with LUA to help me, I just want a general idea of how I could go about fixing this.

Could you not store the achievement announcements in a table, then just loop through it at the end of the round, and announce each one? (I believe Fretta has hooks for when the round ends.)

TTT has hooks for the round end.

I’m not that great with tables and stuff though, how could I go about storing them in one since there are a few different parts to the announcement itself?

Just store a table of the stat that needs to be changed and to what value, then run the usermessages on round end

Still a tad confused. I have never used tables before and I’m still trying to get my head around how I should handle this.

My main issues are -

Where should I create the table?
How would I append each new achievement earned to the table? (The function only takes ‘ply’ and ‘achievement’)
At what point would I iterate through the table and pass everything through the function to announce them, and how would I go about clearing the table after each round has passed? Could this be thrown in a separate file in autorun and still use the function from the achievement addon?

I’d also need to check if the table has anything in it before trying to announce anything, in case nobody has earned any achievements that round.

Sorry about all the questions, just having a hard time figuring out how to do all of this considering I havent really used tables before and I’m not sure where everything should go.

At the top of your file, just do something like:

[lua]local Announcements = {} – declare an empty table[/lua]

Then when someone gains an achievement, you do:

[lua]table.insert( Announcements, { “string1”, “string2”, “string3” } ) – I noticed you send 3 strings for the achievement, so this is actually a table containing the three strings, stored in another table[/lua]

Then, you use something like this do display them at the end:

[lua]hook.Add( “RoundEnd”, “AnnounceAchievements”, function() – this is a hook, any function added to a hook will be called when that hook is called, in this case we want the RoundEnd hook

for k, v in pairs( Announcements ) do -- loop through the table, k is the index, v is the value stored at that index

    umsg.Start( "your announcement usermessage" ) -- start the usermessage

        umsg.String( v[1] ) -- as v is actually a table containing the 3 strings
        umsg.String( v[2] ) -- we can get each string like this, we didn't specify
        umsg.String( v[3] ) -- any keys in our table, so it defaults to 1, 2, 3, 4, etc



Announcements = {} -- clears the table

end )[/lua]

Thanks a ton, that makes sense. The way I was thinking I would have to do it was to actually store the player and achievement and only update them as well as announce them on round end, instead of just updating them when they are earned then doing the announcements later.

I’ll give it a shot now.


Works like a charm, thanks a bunch.

That worked fine for the announcement, but the effects and sound still played when the achievement was gained, so I did some cut+pasting and also inserted the player into the table

function s_achievements.AchievementEarned( ply, achievement )
local name = ply:Nick()
local color = team.GetColor( ply:Team() )
s_achievements.CallHook( “achievement_earned”, { ply, achievement } )
table.insert( Announcements, { name, color.r…","…color.g…","…color.b, achievement, ply } )

hook.Add( “TTTEndRound”, “AnnounceAchievements”, function()
if (Announcements == {}) then

	for k, v in pairs( Announcements ) do 

		local filter = RecipientFilter()
		umsg.Start( "s_achievement", filter )
			umsg.String( "announce_achievement" )
			umsg.String( v[1] )
			umsg.String( v[2] )
			umsg.String( v[3] )
Announcements = {} 

end )

No problem :smile: