public Fly(Actor self, Target t, WDist minRange, WDist maxRange, WPos?initialTargetPosition = null, Color?targetLineColor = null) : this(self, t, initialTargetPosition, targetLineColor) { this.maxRange = maxRange; this.minRange = minRange; }
public MoveWithinRange(Actor self, Target target, WDist minRange, WDist maxRange, WPos?initialTargetPosition = null, Color?targetLineColor = null) : base(self, target, initialTargetPosition, targetLineColor) { this.minRange = minRange; this.maxRange = maxRange; }
// For places that only want to update some of the fields (usually DamageModifiers) public WarheadArgs(WarheadArgs args) { Weapon = args.Weapon; DamageModifiers = args.DamageModifiers; Source = args.Source; SourceActor = args.SourceActor; WeaponTarget = args.WeaponTarget; }
public WarheadArgs(ProjectileArgs args) { Weapon = args.Weapon; DamageModifiers = args.DamageModifiers; Source = args.Source; SourceActor = args.SourceActor; WeaponTarget = args.GuidedTarget; }
public Activity MoveToTarget(Actor self, Target target, WPos?initialTargetPosition = null, Color?targetLineColor = null) { if (target.Type == TargetType.Invalid) { return(null); } return(new MoveAdjacentTo(self, target, initialTargetPosition, targetLineColor)); }
public Activity MoveWithinRange(Target target, WDist range, WPos?initialTargetPosition = null, Color?targetLineColor = null) { if (!Info.CanHover) { return(new Fly(self, target, WDist.Zero, range, initialTargetPosition, targetLineColor)); } return(new HeliFly(self, target, WDist.Zero, range, initialTargetPosition, targetLineColor)); }
public RadarPing Add(Func<bool> isVisible, WPos position, Color color, int duration) { var ping = new RadarPing(isVisible, position, color, duration, info.FromRadius, info.ToRadius, info.ShrinkSpeed, info.RotationSpeed); if (ping.IsVisible()) LastPingPosition = ping.Position; Pings.Add(ping); return ping; }
public Activity MoveFollow(Actor self, Target target, WDist minRange, WDist maxRange, WPos?initialTargetPosition = null, Color?targetLineColor = null) { if (!Info.CanHover) { return(new FlyFollow(self, target, minRange, maxRange, initialTargetPosition, targetLineColor)); } return(new Follow(self, target, minRange, maxRange, initialTargetPosition, targetLineColor)); }
public Activity MoveToTarget(Actor self, Target target, WPos?initialTargetPosition = null, Color?targetLineColor = null) { if (!Info.CanHover) { return(new Fly(self, target, WDist.FromCells(3), WDist.FromCells(5), initialTargetPosition, targetLineColor)); } return(ActivityUtils.SequenceActivities(self, new HeliFly(self, target, initialTargetPosition, targetLineColor), new Turn(self, Info.InitialFacing))); }
public RadarPing Add(Func <bool> isVisible, WPos position, Color color, int duration) { var ping = new RadarPing(isVisible, position, color, duration, info.FromRadius, info.ToRadius, info.ShrinkSpeed, info.RotationSpeed); if (ping.IsVisible()) { LastPingPosition = ping.Position; } Pings.Add(ping); return(ping); }
public Follow(Actor self, Target target, WDist minRange, WDist maxRange, WPos? initialTargetPosition, Color? targetLineColor = null) { this.target = target; this.minRange = minRange; this.maxRange = maxRange; this.targetLineColor = targetLineColor; move = self.Trait<IMove>(); // The target may become hidden between the initial order request and the first tick (e.g. if queued) // Moving to any position (even if quite stale) is still better than immediately giving up if ((target.Type == TargetType.Actor && target.Actor.CanBeViewedByPlayer(self.Owner)) || target.Type == TargetType.FrozenActor || target.Type == TargetType.Terrain) lastVisibleTarget = Target.FromPos(target.CenterPosition); else if (initialTargetPosition.HasValue) lastVisibleTarget = Target.FromPos(initialTargetPosition.Value); }
public Fly(Actor self, Target t, WPos?initialTargetPosition = null, Color?targetLineColor = null) { aircraft = self.Trait <Aircraft>(); target = t; this.targetLineColor = targetLineColor; // The target may become hidden between the initial order request and the first tick (e.g. if queued) // Moving to any position (even if quite stale) is still better than immediately giving up if ((target.Type == TargetType.Actor && target.Actor.CanBeViewedByPlayer(self.Owner)) || target.Type == TargetType.FrozenActor || target.Type == TargetType.Terrain) { lastVisibleTarget = Target.FromPos(target.CenterPosition); } else if (initialTargetPosition.HasValue) { lastVisibleTarget = Target.FromPos(initialTargetPosition.Value); } }
void ITick.Tick(Actor self) { if (IsTraitDisabled) { return; } if (state != PeriodicConditionState.Ready && --ticks < 0) { if (IsEnabled) { ticks = info.CooldownDuration.Length == 2 ? self.World.SharedRandom.Next(info.CooldownDuration[0], info.CooldownDuration[1]) : info.CooldownDuration[0]; cooldown = ticks; DisableCondition(); state = PeriodicConditionState.Charging; } else { ticks = info.ActiveDuration.Length == 2 ? self.World.SharedRandom.Next(info.ActiveDuration[0], info.ActiveDuration[1]) : info.ActiveDuration[0]; active = ticks; state = PeriodicConditionState.Ready; } } if (Info.Triggers.HasFlag(PeriodicConditionTrigger.Move)) { if (state == PeriodicConditionState.Ready && (lastPos == null || lastPos.Value != self.CenterPosition)) { TryEnableCondition(); } lastPos = self.CenterPosition; } }
public MoveAdjacentTo(Actor self, Target target, WPos?initialTargetPosition = null, Color?targetLineColor = null) { this.target = target; this.targetLineColor = targetLineColor; Mobile = self.Trait <Mobile>(); pathFinder = self.World.WorldActor.Trait <IPathFinder>(); domainIndex = self.World.WorldActor.Trait <DomainIndex>(); ChildHasPriority = false; // The target may become hidden between the initial order request and the first tick (e.g. if queued) // Moving to any position (even if quite stale) is still better than immediately giving up if ((target.Type == TargetType.Actor && target.Actor.CanBeViewedByPlayer(self.Owner)) || target.Type == TargetType.FrozenActor || target.Type == TargetType.Terrain) { lastVisibleTarget = Target.FromPos(target.CenterPosition); lastVisibleTargetLocation = self.World.Map.CellContaining(target.CenterPosition); } else if (initialTargetPosition.HasValue) { lastVisibleTarget = Target.FromPos(initialTargetPosition.Value); lastVisibleTargetLocation = self.World.Map.CellContaining(initialTargetPosition.Value); } }
public Activity MoveWithinRange(Target target, WDist range, WPos?initialTargetPosition = null, Color?targetLineColor = null) { return(new MoveWithinRange(self, target, WDist.Zero, range, initialTargetPosition, targetLineColor)); }
public Activity MoveFollow(Actor self, Target target, WDist minRange, WDist maxRange, WPos?initialTargetPosition = null, Color?targetLineColor = null) { return(WrapMove(new Follow(self, target, minRange, maxRange, initialTargetPosition, targetLineColor))); }
public Activity MoveToTarget(Actor self, Target target, WPos?initialTargetPosition = null, Color?targetLineColor = null) { return(new ShootableBallisticMissileFly(self, target)); }
public Activity MoveFollow(Actor self, Target target, WDist minRange, WDist maxRange, WPos?initialTargetPosition = null, Color?targetLineColor = null) { return(null); }
public Fly(Actor self, Target t, WDist nearEnough, WPos?initialTargetPosition = null, Color?targetLineColor = null) : this(self, t, initialTargetPosition, targetLineColor) { this.nearEnough = nearEnough; }
public Activity MoveToTarget(Actor self, Target target, WPos?initialTargetPosition = default(WPos?), Primitives.Color?targetLineColor = default(Primitives.Color?)) { return(null); }
public Actor[] SendAirstrike(Actor self, WPos target, WAngle?facing = null) { var aircraft = new List <Actor>(); if (!facing.HasValue) { facing = new WAngle(1024 * self.World.SharedRandom.Next(info.QuantizedFacings) / info.QuantizedFacings); } 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 && camera == 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), }); }); } RemoveBeacon(beacon); 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)) { RemoveCamera(camera); } }; Action <Actor> onRemovedFromWorld = a => { aircraftInRange[a] = false; // Checking for attack range is not relevant here because // aircraft may be shot down before entering the range. // If at the map's edge, they may be removed from world before leaving. if (aircraftInRange.All(kv => !kv.Key.IsInWorld)) { RemoveCamera(camera); RemoveBeacon(beacon); } }; WPos?startPos = null; // Create the actors immediately so they can be returned. foreach (var squadMember in info.Squad) { var a = self.World.CreateActor(false, squadMember.UnitType, new TypeDictionary { new OwnerInit(self.Owner), new FacingInit(facing.Value) }); aircraft.Add(a); aircraftInRange.Add(a, false); } self.World.AddFrameEndTask(w => { PlayLaunchSounds(); Actor distanceTestActor = null; for (var i = 0; i < aircraft.Count; i++) { var squadMember = info.Squad[i]; var actor = aircraft[i]; var altitude = self.World.Map.Rules.Actors[squadMember.UnitType].TraitInfo <AircraftInfo>().CruiseAltitude.Length; var attackRotation = WRot.FromYaw(facing.Value); var delta = new WVec(0, -1024, 0).Rotate(attackRotation); var targetPos = target + new WVec(0, 0, altitude); var startEdge = targetPos - (self.World.Map.DistanceToEdge(target, -delta) + info.Cordon).Length * delta / 1024; var finishEdge = targetPos + (self.World.Map.DistanceToEdge(target, delta) + info.Cordon).Length * delta / 1024; startPos = startEdge; // Includes the 90 degree rotation between body and world coordinates var so = squadMember.SpawnOffset; var to = squadMember.TargetOffset; var spawnOffset = new WVec(so.Y, -1 * so.X, 0).Rotate(attackRotation); var targetOffset = new WVec(to.Y, 0, 0).Rotate(attackRotation); actor.Trait <IPositionable>().SetPosition(actor, startEdge + spawnOffset); w.Add(actor); var attack = actor.Trait <AttackBomber>(); attack.SetTarget(self.World, targetPos + targetOffset); attack.OnEnteredAttackRange += onEnterRange; attack.OnExitedAttackRange += onExitRange; attack.OnRemovedFromWorld += onRemovedFromWorld; for (var strikes = 0; strikes < info.Strikes; strikes++) { actor.QueueActivity(new Fly(actor, Target.FromPos(target + spawnOffset))); if (info.Strikes > 1) { actor.QueueActivity(new FlyForward(actor, info.CircleDelay)); } } actor.QueueActivity(new Fly(actor, Target.FromPos(finishEdge + spawnOffset))); actor.QueueActivity(new RemoveSelf()); distanceTestActor = actor; } if (Info.DisplayBeacon && startPos.HasValue) { var distance = (target - startPos.Value).HorizontalLength; beacon = new Beacon( self.Owner, new WPos(target.X, target.Y, 0), Info.BeaconPaletteIsPlayerPalette, Info.BeaconPalette, Info.BeaconImage, Info.BeaconPoster, Info.BeaconPosterPalette, Info.BeaconSequence, Info.ArrowSequence, Info.CircleSequence, Info.ClockSequence, () => 1 - ((distanceTestActor.CenterPosition - target).HorizontalLength - info.BeaconDistanceOffset.Length) * 1f / distance, Info.BeaconDelay); w.Add(beacon); } }); return(aircraft.ToArray()); }
public Activity MoveWithinRange(Target target, WDist minRange, WDist maxRange, WPos?initialTargetPosition = null, Color?targetLineColor = null) { return(new ShootableBallisticMissileFly(self, target)); }
public Activity MoveWithinRange(Target target, WDist range, WPos?initialTargetPosition = default(WPos?), Primitives.Color?targetLineColor = default(Primitives.Color?)) { return(null); }
public Activity MoveWithinRange(Target target, WDist minRange, WDist maxRange, WPos?initialTargetPosition = null, Color?targetLineColor = null) { return(null); }
public Activity MoveFollow(Actor self, Target target, WDist minRange, WDist maxRange, WPos?initialTargetPosition = default(WPos?), Primitives.Color?targetLineColor = default(Primitives.Color?)) { return(null); }
public Activity MoveToTarget(Actor self, Target target, WPos?initialTargetPosition = null, Color?targetLineColor = null) { return(null); }
public void SendAirstrike(Actor self, WPos target, bool randomize = true, int attackFacing = 0) { if (randomize) { attackFacing = 256 * self.World.SharedRandom.Next(info.QuantizedFacings) / info.QuantizedFacings; } 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 && camera == 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), }); }); } RemoveBeacon(beacon); 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)) { RemoveCamera(camera); } }; Action <Actor> onRemovedFromWorld = a => { aircraftInRange[a] = false; // Checking for attack range is not relevant here because // aircraft may be shot down before entering. Thus we remove // the camera and beacon only if the whole squad is dead. if (aircraftInRange.All(kv => kv.Key.IsDead)) { RemoveCamera(camera); RemoveBeacon(beacon); } }; self.World.AddFrameEndTask(w => { WPos?startPos = null; foreach (var squadMember in info.Squad) { var altitude = self.World.Map.Rules.Actors[squadMember.UnitType].TraitInfo <AircraftInfo>().CruiseAltitude.Length; var attackRotation = WRot.FromFacing(attackFacing); var delta = new WVec(0, -1024, 0).Rotate(attackRotation); var targetPos = target + new WVec(0, 0, altitude); var startEdge = targetPos - (self.World.Map.DistanceToEdge(targetPos, -delta) + info.Cordon).Length * delta / 1024; var finishEdge = targetPos + (self.World.Map.DistanceToEdge(targetPos, delta) + info.Cordon).Length * delta / 1024; startPos = startEdge; PlayLaunchSounds(); var spawnOffset = squadMember.SpawnOffset.Rotate(attackRotation); var targetOffset = squadMember.TargetOffset.Rotate(attackRotation); var a = w.CreateActor(squadMember.UnitType, new TypeDictionary { new CenterPositionInit(startEdge + spawnOffset), new OwnerInit(self.Owner), new FacingInit(attackFacing), new CreationActivityDelayInit(squadMember.SpawnDelay) }); var attack = a.Trait <AttackBomber>(); attack.SetTarget(w, targetPos + targetOffset); attack.OnEnteredAttackRange += onEnterRange; attack.OnExitedAttackRange += onExitRange; attack.OnRemovedFromWorld += onRemovedFromWorld; for (var strikes = 0; strikes < info.Strikes; strikes++) { a.QueueActivity(new Fly(a, Target.FromPos(target + spawnOffset))); if (info.Strikes > 1) { a.QueueActivity(new FlyTimed(info.CircleDelay, a)); } } a.QueueActivity(new Fly(a, Target.FromPos(finishEdge + spawnOffset))); a.QueueActivity(new RemoveSelf()); aircraftInRange.Add(a, false); } if (Info.DisplayBeacon && startPos.HasValue) { var distance = (target - startPos.Value).HorizontalLength; beacon = new Beacon( self.Owner, new WPos(target.X, target.Y, 0), Info.BeaconPaletteIsPlayerPalette, Info.BeaconPalette, Info.BeaconImage, Info.BeaconPoster, Info.BeaconPosterPalette, Info.BeaconSequence, Info.ArrowSequence, Info.CircleSequence, Info.ClockSequence, () => { // To account for different spawn times and potentially different movement speeds. var closestActor = aircraftInRange.Keys.MinBy(x => (x.CenterPosition - target).HorizontalLengthSquared); return(1 - ((closestActor.CenterPosition - target).HorizontalLength - info.BeaconDistanceOffset.Length) * 1f / distance); }, Info.BeaconDelay); w.Add(beacon); } }); }