コード例 #1
0
    private void UpdateLocations()
    {
        // TODO: FIX THIS SO THAT DESTROYED OBJECTS GET THEIR ENTRIES GC'ed.
        foreach (var p in Registry <PhysicalObject>())
        {
            var o = p.gameObject;
            var n = locationRoot.ChildWithKey(o);
            // Don't do anything if /perception/location/O:Location:override in database,
            // which would mean the character is brainwashed about O's position.
            if (n == null || n.Children.Count == 0 || !n.Children[0].ContainsKey(brainwashedSymbol))
            {
                if (!p.Exists)
                {
                    // Dead; remove it.
                    locationRoot.DeleteKey(o);
                }
                // Determine if it's inside something
                else if (p.Container == null)
                {
                    // It's not inside another object, so find what room it's in.

                    if (n == null || !n.ExclusiveKeyValue <GameObject>().GetComponent <Room>().Contains(o))
                    {
                        var r        = TileMap.TheTileMap.TileRoom(o);
                        var location = r != null?(r.gameObject):null;
                        if (location == null && p is Door)
                        {
                            location = ((Door)p).ForceRoom;
                        }
                        ELNode.Store(locationRoot / o % location);
                        if (o == gameObject)
                        {
                            myCurrentRoom = r;
                        }
                    }
                }
                else
                {
                    if (!p.IsHidden)
                    {
                        ELNode.Store((locationRoot / o % p.Container));
                    }
                }
            }
        }
    }
コード例 #2
0
 private void UpdateSpeechBubble()
 {
     // Clear speech bubble if it's time.
     if (currentlySpeaking && Time.time > clearSpeechTime)
     {
         currentSpeechBubbleText = null;
         currentlySpeaking       = false;
         motorRoot.DeleteKey(SIAmSpeaking);
     }
 }
コード例 #3
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));
        }
    }
コード例 #4
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;
                }
            }
        }
    }