コード例 #1
0
 /// <summary>
 /// Handles the results of the facility's attempt to execute the provided directive.
 /// </summary>
 /// <param name="directive">The directive.</param>
 /// <param name="facility">The facility.</param>
 /// <param name="isSuccess">if set to <c>true</c> the directive was successfully completed. May still be ongoing.</param>
 /// <param name="target">The target. Can be null.</param>
 /// <param name="failCause">The failure cause if not successful.</param>
 internal void HandleOrderOutcome(FacilityDirective directive, FacilityItem facility, bool isSuccess, IElementAttackable target = null, UnitItemOrderFailureCause failCause = UnitItemOrderFailureCause.None) {
     UponOrderOutcome(directive, facility, isSuccess, target, failCause);
 }
コード例 #2
0
 private void UponOrderOutcome(FacilityDirective directive, FacilityItem facility, bool isSuccess, IElementAttackable target, UnitItemOrderFailureCause failCause) {
     RelayToCurrentState(directive, facility, isSuccess, target, failCause);
 }
コード例 #3
0
ファイル: FleetCmdItem.cs プロジェクト: Maxii/CodeEnv.Master
    void AssumingFormation_UponOrderOutcome(ShipDirective directive, ShipItem ship, bool isSuccess, IShipNavigable target, UnitItemOrderFailureCause failCause) {
        LogEvent();
        if (directive != ShipDirective.AssumeStation) {
            D.Warn("{0} State {1} erroneously received OrderOutcome callback with {2} {3}.", DebugName, CurrentState.GetValueName(), typeof(ShipDirective).Name, directive.GetValueName());
            return;
        }

        D.AssertNull(target);
        if (isSuccess) {
            _fsmShipWaitForOnStationCount--;
        }
        else {
            switch (failCause) {
                case UnitItemOrderFailureCause.UnitItemNeedsRepair:
                    // Ship will get repaired, but even if it goes to its formationStation to do so
                    // it won't communicate its success back to Cmd since Captain ordered it, not Cmd
                    _fsmShipWaitForOnStationCount--;
                    break;
                case UnitItemOrderFailureCause.UnitItemDeath:
                    _fsmShipWaitForOnStationCount--;
                    break;
                case UnitItemOrderFailureCause.TgtDeath:
                case UnitItemOrderFailureCause.TgtRelationship:
                case UnitItemOrderFailureCause.TgtUncatchable:
                case UnitItemOrderFailureCause.TgtUnreachable:
                case UnitItemOrderFailureCause.None:
                default:
                    throw new NotImplementedException(ErrorMessages.UnanticipatedSwitchValue.Inject(failCause));
            }
        }
        if (_fsmShipWaitForOnStationCount == Constants.Zero) {
            Return();
        }
    }
コード例 #4
0
 protected void ExecuteAttackOrder_UponOrderOutcome(FacilityDirective directive, FacilityItem facility, bool isSuccess, IElementAttackable target, UnitItemOrderFailureCause failCause) {
     LogEvent();
     if (directive != FacilityDirective.Attack) {
         D.Warn("{0} State {1} erroneously received OrderOutcome callback with {2} {3}.", DebugName, CurrentState.GetValueName(), typeof(FacilityDirective).Name, directive.GetValueName());
         return;
     }
     // TODO What? It will be common for an attack by a facility to fail for cause unreachable as its target moves out of range...
 }
コード例 #5
0
ファイル: FleetCmdItem.cs プロジェクト: Maxii/CodeEnv.Master
 /// <summary>
 /// Evaluates whether the current Moving state should be reassessed by Return()ing
 /// it to the state that Call()ed it with an OrderFailureCause.
 /// <remarks>This method should only be called when the owner of _fsmTgt is known.
 /// There is no point in doing the evaluation if the owner is not known as it is
 /// ALWAYS OK to move to a target if the owner is unknown.</remarks>
 /// </summary>
 /// <param name="failCause">The resulting fail cause.</param>
 /// <param name="__isFsmInfoAccessChgd">if set to <c>true</c> [is FSM info access CHGD]. IMPROVE</param>
 /// <returns></returns>
 /// <exception cref="System.NotImplementedException"></exception>
 /// <exception cref="NotImplementedException"></exception>
 private bool ShouldMovingBeReassessed(out UnitItemOrderFailureCause failCause, bool __isFsmInfoAccessChgd) {
     bool toReassessMoving = false;
     UnitItemOrderFailureCause failureCause = UnitItemOrderFailureCause.None;
     switch (LastState) {
         case FleetState.ExecuteExploreOrder:
             IFleetExplorable fleetExploreTgt = _fsmTgt as IFleetExplorable;
             if (!fleetExploreTgt.IsExploringAllowedBy(Owner)) {
                 // Owner exposure or relations change caused a loss of explore rights
                 failureCause = UnitItemOrderFailureCause.TgtRelationship;
                 toReassessMoving = true;
             }
             if (fleetExploreTgt.IsFullyExploredBy(Owner)) {
                 // last remaining ship explore target was explored by another fleet's ship owned by us
                 // OR a relations change to Ally instantly made target fully explored
                 failureCause = UnitItemOrderFailureCause.TgtRelationship;
                 toReassessMoving = true;
             }
             break;
         case FleetState.ExecutePatrolOrder:
             IPatrollable patrolTgt = _fsmTgt as IPatrollable;
             if (!patrolTgt.IsPatrollingAllowedBy(Owner)) {
                 failureCause = UnitItemOrderFailureCause.TgtRelationship;
                 toReassessMoving = true;
             }
             break;
         case FleetState.ExecuteGuardOrder:
             IGuardable guardTgt = _fsmTgt as IGuardable;
             if (!guardTgt.IsGuardingAllowedBy(Owner)) {
                 failureCause = UnitItemOrderFailureCause.TgtRelationship;
                 toReassessMoving = true;
             }
             break;
         case FleetState.ExecuteAttackOrder:
             IUnitAttackable unitAttackTgt = _fsmTgt as IUnitAttackable;
             if (__isFsmInfoAccessChgd) {
                 if (!unitAttackTgt.IsAttackByAllowed(Owner)) {
                     failureCause = UnitItemOrderFailureCause.TgtRelationship;
                     toReassessMoving = true;
                 }
             }
             else {
                 // If fsmOwner changed, then should not continue attack unless we are at War with new owner.
                 // If fsmOwner relationship changed, then should not continue attack unless new relationship is War
                 // Attack currently underway could have been on a ColdWar opponent.
                 if (!unitAttackTgt.IsWarAttackByAllowed(Owner)) {
                     failureCause = UnitItemOrderFailureCause.TgtRelationship;
                     toReassessMoving = true;
                 }
             }
             break;
         case FleetState.ExecuteMoveOrder:
             var unitCmdMoveTgt = _fsmTgt as IUnitCmd_Ltd;
             if (unitCmdMoveTgt != null) {   // as this is about standoff distance, only Units have weapons
                 Player unitCmdMoveTgtOwner;
                 bool haveOwnerAccess = unitCmdMoveTgt.TryGetOwner(Owner, out unitCmdMoveTgtOwner);
                 if (!haveOwnerAccess) {
                     D.Error("{0}.ShouldMovingBeReassessed() should not be called without Owner access.", DebugName);
                 }
                 // moving to fleet or base owned by player whose relations with us have changed, or whose ownership of _fsmTgt just became known
                 if (Owner.IsEnemyOf(unitCmdMoveTgtOwner)) {
                     // now known as an enemy
                     if (!Owner.IsPreviouslyEnemyOf(unitCmdMoveTgtOwner)) {
                         // definitely reassess as changed from non-enemy to enemy
                         failureCause = UnitItemOrderFailureCause.TgtRelationship;
                         toReassessMoving = true;
                     }
                     // else no need to reassess as no change in being an enemy
                 }
                 else {
                     // now known as not an enemy
                     if (Owner.IsPreviouslyEnemyOf(unitCmdMoveTgtOwner)) {
                         // changed from enemy to non-enemy so reassess as StandoffDistance can be shortened
                         failureCause = UnitItemOrderFailureCause.TgtRelationship;
                         toReassessMoving = true;
                     }
                 }
             }
             // Could also be moving to 1) an AssemblyStation from within a System or Sector, 2) a System or Sector
             // from outside, 3) a Planet, Star or UniverseCenter. Since none of these can fire on us, no reason to worry
             // about recalculating StandoffDistance.
             break;
         case FleetState.ExecuteJoinFleetOrder:
             // UNCLEAR an owner chg in our target Fleet (_fsmTgt) would show up here?
             IFleetCmd_Ltd tgtFleet = _fsmTgt as IFleetCmd_Ltd;
             if (tgtFleet.IsOwnerAccessibleTo(Owner)) {
                 Player tgtFleetOwner;
                 bool isAccessible = tgtFleet.TryGetOwner(Owner, out tgtFleetOwner);
                 D.Assert(isAccessible);
                 if (tgtFleetOwner == Owner) {
                     // target fleet owner is still us
                     break;
                 }
             }
             // owner is no longer us
             failureCause = UnitItemOrderFailureCause.TgtRelationship;
             toReassessMoving = true;
             break;
         case FleetState.ExecuteAssumeFormationOrder:
         // shouldn't be possible
         case FleetState.Guarding:
         case FleetState.Patrolling:
         case FleetState.Moving:
         case FleetState.AssumingFormation:
         case FleetState.Idling:
         case FleetState.Dead:
         // doesn't Call() Moving
         case FleetState.Entrenching:
         case FleetState.GoRepair:
         case FleetState.Repairing:
         case FleetState.GoRefit:
         case FleetState.Refitting:
         case FleetState.GoRetreat:
         case FleetState.GoDisband:
         case FleetState.Disbanding:
         // not yet implemented
         case FleetState.None:
         default:
             throw new NotImplementedException(ErrorMessages.UnanticipatedSwitchValue.Inject(LastState));
     }
     if (ShowDebugLog) {
         //string resultMsg = toReassessMoving ? "true, FailCause = {0}".Inject(failureCause.GetValueName()) : "false";
         //D.Log("{0}.ShouldMovingBeReassessed() called. LastState = {1}, Result = {2}.", DebugName, LastState.GetValueName(), resultMsg);
     }
     failCause = failureCause;
     return toReassessMoving;
 }
コード例 #6
0
ファイル: FleetCmdItem.cs プロジェクト: Maxii/CodeEnv.Master
 private void UponOrderOutcome(ShipDirective directive, ShipItem ship, bool isSuccess, IShipNavigable target = null, UnitItemOrderFailureCause failCause = UnitItemOrderFailureCause.None) {
     RelayToCurrentState(directive, ship, isSuccess, target, failCause);
 }
コード例 #7
0
ファイル: FleetCmdItem.cs プロジェクト: Maxii/CodeEnv.Master
 /// <summary>
 /// Handles the results of the ship's attempt to execute the provided directive.
 /// </summary>
 /// <param name="directive">The directive.</param>
 /// <param name="ship">The ship.</param>
 /// <param name="isSuccess">if set to <c>true</c> the directive was successfully completed. May still be ongoing.</param>
 /// <param name="target">The target. Can be null.</param>
 /// <param name="failCause">The failure cause if not successful.</param>
 internal void HandleOrderOutcome(ShipDirective directive, ShipItem ship, bool isSuccess, IShipNavigable target = null, UnitItemOrderFailureCause failCause = UnitItemOrderFailureCause.None) {
     UponOrderOutcome(directive, ship, isSuccess, target, failCause);
 }
コード例 #8
0
ファイル: FleetCmdItem.cs プロジェクト: Maxii/CodeEnv.Master
 void ExecuteAttackOrder_UponOrderOutcome(ShipDirective directive, ShipItem ship, bool isSuccess, IShipNavigable target, UnitItemOrderFailureCause failCause) {
     LogEvent();
     if (directive != ShipDirective.Attack) {
         D.Warn("{0} State {1} erroneously received OrderOutcome callback with {2} {3}.", DebugName, CurrentState.GetValueName(), typeof(ShipDirective).Name, directive.GetValueName());
         return;
     }
     // TODO keep track of results to make better resulting decisions about what to do as battle rages
     // IShipAttackable attackedTgt = target as IShipAttackable;    // target can be null if ship failed and didn't have a target: Disengaged...
 }
コード例 #9
0
ファイル: FleetCmdItem.cs プロジェクト: Maxii/CodeEnv.Master
    void ExecuteExploreOrder_UponOrderOutcome(ShipDirective directive, ShipItem ship, bool isSuccess, IShipNavigable target,
        UnitItemOrderFailureCause failCause) {
        LogEvent();
        if (directive != ShipDirective.Explore) {
            D.Warn("{0} State {1} erroneously received OrderOutcome callback with {2} {3}.", DebugName, CurrentState.GetValueName(), typeof(ShipDirective).Name, directive.GetValueName());
            return;
        }

        IShipExplorable shipExploreTgt = target as IShipExplorable;
        D.AssertNotNull(shipExploreTgt);

        bool issueFleetRecall = false;
        if (IsShipExploreTargetPartOfSystem(shipExploreTgt)) {
            // exploreTgt is a planet or star
            D.Assert(_shipSystemExploreTgtAssignments.ContainsKey(shipExploreTgt));
            if (isSuccess) {
                HandleSystemTargetExploredOrDead(ship, shipExploreTgt);
            }
            else {
                bool isNewShipAssigned;
                bool testForAdditionalExploringShips = false;
                switch (failCause) {
                    case UnitItemOrderFailureCause.TgtRelationship:
                        // exploration failed so recall all ships
                        issueFleetRecall = true;
                        break;
                    case UnitItemOrderFailureCause.TgtDeath:
                        HandleSystemTargetExploredOrDead(ship, shipExploreTgt);
                        // This is effectively counted as a success and will show up during the _EnterState's
                        // continuous test System.IsFullyExplored. As not really a failure, no reason to issue a fleet recall.
                        break;
                    case UnitItemOrderFailureCause.UnitItemNeedsRepair:
                        isNewShipAssigned = HandleShipNoLongerAvailableToExplore(ship, shipExploreTgt);
                        if (!isNewShipAssigned) {
                            if (Elements.Count > 1) {
                                // This is not the last ship in the fleet, but the others aren't available. Since it usually takes 
                                // more than one ship to explore a System, the other ships might currently be exploring
                                testForAdditionalExploringShips = true;
                            }
                            else {
                                D.AssertEqual(Constants.One, Elements.Count);
                                // Damaged ship is only one left in fleet and it can't explore so exploration failed
                                issueFleetRecall = true;
                            }
                        }
                        break;
                    case UnitItemOrderFailureCause.UnitItemDeath:
                        isNewShipAssigned = HandleShipNoLongerAvailableToExplore(ship, shipExploreTgt);
                        if (!isNewShipAssigned) {
                            if (Elements.Count > 1) {    // >1 as dead ship has not yet been removed from fleet
                                                         // This is not the last ship in the fleet, but the others aren't available. Since it usually takes 
                                                         // more than one ship to explore a System, the other ships might currently be exploring
                                testForAdditionalExploringShips = true;
                            }
                            else {
                                D.AssertEqual(Constants.One, Elements.Count);  // dead ship has not yet been removed from fleet
                                // Do nothing as Unit is about to die
                            }
                        }
                        break;
                    case UnitItemOrderFailureCause.TgtUncatchable:
                    case UnitItemOrderFailureCause.TgtUnreachable:
                    case UnitItemOrderFailureCause.None:
                    default:
                        throw new NotImplementedException(ErrorMessages.UnanticipatedSwitchValue.Inject(failCause));
                }

                if (testForAdditionalExploringShips) {
                    var otherShipsCurrentlyExploring = Elements.Cast<ShipItem>().Except(ship).Where(s => s.IsCurrentOrderDirectiveAnyOf(ShipDirective.Explore));
                    if (otherShipsCurrentlyExploring.Any()) {
                        // Do nothing as there are other ships currently exploring so exploreTarget will eventually be assigned a ship
                    }
                    else {
                        // There are no remaining ships out exploring -> the exploration attempt has failed so issue recall
                        issueFleetRecall = true;
                    }
                }
            }
        }
        else {
            // exploreTgt is UCenter
            D.Assert(shipExploreTgt is UniverseCenterItem);
            if (isSuccess) {
                // exploration of UCenter has successfully completed so issue fleet recall
                issueFleetRecall = true;
            }
            else {
                bool isNewShipAssigned;
                switch (failCause) {
                    case UnitItemOrderFailureCause.UnitItemNeedsRepair:
                        isNewShipAssigned = HandleShipNoLongerAvailableToExplore(ship, shipExploreTgt);
                        if (!isNewShipAssigned) {
                            // No more ships are available to finish UCenter explore. Since it only takes one ship
                            // to explore UCenter, the other ships, if any, can't currently be exploring, so no reason to wait for them
                            // to complete their exploration. -> the exploration attempt has failed so issue recall
                            issueFleetRecall = true;
                        }
                        break;
                    case UnitItemOrderFailureCause.UnitItemDeath:
                        isNewShipAssigned = HandleShipNoLongerAvailableToExplore(ship, shipExploreTgt);
                        if (!isNewShipAssigned) {
                            if (Elements.Count > 1) {    // >1 as dead ship has not yet been removed from fleet
                                                         // This is not the last ship in the fleet, but the others aren't available. Since it only takes one ship
                                                         // to explore UCenter, the other ships can't currently be exploring, so no reason to wait for them
                                                         // to complete their exploration. -> the exploration attempt has failed so issue recall
                                issueFleetRecall = true;
                            }
                            else {
                                D.AssertEqual(Constants.One, Elements.Count);  // dead ship has not yet been removed from fleet
                                // Do nothing as Unit is about to die
                            }
                        }
                        break;
                    case UnitItemOrderFailureCause.TgtDeath:
                    case UnitItemOrderFailureCause.TgtRelationship:
                    case UnitItemOrderFailureCause.TgtUncatchable:
                    case UnitItemOrderFailureCause.TgtUnreachable:
                    case UnitItemOrderFailureCause.None:
                    default:
                        throw new NotImplementedException(ErrorMessages.UnanticipatedSwitchValue.Inject(failCause));
                }
            }
        }
        if (issueFleetRecall) {
            IFleetExplorable fleetExploreTgt = CurrentOrder.Target as IFleetExplorable;
            var closestLocalAssyStation = GameUtility.GetClosest(Position, fleetExploreTgt.LocalAssemblyStations);
            CurrentOrder = new FleetOrder(FleetDirective.AssumeFormation, OrderSource.CmdStaff, closestLocalAssyStation);
        }
    }