Added a player action dropdown.
Adds options for: - handling kick - transferring admin - move to spectator
This commit is contained in:
@@ -37,6 +37,8 @@ namespace OpenRA.Mods.Common.Server
|
||||
{ "option", Option },
|
||||
{ "assignteams", AssignTeams },
|
||||
{ "kick", Kick },
|
||||
{ "make_admin", MakeAdmin },
|
||||
{ "make_spectator", MakeSpectator },
|
||||
{ "name", Name },
|
||||
{ "faction", Faction },
|
||||
{ "team", Team },
|
||||
@@ -601,6 +603,65 @@ namespace OpenRA.Mods.Common.Server
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool MakeAdmin(S server, Connection conn, Session.Client client, string s)
|
||||
{
|
||||
if (!client.IsAdmin)
|
||||
{
|
||||
server.SendOrderTo(conn, "Message", "Only admins can transfer admin to another player.");
|
||||
return true;
|
||||
}
|
||||
|
||||
int newAdminId;
|
||||
Exts.TryParseIntegerInvariant(s, out newAdminId);
|
||||
var newAdminConn = server.Conns.SingleOrDefault(c => server.GetClient(c) != null && server.GetClient(c).Index == newAdminId);
|
||||
|
||||
if (newAdminConn == null)
|
||||
{
|
||||
server.SendOrderTo(conn, "Message", "No-one in that slot.");
|
||||
return true;
|
||||
}
|
||||
|
||||
var newAdminClient = server.GetClient(newAdminConn);
|
||||
client.IsAdmin = false;
|
||||
newAdminClient.IsAdmin = true;
|
||||
server.SendMessage("{0} is now the admin.".F(newAdminClient.Name));
|
||||
Log.Write("server", "{0} is now the admin.".F(newAdminClient.Name));
|
||||
server.SyncLobbyClients();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool MakeSpectator(S server, Connection conn, Session.Client client, string s)
|
||||
{
|
||||
if (!client.IsAdmin)
|
||||
{
|
||||
server.SendOrderTo(conn, "Message", "Only the host can move players to spectators.");
|
||||
return true;
|
||||
}
|
||||
|
||||
int targetId;
|
||||
Exts.TryParseIntegerInvariant(s, out targetId);
|
||||
var targetConn = server.Conns.SingleOrDefault(c => server.GetClient(c) != null && server.GetClient(c).Index == targetId);
|
||||
|
||||
if (targetConn == null)
|
||||
{
|
||||
server.SendOrderTo(conn, "Message", "No-one in that slot.");
|
||||
return true;
|
||||
}
|
||||
|
||||
var targetClient = server.GetClient(targetConn);
|
||||
targetClient.Slot = null;
|
||||
targetClient.SpawnPoint = 0;
|
||||
targetClient.Team = 0;
|
||||
targetClient.Color = HSLColor.FromRGB(255, 255, 255);
|
||||
server.SendMessage("{0} moved {1} to spectators.".F(client.Name, targetClient.Name));
|
||||
Log.Write("server", "{0} moved {1} to spectators.".F(client.Name, targetClient.Name));
|
||||
server.SyncLobbyClients();
|
||||
CheckAutoStart(server);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool Name(S server, Connection conn, Session.Client client, string s)
|
||||
{
|
||||
var sanitizedName = Settings.SanitizedPlayerName(s);
|
||||
|
||||
@@ -594,18 +594,19 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
template = nonEditablePlayerTemplate.Clone();
|
||||
|
||||
LobbyUtils.SetupClientWidget(template, client, orderManager, client.Bot == null);
|
||||
LobbyUtils.SetupNameWidget(template, slot, client);
|
||||
LobbyUtils.SetupKickWidget(template, slot, client, orderManager, lobby,
|
||||
() => panel = PanelType.Kick, () => panel = PanelType.Players);
|
||||
LobbyUtils.SetupColorWidget(template, slot, client);
|
||||
LobbyUtils.SetupFactionWidget(template, slot, client, factions);
|
||||
|
||||
if (isHost)
|
||||
{
|
||||
LobbyUtils.SetupEditableTeamWidget(template, slot, client, orderManager, map);
|
||||
LobbyUtils.SetupEditableSpawnWidget(template, slot, client, orderManager, map);
|
||||
LobbyUtils.SetupPlayerActionWidget(template, slot, client, orderManager, lobby,
|
||||
() => panel = PanelType.Kick, () => panel = PanelType.Players);
|
||||
}
|
||||
else
|
||||
{
|
||||
LobbyUtils.SetupNameWidget(template, slot, client);
|
||||
LobbyUtils.SetupTeamWidget(template, slot, client);
|
||||
LobbyUtils.SetupSpawnWidget(template, slot, client);
|
||||
}
|
||||
@@ -650,9 +651,11 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
if (template == null || template.Id != nonEditableSpectatorTemplate.Id)
|
||||
template = nonEditableSpectatorTemplate.Clone();
|
||||
|
||||
LobbyUtils.SetupNameWidget(template, null, client);
|
||||
LobbyUtils.SetupKickWidget(template, null, client, orderManager, lobby,
|
||||
if (isHost)
|
||||
LobbyUtils.SetupPlayerActionWidget(template, null, client, orderManager, lobby,
|
||||
() => panel = PanelType.Kick, () => panel = PanelType.Players);
|
||||
else
|
||||
LobbyUtils.SetupNameWidget(template, null, client);
|
||||
|
||||
if (client.IsAdmin)
|
||||
LobbyUtils.SetupReadyWidget(template, null, client);
|
||||
@@ -708,13 +711,6 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
Ui.CloseWindow();
|
||||
onStart();
|
||||
}
|
||||
|
||||
class DropDownOption
|
||||
{
|
||||
public string Title;
|
||||
public Func<bool> IsSelected;
|
||||
public Action OnClick;
|
||||
}
|
||||
}
|
||||
|
||||
public class LobbyFaction
|
||||
@@ -724,4 +720,11 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
public string Description;
|
||||
public string Side;
|
||||
}
|
||||
|
||||
class DropDownOption
|
||||
{
|
||||
public string Title;
|
||||
public Func<bool> IsSelected = () => false;
|
||||
public Action OnClick;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,6 +73,60 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 167, options, setupItem);
|
||||
}
|
||||
|
||||
public static void ShowPlayerActionDropDown(DropDownButtonWidget dropdown, Session.Slot slot,
|
||||
Session.Client c, OrderManager orderManager, Widget lobby, Action before, Action after)
|
||||
{
|
||||
Action<bool> okPressed = tempBan => { orderManager.IssueOrder(Order.Command("kick {0} {1}".F(c.Index, tempBan))); after(); };
|
||||
var onClick = new Action(() =>
|
||||
{
|
||||
before();
|
||||
|
||||
Game.LoadWidget(null, "KICK_CLIENT_DIALOG", lobby.Get("TOP_PANELS_ROOT"), new WidgetArgs
|
||||
{
|
||||
{ "clientName", c.Name },
|
||||
{ "okPressed", okPressed },
|
||||
{ "cancelPressed", after }
|
||||
});
|
||||
});
|
||||
|
||||
var options = new List<DropDownOption>
|
||||
{
|
||||
new DropDownOption
|
||||
{
|
||||
Title = "Kick",
|
||||
OnClick = onClick
|
||||
},
|
||||
};
|
||||
|
||||
if (orderManager.LobbyInfo.GlobalSettings.Dedicated)
|
||||
{
|
||||
options.Add(new DropDownOption
|
||||
{
|
||||
Title = "Transfer Admin",
|
||||
OnClick = () => orderManager.IssueOrder(Order.Command("make_admin {0}".F(c.Index)))
|
||||
});
|
||||
}
|
||||
|
||||
if (!c.IsObserver && orderManager.LobbyInfo.GlobalSettings.AllowSpectators)
|
||||
{
|
||||
options.Add(new DropDownOption
|
||||
{
|
||||
Title = "Move to Spectator",
|
||||
OnClick = () => orderManager.IssueOrder(Order.Command("make_spectator {0}".F(c.Index)))
|
||||
});
|
||||
}
|
||||
|
||||
Func<DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (o, itemTemplate) =>
|
||||
{
|
||||
var item = ScrollItemWidget.Setup(itemTemplate, o.IsSelected, o.OnClick);
|
||||
var labelWidget = item.Get<LabelWidget>("LABEL");
|
||||
labelWidget.GetText = () => o.Title;
|
||||
return item;
|
||||
};
|
||||
|
||||
dropdown.ShowDropDown("PLAYERACTION_DROPDOWN_TEMPLATE", 167, options, setupItem);
|
||||
}
|
||||
|
||||
public static void ShowTeamDropDown(DropDownButtonWidget dropdown, Session.Client client,
|
||||
OrderManager orderManager, int teamCount)
|
||||
{
|
||||
@@ -316,6 +370,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
public static void SetupNameWidget(Widget parent, Session.Slot s, Session.Client c)
|
||||
{
|
||||
var name = parent.Get<LabelWidget>("NAME");
|
||||
name.IsVisible = () => true;
|
||||
var font = Game.Renderer.Fonts[name.Font];
|
||||
var label = WidgetUtils.TruncateText(c.Name, name.Bounds.Width, font);
|
||||
name.GetText = () => label;
|
||||
@@ -343,23 +398,16 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
HideChildWidget(parent, "SLOT_OPTIONS");
|
||||
}
|
||||
|
||||
public static void SetupKickWidget(Widget parent, Session.Slot s, Session.Client c, OrderManager orderManager, Widget lobby, Action before, Action after)
|
||||
public static void SetupPlayerActionWidget(Widget parent, Session.Slot s, Session.Client c, OrderManager orderManager, Widget lobby, Action before, Action after)
|
||||
{
|
||||
var button = parent.Get<ButtonWidget>("KICK");
|
||||
button.IsVisible = () => Game.IsHost && c.Index != orderManager.LocalClient.Index;
|
||||
button.IsDisabled = () => orderManager.LocalClient.IsReady;
|
||||
Action<bool> okPressed = tempBan => { orderManager.IssueOrder(Order.Command("kick {0} {1}".F(c.Index, tempBan))); after(); };
|
||||
button.OnClick = () =>
|
||||
{
|
||||
before();
|
||||
var slot = parent.Get<DropDownButtonWidget>("PLAYER_ACTION");
|
||||
slot.IsVisible = () => Game.IsHost && c.Index != orderManager.LocalClient.Index;
|
||||
slot.IsDisabled = () => orderManager.LocalClient.IsReady;
|
||||
slot.GetText = () => c != null ? c.Name : string.Empty;
|
||||
slot.OnMouseDown = _ => ShowPlayerActionDropDown(slot, s, c, orderManager, lobby, before, after);
|
||||
|
||||
Game.LoadWidget(null, "KICK_CLIENT_DIALOG", lobby.Get("TOP_PANELS_ROOT"), new WidgetArgs
|
||||
{
|
||||
{ "clientName", c.Name },
|
||||
{ "okPressed", okPressed },
|
||||
{ "cancelPressed", after }
|
||||
});
|
||||
};
|
||||
// Ensure Name selector (if present) is hidden
|
||||
HideChildWidget(parent, "NAME");
|
||||
}
|
||||
|
||||
public static void SetupKickSpectatorsWidget(Widget parent, OrderManager orderManager, Widget lobby, Action before, Action after, bool skirmishMode)
|
||||
@@ -578,4 +626,17 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
widget.IsVisible = () => false;
|
||||
}
|
||||
}
|
||||
|
||||
class ShowPlayerActionDropDownOption
|
||||
{
|
||||
public Action Click { get; set; }
|
||||
public string Title;
|
||||
public Func<bool> Selected = () => false;
|
||||
|
||||
public ShowPlayerActionDropDownOption(string title, Action click)
|
||||
{
|
||||
Click = click;
|
||||
Title = title;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,23 @@ ScrollPanel@LABEL_DROPDOWN_TEMPLATE:
|
||||
Width: PARENT_RIGHT - 20
|
||||
Height: 25
|
||||
|
||||
ScrollPanel@PLAYERACTION_DROPDOWN_TEMPLATE:
|
||||
Width: DROPDOWN_WIDTH
|
||||
Background: panel-black
|
||||
Children:
|
||||
ScrollItem@TEMPLATE:
|
||||
Width: PARENT_RIGHT - 27
|
||||
Height: 25
|
||||
X: 2
|
||||
Y: 0
|
||||
Visible: false
|
||||
Children:
|
||||
Label@LABEL:
|
||||
X: 10
|
||||
Width: PARENT_RIGHT - 20
|
||||
Height: 25
|
||||
Align: Left
|
||||
|
||||
ScrollPanel@FACTION_DROPDOWN_TEMPLATE:
|
||||
Width: DROPDOWN_WIDTH
|
||||
Background: panel-black
|
||||
|
||||
@@ -185,16 +185,13 @@ Container@LOBBY_PLAYER_BIN:
|
||||
Y: 0 - 1
|
||||
Width: 180
|
||||
Height: 25
|
||||
Button@KICK:
|
||||
X: 180
|
||||
Width: 25
|
||||
DropDownButton@PLAYER_ACTION:
|
||||
X: 15
|
||||
Width: 190
|
||||
Height: 25
|
||||
Children:
|
||||
Image:
|
||||
ImageCollection: lobby-bits
|
||||
ImageName: kick
|
||||
X: 7
|
||||
Y: 7
|
||||
Font: Regular
|
||||
Visible: false
|
||||
Align: Left
|
||||
ColorBlock@COLORBLOCK:
|
||||
X: 215
|
||||
Y: 6
|
||||
@@ -358,16 +355,13 @@ Container@LOBBY_PLAYER_BIN:
|
||||
Y: 0 - 1
|
||||
Width: 180
|
||||
Height: 25
|
||||
Button@KICK:
|
||||
X: 180
|
||||
Width: 25
|
||||
DropDownButton@PLAYER_ACTION:
|
||||
X: 15
|
||||
Width: 190
|
||||
Height: 25
|
||||
Children:
|
||||
Image:
|
||||
ImageCollection: lobby-bits
|
||||
ImageName: kick
|
||||
X: 7
|
||||
Y: 7
|
||||
Font: Regular
|
||||
Visible: false
|
||||
Align: Left
|
||||
Label@SPECTATOR:
|
||||
X: 210
|
||||
Width: 341
|
||||
|
||||
@@ -26,6 +26,22 @@ ScrollPanel@LABEL_DROPDOWN_TEMPLATE:
|
||||
Width: PARENT_RIGHT - 20
|
||||
Height: 25
|
||||
|
||||
ScrollPanel@PLAYERACTION_DROPDOWN_TEMPLATE:
|
||||
Width: DROPDOWN_WIDTH
|
||||
Children:
|
||||
ScrollItem@TEMPLATE:
|
||||
Width: PARENT_RIGHT - 27
|
||||
Height: 25
|
||||
X: 2
|
||||
Y: 0
|
||||
Visible: false
|
||||
Children:
|
||||
Label@LABEL:
|
||||
X: 10
|
||||
Width: PARENT_RIGHT - 20
|
||||
Height: 25
|
||||
Align: Left
|
||||
|
||||
ScrollPanel@TEAM_DROPDOWN_TEMPLATE:
|
||||
Width: DROPDOWN_WIDTH
|
||||
Children:
|
||||
|
||||
@@ -181,13 +181,13 @@ Container@LOBBY_PLAYER_BIN:
|
||||
Width: 165
|
||||
Height: 25
|
||||
Text: Name
|
||||
Button@KICK:
|
||||
X: 155
|
||||
Y: 2
|
||||
Width: 25
|
||||
Height: 23
|
||||
Text: X
|
||||
Font: Bold
|
||||
DropDownButton@PLAYER_ACTION:
|
||||
X: 15
|
||||
Width: 165
|
||||
Height: 25
|
||||
Font: Regular
|
||||
Visible: false
|
||||
Align: Left
|
||||
ColorBlock@COLORBLOCK:
|
||||
X: 195
|
||||
Y: 6
|
||||
@@ -347,13 +347,13 @@ Container@LOBBY_PLAYER_BIN:
|
||||
X: 20
|
||||
Y: 0 - 1
|
||||
Text: Name
|
||||
Button@KICK:
|
||||
X: 155
|
||||
Y: 2
|
||||
Width: 25
|
||||
Height: 23
|
||||
Text: X
|
||||
Font: Bold
|
||||
DropDownButton@PLAYER_ACTION:
|
||||
X: 15
|
||||
Width: 165
|
||||
Height: 25
|
||||
Font: Regular
|
||||
Visible: false
|
||||
Align: Left
|
||||
Label@SPECTATOR:
|
||||
X: 190
|
||||
Width: 326
|
||||
|
||||
Reference in New Issue
Block a user