Add method to reset talk count
[wgj58.git] / wgj58.js
index f14b63701cb75c1c2a2d4ca52771e23f77edb6ac..2c503f0829a15065ad0859591ef4640b72353a0f 100644 (file)
--- a/wgj58.js
+++ b/wgj58.js
@@ -160,6 +160,7 @@ class Player extends Phaser.Sprite {
                this.loadTexture(npc.key);
                npc.kill();
                this.disguise = npc;
+               logic.gameinterface.dropNoticeTimeout(Phaser.Timer.SECOND * 5, "You are now identified as " + npc.fullname + "!");
        }
 }
 
@@ -171,12 +172,14 @@ class GameNPC extends Phaser.Sprite {
                this.fullname = fullname;
                this.interaction_distance = interaction_distance;
                this.interactable = false;
-               this.talkcount = 0;
+               this.resetTalk();
+               this.happy = false;
        }
 
        kill() {
                super.kill();
                this.exists = false;
+               this.happy = false;                     // Dead people are not happy.
        }
 
        update() {
@@ -191,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() {
@@ -209,6 +217,20 @@ class GameNPC extends Phaser.Sprite {
        endTalk() {
                return true;
        }
+
+       resetTalk() {
+               this.talkcount = 0;
+       }
+
+       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 {
@@ -402,6 +424,7 @@ class NPC_Saiki extends GameNPC {
                                                { actor: logic.player, text: "Haha! I always get it, Saiki!" } ] ));
                                        logic.closeDoor("carlosdoor");
                                        logic.openDoor("saikidoor");
+                                       logic.openDoor("peterdoor");
                                        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." },
@@ -430,16 +453,22 @@ class NPC_Saiki extends GameNPC {
                                                        { 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 + 128, logic.carlos.y), this.tpdone);
+                                               this.offscreenTeleportation(new Phaser.Point(logic.carlos.x, logic.carlos.y + 64), this.tpDone, this);
                                        }
                                        else {
-                                               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!" } ] ));
+                                               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." } ] ));
+                                               }
                                        }
                        }
                }
@@ -468,7 +497,7 @@ class NPC_Saiki extends GameNPC {
                                                { actor: this, text: "..." } ] ));
                                        break;
                                default:
-                                       logic.gameinterface.talk(new Dialogue( [ { actor: this, text: "Don't you have anything better to do?" } ] ));
+                                       logic.gameinterface.talk(new Dialogue( [ { actor: this, text: "Don't you have anything better to do, Carlos?" } ] ));
                        }
                }
                super.actionTalk();
@@ -483,12 +512,202 @@ class NPC_Saiki extends GameNPC {
        actionTake() {
                logic.closeDoor("carlosdoor");
                logic.openDoor("saikidoor");
+               logic.openDoor("peterdoor");
+               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 NPC_Peter extends GameNPC {
+       actionTalk() {
+               if (logic.saiki.alive) {
+                       switch (this.talkcount) {
+                               case 0:
+                                       logic.gameinterface.talk(new Dialogue( [ { actor: logic.player, text: "Hi Peter! What's up?" },
+                                               { actor: this, text: "Hi John! Bianca has locked herself in the large meeting room." },
+                                               { actor: logic.player, text: "Why would she do that?" },
+                                               { actor: this, text: "I have no idea." },
+                                               { 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." },
+                                               { actor: logic.player, text: "That was rude. I think you should care more about your colleagues." },
+                                               { actor: this, text: "Ahh... You're right. I didn't mean it. I'm just so frustrated about all the shit going on here." } ] ));
+                                       logic.closeDoor("saikidoor");
+                                       logic.openDoor("peterdoor");
+                                       logic.openDoor("biancadoor");
+                                       break;
+                               case 1:
+                                       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." } ] ));
+                                       break;
+                               default:
+                                       if ((logic.clara.talkcount >= 5) && (this.talkcount == 2)) {
+                                               logic.gameinterface.talk(new Dialogue( [ { actor: logic.player, text: "Do you know Clara from the Reception?" },
+                                                       { actor: this, text: "Of course I do." },
+                                                       { actor: logic.player, text: "I think she's mad at me..." },
+                                                       { actor: this, text: "Why would she?" },
+                                                       { actor: logic.player, text: "I kind of... asked her out." },
+                                                       { actor: logic.player, text: "She said no." },
+                                                       { actor: this, text: "What the heck, dude?" },
+                                                       { actor: this, text: "..." },
+                                                       { actor: this, text: "You should know it's against the company etiquette..." },
+                                                       { actor: this, text: "Regardless, I don't think she's really mad. You're a cool guy." },
+                                                       { 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." } ] ));
+                                               this.offscreenTeleportation(new Phaser.Point(logic.clara.x - 160, logic.clara.y), this.tpDone, this);
+                                       }
+                                       else {
+                                               logic.gameinterface.talk(new Dialogue( [ { actor: this, text: "I'm kind of busy, man." } ] ));
+                                       }
+                       }
+               }
+               else {
+                       switch (this.talkcount) {
+                               case 0:
+                                       logic.gameinterface.talk(new Dialogue( [ { actor: logic.player, text: "What a wonderful day, Peter!" },
+                                               { actor: this, text: "Yikes! Saiki! You scared me!" },
+                                               { actor: logic.player, text: "I didn't even say \"boo\"." },
+                                               { actor: this, text: "Are you OK? You look horrible! You should really see a doctor." },
+                                               { actor: logic.player, text: "I'm fine, Peter. And you?" },
+                                               { actor: this, text: "No... Not at all." },
+                                               { actor: logic.player, text: "I'm sorry to hear that..." } ] ));
+                                       break;
+                               case 1:
+                                       logic.gameinterface.talk(new Dialogue( [ { actor: this, text: "Don't come closer to me!" },
+                                               { actor: logic.player, text: "Why?" },
+                                               { actor: this, text: "I don't mean to offend you, but... you really creep me out..." },
+                                               { actor: logic.player, text: "Why do you say that?" },
+                                               { actor: this, text: "I honestly can't tell what's wrong with you, but... you look like that ghost girl from The Ring!" } ] ));
+                                       break;
+                               case 2:
+                                       logic.gameinterface.talk(new Dialogue( [ { actor: logic.player, text: "Now that was pretty much racist..." },
+                                               { 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?" },
+                                               { actor: this, text: "Geez... that's not even a Japanese movie! And the actress is American..." },
+                                               { actor: logic.player, text: "The original movie is Japanese." },
+                                               { actor: this, text: "I don't care... Just... keep distance, please!" } ] ));
+                                       break;
+                               default:
+                                       if (Phaser.Math.random() < 0.5) {
+                                               logic.gameinterface.talk(new Dialogue( [ { actor: this, text: "STAY AWAY FROM ME!" } ] ));
+                                       }
+                                       else {
+                                               logic.gameinterface.talk(new Dialogue( [ { actor: this, text: "DON'T COME ANY CLOSER!" } ] ));
+                                       }
+                       }
+               }
+               super.actionTalk();
+       }
+
+       actionTake() {
+               logic.closeDoor("saikidoor");
+               logic.openDoor("peterdoor");
+               logic.openDoor("biancadoor");
+               return super.actionTake();
+       }
+
+       endTalk() {
+               return (logic.saiki.alive) && (this.talkcount < 3);
+       }
+
+       tpDone(value) {
+               console.log("Woot-woot! Teleport complete:", value);
+               value.makeHappy();
+               logic.clara.makeHappy();
+               // FIXME: Need to find a prettier way than this.
+               logic.clara.update = function() { };            // Disable Clara's interaction. (Peter will talk for him.)
+       }
+}
+
+class NPC_Bianca extends GameNPC {
+       actionTalk() {
+               if (logic.peter.alive) {
+                       switch (this.talkcount) {
+                               case 0:
+                                       logic.gameinterface.talk(new Dialogue( [ { actor: logic.player, text: "... Hi Bianca!" },
+                                               { actor: this, text: "... Hello John!" },
+                                               { actor: logic.player, text: "So I've been told, you've been spending most of the day in this meeting room..." },
+                                               { actor: this, text: "Yeah?" },
+                                               { actor: logic.player, text: "... Your colleagues want to hold a meeting in this room and you're blocking it." },
+                                               { actor: this, text: "Hmm... Kind of that's the point... There is no need for that meeting." },
+                                               { actor: logic.player, text: "May I know why?" },
+                                               { 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." },
+                                               { actor: this, text: "But today morning, I received a list with about 50% of the employees... Many of them are great friends of mine..." },
+                                               { 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." },
+                                               { actor: logic.player, text: "That's rough. Does this company even need people?" },
+                                               { actor: this, text: "..." } ] ));
+                                       logic.openDoor("cutedoor");
+                                       logic.closeDoor("peterdoor");
+                                       break;
+                               case 1:
+                                       logic.gameinterface.talk(new Dialogue( [ { actor: logic.player, text: "Bianca... Am I on that list?" },
+                                               { actor: this, text: "Yes, John." },
+                                               { actor: this, text: "Well, I'll try to convince them to keep you and many other great folks from the list." },
+                                               { 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." },
+                                               { actor: logic.player, text: "Thank you very much... I'll see what I can do." } ] ));
+                                       break;
+                               case 2:
+                                       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." },
+                                               { actor: this, text: "I know. It's just part of my work..." },
+                                               { 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." },
+                                               { actor: this, text: "... I feel like I'm growing distant from the company." },
+                                               { 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." },
+                                               { actor: logic.player, text: "Yeah, you should definitely not talk about it to others... I mean, maybe only those you deeply trust." },
+                                               { actor: this, text: "I don't care anymore..." },
+                                               { actor: logic.player, text: "Fine." },
+                                               { actor: logic.player, text: "See... probably there is no need for such drama. Maybe it's for the best for everyone." },
+                                               { actor: logic.player, text: "... After all, there IS life beyond the company..." },
+                                               { actor: this, text: "You think so?..." },
+                                               { actor: this, text: "Hmm..." },
+                                               { actor: this, text: "I never thought about it for a long time..." },
+                                               { actor: logic.player, text: "There are plenty of other opportunities for us! Everything will be fine!" },
+                                               { actor: this, text: "..." },
+                                               { actor: this, text: "Thank you. This helped me to regain a bit of my composure..." },
+                                               { actor: logic.player, text: "You're welcome." } ] ));
+                                       this.makeHappy();
+                                       break;
+                               default:
+                                       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." } ] ));
+                       }
+               }
+               else {
+                       switch (this.talkcount) {
+                               case 0:
+                                       logic.gameinterface.talk(new Dialogue( [ { actor: logic.player, text: "..." },
+                                               { actor: this, text: "... So you came for me too." },
+                                               { actor: this, text: "..." },
+                                               { actor: this, text: "I know what you are..." },
+                                               { actor: this, text: "..." },
+                                               { actor: this, text: "Let's get over with." },
+                                               { actor: logic.player, text: "..." } ] ));
+                                       break;
+                               default:
+                                       logic.gameinterface.talk(new Dialogue( [ { actor: this, text: "What are you waiting for?" } ] ));
+                       }
+               }
+               super.actionTalk();
+       }
+
+       actionLeave() {
+               if (this.happy) {
+                       logic.gameinterface.dropNotice(this.shortname + ": Thank you. I'll go back to work soon.");
+               }
+       }
+
+       actionTake() {
+               // All doors open for you if you have all the cards.
+               logic.openDoor("cutedoor");
+               logic.openDoor("carlosdoor");
+               logic.openDoor("saikidoor");
+               return super.actionTake();
+       }
 }
 
 
@@ -500,8 +719,7 @@ class GameInterface extends Phaser.Group {
                this.back_notice.drawRect(0, 0, game.width, 30);
                this.back_notice.endFill();
                this.add(this.back_notice);
-               this.text_notice = new Phaser.Text(game, 0, this.back_notice.y, null, { align: 'left', fill: 'white', font: 'Ubuntu Mono', fontSize: 18, fontWeight: 'bold' });
-               this.text_notice.anchor.setTo(-0.5, -0.2);
+               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' });
                this.add(this.text_notice);
                this.clearNotice();
 
@@ -563,6 +781,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;
@@ -701,9 +924,17 @@ class GameLogic {
                                this.carlos = newChar;
                                break;
                        case 'saiki':
-                               newChar = new NPC_Saiki(object.x, object.y, 'saiki', "Saiki", "Saiki Ytpme", 200);
+                               newChar = new NPC_Saiki(object.x, object.y, 'saiki', "Saiki", "Saiki Ytpme", 150);
                                this.saiki = newChar;
                                break;
+                       case 'peter':
+                               newChar = new NPC_Peter(object.x, object.y, 'peter', "Peter", "Peter Tluaf", 225);
+                               this.peter = newChar;
+                               break;
+                       case 'bianca':
+                               newChar = new NPC_Bianca(object.x, object.y, 'bianca', "Bianca", "Bianca Gnihton", 150);
+                               this.bianca = newChar;
+                               break;
                        default:
                                console.error("Unknown character:", object);
                }
@@ -765,6 +996,10 @@ class GameLogic {
                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)) {
@@ -784,7 +1019,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);
 
        }
 
@@ -794,6 +1029,8 @@ class GamePlay extends Phaser.State {
                game.load.image('clara', 'clara.png');
                game.load.image('carlos', 'carlos.png');
                game.load.image('saiki', 'saiki.png');
+               game.load.image('peter', 'peter.png');
+               game.load.image('bianca', 'bianca.png');
                game.load.image('tileset', 'tileset.png');
                game.load.image('objects', 'objects.png');
                game.load.tilemap('gamemap', 'tilemap.json', null, Phaser.Tilemap.TILED_JSON);
@@ -837,3 +1074,50 @@ class GamePlay extends Phaser.State {
 
        }
 }
+
+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.";
+               }
+       }
+
+}