diff --git a/OpenRA.Mods.RA/Widgets/Logic/DiplomacyLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/DiplomacyLogic.cs index b206383a3c..8cde095269 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/DiplomacyLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/DiplomacyLogic.cs @@ -13,118 +13,61 @@ using System.Collections.Generic; using System.Drawing; using System.Linq; using OpenRA.Traits; +using OpenRA.Network; using OpenRA.Widgets; namespace OpenRA.Mods.RA.Widgets.Logic { public class DiplomacyLogic { - static List controls = new List(); - - int validPlayers = 0; readonly World world; + ScrollPanelWidget diplomacyPanel; + [ObjectCreator.UseCtor] - public DiplomacyLogic(World world) + public DiplomacyLogic(Widget widget, Action onExit, World world) { this.world = world; - var root = Ui.Root.Get("INGAME_ROOT"); - var diplomacyBG = root.Get("DIPLOMACY_BG"); - var diplomacy = root.Get("INGAME_DIPLOMACY_BUTTON"); - diplomacy.OnClick = () => - { - diplomacyBG.Visible = !diplomacyBG.Visible; - if (diplomacyBG.IsVisible()) - LayoutDialog(diplomacyBG); - }; + diplomacyPanel = widget.Get("DIPLOMACY_PANEL"); - validPlayers = world.Players.Where(a => a != world.LocalPlayer && !a.NonCombatant).Count(); - diplomacy.IsVisible = () => (validPlayers > 0); - - diplomacyBG.Get("CLOSE_DIPLOMACY").OnClick = () => { diplomacyBG.Visible = false; }; + LayoutPlayers(); } - // This is shit - void LayoutDialog(Widget bg) + void LayoutPlayers() { - foreach (var c in controls) - bg.RemoveChild(c); - controls.Clear(); - - var y = 50; - var margin = 20; - var labelWidth = (bg.Bounds.Width - 3 * margin) / 3; - - var ts = new LabelWidget + var teamTemplate = diplomacyPanel.Get("TEAM_TEMPLATE"); + var players = world.Players.Where(p => p != world.LocalPlayer && !p.NonCombatant); + var teams = players.GroupBy(p => (world.LobbyInfo.ClientWithIndex(p.ClientIndex) ?? new Session.Client()).Team).OrderBy(g => g.Key); + foreach (var t in teams) { - Font = "Bold", - Bounds = new Rectangle(margin + labelWidth + 10, y, labelWidth, 25), - Text = "Their Stance", - Align = TextAlign.Left, - }; - - bg.AddChild(ts); - controls.Add(ts); - - var ms = new LabelWidget - { - Font = "Bold", - Bounds = new Rectangle(margin + 2 * labelWidth + 20, y, labelWidth, 25), - Text = "My Stance", - Align = TextAlign.Left, - }; - - bg.AddChild(ms); - controls.Add(ms); - - y += 35; - - foreach (var p in world.Players.Where(a => a != world.LocalPlayer && !a.NonCombatant)) - { - var pp = p; - var label = new LabelWidget + var team = t; + var tt = ScrollItemWidget.Setup(teamTemplate, () => false, () => { }); + tt.IgnoreMouseOver = true; + tt.Get("TEAM").GetText = () => team.Key == 0 ? "No Team" : "Team " + team.Key; + diplomacyPanel.AddChild(tt); + foreach (var p in team) { - Bounds = new Rectangle(margin, y, labelWidth, 25), - Text = p.PlayerName, - Align = TextAlign.Left, - Font = "Bold", - Color = p.Color.RGB, - }; - - bg.AddChild(label); - controls.Add(label); - - var theirStance = new LabelWidget - { - Bounds = new Rectangle( margin + labelWidth + 10, y, labelWidth, 25), - Text = p.PlayerName, - Align = TextAlign.Left, - - GetText = () => pp.Stances[ world.LocalPlayer ].ToString(), - }; - - bg.AddChild(theirStance); - controls.Add(theirStance); - - var myStance = new DropDownButtonWidget - { - Bounds = new Rectangle( margin + 2 * labelWidth + 20, y, labelWidth, 25), - GetText = () => world.LocalPlayer.Stances[ pp ].ToString(), - }; - - if (!p.World.LobbyInfo.GlobalSettings.FragileAlliances) - myStance.Disabled = true; - - myStance.OnMouseDown = mi => ShowDropDown(pp, myStance); - - bg.AddChild(myStance); - controls.Add(myStance); - - y += 35; + var player = p; + diplomacyPanel.AddChild(DiplomaticStatus(player)); + } } } + ScrollItemWidget DiplomaticStatus(Player player) + { + var playerTemplate = diplomacyPanel.Get("PLAYER_TEMPLATE"); + var pt = ScrollItemWidget.Setup(playerTemplate, () => false, () => { }); + pt.IgnoreMouseOver = true; + LobbyUtils.AddPlayerFlagAndName(pt, player); + pt.Get("THEIR_STANCE").GetText = () => player.Stances[world.LocalPlayer].ToString(); + var myStance = pt.Get("MY_STANCE"); + myStance.GetText = () => world.LocalPlayer.Stances[player].ToString(); + myStance.IsDisabled = () => !world.LobbyInfo.GlobalSettings.FragileAlliances; + myStance.OnMouseDown = mi => ShowDropDown(player, myStance); + return pt; + } + void ShowDropDown(Player p, DropDownButtonWidget dropdown) { var stances = Enum.GetValues(); @@ -144,9 +87,9 @@ namespace OpenRA.Mods.RA.Widgets.Logic void SetStance(ButtonWidget bw, Player p, Stance ss) { if (!p.World.LobbyInfo.GlobalSettings.FragileAlliances) - return; // team changes are banned + return; // stance changes are banned - // NOTE(jsd): Abuse of the type system here with `CPos` + // HACK: Abuse of the type system here with `CPos` world.IssueOrder(new Order("SetStance", world.LocalPlayer.PlayerActor, false) { TargetLocation = new CPos((int)ss, 0), TargetString = p.InternalName }); diff --git a/OpenRA.Mods.RA/Widgets/Logic/IngameChromeLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/IngameChromeLogic.cs index e8a1743cea..c78c0b53ac 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/IngameChromeLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/IngameChromeLogic.cs @@ -83,6 +83,17 @@ namespace OpenRA.Mods.RA.Widgets.Logic { var playerWidgets = Game.LoadWidget(world, "PLAYER_WIDGETS", playerRoot, new WidgetArgs()); + Widget diplomacy = null; + diplomacy = Game.LoadWidget(world, "DIPLOMACY", playerWidgets, new WidgetArgs + { + { "onExit", () => diplomacy.Visible = false } + }); + var diplomacyButton = playerWidgets.Get("INGAME_DIPLOMACY_BUTTON"); + diplomacyButton.OnClick = () => diplomacy.Visible ^= true; + int validPlayers = 0; + validPlayers = world.Players.Where(a => a != world.LocalPlayer && !a.NonCombatant).Count(); + diplomacyButton.IsVisible = () => validPlayers > 0; + Widget cheats = null; cheats = Game.LoadWidget(world, "CHEATS_PANEL", playerWidgets, new WidgetArgs { diff --git a/OpenRA.Mods.RA/Widgets/Logic/LobbyUtils.cs b/OpenRA.Mods.RA/Widgets/Logic/LobbyUtils.cs index d87e1a327e..b348311e17 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/LobbyUtils.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/LobbyUtils.cs @@ -348,5 +348,16 @@ namespace OpenRA.Mods.RA.Widgets.Logic { parent.Get("STATUS_IMAGE").IsVisible = () => c.IsReady || c.Bot != null; } + + public static void AddPlayerFlagAndName(ScrollItemWidget template, Player player) + { + var flag = template.Get("FLAG"); + flag.GetImageName = () => player.Country.Race; + flag.GetImageCollection = () => "flags"; + + var playerName = template.Get("PLAYER"); + playerName.GetText = () => player.PlayerName + (player.WinState == WinState.Undefined ? "" : " (" + player.WinState + ")"); + playerName.GetColor = () => player.Color.RGB; + } } } diff --git a/OpenRA.Mods.RA/Widgets/Logic/ObserverStatsLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/ObserverStatsLogic.cs index 4b03b0818a..57fa13c1a1 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/ObserverStatsLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/ObserverStatsLogic.cs @@ -170,7 +170,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic var team = t; var tt = ScrollItemWidget.Setup(teamTemplate, () => false, () => { }); tt.IgnoreMouseOver = true; - tt.Get("TEAM").GetText = () => team.Key == 0 ? "No team" : "Team " + team.Key; + tt.Get("TEAM").GetText = () => team.Key == 0 ? "No Team" : "Team " + team.Key; playerStatsPanel.AddChild(tt); foreach (var p in team) { @@ -185,7 +185,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic combatStatsHeaders.Visible = true; var template = SetupPlayerScrollItemWidget(combatPlayerTemplate, player); - AddPlayerFlagAndName(template, player); + LobbyUtils.AddPlayerFlagAndName(template, player); var stats = player.PlayerActor.TraitOrDefault(); if (stats == null) return template; @@ -205,7 +205,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic productionStatsHeaders.Visible = true; var template = SetupPlayerScrollItemWidget(productionPlayerTemplate, player); - AddPlayerFlagAndName(template, player); + LobbyUtils.AddPlayerFlagAndName(template, player); template.Get("PRODUCTION_ICONS").GetPlayer = () => player; template.Get("SUPPORT_POWER_ICONS").GetPlayer = () => player; @@ -218,7 +218,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic economyStatsHeaders.Visible = true; var template = SetupPlayerScrollItemWidget(economyPlayerTemplate, player); - AddPlayerFlagAndName(template, player); + LobbyUtils.AddPlayerFlagAndName(template, player); var res = player.PlayerActor.Trait(); var stats = player.PlayerActor.TraitOrDefault(); @@ -246,7 +246,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic basicStatsHeaders.Visible = true; var template = SetupPlayerScrollItemWidget(basicPlayerTemplate, player); - AddPlayerFlagAndName(template, player); + LobbyUtils.AddPlayerFlagAndName(template, player); var res = player.PlayerActor.Trait(); template.Get("CASH").GetText = () => "$" + (res.DisplayCash + res.DisplayOre); @@ -293,17 +293,6 @@ namespace OpenRA.Mods.RA.Widgets.Logic return "$" + (world.FrameNumber == 0 ? 0 : earned / (world.FrameNumber / 1500.0)).ToString("F2"); } - static void AddPlayerFlagAndName(ScrollItemWidget template, Player player) - { - var flag = template.Get("FLAG"); - flag.GetImageName = () => player.Country.Race; - flag.GetImageCollection = () => "flags"; - - var playerName = template.Get("PLAYER"); - playerName.GetText = () => player.PlayerName + (player.WinState == WinState.Undefined ? "" : " (" + player.WinState + ")"); - playerName.GetColor = () => player.Color.RGB; - } - static Color GetPowerColor(PowerState state) { if (state == PowerState.Critical) return Color.Red; diff --git a/mods/d2k/chrome/ingame.yaml b/mods/d2k/chrome/ingame.yaml index b9d113e351..96e19730c9 100644 --- a/mods/d2k/chrome/ingame.yaml +++ b/mods/d2k/chrome/ingame.yaml @@ -162,30 +162,6 @@ Container@PLAYER_WIDGETS: IconHeight: 48 Columns: 3 Rows: 4 - Background@DIPLOMACY_BG: - Logic:DiplomacyLogic - X:(WINDOW_RIGHT - WIDTH)/2 - Y:(WINDOW_BOTTOM - HEIGHT)/2 - Width:450 - Height:400 - Visible:false - Children: - Label@LABEL_TITLE: - X:(PARENT_RIGHT - WIDTH)/2 - Y:20 - Width:250 - Height:25 - Text:Diplomacy - Align:Center - Font:Bold - Button@CLOSE_DIPLOMACY: - X:(PARENT_RIGHT - WIDTH)/2 - Y:350 - Width:160 - Height:25 - Text:Close - Font:Bold - Key:escape Container@OBSERVER_WIDGETS: Children: diff --git a/mods/d2k/mod.yaml b/mods/d2k/mod.yaml index 161d48223c..985f66aa4d 100644 --- a/mods/d2k/mod.yaml +++ b/mods/d2k/mod.yaml @@ -51,6 +51,7 @@ ChromeLayout: mods/d2k/chrome/gameinit.yaml mods/d2k/chrome/ingame.yaml mods/ra/chrome/ingame-chat.yaml + mods/ra/chrome/ingame-diplomacy.yaml mods/ra/chrome/ingame-fmvplayer.yaml mods/ra/chrome/ingame-menu.yaml mods/ra/chrome/ingame-observerstats.yaml diff --git a/mods/ra/chrome/ingame-diplomacy.yaml b/mods/ra/chrome/ingame-diplomacy.yaml new file mode 100644 index 0000000000..421dbe4bde --- /dev/null +++ b/mods/ra/chrome/ingame-diplomacy.yaml @@ -0,0 +1,83 @@ +Background@DIPLOMACY: + Logic:DiplomacyLogic + X:25 + Y:50 + Width:490 + Height:300 + Visible:false + Children: + Label@LABEL_TITLE: + X:(PARENT_RIGHT - WIDTH)/2 + Y:17 + Width:250 + Height:20 + Text:Diplomacy + Align:Center + Font:Bold + Container@DIPLOMACY_HEADERS: + X:20 + Y:40 + Width:PARENT_RIGHT-40 + Height:PARENT_BOTTOM + Children: + Label@PLAYER_HEADER: + X:20 + Width:160 + Height:25 + Font:Bold + Text:Player + Label@THEIR_STANCE_HEADER: + X:210 + Width:80 + Height:25 + Font:Bold + Text:Their Stance + Align:Center + Label@MY_STANCE_HEADER: + X:307 + Width:100 + Height:25 + Font:Bold + Text:My Stance + Align:Center + ScrollPanel@DIPLOMACY_PANEL: + X:20 + Y:67 + Width:PARENT_RIGHT-40 + Height:PARENT_BOTTOM-87 + ItemSpacing:5 + Children: + ScrollItem@TEAM_TEMPLATE: + Width:PARENT_RIGHT + Height:25 + Children: + Label@TEAM: + X:10 + Width:PARENT_RIGHT + Height:PARENT_BOTTOM + Font:Bold + ScrollItem@PLAYER_TEMPLATE: + Width:PARENT_RIGHT-35 + Height:25 + Children: + Image@FLAG: + X:20 + Y:5 + Width:35 + Height:PARENT_BOTTOM-5 + ImageName:random + ImageCollection:flags + Label@PLAYER: + X:55 + Width:160 + Height:PARENT_BOTTOM + Font:Bold + Label@THEIR_STANCE: + X:210 + Width:80 + Height:PARENT_BOTTOM + Align:Center + DropDownButton@MY_STANCE: + X:307 + Width:100 + Height:PARENT_BOTTOM \ No newline at end of file diff --git a/mods/ra/chrome/ingame.yaml b/mods/ra/chrome/ingame.yaml index 450626e20a..afc3e46fa9 100644 --- a/mods/ra/chrome/ingame.yaml +++ b/mods/ra/chrome/ingame.yaml @@ -158,30 +158,6 @@ Container@PLAYER_WIDGETS: ReadyText: READY HoldText: ON HOLD RequiresText: Requires - Background@DIPLOMACY_BG: - Logic:DiplomacyLogic - X:(WINDOW_RIGHT - WIDTH)/2 - Y:(WINDOW_BOTTOM - HEIGHT)/2 - Width:450 - Height:400 - Visible:false - Children: - Label@LABEL_TITLE: - X:(PARENT_RIGHT - WIDTH)/2 - Y:20 - Width:250 - Height:25 - Text:Diplomacy - Align:Center - Font:Bold - Button@CLOSE_DIPLOMACY: - X:(PARENT_RIGHT - WIDTH)/2 - Y:350 - Width:160 - Height:25 - Text:Close - Font:Bold - Key:escape Container@OBSERVER_WIDGETS: Children: diff --git a/mods/ra/chrome/lobby-dialogs.yaml b/mods/ra/chrome/lobby-dialogs.yaml index 633f4d6c5b..e129f5157f 100644 --- a/mods/ra/chrome/lobby-dialogs.yaml +++ b/mods/ra/chrome/lobby-dialogs.yaml @@ -81,27 +81,27 @@ Background@LOBBY_OPTIONS_BIN: Height:20 Text:Fog of War Checkbox@CRATES_CHECKBOX: - X:155 + X:125 Width:230 Height:20 Text:Crates Appear Checkbox@ALLYBUILDRADIUS_CHECKBOX: - X:155 + X:125 Y:40 Width:230 Height:20 Text:Build off Ally ConYards Checkbox@ALLOWCHEATS_CHECKBOX: - X:350 + X:320 Width:230 Height:20 Text:Debug Menu Checkbox@FRAGILEALLIANCES_CHECKBOX: - X:350 + X:320 Y:40 Width:220 Height:20 - Text:Team Changes + Text:Diplomacy Changes Label@STARTINGCASH_DESC: Y:87 Width:80 diff --git a/mods/ra/mod.yaml b/mods/ra/mod.yaml index dc6175d4e8..531c12857f 100644 --- a/mods/ra/mod.yaml +++ b/mods/ra/mod.yaml @@ -62,6 +62,7 @@ ChromeLayout: mods/ra/chrome/gameinit.yaml mods/ra/chrome/ingame.yaml mods/ra/chrome/ingame-chat.yaml + mods/ra/chrome/ingame-diplomacy.yaml mods/ra/chrome/ingame-fmvplayer.yaml mods/ra/chrome/ingame-menu.yaml mods/ra/chrome/ingame-objectives.yaml diff --git a/mods/ts/mod.yaml b/mods/ts/mod.yaml index 9c893483c1..3f07d212d5 100644 --- a/mods/ts/mod.yaml +++ b/mods/ts/mod.yaml @@ -92,6 +92,7 @@ ChromeLayout: mods/ra/chrome/gameinit.yaml mods/ra/chrome/ingame.yaml mods/ra/chrome/ingame-chat.yaml + mods/ra/chrome/ingame-diplomacy.yaml mods/ra/chrome/ingame-fmvplayer.yaml mods/ra/chrome/ingame-menu.yaml mods/ra/chrome/ingame-objectives.yaml