Player voting system

What it does
The scripts that make up the Player Voting system are mainly intended for use on beta testing servers, though they can be adapted for use as the builder sees fit. What they do is allow the players in a game to vote on an issue (they were built primarily to allow players to vote on whether a module restart was necessary in case something goes wrong in a game and there is no DM online at the time). It is not difficult to expand what they can vote on.

This version allows PC's to vote on a module restart. It requires one placeable object to be built and placed somewhere in the module, preferably somewhere players can reach easily. There are two scripts for the placeable. It also requires one creature to be built, which is spawned during the voting process to collect player votes. There are two scripts for the creature.

Further notes on the creature. It should have its own faction that is neutral to every other faction to prevent problems if a vote is called while a pc is in combat. Good idea there Tethyr

The scripts, Part 1
Put On The placeable

OnUsed
void main { object oVoter = GetFirstPC; vector vPosition; location lLoc; /*  Use whatever message you feel is appropriate to the vote that has been called. Just make sure that you indicate what a PC should say to cast their vote (depending on what you specify that to be in the vote gathering creature's  scripts). */ string sVoting = "A vote to reset the module has been called. Please say YES or NO to cast your vote, repeating it until you are informed your vote has been registered. You have 20 seconds to decide."; /*  Cycle through all players in the module, telling them a vote has been called, and spawning the vote gatherer at their location. */ while(GetIsObjectValid(oVoter)) {  vPosition = GetPosition(oVoter) - Vector(1.0,1.0,0.0); lLoc = Location(GetArea(oVoter),vPosition,GetFacing(oVoter)); //Use the blueprint of your creature here. CreateObject(OBJECT_TYPE_CREATURE,"votingbooth",lLoc); DelayCommand(1.0f,SendMessageToPC(oVoter,sVoting)); oVoter = GetNextPC; } /*  Use an appropriate event number here, and delay for as long as you wish to give the players to decide (also reflect this time in the  message sent to the players earlier in this script). */ DelayCommand(21.0f,SignalEvent(OBJECT_SELF,EventUserDefined(1500))); }

UserDefined
void main { int nEvent = GetUserDefinedEventNumber; int nAyes; int nNays; /* Use appropriate messages to tell the player the result of the vote, and in the case of a yes vote, how long they have until the server resets. string sYesVote = "The vote has been tallied and the majority voted YES. The server will be reset in 30 seconds, so if you wish to preserve your character please log off now."; string sNoVote = "The vote has been tallied and the majority voted NO. The server will not be reset."; object oVoter = GetFirstPC; /* Use the event number you specified in the placeable's OnUsed script. if(nEvent == 1500) { nAyes = GetLocalInt(OBJECT_SELF,"VotedYes"); nNays = GetLocalInt(OBJECT_SELF,"VotedNo"); /* If you just wish a simple majority to allow the server to be reset this will be fine. You might want a two-thirds majority of players to vote yes before allowing the server to be reset. Simply use the math you want in this if line. if(nAyes > nNays) { //Cycle through the players telling them the result of the vote. while(GetIsObjectValid(oVoter)) {   SendMessageToPC(oVoter,sYesVote); oVoter = GetNextPC; } /*  Restart the module after the specified time (be sure to reflect   this in the message sent to the player on a yes vote). Use the name of your module here (not tag) without the .mod extension */  DelayCommand(30.0f,StartNewModule("Test Module")); } else { /*  Cycle through the players letting them know the result was No, and reset all variables and delete any left over vote gatherers. */  while(GetIsObjectValid(oVoter)) {   SendMessageToPC(oVoter,sNoVote); DeleteLocalInt(oVoter,"Voted"); oVoter = GetNextPC; }  int nNth = 1; //Use the creature's tag here. object oVotingBooth = GetObjectByTag("VOTINGBOOTH",nNth); while(GetIsObjectValid(oVotingBooth)) {   DestroyObject(oVotingBooth); nNth++; oVotingBooth = GetObjectByTag("VOTINGBOOTH",nNth); }  SetLocalInt(OBJECT_SELF,"VotedYes",0); SetLocalInt(OBJECT_SELF,"VotedNo",0); } } }

The Scripts, Part 2
Place on vote gathering creature's

OnSpawn
void main { /* Tell the creature to be listening, and set what words the vote gathering creature will be listening for. string sAye = "YES"; string sNay = "NO"; SetListening(OBJECT_SELF,TRUE); SetListenPattern(OBJECT_SELF,sAye,1200); SetListenPattern(OBJECT_SELF,sNay,1201); }

OnConversation
void main { int nVote = GetListenPatternNumber; object oVoter; //Use the placeable's tag here. object oStone = GetObjectByTag("RESETSTONE"); int nVoted; int nVotedYes = GetLocalInt(oStone,"VotedYes"); int nVotedNo = GetLocalInt(oStone,"VotedNo"); /* Ensure that you use the correct numbers here (you specified them in the creature's OnSpawn script). if(nVote == 1200) { /* Some checking to ensure several creature's don't register the same players vote should several players be in close quarters when a vote is called. Each creature should only respond to the nearest player. A bit clumsy as it requires the voter to speak twice to get their vote registered. oVoter = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR,PLAYER_CHAR_IS_PC,OBJECT_SELF,1); if(GetName(GetLastSpeaker) == GetName(oVoter)) { //Check that oVoter hasn't voted already. nVoted = GetLocalInt(oVoter,"Voted"); if(nVoted != 1) {   nVotedYes++; //Ensure that oVoter can't vote again in this vote. SetLocalInt(oVoter,"Voted",1); //Increment the number of votes for - Yes in this case. SetLocalInt(oStone,"VotedYes",nVotedYes); //Let the player know his vote has been registered. SpeakString(GetName(oVoter) + "'s vote has been registered."); //Remove the creature after it has served its purpose. DelayCommand(2.0f,DestroyObject(OBJECT_SELF)); } } } else if(nVote == 1201) { oVoter = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR,PLAYER_CHAR_IS_PC,OBJECT_SELF,1); if(GetName(GetLastSpeaker) == GetName(oVoter)) {  nVoted = GetLocalInt(oVoter,"Voted"); if(nVoted != 1) {   nVotedNo++; SetLocalInt(oVoter,"Voted",1); SetLocalInt(oStone,"VotedNo",nVotedNo); SpeakString(GetName(oVoter) + "'s vote has been registered."); DelayCommand(2.0f,DestroyObject(OBJECT_SELF)); } } } }