Esempio n. 1
0
        public ObserverStatsLogic(World world, WorldRenderer worldRenderer, Widget widget, Action onExit)
        {
            this.world         = world;
            this.worldRenderer = worldRenderer;
            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");

            statsDropDown             = widget.Get <DropDownButtonWidget>("STATS_DROPDOWN");
            statsDropDown.GetText     = () => "Basic";
            statsDropDown.OnMouseDown = _ =>
            {
                var options = new List <StatsDropDownOption>
                {
                    new StatsDropDownOption
                    {
                        Title      = "Basic",
                        IsSelected = () => basicStatsHeaders.Visible,
                        OnClick    = () =>
                        {
                            ClearStats();
                            statsDropDown.GetText = () => "Basic";
                            DisplayStats(BasicStats);
                        }
                    },
                    new StatsDropDownOption
                    {
                        Title      = "Economy",
                        IsSelected = () => economyStatsHeaders.Visible,
                        OnClick    = () =>
                        {
                            ClearStats();
                            statsDropDown.GetText = () => "Economy";
                            DisplayStats(EconomyStats);
                        }
                    },
                    new StatsDropDownOption
                    {
                        Title      = "Production",
                        IsSelected = () => productionStatsHeaders.Visible,
                        OnClick    = () =>
                        {
                            ClearStats();
                            statsDropDown.GetText = () => "Production";
                            DisplayStats(ProductionStats);
                        }
                    },
                    new StatsDropDownOption
                    {
                        Title      = "Combat",
                        IsSelected = () => combatStatsHeaders.Visible,
                        OnClick    = () =>
                        {
                            ClearStats();
                            statsDropDown.GetText = () => "Combat";
                            DisplayStats(CombatStats);
                        }
                    },
                    new StatsDropDownOption
                    {
                        Title      = "Earnings (graph)",
                        IsSelected = () => earnedThisMinuteGraphHeaders.Visible,
                        OnClick    = () =>
                        {
                            ClearStats();
                            statsDropDown.GetText = () => "Earnings (graph)";
                            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.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 150, options, setupItem);
            };

            ClearStats();
            DisplayStats(BasicStats);

            var close = widget.GetOrNull <ButtonWidget>("CLOSE");

            if (close != null)
            {
                close.OnClick = () =>
                {
                    Ui.CloseWindow();
                    Ui.Root.RemoveChild(widget);
                    onExit();
                }
            }
            ;
        }

        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);
        }

        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>("KILLS_COST").GetText       = () => "$" + stats.KillsCost;
            template.Get <LabelWidget>("DEATHS_COST").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;

            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.DisplayCash + res.DisplayResources);
            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.DisplayCash + res.DisplayResources);
            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>("KD_RATIO").GetText    = () => KillDeathRatio(stats.UnitsKilled + stats.BuildingsKilled, stats.UnitsDead + stats.BuildingsDead);
            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);
                }
            }));
        }
Esempio n. 2
0
        List <Widget> LoadGameRows(List <GameServer> games, out ScrollItemWidget nextServerRow)
        {
            nextServerRow = null;
            var rows = new List <Widget>();
            var mods = games.GroupBy(g => g.ModLabel)
                       .OrderByDescending(g => GroupSortOrder(g.First()))
                       .ThenByDescending(g => g.Count());

            foreach (var modGames in mods)
            {
                if (modGames.All(Filtered))
                {
                    continue;
                }

                var header = ScrollItemWidget.Setup(headerTemplate, () => true, () => { });

                var headerTitle = modGames.First().ModLabel;
                header.Get <LabelWidget>("LABEL").GetText = () => headerTitle;
                rows.Add(header);

                Func <GameServer, int> listOrder = g =>
                {
                    // Servers waiting for players are always first
                    if (g.State == (int)ServerState.WaitingPlayers && g.Players > 0)
                    {
                        return(0);
                    }

                    // Then servers with spectators
                    if (g.State == (int)ServerState.WaitingPlayers && g.Spectators > 0)
                    {
                        return(1);
                    }

                    // Then active games
                    if (g.State >= (int)ServerState.GameStarted)
                    {
                        return(2);
                    }

                    // Empty servers are shown at the end because a flood of empty servers
                    // at the top of the game list make the community look dead
                    return(3);
                };

                foreach (var modGamesByState in modGames.GroupBy(listOrder).OrderBy(g => g.Key))
                {
                    // Sort 'Playing' games by Started, others by number of players
                    foreach (var game in modGamesByState.Key == 2 ? modGamesByState.OrderByDescending(g => g.Started) : modGamesByState.OrderByDescending(g => g.Players))
                    {
                        if (Filtered(game))
                        {
                            continue;
                        }

                        var canJoin = game.IsJoinable;
                        var item    = ScrollItemWidget.Setup(serverTemplate, () => currentServer == game, () => SelectServer(game), () => onJoin(game));
                        var title   = item.GetOrNull <LabelWithTooltipWidget>("TITLE");
                        if (title != null)
                        {
                            WidgetUtils.TruncateLabelToTooltip(title, game.Name);
                            title.GetColor = () => canJoin ? title.TextColor : incompatibleGameColor;
                        }

                        var password = item.GetOrNull <ImageWidget>("PASSWORD_PROTECTED");
                        if (password != null)
                        {
                            password.IsVisible    = () => game.Protected;
                            password.GetImageName = () => canJoin ? "protected" : "protected-disabled";
                        }

                        var auth = item.GetOrNull <ImageWidget>("REQUIRES_AUTHENTICATION");
                        if (auth != null)
                        {
                            auth.IsVisible    = () => game.Authentication;
                            auth.GetImageName = () => canJoin ? "authentication" : "authentication-disabled";

                            if (game.Protected && password != null)
                            {
                                auth.Bounds.X -= password.Bounds.Width + 5;
                            }
                        }

                        var players = item.GetOrNull <LabelWithTooltipWidget>("PLAYERS");
                        if (players != null)
                        {
                            var label = "{0} / {1}".F(game.Players + game.Bots, game.MaxPlayers + game.Bots)
                                        + (game.Spectators > 0 ? " + {0}".F(game.Spectators) : "");

                            var color = canJoin ? players.TextColor : incompatibleGameColor;
                            players.GetText  = () => label;
                            players.GetColor = () => color;

                            if (game.Clients.Any())
                            {
                                var displayClients = game.Clients.Select(c => c.Name);
                                if (game.Clients.Length > 10)
                                {
                                    displayClients = displayClients
                                                     .Take(9)
                                                     .Append("+ {0} other players".F(game.Clients.Length - 9));
                                }

                                var tooltip = displayClients.JoinWith("\n");
                                players.GetTooltipText = () => tooltip;
                            }
                            else
                            {
                                players.GetTooltipText = null;
                            }
                        }

                        var state = item.GetOrNull <LabelWidget>("STATUS");
                        if (state != null)
                        {
                            var label = game.State >= (int)ServerState.GameStarted ?
                                        "Playing" : "Waiting";
                            state.GetText = () => label;

                            var color = GetStateColor(game, state, !canJoin);
                            state.GetColor = () => color;
                        }

                        var location = item.GetOrNull <LabelWidget>("LOCATION");
                        if (location != null)
                        {
                            var font  = Game.Renderer.Fonts[location.Font];
                            var label = WidgetUtils.TruncateText(game.Location, location.Bounds.Width, font);
                            location.GetText  = () => label;
                            location.GetColor = () => canJoin ? location.TextColor : incompatibleGameColor;
                        }

                        if (currentServer != null && game.Address == currentServer.Address)
                        {
                            nextServerRow = item;
                        }

                        rows.Add(item);
                    }
                }
            }

            return(rows);
        }
        public ObserverShroudSelectorLogic(Widget widget, World world)
        {
            limitViews = world.Map.Visibility.HasFlag(MapVisibility.MissionSelector);

            var groups = new Dictionary <string, IEnumerable <CameraOption> >();

            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);
            }

            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
                });
            }

            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.GetText   = () => option.Label;
                    label.GetColor  = () => option.Color;

                    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);
            };

            var 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.OnKeyPress = HandleKeyPress;

            selected = limitViews ? groups.First().Value.First() : disableShroud;
            selected.OnClick();
        }
Esempio n. 4
0
        public SaveMapLogic(Widget widget, ModData modData, Action <string> onSave, Action onExit,
                            Map map, List <MiniYamlNode> playerDefinitions, List <MiniYamlNode> actorDefinitions)
        {
            var title = widget.Get <TextFieldWidget>("TITLE");

            title.Text = map.Title;

            var author = widget.Get <TextFieldWidget>("AUTHOR");

            author.Text = map.Author;

            // TODO: This should use a multi-selection dropdown once they exist
            var visibilityDropdown = widget.Get <DropDownButtonWidget>("VISIBILITY_DROPDOWN");
            {
                var mapVisibility = new List <string>(Enum.GetNames(typeof(MapVisibility)));
                Func <string, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                {
                    var item = ScrollItemWidget.Setup(template,
                                                      () => visibilityDropdown.Text == option,
                                                      () => { visibilityDropdown.Text = option; });
                    item.Get <LabelWidget>("LABEL").GetText = () => option;
                    return(item);
                };

                visibilityDropdown.Text    = Enum.GetName(typeof(MapVisibility), map.Visibility);
                visibilityDropdown.OnClick = () =>
                                             visibilityDropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 210, mapVisibility, setupItem);
            }

            var           writableDirectories = new List <SaveDirectory>();
            SaveDirectory selectedDirectory   = null;

            var directoryDropdown = widget.Get <DropDownButtonWidget>("DIRECTORY_DROPDOWN");
            {
                Func <SaveDirectory, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                {
                    var item = ScrollItemWidget.Setup(template,
                                                      () => selectedDirectory == option,
                                                      () => selectedDirectory = option);
                    item.Get <LabelWidget>("LABEL").GetText = () => option.DisplayName;
                    return(item);
                };

                foreach (var kv in modData.MapCache.MapLocations)
                {
                    var folder = kv.Key as Folder;
                    if (folder == null)
                    {
                        continue;
                    }

                    try
                    {
                        using (var fs = File.Create(Path.Combine(folder.Name, ".testwritable"), 1, FileOptions.DeleteOnClose))
                        {
                            // Do nothing: we just want to test whether we can create the file
                        }

                        writableDirectories.Add(new SaveDirectory(folder, kv.Value));
                    }
                    catch
                    {
                        // Directory is not writable
                    }
                }

                if (map.Package != null)
                {
                    selectedDirectory = writableDirectories.FirstOrDefault(k => k.Folder.Contains(map.Package.Name));
                }

                // Prioritize MapClassification.User directories over system directories
                if (selectedDirectory == null)
                {
                    selectedDirectory = writableDirectories.OrderByDescending(kv => kv.Classification).First();
                }

                directoryDropdown.GetText = () => selectedDirectory == null ? "" : selectedDirectory.DisplayName;
                directoryDropdown.OnClick = () =>
                                            directoryDropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 210, writableDirectories, setupItem);
            }

            var mapIsUnpacked = map.Package != null && (map.Package is Folder || map.Package is ZipFolder);

            var filename = widget.Get <TextFieldWidget>("FILENAME");

            filename.Text = map.Package == null ? "" : mapIsUnpacked?Path.GetFileName(map.Package.Name) : Path.GetFileNameWithoutExtension(map.Package.Name);

            var fileType = mapIsUnpacked ? MapFileType.Unpacked : MapFileType.OraMap;

            var fileTypes = new Dictionary <MapFileType, MapFileTypeInfo>()
            {
                { MapFileType.OraMap, new MapFileTypeInfo {
                      Extension = ".oramap", UiLabel = ".oramap"
                  } },
                { MapFileType.Unpacked, new MapFileTypeInfo {
                      Extension = "", UiLabel = "(unpacked)"
                  } }
            };

            var typeDropdown = widget.Get <DropDownButtonWidget>("TYPE_DROPDOWN");
            {
                Func <KeyValuePair <MapFileType, MapFileTypeInfo>, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                {
                    var item = ScrollItemWidget.Setup(template,
                                                      () => fileType == option.Key,
                                                      () => { typeDropdown.Text = option.Value.UiLabel; fileType = option.Key; });
                    item.Get <LabelWidget>("LABEL").GetText = () => option.Value.UiLabel;
                    return(item);
                };

                typeDropdown.Text = fileTypes[fileType].UiLabel;

                typeDropdown.OnClick = () =>
                                       typeDropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 210, fileTypes, setupItem);
            }

            var close = widget.Get <ButtonWidget>("BACK_BUTTON");

            close.OnClick = () => { Ui.CloseWindow(); onExit(); };

            var save = widget.Get <ButtonWidget>("SAVE_BUTTON");

            save.OnClick = () =>
            {
                if (string.IsNullOrEmpty(filename.Text))
                {
                    return;
                }

                map.Title      = title.Text;
                map.Author     = author.Text;
                map.Visibility = (MapVisibility)Enum.Parse(typeof(MapVisibility), visibilityDropdown.Text);

                if (actorDefinitions != null)
                {
                    map.ActorDefinitions = actorDefinitions;
                }

                if (playerDefinitions != null)
                {
                    map.PlayerDefinitions = playerDefinitions;
                }

                map.RequiresMod = modData.Manifest.Mod.Id;

                var combinedPath = Platform.ResolvePath(Path.Combine(selectedDirectory.Folder.Name, filename.Text + fileTypes[fileType].Extension));

                // Invalidate the old map metadata
                if (map.Uid != null && map.Package != null && map.Package.Name == combinedPath)
                {
                    modData.MapCache[map.Uid].Invalidate();
                }

                try
                {
                    var package = map.Package as IReadWritePackage;
                    if (package == null || package.Name != combinedPath)
                    {
                        selectedDirectory.Folder.Delete(combinedPath);
                        if (fileType == MapFileType.OraMap)
                        {
                            package = ZipFile.Create(combinedPath, selectedDirectory.Folder);
                        }
                        else
                        {
                            package = new Folder(combinedPath);
                        }
                    }

                    map.Save(package);
                }
                catch
                {
                    Console.WriteLine("Failed to save map at {0}", combinedPath);
                }

                // Update the map cache so it can be loaded without restarting the game
                modData.MapCache[map.Uid].UpdateFromMap(map.Package, selectedDirectory.Folder, selectedDirectory.Classification, null, map.Grid.Type);

                Console.WriteLine("Saved current map at {0}", combinedPath);
                Ui.CloseWindow();

                onSave(map.Uid);
            };
        }
Esempio n. 5
0
        public NewMapLogic(Action onExit, Action <string> onSelect, Widget widget, World world, ModData modData)
        {
            panel = widget;

            panel.Get <ButtonWidget>("CANCEL_BUTTON").OnClick = () => { Ui.CloseWindow(); onExit(); };

            var tilesetDropDown = panel.Get <DropDownButtonWidget>("TILESET");
            var tilesets        = modData.DefaultTerrainInfo.Keys;
            Func <string, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
            {
                var item = ScrollItemWidget.Setup(template,
                                                  () => tilesetDropDown.Text == option,
                                                  () => { tilesetDropDown.Text = option; });
                item.Get <LabelWidget>("LABEL").GetText = () => option;
                return(item);
            };

            tilesetDropDown.Text    = tilesets.First();
            tilesetDropDown.OnClick = () =>
                                      tilesetDropDown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 210, tilesets, setupItem);

            var widthTextField  = panel.Get <TextFieldWidget>("WIDTH");
            var heightTextField = panel.Get <TextFieldWidget>("HEIGHT");

            panel.Get <ButtonWidget>("CREATE_BUTTON").OnClick = () =>
            {
                int.TryParse(widthTextField.Text, out var width);
                int.TryParse(heightTextField.Text, out var height);

                // Require at least a 2x2 playable area so that the
                // ground is visible through the edge shroud
                width  = Math.Max(2, width);
                height = Math.Max(2, height);

                var maxTerrainHeight = world.Map.Grid.MaximumTerrainHeight;
                var tileset          = modData.DefaultTerrainInfo[tilesetDropDown.Text];
                var map = new Map(Game.ModData, tileset, width + 2, height + maxTerrainHeight + 2);

                var tl = new PPos(1, 1 + maxTerrainHeight);
                var br = new PPos(width, height + maxTerrainHeight);
                map.SetBounds(tl, br);

                map.PlayerDefinitions = new MapPlayers(map.Rules, 0).ToMiniYaml();

                if (map.Rules.TerrainInfo is ITerrainInfoNotifyMapCreated notifyMapCreated)
                {
                    notifyMapCreated.MapCreated(map);
                }

                Action <string> afterSave = uid =>
                {
                    // HACK: Work around a synced-code change check.
                    // It's not clear why this is needed here, but not in the other places that load maps.
                    Game.RunAfterTick(() => Game.LoadEditor(uid));

                    Ui.CloseWindow();
                    onSelect(uid);
                };

                Ui.OpenWindow("SAVE_MAP_PANEL", new WidgetArgs()
                {
                    { "onSave", afterSave },
                    { "onExit", () => { Ui.CloseWindow(); onExit(); } },
                    { "map", map },
                    { "playerDefinitions", map.PlayerDefinitions },
                    { "actorDefinitions", map.ActorDefinitions }
                });
            };
        }
Esempio n. 6
0
        protected override void InitializePreviews()
        {
            Panel.RemoveChildren();
            if (!SelectedCategories.Any())
            {
                return;
            }

            foreach (var a in allActors)
            {
                if (!SelectedCategories.Overlaps(a.Categories))
                {
                    continue;
                }

                if (!string.IsNullOrEmpty(searchFilter) && !a.SearchTerms.Any(s => s.IndexOf(searchFilter, StringComparison.OrdinalIgnoreCase) >= 0))
                {
                    continue;
                }

                var actor = a.Actor;
                var td    = new TypeDictionary();
                td.Add(new OwnerInit(selectedOwner.Name));
                td.Add(new FactionInit(selectedOwner.Faction));
                foreach (var api in actor.TraitInfos <IActorPreviewInitInfo>())
                {
                    foreach (var o in api.ActorPreviewInits(actor, ActorPreviewType.MapEditorSidebar))
                    {
                        td.Add(o);
                    }
                }

                try
                {
                    var item = ScrollItemWidget.Setup(ItemTemplate,
                                                      () => { var brush = Editor.CurrentBrush as EditorActorBrush; return(brush != null && brush.Actor == actor); },
                                                      () => Editor.SetBrush(new EditorActorBrush(Editor, actor, selectedOwner, WorldRenderer)));

                    var preview = item.Get <ActorPreviewWidget>("ACTOR_PREVIEW");
                    preview.SetPreview(actor, td);

                    // Scale templates to fit within the panel
                    var scale = 1f;
                    if (scale * preview.IdealPreviewSize.X > ItemTemplate.Bounds.Width)
                    {
                        scale = (ItemTemplate.Bounds.Width - Panel.ItemSpacing) / (float)preview.IdealPreviewSize.X;
                    }

                    preview.GetScale      = () => scale;
                    preview.Bounds.Width  = (int)(scale * preview.IdealPreviewSize.X);
                    preview.Bounds.Height = (int)(scale * preview.IdealPreviewSize.Y);

                    item.Bounds.Width  = preview.Bounds.Width + 2 * preview.Bounds.X;
                    item.Bounds.Height = preview.Bounds.Height + 2 * preview.Bounds.Y;
                    item.IsVisible     = () => true;

                    item.GetTooltipText = () => a.Tooltip;

                    Panel.AddChild(item);
                }
                catch
                {
                    Log.Write("debug", "Map editor ignoring actor {0}, because of missing sprites for tileset {1}.",
                              actor.Name, World.Map.Rules.TileSet.Id);
                    continue;
                }
            }
        }
        public NewMapWithTileSelectionLogic(Action onExit, Action <string> onSelect, Widget widget, World world, ModData modData)
        {
            panel = widget;

            panel.Get <ButtonWidget>("CANCEL_BUTTON").OnClick = () => { Ui.CloseWindow(); onExit(); };

            var tileDropDown = panel.Get <DropDownButtonWidget>("TILE");

            var tileset = modData.DefaultTerrainInfo.First().Value;

            var terrainInfo = world.Map.Rules.TerrainInfo as ITemplatedTerrainInfo;

            var clearTiles = terrainInfo.Templates.Where(t => ((CustomTerrainTemplateInfo)t.Value).ClearTile)
                             .Select(t => (Type: t.Value.Id,
                                           Description: terrainInfo.TerrainTypes[terrainInfo.GetTerrainInfo(new TerrainTile(t.Key, 0)).TerrainType].Type));

            Func <string, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
            {
                var item = ScrollItemWidget.Setup(template,
                                                  () => tileDropDown.Text == option,
                                                  () => { tileDropDown.Text = option; });
                item.Get <LabelWidget>("LABEL").GetText = () => option;
                return(item);
            };

            tileDropDown.Text = clearTiles.First().Description;
            var options = clearTiles.Select(t => t.Description);

            tileDropDown.OnClick = () =>
                                   tileDropDown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 210, options, setupItem);

            var widthTextField  = panel.Get <TextFieldWidget>("WIDTH");
            var heightTextField = panel.Get <TextFieldWidget>("HEIGHT");

            panel.Get <ButtonWidget>("CREATE_BUTTON").OnClick = () =>
            {
                int.TryParse(widthTextField.Text, out int width);
                int.TryParse(heightTextField.Text, out int height);

                // Require at least a 2x2 playable area so that the
                // ground is visible through the edge shroud
                width  = Math.Max(2, width);
                height = Math.Max(2, height);

                var maxTerrainHeight = world.Map.Grid.MaximumTerrainHeight;
                var map = new Map(Game.ModData, tileset, width + 2, height + maxTerrainHeight + 2);

                var tl = new PPos(1, 1 + maxTerrainHeight);
                var br = new PPos(width, height + maxTerrainHeight);
                map.SetBounds(tl, br);

                var type = clearTiles.First(c => c.Description == tileDropDown.Text).Type;
                for (var j = map.Bounds.Top; j < map.Bounds.Bottom; j++)
                {
                    for (var i = map.Bounds.Left; i < map.Bounds.Right; i++)
                    {
                        var template = terrainInfo.Templates[type];
                        map.Tiles[new MPos(i, j)] = new TerrainTile(type, 0);
                    }
                }

                map.PlayerDefinitions = new MapPlayers(map.Rules, 0).ToMiniYaml();
                if (map.Rules.TerrainInfo is ITerrainInfoNotifyMapCreated notifyMapCreated)
                {
                    notifyMapCreated.MapCreated(map);
                }

                Action <string> afterSave = uid =>
                {
                    // HACK: Work around a synced-code change check.
                    // It's not clear why this is needed here, but not in the other places that load maps.
                    Game.RunAfterTick(() =>
                    {
                        ConnectionLogic.Connect(Game.CreateLocalServer(uid), "",
                                                () => Game.LoadEditor(uid),
                                                () => { Game.CloseServer(); onExit(); });
                    });

                    Ui.CloseWindow();
                    onSelect(uid);
                };

                Ui.OpenWindow("SAVE_MAP_PANEL", new WidgetArgs()
                {
                    { "onSave", afterSave },
                    { "onExit", () => { Ui.CloseWindow(); onExit(); } },
                    { "map", map },
                    { "playerDefinitions", map.PlayerDefinitions },
                    { "actorDefinitions", map.ActorDefinitions }
                });
            };
        }
        Action InitInputPanel(Widget panel)
        {
            var gs = Game.Settings.Game;
            var ks = Game.Settings.Keys;

            BindCheckboxPref(panel, "CLASSICORDERS_CHECKBOX", gs, "UseClassicMouseStyle");
            BindCheckboxPref(panel, "EDGESCROLL_CHECKBOX", gs, "ViewportEdgeScroll");
            BindCheckboxPref(panel, "LOCKMOUSE_CHECKBOX", gs, "LockMouseWindow");
            BindCheckboxPref(panel, "ALLOW_ZOOM_CHECKBOX", gs, "AllowZoom");
            BindSliderPref(panel, "SCROLLSPEED_SLIDER", gs, "ViewportEdgeScrollStep");
            BindSliderPref(panel, "UI_SCROLLSPEED_SLIDER", gs, "UIScrollSpeed");

            // Apply mouse focus preferences immediately
            var lockMouseCheckbox = panel.Get <CheckboxWidget>("LOCKMOUSE_CHECKBOX");
            var oldOnClick        = lockMouseCheckbox.OnClick;

            lockMouseCheckbox.OnClick = () =>
            {
                // Still perform the old behaviour for clicking the checkbox, before
                // applying the changes live.
                oldOnClick();

                MakeMouseFocusSettingsLive();
            };

            var middleMouseScrollDropdown = panel.Get <DropDownButtonWidget>("MIDDLE_MOUSE_SCROLL");

            middleMouseScrollDropdown.OnMouseDown = _ => ShowMouseScrollDropdown(middleMouseScrollDropdown, gs, false);
            middleMouseScrollDropdown.GetText     = () => gs.MiddleMouseScroll.ToString();

            var rightMouseScrollDropdown = panel.Get <DropDownButtonWidget>("RIGHT_MOUSE_SCROLL");

            rightMouseScrollDropdown.OnMouseDown = _ => ShowMouseScrollDropdown(rightMouseScrollDropdown, gs, true);
            rightMouseScrollDropdown.GetText     = () => gs.RightMouseScroll.ToString();

            var zoomModifierDropdown = panel.Get <DropDownButtonWidget>("ZOOM_MODIFIER");

            zoomModifierDropdown.OnMouseDown = _ => ShowZoomModifierDropdown(zoomModifierDropdown, gs);
            zoomModifierDropdown.GetText     = () => gs.ZoomModifier.ToString();

            var hotkeyList = panel.Get <ScrollPanelWidget>("HOTKEY_LIST");

            hotkeyList.Layout = new GridLayout(hotkeyList);
            var hotkeyHeader       = hotkeyList.Get <ScrollItemWidget>("HEADER");
            var globalTemplate     = hotkeyList.Get("GLOBAL_TEMPLATE");
            var unitTemplate       = hotkeyList.Get("UNIT_TEMPLATE");
            var productionTemplate = hotkeyList.Get("PRODUCTION_TEMPLATE");
            var developerTemplate  = hotkeyList.Get("DEVELOPER_TEMPLATE");

            hotkeyList.RemoveChildren();

            Func <bool> returnTrue = () => true;
            Action      doNothing  = () => { };

            // Game
            {
                var hotkeys = new Dictionary <string, string>()
                {
                    { "CycleBaseKey", "Jump to base" },
                    { "ToLastEventKey", "Jump to last radar event" },
                    { "ToSelectionKey", "Jump to selection" },
                    { "SelectAllUnitsKey", "Select all combat units" },
                    { "SelectUnitsByTypeKey", "Select units by type" },

                    { "PlaceBeaconKey", "Place beacon" },

                    { "PauseKey", "Pause / Unpause" },
                    { "SellKey", "Sell mode" },
                    { "PowerDownKey", "Power-down mode" },
                    { "RepairKey", "Repair mode" },

                    { "NextProductionTabKey", "Next production tab" },
                    { "PreviousProductionTabKey", "Previous production tab" },
                    { "CycleProductionBuildingsKey", "Cycle production facilities" },

                    { "CycleStatusBarsKey", "Cycle status bars display" },
                    { "TogglePixelDoubleKey", "Toggle pixel doubling" },
                    { "ToggleMuteKey", "Toggle audio mute" },
                    { "TogglePlayerStanceColorsKey", "Toggle player stance colors" }
                };

                var header = ScrollItemWidget.Setup(hotkeyHeader, returnTrue, doNothing);
                header.Get <LabelWidget>("LABEL").GetText = () => "Game Commands";
                hotkeyList.AddChild(header);

                foreach (var kv in hotkeys)
                {
                    BindHotkeyPref(kv, ks, globalTemplate, hotkeyList);
                }
            }

            // Viewport
            {
                var hotkeys = new Dictionary <string, string>()
                {
                    { "MapScrollUp", "Scroll up" },
                    { "MapScrollDown", "Scroll down" },
                    { "MapScrollLeft", "Scroll left" },
                    { "MapScrollRight", "Scroll right" },

                    { "MapPushTop", "Jump to top edge" },
                    { "MapPushBottom", "Jump to bottom edge" },
                    { "MapPushLeftEdge", "Jump to left edge" },
                    { "MapPushRightEdge", "Jump to right edge" },

                    { "ViewPortBookmarkSaveSlot1", "Record bookmark #1" },
                    { "ViewPortBookmarkUseSlot1", "Jump to bookmark #1" },
                    { "ViewPortBookmarkSaveSlot2", "Record bookmark #2" },
                    { "ViewPortBookmarkUseSlot2", "Jump to bookmark #2" },
                    { "ViewPortBookmarkSaveSlot3", "Record bookmark #3" },
                    { "ViewPortBookmarkUseSlot3", "Jump to bookmark #3" },
                    { "ViewPortBookmarkSaveSlot4", "Record bookmark #4" },
                    { "ViewPortBookmarkUseSlot4", "Jump to bookmark #4" }
                };

                var header = ScrollItemWidget.Setup(hotkeyHeader, returnTrue, doNothing);
                header.Get <LabelWidget>("LABEL").GetText = () => "Viewport Commands";
                hotkeyList.AddChild(header);

                foreach (var kv in hotkeys)
                {
                    BindHotkeyPref(kv, ks, globalTemplate, hotkeyList);
                }
            }

            // Observer
            {
                var hotkeys = new Dictionary <string, string>()
                {
                    { "ObserverCombinedView", "All Players" },
                    { "ObserverWorldView", "Disable Shroud" },
                    { "PauseKey", "Pause/Play" },
                    { "ReplaySpeedSlowKey", "Slow speed" },
                    { "ReplaySpeedRegularKey", "Regular speed" },
                    { "ReplaySpeedFastKey", "Fast speed" },
                    { "ReplaySpeedMaxKey", "Maximum speed" }
                };

                var header = ScrollItemWidget.Setup(hotkeyHeader, returnTrue, doNothing);
                header.Get <LabelWidget>("LABEL").GetText = () => "Observer Commands";
                hotkeyList.AddChild(header);

                foreach (var kv in hotkeys)
                {
                    BindHotkeyPref(kv, ks, globalTemplate, hotkeyList);
                }
            }

            // Unit
            {
                var hotkeys = new Dictionary <string, string>()
                {
                    { "AttackMoveKey", "Attack Move" },
                    { "StopKey", "Stop" },
                    { "ScatterKey", "Scatter" },
                    { "DeployKey", "Deploy" },
                    { "GuardKey", "Guard" }
                };

                var header = ScrollItemWidget.Setup(hotkeyHeader, returnTrue, doNothing);
                header.Get <LabelWidget>("LABEL").GetText = () => "Unit Commands";
                hotkeyList.AddChild(header);

                foreach (var kv in hotkeys)
                {
                    BindHotkeyPref(kv, ks, unitTemplate, hotkeyList);
                }
            }

            // Unit stance
            {
                var hotkeys = new Dictionary <string, string>()
                {
                    { "StanceHoldFireKey", "Hold fire" },
                    { "StanceReturnFireKey", "Return fire" },
                    { "StanceDefendKey", "Defend" },
                    { "StanceAttackAnythingKey", "Attack anything" }
                };

                var header = ScrollItemWidget.Setup(hotkeyHeader, returnTrue, doNothing);
                header.Get <LabelWidget>("LABEL").GetText = () => "Unit Stance Commands";
                hotkeyList.AddChild(header);

                foreach (var kv in hotkeys)
                {
                    BindHotkeyPref(kv, ks, globalTemplate, hotkeyList);
                }
            }

            // Production
            {
                var hotkeys = new Dictionary <string, string>()
                {
                    { "ProductionTypeBuildingKey", "Building Tab" },
                    { "ProductionTypeDefenseKey", "Defense Tab" },
                    { "ProductionTypeInfantryKey", "Infantry Tab" },
                    { "ProductionTypeVehicleKey", "Vehicle Tab" },
                    { "ProductionTypeAircraftKey", "Aircraft Tab" },
                    { "ProductionTypeNavalKey", "Naval Tab" },
                    { "ProductionTypeTankKey", "Tank Tab" },
                    { "ProductionTypeMerchantKey", "Starport Tab" },
                    { "ProductionTypeUpgradeKey", "Upgrade Tab" }
                };

                for (var i = 1; i <= 24; i++)
                {
                    hotkeys.Add("Production{0:D2}Key".F(i), "Slot {0}".F(i));
                }

                var header = ScrollItemWidget.Setup(hotkeyHeader, returnTrue, doNothing);
                header.Get <LabelWidget>("LABEL").GetText = () => "Production Commands";
                hotkeyList.AddChild(header);

                foreach (var kv in hotkeys)
                {
                    BindHotkeyPref(kv, ks, productionTemplate, hotkeyList);
                }
            }

            // Support powers
            {
                var hotkeys = new Dictionary <string, string>();
                for (var i = 1; i <= 6; i++)
                {
                    hotkeys.Add("SupportPower{0:D2}Key".F(i), "Slot {0}".F(i));
                }

                var header = ScrollItemWidget.Setup(hotkeyHeader, returnTrue, doNothing);
                header.Get <LabelWidget>("LABEL").GetText = () => "Support Power Commands";
                hotkeyList.AddChild(header);

                foreach (var kv in hotkeys)
                {
                    BindHotkeyPref(kv, ks, productionTemplate, hotkeyList);
                }
            }

            // Developer
            {
                var hotkeys = new Dictionary <string, string>()
                {
                    { "DevReloadChromeKey", "Reload Chrome" },
                    { "HideUserInterfaceKey", "Hide UI" },
                    { "TakeScreenshotKey", "Take screenshot" }
                };

                var header = ScrollItemWidget.Setup(hotkeyHeader, returnTrue, doNothing);
                header.Get <LabelWidget>("LABEL").GetText = () => "Developer Commands";
                hotkeyList.AddChild(header);

                foreach (var kv in hotkeys)
                {
                    BindHotkeyPref(kv, ks, developerTemplate, hotkeyList);
                }
            }

            // Music
            {
                var hotkeys = new Dictionary <string, string>()
                {
                    { "NextTrack", "Next" },
                    { "PreviousTrack", "Previous" },
                    { "StopMusic", "Stop" },
                    { "PauseMusic", "Pause or Resume" }
                };

                var header = ScrollItemWidget.Setup(hotkeyHeader, returnTrue, doNothing);
                header.Get <LabelWidget>("LABEL").GetText = () => "Music Commands";
                hotkeyList.AddChild(header);

                foreach (var kv in hotkeys)
                {
                    BindHotkeyPref(kv, ks, developerTemplate, hotkeyList);
                }
            }

            return(() => { });
        }
Esempio n. 9
0
        void SetupReplayDependentFilters()
        {
            // Map
            {
                var ddb = panel.GetOrNull <DropDownButtonWidget>("FLT_MAPNAME_DROPDOWNBUTTON");
                if (ddb != null)
                {
                    var options = replays.Select(r => r.GameInfo.MapTitle).Distinct(StringComparer.OrdinalIgnoreCase).ToList();
                    options.Sort(StringComparer.OrdinalIgnoreCase);
                    options.Insert(0, null);                            // no filter

                    var anyText = ddb.GetText();
                    ddb.GetText     = () => string.IsNullOrEmpty(filter.MapName) ? anyText : filter.MapName;
                    ddb.OnMouseDown = _ =>
                    {
                        Func <string, ScrollItemWidget, ScrollItemWidget> setupItem = (option, tpl) =>
                        {
                            var item = ScrollItemWidget.Setup(
                                tpl,
                                () => string.Compare(filter.MapName, option, true) == 0,
                                () => { filter.MapName = option; ApplyFilter(); });
                            item.Get <LabelWidget>("LABEL").GetText = () => option ?? anyText;
                            return(item);
                        };

                        ddb.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 330, options, setupItem);
                    };
                }
            }

            // Players
            {
                var ddb = panel.GetOrNull <DropDownButtonWidget>("FLT_PLAYER_DROPDOWNBUTTON");
                if (ddb != null)
                {
                    var options = replays.SelectMany(r => r.GameInfo.Players.Select(p => p.Name)).Distinct(StringComparer.OrdinalIgnoreCase).ToList();
                    options.Sort(StringComparer.OrdinalIgnoreCase);
                    options.Insert(0, null);                            // no filter

                    var anyText = ddb.GetText();
                    ddb.GetText     = () => string.IsNullOrEmpty(filter.PlayerName) ? anyText : filter.PlayerName;
                    ddb.OnMouseDown = _ =>
                    {
                        Func <string, ScrollItemWidget, ScrollItemWidget> setupItem = (option, tpl) =>
                        {
                            var item = ScrollItemWidget.Setup(
                                tpl,
                                () => string.Compare(filter.PlayerName, option, true) == 0,
                                () => { filter.PlayerName = option; ApplyFilter(); });
                            item.Get <LabelWidget>("LABEL").GetText = () => option ?? anyText;
                            return(item);
                        };

                        ddb.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 330, options, setupItem);
                    };
                }
            }

            // Faction (depends on Player)
            {
                var ddb = panel.GetOrNull <DropDownButtonWidget>("FLT_FACTION_DROPDOWNBUTTON");
                if (ddb != null)
                {
                    ddb.IsDisabled = () => string.IsNullOrEmpty(filter.PlayerName);

                    var options = replays
                                  .SelectMany(r => r.GameInfo.Players.Select(p => p.FactionName).Where(n => !string.IsNullOrEmpty(n)))
                                  .Distinct(StringComparer.OrdinalIgnoreCase).ToList();
                    options.Sort(StringComparer.OrdinalIgnoreCase);
                    options.Insert(0, null);                            // no filter

                    var anyText = ddb.GetText();
                    ddb.GetText     = () => string.IsNullOrEmpty(filter.Faction) ? anyText : filter.Faction;
                    ddb.OnMouseDown = _ =>
                    {
                        Func <string, ScrollItemWidget, ScrollItemWidget> setupItem = (option, tpl) =>
                        {
                            var item = ScrollItemWidget.Setup(
                                tpl,
                                () => string.Compare(filter.Faction, option, true) == 0,
                                () => { filter.Faction = option; ApplyFilter(); });
                            item.Get <LabelWidget>("LABEL").GetText = () => option ?? anyText;
                            return(item);
                        };

                        ddb.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 330, options, setupItem);
                    };
                }
            }
        }
Esempio n. 10
0
        void RefreshServerListInner(IEnumerable <GameServer> games)
        {
            if (games == null)
            {
                return;
            }

            var mods = games.GroupBy(g => g.Mods)
                       .OrderByDescending(g => GroupSortOrder(g.First()))
                       .ThenByDescending(g => g.Count());

            var rows = new List <Widget>();

            foreach (var modGames in mods)
            {
                if (modGames.All(Filtered))
                {
                    continue;
                }

                var header = ScrollItemWidget.Setup(headerTemplate, () => true, () => { });

                var headerTitle = modGames.First().ModLabel;
                header.Get <LabelWidget>("LABEL").GetText = () => headerTitle;
                rows.Add(header);

                foreach (var loop in modGames.OrderByDescending(g => g.IsJoinable).ThenByDescending(g => g.Players))
                {
                    var game = loop;
                    if (game == null || Filtered(game))
                    {
                        continue;
                    }

                    var canJoin    = game.IsJoinable;
                    var compatible = game.IsCompatible;

                    var item = ScrollItemWidget.Setup(serverTemplate, () => currentServer == game, () => currentServer = game, () => Join(game));

                    var map     = Game.ModData.MapCache[game.Map];
                    var preview = item.GetOrNull <MapPreviewWidget>("MAP_PREVIEW");
                    if (preview != null)
                    {
                        preview.Preview = () => map;
                    }

                    var title = item.GetOrNull <LabelWidget>("TITLE");
                    if (title != null)
                    {
                        title.GetText  = () => game.Name;
                        title.GetColor = () => !compatible ? incompatibleGameColor : !canJoin ? cantJoinGameColor : title.TextColor;
                    }

                    var maptitle = item.GetOrNull <LabelWidget>("MAP");
                    if (maptitle != null)
                    {
                        maptitle.GetText  = () => map.Title;
                        maptitle.GetColor = () => !compatible ? Color.DarkGray : !canJoin ? Color.LightGray : maptitle.TextColor;
                    }

                    var players = item.GetOrNull <LabelWidget>("PLAYERS");
                    if (players != null)
                    {
                        players.GetText = () => "{0} / {1}".F(game.Players, game.MaxPlayers)
                                          + (game.Spectators > 0 ? "  ({0} Spectator{1})".F(game.Spectators, game.Spectators > 1 ? "s" : "") : "");
                        players.GetColor = () => !compatible ? incompatibleGameColor : !canJoin ? cantJoinGameColor : players.TextColor;
                    }

                    var state = item.GetOrNull <LabelWidget>("STATE");
                    if (state != null)
                    {
                        state.GetText  = () => GetStateLabel(game);
                        state.GetColor = () => GetStateColor(game, state, !compatible || !canJoin);
                    }

                    var ip = item.GetOrNull <LabelWidget>("IP");
                    if (ip != null)
                    {
                        ip.GetText  = () => game.Address;
                        ip.GetColor = () => !compatible ? incompatibleGameColor : !canJoin ? cantJoinGameColor : ip.TextColor;
                    }

                    var location = item.GetOrNull <LabelWidget>("LOCATION");
                    if (location != null)
                    {
                        var cachedServerLocation = GeoIP.LookupCountry(game.Address.Split(':')[0]);
                        location.GetText  = () => cachedServerLocation;
                        location.GetColor = () => !compatible ? incompatibleGameColor : !canJoin ? cantJoinGameColor : location.TextColor;
                    }

                    rows.Add(item);
                }
            }

            Game.RunAfterTick(() =>
            {
                serverList.RemoveChildren();
                currentServer = null;

                if (games == null)
                {
                    searchStatus = SearchStatus.Failed;
                    return;
                }

                if (!games.Any())
                {
                    searchStatus = SearchStatus.NoGames;
                    return;
                }

                currentServer = games.FirstOrDefault();
                searchStatus  = SearchStatus.Hidden;

                // Search for any unknown maps
                if (Game.Settings.Game.AllowDownloading)
                {
                    Game.ModData.MapCache.QueryRemoteMapDetails(games.Where(g => !Filtered(g)).Select(g => g.Map));
                }

                foreach (var row in rows)
                {
                    serverList.AddChild(row);
                }
            });
        }
Esempio n. 11
0
        public AssetBrowserLogic(Widget widget, Action onExit, World world)
        {
            this.world = world;

            panel       = widget;
            assetSource = GlobalFileSystem.MountedFolders.First();

            var ticker = panel.GetOrNull <LogicTickerWidget>("ANIMATION_TICKER");

            if (ticker != null)
            {
                ticker.OnTick = () =>
                {
                    if (animateFrames)
                    {
                        SelectNextFrame();
                    }
                };
            }

            var sourceDropdown = panel.GetOrNull <DropDownButtonWidget>("SOURCE_SELECTOR");

            if (sourceDropdown != null)
            {
                sourceDropdown.OnMouseDown = _ => ShowSourceDropdown(sourceDropdown);
                sourceDropdown.GetText     = () =>
                {
                    var name = assetSource != null?assetSource.Name.Replace(Platform.SupportDir, "^") : "All Packages";

                    if (name.Length > 15)
                    {
                        name = "..." + name.Substring(name.Length - 15);
                    }

                    return(name);
                };
            }

            var spriteWidget = panel.GetOrNull <SpriteWidget>("SPRITE");

            if (spriteWidget != null)
            {
                spriteWidget.GetSprite  = () => currentSprites != null ? currentSprites[currentFrame] : null;
                currentPalette          = spriteWidget.Palette;
                spriteWidget.GetPalette = () => currentPalette;
            }

            var paletteDropDown = panel.GetOrNull <DropDownButtonWidget>("PALETTE_SELECTOR");

            if (paletteDropDown != null)
            {
                paletteDropDown.OnMouseDown = _ => ShowPaletteDropdown(paletteDropDown, world);
                paletteDropDown.GetText     = () => currentPalette;
            }

            var colorPreview = panel.GetOrNull <ColorPreviewManagerWidget>("COLOR_MANAGER");

            if (colorPreview != null)
            {
                colorPreview.Color = Game.Settings.Player.Color;
            }

            var colorDropdown = panel.GetOrNull <DropDownButtonWidget>("COLOR");

            if (colorDropdown != null)
            {
                colorDropdown.IsDisabled  = () => currentPalette != colorPreview.Palette;
                colorDropdown.OnMouseDown = _ => ShowColorDropDown(colorDropdown, colorPreview, world);
                panel.Get <ColorBlockWidget>("COLORBLOCK").GetColor = () => Game.Settings.Player.Color.RGB;
            }

            filenameInput            = panel.Get <TextFieldWidget>("FILENAME_INPUT");
            filenameInput.OnEnterKey = () => LoadAsset(filenameInput.Text);

            var frameContainer = panel.GetOrNull("FRAME_SELECTOR");

            if (frameContainer != null)
            {
                frameContainer.IsVisible = () => currentSprites != null && currentSprites.Length > 1;
            }

            frameSlider           = panel.Get <SliderWidget>("FRAME_SLIDER");
            frameSlider.OnChange += x => { currentFrame = (int)Math.Round(x); };
            frameSlider.GetValue  = () => currentFrame;

            var frameText = panel.GetOrNull <LabelWidget>("FRAME_COUNT");

            if (frameText != null)
            {
                frameText.GetText = () => "{0} / {1}".F(currentFrame + 1, currentSprites.Length);
            }

            var playButton = panel.GetOrNull <ButtonWidget>("BUTTON_PLAY");

            if (playButton != null)
            {
                playButton.OnClick   = () => animateFrames = true;
                playButton.IsVisible = () => !animateFrames;
            }

            var pauseButton = panel.GetOrNull <ButtonWidget>("BUTTON_PAUSE");

            if (pauseButton != null)
            {
                pauseButton.OnClick   = () => animateFrames = false;
                pauseButton.IsVisible = () => animateFrames;
            }

            var stopButton = panel.GetOrNull <ButtonWidget>("BUTTON_STOP");

            if (stopButton != null)
            {
                stopButton.OnClick = () =>
                {
                    frameSlider.Value = 0;
                    currentFrame      = 0;
                    animateFrames     = false;
                };
            }

            var nextButton = panel.GetOrNull <ButtonWidget>("BUTTON_NEXT");

            if (nextButton != null)
            {
                nextButton.OnClick = SelectNextFrame;
            }

            var prevButton = panel.GetOrNull <ButtonWidget>("BUTTON_PREV");

            if (prevButton != null)
            {
                prevButton.OnClick = SelectPreviousFrame;
            }

            var loadButton = panel.GetOrNull <ButtonWidget>("LOAD_BUTTON");

            if (loadButton != null)
            {
                loadButton.OnClick = () => LoadAsset(filenameInput.Text);
            }

            assetList = panel.Get <ScrollPanelWidget>("ASSET_LIST");
            template  = panel.Get <ScrollItemWidget>("ASSET_TEMPLATE");
            PopulateAssetList();

            var closeButton = panel.GetOrNull <ButtonWidget>("CLOSE_BUTTON");

            if (closeButton != null)
            {
                closeButton.OnClick = () => { Ui.CloseWindow(); onExit(); }
            }
            ;
        }

        void SelectNextFrame()
        {
            currentFrame++;
            if (currentFrame >= currentSprites.Length)
            {
                currentFrame = 0;
            }
        }

        void SelectPreviousFrame()
        {
            currentFrame--;
            if (currentFrame < 0)
            {
                currentFrame = currentSprites.Length - 1;
            }
        }

        void AddAsset(ScrollPanelWidget list, string filepath, ScrollItemWidget template)
        {
            var filename = Path.GetFileName(filepath);
            var item     = ScrollItemWidget.Setup(template,
                                                  () => currentFilename == filename,
                                                  () => { filenameInput.Text = filename; LoadAsset(filename); });

            item.Get <LabelWidget>("TITLE").GetText = () => filepath;

            list.AddChild(item);
        }

        bool LoadAsset(string filename)
        {
            if (string.IsNullOrEmpty(filename))
            {
                return(false);
            }

            if (!GlobalFileSystem.Exists(filename))
            {
                return(false);
            }

            currentFilename          = filename;
            currentSprites           = world.Map.SequenceProvider.SpriteLoader.LoadAllSprites(filename);
            currentFrame             = 0;
            frameSlider.MaximumValue = (float)currentSprites.Length - 1;
            frameSlider.Ticks        = currentSprites.Length;

            return(true);
        }

        bool ShowSourceDropdown(DropDownButtonWidget dropdown)
        {
            Func <IFolder, ScrollItemWidget, ScrollItemWidget> setupItem = (source, itemTemplate) =>
            {
                var item = ScrollItemWidget.Setup(itemTemplate,
                                                  () => assetSource == source,
                                                  () => { assetSource = source; PopulateAssetList(); });
                item.Get <LabelWidget>("LABEL").GetText = () => source != null?source.Name.Replace(Platform.SupportDir, "^") : "All Packages";

                return(item);
            };

            // TODO: Re-enable "All Packages" once list generation is done in a background thread
            // var sources = new[] { (IFolder)null }.Concat(GlobalFileSystem.MountedFolders);

            var sources = GlobalFileSystem.MountedFolders;

            dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 280, sources, setupItem);
            return(true);
        }

        void PopulateAssetList()
        {
            assetList.RemoveChildren();
            availableShps.Clear();

            // TODO: This is too slow to run in the main thread
            // var files = AssetSource != null ? AssetSource.AllFileNames() :
            // GlobalFileSystem.MountedFolders.SelectMany(f => f.AllFileNames());

            if (assetSource == null)
            {
                return;
            }

            var files = assetSource.AllFileNames().OrderBy(s => s);

            foreach (var file in files)
            {
                if (AllowedExtensions.Any(ext => file.EndsWith(ext, true, CultureInfo.InvariantCulture)))
                {
                    AddAsset(assetList, file, template);
                    availableShps.Add(file);
                }
            }
        }

        bool ShowPaletteDropdown(DropDownButtonWidget dropdown, World world)
        {
            Func <PaletteFromFile, ScrollItemWidget, ScrollItemWidget> setupItem = (palette, itemTemplate) =>
            {
                var name = palette.Name;
                var item = ScrollItemWidget.Setup(itemTemplate,
                                                  () => currentPalette == name,
                                                  () => currentPalette = name);
                item.Get <LabelWidget>("LABEL").GetText = () => name;

                return(item);
            };

            var palettes = world.WorldActor.TraitsImplementing <PaletteFromFile>();

            dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 280, palettes, setupItem);
            return(true);
        }
Esempio n. 12
0
        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 TileSelectorLogic(Widget widget, WorldRenderer worldRenderer)
        {
            tileset            = worldRenderer.World.Map.Rules.TileSet;
            this.worldRenderer = worldRenderer;

            editor       = widget.Parent.Get <EditorViewportControllerWidget>("MAP_EDITOR");
            panel        = widget.Get <ScrollPanelWidget>("TILETEMPLATE_LIST");
            itemTemplate = panel.Get <ScrollItemWidget>("TILEPREVIEW_TEMPLATE");
            panel.Layout = new GridLayout(panel);

            allTemplates = tileset.Templates.Values.Select(t => new TileSelectorTemplate(t)).ToArray();

            var orderedCategories = allTemplates.SelectMany(t => t.Categories)
                                    .Distinct()
                                    .OrderBy(CategoryOrder)
                                    .ToArray();

            var searchTextField = widget.Get <TextFieldWidget>("SEARCH_TEXTFIELD");

            searchTextField.OnTextEdited = () =>
            {
                searchFilter     = searchTextField.Text.Trim();
                selectedCategory = string.IsNullOrEmpty(searchFilter) ? userSelectedCategory : null;

                InitializeTilePreview();
            };

            searchTextField.OnEscKey = () =>
            {
                searchTextField.Text = "";
                searchTextField.YieldKeyboardFocus();
                return(true);
            };

            Func <string, string> categoryTitle = s => s != null ? s : "Search Results";
            Func <string, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
            {
                var item = ScrollItemWidget.Setup(template, () => selectedCategory == option, () =>
                {
                    selectedCategory = option;
                    if (option != null)
                    {
                        userSelectedCategory = option;
                    }

                    InitializeTilePreview();
                });

                var title = categoryTitle(option);
                item.Get <LabelWidget>("LABEL").GetText = () => title;
                return(item);
            };

            var tileCategorySelector = widget.Get <DropDownButtonWidget>("CATEGORIES_DROPDOWN");

            tileCategorySelector.OnClick = () =>
            {
                if (searchTextField != null)
                {
                    searchTextField.YieldKeyboardFocus();
                }

                var categories = orderedCategories.AsEnumerable();
                if (!string.IsNullOrEmpty(searchFilter))
                {
                    var filteredCategories = allTemplates.Where(t => t.SearchTerms.Any(
                                                                    s => s.IndexOf(searchFilter, StringComparison.OrdinalIgnoreCase) >= 0))
                                             .SelectMany(t => t.Categories)
                                             .Distinct()
                                             .OrderBy(CategoryOrder);
                    categories = new string[] { null }.Concat(filteredCategories);
                }

                tileCategorySelector.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 270, categories, setupItem);
            };

            var actorCategorySelector = widget.Get <DropDownButtonWidget>("CATEGORIES_DROPDOWN");

            actorCategorySelector.GetText = () => categoryTitle(selectedCategory);

            selectedCategory = userSelectedCategory = orderedCategories.First();
            InitializeTilePreview();
        }
Esempio n. 14
0
        void EnumerateMaps(Action <string> onSelect)
        {
            var maps = Game.modData.MapCache
                       .Where(m => m.Status == MapStatus.Available && m.Map.Selectable)
                       .Where(m => m.Type == gameMode || gameMode == null)
                       .OrderBy(m => m.PlayerCount)
                       .ThenBy(m => m.Title);

            scrollpanel.RemoveChildren();
            foreach (var loop in maps)
            {
                var preview = loop;
                var item    = ScrollItemWidget.Setup(preview.Uid, itemTemplate, () => selectedUid == preview.Uid, () => selectedUid = preview.Uid, () => { Ui.CloseWindow(); onSelect(preview.Uid); });

                var titleLabel = item.Get <LabelWidget>("TITLE");
                titleLabel.GetText = () => preview.Title;

                var previewWidget = item.Get <MapPreviewWidget>("PREVIEW");
                previewWidget.IgnoreMouseOver  = true;
                previewWidget.IgnoreMouseInput = true;
                previewWidget.Preview          = () => preview;
                previewWidget.IsVisible        = () => previewWidget.RenderBounds.IntersectsWith(scrollpanel.RenderBounds);

                var previewLoadingWidget = item.GetOrNull <BackgroundWidget>("PREVIEW_PLACEHOLDER");
                if (previewLoadingWidget != null)
                {
                    previewLoadingWidget.IsVisible = () => !previewWidget.Loaded;
                }

                var detailsWidget = item.GetOrNull <LabelWidget>("DETAILS");
                if (detailsWidget != null)
                {
                    detailsWidget.GetText = () => "{0} ({1} players)".F(preview.Type, preview.PlayerCount);
                }

                var authorWidget = item.GetOrNull <LabelWidget>("AUTHOR");
                if (authorWidget != null)
                {
                    authorWidget.GetText = () => "Created by {0}".F(preview.Author);
                }

                var sizeWidget = item.GetOrNull <LabelWidget>("SIZE");
                if (sizeWidget != null)
                {
                    var size = preview.Bounds.Width + "x" + preview.Bounds.Height;
                    var numberPlayableCells = preview.Bounds.Width * preview.Bounds.Height;
                    if (numberPlayableCells >= 120 * 120)
                    {
                        size += " (Huge)";
                    }
                    else if (numberPlayableCells >= 90 * 90)
                    {
                        size += " (Large)";
                    }
                    else if (numberPlayableCells >= 60 * 60)
                    {
                        size += " (Medium)";
                    }
                    else
                    {
                        size += " (Small)";
                    }
                    sizeWidget.GetText = () => size;
                }

                scrollpanel.AddChild(item);
            }

            visibleMaps = maps.Select(m => m.Uid).ToList();
            if (visibleMaps.Contains(selectedUid))
            {
                scrollpanel.ScrollToItem(selectedUid);
            }
        }
Esempio n. 15
0
        internal LobbyLogic(Widget widget, ModData modData, WorldRenderer worldRenderer, OrderManager orderManager,
                            Action onExit, Action onStart, bool skirmishMode)
        {
            map               = MapCache.UnknownMap;
            lobby             = widget;
            this.modData      = modData;
            this.orderManager = orderManager;
            this.onStart      = onStart;
            this.onExit       = onExit;
            this.skirmishMode = skirmishMode;

            // TODO: This needs to be reworked to support per-map tech levels, bots, etc.
            this.modRules = modData.DefaultRules;
            shellmapWorld = worldRenderer.World;

            services = modData.Manifest.Get <WebServices>();

            orderManager.AddChatLine    += AddChatLine;
            Game.LobbyInfoChanged       += UpdateCurrentMap;
            Game.LobbyInfoChanged       += UpdatePlayerList;
            Game.BeforeGameStart        += OnGameStart;
            Game.ConnectionStateChanged += ConnectionStateChanged;

            var name = lobby.GetOrNull <LabelWidget>("SERVER_NAME");

            if (name != null)
            {
                name.GetText = () => orderManager.LobbyInfo.GlobalSettings.ServerName;
            }

            var mapContainer = Ui.LoadWidget("MAP_PREVIEW", lobby.Get("MAP_PREVIEW_ROOT"), new WidgetArgs
            {
                { "orderManager", orderManager },
                { "getMap", (Func <MapPreview>)(() => map) },
                { "onMouseDown", (Action <MapPreviewWidget, MapPreview, MouseInput>)((preview, mapPreview, mi) =>
                                                                                     LobbyUtils.SelectSpawnPoint(orderManager, preview, mapPreview, mi)) },
                { "getSpawnOccupants", (Func <MapPreview, Dictionary <CPos, SpawnOccupant> >)(mapPreview => LobbyUtils.GetSpawnOccupants(orderManager.LobbyInfo, mapPreview)) },
                { "showUnoccupiedSpawnpoints", true },
            });

            mapContainer.IsVisible = () => panel != PanelType.Servers;

            UpdateCurrentMap();

            var playerBin = Ui.LoadWidget("LOBBY_PLAYER_BIN", lobby.Get("TOP_PANELS_ROOT"), new WidgetArgs());

            playerBin.IsVisible = () => panel == PanelType.Players;

            players = playerBin.Get <ScrollPanelWidget>("LOBBY_PLAYERS");
            editablePlayerTemplate       = players.Get("TEMPLATE_EDITABLE_PLAYER");
            nonEditablePlayerTemplate    = players.Get("TEMPLATE_NONEDITABLE_PLAYER");
            emptySlotTemplate            = players.Get("TEMPLATE_EMPTY");
            editableSpectatorTemplate    = players.Get("TEMPLATE_EDITABLE_SPECTATOR");
            nonEditableSpectatorTemplate = players.Get("TEMPLATE_NONEDITABLE_SPECTATOR");
            newSpectatorTemplate         = players.Get("TEMPLATE_NEW_SPECTATOR");
            colorPreview       = lobby.Get <ColorPreviewManagerWidget>("COLOR_MANAGER");
            colorPreview.Color = Game.Settings.Player.Color;

            foreach (var f in modRules.Actors["world"].TraitInfos <FactionInfo>())
            {
                factions.Add(f.InternalName, new LobbyFaction {
                    Selectable = f.Selectable, Name = f.Name, Side = f.Side, Description = f.Description
                });
            }

            var         gameStarting          = false;
            Func <bool> configurationDisabled = () => !Game.IsHost || gameStarting ||
                                                panel == PanelType.Kick || panel == PanelType.ForceStart ||
                                                !map.RulesLoaded || map.InvalidCustomRules ||
                                                orderManager.LocalClient == null || orderManager.LocalClient.IsReady;

            var mapButton = lobby.GetOrNull <ButtonWidget>("CHANGEMAP_BUTTON");

            if (mapButton != null)
            {
                mapButton.IsVisible  = () => panel != PanelType.Servers;
                mapButton.IsDisabled = () => gameStarting || panel == PanelType.Kick || panel == PanelType.ForceStart ||
                                       orderManager.LocalClient == null || orderManager.LocalClient.IsReady;
                mapButton.OnClick = () =>
                {
                    var onSelect = new Action <string>(uid =>
                    {
                        // Don't select the same map again
                        if (uid == map.Uid)
                        {
                            return;
                        }

                        orderManager.IssueOrder(Order.Command("map " + uid));
                        Game.Settings.Server.Map = uid;
                        Game.Settings.Save();
                    });

                    Ui.OpenWindow("MAPCHOOSER_PANEL", new WidgetArgs()
                    {
                        { "initialMap", map.Uid },
                        { "initialTab", MapClassification.System },
                        { "onExit", DoNothing },
                        { "onSelect", Game.IsHost ? onSelect : null },
                        { "filter", MapVisibility.Lobby },
                    });
                };
            }

            var slotsButton = lobby.GetOrNull <DropDownButtonWidget>("SLOTS_DROPDOWNBUTTON");

            if (slotsButton != null)
            {
                slotsButton.IsVisible  = () => panel != PanelType.Servers;
                slotsButton.IsDisabled = () => configurationDisabled() || panel != PanelType.Players ||
                                         (orderManager.LobbyInfo.Slots.Values.All(s => !s.AllowBots) &&
                                          orderManager.LobbyInfo.Slots.Count(s => !s.Value.LockTeam && orderManager.LobbyInfo.ClientInSlot(s.Key) != null) == 0);

                slotsButton.OnMouseDown = _ =>
                {
                    var botTypes = map.Rules.Actors["player"].TraitInfos <IBotInfo>().Select(t => t.Type);
                    var options  = new Dictionary <string, IEnumerable <DropDownOption> >();

                    var botController = orderManager.LobbyInfo.Clients.FirstOrDefault(c => c.IsAdmin);
                    if (orderManager.LobbyInfo.Slots.Values.Any(s => s.AllowBots))
                    {
                        var botOptions = new List <DropDownOption>()
                        {
                            new DropDownOption()
                            {
                                Title      = "Add",
                                IsSelected = () => false,
                                OnClick    = () =>
                                {
                                    foreach (var slot in orderManager.LobbyInfo.Slots)
                                    {
                                        var bot = botTypes.Random(Game.CosmeticRandom);
                                        var c   = orderManager.LobbyInfo.ClientInSlot(slot.Key);
                                        if (slot.Value.AllowBots == true && (c == null || c.Bot != null))
                                        {
                                            orderManager.IssueOrder(Order.Command("slot_bot {0} {1} {2}".F(slot.Key, botController.Index, bot)));
                                        }
                                    }
                                }
                            }
                        };

                        if (orderManager.LobbyInfo.Clients.Any(c => c.Bot != null))
                        {
                            botOptions.Add(new DropDownOption()
                            {
                                Title      = "Remove",
                                IsSelected = () => false,
                                OnClick    = () =>
                                {
                                    foreach (var slot in orderManager.LobbyInfo.Slots)
                                    {
                                        var c = orderManager.LobbyInfo.ClientInSlot(slot.Key);
                                        if (c != null && c.Bot != null)
                                        {
                                            orderManager.IssueOrder(Order.Command("slot_open " + slot.Value.PlayerReference));
                                        }
                                    }
                                }
                            });
                        }

                        options.Add("Configure Bots", botOptions);
                    }

                    var teamCount = (orderManager.LobbyInfo.Slots.Count(s => !s.Value.LockTeam && orderManager.LobbyInfo.ClientInSlot(s.Key) != null) + 1) / 2;
                    if (teamCount >= 1)
                    {
                        var teamOptions = Enumerable.Range(2, teamCount - 1).Reverse().Select(d => new DropDownOption
                        {
                            Title      = "{0} Teams".F(d),
                            IsSelected = () => false,
                            OnClick    = () => orderManager.IssueOrder(Order.Command("assignteams {0}".F(d.ToString())))
                        }).ToList();

                        if (orderManager.LobbyInfo.Slots.Any(s => s.Value.AllowBots))
                        {
                            teamOptions.Add(new DropDownOption
                            {
                                Title      = "Humans vs Bots",
                                IsSelected = () => false,
                                OnClick    = () => orderManager.IssueOrder(Order.Command("assignteams 1"))
                            });
                        }

                        teamOptions.Add(new DropDownOption
                        {
                            Title      = "Free for all",
                            IsSelected = () => false,
                            OnClick    = () => orderManager.IssueOrder(Order.Command("assignteams 0"))
                        });

                        options.Add("Configure Teams", teamOptions);
                    }

                    Func <DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get <LabelWidget>("LABEL").GetText = () => option.Title;
                        return(item);
                    };
                    slotsButton.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 175, options, setupItem);
                };
            }

            var optionsBin = Ui.LoadWidget("LOBBY_OPTIONS_BIN", lobby.Get("TOP_PANELS_ROOT"), new WidgetArgs()
            {
                { "orderManager", orderManager },
                { "getMap", (Func <MapPreview>)(() => map) },
                { "configurationDisabled", configurationDisabled }
            });

            optionsBin.IsVisible = () => panel == PanelType.Options;

            var musicBin = Ui.LoadWidget("LOBBY_MUSIC_BIN", lobby.Get("TOP_PANELS_ROOT"), new WidgetArgs
            {
                { "onExit", DoNothing },
                { "world", worldRenderer.World }
            });

            musicBin.IsVisible = () => panel == PanelType.Music;

            ServerListLogic serverListLogic = null;

            if (!skirmishMode)
            {
                Action <GameServer> doNothingWithServer = _ => { };

                var serversBin = Ui.LoadWidget("LOBBY_SERVERS_BIN", lobby.Get("TOP_PANELS_ROOT"), new WidgetArgs
                {
                    { "onJoin", doNothingWithServer },
                });

                serverListLogic      = serversBin.LogicObjects.Select(l => l as ServerListLogic).FirstOrDefault(l => l != null);
                serversBin.IsVisible = () => panel == PanelType.Servers;
            }

            var tabContainer = skirmishMode ? lobby.Get("SKIRMISH_TABS") : lobby.Get("MULTIPLAYER_TABS");

            tabContainer.IsVisible = () => true;

            var optionsTab = tabContainer.Get <ButtonWidget>("OPTIONS_TAB");

            optionsTab.IsHighlighted = () => panel == PanelType.Options;
            optionsTab.IsDisabled    = OptionsTabDisabled;
            optionsTab.OnClick       = () => panel = PanelType.Options;
            optionsTab.GetText       = () => !map.RulesLoaded ? "Loading..." : optionsTab.Text;

            var playersTab = tabContainer.Get <ButtonWidget>("PLAYERS_TAB");

            playersTab.IsHighlighted = () => panel == PanelType.Players;
            playersTab.IsDisabled    = () => panel == PanelType.Kick || panel == PanelType.ForceStart;
            playersTab.OnClick       = () => panel = PanelType.Players;

            var musicTab = tabContainer.Get <ButtonWidget>("MUSIC_TAB");

            musicTab.IsHighlighted = () => panel == PanelType.Music;
            musicTab.IsDisabled    = () => panel == PanelType.Kick || panel == PanelType.ForceStart;
            musicTab.OnClick       = () => panel = PanelType.Music;

            var serversTab = tabContainer.GetOrNull <ButtonWidget>("SERVERS_TAB");

            if (serversTab != null)
            {
                serversTab.IsHighlighted = () => panel == PanelType.Servers;
                serversTab.IsDisabled    = () => panel == PanelType.Kick || panel == PanelType.ForceStart;
                serversTab.OnClick       = () =>
                {
                    // Refresh the list when switching to the servers tab
                    if (serverListLogic != null && panel != PanelType.Servers)
                    {
                        serverListLogic.RefreshServerList();
                    }

                    panel = PanelType.Servers;
                };
            }

            // Force start panel
            Action startGame = () =>
            {
                gameStarting = true;
                orderManager.IssueOrder(Order.Command("startgame"));
            };

            var startGameButton = lobby.GetOrNull <ButtonWidget>("START_GAME_BUTTON");

            if (startGameButton != null)
            {
                startGameButton.IsDisabled = () => configurationDisabled() || map.Status != MapStatus.Available ||
                                             orderManager.LobbyInfo.Slots.Any(sl => sl.Value.Required && orderManager.LobbyInfo.ClientInSlot(sl.Key) == null) ||
                                             (!orderManager.LobbyInfo.GlobalSettings.EnableSingleplayer && orderManager.LobbyInfo.NonBotPlayers.Count() < 2);

                startGameButton.OnClick = () =>
                {
                    // Bots and admins don't count
                    if (orderManager.LobbyInfo.Clients.Any(c => c.Slot != null && !c.IsAdmin && c.Bot == null && !c.IsReady))
                    {
                        panel = PanelType.ForceStart;
                    }
                    else
                    {
                        startGame();
                    }
                };
            }

            var forceStartBin = Ui.LoadWidget("FORCE_START_DIALOG", lobby.Get("TOP_PANELS_ROOT"), new WidgetArgs());

            forceStartBin.IsVisible = () => panel == PanelType.ForceStart;
            forceStartBin.Get("KICK_WARNING").IsVisible               = () => orderManager.LobbyInfo.Clients.Any(c => c.IsInvalid);
            forceStartBin.Get <ButtonWidget>("OK_BUTTON").OnClick     = startGame;
            forceStartBin.Get <ButtonWidget>("CANCEL_BUTTON").OnClick = () => panel = PanelType.Players;

            var disconnectButton = lobby.Get <ButtonWidget>("DISCONNECT_BUTTON");

            disconnectButton.OnClick = () => { Ui.CloseWindow(); onExit(); };

            if (skirmishMode)
            {
                disconnectButton.Text = "Back";
            }

            chatLabel = lobby.Get <LabelWidget>("LABEL_CHATTYPE");
            var chatTextField = lobby.Get <TextFieldWidget>("CHAT_TEXTFIELD");

            chatTextField.MaxLength = UnitOrders.ChatMessageMaxLength;

            chatTextField.TakeKeyboardFocus();
            chatTextField.OnEnterKey = () =>
            {
                if (chatTextField.Text.Length == 0)
                {
                    return(true);
                }

                // Always scroll to bottom when we've typed something
                lobbyChatPanel.ScrollToBottom();

                orderManager.IssueOrder(Order.Chat(teamChat, chatTextField.Text));
                chatTextField.Text = "";
                return(true);
            };

            chatTextField.OnTabKey = () =>
            {
                var previousText = chatTextField.Text;
                chatTextField.Text           = tabCompletion.Complete(chatTextField.Text);
                chatTextField.CursorPosition = chatTextField.Text.Length;

                if (chatTextField.Text == previousText)
                {
                    return(SwitchTeamChat());
                }
                else
                {
                    return(true);
                }
            };

            chatTextField.OnEscKey = () => { chatTextField.Text = ""; return(true); };

            lobbyChatPanel = lobby.Get <ScrollPanelWidget>("CHAT_DISPLAY");
            chatTemplate   = lobbyChatPanel.Get("CHAT_TEMPLATE");
            lobbyChatPanel.RemoveChildren();

            var settingsButton = lobby.GetOrNull <ButtonWidget>("SETTINGS_BUTTON");

            if (settingsButton != null)
            {
                settingsButton.OnClick = () => Ui.OpenWindow("SETTINGS_PANEL", new WidgetArgs
                {
                    { "onExit", DoNothing },
                    { "worldRenderer", worldRenderer }
                });
            }

            // Add a bot on the first lobbyinfo update
            if (skirmishMode)
            {
                addBotOnMapLoad = true;
            }
        }
Esempio n. 16
0
        void SelectReplay(ReplayMetadata replay)
        {
            selectedReplay = replay;
            map            = selectedReplay != null ? selectedReplay.GameInfo.MapPreview : MapCache.UnknownMap;

            if (replay == null)
            {
                return;
            }

            try
            {
                if (map.Status != MapStatus.Available)
                {
                    if (map.Status == MapStatus.DownloadAvailable)
                    {
                        LoadMapPreviewRules(map);
                    }
                    else if (Game.Settings.Game.AllowDownloading)
                    {
                        modData.MapCache.QueryRemoteMapDetails(services.MapRepository, new[] { map.Uid }, LoadMapPreviewRules);
                    }
                }

                var players = replay.GameInfo.Players
                              .GroupBy(p => p.Team)
                              .OrderBy(g => g.Key);

                var teams   = new Dictionary <string, IEnumerable <GameInformation.Player> >();
                var noTeams = players.Count() == 1;
                foreach (var p in players)
                {
                    var label = noTeams ? "Players" : p.Key == 0 ? "No Team" : "Team {0}".F(p.Key);
                    teams.Add(label, p);
                }

                playerList.RemoveChildren();

                foreach (var kv in teams)
                {
                    var group = kv.Key;
                    if (group.Length > 0)
                    {
                        var header = ScrollItemWidget.Setup(playerHeader, () => true, () => { });
                        header.Get <LabelWidget>("LABEL").GetText = () => group;
                        playerList.AddChild(header);
                    }

                    foreach (var option in kv.Value)
                    {
                        var o = option;

                        var color = o.Color.RGB;

                        var item = ScrollItemWidget.Setup(playerTemplate, () => false, () => { });

                        var label = item.Get <LabelWidget>("LABEL");
                        var font  = Game.Renderer.Fonts[label.Font];
                        var name  = WidgetUtils.TruncateText(o.Name, label.Bounds.Width, font);
                        label.GetText  = () => name;
                        label.GetColor = () => color;

                        var flag = item.Get <ImageWidget>("FLAG");
                        flag.GetImageCollection = () => "flags";
                        var factionInfo = modData.DefaultRules.Actors["world"].TraitInfos <FactionInfo>();
                        flag.GetImageName = () => (factionInfo != null && factionInfo.Any(f => f.InternalName == o.FactionId)) ? o.FactionId : "Random";

                        playerList.AddChild(item);
                    }
                }
            }
            catch (Exception e)
            {
                Log.Write("debug", "Exception while parsing replay: {0}", e);
                SelectReplay(null);
            }
        }
Esempio n. 17
0
        public AssetBrowserLogic(Widget widget, Action onExit, ModData modData, World world, Dictionary <string, MiniYaml> logicArgs)
        {
            this.world   = world;
            this.modData = modData;
            panel        = widget;

            var ticker = panel.GetOrNull <LogicTickerWidget>("ANIMATION_TICKER");

            if (ticker != null)
            {
                ticker.OnTick = () =>
                {
                    if (animateFrames)
                    {
                        SelectNextFrame();
                    }
                };
            }

            var sourceDropdown = panel.GetOrNull <DropDownButtonWidget>("SOURCE_SELECTOR");

            if (sourceDropdown != null)
            {
                sourceDropdown.OnMouseDown = _ => ShowSourceDropdown(sourceDropdown);
                sourceDropdown.GetText     = () =>
                {
                    var name = assetSource != null?Platform.UnresolvePath(assetSource.Name) : "All Packages";

                    if (name.Length > 15)
                    {
                        name = "..." + name.Substring(name.Length - 15);
                    }

                    return(name);
                };
            }

            var spriteWidget = panel.GetOrNull <SpriteWidget>("SPRITE");

            if (spriteWidget != null)
            {
                spriteWidget.GetSprite  = () => currentSprites != null ? currentSprites[currentFrame] : null;
                currentPalette          = spriteWidget.Palette;
                spriteWidget.GetPalette = () => currentPalette;
                spriteWidget.IsVisible  = () => !isVideoLoaded && !IsErrorLabelVisible;
            }

            var playerWidget = panel.GetOrNull <VqaPlayerWidget>("PLAYER");

            if (playerWidget != null)
            {
                playerWidget.IsVisible = () => isVideoLoaded && !IsErrorLabelVisible;
            }

            errorLabelWidget = panel.GetOrNull <LabelWidget>("ERROR");
            if (errorLabelWidget != null)
            {
                errorFont = Game.Renderer.Fonts[errorLabelWidget.Font];
            }

            var paletteDropDown = panel.GetOrNull <DropDownButtonWidget>("PALETTE_SELECTOR");

            if (paletteDropDown != null)
            {
                paletteDropDown.OnMouseDown = _ => ShowPaletteDropdown(paletteDropDown, world);
                paletteDropDown.GetText     = () => currentPalette;
            }

            var colorPreview = panel.GetOrNull <ColorPreviewManagerWidget>("COLOR_MANAGER");

            if (colorPreview != null)
            {
                colorPreview.Color = Game.Settings.Player.Color;
            }

            var colorDropdown = panel.GetOrNull <DropDownButtonWidget>("COLOR");

            if (colorDropdown != null)
            {
                colorDropdown.IsDisabled  = () => currentPalette != colorPreview.PaletteName;
                colorDropdown.OnMouseDown = _ => ColorPickerLogic.ShowColorDropDown(colorDropdown, colorPreview, world);
                panel.Get <ColorBlockWidget>("COLORBLOCK").GetColor = () => Game.Settings.Player.Color.RGB;
            }

            filenameInput = panel.Get <TextFieldWidget>("FILENAME_INPUT");
            filenameInput.OnTextEdited = () => ApplyFilter(filenameInput.Text);
            filenameInput.OnEscKey     = filenameInput.YieldKeyboardFocus;

            var frameContainer = panel.GetOrNull("FRAME_SELECTOR");

            if (frameContainer != null)
            {
                frameContainer.IsVisible = () => (currentSprites != null && currentSprites.Length > 1) ||
                                           (isVideoLoaded && player != null && player.Video != null && player.Video.Frames > 1);
            }

            frameSlider = panel.Get <SliderWidget>("FRAME_SLIDER");
            if (frameSlider != null)
            {
                frameSlider.OnChange += x =>
                {
                    if (!isVideoLoaded)
                    {
                        currentFrame = (int)Math.Round(x);
                    }
                };

                frameSlider.GetValue   = () => isVideoLoaded ? player.Video.CurrentFrame : currentFrame;
                frameSlider.IsDisabled = () => isVideoLoaded;
            }

            var frameText = panel.GetOrNull <LabelWidget>("FRAME_COUNT");

            if (frameText != null)
            {
                frameText.GetText = () =>
                                    isVideoLoaded ?
                                    "{0} / {1}".F(player.Video.CurrentFrame + 1, player.Video.Frames) :
                                    "{0} / {1}".F(currentFrame, currentSprites.Length - 1);
            }

            var playButton = panel.GetOrNull <ButtonWidget>("BUTTON_PLAY");

            if (playButton != null)
            {
                playButton.Key     = new Hotkey(Keycode.SPACE, Modifiers.None);
                playButton.OnClick = () =>
                {
                    if (isVideoLoaded)
                    {
                        player.Play();
                    }
                    else
                    {
                        animateFrames = true;
                    }
                };

                playButton.IsVisible = () => isVideoLoaded ? player.Paused : !animateFrames;
            }

            var pauseButton = panel.GetOrNull <ButtonWidget>("BUTTON_PAUSE");

            if (pauseButton != null)
            {
                pauseButton.Key     = new Hotkey(Keycode.SPACE, Modifiers.None);
                pauseButton.OnClick = () =>
                {
                    if (isVideoLoaded)
                    {
                        player.Pause();
                    }
                    else
                    {
                        animateFrames = false;
                    }
                };

                pauseButton.IsVisible = () => isVideoLoaded ? !player.Paused : animateFrames;
            }

            var stopButton = panel.GetOrNull <ButtonWidget>("BUTTON_STOP");

            if (stopButton != null)
            {
                stopButton.Key     = new Hotkey(Keycode.RETURN, Modifiers.None);
                stopButton.OnClick = () =>
                {
                    if (isVideoLoaded)
                    {
                        player.Stop();
                    }
                    else
                    {
                        frameSlider.Value = 0;
                        currentFrame      = 0;
                        animateFrames     = false;
                    }
                };
            }

            var nextButton = panel.GetOrNull <ButtonWidget>("BUTTON_NEXT");

            if (nextButton != null)
            {
                nextButton.Key     = new Hotkey(Keycode.RIGHT, Modifiers.None);
                nextButton.OnClick = () =>
                {
                    if (!isVideoLoaded)
                    {
                        nextButton.OnClick = SelectNextFrame;
                    }
                };

                nextButton.IsVisible = () => !isVideoLoaded;
            }

            var prevButton = panel.GetOrNull <ButtonWidget>("BUTTON_PREV");

            if (prevButton != null)
            {
                prevButton.Key     = new Hotkey(Keycode.LEFT, Modifiers.None);
                prevButton.OnClick = () =>
                {
                    if (!isVideoLoaded)
                    {
                        SelectPreviousFrame();
                    }
                };

                prevButton.IsVisible = () => !isVideoLoaded;
            }

            if (logicArgs.ContainsKey("SupportedFormats"))
            {
                allowedExtensions = FieldLoader.GetValue <string[]>("SupportedFormats", logicArgs["SupportedFormats"].Value);
            }
            else
            {
                allowedExtensions = new string[0];
            }

            acceptablePackages = modData.ModFiles.MountedPackages.Where(p =>
                                                                        p.Contents.Any(c => allowedExtensions.Contains(Path.GetExtension(c).ToLowerInvariant())));

            assetList = panel.Get <ScrollPanelWidget>("ASSET_LIST");
            template  = panel.Get <ScrollItemWidget>("ASSET_TEMPLATE");
            PopulateAssetList();

            var closeButton = panel.GetOrNull <ButtonWidget>("CLOSE_BUTTON");

            if (closeButton != null)
            {
                closeButton.OnClick = () =>
                {
                    if (isVideoLoaded)
                    {
                        player.Stop();
                    }
                    Ui.CloseWindow();
                    onExit();
                }
            }
            ;
        }

        void SelectNextFrame()
        {
            currentFrame++;
            if (currentFrame >= currentSprites.Length)
            {
                currentFrame = 0;
            }
        }

        void SelectPreviousFrame()
        {
            currentFrame--;
            if (currentFrame < 0)
            {
                currentFrame = currentSprites.Length - 1;
            }
        }

        Dictionary <string, bool> assetVisByName = new Dictionary <string, bool>();

        bool FilterAsset(string filename)
        {
            var filter = filenameInput.Text;

            if (string.IsNullOrWhiteSpace(filter))
            {
                return(true);
            }

            if (filename.IndexOf(filter, StringComparison.OrdinalIgnoreCase) >= 0)
            {
                return(true);
            }

            return(false);
        }

        void ApplyFilter(string filename)
        {
            assetVisByName.Clear();
            assetList.Layout.AdjustChildren();
            assetList.ScrollToTop();

            // Select the first visible
            var firstVisible = assetVisByName.FirstOrDefault(kvp => kvp.Value);

            if (firstVisible.Key != null)
            {
                LoadAsset(firstVisible.Key);
            }
        }

        void AddAsset(ScrollPanelWidget list, string filepath, ScrollItemWidget template)
        {
            var filename = Path.GetFileName(filepath);
            var item     = ScrollItemWidget.Setup(template,
                                                  () => currentFilename == filename,
                                                  () => { LoadAsset(filename); });

            item.Get <LabelWidget>("TITLE").GetText = () => filepath;
            item.IsVisible = () =>
            {
                bool visible;
                if (assetVisByName.TryGetValue(filepath, out visible))
                {
                    return(visible);
                }

                visible = FilterAsset(filepath);
                assetVisByName.Add(filepath, visible);
                return(visible);
            };

            list.AddChild(item);
        }

        bool LoadAsset(string filename)
        {
            if (isVideoLoaded)
            {
                player.Stop();
                player        = null;
                isVideoLoaded = false;
            }

            if (string.IsNullOrEmpty(filename))
            {
                return(false);
            }

            if (!modData.DefaultFileSystem.Exists(filename))
            {
                return(false);
            }

            errorLabelWidget.Visible = false;

            try
            {
                if (Path.GetExtension(filename.ToLowerInvariant()) == ".vqa")
                {
                    player          = panel.Get <VqaPlayerWidget>("PLAYER");
                    currentFilename = filename;
                    player.Load(filename);
                    player.DrawOverlay       = false;
                    isVideoLoaded            = true;
                    frameSlider.MaximumValue = (float)player.Video.Frames - 1;
                    frameSlider.Ticks        = 0;
                    return(true);
                }

                currentFilename          = filename;
                currentSprites           = world.Map.Rules.Sequences.SpriteCache[filename];
                currentFrame             = 0;
                frameSlider.MaximumValue = (float)currentSprites.Length - 1;
                frameSlider.Ticks        = currentSprites.Length;
            }
            catch (Exception ex)
            {
                if (errorLabelWidget != null)
                {
                    errorLabelWidget.Text = WidgetUtils.TruncateText(errorLabelWidget.Text.Replace("{filename}", filename),
                                                                     errorLabelWidget.Bounds.Width, errorFont);

                    currentSprites           = new Sprite[0];
                    errorLabelWidget.Visible = true;
                }

                Log.AddChannel("assetbrowser", "assetbrowser.log");
                Log.Write("assetbrowser", "Error reading {0}:{3} {1}{3}{2}", filename, ex.Message, ex.StackTrace, Environment.NewLine);

                return(false);
            }

            return(true);
        }

        bool ShowSourceDropdown(DropDownButtonWidget dropdown)
        {
            Func <IReadOnlyPackage, ScrollItemWidget, ScrollItemWidget> setupItem = (source, itemTemplate) =>
            {
                var item = ScrollItemWidget.Setup(itemTemplate,
                                                  () => assetSource == source,
                                                  () => { assetSource = source; PopulateAssetList(); });
                item.Get <LabelWidget>("LABEL").GetText = () => source != null?Platform.UnresolvePath(source.Name) : "All Packages";

                return(item);
            };

            var sources = new[] { (IReadOnlyPackage)null }.Concat(acceptablePackages);

            dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 280, sources, setupItem);
            return(true);
        }

        void PopulateAssetList()
        {
            assetList.RemoveChildren();
            availableShps.Clear();

            var files = assetSource != null ? assetSource.Contents : modData.ModFiles.MountedPackages.SelectMany(f => f.Contents).Distinct();

            foreach (var file in files.OrderBy(s => s))
            {
                if (allowedExtensions.Any(ext => file.EndsWith(ext, true, CultureInfo.InvariantCulture)))
                {
                    AddAsset(assetList, file, template);
                    availableShps.Add(file);
                }
            }
        }

        bool ShowPaletteDropdown(DropDownButtonWidget dropdown, World world)
        {
            Func <string, ScrollItemWidget, ScrollItemWidget> setupItem = (name, itemTemplate) =>
            {
                var item = ScrollItemWidget.Setup(itemTemplate,
                                                  () => currentPalette == name,
                                                  () => currentPalette = name);
                item.Get <LabelWidget>("LABEL").GetText = () => name;

                return(item);
            };

            var palettes = world.WorldActor.TraitsImplementing <IProvidesAssetBrowserPalettes>()
                           .SelectMany(p => p.PaletteNames);

            dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 280, palettes, setupItem);
            return(true);
        }
    }
Esempio n. 18
0
        public ObserverStatsLogic(World world, WorldRenderer worldRenderer, Widget widget)
        {
            this.world         = world;
            this.worldRenderer = worldRenderer;
            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");

            statsDropDown             = widget.Get <DropDownButtonWidget>("STATS_DROPDOWN");
            statsDropDown.GetText     = () => "Basic";
            statsDropDown.OnMouseDown = _ =>
            {
                var options = new List <StatsDropDownOption>
                {
                    new StatsDropDownOption
                    {
                        Title      = "Basic",
                        IsSelected = () => basicStatsHeaders.Visible,
                        OnClick    = () =>
                        {
                            ClearStats();
                            statsDropDown.GetText = () => "Basic";
                            DisplayStats(BasicStats);
                        }
                    },
                    new StatsDropDownOption
                    {
                        Title      = "Economy",
                        IsSelected = () => economyStatsHeaders.Visible,
                        OnClick    = () =>
                        {
                            ClearStats();
                            statsDropDown.GetText = () => "Economy";
                            DisplayStats(EconomyStats);
                        }
                    },
                    new StatsDropDownOption
                    {
                        Title      = "Production",
                        IsSelected = () => productionStatsHeaders.Visible,
                        OnClick    = () =>
                        {
                            ClearStats();
                            statsDropDown.GetText = () => "Production";
                            DisplayStats(ProductionStats);
                        }
                    },
                    new StatsDropDownOption
                    {
                        Title      = "Combat",
                        IsSelected = () => combatStatsHeaders.Visible,
                        OnClick    = () =>
                        {
                            ClearStats();
                            statsDropDown.GetText = () => "Combat";
                            DisplayStats(CombatStats);
                        }
                    },
                    new StatsDropDownOption
                    {
                        Title      = "Earnings (graph)",
                        IsSelected = () => earnedThisMinuteGraphHeaders.Visible,
                        OnClick    = () =>
                        {
                            ClearStats();
                            statsDropDown.GetText = () => "Earnings (graph)";
                            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.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 150, options, setupItem);
            };

            ClearStats();
            DisplayStats(BasicStats);
        }
Esempio n. 19
0
        public ActorSelectorLogic(Widget widget, World world, WorldRenderer worldRenderer)
            : base(widget, world, worldRenderer, "ACTORTEMPLATE_LIST", "ACTORPREVIEW_TEMPLATE")
        {
            mapRules       = world.Map.Rules;
            ownersDropDown = widget.Get <DropDownButtonWidget>("OWNERS_DROPDOWN");
            var editorLayer = world.WorldActor.Trait <EditorActorLayer>();

            selectedOwner = editorLayer.Players.Players.Values.First();
            Func <PlayerReference, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
            {
                var item = ScrollItemWidget.Setup(template, () => selectedOwner == option, () => SelectOwner(option));

                item.Get <LabelWidget>("LABEL").GetText = () => option.Name;
                item.GetColor = () => option.Color;

                return(item);
            };

            editorLayer.OnPlayerRemoved = () =>
            {
                if (editorLayer.Players.Players.Values.Any(p => p.Name == selectedOwner.Name))
                {
                    return;
                }
                SelectOwner(editorLayer.Players.Players.Values.First());
            };

            ownersDropDown.OnClick = () =>
            {
                var owners = editorLayer.Players.Players.Values.OrderBy(p => p.Name);
                ownersDropDown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 270, owners, setupItem);
            };

            ownersDropDown.Text      = selectedOwner.Name;
            ownersDropDown.TextColor = selectedOwner.Color;

            var tileSetId     = world.Map.Rules.TileSet.Id;
            var allActorsTemp = new List <ActorSelectorActor>();

            foreach (var a in mapRules.Actors.Values)
            {
                // Partial templates are not allowed
                if (a.Name.Contains('^'))
                {
                    continue;
                }

                // Actor must have a preview associated with it
                if (!a.HasTraitInfo <IRenderActorPreviewInfo>())
                {
                    continue;
                }

                var editorData = a.TraitInfoOrDefault <MapEditorDataInfo>();

                // Actor must be included in at least one category
                if (editorData == null || editorData.Categories == null)
                {
                    continue;
                }

                // Excluded by tileset
                if (editorData.ExcludeTilesets != null && editorData.ExcludeTilesets.Contains(tileSetId))
                {
                    continue;
                }

                if (editorData.RequireTilesets != null && !editorData.RequireTilesets.Contains(tileSetId))
                {
                    continue;
                }

                var tooltip = a.TraitInfos <EditorOnlyTooltipInfo>().FirstOrDefault(ti => ti.EnabledByDefault) as TooltipInfoBase
                              ?? a.TraitInfos <TooltipInfo>().FirstOrDefault(ti => ti.EnabledByDefault);

                var searchTerms = new List <string>()
                {
                    a.Name
                };
                if (tooltip != null)
                {
                    searchTerms.Add(tooltip.Name);
                }

                var tooltipText = (tooltip == null ? "Type: " : tooltip.Name + "\nType: ") + a.Name;
                allActorsTemp.Add(new ActorSelectorActor(a, editorData.Categories, searchTerms.ToArray(), tooltipText));
            }

            allActors = allActorsTemp.ToArray();

            allCategories = allActors.SelectMany(ac => ac.Categories)
                            .Distinct()
                            .OrderBy(x => x)
                            .ToArray();

            foreach (var c in allCategories)
            {
                SelectedCategories.Add(c);
                FilteredCategories.Add(c);
            }

            SearchTextField.OnTextEdited = () =>
            {
                searchFilter = SearchTextField.Text.Trim();
                FilteredCategories.Clear();

                if (!string.IsNullOrEmpty(searchFilter))
                {
                    FilteredCategories.AddRange(
                        allActors.Where(t => t.SearchTerms.Any(
                                            s => s.IndexOf(searchFilter, StringComparison.OrdinalIgnoreCase) >= 0))
                        .SelectMany(t => t.Categories)
                        .Distinct()
                        .OrderBy(x => x));
                }
                else
                {
                    FilteredCategories.AddRange(allCategories);
                }

                InitializePreviews();
            };

            InitializePreviews();
        }
Esempio n. 20
0
        void SelectMap(MapPreview preview)
        {
            selectedMap = preview;

            // Cache the rules on a background thread to avoid jank
            var difficultyDisabled = true;
            var difficulties       = new Dictionary <string, string>();

            var briefingVideo        = "";
            var briefingVideoVisible = false;

            var infoVideo        = "";
            var infoVideoVisible = false;

            new Thread(() =>
            {
                var mapDifficulty = preview.WorldActorInfo.TraitInfos <ScriptLobbyDropdownInfo>()
                                    .FirstOrDefault(sld => sld.ID == "difficulty");

                if (mapDifficulty != null)
                {
                    difficulty         = mapDifficulty.Default;
                    difficulties       = mapDifficulty.Values;
                    difficultyDisabled = mapDifficulty.Locked;
                }

                var missionData = preview.WorldActorInfo.TraitInfoOrDefault <MissionDataInfo>();
                if (missionData != null)
                {
                    briefingVideo        = missionData.BriefingVideo;
                    briefingVideoVisible = briefingVideo != null;

                    infoVideo        = missionData.BackgroundVideo;
                    infoVideoVisible = infoVideo != null;

                    var briefing = WidgetUtils.WrapText(missionData.Briefing.Replace("\\n", "\n"), description.Bounds.Width, descriptionFont);
                    var height   = descriptionFont.Measure(briefing).Y;
                    Game.RunAfterTick(() =>
                    {
                        if (preview == selectedMap)
                        {
                            description.Text          = briefing;
                            description.Bounds.Height = height;
                            descriptionPanel.Layout.AdjustChildren();
                        }
                    });
                }
            }).Start();

            startBriefingVideoButton.IsVisible = () => briefingVideoVisible && playingVideo != PlayingVideo.Briefing;
            startBriefingVideoButton.OnClick   = () => PlayVideo(videoPlayer, briefingVideo, PlayingVideo.Briefing);

            startInfoVideoButton.IsVisible = () => infoVideoVisible && playingVideo != PlayingVideo.Info;
            startInfoVideoButton.OnClick   = () => PlayVideo(videoPlayer, infoVideo, PlayingVideo.Info);

            descriptionPanel.ScrollToTop();

            if (difficultyButton != null)
            {
                var difficultyName = new CachedTransform <string, string>(id => id == null || !difficulties.ContainsKey(id) ? "Normal" : difficulties[id]);
                difficultyButton.IsDisabled  = () => difficultyDisabled;
                difficultyButton.GetText     = () => difficultyName.Update(difficulty);
                difficultyButton.OnMouseDown = _ =>
                {
                    var options = difficulties.Select(kv => new DropDownOption
                    {
                        Title      = kv.Value,
                        IsSelected = () => difficulty == kv.Key,
                        OnClick    = () => difficulty = kv.Key
                    });

                    Func <DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get <LabelWidget>("LABEL").GetText = () => option.Title;
                        return(item);
                    };

                    difficultyButton.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
                };
            }

            if (gameSpeedButton != null)
            {
                var speeds = modData.Manifest.Get <GameSpeeds>().Speeds;
                gameSpeed = "default";

                gameSpeedButton.GetText     = () => speeds[gameSpeed].Name;
                gameSpeedButton.OnMouseDown = _ =>
                {
                    var options = speeds.Select(s => new DropDownOption
                    {
                        Title      = s.Value.Name,
                        IsSelected = () => gameSpeed == s.Key,
                        OnClick    = () => gameSpeed = s.Key
                    });

                    Func <DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get <LabelWidget>("LABEL").GetText = () => option.Title;
                        return(item);
                    };

                    gameSpeedButton.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
                };
            }
        }
Esempio n. 21
0
        void IntializeActorPreviews()
        {
            panel.RemoveChildren();

            var actors = mapRules.Actors.Where(a => !a.Value.Name.Contains('^'))
                         .Select(a => a.Value);

            foreach (var a in actors)
            {
                var actor = a;
                if (actor.HasTraitInfo <BridgeInfo>())                // bridge layer takes care about that automatically
                {
                    continue;
                }

                if (!actor.HasTraitInfo <IRenderActorPreviewInfo>())
                {
                    continue;
                }

                var filter = actor.TraitInfoOrDefault <EditorTilesetFilterInfo>();
                if (filter != null)
                {
                    if (filter.ExcludeTilesets != null && filter.ExcludeTilesets.Contains(world.TileSet.Id))
                    {
                        continue;
                    }
                    if (filter.RequireTilesets != null && !filter.RequireTilesets.Contains(world.TileSet.Id))
                    {
                        continue;
                    }
                }

                var td = new TypeDictionary();
                td.Add(new FacingInit(92));
                td.Add(new TurretFacingInit(92));
                td.Add(new HideBibPreviewInit());
                td.Add(new OwnerInit(selectedOwner.Name));
                td.Add(new FactionInit(selectedOwner.Faction));

                try
                {
                    var item = ScrollItemWidget.Setup(itemTemplate,
                                                      () => { var brush = editor.CurrentBrush as EditorActorBrush; return(brush != null && brush.Actor == actor); },
                                                      () => editor.SetBrush(new EditorActorBrush(editor, actor, selectedOwner, worldRenderer)));

                    var preview = item.Get <ActorPreviewWidget>("ACTOR_PREVIEW");
                    preview.SetPreview(actor, td);

                    // Scale templates to fit within the panel
                    var scale = 1f;
                    if (scale * preview.IdealPreviewSize.X > itemTemplate.Bounds.Width)
                    {
                        scale = (float)(itemTemplate.Bounds.Width - panel.ItemSpacing) / (float)preview.IdealPreviewSize.X;
                    }

                    preview.GetScale      = () => scale;
                    preview.Bounds.Width  = (int)(scale * preview.IdealPreviewSize.X);
                    preview.Bounds.Height = (int)(scale * preview.IdealPreviewSize.Y);

                    item.Bounds.Width  = preview.Bounds.Width + 2 * preview.Bounds.X;
                    item.Bounds.Height = preview.Bounds.Height + 2 * preview.Bounds.Y;
                    item.IsVisible     = () => true;

                    var tooltip = actor.TraitInfoOrDefault <EditorOnlyTooltipInfo>() as TooltipInfoBase ?? actor.TraitInfoOrDefault <TooltipInfo>();
                    item.GetTooltipText = () => (tooltip == null ? "Type: " : tooltip.Name + "\nType: ") + actor.Name;

                    panel.AddChild(item);
                }
                catch
                {
                    Log.Write("debug", "Map editor ignoring actor {0}, because of missing sprites for tileset {1}.",
                              actor.Name, world.TileSet.Id);
                    continue;
                }
            }
        }
Esempio n. 22
0
        internal LobbyLogic(Widget widget, WorldRenderer worldRenderer, OrderManager orderManager,
                            Action onExit, Action onStart, bool skirmishMode, Ruleset modRules)
        {
            lobby             = widget;
            this.orderManager = orderManager;
            this.onStart      = onStart;
            this.onExit       = onExit;
            this.skirmishMode = skirmishMode;
            this.modRules     = modRules;

            Game.LobbyInfoChanged       += UpdateCurrentMap;
            Game.LobbyInfoChanged       += UpdatePlayerList;
            Game.BeforeGameStart        += OnGameStart;
            Game.AddChatLine            += AddChatLine;
            Game.ConnectionStateChanged += ConnectionStateChanged;

            var name = lobby.GetOrNull <LabelWidget>("SERVER_NAME");

            if (name != null)
            {
                name.GetText = () => orderManager.LobbyInfo.GlobalSettings.ServerName;
            }

            Ui.LoadWidget("LOBBY_MAP_PREVIEW", lobby.Get("MAP_PREVIEW_ROOT"), new WidgetArgs
            {
                { "orderManager", orderManager },
                { "lobby", this }
            });

            UpdateCurrentMap();
            players           = Ui.LoadWidget <ScrollPanelWidget>("LOBBY_PLAYER_BIN", lobby.Get("PLAYER_BIN_ROOT"), new WidgetArgs());
            players.IsVisible = () => panel == PanelType.Players;

            var playerBinHeaders = lobby.GetOrNull <ContainerWidget>("LABEL_CONTAINER");

            if (playerBinHeaders != null)
            {
                playerBinHeaders.IsVisible = () => panel == PanelType.Players;
            }

            editablePlayerTemplate       = players.Get("TEMPLATE_EDITABLE_PLAYER");
            nonEditablePlayerTemplate    = players.Get("TEMPLATE_NONEDITABLE_PLAYER");
            emptySlotTemplate            = players.Get("TEMPLATE_EMPTY");
            editableSpectatorTemplate    = players.Get("TEMPLATE_EDITABLE_SPECTATOR");
            nonEditableSpectatorTemplate = players.Get("TEMPLATE_NONEDITABLE_SPECTATOR");
            newSpectatorTemplate         = players.Get("TEMPLATE_NEW_SPECTATOR");
            colorPreview       = lobby.Get <ColorPreviewManagerWidget>("COLOR_MANAGER");
            colorPreview.Color = Game.Settings.Player.Color;

            countryNames = modRules.Actors["world"].Traits.WithInterface <CountryInfo>()
                           .Where(c => c.Selectable)
                           .ToDictionary(a => a.Race, a => a.Name);
            countryNames.Add("random", "Any");

            var         gameStarting          = false;
            Func <bool> configurationDisabled = () => !Game.IsHost || gameStarting ||
                                                panel == PanelType.Kick || panel == PanelType.ForceStart ||
                                                orderManager.LocalClient == null || orderManager.LocalClient.IsReady;

            var mapButton = lobby.GetOrNull <ButtonWidget>("CHANGEMAP_BUTTON");

            if (mapButton != null)
            {
                mapButton.IsDisabled = configurationDisabled;
                mapButton.OnClick    = () =>
                {
                    var onSelect = new Action <string>(uid =>
                    {
                        orderManager.IssueOrder(Order.Command("map " + uid));
                        Game.Settings.Server.Map = uid;
                        Game.Settings.Save();
                    });

                    Ui.OpenWindow("MAPCHOOSER_PANEL", new WidgetArgs()
                    {
                        { "initialMap", Map.Uid },
                        { "onExit", DoNothing },
                        { "onSelect", onSelect }
                    });
                };
            }

            var slotsButton = lobby.GetOrNull <DropDownButtonWidget>("SLOTS_DROPDOWNBUTTON");

            if (slotsButton != null)
            {
                slotsButton.IsDisabled = () => configurationDisabled() || panel != PanelType.Players ||
                                         Map.RuleStatus != MapRuleStatus.Cached || !orderManager.LobbyInfo.Slots.Values.Any(s => s.AllowBots || !s.LockTeam);

                var botNames = modRules.Actors["player"].Traits.WithInterface <IBotInfo>().Select(t => t.Name);
                slotsButton.OnMouseDown = _ =>
                {
                    var options = new Dictionary <string, IEnumerable <DropDownOption> >();

                    var botController = orderManager.LobbyInfo.Clients.FirstOrDefault(c => c.IsAdmin);
                    if (orderManager.LobbyInfo.Slots.Values.Any(s => s.AllowBots))
                    {
                        var botOptions = new List <DropDownOption>()
                        {
                            new DropDownOption()
                            {
                                Title      = "Add",
                                IsSelected = () => false,
                                OnClick    = () =>
                                {
                                    foreach (var slot in orderManager.LobbyInfo.Slots)
                                    {
                                        var bot = botNames.Random(Game.CosmeticRandom);
                                        var c   = orderManager.LobbyInfo.ClientInSlot(slot.Key);
                                        if (slot.Value.AllowBots == true && (c == null || c.Bot != null))
                                        {
                                            orderManager.IssueOrder(Order.Command("slot_bot {0} {1} {2}".F(slot.Key, botController.Index, bot)));
                                        }
                                    }
                                }
                            }
                        };

                        if (orderManager.LobbyInfo.Clients.Any(c => c.Bot != null))
                        {
                            botOptions.Add(new DropDownOption()
                            {
                                Title      = "Remove",
                                IsSelected = () => false,
                                OnClick    = () =>
                                {
                                    foreach (var slot in orderManager.LobbyInfo.Slots)
                                    {
                                        var c = orderManager.LobbyInfo.ClientInSlot(slot.Key);
                                        if (c != null && c.Bot != null)
                                        {
                                            orderManager.IssueOrder(Order.Command("slot_open " + slot.Value.PlayerReference));
                                        }
                                    }
                                }
                            });
                        }

                        options.Add("Configure Bots", botOptions);
                    }

                    var teamCount = (orderManager.LobbyInfo.Slots.Count(s => !s.Value.LockTeam && orderManager.LobbyInfo.ClientInSlot(s.Key) != null) + 1) / 2;
                    if (teamCount >= 1)
                    {
                        var teamOptions = Enumerable.Range(2, teamCount - 1).Reverse().Select(d => new DropDownOption
                        {
                            Title      = "{0} Teams".F(d),
                            IsSelected = () => false,
                            OnClick    = () => orderManager.IssueOrder(Order.Command("assignteams {0}".F(d.ToString())))
                        }).ToList();

                        if (orderManager.LobbyInfo.Slots.Any(s => s.Value.AllowBots))
                        {
                            teamOptions.Add(new DropDownOption
                            {
                                Title      = "Humans vs Bots",
                                IsSelected = () => false,
                                OnClick    = () => orderManager.IssueOrder(Order.Command("assignteams 1"))
                            });
                        }

                        teamOptions.Add(new DropDownOption
                        {
                            Title      = "Free for all",
                            IsSelected = () => false,
                            OnClick    = () => orderManager.IssueOrder(Order.Command("assignteams 0"))
                        });

                        options.Add("Configure Teams", teamOptions);
                    }

                    Func <DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get <LabelWidget>("LABEL").GetText = () => option.Title;
                        return(item);
                    };
                    slotsButton.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 175, options, setupItem);
                };
            }

            var optionsBin = Ui.LoadWidget("LOBBY_OPTIONS_BIN", lobby, new WidgetArgs());

            optionsBin.IsVisible = () => panel == PanelType.Options;

            var optionsButton = lobby.Get <ButtonWidget>("OPTIONS_BUTTON");

            optionsButton.IsDisabled = () => Map.RuleStatus != MapRuleStatus.Cached || panel == PanelType.Kick || panel == PanelType.ForceStart;
            optionsButton.GetText    = () => panel == PanelType.Options ? "Players" : "Options";
            optionsButton.OnClick    = () => panel = (panel == PanelType.Options) ? PanelType.Players : PanelType.Options;

            // Force start panel
            Action startGame = () =>
            {
                gameStarting = true;
                orderManager.IssueOrder(Order.Command("startgame"));
            };

            var startGameButton = lobby.GetOrNull <ButtonWidget>("START_GAME_BUTTON");

            if (startGameButton != null)
            {
                startGameButton.IsDisabled = () => configurationDisabled() || Map.RuleStatus != MapRuleStatus.Cached ||
                                             orderManager.LobbyInfo.Slots.Any(sl => sl.Value.Required && orderManager.LobbyInfo.ClientInSlot(sl.Key) == null);
                startGameButton.OnClick = () =>
                {
                    Func <KeyValuePair <string, Session.Slot>, bool> notReady = sl =>
                    {
                        var cl = orderManager.LobbyInfo.ClientInSlot(sl.Key);

                        // Bots and admins don't count
                        return(cl != null && !cl.IsAdmin && cl.Bot == null && !cl.IsReady);
                    };

                    if (orderManager.LobbyInfo.Slots.Any(notReady))
                    {
                        panel = PanelType.ForceStart;
                    }
                    else
                    {
                        startGame();
                    }
                };
            }

            var forceStartBin = Ui.LoadWidget("FORCE_START_DIALOG", lobby, new WidgetArgs());

            forceStartBin.IsVisible = () => panel == PanelType.ForceStart;
            forceStartBin.Get("KICK_WARNING").IsVisible               = () => orderManager.LobbyInfo.Clients.Any(c => c.IsInvalid);
            forceStartBin.Get <ButtonWidget>("OK_BUTTON").OnClick     = startGame;
            forceStartBin.Get <ButtonWidget>("CANCEL_BUTTON").OnClick = () => panel = PanelType.Players;

            // Options panel
            var allowCheats = optionsBin.GetOrNull <CheckboxWidget>("ALLOWCHEATS_CHECKBOX");

            if (allowCheats != null)
            {
                allowCheats.IsChecked  = () => orderManager.LobbyInfo.GlobalSettings.AllowCheats;
                allowCheats.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.Cheats.HasValue || configurationDisabled();
                allowCheats.OnClick    = () => orderManager.IssueOrder(Order.Command(
                                                                           "allowcheats {0}".F(!orderManager.LobbyInfo.GlobalSettings.AllowCheats)));
            }

            var crates = optionsBin.GetOrNull <CheckboxWidget>("CRATES_CHECKBOX");

            if (crates != null)
            {
                crates.IsChecked  = () => orderManager.LobbyInfo.GlobalSettings.Crates;
                crates.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.Crates.HasValue || configurationDisabled();
                crates.OnClick    = () => orderManager.IssueOrder(Order.Command(
                                                                      "crates {0}".F(!orderManager.LobbyInfo.GlobalSettings.Crates)));
            }

            var allybuildradius = optionsBin.GetOrNull <CheckboxWidget>("ALLYBUILDRADIUS_CHECKBOX");

            if (allybuildradius != null)
            {
                allybuildradius.IsChecked  = () => orderManager.LobbyInfo.GlobalSettings.AllyBuildRadius;
                allybuildradius.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.AllyBuildRadius.HasValue || configurationDisabled();
                allybuildradius.OnClick    = () => orderManager.IssueOrder(Order.Command(
                                                                               "allybuildradius {0}".F(!orderManager.LobbyInfo.GlobalSettings.AllyBuildRadius)));
            }

            var fragileAlliance = optionsBin.GetOrNull <CheckboxWidget>("FRAGILEALLIANCES_CHECKBOX");

            if (fragileAlliance != null)
            {
                fragileAlliance.IsChecked  = () => orderManager.LobbyInfo.GlobalSettings.FragileAlliances;
                fragileAlliance.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.FragileAlliances.HasValue || configurationDisabled();
                fragileAlliance.OnClick    = () => orderManager.IssueOrder(Order.Command(
                                                                               "fragilealliance {0}".F(!orderManager.LobbyInfo.GlobalSettings.FragileAlliances)));
            }

            var difficulty = optionsBin.GetOrNull <DropDownButtonWidget>("DIFFICULTY_DROPDOWNBUTTON");

            if (difficulty != null)
            {
                difficulty.IsVisible   = () => Map.Status == MapStatus.Available && Map.Map.Options.Difficulties.Any();
                difficulty.IsDisabled  = () => Map.Status != MapStatus.Available || configurationDisabled();
                difficulty.GetText     = () => orderManager.LobbyInfo.GlobalSettings.Difficulty;
                difficulty.OnMouseDown = _ =>
                {
                    var options = Map.Map.Options.Difficulties.Select(d => new DropDownOption
                    {
                        Title      = d,
                        IsSelected = () => orderManager.LobbyInfo.GlobalSettings.Difficulty == d,
                        OnClick    = () => orderManager.IssueOrder(Order.Command("difficulty {0}".F(d)))
                    });
                    Func <DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get <LabelWidget>("LABEL").GetText = () => option.Title;
                        return(item);
                    };
                    difficulty.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
                };

                optionsBin.Get <LabelWidget>("DIFFICULTY_DESC").IsVisible = difficulty.IsVisible;
            }

            var startingUnits = optionsBin.GetOrNull <DropDownButtonWidget>("STARTINGUNITS_DROPDOWNBUTTON");

            if (startingUnits != null)
            {
                var classNames = new Dictionary <string, string>()
                {
                    { "none", "MCV Only" },
                    { "light", "Light Support" },
                    { "heavy", "Heavy Support" },
                };

                Func <string, string> className = c => classNames.ContainsKey(c) ? classNames[c] : c;
                var classes = modRules.Actors["world"].Traits.WithInterface <MPStartUnitsInfo>()
                              .Select(a => a.Class).Distinct();

                startingUnits.IsDisabled  = () => Map.Status != MapStatus.Available || !Map.Map.Options.ConfigurableStartingUnits || configurationDisabled();
                startingUnits.GetText     = () => Map.Status != MapStatus.Available || !Map.Map.Options.ConfigurableStartingUnits ? "Not Available" : className(orderManager.LobbyInfo.GlobalSettings.StartingUnitsClass);
                startingUnits.OnMouseDown = _ =>
                {
                    var options = classes.Select(c => new DropDownOption
                    {
                        Title      = className(c),
                        IsSelected = () => orderManager.LobbyInfo.GlobalSettings.StartingUnitsClass == c,
                        OnClick    = () => orderManager.IssueOrder(Order.Command("startingunits {0}".F(c)))
                    });

                    Func <DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get <LabelWidget>("LABEL").GetText = () => option.Title;
                        return(item);
                    };

                    startingUnits.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
                };

                optionsBin.Get <LabelWidget>("STARTINGUNITS_DESC").IsVisible = startingUnits.IsVisible;
            }

            var startingCash = optionsBin.GetOrNull <DropDownButtonWidget>("STARTINGCASH_DROPDOWNBUTTON");

            if (startingCash != null)
            {
                startingCash.IsDisabled  = () => Map.Status != MapStatus.Available || Map.Map.Options.StartingCash.HasValue || configurationDisabled();
                startingCash.GetText     = () => Map.Status != MapStatus.Available || Map.Map.Options.StartingCash.HasValue ? "Not Available" : "${0}".F(orderManager.LobbyInfo.GlobalSettings.StartingCash);
                startingCash.OnMouseDown = _ =>
                {
                    var options = modRules.Actors["player"].Traits.Get <PlayerResourcesInfo>().SelectableCash.Select(c => new DropDownOption
                    {
                        Title      = "${0}".F(c),
                        IsSelected = () => orderManager.LobbyInfo.GlobalSettings.StartingCash == c,
                        OnClick    = () => orderManager.IssueOrder(Order.Command("startingcash {0}".F(c)))
                    });

                    Func <DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get <LabelWidget>("LABEL").GetText = () => option.Title;
                        return(item);
                    };

                    startingCash.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
                };
            }

            var techLevel = optionsBin.GetOrNull <DropDownButtonWidget>("TECHLEVEL_DROPDOWNBUTTON");

            if (techLevel != null)
            {
                var techTraits = modRules.Actors["player"].Traits.WithInterface <ProvidesTechPrerequisiteInfo>().ToArray();
                techLevel.IsVisible = () => techTraits.Length > 0;
                optionsBin.GetOrNull <LabelWidget>("TECHLEVEL_DESC").IsVisible = () => techTraits.Length > 0;
                techLevel.IsDisabled  = () => Map.Status != MapStatus.Available || Map.Map.Options.TechLevel != null || configurationDisabled() || techTraits.Length <= 1;
                techLevel.GetText     = () => Map.Status != MapStatus.Available || Map.Map.Options.TechLevel != null ? "Not Available" : "{0}".F(orderManager.LobbyInfo.GlobalSettings.TechLevel);
                techLevel.OnMouseDown = _ =>
                {
                    var options = techTraits.Select(c => new DropDownOption
                    {
                        Title      = "{0}".F(c.Name),
                        IsSelected = () => orderManager.LobbyInfo.GlobalSettings.TechLevel == c.Name,
                        OnClick    = () => orderManager.IssueOrder(Order.Command("techlevel {0}".F(c.Name)))
                    });

                    Func <DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get <LabelWidget>("LABEL").GetText = () => option.Title;
                        return(item);
                    };

                    techLevel.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
                };
            }

            var enableShroud = optionsBin.GetOrNull <CheckboxWidget>("SHROUD_CHECKBOX");

            if (enableShroud != null)
            {
                enableShroud.IsChecked  = () => orderManager.LobbyInfo.GlobalSettings.Shroud;
                enableShroud.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.Shroud.HasValue || configurationDisabled();
                enableShroud.OnClick    = () => orderManager.IssueOrder(Order.Command(
                                                                            "shroud {0}".F(!orderManager.LobbyInfo.GlobalSettings.Shroud)));
            }

            var enableFog = optionsBin.GetOrNull <CheckboxWidget>("FOG_CHECKBOX");

            if (enableFog != null)
            {
                enableFog.IsChecked  = () => orderManager.LobbyInfo.GlobalSettings.Fog;
                enableFog.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.Fog.HasValue || configurationDisabled();
                enableFog.OnClick    = () => orderManager.IssueOrder(Order.Command(
                                                                         "fog {0}".F(!orderManager.LobbyInfo.GlobalSettings.Fog)));
            }

            var disconnectButton = lobby.Get <ButtonWidget>("DISCONNECT_BUTTON");

            disconnectButton.OnClick = () => { CloseWindow(); onExit(); };

            if (skirmishMode)
            {
                disconnectButton.Text = "Cancel";
            }

            bool teamChat      = false;
            var  chatLabel     = lobby.Get <LabelWidget>("LABEL_CHATTYPE");
            var  chatTextField = lobby.Get <TextFieldWidget>("CHAT_TEXTFIELD");

            chatTextField.OnEnterKey = () =>
            {
                if (chatTextField.Text.Length == 0)
                {
                    return(true);
                }

                // Always scroll to bottom when we've typed something
                chatPanel.ScrollToBottom();

                orderManager.IssueOrder(Order.Chat(teamChat, chatTextField.Text));
                chatTextField.Text = "";
                return(true);
            };

            chatTextField.OnTabKey = () =>
            {
                teamChat      ^= true;
                chatLabel.Text = teamChat ? "Team:" : "Chat:";
                return(true);
            };

            chatPanel    = lobby.Get <ScrollPanelWidget>("CHAT_DISPLAY");
            chatTemplate = chatPanel.Get("CHAT_TEMPLATE");
            chatPanel.RemoveChildren();

            var musicButton = lobby.GetOrNull <ButtonWidget>("MUSIC_BUTTON");

            if (musicButton != null)
            {
                musicButton.OnClick = () => Ui.OpenWindow("MUSIC_PANEL", new WidgetArgs {
                    { "onExit", DoNothing }
                });
            }

            var settingsButton = lobby.GetOrNull <ButtonWidget>("SETTINGS_BUTTON");

            if (settingsButton != null)
            {
                settingsButton.OnClick = () => Ui.OpenWindow("SETTINGS_PANEL", new WidgetArgs
                {
                    { "onExit", DoNothing },
                    { "worldRenderer", worldRenderer }
                });
            }

            // Add a bot on the first lobbyinfo update
            if (skirmishMode)
            {
                Game.LobbyInfoChanged += WidgetUtils.Once(() =>
                {
                    var slot          = orderManager.LobbyInfo.FirstEmptyBotSlot();
                    var bot           = modRules.Actors["player"].Traits.WithInterface <IBotInfo>().Select(t => t.Name).FirstOrDefault();
                    var botController = orderManager.LobbyInfo.Clients.FirstOrDefault(c => c.IsAdmin);
                    if (slot != null && bot != null)
                    {
                        orderManager.IssueOrder(Order.Command("slot_bot {0} {1} {2}".F(slot, botController.Index, bot)));
                    }
                });
            }
        }
Esempio n. 23
0
        void RefreshServerListInner(IEnumerable <GameServer> games)
        {
            if (games == null)
            {
                return;
            }

            var mods = games.GroupBy(g => g.Mods)
                       .OrderByDescending(g => GroupSortOrder(g.First()))
                       .ThenByDescending(g => g.Count());

            ScrollItemWidget nextServerRow = null;
            var rows = new List <Widget>();

            foreach (var modGames in mods)
            {
                if (modGames.All(Filtered))
                {
                    continue;
                }

                var header = ScrollItemWidget.Setup(headerTemplate, () => true, () => { });

                var headerTitle = modGames.First().ModLabel;
                header.Get <LabelWidget>("LABEL").GetText = () => headerTitle;
                rows.Add(header);

                Func <GameServer, int> listOrder = g =>
                {
                    // Servers waiting for players are always first
                    if (g.State == (int)ServerState.WaitingPlayers && g.Players > 0)
                    {
                        return(0);
                    }

                    // Then active games
                    if (g.State >= (int)ServerState.GameStarted)
                    {
                        return(1);
                    }

                    // Empty servers are shown at the end because a flood of empty servers
                    // at the top of the game list make the community look dead
                    return(2);
                };

                foreach (var loop in modGames.OrderBy(listOrder).ThenByDescending(g => g.Players))
                {
                    var game = loop;
                    if (game == null || Filtered(game))
                    {
                        continue;
                    }

                    var canJoin = game.IsJoinable;
                    var item    = ScrollItemWidget.Setup(serverTemplate, () => currentServer == game, () => SelectServer(game), () => Join(game));
                    var title   = item.GetOrNull <LabelWidget>("TITLE");
                    if (title != null)
                    {
                        var font  = Game.Renderer.Fonts[title.Font];
                        var label = WidgetUtils.TruncateText(game.Name, title.Bounds.Width, font);
                        title.GetText  = () => label;
                        title.GetColor = () => canJoin ? title.TextColor : incompatibleGameColor;
                    }

                    var password = item.GetOrNull <ImageWidget>("PASSWORD_PROTECTED");
                    if (password != null)
                    {
                        password.IsVisible    = () => game.Protected;
                        password.GetImageName = () => canJoin ? "protected" : "protected-disabled";
                    }

                    var players = item.GetOrNull <LabelWidget>("PLAYERS");
                    if (players != null)
                    {
                        players.GetText = () => "{0} / {1}".F(game.Players, game.MaxPlayers)
                                          + (game.Spectators > 0 ? " + {0}".F(game.Spectators) : "");

                        players.GetColor = () => canJoin ? players.TextColor : incompatibleGameColor;
                    }

                    var state = item.GetOrNull <LabelWidget>("STATUS");
                    if (state != null)
                    {
                        var label = game.State >= (int)ServerState.GameStarted ?
                                    "Playing" : "Waiting";
                        state.GetText = () => label;

                        var color = GetStateColor(game, state, !canJoin);
                        state.GetColor = () => color;
                    }

                    var location = item.GetOrNull <LabelWidget>("LOCATION");
                    if (location != null)
                    {
                        var font = Game.Renderer.Fonts[location.Font];
                        var cachedServerLocation = GeoIP.LookupCountry(game.Address.Split(':')[0]);
                        var label = WidgetUtils.TruncateText(cachedServerLocation, location.Bounds.Width, font);
                        location.GetText  = () => label;
                        location.GetColor = () => canJoin ? location.TextColor : incompatibleGameColor;
                    }

                    if (currentServer != null && game.Address == currentServer.Address)
                    {
                        nextServerRow = item;
                    }

                    rows.Add(item);
                }
            }

            Game.RunAfterTick(() =>
            {
                serverList.RemoveChildren();
                SelectServer(null);

                if (games == null)
                {
                    searchStatus = SearchStatus.Failed;
                    return;
                }

                if (!rows.Any())
                {
                    searchStatus = SearchStatus.NoGames;
                    return;
                }

                searchStatus = SearchStatus.Hidden;

                // Search for any unknown maps
                if (Game.Settings.Game.AllowDownloading)
                {
                    modData.MapCache.QueryRemoteMapDetails(games.Where(g => !Filtered(g)).Select(g => g.Map));
                }

                foreach (var row in rows)
                {
                    serverList.AddChild(row);
                }

                if (nextServerRow != null)
                {
                    nextServerRow.OnClick();
                }
            });
        }
Esempio n. 24
0
        public NewMapLogic(Action onExit, Action <string> onSelect, Ruleset modRules, Widget widget, World world)
        {
            panel = widget;

            panel.Get <ButtonWidget>("CANCEL_BUTTON").OnClick = () => { Ui.CloseWindow(); onExit(); };

            var tilesetDropDown = panel.Get <DropDownButtonWidget>("TILESET");
            var tilesets        = modRules.TileSets.Select(t => t.Key).ToList();
            Func <string, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
            {
                var item = ScrollItemWidget.Setup(template,
                                                  () => tilesetDropDown.Text == option,
                                                  () => { tilesetDropDown.Text = option; });
                item.Get <LabelWidget>("LABEL").GetText = () => option;
                return(item);
            };

            tilesetDropDown.Text    = tilesets.First();
            tilesetDropDown.OnClick = () =>
                                      tilesetDropDown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 210, tilesets, setupItem);

            var widthTextField  = panel.Get <TextFieldWidget>("WIDTH");
            var heightTextField = panel.Get <TextFieldWidget>("HEIGHT");

            panel.Get <ButtonWidget>("CREATE_BUTTON").OnClick = () =>
            {
                var tileset = modRules.TileSets[tilesetDropDown.Text];
                var map     = Map.FromTileset(tileset);

                int width, height;
                int.TryParse(widthTextField.Text, out width);
                int.TryParse(heightTextField.Text, out height);

                // Require at least a 2x2 playable area so that the
                // ground is visible through the edge shroud
                width  = Math.Max(2, width);
                height = Math.Max(2, height);

                map.Resize(width + 2, height + tileset.MaxGroundHeight + 2);
                map.ResizeCordon(1, 1, width + 1, height + tileset.MaxGroundHeight + 1);
                map.PlayerDefinitions = new MapPlayers(map.Rules, map.SpawnPoints.Value.Length).ToMiniYaml();
                map.FixOpenAreas(modRules);

                var userMapFolder = Game.ModData.Manifest.MapFolders.First(f => f.Value == "User").Key;

                // Ignore optional flag
                if (userMapFolder.StartsWith("~"))
                {
                    userMapFolder = userMapFolder.Substring(1);
                }

                var mapDir = Platform.ResolvePath(userMapFolder);
                Directory.CreateDirectory(mapDir);
                var tempLocation = Path.Combine(mapDir, "temp") + ".oramap";
                map.Save(tempLocation);                 // TODO: load it right away and save later properly

                var newMap = new Map(tempLocation);
                Game.ModData.MapCache[newMap.Uid].UpdateFromMap(newMap, MapClassification.User);

                ConnectionLogic.Connect(System.Net.IPAddress.Loopback.ToString(),
                                        Game.CreateLocalServer(newMap.Uid),
                                        "",
                                        () => { Game.LoadEditor(newMap.Uid); },
                                        () => { Game.CloseServer(); onExit(); });
                onSelect(newMap.Uid);
            };
        }
Esempio n. 25
0
        void SelectServer(GameServer server)
        {
            currentServer = server;
            currentMap    = server != null ? modData.MapCache[server.Map] : null;

            // Can only show factions if the server is running the same mod
            if (server != null && mapPreview != null)
            {
                var spawns    = currentMap.SpawnPoints;
                var occupants = server.Clients
                                .Where(c => (c.SpawnPoint - 1 >= 0) && (c.SpawnPoint - 1 < spawns.Length))
                                .ToDictionary(c => c.SpawnPoint, c => new SpawnOccupant(c, server.Mod != modData.Manifest.Id));

                mapPreview.SpawnOccupants      = () => occupants;
                mapPreview.DisabledSpawnPoints = () => server.DisabledSpawnPoints;
            }

            if (server == null || !server.Clients.Any())
            {
                if (joinButton != null)
                {
                    joinButton.Bounds.Y = joinButtonY;
                }

                return;
            }

            if (joinButton != null)
            {
                joinButton.Bounds.Y = clientContainer.Bounds.Bottom;
            }

            if (clientList == null)
            {
                return;
            }

            clientList.RemoveChildren();

            var players = server.Clients
                          .Where(c => !c.IsSpectator)
                          .GroupBy(p => p.Team)
                          .OrderBy(g => g.Key);

            var teams   = new Dictionary <string, IEnumerable <GameClient> >();
            var noTeams = players.Count() == 1;

            foreach (var p in players)
            {
                var label = noTeams ? "Players" : p.Key == 0 ? "No Team" : "Team {0}".F(p.Key);
                teams.Add(label, p);
            }

            if (server.Clients.Any(c => c.IsSpectator))
            {
                teams.Add("Spectators", server.Clients.Where(c => c.IsSpectator));
            }

            var factionInfo = modData.DefaultRules.Actors["world"].TraitInfos <FactionInfo>();

            foreach (var kv in teams)
            {
                var group = kv.Key;
                if (group.Length > 0)
                {
                    var header = ScrollItemWidget.Setup(clientHeader, () => true, () => { });
                    header.Get <LabelWidget>("LABEL").GetText = () => group;
                    clientList.AddChild(header);
                }

                foreach (var option in kv.Value)
                {
                    var o = option;

                    var item = ScrollItemWidget.Setup(clientTemplate, () => false, () => { });
                    if (!o.IsSpectator && server.Mod == modData.Manifest.Id)
                    {
                        var label = item.Get <LabelWidget>("LABEL");
                        var font  = Game.Renderer.Fonts[label.Font];
                        var name  = WidgetUtils.TruncateText(o.Name, label.Bounds.Width, font);
                        label.GetText  = () => name;
                        label.GetColor = () => o.Color;

                        var flag = item.Get <ImageWidget>("FLAG");
                        flag.IsVisible          = () => true;
                        flag.GetImageCollection = () => "flags";
                        flag.GetImageName       = () => (factionInfo != null && factionInfo.Any(f => f.InternalName == o.Faction)) ? o.Faction : "Random";
                    }
                    else
                    {
                        var label = item.Get <LabelWidget>("NOFLAG_LABEL");
                        var font  = Game.Renderer.Fonts[label.Font];
                        var name  = WidgetUtils.TruncateText(o.Name, label.Bounds.Width, font);

                        // Force spectator color to prevent spoofing by the server
                        var color = o.IsSpectator ? Color.White : o.Color;
                        label.GetText  = () => name;
                        label.GetColor = () => color;
                    }

                    clientList.AddChild(item);
                }
            }
        }
Esempio n. 26
0
        void EnumerateMaps()
        {
            var maps = Game.modData.AvailableMaps
                       .Where(kv => kv.Value.Selectable)
                       .Where(kv => kv.Value.Type == gameMode || gameMode == null)
                       .OrderBy(kv => kv.Value.PlayerCount)
                       .ThenBy(kv => kv.Value.Title);

            scrollpanel.RemoveChildren();
            foreach (var kv in maps)
            {
                var m    = kv.Value;
                var item = ScrollItemWidget.Setup(kv.Key, itemTemplate, () => m == map, () => map = m);

                var titleLabel = item.Get <LabelWidget>("TITLE");
                titleLabel.GetText = () => m.Title;

                var previewWidget = item.Get <MapPreviewWidget>("PREVIEW");
                previewWidget.IgnoreMouseOver  = true;
                previewWidget.IgnoreMouseInput = true;
                previewWidget.Map       = () => m;
                previewWidget.IsVisible = () => previewWidget.RenderBounds.IntersectsWith(scrollpanel.RenderBounds);

                var previewLoadingWidget = item.GetOrNull <BackgroundWidget>("PREVIEW_PLACEHOLDER");
                if (previewLoadingWidget != null)
                {
                    previewLoadingWidget.IsVisible = () => !previewWidget.Loaded;
                }

                var detailsWidget = item.GetOrNull <LabelWidget>("DETAILS");
                if (detailsWidget != null)
                {
                    detailsWidget.GetText = () => "{0} ({1} players)".F(m.Type, m.PlayerCount);
                }

                var authorWidget = item.GetOrNull <LabelWidget>("AUTHOR");
                if (authorWidget != null)
                {
                    authorWidget.GetText = () => "Created by {0}".F(m.Author);
                }

                var sizeWidget = item.GetOrNull <LabelWidget>("SIZE");
                if (sizeWidget != null)
                {
                    var size = m.Bounds.Width + "x" + m.Bounds.Height;
                    var numberPlayableCells = m.Bounds.Width * m.Bounds.Height;
                    if (numberPlayableCells >= 120 * 120)
                    {
                        size += " (Huge)";
                    }
                    else if (numberPlayableCells >= 90 * 90)
                    {
                        size += " (Large)";
                    }
                    else if (numberPlayableCells >= 60 * 60)
                    {
                        size += " (Medium)";
                    }
                    else
                    {
                        size += " (Small)";
                    }
                    sizeWidget.GetText = () => size;
                }

                scrollpanel.AddChild(item);
            }

            visibleMaps = maps.ToDictionary(kv => kv.Key, kv => kv.Value);
            if (visibleMaps.ContainsValue(map))
            {
                scrollpanel.ScrollToItem(visibleMaps.First(m => m.Value == map).Key);
            }
        }
Esempio n. 27
0
        void EnumerateMaps(MapClassification tab, ScrollItemWidget template)
        {
            if (!int.TryParse(mapFilter, out var playerCountFilter))
            {
                playerCountFilter = -1;
            }

            var maps = tabMaps[tab]
                       .Where(m => category == null || m.Categories.Contains(category))
                       .Where(m => mapFilter == null ||
                              (m.Title != null && m.Title.IndexOf(mapFilter, StringComparison.OrdinalIgnoreCase) >= 0) ||
                              (m.Author != null && m.Author.IndexOf(mapFilter, StringComparison.OrdinalIgnoreCase) >= 0) ||
                              m.PlayerCount == playerCountFilter)
                       .OrderBy(m => m.PlayerCount)
                       .ThenBy(m => m.Title);

            scrollpanels[tab].RemoveChildren();
            foreach (var loop in maps)
            {
                var preview = loop;

                // Access the minimap to trigger async generation of the minimap.
                preview.GetMinimap();

                Action dblClick = () =>
                {
                    if (onSelect != null)
                    {
                        Ui.CloseWindow();
                        onSelect(preview.Uid);
                    }
                };

                var item = ScrollItemWidget.Setup(preview.Uid, template, () => selectedUid == preview.Uid,
                                                  () => selectedUid = preview.Uid, dblClick);
                item.IsVisible = () => item.RenderBounds.IntersectsWith(scrollpanels[tab].RenderBounds);

                var titleLabel = item.Get <LabelWithTooltipWidget>("TITLE");
                if (titleLabel != null)
                {
                    WidgetUtils.TruncateLabelToTooltip(titleLabel, preview.Title);
                }

                var previewWidget = item.Get <MapPreviewWidget>("PREVIEW");
                previewWidget.Preview = () => preview;

                var detailsWidget = item.GetOrNull <LabelWidget>("DETAILS");
                if (detailsWidget != null)
                {
                    var type    = preview.Categories.FirstOrDefault();
                    var details = "";
                    if (type != null)
                    {
                        details = type + " ";
                    }

                    details += $"({preview.PlayerCount} players)";
                    detailsWidget.GetText = () => details;
                }

                var authorWidget = item.GetOrNull <LabelWithTooltipWidget>("AUTHOR");
                if (authorWidget != null)
                {
                    WidgetUtils.TruncateLabelToTooltip(authorWidget, $"Created by {preview.Author}");
                }

                var sizeWidget = item.GetOrNull <LabelWidget>("SIZE");
                if (sizeWidget != null)
                {
                    var size = preview.Bounds.Width + "x" + preview.Bounds.Height;
                    var numberPlayableCells = preview.Bounds.Width * preview.Bounds.Height;
                    if (numberPlayableCells >= 120 * 120)
                    {
                        size += " (Huge)";
                    }
                    else if (numberPlayableCells >= 90 * 90)
                    {
                        size += " (Large)";
                    }
                    else if (numberPlayableCells >= 60 * 60)
                    {
                        size += " (Medium)";
                    }
                    else
                    {
                        size += " (Small)";
                    }
                    sizeWidget.GetText = () => size;
                }

                scrollpanels[tab].AddChild(item);
            }

            if (tab == currentTab)
            {
                visibleMaps = maps.Select(m => m.Uid).ToArray();
                SetupGameModeDropdown(currentTab, gameModeDropdown, template);
            }

            if (visibleMaps.Contains(selectedUid))
            {
                scrollpanels[tab].ScrollToItem(selectedUid);
            }
        }
Esempio n. 28
0
        public NewMapLogic(Action onExit, Action <string> onSelect, Ruleset modRules, Widget widget, World world)
        {
            panel = widget;

            panel.Get <ButtonWidget>("CANCEL_BUTTON").OnClick = () => { Ui.CloseWindow(); onExit(); };

            var tilesetDropDown = panel.Get <DropDownButtonWidget>("TILESET");
            var tilesets        = modRules.TileSets.Select(t => t.Key).ToList();
            Func <string, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
            {
                var item = ScrollItemWidget.Setup(template,
                                                  () => tilesetDropDown.Text == option,
                                                  () => { tilesetDropDown.Text = option; });
                item.Get <LabelWidget>("LABEL").GetText = () => option;
                return(item);
            };

            tilesetDropDown.Text    = tilesets.First();
            tilesetDropDown.OnClick = () =>
                                      tilesetDropDown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 210, tilesets, setupItem);

            var widthTextField  = panel.Get <TextFieldWidget>("WIDTH");
            var heightTextField = panel.Get <TextFieldWidget>("HEIGHT");

            panel.Get <ButtonWidget>("CREATE_BUTTON").OnClick = () =>
            {
                int width, height;
                int.TryParse(widthTextField.Text, out width);
                int.TryParse(heightTextField.Text, out height);

                // Require at least a 2x2 playable area so that the
                // ground is visible through the edge shroud
                width  = Math.Max(2, width);
                height = Math.Max(2, height);

                var maxTerrainHeight = Game.ModData.Manifest.MaximumTerrainHeight;
                var tileset          = modRules.TileSets[tilesetDropDown.Text];
                var map = new Map(tileset, width + 2, height + maxTerrainHeight + 2);

                var tl = new PPos(1, 1);
                var br = new PPos(width, height + maxTerrainHeight);
                map.SetBounds(tl, br);

                map.PlayerDefinitions = new MapPlayers(map.Rules, map.SpawnPoints.Value.Length).ToMiniYaml();
                map.FixOpenAreas(modRules);

                Action <string> afterSave = uid =>
                {
                    // HACK: Work around a synced-code change check.
                    // It's not clear why this is needed here, but not in the other places that load maps.
                    Game.RunAfterTick(() =>
                    {
                        ConnectionLogic.Connect(System.Net.IPAddress.Loopback.ToString(),
                                                Game.CreateLocalServer(uid), "",
                                                () => Game.LoadEditor(uid),
                                                () => { Game.CloseServer(); onExit(); });
                    });

                    Ui.CloseWindow();
                    onSelect(uid);
                };

                Ui.OpenWindow("SAVE_MAP_PANEL", new WidgetArgs()
                {
                    { "onSave", afterSave },
                    { "onExit", () => { Ui.CloseWindow(); onExit(); } },
                    { "map", map },
                    { "playerDefinitions", map.PlayerDefinitions },
                    { "actorDefinitions", map.ActorDefinitions }
                });
            };
        }
Esempio n. 29
0
        void SetupFilters()
        {
            // Game type
            {
                var ddb = panel.GetOrNull <DropDownButtonWidget>("FLT_GAMETYPE_DROPDOWNBUTTON");
                if (ddb != null)
                {
                    // Using list to maintain the order
                    var options = new List <(GameType GameType, string Text)>
                    {
                        (GameType.Any, ddb.GetText()),
                        (GameType.Singleplayer, "Singleplayer"),
                        (GameType.Multiplayer, "Multiplayer")
                    };

                    var lookup = options.ToDictionary(kvp => kvp.GameType, kvp => kvp.Text);

                    ddb.GetText     = () => lookup[filter.Type];
                    ddb.OnMouseDown = _ =>
                    {
                        Func <(GameType GameType, string Text), ScrollItemWidget, ScrollItemWidget> setupItem = (option, tpl) =>
                        {
                            var item = ScrollItemWidget.Setup(
                                tpl,
                                () => filter.Type == option.GameType,
                                () => { filter.Type = option.GameType; ApplyFilter(); });
                            item.Get <LabelWidget>("LABEL").GetText = () => option.Text;
                            return(item);
                        };

                        ddb.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 330, options, setupItem);
                    };
                }
            }

            // Date type
            {
                var ddb = panel.GetOrNull <DropDownButtonWidget>("FLT_DATE_DROPDOWNBUTTON");
                if (ddb != null)
                {
                    // Using list to maintain the order
                    var options = new List <(DateType DateType, string Text)>
                    {
                        (DateType.Any, ddb.GetText()),
                        (DateType.Today, "Today"),
                        (DateType.LastWeek, "Last 7 days"),
                        (DateType.LastFortnight, "Last 14 days"),
                        (DateType.LastMonth, "Last 30 days")
                    };

                    var lookup = options.ToDictionary(kvp => kvp.DateType, kvp => kvp.Text);

                    ddb.GetText     = () => lookup[filter.Date];
                    ddb.OnMouseDown = _ =>
                    {
                        Func <(DateType DateType, string Text), ScrollItemWidget, ScrollItemWidget> setupItem = (option, tpl) =>
                        {
                            var item = ScrollItemWidget.Setup(
                                tpl,
                                () => filter.Date == option.DateType,
                                () => { filter.Date = option.DateType; ApplyFilter(); });

                            item.Get <LabelWidget>("LABEL").GetText = () => option.Text;
                            return(item);
                        };

                        ddb.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 330, options, setupItem);
                    };
                }
            }

            // Duration
            {
                var ddb = panel.GetOrNull <DropDownButtonWidget>("FLT_DURATION_DROPDOWNBUTTON");
                if (ddb != null)
                {
                    // Using list to maintain the order
                    var options = new List <(DurationType DurationType, string Text)>
                    {
                        (DurationType.Any, ddb.GetText()),
                        (DurationType.VeryShort, "Under 5 min"),
                        (DurationType.Short, "Short (10 min)"),
                        (DurationType.Medium, "Medium (30 min)"),
                        (DurationType.Long, "Long (60+ min)")
                    };

                    var lookup = options.ToDictionary(kvp => kvp.DurationType, kvp => kvp.Text);

                    ddb.GetText     = () => lookup[filter.Duration];
                    ddb.OnMouseDown = _ =>
                    {
                        Func <(DurationType DurationType, string Text), ScrollItemWidget, ScrollItemWidget> setupItem = (option, tpl) =>
                        {
                            var item = ScrollItemWidget.Setup(
                                tpl,
                                () => filter.Duration == option.DurationType,
                                () => { filter.Duration = option.DurationType; ApplyFilter(); });
                            item.Get <LabelWidget>("LABEL").GetText = () => option.Text;
                            return(item);
                        };

                        ddb.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 330, options, setupItem);
                    };
                }
            }

            // Outcome (depends on Player)
            {
                var ddb = panel.GetOrNull <DropDownButtonWidget>("FLT_OUTCOME_DROPDOWNBUTTON");
                if (ddb != null)
                {
                    ddb.IsDisabled = () => string.IsNullOrEmpty(filter.PlayerName);

                    // Using list to maintain the order
                    var options = new List <(WinState WinState, string Text)>
                    {
                        (WinState.Undefined, ddb.GetText()),
                        (WinState.Lost, "Defeat"),
                        (WinState.Won, "Victory")
                    };

                    var lookup = options.ToDictionary(kvp => kvp.WinState, kvp => kvp.Text);

                    ddb.GetText     = () => lookup[filter.Outcome];
                    ddb.OnMouseDown = _ =>
                    {
                        Func <(WinState WinState, string Text), ScrollItemWidget, ScrollItemWidget> setupItem = (option, tpl) =>
                        {
                            var item = ScrollItemWidget.Setup(
                                tpl,
                                () => filter.Outcome == option.WinState,
                                () => { filter.Outcome = option.WinState; ApplyFilter(); });
                            item.Get <LabelWidget>("LABEL").GetText = () => option.Text;
                            return(item);
                        };

                        ddb.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 330, options, setupItem);
                    };
                }
            }

            // Reset button
            {
                var button = panel.Get <ButtonWidget>("FLT_RESET_BUTTON");
                button.IsDisabled = () => filter.IsEmpty;
                button.OnClick    = () => { filter = new Filter(); ApplyFilter(); };
            }
        }
Esempio n. 30
0
        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();
            }
        }