Пример #1
0
        public static void DrawRangeCircle(WorldRenderer wr, WPos centerPosition, WDist radius,
			float width, Color color, float contrastWidth, Color contrastColor)
        {
            var wcr = Game.Renderer.WorldRgbaColorRenderer;
            var offset = new WVec(radius.Length, 0, 0);
            for (var i = 0; i < RangeCircleSegments; i++)
            {
                var a = wr.Screen3DPosition(centerPosition + offset.Rotate(RangeCircleStartRotations[i]));
                var b = wr.Screen3DPosition(centerPosition + offset.Rotate(RangeCircleEndRotations[i]));

                if (contrastWidth > 0)
                    wcr.DrawLine(a, b, contrastWidth / wr.Viewport.Zoom, contrastColor);

                if (width > 0)
                    wcr.DrawLine(a, b, width / wr.Viewport.Zoom, color);
            }
        }
Пример #2
0
        public void Render(WorldRenderer wr)
        {
            if (!waypoints.Any())
            {
                return;
            }

            var first = wr.Viewport.WorldToViewPx(wr.Screen3DPosition(waypoints.First()));
            var a     = first;

            foreach (var b in waypoints.Skip(1).Select(pos => wr.Viewport.WorldToViewPx(wr.Screen3DPosition(pos))))
            {
                Game.Renderer.RgbaColorRenderer.DrawLine(a, b, width, color);
                DrawTargetMarker(wr, color, b, markerSize);
                a = b;
            }

            DrawTargetMarker(wr, color, first);
        }
Пример #3
0
            public void RenderDebugGeometry(WorldRenderer wr)
            {
                var groundPos = voxel.pos - new WVec(0, 0, wr.World.Map.DistanceAboveTerrain(voxel.pos).Length);
                var groundZ = wr.World.Map.Grid.TileSize.Height * (groundPos.Z - voxel.pos.Z) / 1024f;
                var pxOrigin = wr.Screen3DPosition(voxel.pos);
                var shadowOrigin = pxOrigin - groundZ * (new float2(renderProxy.ShadowDirection, 1));
                var iz = 1 / wr.Viewport.Zoom;

                // Draw sprite rect
                var offset = pxOrigin + renderProxy.Sprite.Offset - 0.5f * renderProxy.Sprite.Size;
                Game.Renderer.WorldRgbaColorRenderer.DrawRect(offset.XY, (offset + renderProxy.Sprite.Size).XY, iz, Color.Red);

                // Draw transformed shadow sprite rect
                var c = Color.Purple;
                var psb = renderProxy.ProjectedShadowBounds;

                Game.Renderer.WorldRgbaColorRenderer.DrawPolygon(new[]
                {
                    shadowOrigin + psb[1],
                    shadowOrigin + psb[3],
                    shadowOrigin + psb[0],
                    shadowOrigin + psb[2]
                }, iz, c);

                // Draw voxel bounding box
                var draw = voxel.voxels.Where(v => v.DisableFunc == null || !v.DisableFunc());
                var scaleTransform = OpenRA.Graphics.Util.ScaleMatrix(voxel.scale, voxel.scale, voxel.scale);
                var cameraTransform = OpenRA.Graphics.Util.MakeFloatMatrix(voxel.camera.AsMatrix());

                foreach (var v in draw)
                {
                    var bounds = v.Voxel.Bounds(v.FrameFunc());
                    var worldTransform = v.RotationFunc().Reverse().Aggregate(scaleTransform,
                        (x, y) => OpenRA.Graphics.Util.MatrixMultiply(x, OpenRA.Graphics.Util.MakeFloatMatrix(y.AsMatrix())));

                    var pxPos = pxOrigin + wr.ScreenVectorComponents(v.OffsetFunc());
                    var screenTransform = OpenRA.Graphics.Util.MatrixMultiply(cameraTransform, worldTransform);
                    DrawBoundsBox(pxPos, screenTransform, bounds, iz, Color.Yellow);
                }
            }
Пример #4
0
            public void Render(WorldRenderer wr)
            {
                var groundPos = voxel.pos - new WVec(0, 0, wr.World.Map.DistanceAboveTerrain(voxel.pos).Length);
                var groundZ = wr.World.Map.Grid.TileSize.Height * (groundPos.Z - voxel.pos.Z) / 1024f;
                var pxOrigin = wr.Screen3DPosition(voxel.pos);

                // HACK: We don't have enough texture channels to pass the depth data to the shader
                // so for now just offset everything forward so that the back corner is rendered at pos.
                pxOrigin -= new float3(0, 0, Screen3DBounds(wr).Second.X);

                var shadowOrigin = pxOrigin - groundZ * (new float2(renderProxy.ShadowDirection, 1));

                var psb = renderProxy.ProjectedShadowBounds;
                var sa = shadowOrigin + psb[0];
                var sb = shadowOrigin + psb[2];
                var sc = shadowOrigin + psb[1];
                var sd = shadowOrigin + psb[3];
                Game.Renderer.WorldRgbaSpriteRenderer.DrawSprite(renderProxy.ShadowSprite, sa, sb, sc, sd);
                Game.Renderer.WorldRgbaSpriteRenderer.DrawSprite(renderProxy.Sprite, pxOrigin - 0.5f * renderProxy.Sprite.Size);
            }
Пример #5
0
        public void Render(WorldRenderer wr)
        {
            if (!waypoints.Any())
                return;

            var iz = 1 / wr.Viewport.Zoom;
            var first = wr.Screen3DPosition(waypoints.First());
            var a = first;
            foreach (var b in waypoints.Skip(1).Select(pos => wr.Screen3DPosition(pos)))
            {
                Game.Renderer.WorldRgbaColorRenderer.DrawLine(a, b, iz, color);
                DrawTargetMarker(wr, color, b);
                a = b;
            }

            DrawTargetMarker(wr, color, first);
        }
Пример #6
0
        public void Render(WorldRenderer wr)
        {
            var vecLength = length.Length;
            if (vecLength == 0)
                return;

            if (shape == BeamRenderableShape.Flat)
            {
                var delta = length * width.Length / (2 * vecLength);
                var corner = new WVec(-delta.Y, delta.X, delta.Z);
                var a = wr.Screen3DPosition(pos - corner);
                var b = wr.Screen3DPosition(pos + corner);
                var c = wr.Screen3DPosition(pos + corner + length);
                var d = wr.Screen3DPosition(pos - corner + length);
                Game.Renderer.WorldRgbaColorRenderer.FillRect(a, b, c, d, color);
            }
            else
            {
                var start = wr.Screen3DPosition(pos);
                var end = wr.Screen3DPosition(pos + length);
                var screenWidth = wr.ScreenVector(new WVec(width, WDist.Zero, WDist.Zero))[0];
                Game.Renderer.WorldRgbaColorRenderer.DrawLine(start, end, screenWidth, color);
            }
        }
Пример #7
0
        void IWorldLoaded.WorldLoaded(World w, WorldRenderer wr)
        {
            // Initialize tile cache
            // This includes the region outside the visible area to cover any sprites peeking outside the map
            foreach (var uv in w.Map.AllCells.MapCoords)
            {
                var pos = w.Map.CenterOfCell(uv.ToCPos(map));
                var screen = wr.Screen3DPosition(pos - new WVec(0, 0, pos.Z));
                var variant = (byte)Game.CosmeticRandom.Next(info.ShroudVariants.Length);
                tileInfos[uv] = new TileInfo(screen, variant);
            }

            // Dirty the whole projected space
            DirtyCells(map.AllCells.MapCoords.Select(uv => (PPos)uv));

            // All tiles are visible in the editor
            if (w.Type == WorldType.Editor)
                visibleUnderShroud = _ => true;
            else
                visibleUnderShroud = puv => map.Contains(puv);

            visibleUnderFog = puv => map.Contains(puv);

            var shroudSheet = shroudSprites[0].Sheet;
            if (shroudSprites.Any(s => s.Sheet != shroudSheet))
                throw new InvalidDataException("Shroud sprites span multiple sheets. Try loading their sequences earlier.");

            var shroudBlend = shroudSprites[0].BlendMode;
            if (shroudSprites.Any(s => s.BlendMode != shroudBlend))
                throw new InvalidDataException("Shroud sprites must all use the same blend mode.");

            var fogSheet = fogSprites[0].Sheet;
            if (fogSprites.Any(s => s.Sheet != fogSheet))
                throw new InvalidDataException("Fog sprites span multiple sheets. Try loading their sequences earlier.");

            var fogBlend = fogSprites[0].BlendMode;
            if (fogSprites.Any(s => s.BlendMode != fogBlend))
                throw new InvalidDataException("Fog sprites must all use the same blend mode.");

            shroudLayer = new TerrainSpriteLayer(w, wr, shroudSheet, shroudBlend, wr.Palette(info.ShroudPalette), false);
            fogLayer = new TerrainSpriteLayer(w, wr, fogSheet, fogBlend, wr.Palette(info.FogPalette), false);
        }
Пример #8
0
        public void DrawCombatOverlay(WorldRenderer wr, RgbaColorRenderer wcr, Actor actor)
        {
            var actorPos = actor.CenterPosition;
            var orientation = new WRot(actor.Orientation.Roll, actor.Orientation.Pitch,
                new WAngle(actor.Orientation.Yaw.Angle + (RotateToIsometry ? 128 : 0)));

            var targetablePositions = actor.TraitsImplementing<ITargetablePositions>();
            if (ApplyToAllTargetablePositions && targetablePositions.Any())
            {
                var positions = targetablePositions.SelectMany(tp => tp.TargetablePositions(actor));
                foreach (var pos in positions)
                {
                    var vertsTop = combatOverlayVertsTop.Select(v => wr.Screen3DPosition(pos + v.Rotate(orientation)));
                    var vertsBottom = combatOverlayVertsBottom.Select(v => wr.Screen3DPosition(pos + v.Rotate(orientation)));
                    wcr.DrawPolygon(vertsTop.ToArray(), 1, Color.Yellow);
                    wcr.DrawPolygon(vertsBottom.ToArray(), 1, Color.Yellow);
                }
            }
            else
            {
                var vertsTop = combatOverlayVertsTop.Select(v => wr.Screen3DPosition(actorPos + v.Rotate(orientation)));
                var vertsBottom = combatOverlayVertsBottom.Select(v => wr.Screen3DPosition(actorPos + v.Rotate(orientation)));
                wcr.DrawPolygon(vertsTop.ToArray(), 1, Color.Yellow);
                wcr.DrawPolygon(vertsBottom.ToArray(), 1, Color.Yellow);
            }
        }
Пример #9
0
        public void Render(WorldRenderer wr)
        {
            // Need at least 4 points to smooth the contrail over
            if (length - skip < 4)
                return;

            var screenWidth = wr.ScreenVector(new WVec(width, WDist.Zero, WDist.Zero))[0];
            var wcr = Game.Renderer.WorldRgbaColorRenderer;

            // Start of the first line segment is the tail of the list - don't smooth it.
            var curPos = trail[Index(next - skip - 1)];
            var curColor = color;
            for (var i = 0; i < length - skip - 4; i++)
            {
                var j = next - skip - i - 2;
                var nextPos = Average(trail[Index(j)], trail[Index(j - 1)], trail[Index(j - 2)], trail[Index(j - 3)]);
                var nextColor = Exts.ColorLerp(i * 1f / (length - 4), color, Color.Transparent);

                if (!world.FogObscures(curPos) && !world.FogObscures(nextPos))
                    wcr.DrawLine(wr.Screen3DPosition(curPos), wr.Screen3DPosition(nextPos), screenWidth, curColor, nextColor);

                curPos = nextPos;
                curColor = nextColor;
            }
        }
Пример #10
0
        public void DrawCombatOverlay(WorldRenderer wr, RgbaColorRenderer wcr, Actor actor)
        {
            var actorPos = actor.CenterPosition;

            var a = actorPos + new WVec(PointA.X, PointA.Y, VerticalTopOffset).Rotate(actor.Orientation);
            var b = actorPos + new WVec(PointB.X, PointB.Y, VerticalTopOffset).Rotate(actor.Orientation);
            var aa = actorPos + new WVec(PointA.X, PointA.Y, VerticalBottomOffset).Rotate(actor.Orientation);
            var bb = actorPos + new WVec(PointB.X, PointB.Y, VerticalBottomOffset).Rotate(actor.Orientation);

            var offset1 = new WVec(a.Y - b.Y, b.X - a.X, 0);
            offset1 = offset1 * Radius.Length / offset1.Length;
            var offset2 = new WVec(aa.Y - bb.Y, bb.X - aa.X, 0);
            offset2 = offset2 * Radius.Length / offset2.Length;

            var c = Color.Yellow;
            RangeCircleRenderable.DrawRangeCircle(wr, a, Radius, 1, c, 0, c);
            RangeCircleRenderable.DrawRangeCircle(wr, b, Radius, 1, c, 0, c);
            wcr.DrawLine(new[] { wr.Screen3DPosition(a - offset1), wr.Screen3DPosition(b - offset1) }, 1, c);
            wcr.DrawLine(new[] { wr.Screen3DPosition(a + offset1), wr.Screen3DPosition(b + offset1) }, 1, c);

            RangeCircleRenderable.DrawRangeCircle(wr, aa, Radius, 1, c, 0, c);
            RangeCircleRenderable.DrawRangeCircle(wr, bb, Radius, 1, c, 0, c);
            wcr.DrawLine(new[] { wr.Screen3DPosition(aa - offset2), wr.Screen3DPosition(bb - offset2) }, 1, c);
            wcr.DrawLine(new[] { wr.Screen3DPosition(aa + offset2), wr.Screen3DPosition(bb + offset2) }, 1, c);
        }
Пример #11
0
        public void Render(WorldRenderer wr)
        {
            var wcr = Game.Renderer.WorldRgbaColorRenderer;
            var center = wr.Screen3DPosition(centerPosition);

            for (var i = 0; i < trailCount; i++)
            {
                var angle = trailAngle - new WAngle(i * (trailSeparation.Angle <= 512 ? 1 : -1));
                var length = radius.Length * new WVec(angle.Cos(), angle.Sin(), 0) / 1024;
                var end = wr.Screen3DPosition(centerPosition + length);
                var alpha = color.A - i * color.A / trailCount;

                wcr.DrawLine(center, end, 3, Color.FromArgb(alpha, contrastColor));
                wcr.DrawLine(center, end, 1, Color.FromArgb(alpha, color));
            }

            RangeCircleRenderable.DrawRangeCircle(wr, centerPosition, radius, 1, color, 3, contrastColor);
        }
Пример #12
0
        void DrawArmaments(Actor self, AttackBase attack, WorldRenderer wr, RgbaColorRenderer wcr, float iz)
        {
            var c = Color.White;

            // Fire ports on garrisonable structures
            var garrison = attack as AttackGarrisoned;
            if (garrison != null)
            {
                var bodyOrientation = coords.Value.QuantizeOrientation(self, self.Orientation);
                foreach (var p in garrison.Info.Ports)
                {
                    var pos = self.CenterPosition + coords.Value.LocalToWorld(p.Offset.Rotate(bodyOrientation));
                    var da = coords.Value.LocalToWorld(new WVec(224, 0, 0).Rotate(WRot.FromYaw(p.Yaw + p.Cone)).Rotate(bodyOrientation));
                    var db = coords.Value.LocalToWorld(new WVec(224, 0, 0).Rotate(WRot.FromYaw(p.Yaw - p.Cone)).Rotate(bodyOrientation));

                    var o = wr.Screen3DPosition(pos);
                    var a = wr.Screen3DPosition(pos + da * 224 / da.Length);
                    var b = wr.Screen3DPosition(pos + db * 224 / db.Length);
                    wcr.DrawLine(o, a, iz, c);
                    wcr.DrawLine(o, b, iz, c);
                }

                return;
            }

            foreach (var a in attack.Armaments)
            {
                foreach (var b in a.Barrels)
                {
                    var muzzle = self.CenterPosition + a.MuzzleOffset(self, b);
                    var dirOffset = new WVec(0, -224, 0).Rotate(a.MuzzleOrientation(self, b));

                    var sm = wr.Screen3DPosition(muzzle);
                    var sd = wr.Screen3DPosition(muzzle + dirOffset);
                    wcr.DrawLine(sm, sd, iz, c);
                    TargetLineRenderable.DrawTargetMarker(wr, c, sm);
                }
            }
        }
Пример #13
0
        void IRenderAboveWorld.RenderAboveWorld(Actor self, WorldRenderer wr)
        {
            if (devMode == null || !devMode.ShowCombatGeometry)
                return;

            var wcr = Game.Renderer.WorldRgbaColorRenderer;
            var iz = 1 / wr.Viewport.Zoom;

            if (healthInfo != null)
                healthInfo.Shape.DrawCombatOverlay(wr, wcr, self);

            var blockers = allBlockers.Where(Exts.IsTraitEnabled).ToList();
            if (blockers.Count > 0)
            {
                var hc = Color.Orange;
                var height = new WVec(0, 0, blockers.Max(b => b.BlockingHeight.Length));
                var ha = wr.Screen3DPosition(self.CenterPosition);
                var hb = wr.Screen3DPosition(self.CenterPosition + height);
                wcr.DrawLine(ha, hb, iz, hc);
                TargetLineRenderable.DrawTargetMarker(wr, hc, ha);
                TargetLineRenderable.DrawTargetMarker(wr, hc, hb);
            }

            foreach (var attack in self.TraitsImplementing<AttackBase>().Where(x => !x.IsTraitDisabled))
                DrawArmaments(self, attack, wr, wcr, iz);
        }