예제 #1
0
파일: MapCache.cs 프로젝트: dnqbob/OpenRA
 public IEnumerable <Map> EnumerateMapsWithoutCaching(MapClassification classification = MapClassification.System)
 {
     foreach (var mapPackage in EnumerateMapPackagesWithoutCaching(classification))
     {
         yield return(new Map(modData, mapPackage));
     }
 }
예제 #2
0
        public void LoadMap(string map, IReadOnlyPackage package, MapClassification classification, MapGrid mapGrid, string oldMap)
        {
            IReadOnlyPackage mapPackage = null;

            try
            {
                using (new Support.PerfTimer(map))
                {
                    mapPackage = package.OpenPackage(map, modData.ModFiles);
                    if (mapPackage != null)
                    {
                        var uid = Map.ComputeUID(mapPackage);
                        previews[uid].UpdateFromMap(mapPackage, package, classification, modData.Manifest.MapCompatibility, mapGrid.Type);

                        if (oldMap != uid)
                        {
                            MapUpdated(oldMap, uid);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                mapPackage?.Dispose();
                Console.WriteLine("Failed to load map: {0}", map);
                Console.WriteLine("Details: {0}", e);
                Log.Write("debug", "Failed to load map: {0}", map);
                Log.Write("debug", "Details: {0}", e);
            }
        }
예제 #3
0
        public IEnumerable <Map> EnumerateMapsWithoutCaching(MapClassification classification = MapClassification.System)
        {
            // Utility mod that does not support maps
            if (!modData.Manifest.Contains <MapGrid>())
            {
                yield break;
            }

            // Enumerate map directories
            foreach (var kv in modData.Manifest.MapFolders)
            {
                MapClassification packageClassification;
                if (!Enum.TryParse(kv.Value, out packageClassification))
                {
                    continue;
                }

                if (!classification.HasFlag(packageClassification))
                {
                    continue;
                }

                var name     = kv.Key;
                var optional = name.StartsWith("~", StringComparison.Ordinal);
                if (optional)
                {
                    name = name.Substring(1);
                }

                // Don't try to open the map directory in the support directory if it doesn't exist
                if (Platform.IsPathRelativeToSupportDirectory(name))
                {
                    var resolved = Platform.ResolvePath(name);
                    if (!Directory.Exists(resolved) || !File.Exists(resolved))
                    {
                        continue;
                    }
                }

                using (var package = (IReadWritePackage)modData.ModFiles.OpenPackage(name))
                {
                    foreach (var map in package.Contents)
                    {
                        var mapPackage = package.OpenPackage(map, modData.ModFiles);
                        if (mapPackage != null)
                        {
                            yield return(new Map(modData, mapPackage));
                        }
                    }
                }
            }
        }
예제 #4
0
        internal MapChooserLogic(Widget widget, ModData modData, string initialMap,
                                 MapClassification initialTab, Action onExit, Action <string> onSelect, MapVisibility filter)
        {
            this.widget   = widget;
            this.modData  = modData;
            this.onSelect = onSelect;

            var approving = new Action(() => { UI.CloseWindow(); onSelect(selectedUid); });
            var canceling = new Action(() => { UI.CloseWindow(); onExit(); });

            var okButton = widget.Get <ButtonWidget>("BUTTON_OK");

            okButton.Disabled = this.onSelect == null;
            okButton.OnClick  = approving;
            widget.Get <ButtonWidget>("BUTTON_CANCEL").OnClick = canceling;

            var itemTemplate = widget.Get <ScrollItemWidget>("MAP_TEMPLATE");

            widget.RemoveChild(itemTemplate);

            var randomMapButton = widget.GetOrNull <ButtonWidget>("RANDOMMAP_BUTTON");

            if (randomMapButton != null)
            {
                randomMapButton.OnClick = () =>
                {
                    var uid = visibleMaps.Random(WarGame.CosmeticRandom);
                    selectedUid = uid;
                };

                randomMapButton.IsDisabled = () => visibleMaps == null || visibleMaps.Length == 0;
            }


            SetupMapTab(MapClassification.User, filter, "USER_MAPS_TAB_BUTTON", "USER_MAPS_TAB", itemTemplate);
            SetupMapTab(MapClassification.System, filter, "SYSTEM_MAPS_TAB_BUTTON", "SYSTEM_MAPS_TAB", itemTemplate);

            if (initialMap == null && tabMaps.Keys.Contains(initialTab) && tabMaps[initialTab].Any())
            {
                selectedUid = WarGame.ModData.MapCache.ChooseInitialMap(tabMaps[initialTab].Select(mp => mp.Uid).First(),
                                                                        WarGame.CosmeticRandom);
                currentTab = initialTab;
            }
            else
            {
                selectedUid = WarGame.ModData.MapCache.ChooseInitialMap(initialMap, WarGame.CosmeticRandom);
                currentTab  = tabMaps.Keys.FirstOrDefault(k => tabMaps[k].Select(mp => mp.Uid).Contains(selectedUid));
            }

            SwitchTab(currentTab, itemTemplate);
        }
예제 #5
0
 public void UpdateFromMap(Map m, MapClassification classification)
 {
     Map           = m;
     Title         = m.Title;
     Type          = m.Type;
     Type          = m.Type;
     Author        = m.Author;
     PlayerCount   = m.Players.Count(x => x.Value.Playable);
     Bounds        = m.Bounds;
     SpawnPoints   = m.GetSpawnPoints().ToList();
     CustomPreview = m.CustomPreview;
     Status        = MapStatus.Available;
     Class         = classification;
 }
예제 #6
0
        void SetupGameModeDropdown(MapClassification tab, DropDownButtonWidget gameModeDropdown, ScrollItemWidget itemTemplate)
        {
            if (gameModeDropdown != null)
            {
                var categoryDict = new Dictionary <string, int>();
                foreach (var map in tabMaps[tab])
                {
                    foreach (var category in map.Categories)
                    {
                        var count = 0;
                        categoryDict.TryGetValue(category, out count);
                        categoryDict[category] = count + 1;
                    }
                }

                // Order categories alphabetically
                var categories = categoryDict
                                 .Select(kv => Pair.New(kv.Key, kv.Value))
                                 .OrderBy(p => p.First)
                                 .ToList();

                // 'all game types' extra item
                categories.Insert(0, Pair.New(null as string, tabMaps[tab].Count()));

                Func <Pair <string, int>, string> showItem = x => "{0} ({1})".F(x.First ?? "All Maps", x.Second);

                Func <Pair <string, int>, ScrollItemWidget, ScrollItemWidget> setupItem = (ii, template) =>
                {
                    var item = ScrollItemWidget.Setup(template,
                                                      () => category == ii.First,
                                                      () => { category = ii.First; EnumerateMaps(tab, itemTemplate); });
                    item.Get <LabelWidget>("LABEL").GetText = () => showItem(ii);
                    return(item);
                };

                gameModeDropdown.OnClick = () =>
                                           gameModeDropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 210, categories, setupItem);

                gameModeDropdown.GetText = () =>
                {
                    var item = categories.FirstOrDefault(m => m.First == category);
                    if (item == default(Pair <string, int>))
                    {
                        item.First = "No matches";
                    }

                    return(showItem(item));
                };
            }
        }
예제 #7
0
		void SetupMapTab(MapClassification tab, MapVisibility filter, string tabButtonName, string tabContainerName, ScrollItemWidget itemTemplate)
		{
			var tabContainer = widget.Get<ContainerWidget>(tabContainerName);
			tabContainer.IsVisible = () => currentTab == tab;
			var tabScrollpanel = tabContainer.Get<ScrollPanelWidget>("MAP_LIST");
			tabScrollpanel.Layout = new GridLayout(tabScrollpanel);
			scrollpanels.Add(tab, tabScrollpanel);

			var tabButton = widget.Get<ButtonWidget>(tabButtonName);
			tabButton.IsHighlighted = () => currentTab == tab;
			tabButton.IsVisible = () => tabMaps[tab].Any();
			tabButton.OnClick = () => SwitchTab(tab, itemTemplate);

			RefreshMaps(tab, filter);
		}
예제 #8
0
        public IEnumerable <IReadWritePackage> EnumerateMapPackagesWithoutCaching(MapClassification classification = MapClassification.System)
        {
            var mapDirPackages = EnumerateMapDirPackages(classification);

            foreach (var mapDirPackage in mapDirPackages)
            {
                foreach (var map in mapDirPackage.Contents)
                {
                    if (mapDirPackage.OpenPackage(map, modData.ModFiles) is IReadWritePackage mapPackage)
                    {
                        yield return(mapPackage);
                    }
                }
            }
        }
예제 #9
0
        public MapDirectoryTracker(MapGrid mapGrid, IReadOnlyPackage package, MapClassification classification)
        {
            this.mapGrid        = mapGrid;
            this.package        = package;
            this.classification = classification;

            watcher          = new FileSystemWatcher(package.Name);
            watcher.Changed += (object sender, FileSystemEventArgs e) => AddMapAction(MapAction.Update, e.FullPath);
            watcher.Created += (object sender, FileSystemEventArgs e) => AddMapAction(MapAction.Add, e.FullPath);
            watcher.Deleted += (object sender, FileSystemEventArgs e) => AddMapAction(MapAction.Delete, e.FullPath);
            watcher.Renamed += (object sender, RenamedEventArgs e) => AddMapAction(MapAction.Add, e.FullPath, e.OldFullPath);

            watcher.IncludeSubdirectories = true;
            watcher.EnableRaisingEvents   = true;
        }
예제 #10
0
        public void UpdateFromMap(Map m, MapClassification classification)
        {
            Map           = m;
            Title         = m.Title;
            Type          = m.Type;
            Type          = m.Type;
            Author        = m.Author;
            Bounds        = m.Bounds;
            SpawnPoints   = m.SpawnPoints.Value;
            CustomPreview = m.CustomPreview;
            Status        = MapStatus.Available;
            Class         = classification;

            var players = new MapPlayers(m.PlayerDefinitions).Players;

            PlayerCount = players.Count(x => x.Value.Playable);

            SuitableForInitialMap = EvaluateUserFriendliness(players);
        }
예제 #11
0
        public IEnumerable <IReadWritePackage> EnumerateMapDirPackages(MapClassification classification = MapClassification.System)
        {
            // Utility mod that does not support maps
            if (!modData.Manifest.Contains <MapGrid>())
            {
                yield break;
            }

            // Enumerate map directories
            foreach (var kv in modData.Manifest.MapFolders)
            {
                if (!Enum.TryParse(kv.Value, out MapClassification packageClassification))
                {
                    continue;
                }

                if (!classification.HasFlag(packageClassification))
                {
                    continue;
                }

                var name     = kv.Key;
                var optional = name.StartsWith("~", StringComparison.Ordinal);
                if (optional)
                {
                    name = name.Substring(1);
                }

                // Don't try to open the map directory in the support directory if it doesn't exist
                var resolved = Platform.ResolvePath(name);
                if (resolved.StartsWith(Platform.SupportDir) && (!Directory.Exists(resolved) || !File.Exists(resolved)))
                {
                    continue;
                }

                using (var package = (IReadWritePackage)modData.ModFiles.OpenPackage(name))
                    yield return(package);
            }
        }
예제 #12
0
        void SetupGameModeDropdown(MapClassification tab, DropDownButtonWidget gameModeDropdown, ScrollItemWidget itemTemplate)
        {
            if (gameModeDropdown != null)
            {
                var gameModes = tabMaps[tab]
                                .GroupBy(m => m.Type)
                                .Select(g => Pair.New(g.Key, g.Count())).ToList();

                // 'all game types' extra item
                gameModes.Insert(0, Pair.New(null as string, tabMaps[tab].Count()));

                Func <Pair <string, int>, string> showItem = x => "{0} ({1})".F(x.First ?? "All Game Types", x.Second);

                Func <Pair <string, int>, ScrollItemWidget, ScrollItemWidget> setupItem = (ii, template) =>
                {
                    var item = ScrollItemWidget.Setup(template,
                                                      () => gameMode == ii.First,
                                                      () => { gameMode = ii.First; EnumerateMaps(tab, itemTemplate); });
                    item.Get <LabelWidget>("LABEL").GetText = () => showItem(ii);
                    return(item);
                };

                gameModeDropdown.OnClick = () =>
                                           gameModeDropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 210, gameModes, setupItem);

                gameModeDropdown.GetText = () =>
                {
                    var item = gameModes.FirstOrDefault(m => m.First == gameMode);
                    if (item == default(Pair <string, int>))
                    {
                        item.First = "No matches";
                    }

                    return(showItem(item));
                };
            }
        }
예제 #13
0
		public void UpdateFromMap(Map m, MapClassification classification)
		{
			Map = m;
			Title = m.Title;
			Type = m.Type;
			Type = m.Type;
			Author = m.Author;
			Bounds = m.Bounds;
			SpawnPoints = m.SpawnPoints.Value;
			GridType = m.Grid.Type;
			CustomPreview = m.CustomPreview;
			Status = MapStatus.Available;
			Class = classification;

			var players = new MapPlayers(m.PlayerDefinitions).Players;
			PlayerCount = players.Count(x => x.Value.Playable);

			SuitableForInitialMap = EvaluateUserFriendliness(players);
		}
예제 #14
0
 public SaveDirectory(Folder folder, string displayName, MapClassification classification)
 {
     Folder         = folder;
     DisplayName    = displayName;
     Classification = classification;
 }
예제 #15
0
파일: MapPreview.cs 프로젝트: pchote/OpenRA
        public void UpdateFromMap(IReadOnlyPackage p, IReadOnlyPackage parent, MapClassification classification, string[] mapCompatibility, MapGridType gridType)
        {
            Dictionary<string, MiniYaml> yaml;
            using (var yamlStream = p.GetStream("map.yaml"))
            {
                if (yamlStream == null)
                    throw new FileNotFoundException("Required file map.yaml not present in this map");

                yaml = new MiniYaml(null, MiniYaml.FromStream(yamlStream, "map.yaml")).ToDictionary();
            }

            Package = p;
            parentPackage = parent;

            var newData = innerData.Clone();
            newData.GridType = gridType;
            newData.Class = classification;

            MiniYaml temp;
            if (yaml.TryGetValue("MapFormat", out temp))
            {
                var format = FieldLoader.GetValue<int>("MapFormat", temp.Value);
                if (format != Map.SupportedMapFormat)
                    throw new InvalidDataException("Map format {0} is not supported.".F(format));
            }

            if (yaml.TryGetValue("Title", out temp))
                newData.Title = temp.Value;

            if (yaml.TryGetValue("Categories", out temp))
                newData.Categories = FieldLoader.GetValue<string[]>("Categories", temp.Value);

            if (yaml.TryGetValue("Tileset", out temp))
                newData.TileSet = temp.Value;

            if (yaml.TryGetValue("Author", out temp))
                newData.Author = temp.Value;

            if (yaml.TryGetValue("Bounds", out temp))
                newData.Bounds = FieldLoader.GetValue<Rectangle>("Bounds", temp.Value);

            if (yaml.TryGetValue("Visibility", out temp))
                newData.Visibility = FieldLoader.GetValue<MapVisibility>("Visibility", temp.Value);

            string requiresMod = string.Empty;
            if (yaml.TryGetValue("RequiresMod", out temp))
                requiresMod = temp.Value;

            newData.Status = mapCompatibility == null || mapCompatibility.Contains(requiresMod) ?
                MapStatus.Available : MapStatus.Unavailable;

            try
            {
                // Actor definitions may change if the map format changes
                MiniYaml actorDefinitions;
                if (yaml.TryGetValue("Actors", out actorDefinitions))
                {
                    var spawns = new List<CPos>();
                    foreach (var kv in actorDefinitions.Nodes.Where(d => d.Value.Value == "mpspawn"))
                    {
                        var s = new ActorReference(kv.Value.Value, kv.Value.ToDictionary());
                        spawns.Add(s.InitDict.Get<LocationInit>().Value(null));
                    }

                    newData.SpawnPoints = spawns.ToArray();
                }
                else
                    newData.SpawnPoints = new CPos[0];
            }
            catch (Exception)
            {
                newData.SpawnPoints = new CPos[0];
                newData.Status = MapStatus.Unavailable;
            }

            try
            {
                // Player definitions may change if the map format changes
                MiniYaml playerDefinitions;
                if (yaml.TryGetValue("Players", out playerDefinitions))
                {
                    newData.Players = new MapPlayers(playerDefinitions.Nodes);
                    newData.PlayerCount = newData.Players.Players.Count(x => x.Value.Playable);
                }
            }
            catch (Exception)
            {
                newData.Status = MapStatus.Unavailable;
            }

            newData.SetRulesetGenerator(modData, () =>
            {
                var ruleDefinitions = LoadRuleSection(yaml, "Rules");
                var weaponDefinitions = LoadRuleSection(yaml, "Weapons");
                var voiceDefinitions = LoadRuleSection(yaml, "Voices");
                var musicDefinitions = LoadRuleSection(yaml, "Music");
                var notificationDefinitions = LoadRuleSection(yaml, "Notifications");
                var sequenceDefinitions = LoadRuleSection(yaml, "Sequences");
                var rules = Ruleset.Load(modData, this, TileSet, ruleDefinitions, weaponDefinitions,
                    voiceDefinitions, notificationDefinitions, musicDefinitions, sequenceDefinitions);
                var flagged = Ruleset.DefinesUnsafeCustomRules(modData, this, ruleDefinitions,
                    weaponDefinitions, voiceDefinitions, notificationDefinitions, sequenceDefinitions);
                return Pair.New(rules, flagged);
            });

            if (p.Contains("map.png"))
                using (var dataStream = p.GetStream("map.png"))
                    newData.Preview = new Bitmap(dataStream);

            // Assign the new data atomically
            innerData = newData;
        }
예제 #16
0
 void RefreshMaps(MapClassification tab, MapVisibility filter)
 {
     tabMaps[tab] = Game.ModData.MapCache.Where(m => m.Status == MapStatus.Available &&
         m.Class == tab && (m.Map.Visibility & filter) != 0).ToArray();
 }
예제 #17
0
        internal MapChooserLogic(Widget widget, ModData modData, string initialMap,
                                 MapClassification initialTab, Action onExit, Action <string> onSelect, MapVisibility filter)
        {
            this.widget   = widget;
            this.modData  = modData;
            this.onSelect = onSelect;

            var approving = new Action(() => { Ui.CloseWindow(); onSelect(selectedUid); });
            var canceling = new Action(() => { Ui.CloseWindow(); onExit(); });

            var okButton = widget.Get <ButtonWidget>("BUTTON_OK");

            okButton.Disabled = this.onSelect == null;
            okButton.OnClick  = approving;
            widget.Get <ButtonWidget>("BUTTON_CANCEL").OnClick = canceling;

            gameModeDropdown = widget.GetOrNull <DropDownButtonWidget>("GAMEMODE_FILTER");

            var itemTemplate = widget.Get <ScrollItemWidget>("MAP_TEMPLATE");

            widget.RemoveChild(itemTemplate);

            var mapFilterInput = widget.GetOrNull <TextFieldWidget>("MAPFILTER_INPUT");

            if (mapFilterInput != null)
            {
                mapFilterInput.TakeKeyboardFocus();
                mapFilterInput.OnEscKey = () =>
                {
                    if (mapFilterInput.Text.Length == 0)
                    {
                        canceling();
                    }
                    else
                    {
                        mapFilter = mapFilterInput.Text = null;
                        EnumerateMaps(currentTab, itemTemplate);
                    }

                    return(true);
                };
                mapFilterInput.OnEnterKey   = () => { approving(); return(true); };
                mapFilterInput.OnTextEdited = () =>
                {
                    mapFilter = mapFilterInput.Text;
                    EnumerateMaps(currentTab, itemTemplate);
                };
            }

            var randomMapButton = widget.GetOrNull <ButtonWidget>("RANDOMMAP_BUTTON");

            if (randomMapButton != null)
            {
                randomMapButton.OnClick = () =>
                {
                    var uid = visibleMaps.Random(Game.CosmeticRandom);
                    selectedUid = uid;
                    scrollpanels[currentTab].ScrollToItem(uid, smooth: true);
                };
                randomMapButton.IsDisabled = () => visibleMaps == null || visibleMaps.Length == 0;
            }

            var deleteMapButton = widget.Get <ButtonWidget>("DELETE_MAP_BUTTON");

            deleteMapButton.IsDisabled = () => modData.MapCache[selectedUid].Class != MapClassification.User;
            deleteMapButton.IsVisible  = () => currentTab == MapClassification.User;
            deleteMapButton.OnClick    = () =>
            {
                DeleteOneMap(selectedUid, (string newUid) =>
                {
                    RefreshMaps(currentTab, filter);
                    EnumerateMaps(currentTab, itemTemplate);
                    if (!tabMaps[currentTab].Any())
                    {
                        SwitchTab(modData.MapCache[newUid].Class, itemTemplate);
                    }
                });
            };

            var deleteAllMapsButton = widget.Get <ButtonWidget>("DELETE_ALL_MAPS_BUTTON");

            deleteAllMapsButton.IsVisible = () => currentTab == MapClassification.User;
            deleteAllMapsButton.OnClick   = () =>
            {
                DeleteAllMaps(visibleMaps, (string newUid) =>
                {
                    RefreshMaps(currentTab, filter);
                    EnumerateMaps(currentTab, itemTemplate);
                    SwitchTab(modData.MapCache[newUid].Class, itemTemplate);
                });
            };

            var refreshMapsButton = widget.GetOrNull <ButtonWidget>("REFRESHMAPS_BUTTON");

            if (refreshMapsButton != null)
            {
                refreshMapsButton.OnClick = () =>
                {
                    Game.ModData.MapCache.LoadMaps();
                    RefreshMaps(currentTab, filter);
                    EnumerateMaps(currentTab, itemTemplate);
                };
            }

            SetupMapTab(MapClassification.User, filter, "USER_MAPS_TAB_BUTTON", "USER_MAPS_TAB", itemTemplate);
            SetupMapTab(MapClassification.System, filter, "SYSTEM_MAPS_TAB_BUTTON", "SYSTEM_MAPS_TAB", itemTemplate);

            if (initialMap == null && tabMaps.Keys.Contains(initialTab) && tabMaps[initialTab].Any())
            {
                selectedUid = Game.ModData.MapCache.ChooseInitialMap(tabMaps[initialTab].Select(mp => mp.Uid).First(),
                                                                     Game.CosmeticRandom);
                currentTab = initialTab;
            }
            else
            {
                selectedUid = Game.ModData.MapCache.ChooseInitialMap(initialMap, Game.CosmeticRandom);
                currentTab  = tabMaps.Keys.FirstOrDefault(k => tabMaps[k].Select(mp => mp.Uid).Contains(selectedUid));
            }

            SwitchTab(currentTab, itemTemplate);
        }
예제 #18
0
        void SetupGameModeDropdown(MapClassification tab, DropDownButtonWidget gameModeDropdown, ScrollItemWidget itemTemplate)
        {
            if (gameModeDropdown != null)
            {
                var categoryDict = new Dictionary<string, int>();
                foreach (var map in tabMaps[tab])
                {
                    foreach (var category in map.Categories)
                    {
                        var count = 0;
                        categoryDict.TryGetValue(category, out count);
                        categoryDict[category] = count + 1;
                    }
                }

                // Order categories alphabetically
                var categories = categoryDict
                    .Select(kv => Pair.New(kv.Key, kv.Value))
                    .OrderBy(p => p.First)
                    .ToList();

                // 'all game types' extra item
                categories.Insert(0, Pair.New(null as string, tabMaps[tab].Count()));

                Func<Pair<string, int>, string> showItem = x => "{0} ({1})".F(x.First ?? "All Maps", x.Second);

                Func<Pair<string, int>, ScrollItemWidget, ScrollItemWidget> setupItem = (ii, template) =>
                {
                    var item = ScrollItemWidget.Setup(template,
                        () => category == ii.First,
                        () => { category = ii.First; EnumerateMaps(tab, itemTemplate); });
                    item.Get<LabelWidget>("LABEL").GetText = () => showItem(ii);
                    return item;
                };

                gameModeDropdown.OnClick = () =>
                    gameModeDropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 210, categories, setupItem);

                gameModeDropdown.GetText = () =>
                {
                    var item = categories.FirstOrDefault(m => m.First == category);
                    if (item == default(Pair<string, int>))
                        item.First = "No matches";

                    return showItem(item);
                };
            }
        }
예제 #19
0
 void SwitchTab(MapClassification tab, ScrollItemWidget itemTemplate)
 {
     currentTab = tab;
     EnumerateMaps(tab, itemTemplate);
 }
예제 #20
0
        public IEnumerable <(IReadWritePackage package, string map)> EnumerateMapDirPackagesAndNames(MapClassification classification = MapClassification.System)
        {
            var mapDirPackages = EnumerateMapDirPackages(classification);

            foreach (var mapDirPackage in mapDirPackages)
            {
                foreach (var map in mapDirPackage.Contents)
                {
                    yield return(mapDirPackage, map);
                }
            }
        }
예제 #21
0
        void EnumerateMaps(MapClassification tab, ScrollItemWidget template)
        {
            int playerCountFilter;
            if (!int.TryParse(mapFilter, out 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<LabelWidget>("TITLE");
                if (titleLabel != null)
                {
                    var font = Game.Renderer.Fonts[titleLabel.Font];
                    var title = WidgetUtils.TruncateText(preview.Title, titleLabel.Bounds.Width, font);
                    titleLabel.GetText = () => 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 += "({0} players)".F(preview.PlayerCount);
                    detailsWidget.GetText = () => details;
                }

                var authorWidget = item.GetOrNull<LabelWidget>("AUTHOR");
                if (authorWidget != null)
                {
                    var font = Game.Renderer.Fonts[authorWidget.Font];
                    var author = WidgetUtils.TruncateText("Created by {0}".F(preview.Author), authorWidget.Bounds.Width, font);
                    authorWidget.GetText = () => 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);
        }
예제 #22
0
        internal MapChooserLogic(Widget widget, string initialMap, MapClassification initialTab, Action onExit, Action<string> onSelect, MapVisibility filter)
        {
            this.widget = widget;
            this.onSelect = onSelect;

            var approving = new Action(() => { Ui.CloseWindow(); onSelect(selectedUid); });
            var canceling = new Action(() => { Ui.CloseWindow(); onExit(); });

            var okButton = widget.Get<ButtonWidget>("BUTTON_OK");
            okButton.Disabled = this.onSelect == null;
            okButton.OnClick = approving;
            widget.Get<ButtonWidget>("BUTTON_CANCEL").OnClick = canceling;

            gameModeDropdown = widget.GetOrNull<DropDownButtonWidget>("GAMEMODE_FILTER");

            var itemTemplate = widget.Get<ScrollItemWidget>("MAP_TEMPLATE");
            widget.RemoveChild(itemTemplate);

            var mapFilterInput = widget.GetOrNull<TextFieldWidget>("MAPFILTER_INPUT");
            if (mapFilterInput != null)
            {
                mapFilterInput.TakeKeyboardFocus();
                mapFilterInput.OnEscKey = () =>
                {
                    if (mapFilterInput.Text.Length == 0)
                        canceling();
                    else
                    {
                        mapFilter = mapFilterInput.Text = null;
                        EnumerateMaps(currentTab, itemTemplate);
                    }

                    return true;
                };
                mapFilterInput.OnEnterKey = () => { approving(); return true; };
                mapFilterInput.OnTextEdited = () =>
                {
                    mapFilter = mapFilterInput.Text;
                    EnumerateMaps(currentTab, itemTemplate);
                };
            }

            var randomMapButton = widget.GetOrNull<ButtonWidget>("RANDOMMAP_BUTTON");
            if (randomMapButton != null)
            {
                randomMapButton.OnClick = () =>
                {
                    var uid = visibleMaps.Random(Game.CosmeticRandom);
                    selectedUid = uid;
                    scrollpanels[currentTab].ScrollToItem(uid, smooth: true);
                };
                randomMapButton.IsDisabled = () => visibleMaps == null || visibleMaps.Length == 0;
            }

            var deleteMapButton = widget.Get<ButtonWidget>("DELETE_MAP_BUTTON");
            deleteMapButton.IsDisabled = () => Game.ModData.MapCache[selectedUid].Class != MapClassification.User;
            deleteMapButton.IsVisible = () => currentTab == MapClassification.User;
            deleteMapButton.OnClick = () =>
            {
                DeleteOneMap(selectedUid, (string newUid) =>
                {
                    RefreshMaps(currentTab, filter);
                    EnumerateMaps(currentTab, itemTemplate);
                    if (!tabMaps[currentTab].Any())
                        SwitchTab(Game.ModData.MapCache[newUid].Class, itemTemplate);
                });
            };

            var deleteAllMapsButton = widget.Get<ButtonWidget>("DELETE_ALL_MAPS_BUTTON");
            deleteAllMapsButton.IsVisible = () => currentTab == MapClassification.User;
            deleteAllMapsButton.OnClick = () =>
            {
                DeleteAllMaps(visibleMaps, (string newUid) =>
                {
                    RefreshMaps(currentTab, filter);
                    EnumerateMaps(currentTab, itemTemplate);
                    SwitchTab(Game.ModData.MapCache[newUid].Class, itemTemplate);
                });
            };

            SetupMapTab(MapClassification.User, filter, "USER_MAPS_TAB_BUTTON", "USER_MAPS_TAB", itemTemplate);
            SetupMapTab(MapClassification.System, filter, "SYSTEM_MAPS_TAB_BUTTON", "SYSTEM_MAPS_TAB", itemTemplate);

            if (initialMap == null && tabMaps.Keys.Contains(initialTab) && tabMaps[initialTab].Any())
            {
                selectedUid = WidgetUtils.ChooseInitialMap(tabMaps[initialTab].Select(mp => mp.Uid).First());
                currentTab = initialTab;
            }
            else
            {
                selectedUid = WidgetUtils.ChooseInitialMap(initialMap);
                currentTab = tabMaps.Keys.FirstOrDefault(k => tabMaps[k].Select(mp => mp.Uid).Contains(selectedUid));
            }

            SwitchTab(currentTab, itemTemplate);
        }
예제 #23
0
 void SwitchTab(MapClassification tab, ScrollItemWidget itemTemplate)
 {
     currentTab = tab;
     EnumerateMaps(tab, itemTemplate);
 }
예제 #24
0
        void SetupMapTab(MapClassification tab, MapVisibility filter, string tabButtonName, string tabContainerName, ScrollItemWidget itemTemplate)
        {
            var tabContainer = widget.Get<ContainerWidget>(tabContainerName);
            tabContainer.IsVisible = () => currentTab == tab;
            var tabScrollpanel = tabContainer.Get<ScrollPanelWidget>("MAP_LIST");
            tabScrollpanel.Layout = new GridLayout(tabScrollpanel);
            scrollpanels.Add(tab, tabScrollpanel);

            var tabButton = widget.Get<ButtonWidget>(tabButtonName);
            tabButton.IsHighlighted = () => currentTab == tab;
            tabButton.IsVisible = () => tabMaps[tab].Any();
            tabButton.OnClick = () => SwitchTab(tab, itemTemplate);

            RefreshMaps(tab, filter);
        }
예제 #25
0
        void SetupGameModeDropdown(MapClassification tab, DropDownButtonWidget gameModeDropdown, ScrollItemWidget itemTemplate)
        {
            if (gameModeDropdown != null)
            {
                var gameModes = tabMaps[tab]
                    .GroupBy(m => m.Type)
                    .Select(g => Pair.New(g.Key, g.Count())).ToList();

                // 'all game types' extra item
                gameModes.Insert(0, Pair.New(null as string, tabMaps[tab].Count()));

                Func<Pair<string, int>, string> showItem = x => "{0} ({1})".F(x.First ?? "All Game Types", x.Second);

                Func<Pair<string, int>, ScrollItemWidget, ScrollItemWidget> setupItem = (ii, template) =>
                {
                    var item = ScrollItemWidget.Setup(template,
                        () => gameMode == ii.First,
                        () => { gameMode = ii.First; EnumerateMaps(tab, itemTemplate); });
                    item.Get<LabelWidget>("LABEL").GetText = () => showItem(ii);
                    return item;
                };

                gameModeDropdown.OnClick = () =>
                    gameModeDropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 210, gameModes, setupItem);

                gameModeDropdown.GetText = () =>
                {
                    var item = gameModes.FirstOrDefault(m => m.First == gameMode);
                    if (item == default(Pair<string, int>))
                        item.First = "No matches";

                    return showItem(item);
                };
            }
        }
예제 #26
0
        void EnumerateMaps(MapClassification tab, ScrollItemWidget template)
        {
            var maps = tabMaps[tab]
                       .Where(m => gameMode == null || m.Type == gameMode)
                       .Where(m => mapFilter == null ||
                              m.Title.IndexOf(mapFilter, StringComparison.OrdinalIgnoreCase) >= 0 ||
                              m.Author.IndexOf(mapFilter, StringComparison.OrdinalIgnoreCase) >= 0)
                       .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 <LabelWidget>("TITLE");
                titleLabel.GetText = () => preview.Title;

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

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

                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);
            }
        }
예제 #27
0
 public SaveDirectory(Folder folder, MapClassification classification)
 {
     Folder = folder;
     DisplayName = Platform.UnresolvePath(Folder.Name);
     Classification = classification;
 }
예제 #28
0
 public SaveDirectory(Folder folder, MapClassification classification)
 {
     Folder         = folder;
     DisplayName    = Platform.UnresolvePath(Folder.Name);
     Classification = classification;
 }
예제 #29
0
 void RefreshMaps(MapClassification tab, MapVisibility filter)
 {
     tabMaps[tab] = modData.MapCache.Where(m => m.Status == MapStatus.Available &&
                                           m.Class == tab && (m.Visibility & filter) != 0).ToArray();
 }
예제 #30
0
        public void UpdateFromMap(IReadOnlyPackage p, IReadOnlyPackage parent, MapClassification classification, string[] mapCompatibility, MapGridType gridType)
        {
            Dictionary <string, MiniYaml> yaml;

            using (var yamlStream = p.GetStream("map.yaml"))
            {
                if (yamlStream == null)
                {
                    throw new FileNotFoundException("Required file map.yaml not present in this map");
                }

                yaml = new MiniYaml(null, MiniYaml.FromStream(yamlStream, "map.yaml")).ToDictionary();
            }

            Package       = p;
            parentPackage = parent;

            var newData = innerData.Clone();

            newData.GridType = gridType;
            newData.Class    = classification;

            MiniYaml temp;

            if (yaml.TryGetValue("MapFormat", out temp))
            {
                var format = FieldLoader.GetValue <int>("MapFormat", temp.Value);
                if (format != Map.SupportedMapFormat)
                {
                    throw new InvalidDataException("Map format {0} is not supported.".F(format));
                }
            }

            if (yaml.TryGetValue("Title", out temp))
            {
                newData.Title = temp.Value;
            }

            if (yaml.TryGetValue("Categories", out temp))
            {
                newData.Categories = FieldLoader.GetValue <string[]>("Categories", temp.Value);
            }

            if (yaml.TryGetValue("Tileset", out temp))
            {
                newData.TileSet = temp.Value;
            }

            if (yaml.TryGetValue("Author", out temp))
            {
                newData.Author = temp.Value;
            }

            if (yaml.TryGetValue("Bounds", out temp))
            {
                newData.Bounds = FieldLoader.GetValue <Rectangle>("Bounds", temp.Value);
            }

            if (yaml.TryGetValue("Visibility", out temp))
            {
                newData.Visibility = FieldLoader.GetValue <MapVisibility>("Visibility", temp.Value);
            }

            string requiresMod = string.Empty;

            if (yaml.TryGetValue("RequiresMod", out temp))
            {
                requiresMod = temp.Value;
            }

            newData.Status = mapCompatibility == null || mapCompatibility.Contains(requiresMod) ?
                             MapStatus.Available : MapStatus.Unavailable;

            try
            {
                // Actor definitions may change if the map format changes
                MiniYaml actorDefinitions;
                if (yaml.TryGetValue("Actors", out actorDefinitions))
                {
                    var spawns = new List <CPos>();
                    foreach (var kv in actorDefinitions.Nodes.Where(d => d.Value.Value == "mpspawn"))
                    {
                        var s = new ActorReference(kv.Value.Value, kv.Value.ToDictionary());
                        spawns.Add(s.InitDict.Get <LocationInit>().Value(null));
                    }

                    newData.SpawnPoints = spawns.ToArray();
                }
                else
                {
                    newData.SpawnPoints = new CPos[0];
                }
            }
            catch (Exception)
            {
                newData.SpawnPoints = new CPos[0];
                newData.Status      = MapStatus.Unavailable;
            }

            try
            {
                // Player definitions may change if the map format changes
                MiniYaml playerDefinitions;
                if (yaml.TryGetValue("Players", out playerDefinitions))
                {
                    newData.Players     = new MapPlayers(playerDefinitions.Nodes);
                    newData.PlayerCount = newData.Players.Players.Count(x => x.Value.Playable);
                }
            }
            catch (Exception)
            {
                newData.Status = MapStatus.Unavailable;
            }

            newData.SetRulesetGenerator(modData, () =>
            {
                var ruleDefinitions          = LoadRuleSection(yaml, "Rules");
                var weaponDefinitions        = LoadRuleSection(yaml, "Weapons");
                var voiceDefinitions         = LoadRuleSection(yaml, "Voices");
                var musicDefinitions         = LoadRuleSection(yaml, "Music");
                var notificationDefinitions  = LoadRuleSection(yaml, "Notifications");
                var sequenceDefinitions      = LoadRuleSection(yaml, "Sequences");
                var modelSequenceDefinitions = LoadRuleSection(yaml, "ModelSequences");
                var rules = Ruleset.Load(modData, this, TileSet, ruleDefinitions, weaponDefinitions,
                                         voiceDefinitions, notificationDefinitions, musicDefinitions, sequenceDefinitions, modelSequenceDefinitions);
                var flagged = Ruleset.DefinesUnsafeCustomRules(modData, this, ruleDefinitions,
                                                               weaponDefinitions, voiceDefinitions, notificationDefinitions, sequenceDefinitions);
                return(Pair.New(rules, flagged));
            });

            if (p.Contains("map.png"))
            {
                using (var dataStream = p.GetStream("map.png"))
                    newData.Preview = new Bitmap(dataStream);
            }

            // Assign the new data atomically
            innerData = newData;
        }
예제 #31
0
        void EnumerateMaps(MapClassification tab, ScrollItemWidget template)
        {
            int playerCountFilter;

            if (!int.TryParse(mapFilter, out 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 <LabelWidget>("TITLE");
                if (titleLabel != null)
                {
                    var font  = Game.Renderer.Fonts[titleLabel.Font];
                    var title = WidgetUtils.TruncateText(preview.Title, titleLabel.Bounds.Width, font);
                    titleLabel.GetText = () => 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 += "({0} players)".F(preview.PlayerCount);
                    detailsWidget.GetText = () => details;
                }

                var authorWidget = item.GetOrNull <LabelWidget>("AUTHOR");
                if (authorWidget != null)
                {
                    var font   = Game.Renderer.Fonts[authorWidget.Font];
                    var author = WidgetUtils.TruncateText("Created by {0}".F(preview.Author), authorWidget.Bounds.Width, font);
                    authorWidget.GetText = () => 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);
            }
        }
예제 #32
0
		public void UpdateFromMap(Map m, MapClassification classification)
		{
			Map = m;
			Title = m.Title;
			Type = m.Type;
			Type = m.Type;
			Author = m.Author;
			PlayerCount = m.Players.Count(x => x.Value.Playable);
			Bounds = m.Bounds;
			SpawnPoints = m.GetSpawnPoints().ToList();
			CustomPreview = m.CustomPreview;
			Status = MapStatus.Available;
			Class = classification;
		}
예제 #33
0
        public void UpdateFromMap(IReadOnlyPackage p, IReadOnlyPackage parent, MapClassification classification, string[] mapCompatibility, MapGridType gridType)
        {
            Dictionary <string, MiniYaml> yaml;

            using (var yamlStream = p.GetStream("map.yaml"))
            {
                if (yamlStream == null)
                {
                    throw new FileNotFoundException("Required file map.yaml not present in this map");
                }

                yaml = new MiniYaml(null, MiniYaml.FromStream(yamlStream, "map.yaml", stringPool: cache.StringPool)).ToDictionary();
            }

            Package       = p;
            parentPackage = parent;

            var newData = innerData.Clone();

            newData.GridType = gridType;
            newData.Class    = classification;

            if (yaml.TryGetValue("MapFormat", out var temp))
            {
                var format = FieldLoader.GetValue <int>("MapFormat", temp.Value);
                if (format != Map.SupportedMapFormat)
                {
                    throw new InvalidDataException($"Map format {format} is not supported.");
                }
            }

            if (yaml.TryGetValue("Title", out temp))
            {
                newData.Title = temp.Value;
            }

            if (yaml.TryGetValue("Categories", out temp))
            {
                newData.Categories = FieldLoader.GetValue <string[]>("Categories", temp.Value);
            }

            if (yaml.TryGetValue("Tileset", out temp))
            {
                newData.TileSet = temp.Value;
            }

            if (yaml.TryGetValue("Author", out temp))
            {
                newData.Author = temp.Value;
            }

            if (yaml.TryGetValue("Bounds", out temp))
            {
                newData.Bounds = FieldLoader.GetValue <Rectangle>("Bounds", temp.Value);
            }

            if (yaml.TryGetValue("Visibility", out temp))
            {
                newData.Visibility = FieldLoader.GetValue <MapVisibility>("Visibility", temp.Value);
            }

            string requiresMod = string.Empty;

            if (yaml.TryGetValue("RequiresMod", out temp))
            {
                requiresMod = temp.Value;
            }

            if (yaml.TryGetValue("MapFormat", out temp))
            {
                newData.MapFormat = FieldLoader.GetValue <int>("MapFormat", temp.Value);
            }

            newData.Status = mapCompatibility == null || mapCompatibility.Contains(requiresMod) ?
                             MapStatus.Available : MapStatus.Unavailable;

            try
            {
                // Actor definitions may change if the map format changes
                if (yaml.TryGetValue("Actors", out var actorDefinitions))
                {
                    var spawns = new List <CPos>();
                    foreach (var kv in actorDefinitions.Nodes.Where(d => d.Value.Value == "mpspawn"))
                    {
                        var s = new ActorReference(kv.Value.Value, kv.Value.ToDictionary());
                        spawns.Add(s.Get <LocationInit>().Value);
                    }

                    newData.SpawnPoints = spawns.ToArray();
                }
                else
                {
                    newData.SpawnPoints = Array.Empty <CPos>();
                }
            }
            catch (Exception)
            {
                newData.SpawnPoints = Array.Empty <CPos>();
                newData.Status      = MapStatus.Unavailable;
            }

            try
            {
                // Player definitions may change if the map format changes
                if (yaml.TryGetValue("Players", out var playerDefinitions))
                {
                    newData.Players     = new MapPlayers(playerDefinitions.Nodes);
                    newData.PlayerCount = newData.Players.Players.Count(x => x.Value.Playable);
                }
            }
            catch (Exception)
            {
                newData.Status = MapStatus.Unavailable;
            }

            newData.SetCustomRules(modData, this, yaml);

            if (p.Contains("map.png"))
            {
                using (var dataStream = p.GetStream("map.png"))
                    newData.Preview = new Png(dataStream);
            }

            // Assign the new data atomically
            innerData = newData;
        }
예제 #34
0
        void EnumerateMaps(MapClassification tab, ScrollItemWidget template)
        {
            var maps = tabMaps[tab]
                .Where(m => gameMode == null || m.Type == gameMode)
                .Where(m => mapFilter == null ||
                    m.Title.IndexOf(mapFilter, StringComparison.OrdinalIgnoreCase) >= 0 ||
                    m.Author.IndexOf(mapFilter, StringComparison.OrdinalIgnoreCase) >= 0)
                .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<LabelWidget>("TITLE");
                titleLabel.GetText = () => preview.Title;

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

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

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