/// <summary> /// Call into Prolog to respond to EVENTDESCRIPTION /// </summary> /// <param name="eventDescription">Term representing the event</param> private void NotifyEvent(object eventDescription) { ELNode.Store(eventHistory / Term.CopyInstantiation(eventDescription)); if (!this.IsTrue(new Structure(SNotifyEvent, eventDescription))) { Debug.LogError("notify_event/1 failed: " + ISOPrologWriter.WriteToString(eventDescription)); } }
private void InitiateAction(object action) { if (action == null) { return; } var actionCopy = Term.CopyInstantiation(action); ELNode.Store(motorRoot / SLastAction % actionCopy); var structure = action as Structure; if (structure != null) { switch (structure.Functor.Name) { case "face": Face(structure.Argument <GameObject>(0)); break; case "say": // Say a fixed string Say(structure.Argument <string>(0), gameObject); break; case "cons": // It's a list of actions to initiate. InitiateAction(structure.Argument(0)); InitiateAction(structure.Argument(1)); break; case "pause": pauseUntil = Time.time + Convert.ToSingle(structure.Argument(0)); break; case "pickup": { var patient = structure.Argument <GameObject>(0); if (patient == gameObject) { throw new InvalidOperationException(name + ": tried to pickup() self!"); } if (patient == gameObject) { return; } if (patient == null) { throw new NullReferenceException("Argument to pickup is not a gameobject"); } var physob = patient.GetComponent <PhysicalObject>(); if (physob == null) { throw new NullReferenceException("Argument to pickup is not a physical object."); } physob.MoveTo(gameObject); break; } case "ingest": { var patient = structure.Argument <GameObject>(0); if (patient == null) { throw new NullReferenceException("Argument to ingest is not a gameobject"); } var physob = patient.GetComponent <PhysicalObject>(); if (physob == null) { throw new NullReferenceException("Argument to ingest is not a physical object."); } physob.Destroy(); // TODO: FIX LOCATION UPDATE SO WE DON'T NEED TO KLUGE THIS locationRoot.DeleteKey(patient); var propinfo = patient.GetComponent <PropInfo>(); if (propinfo != null) { if (propinfo.IsFood) { physiologicalStates.DeleteKey(Symbol.Intern("hungry")); } if (propinfo.IsBeverage) { physiologicalStates.DeleteKey(Symbol.Intern("thirsty")); } } break; } case "putdown": { var patient = structure.Argument <GameObject>(0); if (patient == gameObject) { throw new InvalidOperationException(name + ": tried to putdown() self!"); } if (patient == null) { throw new NullReferenceException("Argument to putdown is not a gameobject"); } var physob = patient.GetComponent <PhysicalObject>(); if (physob == null) { throw new NullReferenceException("Argument to putdown is not a physical object."); } var dest = structure.Argument <GameObject>(1); if (dest == null) { throw new NullReferenceException("Argument to putdown is not a gameobject"); } physob.MoveTo(dest); break; } case "flash": { flashColorA = structure.Argument <Color>(0); flashColorB = structure.Argument <Color>(1); flashPeriod = Convert.ToSingle(structure.Argument(2)); flashStartTime = Time.time; flashEndTime = flashStartTime + Convert.ToSingle(structure.Argument(3)); break; } case "get_in": GetIn(structure.Argument <GameObject>(0)); break; case "dismount": Dismount(); break; case "end_game": Application.Quit(); break; default: // Assume it's dialog this.IsTrue("log_dialog_act", structure); GameObject thisAddressee = ((structure.Arity >= 2) ? structure.Argument(1) as GameObject : gameObject) ?? gameObject; var talkingToSelf = thisAddressee == gameObject; if (!talkingToSelf || ShowMentalMonologue) { var textVar = new LogicVariable("DialogText"); object text = null; try { text = gameObject.SolveFor(textVar, "generate_text", structure, textVar); } catch (Exception e) { Debug.LogError(string.Format("Exception while generating text for {0}", gameObject.name)); Debug.LogException(e); } var textString = text as string; if (textString == null) { throw new Exception( "generate_text returned " + ISOPrologWriter.WriteToString(text) + " for " + ISOPrologWriter.WriteToString(structure)); } var talkingToPlayer = structure.Arity >= 2 && ReferenceEquals(structure.Argument(1), playerSymbol); SetSpeechTimeout(textString); if (talkingToPlayer) // Character is talking to zhimself { if (nlPrompt != null) { nlPrompt.OutputToPlayer(textString); } else { Say(string.Format("({0})", textString), thisAddressee); } } else { Say(textString, thisAddressee); } if (!talkingToPlayer && !talkingToSelf) { // Tell the other characters foreach (var node in socialSpace.Children) { var character = (GameObject)(node.Key); if (character != gameObject) { character.QueueEvent((Structure)Term.CopyInstantiation(structure)); } } // TODO: fix it so that when characters appear, the system computes their social // spaces from scratch. Then we won't need this kluge. if (!socialSpace.ContainsKey(thisAddressee)) { thisAddressee.QueueEvent((Structure)Term.CopyInstantiation(structure)); } } } break; } if (structure.Functor.Name != "pause") { // Report back to the character that the action has occurred. QueueEvent(structure); } } else { throw new InvalidOperationException("Unknown action: " + ISOPrologWriter.WriteToString(action)); } }
private void TryCompletion() { // Update the mouse selection, so Prolog can get at it. mouseSelectionELNode.StoreExclusive(MouseSelection, true); var completionVar = new LogicVariable("Output"); var dialogActVar = new LogicVariable("DialogAct"); bool completionSuccess = false; try { completionSuccess = this.IsTrue("input_completion", input, completionVar, dialogActVar); } catch (InferenceStepsExceededException e) { Debug.LogError("Completion took too many steps for input: " + input); Debug.LogException(e); } if (completionSuccess) { completion = (string)completionVar.Value; dialogAct = Term.CopyInstantiation(dialogActVar.Value); if (this.IsTrue("well_formed_dialog_act", dialogAct)) { formatted = completion == "" ? string.Format("<b><color=lime>{0}</color></b>", input) : string.Format("<color=lime>{0}{1}<i>{2}</i></color>", input, (input.EndsWith(" ") || input.EndsWith("'") || !char.IsLetterOrDigit(completion[0])) ? "" : " ", completion); var da = dialogAct as Structure; if (da != null && da.Arity > 1) { var a = da.Argument <GameObject>(1); var addressee = (a == gameObject) ? "myself" : a.name; commentary = string.Format("{0} to {1}\n{2}", da.Functor, addressee, ISOPrologWriter.WriteToString(dialogActVar.Value)); formatted = string.Format("{1} (speaking to {0})", addressee, formatted); } else { commentary = ISOPrologWriter.WriteToString(dialogActVar.Value); } } else { // Input is grammatical but not well formed. formatted = completion == "" ? string.Format("<b><color=yellow>{0}</color></b>", input) : string.Format("<color=yellow>{0}{1}</color><color=grey><i>{2}</i></color>", input, (input.EndsWith(" ") || !char.IsLetterOrDigit(completion[0])) ? "" : " ", completion); if (completion == "") { commentary = string.Format( "This input is grammatical, but doesn't make sense to me\n{0}", ISOPrologWriter.WriteToString(dialogActVar.Value)); } else { commentary = "This is grammatical but nonsensical\n" + ISOPrologWriter.WriteToString(dialogActVar.Value); } } } else { var lastWordOfInput = LastWordOfInput; if (lastWordOfInput != "" && Prolog.Prolog.IsPrefixOfDistinctLexicalItem(lastWordOfInput)) { FormatInputWithoutColorCoding(); } else { FormatRejectionOfInput(); } } }
private void TryCompletion() { var completionVar = new LogicVariable("Output"); var dialogActVar = new LogicVariable("DialogAct"); bool completionSuccess = false; try { completionSuccess = this.IsTrue("input_completion", this.input, completionVar, dialogActVar); } catch (InferenceStepsExceededException e) { Debug.LogError("Completion took too many steps for input: " + this.input); Debug.LogException(e); } if (completionSuccess) { this.completion = (string)completionVar.Value; this.dialogAct = Term.CopyInstantiation(dialogActVar.Value); if (this.IsTrue("well_formed_dialog_act", this.dialogAct)) { this.formatted = this.completion == "" ? string.Format("<b><color=lime>{0}</color></b>", this.input) : string.Format("<color=lime>{0}{1}<i>{2}</i></color>", this.input, (this.input.EndsWith(" ") || this.input.EndsWith("'") || !char.IsLetterOrDigit(this.completion[0])) ? "" : " ", this.completion); var da = this.dialogAct as Structure; if (da != null && da.Arity > 1) { var a = da.Argument <GameObject>(1); this.commentary = string.Format("{0} to {1}\n{2}", da.Functor, (a == this) ? "myself" : a.name, ISOPrologWriter.WriteToString(dialogActVar.Value)); } else { this.commentary = ISOPrologWriter.WriteToString(dialogActVar.Value); } } else { // Input is grammatical but not well formed. this.formatted = this.completion == "" ? string.Format("<b><color=yellow>{0}</color></b>", this.input) : string.Format("<color=yellow>{0}{1}</color><color=grey><i>{2}</i></color>", this.input, (this.input.EndsWith(" ") || !char.IsLetterOrDigit(this.completion[0])) ? "" : " ", this.completion); if (this.completion == "") { this.commentary = string.Format( "This input is grammatical, but doesn't make sense to me\n{0}", ISOPrologWriter.WriteToString(dialogActVar.Value)); } else { this.commentary = "This is grammatical but nonsensical\n" + ISOPrologWriter.WriteToString(dialogActVar.Value); } } } else { this.formatted = string.Format("<color=red>{0}</color>", this.input); this.commentary = "Sorry; I don't understand any sentences beginning with those words."; } }