Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modify GameInformationPanel to optionally display as an invite #633

Open
wants to merge 7 commits into
base: develop
Choose a base branch
from
61 changes: 36 additions & 25 deletions DXMainClient/DXGUI/Multiplayer/CnCNet/CnCNetLobby.cs
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@ private bool HostedGameMatches(GenericHostedGame hg)

string textUpper = tbGameSearch?.Text?.ToUpperInvariant();

string translatedGameMode = string.IsNullOrEmpty(hg.GameMode)
string translatedGameMode = string.IsNullOrEmpty(hg.GameMode)
? "Unknown".L10N("Client:Main:Unknown")
: hg.GameMode.L10N($"INI:GameModes:{hg.GameMode}:UIName", notify: false);

Expand Down Expand Up @@ -782,7 +782,7 @@ private void SetLogOutButtonText()
private void BtnJoinGame_LeftClick(object sender, EventArgs e) => JoinSelectedGame();

private void LbGameList_DoubleLeftClick(object sender, EventArgs e) => JoinSelectedGame();

private void LbGameList_RightClick(object sender, EventArgs e)
{
lbGameList.SelectedIndex = lbGameList.HoveredIndex;
Expand Down Expand Up @@ -1270,47 +1270,58 @@ private void HandleGameInviteCommand(string sender, string argumentsString)
return;
}

var gameInviteChoiceBox = new ChoiceNotificationBox(WindowManager);

WindowManager.AddAndInitializeControl(gameInviteChoiceBox);

// show the invitation at top left; it will remain until it is acted upon or the target game is closed
gameInviteChoiceBox.Show(
"GAME INVITATION".L10N("Client:Main:GameInviteTitle"),
GetUserTexture(sender),
sender,
string.Format("Join {0}?".L10N("Client:Main:GameInviteText"), gameName),
"Yes".L10N("Client:Main:ButtonYes"), "No".L10N("Client:Main:ButtonNo"), 0);
GameInvitePanel panelGameInvite;
panelGameInvite = new GameInvitePanel(WindowManager, mapLoader);
panelGameInvite.Name = nameof(panelGameInvite);
panelGameInvite.BackgroundTexture = AssetLoader.LoadTexture("cncnetlobbypanelbg.png");
panelGameInvite.DrawMode = ControlDrawMode.UNIQUE_RENDER_TARGET;
panelGameInvite.Initialize();
panelGameInvite.Enable();
panelGameInvite.InputEnabled = true;
panelGameInvite.Alpha = 0.5f;
panelGameInvite.AlphaRate = 0.5f;

var hostedGame = lbGameList.HostedGames[lbGameList.HostedGames.FindIndex(hg => ((HostedCnCNetGame)hg).ChannelName == channelName)];
WindowManager.AddAndInitializeControl(panelGameInvite);
WindowManager.CenterControlOnScreen(panelGameInvite);
panelGameInvite.SetInfo(hostedGame);

// add the invitation to the index so we can remove it if the target game is closed
// also lets us silently ignore new invitations from the same person while this one is still outstanding
invitationIndex[invitationIdentity] =
new WeakReference(gameInviteChoiceBox);
new WeakReference(panelGameInvite);

gameInviteChoiceBox.AffirmativeClickedAction = delegate (ChoiceNotificationBox choiceBox)
panelGameInvite.AcceptInvite += () =>
{
// if we're currently in a game lobby, first leave that channel
if (isInGameRoom)
// Handle accept invite logic
// if we're currently in a game lobby that differs to the invite, first leave that channel
if (isInGameRoom && channelName != gameOfLastJoinAttempt.ChannelName)
{
gameLobby.LeaveGameLobby();
}

// JoinGameByIndex does bounds checking so we're safe to pass -1 if the game doesn't exist
if (!JoinGameByIndex(lbGameList.HostedGames.FindIndex(hg => ((HostedCnCNetGame)hg).ChannelName == channelName), password))
//if we're in a game room already, it will be the one we're invited to, so don't do anything.
if (!isInGameRoom)
{
XNAMessageBox.Show(WindowManager,
"Failed to join".L10N("Client:Main:JoinFailedTitle"),
string.Format("Unable to join {0}'s game. The game may be locked or closed.".L10N("Client:Main:JoinFailedText"), sender));
if (!JoinGameByIndex(lbGameList.HostedGames.FindIndex(hg => ((HostedCnCNetGame)hg).ChannelName == channelName), password))
{
XNAMessageBox.Show(WindowManager,
"Failed to join".L10N("Client:Main:JoinFailedTitle"),
string.Format("Unable to join {0}'s game. The game may be locked, closed, or on a different version.".L10N("Client:Main:JoinFailedText"), sender));
}
}

// clean up the index as this invitation no longer exists
invitationIndex.Remove(invitationIdentity);
WindowManager.RemoveControl(panelGameInvite);
};

gameInviteChoiceBox.NegativeClickedAction = delegate (ChoiceNotificationBox choiceBox)
panelGameInvite.DeclineInvite += () =>
{
// clean up the index as this invitation no longer exists
// Handle decline invite logic
invitationIndex.Remove(invitationIdentity);
WindowManager.RemoveControl(panelGameInvite);
};

sndGameInviteReceived.Play();
Expand Down Expand Up @@ -1358,7 +1369,7 @@ private void DdCurrentChannel_SelectedIndexChanged(object sender, EventArgs e)
currentChatChannel = (Channel)ddCurrentChannel.SelectedItem?.Tag;
if (currentChatChannel == null)
throw new Exception("Current selected chat channel is null. This should not happen.");

currentChatChannel.UserAdded += RefreshPlayerList;
currentChatChannel.UserLeft += RefreshPlayerList;
currentChatChannel.UserQuitIRC += RefreshPlayerList;
Expand Down Expand Up @@ -1694,7 +1705,7 @@ private void DismissInvitation(UserChannelPair invitationIdentity)
{
if (invitationIndex.ContainsKey(invitationIdentity))
{
var invitationNotification = invitationIndex[invitationIdentity].Target as ChoiceNotificationBox;
var invitationNotification = invitationIndex[invitationIdentity].Target as GameInvitePanel;

if (invitationNotification != null)
{
Expand Down
113 changes: 113 additions & 0 deletions DXMainClient/DXGUI/Multiplayer/GameInvitePanel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
using System;
using System.Diagnostics;
using System.Windows.Forms;

using ClientCore;
using ClientCore.Extensions;

using ClientGUI;

using DTAClient.Domain.Multiplayer;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

using Rampastring.XNAUI;
using Rampastring.XNAUI.XNAControls;

namespace DTAClient.DXGUI.Multiplayer
{
/// <summary>
/// A UI panel that displays information about a hosted CnCNet or LAN game.
/// </summary>
public class GameInvitePanel : XNAPanel
{
public GameInvitePanel(WindowManager windowManager, MapLoader mapLoader)
: base(windowManager)
{
this.mapLoader = mapLoader;
DrawMode = ControlDrawMode.UNIQUE_RENDER_TARGET;
}

private MapLoader mapLoader;
11EJDE11 marked this conversation as resolved.
Show resolved Hide resolved

private GenericHostedGame game = null;

private const int buttonWidth = 75;
private const int buttonHeight = 30;
private const int padding = 10;
11EJDE11 marked this conversation as resolved.
Show resolved Hide resolved

private XNALabel lblInviteHeading;
private XNAClientButton btnInviteAccept;
private XNAClientButton btnInviteDecline;
private GameInformationPanel panelGameInformation;

public event Action AcceptInvite;
public event Action DeclineInvite;

public override void Initialize()
{
panelGameInformation = new GameInformationPanel(WindowManager, mapLoader);
panelGameInformation.Name = nameof(panelGameInformation);
panelGameInformation.BackgroundTexture = AssetLoader.LoadTexture("cncnetlobbypanelbg.png");
panelGameInformation.DrawMode = ControlDrawMode.UNIQUE_RENDER_TARGET;
panelGameInformation.Initialize();
panelGameInformation.ClearInfo();
panelGameInformation.Disable();
panelGameInformation.InputEnabled = false;
panelGameInformation.Alpha = 0.5f;
panelGameInformation.AlphaRate = 0.5f;
AddChild(panelGameInformation);

lblInviteHeading = new XNALabel(WindowManager);
lblInviteHeading.FontIndex = 1;
lblInviteHeading.Text = "INVITATION TO JOIN GAME".L10N("Client:Main:InviteHeading");
lblInviteHeading.X = (panelGameInformation.Width / 2) - (lblInviteHeading.Width/2);
lblInviteHeading.Y = ((lblInviteHeading.Height + padding) / 2) - (lblInviteHeading.Height/2);

ClientRectangle = new Rectangle(0, 0, panelGameInformation.Width, padding + lblInviteHeading.Height + panelGameInformation.Height + padding + buttonHeight + padding);
11EJDE11 marked this conversation as resolved.
Show resolved Hide resolved
BackgroundTexture = AssetLoader.CreateTexture(new Color(0, 0, 0, 255), 1, 1);
PanelBackgroundDrawMode = PanelBackgroundImageDrawMode.STRETCHED;

AddChild(lblInviteHeading);
lblInviteHeading.Visible = true;
panelGameInformation.Y = lblInviteHeading.Height + padding;

btnInviteAccept = new XNAClientButton(WindowManager);
btnInviteAccept.Text = "Accept".L10N("Client:Main:InviteAccept");
btnInviteAccept.ClientRectangle = new Rectangle(ClientRectangle.Width / 2 - buttonWidth - (padding / 2), panelGameInformation.Y + panelGameInformation.Height + padding, buttonWidth, buttonHeight);
btnInviteAccept.LeftClick += (s, e) => AcceptInvite?.Invoke();
btnInviteAccept.Visible = true;
btnInviteAccept.Name = "btnInviteAccept";
AddChild(btnInviteAccept);

btnInviteDecline = new XNAClientButton(WindowManager);
btnInviteDecline.Text = "Decline".L10N("Client:Main:InviteDecline");
btnInviteDecline.ClientRectangle = new Rectangle(ClientRectangle.Width / 2 + (padding / 2), btnInviteAccept.Y, buttonWidth, buttonHeight);
btnInviteDecline.LeftClick += (s, e) => DeclineInvite?.Invoke();
btnInviteDecline.Visible = true;
btnInviteDecline.Name = "btnInviteDecline";
11EJDE11 marked this conversation as resolved.
Show resolved Hide resolved
AddChild(btnInviteDecline);
base.Initialize();
}

public void SetInfo(GenericHostedGame game)
{

this.game = game;
11EJDE11 marked this conversation as resolved.
Show resolved Hide resolved

panelGameInformation.SetInfo(game);
panelGameInformation.Enable();
}

public override void Draw(GameTime gameTime)
{
if (Alpha > 0.0f)
{
base.Draw(gameTime);

DrawChildren(gameTime);
}
}
}
}