예제 #1
0
        public override Activity Tick(Actor self)
        {
            if (cargo.IsDead || !carryall.IsBusy)
            {
                carryall.UnreserveCarryable();
                return(NextActivity);
            }

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

            case State.LockCarryable:
                // Last check
                if (carryable.StandbyForPickup(self))
                {
                    state = State.MoveToCarryable;
                    return(this);
                }

                // We got cancelled
                carryall.UnreserveCarryable();
                return(NextActivity);

            case State.MoveToCarryable:                     // We arrived, move on top
                if (self.Location == cargo.Location)
                {
                    state = State.Turn;
                    return(this);
                }

                return(Util.SequenceActivities(movement.MoveTo(cargo.Location, 0), this));

            case State.Turn:                     // Align facing and Land
                if (selfFacing.Facing != cargoFacing.Facing)
                {
                    return(Util.SequenceActivities(new Turn(self, cargoFacing.Facing), this));
                }
                state = State.Pickup;
                return(Util.SequenceActivities(new HeliLand(self, false), new Wait(10), this));

            case State.Pickup:
                // Remove our carryable from world
                self.World.AddFrameEndTask(w => cargo.World.Remove(cargo));
                carryall.AttachCarryable(cargo);
                state = State.TakeOff;
                return(this);

            case State.TakeOff:
                if (HeliFly.AdjustAltitude(self, aircraft, aircraft.Info.CruiseAltitude))
                {
                    return(this);
                }
                return(NextActivity);
            }

            return(NextActivity);
        }
예제 #2
0
        public override Activity Tick(Actor self)
        {
            if (cargo.IsDead || !carryall.IsBusy)
            {
                carryall.UnreserveCarryable();
                return(NextActivity);
            }

            switch (state)
            {
            case State.Transport:
                var targetl = GetLocationToDrop(carryable.Destination);
                state = State.Land;
                return(ActivityUtils.SequenceActivities(movement.MoveTo(targetl, 0), this));

            case State.Land:
                if (!CanDropHere())
                {
                    state = State.Transport;
                    return(this);
                }

                if (HeliFly.AdjustAltitude(self, aircraft, aircraft.Info.LandAltitude))
                {
                    return(this);
                }
                state = State.Release;
                return(ActivityUtils.SequenceActivities(new Wait(15), this));

            case State.Release:
                if (!CanDropHere())
                {
                    state = State.Transport;
                    return(this);
                }

                Release();
                return(NextActivity);
            }

            return(NextActivity);
        }
예제 #3
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);
        }
예제 #4
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);
        }
예제 #5
0
        public override Activity Tick(Actor self)
        {
            if (innerActivity != null)
            {
                innerActivity = ActivityUtils.RunActivity(self, innerActivity);
                return(this);
            }

            if (IsCanceled)
            {
                return(NextActivity);
            }

            if ((carryall.State == Carryall.CarryallState.Idle || carryall.Carryable.IsDead) && state != DeliveryState.TakeOff)
            {
                state = DeliveryState.Aborted;
            }

            switch (state)
            {
            case DeliveryState.Transport:
            {
                var targetLocation = FindDropLocation(destination, carryall.Info.DropRange);

                // Can't land, so wait at the target until something changes
                if (!targetLocation.HasValue)
                {
                    innerActivity = ActivityUtils.SequenceActivities(
                        new HeliFly(self, Target.FromCell(self.World, destination)),
                        new Wait(25));

                    return(this);
                }

                var targetPosition = self.World.Map.CenterOfCell(targetLocation.Value);

                var localOffset       = carryall.CarryableOffset.Rotate(body.QuantizeOrientation(self, self.Orientation));
                var carryablePosition = self.CenterPosition + body.LocalToWorld(localOffset);
                if ((carryablePosition - targetPosition).HorizontalLengthSquared != 0)
                {
                    // For non-zero offsets the drop position depends on the carryall facing
                    // We therefore need to predict/correct for the facing *at the drop point*
                    if (carryall.CarryableOffset.HorizontalLengthSquared != 0)
                    {
                        var facing = (targetPosition - self.CenterPosition).Yaw.Facing;
                        localOffset   = carryall.CarryableOffset.Rotate(body.QuantizeOrientation(self, WRot.FromFacing(facing)));
                        innerActivity = ActivityUtils.SequenceActivities(
                            new HeliFly(self, Target.FromPos(targetPosition - body.LocalToWorld(localOffset))),
                            new Turn(self, facing));

                        return(this);
                    }

                    innerActivity = new HeliFly(self, Target.FromPos(targetPosition));
                    return(this);
                }

                state = DeliveryState.Land;
                return(this);
            }

            case DeliveryState.Land:
            {
                if (!CanDropHere())
                {
                    state = DeliveryState.Transport;
                    return(this);
                }

                // Make sure that the carried actor is on the ground before releasing it
                var localOffset       = carryall.CarryableOffset.Rotate(body.QuantizeOrientation(self, self.Orientation));
                var carryablePosition = self.CenterPosition + body.LocalToWorld(localOffset);
                if (self.World.Map.DistanceAboveTerrain(carryablePosition) != WDist.Zero)
                {
                    innerActivity = new HeliLand(self, false, -new WDist(carryall.CarryableOffset.Z));
                    return(this);
                }

                state = carryall.Info.UnloadingDelay > 0 ? DeliveryState.Wait : DeliveryState.Release;
                return(this);
            }

            case DeliveryState.Wait:
                state         = DeliveryState.Release;
                innerActivity = new Wait(carryall.Info.UnloadingDelay, false);
                return(this);

            case DeliveryState.Release:
                if (!CanDropHere())
                {
                    state = DeliveryState.Transport;
                    return(this);
                }

                Release();
                state = DeliveryState.TakeOff;
                return(this);

            case DeliveryState.TakeOff:
                return(ActivityUtils.SequenceActivities(new HeliFly(self, Target.FromPos(self.CenterPosition)), NextActivity));

            case DeliveryState.Aborted:
                carryall.UnreserveCarryable(self);
                break;
            }

            return(NextActivity);
        }