Ejemplo n.º 1
0
    public override ClueItem GetItem(Noun n1, Noun n2)
    {
        string sprite = "Newspaper";
        string desc   = "";

        if (n1.Type() == NounType.Identity)
        {
            desc = "A newspaper article about " + n1.AsSubject() + ", who " + n2.AsObject() + ".";
        }
        else if (n2.Type() == NounType.Identity)
        {
            desc = "A newspaper article about " + n2.AsSubject() + ", who " + n1.AsObject() + ".";
        }
        else if (n1.Type() == NounType.Name)
        {
            desc = "A newspaper article about " + n1.AsSubject() + ", who " + n2.AsObject() + ".";
        }
        else if (n2.Type() == NounType.Name)
        {
            desc = "A newspaper article about " + n2.AsSubject() + ", who " + n1.AsObject() + ".";
        }

        ClueItem item = new ClueItem(n1, n2, Verb.Has, sprite, desc);

        return(item);
    }
 private void Start()
 {
     _textMeshProUGUI      = transform.GetComponent <TextMeshProUGUI>();
     _clueItem             = transform.parent.GetComponent <ClueItem>();
     _text                 = _clueItem.item.clue;
     _textMeshProUGUI.text = _text;
 }
    void HandleClueViewing(ref ClueItem currentClue)
    {
        // Return the ClueItem information stored in the Clue Item we just clicked on
        // and log it to the console.
        print(currentClue.ToString()); // overrode its ToString method.

        if (cloneClueItem != false)
        {
            cloneClueItem.isInspectable = true;
        }

        // Set up position to set up the light for inspecting the clueItem
        Vector3 clueLightLocation = new Vector3(0, 0, 0);

        if (cloneClue != null)
        {
            clueLightLocation = cloneClue.transform.position + _lightOffset;

            // Create a light to view inspectable clueItem
            if (inspectionLight == null)
            {
                inspectionLight = CreateLight(clueLightLocation);
            }
        }
    }
Ejemplo n.º 4
0
    public void PlayerFoundClue(ClueObject clue)
    {
        // TODO: check if the object is the not-paper photo. If so, play PICKUP
        AudioPlayer.PlaySound(AudioClipIndex.PAPER);
        ClueItem    item   = clue.mItem;
        PersonState player = mPeople[0];

        // add clue to journal
        if (item.info != null)
        {
            PlayerJournal.AddClue(item.info);
        }

        player.knowledge.AddKnowledge(item.info.GetSentence());

        List <ClueItem> clues = mCluesInRooms[mCurrentRoom];

        clues.Remove(item);
        Destroy(clue.gameObject);

        Sprite      relevantImage = SpriteManager.GetSprite(item.spriteName);
        DialogBlock discussion    = new DialogBlock(new PersonState[] { player }, OnClueDismissed);

        discussion.QueueDialogue(player, new Sprite[] { relevantImage }, item.description);
        mCluesFoundThisRound++;
        if (mCluesFoundThisRound >= MAX_CLUES_PER_ROUND)
        {
            discussion.QueueDialogue(player, new Sprite[] { }, "I'd better get back to the common area now.");
        }
        discussion.Start();
    }
Ejemplo n.º 5
0
 // Constructor that passes a ClueItem object by reference
 public ClueInfo(ref ClueItem item)
 {
     id          = item.ID;
     rating      = item.Rating;
     clueName    = item.ClueName;
     description = item.Description;
 }
Ejemplo n.º 6
0
    //Adds ClueItem and its ClueInfo passed from ClueItemInspector's raycasted ClueItem
    public void AddClue(ref ClueItem hitClue)
    {
        //Check if this ClueItem has already been found
        if (!hitClue.isCollected)
        {
            hitClue.isCollected = true;

            // Objects are not staying in this list between scenes

            _cluesCollected.Add(hitClue);
            ClueItem objectHit  = hitClue;
            ClueInfo objectInfo = new ClueInfo(ref hitClue);
            _clueInfoOfCollected.Add(objectInfo);

            print("Last collected clue: " + _clueInfoOfCollected[_clueInfoOfCollected.Count - 1].clueName);

            PopulateYarnVars();

            //Call for CanvasManager to enable "Gather Crew" buttons ONLY when enough clues are collected
            //TODO: Make sure this works even if cluesLeftToChoose changes. Might want to make a default int for the clues to get
            if (_cluesCollected.Count == AccusationManager.S.cluesLeftToChoose)
            {
                CanvasManager.S.enableGatherButtons();
            }
            //Creates a new button in the Clue Inventory UI
            if (UI_ButtonManager.S != null)
            {
                GameObject      button       = UI_ButtonManager.S.CreateButton(ref hitClue);;
                Button_ClueList buttonInfo   = button.AddComponent <Button_ClueList>();
                Button          buttonScript = button.GetComponent <Button>();
                //Be careful, setup dependent.
                Image clueIcon = button.GetComponent <Image>();

                //Button creation

                //Add Components and parameters that are specific to Clue Item
                buttonInfo.clueInfo = objectInfo;
                buttonScript.onClick.AddListener(buttonInfo.SelectClue);
                clueIcon.sprite = Resources.Load("Sprites\\" + objectInfo.clueName, typeof(Sprite)) as Sprite;
            }
            //Gives the player a notification that the clue was added

            if (UI_ButtonManager.S.addedClueNotification.transform.parent.gameObject.activeSelf)
            {
                clueCount++;

                UI_ButtonManager.S.addedClueNotif(true);

                Clues.setValue(clueCount);

                Debug.Log("Set the value!");
            }
        }
        else if (UI_ButtonManager.S.addedClueNotification.transform.parent.gameObject.activeSelf)
        {
            UI_ButtonManager.S.addedClueNotif(false);

            Loyalty.setValue(0);
        }
    }
Ejemplo n.º 7
0
 private void Start()
 {
     _textMeshProUGUI      = transform.GetComponent <TextMeshProUGUI>();
     _title                = "???";
     _clueItem             = transform.parent.GetComponent <ClueItem>();
     _textMeshProUGUI.text = _title;
 }
Ejemplo n.º 8
0
 // copy Constructor
 public ClueItem(ref ClueItem passedClueItem)
 {
     ID          = passedClueItem.id;
     Rating      = passedClueItem.rating;
     ClueName    = passedClueItem.clueName;
     Description = passedClueItem.description;
     IsCollected = passedClueItem.isCollected;
 }
    //Should change back to ref if it makes sense
    public void SetCurrentClue(GameObject objectHit)
    {
        if (currentClue == null)
        {
            //Separate ClueItem script management from clone manipulation

            currentClue = objectHit.GetComponent <ClueItem>();
            print("current clue:" + currentClue.ItemName);

            itemNameDisplay.text    = currentClue.ItemName;
            itemDescripDisplay.text = currentClue.Description;

            //Alex code  - Set current clue position to cam position
            Vector3 desiredViewingLocation = new Vector3(Camera.main.transform.position.x, Camera.main.transform.position.y, -1f);

            //Vector3 location to spawn clone
            //Vector3 desiredViewingLocation = cloneCluePos;

            cloneClue = Instantiate(objectHit, desiredViewingLocation, Quaternion.Euler(0, 0, 0));
            cloneClue.transform.localScale *= currentClue.cloneScale;
            cloneClue.transform.rotation    = Quaternion.Euler(currentClue.cloneRot.x, currentClue.cloneRot.y, currentClue.cloneRot.z);
            cloneClue.AddComponent <Rotater>();
            cloneClue.GetComponent <Rotater>().rotateSpeed   = 120f;
            cloneClue.GetComponent <Rotater>().diffThreshold = 40;

            CanvasClueObject.S.SetCloneClue(ref cloneClue);

            cloneClueCol = cloneClue.GetComponent <Collider>();

            cloneClueItem = cloneClue.GetComponent <ClueItem>();
            //cloneClueItem.isCollected = true;

            cloneClueCol.enabled  = false;
            cloneClueItem.enabled = false;

            inspectingItem = true;
        }


        //Needs to be replaced by clicking out

        /*
         * else if (objectHit.collider.GetComponent<ClueItem>() != currentClue)
         * {
         *  ResetCurrentClue();
         * }
         */
    }
Ejemplo n.º 10
0
    public override ClueItem GetItem(Noun n1, Noun n2)
    {
        // ensure n1 is the hair color
        if (n1.Type() == NounType.Identity)
        {
            Noun temp = n1;
            n1 = n2;
            n2 = temp;
        }

        string   spriteName  = Random.Range(0, 2) == 0 ? "Photo" : "Photo2"; //int range is max exclusive
        string   description = "A photo of the victim and " + n2.WithVictim() + ", who " + n1.AsObject() + ".";
        ClueItem item        = new ClueItem(n1, n2, Verb.Is, spriteName, description);

        return(item);
    }
Ejemplo n.º 11
0
    private ClueItem GetClueInternal(Noun n1, Noun n2)
    {
        NounType t1 = n1.Type();
        NounType t2 = n2.Type();

        foreach (GameObject g in clues)
        {
            ClueGenerator generator = g.GetComponent <ClueGenerator>();
            if (generator.MatchTypes(t1, t2))
            {
                ClueItem item = generator.GetItem(n1, n2);
                return(item);
            }
        }
        return(null);
    }
Ejemplo n.º 12
0
    public override ClueItem GetItem(Noun n1, Noun n2)
    {
        // ensure n1 is the identity
        if (n1.Type() == NounType.Name)
        {
            Noun temp = n1;
            n1 = n2;
            n2 = temp;
        }

        string   spriteName  = "Letter";
        string   description = "A letter to the victim about " + Utilities.bold(n2.ToString()) + ", " + n1.WithVictim() + ".";
        ClueItem item        = new ClueItem(n1, n2, Verb.Is, spriteName, description);

        return(item);
    }
Ejemplo n.º 13
0
    public override ClueItem GetItem(Noun n1, Noun n2)
    {
        string sprite = "";
        string desc   = "";

        if (n1 == Noun.Potion || n2 == Noun.Potion)
        {
            sprite = "Potion";
            desc   = "This is an airborne drug that causes temporary memory loss.";
        }
        // TODO: newspaper article about the victim
        // this could also be a backstory clue

        ClueItem item = new ClueItem(n1, n2, Verb.Has, sprite, desc);

        return(item);
    }
    //Specific to ClueItems for now. Need to make an overload function for other buttons, such as crew.
    public GameObject CreateButton(ref ClueItem clue)
    {
        //Placement params
        RectTransform   btnGroupRectTrans  = buttonGroup.GetComponent <RectTransform>();
        GridLayoutGroup btnGroupGridLayout = buttonGroup.GetComponent <GridLayoutGroup>();

        //Create button from buttonPrefab
        GameObject button = Instantiate(buttonPrefab, buttonGroup.GetComponent <RectTransform>()) as GameObject;

        //Params and Components that have to be set outside the Prefab
        Button buttonScript;

        buttonScript = button.GetComponent <Button>();

        RectTransform btnRectTrans = button.GetComponent <RectTransform>();


        float rowsRaw =
            ((scrollingContent.rect.height - (btnGroupGridLayout.padding.top + btnGroupGridLayout.padding.top)) /
             (btnGroupGridLayout.cellSize.y + btnGroupGridLayout.spacing.y));

        if (rowsRaw > (Mathf.Ceil(buttonsInGroup.Count / btnGroupGridLayout.constraintCount)))
        {
            rowsRaw += Mathf.Ceil(buttonsInGroup.Count / btnGroupGridLayout.constraintCount);
        }
        int rowsAvailable = Mathf.FloorToInt(rowsRaw);

        //if (Mathf.Abs(btnRectTrans.anchoredPosition.y) >= scrollingContent.rect.height)

        print(rowsAvailable);
        print(buttonsInGroup.Count);
        print(rowsAvailable * btnGroupGridLayout.constraintCount);

        if (buttonsInGroup.Count + 1 > rowsAvailable * btnGroupGridLayout.constraintCount)
        {
            //Updates size of Content in UI
            scrollingContent.sizeDelta = new Vector2(0, scrollingContent.rect.height + btnGroupGridLayout.cellSize.y + btnGroupGridLayout.spacing.y);
        }
        //loadImage(clue.icon);

        //Currently not super secure, because it gets Text in ALL children. Needs to be changed, unless all buttons are set up the same way.
        button.GetComponentInChildren <Text>().text = clue.ItemName;

        buttonsInGroup.Add(button);
        return(button);
    }
Ejemplo n.º 15
0
 // Constructor that passes a ClueItem object by reference
 public ClueInfo(ref ClueItem item)
 {
     id          = item.ID;
     clueName    = item.ItemName;
     rating      = item.Rating;
     description = item.Description;
     clueOwner1  = item.ClueOwner1;
     clueOwner2  = item.ClueOwner2;
     location    = item.Location;
     addedToYarn = false;
     // Set if the Item is considered a clue if the ClueItem GameObject is tagged as "Clue" in Unity
     if (item.CompareTag("Clue"))
     {
         isClue = true;
     }
     else
     {
         isClue = false;
     }
 }
    //
    public void ResetCurrentClue()
    {
        //currentClue.transform.position = cluePrevPos;
        //currentClue.transform.rotation = cluePrevRot;
        currentClue.isInspectable = false;
        if (cloneClue != null)
        {
            Destroy(cloneClue);
        }

        currentClue   = null;
        cloneClue     = null;
        cloneClueItem = null;

        //when we're not inspecting anything, we won't need the light
        if (inspectionLight != null)
        {
            Destroy(inspectionLight);
        }

        inspectingItem = false;
    }
Ejemplo n.º 17
0
    void RaycastForClues()
    {
        // On Mouse Button Up Collect the object you have raycasted against if it is indeed a clue
        if (Input.GetMouseButtonUp(0))
        {
            // Make sure function is firing
            print("ClueManager MouseUpAsButton function entered.");

            Vector3    mousePosition;
            RaycastHit hit;
            Ray        ray;

            //Update ray
            ray           = Camera.main.ScreenPointToRay(Input.mousePosition);
            mousePosition = Input.mousePosition;

            //The raycast works but in scene view it points towards canvas
            Debug.DrawRay(transform.position, mousePosition, Color.green);

            if (Physics.Raycast(ray, out hit, 100.0f, _clueLayer))
            {
                print("hit on Clue Layer");
                // If object hit is a piece of evidence
                if (hit.collider.gameObject.tag == "Evidence")
                {
                    Debug.Log("You have selected the " + hit.transform.GetComponent <ClueItem> ().ClueName);
                    // Objects are not staying in this list between scenes
                    _cluesCollected.Add(hit.collider.gameObject.GetComponent <ClueItem>());
                    ClueItem objectHit  = hit.collider.gameObject.GetComponent <ClueItem> ();
                    ClueInfo objectInfo = new ClueInfo(ref objectHit);
                    _clueInfoOfCollected.Add(objectInfo);
                    // Set the object hit setActive value to false
                    hit.collider.gameObject.SetActive(false);
                }
            }
        }
    }
Ejemplo n.º 18
0
    public static void Generate(out PersonState[] people, out ClueInfo startingClue, out List <ClueItem> cluesToScatter)
    {
        cluesToScatter = new List <ClueItem>();

        // Randomly determine the world

        // The player is going to have some natural questions, and we should
        // create clues that answer them, otherwise they're going to be unsatisfied.

        // questions:
        // who's the killer?
        // why don't we remember anything?
        // where are we?
        // who is each person?
        // why are we here?
        // what's the story? what events led to where we are now?

        // TODO - have predermined pairings between backstory / motive / identity

        // Generate people by shuffling a list of indexes for each attribute type.
        Noun[][] attributeLists = { appearances, identities, names };
        int[][]  shuffledLists  =
        {
            Utilities.RandomList(3, 3),
            Utilities.RandomList(3, 3),
            Utilities.RandomList(3, 3),
            // Don't randomize backstories and motives
            // Utilities.RandomList(backstories.Length, 3),
            // Utilities.RandomList(3, 3),
        };
        people = new PersonState[3];
        for (int i = 0; i < names.Length; ++i)
        {
            people[i] = new PersonState(i);
            Dictionary <NounType, Noun> attributes = people[i].AttributeMap;
            for (int attrIndex = 0; attrIndex < attributeLists.Length; attrIndex++)
            {
                Noun playerAttr = attributeLists[attrIndex][shuffledLists[attrIndex][i]];
                attributes.Add(playerAttr.Type(), playerAttr);
            }
            Noun[] depNouns = mDependentNouns[attributes[NounType.Identity]];
            for (int nounI = 0; nounI < depNouns.Length; nounI++)
            {
                attributes.Add(depNouns[nounI].Type(), depNouns[nounI]);
            }
        }
        // Each player knows the existence of the hair-colors of the other players
        for (int i = 0; i < names.Length; i++)
        {
            for (int j = 0; j < names.Length; j++)
            {
                if (i != j)
                {
                    people[i].knowledge.KnownWords.Add(people[j].AttributeMap[NounType.HairColor]);
                }
            }
        }

        // Pick a killer
        GameState.Get().KillerId = Random.Range(0, 3);
        people[GameState.Get().KillerId].IsKiller = true;
        // Pick a person to have no motive
        int innocentId = Random.Range(0, 2); // two possible values

        if (innocentId >= GameState.Get().KillerId)
        {
            innocentId += 1;
        }

        // Generate an additional clue for the killer
        // starting: victim wrote a name in blood
        Noun     killerName = people[GameState.Get().KillerId].AttributeMap[NounType.Name];
        ClueInfo deathClue  = new ClueInfo(Noun.SuspectedName, killerName);

        startingClue = deathClue;

        // Generate clues for everything else
        // this is probably too many, and we want to strategically
        // omit certain clues (so that we don't have an immediate person -> name clue)
        for (int i = 0; i < names.Length; ++i)
        {
            Noun hair      = people[i].AttributeMap[NounType.HairColor];
            Noun identity  = people[i].AttributeMap[NounType.Identity];
            Noun name      = people[i].AttributeMap[NounType.Name];
            Noun motive    = people[i].AttributeMap[NounType.Motive];
            Noun backstory = people[i].AttributeMap[NounType.Backstory];

            ClueItem appearanceToIdentity = ClueManifest.GetClue(hair, identity);
            if (appearanceToIdentity != null)
            {
                cluesToScatter.Add(appearanceToIdentity);
            }
            else
            {
                Debug.Log("No clue for " + hair + " <-> " + identity + "!");
            }

            ClueItem identityToName = ClueManifest.GetClue(identity, name);
            if (identityToName != null)
            {
                cluesToScatter.Add(identityToName);
            }
            else
            {
                Debug.Log("No clue for " + hair + " <-> " + identity + "!");
            }

            if (i != innocentId)
            {
                // Connect identity to motive (for thematic and mechanical reasons)
                ClueItem motiveClue = ClueManifest.GetClue(identity, motive);
                if (motiveClue != null)
                {
                    cluesToScatter.Add(motiveClue);
                }
                else
                {
                    Debug.Log("No clue for " + identity + " <-> " + motive + "!");
                }
            }
            // Generate a clue connecting something to backstory
            Noun     identityOrName = Random.Range(0, 2) == 0 ? identity : name;
            ClueItem backstoryClue  = ClueManifest.GetClue(identityOrName, backstory);
            if (backstoryClue != null)
            {
                cluesToScatter.Add(backstoryClue);
            }
            else
            {
                Debug.Log("No clue for " + identityOrName + " <-> " + backstory + "!");
            }
        }
        // Unique clues
        ClueItem potion = ClueManifest.GetClue(Noun.Potion, Noun.MemoryLoss);

        if (potion != null)
        {
            cluesToScatter.Add(potion);
        }
        else
        {
            Debug.Log("No clue for " + Noun.Potion + " <-> " + Noun.MemoryLoss + "!");
        }
    }
Ejemplo n.º 19
0
 public void SetCloneClue(ref GameObject passedClone)
 {
     cloneClue     = passedClone;
     cloneClueItem = passedClone.GetComponent <ClueItem>();
 }
Ejemplo n.º 20
0
    private void StartStage(GameStage stage)
    {
        Debug.Log("starting stage " + stage);
        mCurrentStage = stage;

        if (stage == GameStage.SEARCH_1)
        {
            // NEVER COMMIT THESE LINES
            // mArrestedPerson = Player;
            // stage = GameStage.CLOSURE;
        }
        if (stage == GameStage.SEARCH_1 || stage == GameStage.SEARCH_2 || stage == GameStage.SEARCH_3)
        {
            if (stage == GameStage.SEARCH_1)
            {
                PlayerJournal.AddListen(VictimId, mStartingClue.GetSentence()); // wait until after the dialogue is over to add this to the player journal
            }

            UIController.Get().ShowJournalButton();
            UIController.Get().ShowMusicButton();

            // assign npcs to rooms (for now, ensure they go to different rooms)
            int[] roomChoices = Utilities.RandomList(clueRooms.Length, 2);
            for (int i = 0, j = 0; i < 3; ++i)
            {
                mRoundClues[i] = null;

                if (i != PlayerId)
                {
                    string npcRoom = clueRooms[roomChoices[j++]];
                    MoveToRoom(i, npcRoom);

                    // npcs pick up a clue in the room they move to
                    if (mCluesInRooms.ContainsKey(npcRoom))
                    {
                        List <ClueItem> cluesInRoom = mCluesInRooms[npcRoom];
                        if (cluesInRoom.Count > 0)
                        {
                            int      clueIdx = Random.Range(0, cluesInRoom.Count);
                            ClueItem clue    = cluesInRoom[clueIdx];
                            cluesInRoom.RemoveAt(clueIdx);

                            ClueInfo info = clue.info;
                            mPeople[i].knowledge.AddKnowledge(info.GetSentence());
                            mRoundClues[i] = info;
                        }
                    }
                }
            }

            MoveToRoom(PlayerId, mCurrentRoom); // hack to reload room with npcs gone
        }
        else if (stage == GameStage.COMMUNAL_1 || stage == GameStage.COMMUNAL_2 || stage == GameStage.COMMUNAL_3)
        {
            for (int i = 0; i < 3; ++i)
            {
                MoveToRoom(i, openingScene);
            }
        }
        else if (stage == GameStage.POLICE)
        {
            MoveToRoom(PlayerId, "EndScene");
        }
        else if (stage == GameStage.REVEAL)
        {
            DialogBlock discussion = new DialogBlock(mPeople, OnDialogueDismissed);

            // check each accusation
            int[] votes          = { 0, 0, 0 };
            int   highestVoteIdx = -1;
            int   majority       = -1;
            int   mostVotes      = 0;
            int   totalVotes     = 0;
            for (int i = 0; i < 3; ++i)
            {
                if (mAccusations[i] >= 0 && mAccusations[i] < 3)
                {
                    votes[mAccusations[i]]++;
                    totalVotes++;
                    if (votes[mAccusations[i]] > mostVotes)
                    {
                        mostVotes      = votes[mAccusations[i]];
                        highestVoteIdx = mAccusations[i];
                    }

                    if (votes[mAccusations[i]] >= 2)
                    {
                        majority = mAccusations[i];
                    }
                }
            }

            if (majority >= 0)
            {
                discussion.QueueDialogue(Police, new Sprite[] { }, "So it was the " + mPeople[majority].AttributeMap[NounType.HairColor] + "?");
                discussion.QueueDialogue(Police, new Sprite[] { mPeople[majority].HeadSprite }, "You're under arrest, ma'am.");
                discussion.QueueDialogue(Police, new Sprite[] { mPeople[(majority + 1) % 3].HeadSprite, mPeople[(majority + 2) % 3].HeadSprite }, "You two, come along and we'll get official statements.");
                mWasAllArrested = false;
                mArrestedPerson = mPeople[majority];
            }
            else
            {
                // no one got a majority
                Sprite[] allThree = new Sprite[] { mPeople[0].HeadSprite, mPeople[1].HeadSprite, mPeople[2].HeadSprite };
                discussion.QueueDialogue(Police, allThree, "You can't agree on what happened?");
                discussion.QueueDialogue(Police, allThree, "I'm going to have to take you all in to the station.");
                mWasAllArrested = true;
            }

            discussion.Start();
        }
        else if (stage == GameStage.CLOSURE)
        {
            blackFade.SetTrigger("FadeOut");
            // Give me closure please!
            // TODO - tell more of the story.
            // TODO - typing sound
            if (mWasAllArrested)
            {
                mEpilogueLines.Add("Because you could not come to a decision as a group, all three of you were arrested.");
                if (Player.IsKiller)
                {
                    mEpilogueLines.Add("You were the killer.");
                }
                else
                {
                    mEpilogueLines.Add(mPeople[KillerId].AttributeMap[NounType.HairColor].AsSubject() + " was the killer.");
                }
            }
            else
            {
                if (mArrestedPerson.IsKiller && mArrestedPerson.IsPlayer)
                {
                    mEpilogueLines.Add("You were the killer, and you were caught.");
                }
                else if (!mArrestedPerson.IsKiller && mArrestedPerson.IsPlayer)
                {
                    mEpilogueLines.Add(mPeople[KillerId].AttributeMap[NounType.HairColor].AsSubject() + " was the killer, but you were the one arrested.");
                }
                else if (mArrestedPerson.IsKiller && !mArrestedPerson.IsPlayer)
                {
                    mEpilogueLines.Add(mPeople[KillerId].AttributeMap[NounType.HairColor].AsSubject() + " was the killer, and was correctly arrested.");
                }
                else if (!mArrestedPerson.IsKiller && !mArrestedPerson.IsPlayer)
                {
                    mEpilogueLines.Add(mPeople[KillerId].AttributeMap[NounType.HairColor].AsSubject() + " was the killer, but " + mArrestedPerson.AttributeMap[NounType.HairColor].AsSubject() + " was arrested instead.");
                }
                else if (!mArrestedPerson.IsKiller && Player.IsKiller)
                {
                    mEpilogueLines.Add("You were the killer, and you escaped because " + mArrestedPerson.AttributeMap[NounType.HairColor].AsSubject() + " was arrested instead.");
                }
                else
                {
                    // I dont think this is possible. But just in case...
                    if (Player.IsKiller)
                    {
                        mEpilogueLines.Add("You were the killer");
                    }
                    else
                    {
                        mEpilogueLines.Add(mPeople[KillerId].AttributeMap[NounType.HairColor].AsSubject() + " was the killer");
                    }
                    if (mArrestedPerson.IsPlayer)
                    {
                        mEpilogueLines.Add("You were arrested");
                    }
                    else
                    {
                        mEpilogueLines.Add(mArrestedPerson.AttributeMap[NounType.HairColor].AsSubject() + " was arrested");
                    }
                }
            }
            mEpilogueLines.Add("The killer " + mPeople[KillerId].AttributeMap[NounType.Identity].AsObject());
            mEpilogueLines.Add("The killer " + mPeople[KillerId].AttributeMap[NounType.Motive].AsObject());
            for (int j = 0; j < 3; j++)
            {
                mEpilogueLines.Add(mPeople[j].AttributeMap[NounType.HairColor].AsSubject() + " " + mPeople[j].AttributeMap[NounType.Name].AsObject());
                mEpilogueLines.Add(mPeople[j].AttributeMap[NounType.HairColor].AsSubject() + " " + mPeople[j].AttributeMap[NounType.Identity].AsObject());
            }

            InvokeRepeating("UpdateEpilogueText", 1.5f, 0.5f); // after 1 seconds start the epilogue text, and do a new line every 0.3 seconds
        }
    }
Ejemplo n.º 21
0
    public void OnRoomLoaded()
    {
        blackFade.ResetTrigger("FadeOut");
        blackFade.SetTrigger("FadeIn");

        mLoadSceneOperation = null;
        mLoadState          = LoadState.NONE;
        mPendingRoom        = null;

        SceneManager.SetActiveScene(SceneManager.GetSceneByName(mCurrentRoom)); // ensures instantiate objects are added to the current room's scene (so they'll be destroyed when leaving)

        // populate room with clues
        if (mCluesInRooms.ContainsKey(mCurrentRoom))
        {
            // TODO: I don't know what to do if there are more clues in this room than spawn points
            // maybe we should just make sure that never happens? maybe it's fine that certain clues never spawn?
            GameObject[] clueSpawns = GameObject.FindGameObjectsWithTag("ClueSpawn");
            int          numClues   = Mathf.Min(mCluesInRooms[mCurrentRoom].Count, clueSpawns.Length);

            List <ClueItem> clues     = mCluesInRooms[mCurrentRoom];
            int[]           clueSpots = Utilities.RandomList(clueSpawns.Length, numClues);
            for (int i = 0; i < numClues; ++i)
            {
                ClueItem   item    = clues[i];
                GameObject clueObj = GameObject.Instantiate(cluePrefab);
                clueObj.GetComponent <ClueObject>().mItem      = item;
                clueObj.GetComponent <SpriteRenderer>().sprite = SpriteManager.GetSprite(item.spriteName);

                // check this: it's annoying as hell when adding objects to scenes for some reason defaults their z to be too close to the camera
                // *but* for spawn points, it's actually convenient to be able to see them in the editor, yet have them be hidden in-game.
                // so, leave the spawn points in their stupid z-position, and spawn clues at their x,y and a sane z-position.
                Vector3 spawnPos = clueSpawns[clueSpots[i]].transform.position;
                clueObj.transform.position = new Vector3(spawnPos.x, spawnPos.y, 0);
            }
        }

        // maybe this is cleaner in its own function, like ContinueGameStage or whatever, idk
        Debug.Log(mCurrentRoom + " loaded. Current stage: " + mCurrentStage);
        if (mCurrentStage == GameStage.MENU)
        {
            mCurrentStage = GameStage.INTRO;

            DialogBlock discussion = new DialogBlock(mPeople, OnDialogueDismissed);
            discussion.QueueDialogue(mPeople[2], new Sprite[] { mPeople[2].HeadSprite }, "Ow...");
            discussion.QueueDialogue(mPeople[1], new Sprite[] { mPeople[1].HeadSprite }, "Ugh... where am I?", AudioClipIndex.HMM);
            discussion.QueueDialogue(mPeople[1], new Sprite[] { mPeople[1].HeadSprite }, "Who are you two?");
            discussion.QueueDialogue(mPeople[2], new Sprite[] { mPeople[2].HeadSprite }, "I don't know... I can't remember!");
            discussion.QueueDialogue(mPeople[1], new Sprite[] { mPeople[1].HeadSprite }, "What about you, " + Player.AttributeMap[NounType.HairColor] + "? What's your name?");
            discussion.QueueDialogue(Player, new Sprite[] { Player.HeadSprite }, "Me? I'm...", AudioClipIndex.SURPRISE_EH);
            discussion.QueueCustomSentence(Player, new Sprite[] { Player.HeadSprite }, new string[] { "Me" }, new string[] { "???" }, delegate { Debug.Log("YEAH WE GOT THE CALLBACK"); });
            discussion.QueueDialogue(mPeople[2], new Sprite[] { mPeople[2].HeadSprite }, "See, I'm not the only one!");
            discussion.QueueDialogue(mPeople[1], new Sprite[] { SpriteManager.GetSprite("Victim") }, "Ahhh! A body!!", AudioClipIndex.SURPRISE_AH);
            discussion.QueueDialogue(mPeople[1], new Sprite[] { SpriteManager.GetSprite("CrimeScene") }, "And there's a name written by it in blood: " + Utilities.bold(mStartingClue.nounB.ToString()) + "!");
            discussion.QueueDialogue(mPeople[2], new Sprite[] { mPeople[2].HeadSprite }, "Oh my gosh! Which one of you is " + mStartingClue.nounB + "?!");
            discussion.QueueDialogue(mPeople[1], new Sprite[] { mPeople[1].HeadSprite }, "Not me! I'm...");
            discussion.QueueDialogue(mPeople[1], new Sprite[] { mPeople[1].HeadSprite }, "I can't remember my name either!");
            discussion.QueueDialogue(mPeople[2], new Sprite[] { mPeople[2].HeadSprite }, "Oh sure! You're probably " + mStartingClue.nounB + ", and you killed this guy!");
            discussion.QueueDialogue(mPeople[1], new Sprite[] { mPeople[1].HeadSprite }, "Calm down, " + mPeople[2].AttributeMap[NounType.HairColor] + "!", AudioClipIndex.DISAGREE);
            discussion.QueueDialogue(mPeople[1], new Sprite[] { mPeople[1].HeadSprite }, "We don't know anything for sure.");
            discussion.QueueDialogue(mPeople[1], new Sprite[] { mPeople[1].HeadSprite }, "Let's look around and see if we can figure out what happened here.");
            discussion.QueueDialogue(mPeople[2], new Sprite[] { mPeople[2].HeadSprite }, "Ok, ok... sorry. We can search the place, but let's not stay separated for long.");
            discussion.QueueDialogue(Player, NonPlayersHeads, "Ok, let's meet back here soon.");
            discussion.Start();
        }
        else if (mCurrentStage == GameStage.COMMUNAL_1 || mCurrentStage == GameStage.COMMUNAL_2)
        {
            DialogBlock discussion = new DialogBlock(mPeople, OnDialogueDismissed);
            discussion.QueueDialogue(mPeople[1], NonPlayersHeads, "What did everyone find?");
            discussion.QueueInformationExchange();
            discussion.QueueDialogue(Player, NonPlayersHeads, "There must be more clues around.");
            discussion.Start();
        }
        else if (mCurrentStage == GameStage.COMMUNAL_3)
        {
            DialogBlock discussion = new DialogBlock(mPeople, OnDialogueDismissed);
            discussion.QueueDialogue(mPeople[1], NonPlayersHeads, "The police are almost here. Let's do a final round of information exchange.");
            discussion.QueueInformationExchange();
            discussion.QueueDialogue(mPeople[2], NonPlayersHeads, "Well, the police are here now.");
            discussion.Start();
        }
        else if (mCurrentStage == GameStage.POLICE)
        {
            DialogBlock discussion = new DialogBlock(mPeople, OnDialogueDismissed);
            discussion.QueueDialogue(Police, new Sprite[] { mPeople[0].HeadSprite, mPeople[1].HeadSprite, mPeople[2].HeadSprite }, "What happened here? How did that man die?");

            // TODO: ask the player for their opinion, either first or last
            discussion.QueueCustomSentence(mPeople[0], new Sprite[] { }, new string[] { "Killer" }, new string[] { "Blonde", "Brunette", "Redhead" }, sentence => {
                for (int personIdx = 0; personIdx < 3; ++personIdx)
                {
                    if (mPeople[personIdx].AttributeMap[NounType.HairColor] == sentence.Subject) // subject + direct object are sorted, so hair colour comes first
                    {
                        mAccusations[0] = personIdx;
                        Debug.Log("Player accused " + mAccusations[0]);
                        break;
                    }
                }
            });

            // get npc evaluations

            // multiple beliefs contribute to an AI thinking that someone is the killer:
            // 1) did the victim write their name in blood?
            // 2) did the killer have a motive?

            Noun[] hairColors = new Noun[] {
                mPeople[0].AttributeMap[NounType.HairColor],
                mPeople[1].AttributeMap[NounType.HairColor],
                mPeople[2].AttributeMap[NounType.HairColor]
            };

            Sentence[] named = new Sentence[]
            {
                new Sentence(hairColors[0], Verb.Is, Noun.SuspectedName, Adverb.True),
                new Sentence(hairColors[1], Verb.Is, Noun.SuspectedName, Adverb.True),
                new Sentence(hairColors[2], Verb.Is, Noun.SuspectedName, Adverb.True),
            };

            Sentence[] motive = new Sentence[]
            {
                new Sentence(hairColors[0], Verb.Has, Noun.Motive, Adverb.True),
                new Sentence(hairColors[1], Verb.Has, Noun.Motive, Adverb.True),
                new Sentence(hairColors[2], Verb.Has, Noun.Motive, Adverb.True)
            };

            for (int i = 1; i < 3; ++i)
            {
                float[] namedScores     = new float[3];
                float[] motiveScores    = new float[3];
                float[] innocenceScores = new float[3];
                float[] killerScores    = new float[3];

                PersonState p = mPeople[i];
                Knowledge   personKnowledge = p.knowledge;
                Sprite[]    sprite          = { mPeople[i].HeadSprite };

                int   bestSuspect = -1;
                float bestScore   = 0f;
                for (int j = 0; j < 3; ++j)
                {
                    namedScores[j]  = personKnowledge.VerifyBelief(named[j]);
                    motiveScores[j] = personKnowledge.VerifyBelief(motive[j]);
                    killerScores[j] = (namedScores[j] + motiveScores[j]) / 2;
                    if (killerScores[j] > bestScore)
                    {
                        bestScore   = killerScores[j];
                        bestSuspect = j;
                    }
                }

                if (bestScore == 0f)
                {
                    // TODO: check innocence
                    discussion.QueueDialogue(mPeople[i], sprite, "I have no idea.");
                    mAccusations[i] = -1;
                }
                else
                {
                    if (bestSuspect == i)
                    {
                        // this is me! Don't accuse myself.
                        if (Random.Range(0, 100) == 0)
                        {
                            discussion.QueueDialogue(p, sprite, "Well I think I did it, but I'm not going to say that out loud.");
                            discussion.QueueDialogue(p, sprite, "...Oh wait.");
                            mAccusations[i] = bestSuspect;
                            continue;
                        }
                        else
                        {
                            // look for another person to pin the blame on
                            bestScore   = 0;
                            bestSuspect = -1;
                            for (int j = 0; j < 3; ++j)
                            {
                                if (j == i)
                                {
                                    continue;
                                }
                                if (killerScores[j] > bestScore)
                                {
                                    bestScore   = killerScores[j];
                                    bestSuspect = j;
                                }
                            }

                            if (bestSuspect < 0)
                            {
                                // randomly accuse someone else
                                int randomAccusation = Random.Range(0, 3);
                                if (randomAccusation == i)
                                {
                                    randomAccusation = (randomAccusation + 1) % 3;
                                }
                                discussion.QueueDialogue(p, sprite, hairColors[randomAccusation] + " did it!");
                                mAccusations[i] = randomAccusation;
                                continue;
                            }
                        }
                    }

                    // explain the accusation
                    mAccusations[i] = bestSuspect;
                    string confidenceQualifier = "";
                    if (bestScore >= 1)
                    {
                        confidenceQualifier = "I'm certain ";
                    }
                    else if (bestScore >= 0.5)
                    {
                        confidenceQualifier = "I'm pretty sure ";
                    }
                    else
                    {
                        confidenceQualifier = "I think ";
                    }
                    discussion.QueueDialogue(p, sprite, confidenceQualifier + hairColors[bestSuspect] + " did it.");
                    List <string> namedExplanation = p.knowledge.ExplainBelief(named[bestSuspect]);
                    foreach (string s in namedExplanation)
                    {
                        discussion.QueueDialogue(p, sprite, s);
                    }

                    List <string> motiveExplanation = p.knowledge.ExplainBelief(motive[bestSuspect]);
                    if (motiveExplanation.Count > 0)
                    {
                        if (namedExplanation.Count > 0)
                        {
                            discussion.QueueDialogue(p, sprite, "Also...");
                        }

                        foreach (string s in motiveExplanation)
                        {
                            discussion.QueueDialogue(p, sprite, s);
                        }
                    }
                }
            }

            // discussion.QueueCustomSentence();

            /*
             * Sentence killer0 = new Sentence(Noun.Blonde, Verb.Is, Noun.Killer, Adverb.True);
             * Sentence killer1 = new Sentence(Noun.Brunette, Verb.Is, Noun.Killer, Adverb.True);
             * Sentence killer2 = new Sentence(Noun.Redhead, Verb.Is, Noun.Killer, Adverb.True);
             * for (int i = 0; i < 3; ++i)
             * {
             *  if(i != PlayerId)
             *  {
             *      Knowledge personKnowledge = mPeople[i].knowledge;
             *      Noun myHair = mPeople[i].AttributeMap[NounType.HairColor];
             *      Sprite[] sprite = { mPeople[i].HeadSprite };
             *
             *      float confidence0 = personKnowledge.VerifyBelief(killer0);
             *      float confidence1 = personKnowledge.VerifyBelief(killer1);
             *      float confidence2 = personKnowledge.VerifyBelief(killer2);
             *
             *      if (confidence0 > 0 && myHair != Noun.Blonde)
             *          discussion.QueueDialogue(mPeople[i], sprite, "I think BLONDE did it (confidence " + confidence0 + ")");
             *      else if (confidence1 > 0 && myHair != Noun.Brunette)
             *          discussion.QueueDialogue(mPeople[i], sprite, "I think BROWN did it (confidence " + confidence1 + ")");
             *      else if (confidence2 > 0 && myHair != Noun.Redhead)
             *          discussion.QueueDialogue(mPeople[i], sprite, "I think RED did it (confidence " + confidence2 + ")");
             *      else
             *      {
             *          float innocenceBlonde = personKnowledge.VerifyBelief(new Sentence(Noun.Blonde, Verb.Is, Noun.Killer, Adverb.False));
             *          float innocenceBrown = personKnowledge.VerifyBelief(new Sentence(Noun.Brunette, Verb.Is, Noun.Killer, Adverb.False));
             *          float innocenceRed = personKnowledge.VerifyBelief(new Sentence(Noun.Redhead, Verb.Is, Noun.Killer, Adverb.False));
             *
             *          if (myHair == Noun.Blonde)
             *          {
             *              if (innocenceBrown > 0f || innocenceRed > 0f)
             *              {
             *                  string innocentName = innocenceBrown > innocenceRed ? "BROWN" : "RED";
             *                  string guiltyName = innocenceBrown > innocenceRed ? "RED" : "BROWN";
             *                  discussion.QueueDialogue(mPeople[i], sprite, "Well I didn't do it, and " + innocentName + " didn't do it, so " + guiltyName + " did.");
             *              }
             *              else
             *              {
             *                  discussion.QueueDialogue(mPeople[i], sprite, "I have no idea.");
             *              }
             *          }
             *          else if (myHair == Noun.Brunette)
             *          {
             *              if (innocenceBlonde > 0f || innocenceRed > 0f)
             *              {
             *                  string innocentName = innocenceBlonde > innocenceRed ? "BLONDE" : "RED";
             *                  string guiltyName = innocenceBlonde > innocenceRed ? "RED" : "BLONDE";
             *                  discussion.QueueDialogue(mPeople[i], sprite, "Well I didn't do it, and " + innocentName + " didn't do it, so " + guiltyName + " did.");
             *              }
             *              else
             *              {
             *                  discussion.QueueDialogue(mPeople[i], sprite, "I have no idea.");
             *              }
             *
             *          }
             *          else if (myHair == Noun.Redhead)
             *          {
             *              if (innocenceBrown > 0f || innocenceBlonde > 0f)
             *              {
             *                  string innocentName = innocenceBrown > innocenceBlonde ? "BROWN" : "BLONDE";
             *                  string guiltyName = innocenceBrown > innocenceBlonde ? "BLONDE" : "BROWN";
             *                  discussion.QueueDialogue(mPeople[i], sprite, "Well I didn't do it, and " + innocentName + " didn't do it, so " + guiltyName + " did.");
             *              }
             *              else
             *              {
             *                  discussion.QueueDialogue(mPeople[i], sprite, "I have no idea.");
             *              }
             *          }
             *      }
             *  }
             * }
             */
            discussion.Start();
        }
    }
    // helper methods
    //TODO This needs to work with mobile as well. Look into Unity's touch class to get an idea of how we can implement this with a touch screen.
    void HandleRotation(ref ClueItem currentClue)
    {
        // If the item is inspectable we handle input to rotate the object.
        // W and S rotate it around the x-axis while A and D rotate around the y-axis
        if (currentClue.isInspectable)
        {
            // Rotate object based on the button pressed
            // TODO Objects not rotating as preferred.

            //			// The following handles code for inspecting (rotating) ClueItems on PC
            //            if (Input.GetKey(KeyCode.W))
            //            {
            //                currentClue.transform.RotateAround(centerOfItem, Vector3.right, currentClue.rotateSpeed * Time.deltaTime);
            //            }
            //            else if (Input.GetKeyUp(KeyCode.W))
            //            {
            //                //rigidbody.constraints = RigidbodyConstraints.None;
            //            }
            //            else if (Input.GetKey(KeyCode.S))
            //            {
            //                //rigidbody.constraints = RigidbodyConstraints.FreezePosition;
            //                currentClue.transform.RotateAround(centerOfItem, Vector3.right, -currentClue.rotateSpeed * Time.deltaTime);
            //            }
            //            else if (Input.GetKeyUp(KeyCode.S))
            //            {
            //                //rigidbody.constraints = RigidbodyConstraints.None;
            //            }
            //            else if (Input.GetKey(KeyCode.A))
            //            {
            //                //rigidbody.constraints = RigidbodyConstraints.FreezePosition;
            //                currentClue.transform.RotateAround(centerOfItem, Vector3.up, currentClue.rotateSpeed * Time.deltaTime);
            //            }
            //            else if (Input.GetKeyUp(KeyCode.A))
            //            {
            //                //rigidbody.constraints = RigidbodyConstraints.None;
            //            }
            //            else if (Input.GetKey(KeyCode.D))
            //            {
            //                //rigidbody.constraints = RigidbodyConstraints.FreezePosition;
            //                currentClue.transform.RotateAround(centerOfItem, Vector3.up, -currentClue.rotateSpeed * Time.deltaTime);
            //            }
            //            else if (Input.GetKeyUp(KeyCode.D))
            //            {
            //                //rigidbody.constraints = RigidbodyConstraints.None;
            //            }

            //This is just to text touch drag functionality on Macs/PCs
            float x = 0;
            float y = 0;

            // //if (Application.platform == RuntimePlatform.WindowsEditor || Application.platform == RuntimePlatform.OSXEditor)
            // if (!touchControlled)
            // {
            //     //VERY GHETTO, DOES NOT FULLY WORK
            //     if (Input.GetMouseButton(0))
            //     {
            //         Vector3 pos =
            //         new Vector3 (0, 0, 0);
            //         //new Vector3(Screen.width/2,Screen.height/2, 0);


            //         pos.x = cloneClueCol.bounds.center.x + Screen.width/2 - Input.mousePosition.x;
            //         /*
            //         float xPos = Screen.width / 2;
            //         float xRange = Screen.width / 6;
            //         float yPos = Screen.height / 2;
            //         float yRange = Screen.height / 8;

            //         if (pos.x > xPos + xRange)
            //             pos.x = xPos + xRange;
            //         else if (pos.x < xPos - xRange)
            //             pos.x = xPos - xRange;

            //         if (pos.y > yPos + yRange)
            //             pos.y = yPos + yRange;
            //         else if (pos.y < yPos - yRange)
            //             pos.y = yPos - yRange;
            //             */
            //         print(pos);

            //         //print(pos.x);
            //         //print(pos.y);

            //         x = pos.x/100;
            //         y = pos.y/100;
            //     }
            // }

            //else
            if (touchControlled)
            {
                // The following handles code for inspecting (rotating) clues on Mobile
                Touch myTouch = Input.GetTouch(0);

                x = myTouch.deltaPosition.x;
                y = myTouch.deltaPosition.y;
            }

            if (Mathf.Abs(y) > Mathf.Abs(x))
            {
                // We are using the y variable in AngleAxis because moving our finger up and down would
                // make the object rotate on it's x (right) axis

                cloneClue.transform.RotateAround(centerOfClone, Vector3.right, y * currentClue.rotateSpeed * Time.deltaTime);
//				rb.constraints = RigidbodyConstraints.FreezePosition;
//				rb.constraints = RigidbodyConstraints.FreezeRotationY;
//				rb.constraints = RigidbodyConstraints.FreezeRotationZ;
            }

            if (Mathf.Abs(x) > Mathf.Abs(y))
            {
                // We are using the x variable in AngleAxis because moving our finger left and right would
                // make the object rotate on it's y (world up) axis

                cloneClue.transform.RotateAround(centerOfClone, Vector3.up, x * currentClue.rotateSpeed * Time.deltaTime);
//				rb.constraints = RigidbodyConstraints.FreezePosition;
//				rb.constraints = RigidbodyConstraints.FreezeRotationX;
//				rb.constraints = RigidbodyConstraints.FreezeRotationZ;
            }
        }
    }