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); } } }
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(); }
// 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; }
//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); } }
private void Start() { _textMeshProUGUI = transform.GetComponent <TextMeshProUGUI>(); _title = "???"; _clueItem = transform.parent.GetComponent <ClueItem>(); _textMeshProUGUI.text = _title; }
// 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(); * } */ }
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); }
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); }
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); }
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); }
// 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; }
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); } } } }
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 + "!"); } }
public void SetCloneClue(ref GameObject passedClone) { cloneClue = passedClone; cloneClueItem = passedClone.GetComponent <ClueItem>(); }
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 } }
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; } } }