void SetPointerToUpdated() { //Pointer.SetStatus(POINTERSTATUS.TASKUPDATED); switch (GENERAL.AUTHORITY) { case AUTHORITY.GLOBAL: // case SCOPE.SOLO: // we're the global server or running solo so we can trigger the pointer. regardless of the task's scope. Pointer.SetStatus(POINTERSTATUS.TASKUPDATED); break; case AUTHORITY.LOCAL: // we're a local client. only if the task is local do we trigger the pointer. if (scope == SCOPE.LOCAL) { Pointer.SetStatus(POINTERSTATUS.TASKUPDATED); } break; default: break; } }
void moveToNextPoint(StoryPointer thePointer) { if (!thePointer.ProgressToNextPoint()) { Warning("Error: killing pointer "); thePointer.SetStatus(POINTERSTATUS.KILLED); pointerStack.RemoveAt(0); } }
void Update() { #if !SOLO // Handle story updates, aiming for 1 per frame, assuming we're tyring to run in sync. // Lowest numbers are oldest. int UpdateCount = StoryUpdateStack.Count; switch (UpdateCount) { case 0: BufferStatusIn = 0; break; case 1: // exactly one, so apply. ApplyStoryUpdate(StoryUpdateStack[0]); StoryUpdateStack.RemoveAt(0); BufferStatusIn = 1; break; case 2: // Two, normally for different frames that happened to arrive in the same frame on this end. // Apply the oldest one, keep the other because we exact 0 updates during our next frame. ApplyStoryUpdate(StoryUpdateStack[0]); StoryUpdateStack.RemoveAt(0); BufferStatusIn = 1; break; default: // More than 2. Apply all the older ones in order of arrival, keep latest one. Warning("Update buffer >2"); BufferStatusIn = 2; while (StoryUpdateStack.Count > 1) { ApplyStoryUpdate(StoryUpdateStack[0]); StoryUpdateStack.RemoveAt(0); } break; } #endif switch (theDirector.status) { case DIRECTORSTATUS.ACTIVE: // Verbose("Director active ."); foreach (StoryTask task in GENERAL.ALLTASKS) { if (task.getCallBack() != "") { // if a callback was set (somewhere on the network) we act on it only if we are the server or if the task is local. if (GENERAL.AUTHORITY == AUTHORITY.GLOBAL || task.scope == SCOPE.LOCAL) { task.Pointer.SetStatus(POINTERSTATUS.TASKUPDATED); } } } theDirector.EvaluatePointers(); List <StoryTask> newTasks = new List <StoryTask>(); for (int p = 0; p < GENERAL.ALLPOINTERS.Count; p++) { StoryPointer pointer = GENERAL.ALLPOINTERS[p]; switch (pointer.scope) { case SCOPE.GLOBAL: // If pointer scope is global, we add a task if our own scope is global as well. (If our scope is local, we'll be receiving the task over the network) if (GENERAL.AUTHORITY == AUTHORITY.GLOBAL) { if (pointer.GetStatus() == POINTERSTATUS.NEWTASK) { pointer.SetStatus(POINTERSTATUS.PAUSED); StoryTask task = new StoryTask(pointer, SCOPE.GLOBAL); task.LoadPersistantData(pointer); newTasks.Add(task); task.modified = true; Verbose("Created global task " + task.Instruction + " for pointer " + pointer.currentPoint.StoryLine); } } break; case SCOPE.LOCAL: default: // If pointer scope is local, check if new tasks have to be generated. if (pointer.GetStatus() == POINTERSTATUS.NEWTASK) { pointer.SetStatus(POINTERSTATUS.PAUSED); StoryTask task = new StoryTask(pointer, SCOPE.LOCAL); task.LoadPersistantData(pointer); newTasks.Add(task); Verbose("Created local task " + task.Instruction + " for pointer " + pointer.currentPoint.StoryLine); } break; } } if (newTasks.Count > 0) { DistributeTasks(new TaskArgs(newTasks)); // if any new tasks call an event, passing on the list of tasks to any handlers listening } break; case DIRECTORSTATUS.READY: GENERAL.SIGNOFFS = eventHandlerCount(); if (GENERAL.SIGNOFFS == 0) { Error("No handlers registred. Pausing director."); theDirector.status = DIRECTORSTATUS.PAUSED; } else { Verbose("" + GENERAL.SIGNOFFS + " handlers registred."); Log("Starting storyline " + launchStoryline); theDirector.NewStoryLine(launchStoryline); theDirector.status = DIRECTORSTATUS.ACTIVE; } break; case DIRECTORSTATUS.NOTREADY: if (script != null) { theDirector.loadScript(script); break; } //if (scriptName != "") //{ // Warning("Please use the TextAsset field for your script."); // theDirector.loadScript(scriptName); // break; //} Error("No script reference found."); break; default: break; } }
bool checkForCallBack(StoryPointer pointer) { // checks for callbacks on the pointer. returns true if the pointer itself was moved. if (pointer.currentTask == null) { return(false); } string callBackValue = pointer.currentTask.getCallBack(); if (callBackValue == "") { return(false); } pointer.currentTask.clearCallBack(); // clear value // a callback refers to a point. if it's a storyline, a new storypoint will launch on the given point. // if it's another point, it works as goto StoryPoint callBackPoint = GENERAL.GetStoryPointByID(callBackValue); if (callBackPoint == null) { return(false); } // check if this point is on our own storyline if (callBackPoint.StoryLine == pointer.currentPoint.StoryLine) { // point is on the storyline our pointer is on, so make our pointer move Log("Callback -> caller's own storyline: " + callBackPoint.StoryLine + " moved to point: " + callBackValue + " task: " + callBackPoint.Instructions[0]); pointer.currentPoint = callBackPoint; pointer.SetStatus(POINTERSTATUS.EVALUATE); return(true); } // check if a pointer exists on the callback point's storyline StoryPointer storyPointer = GENERAL.GetPointerForStoryline(callBackPoint.StoryLine); if (storyPointer == null) { // no pointer for the callback point's storyline exists, we'll create one Log("Callback -> new storyline: " + callBackPoint.StoryLine + " starting at point: " + callBackValue + " task: " + callBackPoint.Instructions[0]); StoryPointer newStoryPointer = new StoryPointer(); newStoryPointer.SetScope(pointer.scope); newStoryPointer.SetStoryPointByID(callBackValue); pointerStack.Add(newStoryPointer); newStoryPointer.persistantData = pointer.persistantData; // inherit data, note that data network distribution is via task only. AD will load value into task } else { // a pointer on the storyline exists, we'll move it Log("Callback -> existing storyline: " + callBackPoint.StoryLine + " moved to point: " + callBackValue + " task: " + callBackPoint.Instructions[0]); storyPointer.currentPoint = callBackPoint; storyPointer.SetStatus(POINTERSTATUS.EVALUATE); } return(false); }
void Update() { SetDebugLevels(); #region APPLYUPDATES if (NetworkHandler.Instance != null) { // Handle story updates, aiming for 1 per frame, assuming we're tyring to run in sync. // Lowest numbers are oldest. int UpdateCount = NetworkHandler.Instance.StoryUpdateStack.Count; switch (UpdateCount) { case 0: BufferStatusIn = 0; break; case 1: // exactly one, so apply. ApplyStoryUpdate(NetworkHandler.Instance.StoryUpdateStack[0]); NetworkHandler.Instance.StoryUpdateStack.RemoveAt(0); BufferStatusIn = 1; break; case 2: // Two, normally for different frames that happened to arrive in the same frame on this end. // Apply the oldest one, keep the other because we expect to get 0 updates during our next frame // (If we're on similar fps) ApplyStoryUpdate(NetworkHandler.Instance.StoryUpdateStack[0]); NetworkHandler.Instance.StoryUpdateStack.RemoveAt(0); BufferStatusIn = 1; break; default: // More than 2. Apply all the older ones in order of arrival, keep latest one because we may get 0 next frame. Warning("Update buffer >2"); BufferStatusIn = 2; while (NetworkHandler.Instance.StoryUpdateStack.Count > 1) { ApplyStoryUpdate(NetworkHandler.Instance.StoryUpdateStack[0]); NetworkHandler.Instance.StoryUpdateStack.RemoveAt(0); } break; } } #endregion #region DIRECTOR switch (theDirector.status) { case DIRECTORSTATUS.ACTIVE: // Verbose("Director active ."); foreach (StoryTask task in GENERAL.ALLTASKS) { if (task.getCallBack() != "") { // if a callback was set (somewhere on the network) we act on it only if we are the server or if the task is local. if (GENERAL.AUTHORITY == AUTHORITY.GLOBAL || task.scope == SCOPE.LOCAL) // if (true || task.scope == SCOPE.LOCAL) { task.Pointer.SetStatus(POINTERSTATUS.TASKUPDATED); } } } theDirector.EvaluatePointers(); List <StoryTask> newTasks = new List <StoryTask>(); for (int p = 0; p < GENERAL.ALLPOINTERS.Count; p++) { StoryPointer pointer = GENERAL.ALLPOINTERS[p]; switch (pointer.scope) { case SCOPE.GLOBAL: // If pointer scope is global, we add a task if our own scope is global as well. (If our scope is local, we'll be receiving the task over the network) if (GENERAL.AUTHORITY == AUTHORITY.GLOBAL) // if (true) { if (pointer.GetStatus() == POINTERSTATUS.NEWTASK) { pointer.SetStatus(POINTERSTATUS.PAUSED); StoryTask task = pointer.SpawnTask(); // StoryTask task = new StoryTask(pointer, SCOPE.GLOBAL); task.LoadPersistantData(pointer); newTasks.Add(task); task.modified = true; Verbose("Created global task " + task.Instruction + " with pointid " + task.PointID + " for pointer " + pointer.currentPoint.StoryLine); } } break; case SCOPE.LOCAL: default: // If pointer scope is local, check if new tasks have to be generated. if (pointer.GetStatus() == POINTERSTATUS.NEWTASK) { pointer.SetStatus(POINTERSTATUS.PAUSED); StoryTask task = pointer.SpawnTask(); //StoryTask task = new StoryTask(pointer, SCOPE.LOCAL); task.LoadPersistantData(pointer); newTasks.Add(task); Verbose("Created local task " + task.Instruction + " with pointid " + task.PointID + " for pointer " + pointer.currentPoint.StoryLine); } break; } } if (newTasks.Count > 0) { if (newTasksEventUnity != null) { newTasksEventUnity.Invoke(newTasks); } // if (newTasksEvent != null) newTasksEvent(this, new TaskArgs(newTasks)); // trigger the event, if there are any listeners // DistributeTasks(new TaskArgs(newTasks)); // if any new tasks call an event, passing on the list of tasks to any handlers listening } break; case DIRECTORSTATUS.READY: int SIGNOFFS = eventHandlerCount(); if (SIGNOFFS == 0) { Error("No handlers registred. Pausing director."); theDirector.status = DIRECTORSTATUS.PAUSED; } else { Verbose("" + SIGNOFFS + " handlers registred at this time."); Verbose("Starting storyline " + launchStoryline); theDirector.NewStoryLine(launchStoryline); theDirector.status = DIRECTORSTATUS.ACTIVE; } break; case DIRECTORSTATUS.NOTREADY: // try addressable script first. //if (scriptAddressable != null && scriptAddressable != "") //{ // // pause while loading // theDirector.status = DIRECTORSTATUS.PAUSED; // Addressables.LoadAssetAsync<TextAsset>(scriptAddressable).Completed += obj => // { // if (obj.Result == null) // { // Error("Addressable script asset failed: " + obj.OperationException.Message); // } // else // { // theDirector.loadScriptAsset(obj.Result); // Log("Script loaded, from addressable asset."); // } // }; //} if (scriptFile != null && scriptFile != "") { // we have a reference to a local script file, so we'll attempt to load it (synchronous). we try to load it from a folder with the current version string script = Transport.FileToText(Application.persistentDataPath + "/scripts/" + App.GetMinor() + "/" + scriptFile); if (script == "") { Log("No script on disk for version: " + App.GetMinor()); } else { theDirector.loadScriptText(script); Log("Script loaded, from local file."); break; } } if (scriptAsset != null) { theDirector.loadScriptAsset(scriptAsset); Log("Script loaded, from asset."); break; } Error("No script reference found, pausing director."); theDirector.status = DIRECTORSTATUS.PAUSED; break; default: break; } #endregion }