public void OnScriptComplete(string error){ if (debug) Debug.Log ("Script "+name+" OnScriptComplete"); // we're done. Assuming no errors, see if we need to send a :COMPLETE message string triggerString = "none"; if (args.ContainsKey("trigger")) triggerString = args["trigger"]; if (triggerString.Contains(":")) { // send :COMPLETE msg to brain string completion; if (error == null || error == "") completion = ":COMPLETE"; else completion = ":"+error.ToUpper(); InteractStatusMsg msg = new InteractStatusMsg(triggerString + completion); Brain.GetInstance().PutMessage(msg); } // hasRun = true; isRunning = false; readyState = readiness.unknown; // will update on the next readiness test. currentLine = scriptLines.Length; // so don't update a line by accident ScriptedObject myCaller = caller; caller = null; // have to do this before, because OnScriptComplete could start us up again! // release character task actors foreach (ObjectInteraction actor in actorObjects){ actor.ReleasedBy(this, myCaller); } if (myCaller == null) Debug.LogWarning("Script Complete but caller was null!!"+name); else{ // added this block 6/19/14 to keep queue from hanging when scripts owned by another // object interaction are run from an objects queue if (!actorObjects.Contains(myCaller.ObjectInteraction)) myCaller.ObjectInteraction.ReleasedBy (this, myCaller); myCaller.OnScriptComplete(this,error); } roleMap.Clear(); // clear the assigned roles so they don't get reserved by accident actorObjects.Clear(); }
public void ExecuteEvent(ScriptedObject thisCaller,string eventName){ // intended to be called from animation Events, start execution at the named line, and // run until an action flagged sequenceEnd=true; // Look for the line. fail if not found int startingIndex=-1; for (int i=0;i<scriptLines.Length;i++){ if (scriptLines[i].name == eventName){ startingIndex=i; break; } } if (startingIndex <0){ Debug.LogError("AnimationEvent using "+name+" could not find line "+eventName); return; } // caller is only used by ExecuteScript and onScriptComplete, so we might go without it... caller = thisCaller; myObject = caller.gameObject; args.Clear(); // do we need any args for events ? SetArgs (startingArgs); currentLine = startingIndex; nextLineLabel = ""; isRunning = true; readyState = readiness.executing; myOI = caller.GetComponent<ObjectInteraction>(); if (debug) Debug.Log ("Script "+name+" execution started"); if (scriptLines[currentLine] != null) scriptLines[currentLine].ForceExecute(this); else OnScriptComplete(""); }
public readiness ReadyState(BaseObject obj,bool reserve){ // figure out how ready we are, and have we been queued or whatever. // if we are executing, that trumps all if (readyState == readiness.executing) return readyState; // if we are queued, we might be stale, otherwise, return queued if (queueCount > 0){ if (isReadyFor(obj)){ readyState = readiness.queued; return readyState; } else{ readyState = readiness.stale; return readyState; } } // else, just how ready are we ? if (isReadyFor(obj)){ // if obj and all our actors are available, we can run if (isReadyToRun (obj,reserve)){ readyState = readiness.readyToRun; return readyState; } else{ readyState = readiness.readyToQueue; return readyState; } } readyState = readiness.unavailable; return readyState; }
public void Execute(ScriptedObject thisCaller,string argString="", GameObject obj=null){ caller = thisCaller; foreach (ObjectInteraction actor in actorObjects){ actor.reservedForScript = null; // incase anyone got reserved who doesn't get picked by the dispatcher } // here, we must find a character for each role, assign and reserve them Dispatcher.GetInstance().FillRoles(this); // bail if fail if (obj == null) myObject = caller.gameObject; // the scripted object by default else myObject = obj; args.Clear(); // clear the dictionary to start SetArgs (startingArgs); SetArgs(argString); currentLine = 0; nextLineLabel = ""; isRunning = true; readyState = readiness.executing; myOI = caller.GetComponent<ObjectInteraction>(); //Debug.LogWarning(name+" reserving "+myOI.name); foreach (ObjectInteraction actor in actorObjects){ actor.actingInScript = this; actor.reservedForScript = null; } foreach (ScriptedAction sa in scriptLines) sa.hasExecuted = false; // really just for debug use, would break 'executeOnlyOnce' // if there's an interaction set specified, send it to the interaction manager. if (interactionSet != null && interactionSet.Name != null && interactionSet.Name != "") InteractionMgr.GetInstance().CurrentSet = interactionSet; if (debug) Debug.Log ("Script "+name+" execution started"); // we're going to have to handle multiple current lines for roles if (scriptLines[currentLine] != null) scriptLines[currentLine].Execute(this); else OnScriptComplete(""); }
public void InitFrom(InteractionScriptInfo info){ // initialize members from deserialized info gameObject.name = info.unityObjectName; // this should only be done if we have gameobject per script triggerStrings = info.triggerStrings; // the string that causes this script to start running triggerOnStatus = info.triggerOnStatus; // should we listen to InteractStatusMessages for our trigger ? startingArgs = info.startingArgs; scriptLines = new ScriptedAction[info.scriptLines.Length]; for (int i = 0; i<info.scriptLines.Length; i++){ GameObject go = new GameObject(info.scriptLines[i].unityObjectName); go.transform.parent = this.transform; scriptLines[i] = go.AddComponent("ScriptedAction") as ScriptedAction; scriptLines[i].InitFrom(info.scriptLines[i]); } // resolve any task sync cross references for (int j = 0; j<info.scriptLines.Length; j++){ if (scriptLines[j].syncToTasks != null && scriptLines[j].syncToTasks.Length > 0){ for (int k=0; k<scriptLines[j].syncToTasks.Length; k++){ scriptLines[j].syncToTasks[k] = scriptLines[scriptLines[j].syncToTasksIndex[k]]; } } } // public ScriptedAction.ScriptedActionInfo[] abortBranch; // the way out, if the user chooses not to complete this script // public ScriptedAction.ScriptedActionInfo[] errorBranch; // what to do if the script hangs, times out, encounters an error... owningRole = info.owningRole; roles = new List<string>(info.roles); // info.roles.CopyTo(roles); // roles = info.roles; // if null, then just one role for this script roleKeyString = info.roleKeyString; // enter this as a string in the editor, it gets parsed into a node tree on awake. autoExecuteInterval = info.autoExecuteInterval; autoExecuteProbability = info.autoExecuteProbability; AddToMenu = info.AddToMenu; menuOrder = info.menuOrder; interactionSet = info.interactionSet; commandVariation = info.commandVariation; // failsafe in case of blank Cmd but variations present, default to use trigger string or script name if (commandVariation != null && commandVariation.Cmd == "" && commandVariation.Variations.Count>0){ commandVariation.Cmd = name; // this is the convention we're using. Trigger string might contain multiples Debug.LogWarning(name+" was missing commandVariations.Cmd value "); } if (commandVariation != null && commandVariation.Cmd != null && commandVariation.Cmd != "") if (Application.isPlaying) FilterInteractions.GetInstance().AddVariation(commandVariation); callbackConfirmVoice = info.callbackConfirmVoice; item = info.item; prettyname = info.prettyname; response = info.response; response_title = info.response_title; note = info.note; tooltip = info.tooltip; sound = info.sound; task = info.task; log = info.log; readyState = info.readyState; // since an object reference is required to calc this, no getter. startPriority = info.startPriority; // 0 is the lowest cancellable = info.cancellable; skillVector = info.skillVector; extraCost = info.extraCost; prereq = info.prereq; category = info.category; param = info.param; debug = info.debug; // print out debug logging while running }