Difference between revisions of "TF2 Voting"
(Fixed error number list) |
(Fixed User Message spelling, and added some links.) |
||
| Line 1: | Line 1: | ||
| − | Team Fortress 2 has a new voting system based on the [[Left 4 Voting|Left 4 Dead Voting system]] and is controlled by events and | + | Team Fortress 2 has a new voting system based on the [[Left 4 Voting|Left 4 Dead Voting system]] and is controlled by [[Game Events (Source)|events]] and [[User Messages]]. You can use either a string from the resource file, or TF_playerid_noteam which will let you create any vote you want. |
== How voting works == | == How voting works == | ||
| − | For a Yes/No vote, the server begins by sending a VoteStart | + | For a Yes/No vote, the server begins by sending a VoteStart User Message. Clients use the "vote" command to register their votes, after which the server sends a vote_cast event. |
| − | When the vote is complete, the server send either a VotePass or VoteFailed | + | When the vote is complete, the server send either a VotePass or VoteFailed User Message. |
| − | A multiple choice vote is much the same as a Yes/No vote, but the server sends a "vote_options" event first, and sets the last argument of the VoteStart | + | A multiple choice vote is much the same as a Yes/No vote, but the server sends a "vote_options" event first, and sets the last argument of the VoteStart User Message to false instead of true. |
== Failure reasons == | == Failure reasons == | ||
| − | The VoteFailed | + | The VoteFailed User Message does not take a string to display. Instead, it takes a number that corresponds to a specific message. |
The values that work are: | The values that work are: | ||
| Line 29: | Line 29: | ||
10 - Voting not allowed while Waiting for Players | 10 - Voting not allowed while Waiting for Players | ||
| − | == | + | == User Messages == |
| − | The | + | The User Messages that exist in the TF2 Voting system are: |
VoteSetup | VoteSetup | ||
Revision as of 23:39, 13 July 2011
Team Fortress 2 has a new voting system based on the Left 4 Dead Voting system and is controlled by events and User Messages. You can use either a string from the resource file, or TF_playerid_noteam which will let you create any vote you want.
Contents
How voting works
For a Yes/No vote, the server begins by sending a VoteStart User Message. Clients use the "vote" command to register their votes, after which the server sends a vote_cast event.
When the vote is complete, the server send either a VotePass or VoteFailed User Message.
A multiple choice vote is much the same as a Yes/No vote, but the server sends a "vote_options" event first, and sets the last argument of the VoteStart User Message to false instead of true.
Failure reasons
The VoteFailed User Message does not take a string to display. Instead, it takes a number that corresponds to a specific message.
The values that work are:
0 - Generic "Vote Failed" message
3 - Yes votes must outnumber No votes
4 - Not Enough Votes
Other error numbers exist, but they are used by CallVoteFailed:
1 = Cannot call vote while other players are still loading
2 = You called a vote recently and cannot call another one for X seconds (second argument to CallVoteFailed specifies the number of seconds)
5 - Server has disabled that issue.
6 - That map does not exist.
7 - You must specify a map name
8 - This vote failed recently
9 - Your team cannot call this vote
10 - Voting not allowed while Waiting for Players
User Messages
The User Messages that exist in the TF2 Voting system are:
VoteSetup
- Byte Count of vote issues allowed on this server * String Vote Issues, same number as Count above.
VoteStart
- Byte Team index or -1 for all - Byte Client index (NOT USERID) of person who started the vote, or 99 for the server. - String Vote issue translation string - String Vote issue text - Bool true for Yes/No, false for Multiple choice
VotePass
- Byte Team index or -1 for all - String Vote issue translation string - String Vote winner (same as vote issue text for Yes/No?)
VoteFail
- Byte Team index or -1 for all - Byte Failure reason code (0, 3-4)
CallVoteFailed
- Byte Failure reason code (1-2, 5-10) - Short If above is 2, number of seconds until you can next start a vote.
Events
Note: Sent to all players when a player chooses a vote option (or more specifically, the server receives a vote command)
| Name: | vote_cast | |||||||||
| Structure: |
|
Note: Sent to players before VoteStart UserMessage to populate choices for a multiple choice vote
| Name: | vote_options | ||||||||||||||||||
| Structure: |
|
Unused?
| Name: | vote_ended | |
| Structure: |
|
| Name: | vote_started | ||||||||||||
| Structure: |
|
| Name: | vote_changed | ||||||||||||||||||
| Structure: |
|
| Name: | vote_passed | |||||||||
| Structure: |
|
| Name: | vote_failed | |||
| Structure: |
|
Example voting plugin
This is a basic plugin that starts a vote, "Is gaben fat?". It does not ensure the same client does not vote multiple times, nor does it actually kick the user.
#include <sourcemod>
// TF2's internal map vote uses client index 99 for the server
#define TF2_SERVER_CLIENT_INDEX 99
#define TF2_TEAM_ALL -1
new yesvotes;
new novotes;
#define MAX_VOTES 4
public Plugin:myinfo =
{
name = "Test Yes/No Vote",
author = "Powerlord",
description = "A test vote plugin for the AlliedMods wiki",
version = "1.0",
url = "http://wiki.alliedmods.net/TF2_Voting"
}
public OnPluginStart()
{
RegConsoleCmd("testvote",Callvote_Handler);
RegConsoleCmd("vote", vote);
}
public Action:Callvote_Handler(client, args)
{
new Handle:bf = StartMessageAll("VoteStart", USERMSG_RELIABLE);
BfWriteByte(bf, TF2_TEAM_ALL);
BfWriteByte(bf, TF2_SERVER_CLIENT_INDEX);
BfWriteString(bf, "#TF_playerid_noteam");
BfWriteString(bf, "Is gaben fat?");
BfWriteBool(bf, true);
EndMessage();
yesvotes = 0;
novotes = 0;
return Plugin_Handled;
}
UpdateVotes()
{
if (yesvotes+novotes >= MAX_VOTES)
{
PrintToServer("voting complete!");
if (yesvotes > novotes)
{
new Handle:bf = StartMessageAll("VotePass");
BfWriteByte(bf, TF2_TEAM_ALL);
BfWriteString(bf, "#TF_playerid_noteam");
BfWriteString(bf, "Gaben is fat");
EndMessage();
}
else
{
new Handle:bf = StartMessageAll("VoteFailed");
BfWriteByte(bf, TF2_TEAM_ALL);
// Check list of failure reasons
BfWriteByte(bf, 3);
EndMessage();
}
}
}
// If the TF2 vote system is running (sv_allow_votes 1), this needs to be a command listener because TF2 registers the vote command only when a vote is ongoing, and thus hooking it using RegConsoleCmd doesn't work.
public Action:vote(client, args)
{
new String:arg[8];
new option = 0;
GetCmdArg(1,arg,8);
PrintToServer("Got vote %s from %i",arg,client);
if (strcmp(arg,"option1",true) == 0)
{
yesvotes++;
option = 0;
}
else if (strcmp(arg,"option2",true) == 0)
{
novotes++;
option = 1;
}
new Handle:msg = CreateEvent("vote_cast");
SetEventInt(msg, "entityid", client);
SetEventInt(msg, "team", -1);
SetEventInt(msg, "vote_option", option);
FireEvent(msg);
UpdateVotes();
return Plugin_Continue;
}
See the following images for examples what this looks like: