Difference between revisions of "Left 4 Voting 2"

From AlliedModders Wiki
Jump to: navigation, search
(Fixed VoteStart having two param1s.)
(Added Server entity)
Line 6: Line 6:
 
# Clients use the "Vote" command to register their votes ("Yes" or "No"), after which the server sends a VoteRegistered UserMessage to that player to acknowledge their vote.  A vote_changed event is sent to all players with updated numbers.
 
# Clients use the "Vote" command to register their votes ("Yes" or "No"), after which the server sends a VoteRegistered UserMessage to that player to acknowledge their vote.  A vote_changed event is sent to all players with updated numbers.
 
# When the vote is complete, the server sends either a VotePass or VoteFail UserMessage.
 
# When the vote is complete, the server sends either a VotePass or VoteFail UserMessage.
 +
 +
== Server Entity ==
 +
 +
The server should update this as appropriate.  Unfortunately, the valid values for m_iActiveIssueIndex is unknown.
 +
 +
{{begin-hl2msg|vote_controller (CVoteController)|string}}
 +
{{hl2msg|int|m_activeIssueIndex|Number of the active issue}}
 +
{{hl2msg|int|m_onlyTeamToVote|Corresponds to VoteStart's team argument.}}
 +
{{hl2msg|int|m_votesYes|Current Yes votes}}
 +
{{hl2msg|int|m_votesNo|Current No votes}}
 +
{{hl2msg|int|m_potentialVotes|Number of players eligible to vote}}
 +
{{end-hl2msg}}
  
 
== Console Commands ==
 
== Console Commands ==

Revision as of 17:35, 2 February 2013

Left 4 Dead 2 has a VGUI voting system controller by a bunch of Events and UserMessages. You can use either a string from the resource file, or L4D_TargetID_Player which will let you create any vote you want.

How voting works

  1. A client issues a callvote with the vote type and argument.
  2. The VoteStart User Message is sent.
  3. Clients use the "Vote" command to register their votes ("Yes" or "No"), after which the server sends a VoteRegistered UserMessage to that player to acknowledge their vote. A vote_changed event is sent to all players with updated numbers.
  4. When the vote is complete, the server sends either a VotePass or VoteFail UserMessage.

Server Entity

The server should update this as appropriate. Unfortunately, the valid values for m_iActiveIssueIndex is unknown.

Name: vote_controller (CVoteController)
Structure:
int m_activeIssueIndex Number of the active issue
int m_onlyTeamToVote Corresponds to VoteStart's team argument.
int m_votesYes Current Yes votes
int m_votesNo Current No votes
int m_potentialVotes Number of players eligible to vote


Console Commands

Vote

Note: This command is only valid when a vote is ongoing.

Name: Vote
Structure:
string option "Yes" or "No"


User Messages

Note: These user messages use unsigned bytes for the team number. Since Valve represents no team as -1, no team is instead represented as its two's complement, 255.

VoteStart

Note: Sent to all players in the vote group, corresponding with teams. The default implementation also sends it to bots.

Name: VoteStart
Structure:
byte team Team index or 255 for all
byte initiator Client index (NOT USERID) of person who started the vote, or 99 for the server.
string issue Vote issue translation string
string param1 Vote issue text
string initiatorName Name of person who started the vote


VoteRegistered

Note: Only sent to player who voted

Name: VoteRegistered
Structure:
byte vote 0 for No, 1 for Yes


VotePass

Note: Sent to all players after a vote passes.

Name: VotePass
Structure:
byte team Team index or 255 for all
string details Vote success translation string
string param1 Vote winner


VoteFail

Note: Sent to all players after a vote fails.

Name: VoteFail
Structure:
byte team Team index or 255 for all


Events

Note: team is -1 when sent to all players)

vote_changed

Name: vote_changed
Structure:
byte yesVotes
byte noVotes
byte potentialVotes


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>

#define L4D2_TEAM_ALL -1

new yesvotes;
new novotes;
#define MAX_VOTES 4

public OnPluginStart()
{
	RegConsoleCmd("testvote",Callvote_Handler);
	RegConsoleCmd("Vote",vote);
}
public Action:Callvote_Handler(client, args)
{
	new Handle:bf = StartMessageAll("VoteStart", USERMSG_RELIABLE);

	BfWriteByte(bf, L4D2_TEAM_ALL);
	BfWriteByte(bf, 0);
	BfWriteString(bf, "#L4D_TargetID_Player");
	BfWriteString(bf, "Is gaben fat?");
	BfWriteString(bf, "Server");
	EndMessage();
	
	yesvotes = 0;
	novotes = 0;
	UpdateVotes();
	
	return Plugin_Handled;
}
public UpdateVotes()
{
	new Handle:msg = CreateEvent("vote_changed");
	SetEventInt(msg,"yesVotes",yesvotes);
	SetEventInt(msg,"noVotes",novotes);
	SetEventInt(msg,"potentialVotes",MAX_VOTES);
	FireEvent(msg);
	
	if (yesvotes+novotes == MAX_VOTES)
	{
		PrintToServer("voting complete!");
		if (yesvotes > novotes)
		{
			new Handle:bf = StartMessageAll("VotePass");
			BfWriteByte(bf, L4D2_TEAM_ALL);
			BfWriteString(bf, "#L4D_TargetID_Player");
			BfWriteString(bf, "Gaben is fat");
			EndMessage();
		}
		else
		{
			new Handle:bf = StartMessageAll("VoteFailed");
			BfWriteByte(bf, L4D2_TEAM_ALL);
			EndMessage();
		}
	}
}
public Action:vote(client, args)
{
	new String:arg[8];
	GetCmdArg(1,arg,8);
	PrintToServer("Got vote %s from %i",arg,client);
	if (strcmp(arg,"Yes",true) == 0)
	{
		yesvotes++;
	}
	else if (strcmp(arg,"No",true) == 0)
	{
		novotes++;
	}
	
	UpdateVotes();
	return Plugin_Continue;
}

See Also