2015-07-22 16:28:15 +00:00
|
|
|
"use strict";
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Implements Gather Model
|
|
|
|
*
|
|
|
|
* Gather States
|
2015-07-24 13:34:02 +00:00
|
|
|
* - Gathering
|
|
|
|
* - Election (Electing leaders)
|
|
|
|
* - Selection (Selecting teams)
|
2015-07-22 16:28:15 +00:00
|
|
|
* - Done
|
|
|
|
*
|
2018-11-18 14:11:23 +00:00
|
|
|
*/
|
2015-07-22 16:28:15 +00:00
|
|
|
|
2016-01-02 21:32:26 +00:00
|
|
|
const Gatherer = require("./gatherer");
|
|
|
|
const StateMachine = require("javascript-state-machine");
|
2018-12-29 13:43:05 +00:00
|
|
|
const Server = require("./server");
|
2018-11-18 21:32:11 +00:00
|
|
|
// const discordBot = require("../discord/bot")();
|
2015-07-22 16:28:15 +00:00
|
|
|
|
2015-07-31 15:06:21 +00:00
|
|
|
function Gather (options) {
|
2016-03-18 14:41:06 +00:00
|
|
|
if (options === undefined) options = {};
|
2015-07-22 16:28:15 +00:00
|
|
|
if (!(this instanceof Gather)) {
|
2015-07-31 15:06:21 +00:00
|
|
|
return new Gather(options);
|
2015-07-22 16:28:15 +00:00
|
|
|
}
|
2015-09-27 15:36:06 +00:00
|
|
|
this.gatherers = [];
|
2015-08-11 11:59:19 +00:00
|
|
|
let noop = () => {};
|
2018-11-18 14:11:23 +00:00
|
|
|
this.onDone = (typeof options.onDone === 'function') ?
|
2015-09-15 20:36:08 +00:00
|
|
|
options.onDone : noop;
|
2018-11-18 14:11:23 +00:00
|
|
|
this.onEvent = (typeof options.onEvent === 'function') ?
|
2015-09-15 20:36:08 +00:00
|
|
|
options.onEvent : noop;
|
2015-09-27 15:36:06 +00:00
|
|
|
this.done = {
|
|
|
|
time: null
|
|
|
|
};
|
2018-11-18 14:11:23 +00:00
|
|
|
|
2016-04-01 12:26:43 +00:00
|
|
|
this.teamSize = options.teamSize || 6;
|
2015-09-27 15:36:06 +00:00
|
|
|
|
|
|
|
// Store cooldown times for gather leaves
|
|
|
|
this.cooldown = {};
|
2015-09-29 10:43:17 +00:00
|
|
|
this.COOLDOWN_TIME = 60 * 3;// 3 Minutes
|
2015-09-27 15:36:06 +00:00
|
|
|
|
2017-04-06 13:11:05 +00:00
|
|
|
this.REGATHER_THRESHOLD = this.teamSize + 2;
|
2016-03-18 14:41:06 +00:00
|
|
|
|
2016-04-01 13:02:26 +00:00
|
|
|
this.type = options.type || "classic";
|
2016-03-18 14:57:44 +00:00
|
|
|
|
2016-04-01 13:02:26 +00:00
|
|
|
this.name = options.name || "Classic Gather";
|
2016-03-18 14:41:06 +00:00
|
|
|
|
2016-04-01 12:26:43 +00:00
|
|
|
this.description = options.description || "No player requirements";
|
2018-11-18 14:11:23 +00:00
|
|
|
|
2015-09-19 23:48:07 +00:00
|
|
|
this.election = {
|
2015-09-27 11:11:54 +00:00
|
|
|
INTERVAL: 60000, // 1 Minute
|
2015-09-19 23:48:07 +00:00
|
|
|
startTime: null,
|
|
|
|
timer: null
|
|
|
|
};
|
2015-09-27 15:36:06 +00:00
|
|
|
|
2016-04-17 14:37:50 +00:00
|
|
|
if (typeof options.membershipTest === 'function') {
|
|
|
|
this.membershipTest = options.membershipTest.bind(this);
|
|
|
|
}
|
|
|
|
|
2018-12-29 13:43:05 +00:00
|
|
|
if (typeof options.serverMembershipTest === 'function') {
|
|
|
|
this.serverMembershipTest = options.serverMembershipTest.bind(this);
|
|
|
|
}
|
|
|
|
|
2015-07-24 13:34:02 +00:00
|
|
|
this.initState();
|
2015-07-22 16:28:15 +00:00
|
|
|
}
|
|
|
|
|
2015-08-11 11:55:04 +00:00
|
|
|
StateMachine.create({
|
|
|
|
target: Gather.prototype,
|
|
|
|
events: [
|
|
|
|
{ name: "initState", from: "none", to: "gathering" },
|
|
|
|
{ name: "addGatherer", from: "gathering", to: "election" },
|
|
|
|
{ name: "selectLeader", from: "election", to: "selection" },
|
|
|
|
{ name: "electionTimeout", from: "election", to: "selection" },
|
|
|
|
{ name: "confirmSelection", from: "selection", to: "done" },
|
2018-11-18 14:11:23 +00:00
|
|
|
{
|
|
|
|
name: "removeGatherer",
|
|
|
|
from: ["gathering", "election", "selection"],
|
|
|
|
to: "gathering"
|
2015-09-17 13:56:44 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "regather",
|
|
|
|
from: ["gathering", "election", "selection"],
|
|
|
|
to: "gathering"
|
2015-09-15 20:36:08 +00:00
|
|
|
}
|
2015-08-11 11:55:04 +00:00
|
|
|
],
|
|
|
|
callbacks: {
|
|
|
|
// Callbacks for events
|
2015-09-25 21:23:30 +00:00
|
|
|
onafterevent: function () {
|
2015-10-02 14:53:11 +00:00
|
|
|
this.onEvent.apply(this, [].slice.call(arguments));
|
2015-08-11 11:55:04 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
// Gathering State
|
2015-09-25 21:23:30 +00:00
|
|
|
onbeforeaddGatherer: function (event, from, to, user) {
|
2015-09-27 15:36:06 +00:00
|
|
|
if (this.needsToCoolOff(user)) return false;
|
2016-04-17 14:37:50 +00:00
|
|
|
if (this.failsTest(user)) return false;
|
2015-08-11 11:55:04 +00:00
|
|
|
this.addUser(user);
|
2017-06-22 13:47:29 +00:00
|
|
|
if (!this.lobbyFull()) {
|
2018-11-18 21:32:11 +00:00
|
|
|
// if(this.gatherers.length > this.teamSize &&
|
|
|
|
// (null === discordBot.spamProtection.fillStatus ||
|
|
|
|
// ((new Date()).getTime() - discordBot.spamProtection.fillStatus.getTime())/1000 > 180)) {
|
|
|
|
// discordBot.notifyChannel("Join the gather at https://gathers.ensl.org | " + this.gatherers.length + " players are already waiting!");
|
|
|
|
// discordBot.spamProtection.fillStatus = new Date();
|
|
|
|
// }
|
2018-11-18 14:11:23 +00:00
|
|
|
|
2017-06-22 13:47:29 +00:00
|
|
|
return false;
|
|
|
|
}
|
2015-08-11 11:55:04 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
// Election State
|
2015-09-25 21:23:30 +00:00
|
|
|
onbeforeselectLeader: function (event, from, to, voter, candidate) {
|
2015-08-11 11:55:04 +00:00
|
|
|
this.voteForLeader(voter, candidate);
|
2016-04-01 12:26:43 +00:00
|
|
|
if (!this.leaderVotesFull()) return false;
|
2015-08-11 11:55:04 +00:00
|
|
|
},
|
|
|
|
|
2015-09-25 21:23:30 +00:00
|
|
|
onenterelection: function () {
|
2018-11-20 19:22:53 +00:00
|
|
|
// discordBot.notifyChannel("Gather is starting! Pick your captains at https://gathers.ensl.org");
|
2015-08-11 11:55:04 +00:00
|
|
|
// Setup timer for elections
|
2015-09-19 23:48:07 +00:00
|
|
|
this.startElectionCountdown();
|
2015-08-11 11:55:04 +00:00
|
|
|
},
|
|
|
|
|
2015-09-25 21:23:30 +00:00
|
|
|
onleaveelection: function () {
|
2015-09-19 23:48:07 +00:00
|
|
|
this.cancelElectionCountdown();
|
2015-08-11 11:55:04 +00:00
|
|
|
},
|
|
|
|
|
2018-11-18 14:11:23 +00:00
|
|
|
// Selection State
|
2015-09-25 21:23:30 +00:00
|
|
|
onenterselection: function () {
|
2015-08-11 11:55:04 +00:00
|
|
|
// Remove all leaders and teams
|
|
|
|
this.gatherers.forEach(gatherer => {
|
|
|
|
gatherer.leader = false;
|
|
|
|
gatherer.team = "lobby";
|
|
|
|
});
|
|
|
|
|
|
|
|
// Assign leaders based on vote
|
|
|
|
// 1st place alien comm
|
|
|
|
// 2nd place marine comm
|
2015-08-11 11:59:19 +00:00
|
|
|
let voteCount = {};
|
2015-08-11 11:55:04 +00:00
|
|
|
this.gatherers.forEach(gatherer => { voteCount[gatherer.id] = 0 });
|
|
|
|
this.leaderVotes().forEach(candidateId => { voteCount[candidateId]++ });
|
2015-08-11 11:59:19 +00:00
|
|
|
let rank = [];
|
|
|
|
for (let candidate in voteCount) {
|
2015-08-11 11:55:04 +00:00
|
|
|
rank.push({ candidate: candidate, count: voteCount[candidate] });
|
|
|
|
}
|
|
|
|
rank.sort((a, b) => {
|
|
|
|
return a.count - b.count;
|
|
|
|
});
|
2015-09-16 14:47:15 +00:00
|
|
|
this.assignAlienLeader(parseInt(rank.pop().candidate, 0));
|
2015-09-19 23:50:03 +00:00
|
|
|
this.assignMarineLeader(parseInt(rank.pop().candidate, 0));
|
2015-08-11 11:55:04 +00:00
|
|
|
},
|
|
|
|
|
2015-10-01 10:31:29 +00:00
|
|
|
onleaveselection: function (event, from, to, voter, candidate) {
|
|
|
|
if (event === "removeGatherer" || event === "regather") {
|
|
|
|
this.gatherers.forEach(gatherer => {
|
|
|
|
gatherer.team = "lobby";
|
|
|
|
});
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2015-09-25 21:23:30 +00:00
|
|
|
onbeforeconfirmSelection: function (event, from, to, leader) {
|
2016-04-01 12:26:43 +00:00
|
|
|
return (this.aliens().length === this.teamSize
|
|
|
|
&& this.marines().length === this.teamSize);
|
2015-08-11 11:55:04 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
// Remove gatherer event
|
2015-09-25 21:23:30 +00:00
|
|
|
onbeforeremoveGatherer: function (event, from, to, user) {
|
2015-08-11 11:55:04 +00:00
|
|
|
// Cancel transition if no gatherers have been removed
|
|
|
|
let userCount = this.gatherers.length;
|
|
|
|
this.removeUser(user);
|
2015-09-27 15:36:06 +00:00
|
|
|
let userRemoved = userCount > this.gatherers.length;
|
2015-10-03 15:55:42 +00:00
|
|
|
if (userRemoved && from !== 'gathering') this.applyCooldown(user);
|
2015-09-27 15:36:06 +00:00
|
|
|
return userRemoved;
|
2015-08-11 11:55:04 +00:00
|
|
|
},
|
|
|
|
|
2015-09-17 13:56:44 +00:00
|
|
|
// Set gatherer vote & if threshold met, reset gather
|
2015-09-25 21:23:30 +00:00
|
|
|
onbeforeregather: function (event, from, to, user, vote) {
|
2015-09-17 13:56:44 +00:00
|
|
|
let self = this;
|
|
|
|
self.modifyGatherer(user, (gatherer) => gatherer.voteRegather(vote));
|
|
|
|
if (self.regatherVotes() >= self.REGATHER_THRESHOLD) {
|
|
|
|
self.resetState();
|
2018-11-20 19:22:53 +00:00
|
|
|
// discordBot.notifyChannel("@here Gather was reset! Rejoin to play!");
|
2015-09-17 13:56:44 +00:00
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2015-08-11 11:55:04 +00:00
|
|
|
// On enter done
|
2015-09-25 21:23:30 +00:00
|
|
|
onenterdone: function () {
|
2018-11-20 19:22:53 +00:00
|
|
|
// discordBot.notifyChannel("Picking finished! Join the server!");
|
2015-09-20 12:00:15 +00:00
|
|
|
this.done.time = new Date();
|
2015-10-02 14:53:11 +00:00
|
|
|
this.onDone.apply(this, [].slice.call(arguments));
|
2015-08-11 11:55:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2016-04-01 12:26:43 +00:00
|
|
|
Gather.prototype.lobbyFull = function () {
|
|
|
|
return this.gatherers.length === (this.teamSize * 2);
|
|
|
|
};
|
|
|
|
|
|
|
|
Gather.prototype.leaderVotesFull = function () {
|
|
|
|
return this.leaderVotes().length === (this.teamSize * 2);
|
|
|
|
};
|
|
|
|
|
2015-09-25 21:23:30 +00:00
|
|
|
Gather.prototype.resetState = function () {
|
2015-09-17 13:56:44 +00:00
|
|
|
this.gatherers = [];
|
2016-04-01 12:26:43 +00:00
|
|
|
this.cancelElectionCountdown();
|
2015-09-17 13:56:44 +00:00
|
|
|
return this;
|
|
|
|
};
|
|
|
|
|
2015-09-25 21:23:30 +00:00
|
|
|
Gather.prototype.alienLeader = function () {
|
2015-08-10 23:44:54 +00:00
|
|
|
return this.gatherers.reduce((acc, gatherer) => {
|
2015-07-24 13:34:02 +00:00
|
|
|
if (gatherer.team === "alien" && gatherer.leader) acc.push(gatherer);
|
|
|
|
return acc;
|
|
|
|
}, []).pop();
|
|
|
|
};
|
|
|
|
|
2015-09-25 21:23:30 +00:00
|
|
|
Gather.prototype.marineLeader = function () {
|
2015-08-10 23:44:54 +00:00
|
|
|
return this.gatherers.reduce((acc, gatherer) => {
|
2015-07-24 13:34:02 +00:00
|
|
|
if (gatherer.team === "marine" && gatherer.leader) acc.push(gatherer);
|
|
|
|
return acc;
|
|
|
|
}, []).pop();
|
|
|
|
};
|
|
|
|
|
2015-09-25 21:23:30 +00:00
|
|
|
Gather.prototype.assignMarineLeader = function (id) {
|
2015-08-10 23:44:54 +00:00
|
|
|
this.modifyGatherer({id: id}, gatherer => {
|
2015-07-24 13:34:02 +00:00
|
|
|
gatherer.leader = true;
|
|
|
|
gatherer.team = "marine";
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2015-09-25 21:23:30 +00:00
|
|
|
Gather.prototype.assignAlienLeader = function (id) {
|
2015-08-10 23:44:54 +00:00
|
|
|
this.modifyGatherer({id: id}, gatherer => {
|
2015-07-24 13:34:02 +00:00
|
|
|
gatherer.leader = true;
|
|
|
|
gatherer.team = "alien";
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2015-09-25 21:23:30 +00:00
|
|
|
Gather.prototype.containsUser = function (user) {
|
2015-08-10 23:44:54 +00:00
|
|
|
return this.gatherers.some(gatherer => {
|
2015-07-23 13:36:51 +00:00
|
|
|
return gatherer.id === user.id;
|
|
|
|
});
|
2018-11-18 14:11:23 +00:00
|
|
|
};
|
2015-07-22 23:30:14 +00:00
|
|
|
|
2015-09-25 21:23:30 +00:00
|
|
|
Gather.prototype.addUser = function (user) {
|
2015-08-11 11:55:04 +00:00
|
|
|
if (this.containsUser(user)) return null;
|
2015-08-11 11:59:19 +00:00
|
|
|
let gatherer = new Gatherer(user);
|
2015-07-23 13:36:51 +00:00
|
|
|
this.gatherers.push(gatherer);
|
|
|
|
return gatherer;
|
2015-07-22 23:30:14 +00:00
|
|
|
};
|
|
|
|
|
2015-09-25 21:23:30 +00:00
|
|
|
Gather.prototype.removeUser = function (user) {
|
2015-08-10 23:44:54 +00:00
|
|
|
this.gatherers = this.gatherers.filter(gatherer => user.id !== gatherer.id);
|
2015-07-22 23:30:14 +00:00
|
|
|
};
|
|
|
|
|
2015-09-25 21:23:30 +00:00
|
|
|
Gather.prototype.modifyGatherer = function (user, callback){
|
2015-08-11 11:55:04 +00:00
|
|
|
return this.gatherers
|
|
|
|
.filter(gatherer => gatherer.id === user.id)
|
|
|
|
.forEach(callback);
|
2015-09-16 11:44:34 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
// Determines picking order of teams
|
|
|
|
// Marine 1 pick first
|
|
|
|
// 2 picks for each team subsequently
|
|
|
|
|
2015-09-25 21:23:30 +00:00
|
|
|
Gather.prototype.pickingTurn = function () {
|
2015-09-16 11:44:34 +00:00
|
|
|
if (this.current !== 'selection') return null;
|
|
|
|
let alienCount = this.aliens().length;
|
|
|
|
let marineCount = this.marines().length;
|
|
|
|
let total = marineCount + alienCount;
|
2018-11-18 14:11:23 +00:00
|
|
|
if (total === 2) return "marine"; // first pick for marines
|
|
|
|
if (total === 4) return "alien"; // first pick round aliens got to picks
|
|
|
|
if (marineCount > alienCount) return "alien"; // applies only after first pick
|
2015-09-16 11:44:34 +00:00
|
|
|
if (marineCount < alienCount) return "marine";
|
2018-11-18 14:11:23 +00:00
|
|
|
return "alien"; // after aliens picked two whenever numbers are equal its aliens turn again
|
2015-09-16 11:44:34 +00:00
|
|
|
};
|
2015-07-24 13:34:02 +00:00
|
|
|
|
2015-09-16 14:47:15 +00:00
|
|
|
// Moves player to marine
|
|
|
|
// Optional `mover` argument which will check mover credentials to select
|
|
|
|
// Credentials: Must be leader, must belong to team, must be turn to pick
|
2015-09-25 21:23:30 +00:00
|
|
|
Gather.prototype.moveToMarine = function (user, mover) {
|
2016-04-01 12:26:43 +00:00
|
|
|
if (this.marines().length >= this.teamSize) return;
|
2015-09-16 14:47:15 +00:00
|
|
|
|
|
|
|
if (mover && this.containsUser(mover)) {
|
|
|
|
let leader = this.getGatherer(mover);
|
2018-11-18 14:11:23 +00:00
|
|
|
if (leader.team !== "marine" ||
|
2015-09-16 14:47:15 +00:00
|
|
|
!leader.leader ||
|
|
|
|
this.pickingTurn() !== "marine") return;
|
|
|
|
|
|
|
|
if (user && this.containsUser(user)) {
|
|
|
|
if (this.getGatherer(user).team !== "lobby") return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-08-10 23:44:54 +00:00
|
|
|
this.modifyGatherer(user, gatherer => gatherer.team = "marine");
|
2015-07-22 23:30:14 +00:00
|
|
|
};
|
|
|
|
|
2015-09-16 14:47:15 +00:00
|
|
|
// Moves player to alien
|
|
|
|
// Optional `mover` argument which will check mover credentials to select
|
|
|
|
// Credentials: Must be leader, must belong to team, must be turn to pick
|
|
|
|
|
2015-09-25 21:23:30 +00:00
|
|
|
Gather.prototype.moveToAlien = function (user, mover) {
|
2016-04-01 12:26:43 +00:00
|
|
|
if (this.aliens().length >= this.teamSize) return;
|
2015-09-16 14:47:15 +00:00
|
|
|
|
|
|
|
if (mover && this.containsUser(mover)) {
|
|
|
|
let leader = this.getGatherer(mover);
|
2018-11-18 14:11:23 +00:00
|
|
|
if (leader.team !== "alien" ||
|
2015-09-16 14:47:15 +00:00
|
|
|
!leader.leader ||
|
|
|
|
this.pickingTurn() !== "alien") return;
|
2015-09-16 15:16:00 +00:00
|
|
|
|
2015-09-16 14:47:15 +00:00
|
|
|
if (user && this.containsUser(user)) {
|
|
|
|
if (this.getGatherer(user).team !== "lobby") return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-18 14:11:23 +00:00
|
|
|
return this.modifyGatherer(user, gatherer => gatherer.team = "alien");
|
2015-07-23 13:36:51 +00:00
|
|
|
};
|
|
|
|
|
2015-09-25 21:23:30 +00:00
|
|
|
Gather.prototype.moveToLobby = function (user) {
|
2015-08-11 11:55:04 +00:00
|
|
|
this.modifyGatherer(user, gatherer => gatherer.team = "lobby");
|
2015-07-23 13:36:51 +00:00
|
|
|
};
|
|
|
|
|
2015-09-25 21:23:30 +00:00
|
|
|
Gather.prototype.retrieveGroup = function (team) {
|
2015-08-10 23:44:54 +00:00
|
|
|
return this.gatherers.filter(gatherer => gatherer.team === team);
|
|
|
|
};
|
2015-07-22 23:30:14 +00:00
|
|
|
|
2015-09-25 21:23:30 +00:00
|
|
|
Gather.prototype.lobby = function () {
|
2015-07-23 13:36:51 +00:00
|
|
|
return this.retrieveGroup("lobby");
|
2015-07-22 23:30:14 +00:00
|
|
|
};
|
|
|
|
|
2015-09-25 21:23:30 +00:00
|
|
|
Gather.prototype.aliens = function () {
|
2015-07-23 13:36:51 +00:00
|
|
|
return this.retrieveGroup("alien");
|
|
|
|
};
|
|
|
|
|
2015-09-25 21:23:30 +00:00
|
|
|
Gather.prototype.marines = function () {
|
2015-07-23 13:36:51 +00:00
|
|
|
return this.retrieveGroup("marine");
|
|
|
|
};
|
|
|
|
|
2015-09-25 21:23:30 +00:00
|
|
|
Gather.prototype.electionStartTime = function () {
|
2018-11-18 14:11:23 +00:00
|
|
|
return (this.election.startTime === null) ?
|
2015-09-19 23:48:07 +00:00
|
|
|
null : this.election.startTime.toISOString();
|
2015-08-11 11:55:04 +00:00
|
|
|
};
|
|
|
|
|
2019-01-10 17:15:14 +00:00
|
|
|
Gather.prototype.toJson = function (onlineIds) {
|
|
|
|
if (onlineIds) {
|
|
|
|
const now = Date.now();
|
|
|
|
for (var gatherer of this.gatherers) {
|
|
|
|
if (gatherer.user.online) {
|
|
|
|
gatherer.user.lastSeen = now;
|
|
|
|
}
|
|
|
|
|
|
|
|
gatherer.user.online = onlineIds.indexOf(gatherer.id) !== -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-23 13:36:51 +00:00
|
|
|
return {
|
2016-03-18 14:41:06 +00:00
|
|
|
name: this.name,
|
|
|
|
description: this.description,
|
2016-03-19 13:31:30 +00:00
|
|
|
type: this.type,
|
2015-07-24 15:01:56 +00:00
|
|
|
gatherers: this.gatherers,
|
2018-12-29 13:43:05 +00:00
|
|
|
servers: this.getServers(),
|
2015-07-31 15:03:09 +00:00
|
|
|
state: this.current,
|
2015-09-16 15:16:00 +00:00
|
|
|
pickingTurn: this.pickingTurn(),
|
2015-07-31 15:03:09 +00:00
|
|
|
election: {
|
2015-09-19 23:48:07 +00:00
|
|
|
startTime: this.electionStartTime(),
|
|
|
|
interval: this.election.INTERVAL
|
2015-09-20 12:00:15 +00:00
|
|
|
},
|
2016-04-01 12:26:43 +00:00
|
|
|
teamSize: this.teamSize,
|
2015-09-20 12:00:15 +00:00
|
|
|
done: {
|
|
|
|
time: this.done.time
|
2015-09-27 15:37:34 +00:00
|
|
|
},
|
|
|
|
cooldown: this.cooldown
|
2015-07-23 13:36:51 +00:00
|
|
|
}
|
2015-07-24 13:34:02 +00:00
|
|
|
};
|
|
|
|
|
2015-12-25 08:01:08 +00:00
|
|
|
Gather.prototype.toggleMapVote = function (voter, mapId) {
|
2015-12-25 07:50:27 +00:00
|
|
|
this.modifyGatherer(voter, gatherer => gatherer.toggleMapVote(mapId));
|
2015-07-29 13:50:39 +00:00
|
|
|
};
|
|
|
|
|
2015-12-25 08:01:08 +00:00
|
|
|
Gather.prototype.toggleServerVote = function (voter, serverId) {
|
|
|
|
this.modifyGatherer(voter, gatherer => gatherer.toggleServerVote(serverId));
|
2015-07-29 13:50:39 +00:00
|
|
|
};
|
|
|
|
|
2015-07-24 13:34:02 +00:00
|
|
|
// Returns an array of IDs representing votes for leaders
|
2015-09-25 21:23:30 +00:00
|
|
|
Gather.prototype.leaderVotes = function () {
|
2015-08-11 11:59:19 +00:00
|
|
|
let self = this;
|
|
|
|
return self.gatherers
|
|
|
|
.map(gatherer => gatherer.leaderVote)
|
2015-08-10 23:44:54 +00:00
|
|
|
.filter(leaderId => typeof leaderId === 'number')
|
2015-08-11 11:59:19 +00:00
|
|
|
.filter(leaderId => self.containsUser({id: leaderId}));
|
2015-07-24 13:34:02 +00:00
|
|
|
};
|
|
|
|
|
2015-09-25 21:23:30 +00:00
|
|
|
Gather.prototype.voteForLeader = function (voter, candidate) {
|
2015-08-11 11:55:04 +00:00
|
|
|
this.modifyGatherer(voter, gatherer => gatherer.voteForLeader(candidate));
|
2015-07-24 13:34:02 +00:00
|
|
|
};
|
|
|
|
|
2015-09-25 21:23:30 +00:00
|
|
|
Gather.prototype.getGatherer = function (user) {
|
2015-08-11 11:55:04 +00:00
|
|
|
return this.gatherers
|
|
|
|
.filter(gatherer => gatherer.id === user.id)
|
|
|
|
.pop() || null;
|
2015-07-28 15:54:29 +00:00
|
|
|
};
|
|
|
|
|
2015-09-25 21:23:30 +00:00
|
|
|
Gather.prototype.regatherVotes = function () {
|
2015-09-17 13:56:44 +00:00
|
|
|
let self = this;
|
|
|
|
return self.gatherers.reduce((acc, gatherer) => {
|
|
|
|
if (gatherer.regatherVote) acc++;
|
|
|
|
return acc;
|
|
|
|
}, 0);
|
2015-09-19 23:48:07 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
// Initiates a timer which will push gather into next state
|
2015-09-25 21:23:30 +00:00
|
|
|
Gather.prototype.startElectionCountdown = function () {
|
2015-09-19 23:48:07 +00:00
|
|
|
let self = this;
|
|
|
|
self.election.startTime = new Date();
|
|
|
|
this.election.timer = setTimeout(() => {
|
|
|
|
if (self.can("electionTimeout")) self.electionTimeout();
|
|
|
|
}, self.election.INTERVAL);
|
|
|
|
};
|
|
|
|
|
2015-09-25 21:23:30 +00:00
|
|
|
Gather.prototype.cancelElectionCountdown = function () {
|
2017-03-01 14:23:00 +00:00
|
|
|
clearTimeout(this.election.timer);
|
2015-09-19 23:48:07 +00:00
|
|
|
this.election.timer = null;
|
|
|
|
this.election.startTime = null;
|
|
|
|
};
|
2015-09-17 13:56:44 +00:00
|
|
|
|
2015-09-27 15:36:06 +00:00
|
|
|
Gather.prototype.applyCooldown = function (user) {
|
|
|
|
if (user && typeof user.id === 'number') {
|
|
|
|
let d = new Date();
|
|
|
|
d.setUTCSeconds(d.getUTCSeconds() + this.COOLDOWN_TIME);
|
|
|
|
this.cooldown[user.id] = d;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
Gather.prototype.needsToCoolOff = function (user) {
|
|
|
|
if (user && typeof user.id === 'number') {
|
|
|
|
let cooldownTime = this.cooldown[user.id];
|
|
|
|
if (cooldownTime === undefined) return false;
|
|
|
|
return cooldownTime > new Date();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2016-04-17 14:37:50 +00:00
|
|
|
Gather.prototype.failsTest = function (user) {
|
|
|
|
if (!this.membershipTest) return false;
|
|
|
|
return !this.membershipTest(user);
|
2018-12-29 13:43:05 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
Gather.prototype.getServers = function () {
|
|
|
|
if (!this.serverMembershipTest) return Server.list;
|
|
|
|
return Server.list.filter(this.serverMembershipTest);
|
|
|
|
};
|
2016-04-17 14:37:50 +00:00
|
|
|
|
2015-07-24 13:34:02 +00:00
|
|
|
module.exports = Gather;
|