public Leap(Actor self, Actor target, WeaponInfo weapon, WRange speed, WAngle angle) { var targetMobile = target.TraitOrDefault <Mobile>(); if (targetMobile == null) { throw new InvalidOperationException("Leap requires a target actor with the Mobile trait"); } this.weapon = weapon; this.angle = angle; mobile = self.Trait <Mobile>(); mobile.SetLocation(mobile.fromCell, mobile.fromSubCell, targetMobile.fromCell, targetMobile.fromSubCell); mobile.IsMoving = true; from = self.CenterPosition; to = targetMobile.fromCell.CenterPosition + MobileInfo.SubCellOffsets[targetMobile.fromSubCell]; length = Math.Max((to - from).Length / speed.Range, 1); self.Trait <RenderInfantry>().Attacking(self, Target.FromActor(target)); if (weapon.Report != null && weapon.Report.Any()) { Sound.Play(weapon.Report.Random(self.World.SharedRandom), self.CenterPosition); } }
public override Activity Tick(Actor self) { if (IsCanceled || !target.IsValidFor(self)) { return(NextActivity); } if (self.IsDisabled()) { return(this); } const int RangeTolerance = 1; /* how far inside our maximum range we should try to sit */ var weapon = attack.ChooseArmamentForTarget(target); if (weapon != null) { var range = WRange.FromCells(Math.Max(0, weapon.Weapon.Range.Range / 1024 - RangeTolerance)); attack.Target = target; if (move != null) { return(Util.SequenceActivities(move.MoveFollow(self, target, range), this)); } } return(NextActivity); }
public CarpetBomb(CarpetBombInfo info) { this.info = info; // TODO: Push this conversion into the yaml range = WRange.FromCells(info.Range); }
public void Tick(Actor self) { if (requiresUpgrade || restrictedByUpgrade) { return; } if (FireDelay > 0) { --FireDelay; } Recoil = new WRange(Math.Max(0, Recoil.Range - Info.RecoilRecovery.Range)); for (var i = 0; i < delayedActions.Count; i++) { var x = delayedActions[i]; if (--x.First <= 0) { x.Second(); } delayedActions[i] = x; } delayedActions.RemoveAll(a => a.First <= 0); }
public override void DoAttack(Actor self, Target target) { if (!CanAttack(self, target)) { return; } var arm = Armaments.FirstOrDefault(); if (arm == null) { return; } // TODO: Define weapon ranges as WRange var range = new WRange((int)(1024 * arm.Weapon.Range)); if (!target.IsInRange(self.CenterPosition, range)) { return; } var facing = self.TraitOrDefault <IFacing>(); foreach (var a in Armaments) { a.CheckFire(self, this, facing, target); } if (target.Actor != null) { target.Actor.ChangeOwner(self.Owner); } }
public override Activity Tick(Actor self) { if (IsCanceled) { return(NextActivity); } var helicopter = self.Trait <Helicopter>(); var cruiseAltitude = new WRange(helicopter.Info.CruiseAltitude * 1024 / Game.CellSize); if (AdjustAltitude(self, helicopter, cruiseAltitude)) { return(this); } // Rotate towards the target var dist = pos - self.CenterPosition; var desiredFacing = Util.GetFacing(dist, helicopter.Facing); helicopter.Facing = Util.TickFacing(helicopter.Facing, desiredFacing, helicopter.ROT); // The next move would overshoot, so just set the final position var move = helicopter.FlyStep(desiredFacing); if (dist.HorizontalLengthSquared < move.HorizontalLengthSquared) { helicopter.SetPosition(self, pos + new WVec(0, 0, cruiseAltitude.Range - pos.Z)); return(NextActivity); } helicopter.SetPosition(self, helicopter.CenterPosition + move); return(this); }
public override Activity Tick(Actor self) { if (IsCanceled || !target.IsValidFor(self)) { return(NextActivity); } if (self.IsDisabled()) { return(this); } var attack = self.Trait <AttackTurreted>(); const int RangeTolerance = 1; /* how far inside our maximum range we should try to sit */ var weapon = attack.ChooseArmamentForTarget(target); if (weapon != null) { var range = WRange.FromCells(Math.Max(0, (int)weapon.Weapon.Range - RangeTolerance)); attack.Target = target; if (allowMove && self.HasTrait <Mobile>() && !self.Info.Traits.Get <MobileInfo>().OnRails) { return(Util.SequenceActivities(new Follow(self, target, range), this)); } } return(NextActivity); }
void ManageSovietUnits() { foreach (var unit in world.Actors.Where(u => u.IsInWorld && u.Owner == soviets && !u.IsDead() && u.IsIdle && u.HasTrait <Mobile>() && u.HasTrait <AttackBase>())) { Activity innerActivity; if (einstein != null) { if (einstein.IsInWorld) { innerActivity = new Move.Move(Target.FromActor(einstein), WRange.FromCells(3)); } else { var container = world.UnitContaining(einstein); if (container != null && !container.HasTrait <Aircraft>() && container.HasTrait <Mobile>()) { innerActivity = new Move.Move(Target.FromActor(container), WRange.FromCells(3)); } else { innerActivity = new Move.Move(extractionLZ.Location, 3); } } unit.QueueActivity(new AttackMove.AttackMoveActivity(unit, innerActivity)); } } }
static IEnumerable <IFinalizedRenderable> DrawZapWandering(WorldRenderer wr, float2 from, float2 to, ISpriteSequence s, string pal) { var z = float2.Zero; /* hack */ var dist = to - from; var norm = (1f / dist.Length) * new float2(-dist.Y, dist.X); var renderables = new List <IFinalizedRenderable>(); if (Game.CosmeticRandom.Next(2) != 0) { var p1 = from + (1 / 3f) * dist + WRange.FromPDF(Game.CosmeticRandom, 2).Range *dist.Length / 4096 * norm; var p2 = from + (2 / 3f) * dist + WRange.FromPDF(Game.CosmeticRandom, 2).Range *dist.Length / 4096 * norm; renderables.AddRange(DrawZap(wr, from, p1, s, out p1, pal)); renderables.AddRange(DrawZap(wr, p1, p2, s, out p2, pal)); renderables.AddRange(DrawZap(wr, p2, to, s, out z, pal)); } else { var p1 = from + (1 / 2f) * dist + WRange.FromPDF(Game.CosmeticRandom, 2).Range *dist.Length / 4096 * norm; renderables.AddRange(DrawZap(wr, from, p1, s, out p1, pal)); renderables.AddRange(DrawZap(wr, p1, to, s, out z, pal)); } return(renderables); }
public Move(CPos destination, WRange nearEnough) { this.getPath = (self, mobile) => self.World.WorldActor.Trait <PathFinder>() .FindUnitPath(mobile.toCell, destination, self); this.destination = destination; this.nearEnough = nearEnough; }
public override Activity Tick(Actor self) { if (IsCanceled || !target.IsValidFor(self)) return NextActivity; var limitedAmmo = self.TraitOrDefault<LimitedAmmo>(); var reloads = self.TraitOrDefault<Reloads>(); if (limitedAmmo != null && !limitedAmmo.HasAmmo() && reloads == null) return Util.SequenceActivities(new HeliReturn(), NextActivity); var helicopter = self.Trait<Helicopter>(); var attack = self.Trait<AttackHeli>(); var dist = target.CenterPosition - self.CenterPosition; // Can rotate facing while ascending var desiredFacing = Util.GetFacing(dist, helicopter.Facing); helicopter.Facing = Util.TickFacing(helicopter.Facing, desiredFacing, helicopter.ROT); var cruiseAltitude = new WRange(helicopter.Info.CruiseAltitude * 1024 / Game.CellSize); if (HeliFly.AdjustAltitude(self, helicopter, cruiseAltitude)) return this; // Fly towards the target if (!target.IsInRange(self.CenterPosition, attack.GetMaximumRange())) helicopter.SetPosition(self, helicopter.CenterPosition + helicopter.FlyStep(desiredFacing)); attack.DoAttack(self, target); return this; }
public override void Tick(Actor self) { base.Tick(self); var facing = self.TraitOrDefault<IFacing>(); var cp = self.CenterPosition; var bombTarget = Target.FromPos(cp - new WVec(0, 0, cp.Z)); // Bombs drop anywhere in range foreach (var a in Armaments.Where(a => a.Info.Name == info.Bombs)) { var range = new WRange((int)(1024 * a.Weapon.Range)); if (!target.IsInRange(self.CenterPosition, range)) continue; a.CheckFire(self, this, facing, bombTarget); } // Guns only fire when approaching the target var facingToTarget = Util.GetFacing(target.CenterPosition - self.CenterPosition, facing.Facing); if (Math.Abs(facingToTarget - facing.Facing) % 256 > info.FacingTolerance) return; foreach (var a in Armaments.Where(a => a.Info.Name == info.Guns)) { var range = new WRange((int)(1024 * a.Weapon.Range)); if (!target.IsInRange(self.CenterPosition, range)) continue; var t = Target.FromPos(cp - new WVec(0, range.Range / 2, cp.Z).Rotate(WRot.FromFacing(facing.Facing))); a.CheckFire(self, this, facing, t); } }
void TryToRushAttack() { var allEnemyBaseBuilder = FindEnemyConstructionYards(); var ownUnits = activeUnits .Where(unit => unit.HasTrait <AttackBase>() && !unit.HasTrait <Aircraft>() && unit.IsIdle).ToList(); if (!allEnemyBaseBuilder.Any() || (ownUnits.Count < Info.SquadSize)) { return; } foreach (var b in allEnemyBaseBuilder) { var enemies = World.FindActorsInCircle(b.CenterPosition, WRange.FromCells(Info.RushAttackScanRadius)) .Where(unit => Player.Stances[unit.Owner] == Stance.Enemy && unit.HasTrait <AttackBase>()).ToList(); if (rushFuzzy.CanAttack(ownUnits, enemies)) { var target = enemies.Any() ? enemies.Random(Random) : b; var rush = GetSquadOfType(SquadType.Rush); if (rush == null) { rush = RegisterNewSquad(SquadType.Rush, target); } foreach (var a3 in ownUnits) { rush.Units.Add(a3); } return; } } }
public override Activity Tick(Actor self) { if (IsCanceled) return NextActivity; var helicopter = self.Trait<Helicopter>(); var cruiseAltitude = new WRange(helicopter.Info.CruiseAltitude * 1024 / Game.CellSize); if (AdjustAltitude(self, helicopter, cruiseAltitude)) return this; // Rotate towards the target var dist = pos - self.CenterPosition; var desiredFacing = Util.GetFacing(dist, helicopter.Facing); helicopter.Facing = Util.TickFacing(helicopter.Facing, desiredFacing, helicopter.ROT); // The next move would overshoot, so just set the final position var move = helicopter.FlyStep(desiredFacing); if (dist.HorizontalLengthSquared < move.HorizontalLengthSquared) { helicopter.SetPosition(self, pos + new WVec(0, 0, cruiseAltitude.Range - pos.Z)); return NextActivity; } helicopter.SetPosition(self, helicopter.CenterPosition + move); return this; }
public FlyFollow(Actor self, Target target, WRange minRange, WRange maxRange) { this.target = target; plane = self.Trait<Plane>(); this.minRange = minRange; this.maxRange = maxRange; }
public ThrowsParticle(ActorInitializer init, ThrowsParticleInfo info) { var self = init.self; var rs = self.Trait <RenderSimple>(); var body = self.Trait <IBodyOrientation>(); // TODO: Carry orientation over from the parent instead of just facing var bodyFacing = init.Contains <FacingInit>() ? init.Get <FacingInit, int>() : 0; facing = Turreted.GetInitialTurretFacing(init, 0); // Calculate final position var throwRotation = WRot.FromFacing(Game.CosmeticRandom.Next(1024)); var throwDistance = Game.CosmeticRandom.Next(info.MinThrowRange.Range, info.MaxThrowRange.Range); initialPos = pos = info.Offset.Rotate(body.QuantizeOrientation(self, WRot.FromFacing(bodyFacing))); finalPos = initialPos + new WVec(throwDistance, 0, 0).Rotate(throwRotation); angle = new WAngle(Game.CosmeticRandom.Next(info.MinThrowAngle.Angle, info.MaxThrowAngle.Angle)); length = (finalPos - initialPos).Length / info.Velocity; // Facing rotation rotation = WRange.FromPDF(Game.CosmeticRandom, 2).Range *info.ROT / 1024; var anim = new Animation(init.world, rs.GetImage(self), () => (int)facing); anim.PlayRepeating(info.Anim); rs.Add(info.Anim, new AnimationWithOffset(anim, () => pos, null)); }
CPos?FindAttackLocationToSupportPower(int radiusOfPower) { CPos?resLoc = null; var countUnits = 0; var x = (world.Map.MapSize.X % radiusOfPower) == 0 ? world.Map.MapSize.X : world.Map.MapSize.X + radiusOfPower; var y = (world.Map.MapSize.Y % radiusOfPower) == 0 ? world.Map.MapSize.Y : world.Map.MapSize.Y + radiusOfPower; for (int i = 0; i < x; i += radiusOfPower * 2) { for (int j = 0; j < y; j += radiusOfPower * 2) { var pos = new CPos(i, j); var targets = world.FindActorsInCircle(pos.CenterPosition, WRange.FromCells(radiusOfPower)).ToList(); var enemies = targets.Where(unit => p.Stances[unit.Owner] == Stance.Enemy).ToList(); var ally = targets.Where(unit => p.Stances[unit.Owner] == Stance.Ally || unit.Owner == p).ToList(); if (enemies.Count < ally.Count || !enemies.Any()) { continue; } if (enemies.Count > countUnits) { countUnits = enemies.Count; resLoc = enemies.Random(random).Location; } } } return(resLoc); }
void ProtectOwn(Actor attacker) { var protectSq = GetSquadOfType(SquadType.Protection); if (protectSq == null) { protectSq = RegisterNewSquad(SquadType.Protection, attacker); } if (!protectSq.TargetIsValid) { protectSq.Target = attacker; } if (!protectSq.IsValid) { var ownUnits = world.FindActorsInCircle(baseCenter.CenterPosition, WRange.FromCells(15)) .Where(unit => unit.Owner == p && !unit.HasTrait <Building>() && unit.HasTrait <AttackBase>()).ToList(); foreach (var a in ownUnits) { protectSq.units.Add(a); } } }
public IEnumerable <IRenderable> RenderAfterWorld(WorldRenderer wr) { if (self.Owner != self.World.LocalPlayer) { yield break; } var jamsMissiles = self.Info.Traits.GetOrDefault <JamsMissilesInfo>(); if (jamsMissiles != null) { yield return(new RangeCircleRenderable( self.CenterPosition, WRange.FromCells(jamsMissiles.Range), 0, Color.FromArgb(128, Color.Red), Color.FromArgb(96, Color.Black))); } var jamsRadar = self.Info.Traits.GetOrDefault <JamsRadarInfo>(); if (jamsRadar != null) { yield return(new RangeCircleRenderable( self.CenterPosition, WRange.FromCells(jamsRadar.Range), 0, Color.FromArgb(128, Color.Blue), Color.FromArgb(96, Color.Black))); } }
protected bool TryGetAlternateTargetInCircle(Actor self, WRange radius, Action <Target> update, Func <Actor, bool> primaryFilter, Func <Actor, bool>[] preferenceFilters = null) { var radiusSquared = radius.Range * radius.Range; var diff = new WVec(radius, radius, WRange.Zero); var candidates = self.World.ActorMap.ActorsInBox(self.CenterPosition - diff, self.CenterPosition + diff) .Where(primaryFilter).Select(a => new { Actor = a, Ls = (self.CenterPosition - a.CenterPosition).HorizontalLengthSquared }) .Where(p => p.Ls <= radiusSquared).OrderBy(p => p.Ls).Select(p => p.Actor); if (preferenceFilters != null) { foreach (var filter in preferenceFilters) { var preferredCandidate = candidates.FirstOrDefault(filter); if (preferredCandidate == null) { continue; } target = Target.FromActor(preferredCandidate); update(target); return(true); } } var candidate = candidates.FirstOrDefault(); if (candidate == null) { return(false); } target = Target.FromActor(candidate); update(target); return(true); }
public FlyFollow(Actor self, Target target, WRange minRange, WRange maxRange) { this.target = target; plane = self.Trait <Plane>(); this.minRange = minRange; this.maxRange = maxRange; }
protected virtual bool ShouldFlee(Squad squad, Func <IEnumerable <Actor>, bool> flee) { if (!squad.IsValid) { return(false); } var u = squad.units.Random(squad.random); var units = squad.world.FindActorsInCircle(u.CenterPosition, WRange.FromCells(DangerRadius)).ToList(); var ownBaseBuildingAround = units.Where(unit => unit.Owner == squad.bot.p && unit.HasTrait <Building>()); if (ownBaseBuildingAround.Any()) { return(false); } var enemyAroundUnit = units.Where(unit => squad.bot.p.Stances[unit.Owner] == Stance.Enemy && unit.HasTrait <AttackBase>()); if (!enemyAroundUnit.Any()) { return(false); } return(flee(enemyAroundUnit)); }
public void Tick(Squad owner) { if (!owner.IsValid) { return; } if (!owner.TargetIsValid) { owner.Target = owner.bot.FindClosestEnemy(owner.CenterPosition, WRange.FromCells(8)); if (owner.Target == null) { owner.fsm.ChangeState(owner, new UnitsForProtectionFleeState(), true); return; } } foreach (var a in owner.units) { owner.world.IssueOrder(new Order("AttackMove", a, false) { TargetLocation = owner.Target.Location }); } }
public override Activity Tick(Actor self) { if (IsCanceled) { return(NextActivity); } // Close enough (ported from old code which checked length against sqrt(50) px) var d = pos - self.CenterPosition; if (d.HorizontalLengthSquared < 91022) { return(NextActivity); } var plane = self.Trait <Plane>(); var desiredFacing = Util.GetFacing(d, plane.Facing); var cruiseAltitude = new WRange(plane.Info.CruiseAltitude * 1024 / Game.CellSize); // Don't turn until we've reached the cruise altitude if (plane.CenterPosition.Z < cruiseAltitude.Range) { desiredFacing = plane.Facing; } FlyToward(self, plane, desiredFacing, cruiseAltitude); return(this); }
public override void DoAttack(Actor self, Target target) { if (target.Type != TargetType.Actor || !CanAttack(self, target)) { return; } var a = ChooseArmamentForTarget(target); if (a == null) { return; } // TODO: Define weapon ranges as WRange var range = new WRange((int)(1024 * a.Weapon.Range)); if (!target.IsInRange(self.CenterPosition, range)) { return; } self.CancelActivity(); self.QueueActivity(new Leap(self, target.Actor, a.Weapon, info.Speed, info.Angle)); }
public void Tick(Actor self) { if (FireDelay > 0) { --FireDelay; } Recoil = new WRange(Math.Max(0, Recoil.Range - Info.RecoilRecovery.Range)); }
public Follow(Actor self, Target target, WRange minRange, WRange maxRange) { this.target = target; this.minRange = minRange; this.maxRange = maxRange; move = self.Trait <IMove>(); }
public Follow(Actor self, Target target, WRange minRange, WRange maxRange) { this.target = target; this.minRange = minRange; this.maxRange = maxRange; move = self.Trait<IMove>(); }
internal Actor FindClosestEnemy(WPos pos, WRange radius) { var enemyUnits = World.FindActorsInCircle(pos, radius) .Where(unit => Player.Stances[unit.Owner] == Stance.Enemy && !unit.HasTrait <Husk>() && unit.HasTrait <ITargetable>()); return(enemyUnits.ClosestTo(pos)); }
public RangeCircleRenderable(WPos centerPosition, WRange radius, int zOffset, Color color, Color contrastColor) { this.centerPosition = centerPosition; this.radius = radius; this.zOffset = zOffset; this.color = color; this.contrastColor = contrastColor; }
public void GuardTarget(Actor self, Target target) { self.SetTargetLine(target, Color.Yellow); var range = WRange.FromCells(target.Actor.Info.Traits.Get <GuardableInfo>().Range); self.QueueActivity(false, new AttackMove.AttackMoveActivity(self, self.Trait <IMove>().MoveFollow(self, target, WRange.Zero, range))); }
public Bullet(BulletInfo info, ProjectileArgs args) { this.info = info; this.args = args; this.pos = args.Source; var world = args.SourceActor.World; if (info.Angle.Length > 1) { angle = new WAngle(world.SharedRandom.Next(info.Angle[0].Angle, info.Angle[1].Angle)); } else { angle = info.Angle[0]; } if (info.Speed.Length > 1) { speed = new WRange(world.SharedRandom.Next(info.Speed[0].Range, info.Speed[1].Range)); } else { speed = info.Speed[0]; } target = args.PassiveTarget; if (info.Inaccuracy.Range > 0) { var inaccuracy = OpenRA.Traits.Util.ApplyPercentageModifiers(info.Inaccuracy.Range, args.InaccuracyModifiers); var maxOffset = inaccuracy * (target - pos).Length / args.Weapon.Range.Range; target += WVec.FromPDF(world.SharedRandom, 2) * maxOffset / 1024; } facing = OpenRA.Traits.Util.GetFacing(target - pos, 0); length = Math.Max((target - pos).Length / speed.Range, 1); if (!string.IsNullOrEmpty(info.Image)) { anim = new Animation(world, info.Image, GetEffectiveFacing); anim.PlayRepeating("idle"); } if (info.ContrailLength > 0) { var color = info.ContrailUsePlayerColor ? ContrailRenderable.ChooseColor(args.SourceActor) : info.ContrailColor; contrail = new ContrailRenderable(world, color, info.ContrailLength, info.ContrailDelay, 0); } trailPalette = info.TrailPalette; if (info.TrailUsePlayerPalette) { trailPalette += args.SourceActor.Owner.InternalName; } smokeTicks = info.TrailDelay; }
public ProximityTrigger(int id, WPos pos, WRange range, Action <Actor> onActorEntered, Action <Actor> onActorExited) { Id = id; this.onActorEntered = onActorEntered; this.onActorExited = onActorExited; Update(pos, range); }
// Scriptable move order // Ignores lane bias and nearby units public Move(CPos destination) { this.getPath = (self, mobile) => self.World.WorldActor.Trait <PathFinder>().FindPath( PathSearch.FromPoint(self.World, mobile.Info, self, mobile.toCell, destination, false) .WithoutLaneBias()); this.destination = destination; this.nearEnough = WRange.Zero; }
public void Explore(World world, CPos center, WRange range) { foreach (var q in FindVisibleTiles(world, center, range)) { explored[q] = true; } Invalidate(); }
public override Activity GetAttackActivity(Actor self, Target newTarget, bool allowMove) { var a = ChooseArmamentForTarget(newTarget); if (a == null) return null; // TODO: Define weapon ranges as WRange var range = new WRange(Math.Max(0,(int)(1024*a.Weapon.Range))); return new Activities.Attack(newTarget, range, allowMove); }
public override Activity Tick(Actor self) { if (IsCanceled || !self.World.Map.IsInMap(self.Location)) return NextActivity; var plane = self.Trait<Plane>(); var cruiseAltitude = new WRange(plane.Info.CruiseAltitude * 1024 / Game.CellSize); Fly.FlyToward(self, plane, plane.Facing, cruiseAltitude); return this; }
public LuaTable ActorsInCircle(WPos location, WRange radius, LuaFunction filter) { var actors = context.World.FindActorsInCircle(location, radius) .Select(a => a.ToLuaValue(context)) .Where(a => { using (var f = filter.Call(a)) return f.First().ToBoolean(); }); return actors.ToLuaTable(context); }
public override Activity Tick(Actor self) { if (IsCanceled || remainingTicks-- == 0) return NextActivity; var plane = self.Trait<Plane>(); var cruiseAltitude = new WRange(plane.Info.CruiseAltitude * 1024 / Game.CellSize); Fly.FlyToward(self, plane, plane.Facing, cruiseAltitude); return this; }
static IEnumerable<CPos> FindVisibleTiles(World world, CPos position, WRange radius) { var map = world.Map; var r = (radius.Range + 1023) / 1024; var limit = radius.Range * radius.Range; var pos = map.CenterOfCell(position); foreach (var cell in map.FindTilesInCircle(position, r)) if ((map.CenterOfCell(cell) - pos).HorizontalLengthSquared <= limit) yield return cell; }
public Attack(Actor self, Target target, WRange minRange, WRange maxRange, bool allowMovement) { Target = target; this.minRange = minRange; this.maxRange = maxRange; attack = self.Trait<AttackBase>(); facing = self.Trait<IFacing>(); move = allowMovement ? self.TraitOrDefault<IMove>() : null; }
public static bool AdjustAltitude(Actor self, Helicopter helicopter, WRange targetAltitude) { var altitude = helicopter.CenterPosition.Z; if (altitude == targetAltitude.Range) return false; var delta = helicopter.Info.AltitudeVelocity.Range; var dz = (targetAltitude.Range - altitude).Clamp(-delta, delta); helicopter.SetPosition(self, helicopter.CenterPosition + new WVec(0, 0, dz)); return true; }
public override Activity Tick(Actor self) { if (IsCanceled) return NextActivity; var plane = self.Trait<Plane>(); // We can't possibly turn this fast var desiredFacing = plane.Facing + 64; var cruiseAltitude = new WRange(plane.Info.CruiseAltitude * 1024 / Game.CellSize); Fly.FlyToward(self, plane, desiredFacing, cruiseAltitude); return this; }
public static void FlyToward(Actor self, Plane plane, int desiredFacing, WRange desiredAltitude) { var move = plane.FlyStep(plane.Facing); var altitude = plane.CenterPosition.Z; plane.Facing = Util.TickFacing(plane.Facing, desiredFacing, plane.ROT); if (altitude != desiredAltitude.Range) { var delta = move.HorizontalLength * plane.Info.MaximumPitch.Tan() / 1024; var dz = (desiredAltitude.Range - altitude).Clamp(-delta, delta); move += new WVec(0, 0, dz); } plane.SetPosition(self, plane.CenterPosition + move); }
public Bullet(BulletInfo info, ProjectileArgs args) { this.info = info; this.args = args; this.pos = args.Source; var world = args.SourceActor.World; if (info.Angle.Length > 1) angle = new WAngle(world.SharedRandom.Next(info.Angle[0].Angle, info.Angle[1].Angle)); else angle = info.Angle[0]; if (info.Speed.Length > 1) speed = new WRange(world.SharedRandom.Next(info.Speed[0].Range, info.Speed[1].Range)); else speed = info.Speed[0]; target = args.PassiveTarget; if (info.Inaccuracy.Range > 0) { var inaccuracy = OpenRA.Traits.Util.ApplyPercentageModifiers(info.Inaccuracy.Range, args.InaccuracyModifiers); var maxOffset = inaccuracy * (target - pos).Length / args.Weapon.Range.Range; target += WVec.FromPDF(world.SharedRandom, 2) * maxOffset / 1024; } facing = OpenRA.Traits.Util.GetFacing(target - pos, 0); length = Math.Max((target - pos).Length / speed.Range, 1); if (!string.IsNullOrEmpty(info.Image)) { anim = new Animation(world, info.Image, GetEffectiveFacing); anim.PlayRepeating("idle"); } if (info.ContrailLength > 0) { var color = info.ContrailUsePlayerColor ? ContrailRenderable.ChooseColor(args.SourceActor) : info.ContrailColor; contrail = new ContrailRenderable(world, color, info.ContrailLength, info.ContrailDelay, 0); } trailPalette = info.TrailPalette; if (info.TrailUsePlayerPalette) trailPalette += args.SourceActor.Owner.InternalName; smokeTicks = info.TrailDelay; }
public override void DoAttack(Actor self, Target target) { if (target.Type != TargetType.Actor || !CanAttack(self, target)) return; var a = ChooseArmamentForTarget(target); if (a == null) return; // TODO: Define weapon ranges as WRange var range = new WRange((int)(1024*a.Weapon.Range)); if (!target.IsInRange(self.CenterPosition, range)) return; self.CancelActivity(); self.QueueActivity(new Leap(self, target.Actor, a.Weapon, info.Speed, info.Angle)); }
public void Tick(Actor self) { var disabled = self.IsDisabled(); if (cachedDisabled != disabled) { Sound.Play(disabled ? info.DisableSound : info.EnableSound, self.CenterPosition); desiredRange = disabled ? WRange.Zero : info.Range; cachedDisabled = disabled; } if (self.CenterPosition != cachedPosition || desiredRange != cachedRange) { cachedPosition = self.CenterPosition; cachedRange = desiredRange; self.World.ActorMap.UpdateProximityTrigger(proximityTrigger, cachedPosition, cachedRange); } }
public Bullet(BulletInfo info, ProjectileArgs args) { this.info = info; this.args = args; this.pos = args.Source; var world = args.SourceActor.World; if (info.Angle.Length > 1 && info.Speed.Length > 1) { angle = new WAngle(args.SourceActor.World.SharedRandom.Next(info.Angle[0].Angle, info.Angle[1].Angle)); speed = new WRange(args.SourceActor.World.SharedRandom.Next(info.Speed[0].Range, info.Speed[1].Range)); } else { angle = info.Angle[0]; speed = info.Speed[0]; } target = args.PassiveTarget; if (info.Inaccuracy.Range > 0) { var maxOffset = info.Inaccuracy.Range * (target - pos).Length / args.Weapon.Range.Range; target += WVec.FromPDF(args.SourceActor.World.SharedRandom, 2) * maxOffset / 1024; } facing = Traits.Util.GetFacing(target - pos, 0); length = Math.Max((target - pos).Length / speed.Range, 1); if (info.Image != null) { anim = new Animation(world, info.Image, GetEffectiveFacing); anim.PlayRepeating("idle"); } if (info.ContrailLength > 0) { var color = info.ContrailUsePlayerColor ? ContrailRenderable.ChooseColor(args.SourceActor) : info.ContrailColor; trail = new ContrailRenderable(args.SourceActor.World, color, info.ContrailLength, info.ContrailDelay, 0); } smokeTicks = info.TrailDelay; }
/// <summary>Evaluates the attractiveness of a position according to all considerations</summary> public int GetAttractiveness(WPos pos, Player firedBy) { var answer = 0; var world = firedBy.World; var targetTile = world.Map.CellContaining(pos); if (!world.Map.Contains(targetTile)) return 0; foreach (var consideration in Considerations) { var radiusToUse = new WRange(consideration.CheckRadius.Range); var checkActors = world.FindActorsInCircle(pos, radiusToUse); foreach (var scrutinized in checkActors) answer += consideration.GetAttractiveness(scrutinized, firedBy.Stances[scrutinized.Owner], firedBy); } return answer; }
public override void DoAttack(Actor self, Target target) { if (!CanAttack(self, target)) return; var arm = Armaments.FirstOrDefault(); if (arm == null) return; // TODO: Define weapon ranges as WRange var range = new WRange((int)(1024*arm.Weapon.Range)); if (!target.IsInRange(self.CenterPosition, range)) return; var facing = self.TraitOrDefault<IFacing>(); foreach (var a in Armaments) a.CheckFire(self, this, facing, target); if (target.Actor != null) target.Actor.ChangeOwner(self.Owner); }
public Leap(Actor self, Actor target, WeaponInfo weapon, WRange speed, WAngle angle) { var targetMobile = target.TraitOrDefault<Mobile>(); if (targetMobile == null) throw new InvalidOperationException("Leap requires a target actor with the Mobile trait"); this.weapon = weapon; this.angle = angle; mobile = self.Trait<Mobile>(); mobile.SetLocation(mobile.fromCell, mobile.fromSubCell, targetMobile.fromCell, targetMobile.fromSubCell); mobile.IsMoving = true; from = self.CenterPosition; to = targetMobile.fromCell.CenterPosition + MobileInfo.SubCellOffsets[targetMobile.fromSubCell]; length = Math.Max((to - from).Length / speed.Range, 1); self.Trait<RenderInfantry>().Attacking(self, Target.FromActor(target)); if (weapon.Report != null && weapon.Report.Any()) Sound.Play(weapon.Report.Random(self.World.SharedRandom), self.CenterPosition); }
public override Activity Tick(Actor self) { if (IsCanceled) return NextActivity; // Close enough (ported from old code which checked length against sqrt(50) px) var d = pos - self.CenterPosition; if (d.HorizontalLengthSquared < 91022) return NextActivity; var plane = self.Trait<Plane>(); var desiredFacing = Util.GetFacing(d, plane.Facing); var cruiseAltitude = new WRange(plane.Info.CruiseAltitude * 1024 / Game.CellSize); // Don't turn until we've reached the cruise altitude if (plane.CenterPosition.Z < cruiseAltitude.Range) desiredFacing = plane.Facing; FlyToward(self, plane, desiredFacing, cruiseAltitude); return this; }
public Bullet(BulletInfo info, ProjectileArgs args) { this.info = info; this.args = args; this.pos = args.Source; // Convert ProjectileArg definitions to world coordinates // TODO: Change the yaml definitions so we don't need this var range = new WRange((int)(1024 * args.Weapon.Range)); // Range in world units var inaccuracy = new WRange((int)(info.Inaccuracy * 1024 / Game.CellSize)); // Offset in world units at max range var speed = (int)(info.Speed * 4 * 1024 / (10 * Game.CellSize)); // Speed in world units per tick angle = WAngle.ArcTan((int)(info.Angle * 4 * 1024), 1024); // Angle in world angle target = args.PassiveTarget; if (info.Inaccuracy > 0) { var maxOffset = inaccuracy.Range * (target - pos).Length / range.Range; target += WVec.FromPDF(args.SourceActor.World.SharedRandom, 2) * maxOffset / 1024; } facing = Traits.Util.GetFacing(target - pos, 0); length = Math.Max((target - pos).Length / speed, 1); if (info.Image != null) { anim = new Animation(info.Image, GetEffectiveFacing); anim.PlayRepeating("idle"); } if (info.ContrailLength > 0) { var color = info.ContrailUsePlayerColor ? ContrailRenderable.ChooseColor(args.SourceActor) : info.ContrailColor; trail = new ContrailRenderable(args.SourceActor.World, color, info.ContrailLength, info.ContrailDelay, 0); } smokeTicks = info.TrailDelay; }
public NukeLaunch(Player firedBy, string weapon, WPos launchPos, WPos targetPos, WRange velocity, int delay, bool skipAscent) { this.firedBy = firedBy; this.weapon = weapon; this.delay = delay; this.turn = delay / 2; var offset = new WVec(WRange.Zero, WRange.Zero, velocity * turn); ascendSource = launchPos; ascendTarget = launchPos + offset; descendSource = targetPos + offset; descendTarget = targetPos; anim = new Animation(firedBy.World, weapon); anim.PlayRepeating("up"); pos = launchPos; var weaponRules = firedBy.World.Map.Rules.Weapons[weapon.ToLowerInvariant()]; if (weaponRules.Report != null && weaponRules.Report.Any()) Sound.Play(weaponRules.Report.Random(firedBy.World.SharedRandom), pos); if (skipAscent) ticks = turn; }
public Fly(Actor self, Target t, WRange minRange, WRange maxRange) : this(self, t) { this.maxRange = maxRange; this.minRange = minRange; }
public bool IsInRange(WPos origin, WRange range) { if (Type == TargetType.Invalid) return false; // Target ranges are calculated in 2D, so ignore height differences var rangeSquared = range.Range*range.Range; return Positions.Any(t => (t - origin).HorizontalLengthSquared <= rangeSquared); }
public Heal(Target target, WRange range, bool allowMovement) : base(target, range, allowMovement) { }
public Activity MoveWithinRange(Target target, WRange minRange, WRange maxRange) { return Util.SequenceActivities(new Fly(self, target, minRange, maxRange), new FlyCircle()); }