Exemplo n.º 1
0
        public override void Display()
        {
            if (r == null || loadTimer.Elapsed.TotalSeconds < 0.25)
            {
                return;
            }

            loadTimer.Restart();

            loadTick = ++loadTick % 8;
            r.BeginFrame(int2.Zero, 1f);
            r.RgbaSpriteRenderer.DrawSprite(gdiLogo, gdiPos);
            r.RgbaSpriteRenderer.DrawSprite(nodLogo, nodPos);
            r.RgbaSpriteRenderer.DrawSprite(evaLogo, evaPos);

            WidgetUtils.DrawPanelPartial(bounds, PanelSides.Edges,
                                         borderTop, borderBottom, borderLeft, borderRight,
                                         cornerTopLeft, cornerTopRight, cornerBottomLeft, cornerBottomRight,
                                         null);
            var barY = bounds.Height - 78;

            // The fonts dictionary may change when switching between the mod and content installer
            if (r.Fonts != rendererFonts)
            {
                rendererFonts = r.Fonts;
                loadingFont   = r.Fonts["BigBold"];
                loadingText   = loadInfo["Text"];
                loadingPos    = new float2((bounds.Width - loadingFont.Measure(loadingText).X) / 2, barY);

                versionFont = r.Fonts["Regular"];
                var versionSize = versionFont.Measure(versionText);
                versionPos = new float2(bounds.Width - 107 - versionSize.X / 2, 115 - versionSize.Y / 2);
            }

            if (loadingFont != null)
            {
                loadingFont.DrawText(loadingText, loadingPos, Color.Gray);
            }
            if (versionFont != null)
            {
                versionFont.DrawTextWithContrast(versionText, versionPos, Color.White, Color.Black, 2);
            }

            for (var i = 0; i <= 8; i++)
            {
                var block = loadTick == i ? brightBlock : dimBlock;
                r.RgbaSpriteRenderer.DrawSprite(block,
                                                new float2(bounds.Width / 2 - 114 - i * 32, barY));
                r.RgbaSpriteRenderer.DrawSprite(block,
                                                new float2(bounds.Width / 2 + 114 + i * 32 - 16, barY));
            }

            r.EndFrame(nih);
        }
        public void Display()
        {
            var r = Game.Renderer;

            if (r == null)
            {
                return;
            }

            r.BeginFrame(int2.Zero, 1f);
            WidgetUtils.FillRectWithSprite(bounds, sprite);
            r.EndFrame(new NullInputHandler());
        }
Exemplo n.º 3
0
        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());
        }
        public override void Draw()
        {
            productionIcons.Clear();
            productionIconsBounds.Clear();

            var player = GetPlayer();

            if (player == null)
            {
                return;
            }

            var queues = world.ActorsWithTrait <ProductionQueue>()
                         .Where(a => a.Actor.Owner == player)
                         .Select((a, i) => new { a.Trait, i });

            foreach (var queue in queues)
            {
                if (!clocks.ContainsKey(queue.Trait))
                {
                    clocks.Add(queue.Trait, new Animation(world, ClockAnimation));
                }
            }

            var currentItemsByItem = queues
                                     .Select(a => a.Trait.CurrentItem())
                                     .Where(pi => pi != null)
                                     .GroupBy(pr => pr.Item)
                                     .OrderBy(g => g.First().Queue.Info.DisplayOrder)
                                     .ThenBy(g => g.First().BuildPaletteOrder)
                                     .ToList();

            Bounds.Width = currentItemsByItem.Count * (IconWidth + IconSpacing);

            var queueCol = 0;

            foreach (var currentItems in currentItemsByItem)
            {
                var current = currentItems.OrderBy(pi => pi.Done ? 0 : (pi.Paused ? 2 : 1)).ThenBy(q => q.RemainingTimeActual).First();
                var queue   = current.Queue;

                var faction = queue.Actor.Owner.Faction.InternalName;
                var actor   = queue.AllItems().FirstOrDefault(a => a.Name == current.Item);
                if (actor == null)
                {
                    continue;
                }

                var rsi  = actor.TraitInfo <RenderSpritesInfo>();
                var icon = new Animation(world, rsi.GetImage(actor, world.Map.Rules.Sequences, faction));
                var bi   = actor.TraitInfo <BuildableInfo>();

                icon.Play(bi.Icon);
                var topLeftOffset = new float2(queueCol * (IconWidth + IconSpacing), 0);

                var iconTopLeft    = RenderOrigin + topLeftOffset;
                var centerPosition = iconTopLeft;

                WidgetUtils.DrawSHPCentered(icon.Image, centerPosition + 0.5f * iconSize, worldRenderer.Palette(bi.IconPalette), 0.5f);

                productionIcons.Add(new ProductionIcon {
                    Actor = actor, ProductionQueue = current.Queue
                });
                productionIconsBounds.Add(new Rectangle((int)iconTopLeft.X, (int)iconTopLeft.Y, (int)iconSize.X, (int)iconSize.Y));

                var pio = queue.Actor.Owner.PlayerActor.TraitsImplementing <IProductionIconOverlay>()
                          .FirstOrDefault(p => p.IsOverlayActive(actor));

                if (pio != null)
                {
                    WidgetUtils.DrawSHPCentered(pio.Sprite, centerPosition + 0.5f * iconSize + pio.Offset(iconSize),
                                                worldRenderer.Palette(pio.Palette), 0.5f);
                }

                var clock = clocks[queue];
                clock.PlayFetchIndex(ClockSequence, () => current.TotalTime == 0 ? 0 :
                                     (current.TotalTime - current.RemainingTime) * (clock.CurrentSequence.Length - 1) / current.TotalTime);

                clock.Tick();
                WidgetUtils.DrawSHPCentered(clock.Image, centerPosition + 0.5f * iconSize, worldRenderer.Palette(ClockPalette), 0.5f);

                var tiny = Game.Renderer.Fonts["Tiny"];
                var text = GetOverlayForItem(current, timestep);
                tiny.DrawTextWithContrast(text,
                                          centerPosition + new float2(16, 12) - new float2(tiny.Measure(text).X / 2, 0),
                                          Color.White, Color.Black, 1);

                if (currentItems.Count() > 1)
                {
                    var bold = Game.Renderer.Fonts["Small"];
                    text = currentItems.Count().ToString();
                    bold.DrawTextWithContrast(text, centerPosition + new float2(16, 0) - new float2(bold.Measure(text).X / 2, 0),
                                              Color.White, Color.Black, 1);
                }

                queueCol++;
            }
        }
Exemplo n.º 5
0
        public override void Draw()
        {
            var iconOffset = 0.5f * IconSize.ToFloat2() + IconSpriteOffset;

            overlayFont  = Game.Renderer.Fonts["TinyBold"];
            timeOffset   = iconOffset - overlayFont.Measure(WidgetUtils.FormatTime(0, World.Timestep)) / 2;
            queuedOffset = new float2(4, 2);
            holdOffset   = iconOffset - overlayFont.Measure(HoldText) / 2;
            readyOffset  = iconOffset - overlayFont.Measure(ReadyText) / 2;

            if (CurrentQueue == null)
            {
                return;
            }

            var buildableItems = CurrentQueue.BuildableItems();

            var pios = currentQueue.Actor.Owner.PlayerActor.TraitsImplementing <IProductionIconOverlay>();

            // Icons
            foreach (var icon in icons.Values)
            {
                WidgetUtils.DrawSHPCentered(icon.Sprite, icon.Pos + iconOffset, icon.Palette);

                // Draw the ProductionIconOverlay's sprite
                var pio = pios.FirstOrDefault(p => p.IsOverlayActive(icon.Actor));
                if (pio != null)
                {
                    WidgetUtils.DrawSHPCentered(pio.Sprite, icon.Pos + iconOffset + pio.Offset(IconSize), worldRenderer.Palette(pio.Palette), 1f);
                }

                // Build progress
                if (icon.Queued.Count > 0)
                {
                    var first = icon.Queued[0];
                    clock.PlayFetchIndex(ClockSequence,
                                         () => (first.TotalTime - first.RemainingTime)
                                         * (clock.CurrentSequence.Length - 1) / first.TotalTime);
                    clock.Tick();

                    WidgetUtils.DrawSHPCentered(clock.Image, icon.Pos + iconOffset, icon.IconClockPalette);
                }
                else if (!buildableItems.Any(a => a.Name == icon.Name))
                {
                    WidgetUtils.DrawSHPCentered(cantBuild.Image, icon.Pos + iconOffset, icon.IconDarkenPalette);
                }
            }

            // Overlays
            foreach (var icon in icons.Values)
            {
                var total = icon.Queued.Count;
                if (total > 0)
                {
                    var first   = icon.Queued[0];
                    var waiting = first != CurrentQueue.CurrentItem() && !first.Done;
                    if (first.Done)
                    {
                        if (ReadyTextStyle == ReadyTextStyleOptions.Solid || orderManager.LocalFrameNumber * worldRenderer.World.Timestep / 360 % 2 == 0)
                        {
                            overlayFont.DrawTextWithContrast(ReadyText, icon.Pos + readyOffset, Color.White, Color.Black, 1);
                        }
                        else if (ReadyTextStyle == ReadyTextStyleOptions.AlternatingColor)
                        {
                            overlayFont.DrawTextWithContrast(ReadyText, icon.Pos + readyOffset, ReadyTextAltColor, Color.Black, 1);
                        }
                    }
                    else if (first.Paused)
                    {
                        overlayFont.DrawTextWithContrast(HoldText,
                                                         icon.Pos + holdOffset,
                                                         Color.White, Color.Black, 1);
                    }
                    else if (!waiting)
                    {
                        overlayFont.DrawTextWithContrast(WidgetUtils.FormatTime(first.RemainingTimeActual, World.Timestep),
                                                         icon.Pos + timeOffset,
                                                         Color.White, Color.Black, 1);
                    }

                    if (total > 1 || waiting)
                    {
                        overlayFont.DrawTextWithContrast(total.ToString(),
                                                         icon.Pos + queuedOffset,
                                                         Color.White, Color.Black, 1);
                    }
                }
            }
        }
Exemplo n.º 6
0
 public override void Draw()
 {
     WidgetUtils.FillRectWithColor(RenderBounds, GetColor());
 }
        public override void Draw()
        {
            var player = GetPlayer();

            if (player == null)
            {
                return;
            }

            var queues = world.ActorsWithTrait <ProductionQueue>()
                         .Where(a => a.Actor.Owner == player)
                         .Select((a, i) => new { a.Trait, i });

            foreach (var queue in queues)
            {
                if (!clocks.ContainsKey(queue.Trait))
                {
                    clocks.Add(queue.Trait, new Animation(world, ClockAnimation));
                }
            }

            var iconSize = new float2(IconWidth, IconHeight);

            foreach (var queue in queues)
            {
                var current = queue.Trait.CurrentItem();
                if (current == null)
                {
                    continue;
                }

                var faction = queue.Trait.Actor.Owner.Faction.InternalName;
                var actor   = queue.Trait.AllItems().FirstOrDefault(a => a.Name == current.Item);
                if (actor == null)
                {
                    continue;
                }

                var rsi  = actor.TraitInfo <RenderSpritesInfo>();
                var icon = new Animation(world, rsi.GetImage(actor, world.Map.SequenceProvider, faction));
                icon.Play(actor.TraitInfo <TooltipInfo>().Icon);
                var bi       = actor.TraitInfo <BuildableInfo>();
                var location = new float2(RenderBounds.Location) + new float2(queue.i * (IconWidth + IconSpacing), 0);
                WidgetUtils.DrawSHPCentered(icon.Image, location + 0.5f * iconSize, worldRenderer.Palette(bi.IconPalette), 0.5f);

                var pio = queue.Trait.Actor.Owner.PlayerActor.TraitsImplementing <IProductionIconOverlay>()
                          .FirstOrDefault(p => p.IsOverlayActive(actor));
                if (pio != null)
                {
                    WidgetUtils.DrawSHPCentered(pio.Sprite, location + 0.5f * iconSize + pio.Offset(0.5f * iconSize),
                                                worldRenderer.Palette(pio.Palette), 0.5f);
                }

                var clock = clocks[queue.Trait];
                clock.PlayFetchIndex(ClockSequence,
                                     () => current.TotalTime == 0 ? 0 : ((current.TotalTime - current.RemainingTime)
                                                                         * (clock.CurrentSequence.Length - 1) / current.TotalTime));
                clock.Tick();
                WidgetUtils.DrawSHPCentered(clock.Image, location + 0.5f * iconSize, worldRenderer.Palette(ClockPalette), 0.5f);

                var tiny = Game.Renderer.Fonts["Tiny"];
                var text = GetOverlayForItem(current, world.Timestep);
                tiny.DrawTextWithContrast(text,
                                          location + new float2(16, 16) - new float2(tiny.Measure(text).X / 2, 0),
                                          Color.White, Color.Black, 1);
            }
        }
Exemplo n.º 8
0
        public override void Draw()
        {
            if (!initialised)
            {
                Init();
            }

            if (!IsVisible())
            {
                return;
            }

            var rb     = RenderBounds;
            var offset = int2.Zero;

            var svc = world.Players.Select(p => p.PlayerActor.TraitOrDefault <StrategicVictoryConditions>()).FirstOrDefault();

            var totalWidth = svc.Total * 32;
            var curX       = -totalWidth / 2;

            foreach (var a in svc.AllPoints)
            {
                WidgetUtils.DrawRGBA(ChromeProvider.GetImage("strategic", "critical_unowned"), offset + new float2(rb.Left + curX, rb.Top));

                if (world.LocalPlayer != null && WorldUtils.AreMutualAllies(a.Actor.Owner, world.LocalPlayer))
                {
                    WidgetUtils.DrawRGBA(ChromeProvider.GetImage("strategic", "player_owned"), offset + new float2(rb.Left + curX, rb.Top));
                }
                else if (!a.Actor.Owner.NonCombatant)
                {
                    WidgetUtils.DrawRGBA(ChromeProvider.GetImage("strategic", "enemy_owned"), offset + new float2(rb.Left + curX, rb.Top));
                }

                curX += 32;
            }

            offset += new int2(0, 32);

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

            if (pendingWinner == null)
            {
                return;
            }
            var winnerSvc = pendingWinner.PlayerActor.Trait <StrategicVictoryConditions>();

            var isVictory = pendingWinner == world.LocalPlayer || !WorldUtils.AreMutualAllies(pendingWinner, world.LocalPlayer);
            var tc        = "Strategic {0} in {1}".F(
                isVictory ? "victory" : "defeat",
                WidgetUtils.FormatTime(winnerSvc.TicksLeft));

            var font = Game.Renderer.Fonts["Bold"];

            var size = font.Measure(tc);

            font.DrawTextWithContrast(tc, offset + new float2(rb.Left - size.X / 2 + 1, rb.Top + 1), Color.White, Color.Black, 1);
            offset += new int2(0, size.Y + 1);
        }
Exemplo n.º 9
0
 public string FormatTime(int ticks, bool leadingMinuteZero = true)
 {
     return(WidgetUtils.FormatTime(ticks, leadingMinuteZero, 40));
 }
Exemplo n.º 10
0
        public override void Draw()
        {
            var pos         = RenderOrigin;
            var chatLogArea = new Rectangle(pos.X, pos.Y, Bounds.Width, Bounds.Height);
            var chatPos     = new int2(chatLogArea.X + 5, chatLogArea.Bottom - 8);

            var font = Game.Renderer.Fonts["Regular"];

            Game.Renderer.EnableScissor(chatLogArea);

            foreach (var line in recentLines.AsEnumerable().Reverse())
            {
                var    lineHeight = TextLineBoxHeight;
                var    inset      = 0;
                string name       = null;

                if (!string.IsNullOrEmpty(line.Name))
                {
                    name  = line.Name + ":";
                    inset = font.Measure(name).X + 5;
                }

                var text     = WidgetUtils.WrapText(line.Text, chatLogArea.Width - inset - 6, font);
                var textSize = font.Measure(text).Y;
                var offset   = font.TopOffset;

                if (chatPos.Y - font.TopOffset < pos.Y)
                {
                    break;
                }

                var textLineHeight = lineHeight;

                var dh = textSize - textLineHeight;
                if (dh > 0)
                {
                    textLineHeight += dh;
                }

                var textOffset = textLineHeight - (textLineHeight - textSize - offset) / 2;
                var textPos    = new int2(chatPos.X + inset, chatPos.Y - textOffset);

                if (name != null)
                {
                    var nameSize = font.Measure(name).Y;
                    var namePos  = chatPos.WithY(chatPos.Y - (textLineHeight - (lineHeight - nameSize - offset) / 2));

                    if (UseContrast)
                    {
                        font.DrawTextWithContrast(name, namePos,
                                                  line.NameColor, BackgroundColorDark, BackgroundColorLight, 1);
                    }
                    else if (UseShadow)
                    {
                        font.DrawTextWithShadow(name, namePos,
                                                line.NameColor, BackgroundColorDark, BackgroundColorLight, 1);
                    }
                    else
                    {
                        font.DrawText(name, namePos, line.NameColor);
                    }
                }

                if (UseContrast)
                {
                    font.DrawTextWithContrast(text, textPos,
                                              line.TextColor, Color.Black, 1);
                }
                else if (UseShadow)
                {
                    font.DrawTextWithShadow(text, textPos,
                                            line.TextColor, Color.Black, 1);
                }
                else
                {
                    font.DrawText(text, textPos, Color.White);
                }

                chatPos = chatPos.WithY(chatPos.Y - Space - textLineHeight);
            }

            Game.Renderer.DisableScissor();
        }
Exemplo n.º 11
0
        public override void Draw()
        {
            var iconOffset = 0.5f * IconSize.ToFloat2() + IconSpriteOffset;

            overlayFont  = Game.Renderer.Fonts["TinyBold"];
            timeOffset   = iconOffset - overlayFont.Measure(WidgetUtils.FormatTime(0)) / 2;
            queuedOffset = new float2(4, 2);
            holdOffset   = iconOffset - overlayFont.Measure(HoldText) / 2;
            readyOffset  = iconOffset - overlayFont.Measure(ReadyText) / 2;

            if (CurrentQueue == null)
            {
                return;
            }

            var buildableItems = CurrentQueue.BuildableItems();

            // Icons
            foreach (var icon in icons.Values)
            {
                WidgetUtils.DrawSHPCentered(icon.Sprite, icon.Pos + iconOffset, worldRenderer);

                // Build progress
                if (icon.Queued.Count > 0)
                {
                    var first = icon.Queued[0];
                    clock.PlayFetchIndex("idle",
                                         () => (first.TotalTime - first.RemainingTime)
                                         * (clock.CurrentSequence.Length - 1) / first.TotalTime);
                    clock.Tick();

                    WidgetUtils.DrawSHPCentered(clock.Image, icon.Pos + iconOffset, worldRenderer);
                }
                else if (!buildableItems.Any(a => a.Name == icon.Name))
                {
                    WidgetUtils.DrawSHPCentered(cantBuild.Image, icon.Pos + iconOffset, worldRenderer);
                }
            }

            // Overlays
            foreach (var icon in icons.Values)
            {
                var total = icon.Queued.Count;
                if (total > 0)
                {
                    var first   = icon.Queued[0];
                    var waiting = first != CurrentQueue.CurrentItem() && !first.Done;
                    if (first.Done)
                    {
                        if (ReadyTextStyle == ReadyTextStyleOptions.Solid || orderManager.LocalFrameNumber / 9 % 2 == 0)
                        {
                            overlayFont.DrawTextWithContrast(ReadyText, icon.Pos + readyOffset, Color.White, Color.Black, 1);
                        }
                        else if (ReadyTextStyle == ReadyTextStyleOptions.AlternatingColor)
                        {
                            overlayFont.DrawTextWithContrast(ReadyText, icon.Pos + readyOffset, ReadyTextAltColor, Color.Black, 1);
                        }
                    }
                    else if (first.Paused)
                    {
                        overlayFont.DrawTextWithContrast(HoldText,
                                                         icon.Pos + holdOffset,
                                                         Color.White, Color.Black, 1);
                    }
                    else if (!waiting)
                    {
                        overlayFont.DrawTextWithContrast(WidgetUtils.FormatTime(first.RemainingTimeActual),
                                                         icon.Pos + timeOffset,
                                                         Color.White, Color.Black, 1);
                    }

                    if (total > 1 || waiting)
                    {
                        overlayFont.DrawTextWithContrast(total.ToString(),
                                                         icon.Pos + queuedOffset,
                                                         Color.White, Color.Black, 1);
                    }
                }
            }
        }
Exemplo n.º 12
0
        public override void Draw()
        {
            var pos         = RenderOrigin;
            var chatLogArea = new Rectangle(pos.X, pos.Y, Bounds.Width, Bounds.Height);
            var chatpos     = new int2(chatLogArea.X + 5, chatLogArea.Bottom - 5);

            var font = Game.Renderer.Fonts["Regular"];

            Game.Renderer.EnableScissor(chatLogArea);

            foreach (var line in recentLines.AsEnumerable().Reverse())
            {
                var    inset = 0;
                string owner = null;

                if (!string.IsNullOrEmpty(line.Owner))
                {
                    owner = line.Owner + ":";
                    inset = font.Measure(owner).X + 5;
                }

                var text = WidgetUtils.WrapText(line.Text, chatLogArea.Width - inset - 6, font);
                chatpos = chatpos.WithY(chatpos.Y - (Math.Max(15, font.Measure(text).Y) + 5));

                if (chatpos.Y < pos.Y)
                {
                    break;
                }

                if (owner != null)
                {
                    if (UseContrast)
                    {
                        font.DrawTextWithContrast(owner, chatpos,
                                                  line.Color, BackgroundColorDark, BackgroundColorLight, 1);
                    }
                    else if (UseShadow)
                    {
                        font.DrawTextWithShadow(owner, chatpos,
                                                line.Color, BackgroundColorDark, BackgroundColorLight, 1);
                    }
                    else
                    {
                        font.DrawText(owner, chatpos, line.Color);
                    }
                }

                if (UseContrast)
                {
                    font.DrawTextWithContrast(text, chatpos + new int2(inset, 0),
                                              Color.White, Color.Black, 1);
                }
                else if (UseShadow)
                {
                    font.DrawTextWithShadow(text, chatpos + new int2(inset, 0),
                                            Color.White, Color.Black, 1);
                }
                else
                {
                    font.DrawText(text, chatpos + new int2(inset, 0), Color.White);
                }
            }

            Game.Renderer.DisableScissor();
        }
Exemplo n.º 13
0
        public override void Draw()
        {
            supportPowerIconsIcons.Clear();
            supportPowerIconsBounds.Clear();

            var player = GetPlayer();

            if (player == null)
            {
                return;
            }

            var powers = player.PlayerActor.Trait <SupportPowerManager>().Powers
                         .Where(x => !x.Value.Disabled && x.Value.GetLevel() != 0)
                         .OrderBy(p => p.Value.Info.SupportPowerPaletteOrder)
                         .Select((a, i) => new { a, i })
                         .ToList();

            foreach (var power in powers)
            {
                if (!clocks.ContainsKey(power.a.Key))
                {
                    clocks.Add(power.a.Key, new Animation(world, ClockAnimation));
                }
            }

            Bounds.Width = powers.Count() * (IconWidth + IconSpacing);

            Game.Renderer.EnableAntialiasingFilter();

            var iconSize = new float2(IconWidth, IconHeight);

            foreach (var power in powers)
            {
                var item = power.a.Value;
                if (item == null || item.Info == null || item.Info.Icons == null)
                {
                    continue;
                }

                var level = item.GetLevel();
                icon = new Animation(worldRenderer.World, item.Info.IconImage);
                icon.Play(item.Info.Icons.First(i => i.Key == level).Value);
                var location = new float2(RenderBounds.Location) + new float2(power.i * (IconWidth + IconSpacing), 0);

                supportPowerIconsIcons.Add(new SupportPowersWidget.SupportPowerIcon {
                    Power = item, Pos = location
                });
                supportPowerIconsBounds.Add(new Rectangle((int)location.X, (int)location.Y, (int)iconSize.X, (int)iconSize.Y));

                WidgetUtils.DrawSHPCentered(icon.Image, location + 0.5f * iconSize, worldRenderer.Palette(item.Info.IconPalette), 0.5f);

                var clock = clocks[power.a.Key];
                clock.PlayFetchIndex(ClockSequence,
                                     () => item.TotalTicks == 0 ? 0 : ((item.TotalTicks - item.RemainingTicks)
                                                                       * (clock.CurrentSequence.Length - 1) / item.TotalTicks));
                clock.Tick();
                WidgetUtils.DrawSHPCentered(clock.Image, location + 0.5f * iconSize, worldRenderer.Palette(ClockPalette), 0.5f);
            }

            Game.Renderer.DisableAntialiasingFilter();

            var tiny = Game.Renderer.Fonts["Tiny"];

            foreach (var icon in supportPowerIconsIcons)
            {
                var text = GetOverlayForItem(icon.Power, timestep);
                tiny.DrawTextWithContrast(text,
                                          icon.Pos + new float2(16, 12) - new float2(tiny.Measure(text).X / 2, 0),
                                          Color.White, Color.Black, 1);
            }
        }
Exemplo n.º 14
0
        void IWorldLoaded.WorldLoaded(World w, OpenRA.Graphics.WorldRenderer wr)
        {
            mapOptions = w.WorldActor.Trait <MapOptions>();
            if (string.IsNullOrWhiteSpace(info.CountdownLabel) || string.IsNullOrWhiteSpace(info.CountdownText))
            {
                return;
            }

            countdownLabel = Ui.Root.GetOrNull <LabelWidget>(info.CountdownLabel);
            if (countdownLabel != null)
            {
                countdown = new OpenRA.Mods.Common.Widgets.CachedTransform <int, string>(t =>
                                                                                         info.CountdownText.F(WidgetUtils.FormatTime(t, true, w.IsReplay ? mapOptions.GameSpeed.Timestep : w.Timestep)));
                countdownLabel.GetText = () => countdown.Update(ticksRemaining);
            }
        }
Exemplo n.º 15
0
 public override void Draw()
 {
     WidgetUtils.DrawPanel(Background, RenderBounds);
 }
Exemplo n.º 16
0
 public override void Draw()
 {
     WidgetUtils.FillRectWithColor(RenderBounds, GetTopLeftColor(), GetTopRightColor(), GetBottomRightColor(), GetBottomLeftColor());
 }
Exemplo n.º 17
0
        public static void BindButtonIcon(ButtonWidget button)
        {
            var icon = button.Get <ImageWidget>("ICON");

            var hasActiveImage         = ChromeProvider.GetImage(icon.ImageCollection, icon.ImageName + "-active") != null;
            var hasActiveDisabledImage = ChromeProvider.GetImage(icon.ImageCollection, icon.ImageName + "-active-disabled") != null;
            var hasActivePressedImage  = ChromeProvider.GetImage(icon.ImageCollection, icon.ImageName + "-active-pressed") != null;
            var hasActiveHoverImage    = ChromeProvider.GetImage(icon.ImageCollection, icon.ImageName + "-active-hover") != null;

            var hasImage         = ChromeProvider.GetImage(icon.ImageCollection, icon.ImageName) != null;
            var hasDisabledImage = ChromeProvider.GetImage(icon.ImageCollection, icon.ImageName + "-disabled") != null;
            var hasPressedImage  = ChromeProvider.GetImage(icon.ImageCollection, icon.ImageName + "-pressed") != null;
            var hasHoverImage    = ChromeProvider.GetImage(icon.ImageCollection, icon.ImageName + "-hover") != null;

            icon.GetImageName = () =>
            {
                var isActive   = button.IsHighlighted();
                var isDisabled = button.IsDisabled();
                var isPressed  = button.Depressed;
                var isHovered  = Ui.MouseOverWidget == button;

                var baseName  = button.IsHighlighted() ? icon.ImageName + "-active" : icon.ImageName;
                var stateName = WidgetUtils.GetStatefulImageName(baseName, isDisabled, isPressed, isHovered);

                if (isActive)
                {
                    if (isDisabled)
                    {
                        return(hasActiveDisabledImage ? stateName : hasActiveImage?baseName : icon.ImageName);
                    }
                    else if (isPressed)
                    {
                        return(hasActivePressedImage ? stateName : hasActiveImage?baseName : icon.ImageName);
                    }
                    else if (isHovered)
                    {
                        return(hasActiveHoverImage ? stateName : hasActiveImage?baseName : icon.ImageName);
                    }
                    else
                    {
                        return(hasActiveImage ? baseName : icon.ImageName);
                    }
                }
                else
                {
                    if (isDisabled)
                    {
                        return(hasDisabledImage ? stateName : baseName);
                    }
                    else if (isPressed)
                    {
                        return(hasPressedImage ? stateName : baseName);
                    }
                    else if (isHovered)
                    {
                        return(hasHoverImage ? stateName : baseName);
                    }
                    else
                    {
                        return(baseName);
                    }
                }
            };
        }
        public override void Draw()
        {
            var apparentText = GetApparentText();
            var font         = Game.Renderer.Fonts[Font];
            var pos          = RenderOrigin;

            var textSize       = font.Measure(apparentText);
            var cursorPosition = font.Measure(apparentText.Substring(0, CursorPosition));

            var disabled = IsDisabled();
            var state    = disabled ? "textfield-disabled" :
                           HasKeyboardFocus ? "textfield-focused" :
                           Ui.MouseOverWidget == this || Children.Any(c => c == Ui.MouseOverWidget) ? "textfield-hover" :
                           "textfield";

            WidgetUtils.DrawPanel(state,
                                  new Rectangle(pos.X, pos.Y, Bounds.Width, Bounds.Height));

            // Inset text by the margin and center vertically
            var verticalMargin = (Bounds.Height - textSize.Y) / 2 - VisualHeight;
            var textPos        = pos + new int2(LeftMargin, verticalMargin);

            // Right align when editing and scissor when the text overflows
            if (textSize.X > Bounds.Width - LeftMargin - RightMargin)
            {
                if (HasKeyboardFocus)
                {
                    textPos += new int2(Bounds.Width - LeftMargin - RightMargin - textSize.X, 0);
                }

                Game.Renderer.EnableScissor(new Rectangle(pos.X + LeftMargin, pos.Y,
                                                          Bounds.Width - LeftMargin - RightMargin, Bounds.Bottom));
            }

            // Draw the highlight around the selected area
            if (selectionStartIndex != -1)
            {
                var visualSelectionStartIndex = selectionStartIndex < selectionEndIndex ? selectionStartIndex : selectionEndIndex;
                var visualSelectionEndIndex   = selectionStartIndex < selectionEndIndex ? selectionEndIndex : selectionStartIndex;
                var highlightStartX           = font.Measure(apparentText.Substring(0, visualSelectionStartIndex)).X;
                var highlightEndX             = font.Measure(apparentText.Substring(0, visualSelectionEndIndex)).X;

                WidgetUtils.FillRectWithColor(
                    new Rectangle(textPos.X + highlightStartX, textPos.Y, highlightEndX - highlightStartX, Bounds.Height - (verticalMargin * 2)), TextColorHighlight);
            }

            var color =
                disabled ? TextColorDisabled
                                : IsValid() ? TextColor
                                : TextColorInvalid;

            font.DrawText(apparentText, textPos, color);

            if (showCursor && HasKeyboardFocus)
            {
                font.DrawText("|", new float2(textPos.X + cursorPosition.X - 2, textPos.Y), TextColor);
            }

            if (textSize.X > Bounds.Width - LeftMargin - RightMargin)
            {
                Game.Renderer.DisableScissor();
            }
        }
Exemplo n.º 19
0
        public override void Draw()
        {
            var preview = Preview();

            if (preview == null)
            {
                return;
            }

            // Stash a copy of the minimap to ensure consistency
            // (it may be modified by another thread)
            minimap = preview.GetMinimap();
            if (minimap == null)
            {
                return;
            }

            // Update map rect
            previewScale = Math.Min(RenderBounds.Width / minimap.Size.X, RenderBounds.Height / minimap.Size.Y);
            var w = (int)(previewScale * minimap.Size.X);
            var h = (int)(previewScale * minimap.Size.Y);
            var x = RenderBounds.X + (RenderBounds.Width - w) / 2;
            var y = RenderBounds.Y + (RenderBounds.Height - h) / 2;

            mapRect = new Rectangle(x, y, w, h);

            Game.Renderer.RgbaSpriteRenderer.DrawSprite(minimap, new float2(mapRect.Location), new float2(mapRect.Size));

            TooltipSpawnIndex = -1;
            if (ShowSpawnPoints)
            {
                var spawnPoints         = preview.SpawnPoints;
                var occupants           = SpawnOccupants();
                var disabledSpawnPoints = DisabledSpawnPoints();
                var gridType            = preview.GridType;
                for (var i = 0; i < spawnPoints.Length; i++)
                {
                    var p = spawnPoints[i];

                    // Spawn numbers are 1 indexed with 0 meaning "random spawn".
                    var occupied = occupants.TryGetValue(i + 1, out var occupant);
                    var disabled = disabledSpawnPoints.Contains(i + 1);
                    var pos      = ConvertToPreview(p, gridType);

                    var sprite = disabled ? spawnDisabled : occupied ? spawnClaimed : spawnUnclaimed;
                    var offset = sprite.Size.XY.ToInt2() / 2;

                    if (((pos - Viewport.LastMousePos).ToFloat2() / offset.ToFloat2()).LengthSquared <= 1)
                    {
                        TooltipSpawnIndex = spawnPoints.IndexOf(p) + 1;
                    }

                    if (disabled)
                    {
                        Game.Renderer.RgbaSpriteRenderer.DrawSprite(spawnDisabled, pos - offset);
                        continue;
                    }

                    if (occupied)
                    {
                        WidgetUtils.FillEllipseWithColor(new Rectangle(pos.X - offset.X + 1, pos.Y - offset.Y + 1, (int)sprite.Size.X - 2, (int)sprite.Size.Y - 2), occupant.Color);
                    }

                    Game.Renderer.RgbaSpriteRenderer.DrawSprite(sprite, pos - offset);

                    var number     = Convert.ToChar('A' + spawnPoints.IndexOf(p)).ToString();
                    var textOffset = spawnFont.Measure(number) / 2 + spawnLabelOffset;

                    spawnFont.DrawTextWithContrast(number, pos - textOffset, spawnColor, spawnContrastColor, 1);
                }
            }
        }
Exemplo n.º 20
0
        public override void Draw()
        {
            SpriteFont font;

            if (!Game.Renderer.Fonts.TryGetValue(Font, out font))
            {
                throw new ArgumentException("Requested font '{0}' was not found.".F(Font));
            }

            var text = GetText();

            if (text == null)
            {
                return;
            }

            var textSize = font.Measure(text);
            var position = RenderOrigin;
            var offset   = font.TopOffset;

            if (VAlign == TextVAlign.Top)
            {
                position += new int2(0, -offset);
            }

            if (VAlign == TextVAlign.Middle)
            {
                position += new int2(0, (Bounds.Height - textSize.Y - offset) / 2);
            }

            if (VAlign == TextVAlign.Bottom)
            {
                position += new int2(0, Bounds.Height - textSize.Y);
            }

            if (Align == TextAlign.Center)
            {
                position += new int2((Bounds.Width - textSize.X) / 2, 0);
            }

            if (Align == TextAlign.Right)
            {
                position += new int2(Bounds.Width - textSize.X, 0);
            }

            if (WordWrap)
            {
                text = WidgetUtils.WrapText(text, Bounds.Width, font);
            }

            var color   = GetColor();
            var bgDark  = GetContrastColorDark();
            var bgLight = GetContrastColorLight();

            if (Contrast)
            {
                font.DrawTextWithContrast(text, position, color, bgDark, bgLight, 2);
            }
            else if (Shadow)
            {
                font.DrawTextWithShadow(text, position, color, bgDark, bgLight, 1);
            }
            else
            {
                font.DrawText(text, position, color);
            }
        }
Exemplo n.º 21
0
        public CommandBarLogic(Widget widget, World world, Dictionary <string, MiniYaml> logicArgs)
        {
            this.world = world;

            var highlightOnButtonPress = false;

            if (logicArgs.ContainsKey("HighlightOnButtonPress"))
            {
                highlightOnButtonPress = FieldLoader.GetValue <bool>("HighlightOnButtonPress", logicArgs["HighlightOnButtonPress"].Value);
            }

            var attackMoveButton = widget.GetOrNull <ButtonWidget>("ATTACK_MOVE");

            if (attackMoveButton != null)
            {
                WidgetUtils.BindButtonIcon(attackMoveButton);

                attackMoveButton.IsDisabled    = () => { UpdateStateIfNecessary(); return(attackMoveDisabled); };
                attackMoveButton.IsHighlighted = () => world.OrderGenerator is AttackMoveOrderGenerator;

                Action <bool> toggle = allowCancel =>
                {
                    if (attackMoveButton.IsHighlighted())
                    {
                        if (allowCancel)
                        {
                            world.CancelInputMode();
                        }
                    }
                    else
                    {
                        world.OrderGenerator = new AttackMoveOrderGenerator(selectedActors, Game.Settings.Game.MouseButtonPreference.Action);
                    }
                };

                attackMoveButton.OnClick    = () => toggle(true);
                attackMoveButton.OnKeyPress = _ => toggle(false);
            }

            var forceMoveButton = widget.GetOrNull <ButtonWidget>("FORCE_MOVE");

            if (forceMoveButton != null)
            {
                WidgetUtils.BindButtonIcon(forceMoveButton);

                forceMoveButton.IsDisabled    = () => { UpdateStateIfNecessary(); return(forceMoveDisabled); };
                forceMoveButton.IsHighlighted = () => !forceMoveButton.IsDisabled() && IsForceModifiersActive(Modifiers.Alt);
                forceMoveButton.OnClick       = () =>
                {
                    if (forceMoveButton.IsHighlighted())
                    {
                        world.CancelInputMode();
                    }
                    else
                    {
                        world.OrderGenerator = new ForceModifiersOrderGenerator(Modifiers.Alt, true);
                    }
                };
            }

            var forceAttackButton = widget.GetOrNull <ButtonWidget>("FORCE_ATTACK");

            if (forceAttackButton != null)
            {
                WidgetUtils.BindButtonIcon(forceAttackButton);

                forceAttackButton.IsDisabled    = () => { UpdateStateIfNecessary(); return(forceAttackDisabled); };
                forceAttackButton.IsHighlighted = () => !forceAttackButton.IsDisabled() && IsForceModifiersActive(Modifiers.Ctrl) &&
                                                  !(world.OrderGenerator is AttackMoveOrderGenerator);

                forceAttackButton.OnClick = () =>
                {
                    if (forceAttackButton.IsHighlighted())
                    {
                        world.CancelInputMode();
                    }
                    else
                    {
                        world.OrderGenerator = new ForceModifiersOrderGenerator(Modifiers.Ctrl, true);
                    }
                };
            }

            var guardButton = widget.GetOrNull <ButtonWidget>("GUARD");

            if (guardButton != null)
            {
                WidgetUtils.BindButtonIcon(guardButton);

                guardButton.IsDisabled    = () => { UpdateStateIfNecessary(); return(guardDisabled); };
                guardButton.IsHighlighted = () => world.OrderGenerator is GuardOrderGenerator;

                Action <bool> toggle = allowCancel =>
                {
                    if (guardButton.IsHighlighted())
                    {
                        if (allowCancel)
                        {
                            world.CancelInputMode();
                        }
                    }
                    else
                    {
                        world.OrderGenerator = new GuardOrderGenerator(selectedActors,
                                                                       "Guard", "guard", Game.Settings.Game.MouseButtonPreference.Action);
                    }
                };

                guardButton.OnClick    = () => toggle(true);
                guardButton.OnKeyPress = _ => toggle(false);
            }

            var scatterButton = widget.GetOrNull <ButtonWidget>("SCATTER");

            if (scatterButton != null)
            {
                WidgetUtils.BindButtonIcon(scatterButton);

                scatterButton.IsDisabled    = () => { UpdateStateIfNecessary(); return(scatterDisabled); };
                scatterButton.IsHighlighted = () => scatterHighlighted > 0;
                scatterButton.OnClick       = () =>
                {
                    if (highlightOnButtonPress)
                    {
                        scatterHighlighted = 2;
                    }

                    PerformKeyboardOrderOnSelection(a => new Order("Scatter", a, false));
                };

                scatterButton.OnKeyPress = ki => { scatterHighlighted = 2; scatterButton.OnClick(); };
            }

            var deployButton = widget.GetOrNull <ButtonWidget>("DEPLOY");

            if (deployButton != null)
            {
                WidgetUtils.BindButtonIcon(deployButton);

                deployButton.IsDisabled = () =>
                {
                    UpdateStateIfNecessary();

                    var queued = Game.GetModifierKeys().HasModifier(Modifiers.Shift);
                    return(!selectedDeploys.Any(pair => pair.Trait.CanIssueDeployOrder(pair.Actor, queued)));
                };

                deployButton.IsHighlighted = () => deployHighlighted > 0;
                deployButton.OnClick       = () =>
                {
                    if (highlightOnButtonPress)
                    {
                        deployHighlighted = 2;
                    }

                    var queued = Game.GetModifierKeys().HasModifier(Modifiers.Shift);
                    PerformDeployOrderOnSelection(queued);
                };

                deployButton.OnKeyPress = ki => { deployHighlighted = 2; deployButton.OnClick(); };
            }

            var stopButton = widget.GetOrNull <ButtonWidget>("STOP");

            if (stopButton != null)
            {
                WidgetUtils.BindButtonIcon(stopButton);

                stopButton.IsDisabled    = () => { UpdateStateIfNecessary(); return(stopDisabled); };
                stopButton.IsHighlighted = () => stopHighlighted > 0;
                stopButton.OnClick       = () =>
                {
                    if (highlightOnButtonPress)
                    {
                        stopHighlighted = 2;
                    }

                    PerformKeyboardOrderOnSelection(a => new Order("Stop", a, false));
                };

                stopButton.OnKeyPress = ki => { stopHighlighted = 2; stopButton.OnClick(); };
            }

            var queueOrdersButton = widget.GetOrNull <ButtonWidget>("QUEUE_ORDERS");

            if (queueOrdersButton != null)
            {
                WidgetUtils.BindButtonIcon(queueOrdersButton);

                queueOrdersButton.IsDisabled    = () => { UpdateStateIfNecessary(); return(waypointModeDisabled); };
                queueOrdersButton.IsHighlighted = () => !queueOrdersButton.IsDisabled() && IsForceModifiersActive(Modifiers.Shift);
                queueOrdersButton.OnClick       = () =>
                {
                    if (queueOrdersButton.IsHighlighted())
                    {
                        world.CancelInputMode();
                    }
                    else
                    {
                        world.OrderGenerator = new ForceModifiersOrderGenerator(Modifiers.Shift, false);
                    }
                };
            }

            var keyOverrides = widget.GetOrNull <LogicKeyListenerWidget>("MODIFIER_OVERRIDES");

            if (keyOverrides != null)
            {
                var noShiftButtons = new[] { guardButton, deployButton, attackMoveButton };
                var keyUpButtons   = new[] { guardButton, attackMoveButton };
                keyOverrides.AddHandler(e =>
                {
                    // HACK: allow command buttons to be triggered if the shift (queue order modifier) key is held
                    if (e.Modifiers.HasModifier(Modifiers.Shift))
                    {
                        var eNoShift        = e;
                        eNoShift.Modifiers &= ~Modifiers.Shift;

                        foreach (var b in noShiftButtons)
                        {
                            // Button is not used by this mod
                            if (b == null)
                            {
                                continue;
                            }

                            // Button is not valid for this event
                            if (b.IsDisabled() || !b.Key.IsActivatedBy(eNoShift))
                            {
                                continue;
                            }

                            // Event is not valid for this button
                            if (!(b.DisableKeyRepeat ^ e.IsRepeat) || (e.Event == KeyInputEvent.Up && !keyUpButtons.Contains(b)))
                            {
                                continue;
                            }

                            b.OnKeyPress(e);
                            return(true);
                        }
                    }

                    // HACK: Attack move can be triggered if the ctrl (assault move modifier)
                    // or shift (queue order modifier) keys are pressed, on both key down and key up
                    var eNoMods        = e;
                    eNoMods.Modifiers &= ~(Modifiers.Ctrl | Modifiers.Shift);

                    if (attackMoveButton != null && !attackMoveDisabled && attackMoveButton.Key.IsActivatedBy(eNoMods))
                    {
                        attackMoveButton.OnKeyPress(e);
                        return(true);
                    }

                    return(false);
                });
            }
        }
Exemplo n.º 22
0
        public override void DrawOuter()
        {
            if (!IsVisible())
            {
                return;
            }

            UpdateSmoothScrolling();

            var rb = RenderBounds;

            var scrollbarHeight = rb.Height - 2 * ScrollbarWidth;

            var thumbHeight = ContentHeight == 0 ? 0 : Math.Max(MinimumThumbSize, (int)(scrollbarHeight * Math.Min(rb.Height * 1f / ContentHeight, 1f)));
            var thumbOrigin = rb.Y + ScrollbarWidth + (int)((scrollbarHeight - thumbHeight) * (-1f * currentListOffset / (ContentHeight - rb.Height)));

            if (thumbHeight == scrollbarHeight)
            {
                thumbHeight = 0;
            }

            switch (ScrollBar)
            {
            case ScrollBar.Left:
                backgroundRect = new Rectangle(rb.X + ScrollbarWidth, rb.Y, rb.Width + 1, rb.Height);
                upButtonRect   = new Rectangle(rb.X, rb.Y, ScrollbarWidth, ScrollbarWidth);
                downButtonRect = new Rectangle(rb.X, rb.Bottom - ScrollbarWidth, ScrollbarWidth, ScrollbarWidth);
                scrollbarRect  = new Rectangle(rb.X, rb.Y + ScrollbarWidth - 1, ScrollbarWidth, scrollbarHeight + 2);
                thumbRect      = new Rectangle(rb.X, thumbOrigin, ScrollbarWidth, thumbHeight);
                break;

            case ScrollBar.Right:
                backgroundRect = new Rectangle(rb.X, rb.Y, rb.Width - ScrollbarWidth + 1, rb.Height);
                upButtonRect   = new Rectangle(rb.Right - ScrollbarWidth, rb.Y, ScrollbarWidth, ScrollbarWidth);
                downButtonRect = new Rectangle(rb.Right - ScrollbarWidth, rb.Bottom - ScrollbarWidth, ScrollbarWidth, ScrollbarWidth);
                scrollbarRect  = new Rectangle(rb.Right - ScrollbarWidth, rb.Y + ScrollbarWidth - 1, ScrollbarWidth, scrollbarHeight + 2);
                thumbRect      = new Rectangle(rb.Right - ScrollbarWidth, thumbOrigin, ScrollbarWidth, thumbHeight);
                break;

            case ScrollBar.Hidden:
                backgroundRect = new Rectangle(rb.X, rb.Y, rb.Width + 1, rb.Height);
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            WidgetUtils.DrawPanel(Background, backgroundRect);

            if (ScrollBar != ScrollBar.Hidden)
            {
                var upHover = Ui.MouseOverWidget == this && upButtonRect.Contains(Viewport.LastMousePos);
                upDisabled = thumbHeight == 0 || currentListOffset >= 0;

                var downHover = Ui.MouseOverWidget == this && downButtonRect.Contains(Viewport.LastMousePos);
                downDisabled = thumbHeight == 0 || currentListOffset <= Bounds.Height - ContentHeight;

                var thumbHover = Ui.MouseOverWidget == this && thumbRect.Contains(Viewport.LastMousePos);
                WidgetUtils.DrawPanel(ScrollBarBackground, scrollbarRect);
                ButtonWidget.DrawBackground(Button, upButtonRect, upDisabled, upPressed, upHover, false);
                ButtonWidget.DrawBackground(Button, downButtonRect, downDisabled, downPressed, downHover, false);

                if (thumbHeight > 0)
                {
                    ButtonWidget.DrawBackground(Button, thumbRect, false, HasMouseFocus && thumbHover, thumbHover, false);
                }

                var upOffset   = !upPressed || upDisabled ? 4 : 4 + ButtonDepth;
                var downOffset = !downPressed || downDisabled ? 4 : 4 + ButtonDepth;

                WidgetUtils.DrawRGBA(ChromeProvider.GetImage("scrollbar", upPressed || upDisabled ? "up_pressed" : "up_arrow"),
                                     new float2(upButtonRect.Left + upOffset, upButtonRect.Top + upOffset));
                WidgetUtils.DrawRGBA(ChromeProvider.GetImage("scrollbar", downPressed || downDisabled ? "down_pressed" : "down_arrow"),
                                     new float2(downButtonRect.Left + downOffset, downButtonRect.Top + downOffset));
            }

            var drawBounds = backgroundRect.InflateBy(-BorderWidth, -BorderWidth, -BorderWidth, -BorderWidth);

            Game.Renderer.EnableScissor(drawBounds);

            // ChildOrigin enumerates the widget tree, so only evaluate it once
            var co = ChildOrigin;

            drawBounds.X -= co.X;
            drawBounds.Y -= co.Y;

            foreach (var child in Children)
            {
                if (child.Bounds.IntersectsWith(drawBounds))
                {
                    child.DrawOuter();
                }
            }

            Game.Renderer.DisableScissor();
        }
Exemplo n.º 23
0
        public override void Draw()
        {
            if (video == null)
            {
                return;
            }

            if (!stopped && !paused)
            {
                var nextFrame = 0;
                if (video.HasAudio && !Game.Sound.DummyEngine)
                {
                    nextFrame = (int)float2.Lerp(0, video.Frames, Game.Sound.VideoSeekPosition * invLength);
                }
                else
                {
                    nextFrame = video.CurrentFrame + 1;
                }

                // Without the 2nd check the sound playback sometimes ends before the final frame is displayed which causes the player to be stuck on the first frame
                if (nextFrame > video.Frames || nextFrame < video.CurrentFrame)
                {
                    Stop();
                    return;
                }

                var skippedFrames = 0;
                while (nextFrame > video.CurrentFrame)
                {
                    video.AdvanceFrame();
                    videoSprite.Sheet.GetTexture().SetData(video.FrameData);
                    skippedFrames++;
                }

                if (skippedFrames > 1)
                {
                    Log.Write("perf", "VqaPlayer : {0} skipped {1} frames at position {2}", cachedVideo, skippedFrames, video.CurrentFrame);
                }
            }

            WidgetUtils.DrawSprite(videoSprite, videoOrigin, videoSize);

            if (DrawOverlay)
            {
                // Create the scan line grid to render over the video
                // To avoid aliasing, this must be an integer number of screen pixels.
                // A few complications to be aware of:
                // - The video may have a different aspect ratio to the widget RenderBounds
                // - The RenderBounds coordinates may be a non-integer scale of the screen pixel size
                // - The screen pixel size may change while the video is playing back
                //   (user moves a window between displays with different DPI on macOS)
                var scale = Game.Renderer.WindowScale;
                if (overlaySheet == null || overlayScale != scale)
                {
                    overlaySheet?.Dispose();

                    // Calculate the scan line height by converting the video scale (copied from Open()) to screen
                    // pixels, halving it (scan lines cover half the pixel height), and rounding to the nearest integer.
                    var videoScale    = Math.Min((float)RenderBounds.Width / video.Width, RenderBounds.Height / (video.Height * AspectRatio));
                    var halfRowHeight = (int)(videoScale * scale / 2 + 0.5f);

                    // The overlay can be minimally stored in a 1px column which is stretched to cover the full screen
                    var overlayHeight    = (int)(RenderBounds.Height * scale / halfRowHeight);
                    var overlaySheetSize = new Size(1, Exts.NextPowerOf2(overlayHeight));
                    var overlay          = new byte[4 * Exts.NextPowerOf2(overlayHeight)];
                    overlaySheet = new Sheet(SheetType.BGRA, overlaySheetSize);

                    // Every second pixel is the scan line - set alpha to 128 to make the lines less harsh
                    for (var i = 3; i < 4 * overlayHeight; i += 8)
                    {
                        overlay[i] = 128;
                    }

                    overlaySheet.GetTexture().SetData(overlay, overlaySheetSize.Width, overlaySheetSize.Height);
                    overlaySprite = new Sprite(overlaySheet, new Rectangle(0, 0, 1, overlayHeight), TextureChannel.RGBA);

                    // Overlay origin must be rounded to the nearest screen pixel to prevent aliasing
                    overlayOrigin = new float2((int)(RenderBounds.X * scale + 0.5f), (int)(RenderBounds.Y * scale + 0.5f)) / scale;
                    overlaySize   = new float2(RenderBounds.Width, overlayHeight * halfRowHeight / scale);
                    overlayScale  = scale;
                }

                WidgetUtils.DrawSprite(overlaySprite, overlayOrigin, overlaySize);
            }
        }
        public override void Draw()
        {
            armyIcons.Clear();

            var player = GetPlayer();

            if (player == null)
            {
                return;
            }

            var playerStatistics = stats.Update(player);

            var items = playerStatistics.Units.Values
                        .Where(u => u.Count > 0 && u.Icon != null)
                        .OrderBy(u => u.ProductionQueueOrder)
                        .ThenBy(u => u.BuildPaletteOrder);

            Game.Renderer.EnableAntialiasingFilter();

            var queueCol = 0;

            foreach (var unit in items)
            {
                var icon          = unit.Icon;
                var topLeftOffset = new int2(queueCol * (IconWidth + IconSpacing), 0);

                var iconTopLeft    = RenderOrigin + topLeftOffset;
                var centerPosition = iconTopLeft;

                var palette = unit.IconPaletteIsPlayerPalette ? unit.IconPalette + player.InternalName : unit.IconPalette;
                WidgetUtils.DrawSpriteCentered(icon.Image, worldRenderer.Palette(palette), centerPosition + 0.5f * iconSize, 0.5f);

                armyIcons.Add(new ArmyIcon
                {
                    Bounds = new Rectangle(iconTopLeft.X, iconTopLeft.Y, (int)iconSize.X, (int)iconSize.Y),
                    Unit   = unit
                });

                queueCol++;
            }

            var newWidth = Math.Max(queueCol * (IconWidth + IconSpacing), MinWidth);

            if (newWidth != Bounds.Width)
            {
                var wasInBounds = EventBounds.Contains(Viewport.LastMousePos);
                Bounds.Width = newWidth;
                var isInBounds = EventBounds.Contains(Viewport.LastMousePos);

                // HACK: Ui.MouseOverWidget is normally only updated when the mouse moves
                // Call ResetTooltips to force a fake mouse movement so the checks in Tick will work properly
                if (wasInBounds != isInBounds)
                {
                    Game.RunAfterTick(Ui.ResetTooltips);
                }
            }

            Game.Renderer.DisableAntialiasingFilter();

            var bold = Game.Renderer.Fonts["TinyBold"];

            foreach (var armyIcon in armyIcons)
            {
                var text = armyIcon.Unit.Count.ToString();
                bold.DrawTextWithContrast(text, armyIcon.Bounds.Location + new float2(iconSize.X, 0) - new float2(bold.Measure(text).X, bold.TopOffset),
                                          Color.White, Color.Black, 1);
            }

            var parentWidth = Bounds.X + Bounds.Width;

            Parent.Bounds.Width = parentWidth;

            var gradient = Parent.Get <GradientColorBlockWidget>("PLAYER_GRADIENT");

            var offset        = gradient.Bounds.X - Bounds.X;
            var gradientWidth = Math.Max(MinWidth - offset, queueCol * (IconWidth + IconSpacing));

            gradient.Bounds.Width = gradientWidth;
            var widestChildWidth = Parent.Parent.Children.Max(x => x.Bounds.Width);

            Parent.Parent.Bounds.Width = Math.Max(25 + widestChildWidth, Bounds.Left + MinWidth);
        }
        public override void Draw()
        {
            var player = GetPlayer();

            if (player == null)
            {
                return;
            }

            var queues = world.ActorsWithTrait <ProductionQueue>()
                         .Where(a => a.Actor.Owner == player)
                         .Select((a, i) => new { a.Trait, i });

            foreach (var queue in queues)
            {
                if (!clocks.ContainsKey(queue.Trait))
                {
                    clocks.Add(queue.Trait, new Animation(world, ClockAnimation));
                }
            }

            if (renderBounds != RenderBounds)
            {
                renderBounds = RenderBounds;
                InitIcons(renderBounds);
            }
            else
            {
                for (var i = 0; i < icons.Length; i++)
                {
                    icons[i].Actor = null;
                }
            }

            int queueColumn        = -1;
            var currentItemsByItem = queues.Select(a => a.Trait.AllQueued().FirstOrDefault()).Where(pi => pi != null).GroupBy(pr => pr.Item)
                                     .OrderBy(g => g.First().Queue.Info.SpectatorUIOrder)
                                     .ThenBy(g => g.First().Queue.Info.Type)
                                     .ThenBy(g => world.Map.Rules.Actors[g.First().Item].TraitInfo <BuildableInfo>().BuildPaletteOrder).ToList();

            foreach (var currentItems in currentItemsByItem)
            {
                var current = currentItems.OrderBy(pi => pi.Done ? 0 : (pi.Paused ? 2 : 1)).ThenBy(q => q.RemainingTimeActual).First();
                var queue   = current.Queue;

                var actor = queue.AllItems().FirstOrDefault(a => a.Name == current.Item);
                if (actor == null)
                {
                    continue;
                }

                queueColumn += 1;
                var rsi  = actor.TraitInfo <RenderSpritesInfo>();
                var icon = new Animation(world, rsi.GetImage(actor, world.Map.Rules.Sequences, queue.Actor.Owner.Faction.InternalName));
                var bi   = actor.TraitInfo <BuildableInfo>();
                icon.Play(bi.Icon);
                var location = new float2(iconRects[queueColumn].Location);
                WidgetUtils.DrawSHPCentered(icon.Image, location + iconSize, worldRenderer.Palette(bi.IconPalette), 1f);

                icons[queueColumn].Actor           = actor;
                icons[queueColumn].ProductionQueue = queue;

                var pio = queue.Actor.Owner.PlayerActor.TraitsImplementing <IProductionIconOverlay>()
                          .FirstOrDefault(p => p.IsOverlayActive(actor));
                if (pio != null)
                {
                    WidgetUtils.DrawSHPCentered(pio.Sprite, location + iconSize + pio.Offset(iconSize * 2f),
                                                worldRenderer.Palette(pio.Palette), 1f);
                }

                var clock = clocks[queue];
                clock.PlayFetchIndex(ClockSequence,
                                     () => current.TotalTime == 0 ? 0 : ((current.TotalTime - current.RemainingTime)
                                                                         * (clock.CurrentSequence.Length - 1) / current.TotalTime));
                clock.Tick();
                WidgetUtils.DrawSHPCentered(clock.Image, location + iconSize, worldRenderer.Palette(ClockPalette), 1f);

                var tiny = Game.Renderer.Fonts["Tiny"];
                var text = GetOverlayForItem(current, timestep);
                tiny.DrawTextWithContrast(text,
                                          location + iconSize - new float2(tiny.Measure(text).X / 2, 3),
                                          Color.White, Color.Black, 1);

                if (currentItems.Count() > 1)
                {
                    var bold = Game.Renderer.Fonts["Bold"];
                    text = currentItems.Count().ToString();
                    bold.DrawTextWithContrast(text,
                                              new float2(RenderBounds.Location) + new float2(queueColumn * (IconWidth * 2 + IconSpacing) + 5, 5),
                                              Color.White, Color.Black, 1);
                }
            }
        }
Exemplo n.º 26
0
        public override void DrawOuter()
        {
            if (!IsVisible())
            {
                return;
            }

            var rb = RenderBounds;

            var scrollbarHeight = rb.Height - 2 * ScrollbarWidth;

            var thumbHeight = ContentHeight == 0 ? 0 : Math.Max(MinimumThumbSize, (int)(scrollbarHeight * Math.Min(rb.Height * 1f / ContentHeight, 1f)));
            var thumbOrigin = rb.Y + ScrollbarWidth + (int)((scrollbarHeight - thumbHeight) * (-1f * currentListOffset / (ContentHeight - rb.Height)));

            if (thumbHeight == scrollbarHeight)
            {
                thumbHeight = 0;
            }

            backgroundRect = new Rectangle(rb.X, rb.Y, rb.Width - ScrollbarWidth + 1, rb.Height);
            upButtonRect   = new Rectangle(rb.Right - ScrollbarWidth, rb.Y, ScrollbarWidth, ScrollbarWidth);
            downButtonRect = new Rectangle(rb.Right - ScrollbarWidth, rb.Bottom - ScrollbarWidth, ScrollbarWidth, ScrollbarWidth);
            scrollbarRect  = new Rectangle(rb.Right - ScrollbarWidth, rb.Y + ScrollbarWidth - 1, ScrollbarWidth, scrollbarHeight + 2);
            thumbRect      = new Rectangle(rb.Right - ScrollbarWidth, thumbOrigin, ScrollbarWidth, thumbHeight);

            var upHover = Ui.MouseOverWidget == this && upButtonRect.Contains(Viewport.LastMousePos);

            upDisabled = thumbHeight == 0 || currentListOffset >= 0;

            var downHover = Ui.MouseOverWidget == this && downButtonRect.Contains(Viewport.LastMousePos);

            downDisabled = thumbHeight == 0 || currentListOffset <= Bounds.Height - ContentHeight;

            var thumbHover = Ui.MouseOverWidget == this && thumbRect.Contains(Viewport.LastMousePos);

            WidgetUtils.DrawPanel(Background, backgroundRect);
            WidgetUtils.DrawPanel(Background, scrollbarRect);
            ButtonWidget.DrawBackground(Button, upButtonRect, upDisabled, upPressed, upHover, false);
            ButtonWidget.DrawBackground(Button, downButtonRect, downDisabled, downPressed, downHover, false);

            if (thumbHeight > 0)
            {
                ButtonWidget.DrawBackground(Button, thumbRect, false, HasMouseFocus && thumbHover, thumbHover, false);
            }

            var upOffset   = !upPressed || upDisabled ? 4 : 4 + ButtonDepth;
            var downOffset = !downPressed || downDisabled ? 4 : 4 + ButtonDepth;

            WidgetUtils.DrawRGBA(ChromeProvider.GetImage("scrollbar", upPressed || upDisabled ? "up_pressed" : "up_arrow"),
                                 new float2(upButtonRect.Left + upOffset, upButtonRect.Top + upOffset));
            WidgetUtils.DrawRGBA(ChromeProvider.GetImage("scrollbar", downPressed || downDisabled ? "down_pressed" : "down_arrow"),
                                 new float2(downButtonRect.Left + downOffset, downButtonRect.Top + downOffset));

            var drawBounds = backgroundRect.InflateBy(-BorderWidth, -BorderWidth, -BorderWidth, -BorderWidth);

            Game.Renderer.EnableScissor(drawBounds);

            drawBounds.Offset((-ChildOrigin).ToPoint());
            foreach (var child in Children)
            {
                if (child.Bounds.IntersectsWith(drawBounds))
                {
                    child.DrawOuter();
                }
            }

            Game.Renderer.DisableScissor();
        }
Exemplo n.º 27
0
        public override void Draw()
        {
            timeOffset = iconOffset - overlayFont.Measure(WidgetUtils.FormatTime(0, World.Timestep)) / 2;

            if (CurrentQueue == null)
            {
                return;
            }

            var buildableItems = CurrentQueue.BuildableItems();

            // Icons
            Game.Renderer.EnableAntialiasingFilter();
            foreach (var icon in icons.Values)
            {
                WidgetUtils.DrawSHPCentered(icon.Sprite, icon.Pos + iconOffset, icon.Palette);

                // Draw the ProductionIconOverlay's sprite
                var pio = pios.FirstOrDefault(p => p.IsOverlayActive(icon.Actor));
                if (pio != null)
                {
                    WidgetUtils.DrawSHPCentered(pio.Sprite, icon.Pos + iconOffset + pio.Offset(IconSize), worldRenderer.Palette(pio.Palette), 1f);
                }

                // Build progress
                if (icon.Queued.Count > 0)
                {
                    var first = icon.Queued[0];
                    clock.PlayFetchIndex(ClockSequence,
                                         () => (first.TotalTime - first.RemainingTime)
                                         * (clock.CurrentSequence.Length - 1) / first.TotalTime);
                    clock.Tick();

                    WidgetUtils.DrawSHPCentered(clock.Image, icon.Pos + iconOffset, icon.IconClockPalette);
                }
                else if (!buildableItems.Any(a => a.Name == icon.Name))
                {
                    WidgetUtils.DrawSHPCentered(cantBuild.Image, icon.Pos + iconOffset, icon.IconDarkenPalette);
                }
            }

            Game.Renderer.DisableAntialiasingFilter();

            // Overlays
            foreach (var icon in icons.Values)
            {
                var total = icon.Queued.Count;
                if (total > 0)
                {
                    var first   = icon.Queued[0];
                    var waiting = !CurrentQueue.IsProducing(first) && !first.Done;
                    if (first.Done)
                    {
                        if (ReadyTextStyle == ReadyTextStyleOptions.Solid || orderManager.LocalFrameNumber * worldRenderer.World.Timestep / 360 % 2 == 0)
                        {
                            overlayFont.DrawTextWithContrast(ReadyText, icon.Pos + readyOffset, Color.White, Color.Black, 1);
                        }
                        else if (ReadyTextStyle == ReadyTextStyleOptions.AlternatingColor)
                        {
                            overlayFont.DrawTextWithContrast(ReadyText, icon.Pos + readyOffset, ReadyTextAltColor, Color.Black, 1);
                        }
                    }
                    else if (first.Paused)
                    {
                        overlayFont.DrawTextWithContrast(HoldText,
                                                         icon.Pos + holdOffset,
                                                         Color.White, Color.Black, 1);
                    }
                    else if (!waiting && DrawTime)
                    {
                        overlayFont.DrawTextWithContrast(WidgetUtils.FormatTime(first.Queue.RemainingTimeActual(first), World.Timestep),
                                                         icon.Pos + timeOffset,
                                                         Color.White, Color.Black, 1);
                    }

                    if (first.Infinite && symbolFont != null)
                    {
                        symbolFont.DrawTextWithContrast(InfiniteSymbol,
                                                        icon.Pos + infiniteOffset,
                                                        Color.White, Color.Black, 1);
                    }
                    else if (total > 1 || waiting)
                    {
                        overlayFont.DrawTextWithContrast(total.ToString(),
                                                         icon.Pos + queuedOffset,
                                                         Color.White, Color.Black, 1);
                    }
                }
            }
        }
Exemplo n.º 28
0
        public override void Draw()
        {
            productionIcons.Clear();
            productionIconsBounds.Clear();

            var player = GetPlayer();

            if (player == null)
            {
                return;
            }

            var queues = world.ActorsWithTrait <ProductionQueue>()
                         .Where(a => a.Actor.Owner == player)
                         .Select((a, i) => new { a.Trait, i });

            foreach (var queue in queues)
            {
                if (!clocks.ContainsKey(queue.Trait))
                {
                    clocks.Add(queue.Trait, new Animation(world, ClockAnimation));
                }
            }

            var currentItemsByItem = queues
                                     .Select(a => a.Trait.CurrentItem())
                                     .Where(pi => pi != null)
                                     .GroupBy(pr => pr.Item)
                                     .OrderBy(g => g.First().Queue.Info.DisplayOrder)
                                     .ThenBy(g => g.First().BuildPaletteOrder)
                                     .ToList();

            Game.Renderer.EnableAntialiasingFilter();

            var queueCol = 0;

            foreach (var currentItems in currentItemsByItem)
            {
                var queued = currentItems
                             .OrderBy(pi => pi.Done ? 0 : (pi.Paused ? 2 : 1))
                             .ThenBy(q => q.RemainingTimeActual)
                             .ToList();

                var current = queued.First();
                var queue   = current.Queue;

                var faction = queue.Actor.Owner.Faction.InternalName;
                var actor   = queue.AllItems().FirstOrDefault(a => a.Name == current.Item);
                if (actor == null)
                {
                    continue;
                }

                var rsi  = actor.TraitInfo <RenderSpritesInfo>();
                var icon = new Animation(world, rsi.GetImage(actor, faction));
                var bi   = actor.TraitInfo <BuildableInfo>();

                icon.Play(bi.Icon);
                var topLeftOffset = new float2(queueCol * (IconWidth + IconSpacing), 0);

                var iconTopLeft    = RenderOrigin + topLeftOffset;
                var centerPosition = iconTopLeft + 0.5f * iconSize;

                var palette = bi.IconPaletteIsPlayerPalette ? bi.IconPalette + player.InternalName : bi.IconPalette;
                WidgetUtils.DrawSpriteCentered(icon.Image, worldRenderer.Palette(palette), centerPosition, 0.5f);

                var rect = new Rectangle((int)iconTopLeft.X, (int)iconTopLeft.Y, (int)iconSize.X, (int)iconSize.Y);
                productionIcons.Add(new ProductionIcon
                {
                    Actor           = actor,
                    Pos             = new float2(rect.Location),
                    Queued          = queued,
                    ProductionQueue = current.Queue
                });

                productionIconsBounds.Add(rect);

                var pio = queue.Actor.Owner.PlayerActor.TraitsImplementing <IProductionIconOverlay>()
                          .FirstOrDefault(p => p.IsOverlayActive(actor));

                if (pio != null)
                {
                    WidgetUtils.DrawSpriteCentered(pio.Sprite, worldRenderer.Palette(pio.Palette),
                                                   centerPosition + pio.Offset(iconSize), 0.5f);
                }

                var clock = clocks[queue];
                clock.PlayFetchIndex(ClockSequence, () => current.TotalTime == 0 ? 0 :
                                     (current.TotalTime - current.RemainingTime) * (clock.CurrentSequence.Length - 1) / current.TotalTime);

                clock.Tick();
                WidgetUtils.DrawSpriteCentered(clock.Image, worldRenderer.Palette(ClockPalette), centerPosition, 0.5f);

                queueCol++;
            }

            var newWidth = Math.Max(queueCol * (IconWidth + IconSpacing), MinWidth);

            if (newWidth != Bounds.Width)
            {
                var wasInBounds = EventBounds.Contains(Viewport.LastMousePos);
                Bounds.Width = newWidth;
                var isInBounds = EventBounds.Contains(Viewport.LastMousePos);

                // HACK: Ui.MouseOverWidget is normally only updated when the mouse moves
                // Call ResetTooltips to force a fake mouse movement so the checks in Tick will work properly
                if (wasInBounds != isInBounds)
                {
                    Game.RunAfterTick(Ui.ResetTooltips);
                }
            }

            Game.Renderer.DisableAntialiasingFilter();

            var tiny = Game.Renderer.Fonts["Tiny"];
            var bold = Game.Renderer.Fonts["Small"];

            foreach (var icon in productionIcons)
            {
                var current = icon.Queued.First();
                var text    = GetOverlayForItem(current, world.Timestep);
                tiny.DrawTextWithContrast(text,
                                          icon.Pos + new float2(16, 12) - new float2(tiny.Measure(text).X / 2, 0),
                                          Color.White, Color.Black, 1);

                if (icon.Queued.Count > 1)
                {
                    text = icon.Queued.Count.ToString();
                    bold.DrawTextWithContrast(text, icon.Pos + new float2(16, 0) - new float2(bold.Measure(text).X / 2, 0),
                                              Color.White, Color.Black, 1);
                }
            }

            var parentWidth = Bounds.X + Bounds.Width;

            Parent.Bounds.Width = parentWidth;

            var gradient = Parent.Get <GradientColorBlockWidget>("PLAYER_GRADIENT");

            var offset        = gradient.Bounds.X - Bounds.X;
            var gradientWidth = Math.Max(MinWidth - offset, currentItemsByItem.Count * (IconWidth + IconSpacing));

            gradient.Bounds.Width = gradientWidth;
            var widestChildWidth = Parent.Parent.Children.Max(x => x.Bounds.Width);

            Parent.Parent.Bounds.Width = Math.Max(25 + widestChildWidth, Bounds.Left + MinWidth);
        }
        public override void Draw()
        {
            var iconOffsetToCenter = 0.5f * IconSize.ToFloat2() + IconSpriteOffset;

            timeOffset   = iconOffsetToCenter - overlayFont.Measure(WidgetUtils.FormatTime(0, World.Timestep)) / 2;
            queuedOffset = new float2(4, 2);
            holdOffset   = iconOffsetToCenter - overlayFont.Measure(HoldText) / 2;
            readyOffset  = iconOffsetToCenter - overlayFont.Measure(ReadyText) / 2;

            if (ChromeMetrics.TryGet("InfiniteOffset", out infiniteOffset))
            {
                infiniteOffset += queuedOffset;
            }
            else
            {
                infiniteOffset = queuedOffset;
            }

            if (CurrentQueue == null)
            {
                return;
            }

            var buildableItems = CurrentQueue.BuildableItems();

            var pios = currentQueue.Actor.Owner.PlayerActor.TraitsImplementing <IProductionIconOverlay>();

            // Icons
            foreach (ProductionIcon icon in icons.Values)
            {
                WidgetUtils.DrawSHPCentered(icon.Sprite, icon.Pos + iconOffsetToCenter, icon.Palette, icon.RenderSize);                 //этот метод использует размер от icon.Sprite.Size для размера в FastQuad

                // Draw the ProductionIconOverlay's sprite
                var pio = pios.FirstOrDefault(p => p.IsOverlayActive(icon.Actor));
                if (pio != null)
                {
                    WidgetUtils.DrawSHPCentered(pio.Sprite, icon.Pos + iconOffsetToCenter + pio.Offset(IconSize), worldRenderer.Palette(pio.Palette), 1f);
                }

                // Build progress
                if (icon.Queued.Count > 0)
                {
                    var first = icon.Queued[0];
                    if (1 == 2)
                    {
                        clock.PlayFetchIndex(ClockSequence,
                                             () => (first.TotalTime - first.RemainingTime) * (clock.CurrentSequence.Length - 1) / first.TotalTime);
                        clock.Tick();

                        WidgetUtils.DrawSHPCentered(clock.Image, icon.Pos + iconOffsetToCenter, icon.IconClockPalette, icon.RenderSize);
                    }
                    else
                    {
                        int    currentframe = (first.TotalTime - first.RemainingTime) * (59) / first.TotalTime;
                        float3 offs         = iconOffsetToCenter - 0.5f * icon.RenderSize.ToFloat2(); // из-за  icon.Pos + iconOffsetToCenter и DrawSHPCentered
                        Game.Renderer.Flush();                                                        // делаем, это  тут, так как рисуем вне очереди, то управляем очередью.
                        Game.Renderer.sproc.AddCommand(1, currentframe, 59, 0, 0, new int2(0, 0), icon.Pos + offs, icon.RenderSize, icon.Sprite, icon.Palette);
                        Game.Renderer.sproc.ExecCommandBuffer();
                    }
                }
                else if (!buildableItems.Any(a => a.Name == icon.Name))
                {
                    WidgetUtils.DrawSHPCentered(cantBuild.Image, icon.Pos + iconOffsetToCenter, icon.IconDarkenPalette, icon.RenderSize);
                }
            }

            // Overlays
            foreach (ProductionIcon icon in icons.Values)
            {
                var total = icon.Queued.Count;
                if (total > 0)
                {
                    var first   = icon.Queued[0];
                    var waiting = !CurrentQueue.IsProducing(first) && !first.Done;
                    if (first.Done)
                    {
                        if (ReadyTextStyle == ReadyTextStyleOptions.Solid || orderManager.LocalFrameNumber * worldRenderer.World.Timestep / 360 % 2 == 0)
                        {
                            overlayFont.DrawTextWithContrast(ReadyText, icon.Pos + readyOffset, Color.White, Color.Black, 1);
                        }
                        else if (ReadyTextStyle == ReadyTextStyleOptions.AlternatingColor)
                        {
                            overlayFont.DrawTextWithContrast(ReadyText, icon.Pos + readyOffset, ReadyTextAltColor, Color.Black, 1);
                        }
                    }
                    else if (first.Paused)
                    {
                        overlayFont.DrawTextWithContrast(HoldText,
                                                         icon.Pos + holdOffset,
                                                         Color.White, Color.Black, 1);
                    }
                    else if (!waiting && DrawTime)
                    {
                        overlayFont.DrawTextWithContrast(WidgetUtils.FormatTime(first.Queue.RemainingTimeActual(first), World.Timestep),
                                                         icon.Pos + timeOffset,
                                                         Color.White, Color.Black, 1);
                    }

                    if (first.Infinite)
                    {
                        symbolFont.DrawTextWithContrast(InfiniteSymbol,
                                                        icon.Pos + infiniteOffset,
                                                        Color.White, Color.Black, 1);
                    }
                    else if (total > 1 || waiting)
                    {
                        overlayFont.DrawTextWithContrast(total.ToString(),
                                                         icon.Pos + queuedOffset,
                                                         Color.White, Color.Black, 1);
                    }
                }
            }
        }