Lesterpig/openparty-mafia

View on GitHub
definition.js

Summary

Maintainability
C
1 day
Test Coverage
/**
 * MAIN DEFINITION FILE FOR OPENPARTY-MAFIA
 * LICENSED UNDER GPLv3
 *
 * From the original idea of Dmitry Davidoff.
 */

'use strict';

var Emitter = require("events").EventEmitter;

var roles      = require("./roles/index");
var stages     = require("./stages/index");
var victory    = require("./lib/victory");
var playerInfo = require("./lib/playerInfo");
var commands   = require("./lib/commands");

module.exports = function() {

  // Metadata

  this.name        = "Mafia";
  this.version     = "0.1.0";
  this.description = "Une version en ligne du jeu de Dimitry Davidoff - v" + this.version;
  this.minPlayers  = 3;
  this.maxPlayers  = 40;
  this.opVersion   = ">0.1.2";

  this.css         = ["mafia.css"];
  this.sounds      = require('./data/audio.json');

  // Start

  this.start = function(room, callback) {

    this.nbDays = 0;
    victory.init(this);
    playerInfo.init(this);

    try {
      room.gameplay.events = new Emitter();
      roles.init(room);
      this.stages = stages.init(room);
    } catch(e) {
      return callback(e.message);
    }

    room.broadcast("playSound", "start");
    callback(null);

    setTimeout(function() {
      room.message("<strong><i>Vous vous trouvez dans le village de Salem. La Mafia rôde, et menace sérieusement la vie des villageois...</i></strong>");

      if(!room.gameplay.gamemasterMode)
        room.nextStage("mafia");
      else
        room.nextStage("wait");
    }, 100);

  };

  // Parameters

  this.parameters = [
  {
    name: "Nombre de Mafiosi (mafia)",
    type: Number,
    value: 1,
    help: "Les Mafiosi ont pour objectif de prendre le contrôle du village. Ensemble, ils décident d'éliminer un citoyen par nuit.",
    role: "mafia"
  },
  {
    name: "Nombre de Parrains (mafia)",
    type: Number,
    value: 0,
    help: "Un parrain fait partie du camp de la mafia mais apparait comme un innocent aux yeux du détective.",
    role: "godfather"
  },
  {
    name: "Nombre de Terroristes (mafia)",
    type: Number,
    value: 0,
    help: "Un terroriste peut commettre un attentat suicide durant une nuit de son choix. Il mourra avec la cible de son choix. Le docteur ne protège pas contre l'attentat; mais empêchera un terroriste d'agir s'il protège celui-ci pendant la nuit.",
    role: "terrorist"
  },
  {
    name: "Nombre de Docteurs",
    type: Number,
    value: 0,
    help: "Un médecin peut protéger un citoyen par nuit s'il le souhaite. Si la vie du protégé est menacée, il survivra quand même.",
    role: "doctor"
  },
  {
    name: "Nombre de Secouristes",
    type: Number,
    value: 0,
    help: "Un secouriste peut sauver une victime de la Mafia. Il est déconseillé de mettre plusieurs secouristes dans la composition, même si cela est possible.",
    role: "rescuer"
  },
  {
    name: "Nombre de Vigiles",
    type: Number,
    value: 0,
    help: "Un vigile peut assassiner un des habitants durant une nuit de son choix. Il est toutefois du côté des honnêtes citoyens.",
    role: "vigilant"
  },
  {
    name: "Nombre de Détectives",
    type: Number,
    value: 0,
    help: "Un détective peut découvrir, chaque nuit, le camp d'un joueur (innocent ou mafioso).",
    role: "detective"
  },
  {
    name: "Nombre de Dentistes",
    type: Number,
    value: 0,
    help: "Un dentiste peut, durant une nuit de son choix, interdire à un habitant de parler au prochain tour.",
    role: "dentist"
  },
  {
    name: "Nombre d'Espions",
    type: Number,
    value: 0,
    help: "Un espion peut connaître la victime de la Mafia chaque nuit, sans se faire repérer.",
    role: "spy"
  },
  {
    name: "Nombre de Conseillers",
    type: Number,
    value: 0,
    help: "Un conseiller peut chaque nuit interdire de vote un habitant du village.",
    role: "councilman"
  },
  {
    name: "Nombre de Parieurs",
    type: Number,
    value: 0,
    help: "Un parieur peut chaque nuit parier sur la victime choisie par les mafieux.",
    role: "gambler"
  },
  {
    name: "Mode Maître du Jeu",
    type: Boolean,
    value: false,
    help: "Quand ce mode est actif, le créateur de la partie devient MENEUR DE JEU. Il dispose de pouvoirs supplémentaires pour animer la partie à sa guise : modification du temps, ajouts de rôles personnalisés, discussions privées avec les joueurs...",
    gamemasterMode: true
  }
  ];

  // Disconnect

  this.onReconnect = function(room, player) {
    // Resend role and players
    player.emit("setGameInfo", "Vous êtes "+ player.canonicalRole +". Vous avez été absent pendant un court instant, l'historique n'est pas totalement disponible.");
    room.gameplay.resetPlayerInfo();

    // Refresh gamemaster private channels
    if(!player.roles.gamemaster && room.gameplay.gamemasterMode) {
      room.gameplay.processUserForGamemaster(player.socket);
    }
  }

  this.onDisconnect = function(room, player) {

    if(player.roles && player.roles.gamemaster) { // TODO : move this is gamemaster.js file
      room.gameplay.gamemasterMode = false;
      room.gameplay.gamemaster     = null;
      room.gameplay.disableAutoVictory = false;

      if(room.getRemainingTime() == Number.POSITIVE_INFINITY) // to avoid infinite stages
        room.setStageDuration(0);

      if(room.currentStage === "wait")
        room.endStage();

      room.players.forEach(function(p) { // disable gamemaster communication
        p.player.setChannel("player-" + player.username, {r: false, w: false});
      });
    }

    if(player.canonicalRole)
      this.room.message("<strong><i>" + player.username + " " + player.canonicalRole + " s'est enfui.</i></strong>");

    // Update vote (if any)
    if(player.choice) {
      player.choice.nbVotes--;
      this.sendPlayerInfo(player.choice.socket)
    }

    if(room.gameplay.checkEnd)
      room.gameplay.checkEnd();
  }

  // Chat styles

  this.processMessage = function(channel, message, player) {

    if(player.roles.gamemaster && commands.test(message, player)) {
      return false;
    }

    if(channel.match(/^player\-/)) {
      player.message("<span class='mafia-private-chat'>À " + channel.replace(/player\-/, "") + " : " + message + "</span>", true);
      message = "<span class='mafia-private-chat'>[PRIVÉ] " + message + "</span>";
    }

    if(channel === "dead") {
      message = "<i class='mafia-dead-chat'>" + message + "</i>";
    }

    if(channel === "mafia") {
      message = "<span class='mafia-mafia-chat'>" + message + "</span>";
    }

    if(player.roles.gamemaster) {
      message = "<span class='mafia-gamemaster-chat'>" + message + "</span>";
    }

    return message;
  }

};