mirror of https://github.com/bra1n/townsquare.git
added seat claiming
This commit is contained in:
parent
0f1397c53d
commit
f42d7dd2be
|
@ -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%;
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -22,6 +22,9 @@ const mutations = {
|
|||
},
|
||||
setPlayerCount(state, playerCount) {
|
||||
state.playerCount = playerCount;
|
||||
},
|
||||
claimSeat(state, claimedSeat) {
|
||||
state.claimedSeat = claimedSeat;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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":
|
||||
|
|
Loading…
Reference in New Issue