public static string WrapText(string text, int width, SpriteFontMSDF font)
        {
            var textSize = font.Measure(text);

            if (textSize.X > width)
            {
                var lines = text.Split('\n').ToList();

                for (var i = 0; i < lines.Count; i++)
                {
                    var line = lines[i];
                    if (font.Measure(line).X <= width)
                    {
                        continue;
                    }

                    // Scan forwards until we find the last word that fits
                    // This guarantees a small bound on the amount of string we need to search before a linebreak
                    var start = 0;
                    while (true)
                    {
                        var spaceIndex = line.IndexOf(' ', start);
                        if (spaceIndex == -1)
                        {
                            break;
                        }

                        var fragmentWidth = font.Measure(line.Substring(0, spaceIndex)).X;
                        if (fragmentWidth > width)
                        {
                            break;
                        }

                        start = spaceIndex + 1;
                    }

                    if (start > 0)
                    {
                        lines[i] = line.Substring(0, start - 1);
                        lines.Insert(i + 1, line.Substring(start));
                    }
                }

                return(string.Join("\n", lines));
            }

            return(text);
        }
        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
            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.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.IconClockPalette);
            }

            // 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, worldRenderer.World.Timestep),
                                                     p.Pos + timeOffset,
                                                     Color.White, Color.Black, 1);
                }
            }
        }
Exemple #3
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 colors = SpawnOccupants().ToDictionary(c => c.Key, c => c.Value.Color);

                var spawnPoints = preview.SpawnPoints;
                var gridType    = preview.GridType;
                foreach (var p in spawnPoints)
                {
                    var owned  = colors.ContainsKey(p);
                    var pos    = ConvertToPreview(p, gridType);
                    var sprite = owned ? spawnClaimed : spawnUnclaimed;
                    var offset = new int2(sprite.Bounds.Width, sprite.Bounds.Height) / 2;

                    if (owned)
                    {
                        WidgetUtils.FillEllipseWithColor(new Rectangle(pos.X - offset.X + 1, pos.Y - offset.Y + 1, sprite.Bounds.Width - 2, sprite.Bounds.Height - 2), colors[p]);
                    }

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

                    if (((pos - Viewport.LastMousePos).ToFloat2() / offset.ToFloat2()).LengthSquared <= 1)
                    {
                        TooltipSpawnIndex = spawnPoints.IndexOf(p) + 1;
                    }
                }
            }
        }
Exemple #4
0
        public void Render(WorldRenderer wr)
        {
            var screenPos   = wr.Viewport.Zoom * (wr.ScreenPosition(pos) - wr.Viewport.TopLeft.ToFloat2()) - 0.5f * font.Measure(text).ToFloat2();
            var screenPxPos = new float2((float)Math.Round(screenPos.X), (float)Math.Round(screenPos.Y));

            font.DrawTextWithContrast(text, screenPxPos, color, bgDark, bgLight, 1);
        }
        public static string TruncateText(string text, int width, SpriteFontMSDF font)
        {
            var trimmedWidth = font.Measure(text).X;

            if (trimmedWidth <= width)
            {
                return(text);
            }

            var trimmed = text;

            while (trimmedWidth > width && trimmed.Length > 3)
            {
                trimmed      = text.Substring(0, trimmed.Length - 4) + "...";
                trimmedWidth = font.Measure(trimmed).X;
            }

            return(trimmed);
        }
        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);
        }
Exemple #7
0
        IEnumerable <IRenderable> RenderInner(Actor self, WorldRenderer wr)
        {
            if (IsTraitDisabled || self.IsDead || !self.IsInWorld)
            {
                return(Enumerable.Empty <IRenderable>());
            }

            if (self.World.RenderPlayer != null)
            {
                var stance = self.Owner.Stances[self.World.RenderPlayer];
                if (!Info.ValidStances.HasStance(stance))
                {
                    return(Enumerable.Empty <IRenderable>());
                }
            }

            if (!ShouldRender(self) || self.World.FogObscures(self))
            {
                return(Enumerable.Empty <IRenderable>());
            }

            var bounds   = decorationBounds.FirstNonEmptyBounds(self, wr);
            var halfSize = font.Measure(Info.Text) / 2;

            var boundsOffset = new int2(bounds.Left + bounds.Right, bounds.Top + bounds.Bottom) / 2;
            var sizeOffset   = new int2();

            if (Info.ReferencePoint.HasFlag(ReferencePoints.Top))
            {
                boundsOffset -= new int2(0, bounds.Height / 2);
                sizeOffset   += new int2(0, halfSize.Y);
            }
            else if (Info.ReferencePoint.HasFlag(ReferencePoints.Bottom))
            {
                boundsOffset += new int2(0, bounds.Height / 2);
                sizeOffset   -= new int2(0, halfSize.Y);
            }

            if (Info.ReferencePoint.HasFlag(ReferencePoints.Left))
            {
                boundsOffset -= new int2(bounds.Width / 2, 0);
                sizeOffset   += new int2(halfSize.X, 0);
            }
            else if (Info.ReferencePoint.HasFlag(ReferencePoints.Right))
            {
                boundsOffset += new int2(bounds.Width / 2, 0);
                sizeOffset   -= new int2(halfSize.X, 0);
            }

            return(new IRenderable[] { new TextRenderable(font, wr.ProjectedPosition(boundsOffset + sizeOffset), Info.ZOffset, color, Info.Text) });
        }
        IEnumerable <IRenderable> DrawControlGroup(Actor self, WorldRenderer wr)
        {
            var group = self.World.Selection.GetControlGroupForActor(self);

            if (group == null)
            {
                yield break;
            }

            var bounds   = decorationBounds.FirstNonEmptyBounds(self, wr);
            var number   = group.Value.ToString();
            var halfSize = font.Measure(number) / 2;

            var boundsOffset = new int2(bounds.Left + bounds.Right, bounds.Top + bounds.Bottom) / 2;
            var sizeOffset   = new int2();

            if (info.ReferencePoint.HasFlag(ReferencePoints.Top))
            {
                boundsOffset -= new int2(0, bounds.Height / 2);
                sizeOffset   += new int2(0, halfSize.Y);
            }
            else if (info.ReferencePoint.HasFlag(ReferencePoints.Bottom))
            {
                boundsOffset += new int2(0, bounds.Height / 2);
                sizeOffset   -= new int2(0, halfSize.Y);
            }

            if (info.ReferencePoint.HasFlag(ReferencePoints.Left))
            {
                boundsOffset -= new int2(bounds.Width / 2, 0);
                sizeOffset   += new int2(halfSize.X, 0);
            }
            else if (info.ReferencePoint.HasFlag(ReferencePoints.Right))
            {
                boundsOffset += new int2(bounds.Width / 2, 0);
                sizeOffset   -= new int2(halfSize.X, 0);
            }

            var screenPos = boundsOffset + sizeOffset + info.ScreenOffset;

            yield return(new TextRenderable(font, wr.ProjectedPosition(screenPos), info.ZOffset, color, number));
        }
        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);
                    }
                }
            }
        }