Updated license headers on virtually all files with extremely minor changes in the name of some sort of strange consistency.
All plugin and include file headers also have been changed to say about GPL3 instead of GPL2.
(This day shall henceforth be known as the Eighty Column Massacre of '07)
3 * =============================================================================
5 * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
6 * =============================================================================
8 * This program is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU General Public License, version 3.0, as published by the
10 * Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
17 * You should have received a copy of the GNU General Public License along with
18 * this program. If not, see <http://www.gnu.org/licenses/>.
20 * As a special exception, AlliedModders LLC gives you permission to link the
21 * code of this program (as well as its derivative works) to "Half-Life 2," the
22 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
23 * by the Valve Corporation. You must obey the GNU General Public License in
24 * all respects for all other code used. Additionally, AlliedModders LLC grants
25 * this exception to all derivative works. AlliedModders LLC defines further
26 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
27 * or <http://www.sourcemod.net/license.php>.
34 #include "MenuVoting.h"
35 #include "PlayerManager.h"
36 #include "sourcemm_api.h"
38 float g_next_vote = 0.0f;
40 void OnVoteDelayChange(ConVar *cvar, const char *value);
41 ConVar sm_vote_delay("sm_vote_delay",
44 "Sets the recommended time in between public votes",
51 void OnVoteDelayChange(ConVar *cvar, const char *value)
53 /* See if the new vote delay isn't something we need to account for */
54 if (sm_vote_delay.GetFloat() < 1.0f)
60 /* If there was never a last vote, ignore this change */
61 if (g_next_vote < 0.1f)
66 /* Subtract the original value, then add the new one. */
67 g_next_vote -= (float)atof(value);
68 g_next_vote += sm_vote_delay.GetFloat();
71 unsigned int VoteMenuHandler::GetRemainingVoteDelay()
73 if (g_next_vote <= gpGlobals->curtime)
78 return (unsigned int)(g_next_vote - gpGlobals->curtime);
81 void VoteMenuHandler::OnSourceModAllInitialized()
83 g_Players.AddClientListener(this);
86 void VoteMenuHandler::OnSourceModShutdown()
88 g_Players.RemoveClientListener(this);
91 void VoteMenuHandler::OnSourceModLevelChange(const char *mapName)
96 unsigned int VoteMenuHandler::GetMenuAPIVersion2()
98 return m_pHandler->GetMenuAPIVersion2();
101 void VoteMenuHandler::OnClientDisconnected(int client)
103 if (!IsVoteInProgress())
108 /* Wipe out their vote if they had one */
110 if ((item = m_ClientVotes[client]) >= 0)
112 assert((unsigned)item < m_Items);
113 assert(m_Votes[item] > 0);
115 m_ClientVotes[client] = -1;
119 bool VoteMenuHandler::IsVoteInProgress()
121 return (m_pCurMenu != NULL);
124 bool VoteMenuHandler::StartVote(IBaseMenu *menu, unsigned int num_clients, int clients[], unsigned int max_time, unsigned int flags/* =0 */)
126 if (!InitializeVoting(menu, menu->GetHandler(), max_time, flags))
131 float fVoteDelay = sm_vote_delay.GetFloat();
132 if (fVoteDelay < 1.0)
136 /* This little trick breaks for infinite votes!
137 * However, we just ignore that since those 1) shouldn't exist and
138 * 2) people must be checking IsVoteInProgress() beforehand anyway.
140 g_next_vote = gpGlobals->curtime + fVoteDelay + (float)max_time;
143 for (unsigned int i=0; i<num_clients; i++)
145 menu->Display(clients[i], max_time, this);
153 bool VoteMenuHandler::InitializeVoting(IBaseMenu *menu,
154 IMenuHandler *handler,
158 if (IsVoteInProgress())
165 /* Mark all clients as not voting */
166 for (int i=1; i<=gpGlobals->maxClients; i++)
168 m_ClientVotes[i] = -2;
171 m_Items = menu->GetItemCount();
173 if (m_Votes.size() < (size_t)m_Items)
175 /* Only clear the items we need to... */
176 size_t size = m_Votes.size();
177 for (size_t i=0; i<size; i++)
181 m_Votes.resize(m_Items, 0);
183 for (unsigned int i=0; i<m_Items; i++)
192 m_pHandler = handler;
194 m_pHandler->OnMenuStart(m_pCurMenu);
199 void VoteMenuHandler::StartVoting()
208 m_pHandler->OnMenuVoteStart(m_pCurMenu);
210 /* By now we know how many clients were set.
211 * If there are none, we should end IMMEDIATELY.
219 void VoteMenuHandler::DecrementPlayerCount()
221 assert(m_Clients > 0);
225 if (m_bStarted && m_Clients == 0)
231 int SortVoteItems(const void *item1, const void *item2)
233 return ((menu_vote_result_t::menu_item_vote_t *)item2)->count
234 - ((menu_vote_result_t::menu_item_vote_t *)item1)->count;
237 void VoteMenuHandler::EndVoting()
239 /* Set when the next delay ends. We ignore cancellation because a menu
240 * was, at one point, displayed, which is all that counts. However, we
241 * do re-calculate the time just in case the menu had no time limit.
243 float fVoteDelay = sm_vote_delay.GetFloat();
244 if (fVoteDelay < 1.0)
248 g_next_vote = gpGlobals->curtime + fVoteDelay;
253 /* If we were cancelled, don't bother tabulating anything.
254 * Reset just in case someone tries to redraw, which means
255 * we need to save our states.
257 IBaseMenu *menu = m_pCurMenu;
258 IMenuHandler *handler = m_pHandler;
260 handler->OnMenuVoteCancel(menu, VoteCancel_Generic);
261 handler->OnMenuEnd(menu, MenuEnd_VotingCancelled);
265 menu_vote_result_t vote;
266 menu_vote_result_t::menu_client_vote_t client_vote[256];
267 menu_vote_result_t::menu_item_vote_t item_vote[256];
269 memset(&vote, 0, sizeof(vote));
271 /* Build the item list */
272 for (unsigned int i=0; i<m_Items; i++)
276 item_vote[vote.num_items].count = m_Votes[i];
277 item_vote[vote.num_items].item = i;
278 vote.num_votes += m_Votes[i];
282 vote.item_list = item_vote;
286 IBaseMenu *menu = m_pCurMenu;
287 IMenuHandler *handler = m_pHandler;
289 handler->OnMenuVoteCancel(menu, VoteCancel_NoVotes);
290 handler->OnMenuEnd(menu, MenuEnd_VotingCancelled);
294 /* Build the client list */
295 for (int i=1; i<=gpGlobals->maxClients; i++)
297 if (m_ClientVotes[i] >= -1)
299 client_vote[vote.num_clients].client = i;
300 client_vote[vote.num_clients].item = m_ClientVotes[i];
304 vote.client_list = client_vote;
306 /* Sort the item list descending like we promised */
309 sizeof(menu_vote_result_t::menu_item_vote_t),
312 /* Save states, then clear what we've saved.
313 * This makes us re-entrant, which is always the safe way to go.
315 IBaseMenu *menu = m_pCurMenu;
316 IMenuHandler *handler = m_pHandler;
320 handler->OnMenuVoteResults(menu, &vote);
321 handler->OnMenuEnd(menu, MenuEnd_VotingDone);
324 void VoteMenuHandler::OnMenuStart(IBaseMenu *menu)
329 void VoteMenuHandler::OnMenuEnd(IBaseMenu *menu, MenuEndReason reason)
331 DecrementPlayerCount();
334 void VoteMenuHandler::OnMenuCancel(IBaseMenu *menu, int client, MenuCancelReason reason)
336 m_pHandler->OnMenuCancel(menu, client, reason);
339 void VoteMenuHandler::OnMenuDisplay(IBaseMenu *menu, int client, IMenuPanel *display)
341 m_ClientVotes[client] = -1;
342 m_pHandler->OnMenuDisplay(menu, client, display);
345 unsigned int VoteMenuHandler::OnMenuDisplayItem(IBaseMenu *menu, int client, IMenuPanel *panel, unsigned int item, const ItemDrawInfo &dr)
347 return m_pHandler->OnMenuDisplayItem(menu, client, panel, item, dr);
350 void VoteMenuHandler::OnMenuDrawItem(IBaseMenu *menu, int client, unsigned int item, unsigned int &style)
352 m_pHandler->OnMenuDrawItem(menu, client, item, style);
355 void VoteMenuHandler::OnMenuSelect(IBaseMenu *menu, int client, unsigned int item)
357 /* Check by our item count, NOT the vote array size */
360 m_ClientVotes[client] = item;
365 m_pHandler->OnMenuSelect(menu, client, item);
368 void VoteMenuHandler::InternalReset()
375 m_bCancelled = false;
379 void VoteMenuHandler::CancelVoting()
381 if (m_bCancelled || !m_pCurMenu)
386 m_pCurMenu->Cancel();
389 IBaseMenu *VoteMenuHandler::GetCurrentMenu()
394 bool VoteMenuHandler::IsCancelling()