mirror of https://github.com/bra1n/townsquare.git
added live sessions for townsquare sync
This commit is contained in:
parent
a028cf867f
commit
da3cd96723
|
@ -57,9 +57,11 @@ export default {
|
||||||
this.$refs.menu.randomizeSeatings();
|
this.$refs.menu.randomizeSeatings();
|
||||||
break;
|
break;
|
||||||
case "e":
|
case "e":
|
||||||
|
if (this.grimoire.isSpectator) return;
|
||||||
this.$store.commit("toggleModal", "edition");
|
this.$store.commit("toggleModal", "edition");
|
||||||
break;
|
break;
|
||||||
case "c":
|
case "c":
|
||||||
|
if (this.grimoire.isSpectator) return;
|
||||||
this.$store.commit("toggleModal", "roles");
|
this.$store.commit("toggleModal", "roles");
|
||||||
break;
|
break;
|
||||||
case "Escape":
|
case "Escape":
|
||||||
|
|
|
@ -43,40 +43,46 @@
|
||||||
<li @click="joinSession" v-if="!grimoire.sessionId">
|
<li @click="joinSession" v-if="!grimoire.sessionId">
|
||||||
Join Live Session
|
Join Live Session
|
||||||
</li>
|
</li>
|
||||||
|
<li class="headline" v-if="grimoire.sessionId">
|
||||||
|
<font-awesome-icon icon="broadcast-tower" />
|
||||||
|
{{ grimoire.isSpectator ? "Spectating" : "Hosting" }}
|
||||||
|
</li>
|
||||||
<li @click="leaveSession" v-if="grimoire.sessionId">
|
<li @click="leaveSession" v-if="grimoire.sessionId">
|
||||||
<em>{{ grimoire.sessionId.substr(2) }}</em>
|
<em>{{ grimoire.sessionId }}</em>
|
||||||
Leave Session
|
Leave Session
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<!-- Users -->
|
<template v-if="!grimoire.isSpectator">
|
||||||
<li class="headline">
|
<!-- Users -->
|
||||||
<font-awesome-icon icon="users" />
|
<li class="headline">
|
||||||
Players
|
<font-awesome-icon icon="users" />
|
||||||
</li>
|
Players
|
||||||
<li @click="addPlayer" v-if="players.length < 20"><em>[A]</em> Add</li>
|
</li>
|
||||||
<li @click="randomizeSeatings" v-if="players.length > 2">
|
<li @click="addPlayer" v-if="players.length < 20"><em>[A]</em> Add</li>
|
||||||
<em>[R]</em> Randomize
|
<li @click="randomizeSeatings" v-if="players.length > 2">
|
||||||
</li>
|
<em>[R]</em> Randomize
|
||||||
<li @click="clearPlayers" v-if="players.length">
|
</li>
|
||||||
Remove all
|
<li @click="clearPlayers" v-if="players.length">
|
||||||
</li>
|
Remove all
|
||||||
|
</li>
|
||||||
|
|
||||||
<!-- Characters -->
|
<!-- Characters -->
|
||||||
<li class="headline">
|
<li class="headline">
|
||||||
<font-awesome-icon icon="theater-masks" />
|
<font-awesome-icon icon="theater-masks" />
|
||||||
Characters
|
Characters
|
||||||
</li>
|
</li>
|
||||||
<li @click="toggleModal('edition')">
|
<li @click="toggleModal('edition')">
|
||||||
<em>[E]</em>
|
<em>[E]</em>
|
||||||
Select Edition
|
Select Edition
|
||||||
</li>
|
</li>
|
||||||
<li @click="toggleModal('roles')" v-if="players.length > 4">
|
<li @click="toggleModal('roles')" v-if="players.length > 4">
|
||||||
<em>[C]</em>
|
<em>[C]</em>
|
||||||
Choose & Assign
|
Choose & Assign
|
||||||
</li>
|
</li>
|
||||||
<li @click="clearRoles" v-if="players.length">
|
<li @click="clearRoles" v-if="players.length">
|
||||||
Remove all
|
Remove all
|
||||||
</li>
|
</li>
|
||||||
|
</template>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -113,7 +119,8 @@ export default {
|
||||||
.substring(2, 7)
|
.substring(2, 7)
|
||||||
);
|
);
|
||||||
if (sessionId) {
|
if (sessionId) {
|
||||||
this.$store.commit("setSessionId", "h:" + sessionId.substr(0, 5));
|
this.$store.commit("setSpectator", false);
|
||||||
|
this.$store.commit("setSessionId", sessionId.substr(0, 5));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
joinSession() {
|
joinSession() {
|
||||||
|
@ -121,29 +128,35 @@ export default {
|
||||||
"Enter the code of the session you want to join"
|
"Enter the code of the session you want to join"
|
||||||
);
|
);
|
||||||
if (sessionId) {
|
if (sessionId) {
|
||||||
this.$store.commit("setSessionId", "j:" + sessionId.substr(0, 5));
|
this.$store.commit("setSpectator", true);
|
||||||
|
this.$store.commit("setSessionId", sessionId.substr(0, 5));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
leaveSession() {
|
leaveSession() {
|
||||||
|
this.$store.commit("setSpectator", false);
|
||||||
this.$store.commit("setSessionId", "");
|
this.$store.commit("setSessionId", "");
|
||||||
},
|
},
|
||||||
addPlayer() {
|
addPlayer() {
|
||||||
|
if (this.grimoire.isSpectator) return;
|
||||||
const name = prompt("Player name");
|
const name = prompt("Player name");
|
||||||
if (name) {
|
if (name) {
|
||||||
this.$store.commit("players/add", name);
|
this.$store.commit("players/add", name);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
randomizeSeatings() {
|
randomizeSeatings() {
|
||||||
|
if (this.grimoire.isSpectator) return;
|
||||||
if (confirm("Are you sure you want to randomize seatings?")) {
|
if (confirm("Are you sure you want to randomize seatings?")) {
|
||||||
this.$store.dispatch("players/randomize");
|
this.$store.dispatch("players/randomize");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
clearPlayers() {
|
clearPlayers() {
|
||||||
|
if (this.grimoire.isSpectator) return;
|
||||||
if (confirm("Are you sure you want to remove all players?")) {
|
if (confirm("Are you sure you want to remove all players?")) {
|
||||||
this.$store.commit("players/clear");
|
this.$store.commit("players/clear");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
clearRoles() {
|
clearRoles() {
|
||||||
|
if (this.grimoire.isSpectator) return;
|
||||||
this.$store.commit("showGrimoire");
|
this.$store.commit("showGrimoire");
|
||||||
if (confirm("Are you sure you want to remove all player roles?")) {
|
if (confirm("Are you sure you want to remove all player roles?")) {
|
||||||
this.$store.dispatch("players/clearRoles");
|
this.$store.dispatch("players/clearRoles");
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
ref="player"
|
ref="player"
|
||||||
class="player"
|
class="player"
|
||||||
:class="{
|
:class="{
|
||||||
dead: player.hasDied,
|
dead: player.isDead,
|
||||||
'no-vote': player.hasVoted,
|
'no-vote': player.isVoteless,
|
||||||
traveler: player.role && player.role.team === 'traveler'
|
traveler: player.role && player.role.team === 'traveler'
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
|
@ -36,8 +36,8 @@
|
||||||
<font-awesome-icon
|
<font-awesome-icon
|
||||||
icon="vote-yea"
|
icon="vote-yea"
|
||||||
class="vote"
|
class="vote"
|
||||||
v-if="player.hasDied && !player.hasVoted"
|
v-if="player.isDead && !player.isVoteless"
|
||||||
@click="updatePlayer('hasVoted', true)"
|
@click="updatePlayer('isVoteless', true)"
|
||||||
title="Ghost vote"
|
title="Ghost vote"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
@ -109,20 +109,23 @@ export default {
|
||||||
},
|
},
|
||||||
toggleStatus() {
|
toggleStatus() {
|
||||||
if (this.grimoire.isPublic) {
|
if (this.grimoire.isPublic) {
|
||||||
if (!this.player.hasDied) {
|
if (!this.player.isDead) {
|
||||||
this.updatePlayer("hasDied", true);
|
this.updatePlayer("isDead", true);
|
||||||
} else if (this.player.hasVoted) {
|
} else if (this.player.isVoteless) {
|
||||||
this.updatePlayer("hasVoted", false);
|
this.updatePlayer("isVoteless", false);
|
||||||
this.updatePlayer("hasDied", false);
|
this.updatePlayer("isDead", false);
|
||||||
} else {
|
} else {
|
||||||
this.updatePlayer("hasVoted", true);
|
this.updatePlayer("isVoteless", true);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.updatePlayer("hasDied", !this.player.hasDied);
|
this.updatePlayer("isDead", !this.player.isDead);
|
||||||
this.updatePlayer("hasVoted", false);
|
if (this.player.isVoteless) {
|
||||||
|
this.updatePlayer("isVoteless", false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
changeName() {
|
changeName() {
|
||||||
|
if (this.grimoire.isSpectator) return;
|
||||||
const name = prompt("Player name", this.player.name) || this.player.name;
|
const name = prompt("Player name", this.player.name) || this.player.name;
|
||||||
this.updatePlayer("name", name);
|
this.updatePlayer("name", name);
|
||||||
},
|
},
|
||||||
|
@ -132,6 +135,7 @@ export default {
|
||||||
this.updatePlayer("reminders", reminders);
|
this.updatePlayer("reminders", reminders);
|
||||||
},
|
},
|
||||||
updatePlayer(property, value) {
|
updatePlayer(property, value) {
|
||||||
|
if (this.grimoire.isSpectator && property !== "reminders") return;
|
||||||
this.$store.commit("players/update", {
|
this.$store.commit("players/update", {
|
||||||
player: this.player,
|
player: this.player,
|
||||||
property,
|
property,
|
||||||
|
@ -181,7 +185,7 @@ export default {
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover:before {
|
#townsquare:not(.spectator) &:hover:before {
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
top: -10px;
|
top: -10px;
|
||||||
transform: scale(1);
|
transform: scale(1);
|
||||||
|
@ -332,7 +336,7 @@ export default {
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
&:hover {
|
#townsquare:not(.spectator) &:hover {
|
||||||
color: red;
|
color: red;
|
||||||
span {
|
span {
|
||||||
display: block;
|
display: block;
|
||||||
|
|
|
@ -47,7 +47,7 @@ export default {
|
||||||
teams: function() {
|
teams: function() {
|
||||||
const { players } = this.$store.state.players;
|
const { players } = this.$store.state.players;
|
||||||
const nonTravelers = this.$store.getters["players/nonTravelers"];
|
const nonTravelers = this.$store.getters["players/nonTravelers"];
|
||||||
const alive = players.filter(player => player.hasDied !== true).length;
|
const alive = players.filter(player => player.isDead !== true).length;
|
||||||
return {
|
return {
|
||||||
...gameJSON[nonTravelers - 5],
|
...gameJSON[nonTravelers - 5],
|
||||||
traveler: players.length - nonTravelers,
|
traveler: players.length - nonTravelers,
|
||||||
|
@ -55,7 +55,7 @@ export default {
|
||||||
votes:
|
votes:
|
||||||
alive +
|
alive +
|
||||||
players.filter(
|
players.filter(
|
||||||
player => player.hasDied === true && player.hasVoted !== true
|
player => player.isDead === true && player.isVoteless !== true
|
||||||
).length
|
).length
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
|
@ -2,7 +2,10 @@
|
||||||
<div
|
<div
|
||||||
id="townsquare"
|
id="townsquare"
|
||||||
class="square"
|
class="square"
|
||||||
v-bind:class="{ public: grimoire.isPublic }"
|
v-bind:class="{
|
||||||
|
public: grimoire.isPublic,
|
||||||
|
spectator: grimoire.isSpectator
|
||||||
|
}"
|
||||||
v-bind:style="{ zoom: grimoire.zoom }"
|
v-bind:style="{ zoom: grimoire.zoom }"
|
||||||
>
|
>
|
||||||
<ul class="circle" v-bind:class="['size-' + players.length]">
|
<ul class="circle" v-bind:class="['size-' + players.length]">
|
||||||
|
@ -70,10 +73,13 @@ export default {
|
||||||
this.$store.commit("toggleModal", "reminder");
|
this.$store.commit("toggleModal", "reminder");
|
||||||
},
|
},
|
||||||
openRoleModal(playerIndex) {
|
openRoleModal(playerIndex) {
|
||||||
|
const player = this.players[playerIndex];
|
||||||
|
if (this.grimoire.isSpectator && player.role.team === "traveler") return;
|
||||||
this.selectedPlayer = playerIndex;
|
this.selectedPlayer = playerIndex;
|
||||||
this.$store.commit("toggleModal", "role");
|
this.$store.commit("toggleModal", "role");
|
||||||
},
|
},
|
||||||
removePlayer(playerIndex) {
|
removePlayer(playerIndex) {
|
||||||
|
if (this.grimoire.isSpectator) return;
|
||||||
if (
|
if (
|
||||||
confirm(
|
confirm(
|
||||||
`Do you really want to remove ${this.players[playerIndex].name}?`
|
`Do you really want to remove ${this.players[playerIndex].name}?`
|
||||||
|
|
|
@ -74,8 +74,7 @@ export default {
|
||||||
|
|
||||||
ul.tokens li {
|
ul.tokens li {
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
height: 120px;
|
width: 6vw;
|
||||||
width: 120px;
|
|
||||||
margin: 5px;
|
margin: 5px;
|
||||||
transition: transform 500ms ease;
|
transition: transform 500ms ease;
|
||||||
|
|
||||||
|
|
|
@ -149,8 +149,7 @@ ul.tokens {
|
||||||
padding-left: 55px;
|
padding-left: 55px;
|
||||||
li {
|
li {
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
height: 120px;
|
width: 6vw;
|
||||||
width: 120px;
|
|
||||||
margin: 5px;
|
margin: 5px;
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
transition: all 250ms;
|
transition: all 250ms;
|
||||||
|
@ -181,7 +180,6 @@ ul.tokens {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 0;
|
||||||
top: 40px;
|
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
line-height: 50px;
|
line-height: 50px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
|
@ -18,7 +18,8 @@ import {
|
||||||
faCheckSquare,
|
faCheckSquare,
|
||||||
faSquare,
|
faSquare,
|
||||||
faRandom,
|
faRandom,
|
||||||
faPeopleArrows
|
faPeopleArrows,
|
||||||
|
faBroadcastTower
|
||||||
} from "@fortawesome/free-solid-svg-icons";
|
} from "@fortawesome/free-solid-svg-icons";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
|
||||||
|
|
||||||
|
@ -38,7 +39,8 @@ library.add(
|
||||||
faCheckSquare,
|
faCheckSquare,
|
||||||
faSquare,
|
faSquare,
|
||||||
faRandom,
|
faRandom,
|
||||||
faPeopleArrows
|
faPeopleArrows,
|
||||||
|
faBroadcastTower
|
||||||
);
|
);
|
||||||
|
|
||||||
Vue.component("font-awesome-icon", FontAwesomeIcon);
|
Vue.component("font-awesome-icon", FontAwesomeIcon);
|
||||||
|
|
|
@ -35,7 +35,8 @@ export default new Vuex.Store({
|
||||||
zoom: 1,
|
zoom: 1,
|
||||||
background: "",
|
background: "",
|
||||||
bluffs: [],
|
bluffs: [],
|
||||||
sessionId: ""
|
sessionId: "",
|
||||||
|
isSpectator: false
|
||||||
},
|
},
|
||||||
modals: {
|
modals: {
|
||||||
edition: false,
|
edition: false,
|
||||||
|
@ -72,6 +73,9 @@ export default new Vuex.Store({
|
||||||
setSessionId({ grimoire }, sessionId) {
|
setSessionId({ grimoire }, sessionId) {
|
||||||
grimoire.sessionId = sessionId;
|
grimoire.sessionId = sessionId;
|
||||||
},
|
},
|
||||||
|
setSpectator({ grimoire }, spectator) {
|
||||||
|
grimoire.isSpectator = spectator;
|
||||||
|
},
|
||||||
setBluff({ grimoire }, { index, role }) {
|
setBluff({ grimoire }, { index, role }) {
|
||||||
grimoire.bluffs.splice(index, 1, role);
|
grimoire.bluffs.splice(index, 1, role);
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
const NEWPLAYER = {
|
const NEWPLAYER = {
|
||||||
role: {},
|
role: {},
|
||||||
reminders: [],
|
reminders: [],
|
||||||
hasVoted: false,
|
isVoteless: false,
|
||||||
hasDied: false
|
isDead: false
|
||||||
};
|
};
|
||||||
|
|
||||||
const state = () => ({
|
const state = () => ({
|
||||||
|
|
|
@ -1,8 +1,262 @@
|
||||||
|
class LiveSession {
|
||||||
|
constructor(store) {
|
||||||
|
this.wss = "wss://connect.websocket.in/v3/";
|
||||||
|
this.key = "zXzDomOphNQ94tWXrHfT8E8gkxjUMSXOQt0ypZetKoFsIUiEBegqWNAlExyd";
|
||||||
|
this.socket = null;
|
||||||
|
this.isSpectator = true;
|
||||||
|
this.gamestate = [];
|
||||||
|
this.store = store;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open a new session for the passed channel.
|
||||||
|
* @param channel
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_open(channel) {
|
||||||
|
this.disconnect();
|
||||||
|
this.socket = new WebSocket(this.wss + channel + "?apiKey=" + this.key);
|
||||||
|
this.socket.addEventListener("message", this._handleMessage.bind(this));
|
||||||
|
this.socket.onopen = this._onOpen.bind(this);
|
||||||
|
this.socket.onclose = () => {
|
||||||
|
this.socket = null;
|
||||||
|
this.store.commit("setSessionId", "");
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a message through the socket.
|
||||||
|
* @param command
|
||||||
|
* @param params
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_send(command, params) {
|
||||||
|
if (this.socket) {
|
||||||
|
this.socket.send(JSON.stringify([command, params]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open event handler for socket.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_onOpen() {
|
||||||
|
if (this.isSpectator) {
|
||||||
|
this._send("req", "gs");
|
||||||
|
} else {
|
||||||
|
this.sendGamestate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle an incoming socket message.
|
||||||
|
* @param data
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_handleMessage({ data }) {
|
||||||
|
const [command, params] = JSON.parse(data);
|
||||||
|
switch (command) {
|
||||||
|
case "req":
|
||||||
|
if (params === "gs") {
|
||||||
|
this.sendGamestate();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "gs":
|
||||||
|
this._updateGamestate(params);
|
||||||
|
break;
|
||||||
|
case "player":
|
||||||
|
this._updatePlayer(params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connect to a new live session, either as host or spectator.
|
||||||
|
* @param channel
|
||||||
|
*/
|
||||||
|
connect(channel) {
|
||||||
|
this.isSpectator = this.store.state.grimoire.isSpectator;
|
||||||
|
this._open(channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close the current session, if any.
|
||||||
|
*/
|
||||||
|
disconnect() {
|
||||||
|
if (this.socket) {
|
||||||
|
this.socket.close();
|
||||||
|
this.socket = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Publish the current gamestate.
|
||||||
|
*/
|
||||||
|
sendGamestate() {
|
||||||
|
if (this.isSpectator) return;
|
||||||
|
this.gamestate = this.store.state.players.players.map(player => ({
|
||||||
|
name: player.name,
|
||||||
|
isDead: player.isDead,
|
||||||
|
isVoteless: player.isVoteless,
|
||||||
|
...(player.role && player.role.team === "traveler"
|
||||||
|
? {
|
||||||
|
role: {
|
||||||
|
id: player.role.id,
|
||||||
|
team: "traveler",
|
||||||
|
name: player.role.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
: {})
|
||||||
|
}));
|
||||||
|
this._send("gs", {
|
||||||
|
gamestate: this.gamestate,
|
||||||
|
edition: this.store.state.edition
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the gamestate based on incoming data.
|
||||||
|
* @param gamestate
|
||||||
|
* @param edition
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_updateGamestate({ gamestate, edition }) {
|
||||||
|
this.store.commit("setEdition", edition);
|
||||||
|
const players = this.store.state.players.players;
|
||||||
|
// adjust number of players
|
||||||
|
if (players.length < gamestate.length) {
|
||||||
|
for (let x = players.length; x < gamestate.length; x++) {
|
||||||
|
this.store.commit("players/add", gamestate[x].name);
|
||||||
|
}
|
||||||
|
} else if (players.length > gamestate.length) {
|
||||||
|
for (let x = players.length; x > gamestate.length; x--) {
|
||||||
|
this.store.commit("players/remove", x - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// update status for each player
|
||||||
|
gamestate.forEach((state, x) => {
|
||||||
|
const player = players[x];
|
||||||
|
const { name, isDead, isVoteless, role } = state;
|
||||||
|
if (player.name !== name) {
|
||||||
|
this.store.commit("players/update", {
|
||||||
|
player,
|
||||||
|
property: "name",
|
||||||
|
value: name
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (player.isDead !== isDead) {
|
||||||
|
this.store.commit("players/update", {
|
||||||
|
player,
|
||||||
|
property: "isDead",
|
||||||
|
value: isDead
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (player.isVoteless !== isVoteless) {
|
||||||
|
this.store.commit("players/update", {
|
||||||
|
player,
|
||||||
|
property: "isVoteless",
|
||||||
|
value: isVoteless
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (role && player.role.id !== role.id) {
|
||||||
|
this.store.commit("players/update", {
|
||||||
|
player,
|
||||||
|
property: "role",
|
||||||
|
value: role
|
||||||
|
});
|
||||||
|
} else if (!role && player.role.team === "traveler") {
|
||||||
|
this.store.commit("players/update", {
|
||||||
|
player,
|
||||||
|
property: "role",
|
||||||
|
value: {}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Publish a player update.
|
||||||
|
* @param player
|
||||||
|
* @param property
|
||||||
|
* @param value
|
||||||
|
*/
|
||||||
|
sendPlayer({ player, property, value }) {
|
||||||
|
if (this.isSpectator || property === "reminders") return;
|
||||||
|
const index = this.store.state.players.players.indexOf(player);
|
||||||
|
if (property === "role") {
|
||||||
|
if (value.team && value.team === "traveler") {
|
||||||
|
// update local gamestate to remember this player as a traveler
|
||||||
|
this.gamestate[index].role = {
|
||||||
|
id: player.role.id,
|
||||||
|
team: "traveler",
|
||||||
|
name: player.role.name
|
||||||
|
};
|
||||||
|
this._send("player", {
|
||||||
|
index,
|
||||||
|
property,
|
||||||
|
value: this.gamestate[index].role
|
||||||
|
});
|
||||||
|
} else if (this.gamestate[index].role) {
|
||||||
|
delete this.gamestate[index].role;
|
||||||
|
this._send("player", { index, property, value: {} });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this._send("player", { index, property, value });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update a player based on incoming data.
|
||||||
|
* @param index
|
||||||
|
* @param property
|
||||||
|
* @param value
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_updatePlayer({ index, property, value }) {
|
||||||
|
const player = this.store.state.players.players[index];
|
||||||
|
if (!player) return;
|
||||||
|
// special case where a player stops being a traveler
|
||||||
|
if (
|
||||||
|
property === "role" &&
|
||||||
|
value.team !== "traveler" &&
|
||||||
|
player.role.team === "traveler"
|
||||||
|
) {
|
||||||
|
// reset to an unknown role
|
||||||
|
this.store.commit("players/update", {
|
||||||
|
player,
|
||||||
|
property: "role",
|
||||||
|
value: {}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// just update the player otherwise
|
||||||
|
this.store.commit("players/update", { player, property, value });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = store => {
|
module.exports = store => {
|
||||||
// setup
|
// setup
|
||||||
|
const session = new LiveSession(store);
|
||||||
|
|
||||||
// listen to mutations
|
// listen to mutations
|
||||||
store.subscribe(({ type, payload }, state) => {
|
store.subscribe(({ type, payload }) => {
|
||||||
console.log(type, payload, state);
|
switch (type) {
|
||||||
|
case "setSessionId":
|
||||||
|
if (payload) {
|
||||||
|
session.connect(payload);
|
||||||
|
} else {
|
||||||
|
session.disconnect();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "players/set":
|
||||||
|
case "players/clear":
|
||||||
|
case "players/remove":
|
||||||
|
case "players/add":
|
||||||
|
case "setEdition":
|
||||||
|
session.sendGamestate();
|
||||||
|
break;
|
||||||
|
case "players/update":
|
||||||
|
session.sendPlayer(payload);
|
||||||
|
break;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue