Exemplo n.º 1
0
		public void SetPreview(ActorInfo actor, TypeDictionary td)
		{
			var init = new ActorPreviewInitializer(actor, worldRenderer, td);
			preview = actor.TraitInfos<IRenderActorPreviewInfo>()
				.SelectMany(rpi => rpi.RenderPreview(init))
				.ToArray();

			// Calculate the preview bounds
			PreviewOffset = int2.Zero;
			IdealPreviewSize = int2.Zero;

			var r = preview
				.SelectMany(p => p.Render(worldRenderer, WPos.Zero))
				.OrderBy(WorldRenderer.RenderableScreenZPositionComparisonKey)
				.Select(rr => rr.PrepareRender(worldRenderer));

			if (r.Any())
			{
				var b = r.First().ScreenBounds(worldRenderer);
				foreach (var rr in r.Skip(1))
					b = Rectangle.Union(b, rr.ScreenBounds(worldRenderer));

				IdealPreviewSize = new int2(b.Width, b.Height);
				PreviewOffset = -new int2(b.Left, b.Top) - IdealPreviewSize / 2;
			}
		}
Exemplo n.º 2
0
		public IEnumerable<IActorPreview> RenderPreview(ActorPreviewInitializer init)
		{
			var sequenceProvider = init.World.Map.SequenceProvider;
			var faction = init.Get<FactionInit, string>();
			var ownerName = init.Get<OwnerInit>().PlayerName;
			var image = GetImage(init.Actor, sequenceProvider, faction);
			var palette = init.WorldRenderer.Palette(Palette ?? PlayerPalette + ownerName);

			var facings = 0;
			var body = init.Actor.TraitInfoOrDefault<BodyOrientationInfo>();
			if (body != null)
			{
				facings = body.QuantizedFacings;

				if (facings == -1)
				{
					var qbo = init.Actor.TraitInfoOrDefault<IQuantizeBodyOrientationInfo>();
					facings = qbo != null ? qbo.QuantizedBodyFacings(init.Actor, sequenceProvider, faction) : 1;
				}
			}

			foreach (var spi in init.Actor.TraitInfos<IRenderActorPreviewSpritesInfo>())
				foreach (var preview in spi.RenderPreviewSprites(init, this, image, facings, palette))
					yield return preview;
		}
Exemplo n.º 3
0
        public override IEnumerable<IActorPreview> RenderPreviewSprites(ActorPreviewInitializer init, RenderSpritesInfo rs, string image, int facings, PaletteReference p)
        {
            // Show a static frame instead of animating all of the fullness states
            var anim = new Animation(init.World, image, () => 0);
            anim.PlayFetchIndex(RenderSprites.NormalizeSequence(anim, init.GetDamageState(), Sequence), () => 0);

            yield return new SpriteActorPreview(anim, WVec.Zero, 0, p, rs.Scale);
        }
Exemplo n.º 4
0
        public IEnumerable <IActorPreview> RenderPreviewSprites(ActorPreviewInitializer init, RenderSpritesInfo rs, string image, int facings, PaletteReference p)
        {
            if (init.Contains <HideBibPreviewInit>() && init.Get <HideBibPreviewInit, bool>())
            {
                yield break;
            }

            if (Palette != null)
            {
                p = init.WorldRenderer.Palette(Palette);
            }

            var bi = init.Actor.TraitInfo <BuildingInfo>();

            var width        = bi.Dimensions.X;
            var bibOffset    = bi.Dimensions.Y - 1;
            var centerOffset = FootprintUtils.CenterOffset(init.World, bi);
            var rows         = HasMinibib ? 1 : 2;
            var map          = init.World.Map;
            var location     = CPos.Zero;

            if (init.Contains <LocationInit>())
            {
                location = init.Get <LocationInit, CPos>();
            }

            for (var i = 0; i < rows * width; i++)
            {
                var index      = i;
                var anim       = new Animation(init.World, image);
                var cellOffset = new CVec(i % width, i / width + bibOffset);
                var cell       = location + cellOffset;

                // Some mods may define terrain-specific bibs
                var terrain      = map.GetTerrainInfo(cell).Type;
                var testSequence = Sequence + "-" + terrain;
                var sequence     = anim.HasSequence(testSequence) ? testSequence : Sequence;
                anim.PlayFetchIndex(sequence, () => index);
                anim.IsDecoration = true;

                // Z-order is one set to the top of the footprint
                var offset = map.CenterOfCell(cell) - map.CenterOfCell(location) - centerOffset;
                yield return(new SpriteActorPreview(anim, offset, -(offset.Y + centerOffset.Y + 512), p, rs.Scale));
            }
        }
Exemplo n.º 5
0
        public IEnumerable <IActorPreview> RenderPreviewSprites(ActorPreviewInitializer init, RenderSpritesInfo rs, string image, int facings, PaletteReference p)
        {
            if (!EnabledByDefault)
            {
                yield break;
            }

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

            // For this, image must not be null
            if (Palette != null)
            {
                p = init.WorldRenderer.Palette(Palette);
            }

            Func <int> facing;

            if (init.Contains <DynamicFacingInit>())
            {
                facing = init.Get <DynamicFacingInit, Func <int> >();
            }
            else
            {
                var f = init.Contains <FacingInit>() ? init.Get <FacingInit, int>() : 0;
                facing = () => f;
            }

            var anim = new Animation(init.World, image);

            anim.PlayThen(OpeningSequence, () => anim.PlayRepeating(Sequence));

            var         body        = init.Actor.TraitInfo <BodyOrientationInfo>();
            Func <WRot> orientation = () => body.QuantizeOrientation(WRot.FromFacing(facing()), facings);
            Func <WVec> offset      = () => body.LocalToWorld(Offset.Rotate(orientation()));
            Func <int>  zOffset     = () =>
            {
                var tmpOffset = offset();
                return(tmpOffset.Y + tmpOffset.Z + 1);
            };

            yield return(new SpriteActorPreview(anim, offset, zOffset, p, rs.Scale));
        }
Exemplo n.º 6
0
        public IEnumerable <IActorPreview> RenderPreviewSprites(ActorPreviewInitializer init, RenderSpritesInfo rs, string image, int facings, PaletteReference p)
        {
            if (UpgradeMinEnabledLevel > 0)
            {
                yield break;
            }

            var body   = init.Actor.Traits.Get <BodyOrientationInfo>();
            var facing = init.Contains <FacingInit>() ? init.Get <FacingInit, int>() : 0;
            var anim   = new Animation(init.World, image, () => facing);

            anim.PlayRepeating(Sequence);

            var orientation = body.QuantizeOrientation(new WRot(WAngle.Zero, WAngle.Zero, WAngle.FromFacing(facing)), facings);
            var offset      = body.LocalToWorld(Offset.Rotate(orientation));

            yield return(new SpriteActorPreview(anim, offset, offset.Y + offset.Z + 1, p, rs.Scale));
        }
Exemplo n.º 7
0
        public virtual IEnumerable <IActorPreview> RenderPreview(ActorPreviewInitializer init)
        {
            var body             = init.Actor.Traits.Get <BodyOrientationInfo>();
            var sequenceProvider = init.World.Map.SequenceProvider;
            var image            = Image ?? init.Actor.Name;
            var facings          = body.QuantizedFacings == -1 ? init.Actor.Traits.Get <IQuantizeBodyOrientationInfo>().QuantizedBodyFacings(sequenceProvider, init.Actor) : body.QuantizedFacings;
            var palette          = init.WorldRenderer.Palette(Palette ?? (init.Owner != null ? PlayerPalette + init.Owner.InternalName : null));

            var facing      = init.Contains <FacingInit>() ? init.Get <FacingInit, int>() : 0;
            var orientation = WRot.FromFacing(facing);
            var components  = init.Actor.Traits.WithInterface <IRenderActorPreviewVoxelsInfo>()
                              .SelectMany(rvpi => rvpi.RenderPreviewVoxels(init, this, image, orientation, facings, palette))
                              .ToArray();

            yield return(new VoxelPreview(components, WVec.Zero, 0, this.Scale, this.LightPitch,
                                          this.LightYaw, this.LightAmbientColor, this.LightDiffuseColor, body.CameraPitch,
                                          palette, init.WorldRenderer.Palette(NormalsPalette), init.WorldRenderer.Palette("shadow")));
        }
Exemplo n.º 8
0
        public IEnumerable <VoxelAnimation> RenderPreviewVoxels(ActorPreviewInitializer init, RenderVoxelsInfo rv, string image, WRot orientation, int facings, PaletteReference p)
        {
            var sequence = LandSequence;

            if (init.Contains <LocationInit>())
            {
                var location = init.Get <LocationInit>().Value(init.World);
                var onWater  = init.World.Map.GetTerrainInfo(location).IsWater;
                sequence = onWater ? WaterSequence : LandSequence;
            }

            var body  = init.Actor.TraitInfo <BodyOrientationInfo>();
            var voxel = VoxelProvider.GetVoxel(image, sequence);

            yield return(new VoxelAnimation(voxel, () => WVec.Zero,
                                            () => new[] { body.QuantizeOrientation(orientation, facings) },
                                            () => false, () => 0));
        }
Exemplo n.º 9
0
        public IEnumerable <IActorPreview> RenderPreviewSprites(ActorPreviewInitializer init, string image, int facings, PaletteReference p)
        {
            if (!EnabledByDefault)
            {
                yield break;
            }

            if (Palette != null)
            {
                var ownerName = init.Get <OwnerInit>().InternalName;
                p = init.WorldRenderer.Palette(IsPlayerPalette ? Palette + ownerName : Palette);
            }

            Func <WAngle> facing;
            var           dynamicfacingInit = init.GetOrDefault <DynamicFacingInit>();

            if (dynamicfacingInit != null)
            {
                facing = dynamicfacingInit.Value;
            }
            else
            {
                var f = init.GetValue <FacingInit, WAngle>(WAngle.Zero);
                facing = () => f;
            }

            var anim = new Animation(init.World, Image ?? image, facing)
            {
                IsDecoration = IsDecoration
            };

            anim.PlayRepeating(RenderSprites.NormalizeSequence(anim, init.GetDamageState(), Sequence));

            var         body        = init.Actor.TraitInfo <BodyOrientationInfo>();
            Func <WRot> orientation = () => body.QuantizeOrientation(WRot.FromYaw(facing()), facings);
            Func <WVec> offset      = () => body.LocalToWorld(Offset.Rotate(orientation()));
            Func <int>  zOffset     = () =>
            {
                var tmpOffset = offset();
                return(tmpOffset.Y + tmpOffset.Z + 1);
            };

            yield return(new SpriteActorPreview(anim, offset, zOffset, p));
        }
Exemplo n.º 10
0
        public override IEnumerable <IActorPreview> RenderPreviewSprites(ActorPreviewInitializer init, RenderSpritesInfo rs, string image, int facings, PaletteReference p)
        {
            if (!EnabledByDefault)
            {
                yield break;
            }

            var t   = init.Actor.TraitInfos <TurretedInfo>().FirstOrDefault();
            var wsb = init.Actor.TraitInfos <WithSpriteBodyInfo>().FirstOrDefault();

            // Show the correct turret facing
            var facing = init.Contains <TurretFacingInit>() ? init.Get <TurretFacingInit>().Value(init.World) : t.InitialFacing;

            var anim = new Animation(init.World, image, () => facing);

            anim.PlayRepeating(RenderSprites.NormalizeSequence(anim, init.GetDamageState(), wsb.Sequence));

            yield return(new SpriteActorPreview(anim, () => WVec.Zero, () => 0, p, rs.Scale));
        }
Exemplo n.º 11
0
        IEnumerable <IRenderable> IRender.Render(Actor self, WorldRenderer wr)
        {
            var bodyOrientation = body.QuantizeOrientation(self, self.Orientation);
            var pos             = self.CenterPosition;
            var i = 0;

            // Generate missing previews
            var missing = previews
                          .Where(kv => kv.Value == null)
                          .Select(kv => kv.Key)
                          .ToList();

            foreach (var p in missing)
            {
                var passengerInits = new TypeDictionary()
                {
                    new OwnerInit(p.Owner),
                    new DynamicFacingInit(() => body.QuantizeFacing(facing.Facing)),
                };

                foreach (var api in p.TraitsImplementing <IActorPreviewInitModifier>())
                {
                    api.ModifyActorPreviewInit(p, passengerInits);
                }

                var init = new ActorPreviewInitializer(p.Info, wr, passengerInits);
                previews[p] = p.Info.TraitInfos <IRenderActorPreviewInfo>()
                              .SelectMany(rpi => rpi.RenderPreview(init))
                              .ToArray();
            }

            foreach (var p in previews.Values.SelectMany(p => p))
            {
                var index       = cargo.PassengerCount > 1 ? i++ % info.LocalOffset.Length : info.LocalOffset.Length / 2;
                var localOffset = info.LocalOffset[index];

                foreach (var pp in p.Render(wr, pos + body.LocalToWorld(localOffset.Rotate(bodyOrientation))))
                {
                    yield return(pp.WithZOffset(1));
                }
            }
        }
Exemplo n.º 12
0
		public IEnumerable<IActorPreview> RenderPreviewSprites(ActorPreviewInitializer init, RenderSpritesInfo rs, string image, int facings, PaletteReference p)
		{
			if (UpgradeMinEnabledLevel > 0)
				yield break;

			var body = init.Actor.TraitInfo<BodyOrientationInfo>();
			var t = init.Actor.TraitInfos<TurretedInfo>()
				.First(tt => tt.Turret == Turret);

			var ifacing = init.Actor.TraitInfoOrDefault<IFacingInfo>();
			var bodyFacing = ifacing != null ? init.Contains<FacingInit>() ? init.Get<FacingInit, int>() : ifacing.GetInitialFacing() : 0;
			var turretFacing = init.Contains<TurretFacingInit>() ? init.Get<TurretFacingInit, int>() : t.InitialFacing;

			var anim = new Animation(init.World, image, () => turretFacing);
			anim.Play(RenderSprites.NormalizeSequence(anim, init.GetDamageState(), Sequence));

			var orientation = body.QuantizeOrientation(new WRot(WAngle.Zero, WAngle.Zero, WAngle.FromFacing(bodyFacing)), facings);
			var offset = body.LocalToWorld(t.Offset.Rotate(orientation));
			yield return new SpriteActorPreview(anim, offset, -(offset.Y + offset.Z) + 1, p, rs.Scale);
		}
Exemplo n.º 13
0
        public IEnumerable <VoxelAnimation> RenderPreviewVoxels(ActorPreviewInitializer init, RenderVoxelsInfo rv, string image, WRot orientation, int facings, PaletteReference p)
        {
            if (UpgradeMinEnabledLevel > 0)
            {
                yield break;
            }

            var body = init.Actor.TraitInfo <BodyOrientationInfo>();
            var t    = init.Actor.TraitInfos <TurretedInfo>()
                       .First(tt => tt.Turret == Turret);

            var voxel        = VoxelProvider.GetVoxel(image, Sequence);
            var turretOffset = body.LocalToWorld(t.Offset.Rotate(orientation));

            var turretFacing          = Turreted.GetInitialTurretFacing(init, t.InitialFacing, Turret);
            var turretBodyOrientation = new WRot(WAngle.Zero, WAngle.Zero, WAngle.FromFacing(turretFacing) - orientation.Yaw);
            var turretOrientation     = new[] { turretBodyOrientation, body.QuantizeOrientation(orientation, facings) };

            yield return(new VoxelAnimation(voxel, () => turretOffset, () => turretOrientation, () => false, () => 0));
        }
Exemplo n.º 14
0
        public virtual IEnumerable <IActorPreview> RenderPreview(ActorPreviewInitializer init)
        {
            var body             = init.Actor.TraitInfo <BodyOrientationInfo>();
            var faction          = init.Get <FactionInit, string>();
            var ownerName        = init.Get <OwnerInit>().PlayerName;
            var sequenceProvider = init.World.Map.Rules.Sequences;
            var image            = Image ?? init.Actor.Name;
            var facings          = body.QuantizedFacings == -1 ?
                                   init.Actor.TraitInfo <IQuantizeBodyOrientationInfo>().QuantizedBodyFacings(init.Actor, sequenceProvider, faction) :
                                   body.QuantizedFacings;
            var palette = init.WorldRenderer.Palette(Palette ?? PlayerPalette + ownerName);

            var components = init.Actor.TraitInfos <IRenderActorPreviewVoxelsInfo>()
                             .SelectMany(rvpi => rvpi.RenderPreviewVoxels(init, this, image, init.GetOrientation(), facings, palette))
                             .ToArray();

            yield return(new ModelPreview(components, WVec.Zero, 0, Scale, LightPitch,
                                          LightYaw, LightAmbientColor, LightDiffuseColor, body.CameraPitch,
                                          palette, init.WorldRenderer.Palette(NormalsPalette), init.WorldRenderer.Palette(ShadowPalette)));
        }
Exemplo n.º 15
0
        public IEnumerable <IActorPreview> RenderPreviewSprites(ActorPreviewInitializer init, RenderSpritesInfo rs, string image, int facings, PaletteReference p)
        {
            if (!EnabledByDefault)
            {
                yield break;
            }

            if (Palette != null)
            {
                p = init.WorldRenderer.Palette(Palette);
            }

            Func <WAngle> facing;
            var           dynamicfacingInit = init.GetOrDefault <DynamicFacingInit>();

            if (dynamicfacingInit != null)
            {
                var getFacing = dynamicfacingInit.Value;
                facing = () => WAngle.FromFacing(getFacing());
            }
            else
            {
                var f = WAngle.FromFacing(init.GetValue <FacingInit, int>(0));
                facing = () => f;
            }

            var anim = new Animation(init.World, image, facing);

            anim.PlayRepeating(RenderSprites.NormalizeSequence(anim, init.GetDamageState(), Sequence));

            var         body        = init.Actor.TraitInfo <BodyOrientationInfo>();
            Func <WRot> orientation = () => body.QuantizeOrientation(WRot.FromYaw(facing()), facings);
            Func <WVec> offset      = () => body.LocalToWorld(Offset.Rotate(orientation()));
            Func <int>  zOffset     = () =>
            {
                var tmpOffset = offset();
                return(tmpOffset.Y + tmpOffset.Z + 1);
            };

            yield return(new SpriteActorPreview(anim, offset, zOffset, p, rs.Scale));
        }
Exemplo n.º 16
0
        public IEnumerable <ModelAnimation> RenderPreviewVoxels(
            ActorPreviewInitializer init, RenderVoxelsInfo rv, string image, Func <WRot> orientation, int facings, PaletteReference p)
        {
            if (!EnabledByDefault)
            {
                yield break;
            }

            var body = init.Actor.TraitInfo <BodyOrientationInfo>();
            var t    = init.Actor.TraitInfos <TurretedInfo>()
                       .First(tt => tt.Turret == Turret);

            var         model        = init.World.ModelCache.GetModelSequence(image, Sequence);
            Func <WVec> turretOffset = () => body.LocalToWorld(t.Offset.Rotate(orientation()));

            var         turretFacing          = Turreted.TurretFacingFromInit(init, t.InitialFacing, Turret);
            Func <WRot> turretBodyOrientation = () => WRot.FromYaw(WAngle.FromFacing(turretFacing()) - orientation().Yaw);

            yield return(new ModelAnimation(model, turretOffset,
                                            () => new[] { turretBodyOrientation(), body.QuantizeOrientation(orientation(), facings) }, () => false, () => 0, ShowShadow));
        }
Exemplo n.º 17
0
        public new IEnumerable <IActorPreview> RenderPreviewSprites(ActorPreviewInitializer init, RenderSpritesInfo rs, string image, int facings, PaletteReference p)
        {
            if (!EnabledByDefault)
            {
                yield break;
            }

            if (Palette != null)
            {
                p = init.WorldRenderer.Palette(Palette);
            }

            var        idleImage = !string.IsNullOrEmpty(Image) ? Image : image;
            Func <int> facing;

            if (init.Contains <DynamicFacingInit>())
            {
                facing = init.Get <DynamicFacingInit, Func <int> >();
            }
            else
            {
                var f = init.Contains <FacingInit>() ? init.Get <FacingInit, int>() : 0;
                facing = () => f;
            }

            var anim = new Animation(init.World, idleImage, facing);

            anim.PlayRepeating(RenderSprites.NormalizeSequence(anim, init.GetDamageState(), Sequence));

            var         body        = init.Actor.TraitInfo <BodyOrientationInfo>();
            Func <WRot> orientation = () => body.QuantizeOrientation(WRot.FromFacing(facing()), facings);
            Func <WVec> offset      = () => body.LocalToWorld(Offset.Rotate(orientation()));
            Func <int>  zOffset     = () =>
            {
                var tmpOffset = offset();
                return(tmpOffset.Y + tmpOffset.Z + 1);
            };

            yield return(new SpriteActorPreview(anim, offset, zOffset, p, rs.Scale));
        }
Exemplo n.º 18
0
        public IEnumerable <IActorPreview> RenderPreviewSprites(ActorPreviewInitializer init, RenderSpritesInfo rs, string image, int facings, PaletteReference p)
        {
            if (!EnabledByDefault)
            {
                yield break;
            }

            var anim = new Animation(init.World, image, init.GetFacing());

            anim.PlayRepeating(RenderSprites.NormalizeSequence(anim, init.GetDamageState(), StandSequences.First()));

            if (IsPlayerPalette)
            {
                p = init.WorldRenderer.Palette(Palette + init.Get <OwnerInit>().InternalName);
            }
            else if (Palette != null)
            {
                p = init.WorldRenderer.Palette(Palette);
            }

            yield return(new SpriteActorPreview(anim, () => WVec.Zero, () => 0, p, rs.Scale));
        }
Exemplo n.º 19
0
        public IEnumerable <IActorPreview> RenderPreview(ActorPreviewInitializer init)
        {
            var sequenceProvider = init.World.Map.SequenceProvider;
            var image            = RenderSprites.GetImage(init.Actor);
            var palette          = init.WorldRenderer.Palette(Palette ?? (init.Owner != null ? PlayerPalette + init.Owner.InternalName : null));

            var facings = 0;
            var body    = init.Actor.Traits.GetOrDefault <BodyOrientationInfo>();

            if (body != null)
            {
                facings = body.QuantizedFacings == -1 ? init.Actor.Traits.Get <IQuantizeBodyOrientationInfo>().QuantizedBodyFacings(sequenceProvider, init.Actor) : body.QuantizedFacings;
            }

            foreach (var spi in init.Actor.Traits.WithInterface <IRenderActorPreviewSpritesInfo>())
            {
                foreach (var preview in spi.RenderPreviewSprites(init, this, image, facings, palette))
                {
                    yield return(preview);
                }
            }
        }
Exemplo n.º 20
0
        public IEnumerable <IActorPreview> RenderPreviewSprites(ActorPreviewInitializer init, RenderSpritesInfo rs, string image, int facings, PaletteReference p)
        {
            if (UpgradeMinEnabledLevel > 0)
            {
                yield break;
            }

            var body     = init.Actor.TraitInfo <BodyOrientationInfo>();
            var armament = init.Actor.TraitInfos <ArmamentInfo>()
                           .First(a => a.Name == Armament);
            var t = init.Actor.TraitInfos <TurretedInfo>()
                    .First(tt => tt.Turret == armament.Turret);

            var anim = new Animation(init.World, image, () => t.InitialFacing);

            anim.Play(RenderSprites.NormalizeSequence(anim, init.GetDamageState(), Sequence));

            var turretOrientation = body.QuantizeOrientation(new WRot(WAngle.Zero, WAngle.Zero, WAngle.FromFacing(t.InitialFacing)), facings);
            var turretOffset      = body.LocalToWorld(t.Offset.Rotate(turretOrientation));

            yield return(new SpriteActorPreview(anim, turretOffset, turretOffset.Y + turretOffset.Z, p, rs.Scale));
        }
Exemplo n.º 21
0
        public IEnumerable <ModelAnimation> RenderPreviewVoxels(
            ActorPreviewInitializer init, RenderVoxelsInfo rv, string image, Func <WRot> orientation, int facings, PaletteReference p)
        {
            if (!EnabledByDefault)
            {
                yield break;
            }

            var body     = init.Actor.TraitInfo <BodyOrientationInfo>();
            var armament = init.Actor.TraitInfos <ArmamentInfo>()
                           .First(a => a.Name == Armament);
            var t = init.Actor.TraitInfos <TurretedInfo>()
                    .First(tt => tt.Turret == armament.Turret);

            var model = init.World.ModelCache.GetModelSequence(image, Sequence);

            var         turretOrientation = t.PreviewOrientation(init, orientation, facings);
            Func <WVec> barrelOffset      = () => body.LocalToWorld(t.Offset + LocalOffset.Rotate(turretOrientation()));
            Func <WRot> barrelOrientation = () => LocalOrientation.Rotate(turretOrientation());

            yield return(new ModelAnimation(model, barrelOffset, barrelOrientation, () => false, () => 0, ShowShadow));
        }
Exemplo n.º 22
0
        public IEnumerable <IActorPreview> RenderPreviewSprites(ActorPreviewInitializer init, string image, int facings, PaletteReference p)
        {
            if (!EnabledByDefault)
            {
                yield break;
            }

            var body = init.Actor.TraitInfo <BodyOrientationInfo>();
            var t    = init.Actor.TraitInfos <TurretedInfo>()
                       .First(tt => tt.Turret == Turret);

            var turretFacing = t.WorldFacingFromInit(init);
            var anim         = new Animation(init.World, image, turretFacing);

            anim.Play(RenderSprites.NormalizeSequence(anim, init.GetDamageState(), Sequence));

            var         facing      = init.GetFacing();
            Func <WRot> orientation = () => body.QuantizeOrientation(WRot.FromYaw(facing()), facings);
            Func <WVec> offset      = () => body.LocalToWorld(t.Offset.Rotate(orientation()));
            Func <int>  zOffset     = () =>
            {
                var tmpOffset = offset();
                return(-(tmpOffset.Y + tmpOffset.Z) + 1);
            };

            if (IsPlayerPalette)
            {
                p = init.WorldRenderer.Palette(Palette + init.Get <OwnerInit>().InternalName);
            }
            else if (Palette != null)
            {
                p = init.WorldRenderer.Palette(Palette);
            }

            yield return(new SpriteActorPreview(anim, offset, zOffset, p));
        }
Exemplo n.º 23
0
        public IEnumerable <IRenderable> RenderAboveShroud(WorldRenderer wr, World world)
        {
            var xy      = wr.Viewport.ViewToWorld(Viewport.LastMousePos);
            var topLeft = xy - FootprintUtils.AdjustForBuildingSize(buildingInfo);
            var offset  = world.Map.CenterOfCell(topLeft) + FootprintUtils.CenterOffset(world, buildingInfo);
            var rules   = world.Map.Rules;

            var actorInfo = rules.Actors[building];

            foreach (var dec in actorInfo.TraitInfos <IPlaceBuildingDecorationInfo>())
            {
                foreach (var r in dec.Render(wr, world, actorInfo, offset))
                {
                    yield return(r);
                }
            }

            var cells = new Dictionary <CPos, bool>();

            var plugInfo = rules.Actors[building].TraitInfoOrDefault <PlugInfo>();

            if (plugInfo != null)
            {
                if (buildingInfo.Dimensions.X != 1 || buildingInfo.Dimensions.Y != 1)
                {
                    throw new InvalidOperationException("Plug requires a 1x1 sized Building");
                }

                cells.Add(topLeft, AcceptsPlug(topLeft, plugInfo));
            }
            else if (rules.Actors[building].HasTraitInfo <LineBuildInfo>())
            {
                // Linebuild for walls.
                if (buildingInfo.Dimensions.X != 1 || buildingInfo.Dimensions.Y != 1)
                {
                    throw new InvalidOperationException("LineBuild requires a 1x1 sized Building");
                }

                if (!Game.GetModifierKeys().HasModifier(Modifiers.Shift))
                {
                    foreach (var t in BuildingUtils.GetLineBuildCells(world, topLeft, building, buildingInfo))
                    {
                        cells.Add(t, buildingInfo.IsCloseEnoughToBase(world, world.LocalPlayer, building, t));
                    }
                }
                else
                {
                    cells.Add(topLeft, buildingInfo.IsCloseEnoughToBase(world, world.LocalPlayer, building, topLeft));
                }
            }
            else
            {
                if (!initialized)
                {
                    var td = new TypeDictionary()
                    {
                        new FactionInit(faction),
                        new OwnerInit(queue.Actor.Owner),
                        new HideBibPreviewInit()
                    };

                    var init = new ActorPreviewInitializer(rules.Actors[building], wr, td);
                    preview = rules.Actors[building].TraitInfos <IRenderActorPreviewInfo>()
                              .SelectMany(rpi => rpi.RenderPreview(init))
                              .ToArray();

                    initialized = true;
                }

                var previewRenderables = preview
                                         .SelectMany(p => p.Render(wr, offset))
                                         .OrderBy(WorldRenderer.RenderableScreenZPositionComparisonKey);

                foreach (var r in previewRenderables)
                {
                    yield return(r);
                }

                var res           = world.WorldActor.Trait <ResourceLayer>();
                var isCloseEnough = buildingInfo.IsCloseEnoughToBase(world, world.LocalPlayer, building, topLeft);
                foreach (var t in FootprintUtils.Tiles(rules, building, buildingInfo, topLeft))
                {
                    cells.Add(t, isCloseEnough && world.IsCellBuildable(t, buildingInfo) && res.GetResource(t) == null);
                }
            }

            var pal        = wr.Palette(placeBuildingInfo.Palette);
            var topLeftPos = world.Map.CenterOfCell(topLeft);

            foreach (var c in cells)
            {
                var tile = c.Value ? buildOk : buildBlocked;
                var pos  = world.Map.CenterOfCell(c.Key);
                yield return(new SpriteRenderable(tile, pos, new WVec(0, 0, topLeftPos.Z - pos.Z),
                                                  -511, pal, 1f, true));
            }
        }
Exemplo n.º 24
0
        public override IEnumerable <IActorPreview> RenderPreviewSprites(ActorPreviewInitializer init, RenderSpritesInfo rs, string image, int facings, PaletteReference p)
        {
            if (!EnabledByDefault)
            {
                yield break;
            }

            var adjacent = 0;

            if (init.Contains <RuntimeNeighbourInit>())
            {
                var location = CPos.Zero;
                if (init.Contains <LocationInit>())
                {
                    location = init.Get <LocationInit, CPos>();
                }

                var neighbours = init.Get <RuntimeNeighbourInit, Dictionary <CPos, string[]> >();
                foreach (var kv in neighbours)
                {
                    var haveNeighbour = false;
                    foreach (var n in kv.Value)
                    {
                        var rb = init.World.Map.Rules.Actors[n].TraitInfos <IWallConnectorInfo>().FirstEnabledTraitOrDefault();
                        if (rb != null && rb.GetWallConnectionType() == Type)
                        {
                            haveNeighbour = true;
                            break;
                        }
                    }

                    if (!haveNeighbour)
                    {
                        continue;
                    }

                    if (kv.Key == location + new CVec(0, -1))
                    {
                        adjacent |= 1;
                    }
                    else if (kv.Key == location + new CVec(+1, 0))
                    {
                        adjacent |= 2;
                    }
                    else if (kv.Key == location + new CVec(0, +1))
                    {
                        adjacent |= 4;
                    }
                    else if (kv.Key == location + new CVec(-1, 0))
                    {
                        adjacent |= 8;
                    }
                }
            }

            var anim = new Animation(init.World, image, () => 0);

            anim.PlayFetchIndex(RenderSprites.NormalizeSequence(anim, init.GetDamageState(), Sequence), () => adjacent);

            yield return(new SpriteActorPreview(anim, () => WVec.Zero, () => 0, p, rs.Scale));
        }
Exemplo n.º 25
0
        public override IEnumerable<IActorPreview> RenderPreviewSprites(ActorPreviewInitializer init, RenderSpritesInfo rs, string image, int facings, PaletteReference p)
        {
            foreach (var orig in base.RenderPreviewSprites(init, rs, image, facings, p))
                yield return orig;

            // Show additional roof overlay
            var anim = new Animation(init.World, image, () => 0);
            anim.PlayRepeating("idle-top");

            var bi = init.Actor.Traits.Get<BuildingInfo>();
            var offset = FootprintUtils.CenterOffset(init.World, bi).Y + 512;
            yield return new SpriteActorPreview(anim, WVec.Zero, offset, p, rs.Scale);
        }
        public IEnumerable <IRenderable> RenderAboveShroud(WorldRenderer wr, World world)
        {
            var topLeft        = viewport.ViewToWorld(Viewport.LastMousePos + topLeftScreenOffset);
            var centerPosition = world.Map.CenterOfCell(topLeft) + centerOffset;
            var rules          = world.Map.Rules;

            foreach (var dec in actorInfo.TraitInfos <IPlaceBuildingDecorationInfo>())
            {
                foreach (var r in dec.RenderAnnotations(wr, world, actorInfo, centerPosition))
                {
                    yield return(r);
                }
            }

            var cells = new Dictionary <CPos, CellType>();

            if (!initialized)
            {
                var td = new TypeDictionary()
                {
                    new FactionInit(faction),
                    new OwnerInit(queue.Actor.Owner),
                };

                foreach (var api in actorInfo.TraitInfos <IActorPreviewInitInfo>())
                {
                    foreach (var o in api.ActorPreviewInits(actorInfo, ActorPreviewType.PlaceBuilding))
                    {
                        td.Add(o);
                    }
                }

                var init = new ActorPreviewInitializer(actorInfo, wr, td);
                preview = actorInfo.TraitInfos <IRenderActorPreviewInfo>()
                          .SelectMany(rpi => rpi.RenderPreview(init))
                          .ToArray();

                initialized = true;
            }

            var previewRenderables = preview
                                     .SelectMany(p => p.Render(wr, centerPosition))
                                     .OrderBy(WorldRenderer.RenderableZPositionComparisonKey);

            foreach (var r in previewRenderables)
            {
                yield return(r);
            }

            var res           = world.WorldActor.TraitOrDefault <ResourceLayer>();
            var isCloseEnough = buildingInfo.IsCloseEnoughToBase(world, world.LocalPlayer, actorInfo, topLeft);

            foreach (var t in buildingInfo.Tiles(topLeft))
            {
                cells.Add(t, MakeCellType(isCloseEnough && world.IsCellBuildable(t, actorInfo, buildingInfo) && (res == null || res.GetResourceDensity(t) == 0)));
            }

            var cellPalette = wr.Palette(footprintPlaceBuildingPreviewInfo.Palette);
            var linePalette = wr.Palette(footprintPlaceBuildingPreviewInfo.LineBuildSegmentPalette);
            var topLeftPos  = world.Map.CenterOfCell(topLeft);

            foreach (var c in cells)
            {
                var tile = !c.Value.HasFlag(CellType.Invalid) ? buildOk : buildBlocked;
                var pal  = c.Value.HasFlag(CellType.LineBuild) ? linePalette : cellPalette;
                var pos  = world.Map.CenterOfCell(c.Key);
                yield return(new SpriteRenderable(tile, pos, new WVec(0, 0, topLeftPos.Z - pos.Z),
                                                  -511, pal, 1f, true));
            }
        }
Exemplo n.º 27
0
        public IEnumerable <IRenderable> RenderAfterWorld(WorldRenderer wr, World world)
        {
            var xy      = wr.Viewport.ViewToWorld(Viewport.LastMousePos);
            var topLeft = xy - FootprintUtils.AdjustForBuildingSize(BuildingInfo);

            var rules = world.Map.Rules;

            var actorInfo = rules.Actors[Building];

            foreach (var dec in actorInfo.Traits.WithInterface <IPlaceBuildingDecoration>())
            {
                foreach (var r in dec.Render(wr, world, actorInfo, world.Map.CenterOfCell(xy)))
                {
                    yield return(r);
                }
            }

            var cells = new Dictionary <CPos, bool>();

            // Linebuild for walls.
            // Requires a 1x1 footprint
            if (rules.Actors[Building].Traits.Contains <LineBuildInfo>())
            {
                if (BuildingInfo.Dimensions.X != 1 || BuildingInfo.Dimensions.Y != 1)
                {
                    throw new InvalidOperationException("LineBuild requires a 1x1 sized Building");
                }

                foreach (var t in BuildingUtils.GetLineBuildCells(world, topLeft, Building, BuildingInfo))
                {
                    cells.Add(t, BuildingInfo.IsCloseEnoughToBase(world, world.LocalPlayer, Building, t));
                }
            }
            else
            {
                if (!initialized)
                {
                    var init = new ActorPreviewInitializer(rules.Actors[Building], Producer.Owner, wr, new TypeDictionary());
                    preview = rules.Actors[Building].Traits.WithInterface <IRenderActorPreviewInfo>()
                              .SelectMany(rpi => rpi.RenderPreview(init))
                              .ToArray();

                    initialized = true;
                }

                var comparer           = new RenderableComparer(wr);
                var offset             = world.Map.CenterOfCell(topLeft) + FootprintUtils.CenterOffset(world, BuildingInfo);
                var previewRenderables = preview
                                         .SelectMany(p => p.Render(wr, offset))
                                         .OrderBy(r => r, comparer);

                foreach (var r in previewRenderables)
                {
                    yield return(r);
                }

                var res           = world.WorldActor.Trait <ResourceLayer>();
                var isCloseEnough = BuildingInfo.IsCloseEnoughToBase(world, world.LocalPlayer, Building, topLeft);
                foreach (var t in FootprintUtils.Tiles(rules, Building, BuildingInfo, topLeft))
                {
                    cells.Add(t, isCloseEnough && world.IsCellBuildable(t, BuildingInfo) && res.GetResource(t) == null);
                }
            }

            var pal = wr.Palette("terrain");

            foreach (var c in cells)
            {
                var tile = c.Value ? buildOk : buildBlocked;
                yield return(new SpriteRenderable(tile, world.Map.CenterOfCell(c.Key),
                                                  WVec.Zero, -511, pal, 1f, true));
            }
        }
        public IEnumerable<IRenderable> RenderAfterWorld(WorldRenderer wr, World world)
        {
            var xy = wr.Viewport.ViewToWorld(Viewport.LastMousePos);
            var topLeft = xy - FootprintUtils.AdjustForBuildingSize(BuildingInfo);

            var rules = world.Map.Rules;

            var actorInfo = rules.Actors[Building];
            foreach (var dec in actorInfo.Traits.WithInterface<IPlaceBuildingDecoration>())
                foreach (var r in dec.Render(wr, world, actorInfo, world.Map.CenterOfCell(xy)))
                    yield return r;

            var cells = new Dictionary<CPos, bool>();
            // Linebuild for walls.
            // Requires a 1x1 footprint
            if (rules.Actors[Building].Traits.Contains<LineBuildInfo>())
            {
                if (BuildingInfo.Dimensions.X != 1 || BuildingInfo.Dimensions.Y != 1)
                    throw new InvalidOperationException("LineBuild requires a 1x1 sized Building");

                foreach (var t in BuildingUtils.GetLineBuildCells(world, topLeft, Building, BuildingInfo))
                    cells.Add(t, BuildingInfo.IsCloseEnoughToBase(world, world.LocalPlayer, Building, t));
            }
            else
            {
                if (!initialized)
                {
                    var init = new ActorPreviewInitializer(rules.Actors[Building], Producer.Owner, wr, new TypeDictionary());
                    preview = rules.Actors[Building].Traits.WithInterface<IRenderActorPreviewInfo>()
                        .SelectMany(rpi => rpi.RenderPreview(init))
                        .ToArray();

                    initialized = true;
                }

                var comparer = new RenderableComparer(wr);
                var offset = world.Map.CenterOfCell(topLeft) + FootprintUtils.CenterOffset(world, BuildingInfo);
                var previewRenderables = preview
                    .SelectMany(p => p.Render(wr, offset))
                    .OrderBy(r => r, comparer);

                foreach (var r in previewRenderables)
                    yield return r;

                var res = world.WorldActor.Trait<ResourceLayer>();
                var isCloseEnough = BuildingInfo.IsCloseEnoughToBase(world, world.LocalPlayer, Building, topLeft);
                foreach (var t in FootprintUtils.Tiles(rules, Building, BuildingInfo, topLeft))
                    cells.Add(t, isCloseEnough && world.IsCellBuildable(t, BuildingInfo) && res.GetResource(t) == null);
            }

            var pal = wr.Palette("terrain");
            foreach (var c in cells)
            {
                var tile = c.Value ? buildOk : buildBlocked;
                yield return new SpriteRenderable(tile, world.Map.CenterOfCell(c.Key),
                    WVec.Zero, -511, pal, 1f, true);
            }
        }
Exemplo n.º 29
0
        public IEnumerable <IRenderable> RenderAboveShroud(WorldRenderer wr, World world)
        {
            var topLeft        = viewport.ViewToWorld(GameViewPort.LastMousePos + topLeftScreenOffset);
            var centerPosition = world.Map.CenterOfCell(topLeft) + centerOffset;
            var rules          = world.Map.Rules;

            var actorInfo = rules.Actors[building];

            foreach (var dec in actorInfo.TraitInfos <IPlaceBuildingDecorationInfo>())
            {
                foreach (var r in dec.Render(wr, world, actorInfo, centerPosition))
                {
                    yield return(r);
                }
            }

            var cells = new Dictionary <CPos, CellType>();

            var plugInfo = rules.Actors[building].TraitInfoOrDefault <PlugInfo>();

            if (plugInfo != null)
            {
                if (buildingInfo.Dimensions.X != 1 || buildingInfo.Dimensions.Y != 1)
                {
                    throw new InvalidOperationException("Plug requires a 1x1 sized Building");
                }

                cells.Add(topLeft, MakeCellType(AcceptsPlug(topLeft, plugInfo)));
            }
            else if (rules.Actors[building].HasTraitInfo <LineBuildInfo>())
            {
            }
            else
            {
                if (!initialized)
                {
                    var actor = rules.Actors[building];

                    var td = new TypeDictionary()
                    {
                        new FactionInit(faction),
                        new OwnerInit(queue.Actor.Owner)
                    };

                    foreach (var api in actor.TraitInfos <IActorPreviewInitInfo>())
                    {
                        foreach (var o in api.ActorPreviewInits(actor, ActorPreviewType.PlaceBuilding))
                        {
                            td.Add(o);
                        }
                    }

                    var init = new ActorPreviewInitializer(actor, wr, td);
                    preview = actor.TraitInfos <IRenderActorPreviewInfo>()
                              .SelectMany(rpi => rpi.RenderPreview(init)).ToArray();

                    initialized = true;
                }

                var previewRenderables = preview.SelectMany(p => p.Render(wr, centerPosition)).OrderBy(WorldRenderer.RenderableScreenZPositionComparisonKey);

                foreach (var r in previewRenderables)
                {
                    yield return(r);
                }

                var res           = world.WorldActor.TraitOrDefault <ResourceLayer>();
                var isCloseEnough = buildingInfo.IsCloseEnoughToBase(world, world.LocalPlayer, building, topLeft);
                foreach (var t in buildingInfo.Tiles(topLeft))
                {
                    cells.Add(t, MakeCellType(isCloseEnough && world.IsCellBuildable(t, buildingInfo) && (res == null || res.GetResource(t) == null)));
                }
            }

            var cellPalette = wr.Palette(placeBuildingInfo.Palette);
            var linePalette = wr.Palette(placeBuildingInfo.LineBuildSegmentPalette);
            var topLeftPos  = world.Map.CenterOfCell(topLeft);

            foreach (var cell in cells)
            {
                var tile = !cell.Value.HasFlag(CellType.Invalid) ? buildOk : buildBlocked;
                var pal  = cell.Value.HasFlag(CellType.LineBuild) ? linePalette : cellPalette;
                var pos  = world.Map.CenterOfCell(cell.Key);

                yield return(new SpriteRenderable(tile, pos, new WVec(0, 0, topLeftPos.Z - pos.Z), -511, pal, 1f, true));
            }
        }
Exemplo n.º 30
0
        public override IEnumerable<IActorPreview> RenderPreviewSprites(ActorPreviewInitializer init, RenderSpritesInfo rs, string image, int facings, PaletteReference p)
        {
            var anim = new Animation(init.World, image);
            anim.PlayFetchIndex(RenderSprites.NormalizeSequence(anim, init.GetDamageState(), Sequences.First()), () => 0);

            yield return new SpriteActorPreview(anim, () => WVec.Zero, () => 0, p, rs.Scale);
        }
Exemplo n.º 31
0
        // Turret offset in world-space
        public Func <WVec> PreviewPosition(ActorPreviewInitializer init, Func <WRot> orientation)
        {
            var body = init.Actor.TraitInfo <BodyOrientationInfo>();

            return(() => body.LocalToWorld(Offset.Rotate(orientation())));
        }
Exemplo n.º 32
0
 public override IEnumerable<IActorPreview> RenderPreviewSprites(ActorPreviewInitializer init, RenderSpritesInfo rs, string image, int facings, PaletteReference p)
 {
     var anim = new Animation(init.World, image);
     var sequence = init.World.Type == WorldType.Editor ? EditorSequence : Sequence;
     var palette = init.World.Type == WorldType.Editor ? init.WorldRenderer.Palette(EditorPalette) : p;
     anim.PlayFetchIndex(RenderSprites.NormalizeSequence(anim, init.GetDamageState(), sequence), () => 0);
     yield return new SpriteActorPreview(anim, () => WVec.Zero, () => 0, palette, rs.Scale);
 }
Exemplo n.º 33
0
        public IEnumerable<IActorPreview> RenderPreview(ActorPreviewInitializer init)
        {
            var sequenceProvider = init.World.Map.SequenceProvider;
            var image = RenderSprites.GetImage(init.Actor);
            var palette = init.WorldRenderer.Palette(Palette ?? (init.Owner != null ? PlayerPalette + init.Owner.InternalName : null));

            var facings = 0;
            var body = init.Actor.Traits.GetOrDefault<BodyOrientationInfo>();
            if (body != null)
                facings = body.QuantizedFacings == -1 ? init.Actor.Traits.Get<IQuantizeBodyOrientationInfo>().QuantizedBodyFacings(sequenceProvider, init.Actor) : body.QuantizedFacings;

            foreach (var spi in init.Actor.Traits.WithInterface<IRenderActorPreviewSpritesInfo>())
                foreach (var preview in spi.RenderPreviewSprites(init, this, image, facings, palette))
                    yield return preview;
        }
Exemplo n.º 34
0
        public IEnumerable <IRenderable> RenderAboveShroud(WorldRenderer wr, World world)
        {
            // Draw chrono range
            yield return(new RangeCircleRenderable(
                             self.CenterPosition,
                             WDist.FromCells(self.Trait <StructureChrono>().Info.MaxDistance),
                             0,
                             Color.FromArgb(128, Color.LawnGreen),
                             Color.FromArgb(96, Color.Black)));

            var xy      = wr.Viewport.ViewToWorld(Viewport.LastMousePos);
            var topLeft = xy - FootprintUtils.AdjustForBuildingSize(buildingInfo);
            var offset  = world.Map.CenterOfCell(topLeft) + FootprintUtils.CenterOffset(world, buildingInfo);
            var rules   = world.Map.Rules;

            var actorInfo = self.Info;             // rules.Actors[building];

            foreach (var dec in actorInfo.TraitInfos <IPlaceBuildingDecorationInfo>())
            {
                foreach (var r in dec.Render(wr, world, actorInfo, offset))
                {
                    yield return(r);
                }
            }

            // Cells, we are about to construct and occupy.
            var cells = new Dictionary <CPos, bool>();

            if (!initialized)
            {
                var td = new TypeDictionary()
                {
                    //new OpenRA.Mods.Common.FactionInit(faction),
                    new OpenRA.Mods.Common.FactionInit(""),
                    new OwnerInit(self.Owner),
                    new HideBibPreviewInit()
                };

                var init = new ActorPreviewInitializer(actorInfo, wr, td);
                preview = actorInfo.TraitInfos <IRenderActorPreviewInfo>()
                          .SelectMany(rpi => rpi.RenderPreview(init))
                          .ToArray();

                initialized = true;
            }

            var previewRenderables = preview
                                     .SelectMany(p => p.Render(wr, offset))
                                     .OrderBy(WorldRenderer.RenderableScreenZPositionComparisonKey);

            foreach (var r in previewRenderables)
            {
                yield return(r);
            }

            var res           = world.WorldActor.Trait <ResourceLayer>();
            var selfPos       = self.Trait <IOccupySpace>().TopLeft;
            var isCloseEnough = ((topLeft - selfPos).Length) <= info.MaxDistance;

            foreach (var t in FootprintUtils.Tiles(rules, building, buildingInfo, topLeft))
            {
                cells.Add(t, isCloseEnough && world.IsCellBuildable(t, buildingInfo) && res.GetResource(t) == null);
            }

            var placeBuildingInfo = self.Owner.PlayerActor.Info.TraitInfo <PlaceBuildingInfo>();
            var pal        = wr.Palette(placeBuildingInfo.Palette);
            var topLeftPos = world.Map.CenterOfCell(topLeft);

            // draw red or white buildable cell indicator.
            foreach (var c in cells)
            {
                var tile = c.Value ? buildOk : buildBlocked;
                var pos  = world.Map.CenterOfCell(c.Key);
                yield return(new SpriteRenderable(tile, pos, new WVec(0, 0, topLeftPos.Z - pos.Z),
                                                  -511, pal, 1f, true));
            }
        }
Exemplo n.º 35
0
        public IEnumerable<IRenderable> RenderAboveShroud(WorldRenderer wr, World world)
        {
            var xy = wr.Viewport.ViewToWorld(Viewport.LastMousePos);
            var topLeft = xy - FootprintUtils.AdjustForBuildingSize(buildingInfo);
            var offset = world.Map.CenterOfCell(topLeft) + FootprintUtils.CenterOffset(world, buildingInfo);
            var rules = world.Map.Rules;

            var actorInfo = rules.Actors[building];
            foreach (var dec in actorInfo.TraitInfos<IPlaceBuildingDecorationInfo>())
                foreach (var r in dec.Render(wr, world, actorInfo, offset))
                    yield return r;

            var cells = new Dictionary<CPos, bool>();

            var plugInfo = rules.Actors[building].TraitInfoOrDefault<PlugInfo>();
            if (plugInfo != null)
            {
                if (buildingInfo.Dimensions.X != 1 || buildingInfo.Dimensions.Y != 1)
                    throw new InvalidOperationException("Plug requires a 1x1 sized Building");

                cells.Add(topLeft, AcceptsPlug(topLeft, plugInfo));
            }
            else if (rules.Actors[building].HasTraitInfo<LineBuildInfo>())
            {
                // Linebuild for walls.
                if (buildingInfo.Dimensions.X != 1 || buildingInfo.Dimensions.Y != 1)
                    throw new InvalidOperationException("LineBuild requires a 1x1 sized Building");

                if (!Game.GetModifierKeys().HasModifier(Modifiers.Shift))
                    foreach (var t in BuildingUtils.GetLineBuildCells(world, topLeft, building, buildingInfo))
                        cells.Add(t, buildingInfo.IsCloseEnoughToBase(world, world.LocalPlayer, building, t));
                else
                    cells.Add(topLeft, buildingInfo.IsCloseEnoughToBase(world, world.LocalPlayer, building, topLeft));
            }
            else
            {
                if (!initialized)
                {
                    var td = new TypeDictionary()
                    {
                        new FactionInit(faction),
                        new OwnerInit(queue.Actor.Owner),
                        new HideBibPreviewInit()
                    };

                    var init = new ActorPreviewInitializer(rules.Actors[building], wr, td);
                    preview = rules.Actors[building].TraitInfos<IRenderActorPreviewInfo>()
                        .SelectMany(rpi => rpi.RenderPreview(init))
                        .ToArray();

                    initialized = true;
                }

                var previewRenderables = preview
                    .SelectMany(p => p.Render(wr, offset))
                    .OrderBy(WorldRenderer.RenderableScreenZPositionComparisonKey);

                foreach (var r in previewRenderables)
                    yield return r;

                var res = world.WorldActor.Trait<ResourceLayer>();
                var isCloseEnough = buildingInfo.IsCloseEnoughToBase(world, world.LocalPlayer, building, topLeft);
                foreach (var t in FootprintUtils.Tiles(rules, building, buildingInfo, topLeft))
                    cells.Add(t, isCloseEnough && world.IsCellBuildable(t, buildingInfo) && res.GetResource(t) == null);
            }

            var pal = wr.Palette(placeBuildingInfo.Palette);
            var topLeftPos = world.Map.CenterOfCell(topLeft);
            foreach (var c in cells)
            {
                var tile = c.Value ? buildOk : buildBlocked;
                var pos = world.Map.CenterOfCell(c.Key);
                yield return new SpriteRenderable(tile, pos, new WVec(0, 0, topLeftPos.Z - pos.Z),
                    -511, pal, 1f, true);
            }
        }