public IEnumerable <Map> EnumerateMapsWithoutCaching(MapClassification classification = MapClassification.System) { foreach (var mapPackage in EnumerateMapPackagesWithoutCaching(classification)) { yield return(new Map(modData, mapPackage)); } }
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); } }
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)); } } } } }
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); }
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; }
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)); }; } }
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); }
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); } } } }
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; }
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); }
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); } }
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)); }; } }
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); }
public SaveDirectory(Folder folder, string displayName, MapClassification classification) { Folder = folder; DisplayName = displayName; Classification = classification; }
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; }
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(); }
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); }
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); }; } }
void SwitchTab(MapClassification tab, ScrollItemWidget itemTemplate) { currentTab = tab; EnumerateMaps(tab, itemTemplate); }
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); } } }
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); }
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); }
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); }; } }
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); } }
public SaveDirectory(Folder folder, MapClassification classification) { Folder = folder; DisplayName = Platform.UnresolvePath(Folder.Name); Classification = classification; }
void RefreshMaps(MapClassification tab, MapVisibility filter) { tabMaps[tab] = modData.MapCache.Where(m => m.Status == MapStatus.Available && m.Class == tab && (m.Visibility & filter) != 0).ToArray(); }
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; }
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); } }
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; }
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); }