Exemplo n.º 1
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).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);

            var iconSize = new float2(IconWidth, IconHeight);

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

                icon.Play(item.Info.Icon);
                var location = new float2(RenderBounds.Location) + new float2(power.i * (IconWidth + IconSpacing), 0);

                supportPowerIconsIcons.Add(new SupportPowersWidget.SupportPowerIcon {
                    Power = item
                });
                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.TotalTime == 0 ? 0 : ((item.TotalTime - item.RemainingTime)
                                                                      * (clock.CurrentSequence.Length - 1) / item.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(item, timestep);
                tiny.DrawTextWithContrast(text,
                                          location + new float2(16, 12) - new float2(tiny.Measure(text).X / 2, 0),
                                          Color.White, Color.Black, 1);
            }
        }
Exemplo n.º 2
0
        public override void Draw()
        {
            var iconOffset = 0.5f * IconSize.ToFloat2() + IconSpriteOffset;

            overlayFont = Game.Renderer.Fonts["TinyBold"];

            holdOffset  = iconOffset - overlayFont.Measure(HoldText) / 2;
            readyOffset = iconOffset - overlayFont.Measure(ReadyText) / 2;
            timeOffset  = iconOffset - overlayFont.Measure(WidgetUtils.FormatTime(0, worldRenderer.World.Timestep)) / 2;

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

                // Charge progress
                var sp = p.Power;
                clock.PlayFetchIndex(ClockSequence,
                                     () => sp.TotalTicks == 0 ? clock.CurrentSequence.Length - 1 : (sp.TotalTicks - sp.RemainingTicks)
                                     * (clock.CurrentSequence.Length - 1) / sp.TotalTicks);

                clock.Tick();
                WidgetUtils.DrawSHPCentered(clock.Image, p.Pos + iconOffset, p.IconClockPalette);
            }

            Game.Renderer.DisableAntialiasingFilter();

            // Overlay
            foreach (var p in icons.Values)
            {
                var customText = p.Power.IconOverlayTextOverride();
                if (customText != null)
                {
                    var customOffset = iconOffset - overlayFont.Measure(customText) / 2;
                    overlayFont.DrawTextWithContrast(customText,
                                                     p.Pos + customOffset,
                                                     Color.White, Color.Black, 1);
                }
                else if (p.Power.Ready)
                {
                    overlayFont.DrawTextWithContrast(ReadyText,
                                                     p.Pos + readyOffset,
                                                     Color.White, Color.Black, 1);
                }
                else if (!p.Power.Active)
                {
                    overlayFont.DrawTextWithContrast(HoldText,
                                                     p.Pos + holdOffset,
                                                     Color.White, Color.Black, 1);
                }
                else
                {
                    overlayFont.DrawTextWithContrast(WidgetUtils.FormatTime(p.Power.RemainingTicks, worldRenderer.World.Timestep),
                                                     p.Pos + timeOffset,
                                                     Color.White, Color.Black, 1);
                }
            }
        }
Exemplo n.º 3
0
        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, "clock"));
                }
            }

            var iconSize = new float2(IconWidth, IconHeight);

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

                var race  = queue.Trait.Actor.Owner.Country.Race;
                var actor = queue.Trait.AllItems().FirstOrDefault(a => a.Name == current.Item);
                if (actor == null)
                {
                    continue;
                }

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

                var clock = clocks[queue.Trait];
                clock.PlayFetchIndex("idle",
                                     () => 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, 0.5f);

                var tiny = Game.Renderer.Fonts["Tiny"];
                var text = GetOverlayForItem(current);
                tiny.DrawTextWithContrast(text,
                                          location + new float2(16, 16) - new float2(tiny.Measure(text).X / 2, 0),
                                          Color.White, Color.Black, 1);
            }
        }
Exemplo n.º 4
0
 public override void Draw()
 {
     if (sprite != null && palette != null)
     {
         var scale            = Game.Cursor is SoftwareCursor && CursorProvider.CursorViewportZoomed ? 2 : 1;
         var directionPalette = worldRenderer.Palette(palette);
         WidgetUtils.DrawSHPCentered(sprite, ChildOrigin, directionPalette, scale);
     }
 }
Exemplo n.º 5
0
        public override void Draw()
        {
            if (sprite != null && palette != null)
            {
                var directionPalette = worldRenderer.Palette(palette);

                // Cursor is rendered in native window coordinates
                // Apply same scaling rules as hardware cursors
                var scale = (graphicSettings.CursorDouble ? 2 : 1) * (Game.Renderer.NativeWindowScale > 1.5f ? 2 : 1);
                WidgetUtils.DrawSHPCentered(sprite, ChildOrigin, directionPalette, scale / Game.Renderer.WindowScale);
            }
        }
Exemplo n.º 6
0
        public override void Draw()
        {
            var iconOffset = 0.5f * IconSize.ToFloat2() + IconSpriteOffset;

            overlayFont = Game.Renderer.Fonts["TinyBold"];

            holdOffset  = iconOffset - overlayFont.Measure(HoldText) / 2;
            readyOffset = iconOffset - overlayFont.Measure(ReadyText) / 2;
            timeOffset  = iconOffset - overlayFont.Measure(WidgetUtils.FormatTime(0)) / 2;

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

                // Charge progress
                var sp = p.Power;
                clock.PlayFetchIndex("idle",
                                     () => sp.TotalTime == 0 ? clock.CurrentSequence.Length - 1 : (sp.TotalTime - sp.RemainingTime)
                                     * (clock.CurrentSequence.Length - 1) / sp.TotalTime);

                clock.Tick();
                WidgetUtils.DrawSHPCentered(clock.Image, p.Pos + iconOffset, p.Palette);
            }

            // Overlay
            foreach (var p in icons.Values)
            {
                if (p.Power.Ready)
                {
                    overlayFont.DrawTextWithContrast(ReadyText,
                                                     p.Pos + readyOffset,
                                                     Color.White, Color.Black, 1);
                }
                else if (!p.Power.Active)
                {
                    overlayFont.DrawTextWithContrast(HoldText,
                                                     p.Pos + holdOffset,
                                                     Color.White, Color.Black, 1);
                }
                else
                {
                    overlayFont.DrawTextWithContrast(WidgetUtils.FormatTime(p.Power.RemainingTime),
                                                     p.Pos + timeOffset,
                                                     Color.White, Color.Black, 1);
                }
            }
        }
Exemplo n.º 7
0
        public override void Draw()
        {
            var player = GetPlayer();

            if (player == null)
            {
                return;
            }

            var powers = player.PlayerActor.Trait <SupportPowerManager>().Powers
                         .Select((a, i) => new { a, i });

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

            var iconSize = new float2(IconWidth, IconHeight);

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

                icon.Play(item.Info.Icon);
                var location = new float2(RenderBounds.Location) + new float2(power.i * (IconWidth + IconSpacing), 0);
                WidgetUtils.DrawSHPCentered(icon.Image, location + 0.5f * iconSize, worldRenderer, 0.5f);

                var clock = clocks[power.a.Key];
                clock.PlayFetchIndex("idle",
                                     () => item.TotalTime == 0 ? 0 : ((item.TotalTime - item.RemainingTime)
                                                                      * (clock.CurrentSequence.Length - 1) / item.TotalTime));
                clock.Tick();
                WidgetUtils.DrawSHPCentered(clock.Image, location + 0.5f * iconSize, worldRenderer, 0.5f);

                var tiny = Game.Renderer.Fonts["Tiny"];
                var text = GetOverlayForItem(item);
                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()
        {
            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);
                    }
                }
            }
        }
        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.º 10
0
        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;

                WidgetUtils.DrawSHPCentered(icon.Image, centerPosition + 0.5f * iconSize, worldRenderer.Palette(unit.IconPalette), 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);
        }
Exemplo n.º 11
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);
                    }
                }
            }
        }
        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.º 13
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, 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 + 0.5f * iconSize;

                var palette = bi.IconPaletteIsPlayerPalette ? bi.IconPalette + player.InternalName : bi.IconPalette;
                WidgetUtils.DrawSHPCentered(icon.Image, centerPosition, worldRenderer.Palette(palette), 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.DrawSHPCentered(pio.Sprite, centerPosition + 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, worldRenderer.Palette(ClockPalette), 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);
        }
Exemplo n.º 14
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);
                    }
                }
            }
        }
        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++;
            }
        }
        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);
                    }
                }
            }
        }