Ejemplo n.º 1
0
        IEnumerable <IRenderable> IRenderAnnotations.RenderAnnotations(Actor self, WorldRenderer wr)
        {
            if (!enabled || self.World.FogObscures(self))
            {
                yield break;
            }

            var referencePoint  = self.CenterPosition;
            var bodyOrientation = coords.QuantizeOrientation(self.Orientation);
            var devRenderOffset = devOffset;

            if (turret != -1)
            {
                var turretOrientation = turrets[turret].WorldOrientation;
                devRenderOffset = devRenderOffset.Rotate(turretOrientation);
                referencePoint += coords.LocalToWorld(turrets[turret].Offset.Rotate(bodyOrientation));
            }

            devRenderOffset = coords.LocalToWorld(devRenderOffset.Rotate(bodyOrientation));

            yield return(new LineAnnotationRenderable(referencePoint - TargetPosHLine, referencePoint + TargetPosHLine, 1, Color.Magenta));

            yield return(new LineAnnotationRenderable(referencePoint - TargetPosVLine, referencePoint + TargetPosVLine, 1, Color.Magenta));

            var devPoint       = referencePoint + devRenderOffset;
            var devOrientation = turret != -1 ? turrets[turret].WorldOrientation :
                                 coords.QuantizeOrientation(self.Orientation);
            var dirOffset = new WVec(0, -224, 0).Rotate(devOrientation);

            yield return(new LineAnnotationRenderable(devPoint, devPoint + dirOffset, 1, Color.Magenta));
        }
Ejemplo n.º 2
0
        // Check if we can drop the unit at our current location.
        bool CanDropHere()
        {
            var localOffset = carryall.CarryableOffset.Rotate(body.QuantizeOrientation(self, self.Orientation));
            var targetCell  = self.World.Map.CellContaining(self.CenterPosition + body.LocalToWorld(localOffset));

            return(positionable.CanEnterCell(targetCell));
        }
Ejemplo n.º 3
0
        WVec BarrelOffset()
        {
            var b                 = self.Orientation;
            var qb                = body.QuantizeOrientation(self, b);
            var localOffset       = Info.LocalOffset + new WVec(-armament.Recoil, WDist.Zero, WDist.Zero);
            var turretLocalOffset = turreted != null ? turreted.Offset : WVec.Zero;
            var turretOrientation = turreted != null?turreted.WorldOrientation(self) - b + WRot.FromYaw(b.Yaw - qb.Yaw) : WRot.None;

            return(body.LocalToWorld((turretLocalOffset + localOffset.Rotate(turretOrientation)).Rotate(qb)));
        }
Ejemplo n.º 4
0
        WVec BarrelOffset()
        {
            var localOffset  = Info.LocalOffset + new WVec(-armament.Recoil, WDist.Zero, WDist.Zero);
            var turretOffset = turreted != null?turreted.Position(self) : WVec.Zero;

            var quantizedBody     = body.QuantizeOrientation(self, self.Orientation);
            var turretOrientation = turreted != null?turreted.WorldOrientation(self) - quantizedBody : WRot.Zero;

            var quantizedTurret = body.QuantizeOrientation(self, turretOrientation);

            return(turretOffset + body.LocalToWorld(localOffset.Rotate(quantizedTurret).Rotate(quantizedBody)));
        }
Ejemplo n.º 5
0
        public IEnumerable <IRenderable> ModifyRender(Actor self, WorldRenderer wr, IEnumerable <IRenderable> r)
        {
            foreach (var rr in r)
            {
                yield return(rr);
            }

            var bodyOrientation = body.QuantizeOrientation(self, self.Orientation);
            var pos             = self.CenterPosition;
            var i = 0;

            foreach (var c in cargo.Passengers)
            {
                var cargoPassenger = c.Trait <Passenger>();
                if (cargoInfo.DisplayTypes.Contains(cargoPassenger.Info.CargoType))
                {
                    var index       = cargo.PassengerCount > 1 ? i++ % cargoInfo.LocalOffset.Length : cargoInfo.LocalOffset.Length / 2;
                    var localOffset = cargoInfo.LocalOffset[index];
                    var offset      = pos - c.CenterPosition + body.LocalToWorld(localOffset.Rotate(bodyOrientation));
                    foreach (var cr in c.Render(wr))
                    {
                        yield return(cr.OffsetBy(offset).WithZOffset(1));
                    }
                }
            }
        }
Ejemplo n.º 6
0
        void ITick.Tick(Actor self)
        {
            if (IsTraitDisabled)
            {
                return;
            }

            if (--fireDelay < 0)
            {
                var localoffset = body != null
                                        ? body.LocalToWorld(info.LocalOffset.Rotate(body.QuantizeOrientation(self, self.Orientation)))
                                        : info.LocalOffset;

                if (weapon.Report != null && weapon.Report.Any())
                {
                    Game.Sound.Play(weapon.Report.Random(self.World.SharedRandom), self.CenterPosition);
                }
                weapon.Impact(Target.FromPos(self.CenterPosition + localoffset), self,
                              self.TraitsImplementing <IFirepowerModifier>().Select(a => a.GetFirepowerModifier()).ToArray());

                if (--burst > 0)
                {
                    fireDelay = weapon.BurstDelay;
                }
                else
                {
                    var modifiers = self.TraitsImplementing <IReloadModifier>()
                                    .Select(m => m.GetReloadModifier());
                    fireDelay = Util.ApplyPercentageModifiers(weapon.ReloadDelay, modifiers);
                    burst     = weapon.Burst;
                }
            }
        }
Ejemplo n.º 7
0
            protected override void OnFirstRun(Actor self)
            {
                self.Trait <Aircraft>().RemoveInfluence();

                var localOffset    = carryall.CarryableOffset.Rotate(body.QuantizeOrientation(self, self.Orientation));
                var targetPosition = self.CenterPosition + body.LocalToWorld(localOffset);
                var targetLocation = self.World.Map.CellContaining(targetPosition);

                carryall.Carryable.Trait <IPositionable>().SetPosition(carryall.Carryable, targetLocation, SubCell.FullCell);

                // HACK: directly manipulate the turret facings to match the new orientation
                // This can eventually go away, when we make turret facings relative to the body
                var carryableFacing = carryall.Carryable.Trait <IFacing>();
                var facingDelta     = facing.Facing - carryableFacing.Facing;

                foreach (var t in carryall.Carryable.TraitsImplementing <Turreted>())
                {
                    t.TurretFacing += facingDelta;
                }

                carryableFacing.Facing = facing.Facing;

                // Put back into world
                self.World.AddFrameEndTask(w =>
                {
                    var cargo     = carryall.Carryable;
                    var carryable = carryall.Carryable.Trait <Carryable>();
                    w.Add(cargo);
                    carryall.DetachCarryable(self);
                    carryable.UnReserve(cargo);
                    carryable.Detached(cargo);
                });
            }
Ejemplo n.º 8
0
            protected override void OnFirstRun(Actor self)
            {
                self.Trait <Aircraft>().RemoveInfluence();

                var localOffset    = carryall.CarryableOffset.Rotate(body.QuantizeOrientation(self, self.Orientation));
                var targetPosition = self.CenterPosition + body.LocalToWorld(localOffset);
                var targetLocation = self.World.Map.CellContaining(targetPosition);

                carryall.Carryable.Trait <IPositionable>().SetPosition(carryall.Carryable, targetLocation, SubCell.FullCell);
                carryall.Carryable.Trait <IFacing>().Facing = facing.Facing;

                // Put back into world
                self.World.AddFrameEndTask(w =>
                {
                    if (self.IsDead)
                    {
                        return;
                    }

                    var cargo = carryall.Carryable;
                    if (cargo == null)
                    {
                        return;
                    }

                    var carryable = cargo.Trait <Carryable>();
                    w.Add(cargo);
                    carryall.DetachCarryable(self);
                    carryable.UnReserve(cargo);
                    carryable.Detached(cargo);
                });
            }
Ejemplo n.º 9
0
        WRot TurretRotation()
        {
            var b  = self.Orientation;
            var qb = body.QuantizeOrientation(self, b);

            return((turreted.WorldOrientation(self) - b + WRot.FromYaw(b.Yaw - qb.Yaw)).Rotate(qb));
        }
Ejemplo n.º 10
0
        IEnumerable <WRot> TurretRotation()
        {
            var b  = self.Orientation;
            var qb = body.QuantizeOrientation(self, b);

            yield return(turreted.WorldOrientation(self) - b + WRot.FromYaw(b.Yaw - qb.Yaw));

            yield return(qb);
        }
Ejemplo n.º 11
0
        void ITick.Tick(Actor self)
        {
            if (IsTraitDisabled)
            {
                return;
            }

            wasStationary = !isMoving;
            isMoving      = self.CenterPosition != cachedPosition;
            if ((isMoving && !Info.TrailWhileMoving) || (!isMoving && !Info.TrailWhileStationary))
            {
                return;
            }

            if (isMoving == wasStationary && (Info.StartDelay > -1))
            {
                cachedInterval = Info.StartDelay;
                ticks          = 0;
            }

            if (++ticks >= cachedInterval)
            {
                var spawnCell = Info.SpawnAtLastPosition ? self.World.Map.CellContaining(cachedPosition) : self.World.Map.CellContaining(self.CenterPosition);
                if (!self.World.Map.Contains(spawnCell))
                {
                    return;
                }

                var type = self.World.Map.GetTerrainInfo(spawnCell).Type;

                if (++offset >= Info.Offsets.Length)
                {
                    offset = 0;
                }

                var offsetRotation = Info.Offsets[offset].Rotate(body.QuantizeOrientation(self, self.Orientation));
                var spawnPosition  = Info.SpawnAtLastPosition ? cachedPosition : self.CenterPosition;

                var pos = Info.Type == TrailType.CenterPosition ? spawnPosition + body.LocalToWorld(offsetRotation) :
                          self.World.Map.CenterOfCell(spawnCell);

                var spawnFacing = Info.SpawnAtLastPosition ? cachedFacing : (facing != null ? facing.Facing : WAngle.Zero);

                if ((Info.TerrainTypes.Count == 0 || Info.TerrainTypes.Contains(type)) && !string.IsNullOrEmpty(Info.Image))
                {
                    self.World.AddFrameEndTask(w => w.Add(new SpriteEffect(pos, spawnFacing, self.World, Info.Image,
                                                                           Info.Sequences.Random(Game.CosmeticRandom), Info.Palette, Info.VisibleThroughFog)));
                }

                cachedPosition = self.CenterPosition;
                cachedFacing   = facing != null ? facing.Facing : WAngle.Zero;
                ticks          = 0;

                cachedInterval = isMoving ? Info.MovingInterval : Info.StationaryInterval;
            }
        }
Ejemplo n.º 12
0
        WVec BarrelOffset()
        {
            // Barrel offset in turret coordinates
            var localOffset = Info.LocalOffset + new WVec(-armament.Recoil, WDist.Zero, WDist.Zero);

            // Turret coordinates to body coordinates
            var bodyOrientation = body.QuantizeOrientation(self, self.Orientation);

            localOffset = localOffset.Rotate(turreted.WorldOrientation) + turreted.Offset.Rotate(bodyOrientation);

            // Body coordinates to world coordinates
            return(body.LocalToWorld(localOffset));
        }
Ejemplo n.º 13
0
        IEnumerable <IRenderable> IRender.Render(Actor self, WorldRenderer wr)
        {
            var bodyOrientation = body.QuantizeOrientation(self.Orientation);
            var pos             = self.CenterPosition;
            var i = 0;

            // Generate missing previews
            var missing = previews
                          .Where(kv => kv.Value == null)
                          .Select(kv => kv.Key)
                          .ToList();

            foreach (var p in missing)
            {
                var passengerInits = new TypeDictionary()
                {
                    new OwnerInit(p.Owner),
                    new DynamicFacingInit(() => body.QuantizeFacing(facing.Facing)),
                };

                foreach (var api in p.TraitsImplementing <IActorPreviewInitModifier>())
                {
                    api.ModifyActorPreviewInit(p, passengerInits);
                }

                var init = new ActorPreviewInitializer(p.Info, wr, passengerInits);
                previews[p] = p.Info.TraitInfos <IRenderActorPreviewInfo>()
                              .SelectMany(rpi => rpi.RenderPreview(init))
                              .ToArray();
            }

            foreach (var actorPreviews in previews.Values)
            {
                if (actorPreviews == null)
                {
                    continue;
                }

                foreach (var p in actorPreviews)
                {
                    var index       = cargo.PassengerCount > 1 ? i++ % info.LocalOffset.Length : info.LocalOffset.Length / 2;
                    var localOffset = info.LocalOffset[index];

                    foreach (var pp in p.Render(wr, pos + body.LocalToWorld(localOffset.Rotate(bodyOrientation))))
                    {
                        yield return(pp.WithZOffset(1));
                    }
                }
            }
        }
        void ITick.Tick(Actor self)
        {
            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);

            if (IsTraitDisabled)
            {
                return;
            }

            if (--fireDelay + Info.InitialDelay < 0)
            {
                if (ammoPool != null && !ammoPool.TakeAmmo(self, 1))
                {
                    return;
                }

                var localoffset = body != null
                                        ? body.LocalToWorld(info.LocalOffset.Rotate(body.QuantizeOrientation(self, self.Orientation)))
                                        : info.LocalOffset;

                var args = new WarheadArgs
                {
                    Weapon          = weapon,
                    DamageModifiers = self.TraitsImplementing <IFirepowerModifier>().Select(a => a.GetFirepowerModifier()).ToArray(),
                    Source          = self.CenterPosition,
                    SourceActor     = self,
                    WeaponTarget    = Target.FromPos(self.CenterPosition + localoffset)
                };

                weapon.Impact(Target.FromPos(self.CenterPosition + localoffset), args);

                if (weapon.Report != null && weapon.Report.Any())
                {
                    Game.Sound.Play(SoundType.World, weapon.Report.Random(self.World.SharedRandom), self.CenterPosition);
                }

                if (burst == weapon.Burst && weapon.StartBurstReport != null && weapon.StartBurstReport.Any())
                {
                    Game.Sound.Play(SoundType.World, weapon.StartBurstReport.Random(self.World.SharedRandom), self.CenterPosition);
                }

                if (--burst > 0)
                {
                    if (weapon.BurstDelays.Length == 1)
                    {
                        fireDelay = weapon.BurstDelays[0];
                    }
                    else
                    {
                        fireDelay = weapon.BurstDelays[weapon.Burst - (burst + 1)];
                    }
                }
                else
                {
                    // here the cost of all passengers and their passengers is calculated
                    var summedCost = 0;
                    foreach (var p in self.TraitOrDefault <Cargo>().Passengers)
                    {
                        summedCost += p.Info.TraitInfos <ValuedInfo>().First().Cost;

                        if (p.TraitOrDefault <Cargo>() != null)
                        {
                            foreach (var p2 in p.TraitOrDefault <Cargo>().Passengers)
                            {
                                summedCost += p2.Info.TraitInfos <ValuedInfo>().First().Cost;
                            }
                        }
                    }

                    var modifiers = self.TraitsImplementing <IReloadModifier>()
                                    .Select(m => m.GetReloadModifier());

                    fireDelay = Util.ApplyPercentageModifiers(weapon.ReloadDelay, modifiers);
                    burst     = weapon.Burst;

                    fireDelay *= summedCost / 200;                                              // Here is the factor which determines how fast units are spawned, higher = faster
                    //Game.Debug(String.Join("; ", fireDelay ));

                    if (weapon.AfterFireSound != null && weapon.AfterFireSound.Any())
                    {
                        ScheduleDelayedAction(weapon.AfterFireSoundDelay, () =>
                        {
                            Game.Sound.Play(SoundType.World, weapon.AfterFireSound.Random(self.World.SharedRandom), self.CenterPosition);
                        });
                    }
                }
            }
        }
Ejemplo n.º 15
0
        void ITick.Tick(Actor self)
        {
            if (IsTraitDisabled || IsTraitPaused || !self.IsInWorld || --ticks > 0)
            {
                return;
            }

            ticks = Info.Delay.Length == 2
                                        ? world.SharedRandom.Next(Info.Delay[0], Info.Delay[1])
                                        : Info.Delay[0];

            var localoffset = body != null
                                        ? body.LocalToWorld(Info.LocalOffset.Rotate(body.QuantizeOrientation(self, self.Orientation)))
                                        : Info.LocalOffset;

            var position = self.CenterPosition + localoffset;

            var availableTargetActors = world.FindActorsOnCircle(position, Info.WeaponInfo.Range)
                                        .Where(x => (Info.AllowSelfHit || x != self) &&
                                               Info.WeaponInfo.IsValidAgainst(Target.FromActor(x), world, self) &&
                                               Info.AimTargetStances.HasStance(self.Owner.Stances[x.Owner]))
                                        .Where(x =>
            {
                var activeShapes = x.TraitsImplementing <HitShape>().Where(Exts.IsTraitEnabled);
                if (!activeShapes.Any())
                {
                    return(false);
                }

                var distance = activeShapes.Min(t => t.DistanceFromEdge(x, position));

                if (distance < Info.WeaponInfo.Range)
                {
                    return(true);
                }

                return(false);
            })
                                        .Shuffle(world.SharedRandom);

            var targetActor = availableTargetActors.GetEnumerator();

            var amount = Info.Amount.Length == 2
                                        ? world.SharedRandom.Next(Info.Amount[0], Info.Amount[1])
                                        : Info.Amount[0];

            for (var i = 0; i < amount; i++)
            {
                Target shrapnelTarget = Target.Invalid;

                if (world.SharedRandom.Next(100) < Info.AimChance && targetActor.MoveNext())
                {
                    shrapnelTarget = Target.FromActor(targetActor.Current);
                }

                if (Info.ThrowWithoutTarget && shrapnelTarget.Type == TargetType.Invalid)
                {
                    var rotation  = WRot.FromFacing(world.SharedRandom.Next(1024));
                    var range     = world.SharedRandom.Next(Info.WeaponInfo.MinRange.Length, Info.WeaponInfo.Range.Length);
                    var targetpos = position + new WVec(range, 0, 0).Rotate(rotation);
                    var tpos      = Target.FromPos(new WPos(targetpos.X, targetpos.Y, world.Map.CenterOfCell(world.Map.CellContaining(targetpos)).Z));
                    if (Info.WeaponInfo.IsValidAgainst(tpos, world, self))
                    {
                        shrapnelTarget = tpos;
                    }
                }

                if (shrapnelTarget.Type == TargetType.Invalid)
                {
                    continue;
                }

                var args = new ProjectileArgs
                {
                    Weapon = Info.WeaponInfo,
                    Facing = (shrapnelTarget.CenterPosition - position).Yaw,

                    DamageModifiers = !self.IsDead ? self.TraitsImplementing <IFirepowerModifier>()
                                      .Select(a => a.GetFirepowerModifier()).ToArray() : new int[0],

                    InaccuracyModifiers = !self.IsDead ? self.TraitsImplementing <IInaccuracyModifier>()
                                          .Select(a => a.GetInaccuracyModifier()).ToArray() : new int[0],

                    RangeModifiers = !self.IsDead ? self.TraitsImplementing <IRangeModifier>()
                                     .Select(a => a.GetRangeModifier()).ToArray() : new int[0],

                    Source        = position,
                    CurrentSource = () => position,
                    SourceActor   = self,
                    GuidedTarget  = shrapnelTarget,
                    PassiveTarget = shrapnelTarget.CenterPosition
                };

                if (args.Weapon.Projectile != null)
                {
                    var projectile = args.Weapon.Projectile.Create(args);
                    if (projectile != null)
                    {
                        world.AddFrameEndTask(w => w.Add(projectile));
                    }

                    if (args.Weapon.Report != null && args.Weapon.Report.Any())
                    {
                        Game.Sound.Play(SoundType.World, args.Weapon.Report.Random(world.SharedRandom), position);
                    }
                }
            }
        }
Ejemplo n.º 16
0
        void ITick.Tick(Actor self)
        {
            if (IsTraitDisabled || IsTraitPaused || !self.IsInWorld || --ticks > 0)
            {
                return;
            }

            ticks = Info.Delay.Length == 2
                                        ? world.SharedRandom.Next(Info.Delay[0], Info.Delay[1])
                                        : Info.Delay[0];

            var localoffset = body != null
                                        ? body.LocalToWorld(Info.LocalOffset.Rotate(body.QuantizeOrientation(self.Orientation)))
                                        : Info.LocalOffset;

            var position = self.CenterPosition + localoffset;

            foreach (var offset in Info.Offsets)
            {
                var targetVector = offset;

                if (Info.Rotate && body != null)
                {
                    targetVector = targetVector.Rotate(body.QuantizeOrientation(self.Orientation));
                }

                var fragmentTargetPosition = position + targetVector;

                if (Info.UseZOffsetAsAbsoluteHeight)
                {
                    fragmentTargetPosition = new WPos(fragmentTargetPosition.X, fragmentTargetPosition.Y,
                                                      world.Map.CenterOfCell(world.Map.CellContaining(fragmentTargetPosition)).Z + offset.Z);
                }

                var fragmentTarget = Target.FromPos(fragmentTargetPosition);
                var fragmentFacing = (fragmentTargetPosition - position).Yaw;

                var projectileArgs = new ProjectileArgs
                {
                    Weapon = Info.WeaponInfo,
                    Facing = fragmentFacing,
                    CurrentMuzzleFacing = () => fragmentFacing,

                    DamageModifiers = !self.IsDead ? self.TraitsImplementing <IFirepowerModifier>()
                                      .Select(a => a.GetFirepowerModifier()).ToArray() : Array.Empty <int>(),

                    InaccuracyModifiers = !self.IsDead ? self.TraitsImplementing <IInaccuracyModifier>()
                                          .Select(a => a.GetInaccuracyModifier()).ToArray() : Array.Empty <int>(),

                    RangeModifiers = !self.IsDead ? self.TraitsImplementing <IRangeModifier>()
                                     .Select(a => a.GetRangeModifier()).ToArray() : Array.Empty <int>(),

                    Source        = position,
                    CurrentSource = () => position,
                    SourceActor   = self,
                    GuidedTarget  = fragmentTarget,
                    PassiveTarget = fragmentTargetPosition
                };

                if (projectileArgs.Weapon.Projectile != null)
                {
                    var projectile = projectileArgs.Weapon.Projectile.Create(projectileArgs);
                    if (projectile != null)
                    {
                        world.AddFrameEndTask(w => w.Add(projectile));
                    }

                    if (projectileArgs.Weapon.Report != null && projectileArgs.Weapon.Report.Any())
                    {
                        Game.Sound.Play(SoundType.World, projectileArgs.Weapon.Report.Random(world.SharedRandom), position);
                    }
                }
            }
        }
Ejemplo n.º 17
0
        public void Tick(Actor self)
        {
            var local = info.Offset.Rotate(body.QuantizeOrientation(self, self.Orientation));

            trail.Update(self.CenterPosition + body.LocalToWorld(local));
        }
Ejemplo n.º 18
0
        void ITick.Tick(Actor self)
        {
            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);

            if (IsTraitDisabled)
            {
                return;
            }

            if (--fireDelay < 0)
            {
                if (ammoPool != null && !ammoPool.TakeAmmo(self, 1))
                {
                    return;
                }

                var localoffset = body != null
                                        ? body.LocalToWorld(info.LocalOffset.Rotate(body.QuantizeOrientation(self, self.Orientation)))
                                        : info.LocalOffset;

                weapon.Impact(Target.FromPos(self.CenterPosition + localoffset), self,
                              self.TraitsImplementing <IFirepowerModifier>().Select(a => a.GetFirepowerModifier()).ToArray());

                if (weapon.Report != null && weapon.Report.Any())
                {
                    Game.Sound.Play(SoundType.World, weapon.Report.Random(self.World.SharedRandom), self.CenterPosition);
                }

                if (burst == weapon.Burst && weapon.StartBurstReport != null && weapon.StartBurstReport.Any())
                {
                    Game.Sound.Play(SoundType.World, weapon.StartBurstReport.Random(self.World.SharedRandom), self.CenterPosition);
                }

                if (--burst > 0)
                {
                    if (weapon.BurstDelays.Length == 1)
                    {
                        fireDelay = weapon.BurstDelays[0];
                    }
                    else
                    {
                        fireDelay = weapon.BurstDelays[weapon.Burst - (burst + 1)];
                    }
                }
                else
                {
                    var modifiers = self.TraitsImplementing <IReloadModifier>()
                                    .Select(m => m.GetReloadModifier());
                    fireDelay = Util.ApplyPercentageModifiers(weapon.ReloadDelay, modifiers);
                    burst     = weapon.Burst;

                    if (weapon.AfterFireSound != null && weapon.AfterFireSound.Any())
                    {
                        ScheduleDelayedAction(weapon.AfterFireSoundDelay, () =>
                                              Game.Sound.Play(SoundType.World, weapon.AfterFireSound.Random(self.World.SharedRandom), self.CenterPosition));
                    }
                }
            }
        }
Ejemplo n.º 19
0
        public override Activity Tick(Actor self)
        {
            if (ChildActivity != null)
            {
                ChildActivity = ActivityUtils.RunActivity(self, ChildActivity);
                if (ChildActivity != null)
                {
                    return(this);
                }
            }

            if (cargo != carryall.Carryable)
            {
                return(NextActivity);
            }

            if (cargo.IsDead || IsCanceling || carryable.IsTraitDisabled || !cargo.AppearsFriendlyTo(self))
            {
                carryall.UnreserveCarryable(self);
                return(NextActivity);
            }

            if (carryall.State != Carryall.CarryallState.Reserved)
            {
                return(NextActivity);
            }

            switch (state)
            {
            case PickupState.Intercept:
                QueueChild(self, movement.MoveWithinRange(Target.FromActor(cargo), WDist.FromCells(4), targetLineColor: Color.Yellow), true);
                state = PickupState.LockCarryable;
                return(this);

            case PickupState.LockCarryable:
                if (!carryable.LockForPickup(cargo, self))
                {
                    Cancel(self);
                }

                state = PickupState.MoveToCarryable;
                return(this);

            case PickupState.MoveToCarryable:
            {
                // Line up with the attachment point
                var localOffset    = carryall.OffsetForCarryable(self, cargo).Rotate(carryableBody.QuantizeOrientation(self, cargo.Orientation));
                var targetPosition = cargo.CenterPosition - carryableBody.LocalToWorld(localOffset);
                if ((self.CenterPosition - targetPosition).HorizontalLengthSquared != 0)
                {
                    QueueChild(self, new Fly(self, Target.FromPos(targetPosition)), true);
                    return(this);
                }

                state = PickupState.Turn;
                return(this);
            }

            case PickupState.Turn:
                if (carryallFacing.Facing != carryableFacing.Facing)
                {
                    QueueChild(self, new Turn(self, carryableFacing.Facing), true);
                    return(this);
                }

                state = PickupState.Land;
                return(this);

            case PickupState.Land:
            {
                var localOffset    = carryall.OffsetForCarryable(self, cargo).Rotate(carryableBody.QuantizeOrientation(self, cargo.Orientation));
                var targetPosition = cargo.CenterPosition - carryableBody.LocalToWorld(localOffset);
                if ((self.CenterPosition - targetPosition).HorizontalLengthSquared != 0 || carryallFacing.Facing != carryableFacing.Facing)
                {
                    state = PickupState.MoveToCarryable;
                    return(this);
                }

                if (targetPosition.Z != self.CenterPosition.Z)
                {
                    QueueChild(self, new Land(self, Target.FromActor(cargo), -carryableBody.LocalToWorld(localOffset)));
                    return(this);
                }

                state = delay > 0 ? PickupState.Wait : PickupState.Pickup;
                return(this);
            }

            case PickupState.Wait:
                QueueChild(self, new Wait(delay, false), true);
                state = PickupState.Pickup;
                return(this);

            case PickupState.Pickup:
                // Remove our carryable from world
                Attach(self);
                return(this);
            }

            return(NextActivity);
        }
Ejemplo n.º 20
0
        public override Activity Tick(Actor self)
        {
            if (innerActivity != null)
            {
                innerActivity = ActivityUtils.RunActivity(self, innerActivity);
                return(this);
            }

            if (cargo != carryall.Carryable)
            {
                return(NextActivity);
            }

            if (cargo.IsDead || IsCanceled || carryable.IsTraitDisabled || !cargo.AppearsFriendlyTo(self))
            {
                carryall.UnreserveCarryable(self);
                return(NextActivity);
            }

            if (carryall.State == Carryall.CarryallState.Idle)
            {
                return(NextActivity);
            }

            switch (state)
            {
            case PickupState.Intercept:
                innerActivity = movement.MoveWithinRange(Target.FromActor(cargo), WDist.FromCells(4));
                state         = PickupState.LockCarryable;
                return(this);

            case PickupState.LockCarryable:
                state = PickupState.MoveToCarryable;
                if (!carryable.LockForPickup(cargo, self))
                {
                    state = PickupState.Aborted;
                }
                return(this);

            case PickupState.MoveToCarryable:
            {
                // Line up with the attachment point
                var localOffset    = carryall.OffsetForCarryable(self, cargo).Rotate(carryableBody.QuantizeOrientation(self, cargo.Orientation));
                var targetPosition = cargo.CenterPosition - carryableBody.LocalToWorld(localOffset);
                if ((self.CenterPosition - targetPosition).HorizontalLengthSquared != 0)
                {
                    // Run the first tick of the move activity immediately to avoid a one-frame pause
                    innerActivity = ActivityUtils.RunActivity(self, new HeliFly(self, Target.FromPos(targetPosition)));
                    return(this);
                }

                state = PickupState.Turn;
                return(this);
            }

            case PickupState.Turn:
                if (carryallFacing.Facing != carryableFacing.Facing)
                {
                    innerActivity = new Turn(self, carryableFacing.Facing);
                    return(this);
                }

                state = PickupState.Land;
                return(this);

            case PickupState.Land:
            {
                var localOffset    = carryall.OffsetForCarryable(self, cargo).Rotate(carryableBody.QuantizeOrientation(self, cargo.Orientation));
                var targetPosition = cargo.CenterPosition - carryableBody.LocalToWorld(localOffset);
                if ((self.CenterPosition - targetPosition).HorizontalLengthSquared != 0 || carryallFacing.Facing != carryableFacing.Facing)
                {
                    state = PickupState.MoveToCarryable;
                    return(this);
                }

                if (targetPosition.Z != self.CenterPosition.Z)
                {
                    innerActivity = new HeliLand(self, false, self.World.Map.DistanceAboveTerrain(targetPosition));
                    return(this);
                }

                state = delay > 0 ? PickupState.Wait : PickupState.Pickup;
                return(this);
            }

            case PickupState.Wait:
                state         = PickupState.Pickup;
                innerActivity = new Wait(delay, false);
                return(this);

            case PickupState.Pickup:
                // Remove our carryable from world
                Attach(self);
                return(NextActivity);

            case PickupState.Aborted:
                // We got cancelled
                carryall.UnreserveCarryable(self);
                break;
            }

            return(NextActivity);
        }