public static ScrollItemWidget Setup(string key, ScrollItemWidget template, Func<bool> isSelected, Action onClick, Action onDoubleClick) { var w = Setup(template, isSelected, onClick); w.OnDoubleClick = onDoubleClick; w.ItemKey = key; return w; }
public static ScrollItemWidget Setup(ScrollItemWidget template, Func<bool> isSelected, Action onClick) { var w = template.Clone() as ScrollItemWidget; w.IsVisible = () => true; w.IsSelected = isSelected; w.OnClick = onClick; return w; }
protected ScrollItemWidget(ScrollItemWidget other) : base(other) { IsVisible = () => false; VisualHeight = 0; IgnoreChildMouseOver = true; Key = other.Key; BaseName = other.BaseName; }
public ReplayBrowserLogic(Widget widget, Action onExit, Action onStart) { panel = widget; this.onStart = onStart; playerList = panel.Get<ScrollPanelWidget>("PLAYER_LIST"); playerHeader = playerList.Get<ScrollItemWidget>("HEADER"); playerTemplate = playerList.Get<ScrollItemWidget>("TEMPLATE"); playerList.RemoveChildren(); panel.Get<ButtonWidget>("CANCEL_BUTTON").OnClick = () => { cancelLoadingReplays = true; Ui.CloseWindow(); onExit(); }; replayList = panel.Get<ScrollPanelWidget>("REPLAY_LIST"); var template = panel.Get<ScrollItemWidget>("REPLAY_TEMPLATE"); var mod = Game.ModData.Manifest.Mod; var dir = Platform.ResolvePath("^", "Replays", mod.Id, mod.Version); if (Directory.Exists(dir)) ThreadPool.QueueUserWorkItem(_ => LoadReplays(dir, template)); var watch = panel.Get<ButtonWidget>("WATCH_BUTTON"); watch.IsDisabled = () => selectedReplay == null || selectedReplay.GameInfo.MapPreview.Status != MapStatus.Available; watch.OnClick = () => { WatchReplay(); }; panel.Get("REPLAY_INFO").IsVisible = () => selectedReplay != null; var preview = panel.Get<MapPreviewWidget>("MAP_PREVIEW"); preview.SpawnOccupants = () => selectedSpawns; preview.Preview = () => selectedReplay != null ? selectedReplay.GameInfo.MapPreview : null; var titleLabel = panel.GetOrNull<LabelWidget>("MAP_TITLE"); if (titleLabel != null) { titleLabel.IsVisible = () => selectedReplay != null; var font = Game.Renderer.Fonts[titleLabel.Font]; var title = new CachedTransform<MapPreview, string>(m => WidgetUtils.TruncateText(m.Title, titleLabel.Bounds.Width, font)); titleLabel.GetText = () => title.Update(selectedReplay.GameInfo.MapPreview); } var type = panel.GetOrNull<LabelWidget>("MAP_TYPE"); if (type != null) type.GetText = () => selectedReplay.GameInfo.MapPreview.Type; panel.Get<LabelWidget>("DURATION").GetText = () => WidgetUtils.FormatTimeSeconds((int)selectedReplay.GameInfo.Duration.TotalSeconds); SetupFilters(); SetupManagement(); }
public static void AddPlayerFlagAndName(ScrollItemWidget template, Player player) { var flag = template.Get<ImageWidget>("FLAG"); flag.GetImageName = () => player.Country.Race; flag.GetImageCollection = () => "flags"; var playerName = template.Get<LabelWidget>("PLAYER"); var client = player.World.LobbyInfo.ClientWithIndex(player.ClientIndex); playerName.GetText = () => { if (client != null && client.State == Network.Session.ClientState.Disconnected) return player.PlayerName + " (Gone)"; return player.PlayerName + (player.WinState == WinState.Undefined ? "" : " (" + player.WinState + ")"); }; playerName.GetColor = () => player.Color.RGB; }
public ActorSelectorLogic(Widget widget, World world, WorldRenderer worldRenderer, Ruleset modRules) { this.modRules = modRules; this.world = world; this.worldRenderer = worldRenderer; editor = widget.Parent.Get<EditorViewportControllerWidget>("MAP_EDITOR"); ownersDropDown = widget.Get<DropDownButtonWidget>("OWNERS_DROPDOWN"); panel = widget.Get<ScrollPanelWidget>("ACTORTEMPLATE_LIST"); itemTemplate = panel.Get<ScrollItemWidget>("ACTORPREVIEW_TEMPLATE"); panel.Layout = new GridLayout(panel); var editorLayer = world.WorldActor.Trait<EditorActorLayer>(); selectedOwner = editorLayer.Players.Players.Values.First(); Func<PlayerReference, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) => { var item = ScrollItemWidget.Setup(template, () => selectedOwner == option, () => { selectedOwner = option; ownersDropDown.Text = selectedOwner.Name; ownersDropDown.TextColor = selectedOwner.Color.RGB; IntializeActorPreviews(); }); item.Get<LabelWidget>("LABEL").GetText = () => option.Name; item.GetColor = () => option.Color.RGB; return item; }; ownersDropDown.OnClick = () => { var owners = editorLayer.Players.Players.Values.OrderBy(p => p.Name); ownersDropDown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 270, owners, setupItem); }; ownersDropDown.Text = selectedOwner.Name; ownersDropDown.TextColor = selectedOwner.Color.RGB; IntializeActorPreviews(); }
public SaveMapLogic(Widget widget, ModData modData, Action <string> onSave, Action onExit, Map map, List <MiniYamlNode> playerDefinitions, List <MiniYamlNode> actorDefinitions) { var title = widget.Get <TextFieldWidget>("TITLE"); title.Text = map.Title; var author = widget.Get <TextFieldWidget>("AUTHOR"); author.Text = map.Author; var visibilityPanel = Ui.LoadWidget("MAP_SAVE_VISIBILITY_PANEL", null, new WidgetArgs()); var visOptionTemplate = visibilityPanel.Get <CheckboxWidget>("VISIBILITY_TEMPLATE"); visibilityPanel.RemoveChildren(); foreach (MapVisibility visibilityOption in Enum.GetValues(typeof(MapVisibility))) { // To prevent users from breaking the game only show the 'Shellmap' option when it is already set. if (visibilityOption == MapVisibility.Shellmap && !map.Visibility.HasFlag(visibilityOption)) { continue; } var checkbox = (CheckboxWidget)visOptionTemplate.Clone(); checkbox.GetText = () => visibilityOption.ToString(); checkbox.IsChecked = () => map.Visibility.HasFlag(visibilityOption); checkbox.OnClick = () => map.Visibility ^= visibilityOption; visibilityPanel.AddChild(checkbox); } var visibilityDropdown = widget.Get <DropDownButtonWidget>("VISIBILITY_DROPDOWN"); visibilityDropdown.OnMouseDown = _ => { visibilityDropdown.RemovePanel(); visibilityDropdown.AttachPanel(visibilityPanel); }; var writableDirectories = new List <SaveDirectory>(); SaveDirectory selectedDirectory = null; var directoryDropdown = widget.Get <DropDownButtonWidget>("DIRECTORY_DROPDOWN"); { Func <SaveDirectory, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) => { var item = ScrollItemWidget.Setup(template, () => selectedDirectory == option, () => selectedDirectory = option); item.Get <LabelWidget>("LABEL").GetText = () => option.DisplayName; return(item); }; foreach (var kv in modData.MapCache.MapLocations) { var folder = kv.Key as Folder; if (folder == null) { continue; } try { using (var fs = File.Create(Path.Combine(folder.Name, ".testwritable"), 1, FileOptions.DeleteOnClose)) { // Do nothing: we just want to test whether we can create the file } writableDirectories.Add(new SaveDirectory(folder, kv.Value.ToString(), kv.Value)); } catch { // Directory is not writable } } if (map.Package != null) { selectedDirectory = writableDirectories.FirstOrDefault(k => k.Folder.Contains(map.Package.Name)); } // Prioritize MapClassification.User directories over system directories if (selectedDirectory == null) { selectedDirectory = writableDirectories.OrderByDescending(kv => kv.Classification).First(); } directoryDropdown.GetText = () => selectedDirectory?.DisplayName ?? ""; directoryDropdown.OnClick = () => directoryDropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 210, writableDirectories, setupItem); } var mapIsUnpacked = map.Package != null && map.Package is Folder; var filename = widget.Get <TextFieldWidget>("FILENAME"); filename.Text = map.Package == null ? "" : mapIsUnpacked?Path.GetFileName(map.Package.Name) : Path.GetFileNameWithoutExtension(map.Package.Name); var fileType = mapIsUnpacked ? MapFileType.Unpacked : MapFileType.OraMap; var fileTypes = new Dictionary <MapFileType, MapFileTypeInfo>() { { MapFileType.OraMap, new MapFileTypeInfo { Extension = ".oramap", UiLabel = ".oramap" } }, { MapFileType.Unpacked, new MapFileTypeInfo { Extension = "", UiLabel = "(unpacked)" } } }; var typeDropdown = widget.Get <DropDownButtonWidget>("TYPE_DROPDOWN"); { Func <KeyValuePair <MapFileType, MapFileTypeInfo>, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) => { var item = ScrollItemWidget.Setup(template, () => fileType == option.Key, () => { typeDropdown.Text = option.Value.UiLabel; fileType = option.Key; }); item.Get <LabelWidget>("LABEL").GetText = () => option.Value.UiLabel; return(item); }; typeDropdown.Text = fileTypes[fileType].UiLabel; typeDropdown.OnClick = () => typeDropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 210, fileTypes, setupItem); } var close = widget.Get <ButtonWidget>("BACK_BUTTON"); close.OnClick = () => { Ui.CloseWindow(); onExit(); }; var save = widget.Get <ButtonWidget>("SAVE_BUTTON"); save.OnClick = () => { if (string.IsNullOrEmpty(filename.Text)) { return; } map.Title = title.Text; map.Author = author.Text; if (actorDefinitions != null) { map.ActorDefinitions = actorDefinitions; } if (playerDefinitions != null) { map.PlayerDefinitions = playerDefinitions; } map.RequiresMod = modData.Manifest.Id; var combinedPath = Platform.ResolvePath(Path.Combine(selectedDirectory.Folder.Name, filename.Text + fileTypes[fileType].Extension)); // Invalidate the old map metadata if (map.Uid != null && map.Package != null && map.Package.Name == combinedPath) { modData.MapCache[map.Uid].Invalidate(); } try { if (!(map.Package is IReadWritePackage package) || package.Name != combinedPath) { selectedDirectory.Folder.Delete(combinedPath); if (fileType == MapFileType.OraMap) { package = ZipFileLoader.Create(combinedPath); } else { package = new Folder(combinedPath); } } map.Save(package); // Update the map cache so it can be loaded without restarting the game modData.MapCache[map.Uid].UpdateFromMap(map.Package, selectedDirectory.Folder, selectedDirectory.Classification, null, map.Grid.Type); Console.WriteLine("Saved current map at {0}", combinedPath); Ui.CloseWindow(); onSave(map.Uid); } catch (Exception e) { Log.Write("debug", "Failed to save map at {0}: {1}", combinedPath, e.Message); Log.Write("debug", "{0}", e.StackTrace); ConfirmationDialogs.ButtonPrompt( title: "Failed to save map", text: "See debug.log for details.", onConfirm: () => { }, confirmText: "OK"); } }; }
void LoadReplays(string dir, ScrollItemWidget template) { using (new Support.PerfTimer("Load replays")) { var loadedReplays = new ConcurrentBag<ReplayMetadata>(); Parallel.ForEach(Directory.GetFiles(dir, "*.orarep"), (fileName, pls) => { if (cancelLoadingReplays) { pls.Stop(); return; } var replay = ReplayMetadata.Read(fileName); if (replay != null) loadedReplays.Add(replay); }); if (cancelLoadingReplays) return; var sortedReplays = loadedReplays.OrderByDescending(replay => replay.GameInfo.StartTimeUtc).ToList(); Game.RunAfterTick(() => { replayList.RemoveChildren(); foreach (var replay in sortedReplays) AddReplay(replay, template); SetupReplayDependentFilters(); ApplyFilter(); }); } }
void SelectMap(MapPreview preview) { selectedMap = preview; // Cache the rules on a background thread to avoid jank var difficultyDisabled = true; var difficulties = new Dictionary <string, string>(); var infoVideo = ""; var infoVideoVisible = false; new Thread(() => { var mapDifficulty = preview.Rules.Actors["world"].TraitInfos <ScriptLobbyDropdownInfo>() .FirstOrDefault(sld => sld.ID == "difficulty"); if (mapDifficulty != null) { difficulty = mapDifficulty.Default; difficulties = mapDifficulty.Values; difficultyDisabled = mapDifficulty.Locked; } var missionData = preview.Rules.Actors["world"].TraitInfoOrDefault <MissionDataInfo>(); if (missionData != null) { //briefingVideo = missionData.BriefingVideo; //briefingVideoVisible = briefingVideo != null; infoVideo = missionData.BackgroundVideo; infoVideoVisible = infoVideo != null; var briefing = WidgetUtils.WrapText(missionData.Briefing.Replace("\\n", "\n"), description.Bounds.Width, descriptionFont); var height = descriptionFont.Measure(briefing).Y; Game.RunAfterTick(() => { if (preview == selectedMap) { description.Text = briefing; description.Bounds.Height = height; descriptionPanel.Layout.AdjustChildren(); } }); } }).Start(); //startBriefingVideoButton.IsVisible = () => briefingVideoVisible && playingVideo != PlayingVideo.Briefing; //startBriefingVideoButton.OnClick = () => PlayVideo(videoPlayer, briefingVideo, PlayingVideo.Briefing); startInfoVideoButton.IsVisible = () => infoVideoVisible && playingVideo != PlayingVideo.Info; startInfoVideoButton.OnClick = () => PlayVideo(videoPlayer, infoVideo, PlayingVideo.Info); descriptionPanel.ScrollToTop(); if (difficultyButton != null) { var difficultyName = new CachedTransform <string, string>(id => id == null || !difficulties.ContainsKey(id) ? "Normal" : difficulties[id]); difficultyButton.IsDisabled = () => difficultyDisabled; difficultyButton.GetText = () => difficultyName.Update(difficulty); difficultyButton.OnMouseDown = _ => { var options = difficulties.Select(kv => new DropDownOption { Title = kv.Value, IsSelected = () => difficulty == kv.Key, OnClick = () => difficulty = kv.Key }); Func <DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) => { var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick); item.Get <LabelWidget>("LABEL").GetText = () => option.Title; return(item); }; difficultyButton.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem); }; } if (gameSpeedButton != null) { var speeds = modData.Manifest.Get <GameSpeeds>().Speeds; gameSpeed = "default"; gameSpeedButton.GetText = () => speeds[gameSpeed].Name; gameSpeedButton.OnMouseDown = _ => { var options = speeds.Select(s => new DropDownOption { Title = s.Value.Name, IsSelected = () => gameSpeed == s.Key, OnClick = () => gameSpeed = s.Key }); Func <DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) => { var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick); item.Get <LabelWidget>("LABEL").GetText = () => option.Title; return(item); }; gameSpeedButton.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem); }; } }
public ObserverShroudSelectorLogic(Widget widget, World world) { var groups = new Dictionary <string, IEnumerable <CameraOption> >(); teams = world.Players.Where(p => !p.NonCombatant) .Select(p => new CameraOption(this, p)) .GroupBy(p => (world.LobbyInfo.ClientWithIndex(p.Player.ClientIndex) ?? new Session.Client()).Team) .OrderBy(g => g.Key); var noTeams = teams.Count() == 1; foreach (var t in teams) { var label = noTeams ? "Players" : t.Key == 0 ? "No Team" : "Team {0}".F(t.Key); groups.Add(label, t); } combined = new CameraOption(this, world, "All Players", world.Players.First(p => p.InternalName == "Everyone")); disableShroud = new CameraOption(this, world, "Disable Shroud", null); groups.Add("Other", new List <CameraOption>() { combined, disableShroud }); var shroudSelector = widget.Get <DropDownButtonWidget>("SHROUD_SELECTOR"); shroudSelector.OnMouseDown = _ => { Func <CameraOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) => { var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick); var showFlag = option.Race != null; var label = item.Get <LabelWidget>("LABEL"); label.IsVisible = () => showFlag; label.GetText = () => option.Label; label.GetColor = () => option.Color; var flag = item.Get <ImageWidget>("FLAG"); flag.IsVisible = () => showFlag; flag.GetImageCollection = () => "flags"; flag.GetImageName = () => option.Race; var labelAlt = item.Get <LabelWidget>("NOFLAG_LABEL"); labelAlt.IsVisible = () => !showFlag; labelAlt.GetText = () => option.Label; labelAlt.GetColor = () => option.Color; return(item); }; shroudSelector.ShowDropDown("SPECTATOR_DROPDOWN_TEMPLATE", 400, groups, setupItem); }; var shroudLabel = shroudSelector.Get <LabelWidget>("LABEL"); shroudLabel.IsVisible = () => selected.Race != null; shroudLabel.GetText = () => selected.Label; shroudLabel.GetColor = () => selected.Color; var shroudFlag = shroudSelector.Get <ImageWidget>("FLAG"); shroudFlag.IsVisible = () => selected.Race != null; shroudFlag.GetImageCollection = () => "flags"; shroudFlag.GetImageName = () => selected.Race; var shroudLabelAlt = shroudSelector.Get <LabelWidget>("NOFLAG_LABEL"); shroudLabelAlt.IsVisible = () => selected.Race == null; shroudLabelAlt.GetText = () => selected.Label; shroudLabelAlt.GetColor = () => selected.Color; var keyhandler = shroudSelector.Get <LogicKeyListenerWidget>("SHROUD_KEYHANDLER"); keyhandler.OnKeyPress = HandleKeyPress; selected = disableShroud; }
public ObserverStatsLogic(World world, ModData modData, WorldRenderer worldRenderer, Widget widget, ObserverStatsPanel activePanel, Dictionary <string, MiniYaml> logicArgs) { this.world = world; this.worldRenderer = worldRenderer; MiniYaml yaml; string[] keyNames = Enum.GetNames(typeof(ObserverStatsPanel)); var statsHotkeys = new HotkeyReference[keyNames.Length]; for (var i = 0; i < keyNames.Length; i++) { statsHotkeys[i] = logicArgs.TryGetValue("Statistics" + keyNames[i] + "Key", out yaml) ? modData.Hotkeys[yaml.Value] : new HotkeyReference(); } players = world.Players.Where(p => !p.NonCombatant); basicStatsHeaders = widget.Get <ContainerWidget>("BASIC_STATS_HEADERS"); economyStatsHeaders = widget.Get <ContainerWidget>("ECONOMY_STATS_HEADERS"); productionStatsHeaders = widget.Get <ContainerWidget>("PRODUCTION_STATS_HEADERS"); combatStatsHeaders = widget.Get <ContainerWidget>("COMBAT_STATS_HEADERS"); earnedThisMinuteGraphHeaders = widget.Get <ContainerWidget>("EARNED_THIS_MIN_GRAPH_HEADERS"); playerStatsPanel = widget.Get <ScrollPanelWidget>("PLAYER_STATS_PANEL"); playerStatsPanel.Layout = new GridLayout(playerStatsPanel); if (players.Count() < 9) { playerStatsPanel.ScrollbarWidth = 0; } basicPlayerTemplate = playerStatsPanel.Get <ScrollItemWidget>("BASIC_PLAYER_TEMPLATE"); economyPlayerTemplate = playerStatsPanel.Get <ScrollItemWidget>("ECONOMY_PLAYER_TEMPLATE"); productionPlayerTemplate = playerStatsPanel.Get <ScrollItemWidget>("PRODUCTION_PLAYER_TEMPLATE"); combatPlayerTemplate = playerStatsPanel.Get <ScrollItemWidget>("COMBAT_PLAYER_TEMPLATE"); earnedThisMinuteGraphTemplate = playerStatsPanel.Get <ContainerWidget>("EARNED_THIS_MIN_GRAPH_TEMPLATE"); var statsDropDown = widget.Get <DropDownButtonWidget>("STATS_DROPDOWN"); Func <string, ContainerWidget, Action, StatsDropDownOption> createStatsOption = (title, headers, a) => { return(new StatsDropDownOption { Title = title, IsSelected = () => headers.Visible, OnClick = () => { ClearStats(); statsDropDown.GetText = () => title; a(); } }); }; var statsDropDownOptions = new StatsDropDownOption[] { createStatsOption("Basic", basicStatsHeaders, () => { AdjustStatisticsPanel(basicStatsHeaders, basicPlayerTemplate); DisplayStats(BasicStats); } ), createStatsOption("Economy", economyStatsHeaders, () => { AdjustStatisticsPanel(economyStatsHeaders, economyPlayerTemplate); DisplayStats(EconomyStats); } ), createStatsOption("Production", productionStatsHeaders, () => { AdjustStatisticsPanel(productionStatsHeaders, productionPlayerTemplate); DisplayStats(ProductionStats); } ), createStatsOption("Combat", combatStatsHeaders, () => { AdjustStatisticsPanel(combatStatsHeaders, combatPlayerTemplate); DisplayStats(CombatStats); } ), createStatsOption("Earnings (graph)", earnedThisMinuteGraphHeaders, () => { playerStatsPanel.Bounds.Width = earnedThisMinuteGraphTemplate.Bounds.Width + 60; playerStatsPanel.Bounds.Height = earnedThisMinuteGraphTemplate.Bounds.Height + 50; playerStatsPanel.ScrollbarWidth = 0; playerStatsPanel.ScrollToTop(); earnedThisMinuteGraphHeaders.Parent.Bounds.Width = playerStatsPanel.Bounds.Width; EarnedThisMinuteGraph(); } ) }; Func <StatsDropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) => { var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick); item.Get <LabelWidget>("LABEL").GetText = () => option.Title; return(item); }; statsDropDown.OnMouseDown = _ => statsDropDown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 150, statsDropDownOptions, setupItem); statsDropDownOptions[(int)activePanel].OnClick(); var keyListener = statsDropDown.Get <LogicKeyListenerWidget>("STATS_DROPDOWN_KEYHANDLER"); keyListener.AddHandler(e => { if (e.Event == KeyInputEvent.Down && !e.IsRepeat) { for (var i = 0; i < statsHotkeys.Length; i++) { if (statsHotkeys[i].IsActivatedBy(e)) { Game.Sound.PlayNotification(modData.DefaultRules, null, "Sounds", "ClickSound", null); statsDropDownOptions[i].OnClick(); return(true); } } } return(false); }); }
Action InitInputPanel(Widget panel) { var gs = Game.Settings.Game; BindCheckboxPref(panel, "CLASSICORDERS_CHECKBOX", gs, "UseClassicMouseStyle"); BindCheckboxPref(panel, "EDGESCROLL_CHECKBOX", gs, "ViewportEdgeScroll"); BindCheckboxPref(panel, "LOCKMOUSE_CHECKBOX", gs, "LockMouseWindow"); BindCheckboxPref(panel, "ALLOW_ZOOM_CHECKBOX", gs, "AllowZoom"); BindSliderPref(panel, "SCROLLSPEED_SLIDER", gs, "ViewportEdgeScrollStep"); BindSliderPref(panel, "UI_SCROLLSPEED_SLIDER", gs, "UIScrollSpeed"); // Apply mouse focus preferences immediately var lockMouseCheckbox = panel.Get <CheckboxWidget>("LOCKMOUSE_CHECKBOX"); var oldOnClick = lockMouseCheckbox.OnClick; lockMouseCheckbox.OnClick = () => { // Still perform the old behaviour for clicking the checkbox, before // applying the changes live. oldOnClick(); MakeMouseFocusSettingsLive(); }; var middleMouseScrollDropdown = panel.Get <DropDownButtonWidget>("MIDDLE_MOUSE_SCROLL"); middleMouseScrollDropdown.OnMouseDown = _ => ShowMouseScrollDropdown(middleMouseScrollDropdown, gs, false); middleMouseScrollDropdown.GetText = () => gs.MiddleMouseScroll.ToString(); var rightMouseScrollDropdown = panel.Get <DropDownButtonWidget>("RIGHT_MOUSE_SCROLL"); rightMouseScrollDropdown.OnMouseDown = _ => ShowMouseScrollDropdown(rightMouseScrollDropdown, gs, true); rightMouseScrollDropdown.GetText = () => gs.RightMouseScroll.ToString(); var zoomModifierDropdown = panel.Get <DropDownButtonWidget>("ZOOM_MODIFIER"); zoomModifierDropdown.OnMouseDown = _ => ShowZoomModifierDropdown(zoomModifierDropdown, gs); zoomModifierDropdown.GetText = () => gs.ZoomModifier.ToString(); var hotkeyList = panel.Get <ScrollPanelWidget>("HOTKEY_LIST"); hotkeyList.Layout = new GridLayout(hotkeyList); var hotkeyHeader = hotkeyList.Get <ScrollItemWidget>("HEADER"); var templates = hotkeyList.Get("TEMPLATES"); hotkeyList.RemoveChildren(); Func <bool> returnTrue = () => true; Action doNothing = () => { }; MiniYaml hotkeyGroups; if (logicArgs.TryGetValue("HotkeyGroups", out hotkeyGroups)) { foreach (var hg in hotkeyGroups.Nodes) { var templateNode = hg.Value.Nodes.FirstOrDefault(n => n.Key == "Template"); var typesNode = hg.Value.Nodes.FirstOrDefault(n => n.Key == "Types"); if (templateNode == null || typesNode == null) { continue; } var header = ScrollItemWidget.Setup(hotkeyHeader, returnTrue, doNothing); header.Get <LabelWidget>("LABEL").GetText = () => hg.Key; hotkeyList.AddChild(header); var types = FieldLoader.GetValue <string[]>("Types", typesNode.Value.Value); var added = new HashSet <HotkeyDefinition>(); var template = templates.Get(templateNode.Value.Value); foreach (var t in types) { foreach (var hd in modData.Hotkeys.Definitions.Where(k => k.Types.Contains(t))) { if (added.Add(hd)) { BindHotkeyPref(hd, modData.Hotkeys, template, hotkeyList); } } } } } return(() => { }); }
public AssetBrowserLogic(Widget widget, Action onExit, ModData modData, WorldRenderer worldRenderer) { world = worldRenderer.World; this.modData = modData; panel = widget; var colorPickerPalettes = world.WorldActor.TraitsImplementing <IProvidesAssetBrowserColorPickerPalettes>() .SelectMany(p => p.ColorPickerPaletteNames) .ToArray(); palettes = world.WorldActor.TraitsImplementing <IProvidesAssetBrowserPalettes>() .SelectMany(p => p.PaletteNames) .Concat(colorPickerPalettes) .ToArray(); var ticker = panel.GetOrNull <LogicTickerWidget>("ANIMATION_TICKER"); if (ticker != null) { ticker.OnTick = () => { if (animateFrames) { SelectNextFrame(); } }; } var sourceDropdown = panel.GetOrNull <DropDownButtonWidget>("SOURCE_SELECTOR"); if (sourceDropdown != null) { sourceDropdown.OnMouseDown = _ => ShowSourceDropdown(sourceDropdown); var sourceName = new CachedTransform <IReadOnlyPackage, string>(GetSourceDisplayName); sourceDropdown.GetText = () => sourceName.Update(assetSource); } var spriteWidget = panel.GetOrNull <SpriteWidget>("SPRITE"); if (spriteWidget != null) { spriteWidget.GetSprite = () => currentSprites != null ? currentSprites[currentFrame] : null; currentPalette = spriteWidget.Palette; spriteWidget.GetPalette = () => currentPalette; spriteWidget.IsVisible = () => !isVideoLoaded && !isLoadError && currentSprites != null; } var playerWidget = panel.GetOrNull <VideoPlayerWidget>("PLAYER"); if (playerWidget != null) { playerWidget.IsVisible = () => isVideoLoaded && !isLoadError; } var modelWidget = panel.GetOrNull <ModelWidget>("VOXEL"); if (modelWidget != null) { modelWidget.GetVoxel = () => currentVoxel; currentPalette = modelWidget.Palette; modelWidget.GetPalette = () => currentPalette; modelWidget.GetPlayerPalette = () => currentPalette; modelWidget.GetRotation = () => modelOrientation; modelWidget.IsVisible = () => !isVideoLoaded && !isLoadError && currentVoxel != null; } var errorLabelWidget = panel.GetOrNull("ERROR"); if (errorLabelWidget != null) { errorLabelWidget.IsVisible = () => isLoadError; } var paletteDropDown = panel.GetOrNull <DropDownButtonWidget>("PALETTE_SELECTOR"); if (paletteDropDown != null) { paletteDropDown.OnMouseDown = _ => ShowPaletteDropdown(paletteDropDown, world); paletteDropDown.GetText = () => currentPalette; } var colorManager = modData.DefaultRules.Actors[SystemActors.World].TraitInfo <ColorPickerManagerInfo>(); colorManager.Color = Game.Settings.Player.Color; var colorDropdown = panel.GetOrNull <DropDownButtonWidget>("COLOR"); if (colorDropdown != null) { colorDropdown.IsDisabled = () => !colorPickerPalettes.Contains(currentPalette); colorDropdown.OnMouseDown = _ => ColorPickerLogic.ShowColorDropDown(colorDropdown, colorManager, worldRenderer); panel.Get <ColorBlockWidget>("COLORBLOCK").GetColor = () => colorManager.Color; } filenameInput = panel.Get <TextFieldWidget>("FILENAME_INPUT"); filenameInput.OnTextEdited = () => ApplyFilter(); filenameInput.OnEscKey = _ => { if (string.IsNullOrEmpty(filenameInput.Text)) { filenameInput.YieldKeyboardFocus(); } else { filenameInput.Text = ""; filenameInput.OnTextEdited(); } return(true); }; var frameContainer = panel.GetOrNull("FRAME_SELECTOR"); if (frameContainer != null) { frameContainer.IsVisible = () => (currentSprites != null && currentSprites.Length > 1) || (isVideoLoaded && player != null && player.Video != null && player.Video.Frames > 1); } frameSlider = panel.GetOrNull <SliderWidget>("FRAME_SLIDER"); if (frameSlider != null) { frameSlider.OnChange += x => { if (!isVideoLoaded) { currentFrame = (int)Math.Round(x); } }; frameSlider.GetValue = () => isVideoLoaded ? player.Video.CurrentFrame : currentFrame; frameSlider.IsDisabled = () => isVideoLoaded; } var frameText = panel.GetOrNull <LabelWidget>("FRAME_COUNT"); if (frameText != null) { frameText.GetText = () => isVideoLoaded ? $"{player.Video.CurrentFrame + 1} / {player.Video.Frames}" : $"{currentFrame} / {currentSprites.Length - 1}"; } var playButton = panel.GetOrNull <ButtonWidget>("BUTTON_PLAY"); if (playButton != null) { playButton.OnClick = () => { if (isVideoLoaded) { player.Play(); } else { animateFrames = true; } }; playButton.IsVisible = () => isVideoLoaded ? player.Paused : !animateFrames; } var pauseButton = panel.GetOrNull <ButtonWidget>("BUTTON_PAUSE"); if (pauseButton != null) { pauseButton.OnClick = () => { if (isVideoLoaded) { player.Pause(); } else { animateFrames = false; } }; pauseButton.IsVisible = () => isVideoLoaded ? !player.Paused : animateFrames; } var stopButton = panel.GetOrNull <ButtonWidget>("BUTTON_STOP"); if (stopButton != null) { stopButton.OnClick = () => { if (isVideoLoaded) { player.Stop(); } else { if (frameSlider != null) { frameSlider.Value = 0; } currentFrame = 0; animateFrames = false; } }; } var nextButton = panel.GetOrNull <ButtonWidget>("BUTTON_NEXT"); if (nextButton != null) { nextButton.OnClick = () => { if (!isVideoLoaded) { nextButton.OnClick = SelectNextFrame; } }; nextButton.IsVisible = () => !isVideoLoaded; } var prevButton = panel.GetOrNull <ButtonWidget>("BUTTON_PREV"); if (prevButton != null) { prevButton.OnClick = () => { if (!isVideoLoaded) { SelectPreviousFrame(); } }; prevButton.IsVisible = () => !isVideoLoaded; } var voxelContainer = panel.GetOrNull("VOXEL_SELECTOR"); if (voxelContainer != null) { voxelContainer.IsVisible = () => currentVoxel != null; } var rollSlider = panel.GetOrNull <SliderWidget>("ROLL_SLIDER"); if (rollSlider != null) { rollSlider.OnChange += x => { var roll = (int)x; modelOrientation = modelOrientation.WithRoll(new WAngle(roll)); }; rollSlider.GetValue = () => modelOrientation.Roll.Angle; } var pitchSlider = panel.GetOrNull <SliderWidget>("PITCH_SLIDER"); if (pitchSlider != null) { pitchSlider.OnChange += x => { var pitch = (int)x; modelOrientation = modelOrientation.WithPitch(new WAngle(pitch)); }; pitchSlider.GetValue = () => modelOrientation.Pitch.Angle; } var yawSlider = panel.GetOrNull <SliderWidget>("YAW_SLIDER"); if (yawSlider != null) { yawSlider.OnChange += x => { var yaw = (int)x; modelOrientation = modelOrientation.WithYaw(new WAngle(yaw)); }; yawSlider.GetValue = () => modelOrientation.Yaw.Angle; } var assetBrowserModData = modData.Manifest.Get <AssetBrowser>(); allowedExtensions = assetBrowserModData.SupportedExtensions; acceptablePackages = modData.ModFiles.MountedPackages.Where(p => p.Contents.Any(c => allowedExtensions.Contains(Path.GetExtension(c).ToLowerInvariant()))); assetList = panel.Get <ScrollPanelWidget>("ASSET_LIST"); template = panel.Get <ScrollItemWidget>("ASSET_TEMPLATE"); PopulateAssetList(); var closeButton = panel.GetOrNull <ButtonWidget>("CLOSE_BUTTON"); if (closeButton != null) { closeButton.OnClick = () => { if (isVideoLoaded) { player.Stop(); } Ui.CloseWindow(); onExit(); } } ; } void SelectNextFrame() { currentFrame++; if (currentFrame >= currentSprites.Length) { currentFrame = 0; } } void SelectPreviousFrame() { currentFrame--; if (currentFrame < 0) { currentFrame = currentSprites.Length - 1; } } Dictionary <string, bool> assetVisByName = new Dictionary <string, bool>(); bool FilterAsset(string filename) { var filter = filenameInput.Text; if (string.IsNullOrWhiteSpace(filter)) { return(true); } if (filename.IndexOf(filter, StringComparison.OrdinalIgnoreCase) >= 0) { return(true); } return(false); } void ApplyFilter() { assetVisByName.Clear(); assetList.Layout.AdjustChildren(); assetList.ScrollToTop(); // Select the first visible var firstVisible = assetVisByName.FirstOrDefault(kvp => kvp.Value); if (firstVisible.Key != null && modData.DefaultFileSystem.TryGetPackageContaining(firstVisible.Key, out var package, out var filename)) { LoadAsset(package, filename); } } void AddAsset(ScrollPanelWidget list, string filepath, IReadOnlyPackage package, ScrollItemWidget template) { var item = ScrollItemWidget.Setup(template, () => currentFilename == filepath && currentPackage == package, () => { LoadAsset(package, filepath); }); var label = item.Get <LabelWithTooltipWidget>("TITLE"); WidgetUtils.TruncateLabelToTooltip(label, filepath); item.IsVisible = () => { if (assetVisByName.TryGetValue(filepath, out var visible)) { return(visible); } visible = FilterAsset(filepath); assetVisByName.Add(filepath, visible); return(visible); }; list.AddChild(item); } bool LoadAsset(IReadOnlyPackage package, string filename) { if (isVideoLoaded) { player.Stop(); player = null; isVideoLoaded = false; } if (string.IsNullOrEmpty(filename)) { return(false); } if (!package.Contains(filename)) { return(false); } isLoadError = false; try { currentPackage = package; currentFilename = filename; var prefix = ""; if (modData.DefaultFileSystem is OpenRA.FileSystem.FileSystem fs) { prefix = fs.GetPrefix(package); if (prefix != null) { prefix += "|"; } } var video = VideoLoader.GetVideo(Game.ModData.DefaultFileSystem.Open(filename), Game.ModData.VideoLoaders); if (video != null) { player = panel.Get <VideoPlayerWidget>("PLAYER"); player.Load(prefix + filename); player.DrawOverlay = false; isVideoLoaded = true; if (frameSlider != null) { frameSlider.MaximumValue = (float)player.Video.Frames - 1; frameSlider.Ticks = 0; } return(true); } if (Path.GetExtension(filename.ToLowerInvariant()) == ".vxl") { var voxelName = Path.GetFileNameWithoutExtension(filename); currentVoxel = world.ModelCache.GetModel(voxelName); currentSprites = null; } else { currentSprites = world.Map.Rules.Sequences.SpriteCache[prefix + filename]; currentFrame = 0; if (frameSlider != null) { frameSlider.MaximumValue = (float)currentSprites.Length - 1; frameSlider.Ticks = currentSprites.Length; } currentVoxel = null; } } catch (Exception ex) { isLoadError = true; Log.AddChannel("assetbrowser", "assetbrowser.log"); Log.Write("assetbrowser", "Error reading {0}:{3} {1}{3}{2}", filename, ex.Message, ex.StackTrace, Environment.NewLine); return(false); } return(true); } bool ShowSourceDropdown(DropDownButtonWidget dropdown) { var sourceName = new CachedTransform <IReadOnlyPackage, string>(GetSourceDisplayName); Func <IReadOnlyPackage, ScrollItemWidget, ScrollItemWidget> setupItem = (source, itemTemplate) => { var item = ScrollItemWidget.Setup(itemTemplate, () => assetSource == source, () => { assetSource = source; PopulateAssetList(); }); item.Get <LabelWidget>("LABEL").GetText = () => sourceName.Update(source); return(item); }; var sources = new[] { (IReadOnlyPackage)null }.Concat(acceptablePackages); dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 280, sources, setupItem); return(true); } void PopulateAssetList() { assetList.RemoveChildren(); var files = new SortedList <string, List <IReadOnlyPackage> >(); if (assetSource != null) { foreach (var content in assetSource.Contents) { files.Add(content, new List <IReadOnlyPackage> { assetSource }); } } else { foreach (var mountedPackage in modData.ModFiles.MountedPackages) { foreach (var content in mountedPackage.Contents) { if (!files.ContainsKey(content)) { files.Add(content, new List <IReadOnlyPackage> { mountedPackage }); } else { files[content].Add(mountedPackage); } } } } foreach (var file in files.OrderBy(s => s.Key)) { if (!allowedExtensions.Any(ext => file.Key.EndsWith(ext, true, CultureInfo.InvariantCulture))) { continue; } foreach (var package in file.Value) { AddAsset(assetList, file.Key, package, template); } } } bool ShowPaletteDropdown(DropDownButtonWidget dropdown, World world) { Func <string, ScrollItemWidget, ScrollItemWidget> setupItem = (name, itemTemplate) => { var item = ScrollItemWidget.Setup(itemTemplate, () => currentPalette == name, () => currentPalette = name); item.Get <LabelWidget>("LABEL").GetText = () => name; return(item); }; dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 280, palettes, setupItem); return(true); } string GetSourceDisplayName(IReadOnlyPackage source) { if (source == null) { return("All Packages"); } // Packages that are explicitly mounted in the filesystem use their explicit mount name var fs = (OpenRA.FileSystem.FileSystem)modData.DefaultFileSystem; var name = fs.GetPrefix(source); // Fall back to the path relative to the mod, engine, or support dir if (name == null) { name = source.Name; var compare = Platform.CurrentPlatform == PlatformType.Windows ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal; if (name.StartsWith(modData.Manifest.Package.Name, compare)) { name = "$" + modData.Manifest.Id + "/" + name.Substring(modData.Manifest.Package.Name.Length + 1); } else if (name.StartsWith(Platform.EngineDir, compare)) { name = "./" + name.Substring(Platform.EngineDir.Length); } else if (name.StartsWith(Platform.SupportDir, compare)) { name = "^" + name.Substring(Platform.SupportDir.Length); } } if (name.Length > 18) { name = "..." + name.Substring(name.Length - 15); } return(name); } }
public MusicPlayerLogic(Widget widget, Ruleset modRules, Action onExit) { this.modRules = modRules; var panel = widget.Get("MUSIC_PANEL"); musicList = panel.Get <ScrollPanelWidget>("MUSIC_LIST"); itemTemplate = musicList.Get <ScrollItemWidget>("MUSIC_TEMPLATE"); BuildMusicTable(); Func <bool> noMusic = () => !installed; panel.Get("NO_MUSIC_LABEL").IsVisible = noMusic; var playButton = panel.Get <ButtonWidget>("BUTTON_PLAY"); playButton.OnClick = Play; playButton.IsDisabled = noMusic; playButton.IsVisible = () => !Sound.MusicPlaying; var pauseButton = panel.Get <ButtonWidget>("BUTTON_PAUSE"); pauseButton.OnClick = Sound.PauseMusic; pauseButton.IsDisabled = noMusic; pauseButton.IsVisible = () => Sound.MusicPlaying; var stopButton = panel.Get <ButtonWidget>("BUTTON_STOP"); stopButton.OnClick = Sound.StopMusic; stopButton.IsDisabled = noMusic; var nextButton = panel.Get <ButtonWidget>("BUTTON_NEXT"); nextButton.OnClick = () => { currentSong = GetNextSong(); Play(); }; nextButton.IsDisabled = noMusic; var prevButton = panel.Get <ButtonWidget>("BUTTON_PREV"); prevButton.OnClick = () => { currentSong = GetPrevSong(); Play(); }; prevButton.IsDisabled = noMusic; var shuffleCheckbox = panel.Get <CheckboxWidget>("SHUFFLE"); shuffleCheckbox.IsChecked = () => Game.Settings.Sound.Shuffle; shuffleCheckbox.OnClick = () => Game.Settings.Sound.Shuffle ^= true; var repeatCheckbox = panel.Get <CheckboxWidget>("REPEAT"); repeatCheckbox.IsChecked = () => Game.Settings.Sound.Repeat; repeatCheckbox.OnClick = () => Game.Settings.Sound.Repeat ^= true; panel.Get <LabelWidget>("TIME_LABEL").GetText = () => (currentSong == null) ? "" : "{0:D2}:{1:D2} / {2:D2}:{3:D2}".F((int)Sound.MusicSeekPosition / 60, (int)Sound.MusicSeekPosition % 60, currentSong.Length / 60, currentSong.Length % 60); var musicSlider = panel.Get <SliderWidget>("MUSIC_SLIDER"); musicSlider.OnChange += x => Sound.MusicVolume = x; musicSlider.Value = Sound.MusicVolume; panel.Get <ButtonWidget>("BACK_BUTTON").OnClick = () => { Game.Settings.Save(); Ui.CloseWindow(); onExit(); }; }
public ServerBrowserLogic(Widget widget, Action onStart, Action onExit) { panel = widget; this.onStart = onStart; serverList = panel.Get <ScrollPanelWidget>("SERVER_LIST"); serverTemplate = serverList.Get <ScrollItemWidget>("SERVER_TEMPLATE"); // Menu buttons var refreshButton = panel.Get <ButtonWidget>("REFRESH_BUTTON"); refreshButton.IsDisabled = () => searchStatus == SearchStatus.Fetching; refreshButton.GetText = () => searchStatus == SearchStatus.Fetching ? "Refreshing..." : "Refresh"; refreshButton.OnClick = RefreshServerList; panel.Get <ButtonWidget>("DIRECTCONNECT_BUTTON").OnClick = OpenDirectConnectPanel; panel.Get <ButtonWidget>("CREATE_BUTTON").OnClick = OpenCreateServerPanel; var join = panel.Get <ButtonWidget>("JOIN_BUTTON"); join.IsDisabled = () => currentServer == null || !currentServer.CanJoin(); join.OnClick = () => Join(currentServer); panel.Get <ButtonWidget>("BACK_BUTTON").OnClick = () => { Ui.CloseWindow(); onExit(); }; // Display the progress label over the server list // The text is only visible when the list is empty var progressText = panel.Get <LabelWidget>("PROGRESS_LABEL"); progressText.IsVisible = () => searchStatus != SearchStatus.Hidden; progressText.GetText = ProgressLabelText; var showWaitingCheckbox = panel.GetOrNull <CheckboxWidget>("WAITING_FOR_PLAYERS"); if (showWaitingCheckbox != null) { showWaitingCheckbox.IsChecked = () => showWaiting; showWaitingCheckbox.OnClick = () => { showWaiting ^= true; RefreshServerList(); }; } var showEmptyCheckbox = panel.GetOrNull <CheckboxWidget>("EMPTY"); if (showEmptyCheckbox != null) { showEmptyCheckbox.IsChecked = () => showEmpty; showEmptyCheckbox.OnClick = () => { showEmpty ^= true; RefreshServerList(); }; } var showAlreadyStartedCheckbox = panel.GetOrNull <CheckboxWidget>("ALREADY_STARTED"); if (showAlreadyStartedCheckbox != null) { showAlreadyStartedCheckbox.IsChecked = () => showStarted; showAlreadyStartedCheckbox.OnClick = () => { showStarted ^= true; RefreshServerList(); }; } var showIncompatibleCheckbox = panel.GetOrNull <CheckboxWidget>("INCOMPATIBLE_VERSION"); if (showIncompatibleCheckbox != null) { showIncompatibleCheckbox.IsChecked = () => showIncompatible; showIncompatibleCheckbox.OnClick = () => { showIncompatible ^= true; RefreshServerList(); }; } RefreshServerList(); }
public MusicPlayerLogic(Widget widget, Ruleset modRules, World world, Action onExit) { var panel = widget.Get("MUSIC_PANEL"); musicList = panel.Get <ScrollPanelWidget>("MUSIC_LIST"); itemTemplate = musicList.Get <ScrollItemWidget>("MUSIC_TEMPLATE"); musicPlaylist = world.WorldActor.Trait <MusicPlaylist>(); BuildMusicTable(); Func <bool> noMusic = () => !musicPlaylist.IsMusicAvailable || musicPlaylist.CurrentSongIsBackground || currentSong == null; panel.Get("NO_MUSIC_LABEL").IsVisible = () => !musicPlaylist.IsMusicAvailable; var playButton = panel.Get <ButtonWidget>("BUTTON_PLAY"); playButton.OnClick = Play; playButton.IsDisabled = noMusic; playButton.IsVisible = () => !Sound.MusicPlaying; var pauseButton = panel.Get <ButtonWidget>("BUTTON_PAUSE"); pauseButton.OnClick = Sound.PauseMusic; pauseButton.IsDisabled = noMusic; pauseButton.IsVisible = () => Sound.MusicPlaying; var stopButton = panel.Get <ButtonWidget>("BUTTON_STOP"); stopButton.OnClick = () => { musicPlaylist.Stop(); }; stopButton.IsDisabled = noMusic; var nextButton = panel.Get <ButtonWidget>("BUTTON_NEXT"); nextButton.OnClick = () => { currentSong = musicPlaylist.GetNextSong(); Play(); }; nextButton.IsDisabled = noMusic; var prevButton = panel.Get <ButtonWidget>("BUTTON_PREV"); prevButton.OnClick = () => { currentSong = musicPlaylist.GetPrevSong(); Play(); }; prevButton.IsDisabled = noMusic; var shuffleCheckbox = panel.Get <CheckboxWidget>("SHUFFLE"); shuffleCheckbox.IsChecked = () => Game.Settings.Sound.Shuffle; shuffleCheckbox.OnClick = () => Game.Settings.Sound.Shuffle ^= true; shuffleCheckbox.IsDisabled = () => musicPlaylist.CurrentSongIsBackground; var repeatCheckbox = panel.Get <CheckboxWidget>("REPEAT"); repeatCheckbox.IsChecked = () => Game.Settings.Sound.Repeat; repeatCheckbox.OnClick = () => Game.Settings.Sound.Repeat ^= true; repeatCheckbox.IsDisabled = () => musicPlaylist.CurrentSongIsBackground; panel.Get <LabelWidget>("TIME_LABEL").GetText = () => { if (currentSong == null || musicPlaylist.CurrentSongIsBackground) { return(""); } var minutes = (int)Sound.MusicSeekPosition / 60; var seconds = (int)Sound.MusicSeekPosition % 60; var totalMinutes = currentSong.Length / 60; var totalSeconds = currentSong.Length % 60; return("{0:D2}:{1:D2} / {2:D2}:{3:D2}".F(minutes, seconds, totalMinutes, totalSeconds)); }; var musicSlider = panel.Get <SliderWidget>("MUSIC_SLIDER"); musicSlider.OnChange += x => Sound.MusicVolume = x; musicSlider.Value = Sound.MusicVolume; var installButton = widget.GetOrNull <ButtonWidget>("INSTALL_BUTTON"); if (installButton != null) { installButton.IsDisabled = () => world == null || world.Type != WorldType.Shellmap; var args = new string[] { "Install.Music=true" }; installButton.OnClick = () => Game.RunAfterTick(() => Game.InitializeMod(Game.Settings.Game.Mod, new Arguments(args))); var installData = Game.ModData.Manifest.Get <ContentInstaller>(); installButton.IsVisible = () => modRules.InstalledMusic.ToArray().Length <= installData.ShippedSoundtracks; } var songWatcher = widget.GetOrNull <LogicTickerWidget>("SONG_WATCHER"); if (songWatcher != null) { songWatcher.OnTick = () => { if (musicPlaylist.CurrentSongIsBackground && currentSong != null) { currentSong = null; } if (Sound.CurrentMusic == null || currentSong == Sound.CurrentMusic || musicPlaylist.CurrentSongIsBackground) { return; } currentSong = Sound.CurrentMusic; }; } panel.Get <ButtonWidget>("BACK_BUTTON").OnClick = () => { Game.Settings.Save(); Ui.CloseWindow(); onExit(); }; }
public void RefreshServerList(Widget panel, IEnumerable <GameServer> games) { var sl = panel.Get <ScrollPanelWidget>("SERVER_LIST"); searchStatus = SearchStatus.Fetching; sl.RemoveChildren(); currentServer = null; if (games == null) { searchStatus = SearchStatus.Failed; return; } if (!games.Any()) { searchStatus = SearchStatus.NoGames; return; } searchStatus = SearchStatus.Hidden; currentServer = games.FirstOrDefault(); foreach (var loop in games.OrderByDescending(g => g.CanJoin()).ThenByDescending(g => g.Players)) { var game = loop; var canJoin = game.CanJoin(); var item = ScrollItemWidget.Setup(serverTemplate, () => currentServer == game, () => currentServer = game, () => Join(game)); var map = Game.modData.MapCache[game.Map]; var preview = item.Get <MapPreviewWidget>("MAP_PREVIEW"); preview.Preview = () => map; var title = item.Get <LabelWidget>("TITLE"); title.GetText = () => game.Name; // TODO: Use game.MapTitle once the server supports it var maptitle = item.Get <LabelWidget>("MAP"); maptitle.GetText = () => map.Title; // TODO: Use game.MaxPlayers once the server supports it var players = item.Get <LabelWidget>("PLAYERS"); players.GetText = () => GetPlayersLabel(game); var state = item.Get <LabelWidget>("STATE"); state.GetText = () => GetStateLabel(game); var ip = item.Get <LabelWidget>("IP"); ip.GetText = () => game.Address; var version = item.Get <LabelWidget>("VERSION"); version.GetText = () => GenerateModLabel(game); version.IsVisible = () => !game.CompatibleVersion(); var location = item.Get <LabelWidget>("LOCATION"); var cachedServerLocation = LobbyUtils.LookupCountry(game.Address.Split(':')[0]); location.GetText = () => cachedServerLocation; location.IsVisible = () => game.CompatibleVersion(); if (!canJoin) { title.GetColor = () => Color.Gray; maptitle.GetColor = () => Color.Gray; players.GetColor = () => Color.Gray; state.GetColor = () => Color.Gray; ip.GetColor = () => Color.Gray; version.GetColor = () => Color.Gray; location.GetColor = () => Color.Gray; } if (!Filtered(game)) { sl.AddChild(item); } } }
public void RefreshServerListInner(IEnumerable <GameServer> games) { if (games == null) { return; } var rows = new List <Widget>(); foreach (var loop in games.OrderByDescending(g => g.CanJoin()).ThenByDescending(g => g.Players)) { var game = loop; if (game == null) { continue; } var canJoin = game.CanJoin(); var item = ScrollItemWidget.Setup(serverTemplate, () => currentServer == game, () => currentServer = game, () => Join(game)); var map = Game.modData.MapCache[game.Map]; var preview = item.GetOrNull <MapPreviewWidget>("MAP_PREVIEW"); if (preview != null) { preview.Preview = () => map; } var title = item.GetOrNull <LabelWidget>("TITLE"); if (title != null) { title.GetText = () => game.Name; title.GetColor = () => canJoin ? title.TextColor : Color.Gray; } var maptitle = item.GetOrNull <LabelWidget>("MAP"); if (title != null) { maptitle.GetText = () => map.Title; maptitle.GetColor = () => canJoin ? maptitle.TextColor : Color.Gray; } var players = item.GetOrNull <LabelWidget>("PLAYERS"); if (players != null) { players.GetText = () => "{0} / {1}".F(game.Players, map.PlayerCount); players.GetColor = () => canJoin ? players.TextColor : Color.Gray; } var state = item.GetOrNull <LabelWidget>("STATE"); if (state != null) { state.GetText = () => GetStateLabel(game); state.GetColor = () => canJoin ? state.TextColor : Color.Gray; } var ip = item.GetOrNull <LabelWidget>("IP"); if (ip != null) { ip.GetText = () => game.Address; ip.GetColor = () => canJoin ? ip.TextColor : Color.Gray; } var version = item.GetOrNull <LabelWidget>("VERSION"); if (version != null) { version.GetText = () => GenerateModLabel(game); version.IsVisible = () => !game.CompatibleVersion(); version.GetColor = () => canJoin ? version.TextColor : Color.Gray; } var location = item.GetOrNull <LabelWidget>("LOCATION"); if (location != null) { var cachedServerLocation = LobbyUtils.LookupCountry(game.Address.Split(':')[0]); location.GetText = () => cachedServerLocation; location.IsVisible = () => game.CompatibleVersion(); location.GetColor = () => canJoin ? location.TextColor : Color.Gray; } if (!Filtered(game)) { rows.Add(item); } } Game.RunAfterTick(() => { serverList.RemoveChildren(); currentServer = null; if (games == null) { searchStatus = SearchStatus.Failed; return; } if (!games.Any()) { searchStatus = SearchStatus.NoGames; return; } currentServer = games.FirstOrDefault(); searchStatus = SearchStatus.Hidden; // Search for any unknown maps if (Game.Settings.Game.AllowDownloading) { Game.modData.MapCache.QueryRemoteMapDetails(games.Where(g => !Filtered(g)).Select(g => g.Map)); } foreach (var row in rows) { serverList.AddChild(row); } }); }
public GameInfoStatsLogic(Widget widget, World world, OrderManager orderManager) { var player = world.RenderPlayer ?? world.LocalPlayer; var playerPanel = widget.Get <ScrollPanelWidget>("PLAYER_LIST"); if (player != null && !player.NonCombatant) { var checkbox = widget.Get <CheckboxWidget>("STATS_CHECKBOX"); var statusLabel = widget.Get <LabelWidget>("STATS_STATUS"); checkbox.IsChecked = () => player.WinState != WinState.Undefined; checkbox.GetCheckType = () => player.WinState == WinState.Won ? "checked" : "crossed"; if (player.HasObjectives) { var mo = player.PlayerActor.Trait <MissionObjectives>(); checkbox.GetText = () => mo.Objectives.First().Description; } statusLabel.GetText = () => player.WinState == WinState.Won ? "Accomplished" : player.WinState == WinState.Lost ? "Failed" : "In progress"; statusLabel.GetColor = () => player.WinState == WinState.Won ? Color.LimeGreen : player.WinState == WinState.Lost ? Color.Red : Color.White; } else { // Expand the stats window to cover the hidden objectives var objectiveGroup = widget.Get("OBJECTIVE"); var statsHeader = widget.Get("STATS_HEADERS"); objectiveGroup.Visible = false; statsHeader.Bounds.Y -= objectiveGroup.Bounds.Height; playerPanel.Bounds.Y -= objectiveGroup.Bounds.Height; playerPanel.Bounds.Height += objectiveGroup.Bounds.Height; } var teamTemplate = playerPanel.Get <ScrollItemWidget>("TEAM_TEMPLATE"); var playerTemplate = playerPanel.Get("PLAYER_TEMPLATE"); playerPanel.RemoveChildren(); var teams = world.Players.Where(p => !p.NonCombatant && p.Playable) .Select(p => new Pair <Player, PlayerStatistics>(p, p.PlayerActor.TraitOrDefault <PlayerStatistics>())) .OrderByDescending(p => p.Second != null ? p.Second.Experience : 0) .GroupBy(p => (world.LobbyInfo.ClientWithIndex(p.First.ClientIndex) ?? new Session.Client()).Team) .OrderByDescending(g => g.Sum(gg => gg.Second != null ? gg.Second.Experience : 0)); foreach (var t in teams) { if (teams.Count() > 1) { var teamHeader = ScrollItemWidget.Setup(teamTemplate, () => true, () => { }); teamHeader.Get <LabelWidget>("TEAM").GetText = () => t.Key == 0 ? "No Team" : "Team {0}".F(t.Key); var teamRating = teamHeader.Get <LabelWidget>("TEAM_SCORE"); teamRating.GetText = () => t.Sum(gg => gg.Second != null ? gg.Second.Experience : 0).ToString(); playerPanel.AddChild(teamHeader); } foreach (var p in t.ToList()) { var pp = p.First; var client = world.LobbyInfo.ClientWithIndex(pp.ClientIndex); var item = playerTemplate.Clone(); LobbyUtils.SetupClientWidget(item, client, orderManager, client != null && client.Bot == null); var nameLabel = item.Get <LabelWidget>("NAME"); var nameFont = Game.Renderer.Fonts[nameLabel.Font]; var suffixLength = new CachedTransform <string, int>(s => nameFont.Measure(s).X); var name = new CachedTransform <Pair <string, int>, string>(c => WidgetUtils.TruncateText(c.First, nameLabel.Bounds.Width - c.Second, nameFont)); nameLabel.GetText = () => { var suffix = pp.WinState == WinState.Undefined ? "" : " (" + pp.WinState + ")"; if (client != null && client.State == Session.ClientState.Disconnected) { suffix = " (Gone)"; } var sl = suffixLength.Update(suffix); return(name.Update(Pair.New(pp.PlayerName, sl)) + suffix); }; nameLabel.GetColor = () => pp.Color.RGB; var flag = item.Get <ImageWidget>("FACTIONFLAG"); flag.GetImageCollection = () => "flags"; if (player == null || player.Stances[pp] == Stance.Ally || player.WinState != WinState.Undefined) { flag.GetImageName = () => pp.Faction.InternalName; item.Get <LabelWidget>("FACTION").GetText = () => pp.Faction.Name; } else { flag.GetImageName = () => pp.DisplayFaction.InternalName; item.Get <LabelWidget>("FACTION").GetText = () => pp.DisplayFaction.Name; } var experience = p.Second != null ? p.Second.Experience : 0; item.Get <LabelWidget>("SCORE").GetText = () => experience.ToString(); playerPanel.AddChild(item); } } }
public ReplayBrowserLogic(Widget widget, Action onExit, Action onStart) { panel = widget; playerList = panel.Get<ScrollPanelWidget>("PLAYER_LIST"); playerHeader = playerList.Get<ScrollItemWidget>("HEADER"); playerTemplate = playerList.Get<ScrollItemWidget>("TEMPLATE"); playerList.RemoveChildren(); panel.Get<ButtonWidget>("CANCEL_BUTTON").OnClick = () => { Ui.CloseWindow(); onExit(); }; replayList = panel.Get<ScrollPanelWidget>("REPLAY_LIST"); var template = panel.Get<ScrollItemWidget>("REPLAY_TEMPLATE"); var mod = Game.modData.Manifest.Mod; var dir = Platform.ResolvePath("^", "Replays", mod.Id, mod.Version); replayList.RemoveChildren(); if (Directory.Exists(dir)) { using (new Support.PerfTimer("Load replays")) { replays = Directory .GetFiles(dir, "*.rep") .Select(ReplayMetadata.Read) .Where(r => r != null) .OrderByDescending(r => r.GameInfo.StartTimeUtc) .ToList(); } foreach (var replay in replays) AddReplay(replay, template); ApplyFilter(); } else replays = new List<ReplayMetadata>(); var watch = panel.Get<ButtonWidget>("WATCH_BUTTON"); watch.IsDisabled = () => selectedReplay == null || selectedReplay.GameInfo.MapPreview.Status != MapStatus.Available; watch.OnClick = () => { WatchReplay(); onStart(); }; panel.Get("REPLAY_INFO").IsVisible = () => selectedReplay != null; var preview = panel.Get<MapPreviewWidget>("MAP_PREVIEW"); preview.SpawnOccupants = () => selectedSpawns; preview.Preview = () => selectedReplay != null ? selectedReplay.GameInfo.MapPreview : null; var title = panel.GetOrNull<LabelWidget>("MAP_TITLE"); if (title != null) title.GetText = () => selectedReplay != null ? selectedReplay.GameInfo.MapPreview.Title : null; var type = panel.GetOrNull<LabelWidget>("MAP_TYPE"); if (type != null) type.GetText = () => selectedReplay.GameInfo.MapPreview.Type; panel.Get<LabelWidget>("DURATION").GetText = () => WidgetUtils.FormatTimeSeconds((int)selectedReplay.GameInfo.Duration.TotalSeconds); SetupFilters(); SetupManagement(); }
public CncMusicPlayerLogic(Widget widget, Action onExit) { panel = widget.Get("MUSIC_PANEL"); var ml = panel.Get <ScrollPanelWidget>("MUSIC_LIST"); itemTemplate = ml.Get <ScrollItemWidget>("MUSIC_TEMPLATE"); BuildMusicTable(ml); currentSong = Sound.CurrentMusic ?? GetNextSong(); installed = Rules.Music.Where(m => m.Value.Exists).Any(); Func <bool> noMusic = () => !installed; panel.Get <ButtonWidget>("BACK_BUTTON").OnClick = () => { Ui.CloseWindow(); onExit(); }; Action afterInstall = () => { // Mount the new mixfile and rebuild the scores list try { var path = new string[] { Platform.SupportDir, "Content", "cnc" }.Aggregate(Path.Combine); FileSystem.Mount(Path.Combine(path, "scores.mix")); FileSystem.Mount(Path.Combine(path, "transit.mix")); Rules.Music.Do(m => m.Value.Reload()); } catch (Exception) { } installed = Rules.Music.Where(m => m.Value.Exists).Any(); BuildMusicTable(ml); }; var installButton = panel.Get <ButtonWidget>("INSTALL_BUTTON"); installButton.OnClick = () => Ui.OpenWindow("INSTALL_MUSIC_PANEL", new WidgetArgs() { { "afterInstall", afterInstall }, { "filesToCopy", new [] { "SCORES.MIX" } }, { "filesToExtract", new [] { "transit.mix" } }, }); installButton.IsVisible = () => music.Length < 3; // Hack around music being split between transit.mix and scores.mix panel.Get("NO_MUSIC_LABEL").IsVisible = noMusic; var playButton = panel.Get <ButtonWidget>("BUTTON_PLAY"); playButton.OnClick = Play; playButton.IsDisabled = noMusic; var pauseButton = panel.Get <ButtonWidget>("BUTTON_PAUSE"); pauseButton.OnClick = Pause; pauseButton.IsDisabled = noMusic; var stopButton = panel.Get <ButtonWidget>("BUTTON_STOP"); stopButton.OnClick = Stop; stopButton.IsDisabled = noMusic; var nextButton = panel.Get <ButtonWidget>("BUTTON_NEXT"); nextButton.OnClick = () => { currentSong = GetNextSong(); Play(); }; nextButton.IsDisabled = noMusic; var prevButton = panel.Get <ButtonWidget>("BUTTON_PREV"); prevButton.OnClick = () => { currentSong = GetPrevSong(); Play(); }; prevButton.IsDisabled = noMusic; var shuffleCheckbox = panel.Get <CheckboxWidget>("SHUFFLE"); shuffleCheckbox.IsChecked = () => Game.Settings.Sound.Shuffle; shuffleCheckbox.OnClick = () => Game.Settings.Sound.Shuffle ^= true; var repeatCheckbox = panel.Get <CheckboxWidget>("REPEAT"); repeatCheckbox.IsChecked = () => Game.Settings.Sound.Repeat; repeatCheckbox.OnClick = () => Game.Settings.Sound.Repeat ^= true; panel.Get <LabelWidget>("TIME_LABEL").GetText = () => (currentSong == null) ? "" : "{0:D2}:{1:D2} / {2:D2}:{3:D2}".F((int)Sound.MusicSeekPosition / 60, (int)Sound.MusicSeekPosition % 60, currentSong.Length / 60, currentSong.Length % 60); panel.Get <LabelWidget>("TITLE_LABEL").GetText = () => (currentSong == null) ? "" : currentSong.Title; var musicSlider = panel.Get <SliderWidget>("MUSIC_SLIDER"); musicSlider.OnChange += x => Sound.MusicVolume = x; musicSlider.Value = Sound.MusicVolume; }
public ActorSelectorLogic(Widget widget, World world, WorldRenderer worldRenderer) { mapRules = world.Map.Rules; this.world = world; this.worldRenderer = worldRenderer; editor = widget.Parent.Get <EditorViewportControllerWidget>("MAP_EDITOR"); ownersDropDown = widget.Get <DropDownButtonWidget>("OWNERS_DROPDOWN"); panel = widget.Get <ScrollPanelWidget>("ACTORTEMPLATE_LIST"); itemTemplate = panel.Get <ScrollItemWidget>("ACTORPREVIEW_TEMPLATE"); panel.Layout = new GridLayout(panel); var editorLayer = world.WorldActor.Trait <EditorActorLayer>(); selectedOwner = editorLayer.Players.Players.Values.First(); Func <PlayerReference, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) => { var item = ScrollItemWidget.Setup(template, () => selectedOwner == option, () => { selectedOwner = option; ownersDropDown.Text = selectedOwner.Name; ownersDropDown.TextColor = selectedOwner.Color.RGB; InitializeActorPreviews(); }); item.Get <LabelWidget>("LABEL").GetText = () => option.Name; item.GetColor = () => option.Color.RGB; return(item); }; ownersDropDown.OnClick = () => { var owners = editorLayer.Players.Players.Values.OrderBy(p => p.Name); ownersDropDown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 270, owners, setupItem); }; ownersDropDown.Text = selectedOwner.Name; ownersDropDown.TextColor = selectedOwner.Color.RGB; var tileSetId = world.Map.Rules.TileSet.Id; var allActorsTemp = new List <ActorSelectorActor>(); foreach (var a in mapRules.Actors.Values) { // Partial templates are not allowed if (a.Name.Contains('^')) { continue; } // Actor must have a preview associated with it if (!a.HasTraitInfo <IRenderActorPreviewInfo>()) { continue; } var editorData = a.TraitInfoOrDefault <EditorTilesetFilterInfo>(); // Actor must be included in at least one category if (editorData == null || editorData.Categories == null) { continue; } // Excluded by tileset if (editorData.ExcludeTilesets != null && editorData.ExcludeTilesets.Contains(tileSetId)) { continue; } if (editorData.RequireTilesets != null && !editorData.RequireTilesets.Contains(tileSetId)) { continue; } var tooltip = a.TraitInfos <EditorOnlyTooltipInfo>().FirstOrDefault(ti => ti.EnabledByDefault) as TooltipInfoBase ?? a.TraitInfos <TooltipInfo>().FirstOrDefault(ti => ti.EnabledByDefault); var searchTerms = new List <string>() { a.Name }; if (tooltip != null) { searchTerms.Add(tooltip.Name); } var tooltipText = (tooltip == null ? "Type: " : tooltip.Name + "\nType: ") + a.Name; allActorsTemp.Add(new ActorSelectorActor(a, editorData.Categories, searchTerms.ToArray(), tooltipText)); } allActors = allActorsTemp.ToArray(); allCategories = allActors.SelectMany(ac => ac.Categories) .Distinct() .OrderBy(x => x) .ToArray(); foreach (var c in allCategories) { selectedCategories.Add(c); filteredCategories.Add(c); } var searchTextField = widget.Get <TextFieldWidget>("SEARCH_TEXTFIELD"); searchTextField.OnTextEdited = () => { searchFilter = searchTextField.Text.Trim(); filteredCategories.Clear(); if (!string.IsNullOrEmpty(searchFilter)) { filteredCategories.AddRange( allActors.Where(t => t.SearchTerms.Any( s => s.IndexOf(searchFilter, StringComparison.OrdinalIgnoreCase) >= 0)) .SelectMany(t => t.Categories) .Distinct() .OrderBy(x => x)); } else { filteredCategories.AddRange(allCategories); } InitializeActorPreviews(); }; searchTextField.OnEscKey = () => { searchTextField.Text = ""; searchTextField.YieldKeyboardFocus(); return(true); }; var actorCategorySelector = widget.Get <DropDownButtonWidget>("CATEGORIES_DROPDOWN"); actorCategorySelector.GetText = () => { if (selectedCategories.Count == 0) { return("None"); } if (!string.IsNullOrEmpty(searchFilter)) { return("Search Results"); } if (selectedCategories.Count == 1) { return(selectedCategories.First()); } if (selectedCategories.Count == allCategories.Length) { return("All"); } return("Multiple"); }; actorCategorySelector.OnMouseDown = _ => { if (searchTextField != null) { searchTextField.YieldKeyboardFocus(); } actorCategorySelector.RemovePanel(); actorCategorySelector.AttachPanel(CreateCategoriesPanel()); }; InitializeActorPreviews(); }
public AssetBrowserLogic(Widget widget, Action onExit, World world, Dictionary <string, MiniYaml> logicArgs) { this.world = world; panel = widget; assetSource = Game.ModData.ModFiles.MountedFolders.First(); var ticker = panel.GetOrNull <LogicTickerWidget>("ANIMATION_TICKER"); if (ticker != null) { ticker.OnTick = () => { if (animateFrames) { SelectNextFrame(); } }; } var sourceDropdown = panel.GetOrNull <DropDownButtonWidget>("SOURCE_SELECTOR"); if (sourceDropdown != null) { sourceDropdown.OnMouseDown = _ => ShowSourceDropdown(sourceDropdown); sourceDropdown.GetText = () => { var name = assetSource != null?Platform.UnresolvePath(assetSource.Name) : "All Packages"; if (name.Length > 15) { name = "..." + name.Substring(name.Length - 15); } return(name); }; } var spriteWidget = panel.GetOrNull <SpriteWidget>("SPRITE"); if (spriteWidget != null) { spriteWidget.GetSprite = () => currentSprites != null ? currentSprites[currentFrame] : null; currentPalette = spriteWidget.Palette; spriteWidget.GetPalette = () => currentPalette; spriteWidget.IsVisible = () => !isVideoLoaded; } var playerWidget = panel.GetOrNull <VqaPlayerWidget>("PLAYER"); if (playerWidget != null) { playerWidget.IsVisible = () => isVideoLoaded; } var paletteDropDown = panel.GetOrNull <DropDownButtonWidget>("PALETTE_SELECTOR"); if (paletteDropDown != null) { paletteDropDown.OnMouseDown = _ => ShowPaletteDropdown(paletteDropDown, world); paletteDropDown.GetText = () => currentPalette; } var colorPreview = panel.GetOrNull <ColorPreviewManagerWidget>("COLOR_MANAGER"); if (colorPreview != null) { colorPreview.Color = Game.Settings.Player.Color; } var colorDropdown = panel.GetOrNull <DropDownButtonWidget>("COLOR"); if (colorDropdown != null) { colorDropdown.IsDisabled = () => currentPalette != colorPreview.PaletteName; colorDropdown.OnMouseDown = _ => ColorPickerLogic.ShowColorDropDown(colorDropdown, colorPreview, world); panel.Get <ColorBlockWidget>("COLORBLOCK").GetColor = () => Game.Settings.Player.Color.RGB; } filenameInput = panel.Get <TextFieldWidget>("FILENAME_INPUT"); filenameInput.OnTextEdited = () => ApplyFilter(filenameInput.Text); filenameInput.OnEscKey = filenameInput.YieldKeyboardFocus; var frameContainer = panel.GetOrNull("FRAME_SELECTOR"); if (frameContainer != null) { frameContainer.IsVisible = () => (currentSprites != null && currentSprites.Length > 1) || (isVideoLoaded && player != null && player.Video != null && player.Video.Frames > 1); } frameSlider = panel.Get <SliderWidget>("FRAME_SLIDER"); if (frameSlider != null) { frameSlider.OnChange += x => { if (!isVideoLoaded) { currentFrame = (int)Math.Round(x); } }; frameSlider.GetValue = () => isVideoLoaded ? player.Video.CurrentFrame : currentFrame; frameSlider.IsDisabled = () => isVideoLoaded; } var frameText = panel.GetOrNull <LabelWidget>("FRAME_COUNT"); if (frameText != null) { frameText.GetText = () => isVideoLoaded ? "{0} / {1}".F(player.Video.CurrentFrame + 1, player.Video.Frames) : "{0} / {1}".F(currentFrame, currentSprites.Length - 1); } var playButton = panel.GetOrNull <ButtonWidget>("BUTTON_PLAY"); if (playButton != null) { playButton.Key = new Hotkey(Keycode.SPACE, Modifiers.None); playButton.OnClick = () => { if (isVideoLoaded) { player.Play(); } else { animateFrames = true; } }; playButton.IsVisible = () => isVideoLoaded ? player.Paused : !animateFrames; } var pauseButton = panel.GetOrNull <ButtonWidget>("BUTTON_PAUSE"); if (pauseButton != null) { pauseButton.Key = new Hotkey(Keycode.SPACE, Modifiers.None); pauseButton.OnClick = () => { if (isVideoLoaded) { player.Pause(); } else { animateFrames = false; } }; pauseButton.IsVisible = () => isVideoLoaded ? !player.Paused : animateFrames; } var stopButton = panel.GetOrNull <ButtonWidget>("BUTTON_STOP"); if (stopButton != null) { stopButton.Key = new Hotkey(Keycode.RETURN, Modifiers.None); stopButton.OnClick = () => { if (isVideoLoaded) { player.Stop(); } else { frameSlider.Value = 0; currentFrame = 0; animateFrames = false; } }; } var nextButton = panel.GetOrNull <ButtonWidget>("BUTTON_NEXT"); if (nextButton != null) { nextButton.Key = new Hotkey(Keycode.RIGHT, Modifiers.None); nextButton.OnClick = () => { if (!isVideoLoaded) { nextButton.OnClick = SelectNextFrame; } }; nextButton.IsVisible = () => !isVideoLoaded; } var prevButton = panel.GetOrNull <ButtonWidget>("BUTTON_PREV"); if (prevButton != null) { prevButton.Key = new Hotkey(Keycode.LEFT, Modifiers.None); prevButton.OnClick = () => { if (!isVideoLoaded) { SelectPreviousFrame(); } }; prevButton.IsVisible = () => !isVideoLoaded; } if (logicArgs.ContainsKey("SupportedFormats")) { allowedExtensions = FieldLoader.GetValue <string[]>("SupportedFormats", logicArgs["SupportedFormats"].Value); } else { allowedExtensions = new string[0]; } assetList = panel.Get <ScrollPanelWidget>("ASSET_LIST"); template = panel.Get <ScrollItemWidget>("ASSET_TEMPLATE"); PopulateAssetList(); var closeButton = panel.GetOrNull <ButtonWidget>("CLOSE_BUTTON"); if (closeButton != null) { closeButton.OnClick = () => { if (isVideoLoaded) { player.Stop(); } Ui.CloseWindow(); onExit(); } } ; } void SelectNextFrame() { currentFrame++; if (currentFrame >= currentSprites.Length) { currentFrame = 0; } } void SelectPreviousFrame() { currentFrame--; if (currentFrame < 0) { currentFrame = currentSprites.Length - 1; } } Dictionary <string, bool> assetVisByName = new Dictionary <string, bool>(); bool FilterAsset(string filename) { var filter = filenameInput.Text; if (string.IsNullOrWhiteSpace(filter)) { return(true); } if (filename.IndexOf(filter, StringComparison.OrdinalIgnoreCase) >= 0) { return(true); } return(false); } void ApplyFilter(string filename) { assetVisByName.Clear(); assetList.Layout.AdjustChildren(); assetList.ScrollToTop(); // Select the first visible var firstVisible = assetVisByName.FirstOrDefault(kvp => kvp.Value); if (firstVisible.Key != null) { LoadAsset(firstVisible.Key); } } void AddAsset(ScrollPanelWidget list, string filepath, ScrollItemWidget template) { var filename = Path.GetFileName(filepath); var item = ScrollItemWidget.Setup(template, () => currentFilename == filename, () => { LoadAsset(filename); }); item.Get <LabelWidget>("TITLE").GetText = () => filepath; item.IsVisible = () => { bool visible; if (assetVisByName.TryGetValue(filepath, out visible)) { return(visible); } visible = FilterAsset(filepath); assetVisByName.Add(filepath, visible); return(visible); }; list.AddChild(item); } bool LoadAsset(string filename) { if (isVideoLoaded) { player.Stop(); player = null; isVideoLoaded = false; } if (string.IsNullOrEmpty(filename)) { return(false); } if (!Game.ModData.ModFiles.Exists(filename)) { return(false); } if (Path.GetExtension(filename.ToLowerInvariant()) == ".vqa") { player = panel.Get <VqaPlayerWidget>("PLAYER"); currentFilename = filename; player.Load(filename); player.DrawOverlay = false; isVideoLoaded = true; frameSlider.MaximumValue = (float)player.Video.Frames - 1; frameSlider.Ticks = 0; return(true); } else { currentFilename = filename; currentSprites = world.Map.SequenceProvider.SpriteCache[filename]; currentFrame = 0; frameSlider.MaximumValue = (float)currentSprites.Length - 1; frameSlider.Ticks = currentSprites.Length; } return(true); } bool ShowSourceDropdown(DropDownButtonWidget dropdown) { Func <IFolder, ScrollItemWidget, ScrollItemWidget> setupItem = (source, itemTemplate) => { var item = ScrollItemWidget.Setup(itemTemplate, () => assetSource == source, () => { assetSource = source; PopulateAssetList(); }); item.Get <LabelWidget>("LABEL").GetText = () => source != null?Platform.UnresolvePath(source.Name) : "All Packages"; return(item); }; // TODO: Re-enable "All Packages" once list generation is done in a background thread // var sources = new[] { (IFolder)null }.Concat(GlobalFileSystem.MountedFolders); var sources = Game.ModData.ModFiles.MountedFolders; dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 280, sources, setupItem); return(true); } void PopulateAssetList() { assetList.RemoveChildren(); availableShps.Clear(); // TODO: This is too slow to run in the main thread // var files = AssetSource != null ? AssetSource.AllFileNames() : // GlobalFileSystem.MountedFolders.SelectMany(f => f.AllFileNames()); if (assetSource == null) { return; } var files = assetSource.AllFileNames().OrderBy(s => s); foreach (var file in files) { if (allowedExtensions.Any(ext => file.EndsWith(ext, true, CultureInfo.InvariantCulture))) { AddAsset(assetList, file, template); availableShps.Add(file); } } } bool ShowPaletteDropdown(DropDownButtonWidget dropdown, World world) { Func <string, ScrollItemWidget, ScrollItemWidget> setupItem = (name, itemTemplate) => { var item = ScrollItemWidget.Setup(itemTemplate, () => currentPalette == name, () => currentPalette = name); item.Get <LabelWidget>("LABEL").GetText = () => name; return(item); }; var palettes = world.WorldActor.TraitsImplementing <IProvidesAssetBrowserPalettes>() .SelectMany(p => p.PaletteNames); dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 280, palettes, setupItem); return(true); } }
public NewMapLogic(Action onExit, Action <string> onSelect, Widget widget, World world, ModData modData) { panel = widget; panel.Get <ButtonWidget>("CANCEL_BUTTON").OnClick = () => { Ui.CloseWindow(); onExit(); }; var tilesetDropDown = panel.Get <DropDownButtonWidget>("TILESET"); var tilesets = modData.DefaultTileSets.Select(t => t.Key).ToList(); Func <string, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) => { var item = ScrollItemWidget.Setup(template, () => tilesetDropDown.Text == option, () => { tilesetDropDown.Text = option; }); item.Get <LabelWidget>("LABEL").GetText = () => option; return(item); }; tilesetDropDown.Text = tilesets.First(); tilesetDropDown.OnClick = () => tilesetDropDown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 210, tilesets, setupItem); var widthTextField = panel.Get <TextFieldWidget>("WIDTH"); var heightTextField = panel.Get <TextFieldWidget>("HEIGHT"); panel.Get <ButtonWidget>("CREATE_BUTTON").OnClick = () => { int width, height; int.TryParse(widthTextField.Text, out width); int.TryParse(heightTextField.Text, out height); // Require at least a 2x2 playable area so that the // ground is visible through the edge shroud width = Math.Max(2, width); height = Math.Max(2, height); var maxTerrainHeight = world.Map.Grid.MaximumTerrainHeight; var tileset = modData.DefaultTileSets[tilesetDropDown.Text]; var map = new Map(Game.ModData, tileset, width + 2, height + maxTerrainHeight + 2); var tl = new PPos(1, 1 + maxTerrainHeight); var br = new PPos(width, height + maxTerrainHeight); map.SetBounds(tl, br); map.PlayerDefinitions = new MapPlayers(map.Rules, 0).ToMiniYaml(); map.FixOpenAreas(); Action <string> afterSave = uid => { // HACK: Work around a synced-code change check. // It's not clear why this is needed here, but not in the other places that load maps. Game.RunAfterTick(() => { ConnectionLogic.Connect(System.Net.IPAddress.Loopback.ToString(), Game.CreateLocalServer(uid), "", () => Game.LoadEditor(uid), () => { Game.CloseServer(); onExit(); }); }); Ui.CloseWindow(); onSelect(uid); }; Ui.OpenWindow("SAVE_MAP_PANEL", new WidgetArgs() { { "onSave", afterSave }, { "onExit", () => { Ui.CloseWindow(); onExit(); } }, { "map", map }, { "playerDefinitions", map.PlayerDefinitions }, { "actorDefinitions", map.ActorDefinitions } }); }; }
public DiplomacyLogic(Widget widget, Action onExit, World world) { this.world = world; diplomacyPanel = widget.Get <ScrollPanelWidget>("DIPLOMACY_PANEL"); LayoutPlayers(); var close = widget.GetOrNull <ButtonWidget>("CLOSE"); if (close != null) { close.OnClick = () => { Ui.CloseWindow(); Ui.Root.RemoveChild(widget); onExit(); } } ; } void LayoutPlayers() { var teamTemplate = diplomacyPanel.Get <ScrollItemWidget>("TEAM_TEMPLATE"); var players = world.Players.Where(p => p != world.LocalPlayer && !p.NonCombatant); var teams = players.GroupBy(p => (world.LobbyInfo.ClientWithIndex(p.ClientIndex) ?? new Session.Client()).Team).OrderBy(g => g.Key); foreach (var t in teams) { var team = t; var tt = ScrollItemWidget.Setup(teamTemplate, () => false, () => { }); tt.IgnoreMouseOver = true; tt.Get <LabelWidget>("TEAM").GetText = () => team.Key == 0 ? "No Team" : "Team " + team.Key; diplomacyPanel.AddChild(tt); foreach (var p in team) { var player = p; diplomacyPanel.AddChild(DiplomaticStatus(player)); } } } ScrollItemWidget DiplomaticStatus(Player player) { var playerTemplate = diplomacyPanel.Get <ScrollItemWidget>("PLAYER_TEMPLATE"); var pt = ScrollItemWidget.Setup(playerTemplate, () => false, () => { }); pt.IgnoreMouseOver = true; LobbyUtils.AddPlayerFlagAndName(pt, player); pt.Get <LabelWidget>("THEIR_STANCE").GetText = () => player.Stances[world.LocalPlayer].ToString(); var myStance = pt.Get <DropDownButtonWidget>("MY_STANCE"); myStance.GetText = () => world.LocalPlayer.Stances[player].ToString(); myStance.IsDisabled = () => !world.LobbyInfo.GlobalSettings.FragileAlliances; myStance.OnMouseDown = mi => ShowDropDown(player, myStance); return(pt); } void ShowDropDown(Player p, DropDownButtonWidget dropdown) { var stances = Enum <Stance> .GetValues(); Func <Stance, ScrollItemWidget, ScrollItemWidget> setupItem = (s, template) => { var item = ScrollItemWidget.Setup(template, () => s == world.LocalPlayer.Stances[p], () => SetStance(dropdown, p, s)); item.Get <LabelWidget>("LABEL").GetText = () => s.ToString(); return(item); }; dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 150, stances, setupItem); } void SetStance(ButtonWidget bw, Player p, Stance ss) { if (!p.World.LobbyInfo.GlobalSettings.FragileAlliances) { return; // stance changes are banned } world.IssueOrder(new Order("SetStance", world.LocalPlayer.PlayerActor, false) { ExtraData = (uint)ss, TargetString = p.InternalName, }); bw.Text = ss.ToString(); } }
internal LobbyLogic(Widget widget, WorldRenderer worldRenderer, OrderManager orderManager, Action onExit, Action onStart, bool skirmishMode, Ruleset modRules) { lobby = widget; this.orderManager = orderManager; this.onStart = onStart; this.onExit = onExit; this.skirmishMode = skirmishMode; this.modRules = modRules; orderManager.AddChatLine += AddChatLine; Game.LobbyInfoChanged += UpdateCurrentMap; Game.LobbyInfoChanged += UpdatePlayerList; Game.BeforeGameStart += OnGameStart; Game.ConnectionStateChanged += ConnectionStateChanged; var name = lobby.GetOrNull <LabelWidget>("SERVER_NAME"); if (name != null) { name.GetText = () => orderManager.LobbyInfo.GlobalSettings.ServerName; } Ui.LoadWidget("LOBBY_MAP_PREVIEW", lobby.Get("MAP_PREVIEW_ROOT"), new WidgetArgs { { "orderManager", orderManager }, { "lobby", this } }); UpdateCurrentMap(); players = Ui.LoadWidget <ScrollPanelWidget>("LOBBY_PLAYER_BIN", lobby.Get("PLAYER_BIN_ROOT"), new WidgetArgs()); players.IsVisible = () => panel == PanelType.Players; var playerBinHeaders = lobby.GetOrNull <ContainerWidget>("LABEL_CONTAINER"); if (playerBinHeaders != null) { playerBinHeaders.IsVisible = () => panel == PanelType.Players; } editablePlayerTemplate = players.Get("TEMPLATE_EDITABLE_PLAYER"); nonEditablePlayerTemplate = players.Get("TEMPLATE_NONEDITABLE_PLAYER"); emptySlotTemplate = players.Get("TEMPLATE_EMPTY"); editableSpectatorTemplate = players.Get("TEMPLATE_EDITABLE_SPECTATOR"); nonEditableSpectatorTemplate = players.Get("TEMPLATE_NONEDITABLE_SPECTATOR"); newSpectatorTemplate = players.Get("TEMPLATE_NEW_SPECTATOR"); colorPreview = lobby.Get <ColorPreviewManagerWidget>("COLOR_MANAGER"); colorPreview.Color = Game.Settings.Player.Color; countryNames = modRules.Actors["world"].Traits.WithInterface <CountryInfo>() .Where(c => c.Selectable) .ToDictionary(a => a.Race, a => a.Name); countryNames.Add("random", "Any"); var gameStarting = false; Func <bool> configurationDisabled = () => !Game.IsHost || gameStarting || panel == PanelType.Kick || panel == PanelType.ForceStart || orderManager.LocalClient == null || orderManager.LocalClient.IsReady; var mapButton = lobby.GetOrNull <ButtonWidget>("CHANGEMAP_BUTTON"); if (mapButton != null) { mapButton.IsDisabled = configurationDisabled; mapButton.OnClick = () => { var onSelect = new Action <string>(uid => { // Don't select the same map again if (uid == Map.Uid) { return; } orderManager.IssueOrder(Order.Command("map " + uid)); Game.Settings.Server.Map = uid; Game.Settings.Save(); }); Ui.OpenWindow("MAPCHOOSER_PANEL", new WidgetArgs() { { "initialMap", Map.Uid }, { "onExit", DoNothing }, { "onSelect", onSelect } }); }; } var slotsButton = lobby.GetOrNull <DropDownButtonWidget>("SLOTS_DROPDOWNBUTTON"); if (slotsButton != null) { slotsButton.IsDisabled = () => configurationDisabled() || panel != PanelType.Players || Map.RuleStatus != MapRuleStatus.Cached || !orderManager.LobbyInfo.Slots.Values.Any(s => s.AllowBots || !s.LockTeam); var botNames = modRules.Actors["player"].Traits.WithInterface <IBotInfo>().Select(t => t.Name); slotsButton.OnMouseDown = _ => { var options = new Dictionary <string, IEnumerable <DropDownOption> >(); var botController = orderManager.LobbyInfo.Clients.FirstOrDefault(c => c.IsAdmin); if (orderManager.LobbyInfo.Slots.Values.Any(s => s.AllowBots)) { var botOptions = new List <DropDownOption>() { new DropDownOption() { Title = "Add", IsSelected = () => false, OnClick = () => { foreach (var slot in orderManager.LobbyInfo.Slots) { var bot = botNames.Random(Game.CosmeticRandom); var c = orderManager.LobbyInfo.ClientInSlot(slot.Key); if (slot.Value.AllowBots == true && (c == null || c.Bot != null)) { orderManager.IssueOrder(Order.Command("slot_bot {0} {1} {2}".F(slot.Key, botController.Index, bot))); } } } } }; if (orderManager.LobbyInfo.Clients.Any(c => c.Bot != null)) { botOptions.Add(new DropDownOption() { Title = "Remove", IsSelected = () => false, OnClick = () => { foreach (var slot in orderManager.LobbyInfo.Slots) { var c = orderManager.LobbyInfo.ClientInSlot(slot.Key); if (c != null && c.Bot != null) { orderManager.IssueOrder(Order.Command("slot_open " + slot.Value.PlayerReference)); } } } }); } options.Add("Configure Bots", botOptions); } var teamCount = (orderManager.LobbyInfo.Slots.Count(s => !s.Value.LockTeam && orderManager.LobbyInfo.ClientInSlot(s.Key) != null) + 1) / 2; if (teamCount >= 1) { var teamOptions = Enumerable.Range(2, teamCount - 1).Reverse().Select(d => new DropDownOption { Title = "{0} Teams".F(d), IsSelected = () => false, OnClick = () => orderManager.IssueOrder(Order.Command("assignteams {0}".F(d.ToString()))) }).ToList(); if (orderManager.LobbyInfo.Slots.Any(s => s.Value.AllowBots)) { teamOptions.Add(new DropDownOption { Title = "Humans vs Bots", IsSelected = () => false, OnClick = () => orderManager.IssueOrder(Order.Command("assignteams 1")) }); } teamOptions.Add(new DropDownOption { Title = "Free for all", IsSelected = () => false, OnClick = () => orderManager.IssueOrder(Order.Command("assignteams 0")) }); options.Add("Configure Teams", teamOptions); } Func <DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) => { var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick); item.Get <LabelWidget>("LABEL").GetText = () => option.Title; return(item); }; slotsButton.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 175, options, setupItem); }; } var optionsBin = Ui.LoadWidget("LOBBY_OPTIONS_BIN", lobby, new WidgetArgs()); optionsBin.IsVisible = () => panel == PanelType.Options; var optionsButton = lobby.Get <ButtonWidget>("OPTIONS_BUTTON"); optionsButton.IsDisabled = () => Map.RuleStatus != MapRuleStatus.Cached || panel == PanelType.Kick || panel == PanelType.ForceStart; optionsButton.GetText = () => panel == PanelType.Options ? "Players" : "Options"; optionsButton.OnClick = () => panel = (panel == PanelType.Options) ? PanelType.Players : PanelType.Options; // Force start panel Action startGame = () => { gameStarting = true; orderManager.IssueOrder(Order.Command("startgame")); }; var startGameButton = lobby.GetOrNull <ButtonWidget>("START_GAME_BUTTON"); if (startGameButton != null) { startGameButton.IsDisabled = () => configurationDisabled() || Map.RuleStatus != MapRuleStatus.Cached || orderManager.LobbyInfo.Slots.Any(sl => sl.Value.Required && orderManager.LobbyInfo.ClientInSlot(sl.Key) == null); startGameButton.OnClick = () => { Func <KeyValuePair <string, Session.Slot>, bool> notReady = sl => { var cl = orderManager.LobbyInfo.ClientInSlot(sl.Key); // Bots and admins don't count return(cl != null && !cl.IsAdmin && cl.Bot == null && !cl.IsReady); }; if (orderManager.LobbyInfo.Slots.Any(notReady)) { panel = PanelType.ForceStart; } else { startGame(); } }; } var forceStartBin = Ui.LoadWidget("FORCE_START_DIALOG", lobby, new WidgetArgs()); forceStartBin.IsVisible = () => panel == PanelType.ForceStart; forceStartBin.Get("KICK_WARNING").IsVisible = () => orderManager.LobbyInfo.Clients.Any(c => c.IsInvalid); forceStartBin.Get <ButtonWidget>("OK_BUTTON").OnClick = startGame; forceStartBin.Get <ButtonWidget>("CANCEL_BUTTON").OnClick = () => panel = PanelType.Players; // Options panel var allowCheats = optionsBin.GetOrNull <CheckboxWidget>("ALLOWCHEATS_CHECKBOX"); if (allowCheats != null) { allowCheats.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.AllowCheats; allowCheats.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.Cheats.HasValue || configurationDisabled(); allowCheats.OnClick = () => orderManager.IssueOrder(Order.Command( "allowcheats {0}".F(!orderManager.LobbyInfo.GlobalSettings.AllowCheats))); } var crates = optionsBin.GetOrNull <CheckboxWidget>("CRATES_CHECKBOX"); if (crates != null) { crates.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.Crates; crates.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.Crates.HasValue || configurationDisabled(); crates.OnClick = () => orderManager.IssueOrder(Order.Command( "crates {0}".F(!orderManager.LobbyInfo.GlobalSettings.Crates))); } var allybuildradius = optionsBin.GetOrNull <CheckboxWidget>("ALLYBUILDRADIUS_CHECKBOX"); if (allybuildradius != null) { allybuildradius.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.AllyBuildRadius; allybuildradius.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.AllyBuildRadius.HasValue || configurationDisabled(); allybuildradius.OnClick = () => orderManager.IssueOrder(Order.Command( "allybuildradius {0}".F(!orderManager.LobbyInfo.GlobalSettings.AllyBuildRadius))); } var fragileAlliance = optionsBin.GetOrNull <CheckboxWidget>("FRAGILEALLIANCES_CHECKBOX"); if (fragileAlliance != null) { fragileAlliance.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.FragileAlliances; fragileAlliance.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.FragileAlliances.HasValue || configurationDisabled(); fragileAlliance.OnClick = () => orderManager.IssueOrder(Order.Command( "fragilealliance {0}".F(!orderManager.LobbyInfo.GlobalSettings.FragileAlliances))); } var difficulty = optionsBin.GetOrNull <DropDownButtonWidget>("DIFFICULTY_DROPDOWNBUTTON"); if (difficulty != null) { difficulty.IsVisible = () => Map.Status == MapStatus.Available && Map.Map.Options.Difficulties.Any(); difficulty.IsDisabled = () => Map.Status != MapStatus.Available || configurationDisabled(); difficulty.GetText = () => orderManager.LobbyInfo.GlobalSettings.Difficulty; difficulty.OnMouseDown = _ => { var options = Map.Map.Options.Difficulties.Select(d => new DropDownOption { Title = d, IsSelected = () => orderManager.LobbyInfo.GlobalSettings.Difficulty == d, OnClick = () => orderManager.IssueOrder(Order.Command("difficulty {0}".F(d))) }); Func <DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) => { var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick); item.Get <LabelWidget>("LABEL").GetText = () => option.Title; return(item); }; difficulty.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem); }; optionsBin.Get <LabelWidget>("DIFFICULTY_DESC").IsVisible = difficulty.IsVisible; } var startingUnits = optionsBin.GetOrNull <DropDownButtonWidget>("STARTINGUNITS_DROPDOWNBUTTON"); if (startingUnits != null) { var startUnitsInfo = modRules.Actors["world"].Traits.WithInterface <MPStartUnitsInfo>(); var classes = startUnitsInfo.Select(a => a.Class).Distinct(); Func <string, string> className = c => { var selectedClass = startUnitsInfo.Where(s => s.Class == c).Select(u => u.ClassName).FirstOrDefault(); return(selectedClass != null ? selectedClass : c); }; startingUnits.IsDisabled = () => Map.Status != MapStatus.Available || !Map.Map.Options.ConfigurableStartingUnits || configurationDisabled(); startingUnits.GetText = () => Map.Status != MapStatus.Available || !Map.Map.Options.ConfigurableStartingUnits ? "Not Available" : className(orderManager.LobbyInfo.GlobalSettings.StartingUnitsClass); startingUnits.OnMouseDown = _ => { var options = classes.Select(c => new DropDownOption { Title = className(c), IsSelected = () => orderManager.LobbyInfo.GlobalSettings.StartingUnitsClass == c, OnClick = () => orderManager.IssueOrder(Order.Command("startingunits {0}".F(c))) }); Func <DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) => { var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick); item.Get <LabelWidget>("LABEL").GetText = () => option.Title; return(item); }; startingUnits.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem); }; optionsBin.Get <LabelWidget>("STARTINGUNITS_DESC").IsVisible = startingUnits.IsVisible; } var startingCash = optionsBin.GetOrNull <DropDownButtonWidget>("STARTINGCASH_DROPDOWNBUTTON"); if (startingCash != null) { startingCash.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.StartingCash.HasValue || configurationDisabled(); startingCash.GetText = () => Map.Status != MapStatus.Available || Map.Map.Options.StartingCash.HasValue ? "Not Available" : "${0}".F(orderManager.LobbyInfo.GlobalSettings.StartingCash); startingCash.OnMouseDown = _ => { var options = modRules.Actors["player"].Traits.Get <PlayerResourcesInfo>().SelectableCash.Select(c => new DropDownOption { Title = "${0}".F(c), IsSelected = () => orderManager.LobbyInfo.GlobalSettings.StartingCash == c, OnClick = () => orderManager.IssueOrder(Order.Command("startingcash {0}".F(c))) }); Func <DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) => { var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick); item.Get <LabelWidget>("LABEL").GetText = () => option.Title; return(item); }; startingCash.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem); }; } var techLevel = optionsBin.GetOrNull <DropDownButtonWidget>("TECHLEVEL_DROPDOWNBUTTON"); if (techLevel != null) { var techTraits = modRules.Actors["player"].Traits.WithInterface <ProvidesTechPrerequisiteInfo>().ToArray(); techLevel.IsVisible = () => techTraits.Length > 0; optionsBin.GetOrNull <LabelWidget>("TECHLEVEL_DESC").IsVisible = () => techTraits.Length > 0; techLevel.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.TechLevel != null || configurationDisabled() || techTraits.Length <= 1; techLevel.GetText = () => Map.Status != MapStatus.Available || Map.Map.Options.TechLevel != null ? "Not Available" : "{0}".F(orderManager.LobbyInfo.GlobalSettings.TechLevel); techLevel.OnMouseDown = _ => { var options = techTraits.Select(c => new DropDownOption { Title = "{0}".F(c.Name), IsSelected = () => orderManager.LobbyInfo.GlobalSettings.TechLevel == c.Name, OnClick = () => orderManager.IssueOrder(Order.Command("techlevel {0}".F(c.Name))) }); Func <DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) => { var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick); item.Get <LabelWidget>("LABEL").GetText = () => option.Title; return(item); }; techLevel.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem); }; } var enableShroud = optionsBin.GetOrNull <CheckboxWidget>("SHROUD_CHECKBOX"); if (enableShroud != null) { enableShroud.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.Shroud; enableShroud.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.Shroud.HasValue || configurationDisabled(); enableShroud.OnClick = () => orderManager.IssueOrder(Order.Command( "shroud {0}".F(!orderManager.LobbyInfo.GlobalSettings.Shroud))); } var enableFog = optionsBin.GetOrNull <CheckboxWidget>("FOG_CHECKBOX"); if (enableFog != null) { enableFog.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.Fog; enableFog.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.Fog.HasValue || configurationDisabled(); enableFog.OnClick = () => orderManager.IssueOrder(Order.Command( "fog {0}".F(!orderManager.LobbyInfo.GlobalSettings.Fog))); } var disconnectButton = lobby.Get <ButtonWidget>("DISCONNECT_BUTTON"); disconnectButton.OnClick = () => { CloseWindow(); onExit(); }; if (skirmishMode) { disconnectButton.Text = "Cancel"; } var teamChat = false; var chatLabel = lobby.Get <LabelWidget>("LABEL_CHATTYPE"); var chatTextField = lobby.Get <TextFieldWidget>("CHAT_TEXTFIELD"); chatTextField.TakeKeyboardFocus(); chatTextField.OnEnterKey = () => { if (chatTextField.Text.Length == 0) { return(true); } // Always scroll to bottom when we've typed something chatPanel.ScrollToBottom(); orderManager.IssueOrder(Order.Chat(teamChat, chatTextField.Text)); chatTextField.Text = ""; return(true); }; chatTextField.OnAltKey = () => { teamChat ^= true; chatLabel.Text = teamChat ? "Team:" : "Chat:"; return(true); }; chatTextField.OnTabKey = () => { chatTextField.Text = tabCompletion.Complete(chatTextField.Text); chatTextField.CursorPosition = chatTextField.Text.Length; return(true); }; chatPanel = lobby.Get <ScrollPanelWidget>("CHAT_DISPLAY"); chatTemplate = chatPanel.Get("CHAT_TEMPLATE"); chatPanel.RemoveChildren(); var musicButton = lobby.GetOrNull <ButtonWidget>("MUSIC_BUTTON"); if (musicButton != null) { musicButton.OnClick = () => Ui.OpenWindow("MUSIC_PANEL", new WidgetArgs { { "onExit", DoNothing }, { "world", orderManager.world } }); } var settingsButton = lobby.GetOrNull <ButtonWidget>("SETTINGS_BUTTON"); if (settingsButton != null) { settingsButton.OnClick = () => Ui.OpenWindow("SETTINGS_PANEL", new WidgetArgs { { "onExit", DoNothing }, { "worldRenderer", worldRenderer } }); } // Add a bot on the first lobbyinfo update if (skirmishMode) { Game.LobbyInfoChanged += WidgetUtils.Once(() => { var slot = orderManager.LobbyInfo.FirstEmptyBotSlot(); var bot = modRules.Actors["player"].Traits.WithInterface <IBotInfo>().Select(t => t.Name).FirstOrDefault(); var botController = orderManager.LobbyInfo.Clients.FirstOrDefault(c => c.IsAdmin); if (slot != null && bot != null) { orderManager.IssueOrder(Order.Command("slot_bot {0} {1} {2}".F(slot, botController.Index, bot))); } }); } }
void SetupFilters() { // Game type { var ddb = panel.GetOrNull <DropDownButtonWidget>("FLT_GAMETYPE_DROPDOWNBUTTON"); if (ddb != null) { // Using list to maintain the order var options = new List <Pair <GameType, string> > { Pair.New(GameType.Any, ddb.GetText()), Pair.New(GameType.Singleplayer, "Singleplayer"), Pair.New(GameType.Multiplayer, "Multiplayer") }; var lookup = options.ToDictionary(kvp => kvp.First, kvp => kvp.Second); ddb.GetText = () => lookup[filter.Type]; ddb.OnMouseDown = _ => { Func <Pair <GameType, string>, ScrollItemWidget, ScrollItemWidget> setupItem = (option, tpl) => { var item = ScrollItemWidget.Setup( tpl, () => filter.Type == option.First, () => { filter.Type = option.First; ApplyFilter(); }); item.Get <LabelWidget>("LABEL").GetText = () => option.Second; return(item); }; ddb.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 330, options, setupItem); }; } } // Date type { var ddb = panel.GetOrNull <DropDownButtonWidget>("FLT_DATE_DROPDOWNBUTTON"); if (ddb != null) { // Using list to maintain the order var options = new List <Pair <DateType, string> > { Pair.New(DateType.Any, ddb.GetText()), Pair.New(DateType.Today, "Today"), Pair.New(DateType.LastWeek, "Last 7 days"), Pair.New(DateType.LastFortnight, "Last 14 days"), Pair.New(DateType.LastMonth, "Last 30 days") }; var lookup = options.ToDictionary(kvp => kvp.First, kvp => kvp.Second); ddb.GetText = () => lookup[filter.Date]; ddb.OnMouseDown = _ => { Func <Pair <DateType, string>, ScrollItemWidget, ScrollItemWidget> setupItem = (option, tpl) => { var item = ScrollItemWidget.Setup( tpl, () => filter.Date == option.First, () => { filter.Date = option.First; ApplyFilter(); }); item.Get <LabelWidget>("LABEL").GetText = () => option.Second; return(item); }; ddb.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 330, options, setupItem); }; } } // Duration { var ddb = panel.GetOrNull <DropDownButtonWidget>("FLT_DURATION_DROPDOWNBUTTON"); if (ddb != null) { // Using list to maintain the order var options = new List <Pair <DurationType, string> > { Pair.New(DurationType.Any, ddb.GetText()), Pair.New(DurationType.VeryShort, "Under 5 min"), Pair.New(DurationType.Short, "Short (10 min)"), Pair.New(DurationType.Medium, "Medium (30 min)"), Pair.New(DurationType.Long, "Long (60+ min)") }; var lookup = options.ToDictionary(kvp => kvp.First, kvp => kvp.Second); ddb.GetText = () => lookup[filter.Duration]; ddb.OnMouseDown = _ => { Func <Pair <DurationType, string>, ScrollItemWidget, ScrollItemWidget> setupItem = (option, tpl) => { var item = ScrollItemWidget.Setup( tpl, () => filter.Duration == option.First, () => { filter.Duration = option.First; ApplyFilter(); }); item.Get <LabelWidget>("LABEL").GetText = () => option.Second; return(item); }; ddb.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 330, options, setupItem); }; } } // Outcome (depends on Player) { var ddb = panel.GetOrNull <DropDownButtonWidget>("FLT_OUTCOME_DROPDOWNBUTTON"); if (ddb != null) { ddb.IsDisabled = () => string.IsNullOrEmpty(filter.PlayerName); // Using list to maintain the order var options = new List <Pair <WinState, string> > { Pair.New(WinState.Undefined, ddb.GetText()), Pair.New(WinState.Lost, "Defeat"), Pair.New(WinState.Won, "Victory") }; var lookup = options.ToDictionary(kvp => kvp.First, kvp => kvp.Second); ddb.GetText = () => lookup[filter.Outcome]; ddb.OnMouseDown = _ => { Func <Pair <WinState, string>, ScrollItemWidget, ScrollItemWidget> setupItem = (option, tpl) => { var item = ScrollItemWidget.Setup( tpl, () => filter.Outcome == option.First, () => { filter.Outcome = option.First; ApplyFilter(); }); item.Get <LabelWidget>("LABEL").GetText = () => option.Second; return(item); }; ddb.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 330, options, setupItem); }; } } // Reset button { var button = panel.Get <ButtonWidget>("FLT_RESET_BUTTON"); button.IsDisabled = () => filter.IsEmpty; button.OnClick = () => { filter = new Filter(); ApplyFilter(); }; } }
public override void Tick() { if (actorIDStatus != nextActorIDStatus) { if ((actorIDStatus & nextActorIDStatus) == 0) { var offset = actorIDErrorLabel.Bounds.Height; if (nextActorIDStatus == ActorIDStatus.Normal) { offset *= -1; } actorEditPanel.Bounds.Height += offset; initContainer.Bounds.Y += offset; buttonContainer.Bounds.Y += offset; } actorIDStatus = nextActorIDStatus; } var actor = editor.DefaultBrush.SelectedActor; if (actor != null) { var origin = worldRenderer.Viewport.WorldToViewPx(new int2(actor.Bounds.Right, actor.Bounds.Top)); // If we scrolled, hide the edit box for a moment if (lastScrollPosition.X != origin.X || lastScrollPosition.Y != origin.Y) { lastScrollTime = Game.RunTime; lastScrollPosition = origin; } // If we changed actor, move widgets if (CurrentActor != actor) { lastScrollTime = 0; // Ensure visible CurrentActor = actor; initialActorID = actorIDField.Text = actor.ID; var font = Game.Renderer.Fonts[typeLabel.Font]; var truncatedType = WidgetUtils.TruncateText(actor.DescriptiveName, typeLabel.Bounds.Width, font); typeLabel.Text = truncatedType; actorIDField.CursorPosition = actor.ID.Length; nextActorIDStatus = ActorIDStatus.Normal; // Remove old widgets var oldInitHeight = initContainer.Bounds.Height; initContainer.Bounds.Height = 0; initContainer.RemoveChildren(); // Add owner dropdown var ownerContainer = dropdownOptionTemplate.Clone(); ownerContainer.Get <LabelWidget>("LABEL").GetText = () => "Owner"; var ownerDropdown = ownerContainer.Get <DropDownButtonWidget>("OPTION"); var selectedOwner = actor.Owner; Func <PlayerReference, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) => { var item = ScrollItemWidget.Setup(template, () => selectedOwner == option, () => { selectedOwner = option; CurrentActor.Owner = selectedOwner; CurrentActor.ReplaceInit(new OwnerInit(selectedOwner.Name)); }); item.Get <LabelWidget>("LABEL").GetText = () => option.Name; item.GetColor = () => option.Color; return(item); }; ownerDropdown.GetText = () => selectedOwner.Name; ownerDropdown.GetColor = () => selectedOwner.Color; ownerDropdown.OnClick = () => { var owners = editorActorLayer.Players.Players.Values.OrderBy(p => p.Name); ownerDropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 270, owners, setupItem); }; initContainer.Bounds.Height += ownerContainer.Bounds.Height; initContainer.AddChild(ownerContainer); // Add new children for inits var options = actor.Info.TraitInfos <IEditorActorOptions>() .SelectMany(t => t.ActorOptions(actor.Info, worldRenderer.World)) .OrderBy(o => o.DisplayOrder); foreach (var o in options) { if (o is EditorActorSlider) { var so = (EditorActorSlider)o; var sliderContainer = sliderOptionTemplate.Clone(); sliderContainer.Bounds.Y = initContainer.Bounds.Height; initContainer.Bounds.Height += sliderContainer.Bounds.Height; sliderContainer.Get <LabelWidget>("LABEL").GetText = () => so.Name; var slider = sliderContainer.Get <SliderWidget>("OPTION"); slider.MinimumValue = so.MinValue; slider.MaximumValue = so.MaxValue; slider.Ticks = so.Ticks; slider.GetValue = () => so.GetValue(actor); slider.OnChange += value => so.OnChange(actor, value); initContainer.AddChild(sliderContainer); } else if (o is EditorActorDropdown) { var ddo = (EditorActorDropdown)o; var dropdownContainer = dropdownOptionTemplate.Clone(); dropdownContainer.Bounds.Y = initContainer.Bounds.Height; initContainer.Bounds.Height += dropdownContainer.Bounds.Height; dropdownContainer.Get <LabelWidget>("LABEL").GetText = () => ddo.Name; var dropdown = dropdownContainer.Get <DropDownButtonWidget>("OPTION"); Func <KeyValuePair <string, string>, ScrollItemWidget, ScrollItemWidget> dropdownSetup = (option, template) => { var item = ScrollItemWidget.Setup(template, () => ddo.GetValue(actor) == option.Key, () => ddo.OnChange(actor, option.Key)); item.Get <LabelWidget>("LABEL").GetText = () => option.Value; return(item); }; dropdown.GetText = () => ddo.Labels[ddo.GetValue(actor)]; dropdown.OnClick = () => dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 270, ddo.Labels, dropdownSetup); initContainer.AddChild(dropdownContainer); } } actorEditPanel.Bounds.Height += initContainer.Bounds.Height - oldInitHeight; buttonContainer.Bounds.Y += initContainer.Bounds.Height - oldInitHeight; } // Set the edit panel to the right of the selection border. actorEditPanel.Bounds.X = origin.X + editPanelPadding; actorEditPanel.Bounds.Y = origin.Y; } else { // Selected actor is null, hide the border and edit panel. actorIDField.YieldKeyboardFocus(); CurrentActor = null; } }
void SetupReplayDependentFilters() { // Map { var ddb = panel.GetOrNull <DropDownButtonWidget>("FLT_MAPNAME_DROPDOWNBUTTON"); if (ddb != null) { var options = replays.Select(r => r.GameInfo.MapTitle).Distinct(StringComparer.OrdinalIgnoreCase).ToList(); options.Sort(StringComparer.OrdinalIgnoreCase); options.Insert(0, null); // no filter var anyText = ddb.GetText(); ddb.GetText = () => string.IsNullOrEmpty(filter.MapName) ? anyText : filter.MapName; ddb.OnMouseDown = _ => { Func <string, ScrollItemWidget, ScrollItemWidget> setupItem = (option, tpl) => { var item = ScrollItemWidget.Setup( tpl, () => string.Compare(filter.MapName, option, true) == 0, () => { filter.MapName = option; ApplyFilter(); }); item.Get <LabelWidget>("LABEL").GetText = () => option ?? anyText; return(item); }; ddb.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 330, options, setupItem); }; } } // Players { var ddb = panel.GetOrNull <DropDownButtonWidget>("FLT_PLAYER_DROPDOWNBUTTON"); if (ddb != null) { var options = replays.SelectMany(r => r.GameInfo.Players.Select(p => p.Name)).Distinct(StringComparer.OrdinalIgnoreCase).ToList(); options.Sort(StringComparer.OrdinalIgnoreCase); options.Insert(0, null); // no filter var anyText = ddb.GetText(); ddb.GetText = () => string.IsNullOrEmpty(filter.PlayerName) ? anyText : filter.PlayerName; ddb.OnMouseDown = _ => { Func <string, ScrollItemWidget, ScrollItemWidget> setupItem = (option, tpl) => { var item = ScrollItemWidget.Setup( tpl, () => string.Compare(filter.PlayerName, option, true) == 0, () => { filter.PlayerName = option; ApplyFilter(); }); item.Get <LabelWidget>("LABEL").GetText = () => option ?? anyText; return(item); }; ddb.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 330, options, setupItem); }; } } // Faction (depends on Player) { var ddb = panel.GetOrNull <DropDownButtonWidget>("FLT_FACTION_DROPDOWNBUTTON"); if (ddb != null) { ddb.IsDisabled = () => string.IsNullOrEmpty(filter.PlayerName); var options = replays .SelectMany(r => r.GameInfo.Players.Select(p => p.FactionName).Where(n => !string.IsNullOrEmpty(n))) .Distinct(StringComparer.OrdinalIgnoreCase).ToList(); options.Sort(StringComparer.OrdinalIgnoreCase); options.Insert(0, null); // no filter var anyText = ddb.GetText(); ddb.GetText = () => string.IsNullOrEmpty(filter.Faction) ? anyText : filter.Faction; ddb.OnMouseDown = _ => { Func <string, ScrollItemWidget, ScrollItemWidget> setupItem = (option, tpl) => { var item = ScrollItemWidget.Setup( tpl, () => string.Compare(filter.Faction, option, true) == 0, () => { filter.Faction = option; ApplyFilter(); }); item.Get <LabelWidget>("LABEL").GetText = () => option ?? anyText; return(item); }; ddb.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 330, options, setupItem); }; } } }
public NewMissionBrowserLogic(Widget widget, ModData modData, World world, Action onStart, Action onExit) { this.modData = modData; this.onStart = onStart; Game.BeforeGameStart += OnGameStart; missionList = widget.Get <ScrollPanelWidget>("MISSION_LIST"); headerTemplate = widget.Get <ScrollItemWidget>("HEADER"); template = widget.Get <ScrollItemWidget>("TEMPLATE"); var title = widget.GetOrNull <LabelWidget>("MISSIONBROWSER_TITLE"); if (title != null) { title.GetText = () => playingVideo != PlayingVideo.None ? selectedMap.Title : title.Text; } widget.Get("MISSION_INFO").IsVisible = () => selectedMap != null; var previewWidget = widget.Get <MapPreviewWidget>("MISSION_PREVIEW"); previewWidget.Preview = () => selectedMap; previewWidget.IsVisible = () => playingVideo == PlayingVideo.None; videoPlayer = widget.Get <BinkPlayerWidget>("MISSION_VIDEO"); widget.Get("MISSION_BIN").IsVisible = () => playingVideo != PlayingVideo.None; fullscreenVideoPlayer = Ui.LoadWidget <BackgroundWidget>("FULLSCREEN_PLAYER", Ui.Root, new WidgetArgs { { "world", world } }); descriptionPanel = widget.Get <ScrollPanelWidget>("MISSION_DESCRIPTION_PANEL"); description = descriptionPanel.Get <LabelWidget>("MISSION_DESCRIPTION"); descriptionFont = Game.Renderer.Fonts[description.Font]; difficultyButton = widget.Get <DropDownButtonWidget>("DIFFICULTY_DROPDOWNBUTTON"); gameSpeedButton = widget.GetOrNull <DropDownButtonWidget>("GAMESPEED_DROPDOWNBUTTON"); //startBriefingVideoButton = widget.Get<ButtonWidget>("START_BRIEFING_VIDEO_BUTTON"); stopBriefingVideoButton = widget.Get <ButtonWidget>("STOP_BRIEFING_VIDEO_BUTTON"); stopBriefingVideoButton.IsVisible = () => playingVideo == PlayingVideo.Briefing; stopBriefingVideoButton.OnClick = () => StopVideo(videoPlayer); startInfoVideoButton = widget.Get <ButtonWidget>("START_INFO_VIDEO_BUTTON"); stopInfoVideoButton = widget.Get <ButtonWidget>("STOP_INFO_VIDEO_BUTTON"); stopInfoVideoButton.IsVisible = () => playingVideo == PlayingVideo.Info; stopInfoVideoButton.OnClick = () => StopVideo(videoPlayer); var allPreviews = new List <MapPreview>(); missionList.RemoveChildren(); // Add a group for each campaign if (modData.Manifest.Missions.Any()) { var yaml = MiniYaml.Merge(modData.Manifest.Missions.Select( m => MiniYaml.FromStream(modData.DefaultFileSystem.Open(m), m))); foreach (var kv in yaml) { var missionMapPaths = kv.Value.Nodes.Select(n => n.Key).ToList(); var previews = modData.MapCache .Where(p => p.Class == MapClassification.System && p.Status == MapStatus.Available) .Select(p => new { Preview = p, Index = missionMapPaths.IndexOf(Path.GetFileName(p.Package.Name)) }) .Where(x => x.Index != -1) .OrderBy(x => x.Index) .Select(x => x.Preview); if (previews.Any()) { CreateMissionGroup(kv.Key, previews); allPreviews.AddRange(previews); } } } // Add an additional group for loose missions var loosePreviews = modData.MapCache .Where(p => p.Status == MapStatus.Available && p.Visibility.HasFlag(MapVisibility.MissionSelector) && !allPreviews.Any(a => a.Uid == p.Uid)); if (loosePreviews.Any()) { CreateMissionGroup("Missions", loosePreviews); allPreviews.AddRange(loosePreviews); } if (allPreviews.Any()) { SelectMap(allPreviews.First()); } // Preload map preview and rules to reduce jank new Thread(() => { foreach (var p in allPreviews) { p.GetMinimap(); p.PreloadRules(); } }).Start(); var startButton = widget.Get <ButtonWidget>("STARTGAME_BUTTON"); startButton.OnClick = StartMissionClicked; startButton.IsDisabled = () => selectedMap == null || selectedMap.InvalidCustomRules; widget.Get <ButtonWidget>("BACK_BUTTON").OnClick = () => { StopVideo(videoPlayer); Game.Disconnect(); Ui.CloseWindow(); onExit(); }; }
public NewMapLogic(Action onExit, Action <string> onSelect, Widget widget, World world, ModData modData) { panel = widget; panel.Get <ButtonWidget>("CANCEL_BUTTON").OnClick = () => { Ui.CloseWindow(); onExit(); }; var tilesetDropDown = panel.Get <DropDownButtonWidget>("TILESET"); var tilesets = modData.DefaultTerrainInfo.Keys; Func <string, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) => { var item = ScrollItemWidget.Setup(template, () => tilesetDropDown.Text == option, () => { tilesetDropDown.Text = option; }); item.Get <LabelWidget>("LABEL").GetText = () => option; return(item); }; tilesetDropDown.Text = tilesets.First(); tilesetDropDown.OnClick = () => tilesetDropDown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 210, tilesets, setupItem); var widthTextField = panel.Get <TextFieldWidget>("WIDTH"); var heightTextField = panel.Get <TextFieldWidget>("HEIGHT"); panel.Get <ButtonWidget>("CREATE_BUTTON").OnClick = () => { int.TryParse(widthTextField.Text, out var width); int.TryParse(heightTextField.Text, out var height); // Require at least a 2x2 playable area so that the // ground is visible through the edge shroud width = Math.Max(2, width); height = Math.Max(2, height); var maxTerrainHeight = world.Map.Grid.MaximumTerrainHeight; var tileset = modData.DefaultTerrainInfo[tilesetDropDown.Text]; var map = new Map(Game.ModData, tileset, width + 2, height + maxTerrainHeight + 2); var tl = new PPos(1, 1 + maxTerrainHeight); var br = new PPos(width, height + maxTerrainHeight); map.SetBounds(tl, br); map.PlayerDefinitions = new MapPlayers(map.Rules, 0).ToMiniYaml(); if (map.Rules.TerrainInfo is ITerrainInfoNotifyMapCreated notifyMapCreated) { notifyMapCreated.MapCreated(map); } Action <string> afterSave = uid => { Game.LoadEditor(uid); Ui.CloseWindow(); onSelect(uid); }; Ui.OpenWindow("SAVE_MAP_PANEL", new WidgetArgs() { { "onSave", afterSave }, { "onExit", () => { Ui.CloseWindow(); onExit(); } }, { "map", map }, { "playerDefinitions", map.PlayerDefinitions }, { "actorDefinitions", map.ActorDefinitions } }); }; }
public ObserverStatsLogic(World world, ModData modData, WorldRenderer worldRenderer, Widget widget, Action onExit, ObserverStatsPanel activePanel, Dictionary <string, MiniYaml> logicArgs) { this.world = world; this.worldRenderer = worldRenderer; MiniYaml yaml; string[] keyNames = Enum.GetNames(typeof(ObserverStatsPanel)); var statsHotkeys = new HotkeyReference[keyNames.Length]; for (var i = 0; i < keyNames.Length; i++) { statsHotkeys[i] = logicArgs.TryGetValue("Statistics" + keyNames[i] + "Key", out yaml) ? modData.Hotkeys[yaml.Value] : new HotkeyReference(); } players = world.Players.Where(p => !p.NonCombatant); basicStatsHeaders = widget.Get <ContainerWidget>("BASIC_STATS_HEADERS"); economyStatsHeaders = widget.Get <ContainerWidget>("ECONOMY_STATS_HEADERS"); productionStatsHeaders = widget.Get <ContainerWidget>("PRODUCTION_STATS_HEADERS"); combatStatsHeaders = widget.Get <ContainerWidget>("COMBAT_STATS_HEADERS"); earnedThisMinuteGraphHeaders = widget.Get <ContainerWidget>("EARNED_THIS_MIN_GRAPH_HEADERS"); playerStatsPanel = widget.Get <ScrollPanelWidget>("PLAYER_STATS_PANEL"); playerStatsPanel.Layout = new GridLayout(playerStatsPanel); basicPlayerTemplate = playerStatsPanel.Get <ScrollItemWidget>("BASIC_PLAYER_TEMPLATE"); economyPlayerTemplate = playerStatsPanel.Get <ScrollItemWidget>("ECONOMY_PLAYER_TEMPLATE"); productionPlayerTemplate = playerStatsPanel.Get <ScrollItemWidget>("PRODUCTION_PLAYER_TEMPLATE"); combatPlayerTemplate = playerStatsPanel.Get <ScrollItemWidget>("COMBAT_PLAYER_TEMPLATE"); earnedThisMinuteGraphTemplate = playerStatsPanel.Get <ContainerWidget>("EARNED_THIS_MIN_GRAPH_TEMPLATE"); teamTemplate = playerStatsPanel.Get <ScrollItemWidget>("TEAM_TEMPLATE"); var statsDropDown = widget.Get <DropDownButtonWidget>("STATS_DROPDOWN"); Func <string, ContainerWidget, Action, StatsDropDownOption> createStatsOption = (title, headers, a) => { return(new StatsDropDownOption { Title = title, IsSelected = () => headers.Visible, OnClick = () => { ClearStats(); statsDropDown.GetText = () => title; a(); } }); }; var statsDropDownOptions = new StatsDropDownOption[] { createStatsOption("Basic", basicStatsHeaders, () => DisplayStats(BasicStats)), createStatsOption("Economy", economyStatsHeaders, () => DisplayStats(EconomyStats)), createStatsOption("Production", productionStatsHeaders, () => DisplayStats(ProductionStats)), createStatsOption("Combat", combatStatsHeaders, () => DisplayStats(CombatStats)), createStatsOption("Earnings (graph)", earnedThisMinuteGraphHeaders, () => EarnedThisMinuteGraph()) }; Func <StatsDropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) => { var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick); item.Get <LabelWidget>("LABEL").GetText = () => option.Title; return(item); }; statsDropDown.OnMouseDown = _ => statsDropDown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 150, statsDropDownOptions, setupItem); statsDropDownOptions[(int)activePanel].OnClick(); var close = widget.GetOrNull <ButtonWidget>("CLOSE"); if (close != null) { close.OnClick = () => { Ui.CloseWindow(); Ui.Root.RemoveChild(widget); onExit(); } } ; var keyListener = statsDropDown.Get <LogicKeyListenerWidget>("STATS_DROPDOWN_KEYHANDLER"); keyListener.AddHandler(e => { if (e.Event == KeyInputEvent.Down && !e.IsRepeat) { for (var i = 0; i < statsHotkeys.Length; i++) { if (statsHotkeys[i].IsActivatedBy(e)) { statsDropDownOptions[i].OnClick(); return(true); } } } return(false); }); } void ClearStats() { playerStatsPanel.Children.Clear(); basicStatsHeaders.Visible = false; economyStatsHeaders.Visible = false; productionStatsHeaders.Visible = false; combatStatsHeaders.Visible = false; earnedThisMinuteGraphHeaders.Visible = false; } void EarnedThisMinuteGraph() { earnedThisMinuteGraphHeaders.Visible = true; var template = earnedThisMinuteGraphTemplate.Clone(); var graph = template.Get <LineGraphWidget>("EARNED_THIS_MIN_GRAPH"); graph.GetSeries = () => players.Select(p => new LineGraphSeries( p.PlayerName, p.Color.RGB, (p.PlayerActor.TraitOrDefault <PlayerStatistics>() ?? new PlayerStatistics(p.PlayerActor)).EarnedSamples.Select(s => (float)s))); playerStatsPanel.AddChild(template); playerStatsPanel.ScrollToTop(); } void DisplayStats(Func <Player, ScrollItemWidget> createItem) { var teams = players.GroupBy(p => (world.LobbyInfo.ClientWithIndex(p.ClientIndex) ?? new Session.Client()).Team).OrderBy(g => g.Key); foreach (var t in teams) { var team = t; var tt = ScrollItemWidget.Setup(teamTemplate, () => false, () => { }); tt.IgnoreMouseOver = true; tt.Get <LabelWidget>("TEAM").GetText = () => team.Key == 0 ? "No Team" : "Team " + team.Key; playerStatsPanel.AddChild(tt); foreach (var p in team) { var player = p; playerStatsPanel.AddChild(createItem(player)); } } } ScrollItemWidget CombatStats(Player player) { combatStatsHeaders.Visible = true; var template = SetupPlayerScrollItemWidget(combatPlayerTemplate, player); LobbyUtils.AddPlayerFlagAndName(template, player); var stats = player.PlayerActor.TraitOrDefault <PlayerStatistics>(); if (stats == null) { return(template); } template.Get <LabelWidget>("ASSETS_DESTROYED").GetText = () => "$" + stats.KillsCost; template.Get <LabelWidget>("ASSETS_LOST").GetText = () => "$" + stats.DeathsCost; template.Get <LabelWidget>("UNITS_KILLED").GetText = () => stats.UnitsKilled.ToString(); template.Get <LabelWidget>("UNITS_DEAD").GetText = () => stats.UnitsDead.ToString(); template.Get <LabelWidget>("BUILDINGS_KILLED").GetText = () => stats.BuildingsKilled.ToString(); template.Get <LabelWidget>("BUILDINGS_DEAD").GetText = () => stats.BuildingsDead.ToString(); return(template); } ScrollItemWidget ProductionStats(Player player) { productionStatsHeaders.Visible = true; var template = SetupPlayerScrollItemWidget(productionPlayerTemplate, player); LobbyUtils.AddPlayerFlagAndName(template, player); template.Get <ObserverProductionIconsWidget>("PRODUCTION_ICONS").GetPlayer = () => player; template.Get <ObserverSupportPowerIconsWidget>("SUPPORT_POWER_ICONS").GetPlayer = () => player; template.IgnoreChildMouseOver = false; return(template); } ScrollItemWidget EconomyStats(Player player) { economyStatsHeaders.Visible = true; var template = SetupPlayerScrollItemWidget(economyPlayerTemplate, player); LobbyUtils.AddPlayerFlagAndName(template, player); var res = player.PlayerActor.Trait <PlayerResources>(); var stats = player.PlayerActor.TraitOrDefault <PlayerStatistics>(); if (stats == null) { return(template); } template.Get <LabelWidget>("CASH").GetText = () => "$" + (res.Cash + res.Resources); template.Get <LabelWidget>("EARNED_MIN").GetText = () => AverageEarnedPerMinute(res.Earned); template.Get <LabelWidget>("EARNED_THIS_MIN").GetText = () => "$" + stats.EarnedThisMinute; template.Get <LabelWidget>("EARNED").GetText = () => "$" + res.Earned; template.Get <LabelWidget>("SPENT").GetText = () => "$" + res.Spent; var assets = template.Get <LabelWidget>("ASSETS"); assets.GetText = () => "$" + world.ActorsHavingTrait <Valued>() .Where(a => a.Owner == player && !a.IsDead) .Sum(a => a.Info.TraitInfos <ValuedInfo>().First().Cost); var harvesters = template.Get <LabelWidget>("HARVESTERS"); harvesters.GetText = () => world.ActorsHavingTrait <Harvester>().Count(a => a.Owner == player && !a.IsDead).ToString(); return(template); } ScrollItemWidget BasicStats(Player player) { basicStatsHeaders.Visible = true; var template = SetupPlayerScrollItemWidget(basicPlayerTemplate, player); LobbyUtils.AddPlayerFlagAndName(template, player); var res = player.PlayerActor.Trait <PlayerResources>(); template.Get <LabelWidget>("CASH").GetText = () => "$" + (res.Cash + res.Resources); template.Get <LabelWidget>("EARNED_MIN").GetText = () => AverageEarnedPerMinute(res.Earned); var powerRes = player.PlayerActor.Trait <PowerManager>(); var power = template.Get <LabelWidget>("POWER"); power.GetText = () => powerRes.PowerDrained + "/" + powerRes.PowerProvided; power.GetColor = () => GetPowerColor(powerRes.PowerState); var stats = player.PlayerActor.TraitOrDefault <PlayerStatistics>(); if (stats == null) { return(template); } template.Get <LabelWidget>("KILLS").GetText = () => (stats.UnitsKilled + stats.BuildingsKilled).ToString(); template.Get <LabelWidget>("DEATHS").GetText = () => (stats.UnitsDead + stats.BuildingsDead).ToString(); template.Get <LabelWidget>("ASSETS_DESTROYED").GetText = () => "$" + stats.KillsCost; template.Get <LabelWidget>("ASSETS_LOST").GetText = () => "$" + stats.DeathsCost; template.Get <LabelWidget>("EXPERIENCE").GetText = () => stats.Experience.ToString(); template.Get <LabelWidget>("ACTIONS_MIN").GetText = () => AverageOrdersPerMinute(stats.OrderCount); return(template); } ScrollItemWidget SetupPlayerScrollItemWidget(ScrollItemWidget template, Player player) { return(ScrollItemWidget.Setup(template, () => false, () => { var playerBase = world.ActorsHavingTrait <BaseBuilding>().FirstOrDefault(a => !a.IsDead && a.Owner == player); if (playerBase != null) { worldRenderer.Viewport.Center(playerBase.CenterPosition); } })); }
protected override void InitializePreviews() { Panel.RemoveChildren(); if (!SelectedCategories.Any()) { return; } foreach (var a in allActors) { if (!SelectedCategories.Overlaps(a.Categories)) { continue; } if (!string.IsNullOrEmpty(searchFilter) && !a.SearchTerms.Any(s => s.IndexOf(searchFilter, StringComparison.OrdinalIgnoreCase) >= 0)) { continue; } var actor = a.Actor; var td = new TypeDictionary(); td.Add(new OwnerInit(selectedOwner.Name)); td.Add(new FactionInit(selectedOwner.Faction)); foreach (var api in actor.TraitInfos <IActorPreviewInitInfo>()) { foreach (var o in api.ActorPreviewInits(actor, ActorPreviewType.MapEditorSidebar)) { td.Add(o); } } try { var item = ScrollItemWidget.Setup(ItemTemplate, () => editorCursor.Type == EditorCursorType.Actor && editorCursor.Actor.Info == actor, () => Editor.SetBrush(new EditorActorBrush(Editor, actor, selectedOwner, WorldRenderer))); var preview = item.Get <ActorPreviewWidget>("ACTOR_PREVIEW"); preview.SetPreview(actor, td); // Scale templates to fit within the panel var scale = 1f; if (scale * preview.IdealPreviewSize.X > ItemTemplate.Bounds.Width) { scale = (ItemTemplate.Bounds.Width - Panel.ItemSpacing) / (float)preview.IdealPreviewSize.X; } preview.GetScale = () => scale; preview.Bounds.Width = (int)(scale * preview.IdealPreviewSize.X); preview.Bounds.Height = (int)(scale * preview.IdealPreviewSize.Y); item.Bounds.Width = preview.Bounds.Width + 2 * preview.Bounds.X; item.Bounds.Height = preview.Bounds.Height + 2 * preview.Bounds.Y; item.IsVisible = () => true; item.GetTooltipText = () => a.Tooltip; Panel.AddChild(item); } catch { Log.Write("debug", "Map editor ignoring actor {0}, because of missing sprites for tileset {1}.", actor.Name, World.Map.Rules.TerrainInfo.Id); continue; } } }
void SetupFilters() { // Game type { var ddb = panel.GetOrNull <DropDownButtonWidget>("FLT_GAMETYPE_DROPDOWNBUTTON"); if (ddb != null) { // Using list to maintain the order var options = new List <Pair <GameType, string> > { Pair.New(GameType.Any, ddb.GetText()), Pair.New(GameType.Singleplayer, "Singleplayer"), Pair.New(GameType.Multiplayer, "Multiplayer") }; var lookup = options.ToDictionary(kvp => kvp.First, kvp => kvp.Second); ddb.GetText = () => lookup[filter.Type]; ddb.OnMouseDown = _ => { Func <Pair <GameType, string>, ScrollItemWidget, ScrollItemWidget> setupItem = (option, tpl) => { var item = ScrollItemWidget.Setup( tpl, () => filter.Type == option.First, () => { filter.Type = option.First; ApplyFilter(); }); item.Get <LabelWidget>("LABEL").GetText = () => option.Second; return(item); }; ddb.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 330, options, setupItem); }; } } // Date type { var ddb = panel.GetOrNull <DropDownButtonWidget>("FLT_DATE_DROPDOWNBUTTON"); if (ddb != null) { // Using list to maintain the order var options = new List <Pair <DateType, string> > { Pair.New(DateType.Any, ddb.GetText()), Pair.New(DateType.Today, "Today"), Pair.New(DateType.LastWeek, "Last 7 days"), Pair.New(DateType.LastFortnight, "Last 14 days"), Pair.New(DateType.LastMonth, "Last 30 days") }; var lookup = options.ToDictionary(kvp => kvp.First, kvp => kvp.Second); ddb.GetText = () => lookup[filter.Date]; ddb.OnMouseDown = _ => { Func <Pair <DateType, string>, ScrollItemWidget, ScrollItemWidget> setupItem = (option, tpl) => { var item = ScrollItemWidget.Setup( tpl, () => filter.Date == option.First, () => { filter.Date = option.First; ApplyFilter(); }); item.Get <LabelWidget>("LABEL").GetText = () => option.Second; return(item); }; ddb.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 330, options, setupItem); }; } } // Duration { var ddb = panel.GetOrNull <DropDownButtonWidget>("FLT_DURATION_DROPDOWNBUTTON"); if (ddb != null) { // Using list to maintain the order var options = new List <Pair <DurationType, string> > { Pair.New(DurationType.Any, ddb.GetText()), Pair.New(DurationType.VeryShort, "Under 5 min"), Pair.New(DurationType.Short, "Short (10 min)"), Pair.New(DurationType.Medium, "Medium (30 min)"), Pair.New(DurationType.Long, "Long (60+ min)") }; var lookup = options.ToDictionary(kvp => kvp.First, kvp => kvp.Second); ddb.GetText = () => lookup[filter.Duration]; ddb.OnMouseDown = _ => { Func <Pair <DurationType, string>, ScrollItemWidget, ScrollItemWidget> setupItem = (option, tpl) => { var item = ScrollItemWidget.Setup( tpl, () => filter.Duration == option.First, () => { filter.Duration = option.First; ApplyFilter(); }); item.Get <LabelWidget>("LABEL").GetText = () => option.Second; return(item); }; ddb.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 330, options, setupItem); }; } } // Map { var ddb = panel.GetOrNull <DropDownButtonWidget>("FLT_MAPNAME_DROPDOWNBUTTON"); if (ddb != null) { var options = replays.Select(r => r.GameInfo.MapTitle).Distinct(StringComparer.OrdinalIgnoreCase).ToList(); options.Sort(StringComparer.OrdinalIgnoreCase); options.Insert(0, null); // no filter var anyText = ddb.GetText(); ddb.GetText = () => string.IsNullOrEmpty(filter.MapName) ? anyText : filter.MapName; ddb.OnMouseDown = _ => { Func <string, ScrollItemWidget, ScrollItemWidget> setupItem = (option, tpl) => { var item = ScrollItemWidget.Setup( tpl, () => string.Compare(filter.MapName, option, true) == 0, () => { filter.MapName = option; ApplyFilter(); }); item.Get <LabelWidget>("LABEL").GetText = () => option ?? anyText; return(item); }; ddb.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 330, options, setupItem); }; } } // Players { var ddb = panel.GetOrNull <DropDownButtonWidget>("FLT_PLAYER_DROPDOWNBUTTON"); if (ddb != null) { var options = replays.SelectMany(r => r.GameInfo.Players.Select(p => p.Name)).Distinct(StringComparer.OrdinalIgnoreCase).ToList(); options.Sort(StringComparer.OrdinalIgnoreCase); options.Insert(0, null); // no filter var anyText = ddb.GetText(); ddb.GetText = () => string.IsNullOrEmpty(filter.PlayerName) ? anyText : filter.PlayerName; ddb.OnMouseDown = _ => { Func <string, ScrollItemWidget, ScrollItemWidget> setupItem = (option, tpl) => { var item = ScrollItemWidget.Setup( tpl, () => string.Compare(filter.PlayerName, option, true) == 0, () => { filter.PlayerName = option; ApplyFilter(); }); item.Get <LabelWidget>("LABEL").GetText = () => option ?? anyText; return(item); }; ddb.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 330, options, setupItem); }; } } // Outcome (depends on Player) { var ddb = panel.GetOrNull <DropDownButtonWidget>("FLT_OUTCOME_DROPDOWNBUTTON"); if (ddb != null) { ddb.IsDisabled = () => string.IsNullOrEmpty(filter.PlayerName); // Using list to maintain the order var options = new List <Pair <WinState, string> > { Pair.New(WinState.Undefined, ddb.GetText()), Pair.New(WinState.Lost, "Defeat"), Pair.New(WinState.Won, "Victory") }; var lookup = options.ToDictionary(kvp => kvp.First, kvp => kvp.Second); ddb.GetText = () => lookup[filter.Outcome]; ddb.OnMouseDown = _ => { Func <Pair <WinState, string>, ScrollItemWidget, ScrollItemWidget> setupItem = (option, tpl) => { var item = ScrollItemWidget.Setup( tpl, () => filter.Outcome == option.First, () => { filter.Outcome = option.First; ApplyFilter(); }); item.Get <LabelWidget>("LABEL").GetText = () => option.Second; return(item); }; ddb.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 330, options, setupItem); }; } } // Faction (depends on Player) { var ddb = panel.GetOrNull <DropDownButtonWidget>("FLT_FACTION_DROPDOWNBUTTON"); if (ddb != null) { ddb.IsDisabled = () => string.IsNullOrEmpty(filter.PlayerName); var options = replays .SelectMany(r => r.GameInfo.Players.Select(p => p.FactionName).Where(n => !string.IsNullOrEmpty(n))) .Distinct(StringComparer.OrdinalIgnoreCase).ToList(); options.Sort(StringComparer.OrdinalIgnoreCase); options.Insert(0, null); // no filter var anyText = ddb.GetText(); ddb.GetText = () => string.IsNullOrEmpty(filter.Faction) ? anyText : filter.Faction; ddb.OnMouseDown = _ => { Func <string, ScrollItemWidget, ScrollItemWidget> setupItem = (option, tpl) => { var item = ScrollItemWidget.Setup( tpl, () => string.Compare(filter.Faction, option, true) == 0, () => { filter.Faction = option; ApplyFilter(); }); item.Get <LabelWidget>("LABEL").GetText = () => option ?? anyText; return(item); }; ddb.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 330, options, setupItem); }; } } // Reset button { var button = panel.Get <ButtonWidget>("FLT_RESET_BUTTON"); button.IsDisabled = () => filter.IsEmpty; button.OnClick = () => { filter = new Filter(); ApplyFilter(); }; } }
public ActorSelectorLogic(Widget widget, World world, WorldRenderer worldRenderer) : base(widget, world, worldRenderer, "ACTORTEMPLATE_LIST", "ACTORPREVIEW_TEMPLATE") { mapRules = world.Map.Rules; ownersDropDown = widget.Get <DropDownButtonWidget>("OWNERS_DROPDOWN"); editorCursor = world.WorldActor.Trait <EditorCursorLayer>(); var editorLayer = world.WorldActor.Trait <EditorActorLayer>(); selectedOwner = editorLayer.Players.Players.Values.First(); Func <PlayerReference, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) => { var item = ScrollItemWidget.Setup(template, () => selectedOwner == option, () => SelectOwner(option)); item.Get <LabelWidget>("LABEL").GetText = () => option.Name; item.GetColor = () => option.Color; return(item); }; editorLayer.OnPlayerRemoved = () => { if (editorLayer.Players.Players.Values.Any(p => p.Name == selectedOwner.Name)) { return; } SelectOwner(editorLayer.Players.Players.Values.First()); }; ownersDropDown.OnClick = () => { var owners = editorLayer.Players.Players.Values.OrderBy(p => p.Name); ownersDropDown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 270, owners, setupItem); }; ownersDropDown.Text = selectedOwner.Name; ownersDropDown.TextColor = selectedOwner.Color; var tileSetId = world.Map.Rules.TerrainInfo.Id; var allActorsTemp = new List <ActorSelectorActor>(); foreach (var a in mapRules.Actors.Values) { // Partial templates are not allowed if (a.Name.Contains('^')) { continue; } // Actor must have a preview associated with it if (!a.HasTraitInfo <IRenderActorPreviewInfo>()) { continue; } var editorData = a.TraitInfoOrDefault <MapEditorDataInfo>(); // Actor must be included in at least one category if (editorData == null || editorData.Categories == null) { continue; } // Excluded by tileset if (editorData.ExcludeTilesets != null && editorData.ExcludeTilesets.Contains(tileSetId)) { continue; } if (editorData.RequireTilesets != null && !editorData.RequireTilesets.Contains(tileSetId)) { continue; } var tooltip = a.TraitInfos <EditorOnlyTooltipInfo>().FirstOrDefault(ti => ti.EnabledByDefault) as TooltipInfoBase ?? a.TraitInfos <TooltipInfo>().FirstOrDefault(ti => ti.EnabledByDefault); var searchTerms = new List <string>() { a.Name }; if (tooltip != null) { searchTerms.Add(tooltip.Name); } var tooltipText = (tooltip == null ? "Type: " : tooltip.Name + "\nType: ") + a.Name; allActorsTemp.Add(new ActorSelectorActor(a, editorData.Categories, searchTerms.ToArray(), tooltipText)); } allActors = allActorsTemp.ToArray(); allCategories = allActors.SelectMany(ac => ac.Categories) .Distinct() .OrderBy(x => x) .ToArray(); foreach (var c in allCategories) { SelectedCategories.Add(c); FilteredCategories.Add(c); } SearchTextField.OnTextEdited = () => { searchFilter = SearchTextField.Text.Trim(); FilteredCategories.Clear(); if (!string.IsNullOrEmpty(searchFilter)) { FilteredCategories.AddRange( allActors.Where(t => t.SearchTerms.Any( s => s.IndexOf(searchFilter, StringComparison.OrdinalIgnoreCase) >= 0)) .SelectMany(t => t.Categories) .Distinct() .OrderBy(x => x)); } else { FilteredCategories.AddRange(allCategories); } InitializePreviews(); }; InitializePreviews(); }
void AddReplay(ReplayMetadata replay, ScrollItemWidget template) { var item = ScrollItemWidget.Setup(template, () => selectedReplay == replay, () => SelectReplay(replay), () => WatchReplay()); replayState[replay] = new ReplayState { Item = item, Visible = true }; item.Text = Path.GetFileNameWithoutExtension(replay.FilePath); item.Get<LabelWidget>("TITLE").GetText = () => item.Text; item.IsVisible = () => replayState[replay].Visible; replayList.AddChild(item); }
internal LobbyLogic(Widget widget, ModData modData, WorldRenderer worldRenderer, OrderManager orderManager, Action onExit, Action onStart, bool skirmishMode) { map = MapCache.UnknownMap; lobby = widget; this.modData = modData; this.orderManager = orderManager; this.onStart = onStart; this.onExit = onExit; this.skirmishMode = skirmishMode; // TODO: This needs to be reworked to support per-map tech levels, bots, etc. this.modRules = modData.DefaultRules; shellmapWorld = worldRenderer.World; services = modData.Manifest.Get <WebServices>(); orderManager.AddChatLine += AddChatLine; Game.LobbyInfoChanged += UpdateCurrentMap; Game.LobbyInfoChanged += UpdatePlayerList; Game.BeforeGameStart += OnGameStart; Game.ConnectionStateChanged += ConnectionStateChanged; var name = lobby.GetOrNull <LabelWidget>("SERVER_NAME"); if (name != null) { name.GetText = () => orderManager.LobbyInfo.GlobalSettings.ServerName; } Ui.LoadWidget("MAP_PREVIEW", lobby.Get("MAP_PREVIEW_ROOT"), new WidgetArgs { { "orderManager", orderManager }, { "getMap", (Func <MapPreview>)(() => map) }, { "onMouseDown", (Action <MapPreviewWidget, MapPreview, MouseInput>)((preview, mapPreview, mi) => LobbyUtils.SelectSpawnPoint(orderManager, preview, mapPreview, mi)) }, { "getSpawnOccupants", (Func <MapPreview, Dictionary <CPos, SpawnOccupant> >)(mapPreview => LobbyUtils.GetSpawnOccupants(orderManager.LobbyInfo, mapPreview)) }, { "showUnoccupiedSpawnpoints", true }, }); UpdateCurrentMap(); var playerBin = Ui.LoadWidget("LOBBY_PLAYER_BIN", lobby.Get("TOP_PANELS_ROOT"), new WidgetArgs()); playerBin.IsVisible = () => panel == PanelType.Players; players = playerBin.Get <ScrollPanelWidget>("LOBBY_PLAYERS"); editablePlayerTemplate = players.Get("TEMPLATE_EDITABLE_PLAYER"); nonEditablePlayerTemplate = players.Get("TEMPLATE_NONEDITABLE_PLAYER"); emptySlotTemplate = players.Get("TEMPLATE_EMPTY"); editableSpectatorTemplate = players.Get("TEMPLATE_EDITABLE_SPECTATOR"); nonEditableSpectatorTemplate = players.Get("TEMPLATE_NONEDITABLE_SPECTATOR"); newSpectatorTemplate = players.Get("TEMPLATE_NEW_SPECTATOR"); colorPreview = lobby.Get <ColorPreviewManagerWidget>("COLOR_MANAGER"); colorPreview.Color = Game.Settings.Player.Color; foreach (var f in modRules.Actors["world"].TraitInfos <FactionInfo>()) { factions.Add(f.InternalName, new LobbyFaction { Selectable = f.Selectable, Name = f.Name, Side = f.Side, Description = f.Description }); } var gameStarting = false; Func <bool> configurationDisabled = () => !Game.IsHost || gameStarting || panel == PanelType.Kick || panel == PanelType.ForceStart || !map.RulesLoaded || map.InvalidCustomRules || orderManager.LocalClient == null || orderManager.LocalClient.IsReady; var mapButton = lobby.GetOrNull <ButtonWidget>("CHANGEMAP_BUTTON"); if (mapButton != null) { mapButton.IsDisabled = () => gameStarting || panel == PanelType.Kick || panel == PanelType.ForceStart || orderManager.LocalClient == null || orderManager.LocalClient.IsReady; mapButton.OnClick = () => { var onSelect = new Action <string>(uid => { // Don't select the same map again if (uid == map.Uid) { return; } orderManager.IssueOrder(Order.Command("map " + uid)); Game.Settings.Server.Map = uid; Game.Settings.Save(); }); Ui.OpenWindow("MAPCHOOSER_PANEL", new WidgetArgs() { { "initialMap", map.Uid }, { "initialTab", MapClassification.System }, { "onExit", DoNothing }, { "onSelect", Game.IsHost ? onSelect : null }, { "filter", MapVisibility.Lobby }, }); }; } var slotsButton = lobby.GetOrNull <DropDownButtonWidget>("SLOTS_DROPDOWNBUTTON"); if (slotsButton != null) { slotsButton.IsDisabled = () => configurationDisabled() || panel != PanelType.Players || (orderManager.LobbyInfo.Slots.Values.All(s => !s.AllowBots) && orderManager.LobbyInfo.Slots.Count(s => !s.Value.LockTeam && orderManager.LobbyInfo.ClientInSlot(s.Key) != null) == 0); slotsButton.OnMouseDown = _ => { var botTypes = map.Rules.Actors["player"].TraitInfos <IBotInfo>().Select(t => t.Type); var options = new Dictionary <string, IEnumerable <DropDownOption> >(); var botController = orderManager.LobbyInfo.Clients.FirstOrDefault(c => c.IsAdmin); if (orderManager.LobbyInfo.Slots.Values.Any(s => s.AllowBots)) { var botOptions = new List <DropDownOption>() { new DropDownOption() { Title = "Add", IsSelected = () => false, OnClick = () => { foreach (var slot in orderManager.LobbyInfo.Slots) { var bot = botTypes.Random(Game.CosmeticRandom); var c = orderManager.LobbyInfo.ClientInSlot(slot.Key); if (slot.Value.AllowBots == true && (c == null || c.Bot != null)) { orderManager.IssueOrder(Order.Command("slot_bot {0} {1} {2}".F(slot.Key, botController.Index, bot))); } } } } }; if (orderManager.LobbyInfo.Clients.Any(c => c.Bot != null)) { botOptions.Add(new DropDownOption() { Title = "Remove", IsSelected = () => false, OnClick = () => { foreach (var slot in orderManager.LobbyInfo.Slots) { var c = orderManager.LobbyInfo.ClientInSlot(slot.Key); if (c != null && c.Bot != null) { orderManager.IssueOrder(Order.Command("slot_open " + slot.Value.PlayerReference)); } } } }); } options.Add("Configure Bots", botOptions); } var teamCount = (orderManager.LobbyInfo.Slots.Count(s => !s.Value.LockTeam && orderManager.LobbyInfo.ClientInSlot(s.Key) != null) + 1) / 2; if (teamCount >= 1) { var teamOptions = Enumerable.Range(2, teamCount - 1).Reverse().Select(d => new DropDownOption { Title = "{0} Teams".F(d), IsSelected = () => false, OnClick = () => orderManager.IssueOrder(Order.Command("assignteams {0}".F(d.ToString()))) }).ToList(); if (orderManager.LobbyInfo.Slots.Any(s => s.Value.AllowBots)) { teamOptions.Add(new DropDownOption { Title = "Humans vs Bots", IsSelected = () => false, OnClick = () => orderManager.IssueOrder(Order.Command("assignteams 1")) }); } teamOptions.Add(new DropDownOption { Title = "Free for all", IsSelected = () => false, OnClick = () => orderManager.IssueOrder(Order.Command("assignteams 0")) }); options.Add("Configure Teams", teamOptions); } Func <DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) => { var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick); item.Get <LabelWidget>("LABEL").GetText = () => option.Title; return(item); }; slotsButton.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 175, options, setupItem); }; } var optionsBin = Ui.LoadWidget("LOBBY_OPTIONS_BIN", lobby.Get("TOP_PANELS_ROOT"), new WidgetArgs() { { "orderManager", orderManager }, { "getMap", (Func <MapPreview>)(() => map) }, { "configurationDisabled", configurationDisabled } }); optionsBin.IsVisible = () => panel == PanelType.Options; var musicBin = Ui.LoadWidget("LOBBY_MUSIC_BIN", lobby.Get("TOP_PANELS_ROOT"), new WidgetArgs { { "onExit", DoNothing }, { "world", worldRenderer.World } }); musicBin.IsVisible = () => panel == PanelType.Music; var optionsTab = lobby.Get <ButtonWidget>("OPTIONS_TAB"); optionsTab.IsHighlighted = () => panel == PanelType.Options; optionsTab.IsDisabled = OptionsTabDisabled; optionsTab.OnClick = () => panel = PanelType.Options; optionsTab.GetText = () => !map.RulesLoaded ? "Loading..." : optionsTab.Text; var playersTab = lobby.Get <ButtonWidget>("PLAYERS_TAB"); playersTab.IsHighlighted = () => panel == PanelType.Players; playersTab.IsDisabled = () => panel == PanelType.Kick || panel == PanelType.ForceStart; playersTab.OnClick = () => panel = PanelType.Players; var musicTab = lobby.Get <ButtonWidget>("MUSIC_TAB"); musicTab.IsHighlighted = () => panel == PanelType.Music; musicTab.IsDisabled = () => panel == PanelType.Kick || panel == PanelType.ForceStart; musicTab.OnClick = () => panel = PanelType.Music; // Force start panel Action startGame = () => { gameStarting = true; orderManager.IssueOrder(Order.Command("startgame")); }; var startGameButton = lobby.GetOrNull <ButtonWidget>("START_GAME_BUTTON"); if (startGameButton != null) { startGameButton.IsDisabled = () => configurationDisabled() || map.Status != MapStatus.Available || orderManager.LobbyInfo.Slots.Any(sl => sl.Value.Required && orderManager.LobbyInfo.ClientInSlot(sl.Key) == null) || (!orderManager.LobbyInfo.GlobalSettings.EnableSingleplayer && orderManager.LobbyInfo.NonBotPlayers.Count() < 2); startGameButton.OnClick = () => { // Bots and admins don't count if (orderManager.LobbyInfo.Clients.Any(c => c.Slot != null && !c.IsAdmin && c.Bot == null && !c.IsReady)) { panel = PanelType.ForceStart; } else { startGame(); } }; } var forceStartBin = Ui.LoadWidget("FORCE_START_DIALOG", lobby.Get("TOP_PANELS_ROOT"), new WidgetArgs()); forceStartBin.IsVisible = () => panel == PanelType.ForceStart; forceStartBin.Get("KICK_WARNING").IsVisible = () => orderManager.LobbyInfo.Clients.Any(c => c.IsInvalid); forceStartBin.Get <ButtonWidget>("OK_BUTTON").OnClick = startGame; forceStartBin.Get <ButtonWidget>("CANCEL_BUTTON").OnClick = () => panel = PanelType.Players; var disconnectButton = lobby.Get <ButtonWidget>("DISCONNECT_BUTTON"); disconnectButton.OnClick = () => { Ui.CloseWindow(); onExit(); }; if (skirmishMode) { disconnectButton.Text = "Back"; } chatLabel = lobby.Get <LabelWidget>("LABEL_CHATTYPE"); var chatTextField = lobby.Get <TextFieldWidget>("CHAT_TEXTFIELD"); chatTextField.MaxLength = UnitOrders.ChatMessageMaxLength; chatTextField.TakeKeyboardFocus(); chatTextField.OnEnterKey = () => { if (chatTextField.Text.Length == 0) { return(true); } // Always scroll to bottom when we've typed something lobbyChatPanel.ScrollToBottom(); orderManager.IssueOrder(Order.Chat(teamChat, chatTextField.Text)); chatTextField.Text = ""; return(true); }; chatTextField.OnTabKey = () => { var previousText = chatTextField.Text; chatTextField.Text = tabCompletion.Complete(chatTextField.Text); chatTextField.CursorPosition = chatTextField.Text.Length; if (chatTextField.Text == previousText) { return(SwitchTeamChat()); } else { return(true); } }; chatTextField.OnEscKey = () => { chatTextField.Text = ""; return(true); }; lobbyChatPanel = lobby.Get <ScrollPanelWidget>("CHAT_DISPLAY"); chatTemplate = lobbyChatPanel.Get("CHAT_TEMPLATE"); lobbyChatPanel.RemoveChildren(); var settingsButton = lobby.GetOrNull <ButtonWidget>("SETTINGS_BUTTON"); if (settingsButton != null) { settingsButton.OnClick = () => Ui.OpenWindow("SETTINGS_PANEL", new WidgetArgs { { "onExit", DoNothing }, { "worldRenderer", worldRenderer } }); } // Add a bot on the first lobbyinfo update if (skirmishMode) { addBotOnMapLoad = true; } }
void SelectReplay(ReplayMetadata replay) { selectedReplay = replay; map = selectedReplay != null ? selectedReplay.GameInfo.MapPreview : MapCache.UnknownMap; if (replay == null) { return; } try { if (map.Status != MapStatus.Available) { if (map.Status == MapStatus.DownloadAvailable) { LoadMapPreviewRules(map); } else if (Game.Settings.Game.AllowDownloading) { modData.MapCache.QueryRemoteMapDetails(services.MapRepository, new[] { map.Uid }, LoadMapPreviewRules); } } var players = replay.GameInfo.Players .GroupBy(p => p.Team) .OrderBy(g => g.Key); var teams = new Dictionary <string, IEnumerable <GameInformation.Player> >(); var noTeams = players.Count() == 1; foreach (var p in players) { var label = noTeams ? "Players" : p.Key == 0 ? "No Team" : "Team {0}".F(p.Key); teams.Add(label, p); } playerList.RemoveChildren(); foreach (var kv in teams) { var group = kv.Key; if (group.Length > 0) { var header = ScrollItemWidget.Setup(playerHeader, () => true, () => { }); header.Get <LabelWidget>("LABEL").GetText = () => group; playerList.AddChild(header); } foreach (var option in kv.Value) { var o = option; var color = o.Color; var item = ScrollItemWidget.Setup(playerTemplate, () => false, () => { }); var label = item.Get <LabelWidget>("LABEL"); var font = Game.Renderer.Fonts[label.Font]; var name = WidgetUtils.TruncateText(o.Name, label.Bounds.Width, font); label.GetText = () => name; label.GetColor = () => color; var flag = item.Get <ImageWidget>("FLAG"); flag.GetImageCollection = () => "flags"; var factionInfo = modData.DefaultRules.Actors["world"].TraitInfos <FactionInfo>(); flag.GetImageName = () => (factionInfo != null && factionInfo.Any(f => f.InternalName == o.FactionId)) ? o.FactionId : "Random"; playerList.AddChild(item); } } } catch (Exception e) { Log.Write("debug", "Exception while parsing replay: {0}", e); SelectReplay(null); } }
internal LobbyLogic(Widget widget, WorldRenderer worldRenderer, OrderManager orderManager, Action onExit, Action onStart, bool skirmishMode, Ruleset modRules) { lobby = widget; this.orderManager = orderManager; this.onStart = onStart; this.onExit = onExit; this.skirmishMode = skirmishMode; this.modRules = modRules; shellmapWorld = worldRenderer.World; orderManager.AddChatLine += AddChatLine; Game.LobbyInfoChanged += UpdateCurrentMap; Game.LobbyInfoChanged += UpdatePlayerList; Game.BeforeGameStart += OnGameStart; Game.ConnectionStateChanged += ConnectionStateChanged; var name = lobby.GetOrNull <LabelWidget>("SERVER_NAME"); if (name != null) { name.GetText = () => orderManager.LobbyInfo.GlobalSettings.ServerName; } Ui.LoadWidget("LOBBY_MAP_PREVIEW", lobby.Get("MAP_PREVIEW_ROOT"), new WidgetArgs { { "orderManager", orderManager }, { "lobby", this } }); UpdateCurrentMap(); var playerBin = Ui.LoadWidget("LOBBY_PLAYER_BIN", lobby.Get("TOP_PANELS_ROOT"), new WidgetArgs()); playerBin.IsVisible = () => panel == PanelType.Players; players = playerBin.Get <ScrollPanelWidget>("LOBBY_PLAYERS"); editablePlayerTemplate = players.Get("TEMPLATE_EDITABLE_PLAYER"); nonEditablePlayerTemplate = players.Get("TEMPLATE_NONEDITABLE_PLAYER"); emptySlotTemplate = players.Get("TEMPLATE_EMPTY"); editableSpectatorTemplate = players.Get("TEMPLATE_EDITABLE_SPECTATOR"); nonEditableSpectatorTemplate = players.Get("TEMPLATE_NONEDITABLE_SPECTATOR"); newSpectatorTemplate = players.Get("TEMPLATE_NEW_SPECTATOR"); colorPreview = lobby.Get <ColorPreviewManagerWidget>("COLOR_MANAGER"); colorPreview.Color = Game.Settings.Player.Color; foreach (var f in modRules.Actors["world"].TraitInfos <FactionInfo>()) { factions.Add(f.InternalName, new LobbyFaction { Selectable = f.Selectable, Name = f.Name, Side = f.Side, Description = f.Description }); } var gameStarting = false; Func <bool> configurationDisabled = () => !Game.IsHost || gameStarting || panel == PanelType.Kick || panel == PanelType.ForceStart || orderManager.LocalClient == null || orderManager.LocalClient.IsReady; var mapButton = lobby.GetOrNull <ButtonWidget>("CHANGEMAP_BUTTON"); if (mapButton != null) { mapButton.IsDisabled = () => gameStarting || panel == PanelType.Kick || panel == PanelType.ForceStart || orderManager.LocalClient == null || orderManager.LocalClient.IsReady; mapButton.OnClick = () => { var onSelect = new Action <string>(uid => { // Don't select the same map again if (uid == Map.Uid) { return; } orderManager.IssueOrder(Order.Command("map " + uid)); Game.Settings.Server.Map = uid; Game.Settings.Save(); }); Ui.OpenWindow("MAPCHOOSER_PANEL", new WidgetArgs() { { "initialMap", Map.Uid }, { "initialTab", MapClassification.System }, { "onExit", DoNothing }, { "onSelect", Game.IsHost ? onSelect : null }, { "filter", MapVisibility.Lobby }, }); }; } var slotsButton = lobby.GetOrNull <DropDownButtonWidget>("SLOTS_DROPDOWNBUTTON"); if (slotsButton != null) { slotsButton.IsDisabled = () => configurationDisabled() || panel != PanelType.Players || Map.RuleStatus != MapRuleStatus.Cached || !orderManager.LobbyInfo.Slots.Values.Any(s => s.AllowBots || !s.LockTeam); var botNames = modRules.Actors["player"].TraitInfos <IBotInfo>().Select(t => t.Name); slotsButton.OnMouseDown = _ => { var options = new Dictionary <string, IEnumerable <DropDownOption> >(); var botController = orderManager.LobbyInfo.Clients.FirstOrDefault(c => c.IsAdmin); if (orderManager.LobbyInfo.Slots.Values.Any(s => s.AllowBots)) { var botOptions = new List <DropDownOption>() { new DropDownOption() { Title = "Add", IsSelected = () => false, OnClick = () => { foreach (var slot in orderManager.LobbyInfo.Slots) { var bot = botNames.Random(Game.CosmeticRandom); var c = orderManager.LobbyInfo.ClientInSlot(slot.Key); if (slot.Value.AllowBots == true && (c == null || c.Bot != null)) { orderManager.IssueOrder(Order.Command("slot_bot {0} {1} {2}".F(slot.Key, botController.Index, bot))); } } } } }; if (orderManager.LobbyInfo.Clients.Any(c => c.Bot != null)) { botOptions.Add(new DropDownOption() { Title = "Remove", IsSelected = () => false, OnClick = () => { foreach (var slot in orderManager.LobbyInfo.Slots) { var c = orderManager.LobbyInfo.ClientInSlot(slot.Key); if (c != null && c.Bot != null) { orderManager.IssueOrder(Order.Command("slot_open " + slot.Value.PlayerReference)); } } } }); } options.Add("Configure Bots", botOptions); } var teamCount = (orderManager.LobbyInfo.Slots.Count(s => !s.Value.LockTeam && orderManager.LobbyInfo.ClientInSlot(s.Key) != null) + 1) / 2; if (teamCount >= 1) { var teamOptions = Enumerable.Range(2, teamCount - 1).Reverse().Select(d => new DropDownOption { Title = "{0} Teams".F(d), IsSelected = () => false, OnClick = () => orderManager.IssueOrder(Order.Command("assignteams {0}".F(d.ToString()))) }).ToList(); if (orderManager.LobbyInfo.Slots.Any(s => s.Value.AllowBots)) { teamOptions.Add(new DropDownOption { Title = "Humans vs Bots", IsSelected = () => false, OnClick = () => orderManager.IssueOrder(Order.Command("assignteams 1")) }); } teamOptions.Add(new DropDownOption { Title = "Free for all", IsSelected = () => false, OnClick = () => orderManager.IssueOrder(Order.Command("assignteams 0")) }); options.Add("Configure Teams", teamOptions); } Func <DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) => { var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick); item.Get <LabelWidget>("LABEL").GetText = () => option.Title; return(item); }; slotsButton.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 175, options, setupItem); }; } var optionsBin = Ui.LoadWidget("LOBBY_OPTIONS_BIN", lobby.Get("TOP_PANELS_ROOT"), new WidgetArgs()); optionsBin.IsVisible = () => panel == PanelType.Options; var musicBin = Ui.LoadWidget("LOBBY_MUSIC_BIN", lobby.Get("TOP_PANELS_ROOT"), new WidgetArgs { { "onExit", DoNothing }, { "world", worldRenderer.World } }); musicBin.IsVisible = () => panel == PanelType.Music; var optionsTab = lobby.Get <ButtonWidget>("OPTIONS_TAB"); optionsTab.IsHighlighted = () => panel == PanelType.Options; optionsTab.IsDisabled = () => Map.RuleStatus != MapRuleStatus.Cached || panel == PanelType.Kick || panel == PanelType.ForceStart; optionsTab.OnClick = () => panel = PanelType.Options; var playersTab = lobby.Get <ButtonWidget>("PLAYERS_TAB"); playersTab.IsHighlighted = () => panel == PanelType.Players; playersTab.IsDisabled = () => panel == PanelType.Kick || panel == PanelType.ForceStart; playersTab.OnClick = () => panel = PanelType.Players; var musicTab = lobby.Get <ButtonWidget>("MUSIC_TAB"); musicTab.IsHighlighted = () => panel == PanelType.Music; musicTab.IsDisabled = () => panel == PanelType.Kick || panel == PanelType.ForceStart; musicTab.OnClick = () => panel = PanelType.Music; // Force start panel Action startGame = () => { gameStarting = true; orderManager.IssueOrder(Order.Command("startgame")); }; var startGameButton = lobby.GetOrNull <ButtonWidget>("START_GAME_BUTTON"); if (startGameButton != null) { startGameButton.IsDisabled = () => configurationDisabled() || Map.RuleStatus != MapRuleStatus.Cached || orderManager.LobbyInfo.Slots.Any(sl => sl.Value.Required && orderManager.LobbyInfo.ClientInSlot(sl.Key) == null); startGameButton.OnClick = () => { // Bots and admins don't count if (orderManager.LobbyInfo.Clients.Any(c => c.Slot != null && !c.IsAdmin && c.Bot == null && !c.IsReady)) { panel = PanelType.ForceStart; } else { startGame(); } }; } var forceStartBin = Ui.LoadWidget("FORCE_START_DIALOG", lobby.Get("TOP_PANELS_ROOT"), new WidgetArgs()); forceStartBin.IsVisible = () => panel == PanelType.ForceStart; forceStartBin.Get("KICK_WARNING").IsVisible = () => orderManager.LobbyInfo.Clients.Any(c => c.IsInvalid); forceStartBin.Get <ButtonWidget>("OK_BUTTON").OnClick = startGame; forceStartBin.Get <ButtonWidget>("CANCEL_BUTTON").OnClick = () => panel = PanelType.Players; // Options panel var allowCheats = optionsBin.GetOrNull <CheckboxWidget>("ALLOWCHEATS_CHECKBOX"); if (allowCheats != null) { allowCheats.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.AllowCheats; allowCheats.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.Cheats.HasValue || configurationDisabled(); allowCheats.OnClick = () => orderManager.IssueOrder(Order.Command( "allowcheats {0}".F(!orderManager.LobbyInfo.GlobalSettings.AllowCheats))); } var crates = optionsBin.GetOrNull <CheckboxWidget>("CRATES_CHECKBOX"); if (crates != null) { crates.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.Crates; crates.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.Crates.HasValue || configurationDisabled(); crates.OnClick = () => orderManager.IssueOrder(Order.Command( "crates {0}".F(!orderManager.LobbyInfo.GlobalSettings.Crates))); } var creeps = optionsBin.GetOrNull <CheckboxWidget>("CREEPS_CHECKBOX"); if (creeps != null) { creeps.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.Creeps; creeps.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.Creeps.HasValue || configurationDisabled(); creeps.OnClick = () => orderManager.IssueOrder(Order.Command( "creeps {0}".F(!orderManager.LobbyInfo.GlobalSettings.Creeps))); } var allybuildradius = optionsBin.GetOrNull <CheckboxWidget>("ALLYBUILDRADIUS_CHECKBOX"); if (allybuildradius != null) { allybuildradius.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.AllyBuildRadius; allybuildradius.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.AllyBuildRadius.HasValue || configurationDisabled(); allybuildradius.OnClick = () => orderManager.IssueOrder(Order.Command( "allybuildradius {0}".F(!orderManager.LobbyInfo.GlobalSettings.AllyBuildRadius))); } var fragileAlliance = optionsBin.GetOrNull <CheckboxWidget>("FRAGILEALLIANCES_CHECKBOX"); if (fragileAlliance != null) { fragileAlliance.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.FragileAlliances; fragileAlliance.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.FragileAlliances.HasValue || configurationDisabled(); fragileAlliance.OnClick = () => orderManager.IssueOrder(Order.Command( "fragilealliance {0}".F(!orderManager.LobbyInfo.GlobalSettings.FragileAlliances))); } var shortGame = optionsBin.GetOrNull <CheckboxWidget>("SHORTGAME_CHECKBOX"); if (shortGame != null) { shortGame.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.ShortGame; shortGame.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.ShortGame.HasValue || configurationDisabled(); shortGame.OnClick = () => orderManager.IssueOrder(Order.Command( "shortgame {0}".F(!orderManager.LobbyInfo.GlobalSettings.ShortGame))); } var difficulty = optionsBin.GetOrNull <DropDownButtonWidget>("DIFFICULTY_DROPDOWNBUTTON"); if (difficulty != null) { difficulty.IsVisible = () => Map.Status == MapStatus.Available && Map.Map.Options.Difficulties.Any(); difficulty.IsDisabled = () => Map.Status != MapStatus.Available || configurationDisabled(); difficulty.GetText = () => orderManager.LobbyInfo.GlobalSettings.Difficulty; difficulty.OnMouseDown = _ => { var options = Map.Map.Options.Difficulties.Select(d => new DropDownOption { Title = d, IsSelected = () => orderManager.LobbyInfo.GlobalSettings.Difficulty == d, OnClick = () => orderManager.IssueOrder(Order.Command("difficulty {0}".F(d))) }); Func <DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) => { var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick); item.Get <LabelWidget>("LABEL").GetText = () => option.Title; return(item); }; difficulty.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem); }; optionsBin.Get <LabelWidget>("DIFFICULTY_DESC").IsVisible = difficulty.IsVisible; } var startingUnits = optionsBin.GetOrNull <DropDownButtonWidget>("STARTINGUNITS_DROPDOWNBUTTON"); if (startingUnits != null) { var startUnitsInfo = modRules.Actors["world"].TraitInfos <MPStartUnitsInfo>(); var classes = startUnitsInfo.Select(a => a.Class).Distinct(); Func <string, string> className = c => { var selectedClass = startUnitsInfo.Where(s => s.Class == c).Select(u => u.ClassName).FirstOrDefault(); return(selectedClass != null ? selectedClass : c); }; startingUnits.IsDisabled = () => Map.Status != MapStatus.Available || !Map.Map.Options.ConfigurableStartingUnits || configurationDisabled(); startingUnits.GetText = () => Map.Status != MapStatus.Available || !Map.Map.Options.ConfigurableStartingUnits ? "Not Available" : className(orderManager.LobbyInfo.GlobalSettings.StartingUnitsClass); startingUnits.OnMouseDown = _ => { var options = classes.Select(c => new DropDownOption { Title = className(c), IsSelected = () => orderManager.LobbyInfo.GlobalSettings.StartingUnitsClass == c, OnClick = () => orderManager.IssueOrder(Order.Command("startingunits {0}".F(c))) }); Func <DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) => { var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick); item.Get <LabelWidget>("LABEL").GetText = () => option.Title; return(item); }; startingUnits.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem); }; optionsBin.Get <LabelWidget>("STARTINGUNITS_DESC").IsVisible = startingUnits.IsVisible; } var startingCash = optionsBin.GetOrNull <DropDownButtonWidget>("STARTINGCASH_DROPDOWNBUTTON"); if (startingCash != null) { startingCash.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.StartingCash.HasValue || configurationDisabled(); startingCash.GetText = () => Map.Status != MapStatus.Available || Map.Map.Options.StartingCash.HasValue ? "Not Available" : "${0}".F(orderManager.LobbyInfo.GlobalSettings.StartingCash); startingCash.OnMouseDown = _ => { var options = modRules.Actors["player"].TraitInfo <PlayerResourcesInfo>().SelectableCash.Select(c => new DropDownOption { Title = "${0}".F(c), IsSelected = () => orderManager.LobbyInfo.GlobalSettings.StartingCash == c, OnClick = () => orderManager.IssueOrder(Order.Command("startingcash {0}".F(c))) }); Func <DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) => { var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick); item.Get <LabelWidget>("LABEL").GetText = () => option.Title; return(item); }; startingCash.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem); }; } var techLevel = optionsBin.GetOrNull <DropDownButtonWidget>("TECHLEVEL_DROPDOWNBUTTON"); if (techLevel != null) { var techTraits = modRules.Actors["player"].TraitInfos <ProvidesTechPrerequisiteInfo>().ToList(); techLevel.IsVisible = () => techTraits.Count > 0; var techLevelDescription = optionsBin.GetOrNull <LabelWidget>("TECHLEVEL_DESC"); if (techLevelDescription != null) { techLevelDescription.IsVisible = () => techTraits.Count > 0; } techLevel.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.TechLevel != null || configurationDisabled() || techTraits.Count <= 1; techLevel.GetText = () => Map.Status != MapStatus.Available || Map.Map.Options.TechLevel != null ? "Not Available" : "{0}".F(orderManager.LobbyInfo.GlobalSettings.TechLevel); techLevel.OnMouseDown = _ => { var options = techTraits.Select(c => new DropDownOption { Title = "{0}".F(c.Name), IsSelected = () => orderManager.LobbyInfo.GlobalSettings.TechLevel == c.Name, OnClick = () => orderManager.IssueOrder(Order.Command("techlevel {0}".F(c.Name))) }); Func <DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) => { var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick); item.Get <LabelWidget>("LABEL").GetText = () => option.Title; return(item); }; techLevel.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem); }; } var gameSpeed = optionsBin.GetOrNull <DropDownButtonWidget>("GAMESPEED_DROPDOWNBUTTON"); if (gameSpeed != null) { var speeds = Game.ModData.Manifest.Get <GameSpeeds>().Speeds; gameSpeed.IsDisabled = () => Map.Status != MapStatus.Available || configurationDisabled(); gameSpeed.GetText = () => { if (Map.Status != MapStatus.Available) { return("Not Available"); } GameSpeed speed; if (!speeds.TryGetValue(orderManager.LobbyInfo.GlobalSettings.GameSpeedType, out speed)) { return("Unknown"); } return(speed.Name); }; gameSpeed.OnMouseDown = _ => { var options = speeds.Select(s => new DropDownOption { Title = s.Value.Name, IsSelected = () => orderManager.LobbyInfo.GlobalSettings.GameSpeedType == s.Key, OnClick = () => orderManager.IssueOrder(Order.Command("gamespeed {0}".F(s.Key))) }); Func <DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) => { var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick); item.Get <LabelWidget>("LABEL").GetText = () => option.Title; return(item); }; gameSpeed.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem); }; } var exploredMap = optionsBin.GetOrNull <CheckboxWidget>("EXPLORED_MAP_CHECKBOX"); if (exploredMap != null) { exploredMap.IsChecked = () => !orderManager.LobbyInfo.GlobalSettings.Shroud; exploredMap.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.Shroud.HasValue || configurationDisabled(); exploredMap.OnClick = () => orderManager.IssueOrder(Order.Command( "shroud {0}".F(!orderManager.LobbyInfo.GlobalSettings.Shroud))); } var enableFog = optionsBin.GetOrNull <CheckboxWidget>("FOG_CHECKBOX"); if (enableFog != null) { enableFog.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.Fog; enableFog.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.Fog.HasValue || configurationDisabled(); enableFog.OnClick = () => orderManager.IssueOrder(Order.Command( "fog {0}".F(!orderManager.LobbyInfo.GlobalSettings.Fog))); } var disconnectButton = lobby.Get <ButtonWidget>("DISCONNECT_BUTTON"); disconnectButton.OnClick = () => { CloseWindow(); onExit(); }; if (skirmishMode) { disconnectButton.Text = "Back"; } var globalChat = Game.LoadWidget(null, "LOBBY_GLOBALCHAT_PANEL", lobby.Get("GLOBALCHAT_ROOT"), new WidgetArgs()); var globalChatInput = globalChat.Get <TextFieldWidget>("CHAT_TEXTFIELD"); globalChat.IsVisible = () => chatPanel == ChatPanelType.Global; var globalChatTab = lobby.Get <ButtonWidget>("GLOBALCHAT_TAB"); globalChatTab.IsHighlighted = () => chatPanel == ChatPanelType.Global; globalChatTab.OnClick = () => { chatPanel = ChatPanelType.Global; globalChatInput.TakeKeyboardFocus(); }; var globalChatLabel = globalChatTab.Text; globalChatTab.GetText = () => { if (globalChatUnreadMessages == 0 || chatPanel == ChatPanelType.Global) { return(globalChatLabel); } return(globalChatLabel + " ({0})".F(globalChatUnreadMessages)); }; globalChatLastReadMessages = Game.GlobalChat.History.Count(m => m.Type == ChatMessageType.Message); var lobbyChat = lobby.Get("LOBBYCHAT"); lobbyChat.IsVisible = () => chatPanel == ChatPanelType.Lobby; chatLabel = lobby.Get <LabelWidget>("LABEL_CHATTYPE"); var chatTextField = lobby.Get <TextFieldWidget>("CHAT_TEXTFIELD"); chatTextField.TakeKeyboardFocus(); chatTextField.OnEnterKey = () => { if (chatTextField.Text.Length == 0) { return(true); } // Always scroll to bottom when we've typed something lobbyChatPanel.ScrollToBottom(); orderManager.IssueOrder(Order.Chat(teamChat, chatTextField.Text)); chatTextField.Text = ""; return(true); }; chatTextField.OnTabKey = () => { var previousText = chatTextField.Text; chatTextField.Text = tabCompletion.Complete(chatTextField.Text); chatTextField.CursorPosition = chatTextField.Text.Length; if (chatTextField.Text == previousText) { return(SwitchTeamChat()); } else { return(true); } }; chatTextField.OnEscKey = () => { chatTextField.Text = ""; return(true); }; var lobbyChatTab = lobby.Get <ButtonWidget>("LOBBYCHAT_TAB"); lobbyChatTab.IsHighlighted = () => chatPanel == ChatPanelType.Lobby; lobbyChatTab.OnClick = () => { chatPanel = ChatPanelType.Lobby; chatTextField.TakeKeyboardFocus(); }; var lobbyChatLabel = lobbyChatTab.Text; lobbyChatTab.GetText = () => { if (lobbyChatUnreadMessages == 0 || chatPanel == ChatPanelType.Lobby) { return(lobbyChatLabel); } return(lobbyChatLabel + " ({0})".F(lobbyChatUnreadMessages)); }; lobbyChatPanel = lobby.Get <ScrollPanelWidget>("CHAT_DISPLAY"); chatTemplate = lobbyChatPanel.Get("CHAT_TEMPLATE"); lobbyChatPanel.RemoveChildren(); var settingsButton = lobby.GetOrNull <ButtonWidget>("SETTINGS_BUTTON"); if (settingsButton != null) { settingsButton.OnClick = () => Ui.OpenWindow("SETTINGS_PANEL", new WidgetArgs { { "onExit", DoNothing }, { "worldRenderer", worldRenderer } }); } // Add a bot on the first lobbyinfo update if (skirmishMode) { Game.LobbyInfoChanged += WidgetUtils.Once(() => { var slot = orderManager.LobbyInfo.FirstEmptyBotSlot(); var bot = modRules.Actors["player"].TraitInfos <IBotInfo>().Select(t => t.Name).FirstOrDefault(); var botController = orderManager.LobbyInfo.Clients.FirstOrDefault(c => c.IsAdmin); if (slot != null && bot != null) { orderManager.IssueOrder(Order.Command("slot_bot {0} {1} {2}".F(slot, botController.Index, bot))); } }); } }