public override void Display()
        {
            if (r == null)
            {
                return;
            }

            // Update text at most every 0.5 seconds
            if (lastUpdate.Elapsed.TotalSeconds < 0.5)
            {
                return;
            }

            if (r.Fonts == null)
            {
                return;
            }

            lastUpdate.Restart();
            var text     = messages.Random(Game.CosmeticRandom);
            var textSize = r.Fonts["Bold"].Measure(text);

            r.BeginFrame(int2.Zero, 1f);

            if (stripe != null)
            {
                WidgetUtils.FillRectWithSprite(stripeRect, stripe);
            }

            if (logo != null)
            {
                r.RgbaSpriteRenderer.DrawSprite(logo, logoPos);
            }

            r.Fonts["Bold"].DrawText(text, new float2(r.Resolution.Width - textSize.X - 20, r.Resolution.Height - textSize.Y - 20), Color.White);
            r.EndFrame(new NullInputHandler());
        }
Exemple #2
0
        public AnonymousProfileTooltipLogic(Widget widget, OrderManager orderManager, Session.Client client)
        {
            var nameLabel = widget.Get <LabelWidget>("NAME");
            var nameFont  = Game.Renderer.Fonts[nameLabel.Font];

            widget.Bounds.Width = nameFont.Measure(nameLabel.Text).X + 2 * nameLabel.Bounds.Left;

            var locationLabel = widget.Get <LabelWidget>("LOCATION");
            var ipLabel       = widget.Get <LabelWidget>("IP");
            var adminLabel    = widget.Get("GAME_ADMIN");

            if (client.Location != null)
            {
                var locationFont  = Game.Renderer.Fonts[locationLabel.Font];
                var locationWidth = widget.Bounds.Width - 2 * locationLabel.Bounds.X;
                var location      = WidgetUtils.TruncateText(client.Location, locationWidth, locationFont);
                locationLabel.IsVisible = () => true;
                locationLabel.GetText   = () => location;
                widget.Bounds.Height   += locationLabel.Bounds.Height;
                ipLabel.Bounds.Y       += locationLabel.Bounds.Height;
                adminLabel.Bounds.Y    += locationLabel.Bounds.Height;
            }

            if (client.AnonymizedIPAddress != null)
            {
                ipLabel.IsVisible     = () => true;
                ipLabel.GetText       = () => client.AnonymizedIPAddress;
                widget.Bounds.Height += ipLabel.Bounds.Height;
                adminLabel.Bounds.Y  += locationLabel.Bounds.Height;
            }

            if (client.IsAdmin)
            {
                adminLabel.IsVisible  = () => true;
                widget.Bounds.Height += adminLabel.Bounds.Height;
            }
        }
Exemple #3
0
        public ProductionPaletteWidget(World world, WorldRenderer worldRenderer)
        {
            this.world         = world;
            this.worldRenderer = worldRenderer;
            tooltipContainer   = Lazy.New(() =>
                                          Widget.RootWidget.GetWidget <TooltipContainerWidget>(TooltipContainer));

            cantBuild = new Animation("clock");
            cantBuild.PlayFetchIndex("idle", () => 0);
            clock = new Animation("clock");

            iconSprites = Rules.Info.Values
                          .Where(u => u.Traits.Contains <BuildableInfo>() && u.Name[0] != '^')
                          .ToDictionary(
                u => u.Name,
                u => Game.modData.SpriteLoader.LoadAllSprites(
                    u.Traits.Get <TooltipInfo>().Icon ?? (u.Name + "icon"))[0]);

            overlayFont  = Game.Renderer.Fonts["TinyBold"];
            holdOffset   = new float2(32, 24) - overlayFont.Measure("On Hold") / 2;
            readyOffset  = new float2(32, 24) - overlayFont.Measure("Ready") / 2;
            timeOffset   = new float2(32, 24) - overlayFont.Measure(WidgetUtils.FormatTime(0)) / 2;
            queuedOffset = new float2(4, 2);
        }
        public override void Draw()
        {
            // TODO this whole block can be removed when arrows are widgets!
            if (visibleIcons < buildableItems.Length)
            {
                var position = new int2(RenderBounds.X + ButtonWidget.Size / 4, RenderBounds.Y + ButtonWidget.Size / 4 + visibleIcons * ButtonWidget.Size);

                sidebar.Buttons.PlayFetchIndex("button-small", () => 0);
                WidgetUtils.DrawSHPCentered(sidebar.Buttons.Image, position, sidebar.IngameUi.Palette);
                sidebar.Buttons.PlayFetchIndex("button-small-down", () => 0);
                WidgetUtils.DrawSHPCentered(sidebar.Buttons.Image, position, sidebar.IngameUi.Palette);

                if (scrollOffset + visibleIcons == buildableItems.Length)
                {
                    WidgetUtils.FillRectWithColor(new Rectangle(
                                                      RenderBounds.X,
                                                      RenderBounds.Y + visibleIcons * ButtonWidget.Size,
                                                      ButtonWidget.Size / 2,
                                                      ButtonWidget.Size / 2), Color.FromArgb(128, 0, 0, 0));
                }

                sidebar.Buttons.PlayFetchIndex("button-small", () => 0);
                WidgetUtils.DrawSHPCentered(sidebar.Buttons.Image, position + new int2(ButtonWidget.Size / 2, 0), sidebar.IngameUi.Palette);
                sidebar.Buttons.PlayFetchIndex("button-small-up", () => 0);
                WidgetUtils.DrawSHPCentered(sidebar.Buttons.Image, position + new int2(ButtonWidget.Size / 2, 0), sidebar.IngameUi.Palette);

                if (scrollOffset == 0)
                {
                    WidgetUtils.FillRectWithColor(new Rectangle(
                                                      RenderBounds.X + ButtonWidget.Size / 2,
                                                      RenderBounds.Y + visibleIcons * ButtonWidget.Size,
                                                      ButtonWidget.Size / 2,
                                                      ButtonWidget.Size / 2), Color.FromArgb(128, 0, 0, 0));
                }
            }
        }
Exemple #5
0
        void ShowAudioDeviceDropdown(DropDownButtonWidget dropdown, SoundDevice[] devices, ScrollPanelWidget scrollPanel)
        {
            var i       = 0;
            var options = devices.ToDictionary(d => (i++).ToString(), d => d);

            Func <string, ScrollItemWidget, ScrollItemWidget> setupItem = (o, itemTemplate) =>
            {
                var item = ScrollItemWidget.Setup(itemTemplate,
                                                  () => soundDevice == options[o],
                                                  () =>
                {
                    soundDevice = options[o];
                    SettingsUtils.AdjustSettingsScrollPanelLayout(scrollPanel);
                });

                var deviceLabel = item.Get <LabelWidget>("LABEL");
                var font        = Game.Renderer.Fonts[deviceLabel.Font];
                var label       = WidgetUtils.TruncateText(options[o].Label, deviceLabel.Bounds.Width, font);
                deviceLabel.GetText = () => label;
                return(item);
            };

            dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 500, options.Keys, setupItem);
        }
Exemple #6
0
        void AddChatLine(Color c, string from, string text)
        {
            var template  = chatTemplate.Clone();
            var nameLabel = template.Get <LabelWidget>("NAME");
            var timeLabel = template.Get <LabelWidget>("TIME");
            var textLabel = template.Get <LabelWidget>("TEXT");

            var name     = from + ":";
            var font     = Game.Renderer.Fonts[nameLabel.Font];
            var nameSize = font.Measure(from);

            var time = DateTime.Now;

            timeLabel.GetText = () => "{0:D2}:{1:D2}".F(time.Hour, time.Minute);

            nameLabel.GetColor      = () => c;
            nameLabel.GetText       = () => name;
            nameLabel.Bounds.Width  = nameSize.X;
            textLabel.Bounds.X     += nameSize.X;
            textLabel.Bounds.Width -= nameSize.X;

            // Hack around our hacky wordwrap behavior: need to resize the widget to fit the text
            text = WidgetUtils.WrapText(text, textLabel.Bounds.Width, font);
            textLabel.GetText = () => text;
            var dh = font.Measure(text).Y - textLabel.Bounds.Height;

            if (dh > 0)
            {
                textLabel.Bounds.Height += dh;
                template.Bounds.Height  += dh;
            }

            chatPanel.AddChild(template);
            chatPanel.ScrollToBottom();
            Sound.PlayNotification(null, "Sounds", "ChatLine", null);
        }
Exemple #7
0
		public override void Draw()
		{
			// Background
			foreach (var rect in Icons.Keys)
				WidgetUtils.DrawPanel("panel-black", rect.InflateBy(1,1,1,1));

			// Icons
			foreach (var p in Icons.Values)
			{
				WidgetUtils.DrawSHP(p.Sprite, p.Pos, worldRenderer);

				// Charge progress
				clock.PlayFetchIndex("idle",
					() => (p.Power.TotalTime - p.Power.RemainingTime)
						* (clock.CurrentSequence.Length - 1) / p.Power.TotalTime);
				clock.Tick();
				WidgetUtils.DrawSHP(clock.Image, p.Pos, worldRenderer);
			}

			// Overlay
			foreach (var p in Icons.Values)
			{
				if (p.Power.Ready)
					overlayFont.DrawTextWithContrast("Ready",
						p.Pos + readyOffset,
						Color.White, Color.Black, 1);
				else if (!p.Power.Active)
					overlayFont.DrawTextWithContrast("On Hold",
						p.Pos + holdOffset,
						Color.White, Color.Black, 1);
				else
					overlayFont.DrawTextWithContrast(WidgetUtils.FormatTime(p.Power.RemainingTime),
						p.Pos + timeOffset,
						Color.White, Color.Black, 1);
			}
		}
Exemple #8
0
        void DrawBuildTabs(World world)
        {
            const int tabWidth  = 24;
            const int tabHeight = 40;
            var       x         = paletteOrigin.X - tabWidth;
            var       y         = paletteOrigin.Y + 9;

            tabs.Clear();

            foreach (var queue in VisibleQueues)
            {
                string[] tabKeys   = { "normal", "ready", "selected" };
                var      producing = queue.CurrentItem();
                var      index     = queue == CurrentQueue ? 2 : (producing != null && producing.Done) ? 1 : 0;

                var race = world.LocalPlayer.Country.Race;
                WidgetUtils.DrawRGBA(ChromeProvider.GetImage("tabs-" + tabKeys[index], race + "-" + queue.Info.Type), new float2(x, y));

                var rect = new Rectangle((int)x, (int)y, tabWidth, tabHeight);
                tabs.Add(Pair.New(rect, HandleTabClick(queue, world)));

                if (rect.Contains(Viewport.LastMousePos))
                {
                    var text = queue.Info.Type;
                    var font = Game.Renderer.Fonts["Bold"];
                    var sz   = font.Measure(text);
                    WidgetUtils.DrawPanelPartial("dialog4",
                                                 Rectangle.FromLTRB(rect.Left - sz.X - 30, rect.Top, rect.Left - 5, rect.Bottom),
                                                 PanelSides.All);

                    font.DrawText(text, new float2(rect.Left - sz.X - 20, rect.Top + 12), Color.White);
                }

                y += tabHeight;
            }
        }
        public override void Draw()
        {
            buttons.Clear();

            if (world.LocalPlayer == null)
            {
                return;
            }

            var manager   = world.LocalPlayer.PlayerActor.Trait <SupportPowerManager>();
            var powers    = manager.Powers.Where(p => !p.Value.Disabled);
            var numPowers = powers.Count();

            if (numPowers == 0)
            {
                return;
            }

            var rectBounds = RenderBounds;

            WidgetUtils.DrawRGBA(WidgetUtils.GetChromeImage(world, "specialbin-top"), new float2(rectBounds.X, rectBounds.Y));
            for (var i = 1; i < numPowers; i++)
            {
                WidgetUtils.DrawRGBA(WidgetUtils.GetChromeImage(world, "specialbin-middle"), new float2(rectBounds.X, rectBounds.Y + i * 51));
            }
            WidgetUtils.DrawRGBA(WidgetUtils.GetChromeImage(world, "specialbin-bottom"), new float2(rectBounds.X, rectBounds.Y + numPowers * 51));

            // Hack Hack Hack
            rectBounds.Width  = 69;
            rectBounds.Height = 10 + numPowers * 51 + 21;

            var y = rectBounds.Y + 10;

            foreach (var kv in powers)
            {
                var sp    = kv.Value;
                var image = spsprites[sp.Info.Image];

                var drawPos = new float2(rectBounds.X + 5, y);
                var rect    = new Rectangle(rectBounds.X + 5, y, 64, 48);

                if (rect.Contains(Viewport.LastMousePos))
                {
                    var pos = drawPos.ToInt2();
                    var tl  = new int2(pos.X - 3, pos.Y - 3);
                    var m   = new int2(pos.X + 64 + 3, pos.Y + 48 + 3);
                    var br  = tl + new int2(64 + 3 + 20, 40);

                    if (sp.TotalTime > 0)
                    {
                        br += new int2(0, 20);
                    }

                    if (sp.Info.LongDesc != null)
                    {
                        br += Game.Renderer.Fonts["Regular"].Measure(sp.Info.LongDesc.Replace("\\n", "\n"));
                    }
                    else
                    {
                        br += new int2(300, 0);
                    }

                    var border = WidgetUtils.GetBorderSizes("dialog4");

                    WidgetUtils.DrawPanelPartial("dialog4", Rectangle.FromLTRB(tl.X, tl.Y, m.X + border[3], m.Y),
                                                 PanelSides.Left | PanelSides.Top | PanelSides.Bottom | PanelSides.Center);
                    WidgetUtils.DrawPanelPartial("dialog4", Rectangle.FromLTRB(m.X - border[2], tl.Y, br.X, m.Y + border[1]),
                                                 PanelSides.Top | PanelSides.Right | PanelSides.Center);
                    WidgetUtils.DrawPanelPartial("dialog4", Rectangle.FromLTRB(m.X, m.Y - border[1], br.X, br.Y),
                                                 PanelSides.Left | PanelSides.Right | PanelSides.Bottom | PanelSides.Center);

                    pos += new int2(77, 5);
                    Game.Renderer.Fonts["Bold"].DrawText(sp.Info.Description, pos, Color.White);

                    if (sp.TotalTime > 0)
                    {
                        pos += new int2(0, 20);
                        Game.Renderer.Fonts["Bold"].DrawText(WidgetUtils.FormatTime(sp.RemainingTime).ToString(), pos, Color.White);
                        Game.Renderer.Fonts["Bold"].DrawText("/ {0}".F(WidgetUtils.FormatTime(sp.TotalTime)), pos + new int2(45, 0), Color.White);
                    }

                    if (sp.Info.LongDesc != null)
                    {
                        pos += new int2(0, 20);
                        Game.Renderer.Fonts["Regular"].DrawText(sp.Info.LongDesc.Replace("\\n", "\n"), pos, Color.White);
                    }
                }

                WidgetUtils.DrawSHP(image, drawPos, worldRenderer);

                clock.PlayFetchIndex("idle",
                                     () => sp.TotalTime == 0 ? clock.CurrentSequence.Length - 1 : (sp.TotalTime - sp.RemainingTime)
                                     * (clock.CurrentSequence.Length - 1) / sp.TotalTime);
                clock.Tick();

                WidgetUtils.DrawSHP(clock.Image, drawPos, worldRenderer);

                var overlay = sp.Ready ? ReadyText : sp.Active ? null : HoldText;
                var font    = Game.Renderer.Fonts["TinyBold"];
                if (overlay != null)
                {
                    var size       = font.Measure(overlay);
                    var overlayPos = drawPos + new float2(32, 16);
                    font.DrawTextWithContrast(overlay, overlayPos - new float2(size.X / 2, 0), Color.White, Color.Black, 1);
                }

                buttons.Add(Pair.New(rect, HandleSupportPower(kv.Key, manager)));

                y += 51;
            }
        }
Exemple #10
0
        void DrawProductionTooltip(World world, string unit, Hotkey hotkey, int2 pos)
        {
            pos.Y += 15;

            var pl = world.LocalPlayer;
            var p  = pos.ToFloat2() - new float2(297, -3);

            var info         = world.Map.Rules.Actors[unit];
            var tooltip      = info.Traits.Get <TooltipInfo>();
            var buildable    = info.Traits.Get <BuildableInfo>();
            var cost         = info.Traits.Get <ValuedInfo>().Cost;
            var canBuildThis = CurrentQueue.CanBuild(info);

            var longDescSize = Game.Renderer.Fonts["Regular"].Measure(tooltip.Description.Replace("\\n", "\n")).Y;

            if (!canBuildThis)
            {
                longDescSize += 8;
            }

            WidgetUtils.DrawPanel("dialog4", new Rectangle(Game.Renderer.Resolution.Width - 300, pos.Y, 300, longDescSize + 65));

            Game.Renderer.Fonts["Bold"].DrawText(
                tooltip.Name + (hotkey.IsValid() ? " ({0})".F(hotkey.DisplayString()) : ""),
                p.ToInt2() + new int2(5, 5), Color.White);

            var resources = pl.PlayerActor.Trait <PlayerResources>();
            var power     = pl.PlayerActor.Trait <PowerManager>();

            DrawRightAligned("${0}".F(cost), pos + new int2(-5, 5),
                             (resources.DisplayCash + resources.DisplayResources >= cost ? Color.White : Color.Red));

            var lowpower = power.PowerState != PowerState.Normal;
            var time     = CurrentQueue.GetBuildTime(info.Name)
                           * ((lowpower) ? CurrentQueue.Info.LowPowerSlowdown : 1);

            DrawRightAligned(WidgetUtils.FormatTime(time), pos + new int2(-5, 35), lowpower ? Color.Red : Color.White);

            var pi = info.Traits.GetOrDefault <PowerInfo>();

            if (pi != null)
            {
                DrawRightAligned("{1}{0}".F(pi.Amount, pi.Amount > 0 ? "+" : ""), pos + new int2(-5, 20),
                                 ((power.PowerProvided - power.PowerDrained) >= -pi.Amount || pi.Amount > 0) ? Color.White : Color.Red);
            }

            p += new int2(5, 35);
            if (!canBuildThis)
            {
                var prereqs = buildable.Prerequisites.Select(s => Description(world.Map.Rules, s)).Where(s => !s.StartsWith("~"));
                if (prereqs.Any())
                {
                    Game.Renderer.Fonts["Regular"].DrawText(RequiresText.F(prereqs.JoinWith(", ")), p.ToInt2(), Color.White);

                    p += new int2(0, 8);
                }
            }

            p += new int2(0, 15);
            Game.Renderer.Fonts["Regular"].DrawText(tooltip.Description.Replace("\\n", "\n"),
                                                    p.ToInt2(), Color.White);
        }
Exemple #11
0
        int DrawPalette(ProductionQueue queue)
        {
            buttons.Clear();

            var paletteCollection = "palette-" + world.LocalPlayer.Country.Race;
            var origin            = new float2(paletteOrigin.X + 9, paletteOrigin.Y + 9);
            var iconOffset        = 0.5f * new float2(IconWidth, IconHeight);
            var x = 0;
            var y = 0;

            if (queue != null)
            {
                var buildableItems = queue.BuildableItems().ToArray();
                var allBuildables  = queue.AllItems().OrderBy(a => a.Traits.Get <BuildableInfo>().BuildPaletteOrder).ToArray();

                var overlayBits = new List <Pair <Sprite, float2> >();
                var textBits    = new List <Pair <float2, string> >();
                numActualRows = Math.Max((allBuildables.Count() + Columns - 1) / Columns, Rows);

                // Palette Background
                WidgetUtils.DrawRGBA(ChromeProvider.GetImage(paletteCollection, "top"), new float2(origin.X - 9, origin.Y - 9));
                for (var w = 0; w < numActualRows; w++)
                {
                    WidgetUtils.DrawRGBA(
                        ChromeProvider.GetImage(paletteCollection, "bg-" + (w % 4)),
                        new float2(origin.X - 9, origin.Y + IconHeight * w));
                }
                WidgetUtils.DrawRGBA(ChromeProvider.GetImage(paletteCollection, "bottom"),
                                     new float2(origin.X - 9, origin.Y - 1 + IconHeight * numActualRows));


                // Icons
                string tooltipItem   = null;
                var    tooltipHotkey = Hotkey.Invalid;
                var    i             = 0;
                foreach (var item in allBuildables)
                {
                    var rect    = new RectangleF(origin.X + x * IconWidth, origin.Y + IconHeight * y, IconWidth, IconHeight);
                    var drawPos = new float2(rect.Location);
                    var icon    = new Animation(world, RenderSimple.GetImage(item));
                    icon.Play(item.Traits.Get <TooltipInfo>().Icon);
                    WidgetUtils.DrawSHPCentered(icon.Image, drawPos + iconOffset, worldRenderer);

                    var firstOfThis = queue.AllQueued().FirstOrDefault(a => a.Item == item.Name);

                    if (rect.Contains(Viewport.LastMousePos))
                    {
                        tooltipItem   = item.Name;
                        tooltipHotkey = Game.Settings.Keys.GetProductionHotkey(i);
                    }

                    var overlayPos = drawPos + new float2(32, 16);

                    if (firstOfThis != null)
                    {
                        clock.PlayFetchIndex("idle",
                                             () => (firstOfThis.TotalTime - firstOfThis.RemainingTime)
                                             * (clock.CurrentSequence.Length - 1) / firstOfThis.TotalTime);
                        clock.Tick();
                        WidgetUtils.DrawSHPCentered(clock.Image, drawPos + iconOffset, worldRenderer);

                        if (queue.CurrentItem() == firstOfThis)
                        {
                            textBits.Add(Pair.New(overlayPos, GetOverlayForItem(firstOfThis)));
                        }

                        var repeats = queue.AllQueued().Count(a => a.Item == item.Name);
                        if (repeats > 1 || queue.CurrentItem() != firstOfThis)
                        {
                            textBits.Add(Pair.New(overlayPos + new float2(-24, -14), repeats.ToString()));
                        }
                    }
                    else
                    if (buildableItems.All(a => a.Name != item.Name))
                    {
                        overlayBits.Add(Pair.New(cantBuild.Image, drawPos));
                    }

                    var closureName = buildableItems.Any(a => a.Name == item.Name) ? item.Name : null;
                    buttons.Add(Pair.New(new Rectangle((int)rect.X, (int)rect.Y, (int)rect.Width, (int)rect.Height), HandleClick(closureName, world)));

                    if (++x == Columns)
                    {
                        x = 0; y++;
                    }
                    i++;
                }
                if (x != 0)
                {
                    y++;
                }

                foreach (var ob in overlayBits)
                {
                    WidgetUtils.DrawSHPCentered(ob.First, ob.Second + iconOffset, worldRenderer);
                }

                var font = Game.Renderer.Fonts["TinyBold"];
                foreach (var tb in textBits)
                {
                    var size = font.Measure(tb.Second);
                    if (ReadyTextStyle == ReadyTextStyleOptions.Solid || orderManager.LocalFrameNumber / 9 % 2 == 0 || tb.Second != ReadyText)
                    {
                        font.DrawTextWithContrast(tb.Second, tb.First - new float2(size.X / 2, 0),
                                                  Color.White, Color.Black, 1);
                    }
                    else if (ReadyTextStyle == ReadyTextStyleOptions.AlternatingColor)
                    {
                        font.DrawTextWithContrast(tb.Second, tb.First - new float2(size.X / 2, 0),
                                                  ReadyTextAltColor, Color.Black, 1);
                    }
                }

                // Tooltip
                if (tooltipItem != null && !paletteAnimating && paletteOpen)
                {
                    DrawProductionTooltip(world, tooltipItem, tooltipHotkey,
                                          new float2(Game.Renderer.Resolution.Width, origin.Y + numActualRows * IconHeight + 9).ToInt2());
                }
            }

            // Palette Dock
            WidgetUtils.DrawRGBA(ChromeProvider.GetImage(paletteCollection, "dock-top"),
                                 new float2(Game.Renderer.Resolution.Width - 14, origin.Y - 23));

            for (var i = 0; i < numActualRows; i++)
            {
                WidgetUtils.DrawRGBA(ChromeProvider.GetImage(paletteCollection, "dock-" + (i % 4)),
                                     new float2(Game.Renderer.Resolution.Width - 14, origin.Y + IconHeight * i));
            }

            WidgetUtils.DrawRGBA(ChromeProvider.GetImage(paletteCollection, "dock-bottom"),
                                 new float2(Game.Renderer.Resolution.Width - 14, origin.Y - 1 + IconHeight * numActualRows));

            return(IconHeight * y + 9);
        }
Exemple #12
0
        public ProductionTooltipLogic(Widget widget, TooltipContainerWidget tooltipContainer, ProductionPaletteWidget palette, World world)
        {
            var mapRules = palette.World.Map.Rules;
            var pm       = palette.World.LocalPlayer.PlayerActor.Trait <PowerManager>();
            var pr       = palette.World.LocalPlayer.PlayerActor.Trait <PlayerResources>();

            widget.IsVisible = () => palette.TooltipIcon != null;
            var nameLabel     = widget.Get <LabelWidget>("NAME");
            var hotkeyLabel   = widget.Get <LabelWidget>("HOTKEY");
            var requiresLabel = widget.Get <LabelWidget>("REQUIRES");
            var powerLabel    = widget.Get <LabelWidget>("POWER");
            var powerIcon     = widget.Get <ImageWidget>("POWER_ICON");
            var timeLabel     = widget.Get <LabelWidget>("TIME");
            var timeIcon      = widget.Get <ImageWidget>("TIME_ICON");
            var costLabel     = widget.Get <LabelWidget>("COST");
            var costIcon      = widget.Get <ImageWidget>("COST_ICON");
            var descLabel     = widget.Get <LabelWidget>("DESC");

            var iconMargin = timeIcon.Bounds.X;

            var       font         = Game.Renderer.Fonts[nameLabel.Font];
            var       descFont     = Game.Renderer.Fonts[descLabel.Font];
            var       requiresFont = Game.Renderer.Fonts[requiresLabel.Font];
            ActorInfo lastActor    = null;

            tooltipContainer.BeforeRender = () =>
            {
                if (palette.TooltipIcon == null)
                {
                    return;
                }

                var actor = palette.TooltipIcon.Actor;
                if (actor == null || actor == lastActor)
                {
                    return;
                }

                var tooltip   = actor.TraitInfo <TooltipInfo>();
                var buildable = actor.TraitInfo <BuildableInfo>();
                var cost      = actor.TraitInfo <ValuedInfo>().Cost;

                nameLabel.GetText = () => tooltip.Name;

                var hotkey      = palette.TooltipIcon.Hotkey;
                var nameWidth   = font.Measure(tooltip.Name).X;
                var hotkeyText  = "({0})".F(hotkey.DisplayString());
                var hotkeyWidth = hotkey.IsValid() ? font.Measure(hotkeyText).X + 2 * nameLabel.Bounds.X : 0;
                hotkeyLabel.GetText  = () => hotkeyText;
                hotkeyLabel.Bounds.X = nameWidth + 2 * nameLabel.Bounds.X;
                hotkeyLabel.Visible  = hotkey.IsValid();

                var prereqs        = buildable.Prerequisites.Select(a => ActorName(mapRules, a)).Where(s => !s.StartsWith("~"));
                var requiresString = prereqs.Any() ? requiresLabel.Text.F(prereqs.JoinWith(", ")) : "";
                requiresLabel.GetText = () => requiresString;

                var power       = actor.TraitInfos <PowerInfo>().Where(i => i.UpgradeMinEnabledLevel < 1).Sum(i => i.Amount);
                var powerString = power.ToString();
                powerLabel.GetText  = () => powerString;
                powerLabel.GetColor = () => ((pm.PowerProvided - pm.PowerDrained) >= -power || power > 0)
                                        ? Color.White : Color.Red;
                powerLabel.IsVisible = () => power != 0;
                powerIcon.IsVisible  = () => power != 0;

                var lowpower = pm.PowerState != PowerState.Normal;
                var time     = palette.CurrentQueue == null ? 0 : palette.CurrentQueue.GetBuildTime(actor.Name)
                               * (lowpower ? palette.CurrentQueue.Info.LowPowerSlowdown : 1);
                var timeString = WidgetUtils.FormatTime(time, world.Timestep);
                timeLabel.GetText  = () => timeString;
                timeLabel.GetColor = () => lowpower ? Color.Red : Color.White;

                var costString = cost.ToString();
                costLabel.GetText  = () => costString;
                costLabel.GetColor = () => pr.DisplayCash + pr.DisplayResources >= cost
                                        ? Color.White : Color.Red;

                var descString = tooltip.Description.Replace("\\n", "\n");
                descLabel.GetText = () => descString;

                var leftWidth = new[] { nameWidth + hotkeyWidth, requiresFont.Measure(requiresString).X, descFont.Measure(descString).X }.Aggregate(Math.Max);
                var rightWidth = new[] { font.Measure(powerString).X, font.Measure(timeString).X, font.Measure(costString).X }.Aggregate(Math.Max);

                timeIcon.Bounds.X   = powerIcon.Bounds.X = costIcon.Bounds.X = leftWidth + 2 * nameLabel.Bounds.X;
                timeLabel.Bounds.X  = powerLabel.Bounds.X = costLabel.Bounds.X = timeIcon.Bounds.Right + iconMargin;
                widget.Bounds.Width = leftWidth + rightWidth + 3 * nameLabel.Bounds.X + timeIcon.Bounds.Width + iconMargin;

                var leftHeight  = font.Measure(tooltip.Name).Y + requiresFont.Measure(requiresString).Y + descFont.Measure(descString).Y;
                var rightHeight = font.Measure(powerString).Y + font.Measure(timeString).Y + font.Measure(costString).Y;
                widget.Bounds.Height = Math.Max(leftHeight, rightHeight) * 3 / 2 + 3 * nameLabel.Bounds.Y;

                lastActor = actor;
            };
        }
Exemple #13
0
        void EnumerateMaps(MapClassification tab, ScrollItemWidget template)
        {
            int playerCountFilter;

            if (!int.TryParse(mapFilter, out playerCountFilter))
            {
                playerCountFilter = -1;
            }

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

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

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

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

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

                var titleLabel = item.Get <LabelWidget>("TITLE");
                if (titleLabel != null)
                {
                    var font  = Game.Renderer.Fonts[titleLabel.Font];
                    var title = WidgetUtils.TruncateText(preview.Title, titleLabel.Bounds.Width, font);
                    titleLabel.GetText = () => title;
                }

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

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

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

                var authorWidget = item.GetOrNull <LabelWidget>("AUTHOR");
                if (authorWidget != null)
                {
                    var font   = Game.Renderer.Fonts[authorWidget.Font];
                    var author = WidgetUtils.TruncateText("Created by {0}".F(preview.Author), authorWidget.Bounds.Width, font);
                    authorWidget.GetText = () => author;
                }

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

                scrollpanels[tab].AddChild(item);
            }

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

            if (visibleMaps.Contains(selectedUid))
            {
                scrollpanels[tab].ScrollToItem(selectedUid);
            }
        }
Exemple #14
0
        internal LobbyLogic(Widget widget, World world, OrderManager orderManager,
                            Action onExit, Action onStart, bool addBots)
        {
            lobby             = widget;
            this.orderManager = orderManager;
            this.OnGameStart  = () => { CloseWindow(); onStart(); };
            this.onExit       = onExit;

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

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

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

            UpdateCurrentMap();
            Players           = Ui.LoadWidget <ScrollPanelWidget>("LOBBY_PLAYER_BIN", lobby.Get("PLAYER_BIN_ROOT"), new WidgetArgs());
            Players.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;

            var mapPreview = lobby.Get <MapPreviewWidget>("MAP_PREVIEW");

            mapPreview.IsVisible    = () => Map != null;
            mapPreview.Map          = () => Map;
            mapPreview.OnMouseDown  = mi => LobbyUtils.SelectSpawnPoint(orderManager, mapPreview, Map, mi);
            mapPreview.SpawnClients = () => LobbyUtils.GetSpawnClients(orderManager, Map);

            var mapTitle = lobby.GetOrNull <LabelWidget>("MAP_TITLE");

            if (mapTitle != null)
            {
                mapTitle.IsVisible = () => Map != null;
                mapTitle.GetText   = () => Map.Title;
            }

            var mapType = lobby.GetOrNull <LabelWidget>("MAP_TYPE");

            if (mapType != null)
            {
                mapType.IsVisible = () => Map != null;
                mapType.GetText   = () => Map.Type;
            }

            var mapAuthor = lobby.GetOrNull <LabelWidget>("MAP_AUTHOR");

            if (mapAuthor != null)
            {
                mapAuthor.IsVisible = () => Map != null;
                mapAuthor.GetText   = () => "Created by {0}".F(Map.Author);
            }

            CountryNames = Rules.Info["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 ||
                                                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 <Map>(m =>
                    {
                        orderManager.IssueOrder(Order.Command("map " + m.Uid));
                        Game.Settings.Server.Map = m.Uid;
                        Game.Settings.Save();
                    });

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

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

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

                var aiModes = Rules.Info["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 = aiModes.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 = () => panel == PanelType.Kick;
            optionsButton.GetText    = () => panel == PanelType.Options ? "Players" : "Options";
            optionsButton.OnClick    = () => panel = (panel == PanelType.Options) ? PanelType.Players : PanelType.Options;

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

            if (startGameButton != null)
            {
                startGameButton.IsDisabled = () => configurationDisabled() ||
                                             orderManager.LobbyInfo.Slots.Any(sl => sl.Value.Required && orderManager.LobbyInfo.ClientInSlot(sl.Key) == null);
                startGameButton.OnClick = () =>
                {
                    gameStarting = true;
                    orderManager.IssueOrder(Order.Command("startgame"));
                };
            }

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

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

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

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

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

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

                startingUnits.IsDisabled  = () => !Map.Options.ConfigurableStartingUnits || configurationDisabled();
                startingUnits.GetText     = () => !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.Options.StartingCash.HasValue || configurationDisabled();
                startingCash.GetText     = () => Map.Options.StartingCash.HasValue ? "Not Available" : "${0}".F(orderManager.LobbyInfo.GlobalSettings.StartingCash);
                startingCash.OnMouseDown = _ =>
                {
                    var options = Rules.Info["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 enableShroud = optionsBin.GetOrNull <CheckboxWidget>("SHROUD_CHECKBOX");

            if (enableShroud != null)
            {
                enableShroud.IsChecked  = () => orderManager.LobbyInfo.GlobalSettings.Shroud;
                enableShroud.IsDisabled = () => 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.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(); };

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

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

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

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

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

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

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

            // Add a bot on the first lobbyinfo update
            if (addBots)
            {
                Game.LobbyInfoChanged += WidgetUtils.Once(() =>
                {
                    var slot          = orderManager.LobbyInfo.FirstEmptySlot();
                    var bot           = Rules.Info["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)));
                    }
                });
            }
        }
        public AssetBrowserLogic(Widget widget, Action onExit, ModData modData, World world, Dictionary <string, MiniYaml> logicArgs)
        {
            this.world   = world;
            this.modData = modData;
            panel        = widget;

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

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

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

            if (sourceDropdown != null)
            {
                sourceDropdown.OnMouseDown = _ => ShowSourceDropdown(sourceDropdown);
                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 <VqaPlayerWidget>("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 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;
            }

            filenameInput = panel.Get <TextFieldWidget>("FILENAME_INPUT");
            filenameInput.OnTextEdited = () => ApplyFilter();
            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.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 ?
                                    "{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.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 = "";
                var fs     = modData.DefaultFileSystem as OpenRA.FileSystem.FileSystem;

                if (fs != null)
                {
                    prefix = fs.GetPrefix(package);
                    if (prefix != null)
                    {
                        prefix += "|";
                    }
                }

                if (Path.GetExtension(filename.ToLowerInvariant()) == ".vqa")
                {
                    player = panel.Get <VqaPlayerWidget>("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);
            };

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

            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);
        }
    }
Exemple #16
0
        public ServerListLogic(Widget widget, ModData modData, Action <GameServer> onJoin)
        {
            this.modData = modData;
            this.onJoin  = onJoin;

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

            incompatibleVersionColor       = ChromeMetrics.Get <Color>("IncompatibleVersionColor");
            incompatibleGameColor          = ChromeMetrics.Get <Color>("IncompatibleGameColor");
            incompatibleProtectedGameColor = ChromeMetrics.Get <Color>("IncompatibleProtectedGameColor");
            protectedGameColor             = ChromeMetrics.Get <Color>("ProtectedGameColor");
            waitingGameColor             = ChromeMetrics.Get <Color>("WaitingGameColor");
            incompatibleWaitingGameColor = ChromeMetrics.Get <Color>("IncompatibleWaitingGameColor");
            gameStartedColor             = ChromeMetrics.Get <Color>("GameStartedColor");
            incompatibleGameStartedColor = ChromeMetrics.Get <Color>("IncompatibleGameStartedColor");

            serverList     = widget.Get <ScrollPanelWidget>("SERVER_LIST");
            headerTemplate = serverList.Get <ScrollItemWidget>("HEADER_TEMPLATE");
            serverTemplate = serverList.Get <ScrollItemWidget>("SERVER_TEMPLATE");

            noticeContainer = widget.GetOrNull("NOTICE_CONTAINER");
            if (noticeContainer != null)
            {
                noticeContainer.IsVisible = () => showNotices;
                noticeContainer.Get("OUTDATED_VERSION_LABEL").IsVisible   = () => services.ModVersionStatus == ModVersionStatus.Outdated;
                noticeContainer.Get("UNKNOWN_VERSION_LABEL").IsVisible    = () => services.ModVersionStatus == ModVersionStatus.Unknown;
                noticeContainer.Get("PLAYTEST_AVAILABLE_LABEL").IsVisible = () => services.ModVersionStatus == ModVersionStatus.PlaytestAvailable;
            }

            var noticeWatcher = widget.Get <LogicTickerWidget>("NOTICE_WATCHER");

            if (noticeWatcher != null && noticeContainer != null)
            {
                var containerHeight = noticeContainer.Bounds.Height;
                noticeWatcher.OnTick = () =>
                {
                    var show = services.ModVersionStatus != ModVersionStatus.NotChecked && services.ModVersionStatus != ModVersionStatus.Latest;
                    if (show != showNotices)
                    {
                        var dir = show ? 1 : -1;
                        serverList.Bounds.Y      += dir * containerHeight;
                        serverList.Bounds.Height -= dir * containerHeight;
                        showNotices = show;
                    }
                };
            }

            joinButton = widget.GetOrNull <ButtonWidget>("JOIN_BUTTON");
            if (joinButton != null)
            {
                joinButton.IsVisible  = () => currentServer != null;
                joinButton.IsDisabled = () => !currentServer.IsJoinable;
                joinButton.OnClick    = () => onJoin(currentServer);
                joinButtonY           = joinButton.Bounds.Y;
            }

            // Display the progress label over the server list
            // The text is only visible when the list is empty
            var progressText = widget.Get <LabelWidget>("PROGRESS_LABEL");

            progressText.IsVisible = () => searchStatus != SearchStatus.Hidden;
            progressText.GetText   = ProgressLabelText;

            var gs = Game.Settings.Game;
            Action <MPGameFilters> toggleFilterFlag = f =>
            {
                gs.MPGameFilters ^= f;
                Game.Settings.Save();
                RefreshServerList();
            };

            var filtersButton = widget.GetOrNull <DropDownButtonWidget>("FILTERS_DROPDOWNBUTTON");

            if (filtersButton != null)
            {
                // HACK: MULTIPLAYER_FILTER_PANEL doesn't follow our normal procedure for dropdown creation
                // but we still need to be able to set the dropdown width based on the parent
                // The yaml should use PARENT_RIGHT instead of DROPDOWN_WIDTH
                var filtersPanel = Ui.LoadWidget("MULTIPLAYER_FILTER_PANEL", filtersButton, new WidgetArgs());
                filtersButton.Children.Remove(filtersPanel);

                var showWaitingCheckbox = filtersPanel.GetOrNull <CheckboxWidget>("WAITING_FOR_PLAYERS");
                if (showWaitingCheckbox != null)
                {
                    showWaitingCheckbox.IsChecked = () => gs.MPGameFilters.HasFlag(MPGameFilters.Waiting);
                    showWaitingCheckbox.OnClick   = () => toggleFilterFlag(MPGameFilters.Waiting);
                }

                var showEmptyCheckbox = filtersPanel.GetOrNull <CheckboxWidget>("EMPTY");
                if (showEmptyCheckbox != null)
                {
                    showEmptyCheckbox.IsChecked = () => gs.MPGameFilters.HasFlag(MPGameFilters.Empty);
                    showEmptyCheckbox.OnClick   = () => toggleFilterFlag(MPGameFilters.Empty);
                }

                var showAlreadyStartedCheckbox = filtersPanel.GetOrNull <CheckboxWidget>("ALREADY_STARTED");
                if (showAlreadyStartedCheckbox != null)
                {
                    showAlreadyStartedCheckbox.IsChecked = () => gs.MPGameFilters.HasFlag(MPGameFilters.Started);
                    showAlreadyStartedCheckbox.OnClick   = () => toggleFilterFlag(MPGameFilters.Started);
                }

                var showProtectedCheckbox = filtersPanel.GetOrNull <CheckboxWidget>("PASSWORD_PROTECTED");
                if (showProtectedCheckbox != null)
                {
                    showProtectedCheckbox.IsChecked = () => gs.MPGameFilters.HasFlag(MPGameFilters.Protected);
                    showProtectedCheckbox.OnClick   = () => toggleFilterFlag(MPGameFilters.Protected);
                }

                var showIncompatibleCheckbox = filtersPanel.GetOrNull <CheckboxWidget>("INCOMPATIBLE_VERSION");
                if (showIncompatibleCheckbox != null)
                {
                    showIncompatibleCheckbox.IsChecked = () => gs.MPGameFilters.HasFlag(MPGameFilters.Incompatible);
                    showIncompatibleCheckbox.OnClick   = () => toggleFilterFlag(MPGameFilters.Incompatible);
                }

                filtersButton.IsDisabled  = () => searchStatus == SearchStatus.Fetching;
                filtersButton.OnMouseDown = _ =>
                {
                    filtersButton.RemovePanel();
                    filtersButton.AttachPanel(filtersPanel);
                };
            }

            var reloadButton = widget.GetOrNull <ButtonWidget>("RELOAD_BUTTON");

            if (reloadButton != null)
            {
                reloadButton.IsDisabled = () => searchStatus == SearchStatus.Fetching;
                reloadButton.OnClick    = RefreshServerList;

                var reloadIcon = reloadButton.GetOrNull <ImageWidget>("IMAGE_RELOAD");
                if (reloadIcon != null)
                {
                    var disabledFrame = 0;
                    var disabledImage = "disabled-" + disabledFrame.ToString();
                    reloadIcon.GetImageName = () => searchStatus == SearchStatus.Fetching ? disabledImage : reloadIcon.ImageName;

                    var reloadTicker = reloadIcon.Get <LogicTickerWidget>("ANIMATION");
                    if (reloadTicker != null)
                    {
                        reloadTicker.OnTick = () =>
                        {
                            disabledFrame = searchStatus == SearchStatus.Fetching ? (disabledFrame + 1) % 12 : 0;
                            disabledImage = "disabled-" + disabledFrame.ToString();
                        };
                    }
                }
            }

            var playersLabel = widget.GetOrNull <LabelWidget>("PLAYER_COUNT");

            if (playersLabel != null)
            {
                var playersText = new CachedTransform <int, string>(c => c == 1 ? "1 Player Online" : c.ToString() + " Players Online");
                playersLabel.IsVisible = () => playerCount != 0;
                playersLabel.GetText   = () => playersText.Update(playerCount);
            }

            mapPreview = widget.GetOrNull <MapPreviewWidget>("SELECTED_MAP_PREVIEW");
            if (mapPreview != null)
            {
                mapPreview.Preview = () => currentMap;
            }

            var mapTitle = widget.GetOrNull <LabelWidget>("SELECTED_MAP");

            if (mapTitle != null)
            {
                var font  = Game.Renderer.Fonts[mapTitle.Font];
                var title = new CachedTransform <MapPreview, string>(m => m == null ? "No Server Selected" :
                                                                     WidgetUtils.TruncateText(m.Title, mapTitle.Bounds.Width, font));
                mapTitle.GetText = () => title.Update(currentMap);
            }

            var ip = widget.GetOrNull <LabelWidget>("SELECTED_IP");

            if (ip != null)
            {
                ip.IsVisible = () => currentServer != null;
                ip.GetText   = () => currentServer.Address;
            }

            var status = widget.GetOrNull <LabelWidget>("SELECTED_STATUS");

            if (status != null)
            {
                status.IsVisible = () => currentServer != null;
                status.GetText   = () => GetStateLabel(currentServer);
                status.GetColor  = () => GetStateColor(currentServer, status);
            }

            var modVersion = widget.GetOrNull <LabelWidget>("SELECTED_MOD_VERSION");

            if (modVersion != null)
            {
                modVersion.IsVisible = () => currentServer != null;
                modVersion.GetColor  = () => currentServer.IsCompatible ? modVersion.TextColor : incompatibleVersionColor;

                var font    = Game.Renderer.Fonts[modVersion.Font];
                var version = new CachedTransform <GameServer, string>(s => WidgetUtils.TruncateText(s.ModLabel, modVersion.Bounds.Width, font));
                modVersion.GetText = () => version.Update(currentServer);
            }

            var players = widget.GetOrNull <LabelWidget>("SELECTED_PLAYERS");

            if (players != null)
            {
                players.IsVisible = () => currentServer != null && (clientContainer == null || !currentServer.Clients.Any());
                players.GetText   = () => PlayersLabel(currentServer);
            }

            clientContainer = widget.GetOrNull("CLIENT_LIST_CONTAINER");
            if (clientContainer != null)
            {
                clientList           = Ui.LoadWidget("MULTIPLAYER_CLIENT_LIST", clientContainer, new WidgetArgs()) as ScrollPanelWidget;
                clientList.IsVisible = () => currentServer != null && currentServer.Clients.Any();
                clientHeader         = clientList.Get <ScrollItemWidget>("HEADER");
                clientTemplate       = clientList.Get <ScrollItemWidget>("TEMPLATE");
                clientList.RemoveChildren();
            }

            lanGameLocations = new List <BeaconLocation>();
            try
            {
                lanGameProbe = new Probe("OpenRALANGame");
                lanGameProbe.BeaconsUpdated += locations => lanGameLocations = locations;
                lanGameProbe.Start();
            }
            catch (Exception ex)
            {
                Log.Write("debug", "BeaconLib.Probe: " + ex.Message);
            }

            RefreshServerList();
        }
Exemple #17
0
 protected override void DrawContents()
 {
     this.Sidebar.Buttons.PlayFetchIndex("sell", () => 0);
     WidgetUtils.DrawSpriteCentered(this.Sidebar.Buttons.Image, this.Sidebar.IngameUi.Palette, this.Center + new int2(0, this.Active ? 1 : 0));
 }
Exemple #18
0
        List <Widget> LoadGameRows(List <GameServer> games, out ScrollItemWidget nextServerRow)
        {
            nextServerRow = null;
            var rows = new List <Widget>();
            var mods = games.GroupBy(g => g.ModLabel)
                       .OrderByDescending(g => GroupSortOrder(g.First()))
                       .ThenByDescending(g => g.Count());

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                        rows.Add(item);
                    }
                }
            }

            return(rows);
        }
Exemple #19
0
        void SelectServer(GameServer server)
        {
            currentServer = server;
            currentMap    = server != null ? modData.MapCache[server.Map] : null;

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

                return;
            }

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

            // Can only show factions if the server is running the same mod
            var disableFactionDisplay = server.Mod != modData.Manifest.Id;

            if (server != null && mapPreview != null)
            {
                var spawns    = currentMap.SpawnPoints;
                var occupants = server.Clients
                                .Where(c => (c.SpawnPoint - 1 >= 0) && (c.SpawnPoint - 1 < spawns.Length))
                                .ToDictionary(c => spawns[c.SpawnPoint - 1], c => new SpawnOccupant(c, disableFactionDisplay));

                mapPreview.SpawnOccupants = () => occupants;
            }

            if (clientList == null)
            {
                return;
            }

            clientList.RemoveChildren();

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

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

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

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

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

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

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

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

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

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

                    clientList.AddChild(item);
                }
            }
        }
Exemple #20
0
 public string FormatTime(int ticks, bool leadingMinuteZero = true)
 {
     return(WidgetUtils.FormatTime(ticks, leadingMinuteZero, 40));
 }
Exemple #21
0
        public GameInfoStatsLogic(Widget widget, World world, OrderManager orderManager, WorldRenderer worldRenderer, Action <bool> hideMenu)
        {
            var player      = 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");
            var spectatorTemplate = playerPanel.Get("SPECTATOR_TEMPLATE");

            playerPanel.RemoveChildren();

            var teams = world.Players.Where(p => !p.NonCombatant && p.Playable)
                        .Select(p => (Player: p, PlayerStatistics: p.PlayerActor.TraitOrDefault <PlayerStatistics>()))
                        .OrderByDescending(p => p.PlayerStatistics?.Experience ?? 0)
                        .GroupBy(p => (world.LobbyInfo.ClientWithIndex(p.Player.ClientIndex) ?? new Session.Client()).Team)
                        .OrderByDescending(g => g.Sum(gg => gg.PlayerStatistics?.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");
                    var scoreCache       = new CachedTransform <int, string>(s => s.ToString());
                    var teamMemberScores = t.Select(tt => tt.PlayerStatistics).Where(s => s != null).ToArray().Select(s => s.Experience);
                    teamRating.GetText = () => scoreCache.Update(teamMemberScores.Sum());

                    playerPanel.AddChild(teamHeader);
                }

                foreach (var p in t.ToList())
                {
                    var pp     = p.Player;
                    var client = world.LobbyInfo.ClientWithIndex(pp.ClientIndex);
                    var item   = playerTemplate.Clone();
                    LobbyUtils.SetupProfileWidget(item, client, orderManager, worldRenderer);

                    var nameLabel = item.Get <LabelWidget>("NAME");
                    WidgetUtils.BindPlayerNameAndStatus(nameLabel, pp);
                    nameLabel.GetColor = () => pp.Color;

                    var flag = item.Get <ImageWidget>("FACTIONFLAG");
                    flag.GetImageCollection = () => "flags";
                    if (player == null || player.RelationshipWith(pp) == PlayerRelationship.Ally || player.WinState != WinState.Undefined)
                    {
                        flag.GetImageName = () => pp.Faction.InternalName;
                        var factionName = pp.Faction.Name != pp.DisplayFaction.Name ? "{0} ({1})".F(pp.DisplayFaction.Name, pp.Faction.Name) : pp.Faction.Name;
                        item.Get <LabelWidget>("FACTION").GetText = () => factionName;
                    }
                    else
                    {
                        flag.GetImageName = () => pp.DisplayFaction.InternalName;
                        item.Get <LabelWidget>("FACTION").GetText = () => pp.DisplayFaction.Name;
                    }

                    var scoreCache = new CachedTransform <int, string>(s => s.ToString());
                    item.Get <LabelWidget>("SCORE").GetText = () => scoreCache.Update(p.PlayerStatistics?.Experience ?? 0);

                    playerPanel.AddChild(item);
                }
            }

            var spectators = orderManager.LobbyInfo.Clients.Where(c => c.IsObserver).ToList();

            if (spectators.Any())
            {
                var spectatorHeader = ScrollItemWidget.Setup(teamTemplate, () => true, () => { });
                spectatorHeader.Get <LabelWidget>("TEAM").GetText = () => "Spectators";

                playerPanel.AddChild(spectatorHeader);

                foreach (var client in spectators)
                {
                    var item = spectatorTemplate.Clone();
                    LobbyUtils.SetupProfileWidget(item, client, orderManager, worldRenderer);

                    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 <(string Name, string Suffix), string>(c =>
                                                                                                  WidgetUtils.TruncateText(c.Name, nameLabel.Bounds.Width - suffixLength.Update(c.Suffix), nameFont) + c.Suffix);

                    nameLabel.GetText = () =>
                    {
                        var suffix = client.State == Session.ClientState.Disconnected ? " (Gone)" : "";
                        return(name.Update((client.Name, suffix)));
                    };

                    var kickButton = item.Get <ButtonWidget>("KICK");
                    kickButton.IsVisible = () => Game.IsHost && client.Index != orderManager.LocalClient.Index && client.State != Session.ClientState.Disconnected;
                    kickButton.OnClick   = () =>
                    {
                        hideMenu(true);
                        ConfirmationDialogs.ButtonPrompt(
                            title: "Kick {0}?".F(client.Name),
                            text: "They will not be able to rejoin this game.",
                            onConfirm: () =>
                        {
                            orderManager.IssueOrder(Order.Command("kick {0} {1}".F(client.Index, false)));
                            hideMenu(false);
                        },
                            onCancel: () => hideMenu(false),
                            confirmText: "Kick");
                    };

                    playerPanel.AddChild(item);
                }
            }
        }
Exemple #22
0
        public ServerCreationLogic(Widget widget, ModData modData, Action onExit, Action openLobby)
        {
            panel       = widget;
            onCreate    = openLobby;
            this.onExit = onExit;

            var settings = Game.Settings;

            preview = modData.MapCache[modData.MapCache.ChooseInitialMap(Game.Settings.Server.Map, Game.CosmeticRandom)];

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

            var mapButton = panel.GetOrNull <ButtonWidget>("MAP_BUTTON");

            if (mapButton != null)
            {
                panel.Get <ButtonWidget>("MAP_BUTTON").OnClick = () =>
                {
                    Ui.OpenWindow("MAPCHOOSER_PANEL", new WidgetArgs()
                    {
                        { "initialMap", preview.Uid },
                        { "initialTab", MapClassification.System },
                        { "onExit", () => { } },
                        { "onSelect", (Action <string>)(uid => preview = modData.MapCache[uid]) },
                        { "filter", MapVisibility.Lobby },
                        { "onStart", () => { } }
                    });
                };

                panel.Get <MapPreviewWidget>("MAP_PREVIEW").Preview = () => preview;

                var titleLabel = panel.GetOrNull <LabelWithTooltipWidget>("MAP_TITLE");
                if (titleLabel != 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(preview);
                    titleLabel.GetTooltipText = () => preview.Title;
                }

                var typeLabel = panel.GetOrNull <LabelWidget>("MAP_TYPE");
                if (typeLabel != null)
                {
                    var type = new CachedTransform <MapPreview, string>(m => m.Categories.FirstOrDefault() ?? "");
                    typeLabel.GetText = () => type.Update(preview);
                }

                var authorLabel = panel.GetOrNull <LabelWidget>("MAP_AUTHOR");
                if (authorLabel != null)
                {
                    var font   = Game.Renderer.Fonts[authorLabel.Font];
                    var author = new CachedTransform <MapPreview, string>(
                        m => WidgetUtils.TruncateText("Created by {0}".F(m.Author), authorLabel.Bounds.Width, font));
                    authorLabel.GetText = () => author.Update(preview);
                }
            }

            var serverName = panel.Get <TextFieldWidget>("SERVER_NAME");

            serverName.Text        = Settings.SanitizedServerName(settings.Server.Name);
            serverName.OnEnterKey  = () => { serverName.YieldKeyboardFocus(); return(true); };
            serverName.OnLoseFocus = () =>
            {
                serverName.Text      = Settings.SanitizedServerName(serverName.Text);
                settings.Server.Name = serverName.Text;
            };

            panel.Get <TextFieldWidget>("LISTEN_PORT").Text = settings.Server.ListenPort.ToString();

            advertiseOnline = Game.Settings.Server.AdvertiseOnline;

            var advertiseCheckbox = panel.Get <CheckboxWidget>("ADVERTISE_CHECKBOX");

            advertiseCheckbox.IsChecked = () => advertiseOnline;
            advertiseCheckbox.OnClick   = () =>
            {
                advertiseOnline ^= true;
                BuildNotices();
            };

            var passwordField = panel.GetOrNull <PasswordFieldWidget>("PASSWORD");

            if (passwordField != null)
            {
                passwordField.Text = Game.Settings.Server.Password;
            }

            noticesLabelA = panel.GetOrNull <LabelWidget>("NOTICES_HEADER_A");
            noticesLabelB = panel.GetOrNull <LabelWidget>("NOTICES_HEADER_B");
            noticesLabelC = panel.GetOrNull <LabelWidget>("NOTICES_HEADER_C");

            var noticesNoUPnP = panel.GetOrNull("NOTICES_NO_UPNP");

            if (noticesNoUPnP != null)
            {
                noticesNoUPnP.IsVisible = () => advertiseOnline &&
                                          (Nat.Status == NatStatus.NotSupported || Nat.Status == NatStatus.Disabled);

                var settingsA = noticesNoUPnP.GetOrNull("SETTINGS_A");
                if (settingsA != null)
                {
                    settingsA.IsVisible = () => Nat.Status == NatStatus.Disabled;
                }

                var settingsB = noticesNoUPnP.GetOrNull("SETTINGS_B");
                if (settingsB != null)
                {
                    settingsB.IsVisible = () => Nat.Status == NatStatus.Disabled;
                }
            }

            var noticesUPnP = panel.GetOrNull("NOTICES_UPNP");

            if (noticesUPnP != null)
            {
                noticesUPnP.IsVisible = () => advertiseOnline && Nat.Status == NatStatus.Enabled;
            }

            var noticesLAN = panel.GetOrNull("NOTICES_LAN");

            if (noticesLAN != null)
            {
                noticesLAN.IsVisible = () => !advertiseOnline;
            }

            BuildNotices();
        }
Exemple #23
0
        void SelectMap(MapPreview preview)
        {
            selectedMap = preview;

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

            var briefingVideo        = "";
            var briefingVideoVisible = false;

            var infoVideo        = "";
            var infoVideoVisible = false;

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

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

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

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

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

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

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

            descriptionPanel.ScrollToTop();

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

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

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

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

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

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

                    gameSpeedButton.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
                };
            }
        }
Exemple #24
0
        public ConnectionSwitchModLogic(Widget widget, OrderManager orderManager, NetworkConnection connection, Action onAbort, Action <string> onRetry)
        {
            var panel        = widget;
            var abortButton  = panel.Get <ButtonWidget>("ABORT_BUTTON");
            var switchButton = panel.Get <ButtonWidget>("SWITCH_BUTTON");

            var mod        = CurrentServerSettings.ServerExternalMod;
            var modTitle   = mod.Title;
            var modVersion = mod.Version;

            switchButton.OnClick = () =>
            {
                var launchCommand = $"Launch.URI={new UriBuilder("tcp", connection.EndPoint.Address.ToString(), connection.EndPoint.Port)}";
                Game.SwitchToExternalMod(CurrentServerSettings.ServerExternalMod, new[] { launchCommand }, () =>
                {
                    orderManager.ServerError = "Failed to switch mod.";
                    Ui.CloseWindow();
                    Ui.OpenWindow("CONNECTIONFAILED_PANEL", new WidgetArgs()
                    {
                        { "orderManager", orderManager },
                        { "onAbort", onAbort },
                        { "onRetry", onRetry }
                    });
                });
            };

            abortButton.Visible = onAbort != null;
            abortButton.OnClick = () => { Ui.CloseWindow(); onAbort(); };

            var width = 0;
            var title = panel.GetOrNull <LabelWidget>("MOD_TITLE");

            if (title != null)
            {
                var font       = Game.Renderer.Fonts[title.Font];
                var label      = WidgetUtils.TruncateText(modTitle, title.Bounds.Width, font);
                var labelWidth = font.Measure(label).X;
                width = Math.Max(width, title.Bounds.X + labelWidth);
                title.Bounds.Width = labelWidth;
                title.GetText      = () => label;
            }

            var version = panel.GetOrNull <LabelWidget>("MOD_VERSION");

            if (version != null)
            {
                var font       = Game.Renderer.Fonts[version.Font];
                var label      = WidgetUtils.TruncateText(modVersion, version.Bounds.Width, font);
                var labelWidth = font.Measure(label).X;
                width = Math.Max(width, version.Bounds.X + labelWidth);
                version.Bounds.Width = labelWidth;
                version.GetText      = () => label;
            }

            var logo = panel.GetOrNull <RGBASpriteWidget>("MOD_ICON");

            if (logo != null)
            {
                logo.GetSprite = () =>
                {
                    var ws = Game.Renderer.WindowScale;
                    if (ws > 2 && mod.Icon3x != null)
                    {
                        return(mod.Icon3x);
                    }

                    if (ws > 1 && mod.Icon2x != null)
                    {
                        return(mod.Icon2x);
                    }

                    return(mod.Icon);
                };

                if (mod.Icon == null)
                {
                    // Hide the logo and center just the text
                    if (title != null)
                    {
                        title.Bounds.X = logo.Bounds.X;
                    }

                    if (version != null)
                    {
                        version.Bounds.X = logo.Bounds.X;
                    }

                    width -= logo.Bounds.Width;
                }
                else
                {
                    // Add an equal logo margin on the right of the text
                    width += logo.Bounds.Width;
                }
            }

            var container = panel.GetOrNull("MOD_CONTAINER");

            if (container != null)
            {
                container.Bounds.X    += (container.Bounds.Width - width) / 2;
                container.Bounds.Width = width;
            }
        }
Exemple #25
0
        public MainMenuLogic(Widget widget, World world, ModData modData)
        {
            rootMenu = widget;
            rootMenu.Get <LabelWidget>("VERSION_LABEL").Text = modData.Manifest.Metadata.Version;

            // Menu buttons
            var mainMenu = widget.Get("MAIN_MENU");

            mainMenu.IsVisible = () => menuType == MenuType.Main;

            mainMenu.Get <ButtonWidget>("SINGLEPLAYER_BUTTON").OnClick = () => SwitchMenu(MenuType.Singleplayer);

            mainMenu.Get <ButtonWidget>("MULTIPLAYER_BUTTON").OnClick = () =>
            {
                SwitchMenu(MenuType.None);
                Ui.OpenWindow("MULTIPLAYER_PANEL", new WidgetArgs
                {
                    { "onStart", RemoveShellmapUI },
                    { "onExit", () => SwitchMenu(MenuType.Main) },
                    { "directConnectHost", null },
                    { "directConnectPort", 0 },
                });
            };

            mainMenu.Get <ButtonWidget>("CONTENT_BUTTON").OnClick = () =>
            {
                // Switching mods changes the world state (by disposing it),
                // so we can't do this inside the input handler.
                Game.RunAfterTick(() =>
                {
                    Game.InitializeMod("modcontent", new Arguments(new[] { "Content.Mod=" + modData.Manifest.Id }));
                });
            };

            mainMenu.Get <ButtonWidget>("SETTINGS_BUTTON").OnClick = () =>
            {
                SwitchMenu(MenuType.None);
                Game.OpenWindow("SETTINGS_PANEL", new WidgetArgs
                {
                    { "onExit", () => SwitchMenu(MenuType.Main) }
                });
            };

            mainMenu.Get <ButtonWidget>("EXTRAS_BUTTON").OnClick = () => SwitchMenu(MenuType.Extras);

            mainMenu.Get <ButtonWidget>("QUIT_BUTTON").OnClick = Game.Exit;

            // Singleplayer menu
            var singleplayerMenu = widget.Get("SINGLEPLAYER_MENU");

            singleplayerMenu.IsVisible = () => menuType == MenuType.Singleplayer;

            var missionsButton = singleplayerMenu.Get <ButtonWidget>("MISSIONS_BUTTON");

            missionsButton.OnClick = () =>
            {
                SwitchMenu(MenuType.None);
                Game.OpenWindow("MISSIONBROWSER_PANEL", new WidgetArgs
                {
                    { "onExit", () => SwitchMenu(MenuType.Singleplayer) },
                    { "onStart", RemoveShellmapUI }
                });
            };

            var hasCampaign = modData.Manifest.Missions.Any();
            var hasMissions = modData.MapCache
                              .Any(p => p.Status == MapStatus.Available && p.Visibility.HasFlag(MapVisibility.MissionSelector));

            missionsButton.Disabled = !hasCampaign && !hasMissions;

            singleplayerMenu.Get <ButtonWidget>("SKIRMISH_BUTTON").OnClick = StartSkirmishGame;

            singleplayerMenu.Get <ButtonWidget>("BACK_BUTTON").OnClick = () => SwitchMenu(MenuType.Main);

            // Extras menu
            var extrasMenu = widget.Get("EXTRAS_MENU");

            extrasMenu.IsVisible = () => menuType == MenuType.Extras;

            extrasMenu.Get <ButtonWidget>("REPLAYS_BUTTON").OnClick = () =>
            {
                SwitchMenu(MenuType.None);
                Ui.OpenWindow("REPLAYBROWSER_PANEL", new WidgetArgs
                {
                    { "onExit", () => SwitchMenu(MenuType.Extras) },
                    { "onStart", RemoveShellmapUI }
                });
            };

            extrasMenu.Get <ButtonWidget>("MUSIC_BUTTON").OnClick = () =>
            {
                SwitchMenu(MenuType.None);
                Ui.OpenWindow("MUSIC_PANEL", new WidgetArgs
                {
                    { "onExit", () => SwitchMenu(MenuType.Extras) },
                    { "world", world }
                });
            };

            extrasMenu.Get <ButtonWidget>("MAP_EDITOR_BUTTON").OnClick = () => SwitchMenu(MenuType.MapEditor);

            var assetBrowserButton = extrasMenu.GetOrNull <ButtonWidget>("ASSETBROWSER_BUTTON");

            if (assetBrowserButton != null)
            {
                assetBrowserButton.OnClick = () =>
                {
                    SwitchMenu(MenuType.None);
                    Game.OpenWindow("ASSETBROWSER_PANEL", new WidgetArgs
                    {
                        { "onExit", () => SwitchMenu(MenuType.Extras) },
                    });
                }
            }
            ;

            extrasMenu.Get <ButtonWidget>("CREDITS_BUTTON").OnClick = () =>
            {
                SwitchMenu(MenuType.None);
                Ui.OpenWindow("CREDITS_PANEL", new WidgetArgs
                {
                    { "onExit", () => SwitchMenu(MenuType.Extras) },
                });
            };

            extrasMenu.Get <ButtonWidget>("BACK_BUTTON").OnClick = () => SwitchMenu(MenuType.Main);

            // Map editor menu
            var mapEditorMenu = widget.Get("MAP_EDITOR_MENU");

            mapEditorMenu.IsVisible = () => menuType == MenuType.MapEditor;

            // Loading into the map editor
            Game.BeforeGameStart += RemoveShellmapUI;

            var onSelect = new Action <string>(uid => LoadMapIntoEditor(modData.MapCache[uid].Uid));

            var newMapButton = widget.Get <ButtonWidget>("NEW_MAP_BUTTON");

            newMapButton.OnClick = () =>
            {
                SwitchMenu(MenuType.None);
                Game.OpenWindow("NEW_MAP_BG", new WidgetArgs()
                {
                    { "onSelect", onSelect },
                    { "onExit", () => SwitchMenu(MenuType.MapEditor) }
                });
            };

            var loadMapButton = widget.Get <ButtonWidget>("LOAD_MAP_BUTTON");

            loadMapButton.OnClick = () =>
            {
                SwitchMenu(MenuType.None);
                Game.OpenWindow("MAPCHOOSER_PANEL", new WidgetArgs()
                {
                    { "initialMap", null },
                    { "initialTab", MapClassification.User },
                    { "onExit", () => SwitchMenu(MenuType.MapEditor) },
                    { "onSelect", onSelect },
                    { "filter", MapVisibility.Lobby | MapVisibility.Shellmap | MapVisibility.MissionSelector },
                });
            };

            mapEditorMenu.Get <ButtonWidget>("BACK_BUTTON").OnClick = () => SwitchMenu(MenuType.Extras);

            var newsBG = widget.GetOrNull("NEWS_BG");

            if (newsBG != null)
            {
                newsBG.IsVisible = () => Game.Settings.Game.FetchNews && menuType != MenuType.None && menuType != MenuType.SystemInfoPrompt;

                newsPanel    = Ui.LoadWidget <ScrollPanelWidget>("NEWS_PANEL", null, new WidgetArgs());
                newsTemplate = newsPanel.Get("NEWS_ITEM_TEMPLATE");
                newsPanel.RemoveChild(newsTemplate);

                newsStatus = newsPanel.Get <LabelWidget>("NEWS_STATUS");
                SetNewsStatus("Loading news");
            }

            Game.OnRemoteDirectConnect += OnRemoteDirectConnect;

            var newsURL = modData.Manifest.Get <WebServices>().GameNews;

            // System information opt-out prompt
            var sysInfoPrompt = widget.Get("SYSTEM_INFO_PROMPT");

            sysInfoPrompt.IsVisible = () => menuType == MenuType.SystemInfoPrompt;
            if (Game.Settings.Debug.SystemInformationVersionPrompt < SystemInformationVersion)
            {
                menuType = MenuType.SystemInfoPrompt;

                var sysInfoCheckbox = sysInfoPrompt.Get <CheckboxWidget>("SYSINFO_CHECKBOX");
                sysInfoCheckbox.IsChecked = () => Game.Settings.Debug.SendSystemInformation;
                sysInfoCheckbox.OnClick   = () => Game.Settings.Debug.SendSystemInformation ^= true;

                var sysInfoData = sysInfoPrompt.Get <ScrollPanelWidget>("SYSINFO_DATA");
                var template    = sysInfoData.Get <LabelWidget>("DATA_TEMPLATE");
                sysInfoData.RemoveChildren();

                foreach (var info in GetSystemInformation().Values)
                {
                    var label = template.Clone() as LabelWidget;
                    var text  = info.First + ": " + info.Second;
                    label.GetText = () => text;
                    sysInfoData.AddChild(label);
                }

                sysInfoPrompt.Get <ButtonWidget>("BACK_BUTTON").OnClick = () =>
                {
                    Game.Settings.Debug.SystemInformationVersionPrompt = SystemInformationVersion;
                    Game.Settings.Save();
                    SwitchMenu(MenuType.Main);
                    LoadAndDisplayNews(newsURL, newsBG);
                };
            }
            else
            {
                LoadAndDisplayNews(newsURL, newsBG);
            }
        }

        void LoadAndDisplayNews(string newsURL, Widget newsBG)
        {
            if (newsBG != null)
            {
                var cacheFile   = Platform.ResolvePath("^", "news.yaml");
                var currentNews = ParseNews(cacheFile);
                if (currentNews != null)
                {
                    DisplayNews(currentNews);
                }

                var newsButton = newsBG.GetOrNull <DropDownButtonWidget>("NEWS_BUTTON");
                if (newsButton != null)
                {
                    if (!fetchedNews)
                    {
                        // Send the mod and engine version to support version-filtered news (update prompts)
                        newsURL += "?version={0}&mod={1}&modversion={2}".F(
                            Uri.EscapeUriString(Game.Mods["modcontent"].Metadata.Version),
                            Uri.EscapeUriString(Game.ModData.Manifest.Id),
                            Uri.EscapeUriString(Game.ModData.Manifest.Metadata.Version));

                        // Append system profile data if the player has opted in
                        if (Game.Settings.Debug.SendSystemInformation)
                        {
                            newsURL += "&sysinfoversion={0}&".F(SystemInformationVersion)
                                       + GetSystemInformation()
                                       .Select(kv => kv.Key + "=" + Uri.EscapeUriString(kv.Value.Second))
                                       .JoinWith("&");
                        }

                        new Download(newsURL, cacheFile, e => { },
                                     e => NewsDownloadComplete(e, cacheFile, currentNews,
                                                               () => newsButton.AttachPanel(newsPanel)));
                    }

                    newsButton.OnClick = () => newsButton.AttachPanel(newsPanel);
                }
            }
        }

        void OnRemoteDirectConnect(string host, int port)
        {
            SwitchMenu(MenuType.None);
            Ui.OpenWindow("MULTIPLAYER_PANEL", new WidgetArgs
            {
                { "onStart", RemoveShellmapUI },
                { "onExit", () => SwitchMenu(MenuType.Main) },
                { "directConnectHost", host },
                { "directConnectPort", port },
            });
        }

        void LoadMapIntoEditor(string uid)
        {
            ConnectionLogic.Connect(IPAddress.Loopback.ToString(),
                                    Game.CreateLocalServer(uid),
                                    "",
                                    () => { Game.LoadEditor(uid); },
                                    () => { Game.CloseServer(); SwitchMenu(MenuType.MapEditor); });
        }

        void SetNewsStatus(string message)
        {
            message            = WidgetUtils.WrapText(message, newsStatus.Bounds.Width, Game.Renderer.Fonts[newsStatus.Font]);
            newsStatus.GetText = () => message;
        }
Exemple #26
0
        public static void InitializeMod(string mod, Arguments args)
        {
            // Clear static state if we have switched mods
            LobbyInfoChanged       = () => { };
            ConnectionStateChanged = om => { };
            BeforeGameStart        = () => { };
            OnRemoteDirectConnect  = (a, b) => { };
            delayedActions         = new ActionQueue();

            Ui.ResetAll();

            if (worldRenderer != null)
            {
                worldRenderer.Dispose();
            }
            worldRenderer = null;
            if (server != null)
            {
                server.Shutdown();
            }
            if (OrderManager != null)
            {
                OrderManager.Dispose();
            }

            if (ModData != null)
            {
                ModData.Dispose();
            }
            ModData = null;

            // Fall back to default if the mod doesn't exist
            if (!ModMetadata.AllMods.ContainsKey(mod))
            {
                mod = new GameSettings().Mod;
            }

            Console.WriteLine("Loading mod: {0}", mod);
            Settings.Game.Mod = mod;

            Sound.StopMusic();
            Sound.StopVideo();
            Sound.Initialize();

            ModData = new ModData(mod, !Settings.Server.Dedicated);
            ModData.InitializeLoaders();
            if (!Settings.Server.Dedicated)
            {
                Renderer.InitializeFonts(ModData.Manifest);
            }

            using (new PerfTimer("LoadMaps"))
                ModData.MapCache.LoadMaps();

            if (Settings.Graphics.HardwareCursors)
            {
                try
                {
                    Cursor = new HardwareCursor(ModData.CursorProvider);
                }
                catch (Exception e)
                {
                    Log.Write("debug", "Failed to initialize hardware cursors. Falling back to software cursors.");
                    Log.Write("debug", "Error was: " + e.Message);

                    Console.WriteLine("Failed to initialize hardware cursors. Falling back to software cursors.");
                    Console.WriteLine("Error was: " + e.Message);

                    Cursor = new SoftwareCursor(ModData.CursorProvider);
                    Settings.Graphics.HardwareCursors = false;
                }
            }
            else
            {
                Cursor = new SoftwareCursor(ModData.CursorProvider);
            }

            PerfHistory.Items["render"].HasNormalTick         = false;
            PerfHistory.Items["batches"].HasNormalTick        = false;
            PerfHistory.Items["render_widgets"].HasNormalTick = false;
            PerfHistory.Items["render_flip"].HasNormalTick    = false;

            JoinLocal();

            if (Settings.Server.Dedicated)
            {
                while (true)
                {
                    Settings.Server.Map = WidgetUtils.ChooseInitialMap(Settings.Server.Map);
                    Settings.Save();
                    CreateServer(new ServerSettings(Settings.Server));
                    while (true)
                    {
                        Thread.Sleep(100);

                        if (server.State == Server.ServerState.GameStarted && server.Conns.Count < 1)
                        {
                            Console.WriteLine("No one is playing, shutting down...");
                            server.Shutdown();
                            break;
                        }
                    }

                    if (Settings.Server.DedicatedLoop)
                    {
                        Console.WriteLine("Starting a new server instance...");
                        ModData.MapCache.LoadMaps();
                        continue;
                    }

                    break;
                }

                Environment.Exit(0);
            }
            else
            {
                ModData.LoadScreen.StartGame(args);
            }
        }
Exemple #27
0
        public ReplayBrowserLogic(Widget widget, ModData modData, Action onExit, Action onStart)
        {
            map   = MapCache.UnknownMap;
            panel = widget;

            services              = modData.Manifest.Get <WebServices>();
            this.modData          = modData;
            this.onStart          = onStart;
            Game.BeforeGameStart += OnGameStart;

            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 = modData.Manifest;
            var dir = Platform.ResolvePath(Platform.SupportDirPrefix, "Replays", mod.Id, mod.Metadata.Version);

            if (Directory.Exists(dir))
            {
                ThreadPool.QueueUserWorkItem(_ => LoadReplays(dir, template));
            }

            var watch = panel.Get <ButtonWidget>("WATCH_BUTTON");

            watch.IsDisabled = () => selectedReplay == null || map.Status != MapStatus.Available;
            watch.OnClick    = () => { WatchReplay(); };

            var mapPreviewRoot = panel.Get("MAP_PREVIEW_ROOT");

            mapPreviewRoot.IsVisible           = () => selectedReplay != null;
            panel.Get("REPLAY_INFO").IsVisible = () => selectedReplay != null;

            Ui.LoadWidget("MAP_PREVIEW", mapPreviewRoot, new WidgetArgs
            {
                { "orderManager", null },
                { "getMap", (Func <MapPreview>)(() => map) },
                { "onMouseDown", (Action <MapPreviewWidget, MapPreview, MouseInput>)((preview, mapPreview, mi) => { }) },
                {
                    "getSpawnOccupants", (Func <MapPreview, Dictionary <CPos, SpawnOccupant> >)(mapPreview =>
                                                                                                LobbyUtils.GetSpawnOccupants(selectedReplay.GameInfo.Players, mapPreview))
                },
                { "showUnoccupiedSpawnpoints", false },
            });

            var replayDuration = new CachedTransform <ReplayMetadata, string>(r =>
                                                                              "Duration: {0}".F(WidgetUtils.FormatTimeSeconds((int)selectedReplay.GameInfo.Duration.TotalSeconds)));

            panel.Get <LabelWidget>("DURATION").GetText = () => replayDuration.Update(selectedReplay);

            SetupFilters();
            SetupManagement();
        }
Exemple #28
0
        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);
                }
            }

            var spectators = orderManager.LobbyInfo.Clients.Where(c => c.IsObserver).ToList();

            if (spectators.Any())
            {
                var spectatorHeader = ScrollItemWidget.Setup(teamTemplate, () => true, () => { });
                spectatorHeader.Get <LabelWidget>("TEAM").GetText = () => "Spectators";

                playerPanel.AddChild(spectatorHeader);

                foreach (var client in spectators)
                {
                    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 = client.State == Session.ClientState.Disconnected ? " (Gone)" : "";
                        var sl     = suffixLength.Update(suffix);
                        return(name.Update(Pair.New(client.Name, sl)) + suffix);
                    };

                    item.Get <ImageWidget>("FACTIONFLAG").IsVisible = () => false;
                    playerPanel.AddChild(item);
                }
            }
        }
        public SupportPowerTooltipLogic(Widget widget, TooltipContainerWidget tooltipContainer, Func <SupportPowersWidget.SupportPowerIcon> getTooltipIcon, World world)
        {
            widget.IsVisible = () => getTooltipIcon() != null && getTooltipIcon().Power.Info != null;
            var nameLabel   = widget.Get <LabelWidget>("NAME");
            var hotkeyLabel = widget.Get <LabelWidget>("HOTKEY");
            var timeLabel   = widget.Get <LabelWidget>("TIME");
            var descLabel   = widget.Get <LabelWidget>("DESC");
            var nameFont    = Game.Renderer.Fonts[nameLabel.Font];
            var hotkeyFont  = Game.Renderer.Fonts[hotkeyLabel.Font];
            var timeFont    = Game.Renderer.Fonts[timeLabel.Font];
            var descFont    = Game.Renderer.Fonts[descLabel.Font];
            var baseHeight  = widget.Bounds.Height;
            var timeOffset  = timeLabel.Bounds.X;

            SupportPowerInstance lastPower = null;
            Hotkey lastHotkey           = Hotkey.Invalid;
            var    lastRemainingSeconds = 0;

            tooltipContainer.BeforeRender = () =>
            {
                var icon = getTooltipIcon();
                if (icon == null || icon.Power == null || icon.Power.Instances.Count == 0)
                {
                    return;
                }

                var sp = icon.Power;

                // HACK: This abuses knowledge of the internals of WidgetUtils.FormatTime
                // to efficiently work when the label is going to change, requiring a panel relayout
                var remainingSeconds = (int)Math.Ceiling(sp.RemainingTicks * world.Timestep / 1000f);

                var hotkey = icon.Hotkey?.GetValue() ?? Hotkey.Invalid;
                if (sp == lastPower && hotkey == lastHotkey && lastRemainingSeconds == remainingSeconds)
                {
                    return;
                }

                nameLabel.Text = sp.Info.Description;
                var nameSize = nameFont.Measure(nameLabel.Text);

                descLabel.Text = sp.Info.LongDesc.Replace("\\n", "\n");
                var descSize = descFont.Measure(descLabel.Text);

                var customLabel = sp.TooltipTimeTextOverride();
                if (customLabel == null)
                {
                    var remaining = WidgetUtils.FormatTime(sp.RemainingTicks, world.Timestep);
                    var total     = WidgetUtils.FormatTime(sp.Info.ChargeInterval, world.Timestep);
                    timeLabel.Text = $"{remaining} / {total}";
                }
                else
                {
                    timeLabel.Text = customLabel;
                }

                var timeSize    = timeFont.Measure(timeLabel.Text);
                var hotkeyWidth = 0;
                hotkeyLabel.Visible = hotkey.IsValid();
                if (hotkeyLabel.Visible)
                {
                    var hotkeyText = $"({hotkey.DisplayString()})";

                    hotkeyWidth          = hotkeyFont.Measure(hotkeyText).X + 2 * nameLabel.Bounds.X;
                    hotkeyLabel.Text     = hotkeyText;
                    hotkeyLabel.Bounds.X = nameSize.X + 2 * nameLabel.Bounds.X;
                }

                var timeWidth = timeSize.X;
                var topWidth  = nameSize.X + hotkeyWidth + timeWidth + timeOffset;
                widget.Bounds.Width  = 2 * nameLabel.Bounds.X + Math.Max(topWidth, descSize.X);
                widget.Bounds.Height = baseHeight + descSize.Y;
                timeLabel.Bounds.X   = widget.Bounds.Width - nameLabel.Bounds.X - timeWidth;

                lastPower            = sp;
                lastHotkey           = hotkey;
                lastRemainingSeconds = remainingSeconds;
            };

            timeLabel.GetColor = () => getTooltipIcon() != null && !getTooltipIcon().Power.Active
                                ? Color.Red : Color.White;
        }
Exemple #30
0
        void SelectReplay(ReplayMetadata replay)
        {
            selectedReplay = replay;
            map            = selectedReplay != null ? selectedReplay.GameInfo.MapPreview : MapCache.UnknownMap;

            if (replay == null)
            {
                return;
            }

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

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

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

                playerList.RemoveChildren();

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

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

                        var color = o.Color;

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