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); }
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); }
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); }
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); }
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); }