public ObserverShroudSelectorLogic(Widget widget, ModData modData, World world, WorldRenderer worldRenderer, Dictionary <string, MiniYaml> logicArgs) { this.world = world; if (logicArgs.TryGetValue("CombinedViewKey", out var yaml)) { combinedViewKey = modData.Hotkeys[yaml.Value]; } if (logicArgs.TryGetValue("WorldViewKey", out yaml)) { worldViewKey = modData.Hotkeys[yaml.Value]; } limitViews = world.Map.Visibility.HasFlag(MapVisibility.MissionSelector); var groups = new Dictionary <string, IEnumerable <CameraOption> >(); combined = new CameraOption(this, world, "All Players", world.Players.First(p => p.InternalName == "Everyone")); disableShroud = new CameraOption(this, world, "Disable Shroud", null); if (!limitViews) { groups.Add("Other", new List <CameraOption>() { combined, disableShroud }); } teams = world.Players.Where(p => !p.NonCombatant && p.Playable) .Select(p => new CameraOption(this, p)) .GroupBy(p => (world.LobbyInfo.ClientWithIndex(p.Player.ClientIndex) ?? new Session.Client()).Team) .OrderBy(g => g.Key); var noTeams = teams.Count() == 1; foreach (var t in teams) { var label = noTeams ? "Players" : t.Key == 0 ? "No Team" : "Team {0}".F(t.Key); groups.Add(label, t); } var shroudSelector = widget.Get <DropDownButtonWidget>("SHROUD_SELECTOR"); shroudSelector.OnMouseDown = _ => { Func <CameraOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) => { var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick); var showFlag = option.Faction != null; var label = item.Get <LabelWidget>("LABEL"); label.IsVisible = () => showFlag; label.GetColor = () => option.Color; if (showFlag) { WidgetUtils.BindPlayerNameAndStatus(label, option.Player); } else { label.GetText = () => option.Label; } var flag = item.Get <ImageWidget>("FLAG"); flag.IsVisible = () => showFlag; flag.GetImageCollection = () => "flags"; flag.GetImageName = () => option.Faction; var labelAlt = item.Get <LabelWidget>("NOFLAG_LABEL"); labelAlt.IsVisible = () => !showFlag; labelAlt.GetText = () => option.Label; labelAlt.GetColor = () => option.Color; return(item); }; shroudSelector.ShowDropDown("SPECTATOR_DROPDOWN_TEMPLATE", 400, groups, setupItem); }; shroudLabel = shroudSelector.Get <LabelWidget>("LABEL"); shroudLabel.IsVisible = () => selected.Faction != null; shroudLabel.GetText = () => selected.Label; shroudLabel.GetColor = () => selected.Color; var shroudFlag = shroudSelector.Get <ImageWidget>("FLAG"); shroudFlag.IsVisible = () => selected.Faction != null; shroudFlag.GetImageCollection = () => "flags"; shroudFlag.GetImageName = () => selected.Faction; var shroudLabelAlt = shroudSelector.Get <LabelWidget>("NOFLAG_LABEL"); shroudLabelAlt.IsVisible = () => selected.Faction == null; shroudLabelAlt.GetText = () => selected.Label; shroudLabelAlt.GetColor = () => selected.Color; var keyhandler = shroudSelector.Get <LogicKeyListenerWidget>("SHROUD_KEYHANDLER"); keyhandler.AddHandler(HandleKeyPress); selected = limitViews ? groups.First().Value.First() : world.WorldActor.Owner.Shroud.ExploreMapEnabled ? combined : disableShroud; selected.OnClick(); // Enable zooming out to fractional zoom levels worldRenderer.Viewport.UnlockMinimumZoom(0.5f); }
public ObserverStatsLogic(World world, ModData modData, WorldRenderer worldRenderer, Widget widget, Dictionary <string, MiniYaml> logicArgs) { this.world = world; this.worldRenderer = worldRenderer; MiniYaml yaml; string[] keyNames = Enum.GetNames(typeof(ObserverStatsPanel)); var statsHotkeys = new HotkeyReference[keyNames.Length]; for (var i = 0; i < keyNames.Length; i++) { statsHotkeys[i] = logicArgs.TryGetValue("Statistics" + keyNames[i] + "Key", out yaml) ? modData.Hotkeys[yaml.Value] : new HotkeyReference(); } players = world.Players.Where(p => !p.NonCombatant); teams = players.GroupBy(p => (world.LobbyInfo.ClientWithIndex(p.ClientIndex) ?? new Session.Client()).Team).OrderBy(g => g.Key); hasTeams = !(teams.Count() == 1 && teams.First().Key == 0); basicStatsHeaders = widget.Get <ContainerWidget>("BASIC_STATS_HEADERS"); economyStatsHeaders = widget.Get <ContainerWidget>("ECONOMY_STATS_HEADERS"); productionStatsHeaders = widget.Get <ContainerWidget>("PRODUCTION_STATS_HEADERS"); supportPowerStatsHeaders = widget.Get <ContainerWidget>("SUPPORT_POWERS_HEADERS"); armyHeaders = widget.Get <ContainerWidget>("ARMY_HEADERS"); combatStatsHeaders = widget.Get <ContainerWidget>("COMBAT_STATS_HEADERS"); playerStatsPanel = widget.Get <ScrollPanelWidget>("PLAYER_STATS_PANEL"); playerStatsPanel.Layout = new GridLayout(playerStatsPanel); playerStatsPanel.IgnoreMouseOver = true; if (ShowScrollBar) { playerStatsPanel.ScrollBar = ScrollBar.Left; AdjustHeader(basicStatsHeaders); AdjustHeader(economyStatsHeaders); AdjustHeader(productionStatsHeaders); AdjustHeader(supportPowerStatsHeaders); AdjustHeader(combatStatsHeaders); AdjustHeader(armyHeaders); } basicPlayerTemplate = playerStatsPanel.Get <ScrollItemWidget>("BASIC_PLAYER_TEMPLATE"); economyPlayerTemplate = playerStatsPanel.Get <ScrollItemWidget>("ECONOMY_PLAYER_TEMPLATE"); productionPlayerTemplate = playerStatsPanel.Get <ScrollItemWidget>("PRODUCTION_PLAYER_TEMPLATE"); supportPowersPlayerTemplate = playerStatsPanel.Get <ScrollItemWidget>("SUPPORT_POWERS_PLAYER_TEMPLATE"); armyPlayerTemplate = playerStatsPanel.Get <ScrollItemWidget>("ARMY_PLAYER_TEMPLATE"); combatPlayerTemplate = playerStatsPanel.Get <ScrollItemWidget>("COMBAT_PLAYER_TEMPLATE"); incomeGraphContainer = widget.Get <ContainerWidget>("INCOME_GRAPH_CONTAINER"); incomeGraph = incomeGraphContainer.Get <LineGraphWidget>("INCOME_GRAPH"); armyValueGraphContainer = widget.Get <ContainerWidget>("ARMY_VALUE_GRAPH_CONTAINER"); armyValueGraph = armyValueGraphContainer.Get <LineGraphWidget>("ARMY_VALUE_GRAPH"); teamTemplate = playerStatsPanel.Get <ScrollItemWidget>("TEAM_TEMPLATE"); var statsDropDown = widget.Get <DropDownButtonWidget>("STATS_DROPDOWN"); Func <string, ObserverStatsPanel, ScrollItemWidget, Action, StatsDropDownOption> createStatsOption = (title, panel, template, a) => { return(new StatsDropDownOption { Title = title, IsSelected = () => activePanel == panel, OnClick = () => { ClearStats(); playerStatsPanel.Visible = true; statsDropDown.GetText = () => title; activePanel = panel; if (template != null) { AdjustStatisticsPanel(template); } a(); Ui.ResetTooltips(); } }); }; var statsDropDownOptions = new StatsDropDownOption[] { new StatsDropDownOption { Title = "Information: None", IsSelected = () => activePanel == ObserverStatsPanel.None, OnClick = () => { statsDropDown.GetText = () => "Information: None"; playerStatsPanel.Visible = false; ClearStats(); activePanel = ObserverStatsPanel.None; } }, createStatsOption("Basic", ObserverStatsPanel.Basic, basicPlayerTemplate, () => DisplayStats(BasicStats)), createStatsOption("Economy", ObserverStatsPanel.Economy, economyPlayerTemplate, () => DisplayStats(EconomyStats)), createStatsOption("Production", ObserverStatsPanel.Production, productionPlayerTemplate, () => DisplayStats(ProductionStats)), createStatsOption("Support Powers", ObserverStatsPanel.SupportPowers, supportPowersPlayerTemplate, () => DisplayStats(SupportPowerStats)), createStatsOption("Combat", ObserverStatsPanel.Combat, combatPlayerTemplate, () => DisplayStats(CombatStats)), createStatsOption("Army", ObserverStatsPanel.Army, armyPlayerTemplate, () => DisplayStats(ArmyStats)), createStatsOption("Earnings (graph)", ObserverStatsPanel.Graph, null, () => IncomeGraph()), createStatsOption("Army (graph)", ObserverStatsPanel.ArmyGraph, null, () => ArmyValueGraph()), }; Func <StatsDropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) => { var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick); item.Get <LabelWidget>("LABEL").GetText = () => option.Title; return(item); }; var statsDropDownPanelTemplate = logicArgs.TryGetValue("StatsDropDownPanelTemplate", out yaml) ? yaml.Value : "LABEL_DROPDOWN_TEMPLATE"; statsDropDown.OnMouseDown = _ => statsDropDown.ShowDropDown(statsDropDownPanelTemplate, 230, statsDropDownOptions, setupItem); statsDropDownOptions[0].OnClick(); var keyListener = statsDropDown.Get <LogicKeyListenerWidget>("STATS_DROPDOWN_KEYHANDLER"); keyListener.AddHandler(e => { if (e.Event == KeyInputEvent.Down && !e.IsRepeat) { for (var i = 0; i < statsHotkeys.Length; i++) { if (statsHotkeys[i].IsActivatedBy(e)) { Game.Sound.PlayNotification(modData.DefaultRules, null, "Sounds", clickSound, null); statsDropDownOptions[i].OnClick(); return(true); } } } return(false); }); if (logicArgs.TryGetValue("ClickSound", out yaml)) { clickSound = yaml.Value; } }
public MenuButtonsChromeLogic(Widget widget, ModData modData, World world, Dictionary <string, MiniYaml> logicArgs) { this.world = world; worldRoot = Ui.Root.Get("WORLD_ROOT"); menuRoot = Ui.Root.Get("MENU_ROOT"); MiniYaml yaml; string[] keyNames = Enum.GetNames(typeof(ObserverStatsPanel)); var statsHotkeys = new HotkeyReference[keyNames.Length]; for (var i = 0; i < keyNames.Length; i++) { statsHotkeys[i] = logicArgs.TryGetValue("Statistics" + keyNames[i] + "Key", out yaml) ? modData.Hotkeys[yaml.Value] : new HotkeyReference(); } // System buttons var options = widget.GetOrNull <MenuButtonWidget>("OPTIONS_BUTTON"); if (options != null) { var blinking = false; var lp = world.LocalPlayer; options.IsDisabled = () => disableSystemButtons; options.OnClick = () => { blinking = false; OpenMenuPanel(options, new WidgetArgs() { { "activePanel", IngameInfoPanel.AutoSelect } }); }; options.IsHighlighted = () => blinking && Game.LocalTick % 50 < 25; if (lp != null) { Action <Player, bool> startBlinking = (player, inhibitAnnouncement) => { if (!inhibitAnnouncement && player == world.LocalPlayer) { blinking = true; } }; var mo = lp.PlayerActor.TraitOrDefault <MissionObjectives>(); if (mo != null) { mo.ObjectiveAdded += startBlinking; } } } var debug = widget.GetOrNull <MenuButtonWidget>("DEBUG_BUTTON"); if (debug != null) { // Can't use DeveloperMode.Enabled because there is a hardcoded hack to *always* // enable developer mode for singleplayer games, but we only want to show the button // if it has been explicitly enabled var def = world.Map.Rules.Actors["player"].TraitInfo <DeveloperModeInfo>().CheckboxEnabled; var enabled = world.LobbyInfo.GlobalSettings.OptionOrDefault("cheats", def); debug.IsVisible = () => enabled; debug.IsDisabled = () => disableSystemButtons; debug.OnClick = () => OpenMenuPanel(debug, new WidgetArgs() { { "activePanel", IngameInfoPanel.Debug } }); } var stats = widget.GetOrNull <MenuButtonWidget>("OBSERVER_STATS_BUTTON"); if (stats != null) { stats.IsDisabled = () => world.Map.Visibility.HasFlag(MapVisibility.MissionSelector); stats.OnClick = () => { if (statistics == null) { statistics = Game.LoadWidget(world, stats.MenuContainer, menuRoot, new WidgetArgs() { { "activePanel", ObserverStatsPanel.Basic } }); } else { statistics.Visible = !statistics.Visible; } }; } var keyListener = widget.GetOrNull <LogicKeyListenerWidget>("OBSERVER_KEY_LISTENER"); if (keyListener != null) { keyListener.AddHandler(e => { if (e.Event == KeyInputEvent.Down && !e.IsRepeat) { for (var i = 0; i < statsHotkeys.Length; i++) { if (statsHotkeys[i].IsActivatedBy(e)) { Game.Sound.PlayNotification(modData.DefaultRules, null, "Sounds", clickSound, null); if (statistics != null) { statistics.Removed(); } statistics = Game.LoadWidget(world, stats.MenuContainer, menuRoot, new WidgetArgs() { { "activePanel", i } }); return(true); } } } return(false); }); } if (logicArgs.TryGetValue("ClickSound", out yaml)) { clickSound = yaml.Value; } }
public MapEditorLogic(Widget widget, ModData modData, World world, WorldRenderer worldRenderer, Dictionary <string, MiniYaml> logicArgs) { MiniYaml yaml; var changeZoomKey = new HotkeyReference(); if (logicArgs.TryGetValue("ChangeZoomKey", out yaml)) { changeZoomKey = modData.Hotkeys[yaml.Value]; } var editorViewport = widget.Get <EditorViewportControllerWidget>("MAP_EDITOR"); var gridButton = widget.GetOrNull <ButtonWidget>("GRID_BUTTON"); var terrainGeometryTrait = world.WorldActor.Trait <TerrainGeometryOverlay>(); if (gridButton != null && terrainGeometryTrait != null) { gridButton.OnClick = () => terrainGeometryTrait.Enabled ^= true; gridButton.IsHighlighted = () => terrainGeometryTrait.Enabled; } var zoomDropdown = widget.GetOrNull <DropDownButtonWidget>("ZOOM_BUTTON"); if (zoomDropdown != null) { var selectedZoom = (Game.Settings.Graphics.PixelDouble ? 2f : 1f).ToString(); zoomDropdown.SelectedItem = selectedZoom; Func <float, ScrollItemWidget, ScrollItemWidget> setupItem = (zoom, itemTemplate) => { var item = ScrollItemWidget.Setup( itemTemplate, () => { return(float.Parse(zoomDropdown.SelectedItem) == zoom); }, () => { zoomDropdown.SelectedItem = selectedZoom = zoom.ToString(); worldRenderer.Viewport.Zoom = float.Parse(selectedZoom); }); var label = zoom.ToString(); item.Get <LabelWidget>("LABEL").GetText = () => label; return(item); }; var options = worldRenderer.Viewport.AvailableZoomSteps; zoomDropdown.OnMouseDown = _ => zoomDropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 150, options, setupItem); zoomDropdown.GetText = () => zoomDropdown.SelectedItem; zoomDropdown.OnKeyPress = e => { if (!changeZoomKey.IsActivatedBy(e)) { return; } var selected = (options.IndexOf(float.Parse(selectedZoom)) + 1) % options.Length; var zoom = options[selected]; worldRenderer.Viewport.Zoom = zoom; selectedZoom = zoom.ToString(); zoomDropdown.SelectedItem = zoom.ToString(); }; } var copypasteButton = widget.GetOrNull <ButtonWidget>("COPYPASTE_BUTTON"); if (copypasteButton != null) { copypasteButton.OnClick = () => editorViewport.SetBrush(new EditorCopyPasteBrush(editorViewport, worldRenderer)); copypasteButton.IsHighlighted = () => editorViewport.CurrentBrush is EditorCopyPasteBrush; } var coordinateLabel = widget.GetOrNull <LabelWidget>("COORDINATE_LABEL"); if (coordinateLabel != null) { coordinateLabel.GetText = () => { var cell = worldRenderer.Viewport.ViewToWorld(Viewport.LastMousePos); var map = worldRenderer.World.Map; return(map.Height.Contains(cell) ? "{0},{1} ({2})".F(cell, map.Height[cell], map.Tiles[cell].Type) : ""); }; } var cashLabel = widget.GetOrNull <LabelWidget>("CASH_LABEL"); if (cashLabel != null) { var reslayer = worldRenderer.World.WorldActor.TraitsImplementing <EditorResourceLayer>().FirstOrDefault(); if (reslayer != null) { cashLabel.GetText = () => "$ {0}".F(reslayer.NetWorth); } } }
public ObserverStatsLogic(World world, ModData modData, WorldRenderer worldRenderer, Widget widget, Action onExit, ObserverStatsPanel activePanel, Dictionary <string, MiniYaml> logicArgs) { this.world = world; this.worldRenderer = worldRenderer; MiniYaml yaml; string[] keyNames = Enum.GetNames(typeof(ObserverStatsPanel)); var statsHotkeys = new HotkeyReference[keyNames.Length]; for (var i = 0; i < keyNames.Length; i++) { statsHotkeys[i] = logicArgs.TryGetValue("Statistics" + keyNames[i] + "Key", out yaml) ? modData.Hotkeys[yaml.Value] : new HotkeyReference(); } players = world.Players.Where(p => !p.NonCombatant); basicStatsHeaders = widget.Get <ContainerWidget>("BASIC_STATS_HEADERS"); economyStatsHeaders = widget.Get <ContainerWidget>("ECONOMY_STATS_HEADERS"); productionStatsHeaders = widget.Get <ContainerWidget>("PRODUCTION_STATS_HEADERS"); combatStatsHeaders = widget.Get <ContainerWidget>("COMBAT_STATS_HEADERS"); earnedThisMinuteGraphHeaders = widget.Get <ContainerWidget>("EARNED_THIS_MIN_GRAPH_HEADERS"); playerStatsPanel = widget.Get <ScrollPanelWidget>("PLAYER_STATS_PANEL"); playerStatsPanel.Layout = new GridLayout(playerStatsPanel); basicPlayerTemplate = playerStatsPanel.Get <ScrollItemWidget>("BASIC_PLAYER_TEMPLATE"); economyPlayerTemplate = playerStatsPanel.Get <ScrollItemWidget>("ECONOMY_PLAYER_TEMPLATE"); productionPlayerTemplate = playerStatsPanel.Get <ScrollItemWidget>("PRODUCTION_PLAYER_TEMPLATE"); combatPlayerTemplate = playerStatsPanel.Get <ScrollItemWidget>("COMBAT_PLAYER_TEMPLATE"); earnedThisMinuteGraphTemplate = playerStatsPanel.Get <ContainerWidget>("EARNED_THIS_MIN_GRAPH_TEMPLATE"); teamTemplate = playerStatsPanel.Get <ScrollItemWidget>("TEAM_TEMPLATE"); var statsDropDown = widget.Get <DropDownButtonWidget>("STATS_DROPDOWN"); Func <string, ContainerWidget, Action, StatsDropDownOption> createStatsOption = (title, headers, a) => { return(new StatsDropDownOption { Title = title, IsSelected = () => headers.Visible, OnClick = () => { ClearStats(); statsDropDown.GetText = () => title; a(); } }); }; var statsDropDownOptions = new StatsDropDownOption[] { createStatsOption("Basic", basicStatsHeaders, () => DisplayStats(BasicStats)), createStatsOption("Economy", economyStatsHeaders, () => DisplayStats(EconomyStats)), createStatsOption("Production", productionStatsHeaders, () => DisplayStats(ProductionStats)), createStatsOption("Combat", combatStatsHeaders, () => DisplayStats(CombatStats)), createStatsOption("Earnings (graph)", earnedThisMinuteGraphHeaders, () => EarnedThisMinuteGraph()) }; Func <StatsDropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) => { var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick); item.Get <LabelWidget>("LABEL").GetText = () => option.Title; return(item); }; statsDropDown.OnMouseDown = _ => statsDropDown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 150, statsDropDownOptions, setupItem); statsDropDownOptions[(int)activePanel].OnClick(); var close = widget.GetOrNull <ButtonWidget>("CLOSE"); if (close != null) { close.OnClick = () => { Ui.CloseWindow(); Ui.Root.RemoveChild(widget); onExit(); } } ; var keyListener = statsDropDown.Get <LogicKeyListenerWidget>("STATS_DROPDOWN_KEYHANDLER"); keyListener.AddHandler(e => { if (e.Event == KeyInputEvent.Down && !e.IsRepeat) { for (var i = 0; i < statsHotkeys.Length; i++) { if (statsHotkeys[i].IsActivatedBy(e)) { Game.Sound.PlayNotification(modData.DefaultRules, null, "Sounds", "ClickSound", null); statsDropDownOptions[i].OnClick(); return(true); } } } return(false); }); } void ClearStats() { playerStatsPanel.Children.Clear(); basicStatsHeaders.Visible = false; economyStatsHeaders.Visible = false; productionStatsHeaders.Visible = false; combatStatsHeaders.Visible = false; earnedThisMinuteGraphHeaders.Visible = false; } void EarnedThisMinuteGraph() { earnedThisMinuteGraphHeaders.Visible = true; var template = earnedThisMinuteGraphTemplate.Clone(); var graph = template.Get <LineGraphWidget>("EARNED_THIS_MIN_GRAPH"); graph.GetSeries = () => players.Select(p => new LineGraphSeries( p.PlayerName, p.Color.RGB, (p.PlayerActor.TraitOrDefault <PlayerStatistics>() ?? new PlayerStatistics(p.PlayerActor)).EarnedSamples.Select(s => (float)s))); playerStatsPanel.AddChild(template); playerStatsPanel.ScrollToTop(); } void DisplayStats(Func <Player, ScrollItemWidget> createItem) { var teams = players.GroupBy(p => (world.LobbyInfo.ClientWithIndex(p.ClientIndex) ?? new Session.Client()).Team).OrderBy(g => g.Key); foreach (var t in teams) { var team = t; var tt = ScrollItemWidget.Setup(teamTemplate, () => false, () => { }); tt.IgnoreMouseOver = true; tt.Get <LabelWidget>("TEAM").GetText = () => team.Key == 0 ? "No Team" : "Team " + team.Key; playerStatsPanel.AddChild(tt); foreach (var p in team) { var player = p; playerStatsPanel.AddChild(createItem(player)); } } } ScrollItemWidget CombatStats(Player player) { combatStatsHeaders.Visible = true; var template = SetupPlayerScrollItemWidget(combatPlayerTemplate, player); LobbyUtils.AddPlayerFlagAndName(template, player); var stats = player.PlayerActor.TraitOrDefault <PlayerStatistics>(); if (stats == null) { return(template); } template.Get <LabelWidget>("ASSETS_DESTROYED").GetText = () => "$" + stats.KillsCost; template.Get <LabelWidget>("ASSETS_LOST").GetText = () => "$" + stats.DeathsCost; template.Get <LabelWidget>("UNITS_KILLED").GetText = () => stats.UnitsKilled.ToString(); template.Get <LabelWidget>("UNITS_DEAD").GetText = () => stats.UnitsDead.ToString(); template.Get <LabelWidget>("BUILDINGS_KILLED").GetText = () => stats.BuildingsKilled.ToString(); template.Get <LabelWidget>("BUILDINGS_DEAD").GetText = () => stats.BuildingsDead.ToString(); return(template); } ScrollItemWidget ProductionStats(Player player) { productionStatsHeaders.Visible = true; var template = SetupPlayerScrollItemWidget(productionPlayerTemplate, player); LobbyUtils.AddPlayerFlagAndName(template, player); template.Get <ObserverProductionIconsWidget>("PRODUCTION_ICONS").GetPlayer = () => player; template.Get <ObserverSupportPowerIconsWidget>("SUPPORT_POWER_ICONS").GetPlayer = () => player; template.IgnoreChildMouseOver = false; return(template); } ScrollItemWidget EconomyStats(Player player) { economyStatsHeaders.Visible = true; var template = SetupPlayerScrollItemWidget(economyPlayerTemplate, player); LobbyUtils.AddPlayerFlagAndName(template, player); var res = player.PlayerActor.Trait <PlayerResources>(); var stats = player.PlayerActor.TraitOrDefault <PlayerStatistics>(); if (stats == null) { return(template); } template.Get <LabelWidget>("CASH").GetText = () => "$" + (res.Cash + res.Resources); template.Get <LabelWidget>("EARNED_MIN").GetText = () => AverageEarnedPerMinute(res.Earned); template.Get <LabelWidget>("EARNED_THIS_MIN").GetText = () => "$" + stats.EarnedThisMinute; template.Get <LabelWidget>("EARNED").GetText = () => "$" + res.Earned; template.Get <LabelWidget>("SPENT").GetText = () => "$" + res.Spent; var assets = template.Get <LabelWidget>("ASSETS"); assets.GetText = () => "$" + world.ActorsHavingTrait <Valued>() .Where(a => a.Owner == player && !a.IsDead) .Sum(a => a.Info.TraitInfos <ValuedInfo>().First().Cost); var harvesters = template.Get <LabelWidget>("HARVESTERS"); harvesters.GetText = () => world.ActorsHavingTrait <Harvester>().Count(a => a.Owner == player && !a.IsDead).ToString(); return(template); } ScrollItemWidget BasicStats(Player player) { basicStatsHeaders.Visible = true; var template = SetupPlayerScrollItemWidget(basicPlayerTemplate, player); LobbyUtils.AddPlayerFlagAndName(template, player); var res = player.PlayerActor.Trait <PlayerResources>(); template.Get <LabelWidget>("CASH").GetText = () => "$" + (res.Cash + res.Resources); template.Get <LabelWidget>("EARNED_MIN").GetText = () => AverageEarnedPerMinute(res.Earned); var powerRes = player.PlayerActor.Trait <PowerManager>(); var power = template.Get <LabelWidget>("POWER"); power.GetText = () => powerRes.PowerDrained + "/" + powerRes.PowerProvided; power.GetColor = () => GetPowerColor(powerRes.PowerState); var stats = player.PlayerActor.TraitOrDefault <PlayerStatistics>(); if (stats == null) { return(template); } template.Get <LabelWidget>("KILLS").GetText = () => (stats.UnitsKilled + stats.BuildingsKilled).ToString(); template.Get <LabelWidget>("DEATHS").GetText = () => (stats.UnitsDead + stats.BuildingsDead).ToString(); template.Get <LabelWidget>("ASSETS_DESTROYED").GetText = () => "$" + stats.KillsCost; template.Get <LabelWidget>("ASSETS_LOST").GetText = () => "$" + stats.DeathsCost; template.Get <LabelWidget>("EXPERIENCE").GetText = () => stats.Experience.ToString(); template.Get <LabelWidget>("ACTIONS_MIN").GetText = () => AverageOrdersPerMinute(stats.OrderCount); return(template); } ScrollItemWidget SetupPlayerScrollItemWidget(ScrollItemWidget template, Player player) { return(ScrollItemWidget.Setup(template, () => false, () => { var playerBase = world.ActorsHavingTrait <BaseBuilding>().FirstOrDefault(a => !a.IsDead && a.Owner == player); if (playerBase != null) { worldRenderer.Viewport.Center(playerBase.CenterPosition); } })); }
public IngameChatLogic(Widget widget, OrderManager orderManager, World world, ModData modData, bool isMenuChat, Dictionary <string, MiniYaml> logicArgs) { this.orderManager = orderManager; modRules = modData.DefaultRules; this.isMenuChat = isMenuChat; this.world = world; var chatTraits = world.WorldActor.TraitsImplementing <INotifyChat>().ToArray(); var players = world.Players.Where(p => p != world.LocalPlayer && !p.NonCombatant && !p.IsBot); var isObserver = orderManager.LocalClient != null && orderManager.LocalClient.IsObserver; var alwaysDisabled = world.IsReplay || world.LobbyInfo.NonBotClients.Count() == 1; var disableTeamChat = alwaysDisabled || (world.LocalPlayer != null && !players.Any(p => p.IsAlliedWith(world.LocalPlayer))); var teamChat = !disableTeamChat; tabCompletion.Commands = chatTraits.OfType <ChatCommands>().SelectMany(x => x.Commands.Keys).ToList(); tabCompletion.Names = orderManager.LobbyInfo.Clients.Select(c => c.Name).Distinct().ToList(); if (logicArgs.TryGetValue("Templates", out var templateIds)) { foreach (var item in templateIds.Nodes) { var key = FieldLoader.GetValue <TextNotificationPool>("key", item.Key); templates[key] = Ui.LoadWidget(item.Value.Value, null, new WidgetArgs()); } } var chatPanel = (ContainerWidget)widget; chatOverlay = chatPanel.GetOrNull <ContainerWidget>("CHAT_OVERLAY"); if (chatOverlay != null) { chatOverlayDisplay = chatOverlay.Get <TextNotificationsDisplayWidget>("CHAT_DISPLAY"); chatOverlay.Visible = false; } chatChrome = chatPanel.Get <ContainerWidget>("CHAT_CHROME"); chatChrome.Visible = true; var chatMode = chatChrome.Get <ButtonWidget>("CHAT_MODE"); chatMode.GetText = () => teamChat && !disableTeamChat ? "Team" : "All"; chatMode.OnClick = () => teamChat ^= true; // Enable teamchat if we are a player and die, // or disable it when we are the only one left in the team if (!alwaysDisabled && world.LocalPlayer != null) { chatMode.IsDisabled = () => { if (world.IsGameOver || !chatEnabled) { return(true); } // The game is over for us, join spectator team chat if (world.LocalPlayer.WinState != WinState.Undefined) { disableTeamChat = false; return(disableTeamChat); } // If team chat isn't already disabled, check if we are the only living team member if (!disableTeamChat) { disableTeamChat = players.All(p => p.WinState != WinState.Undefined || !p.IsAlliedWith(world.LocalPlayer)); } return(disableTeamChat); }; } else { chatMode.IsDisabled = () => disableTeamChat || !chatEnabled; } // Disable team chat after the game ended world.GameOver += () => disableTeamChat = true; chatText = chatChrome.Get <TextFieldWidget>("CHAT_TEXTFIELD"); chatText.MaxLength = UnitOrders.ChatMessageMaxLength; chatText.OnEnterKey = _ => { var team = teamChat && !disableTeamChat; if (chatText.Text != "") { if (!chatText.Text.StartsWith("/", StringComparison.Ordinal)) { // This should never happen, but avoid a crash if it does somehow (chat will just stay open) if (!isObserver && orderManager.LocalClient == null && world.LocalPlayer == null) { return(true); } var teamNumber = 0U; if (team) { teamNumber = (isObserver || world.LocalPlayer.WinState != WinState.Undefined) ? uint.MaxValue : (uint)orderManager.LocalClient.Team; } orderManager.IssueOrder(Order.Chat(chatText.Text.Trim(), teamNumber)); } else if (chatTraits != null) { var text = chatText.Text.Trim(); var from = world.IsReplay ? null : orderManager.LocalClient.Name; foreach (var trait in chatTraits) { trait.OnChat(from, text); } } } chatText.Text = ""; if (!isMenuChat) { CloseChat(); } return(true); }; chatText.OnTabKey = e => { if (!chatMode.Key.IsActivatedBy(e) || chatMode.IsDisabled()) { chatText.Text = tabCompletion.Complete(chatText.Text); chatText.CursorPosition = chatText.Text.Length; } else { chatMode.OnKeyPress(e); } return(true); }; chatText.OnEscKey = _ => { if (!isMenuChat) { CloseChat(); } else { chatText.YieldKeyboardFocus(); } return(true); }; chatDisabledLabel = new CachedTransform <int, string>(x => x > 0 ? $"Chat available in {x} seconds..." : "Chat Disabled"); if (!isMenuChat) { var openTeamChatKey = new HotkeyReference(); if (logicArgs.TryGetValue("OpenTeamChatKey", out var hotkeyArg)) { openTeamChatKey = modData.Hotkeys[hotkeyArg.Value]; } var openGeneralChatKey = new HotkeyReference(); if (logicArgs.TryGetValue("OpenGeneralChatKey", out hotkeyArg)) { openGeneralChatKey = modData.Hotkeys[hotkeyArg.Value]; } var chatClose = chatChrome.Get <ButtonWidget>("CHAT_CLOSE"); chatClose.OnClick += CloseChat; chatPanel.OnKeyPress = e => { if (e.Event == KeyInputEvent.Up) { return(false); } if (!chatChrome.IsVisible() && (openTeamChatKey.IsActivatedBy(e) || openGeneralChatKey.IsActivatedBy(e))) { teamChat = !disableTeamChat && !openGeneralChatKey.IsActivatedBy(e); OpenChat(); return(true); } return(false); }; } chatScrollPanel = chatChrome.Get <ScrollPanelWidget>("CHAT_SCROLLPANEL"); chatScrollPanel.RemoveChildren(); chatScrollPanel.ScrollToBottom(); foreach (var notification in orderManager.NotificationsCache) { if (IsNotificationEligible(notification)) { AddNotification(notification, true); } } orderManager.AddTextNotification += AddNotificationWrapper; chatText.IsDisabled = () => !chatEnabled || (world.IsReplay && !Game.Settings.Debug.EnableDebugCommandsInReplays); if (!isMenuChat) { CloseChat(); var keyListener = chatChrome.Get <LogicKeyListenerWidget>("KEY_LISTENER"); keyListener.AddHandler(e => { if (e.Event == KeyInputEvent.Up || !chatText.IsDisabled()) { return(false); } if ((e.Key == Keycode.RETURN || e.Key == Keycode.KP_ENTER || e.Key == Keycode.ESCAPE) && e.Modifiers == Modifiers.None) { CloseChat(); return(true); } return(false); }); } if (logicArgs.TryGetValue("ChatLineSound", out var yaml)) { chatLineSound = yaml.Value; } }
public MapEditorLogic(Widget widget, ModData modData, World world, WorldRenderer worldRenderer, Dictionary <string, MiniYaml> logicArgs) { MiniYaml yaml; var changeZoomKey = new HotkeyReference(); if (logicArgs.TryGetValue("ChangeZoomKey", out yaml)) { changeZoomKey = modData.Hotkeys[yaml.Value]; } var editorViewport = widget.Get <EditorViewportControllerWidget>("MAP_EDITOR"); var gridButton = widget.GetOrNull <ButtonWidget>("GRID_BUTTON"); var terrainGeometryTrait = world.WorldActor.Trait <TerrainGeometryOverlay>(); if (gridButton != null && terrainGeometryTrait != null) { gridButton.OnClick = () => terrainGeometryTrait.Enabled ^= true; gridButton.IsHighlighted = () => terrainGeometryTrait.Enabled; } var zoomDropdown = widget.GetOrNull <DropDownButtonWidget>("ZOOM_BUTTON"); if (zoomDropdown != null) { var selectedZoom = (Game.Settings.Graphics.PixelDouble ? 2f : 1f).ToString(); zoomDropdown.SelectedItem = selectedZoom; Func <float, ScrollItemWidget, ScrollItemWidget> setupItem = (zoom, itemTemplate) => { var item = ScrollItemWidget.Setup( itemTemplate, () => { return(float.Parse(zoomDropdown.SelectedItem) == zoom); }, () => { zoomDropdown.SelectedItem = selectedZoom = zoom.ToString(); worldRenderer.Viewport.Zoom = float.Parse(selectedZoom); }); var label = zoom.ToString(); item.Get <LabelWidget>("LABEL").GetText = () => label; return(item); }; var options = worldRenderer.Viewport.AvailableZoomSteps; zoomDropdown.OnMouseDown = _ => zoomDropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 150, options, setupItem); zoomDropdown.GetText = () => zoomDropdown.SelectedItem; zoomDropdown.OnKeyPress = e => { if (!changeZoomKey.IsActivatedBy(e)) { return; } var selected = (options.IndexOf(float.Parse(selectedZoom)) + 1) % options.Length; var zoom = options[selected]; worldRenderer.Viewport.Zoom = zoom; selectedZoom = zoom.ToString(); zoomDropdown.SelectedItem = zoom.ToString(); }; } var copypasteButton = widget.GetOrNull <ButtonWidget>("COPYPASTE_BUTTON"); if (copypasteButton != null) { // HACK: Replace Ctrl with Cmd on macOS // TODO: Add platform-specific override support to HotkeyManager // and then port the editor hotkeys to this system. var copyPasteKey = copypasteButton.Key.GetValue(); if (Platform.CurrentPlatform == PlatformType.OSX && copyPasteKey.Modifiers.HasModifier(Modifiers.Ctrl)) { var modified = new Hotkey(copyPasteKey.Key, copyPasteKey.Modifiers & ~Modifiers.Ctrl | Modifiers.Meta); copypasteButton.Key = FieldLoader.GetValue <HotkeyReference>("Key", modified.ToString()); } copypasteButton.OnClick = () => editorViewport.SetBrush(new EditorCopyPasteBrush(editorViewport, worldRenderer, () => copyFilters)); copypasteButton.IsHighlighted = () => editorViewport.CurrentBrush is EditorCopyPasteBrush; } var copyFilterDropdown = widget.Get <DropDownButtonWidget>("COPYFILTER_BUTTON"); copyFilterDropdown.OnMouseDown = _ => { copyFilterDropdown.RemovePanel(); copyFilterDropdown.AttachPanel(CreateCategoriesPanel()); }; var coordinateLabel = widget.GetOrNull <LabelWidget>("COORDINATE_LABEL"); if (coordinateLabel != null) { coordinateLabel.GetText = () => { var cell = worldRenderer.Viewport.ViewToWorld(Viewport.LastMousePos); var map = worldRenderer.World.Map; return(map.Height.Contains(cell) ? "{0},{1} ({2})".F(cell, map.Height[cell], map.Tiles[cell].Type) : ""); }; } var cashLabel = widget.GetOrNull <LabelWidget>("CASH_LABEL"); if (cashLabel != null) { var reslayer = worldRenderer.World.WorldActor.TraitsImplementing <EditorResourceLayer>().FirstOrDefault(); if (reslayer != null) { cashLabel.GetText = () => "$ {0}".F(reslayer.NetWorth); } } var actionManager = world.WorldActor.Trait <EditorActionManager>(); var undoButton = widget.GetOrNull <ButtonWidget>("UNDO_BUTTON"); if (undoButton != null) { undoButton.IsDisabled = () => !actionManager.HasUndos(); undoButton.OnClick = () => actionManager.Undo(); } var redoButton = widget.GetOrNull <ButtonWidget>("REDO_BUTTON"); if (redoButton != null) { redoButton.IsDisabled = () => !actionManager.HasRedos(); redoButton.OnClick = () => actionManager.Redo(); } }