added seat claiming

This commit is contained in:
Steffen 2020-05-31 00:18:31 +02:00
parent 0f1397c53d
commit f42d7dd2be
No known key found for this signature in database
GPG Key ID: 764D74E98267DFC6
5 changed files with 138 additions and 23 deletions

View File

@ -3,11 +3,14 @@
<div
ref="player"
class="player"
:class="{
dead: player.isDead,
'no-vote': player.isVoteless,
traveler: player.role && player.role.team === 'traveler'
}"
:class="[
{
dead: player.isDead,
'no-vote': player.isVoteless,
you: player.id === session.playerId
},
player.role.team
]"
>
<div class="shroud" @click="toggleStatus()"></div>
<div class="life" @click="toggleStatus()"></div>
@ -31,8 +34,12 @@
}}</span>
</div>
<Token :role="player.role" @set-role="$emit('set-role')" />
<Token
:role="player.role"
@set-role="$emit('trigger', ['openRoleModal'])"
/>
<!-- Overlay icons -->
<font-awesome-icon
icon="times-circle"
class="cancel"
@ -52,6 +59,10 @@
title="Move player to this seat"
/>
<!-- Claimed seat icon -->
<font-awesome-icon icon="chair" v-if="player.id" class="seat" />
<!-- Ghost vote icon -->
<font-awesome-icon
icon="vote-yea"
class="vote"
@ -90,13 +101,17 @@
<font-awesome-icon icon="camera" />
Screenshot
</li>
<li @click="$emit('remove-player')">
<li @click="$emit('trigger', ['removePlayer'])">
<font-awesome-icon icon="times-circle" />
Remove
</li>
</template>
<li @click="claimSeat" v-if="session.isSpectator">
<font-awesome-icon icon="chair" /> Claim seat
<font-awesome-icon icon="chair" />
<template v-if="player.id !== session.playerId">
Claim seat
</template>
<template v-else> Vacate seat </template>
</li>
</ul>
</transition>
@ -121,7 +136,7 @@
{{ reminder.name }}
</div>
</template>
<div class="reminder add" @click="$emit('add-reminder')">
<div class="reminder add" @click="$emit('trigger', ['openReminderModal'])">
<span class="icon"></span>
</div>
</li>
@ -198,14 +213,18 @@ export default {
},
swapPlayer(player) {
this.isMenuOpen = false;
this.$emit("swap-player", player);
this.$emit("trigger", ["swapPlayer", player]);
},
movePlayer(player) {
this.isMenuOpen = false;
this.$emit("move-player", player);
this.$emit("trigger", ["movePlayer", player]);
},
cancel() {
this.$emit("cancel");
this.$emit("trigger", ["cancel"]);
},
claimSeat() {
this.isMenuOpen = false;
this.$emit("trigger", ["claimSeat"]);
}
}
};
@ -407,7 +426,6 @@ li.move:not(.from) .player > svg.move {
bottom: 45px;
color: #fff;
filter: drop-shadow(0 0 3px black);
cursor: pointer;
transition: opacity 250ms;
#townsquare.public & {
@ -416,6 +434,50 @@ li.move:not(.from) .player > svg.move {
}
}
@mixin glow($name, $color) {
@keyframes #{$name}-glow {
0% {
box-shadow: 0 0 rgba($color, 1);
border-color: $color;
}
50% {
border-color: black;
}
100% {
box-shadow: 0 0 20px 16px transparent;
border-color: $color;
}
}
.player.you.#{$name} .token {
animation: #{$name}-glow 2s ease-in-out infinite;
}
}
@include glow("townsfolk", $townsfolk);
@include glow("outsider", $outsider);
@include glow("demon", $demon);
@include glow("minion", $minion);
@include glow("traveler", $traveler);
.player.you .token {
animation: townsfolk-glow 2s ease-in-out infinite;
}
/****** Seat icon ********/
.player .seat {
position: absolute;
left: 2px;
bottom: 45px;
color: #fff;
filter: drop-shadow(0 0 3px black);
cursor: default;
}
.player.you .seat {
color: $townsfolk;
}
/***** Player name *****/
.player > .name {
font-size: 120%;

View File

@ -13,13 +13,8 @@
v-for="(player, index) in players"
:key="index"
:player="player"
@add-reminder="openReminderModal(index)"
@set-role="openRoleModal(index)"
@remove-player="removePlayer(index)"
@cancel="cancel(index)"
@swap-player="swapPlayer(index, $event)"
@move-player="movePlayer(index, $event)"
@screenshot="$emit('screenshot', $event)"
@trigger="handleTrigger(index, $event)"
v-bind:class="{
from: Math.max(swap, move, nominate) === index,
swap: swap > -1,
@ -80,6 +75,19 @@ export default {
const { width, height, x, y } = this.$refs.bluffs.getBoundingClientRect();
this.$emit("screenshot", { width, height, x, y });
},
handleTrigger(playerIndex, [method, params]) {
if (typeof this[method] === "function") {
this[method](playerIndex, params);
}
},
claimSeat(playerIndex) {
if (!this.session.isSpectator) return;
if (this.session.playerId === this.players[playerIndex].id) {
this.$store.commit("session/claimSeat", -1);
} else {
this.$store.commit("session/claimSeat", playerIndex);
}
},
openReminderModal(playerIndex) {
this.selectedPlayer = playerIndex;
this.$store.commit("toggleModal", "reminder");

View File

@ -1,4 +1,6 @@
const NEWPLAYER = {
name: "",
id: "",
role: {},
reminders: [],
isVoteless: false,
@ -60,9 +62,9 @@ const actions = {
});
} else {
players = state.players.map(({ name, id }) => ({
...NEWPLAYER,
name,
id,
...NEWPLAYER
id
}));
}
commit("set", players);
@ -84,8 +86,8 @@ const mutations = {
},
add(state, name) {
state.players.push({
name,
...NEWPLAYER
...NEWPLAYER,
name
});
},
remove(state, index) {

View File

@ -22,6 +22,9 @@ const mutations = {
},
setPlayerCount(state, playerCount) {
state.playerCount = playerCount;
},
claimSeat(state, claimedSeat) {
state.claimedSeat = claimedSeat;
}
};

View File

@ -93,6 +93,9 @@ class LiveSession {
case "player":
this._updatePlayer(params);
break;
case "claim":
this._updateSeat(params);
break;
case "ping":
this._handlePing(params);
break;
@ -304,6 +307,40 @@ class LiveSession {
Object.keys(this._players).length
);
}
/**
* Claim a seat, needs to be confirmed by the Storyteller.
* @param seat either -1 or the index of the seat claimed
*/
claimSeat(seat) {
if (!this._isSpectator) return;
if (this._store.state.players.players.length > seat) {
this._send("claim", [seat, this._store.state.session.playerId]);
}
}
/**
* Update a player id associated with that seat.
* @param index seat index or -1
* @param value playerId to add / remove
* @private
*/
_updateSeat([index, value]) {
const property = "id";
// remove previous seat
const player = this._store.state.players.players.find(
({ id }) => id === value
);
if (player) {
this._store.commit("players/update", { player, property, value: "" });
}
// add playerId to new seat
if (index >= 0) {
const player = this._store.state.players.players[index];
if (!player) return;
this._store.commit("players/update", { player, property, value });
}
}
}
module.exports = store => {
@ -321,6 +358,9 @@ module.exports = store => {
session.disconnect();
}
break;
case "session/claimSeat":
session.claimSeat(payload);
break;
case "players/set":
case "players/swap":
case "players/move":