mirror of https://github.com/bra1n/townsquare.git
add 'on the block' indicator
- after vote, ST chooses to put onto block / empty block / no change to block - player menu has add / remove from block - players are automatically removed from the block when (i) they die (ii) another player is put onto block - fixed crash on add/remove/etc player mid vote
This commit is contained in:
parent
3ae36e2f0f
commit
943d228e98
|
@ -1,5 +1,7 @@
|
|||
# Release Notes
|
||||
|
||||
- add 'on the block' indicator
|
||||
|
||||
### Version 2.12.0
|
||||
- tweak reference sheet to better fit screen in single column layout
|
||||
- add warning icon overlay for setup roles on character assignment modal
|
||||
|
|
|
@ -143,7 +143,7 @@
|
|||
</template>
|
||||
</template>
|
||||
|
||||
<template v-if="tab === 'players' && !session.isSpectator">
|
||||
<template v-if="tab === 'players' && !session.isSpectator && !session.nomination">
|
||||
<!-- Users -->
|
||||
<li class="headline">Players</li>
|
||||
<li @click="addPlayer" v-if="players.length < 20">Add<em>[A]</em></li>
|
||||
|
|
|
@ -97,6 +97,11 @@
|
|||
@click="updatePlayer('isVoteless', true)"
|
||||
title="Ghost vote"
|
||||
/>
|
||||
<font-awesome-icon
|
||||
icon="crosshairs"
|
||||
v-if="player.isOnBlock"
|
||||
class="on-block"
|
||||
/>
|
||||
<div
|
||||
class="name"
|
||||
@click="isMenuOpen = !isMenuOpen"
|
||||
|
@ -124,18 +129,28 @@
|
|||
<li @click="changeName">
|
||||
<font-awesome-icon icon="user-edit" />Rename
|
||||
</li>
|
||||
<li v-if="!session.nomination" @click="nominatePlayer()">
|
||||
<font-awesome-icon icon="hand-point-right" />
|
||||
Nomination
|
||||
</li>
|
||||
<li @click="movePlayer()">
|
||||
<font-awesome-icon icon="redo-alt" />
|
||||
Move player
|
||||
</li>
|
||||
<li @click="swapPlayer()">
|
||||
<font-awesome-icon icon="exchange-alt" />
|
||||
Swap seats
|
||||
<li v-if="!session.nomination" @click="removePlayer">
|
||||
<font-awesome-icon icon="times-circle" />
|
||||
Remove
|
||||
</li>
|
||||
<template v-if="!session.nomination">
|
||||
<li @click="movePlayer()">
|
||||
<font-awesome-icon icon="redo-alt" />
|
||||
Move player
|
||||
</li>
|
||||
<li @click="swapPlayer()">
|
||||
<font-awesome-icon icon="exchange-alt" />
|
||||
Swap seats
|
||||
</li>
|
||||
<li @click="toggleOnBlock()">
|
||||
<font-awesome-icon icon="crosshairs" />
|
||||
{{ player.isOnBlock ? "Take off block" : "Put on block" }}
|
||||
</li>
|
||||
<li @click="nominatePlayer()">
|
||||
<font-awesome-icon icon="hand-point-right" />
|
||||
Nomination
|
||||
</li>
|
||||
</template>
|
||||
<li
|
||||
@click="updatePlayer('id', '', true)"
|
||||
v-if="player.id && session.sessionId"
|
||||
|
@ -143,10 +158,6 @@
|
|||
<font-awesome-icon icon="chair" />
|
||||
Empty seat
|
||||
</li>
|
||||
<li @click="removePlayer">
|
||||
<font-awesome-icon icon="times-circle" />
|
||||
Remove
|
||||
</li>
|
||||
</template>
|
||||
<li
|
||||
@click="claimSeat"
|
||||
|
@ -257,6 +268,9 @@ export default {
|
|||
if (this.grimoire.isPublic) {
|
||||
if (!this.player.isDead) {
|
||||
this.updatePlayer("isDead", true);
|
||||
if (this.player.isOnBlock) {
|
||||
this.toggleOnBlock();
|
||||
}
|
||||
} else if (this.player.isVoteless) {
|
||||
this.updatePlayer("isVoteless", false);
|
||||
this.updatePlayer("isDead", false);
|
||||
|
@ -265,6 +279,9 @@ export default {
|
|||
}
|
||||
} else {
|
||||
this.updatePlayer("isDead", !this.player.isDead);
|
||||
if (this.player.isOnBlock) {
|
||||
this.toggleOnBlock();
|
||||
}
|
||||
if (this.player.isVoteless) {
|
||||
this.updatePlayer("isVoteless", false);
|
||||
}
|
||||
|
@ -319,6 +336,10 @@ export default {
|
|||
this.isMenuOpen = false;
|
||||
this.$emit("trigger", ["claimSeat"]);
|
||||
},
|
||||
toggleOnBlock() {
|
||||
this.isMenuOpen = false;
|
||||
this.$emit("trigger", ["toggleOnBlock"]);
|
||||
},
|
||||
/**
|
||||
* Allow the ST to override a locked vote.
|
||||
*/
|
||||
|
@ -578,10 +599,7 @@ li.move:not(.from) .player .overlay svg.move {
|
|||
}
|
||||
|
||||
/****** Vote icon ********/
|
||||
.player .has-vote {
|
||||
position: absolute;
|
||||
right: 2px;
|
||||
margin-top: -15%;
|
||||
.player .has-vote .on-block {
|
||||
color: #fff;
|
||||
filter: drop-shadow(0 0 3px black);
|
||||
transition: opacity 250ms;
|
||||
|
@ -593,6 +611,19 @@ li.move:not(.from) .player .overlay svg.move {
|
|||
}
|
||||
}
|
||||
|
||||
.has-vote {
|
||||
position: absolute;
|
||||
margin-top: -15%;
|
||||
right: 2px;
|
||||
}
|
||||
|
||||
.on-block {
|
||||
position: absolute;
|
||||
margin-top: -15%;
|
||||
left: 3px;
|
||||
color: darkred;
|
||||
}
|
||||
|
||||
/****** Session seat glow *****/
|
||||
@mixin glow($name, $color) {
|
||||
@keyframes #{$name}-glow {
|
||||
|
|
|
@ -201,6 +201,13 @@ export default {
|
|||
this.move = -1;
|
||||
this.swap = -1;
|
||||
this.nominate = -1;
|
||||
},
|
||||
toggleOnBlock(playerIndex) {
|
||||
if (this.players[playerIndex].isOnBlock) {
|
||||
this.$store.commit("players/setOnBlock", -1);
|
||||
} else {
|
||||
this.$store.commit("players/setOnBlock", playerIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -62,6 +62,19 @@
|
|||
<div class="button demon" @click="finish">Close</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="!session.isSpectator">
|
||||
<div
|
||||
class="button-group"
|
||||
v-if="session.lockedVote && !session.isVoteInProgress"
|
||||
>
|
||||
<div class="button demon" @click="setOnBlock">
|
||||
Put on block
|
||||
</div>
|
||||
<div class="button demon" @click="emptyBlock">
|
||||
Empty block
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else-if="canVote">
|
||||
<div v-if="!session.isVoteInProgress">
|
||||
{{ session.votingSpeed / 1000 }} seconds between votes
|
||||
|
@ -235,6 +248,14 @@ export default {
|
|||
if (speed > 0) {
|
||||
this.$store.commit("session/setVotingSpeed", speed);
|
||||
}
|
||||
},
|
||||
setOnBlock() {
|
||||
this.$store.commit("players/setOnBlock", this.session.nomination[1]);
|
||||
this.finish();
|
||||
},
|
||||
emptyBlock() {
|
||||
this.$store.commit("players/setOnBlock", -1);
|
||||
this.finish();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -16,6 +16,7 @@ const faIcons = [
|
|||
"CloudMoon",
|
||||
"Cog",
|
||||
"Copy",
|
||||
"Crosshairs",
|
||||
"Dice",
|
||||
"Dragon",
|
||||
"ExchangeAlt",
|
||||
|
|
|
@ -5,6 +5,7 @@ const NEWPLAYER = {
|
|||
reminders: [],
|
||||
isVoteless: false,
|
||||
isDead: false,
|
||||
isOnBlock: false,
|
||||
pronouns: ""
|
||||
};
|
||||
|
||||
|
@ -136,6 +137,14 @@ const mutations = {
|
|||
move(state, [from, to]) {
|
||||
state.players.splice(to, 0, state.players.splice(from, 1)[0]);
|
||||
},
|
||||
setOnBlock(state, playerIndex) {
|
||||
state.players.forEach(player => {
|
||||
player.isOnBlock = false;
|
||||
});
|
||||
if (playerIndex >= 0) {
|
||||
state.players[playerIndex].isOnBlock = true;
|
||||
}
|
||||
},
|
||||
setBluff(state, { index, role } = {}) {
|
||||
if (index !== undefined) {
|
||||
state.bluffs.splice(index, 1, role);
|
||||
|
|
|
@ -168,6 +168,10 @@ class LiveSession {
|
|||
if (!this._isSpectator) return;
|
||||
this._store.commit("players/remove", params);
|
||||
break;
|
||||
case "onBlock":
|
||||
if (!this._isSpectator) return;
|
||||
this._store.commit("players/setOnBlock", params);
|
||||
break;
|
||||
case "isNight":
|
||||
if (!this._isSpectator) return;
|
||||
this._store.commit("toggleNight", params);
|
||||
|
@ -251,6 +255,7 @@ class LiveSession {
|
|||
id: player.id,
|
||||
isDead: player.isDead,
|
||||
isVoteless: player.isVoteless,
|
||||
isOnBlock: player.isOnBlock,
|
||||
pronouns: player.pronouns,
|
||||
...(player.role && player.role.team === "traveler"
|
||||
? { roleId: player.role.id }
|
||||
|
@ -312,12 +317,14 @@ class LiveSession {
|
|||
const player = players[x];
|
||||
const { roleId } = state;
|
||||
// update relevant properties
|
||||
["name", "id", "isDead", "isVoteless", "pronouns"].forEach(property => {
|
||||
const value = state[property];
|
||||
if (player[property] !== value) {
|
||||
this._store.commit("players/update", { player, property, value });
|
||||
["name", "id", "isDead", "isVoteless", "isOnBlock", "pronouns"].forEach(
|
||||
property => {
|
||||
const value = state[property];
|
||||
if (player[property] !== value) {
|
||||
this._store.commit("players/update", { player, property, value });
|
||||
}
|
||||
}
|
||||
});
|
||||
);
|
||||
// roles are special, because of travelers
|
||||
if (roleId && player.role.id !== roleId) {
|
||||
const role =
|
||||
|
@ -697,6 +704,15 @@ class LiveSession {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set which player is on the block. ST only
|
||||
* @param id, player id or -1 for empty
|
||||
*/
|
||||
setOnBlock(playerIndex) {
|
||||
if (this._isSpectator) return;
|
||||
this._send("onBlock", playerIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the vote history for everyone. ST only
|
||||
*/
|
||||
|
@ -849,6 +865,9 @@ export default store => {
|
|||
case "players/setFabled":
|
||||
session.sendFabled();
|
||||
break;
|
||||
case "players/setOnBlock":
|
||||
session.setOnBlock(payload);
|
||||
break;
|
||||
case "players/swap":
|
||||
session.swapPlayer(payload);
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue