hints.js
1    function getHints()
2    {
3      g.suspects = shuffleArray(g.suspects);
4      let hints = [];
5    
6      hints.push(getHint(g.culprit.attributes.gender));
7      hints.push(getHint(g.culprit.attributes.body));
8      hints.push(getHint(g.culprit.attributes.height));
9      hints.push(getHint(g.culprit.attributes.hair));
10   
11     hints = hints.concat(getSingleHints());
12     hints = hints.concat(getDistractors());
13   
14     let roomArray = objectToArray(g.rooms);
15     let places = roomArray.concat(g.suspects);
16   
17     let numHints = Math.floor(Math.random() * (places.length));
18     numHints = Math.max(4, g.numSuspects, numHints);
19     g.player.numHintsToFind = numHints;
20     hints = getLinkedHints(hints);
21     g.player.maxScore += (g.player.numHintsToFind * g.POINTS_PER_HINT);
22   
23     for (let i = 0; i < numHints; i++)
24     {
25       let index = Math.floor(Math.random() * places.length);
26       let place = places[index];
27       hints[i].speaker = place.name;
28       place.hints.push(hints[i]);
29     }
30     return numHints;
31   }
32   
33   function getHint(type)
34   {
35     let hints = [];
36     switch (type)
37     {
38   //gender
39       case g.FEMALE:
40         hints.push(`I heard a woman's voice right before the incident.`);
41         hints.push(`You can't fool me. A lady was responsible for this.`);
42         hints.push(`It wasn't a man who did this.`);
43         hints.push(`None of the guys around here would do such a thing.`);
44         break;
45   
46       case g.MALE:
47         hints.push(`I heard a deep voice right before it all happened.`);
48         hints.push(`It was definitely a guy who did this.`);
49         hints.push(`None of the ladies here would hurt a fly.`);
50         hints.push(`I'm certain it wasn't a girl who did this.`);
51         break;
52   
53   //body type
54       case g.LIGHT:
55         hints.push(`The victim was heavier than the culprit.`);
56         hints.push(`The footprints in the area were rather faint.`);
57         hints.push(`The culprit didn't even make the floor squeak.`);
58         hints.push(`The culprit is rather slender.`);
59         break;
60   
61   
62       case g.HEAVY:
63         hints.push(`The floor really creaked under the culprit's feet.`);
64         hints.push(`I'm sure the culprit had to squeeze through the doorway.`);
65         hints.push(`The footprints dug into the ground pretty deeply.`);
66         hints.push(`It's pretty obvious the culprit is heavyset.`);
67         break;
68   
69   //height
70       case g.TALL:
71         hints.push(`The culprit had to bend their head to escape through the door.`);
72         hints.push(`The culprit was probably light-headed from being so tall.`);
73         hints.push(`I doubt the culprit could fit under the table.`);
74         hints.push(`The culprit cast a long shadow.`);
75         break;
76   
77       case g.SHORT:
78         hints.push(`I doubt the culprit can reach the upper cupboards.`);
79         hints.push(`I'm sure the culprit needed a ladder to get the drop on the victim.`);
80         hints.push(`The culprit can probably run right under a table without bending.`);
81         hints.push(`I bet the culprit often needs to use a ladder.`);
82         break;
83   
84   //hair
85       case g.LONG:
86         hints.push(`Long strands of hair were found at the crime scene.`);
87         hints.push(`Long hair was found on the culprit's brush.`);
88         hints.push(`I'm sure the culprit doesn't have short hair.`);
89         hints.push(`No one with short hair would do such a thing.`);
90         break;
91   
92       case g.TRIMMED:
93         hints.push(`Short hair was found at the scene of the crime.`);
94         hints.push(`Long-haired people wouldn't hurt a fly.`);
95         hints.push(`Short hair, short temper, I always say.`);
96         hints.push(`The culprit reeked of a recent haircut.`);
97         break;
98   
99       default:
100        console.log(`Couldn’t process the culprit hint.`);
101    }
102  
103    let index = Math.floor(Math.random() * hints.length);
104    return {
105      hint: hints[index],
106      type: type,
107      speaker: ""};
108  }
109  
110  function getSingleHints()
111  {
112    let numHints = Math.floor(Math.random() * 4);
113    let hints = [];
114  
115    for (let i = 0; i < g.numHints; i++)
116    {
117      let s = Math.floor(Math.random() * g.suspects.length);
118      let suspect = g.suspects[s];
119  
120  
121      if (suspect.name === g.culprit.name || suspect.name === g.suspects[i].name)
122      {
123        continue;
124      }
125  
126      let hint = {type: "profession", speaker: ""};
127  
128      let possibles =
129          [
130            `The ${suspect.profession} was nowhere near the crime scene.`,
131            `I've known the ${suspect.profession} for years. Never'd never hurt a fly.`,
132            `The ${suspect.profession} got here after the crime was committed.`,
133            `There's no way the ${suspect.profession} did this.`,
134            `The cat knows a mean person when he meets one, and he likes the ${suspect.profession}.`,
135            `The ${suspect.profession} didn't have a motive for this crime.`,
136            `There are people more dangerous than the ${suspect.profession}.`,
137            `You're more likely to have done it than the ${suspect.profession}, Detective.`
138          ];
139  
140      let index = Math.floor(Math.random() * possibles.length);
141      hint.hint = possibles[index];
142      hint.profession = suspect.profession;
143      hints.push(hint);
144    }
145    return hints;
146  }
147  
148  function getDistractors()
149  {
150    let hints = [];
151    hints.push(`There was a lot of yelling before the incident.`);
152    hints.push(`I'm sure there was a long history of animosity between the culprit and the victim.`);
153    hints.push(`The victim was always so nice to me.`);
154    hints.push(`It's a terrible shame, what happened.`);
155    hints.push(`Have you checked all the rooms for hints?`);
156    hints.push(`I don't have anything I want to share with you right now.`);
157    hints.push(`Are you new to this kind of work?`);
158    hints.push(`I think I saw the culprit running from the scene.`);
159    hints.push(`The victim really didn't deserve that.`);
160    hints.push(`I'm going to have nightmares about this for weeks.`);
161    hints.push(`I'm just glad it wasn't me who got hurt.`);
162    hints.push(`All this interrogating is making me hungry.`);
163    hints.push(`My brother used to be a detective.`);
164    hints.push(`Did you notice if there was a cat around?`);
165    hints.push(`Where did I leave my umbrella?`);
166    hints.push(`I've never been attacked before myself.`);
167    hints.push(`My kid sister used to get into scrapes.`);
168    hints.push(`There were footprints at the scene of the crime.`);
169    hints.push(`I heard a hair sample was found at the crime scene.`);
170    hints.push(`I can't believe there's someone among us who could do such a thing.`);
171    hints.push(`I wish I could be more help to you.`);
172    hints.push(`I'll let you know if I think of something useful.`);
173    hints.push(`I was the one who called the police.`);
174    hints.push(`How long are they going to keep us locked in here?`);
175    hints.push(`You don't happen to have a protein bar on you, do you?`);
176    hints.push(`I knew I shouldn't have come here today.`);
177    hints.push(`There's nothing I can do but wait.`);
178    hints.push(`Can I make a phone call?`);
179  
180    hints = shuffleArray(hints);
181  
182    let hintList = [];
183  
184    for (let hint of hints)
185    {
186      hintList.push(
187          {
188            hint: hint,
189            type: "distractor",
190            speaker: ""
191          });
192    }
193  
194    return hintList;
195  }
196  
197  function searchRoom()
198  {
199    let room;
200    for (let r in g.rooms)
201    {
202      if (r === g.player.currentRoom.name)
203      {
204        room = g.rooms[r];
205      }
206    }
207  
208    if (room.darkness)
209    {
210      updateNarration(`You stumble around in the darkness.`, true);
211  
212      if (Math.random() < 0.25)
213      {
214        updateNarration(`<p>You found the light switch.</p>`);
215        room.darkness = false;
216        checkRooms();
217      }
218      else
219      {
220        updateNarration(`<p>But you can’t find the light switch.</p>`);
221      }
222    }
223    else
224    {
225      updateNarration(`You search ${room.search}.`, true);
226  
227      if (room.hints.length === 0)
228      {
229        updateNarration(`<p>But you didn't find anything.</p>`);
230      }
231      else
232      {
233        let hint = room.hints.shift();
234        let text = `<p>You found a note written by someone in the house. `;
235        text += `It says: </p>`;
236        text += `<p>${hint.hint}</p>`;
237        text += `You gain ${g.POINTS_PER_HINT} points.`;
238        updateNarration(text, false);
239  
240        if (hint.type === "linked")
241        {
242          hint.type = "distractor";
243          hint.linked.room.hints.push(hint.linked.hint);
244          hint.linked = null;
245        }
246  
247        g.player.hints.push(hint);
248        g.player.score += g.POINTS_PER_HINT;
249        checkRooms();
250      }
251    } //Note: This brace will be important later
252    takeAction();
253  }
254  
255  function talk()
256  {
257  //interrogation starts a game
258    let suspectName = g.ui.dossier.value;
259    let suspect;
260    for (let s of g.suspects)
261    {
262      if (s.name === suspectName)
263      {
264        suspect = s;
265        break;
266      }
267    }
268  
269  //play a game
270  //Note: We'll be updating this a lot later
271  
272    const gameNames = ["Random Chance", "Tic-Tac-Toe", "23 Pennies", "Bubble Pop", "Hangman", "Pair Up", "All Open", "Treasure Quest", "Guess My Number", "Bunny Race", "Crane Game", "Jumper"];
273  
274    const gameFunctions = [randomChance, ticTacToe, pennyGame, bubblePop, hangman, pairUp, allOpen, treasureQuest, guessMyNumber, bunnyRace, craneGame, jumper];
275  
276    let index = Math.floor(Math.random() * gameNames.length);
277  
278    //index = 4; //Note: For debugging later
279  
280    let game = gameFunctions[index];
281    updateNarration(`${suspect.name} challenges you to<br>${gameNames[index]}.`, true);
282    g.ui.game.scene.classList.remove("display-none");
283    g.ui.game.title.innerHTML = gameNames[index];
284    removeAllChildNodes(g.ui.game.interfaceWrapper);
285    g.ui.game.interfaceWrapper.style.width = "unset";
286    g.ui.game.interfaceWrapper.style.height = "unset";
287  
288    game();
289  }
290  
291  function gameResult(victory)
292  {
293  //this ends the interrogation
294    g.ui.game.scene.classList.add("display-none");
295    g.ui.game.info.innerHTML = "";
296    g.ui.game.ok.onclick = null;
297  
298    let suspect = getSuspect();
299  
300    if (victory)
301    {
302      let hint = suspect.hints.shift();
303      let text = `<h4>You were successful!</h4>`;
304      text += `You earn ${g.POINTS_PER_HINT} points.`;
305      text += `<p><b>${suspect.name} says:</b><br>`;
306      text += `${hint.hint}</p>`;
307      updateNarration(text, true);
308  
309      if (hint.type === "linked")
310      {
311        hint.type = "distractor";
312        hint.linked.room.hints.push(hint.linked.hint);
313        hint.linked = null;
314      }
315  
316      g.player.hints.push(hint);
317      g.player.score += g.POINTS_PER_HINT;
318    }
319    else
320    {
321      let text = `<h4>Your interrogation failed.</h4>`;
322      text += `You lose ${g.INTERROGATION_PENALTY} points.`;
323      text += `<p>${suspect.name} won't talk to you.<br>`;
324      updateNarration(text, true);
325      suspect.irritation++;
326      suspect.irritation = Math.min(g.IRRITATION_MAX, suspect.irritation);
327      g.player.score -= g.INTERROGATION_PENALTY;
328    }
329    checkRooms();
330    showDossier();
331    takeAction();
332  }
333  
334  function closeHintScene()
335  {
336    g.ui.hint.scene.classList.add("display-none");
337  
338    for (let i in g.ui.appearance)
339    {
340      let button = g.ui.appearance[i];
341      button.classList.remove("pop-up");
342    }
343  }
344  
345  function showHints()
346  {
347    g.ui.hint.scene.classList.remove("display-none");
348    for (let i in g.ui.appearance)
349    {
350      let button = g.ui.appearance[i];
351      button.classList.add("pop-up");
352    }
353  
354    let text = ``;
355    if (g.player.hints.length === 0)
356    {
357      text += `<h2>You don't have any hints yet. Search rooms and interrogate suspects to find some.</h2>`;
358    }
359    else
360    {
361      for (let i = 0; i < g.player.hints.length; i++)
362      {
363        let hint = g.player.hints[i];
364        text += `<p><b>Hint ${(i + 1)}</b>: `;
365        text += `<i>${hint.speaker}</i>: `;
366        text += `${hint.hint}</p>`;
367      }
368    }
369    g.ui.hint.hints.innerHTML = text;
370  }
371  
372  function getLinkedHints(hints)
373  {
374    let linkedHints = Math.floor(Math.random() * 5) + 3;
375  
376    let roomsArray = objectToArray(g.rooms);
377  
378    for (let i = 0; i < linkedHints; i++)
379    {
380      let hintIndex = Math.floor(Math.random() * Math.min(8, hints.length));
381      let hint = hints[hintIndex];
382  
383      let roomIndex = Math.floor(Math.random() * roomsArray.length);
384      let room = roomsArray[roomIndex];
385  
386      let newHint =
387          {
388            hint: `I saw something ${room.search} in the ${room.name}.`,
389            type: `linked`,
390            linked:
391                {
392                  room: room,
393                  hint: hint
394                }
395          };
396      newHint.linked.hint.speaker = room.name;
397      roomsArray.splice(roomIndex, 1);
398      hints[hintIndex] = newHint;
399      g.player.numHintsToFind++;
400    }
401    return hints;
402  }
403  
404