Remove abrupt game over
[wgj58.git] / wgj58.js
index e034b01..9405c5a 100644 (file)
--- a/wgj58.js
+++ b/wgj58.js
@@ -40,10 +40,63 @@ class Dialogue {
 }
 
 class Door extends Phaser.TileSprite {
-       constructor(x, y, name, vector, longpanel) {
+       constructor(x, y, name, rotation, vector, longpanel) {
                super(game, x, y, 64, 64, 'objects');
-               this.tilePosition = new Phaser.Point(-64, -64);
-               console.log("New door:", this);
+               this.name = name;
+               this.longpanel = longpanel;
+               if (!longpanel) {
+                       this.anchor = new Phaser.Point(0.5, 0.5);
+                       this.tilePosition = new Phaser.Point(-64, -64);
+                       this.openvector = Phaser.Point.multiply(vector, new Phaser.Point(56, 56));
+               }
+               else {
+                       this.width *= 2;
+                       this.anchor = new Phaser.Point(0.75, 0.5);
+                       this.tilePosition = new Phaser.Point(0, -64);
+                       this.openvector = Phaser.Point.multiply(vector, new Phaser.Point(116, 116));
+               }
+               if (rotation === undefined) rotation = 0;
+               this.rotation = rotation * (Math.PI / 180);
+               this.closetween = game.add.tween(this).to({ x: this.position.x, y: this.position.y }, 1000, Phaser.Easing.Sinusoidal.InOut, false, 0, 0, false);
+               this.openposition = Phaser.Point.add(this.position, this.openvector);
+               this.opentween = game.add.tween(this).to({ x: this.openposition.x, y: this.openposition.y }, 1000, Phaser.Easing.Sinusoidal.InOut, false, 0, 0, false);
+               this.isOpen = false;
+               game.physics.arcade.enable(this);
+               this.body.immovable = true;
+               this.setBody(rotation);
+       }
+
+       setBody(rotation) {
+               switch(rotation) {
+                       case 0:
+                       case 180:
+                               this.body.setSize(this.width, 10, this.longpanel * (rotation / 180) * 64, 27);
+                               break;
+                       case 90:
+                       case 270:
+                               this.body.setSize(10, this.width, 27 + (this.longpanel * 64), this.longpanel * ((rotation - 270) / 180) * 64);
+                               break;
+                       default:
+                               console.log("Unable to set body due to unknown rotation:", rotation);
+               }
+       }
+
+       open() {
+               if (!this.isOpen) {
+                       this.opentween.start();
+                       this.isOpen = true;
+               }
+       }
+
+       close() {
+               if (this.isOpen) {
+                       this.closetween.start();
+                       this.isOpen = false;
+               }
+       }
+
+       update() {
+               game.debug.body(this);
        }
 }
 
@@ -106,6 +159,8 @@ class Player extends Phaser.Sprite {
        takeMe(npc) {
                this.loadTexture(npc.key);
                npc.kill();
+               this.disguise = npc;
+               logic.gameinterface.dropNoticeTimeout(Phaser.Timer.SECOND * 5, "You are now identified as " + npc.fullname + "!");
        }
 }
 
@@ -118,11 +173,13 @@ class GameNPC extends Phaser.Sprite {
                this.interaction_distance = interaction_distance;
                this.interactable = false;
                this.talkcount = 0;
+               this.happy = false;
        }
 
        kill() {
                super.kill();
                this.exists = false;
+               this.happy = false;                     // Dead people are not happy.
        }
 
        update() {
@@ -137,6 +194,11 @@ class GameNPC extends Phaser.Sprite {
                        logic.player.offerInteraction(null);
                        this.interactable = false;
                }
+               if ((this.teleport_instructions) && (game.physics.arcade.distanceBetween(this, logic.player) > (game.width + 200))) {
+                       this.position = this.teleport_instructions.newPosition;
+                       this.teleport_instructions.callback(this.teleport_instructions.callbackValue);
+                       this.teleport_instructions = null;
+               }
        }
 
        actionTalk() {
@@ -155,6 +217,16 @@ class GameNPC extends Phaser.Sprite {
        endTalk() {
                return true;
        }
+
+       makeHappy() {
+               this.happy = true;
+               console.log(this.shortname, "is happy!");
+       }
+
+       offscreenTeleportation(newPosition, callback, callbackValue) {
+               this.teleport_instructions = { newPosition: newPosition, callback: callback, callbackValue: callbackValue };
+               console.log("Offscreen teleport request registered:", this.teleport_instructions);
+       }
 }
 
 class NPC_Clara extends GameNPC {
@@ -169,7 +241,9 @@ class NPC_Clara extends GameNPC {
                                        { actor: logic.player, text: "Well, maybe if we dare to joke about it, it won't happen to us..." },
                                        { actor: this, text: "Wish it worked like that... Is it some superstition like the belief that having an umbrella with you prevents rain?" },
                                        { actor: logic.player, text: "Nah, that actually works; it's not a superstition, but Murphy's Law!" },
-                                       { actor: this, text: "If you say so..." } ] ));
+                                       { actor: this, text: "If you say so..." },
+                                       { actor: this, text: "Anyway, I logged you in and opened the door for you." } ] ));
+                               logic.openDoor("cutedoor");
                                break;
                        case 1:
                                logic.gameinterface.talk(new Dialogue( [ { actor: this, text: "John, have you ever thought about losing your employee card?" },
@@ -207,6 +281,8 @@ class NPC_Clara extends GameNPC {
                                        { actor: logic.player, text: "Would you go out on a date with me?" },
                                        { actor: this, text: "..." },
                                        { actor: this, text: "No." } ] ));
+                               // FIXME: Clara should have another happy condition.
+                               this.makeHappy();
                                break;
                        default:
                                logic.gameinterface.talk(new Dialogue( [ { actor: this, text: "..." } ] ));
@@ -218,11 +294,238 @@ class NPC_Clara extends GameNPC {
                logic.gameinterface.dropNotice(this.shortname + ": Have a great day, John!");
        }
 
+       actionTake() {
+               logic.openDoor("cutedoor");
+               return super.actionTake();
+       }
+
        endTalk() {
                return (this.talkcount < 6);
        }
 }
 
+class NPC_Carlos extends GameNPC {
+       actionTalk() {
+               if (logic.clara.alive) {
+                       switch (this.talkcount) {
+                               case 0:
+                                       logic.gameinterface.talk(new Dialogue( [ { actor: logic.player, text: "Good morning, Carlos! What's up?" },
+                                               { actor: this, text: "Hey, John! Not too much, I'm just trying to sell some shit to this new client." },
+                                               { actor: logic.player, text: "And so? Is it hard to convince them?" },
+                                               { actor: this, text: "Of course, they don't want to buy. It's shit." },
+                                               { actor: this, text: "I mean, who would want to buy shit?" },
+                                               { actor: logic.player, text: "Yeah. Relatable... But why are you trying to sell shit? I mean, why not one of our cutting edge technologies?" },
+                                               { actor: this, text: "They couldn't afford it." },
+                                               { actor: logic.player, text: "Then why are you trying to sell them... anything at all? They'd better off with a cheaper company." },
+                                               { actor: this, text: "Company policies. Plus the management instructed me to sell to them, no matter what." },
+                                               { actor: logic.player, text: "That sucks... Well... good luck!" },
+                                               { actor: this, text: "Thanks..." } ] ));
+                                       logic.closeDoor("cutedoor");
+                                       logic.openDoor("carlosdoor");
+                                       break;
+                               case 1:
+                                       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." },
+                                               { actor: this, text: "These layoffs are terrifying. They let go of anyone for even the slightest mistake." },
+                                               { actor: logic.player, text: "But it's not a mistake when our client doesn't buy something they don't need." },
+                                               { actor: this, text: "Tell this to my boss..." } ] ));
+                                       break;
+                               case 2:
+                                       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." },
+                                               { actor: this, text: "..." },
+                                               { 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..." },
+                                               { 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." },
+                                               { actor: this, text: "So I thought I could grow my own pig in the garden from pig seeds!" },
+                                               { actor: logic.player, text: "Interesting. Where are you going with this?" },
+                                               { actor: this, text: "I don't know... sometimes I feel like I'd rather sell pig semen to our clients, heh!" },
+                                               { actor: this, text: "Uhm..." },
+                                               { actor: this, text: "Totally don't tell this to Saiki!" } ] ));
+                                       this.pigsemen = true;
+                                       break;
+                               case 3:
+                                       logic.gameinterface.talk(new Dialogue( [ { actor: this, text: "Weren't you heading to the IT department to the right?" },
+                                               { actor: this, text: "You know... the green department which looks way better than blue!" },
+                                               { actor: this, text: "..." },
+                                               { actor: this, text: "Damn, why do I have to work in blue? I just feel... so blue about it." } ] ));
+                                       break;
+                               case 4:
+                                       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." },
+                                               { actor: this, text: "You're so lucky that you can work with her every day!" } ] ));
+                                       break;
+                               default:
+                                       logic.gameinterface.talk(new Dialogue( [ { actor: this, text: "Guess you'll stay here then. It's cool, you're great company anyway." } ] ));
+                       }
+               }
+               else {
+                       switch (this.talkcount) {
+                               case 0:
+                                       logic.gameinterface.talk(new Dialogue( [ { actor: logic.player, text: "Good morning, Carlos!" },
+                                               { actor: this, text: "Whoa, Clara! You have changed so much! I barely recognize you. What's up?" },
+                                               { actor: logic.player, text: "I need to talk to Saiki at the IT department, but... my card doesn't allow me to enter there." },
+                                               { actor: this, text: "Well... I can certainly help you with that..." },
+                                               { actor: this, text: "..." } ] ));
+                                       break;
+                               case 1:
+                                       logic.gameinterface.talk(new Dialogue( [ { actor: logic.player, text: "Carlos. You promised to help me." },
+                                               { actor: this, text: "Uhm... It's just... Please give me 5 mins to finish this e-mail." },
+                                               { actor: logic.player, text: "I don't have much time, Carlos." },
+                                               { 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." },
+                                               { actor: logic.player, text: "..." } ] ));
+                                       break;
+                               case 2:
+                                       logic.gameinterface.talk(new Dialogue( [ { actor: logic.player, text: "Time is up, Carlos!" },
+                                               { actor: this, text: "Please give me just another min." },
+                                               { actor: logic.player, text: "Fine. Please just give me your card and I'll help myself!" },
+                                               { actor: this, text: "But... you know that company policies forbid that, Clara! Please just be a little more patient!" },
+                                               { actor: logic.player, text: "You will give me your card now or you will regret!" },
+                                               { actor: this, text: "...?" },
+                                               { actor: this, text: "You're not gonna treat me like this. Forget it!" },
+                                               { actor: logic.player, text: "You'll not work here tomorrow." } ] ));
+                                       break;
+                               default:
+                                       logic.gameinterface.talk(new Dialogue( [ { actor: this, text: "..." } ] ));
+                       }
+               }
+               super.actionTalk();
+       }
+
+       actionLeave() {
+               if (logic.clara.alive) {
+                       logic.gameinterface.dropNotice(this.shortname + ": Bye, John! Pass on my greetings to Saiki!");
+               }
+       }
+
+       actionTake() {
+               logic.closeDoor("cutedoor");
+               logic.openDoor("carlosdoor");
+               return super.actionTake();
+       }
+
+       endTalk() {
+               return (logic.clara.alive) || (this.talkcount < 3);
+       }
+}
+
+class NPC_Saiki extends GameNPC {
+       actionTalk() {
+               if (logic.carlos.alive) {
+                       switch (this.talkcount) {
+                               case 0:
+                                       logic.gameinterface.talk(new Dialogue( [ { actor: logic.player, text: "Hi Saiki!" },
+                                               { actor: this, text: "Hi John! Glad you arrived, here's some work for you!" },
+                                               { actor: logic.player, text: "Awesome! What is it?" },
+                                               { actor: this, text: "Haha, joking! Actually, our queue is suspiciously empty for today." },
+                                               { actor: logic.player, text: "Yeah... That's really suspicious!" },
+                                               { actor: logic.player, text: "Maybe I can get home today in time?" },
+                                               { actor: this, text: "You mean, you wouldn't spend the mandatory free extra working hours?" },
+                                               { 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?" },
+                                               { actor: this, text: "*Whispers with wink.* I hope you get my sarcasm." },
+                                               { actor: logic.player, text: "Haha! I always get it, Saiki!" } ] ));
+                                       logic.closeDoor("carlosdoor");
+                                       logic.openDoor("saikidoor");
+                                       break;
+                               case 1:
+                                       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." },
+                                               { actor: this, text: "Clara has to enter people manually." },
+                                               { actor: logic.player, text: "Yeah, I'll definitely check that." } ] ));
+                                       break;
+                               case 2:
+                                       logic.gameinterface.talk(new Dialogue( [ { actor: logic.player, text: "So... what's up with the trash can?" },
+                                               { actor: this, text: "I'm always up for such deep conversation" },
+                                               { actor: this, text: "about trash cans." },
+                                               { 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." },
+                                               { 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." },
+                                               { actor: logic.player, text: "Hmm... Maybe it's too much to ask. Can we take one from another department?" },
+                                               { actor: this, text: "No, everyone holds on to their trash cans." },
+                                               { actor: logic.player, text: "You certainly did your research." },
+                                               { actor: this, text: "Of course. It's an important subject." } ] ));
+                                       break;
+                               case 3:
+                                       logic.gameinterface.talk(new Dialogue( [ { actor: this, text: "My parents named me after a Japanese rock singer." },
+                                               { actor: logic.player, text: "Cool! Which band?" },
+                                               { 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." } ] ));
+                                       break;
+                               default:
+                                       if ((logic.carlos.pigsemen) && (this.talkcount == 4)) {
+                                               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?" },
+                                                       { actor: this, text: "Hmm..." },
+                                                       { actor: this, text: "I guess it didn't work." },
+                                                       { actor: this, text: "So do you want to know what I think about this?" },
+                                                       { actor: this, text: "..." },
+                                                       { actor: this, text: "IT'S BRILLIANT!!!" },
+                                                       { actor: this, text: "You know, it really sparkled my artistic vision! Now I must draw a pig with its legs rooted into the ground!" },
+                                                       { actor: logic.player, text: "That's gross. Poor pig." },
+                                                       { 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." },
+                                                       { actor: logic.player, text: "You have a point." },
+                                                       { 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." } ] ));
+                                               this.offscreenTeleportation(new Phaser.Point(logic.carlos.x, logic.carlos.y + 64), this.tpDone, this);
+                                       }
+                                       else {
+                                               if (Phaser.Math.random() < 0.5) {
+                                                       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!" } ] ));
+                                               }
+                                               else {
+                                                       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." } ] ));
+                                               }
+                                       }
+                       }
+               }
+               else {
+                       switch (this.talkcount) {
+                               case 0:
+                                       logic.gameinterface.talk(new Dialogue( [ { actor: logic.player, text: "I love you, Saiki!" },
+                                               { actor: this, text: "Hi Carlos..." },
+                                               { actor: logic.player, text: "I'm infatuated by the mere thought of you." },
+                                               { actor: this, text: "Well... it sounds pretty much creepy." },
+                                               { actor: logic.player, text: "Will you go out on a date with me?" },
+                                               { actor: this, text: "..." },
+                                               { actor: this, text: "Sorry to hurt your feelings, but... even though I like you... Your sudden, unprecedented confession makes me scared." },
+                                               { actor: this, text: "Especially with that facial expression." },
+                                               { actor: this, text: "I mean... you're not even joking." },
+                                               { actor: this, text: "So sorry... I won't date you." } ] ));
+                                       break;
+                               case 1:
+                                       logic.gameinterface.talk(new Dialogue( [ { actor: logic.player, text: "I thought I could impress you." },
+                                               { actor: this, text: "I'm sorry." } ] ));
+                                       break;
+                               case 2:
+                                       logic.gameinterface.talk(new Dialogue( [ { actor: logic.player, text: "You will give me your card." },
+                                               { actor: this, text: "Geez, what for? Go back to your department and work!" },
+                                               { actor: logic.player, text: "I need it." },
+                                               { actor: this, text: "..." } ] ));
+                                       break;
+                               default:
+                                       logic.gameinterface.talk(new Dialogue( [ { actor: this, text: "Don't you have anything better to do, Carlos?" } ] ));
+                       }
+               }
+               super.actionTalk();
+       }
+
+       actionLeave() {
+               if (logic.carlos.alive) {
+                       logic.gameinterface.dropNotice(this.shortname + ": It was nice talking to you!");
+               }
+       }
+
+       actionTake() {
+               logic.closeDoor("carlosdoor");
+               logic.openDoor("saikidoor");
+               logic.carlos.kill();
+               return super.actionTake();
+       }
+
+       endTalk() {
+               return (logic.carlos.alive);
+       }
+
+       tpDone(value) {
+               console.log("Woot-woot! Teleport complete:", value);
+               value.makeHappy();
+               logic.carlos.makeHappy();
+               // FIXME: Need to find a prettier way than this.
+               logic.carlos.update = function() { };           // Disable Carlos' interaction. (Saiki will talk for him.)
+       }
+}
+
 
 class GameInterface extends Phaser.Group {
        constructor(game, parent) {
@@ -271,9 +574,14 @@ class GameInterface extends Phaser.Group {
                this.back_talk.lineTo(this.back_talk.width - 10, 35);
                this.add(this.back_talk);
                style = { align: 'left', fill: 'yellow', font: 'Ubuntu Mono', fontSize: 22, fontWeight: 'bold' };
-               this.text_talktitle = new Phaser.Text(game, this.back_talk.x, this.back_talk.y, null, style);
-               this.text_talktitle.anchor.setTo(-0.2, -0.2);
+               this.text_talktitle = new Phaser.Text(game, this.back_talk.x + 15, this.back_talk.y + 6, null, style);
+               //this.text_talktitle.anchor.setTo(-0.2, -0.2);
                this.add(this.text_talktitle);
+               this.strikethrough_talktitle = new Phaser.Graphics(game, this.back_talk.x, this.back_talk.y);
+               this.strikethrough_talktitle.lineStyle(3, Phaser.Color.RED, 1);
+               this.strikethrough_talktitle.moveTo(12, 20);
+               this.strikethrough_talktitle.lineTo(67, 20);
+               this.add(this.strikethrough_talktitle);
                style = { align: 'left', fill: 'white', font: 'Ubuntu Mono', fontSize: 18, fontWeight: 'bold' };
                this.text_talk = new Phaser.Text(game, this.back_talk.x + 35, this.back_talk.y + 40, null, style);
                this.text_talk.wordWrap = true;
@@ -290,6 +598,11 @@ class GameInterface extends Phaser.Group {
                this.text_notice.visible = true;
        }
 
+       dropNoticeTimeout(timeout, text) {
+               this.dropNotice(text);
+               game.time.events.add(timeout, this.clearNotice, this);
+       }
+
        clearNotice() {
                this.back_notice.visible = false;
                this.text_notice.visible = false;
@@ -336,6 +649,7 @@ class GameInterface extends Phaser.Group {
                this.dialogue = null;
                this.back_talk.visible = false;
                this.text_talktitle.visible = false;
+               this.strikethrough_talktitle.visible = false;
                this.text_talk.visible = false;
        }
 
@@ -344,7 +658,14 @@ class GameInterface extends Phaser.Group {
                console.log(this.dialogue.actual());
                var actualdialogue = this.dialogue.actual();
                if (actualdialogue) {
-                       this.text_talktitle.text = actualdialogue.actor.shortname;
+                       if (actualdialogue.actor.disguise) {
+                               this.text_talktitle.text = actualdialogue.actor.shortname + " " + actualdialogue.actor.disguise.shortname;
+                               this.strikethrough_talktitle.visible = true;
+                       }
+                       else {
+                               this.text_talktitle.text = actualdialogue.actor.shortname;
+                               this.strikethrough_talktitle.visible = false;
+                       }
                        this.text_talk.text = actualdialogue.text;
                        this.dialogue.advance();
                }
@@ -415,6 +736,14 @@ class GameLogic {
                                newChar = new NPC_Clara(object.x, object.y, 'clara', "Clara", "Clara Tnavelerri", 200);
                                this.clara = newChar;
                                break;
+                       case 'carlos':
+                               newChar = new NPC_Carlos(object.x, object.y, 'carlos', "Carlos", "Carlos Elbacalper", 150);
+                               this.carlos = newChar;
+                               break;
+                       case 'saiki':
+                               newChar = new NPC_Saiki(object.x, object.y, 'saiki', "Saiki", "Saiki Ytpme", 150);
+                               this.saiki = newChar;
+                               break;
                        default:
                                console.error("Unknown character:", object);
                }
@@ -424,16 +753,17 @@ class GameLogic {
        }
 
        createDoor(object) {
+               /* Calculate movement vector and correct position (32 = half tile width/height). */
                var vector;
                switch (object.rotation) {
                        case undefined:
-                       case 0:         vector = new Phaser.Point( -1,  0); break;
-                       case 90:        vector = new Phaser.Point(  0, -1); break;
-                       case 180:       vector = new Phaser.Point(  1,  0); break;
-                       case 270:       vector = new Phaser.Point(  0,  1); break;
+                       case 0:         vector = new Phaser.Point( -1,  0); object.x += 32; object.y -= 32; break;
+                       case 90:        vector = new Phaser.Point(  0, -1); object.x += 32; object.y += 32; break;
+                       case 180:       vector = new Phaser.Point(  1,  0); object.x -= 32; object.y += 32; break;
+                       case 270:       vector = new Phaser.Point(  0,  1); object.x -= 32; object.y -= 32; break;
                        default:        console.error("Invalid rotation:", object.rotation);
                }
-               this.doors.add(new Door(object.x, object.y, object.name, vector, object.properties.longpanel));
+               this.doors.add(new Door(object.x, object.y, object.name, object.rotation, vector, object.properties.longpanel));
        }
 
        callMenu(menuitem) {
@@ -467,6 +797,18 @@ class GameLogic {
                }
        }
 
+       openDoor(doorname) {
+               this.doors.children.forEach(function(o) { if (o.name == doorname) o.open(); });
+       }
+
+       closeDoor(doorname) {
+               this.doors.children.forEach(function(o) { if (o.name == doorname) o.close(); });
+       }
+
+       checkAllHappy() {
+               return (this.clara.happy) && (this.carlos.happy) && (this.saiki.happy);
+       }
+
        update() {
                if ((game.input.keyboard.isDown(Phaser.Keyboard.ENTER)) && (hasTimePassed(this.last_menuselect, WAIT_MENUSTEP))) {
                        if ((this.player.interactablenpc) && (this.player.interactablenpc.interactable) && (!this.gameinterface.inMenu) && (!this.gameinterface.inTalk)) {
@@ -486,7 +828,7 @@ class GamePlay extends Phaser.State {
                super();
                logic = new GameLogic();
                game.world.updateOnlyExistingChildren = true;
-               //game.state.add('GameOver', GameOver, false);
+               game.state.add('GameOver', GameOver, false);
 
        }
 
@@ -494,6 +836,7 @@ class GamePlay extends Phaser.State {
 
                game.load.image('player', 'john.png');
                game.load.image('clara', 'clara.png');
+               game.load.image('carlos', 'carlos.png');
                game.load.image('saiki', 'saiki.png');
                game.load.image('tileset', 'tileset.png');
                game.load.image('objects', 'objects.png');
@@ -506,6 +849,7 @@ class GamePlay extends Phaser.State {
                game.world.setBounds(0, 0, 800, 600);
                game.stage.backgroundColor = '#000000';
                game.physics.startSystem(Phaser.Physics.ARCADE);
+               console.log("Debug enabled:", !game.debug.isDisabled);
 
                var map = game.add.tilemap('gamemap');
                map.addTilesetImage('tileset', 'tileset');
@@ -532,7 +876,55 @@ class GamePlay extends Phaser.State {
 
                game.physics.arcade.collide(logic.player, this.layer_walls);
                game.physics.arcade.collide(logic.player, this.layer_furniture);
+               game.physics.arcade.collide(logic.player, logic.doors);
                logic.update();
 
        }
 }
+
+class GameOver extends Phaser.State {
+
+       create() {
+
+               console.log("Entered GameOver state.");
+               game.stage.removeChildren(1);
+               game.camera.follow(logic.player);
+               logic.player.freeze();
+
+               var g = game.add.group(game.stage, "GAMEOVER");
+               this.back_gameover = new Phaser.Graphics(game, 100, game.height / 2 - 200);
+               this.back_gameover.beginFill(0x000000);
+               this.back_gameover.drawRect(0, 0, game.width - 200, 400);
+               this.back_gameover.endFill();
+               this.back_gameover.lineStyle(3, Phaser.Color.YELLOW, 1);
+               this.back_gameover.moveTo(10, 35);
+               this.back_gameover.lineTo(this.back_gameover.width - 10, 35);
+               g.add(this.back_gameover);
+               var style = { align: 'left', fill: 'yellow', font: 'Ubuntu Mono', fontSize: 22, fontWeight: 'bold' };
+               this.text_title = new Phaser.Text(game, this.back_gameover.x + 15, this.back_gameover.y + 6, "ABRUPT GAME OVER", style);
+               g.add(this.text_title);
+               style = { align: 'left', fill: 'white', font: 'Ubuntu Mono', fontSize: 18, fontWeight: 'bold' };
+               this.text_gameover = new Phaser.Text(game, this.back_gameover.x + 35, this.back_gameover.y + 60, null, style);
+               this.text_gameover.wordWrap = true;
+               this.text_gameover.wordWrapWidth = this.back_gameover.width - 70;
+               this.text_gameover.lineSpacing = -5;
+               g.add(this.text_gameover);
+
+               this.text_gameover.text = this.assess();
+
+       }
+
+       assess() {
+               if (logic.checkAllHappy()) {
+                       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.";
+               }
+               else if (logic.player.disguise) {
+                       this.text_gameover.style.fill = 'red';
+                       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.";
+               }
+               else {
+                       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.";
+               }
+       }
+
+}