Merge pull request #160 from nicfreeman1209/on_block

add 'on the block' indicator
This commit is contained in:
Steffen 2021-05-10 21:16:42 +02:00 committed by GitHub
commit f718d8b24b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 115 additions and 19 deletions

View File

@ -6,6 +6,7 @@
- added global animation toggle for better performance
- added record vote history toggle to session menu, and clear vote history button
- add support for custom Fabled characters
- add 'marked for execution' indicator
---

View File

@ -119,7 +119,7 @@ export default {
break;
case "s":
if (this.session.isSpectator) return;
this.$store.commit("toggleNight");
this.$refs.menu.toggleNight();
break;
case "escape":
this.$store.commit("toggleModal");

View File

@ -339,12 +339,17 @@ export default {
this.$store.dispatch("players/clearRoles");
}
},
toggleNight() {
this.$store.commit("toggleNight");
if (this.grimoire.isNight) {
this.$store.commit("session/setMarkedPlayer", -1);
}
},
...mapMutations([
"toggleGrimoire",
"toggleMenu",
"toggleImageOptIn",
"toggleMuted",
"toggleNight",
"toggleNightOrder",
"toggleStatic",
"setZoom",

View File

@ -6,6 +6,7 @@
:class="[
{
dead: player.isDead,
marked: session.markedPlayer === index,
'no-vote': player.isVoteless,
you: session.sessionId && player.id && player.id === session.playerId,
'vote-yes': session.votes[index],
@ -97,6 +98,11 @@
@click="updatePlayer('isVoteless', true)"
title="Ghost vote"
/>
<!-- On block icon -->
<div class="marked">
<font-awesome-icon icon="skull" />
</div>
<div
class="name"
@click="isMenuOpen = !isMenuOpen"
@ -124,10 +130,6 @@
<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()" :class="{ disabled: session.lockedVote }">
<font-awesome-icon icon="redo-alt" />
Move player
@ -136,6 +138,10 @@
<font-awesome-icon icon="exchange-alt" />
Swap seats
</li>
<li @click="removePlayer" :class="{ disabled: session.lockedVote }">
<font-awesome-icon icon="times-circle" />
Remove
</li>
<li
@click="updatePlayer('id', '', true)"
v-if="player.id && session.sessionId"
@ -143,10 +149,12 @@
<font-awesome-icon icon="chair" />
Empty seat
</li>
<li @click="removePlayer" :class="{ disabled: session.lockedVote }">
<font-awesome-icon icon="times-circle" />
Remove
</li>
<template v-if="!session.nomination">
<li @click="nominatePlayer()">
<font-awesome-icon icon="hand-point-right" />
Nomination
</li>
</template>
</template>
<li
@click="claimSeat"
@ -257,6 +265,9 @@ export default {
if (this.grimoire.isPublic) {
if (!this.player.isDead) {
this.updatePlayer("isDead", true);
if (this.player.isMarked) {
this.updatePlayer("isMarked", false);
}
} else if (this.player.isVoteless) {
this.updatePlayer("isVoteless", false);
this.updatePlayer("isDead", false);
@ -265,6 +276,9 @@ export default {
}
} else {
this.updatePlayer("isDead", !this.player.isDead);
if (this.player.isMarked) {
this.updatePlayer("isMarked", false);
}
if (this.player.isVoteless) {
this.updatePlayer("isVoteless", false);
}
@ -579,9 +593,6 @@ li.move:not(.from) .player .overlay svg.move {
/****** Vote icon ********/
.player .has-vote {
position: absolute;
right: 2px;
margin-top: -15%;
color: #fff;
filter: drop-shadow(0 0 3px black);
transition: opacity 250ms;
@ -593,6 +604,12 @@ li.move:not(.from) .player .overlay svg.move {
}
}
.has-vote {
position: absolute;
margin-top: -15%;
right: 2px;
}
/****** Session seat glow *****/
@mixin glow($name, $color) {
@keyframes #{$name}-glow {
@ -624,6 +641,38 @@ li.move:not(.from) .player .overlay svg.move {
animation: townsfolk-glow 5s ease-in-out infinite;
}
/****** Marked icon ******/
.player .marked {
position: absolute;
width: 100%;
top: 0;
filter: drop-shadow(0px 0px 6px black);
pointer-events: none;
display: flex;
align-items: center;
justify-content: center;
transition: opacity 250ms;
opacity: 0;
&:before {
content: " ";
padding-top: 100%;
display: block;
}
svg {
height: 60%;
width: 60%;
position: absolute;
stroke: white;
stroke-width: 15px;
path {
fill: white;
}
}
}
.player.marked .marked {
opacity: 0.5;
}
/****** Seat icon ********/
.player .seat {
position: absolute;

View File

@ -19,12 +19,6 @@
</em>
<em v-else>(majority is {{ Math.ceil(players.length / 2) }})</em>
<div v-if="session.isVoteInProgress || session.lockedVote > 1">
<em class="blue" v-if="voters.length">{{ voters.join(", ") }} </em>
<span v-else>nobody</span>
had their hand <em>UP</em>
</div>
<template v-if="!session.isSpectator">
<div v-if="!session.isVoteInProgress && session.lockedVote < 1">
Time per player:
@ -61,6 +55,20 @@
</template>
<div class="button demon" @click="finish">Close</div>
</div>
<div class="button-group mark" v-if="nominee.role.team !== 'traveler'">
<div
class="button"
:class="{
disabled: session.nomination[1] === session.markedPlayer
}"
@click="setMarked"
>
Mark for execution
</div>
<div class="button" @click="removeMarked">
Clear mark
</div>
</div>
</template>
<template v-else-if="canVote">
<div v-if="!session.isVoteInProgress">
@ -235,6 +243,12 @@ export default {
if (speed > 0) {
this.$store.commit("session/setVotingSpeed", speed);
}
},
setMarked() {
this.$store.commit("session/setMarkedPlayer", this.session.nomination[1]);
},
removeMarked() {
this.$store.commit("session/setMarkedPlayer", -1);
}
}
};
@ -257,6 +271,11 @@ export default {
text-shadow: 0 1px 2px #000000, 0 -1px 2px #000000, 1px 0 2px #000000,
-1px 0 2px #000000;
.mark .button {
font-size: 75%;
margin: 0;
}
&:after {
content: " ";
padding-bottom: 100%;

View File

@ -35,6 +35,7 @@ const faIcons = [
"RedoAlt",
"SearchMinus",
"SearchPlus",
"Skull",
"Square",
"TheaterMasks",
"Times",

View File

@ -25,6 +25,7 @@ const state = () => ({
votingSpeed: 3000,
isVoteInProgress: false,
voteHistory: [],
markedPlayer: -1,
isVoteHistoryAllowed: true,
isRolesDistributed: false
});
@ -46,6 +47,7 @@ const mutations = {
setPing: set("ping"),
setVotingSpeed: set("votingSpeed"),
setVoteInProgress: set("isVoteInProgress"),
setMarkedPlayer: set("markedPlayer"),
setNomination: set("nomination"),
setVoteHistoryAllowed: set("isVoteHistoryAllowed"),
claimSeat: set("claimedSeat"),

View File

@ -168,6 +168,10 @@ class LiveSession {
if (!this._isSpectator) return;
this._store.commit("players/remove", params);
break;
case "marked":
if (!this._isSpectator) return;
this._store.commit("session/setMarkedPlayer", params);
break;
case "isNight":
if (!this._isSpectator) return;
this._store.commit("toggleNight", params);
@ -278,6 +282,7 @@ class LiveSession {
votingSpeed: session.votingSpeed,
lockedVote: session.lockedVote,
isVoteInProgress: session.isVoteInProgress,
markedPlayer: session.markedPlayer,
fabled: fabled.map(f => (f.isCustom ? f : { id: f.id })),
...(session.nomination ? { votes: session.votes } : {})
});
@ -301,6 +306,7 @@ class LiveSession {
votes,
lockedVote,
isVoteInProgress,
markedPlayer,
fabled
} = data;
const players = this._store.state.players.players;
@ -355,6 +361,7 @@ class LiveSession {
lockedVote,
isVoteInProgress
});
this._store.commit("session/setMarkedPlayer", markedPlayer);
this._store.commit("players/setFabled", {
fabled: fabled.map(f => this._store.state.fabled.get(f.id) || f)
});
@ -718,6 +725,15 @@ class LiveSession {
}
}
/**
* Set which player is on the block. ST only
* @param playerIndex, player id or -1 for empty
*/
setMarked(playerIndex) {
if (this._isSpectator) return;
this._send("marked", playerIndex);
}
/**
* Clear the vote history for everyone. ST only
*/
@ -874,6 +890,9 @@ export default store => {
case "players/setFabled":
session.sendFabled();
break;
case "session/setMarkedPlayer":
session.setMarked(payload);
break;
case "players/swap":
session.swapPlayer(payload);
break;