Beispiel #1
0
        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);
            }
Beispiel #3
0
        public CarpetBomb(CarpetBombInfo info)
        {
            this.info = info;

            // TODO: Push this conversion into the yaml
            range = WRange.FromCells(info.Range);
        }
Beispiel #4
0
        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);
        }
Beispiel #5
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);
            }
        }
Beispiel #6
0
        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);
        }
Beispiel #7
0
            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);
            }
Beispiel #8
0
        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));
                }
            }
        }
Beispiel #9
0
        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);
        }
Beispiel #10
0
 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;
 }
Beispiel #11
0
        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;
        }
Beispiel #12
0
        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);
            }
        }
Beispiel #13
0
        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;
                }
            }
        }
Beispiel #14
0
        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;
        }
Beispiel #15
0
		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));
        }
Beispiel #17
0
        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);
        }
Beispiel #18
0
        public CarpetBomb(CarpetBombInfo info)
        {
            this.info = info;

            // TODO: Push this conversion into the yaml
            range = WRange.FromCells(info.Range);
        }
Beispiel #19
0
        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);
                }
            }
        }
Beispiel #20
0
        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)));
            }
        }
Beispiel #21
0
        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);
        }
Beispiel #22
0
 public FlyFollow(Actor self, Target target, WRange minRange, WRange maxRange)
 {
     this.target   = target;
     plane         = self.Trait <Plane>();
     this.minRange = minRange;
     this.maxRange = maxRange;
 }
Beispiel #23
0
        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));
        }
Beispiel #24
0
        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
                });
            }
        }
Beispiel #25
0
        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);
        }
Beispiel #26
0
        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));
        }
Beispiel #27
0
 public void Tick(Actor self)
 {
     if (FireDelay > 0)
     {
         --FireDelay;
     }
     Recoil = new WRange(Math.Max(0, Recoil.Range - Info.RecoilRecovery.Range));
 }
Beispiel #28
0
        public Follow(Actor self, Target target, WRange minRange, WRange maxRange)
        {
            this.target   = target;
            this.minRange = minRange;
            this.maxRange = maxRange;

            move = self.Trait <IMove>();
        }
Beispiel #29
0
        public Follow(Actor self, Target target, WRange minRange, WRange maxRange)
        {
            this.target = target;
            this.minRange = minRange;
            this.maxRange = maxRange;

            move = self.Trait<IMove>();
        }
Beispiel #30
0
        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;
 }
Beispiel #32
0
        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)));
        }
Beispiel #33
0
 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;
 }
Beispiel #34
0
        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;
        }
Beispiel #35
0
            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);
            }
Beispiel #36
0
 // 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;
 }
Beispiel #37
0
        public void Explore(World world, CPos center, WRange range)
        {
            foreach (var q in FindVisibleTiles(world, center, range))
            {
                explored[q] = true;
            }

            Invalidate();
        }
Beispiel #38
0
        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);
        }
Beispiel #39
0
        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;
        }
Beispiel #40
0
		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);
		}
Beispiel #41
0
        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;
        }
Beispiel #42
0
		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;
		}
Beispiel #43
0
		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;
		}
Beispiel #44
0
		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;
		}
Beispiel #45
0
        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;
        }
Beispiel #46
0
		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);
		}
Beispiel #47
0
        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;
        }
Beispiel #48
0
        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));
        }
Beispiel #49
0
        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);
            }
        }
Beispiel #50
0
		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;
		}
Beispiel #51
0
        /// <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;
        }
Beispiel #52
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);
        }
Beispiel #53
0
        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);
        }
Beispiel #54
0
        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;
        }
Beispiel #55
0
        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;
        }
Beispiel #56
0
        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;
        }
Beispiel #57
0
		public Fly(Actor self, Target t, WRange minRange, WRange maxRange)
			: this(self, t)
		{
			this.maxRange = maxRange;
			this.minRange = minRange;
		}
Beispiel #58
0
        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);
        }
Beispiel #59
0
 public Heal(Target target, WRange range, bool allowMovement)
     : base(target, range, allowMovement)
 {
 }
Beispiel #60
0
 public Activity MoveWithinRange(Target target, WRange minRange, WRange maxRange)
 {
     return Util.SequenceActivities(new Fly(self, target, minRange, maxRange), new FlyCircle());
 }