diff --git a/src/components/Menu.vue b/src/components/Menu.vue
index 40abc72..d63c70b 100644
--- a/src/components/Menu.vue
+++ b/src/components/Menu.vue
@@ -130,6 +130,10 @@
Send Characters
+
+ Reveal Grimoire
+
+
({
votingSpeed: 3000,
isVoteInProgress: false,
voteHistory: [],
- isRolesDistributed: false
+ isRolesDistributed: false,
+ isGrimoireRevealed: false
});
const getters = {};
@@ -47,6 +48,7 @@ const mutations = {
setVoteInProgress: set("isVoteInProgress"),
claimSeat: set("claimedSeat"),
distributeRoles: set("isRolesDistributed"),
+ revealGrimoire: set("isGrimoireRevealed"),
setSessionId(state, sessionId) {
state.sessionId = sessionId
.toLocaleLowerCase()
diff --git a/src/store/socket.js b/src/store/socket.js
index e193a08..c8039df 100644
--- a/src/store/socket.js
+++ b/src/store/socket.js
@@ -240,11 +240,17 @@ class LiveSession {
/**
* Publish the current gamestate.
- * Optional param to reduce traffic. (send only player data)
+ * Optional param isLightweight to reduce traffic (=send only player data)
+ * Optional param isRevealGrimoire to reveal grimoire (=include ALL player roles, reminders & bluffs), overrides isLightweight
* @param playerId
* @param isLightweight
+ * @param isRevealGrimoire
*/
- sendGamestate(playerId = "", isLightweight = false) {
+ sendGamestate(
+ playerId = "",
+ isLightweight = false,
+ isRevealGrimoire = false
+ ) {
if (this._isSpectator) return;
this._gamestate = this._store.state.players.players.map(player => ({
name: player.name,
@@ -252,28 +258,39 @@ class LiveSession {
isDead: player.isDead,
isVoteless: player.isVoteless,
pronouns: player.pronouns,
- ...(player.role && player.role.team === "traveler"
+ ...(player.role && (player.role.team === "traveler" || isRevealGrimoire)
? { roleId: player.role.id }
- : {})
+ : {}),
+ reminders: isRevealGrimoire
+ ? player.reminders.map(reminder => ({
+ name: reminder.name,
+ role: reminder.role
+ }))
+ : {}
}));
- if (isLightweight) {
+ if (isLightweight && !isRevealGrimoire) {
this._sendDirect(playerId, "gs", {
gamestate: this._gamestate,
isLightweight
});
} else {
const { session, grimoire } = this._store.state;
- const { fabled } = this._store.state.players;
+ const { fabled, bluffs } = this._store.state.players;
this.sendEdition(playerId);
this._sendDirect(playerId, "gs", {
gamestate: this._gamestate,
+ isLightweight: isLightweight,
+ isRevealGrimoire: isRevealGrimoire,
isNight: grimoire.isNight,
nomination: session.nomination,
votingSpeed: session.votingSpeed,
lockedVote: session.lockedVote,
isVoteInProgress: session.isVoteInProgress,
fabled: fabled.map(({ id }) => id),
- ...(session.nomination ? { votes: session.votes } : {})
+ ...(session.nomination ? { votes: session.votes } : {}),
+ bluffs: isRevealGrimoire
+ ? bluffs.map(bluff => ({ roleId: bluff.id }))
+ : []
});
}
}
@@ -288,14 +305,24 @@ class LiveSession {
const {
gamestate,
isLightweight,
+ isRevealGrimoire,
isNight,
nomination,
votingSpeed,
votes,
lockedVote,
isVoteInProgress,
- fabled
+ fabled,
+ bluffs
} = data;
+ if (isRevealGrimoire) {
+ // includes ALL roles, reminders & bluffs
+ const popup =
+ "Reveal the Storyteller's grimoire? This will overwrite your grimoire.";
+ if (!confirm(popup)) {
+ return;
+ }
+ }
const players = this._store.state.players.players;
// adjust number of players
if (players.length < gamestate.length) {
@@ -337,6 +364,14 @@ class LiveSession {
value: {}
});
}
+ // reminder tokens
+ if (isRevealGrimoire) {
+ this._store.commit("players/update", {
+ player,
+ property: "reminders",
+ value: state.reminders
+ });
+ }
});
if (!isLightweight) {
this._store.commit("toggleNight", !!isNight);
@@ -350,6 +385,18 @@ class LiveSession {
this._store.commit("players/setFabled", {
fabled: fabled.map(id => this._store.state.fabled.get(id))
});
+ if (isRevealGrimoire) {
+ this._store.commit("session/revealGrimoire", true);
+ bluffs.forEach((bluff, i) => {
+ const role =
+ this._store.state.roles.get(bluff.roleId) ||
+ this._store.getters.rolesJSONbyId.get(bluff.roleId) || {};
+ this._store.commit("players/setBluff", {
+ index: i,
+ role
+ });
+ });
+ }
}
}
@@ -462,8 +509,8 @@ class LiveSession {
if (!this._isSpectator) return;
const player = this._store.state.players.players[index];
if (!player) return;
- // special case where a player stops being a traveler
if (property === "role") {
+ // special case where a player stops being a traveler
if (!value && player.role.team === "traveler") {
// reset to an unknown role
this._store.commit("players/update", {
@@ -472,7 +519,7 @@ class LiveSession {
value: {}
});
} else {
- // load role, first from session, the global, then fail gracefully
+ // load role, first from session, then global, then fail gracefully
const role =
this._store.state.roles.get(value) ||
this._store.getters.rolesJSONbyId.get(value) ||
@@ -822,6 +869,9 @@ export default store => {
session.distributeRoles();
}
break;
+ case "session/revealGrimoire":
+ session.sendGamestate("", false, true);
+ break;
case "session/nomination":
session.nomination(payload);
break;