Inheritance: IEffect, IScriptBindable, IEffectAboveShroud
Exemplo n.º 1
0
        public void ResolveOrder(Actor self, Order order)
        {
            if (order.OrderString != "PlaceBeacon")
                return;

            var pos = self.World.Map.CenterOfCell(order.TargetLocation);

            self.World.AddFrameEndTask(w =>
            {
                if (playerBeacon != null)
                    self.World.Remove(playerBeacon);

                playerBeacon = new Beacon(self.Owner, pos, info.Duration, info.PalettePrefix);
                self.World.Add(playerBeacon);

                if (self.Owner.IsAlliedWith(self.World.RenderPlayer))
                    Game.Sound.PlayNotification(self.World.Map.Rules, null, info.NotificationType, info.Notification,
                        self.World.RenderPlayer != null ? self.World.RenderPlayer.Faction.InternalName : null);

                if (radarPings != null)
                {
                    if (playerRadarPing != null)
                        radarPings.Remove(playerRadarPing);

                    playerRadarPing = radarPings.Add(
                        () => self.Owner.IsAlliedWith(self.World.RenderPlayer),
                        pos,
                        self.Owner.Color.RGB,
                        info.Duration);
                }
            });
        }
		public AirstrikePowerASEffect(World world, Player p, WPos pos, IEnumerable<Actor> planes, AirstrikePowerASInfo info)
		{
			this.info = info;
			this.world = world;
			this.Owner = p;
			this.pos = pos;
			this.planes = planes;

			if (info.DisplayBeacon)
			{
				var distance = (planes.First().OccupiesSpace.CenterPosition - pos).HorizontalLength;

				beacon = new Beacon(
					Owner,
					pos - new WVec(WDist.Zero, WDist.Zero, world.Map.DistanceAboveTerrain(pos)),
					info.BeaconPaletteIsPlayerPalette,
					info.BeaconPalette,
					info.BeaconImage,
					info.BeaconPoster,
					info.BeaconPosterPalette,
					info.ArrowSequence,
					info.CircleSequence,
					info.ClockSequence,
						() => 1 - ((planes.First().OccupiesSpace.CenterPosition - pos).HorizontalLength - info.BeaconDistanceOffset.Length) * 1f / distance);

				world.AddFrameEndTask(w => w.Add(beacon));
			}
		}
Exemplo n.º 3
0
        public Beacon New(Player owner,  WPos position, int duration = 30 * 25, bool showRadarPings = true, string palettePrefix = "player")
        {
            var playerBeacon = new Beacon(owner, position, duration, palettePrefix);
            owner.PlayerActor.World.AddFrameEndTask(w => w.Add(playerBeacon));

            if (showRadarPings && radarPings != null)
            {
                radarPings.Add(
                    () => owner.IsAlliedWith(owner.World.RenderPlayer),
                    position,
                    owner.Color.RGB,
                    duration);
            }

            return playerBeacon;
        }
Exemplo n.º 4
0
        public override void Activate(Actor self, Order order, SupportPowerManager manager)
        {
            base.Activate(self, order, manager);

            var info = Info as ParatroopersPowerInfo;
            var dropFacing = Util.QuantizeFacing(self.World.SharedRandom.Next(256), info.QuantizedFacings) * (256 / info.QuantizedFacings);
            var dropRotation = WRot.FromFacing(dropFacing);
            var delta = new WVec(0, -1024, 0).Rotate(dropRotation);

            var altitude = self.World.Map.Rules.Actors[info.UnitType].Traits.Get<PlaneInfo>().CruiseAltitude.Range;
            var target = self.World.Map.CenterOfCell(order.TargetLocation) + new WVec(0, 0, altitude);
            var startEdge = target - (self.World.Map.DistanceToEdge(target, -delta) + info.Cordon).Range * delta / 1024;
            var finishEdge = target + (self.World.Map.DistanceToEdge(target, delta) + info.Cordon).Range * delta / 1024;

            Actor camera = null;
            Beacon beacon = null;
            var aircraftInRange = new Dictionary<Actor, bool>();

            Action<Actor> onEnterRange = a =>
            {
                // Spawn a camera and remove the beacon when the first plane enters the target area
                if (info.CameraActor != null && !aircraftInRange.Any(kv => kv.Value))
                {
                    self.World.AddFrameEndTask(w =>
                    {
                        camera = w.CreateActor(info.CameraActor, new TypeDictionary
                        {
                            new LocationInit(order.TargetLocation),
                            new OwnerInit(self.Owner),
                        });
                    });
                }

                if (beacon != null)
                {
                    self.World.AddFrameEndTask(w =>
                    {
                        w.Remove(beacon);
                        beacon = null;
                    });
                }

                aircraftInRange[a] = true;
            };

            Action<Actor> onExitRange = a =>
            {
                aircraftInRange[a] = false;

                // Remove the camera when the final plane leaves the target area
                if (!aircraftInRange.Any(kv => kv.Value))
                {
                    if (camera != null)
                    {
                        camera.QueueActivity(new Wait(info.CameraRemoveDelay));
                        camera.QueueActivity(new RemoveSelf());
                    }

                    camera = null;

                    if (beacon != null)
                    {
                        self.World.AddFrameEndTask(w =>
                        {
                            w.Remove(beacon);
                            beacon = null;
                        });
                    }
                }
            };

            self.World.AddFrameEndTask(w =>
            {
                var notification = self.Owner.IsAlliedWith(self.World.RenderPlayer) ? Info.LaunchSound : Info.IncomingSound;
                Sound.Play(notification);

                Actor distanceTestActor = null;

                var passengersPerPlane = (info.DropItems.Length + info.SquadSize - 1) / info.SquadSize;
                var added = 0;
                for (var i = -info.SquadSize / 2; i <= info.SquadSize / 2; i++)
                {
                    // Even-sized squads skip the lead plane
                    if (i == 0 && (info.SquadSize & 1) == 0)
                        continue;

                    // Includes the 90 degree rotation between body and world coordinates
                    var so = info.SquadOffset;
                    var spawnOffset = new WVec(i * so.Y, -Math.Abs(i) * so.X, 0).Rotate(dropRotation);
                    var targetOffset = new WVec(i * so.Y, 0, 0).Rotate(dropRotation);

                    var a = w.CreateActor(info.UnitType, new TypeDictionary
                    {
                        new CenterPositionInit(startEdge + spawnOffset),
                        new OwnerInit(self.Owner),
                        new FacingInit(dropFacing),
                    });

                    var drop = a.Trait<ParaDrop>();
                    drop.SetLZ(w.Map.CellContaining(target + targetOffset), !info.AllowImpassableCells);
                    drop.OnEnteredDropRange += onEnterRange;
                    drop.OnExitedDropRange += onExitRange;
                    drop.OnRemovedFromWorld += onExitRange;

                    var cargo = a.Trait<Cargo>();
                    var passengers = info.DropItems.Skip(added).Take(passengersPerPlane);
                    added += passengersPerPlane;

                    foreach (var p in passengers)
                        cargo.Load(a, self.World.CreateActor(false, p.ToLowerInvariant(),
                            new TypeDictionary { new OwnerInit(a.Owner) }));

                    a.QueueActivity(new Fly(a, Target.FromPos(finishEdge + spawnOffset)));
                    a.QueueActivity(new RemoveSelf());
                    aircraftInRange.Add(a, false);
                    distanceTestActor = a;
                }

                if (Info.DisplayBeacon)
                {
                    var distance = (target - startEdge).HorizontalLength;

                    beacon = new Beacon(
                        order.Player,
                        self.World.Map.CenterOfCell(order.TargetLocation),
                        Info.BeaconPalettePrefix,
                        Info.BeaconPoster,
                        Info.BeaconPosterPalette,
                        () => 1 - ((distanceTestActor.CenterPosition - target).HorizontalLength - info.BeaconDistanceOffset.Range) * 1f / distance
                    );

                    w.Add(beacon);
                }
            });
        }
Exemplo n.º 5
0
        public void SendAirstrike(Actor self, WPos target, bool randomize = true, int attackFacing = 0)
        {
            var info = Info as AirstrikePowerInfo;

            if (randomize)
                attackFacing = Util.QuantizeFacing(self.World.SharedRandom.Next(256), info.QuantizedFacings) * (256 / info.QuantizedFacings);

            var altitude = self.World.Map.Rules.Actors[info.UnitType].Traits.Get<PlaneInfo>().CruiseAltitude.Range;
            var attackRotation = WRot.FromFacing(attackFacing);
            var delta = new WVec(0, -1024, 0).Rotate(attackRotation);
            target = target + new WVec(0, 0, altitude);
            var startEdge = target - (self.World.Map.DistanceToEdge(target, -delta) + info.Cordon).Range * delta / 1024;
            var finishEdge = target + (self.World.Map.DistanceToEdge(target, delta) + info.Cordon).Range * delta / 1024;

            Actor camera = null;
            Beacon beacon = null;
            var aircraftInRange = new Dictionary<Actor, bool>();

            Action<Actor> onEnterRange = a =>
            {
                // Spawn a camera and remove the beacon when the first plane enters the target area
                if (info.CameraActor != null && !aircraftInRange.Any(kv => kv.Value))
                {
                    self.World.AddFrameEndTask(w =>
                    {
                        camera = w.CreateActor(info.CameraActor, new TypeDictionary
                        {
                            new LocationInit(self.World.Map.CellContaining(target)),
                            new OwnerInit(self.Owner),
                        });
                    });
                }

                if (beacon != null)
                {
                    self.World.AddFrameEndTask(w =>
                    {
                        w.Remove(beacon);
                        beacon = null;
                    });
                }

                aircraftInRange[a] = true;
            };

            Action<Actor> onExitRange = a =>
            {
                aircraftInRange[a] = false;

                // Remove the camera when the final plane leaves the target area
                if (!aircraftInRange.Any(kv => kv.Value))
                {
                    if (camera != null)
                    {
                        camera.QueueActivity(new Wait(info.CameraRemoveDelay));
                        camera.QueueActivity(new RemoveSelf());
                    }

                    camera = null;

                    if (beacon != null)
                    {
                        self.World.AddFrameEndTask(w =>
                        {
                            w.Remove(beacon);
                            beacon = null;
                        });
                    }
                }
            };

            self.World.AddFrameEndTask(w =>
            {
                var notification = self.Owner.IsAlliedWith(self.World.RenderPlayer) ? Info.LaunchSound : Info.IncomingSound;
                Sound.Play(notification);

                Actor distanceTestActor = null;
                for (var i = -info.SquadSize / 2; i <= info.SquadSize / 2; i++)
                {
                    // Even-sized squads skip the lead plane
                    if (i == 0 && (info.SquadSize & 1) == 0)
                        continue;

                    // Includes the 90 degree rotation between body and world coordinates
                    var so = info.SquadOffset;
                    var spawnOffset = new WVec(i * so.Y, -Math.Abs(i) * so.X, 0).Rotate(attackRotation);
                    var targetOffset = new WVec(i * so.Y, 0, 0).Rotate(attackRotation);

                    var a = w.CreateActor(info.UnitType, new TypeDictionary
                    {
                        new CenterPositionInit(startEdge + spawnOffset),
                        new OwnerInit(self.Owner),
                        new FacingInit(attackFacing),
                    });

                    var attack = a.Trait<AttackBomber>();
                    attack.SetTarget(w, target + targetOffset);
                    attack.OnEnteredAttackRange += onEnterRange;
                    attack.OnExitedAttackRange += onExitRange;
                    attack.OnRemovedFromWorld += onExitRange;

                    a.QueueActivity(new Fly(a, Target.FromPos(target + spawnOffset)));
                    a.QueueActivity(new Fly(a, Target.FromPos(finishEdge + spawnOffset)));
                    a.QueueActivity(new RemoveSelf());
                    aircraftInRange.Add(a, false);
                    distanceTestActor = a;
                }

                if (Info.DisplayBeacon)
                {
                    var distance = (target - startEdge).HorizontalLength;

                    beacon = new Beacon(
                        self.Owner,
                        target - new WVec(0, 0, altitude),
                        Info.BeaconPalettePrefix,
                        Info.BeaconPoster,
                        Info.BeaconPosterPalette,
                        () => 1 - ((distanceTestActor.CenterPosition - target).HorizontalLength - info.BeaconDistanceOffset.Range) * 1f / distance);

                    w.Add(beacon);
                }
            });
        }
		public override void Activate(Actor self, Order order, SupportPowerManager manager)
		{
			base.Activate(self, order, manager);

			activeArmaments = Armaments.Where(x => !x.IsTraitDisabled).ToHashSet();

			var armamentturrets = activeArmaments.Select(x => x.Info.Turret).ToHashSet();

			// TODO: Fix this when upgradable Turreteds arrive.
			turrets = self.TraitsImplementing<Turreted>().Where(x => armamentturrets.Contains(x.Name)).ToHashSet();

			if (self.Owner.IsAlliedWith(self.World.RenderPlayer))
				Game.Sound.Play(FireArmamentPowerInfo.LaunchSound);
			else
				Game.Sound.Play(FireArmamentPowerInfo.IncomingSound);

			target = Target.FromCell(self.World, order.TargetLocation);

			enabled = true;

			// TODO: Estimate the projectile travel time somehow
			estimatedTicks = activeArmaments.Max(x => x.FireDelay);

			if (FireArmamentPowerInfo.CameraActor != null)
			{
				var camera = self.World.CreateActor(false, FireArmamentPowerInfo.CameraActor, new TypeDictionary
				                                    {
					new LocationInit(order.TargetLocation),
					new OwnerInit(self.Owner),
				});

				camera.QueueActivity(new Wait(FireArmamentPowerInfo.CameraSpawnAdvance + FireArmamentPowerInfo.CameraRemoveDelay));
				camera.QueueActivity(new RemoveSelf());

				Action addCamera = () => self.World.AddFrameEndTask(w => w.Add(camera));
				self.World.AddFrameEndTask(w => w.Add(new DelayedAction(estimatedTicks - FireArmamentPowerInfo.CameraSpawnAdvance, addCamera)));
			}

			if (FireArmamentPowerInfo.DisplayBeacon)
			{
				var beacon = new Beacon(
					order.Player,
					self.World.Map.CenterOfCell(order.TargetLocation),
					FireArmamentPowerInfo.BeaconPaletteIsPlayerPalette,
					FireArmamentPowerInfo.BeaconPalette,
					FireArmamentPowerInfo.BeaconImage,
					FireArmamentPowerInfo.BeaconPoster,
					FireArmamentPowerInfo.BeaconPosterPalette,
					FireArmamentPowerInfo.ArrowSequence,
					FireArmamentPowerInfo.CircleSequence,
					FireArmamentPowerInfo.ClockSequence,
					() => FractionComplete);

				Action removeBeacon = () => self.World.AddFrameEndTask(w =>
				                                                       {
					w.Remove(beacon);
					beacon = null;
				});

				self.World.AddFrameEndTask(w =>
				                           {
					w.Add(beacon);
					w.Add(new DelayedAction(estimatedTicks - FireArmamentPowerInfo.BeaconRemoveAdvance, removeBeacon));
				});
			}

			ticks = 0;
		}
		void TryRemoveBeacon()
		{
			if (beacon != null)
			{
				world.AddFrameEndTask(w =>
				{
					w.Remove(beacon);
					beacon = null;
				});
			}
		}
Exemplo n.º 8
0
        public Actor[] SendParatroopers(Actor self, WPos target, bool randomize = true, int dropFacing = 0)
        {
            var units = new List<Actor>();

            var info = Info as ParatroopersPowerInfo;

            if (randomize)
                dropFacing = 256 * self.World.SharedRandom.Next(info.QuantizedFacings) / info.QuantizedFacings;

            var utLower = info.UnitType.ToLowerInvariant();
            ActorInfo unitType;
            if (!self.World.Map.Rules.Actors.TryGetValue(utLower, out unitType))
                throw new YamlException("Actors ruleset does not include the entry '{0}'".F(utLower));

            var altitude = unitType.TraitInfo<AircraftInfo>().CruiseAltitude.Length;
            var dropRotation = WRot.FromFacing(dropFacing);
            var delta = new WVec(0, -1024, 0).Rotate(dropRotation);
            target = target + new WVec(0, 0, altitude);
            var startEdge = target - (self.World.Map.DistanceToEdge(target, -delta) + info.Cordon).Length * delta / 1024;
            var finishEdge = target + (self.World.Map.DistanceToEdge(target, delta) + info.Cordon).Length * delta / 1024;

            Actor camera = null;
            Beacon beacon = null;
            var aircraftInRange = new Dictionary<Actor, bool>();

            Action<Actor> onEnterRange = a =>
            {
                // Spawn a camera and remove the beacon when the first plane enters the target area
                if (info.CameraActor != null && !aircraftInRange.Any(kv => kv.Value))
                {
                    self.World.AddFrameEndTask(w =>
                    {
                        camera = w.CreateActor(info.CameraActor, new TypeDictionary
                        {
                            new LocationInit(self.World.Map.CellContaining(target)),
                            new OwnerInit(self.Owner),
                        });
                    });
                }

                if (beacon != null)
                {
                    self.World.AddFrameEndTask(w =>
                    {
                        w.Remove(beacon);
                        beacon = null;
                    });
                }

                aircraftInRange[a] = true;
            };

            Action<Actor> onExitRange = a =>
            {
                aircraftInRange[a] = false;

                // Remove the camera when the final plane leaves the target area
                if (!aircraftInRange.Any(kv => kv.Value))
                {
                    if (camera != null)
                    {
                        camera.QueueActivity(new Wait(info.CameraRemoveDelay));
                        camera.QueueActivity(new RemoveSelf());
                    }

                    camera = null;

                    if (beacon != null)
                    {
                        self.World.AddFrameEndTask(w =>
                        {
                            w.Remove(beacon);
                            beacon = null;
                        });
                    }
                }
            };

            foreach (var p in info.DropItems)
            {
                var unit = self.World.CreateActor(false, p.ToLowerInvariant(),
                    new TypeDictionary { new OwnerInit(self.Owner) });

                units.Add(unit);
            }

            self.World.AddFrameEndTask(w =>
            {
                var notification = self.Owner.IsAlliedWith(self.World.RenderPlayer) ? Info.LaunchSound : Info.IncomingSound;
                Game.Sound.Play(notification);

                Actor distanceTestActor = null;

                var passengersPerPlane = (info.DropItems.Length + info.SquadSize - 1) / info.SquadSize;
                var added = 0;
                for (var i = -info.SquadSize / 2; i <= info.SquadSize / 2; i++)
                {
                    // Even-sized squads skip the lead plane
                    if (i == 0 && (info.SquadSize & 1) == 0)
                        continue;

                    // Includes the 90 degree rotation between body and world coordinates
                    var so = info.SquadOffset;
                    var spawnOffset = new WVec(i * so.Y, -Math.Abs(i) * so.X, 0).Rotate(dropRotation);
                    var targetOffset = new WVec(i * so.Y, 0, 0).Rotate(dropRotation);

                    var a = w.CreateActor(info.UnitType, new TypeDictionary
                    {
                        new CenterPositionInit(startEdge + spawnOffset),
                        new OwnerInit(self.Owner),
                        new FacingInit(dropFacing),
                    });

                    var drop = a.Trait<ParaDrop>();
                    drop.SetLZ(w.Map.CellContaining(target + targetOffset), !info.AllowImpassableCells);
                    drop.OnEnteredDropRange += onEnterRange;
                    drop.OnExitedDropRange += onExitRange;
                    drop.OnRemovedFromWorld += onExitRange;

                    var cargo = a.Trait<Cargo>();
                    var passengers = units.Skip(added).Take(passengersPerPlane);
                    added += passengersPerPlane;

                    foreach (var p in passengers)
                        cargo.Load(a, p);

                    a.QueueActivity(new Fly(a, Target.FromPos(target + spawnOffset)));
                    a.QueueActivity(new Fly(a, Target.FromPos(finishEdge + spawnOffset)));
                    a.QueueActivity(new RemoveSelf());
                    aircraftInRange.Add(a, false);
                    distanceTestActor = a;
                }

                if (Info.DisplayBeacon)
                {
                    var distance = (target - startEdge).HorizontalLength;

                    beacon = new Beacon(
                        self.Owner,
                        target - new WVec(0, 0, altitude),
                        Info.BeaconPalettePrefix,
                        Info.BeaconPoster,
                        Info.BeaconPosterPalette,
                        () => 1 - ((distanceTestActor.CenterPosition - target).HorizontalLength - info.BeaconDistanceOffset.Length) * 1f / distance);

                    w.Add(beacon);
                }
            });

            return units.ToArray();
        }
		public override void Activate(Actor self, Order order, SupportPowerManager manager)
		{
			base.Activate(self, order, manager);

			if (self.Owner.IsAlliedWith(self.World.RenderPlayer))
				Game.Sound.Play(Info.LaunchSound);
			else
				Game.Sound.Play(Info.IncomingSound);

			if (!string.IsNullOrEmpty(Info.ActivationSequence))
			{
				var wsb = self.Trait<WithSpriteBody>();
				wsb.PlayCustomAnimation(self, Info.ActivationSequence);
			}

			var targetPosition = self.World.Map.CenterOfCell(order.TargetLocation) + new WVec(WDist.Zero, WDist.Zero, Info.AirburstAltitude);

			Action detonateWeapon = () => self.World.AddFrameEndTask(w => Info.WeaponInfo.Impact(Target.FromPos(targetPosition), self, Enumerable.Empty<int>()));

			self.World.AddFrameEndTask(w => w.Add(new DelayedAction(Info.ActivationDelay, detonateWeapon)));

			if (Info.CameraActor != null)
			{
				var camera = self.World.CreateActor(false, Info.CameraActor, new TypeDictionary
					{
						new LocationInit(order.TargetLocation),
						new OwnerInit(self.Owner),
					});

				camera.QueueActivity(new Wait(Info.CameraSpawnAdvance + Info.CameraRemoveDelay));
				camera.QueueActivity(new RemoveSelf());

				Action addCamera = () => self.World.AddFrameEndTask(w => w.Add(camera));
				self.World.AddFrameEndTask(w => w.Add(new DelayedAction(Info.ActivationDelay - Info.CameraSpawnAdvance, addCamera)));
			}

			if (Info.DisplayBeacon)
			{
				var beacon = new Beacon(
					order.Player,
					targetPosition,
					Info.BeaconPaletteIsPlayerPalette,
					Info.BeaconPalette,
					Info.BeaconImage,
					Info.BeaconPoster,
					Info.BeaconPosterPalette,
					Info.ArrowSequence,
					Info.CircleSequence,
					Info.ClockSequence,
					() => FractionComplete);

				Action removeBeacon = () => self.World.AddFrameEndTask(w =>
					{
						w.Remove(beacon);
						beacon = null;
					});

				self.World.AddFrameEndTask(w =>
					{
						w.Add(beacon);
						w.Add(new DelayedAction(Info.ActivationDelay - Info.BeaconRemoveAdvance, removeBeacon));
					});
			}
		}