Add Carlos afternoon dialogue
[wgj58.git] / wgj58.js
1 var game = new Phaser.Game(800, 600, Phaser.AUTO, '', { preload: function() { this.state.add('GamePlay', GamePlay, true); } });
2 var logic;
3 var cursors;
4
5 const PLAYER_SPEED = 200;
6 const WAIT_MENUSTEP = 100;
7 const WAIT_TALK = 250;
8
9 const MENUITEM_TALK = 0;
10 const MENUITEM_LEAVE = 1;
11 const MENUITEM_TAKE = 2;
12
13 const GUI_MENUITEM_DISTANCE = 20;
14
15 window.addEventListener("keydown", function(e) {
16 // Prevent default browser action for arrows and spacebar
17 if([32, 37, 38, 39, 40].indexOf(e.keyCode) > -1) {
18 e.preventDefault();
19 }
20 }, false);
21
22 function hasTimePassed(time, delay) {
23 return (game.time.now - time) > delay;
24 }
25
26 class Dialogue {
27 // dialogue is array of {actor, text} records.
28 constructor(dialogue) {
29 this.dialogue = dialogue;
30 this.state = 0;
31 }
32
33 actual() {
34 return this.dialogue[this.state];
35 }
36
37 advance() {
38 this.state++;
39 }
40 }
41
42 class Door extends Phaser.TileSprite {
43 constructor(x, y, name, rotation, vector, longpanel) {
44 super(game, x, y, 64, 64, 'objects');
45 this.name = name;
46 this.longpanel = longpanel;
47 if (!longpanel) {
48 this.anchor = new Phaser.Point(0.5, 0.5);
49 this.tilePosition = new Phaser.Point(-64, -64);
50 this.openvector = Phaser.Point.multiply(vector, new Phaser.Point(56, 56));
51 }
52 else {
53 this.width *= 2;
54 this.anchor = new Phaser.Point(0.75, 0.5);
55 this.tilePosition = new Phaser.Point(0, -64);
56 this.openvector = Phaser.Point.multiply(vector, new Phaser.Point(116, 116));
57 }
58 if (rotation === undefined) rotation = 0;
59 this.rotation = rotation * (Math.PI / 180);
60 this.closetween = game.add.tween(this).to({ x: this.position.x, y: this.position.y }, 1000, Phaser.Easing.Sinusoidal.InOut, false, 0, 0, false);
61 this.openposition = Phaser.Point.add(this.position, this.openvector);
62 this.opentween = game.add.tween(this).to({ x: this.openposition.x, y: this.openposition.y }, 1000, Phaser.Easing.Sinusoidal.InOut, false, 0, 0, false);
63 this.isOpen = false;
64 game.physics.arcade.enable(this);
65 this.body.immovable = true;
66 this.setBody(rotation);
67 }
68
69 setBody(rotation) {
70 switch(rotation) {
71 case 0:
72 case 180:
73 this.body.setSize(this.width, 10, this.longpanel * (rotation / 180) * 64, 27);
74 break;
75 case 90:
76 case 270:
77 this.body.setSize(10, this.width, 27 + (this.longpanel * 64), this.longpanel * ((rotation - 270) / 180) * 64);
78 break;
79 default:
80 console.log("Unable to set body due to unknown rotation:", rotation);
81 }
82 }
83
84 open() {
85 if (!this.isOpen) {
86 this.opentween.start();
87 this.isOpen = true;
88 }
89 }
90
91 close() {
92 if (this.isOpen) {
93 this.closetween.start();
94 this.isOpen = false;
95 }
96 }
97
98 update() {
99 game.debug.body(this);
100 }
101 }
102
103 class Player extends Phaser.Sprite {
104 constructor(x, y) {
105 super(game, x, y, 'player');
106 this.y -= this.height;
107 this.shortname = "John";
108 this.fullname = "John Evals";
109 this.offerInteraction(null);
110 this.unfreeze();
111 }
112
113 enablePhysics() {
114 game.physics.arcade.enable(this);
115 this.body.bounce.y = 0.2;
116 this.body.bounce.x = 0.2;
117 this.body.collideWorldBounds = true;
118 }
119
120 control() {
121 if ((this.alive) && (!this.freezed))
122 {
123 if (cursors.left.isDown)
124 {
125 this.body.velocity.x = -PLAYER_SPEED;
126 }
127 else if (cursors.right.isDown)
128 {
129 this.body.velocity.x = PLAYER_SPEED;
130 }
131 if (cursors.up.isDown)
132 {
133 this.body.velocity.y = -PLAYER_SPEED;
134 }
135 else if (cursors.down.isDown)
136 {
137 this.body.velocity.y = PLAYER_SPEED;
138 }
139 }
140 }
141
142 update() {
143 this.body.velocity.x = this.body.velocity.y = 0;
144 this.control();
145 }
146
147 freeze() {
148 this.freezed = true;
149 }
150
151 unfreeze() {
152 this.freezed = false;
153 }
154
155 offerInteraction(npc) {
156 this.interactablenpc = npc;
157 }
158
159 takeMe(npc) {
160 this.loadTexture(npc.key);
161 npc.kill();
162 this.disguise = npc;
163 logic.gameinterface.dropNoticeTimeout(Phaser.Timer.SECOND * 5, "You are now identified as " + npc.fullname + "!");
164 }
165 }
166
167 class GameNPC extends Phaser.Sprite {
168 constructor(x, y, key, shortname, fullname, interaction_distance) {
169 super(game, x, y, key);
170 this.y -= this.height;
171 this.shortname = shortname;
172 this.fullname = fullname;
173 this.interaction_distance = interaction_distance;
174 this.interactable = false;
175 this.resetTalk();
176 this.happy = false;
177 }
178
179 kill() {
180 super.kill();
181 this.exists = false;
182 this.happy = false; // Dead people are not happy.
183 }
184
185 update() {
186 super.update();
187 if ((!this.interactable) && (game.physics.arcade.distanceBetween(this, logic.player) < this.interaction_distance)) {
188 logic.gameinterface.dropNotice("(ENTER) Interact with " + this.shortname + "!");
189 logic.player.offerInteraction(this);
190 this.interactable = true;
191 }
192 else if ((this.interactable) && (game.physics.arcade.distanceBetween(this, logic.player) > this.interaction_distance)) {
193 logic.gameinterface.clearNotice();
194 logic.player.offerInteraction(null);
195 this.interactable = false;
196 }
197 if ((this.teleport_instructions) && (game.physics.arcade.distanceBetween(this, logic.player) > (game.width + 200))) {
198 this.position = this.teleport_instructions.newPosition;
199 this.teleport_instructions.callback(this.teleport_instructions.callbackValue);
200 this.teleport_instructions = null;
201 }
202 }
203
204 actionTalk() {
205 this.talkcount++;
206 }
207
208 actionLeave() {
209 }
210
211 actionTake() {
212 logic.player.offerInteraction(null);
213 logic.player.takeMe(this);
214 return true;
215 }
216
217 endTalk() {
218 return true;
219 }
220
221 resetTalk() {
222 this.talkcount = 0;
223 }
224
225 makeHappy() {
226 this.happy = true;
227 console.log(this.shortname, "is happy!");
228 }
229
230 offscreenTeleportation(newPosition, callback, callbackValue) {
231 this.teleport_instructions = { newPosition: newPosition, callback: callback, callbackValue: callbackValue };
232 console.log("Offscreen teleport request registered:", this.teleport_instructions);
233 }
234 }
235
236 class NPC_Clara extends GameNPC {
237 actionTalk() {
238 switch (this.talkcount) {
239 case 0:
240 logic.gameinterface.talk(new Dialogue( [ { actor: this, text: "What a morning..." },
241 { actor: logic.player, text: "Hi Clara! What happened?" },
242 { actor: this, text: "No one cares to tell. I just know that I have to log on people manually, as the access control system doesn't work properly." },
243 { actor: logic.player, text: "Hmm... I'll look into it. Maybe it's just that everyone is fired." },
244 { actor: this, text: "Haha! Wouldn't joke about this, though, due to the recent layoffs." },
245 { actor: logic.player, text: "Well, maybe if we dare to joke about it, it won't happen to us..." },
246 { actor: this, text: "Wish it worked like that... Is it some superstition like the belief that having an umbrella with you prevents rain?" },
247 { actor: logic.player, text: "Nah, that actually works; it's not a superstition, but Murphy's Law!" },
248 { actor: this, text: "If you say so..." },
249 { actor: this, text: "Anyway, I logged you in and opened the door for you." } ] ));
250 logic.openDoor("cutedoor");
251 break;
252 case 1:
253 logic.gameinterface.talk(new Dialogue( [ { actor: this, text: "John, have you ever thought about losing your employee card?" },
254 { actor: logic.player, text: "Yeah, you'd just get a new one." },
255 { actor: this, text: "You don't understand me, John!" },
256 { actor: this, text: "..." },
257 { actor: this, text: "I mean... Losing it for real..." },
258 { actor: this, text: "Doesn't it feel like it's the culmination of your being?" },
259 { actor: this, text: "If I had no card, would I still exist?" },
260 { actor: logic.player, text: "..." },
261 { actor: logic.player, text: "You sound very philosophical today." } ] ));
262 break;
263 case 2:
264 case 3:
265 case 4:
266 logic.gameinterface.talk(new Dialogue( [ { actor: this, text: "Would you like to hear a random fun fact?" },
267 { actor: logic.player, text: "Of course!" },
268 { actor: this, text: "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s," },
269 { actor: this, text: "when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap" },
270 { actor: this, text: "into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem" },
271 { actor: this, text: "Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum." },
272 { actor: logic.player, text: "That's very interesting, I didn't know that!" },
273 { actor: logic.player, text: "Thanks for sharing, Clara!" } ] ));
274 break;
275 case 5:
276 logic.gameinterface.talk(new Dialogue( [ { actor: this, text: "Would you like to hear a random fun fact?" },
277 { actor: logic.player, text: "Of course!..." },
278 { actor: logic.player, text: "But first..." },
279 { actor: this, text: "What is it?" },
280 { actor: logic.player, text: "..." },
281 { actor: logic.player, text: "Never mind, go on with what you wanted to say." },
282 { actor: this, text: "Lorem Ipsum is simply dummy text of the printing and typesetting industry..." },
283 { actor: logic.player, text: "I knew that already..." },
284 { actor: logic.player, text: "But..." },
285 { actor: logic.player, text: "Would you go out on a date with me?" },
286 { actor: this, text: "..." },
287 { actor: this, text: "No." } ] ));
288 break;
289 default:
290 logic.gameinterface.talk(new Dialogue( [ { actor: this, text: "..." } ] ));
291 }
292 super.actionTalk();
293 }
294
295 actionLeave() {
296 logic.gameinterface.dropNotice(this.shortname + ": Have a great day, John!");
297 }
298
299 actionTake() {
300 logic.openDoor("cutedoor");
301 return super.actionTake();
302 }
303
304 endTalk() {
305 return (this.talkcount < 6);
306 }
307 }
308
309 class NPC_Carlos extends GameNPC {
310 actionTalk() {
311 if (logic.clara.alive) {
312 if (logic.peter.talkcount == 0) {
313 switch (this.talkcount) {
314 case 0:
315 logic.gameinterface.talk(new Dialogue( [ { actor: logic.player, text: "Good morning, Carlos! What's up?" },
316 { actor: this, text: "Hey, John! Not too much, I'm just trying to sell some shit to this new client." },
317 { actor: logic.player, text: "And so? Is it hard to convince them?" },
318 { actor: this, text: "Of course, they don't want to buy. It's shit." },
319 { actor: this, text: "I mean, who would want to buy shit?" },
320 { actor: logic.player, text: "Yeah. Relatable... But why are you trying to sell shit? I mean, why not one of our cutting edge technologies?" },
321 { actor: this, text: "They couldn't afford it." },
322 { actor: logic.player, text: "Then why are you trying to sell them... anything at all? They'd better off with a cheaper company." },
323 { actor: this, text: "Company policies. Plus the management instructed me to sell to them, no matter what." },
324 { actor: logic.player, text: "That sucks... Well... good luck!" },
325 { actor: this, text: "Thanks..." } ] ));
326 logic.closeDoor("cutedoor");
327 logic.openDoor("carlosdoor");
328 break;
329 case 1:
330 logic.gameinterface.talk(new Dialogue( [ { actor: this, text: "*Sigh.* I'll probably not work here for long, if I can't sell this shit to the customer." },
331 { actor: this, text: "These layoffs are terrifying. They let go of anyone for even the slightest mistake." },
332 { actor: logic.player, text: "But it's not a mistake when our client doesn't buy something they don't need." },
333 { actor: this, text: "Tell this to my boss..." } ] ));
334 break;
335 case 2:
336 logic.gameinterface.talk(new Dialogue( [ { actor: this, text: "You know, generally, I think it sucks being a child. One thing I miss though, if you're a child, you're allowed to be silly." },
337 { actor: this, text: "..." },
338 { actor: this, text: "For example, when my Dad told me that semen is the seed of animals, I theoretized, if I'd bury some pig semen in the garden, a pig would grow out of it..." },
339 { actor: this, text: "I was totally fascinated by the thought, because I really wanted to have a pet pig, but Dad wouldn't let me have one." },
340 { actor: this, text: "So I thought I could grow my own pig in the garden from pig seeds!" },
341 { actor: logic.player, text: "Interesting. Where are you going with this?" },
342 { actor: this, text: "I don't know... sometimes I feel like I'd rather sell pig semen to our clients, heh!" },
343 { actor: this, text: "Uhm..." },
344 { actor: this, text: "Totally don't tell this to Saiki!" } ] ));
345 this.pigsemen = true;
346 break;
347 case 3:
348 logic.gameinterface.talk(new Dialogue( [ { actor: this, text: "Weren't you heading to the IT department to the right?" },
349 { actor: this, text: "You know... the green department which looks way better than blue!" },
350 { actor: this, text: "..." },
351 { actor: this, text: "Damn, why do I have to work in blue? I just feel... so blue about it." } ] ));
352 break;
353 case 4:
354 logic.gameinterface.talk(new Dialogue( [ { actor: this, text: "Weren't you heading to the conveniently green department to the right? I guess Saiki is waiting for you." },
355 { actor: this, text: "You're so lucky that you can work with her every day!" } ] ));
356 break;
357 default:
358 logic.gameinterface.talk(new Dialogue( [ { actor: this, text: "Guess you'll stay here then. It's cool, you're great company anyway." } ] ));
359 }
360 }
361 else {
362 switch (this.talkcount) {
363 case 0:
364 logic.gameinterface.talk(new Dialogue( [ { actor: this, text: "Phew... long shift, I gotta go!" },
365 { actor: this, text: "Why are you still here? I mean, you engineers stay here 'til late at night. Why don't you just go home at 4 pm?" },
366 { actor: this, text: "This is why I can never ask out Saiki... She always works for so long..." },
367 { actor: logic.player, text: "We tend to have lots of work with impossible deadlines..." },
368 { actor: this, text: "I bet you get lots of money for the overtimes!" },
369 { actor: logic.player, text: "No, we don't get paid for overtimes." },
370 { actor: this, text: "... Then why do you stay beyond the office hours?" },
371 { actor: logic.player, text: "Otherwise we're fired. That's the deal. Either we work 2 extra hours or we get replaced." },
372 { actor: this, text: "Wow... and I thought we have a shortage on engineers..." } ] ));
373 break;
374 case 1:
375 logic.gameinterface.talk(new Dialogue( [ { actor: logic.player, text: "And how's the business going? Did you manage to shell the shit?" },
376 { actor: this, text: "In a heartbeat! Now they're buying so much shit that I'm afraid we don't have enough assholes to produce that quantity." },
377 { actor: this, text: "Be prepared for another month of overtimes. This deal will be huge!" },
378 { actor: logic.player, text: "Well done, man!" } ] ));
379 break;
380 default:
381 logic.gameinterface.talk(new Dialogue( [ { actor: this, text: "I really want to leave now." } ] ));
382 this.offscreenTeleportation(new Phaser.Point(0, 0), this.tpDone, this);
383 }
384 }
385 }
386 else {
387 switch (this.talkcount) {
388 case 0:
389 logic.gameinterface.talk(new Dialogue( [ { actor: logic.player, text: "Good morning, Carlos!" },
390 { actor: this, text: "Whoa, Clara! You have changed so much! I barely recognize you. What's up?" },
391 { actor: logic.player, text: "I need to talk to Saiki at the IT department, but... my card doesn't allow me to enter there." },
392 { actor: this, text: "Well... I can certainly help you with that..." },
393 { actor: this, text: "..." } ] ));
394 break;
395 case 1:
396 logic.gameinterface.talk(new Dialogue( [ { actor: logic.player, text: "Carlos. You promised to help me." },
397 { actor: this, text: "Uhm... It's just... Please give me 5 mins to finish this e-mail." },
398 { actor: logic.player, text: "I don't have much time, Carlos." },
399 { actor: this, text: "See, it's just 5 mins, please be patient. I have a chocolate bar in the fridge. I give it to you. Feel free to have it meanwhile." },
400 { actor: logic.player, text: "..." } ] ));
401 break;
402 case 2:
403 logic.gameinterface.talk(new Dialogue( [ { actor: logic.player, text: "Time is up, Carlos!" },
404 { actor: this, text: "Please give me just another min." },
405 { actor: logic.player, text: "Fine. Please just give me your card and I'll help myself!" },
406 { actor: this, text: "But... you know that company policies forbid that, Clara! Please just be a little more patient!" },
407 { actor: logic.player, text: "You will give me your card now or you will regret!" },
408 { actor: this, text: "...?" },
409 { actor: this, text: "You're not gonna treat me like this. Forget it!" },
410 { actor: logic.player, text: "You'll not work here tomorrow." } ] ));
411 break;
412 default:
413 logic.gameinterface.talk(new Dialogue( [ { actor: this, text: "..." } ] ));
414 }
415 }
416 super.actionTalk();
417 }
418
419 actionLeave() {
420 if ((logic.clara.alive) && (logic.peter.talkcount == 0)) {
421 logic.gameinterface.dropNotice(this.shortname + ": Bye, John! Pass on my greetings to Saiki!");
422 }
423 }
424
425 actionTake() {
426 logic.closeDoor("cutedoor");
427 logic.openDoor("carlosdoor");
428 return super.actionTake();
429 }
430
431 endTalk() {
432 return ((logic.clara.alive) && (logic.peter.talkcount == 0)) || (this.talkcount < 3);
433 }
434
435 tpDone(value) {
436 console.log("Woot-woot! Teleport complete:", value);
437 value.visible = false;
438 }
439 }
440
441 class NPC_Saiki extends GameNPC {
442 actionTalk() {
443 if (logic.carlos.alive) {
444 switch (this.talkcount) {
445 case 0:
446 logic.gameinterface.talk(new Dialogue( [ { actor: logic.player, text: "Hi Saiki!" },
447 { actor: this, text: "Hi John! Glad you arrived, here's some work for you!" },
448 { actor: logic.player, text: "Awesome! What is it?" },
449 { actor: this, text: "Haha, joking! Actually, our queue is suspiciously empty for today." },
450 { actor: logic.player, text: "Yeah... That's really suspicious!" },
451 { actor: logic.player, text: "Maybe I can get home today in time?" },
452 { actor: this, text: "You mean, you wouldn't spend the mandatory free extra working hours?" },
453 { actor: this, text: "You steal from the company! The company needs your unpaid hours of work! Otherwise, how would we finance the trash can I ordered for the department?" },
454 { actor: this, text: "*Whispers with wink.* I hope you get my sarcasm." },
455 { actor: logic.player, text: "Haha! I always get it, Saiki!" } ] ));
456 logic.closeDoor("carlosdoor");
457 logic.openDoor("saikidoor");
458 logic.openDoor("peterdoor");
459 break;
460 case 1:
461 logic.gameinterface.talk(new Dialogue( [ { actor: this, text: "Now that I think about it, there's still one thing. You could look into why the access control system is acting so funny today." },
462 { actor: this, text: "Clara has to enter people manually." },
463 { actor: logic.player, text: "Yeah, I'll definitely check that." } ] ));
464 break;
465 case 2:
466 logic.gameinterface.talk(new Dialogue( [ { actor: logic.player, text: "So... what's up with the trash can?" },
467 { actor: this, text: "I'm always up for such deep conversation" },
468 { actor: this, text: "about trash cans." },
469 { actor: this, text: "While we only have one trash can, other departments seem to be abundant of them. And ours is always filled. So I requested an additional trash can." },
470 { actor: this, text: "Now the ticket is in PENDING status. The latest work note is from two months ago, telling there is no budget at the moment." },
471 { actor: logic.player, text: "Hmm... Maybe it's too much to ask. Can we take one from another department?" },
472 { actor: this, text: "No, everyone holds on to their trash cans." },
473 { actor: logic.player, text: "You certainly did your research." },
474 { actor: this, text: "Of course. It's an important subject." } ] ));
475 break;
476 case 3:
477 logic.gameinterface.talk(new Dialogue( [ { actor: this, text: "My parents named me after a Japanese rock singer." },
478 { actor: logic.player, text: "Cool! Which band?" },
479 { actor: this, text: "I don't remember the band name. But the particular singer has a blue rose in her hair most of the time." } ] ));
480 break;
481 default:
482 if ((logic.carlos.pigsemen) && (this.talkcount == 4)) {
483 logic.gameinterface.talk(new Dialogue( [ { actor: logic.player, text: "Did you know that Carlos thought he can grow a pig by burying pig semen in the ground? What do you think about this?" },
484 { actor: this, text: "Hmm..." },
485 { actor: this, text: "I guess it didn't work." },
486 { actor: this, text: "So do you want to know what I think about this?" },
487 { actor: this, text: "..." },
488 { actor: this, text: "IT'S BRILLIANT!!!" },
489 { actor: this, text: "You know, it really sparkled my artistic vision! Now I must draw a pig with its legs rooted into the ground!" },
490 { actor: logic.player, text: "That's gross. Poor pig." },
491 { actor: this, text: "Indeed. But this is the point. He's stuck in one place, cannot move. Like you in life. So you feel sympathy for him." },
492 { actor: logic.player, text: "You have a point." },
493 { actor: this, text: "I think I'll catch Carlos and talk to him. I always liked that guy but I didn't know he's such imaginative." } ] ));
494 this.offscreenTeleportation(new Phaser.Point(logic.carlos.x, logic.carlos.y + 64), this.tpDone, this);
495 }
496 else {
497 if (Phaser.Math.random() < 0.5) {
498 logic.gameinterface.talk(new Dialogue( [ { actor: this, text: "I've found an orchestrated rendition of „Potential for Anything”. You'll have to check it out, it's breathtaking!" } ] ));
499 }
500 else {
501 logic.gameinterface.talk(new Dialogue( [ { actor: this, text: "I don't like that our department is green. The blue one, where Carlos works, looks much better." } ] ));
502 }
503 }
504 }
505 }
506 else {
507 switch (this.talkcount) {
508 case 0:
509 logic.gameinterface.talk(new Dialogue( [ { actor: logic.player, text: "I love you, Saiki!" },
510 { actor: this, text: "Hi Carlos..." },
511 { actor: logic.player, text: "I'm infatuated by the mere thought of you." },
512 { actor: this, text: "Well... it sounds pretty much creepy." },
513 { actor: logic.player, text: "Will you go out on a date with me?" },
514 { actor: this, text: "..." },
515 { actor: this, text: "Sorry to hurt your feelings, but... even though I like you... Your sudden, unprecedented confession makes me scared." },
516 { actor: this, text: "Especially with that facial expression." },
517 { actor: this, text: "I mean... you're not even joking." },
518 { actor: this, text: "So sorry... I won't date you." } ] ));
519 break;
520 case 1:
521 logic.gameinterface.talk(new Dialogue( [ { actor: logic.player, text: "I thought I could impress you." },
522 { actor: this, text: "I'm sorry." } ] ));
523 break;
524 case 2:
525 logic.gameinterface.talk(new Dialogue( [ { actor: logic.player, text: "You will give me your card." },
526 { actor: this, text: "Geez, what for? Go back to your department and work!" },
527 { actor: logic.player, text: "I need it." },
528 { actor: this, text: "..." } ] ));
529 break;
530 default:
531 logic.gameinterface.talk(new Dialogue( [ { actor: this, text: "Don't you have anything better to do, Carlos?" } ] ));
532 }
533 }
534 super.actionTalk();
535 }
536
537 actionLeave() {
538 if (logic.carlos.alive) {
539 logic.gameinterface.dropNotice(this.shortname + ": It was nice talking to you!");
540 }
541 }
542
543 actionTake() {
544 logic.closeDoor("carlosdoor");
545 logic.openDoor("saikidoor");
546 logic.openDoor("peterdoor");
547 logic.carlos.kill();
548 return super.actionTake();
549 }
550
551 endTalk() {
552 return (logic.carlos.alive);
553 }
554
555 tpDone(value) {
556 console.log("Woot-woot! Teleport complete:", value);
557 value.makeHappy();
558 logic.carlos.makeHappy();
559 // FIXME: Need to find a prettier way than this.
560 logic.carlos.update = function() { }; // Disable Carlos' interaction. (Saiki will talk for him.)
561 }
562 }
563
564 class NPC_Peter extends GameNPC {
565 actionTalk() {
566 if (logic.saiki.alive) {
567 switch (this.talkcount) {
568 case 0:
569 logic.gameinterface.talk(new Dialogue( [ { actor: logic.player, text: "Hi Peter! What's up?" },
570 { actor: this, text: "Hi John! Bianca has locked herself in the large meeting room." },
571 { actor: logic.player, text: "Why would she do that?" },
572 { actor: this, text: "I have no idea." },
573 { actor: this, text: "Normally, I would give a fuck about what she's doing and her problems, but I want to hold a meeting in an hour." },
574 { actor: logic.player, text: "That was rude. I think you should care more about your colleagues." },
575 { actor: this, text: "Ahh... You're right. I didn't mean it. I'm just so frustrated about all the shit going on here." } ] ));
576 logic.closeDoor("saikidoor");
577 logic.openDoor("peterdoor");
578 logic.openDoor("biancadoor");
579 logic.carlos.resetTalk();
580 break;
581 case 1:
582 logic.gameinterface.talk(new Dialogue( [ { actor: this, text: "See... Would you talk to Bianca? We don't understand each other pretty well. That's why I'd rather wouldn't make a shot." } ] ));
583 break;
584 default:
585 if ((logic.clara.talkcount >= 5) && (this.talkcount == 2)) {
586 logic.gameinterface.talk(new Dialogue( [ { actor: logic.player, text: "Do you know Clara from the Reception?" },
587 { actor: this, text: "Of course I do." },
588 { actor: logic.player, text: "I think she's mad at me..." },
589 { actor: this, text: "Why would she?" },
590 { actor: logic.player, text: "I kind of... asked her out." },
591 { actor: logic.player, text: "She said no." },
592 { actor: this, text: "What the heck, dude?" },
593 { actor: this, text: "..." },
594 { actor: this, text: "You should know it's against the company etiquette..." },
595 { actor: this, text: "Regardless, I don't think she's really mad. You're a cool guy." },
596 { actor: logic.player, text: "I hope this will be sorted out... I totally accept her answer, but I wouldn't like her to have negative feelings towards me." } ] ));
597 this.offscreenTeleportation(new Phaser.Point(logic.clara.x - 160, logic.clara.y), this.tpDone, this);
598 }
599 else {
600 logic.gameinterface.talk(new Dialogue( [ { actor: this, text: "I'm kind of busy, man." } ] ));
601 }
602 }
603 }
604 else {
605 switch (this.talkcount) {
606 case 0:
607 logic.gameinterface.talk(new Dialogue( [ { actor: logic.player, text: "What a wonderful day, Peter!" },
608 { actor: this, text: "Yikes! Saiki! You scared me!" },
609 { actor: logic.player, text: "I didn't even say \"boo\"." },
610 { actor: this, text: "Are you OK? You look horrible! You should really see a doctor." },
611 { actor: logic.player, text: "I'm fine, Peter. And you?" },
612 { actor: this, text: "No... Not at all." },
613 { actor: logic.player, text: "I'm sorry to hear that..." } ] ));
614 break;
615 case 1:
616 logic.gameinterface.talk(new Dialogue( [ { actor: this, text: "Don't come closer to me!" },
617 { actor: logic.player, text: "Why?" },
618 { actor: this, text: "I don't mean to offend you, but... you really creep me out..." },
619 { actor: logic.player, text: "Why do you say that?" },
620 { actor: this, text: "I honestly can't tell what's wrong with you, but... you look like that ghost girl from The Ring!" } ] ));
621 break;
622 case 2:
623 logic.gameinterface.talk(new Dialogue( [ { actor: logic.player, text: "Now that was pretty much racist..." },
624 { actor: logic.player, text: "Just because I have a Japanese name and long black hair, that makes me immediately look like the Japanese girl from Ring when I'm sick?" },
625 { actor: this, text: "Geez... that's not even a Japanese movie! And the actress is American..." },
626 { actor: logic.player, text: "The original movie is Japanese." },
627 { actor: this, text: "I don't care... Just... keep distance, please!" } ] ));
628 break;
629 default:
630 if (Phaser.Math.random() < 0.5) {
631 logic.gameinterface.talk(new Dialogue( [ { actor: this, text: "STAY AWAY FROM ME!" } ] ));
632 }
633 else {
634 logic.gameinterface.talk(new Dialogue( [ { actor: this, text: "DON'T COME ANY CLOSER!" } ] ));
635 }
636 }
637 }
638 super.actionTalk();
639 }
640
641 actionTake() {
642 logic.closeDoor("saikidoor");
643 logic.openDoor("peterdoor");
644 logic.openDoor("biancadoor");
645 return super.actionTake();
646 }
647
648 endTalk() {
649 return (logic.saiki.alive) && (this.talkcount < 3);
650 }
651
652 tpDone(value) {
653 console.log("Woot-woot! Teleport complete:", value);
654 value.makeHappy();
655 logic.clara.makeHappy();
656 // FIXME: Need to find a prettier way than this.
657 logic.clara.update = function() { }; // Disable Clara's interaction. (Peter will talk for him.)
658 }
659 }
660
661 class NPC_Bianca extends GameNPC {
662 actionTalk() {
663 if (logic.peter.alive) {
664 switch (this.talkcount) {
665 case 0:
666 logic.gameinterface.talk(new Dialogue( [ { actor: logic.player, text: "... Hi Bianca!" },
667 { actor: this, text: "... Hello John!" },
668 { actor: logic.player, text: "So I've been told, you've been spending most of the day in this meeting room..." },
669 { actor: this, text: "Yeah?" },
670 { actor: logic.player, text: "... Your colleagues want to hold a meeting in this room and you're blocking it." },
671 { actor: this, text: "Hmm... Kind of that's the point... There is no need for that meeting." },
672 { actor: logic.player, text: "May I know why?" },
673 { actor: this, text: "You must have heard about the layoffs. We weren't happy with that, but it was inevitable to meet the productivity requirements." },
674 { actor: this, text: "But today morning, I received a list with about 50% of the employees... Many of them are great friends of mine..." },
675 { actor: this, text: "We were like a big family here and we're torn apart like this... The worst is that I have to tell the news to all of them." },
676 { actor: logic.player, text: "That's rough. Does this company even need people?" },
677 { actor: this, text: "..." } ] ));
678 logic.openDoor("cutedoor");
679 logic.closeDoor("peterdoor");
680 break;
681 case 1:
682 logic.gameinterface.talk(new Dialogue( [ { actor: logic.player, text: "Bianca... Am I on that list?" },
683 { actor: this, text: "Yes, John." },
684 { actor: this, text: "Well, I'll try to convince them to keep you and many other great folks from the list." },
685 { actor: this, text: "But... I can't promise anything. Also, it would help your case a lot if you made some notable work today, so I could mention it as your recent achievement." },
686 { actor: logic.player, text: "Thank you very much... I'll see what I can do." } ] ));
687 break;
688 case 2:
689 logic.gameinterface.talk(new Dialogue( [ { actor: logic.player, text: "You seem to be somehow blaming yourself. It's not your fault. You're just doing your job." },
690 { actor: this, text: "I know. It's just part of my work..." },
691 { actor: this, text: "But if you have to sweep out such a great volume of people within such a short time... It does take its toll on the person." },
692 { actor: this, text: "... I feel like I'm growing distant from the company." },
693 { actor: this, text: "I mean... probably it's heresy to say that, but I feel I can less and less identify with the company's values." },
694 { actor: logic.player, text: "Yeah, you should definitely not talk about it to others... I mean, maybe only those you deeply trust." },
695 { actor: this, text: "I don't care anymore..." },
696 { actor: logic.player, text: "Fine." },
697 { actor: logic.player, text: "See... probably there is no need for such drama. Maybe it's for the best for everyone." },
698 { actor: logic.player, text: "... After all, there IS life beyond the company..." },
699 { actor: this, text: "You think so?..." },
700 { actor: this, text: "Hmm..." },
701 { actor: this, text: "I never thought about it for a long time..." },
702 { actor: logic.player, text: "There are plenty of other opportunities for us! Everything will be fine!" },
703 { actor: this, text: "..." },
704 { actor: this, text: "Thank you. This helped me to regain a bit of my composure..." },
705 { actor: logic.player, text: "You're welcome." } ] ));
706 this.makeHappy();
707 break;
708 default:
709 logic.gameinterface.talk(new Dialogue( [ { actor: this, text: "Thank you. I'll go back to work soon. Just give some more minutes of alone time." } ] ));
710 }
711 }
712 else {
713 switch (this.talkcount) {
714 case 0:
715 logic.gameinterface.talk(new Dialogue( [ { actor: logic.player, text: "..." },
716 { actor: this, text: "... So you came for me too." },
717 { actor: this, text: "..." },
718 { actor: this, text: "I know what you are..." },
719 { actor: this, text: "..." },
720 { actor: this, text: "Let's get over with." },
721 { actor: logic.player, text: "..." } ] ));
722 break;
723 default:
724 logic.gameinterface.talk(new Dialogue( [ { actor: this, text: "What are you waiting for?" } ] ));
725 }
726 }
727 super.actionTalk();
728 }
729
730 actionLeave() {
731 if (this.happy) {
732 logic.gameinterface.dropNotice(this.shortname + ": Thank you. I'll go back to work soon.");
733 }
734 }
735
736 actionTake() {
737 // All doors open for you if you have all the cards.
738 logic.openDoor("cutedoor");
739 logic.openDoor("carlosdoor");
740 logic.openDoor("saikidoor");
741 return super.actionTake();
742 }
743 }
744
745
746 class GameInterface extends Phaser.Group {
747 constructor(game, parent) {
748 super(game, parent, 'GUI', false, false, 0);
749 this.back_notice = new Phaser.Graphics(game, 0, game.height - 50);
750 this.back_notice.beginFill(0x000000);
751 this.back_notice.drawRect(0, 0, game.width, 30);
752 this.back_notice.endFill();
753 this.add(this.back_notice);
754 this.text_notice = new Phaser.Text(game, 125, this.back_notice.y + 5, null, { align: 'left', fill: 'white', font: 'Ubuntu Mono', fontSize: 18, fontWeight: 'bold' });
755 this.add(this.text_notice);
756 this.clearNotice();
757
758 this.back_menu = new Phaser.Graphics(game, 150, (game.height / 2) + 40);
759 this.back_menu.beginFill(0x000000);
760 this.back_menu.drawRect(0, 0, 155, 105);
761 this.back_menu.endFill();
762 this.back_menu.lineStyle(3, Phaser.Color.YELLOW, 1);
763 this.back_menu.moveTo(10, 35);
764 this.back_menu.lineTo(this.back_menu.width - 10, 35);
765 this.add(this.back_menu);
766 var style = { align: 'left', fill: 'yellow', font: 'Ubuntu Mono', fontSize: 22, fontWeight: 'bold' };
767 this.text_menutitle = new Phaser.Text(game, this.back_menu.x, this.back_menu.y, null, style);
768 this.text_menutitle.anchor.setTo(-0.2, -0.2);
769 style = { align: 'left', fill: 'white', font: 'Ubuntu Mono', fontSize: 18, fontWeight: 'bold' };
770 this.text_menuitem_Talk = new Phaser.Text(game, this.back_menu.x + 35, this.back_menu.y + 40, "Talk", style);
771 this.text_menuitem_Leave = new Phaser.Text(game, this.back_menu.x + 35, this.text_menuitem_Talk.y + GUI_MENUITEM_DISTANCE, "Leave", style);
772 this.text_menuitem_Take = new Phaser.Text(game, this.back_menu.x + 35, this.text_menuitem_Leave.y + GUI_MENUITEM_DISTANCE, "Take ID", style);
773 style.fill = 'yellow';
774 this.text_menucursor = new Phaser.Text(game, this.back_menu.x + 15, this.text_menuitem_Talk.y, "→", style);
775 this.add(this.text_menutitle);
776 this.add(this.text_menuitem_Talk);
777 this.add(this.text_menuitem_Leave);
778 this.add(this.text_menuitem_Take);
779 this.add(this.text_menucursor);
780 this.leaveMenu();
781 this.last_menustep = 0;
782
783 this.back_talk = new Phaser.Graphics(game, 100, game.height - 120);
784 this.back_talk.beginFill(0x000000);
785 this.back_talk.drawRect(0, 0, game.width - 200, 105);
786 this.back_talk.endFill();
787 this.back_talk.lineStyle(3, Phaser.Color.YELLOW, 1);
788 this.back_talk.moveTo(10, 35);
789 this.back_talk.lineTo(this.back_talk.width - 10, 35);
790 this.add(this.back_talk);
791 style = { align: 'left', fill: 'yellow', font: 'Ubuntu Mono', fontSize: 22, fontWeight: 'bold' };
792 this.text_talktitle = new Phaser.Text(game, this.back_talk.x + 15, this.back_talk.y + 6, null, style);
793 //this.text_talktitle.anchor.setTo(-0.2, -0.2);
794 this.add(this.text_talktitle);
795 this.strikethrough_talktitle = new Phaser.Graphics(game, this.back_talk.x, this.back_talk.y);
796 this.strikethrough_talktitle.lineStyle(3, Phaser.Color.RED, 1);
797 this.strikethrough_talktitle.moveTo(12, 20);
798 this.strikethrough_talktitle.lineTo(67, 20);
799 this.add(this.strikethrough_talktitle);
800 style = { align: 'left', fill: 'white', font: 'Ubuntu Mono', fontSize: 18, fontWeight: 'bold' };
801 this.text_talk = new Phaser.Text(game, this.back_talk.x + 35, this.back_talk.y + 40, null, style);
802 this.text_talk.wordWrap = true;
803 this.text_talk.wordWrapWidth = this.back_talk.width - 70;
804 this.text_talk.lineSpacing = -5;
805 this.add(this.text_talk);
806 this.leaveTalk();
807 this.last_talk = 0;
808 }
809
810 dropNotice(text) {
811 this.text_notice.text = text;
812 this.back_notice.visible = true;
813 this.text_notice.visible = true;
814 }
815
816 dropNoticeTimeout(timeout, text) {
817 this.dropNotice(text);
818 game.time.events.add(timeout, this.clearNotice, this);
819 }
820
821 clearNotice() {
822 this.back_notice.visible = false;
823 this.text_notice.visible = false;
824 }
825
826 npcMenu(npc) {
827 if (!this.inMenu) {
828 this.inMenu = true;
829 this.clearNotice();
830 this.text_menutitle.text = npc.shortname;
831 this.back_menu.visible = true;
832 this.text_menutitle.visible = true;
833 this.text_menuitem_Talk.visible = true;
834 this.text_menuitem_Leave.visible = true;
835 this.text_menuitem_Take.visible = true;
836 this.currentmenuitem = MENUITEM_TALK;
837 this.actualizeCursorPosition();
838 this.text_menucursor.visible = true;
839 this.last_menustep = game.time.now;
840 }
841 }
842
843 leaveMenu() {
844 this.back_menu.visible = false;
845 this.text_menutitle.visible = false;
846 this.text_menuitem_Talk.visible = false;
847 this.text_menuitem_Leave.visible = false;
848 this.text_menuitem_Take.visible = false;
849 this.text_menucursor.visible = false;
850 this.inMenu = false;
851 }
852
853 talk(dialogue) {
854 this.inTalk = true;
855 this.dialogue = dialogue;
856 this.advanceTalk();
857 this.back_talk.visible = true;
858 this.text_talktitle.visible = true;
859 this.text_talk.visible = true;
860 }
861
862 leaveTalk() {
863 this.inTalk = false;
864 this.dialogue = null;
865 this.back_talk.visible = false;
866 this.text_talktitle.visible = false;
867 this.strikethrough_talktitle.visible = false;
868 this.text_talk.visible = false;
869 }
870
871 advanceTalk() {
872 console.log(this.dialogue);
873 console.log(this.dialogue.actual());
874 var actualdialogue = this.dialogue.actual();
875 if (actualdialogue) {
876 if (actualdialogue.actor.disguise) {
877 this.text_talktitle.text = actualdialogue.actor.shortname + " " + actualdialogue.actor.disguise.shortname;
878 this.strikethrough_talktitle.visible = true;
879 }
880 else {
881 this.text_talktitle.text = actualdialogue.actor.shortname;
882 this.strikethrough_talktitle.visible = false;
883 }
884 this.text_talk.text = actualdialogue.text;
885 this.dialogue.advance();
886 }
887 else {
888 this.leaveTalk();
889 logic.endTalk();
890 }
891 this.last_talk = game.time.now;
892 }
893
894 actualizeCursorPosition() {
895 this.text_menucursor.y = this.text_menuitem_Talk.y + (this.currentmenuitem * GUI_MENUITEM_DISTANCE);
896 }
897
898 update() {
899 if ((this.inMenu) && (hasTimePassed(this.last_menustep, WAIT_MENUSTEP))) {
900 if (cursors.up.isDown)
901 {
902 this.currentmenuitem--;
903 if (this.currentmenuitem < MENUITEM_TALK) this.currentmenuitem = MENUITEM_TAKE;
904 this.actualizeCursorPosition();
905 }
906 else if (cursors.down.isDown)
907 {
908 this.currentmenuitem++;
909 if (this.currentmenuitem > MENUITEM_TAKE) this.currentmenuitem = MENUITEM_TALK;
910 this.actualizeCursorPosition();
911 }
912 if (game.input.keyboard.isDown(Phaser.Keyboard.ENTER)) {
913 logic.callMenu(this.currentmenuitem);
914 }
915 this.last_menustep = game.time.now;
916 }
917 if ((this.inTalk) && (game.input.keyboard.isDown(Phaser.Keyboard.ENTER)) && (hasTimePassed(this.last_talk, WAIT_TALK))) {
918 this.advanceTalk();
919 }
920 }
921 }
922
923 class GameLogic {
924
925 constructor() {
926 this.player = this.clara = this.carlos = this.saiki = this.peter = this.bianca = null;
927 this.gameinterface = new GameInterface(game, game.stage);
928 //this.doors = game.add.group(game.world, "doors");
929 this.last_menuselect = 0;
930 }
931
932 createObject(object) {
933 switch (object.type) {
934 case 'spawnpoint': this.createCharacter(object); break;
935 case 'door': this.createDoor(object); break;
936 case '': console.error("Object type is empty:", object); break;
937 default: console.error("Unknown object type:", object);
938 }
939 }
940
941 createCharacter(object) {
942 var newChar;
943 switch (object.name) {
944 case 'john':
945 newChar = new Player(object.x, object.y, 'player');
946 this.player = newChar;
947 this.player.enablePhysics();
948 game.camera.follow(this.player);
949 break;
950 case 'clara':
951 newChar = new NPC_Clara(object.x, object.y, 'clara', "Clara", "Clara Tnavelerri", 200);
952 this.clara = newChar;
953 break;
954 case 'carlos':
955 newChar = new NPC_Carlos(object.x, object.y, 'carlos', "Carlos", "Carlos Elbacalper", 150);
956 this.carlos = newChar;
957 break;
958 case 'saiki':
959 newChar = new NPC_Saiki(object.x, object.y, 'saiki', "Saiki", "Saiki Ytpme", 150);
960 this.saiki = newChar;
961 break;
962 case 'peter':
963 newChar = new NPC_Peter(object.x, object.y, 'peter', "Peter", "Peter Tluaf", 225);
964 this.peter = newChar;
965 break;
966 case 'bianca':
967 newChar = new NPC_Bianca(object.x, object.y, 'bianca', "Bianca", "Bianca Gnihton", 150);
968 this.bianca = newChar;
969 break;
970 default:
971 console.error("Unknown character:", object);
972 }
973 newChar.name = object.name;
974 game.add.existing(newChar);
975 console.log(newChar);
976 }
977
978 createDoor(object) {
979 /* Calculate movement vector and correct position (32 = half tile width/height). */
980 var vector;
981 switch (object.rotation) {
982 case undefined:
983 case 0: vector = new Phaser.Point( -1, 0); object.x += 32; object.y -= 32; break;
984 case 90: vector = new Phaser.Point( 0, -1); object.x += 32; object.y += 32; break;
985 case 180: vector = new Phaser.Point( 1, 0); object.x -= 32; object.y += 32; break;
986 case 270: vector = new Phaser.Point( 0, 1); object.x -= 32; object.y -= 32; break;
987 default: console.error("Invalid rotation:", object.rotation);
988 }
989 this.doors.add(new Door(object.x, object.y, object.name, object.rotation, vector, object.properties.longpanel));
990 }
991
992 callMenu(menuitem) {
993 console.log("Menu callback received:", menuitem);
994 this.last_menuselect = game.time.now;
995 this.gameinterface.leaveMenu();
996 switch (menuitem) {
997 case MENUITEM_TALK:
998 this.player.interactablenpc.actionTalk();
999 break;
1000 case MENUITEM_LEAVE:
1001 this.player.interactablenpc.actionLeave();
1002 this.player.unfreeze();
1003 break;
1004 case MENUITEM_TAKE:
1005 if (this.player.interactablenpc.actionTake())
1006 this.player.unfreeze();
1007 break;
1008 }
1009 }
1010
1011 endTalk() {
1012 if (this.player.interactablenpc) {
1013 if (this.player.interactablenpc.endTalk()) {
1014 this.gameinterface.npcMenu(this.player.interactablenpc);
1015 }
1016 else {
1017 this.player.unfreeze();
1018 this.last_menuselect = game.time.now;
1019 }
1020 }
1021 }
1022
1023 openDoor(doorname) {
1024 this.doors.children.forEach(function(o) { if (o.name == doorname) o.open(); });
1025 }
1026
1027 closeDoor(doorname) {
1028 this.doors.children.forEach(function(o) { if (o.name == doorname) o.close(); });
1029 }
1030
1031 checkAllHappy() {
1032 return (this.clara.happy) && (this.carlos.happy) && (this.saiki.happy);
1033 }
1034
1035 update() {
1036 if ((game.input.keyboard.isDown(Phaser.Keyboard.ENTER)) && (hasTimePassed(this.last_menuselect, WAIT_MENUSTEP))) {
1037 if ((this.player.interactablenpc) && (this.player.interactablenpc.interactable) && (!this.gameinterface.inMenu) && (!this.gameinterface.inTalk)) {
1038 console.log("Starting interaction with", this.player.interactablenpc.fullname);
1039 this.player.freeze();
1040 this.gameinterface.npcMenu(this.player.interactablenpc);
1041 }
1042 }
1043 }
1044
1045 }
1046
1047 class GamePlay extends Phaser.State {
1048
1049 constructor() {
1050
1051 super();
1052 logic = new GameLogic();
1053 game.world.updateOnlyExistingChildren = true;
1054 game.state.add('GameOver', GameOver, false);
1055
1056 }
1057
1058 preload() {
1059
1060 game.load.image('player', 'john.png');
1061 game.load.image('clara', 'clara.png');
1062 game.load.image('carlos', 'carlos.png');
1063 game.load.image('saiki', 'saiki.png');
1064 game.load.image('peter', 'peter.png');
1065 game.load.image('bianca', 'bianca.png');
1066 game.load.image('tileset', 'tileset.png');
1067 game.load.image('objects', 'objects.png');
1068 game.load.tilemap('gamemap', 'tilemap.json', null, Phaser.Tilemap.TILED_JSON);
1069
1070 }
1071
1072 create() {
1073
1074 game.world.setBounds(0, 0, 800, 600);
1075 game.stage.backgroundColor = '#000000';
1076 game.physics.startSystem(Phaser.Physics.ARCADE);
1077 console.log("Debug enabled:", !game.debug.isDisabled);
1078
1079 var map = game.add.tilemap('gamemap');
1080 map.addTilesetImage('tileset', 'tileset');
1081 map.addTilesetImage('objects', 'objects');
1082 var layer_floor = map.createLayer('floor');
1083 layer_floor.resizeWorld();
1084 this.layer_walls = map.createLayer('walls');
1085 map.setCollisionBetween(1, 100, true, this.layer_walls);
1086 this.layer_furniture = map.createLayer('furniture');
1087 map.setCollisionBetween(1, 100, true, this.layer_furniture);
1088
1089 // FIXME: Don't create a group here like this, it's too ugly! Now I have it here due to the display order.
1090 logic.doors = game.add.group(game.world, "doors");
1091
1092 map.objects['objects'].forEach(function(o) { logic.createObject(o); });
1093 console.log(map.objects);
1094
1095 cursors = game.input.keyboard.createCursorKeys();
1096 console.log(logic);
1097
1098 }
1099
1100 update() {
1101
1102 game.physics.arcade.collide(logic.player, this.layer_walls);
1103 game.physics.arcade.collide(logic.player, this.layer_furniture);
1104 game.physics.arcade.collide(logic.player, logic.doors);
1105 logic.update();
1106
1107 }
1108 }
1109
1110 class GameOver extends Phaser.State {
1111
1112 create() {
1113
1114 console.log("Entered GameOver state.");
1115 game.stage.removeChildren(1);
1116 game.camera.follow(logic.player);
1117 logic.player.freeze();
1118
1119 var g = game.add.group(game.stage, "GAMEOVER");
1120 this.back_gameover = new Phaser.Graphics(game, 100, game.height / 2 - 200);
1121 this.back_gameover.beginFill(0x000000);
1122 this.back_gameover.drawRect(0, 0, game.width - 200, 400);
1123 this.back_gameover.endFill();
1124 this.back_gameover.lineStyle(3, Phaser.Color.YELLOW, 1);
1125 this.back_gameover.moveTo(10, 35);
1126 this.back_gameover.lineTo(this.back_gameover.width - 10, 35);
1127 g.add(this.back_gameover);
1128 var style = { align: 'left', fill: 'yellow', font: 'Ubuntu Mono', fontSize: 22, fontWeight: 'bold' };
1129 this.text_title = new Phaser.Text(game, this.back_gameover.x + 15, this.back_gameover.y + 6, "ABRUPT GAME OVER", style);
1130 g.add(this.text_title);
1131 style = { align: 'left', fill: 'white', font: 'Ubuntu Mono', fontSize: 18, fontWeight: 'bold' };
1132 this.text_gameover = new Phaser.Text(game, this.back_gameover.x + 35, this.back_gameover.y + 60, null, style);
1133 this.text_gameover.wordWrap = true;
1134 this.text_gameover.wordWrapWidth = this.back_gameover.width - 70;
1135 this.text_gameover.lineSpacing = -5;
1136 g.add(this.text_gameover);
1137
1138 this.text_gameover.text = this.assess();
1139
1140 }
1141
1142 assess() {
1143 if (logic.checkAllHappy()) {
1144 return "You listened to all of your colleagues' and affected them to make their day a little better. Next day, the company fired Clara, Carlos, Saiki, and you, to comply with its productivity requirements. The company's internal code demand unconditional and illimitable loyalty from employees to maximize productivity. This includes requisites for employees not to exercise human qualities or express personal needs within and outside the corporate environment. The company has determined that neither of the mentioned people complied to these guidelines, due to the amount of socialization they pursued during the work day.\n\nIronically, the layoffs turned everyone's life for the better.";
1145 }
1146 else if (logic.player.disguise) {
1147 this.text_gameover.style.fill = 'red';
1148 return "You went on your day to accomplish your tasks without caring about anyone. Where are your colleagues now? Clara, Carlos, Saiki? You don't know. But you don't even care. You have never seen them after they served your needs.\n\nNext day, the company promoted you for your effectiveness and loyalty.";
1149 }
1150 else {
1151 return "The company is concerned that you may develop other needs (like wanting to pursue hobbies, spend time with friends and family) those compete for the time you devote for your job. The company reminds you that they demand your entire being to exclusively serve the company's interests. Socializing with your colleagues outside the dedicated team building occasions may hurt your performance. To comply with the productivity requirements, the company has terminated your employment.\n\nClara, Carlos, Saiki are still loyal employees of the company. Probably you could have done something different to find a better outcome.";
1152 }
1153 }
1154
1155 }