public IEnumerator HasCompletedObjective(ObjectiveScript script) { //reset the script's completed state script.Reset(); script.CheckIfCompleted(); //wait for the script to finish checking while (!script.FinishedChecking) { yield return(null); } //add completed state to objective's completed state //TryToComplete will automatically break if State.Completed returns false State.Completed &= script.HasCompleted; if (script.Status != MissionStatus.Dormant) { State.Status |= script.Status; } yield break; }
public IEnumerator TryToComplete() { //have we already completed? bool checkThisObjective = true; //toggling objectives is buggy at the moment //and we don't have any missions that use them //so skip this for now // if (State.Completed) { // switch (State.Behavior) { // case ObjectiveBehavior.Permanent: // //don't bother to check for completion // //we're permanently complete // checkThisObjective = false; // break; // // case ObjectiveBehavior.Toggle: // default: // //yup, check every time // break; // } // } if (!Flags.Check((uint)State.Status, (uint)MissionStatus.Active, Flags.CheckType.MatchAny)) { //Debug.Log ("Objective " + State.Name + " status doesn't have Active, not checking objective"); //if the objective isn't active yet then don't check checkThisObjective = false; } //are we supposed to check THIS objective? if so do it now //otherwise we've already completed - return true if (checkThisObjective) //check each objective script //reset this objective's completed state { State.ResetCompleted(); bool thisObjectiveCompleted = true; //this is used for scripts that complete and don't require all bool completedOverride = false; for (int i = 0; i < State.Scripts.Count; i++) { ObjectiveScript script = State.Scripts [i]; var hasCompletedObjective = HasCompletedObjective(script); while (hasCompletedObjective.MoveNext()) { yield return(hasCompletedObjective.Current); } //if the script has completed AND it doesn't require all other scripts thisObjectiveCompleted &= script.HasCompleted; if (script.HasCompleted && !script.RequiresAll) //then this objective is automatically completed regardless of the state of other scripts { completedOverride = true; } } //ok we've checked all the scripts //now apply the completed override State.Completed = thisObjectiveCompleted | completedOverride; if (State.Completed) { State.Status &= ~MissionStatus.Active; } } //check next objectives now foreach (MissionObjective nextObjective in NextObjectives) { //see if the objective should be active but isn't //(usually happens in the case of 'ignore objective') if (!Flags.Check((uint)nextObjective.State.Status, (uint)MissionStatus.Active, Flags.CheckType.MatchAny) && nextObjective.State.Activation == ObjectiveActivation.AutomaticOnPreviousCompletion && State.Completed) { //wrap this in a try/catch because we don't want random stuff listening for avatar actions to screw us up nextObjective.ActivateObjective(ObjectiveActivation.AutomaticOnPreviousCompletion, MissionOriginType.Mission, string.Empty); } //this will automatically set mission.State.ObjectivesCompleted var tryToComplete = nextObjective.TryToComplete(); while (tryToComplete.MoveNext()) { yield return(tryToComplete.Current); } } if (!checkThisObjective) { //if we're not checking this objective then we're done yield break; } //alright we're checking whether we've completed //check to see whether this results in failure if (State.Completed) { State.TimeCompleted = WorldClock.AdjustedRealTime; //the mission objective is complete! yay! //now check for success or failure switch (State.Type) { case ObjectiveType.Optional: //if the objective type is optional //then it doesn't matter what the result was //don't add our Status because it might contain a failure status //so just add Completed instead mission.State.Status |= MissionStatus.Completed; break; case ObjectiveType.Required: //if the objective type is required //then failure results in a failed mission //our Status already contains a failure status //so just add that mission.State.Status |= State.Status; break; case ObjectiveType.RequiredOnceActive: //if the objective is only required once active //first check to see if it's active if (Flags.Check((uint)State.Status, (uint)MissionStatus.Active, Flags.CheckType.MatchAny)) { //if it's not, just add completed mission.State.Status |= MissionStatus.Completed; } else { //if it is active, add Status mission.State.Status |= State.Status; } break; } //now check whether we've failed or succeeded if (Flags.Check((uint)State.Status, (uint)MissionStatus.Failed, Flags.CheckType.MatchAny) && !State.HasAnnouncedFailure) { Player.Get.AvatarActions.ReceiveAction((AvatarAction.MissionObjectiveFail), WorldClock.AdjustedRealTime); Player.Get.AvatarActions.ReceiveAction((AvatarAction.MissionUpdated), WorldClock.AdjustedRealTime); if (!string.IsNullOrEmpty(State.IntrospectionOnFail)) { GUIManager.PostIntrospection(State.IntrospectionOnFail); } if (State.Hidden) { GUIManager.PostDanger("Objective failed: " + State.Name); } State.HasAnnouncedFailure = true; } else if (!State.HasAnnouncedCompletion) { Player.Get.AvatarActions.ReceiveAction((AvatarAction.MissionObjectiveComplete), WorldClock.AdjustedRealTime); Player.Get.AvatarActions.ReceiveAction((AvatarAction.MissionUpdated), WorldClock.AdjustedRealTime); if (!string.IsNullOrEmpty(State.IntrospectionOnComplete)) { GUIManager.PostIntrospection(State.IntrospectionOnComplete); } if (!State.Hidden) { GUIManager.PostSuccess("Objective complete: " + State.Name); } State.HasAnnouncedCompletion = true; } //finally, activate next objectives foreach (MissionObjective nextObjective in NextObjectives) { if (nextObjective.State.Activation == ObjectiveActivation.AutomaticOnPreviousCompletion) { nextObjective.ActivateObjective(ObjectiveActivation.AutomaticOnPreviousCompletion, MissionOriginType.None, string.Empty); } } } //add our status to the mission status mission.State.Status |= State.Status; yield break; }