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