示例#1
0
 private void IssueMoveOrderToAllShips(IFleetNavigable fleetTgt, float tgtStandoffDistance) {
     bool isFleetwideMove = true;
     var shipMoveToOrder = new ShipMoveOrder(_fleet.CurrentOrder.Source, fleetTgt as IShipNavigable, ApSpeedSetting, isFleetwideMove, tgtStandoffDistance);
     _fleet.Elements.ForAll(e => {
         var ship = e as ShipItem;
         //D.Log(ShowDebugLog, "{0} issuing Move order to {1}. Target: {2}, Speed: {3}, StandoffDistance: {4:0.#}.", 
         //Name, ship.DebugName, fleetTgt.DebugName, _apMoveSpeed.GetValueName(), tgtStandoffDistance);
         ship.CurrentOrder = shipMoveToOrder;
     });
     _fleetData.CurrentHeading = (fleetTgt.Position - Position).normalized;
 }
示例#2
0
 /// <summary>
 /// Refreshes the course.
 /// </summary>
 /// <param name="mode">The mode.</param>
 /// <param name="waypoint">The optional waypoint. When not null, this is always a StationaryLocation detour to avoid an obstacle.</param>
 /// <exception cref="System.NotImplementedException"></exception>
 private void RefreshApCourse(CourseRefreshMode mode, IFleetNavigable waypoint = null) {
     //D.Log(ShowDebugLog, "{0}.RefreshCourse() called. Mode = {1}. CourseCountBefore = {2}.", DebugName, mode.GetValueName(), ApCourse.Count);
     switch (mode) {
         case CourseRefreshMode.NewCourse:
             D.AssertNull(waypoint);
             // A fleet course is constructed by ConstructCourse
             D.Error("{0}: Illegal {1}.{2}.", DebugName, typeof(CourseRefreshMode).Name, mode.GetValueName());
             break;
         case CourseRefreshMode.AddWaypoint:
             D.Assert(waypoint is StationaryLocation);
             ApCourse.Insert(_currentApCourseIndex, waypoint);    // changes Course.Count
             break;
         case CourseRefreshMode.ReplaceObstacleDetour:
             D.Assert(waypoint is StationaryLocation);
             ApCourse.RemoveAt(_currentApCourseIndex);          // changes Course.Count
             ApCourse.Insert(_currentApCourseIndex, waypoint);    // changes Course.Count
             break;
         case CourseRefreshMode.RemoveWaypoint:
             D.Assert(waypoint is StationaryLocation);
             D.AssertEqual(ApCourse[_currentApCourseIndex], waypoint);
             bool isRemoved = ApCourse.Remove(waypoint);         // changes Course.Count
             D.Assert(isRemoved);
             _currentApCourseIndex--;
             break;
         case CourseRefreshMode.ClearCourse:
             D.AssertNull(waypoint);
             ApCourse.Clear();
             break;
         default:
             throw new NotImplementedException(ErrorMessages.UnanticipatedSwitchValue.Inject(mode));
     }
     //D.Log(ShowDebugLog, "CourseCountAfter = {0}.", ApCourse.Count);
     HandleApCourseChanged();
 }
示例#3
0
        private bool TryCheckForObstacleEnrouteTo(IFleetNavigable destination, out IFleetNavigable detour, ref int iterationCount) {
            D.AssertException(iterationCount++ < 10);
            detour = null;
            Vector3 destinationBearing = (destination.Position - Position).normalized;
            float rayLength = destination.GetObstacleCheckRayLength(Position);
            Ray ray = new Ray(Position, destinationBearing);

            RaycastHit hitInfo;
            if (Physics.Raycast(ray, out hitInfo, rayLength, AvoidableObstacleZoneOnlyLayerMask.value)) {
                // there is an AvoidableObstacleZone in the way. Warning: hitInfo.transform returns the rigidbody parent since 
                // the obstacleZone trigger collider is static. UNCLEAR if this means it forms a compound collider as this is a raycast
                var obstacleZoneGo = hitInfo.collider.gameObject;
                var obstacleZoneHitDistance = hitInfo.distance;
                IAvoidableObstacle obstacle = obstacleZoneGo.GetSafeFirstInterfaceInParents<IAvoidableObstacle>(excludeSelf: true);

                if (obstacle == destination) {
                    D.Error("{0} encountered obstacle {1} which is the destination. \nRay length = {2:0.00}, DistanceToHit = {3:0.00}.", DebugName, obstacle.DebugName, rayLength, obstacleZoneHitDistance);
                }
                else {
                    //D.Log(ShowDebugLog, "{0} encountered obstacle {1} at {2} when checking approach to {3}. \nRay length = {4:0.#}, DistanceToHit = {5:0.#}.",
                    //Name, obstacle.DebugName, obstacle.Position, destination.DebugName, rayLength, obstacleZoneHitDistance);
                }
                if (!TryGenerateDetourAroundObstacle(obstacle, hitInfo, out detour)) {
                    return false;
                }

                IFleetNavigable newDetour;
                if (TryCheckForObstacleEnrouteTo(detour, out newDetour, ref iterationCount)) {
                    D.Log(ShowDebugLog, "{0} found another obstacle on the way to detour {1}.", DebugName, detour.DebugName);
                    detour = newDetour;
                }
                return true;
            }
            return false;
        }
示例#4
0
 private bool TryGenerateDetourAroundObstacle(IAvoidableObstacle obstacle, RaycastHit zoneHitInfo, out IFleetNavigable detour) {
     detour = GenerateDetourAroundObstacle(obstacle, zoneHitInfo, _fleet.UnitMaxFormationRadius);
     if (obstacle.IsMobile) {
         Vector3 detourBearing = (detour.Position - Position).normalized;
         float reqdTurnAngleToDetour = Vector3.Angle(_fleetData.CurrentFlagshipFacing, detourBearing);
         if (reqdTurnAngleToDetour < DetourTurnAngleThreshold) {
             // Note: can't use a distance check here as Fleets don't check for obstacles based on time.
             // They only check when embarking on a new course leg
             //D.Log(ShowDebugLog, "{0} has declined to generate a detour around mobile obstacle {1}. Reqd Turn = {2:0.#} degrees.", DebugName, obstacle.DebugName, reqdTurnAngleToDetour);
             return false;
         }
     }
     return true;
 }
示例#5
0
 /// <summary>
 /// Attempts subscribing or unsubscribing to <c>fsmTgt</c> in the mode provided.
 /// Returns <c>true</c> if the indicated subscribe action was taken, <c>false</c> if not.
 /// <remarks>Issues a warning if attempting to create a duplicate subscription.</remarks>
 /// </summary>
 /// <param name="subscriptionMode">The subscription mode.</param>
 /// <param name="fsmTgt">The target used by the State Machine.</param>
 /// <param name="toSubscribe">if set to <c>true</c> subscribe, otherwise unsubscribe.</param>
 /// <returns></returns>
 /// <exception cref="NotImplementedException"></exception>
 protected bool __AttemptFsmTgtSubscriptionChg(FsmTgtEventSubscriptionMode subscriptionMode, IFleetNavigable fsmTgt, bool toSubscribe) {
     Utility.ValidateNotNull(fsmTgt);
     bool isSubscribeActionTaken = false;
     bool isDuplicateSubscriptionAttempted = false;
     IItem_Ltd itemFsmTgt = null;
     bool isSubscribed = __subscriptionStatusLookup[subscriptionMode];
     switch (subscriptionMode) {
         case FsmTgtEventSubscriptionMode.TargetDeath:
             var mortalFsmTgt = fsmTgt as IMortalItem_Ltd;
             if (mortalFsmTgt != null) {
                 if (!toSubscribe) {
                     mortalFsmTgt.deathOneShot -= FsmTargetDeathEventHandler;
                     isSubscribeActionTaken = true;
                 }
                 else if (!isSubscribed) {
                     mortalFsmTgt.deathOneShot += FsmTargetDeathEventHandler;
                     isSubscribeActionTaken = true;
                 }
                 else {
                     isDuplicateSubscriptionAttempted = true;
                 }
             }
             break;
         case FsmTgtEventSubscriptionMode.InfoAccessChg:
             itemFsmTgt = fsmTgt as IItem_Ltd;
             if (itemFsmTgt != null) {    // fsmTgt can be a StationaryLocation
                 if (!toSubscribe) {
                     itemFsmTgt.infoAccessChgd -= FsmTgtInfoAccessChgdEventHandler;
                     isSubscribeActionTaken = true;
                 }
                 else if (!isSubscribed) {
                     itemFsmTgt.infoAccessChgd += FsmTgtInfoAccessChgdEventHandler;
                     isSubscribeActionTaken = true;
                 }
                 else {
                     isDuplicateSubscriptionAttempted = true;
                 }
             }
             break;
         case FsmTgtEventSubscriptionMode.OwnerChg:
             itemFsmTgt = fsmTgt as IItem_Ltd;
             if (itemFsmTgt != null) {    // fsmTgt can be a StationaryLocation
                 if (!toSubscribe) {
                     itemFsmTgt.ownerChanged -= FsmTgtOwnerChgdEventHandler;
                     isSubscribeActionTaken = true;
                 }
                 else if (!isSubscribed) {
                     itemFsmTgt.ownerChanged += FsmTgtOwnerChgdEventHandler;
                     isSubscribeActionTaken = true;
                 }
                 else {
                     isDuplicateSubscriptionAttempted = true;
                 }
             }
             break;
         case FsmTgtEventSubscriptionMode.None:
         default:
             throw new NotImplementedException(ErrorMessages.UnanticipatedSwitchValue.Inject(subscriptionMode));
     }
     if (isDuplicateSubscriptionAttempted) {
         D.Warn("{0}: Attempting to subscribe to {1}'s {2} when already subscribed.", DebugName, fsmTgt.DebugName, subscriptionMode.GetValueName());
     }
     if (isSubscribeActionTaken) {
         __subscriptionStatusLookup[subscriptionMode] = toSubscribe;
     }
     return isSubscribeActionTaken;
 }
示例#6
0
    //private float CalcApMoveTgtStandoffDistance(IFleetNavigable moveTgt) {
    //    float standoffDistance = Constants.ZeroF;
    //    var baseTgt = moveTgt as AUnitBaseCmdItem;
    //    if (baseTgt != null) {
    //        // move target is a base
    //        if (Owner.IsEnemyOf(baseTgt.Owner)) {
    //            // its an enemy base
    //            standoffDistance = TempGameValues.__MaxBaseWeaponsRangeDistance;
    //        }
    //    }
    //    else {
    //        var fleetTgt = moveTgt as FleetCmdItem;
    //        if (fleetTgt != null) {
    //            // move target is a fleet
    //            if (Owner.IsEnemyOf(fleetTgt.Owner)) {
    //                // its an enemy fleet
    //                standoffDistance = TempGameValues.__MaxFleetWeaponsRangeDistance;
    //            }
    //        }
    //    }
    //    return standoffDistance;
    //}

    #endregion

    void ExecuteMoveOrder_UponPreconfigureState() {
        LogEvent();

        if (_fsmTgt != null) {
            D.Error("{0} _fsmMoveTgt {1} should not already be assigned.", DebugName, _fsmTgt.DebugName);
        }
        D.AssertDefault((int)_orderFailureCause, _orderFailureCause.GetValueName());
        D.AssertNotNull(CurrentOrder.Target);

        _fsmTgt = DetermineApMoveTarget(CurrentOrder);

        __AttemptFsmTgtSubscriptionChg(FsmTgtEventSubscriptionMode.TargetDeath, _fsmTgt, toSubscribe: true);
        __AttemptFsmTgtSubscriptionChg(FsmTgtEventSubscriptionMode.InfoAccessChg, _fsmTgt, toSubscribe: true);
        __AttemptFsmTgtSubscriptionChg(FsmTgtEventSubscriptionMode.OwnerChg, _fsmTgt, toSubscribe: true);
    }
示例#7
0
    void ExecuteJoinFleetOrder_ExitState() {
        LogEvent();

        bool isUnsubscribed = __AttemptFsmTgtSubscriptionChg(FsmTgtEventSubscriptionMode.TargetDeath, _fsmTgt, toSubscribe: false);
        D.Assert(isUnsubscribed);
        isUnsubscribed = __AttemptFsmTgtSubscriptionChg(FsmTgtEventSubscriptionMode.InfoAccessChg, _fsmTgt, toSubscribe: false);
        D.Assert(isUnsubscribed);
        isUnsubscribed = __AttemptFsmTgtSubscriptionChg(FsmTgtEventSubscriptionMode.OwnerChg, _fsmTgt, toSubscribe: false);
        D.Assert(isUnsubscribed);

        _fsmTgt = null;
        _orderFailureCause = UnitItemOrderFailureCause.None;
    }
示例#8
0
 void ExecuteAssumeFormationOrder_ExitState() {
     LogEvent();
     _fsmTgt = null;
     _orderFailureCause = UnitItemOrderFailureCause.None;
 }
示例#9
0
    void ExecuteGuardOrder_UponPreconfigureState() {
        LogEvent();

        if (_fsmTgt != null) {
            D.Error("{0} _fsmMoveTgt {1} should not already be assigned.", DebugName, _fsmTgt.DebugName);
        }
        D.AssertDefault((int)_orderFailureCause, _orderFailureCause.GetValueName());

        IGuardable guardableTgt = CurrentOrder.Target as IGuardable;
        D.AssertNotNull(guardableTgt); // Guardable targets are non-enemy owned Sectors, Systems, Planets, Bases and UCenter
        D.Assert(guardableTgt.IsGuardingAllowedBy(Owner));
        _fsmTgt = guardableTgt as IFleetNavigable;

        __AttemptFsmTgtSubscriptionChg(FsmTgtEventSubscriptionMode.TargetDeath, _fsmTgt, toSubscribe: true);
        bool isSubscribed = __AttemptFsmTgtSubscriptionChg(FsmTgtEventSubscriptionMode.InfoAccessChg, _fsmTgt, toSubscribe: true);
        D.Assert(isSubscribed);
        isSubscribed = __AttemptFsmTgtSubscriptionChg(FsmTgtEventSubscriptionMode.OwnerChg, _fsmTgt, toSubscribe: true);
        D.Assert(isSubscribed);
    }
示例#10
0
    void ExecuteJoinFleetOrder_UponPreconfigureState() {
        LogEvent();

        if (_fsmTgt != null) {
            D.Error("{0} _fsmMoveTgt {1} should not already be assigned.", DebugName, _fsmTgt.DebugName);
        }
        D.AssertDefault((int)_orderFailureCause, _orderFailureCause.GetValueName());

        var fleetToJoin = CurrentOrder.Target as FleetCmdItem;
        D.AssertNotNull(fleetToJoin);
        _fsmTgt = fleetToJoin;

        bool isSubscribed = __AttemptFsmTgtSubscriptionChg(FsmTgtEventSubscriptionMode.TargetDeath, _fsmTgt, toSubscribe: true);
        D.Assert(isSubscribed);
        isSubscribed = __AttemptFsmTgtSubscriptionChg(FsmTgtEventSubscriptionMode.InfoAccessChg, _fsmTgt, toSubscribe: true);
        D.Assert(isSubscribed);
        isSubscribed = __AttemptFsmTgtSubscriptionChg(FsmTgtEventSubscriptionMode.OwnerChg, _fsmTgt, toSubscribe: true);
        D.Assert(isSubscribed);
    }
示例#11
0
    void ExecuteExploreOrder_ExitState() {
        LogEvent();

        bool isUnsubscribed = __AttemptFsmTgtSubscriptionChg(FsmTgtEventSubscriptionMode.TargetDeath, _fsmTgt, toSubscribe: false);
        D.Assert(!isUnsubscribed);    // OPTIMIZE IFleetExplorable cannot die
        isUnsubscribed = __AttemptFsmTgtSubscriptionChg(FsmTgtEventSubscriptionMode.InfoAccessChg, _fsmTgt, toSubscribe: false);
        D.Assert(isUnsubscribed);
        isUnsubscribed = __AttemptFsmTgtSubscriptionChg(FsmTgtEventSubscriptionMode.OwnerChg, _fsmTgt, toSubscribe: false);
        D.Assert(isUnsubscribed);

        _fsmTgt = null;
        _shipSystemExploreTgtAssignments = null;
        _orderFailureCause = UnitItemOrderFailureCause.None;
    }
示例#12
0
    void ExecuteExploreOrder_UponPreconfigureState() {
        LogEvent();

        if (_fsmTgt != null) {
            D.Error("{0} _fsmMoveTgt {1} should not already be assigned.", DebugName, _fsmTgt.DebugName);
        }
        D.AssertDefault((int)_orderFailureCause, _orderFailureCause.GetValueName());

        IFleetExplorable fleetExploreTgt = CurrentOrder.Target as IFleetExplorable; // Fleet explorable targets are non-enemy owned sectors, systems and UCenter
        D.AssertNotNull(fleetExploreTgt);
        D.Assert(fleetExploreTgt.IsExploringAllowedBy(Owner));
        D.Assert(!fleetExploreTgt.IsFullyExploredBy(Owner));
        _fsmTgt = fleetExploreTgt;

        bool isSubscribed = __AttemptFsmTgtSubscriptionChg(FsmTgtEventSubscriptionMode.TargetDeath, _fsmTgt, toSubscribe: true);
        D.Assert(!isSubscribed);    // OPTIMIZE IFleetExplorable cannot die
        isSubscribed = __AttemptFsmTgtSubscriptionChg(FsmTgtEventSubscriptionMode.InfoAccessChg, _fsmTgt, toSubscribe: true);
        D.Assert(isSubscribed);
        isSubscribed = __AttemptFsmTgtSubscriptionChg(FsmTgtEventSubscriptionMode.OwnerChg, _fsmTgt, toSubscribe: true);
        D.Assert(isSubscribed);
    }
示例#13
0
    void ExecuteMoveOrder_ExitState() {
        LogEvent();

        __AttemptFsmTgtSubscriptionChg(FsmTgtEventSubscriptionMode.TargetDeath, _fsmTgt, toSubscribe: false);
        __AttemptFsmTgtSubscriptionChg(FsmTgtEventSubscriptionMode.InfoAccessChg, _fsmTgt, toSubscribe: false);
        __AttemptFsmTgtSubscriptionChg(FsmTgtEventSubscriptionMode.OwnerChg, _fsmTgt, toSubscribe: false);

        _fsmTgt = null;
        _orderFailureCause = UnitItemOrderFailureCause.None;
    }
示例#14
0
    void ExecuteAssumeFormationOrder_UponPreconfigureState() {
        LogEvent();

        if (_fsmTgt != null) {
            D.Error("{0} _fsmMoveTgt {1} should not already be assigned.", DebugName, _fsmTgt.DebugName);
        }
        D.AssertDefault((int)_orderFailureCause, _orderFailureCause.GetValueName());

        _fsmTgt = CurrentOrder.Target;
        // No reason to subscribe to _fsmTgt-related events as _fsmTgt is either StationaryLocation or null
    }
示例#15
0
 private void __ValidateKnowledgeOfOrderTarget(IFleetNavigable target, FleetDirective directive) {
     if (directive == FleetDirective.Retreat || directive == FleetDirective.Withdraw || directive == FleetDirective.Disband
         || directive == FleetDirective.Refit || directive == FleetDirective.Repair || directive == FleetDirective.StopAttack) {
         // directives aren't yet implemented
         return;
     }
     if (target is StarItem || target is SystemItem || target is UniverseCenterItem) {
         // unnecessary check as all players have knowledge of these targets
         return;
     }
     if (directive == FleetDirective.AssumeFormation) {
         D.Assert(target == null || target is StationaryLocation || target is MobileLocation);
         return;
     }
     if (directive == FleetDirective.Scuttle) {
         D.AssertNull(target);
         return;
     }
     if (target is ISector) {
         return; // IMPROVE currently PlayerKnowledge does not keep track of Sectors
     }
     if (!OwnerAIMgr.HasKnowledgeOf(target as IItem_Ltd)) {
         D.Error("{0} received {1} order with Target {2} that {3} has no knowledge of.", DebugName, directive.GetValueName(), target.DebugName, Owner.LeaderName);
     }
 }
示例#16
0
    IEnumerator ExecuteAssumeFormationOrder_EnterState() {
        LogEvent();

        if (_fsmTgt != null) {
            // a LocalAssyStation target was specified so move there together first
            D.Assert(_fsmTgt is StationaryLocation);

            _apMoveSpeed = Speed.Standard;
            _apMoveTgtStandoffDistance = Constants.ZeroF;

            Call(FleetState.Moving);
            yield return null;  // reqd so Return()s here

            if (_orderFailureCause != UnitItemOrderFailureCause.None) {
                switch (_orderFailureCause) {
                    case UnitItemOrderFailureCause.UnitItemNeedsRepair:
                        // TODO Initiate Fleet Repair and communicate failure to boss?
                        break;
                    case UnitItemOrderFailureCause.UnitItemDeath:
                        // TODO Communicate failure to boss?
                        break;
                    case UnitItemOrderFailureCause.TgtDeath:
                    case UnitItemOrderFailureCause.TgtUncatchable:
                    case UnitItemOrderFailureCause.TgtRelationship:
                    case UnitItemOrderFailureCause.TgtUnreachable:
                    case UnitItemOrderFailureCause.None:
                    default:
                        throw new NotImplementedException(ErrorMessages.UnanticipatedSwitchValue.Inject(_orderFailureCause));
                }
                yield return null;
            }

            // If there was a failure generated by Moving, resulting new Orders or Dead state should keep this point from being reached
            D.AssertDefault((int)_orderFailureCause, _orderFailureCause.GetValueName());
            _fsmTgt = null; // only used to Move to the target if any
        }

        Call(FleetState.AssumingFormation);
        yield return null;

        if (_orderFailureCause != UnitItemOrderFailureCause.None) {
            switch (_orderFailureCause) {
                case UnitItemOrderFailureCause.UnitItemNeedsRepair:
                    // TODO Initiate Fleet Repair and communicate failure to boss?
                    break;
                case UnitItemOrderFailureCause.UnitItemDeath:
                    // TODO Communicate failure to boss?
                    break;
                case UnitItemOrderFailureCause.TgtDeath:
                case UnitItemOrderFailureCause.TgtRelationship:
                case UnitItemOrderFailureCause.TgtUncatchable:
                case UnitItemOrderFailureCause.TgtUnreachable:
                case UnitItemOrderFailureCause.None:
                default:
                    throw new NotImplementedException(ErrorMessages.UnanticipatedSwitchValue.Inject(_orderFailureCause));
            }
            yield return null;
        }

        // If there was a failure generated by AssumingFormation, resulting new Orders or Dead state should keep this point from being reached
        D.AssertDefault((int)_orderFailureCause, _orderFailureCause.GetValueName());

        CurrentState = FleetState.Idling;
    }
示例#17
0
        /// <summary>
        /// Plots the course to the target and notifies the requester of the outcome via the onCoursePlotSuccess or Failure events.
        /// </summary>
        /// <param name="apTgt">The target this AutoPilot is being engaged to reach.</param>
        /// <param name="apSpeed">The speed the autopilot should travel at.</param>
        /// <param name="apTgtStandoffDistance">The target standoff distance.</param>
        internal void PlotPilotCourse(IFleetNavigable apTgt, Speed apSpeed, float apTgtStandoffDistance) {
            Utility.ValidateNotNull(apTgt);
            D.Assert(!InvalidApSpeeds.Contains(apSpeed), apSpeed.GetValueName());
            ApTarget = apTgt;
            ApSpeedSetting = apSpeed;
            _apTgtStandoffDistance = apTgtStandoffDistance;

            IList<Vector3> directCourse;
            if (TryDirectCourse(out directCourse)) {
                // use this direct course
                //D.Log(ShowDebugLog, "{0} will use a direct course to {1}.", DebugName, ApTarget.DebugName);
                _isApCourseFromPath = false;
                ConstructApCourse(directCourse);
                HandleApCoursePlotSuccess();
            }
            else {
                _isApCourseFromPath = true;
                ResetPathReplotValues();
                PlotPath();
            }
        }
示例#18
0
    private void GetApMoveOrderSettings(FleetOrder moveOrder, out IFleetNavigable apMoveTgt, out Speed apMoveSpeed, out float apMoveTgtStandoffDistance) {
        D.Assert(moveOrder.Directive == FleetDirective.Move || moveOrder.Directive == FleetDirective.FullSpeedMove);

        // Determine move speed
        apMoveSpeed = moveOrder.Directive == FleetDirective.FullSpeedMove ? Speed.Full : Speed.Standard;

        // Determine move target
        IFleetNavigable moveTgt = null;
        IFleetNavigable moveOrderTgt = moveOrder.Target;
        ISystem_Ltd systemMoveTgt = moveOrderTgt as ISystem_Ltd;
        if (systemMoveTgt != null) {
            // move target is a system
            if (Topography == Topography.System) {
                // fleet is currently in a system
                ISector_Ltd fleetSector = SectorGrid.Instance.GetSectorContaining(Position);
                ISystem_Ltd fleetSystem = fleetSector.System;
                if (fleetSystem == systemMoveTgt) {
                    // move target of a system from inside the same system is the closest assembly station within that system
                    moveTgt = GameUtility.GetClosest(Position, systemMoveTgt.LocalAssemblyStations);
                }
            }
        }
        else {
            ISector_Ltd sectorMoveTgt = moveOrderTgt as ISector_Ltd;
            if (sectorMoveTgt != null) {
                // target is a sector
                ISector_Ltd fleetSector = SectorGrid.Instance.GetSectorContaining(Position);
                if (fleetSector == sectorMoveTgt) {
                    // move target of a sector from inside the same sector is the closest assembly station within that sector
                    moveTgt = GameUtility.GetClosest(Position, sectorMoveTgt.LocalAssemblyStations);
                }
            }
        }
        if (moveTgt == null) {
            moveTgt = moveOrderTgt;
        }
        apMoveTgt = moveTgt;

        // Determine move target standoff distance
        apMoveTgtStandoffDistance = CalcApMoveTgtStandoffDistance(moveOrderTgt);
    }
示例#19
0
 /// <summary>
 /// Checks for an obstacle en-route to the provided <c>destination</c>. Returns true if one
 /// is found that requires immediate action and provides the detour to avoid it, false otherwise.
 /// </summary>
 /// <param name="destination">The current destination. May be the ApTarget or an obstacle detour.</param>
 /// <param name="detour">The obstacle detour.</param>
 /// <returns>
 ///   <c>true</c> if an obstacle was found and a detour generated, false if the way is effectively clear.
 /// </returns>
 private bool TryCheckForObstacleEnrouteTo(IFleetNavigable destination, out IFleetNavigable detour) {
     int iterationCount = Constants.Zero;
     return TryCheckForObstacleEnrouteTo(destination, out detour, ref iterationCount);
 }
示例#20
0
 /// <summary>
 /// Initializes a new instance of the <see cref="FleetOrder" /> class.
 /// </summary>
 /// <param name="directive">The order directive.</param>
 /// <param name="source">The source of this order.</param>
 /// <param name="target">The target of this order. Default is null.</param>
 public FleetOrder(FleetDirective directive, OrderSource source, IFleetNavigable target = null) {
     D.AssertNotEqual(OrderSource.Captain, source);
     Directive = directive;
     Source = source;
     Target = target;
 }
示例#21
0
 /// <summary>
 /// Gets the standoff distance for the provided moveTgt. 
 /// </summary>
 /// <param name="moveTgt">The move target.</param>
 /// <returns></returns>
 private float CalcApMoveTgtStandoffDistance(IFleetNavigable moveTgt) {
     float standoffDistance = Constants.ZeroF;
     Player moveTgtOwner;
     var baseTgt = moveTgt as IUnitBaseCmd_Ltd;
     if (baseTgt != null) {
         // move target is a base
         if (baseTgt.TryGetOwner(Owner, out moveTgtOwner)) {
             if (Owner.IsEnemyOf(moveTgtOwner)) {
                 // its an enemy base
                 standoffDistance = TempGameValues.__MaxBaseWeaponsRangeDistance;
             }
         }
     }
     else {
         var fleetTgt = moveTgt as IFleetCmd_Ltd;
         if (fleetTgt != null) {
             // move target is a fleet
             if (fleetTgt.TryGetOwner(Owner, out moveTgtOwner)) {
                 if (Owner.IsEnemyOf(moveTgtOwner)) {
                     // its an enemy fleet
                     standoffDistance = TempGameValues.__MaxFleetWeaponsRangeDistance;
                 }
             }
         }
     }
     return standoffDistance;
 }