/*! Creates a new storypointer, if the storyline doesn't exist, with a given scope and adds it to the pointerstack. */ public void NewStoryLineExclusive(string _name, SCOPE _scope = SCOPE.LOCAL) { if (_name == "") { Warning("New storyline name is empty."); return; } Log("new storyline " + _name); if (GENERAL.GetPointerForStoryline(_name) == null) { // StoryPointer pointer = new StoryPointer(_name, _scope); // constructor adds pointer to GENERAL.allpointers StoryPointer pointer = new StoryPointer(); // constructor adds pointer to GENERAL.allpointers pointer.SetScope(_scope); pointer.SetStoryPointByID(_name); } else { Log("Storyline already running, you called exclusive."); } //pointer.scope = _scope; }
void ApplyPointerUpdate(PointerUpdateBundled pointerUpdate) { // Right now the only update we send for pointers is when they are killed. StoryPointer pointer = GENERAL.GetPointerForStoryline(pointerUpdate.StoryLineName); Log("Server says kill pointer: " + pointerUpdate.StoryLineName); if (pointer != null) { // We remove it instantly. No need to mark it as deleted, nothing else to do with it. GENERAL.ALLPOINTERS.Remove(pointer); Log("Removing pointer: " + pointer.currentPoint.StoryLine); // Server passes tasks, so if it is faster, client may be processing more than one task for a storyline. (Even if the deus dash would show it) for (int i = GENERAL.ALLTASKS.Count - 1; i >= 0; i--) { StoryTask task = GENERAL.ALLTASKS[i]; if (task.Point != null && task.Point.StoryLine == pointerUpdate.StoryLineName) { Log("Removing task: " + task.Instruction); GENERAL.ALLTASKS.Remove(task); } } } }
public static StoryTask FindTaskByByLabel(string id) { StoryTask r = null; r = GENERAL.GetTaskForPoint(id); return(r); }
void ApplyTaskUpdate(StoryTaskUpdate taskUpdate) { // See if we already have a task on this storypoint. StoryTask updateTask = GENERAL.GetTaskForPoint(taskUpdate.pointID); if (updateTask == null) { // Are we client ? -> create the task // (If we're the server, we'll ignore updates for tasks we no longer know about) if (GENERAL.AUTHORITY == AUTHORITY.LOCAL) { // Do we already have a pointer for this storyline? StoryPointer updatePointer = GENERAL.GetStorylinePointerForPointID(taskUpdate.pointID); if (updatePointer == null) { // Create a new pointer updatePointer = new StoryPointer(); Log("Created a new pointer for point with ID " + taskUpdate.pointID); } updatePointer.SetStoryPointByID(taskUpdate.pointID); updatePointer.SetScope(SCOPE.GLOBAL);// global because we just got it updateTask = updatePointer.SpawnTask(); //updateTask = new StoryTask(taskUpdate.pointID,updatePointer); // global because we just got it Log("Created an instance of global task " + updateTask.Instruction + " id " + updateTask.PointID); //Log("Populated pointer " + updatePointer.currentPoint.StoryLine + " with task " + updateTask.Instruction); updateTask.ApplyUpdate(taskUpdate); // updatePointer.PopulateWithTask(updateTask); List <StoryTask> newTasks = new List <StoryTask>(); newTasks.Add(updateTask); if (newTasksEventUnity != null) { newTasksEventUnity.Invoke(newTasks); } } } else { updateTask.ApplyUpdate(taskUpdate); updateTask.scope = SCOPE.GLOBAL;// if a task was local it now becomes global Verbose("Applied update to existing task " + updateTask.Instruction); } }
public void PopulateWithTask(StoryTask task) { // Filling an empty pointer with task info. Used for network task and pointer creation. currentPoint = GENERAL.GetStoryPointByID(task.PointID); currentTask = task; task.Pointer = this; scope = task.scope; }
//int LastUpdateFrame = -1; //int UpdatesPerFrame = 0; //public int LastUpdatesPerFrame = 0; //public int MaxUpdatesPerFrame = 0; // ------------------------------------------------ #region CONSTRUCTOR // Tasks are create by calling spawntask on a pointer. public StoryTask(StoryPointer _fromPointer) : base("StoryTask", _fromPointer.scope) { // Create a task based on the current storypoint in the pointer. Pointer = _fromPointer; __point = _fromPointer.currentPoint; scope = _fromPointer.scope; setDefaults(); GENERAL.AddTask(this); }
public StoryTask(string _fromPointID, SCOPE _scope) { // Creating a task from a storypoint -> pointer to be created from this task. //pointID = storyPointID; __point = GENERAL.GetStoryPointByID(_fromPointID); //description = point.task[0]; scope = _scope; __pointer = null; setDefaults(); GENERAL.ALLTASKS.Add(this); }
void ApplyTaskUpdate(TaskUpdateBundled taskUpdate) { // See if we have a task on this storypoint. StoryTask updateTask = GENERAL.GetTaskForPoint(taskUpdate.pointID); if (updateTask == null) { // If not, and we're a client, we create the task. // If we're the server, we ignore updates for task we no longer know about. if (GENERAL.AUTHORITY == AUTHORITY.LOCAL) { updateTask = new StoryTask(taskUpdate.pointID, SCOPE.GLOBAL); updateTask.ApplyUpdateMessage(taskUpdate); Log("Created an instance of global task " + updateTask.Instruction + " id " + updateTask.PointID); if (taskUpdate.pointID != "GLOBALS") { // Now find a pointer. StoryPointer updatePointer = GENERAL.GetStorylinePointerForPointID(taskUpdate.pointID); if (updatePointer == null) { updatePointer = new StoryPointer(); Log("Created a new pointer for task " + updateTask.Instruction); } updatePointer.PopulateWithTask(updateTask); Log("Populated pointer " + updatePointer.currentPoint.StoryLine + " with task " + updateTask.Instruction); DistributeTasks(new TaskArgs(updateTask)); } } } else { updateTask.ApplyUpdateMessage(taskUpdate); updateTask.scope = SCOPE.GLOBAL;//?? Verbose("Applied update to existing task " + updateTask.Instruction); } }
bool checkForCallBack(StoryPointer pointer) { // checks and trigger callback on the current task for given pointer. does not touch the pointer itself. if (pointer.currentTask == null) { return(false); } string callBackValue = pointer.currentTask.getCallBack(); if (callBackValue == "") { return(false); } pointer.currentTask.clearCallBack(); // clear value // A callback is equivalent to 'start name', launching a new storypointer on the given point. if (GENERAL.GetPointerForStoryline(pointer.currentTask.getCallBack()) == null) { Log("New callback storyline: " + callBackValue); StoryPointer newStoryPointer = new StoryPointer(callBackValue, pointer.scope); if (newStoryPointer.currentPoint == null) { // callback value was invalid, no point was found, we don't add the pointer. GENERAL.ALLPOINTERS.Remove(newStoryPointer);// was auto-added in constructor, so must be removed Warning("Callback storyline doesn't exist: " + callBackValue); } else { //newStoryPointer.modified = true; 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 { Log("Callback storyline already started: " + callBackValue); } return(true); }
public StoryPointer(string pointID, SCOPE setScope) { // Create a pointer from a given point. Task to be added later. currentPoint = GENERAL.GetStoryPointByID(pointID); currentTask = null; status = POINTERSTATUS.EVALUATE; scope = setScope; // GENERAL.AddPointer(this); GENERAL.ALLPOINTERS.Add(this); // updateMessageSend = new PointerUpdateBundled(); // we'll reuse. }
public void SetStoryPointByID(string pointID) { currentPoint = GENERAL.GetStoryPointByID(pointID); status = POINTERSTATUS.EVALUATE; }
//public void NewStoryLine(string _name) //{ // // Creates a new LOCAL storypointer and adds it to the pointerstack. // new StoryPointer(_name, SCOPE.LOCAL); // constructor adds pointer to GENERAL.allpointers //} public void EvaluatePointers() { // Create a stack of pointers for processing. pointerStack = new List <StoryPointer>(); for (int p = GENERAL.ALLPOINTERS.Count - 1; p >= 0; p--) { StoryPointer sp = GENERAL.ALLPOINTERS[p]; // For consistency of network logic, local pointers that were killed are disposed here. // Global pointers are disposed by the AD, after updating clients about them. if (sp.scope == SCOPE.LOCAL && sp.GetStatus() == POINTERSTATUS.KILLED) { Log("Removing pointer: " + sp.currentPoint.StoryLine); GENERAL.ALLPOINTERS.RemoveAt(p); } if (sp.GetStatus() == POINTERSTATUS.EVALUATE || sp.GetStatus() == POINTERSTATUS.TASKUPDATED) { // pointer needs evaluating. but we only do this if pointer is local OR if pointer is global and we are the server if ((sp.scope == SCOPE.GLOBAL && GENERAL.AUTHORITY == AUTHORITY.GLOBAL) || (sp.scope == SCOPE.LOCAL)) { pointerStack.Add(sp); } } } if (pointerStack.Count > 0) { Log("Evaluating " + pointerStack.Count + " of " + GENERAL.ALLPOINTERS.Count + " storypointers."); } while (pointerStack.Count > 0) { // Keep processing items on the stack untill empty. StoryPointer pointer; string targetPointerName, targetValue; StoryPointer newPointer, targetPointer; StoryPoint targetPoint; pointer = pointerStack[0]; Log("Evaluating pointer: " + pointer.currentPoint.StoryLine); pointer.LoadPersistantData(); switch (pointer.currentPoint.taskType) { case TASKTYPE.ROUTING: string type = pointer.currentPoint.Instructions[0]; switch (type) { case "hold": // Put this pointer on hold. Remove from stack. Log("Pausing pointer."); pointer.SetStatus(POINTERSTATUS.PAUSED); pointerStack.RemoveAt(0); break; case "tell": // Control another pointer. Finds a/the(!) pointer on the given storyline and moves it to the given storypoint, marking the pointer for evaluation. // Progress this pointer, keeping it on the stack targetPointerName = pointer.currentPoint.Instructions[1]; targetValue = pointer.currentPoint.Instructions[2]; targetPointer = GENERAL.GetPointerForStoryline(targetPointerName); if (targetPointer != null) { targetPoint = GENERAL.GetStoryPointByID(targetValue); if (targetPoint != null) { targetPointer.currentPoint = targetPoint; } else { Warning("Tell was unable to find the indicated storypoint."); } targetPointer.SetStatus(POINTERSTATUS.EVALUATE); Log("Telling pointer on storyline " + targetPointerName + " to move to point " + targetValue); } else { Warning("Tell was unable to find the indicated storypointer."); } moveToNextPoint(pointer); break; case "goto": // Moves this pointer to another point anywhere in the script. Mark for evaluation, keep on stack. targetValue = pointer.currentPoint.Instructions[1]; targetPoint = GENERAL.GetStoryPointByID(targetValue); if (targetPoint != null) { pointer.currentPoint = targetPoint; Log("Go to point " + targetValue); } else { Warning("Goto point not found."); } pointer.SetStatus(POINTERSTATUS.EVALUATE); break; case "start": // Start a new pointer on the given storypoint. // Create a new pointer, add it to the list of pointers and add it to the stack. // Progress the current pointer, keeping it on the stack. targetPointerName = pointer.currentPoint.Instructions[1]; if (GENERAL.GetPointerForStoryline(targetPointerName) == null) { Log("Starting new pointer for storypoint: " + targetPointerName); newPointer = new StoryPointer(targetPointerName, pointer.scope); pointerStack.Add(newPointer); } else { Log("Storyline already active for storypoint " + targetPointerName); } moveToNextPoint(pointer); break; case "stop": // Stop another storypointer by storyline name, or all other storylines with 'all'. targetPointerName = pointer.currentPoint.Instructions[1]; if (targetPointerName == "all") { foreach (StoryPointer stp in GENERAL.ALLPOINTERS) { if (stp != pointer) { Log("Stopping pointer " + stp.currentPoint.StoryLine); stp.Kill(); if (GENERAL.ALLTASKS.Remove(stp.currentTask)) { Log("Removing task " + stp.currentTask.Instruction); } else { Warning("Failed removing task " + stp.currentTask.Instruction); } } } // Remove all pointers from stack, re-adding the one we're on. pointerStack.Clear(); pointerStack.Add(pointer); } else { // Stop a single storypointer on given storyline. targetPointer = GENERAL.GetPointerForStoryline(targetPointerName); if (targetPointer != null) { Log("Stopping pointer " + targetPointer.currentPoint.StoryLine); pointerStack.Remove(targetPointer); targetPointer.Kill(); if (GENERAL.ALLTASKS.Remove(targetPointer.currentTask)) { Log("Removing task " + targetPointer.currentTask.Instruction); } else { Warning("Failed removing task " + targetPointer.currentTask.Instruction); } } else { Log("No pointer found for " + targetPointerName); } } moveToNextPoint(pointer); break; default: break; } break; //case TASKTYPE.END: // // End of a storyline. // checkForCallBack(pointer); // if (pointer.currentTask != null && pointer.currentTask.getStatus() != TASKSTATUS.COMPLETE) // { // Warning("Encountered end of storyline, but current task didn't complete?"); // } // pointer.SetStatus(POINTERSTATUS.NEWTASK); // // pointer.Kill(); // pointerStack.RemoveAt(0); // break; case TASKTYPE.BASIC: // case TASKTYPE.END: if (pointer.GetStatus() == POINTERSTATUS.EVALUATE) { // A normal task to be executed. Assistant director will generate task. Log("Task to be executed: " + pointer.currentPoint.Instructions[0]); pointer.SetStatus(POINTERSTATUS.NEWTASK); pointerStack.RemoveAt(0); } if (pointer.GetStatus() == POINTERSTATUS.TASKUPDATED) { // Something has happened in the task that we need to evaluate. if (pointer.currentTask.getStatus() == TASKSTATUS.COMPLETE) { // Task was completed. Check if there's a callback before moving on. checkForCallBack(pointer); // Task was completed, progress to the next point. Log("task completed: " + pointer.currentTask.Instruction); pointer.SetStatus(POINTERSTATUS.EVALUATE); moveToNextPoint(pointer); } if (pointer.currentTask.getStatus() == TASKSTATUS.ACTIVE) { // See if there's a callback. checkForCallBack(pointer); // Return pointerstatus to paused and stop evaluating it for now. // Debug.LogWarning (me + "Pointerstatus says taskupdated, but taskstatus for task " + pointer.currentTask.description + " is active."); pointer.SetStatus(POINTERSTATUS.PAUSED); pointerStack.RemoveAt(0); } } break; default: // This shouldn't occur. Warning("Error: unkown storypoint type. "); pointerStack.RemoveAt(0); 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); }