Skip to content

Commit

Permalink
Use notification popups for voting.
Browse files Browse the repository at this point in the history
Removes some complexity and hacks from the previous iteration.
  • Loading branch information
KJeff01 committed Mar 27, 2020
1 parent 6b869f9 commit 4a94047
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 58 deletions.
1 change: 1 addition & 0 deletions lib/netplay/netplay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3716,6 +3716,7 @@ const char *messageTypeToString(unsigned messageType_)
case NET_FILE_PAYLOAD: return "NET_FILE_PAYLOAD";
case NET_DEBUG_SYNC: return "NET_DEBUG_SYNC";
case NET_VOTE: return "NET_VOTE";
case NET_VOTE_REQUEST: return "NET_VOTE_REQUEST";
case NET_MAX_TYPE: return "NET_MAX_TYPE";

// Game-state-related messages, must be processed by all clients at the same game time.
Expand Down
3 changes: 2 additions & 1 deletion lib/netplay/netplay.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ enum MESSAGE_TYPES
NET_FILE_CANCELLED, ///< Player cancelled a file request
NET_FILE_PAYLOAD, ///< sending file to the player that needs it
NET_DEBUG_SYNC, ///< Synch error messages, so people don't have to use pastebin.
NET_VOTE, ///< vote request
NET_VOTE, ///< player vote
NET_VOTE_REQUEST, ///< Setup a vote popup
NET_MAX_TYPE, ///< Maximum+1 valid NET_ type, *MUST* be last.

// Game-state-related messages, must be processed by all clients at the same game time.
Expand Down
2 changes: 0 additions & 2 deletions src/frontend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -633,14 +633,12 @@ bool runMultiPlayerMenu()
ingame.bHostSetup = true;
bMultiPlayer = true;
bMultiMessages = true;
resetVoteData();
NETinit(true);
NETdiscoverUPnPDevices();
game.type = SKIRMISH; // needed?
changeTitleUI(std::make_shared<WzMultiOptionTitleUI>(wzTitleUICurrent));
break;
case FRONTEND_JOIN:
resetVoteData();
NETinit(true);
ingame.bHostSetup = false;
if (getLobbyError() != ERROR_INVALID)
Expand Down
121 changes: 73 additions & 48 deletions src/multiint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@
#include "modding.h"
#include "qtscript.h"
#include "random.h"
#include "notifications.h"

#include "multiplay.h"
#include "multiint.h"
Expand All @@ -113,6 +114,7 @@
#include <algorithm>

#define MAP_PREVIEW_DISPLAY_TIME 2500 // number of milliseconds to show map in preview
#define VOTE_TAG "voting"

// ////////////////////////////////////////////////////////////////////////////
// tertile dependent colors for map preview
Expand Down Expand Up @@ -159,8 +161,6 @@ static int difficultyChooserUp = -1;
static int positionChooserUp = -1;
static UDWORD hideTime = 0;
static uint8_t playerVotes[MAX_PLAYERS];
static uint8_t currentVote = 0;
static bool votedOnJoin = false;
LOBBY_ERROR_TYPES LobbyError = ERROR_NOERROR;
/// end of globals.
// ////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -1120,26 +1120,14 @@ WzString formatGameName(WzString name)

void resetVoteData()
{
votedOnJoin = false;
currentVote = 0;
for (unsigned int i = 0; i < MAX_PLAYERS; ++i)
{
playerVotes[i] = 0;
}
}

static void sendVoteData(bool cancelEvent)
static void sendVoteData(uint8_t currentVote)
{
if (cancelEvent)
{
resetVoteData();
((MultichoiceWidget *)widgGetFromID(psWScreen, MULTIOP_VOTE))->choose(0);
}
else
{
currentVote = ((MultichoiceWidget *)widgGetFromID(psWScreen, MULTIOP_VOTE))->currentValue();
}

NETbeginEncode(NETbroadcastQueue(), NET_VOTE);
NETuint32_t(&selectedPlayer);
NETuint8_t(&currentVote);
Expand Down Expand Up @@ -1205,6 +1193,62 @@ static bool recvVote(NETQUEUE queue)
return true;
}

// Show a vote popup to allow changing maps or using the randomization feature.
static void setupVoteChoice()
{
//This shouldn't happen...
if (NetPlay.isHost)
{
ASSERT(false, "Host tried to send vote data to themself");
return;
}

if (!hasNotificationsWithTag(VOTE_TAG))
{
WZ_Notification notification;
notification.duration = 0;
notification.contentTitle = "Vote";
notification.contentText = "Allow host to change map or randomize?";
notification.action = WZ_Notification_Action("Allow", [](const WZ_Notification&) {
uint8_t vote = 1;
sendVoteData(vote);
});
notification.tag = VOTE_TAG;

addNotification(notification, WZ_Notification_Trigger(GAME_TICKS_PER_SEC * 1));
}
}

static bool canChangeMapOrRandomize()
{
if (!NetPlay.isHost || !bHosted) // Only host should act, and only if the game hasn't started yet.
{
ASSERT(false, "Host only routine detected for client!");
return true;
}

uint8_t numHumans = NET_numHumanPlayers();
bool allowed = (static_cast<float>(getVoteTotal()) / static_cast<float>(numHumans)) > 0.5f;

resetVoteData(); //So the host can only do one change every vote session

if (numHumans == 1)
{
return true;
}

if (!allowed)
{
//setup a vote popup for the clients
NETbeginEncode(NETbroadcastQueue(), NET_VOTE_REQUEST);
NETend();

addConsoleMessage(_("Not enough votes to randomize or change the map."), DEFAULT_JUSTIFY, SYSTEM_MESSAGE);
}

return allowed;
}

// need to check for side effects.
static void addGameOptions()
{
Expand Down Expand Up @@ -1344,25 +1388,6 @@ static void addGameOptions()
hostButton->addButton(0, Image(FrontImages, IMAGE_HOST), Image(FrontImages, IMAGE_HOST_HI), _("Start Hosting Game"));
optionsList->addWidgetToLayout(hostButton);
}
else if (!challengeActive && !NetPlay.isHost)
{
MultichoiceWidget *voteChoice = new MultichoiceWidget(optionsList, currentVote);
voteChoice->id = MULTIOP_VOTE;
voteChoice->setLabel(_("Vote"));
voteChoice->addButton(MULTIOP_VOTE_NO, Image(FrontImages, IMAGE_CHECK_OFF), Image(FrontImages, IMAGE_CHECK_OFF_HI), _("No. Do not allow host to randomize or change map"));
voteChoice->addButton(MULTIOP_VOTE_YES, Image(FrontImages, IMAGE_CHECK_ON), Image(FrontImages, IMAGE_CHECK_ON_HI), _("Yes. Allow host to randomize or change map"));
voteChoice->enable(true);
optionsList->addWidgetToLayout(voteChoice);

//Big hack here
if (!votedOnJoin)
{
currentVote = 0;
((MultichoiceWidget *)widgGetFromID(psWScreen, MULTIOP_VOTE))->choose(0);
sendVoteData(false);
votedOnJoin = true;
}
}

// cancel
addMultiBut(psWScreen, MULTIOP_OPTIONS, CON_CANCEL,
Expand Down Expand Up @@ -2393,7 +2418,7 @@ static void disableMultiButs()
static void stopJoining(std::shared_ptr<WzTitleUI> parent)
{
reloadMPConfig(); // reload own settings
resetVoteData();
cancelOrDismissNotificationsWithTag(VOTE_TAG);

debug(LOG_NET, "player %u (Host is %s) stopping.", selectedPlayer, NetPlay.isHost ? "true" : "false");

Expand Down Expand Up @@ -2651,10 +2676,8 @@ static void randomizeLimit(const char *name)
/* Generate random options */
static void randomizeOptions()
{
uint8_t numHumans = NET_numHumanPlayers();
if (NetPlay.bComms && bHosted && numHumans > 1 && (static_cast<float>(getVoteTotal()) / static_cast<float>(numHumans)) <= 0.5f)
if (NetPlay.bComms && bHosted && !canChangeMapOrRandomize())
{
addConsoleMessage(_("Not enough votes to randomize or change the map."), DEFAULT_JUSTIFY, SYSTEM_MESSAGE);
return;
}

Expand Down Expand Up @@ -3034,20 +3057,14 @@ void WzMultiOptionTitleUI::processMultiopWidgets(UDWORD id)
widgSetString(psWScreen, MULTIOP_CHATEDIT, ""); // clear box
break;

case MULTIOP_VOTE:
if (!NetPlay.isHost)
{
sendVoteData(false);
}
break;

case CON_CANCEL:
pie_LoadBackDrop(SCREEN_RANDOMBDROP);
if (!challengeActive)
{
if (NetPlay.bComms && !NetPlay.isHost && !bHosted && !ingame.bHostSetup)
{
sendVoteData(true);
uint8_t vote = 0;
sendVoteData(vote); //remove a potential "allow" vote if we gracefully leave
}
NETGameLocked(false); // reset status on a cancel
stopJoining(parent);
Expand Down Expand Up @@ -3453,6 +3470,7 @@ void WzMultiOptionTitleUI::frontendMultiMessages(bool running)
break;
}
case NET_FIREUP: // campaign game started.. can fire the whole shebang up...
cancelOrDismissNotificationsWithTag(VOTE_TAG); // don't need vote notifications anymore
if (NET_HOST_ONLY != queue.index)
{
HandleBadParam("NET_FIREUP given incorrect params.", 255, queue.index);
Expand Down Expand Up @@ -3547,6 +3565,13 @@ void WzMultiOptionTitleUI::frontendMultiMessages(bool running)
}
break;

case NET_VOTE_REQUEST:
if (!NetPlay.isHost)
{
setupVoteChoice();
}
break;

default:
debug(LOG_ERROR, "Didn't handle %s message!", messageTypeToString(type));
break;
Expand Down Expand Up @@ -3661,9 +3686,8 @@ TITLECODE WzMultiOptionTitleUI::run()
addConsoleMessage(_("Cannot change to a map with too few slots for all players."), DEFAULT_JUSTIFY, SYSTEM_MESSAGE);
break;
}
if (numHumans > 1 && (static_cast<float>(getVoteTotal()) / static_cast<float>(NET_numHumanPlayers())) <= 0.5f)
if (!canChangeMapOrRandomize())
{
addConsoleMessage(_("Not enough votes to randomize or change the map."), DEFAULT_JUSTIFY, SYSTEM_MESSAGE);
break;
}
}
Expand Down Expand Up @@ -3768,6 +3792,7 @@ TITLECODE WzMultiOptionTitleUI::run()
}
if (!NetPlay.isHostAlive && !ingame.bHostSetup)
{
cancelOrDismissNotificationsWithTag(VOTE_TAG);
changeTitleUI(std::make_shared<WzMsgBoxTitleUI>(WzString(_("The host has quit.")), parent));
pie_LoadBackDrop(SCREEN_RANDOMBDROP);
}
Expand Down
4 changes: 0 additions & 4 deletions src/multiint.h
Original file line number Diff line number Diff line change
Expand Up @@ -313,10 +313,6 @@ void resetVoteData();
#define MULTIOP_DIFFICULTY_CHOOSE_START (MULTIOP_DIFFICULTY_INIT_END + 1)
#define MULTIOP_DIFFICULTY_CHOOSE_END (MULTIOP_DIFFICULTY_CHOOSE_START + MAX_PLAYERS)

#define MULTIOP_VOTE 148940
#define MULTIOP_VOTE_YES 1
#define MULTIOP_VOTE_NO 0


// ///////////////////////////////
// Many Button Variations..
Expand Down
3 changes: 0 additions & 3 deletions src/titleui/protocol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,19 +111,16 @@ TITLECODE WzProtocolTitleUI::run()
bMultiMessages = false;
break;
case CON_TYPESID_START+0: // Lobby button
resetVoteData();
if (getLobbyError() != ERROR_INVALID)
{
setLobbyError(ERROR_NOERROR);
}
changeTitleUI(std::make_shared<WzGameFindTitleUI>());
break;
case CON_TYPESID_START+1: // IP button
resetVoteData();
openIPDialog();
break;
case CON_OK:
resetVoteData();
sstrcpy(serverName, widgGetString(curScreen, CON_IP));
if (serverName[0] == '\0')
{
Expand Down

0 comments on commit 4a94047

Please sign in to comment.