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