Left 4 Voting

From AlliedModders Wiki
Revision as of 17:36, 2 February 2013 by Powerlord (talk | contribs) (Added Server Entity)
Jump to: navigation, search

Left 4 Dead has a new VGUI voting system, it's controlled by a bunch of events. 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. Server sends a vote_started event
  2. Servers sends a vote_changed event
  3. Clients use the "Vote" command to register their votes ("Yes" or "No"), after which the server sends a vote_cast_yes or vote_cast_no event, followed by a vote_changed event with updated numbers.
  4. Server ends the vote by sending vote_ended event, followed by a vote_passed or vote_failed event.

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"


Events

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

vote_ended

Name: vote_ended
Structure:
None None


vote_started

Name: vote_started
Structure:
string issue
string param1
byte team
long initiator entity id of the player who initiated the vote


vote_changed

Name: vote_changed
Structure:
byte yesVotes
byte noVotes
byte potentialVotes


vote_passed

Name: vote_passed
Structure:
string details
string param1
byte team


vote_failed

Name: vote_failed
Structure:
byte team


vote_cast_yes

Name: vote_cast_yes
Structure:
byte team
long entityid entity id of the voter


vote_cast_no

Name: vote_cast_no
Structure:
byte team
long entityid entity id of the voter


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>
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:msg = CreateEvent("vote_started");
	SetEventString(msg,"issue","#L4D_TargetID_Player");
	SetEventString(msg,"param1","Is gaben fat?");
	SetEventInt(msg,"team",0);
	SetEventInt(msg,"initiator",0);
	FireEvent(msg);
	
	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!");
		msg = CreateEvent("vote_ended");
		FireEvent(msg);
		if (yesvotes > novotes)
		{
			msg = CreateEvent("vote_passed");
			SetEventString(msg,"details","#L4D_TargetID_Player");
			SetEventString(msg,"param1","Gaben is fat");
			SetEventInt(msg,"team",0);
			FireEvent(msg);
		}
		else
		{
			msg = CreateEvent("vote_failed");
			SetEventInt(msg,"team",0);
			FireEvent(msg);
		}
	}
}
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 the following images for examples what this looks like:

http://devicenull.org/temp/l4d_question.jpg

http://devicenull.org/temp/l4d_result.jpg

See Also