Exemple #1
0
    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));
        }
    }
Exemple #2
0
    /// <summary>
    /// Update the set of character's within this characters' conversational space
    /// and generate any necessary enter/leave events.
    /// </summary>
    private void UpdateSpace(Collider2D[] colliders, float radius, ELNode statusNode, string enterEvent, string exitEvent, bool updateNobodySpeaking)
    {
        var characterCount = Physics2D.OverlapCircleNonAlloc(
            transform.position,
            radius,
            colliders,
            1 << gameObject.layer);
        if (characterCount==MaxConversationalSpaceColliders)
            throw new Exception("Too many colliders in conversational space!");

        // Clean out entries that are no longer in the area
        statusNode.DeleteAll(
            node =>
            {
                // Look to see if node's key (a character) appears in the colliders
                for (var i = 0; i<characterCount;i++)
                    if (ReferenceEquals(node.Key, colliders[i].gameObject))
                        return false;
                // It doesn't, so the character left this character's conversational space.

                // Tell this character about it
                QueueEvent(exitEvent, node.Key);

                // Remove the character
                return true;
            });

        // Add new entries
        for (var i = 0; i<characterCount;i++)
        {
            var character = colliders[i].gameObject;
            if (character != gameObject && !statusNode.ContainsKey(character) && myCurrentRoom.Contains(character))
            {
                // The character just arrived in this character's conversational space

                // Tell this character
                QueueEvent(enterEvent, character);

                // Update the KB
                ELNode.Store(statusNode/character);
            }
        }

        if (updateNobodySpeaking)
        {
            bool nobodySpeaking = true;
            for (var i = 0; i<characterCount; i++)
                if (colliders[i].GetComponent<SimController>().IsSpeaking)
                    nobodySpeaking = false;
            if (nobodySpeaking)
                ELNode.Store(perceptionRoot/SNobodySpeaking);
            else
            {
                if (perceptionRoot.ContainsKey(SNobodySpeaking))
                {
                    perceptionRoot.DeleteKey(SNobodySpeaking);
                    pollActions = true;
                }
            }
        }
    }
Exemple #3
0
    /// <summary>
    /// Update the set of character's within this characters' conversational space
    /// and generate any necessary enter/leave events.
    /// </summary>
    private void UpdateSpace(Collider2D[] colliders, float radius, ELNode statusNode, string enterEvent, string exitEvent, bool updateNobodySpeaking)
    {
        var characterCount = Physics2D.OverlapCircleNonAlloc(
            transform.position,
            radius,
            colliders,
            1 << gameObject.layer);

        if (characterCount == MaxConversationalSpaceColliders)
        {
            throw new Exception("Too many colliders in conversational space!");
        }

        // Clean out entries that are no longer in the area
        statusNode.DeleteAll(
            node =>
        {
            // Look to see if node's key (a character) appears in the colliders
            for (var i = 0; i < characterCount; i++)
            {
                if (ReferenceEquals(node.Key, colliders[i].gameObject))
                {
                    return(false);
                }
            }
            // It doesn't, so the character left this character's conversational space.

            // Tell this character about it
            QueueEvent(exitEvent, node.Key);

            // Remove the character
            return(true);
        });

        // Add new entries
        for (var i = 0; i < characterCount; i++)
        {
            var character = colliders[i].gameObject;
            if (character != gameObject && !statusNode.ContainsKey(character) && myCurrentRoom != null && myCurrentRoom.Contains(character))
            {
                // The character just arrived in this character's conversational space

                // Tell this character
                QueueEvent(enterEvent, character);

                // Update the KB
                ELNode.Store(statusNode / character);
            }
        }

        if (updateNobodySpeaking)
        {
            bool nobodySpeaking = true;
            for (var i = 0; i < characterCount; i++)
            {
                if (colliders[i].GetComponent <SimController>().IsSpeaking)
                {
                    nobodySpeaking = false;
                }
            }
            if (currentlySpeaking)
            {
                nobodySpeaking = false;
            }
            if (nobodySpeaking)
            {
                ELNode.Store(perceptionRoot / SNobodySpeaking);
            }
            else
            {
                if (perceptionRoot.ContainsKey(SNobodySpeaking))
                {
                    perceptionRoot.DeleteKey(SNobodySpeaking);
                    pollActions = true;
                }
            }
        }
    }