2020-04-01 22:57:14 +02:00
|
|
|
<template>
|
2020-04-15 22:40:58 +02:00
|
|
|
<div
|
|
|
|
id="townsquare"
|
|
|
|
class="square"
|
2020-05-09 21:47:00 +02:00
|
|
|
v-bind:class="{
|
|
|
|
public: grimoire.isPublic,
|
2020-05-12 20:48:00 +02:00
|
|
|
spectator: session.isSpectator
|
2020-05-09 21:47:00 +02:00
|
|
|
}"
|
2020-05-02 21:33:44 +02:00
|
|
|
v-bind:style="{ zoom: grimoire.zoom }"
|
2020-04-15 22:40:58 +02:00
|
|
|
>
|
2020-04-04 16:14:25 +02:00
|
|
|
<ul class="circle" v-bind:class="['size-' + players.length]">
|
|
|
|
<Player
|
2020-04-05 21:50:06 +02:00
|
|
|
v-for="(player, index) in players"
|
|
|
|
:key="index"
|
2020-04-05 19:50:33 +02:00
|
|
|
:player="player"
|
2020-05-03 23:05:17 +02:00
|
|
|
@add-reminder="openReminderModal(index)"
|
|
|
|
@set-role="openRoleModal(index)"
|
|
|
|
@remove-player="removePlayer(index)"
|
2020-05-19 15:19:19 +02:00
|
|
|
@cancel="cancel(index)"
|
|
|
|
@swap-player="swapPlayer(index, $event)"
|
|
|
|
@move-player="movePlayer(index, $event)"
|
2020-04-19 22:54:25 +02:00
|
|
|
@screenshot="$emit('screenshot', $event)"
|
2020-05-12 22:22:36 +02:00
|
|
|
v-bind:class="{
|
2020-05-19 15:19:19 +02:00
|
|
|
from: Math.max(swap, move, nominate) === index,
|
|
|
|
swap: swap > -1,
|
|
|
|
move: move > -1,
|
|
|
|
nominate: nominate > -1
|
2020-05-12 22:22:36 +02:00
|
|
|
}"
|
2020-04-04 16:14:25 +02:00
|
|
|
></Player>
|
|
|
|
</ul>
|
2020-05-03 23:05:17 +02:00
|
|
|
|
2020-04-19 22:54:25 +02:00
|
|
|
<div class="bluffs" v-if="players.length > 6" ref="bluffs">
|
2020-04-18 21:03:58 +02:00
|
|
|
<h3>Demon bluffs</h3>
|
2020-04-19 22:54:25 +02:00
|
|
|
<font-awesome-icon icon="camera" @click.stop="takeScreenshot" />
|
2020-04-18 21:03:58 +02:00
|
|
|
<ul>
|
2020-04-05 19:50:33 +02:00
|
|
|
<li
|
2020-05-03 23:05:17 +02:00
|
|
|
v-for="index in bluffs"
|
|
|
|
:key="index"
|
|
|
|
@click="openRoleModal(index * -1)"
|
2020-04-05 19:50:33 +02:00
|
|
|
>
|
2020-05-03 23:05:17 +02:00
|
|
|
<Token :role="grimoire.bluffs[index - 1]"></Token>
|
2020-04-04 16:14:25 +02:00
|
|
|
</li>
|
|
|
|
</ul>
|
2020-05-03 23:05:17 +02:00
|
|
|
</div>
|
2020-05-02 21:33:44 +02:00
|
|
|
|
2020-05-03 23:05:17 +02:00
|
|
|
<ReminderModal :player-index="selectedPlayer"></ReminderModal>
|
|
|
|
<RoleModal :player-index="selectedPlayer"></RoleModal>
|
2020-04-04 16:14:25 +02:00
|
|
|
</div>
|
2020-04-01 22:57:14 +02:00
|
|
|
</template>
|
|
|
|
|
|
|
|
<script>
|
2020-05-03 23:05:17 +02:00
|
|
|
import { mapState } from "vuex";
|
2020-04-05 19:50:33 +02:00
|
|
|
import Player from "./Player";
|
2020-04-15 22:40:58 +02:00
|
|
|
import Token from "./Token";
|
2020-05-03 23:05:17 +02:00
|
|
|
import ReminderModal from "./modals/ReminderModal";
|
|
|
|
import RoleModal from "./modals/RoleModal";
|
2020-04-01 22:57:14 +02:00
|
|
|
|
2020-04-05 19:50:33 +02:00
|
|
|
export default {
|
|
|
|
components: {
|
2020-05-03 23:05:17 +02:00
|
|
|
Player,
|
2020-04-15 22:40:58 +02:00
|
|
|
Token,
|
2020-05-03 23:05:17 +02:00
|
|
|
RoleModal,
|
|
|
|
ReminderModal
|
2020-04-05 19:50:33 +02:00
|
|
|
},
|
2020-05-03 23:05:17 +02:00
|
|
|
computed: {
|
2020-05-12 20:48:00 +02:00
|
|
|
...mapState(["grimoire", "roles", "session"]),
|
2020-05-03 23:05:17 +02:00
|
|
|
...mapState("players", ["players"])
|
2020-04-05 22:54:15 +02:00
|
|
|
},
|
2020-04-05 19:50:33 +02:00
|
|
|
data() {
|
|
|
|
return {
|
2020-05-03 23:05:17 +02:00
|
|
|
selectedPlayer: 0,
|
2020-05-12 22:22:36 +02:00
|
|
|
bluffs: 3,
|
2020-05-19 15:19:19 +02:00
|
|
|
swap: -1,
|
|
|
|
move: -1,
|
|
|
|
nominate: -1
|
2020-04-05 19:50:33 +02:00
|
|
|
};
|
|
|
|
},
|
|
|
|
methods: {
|
2020-04-19 22:54:25 +02:00
|
|
|
takeScreenshot() {
|
|
|
|
const { width, height, x, y } = this.$refs.bluffs.getBoundingClientRect();
|
|
|
|
this.$emit("screenshot", { width, height, x, y });
|
|
|
|
},
|
2020-05-03 23:05:17 +02:00
|
|
|
openReminderModal(playerIndex) {
|
|
|
|
this.selectedPlayer = playerIndex;
|
|
|
|
this.$store.commit("toggleModal", "reminder");
|
2020-04-05 19:50:33 +02:00
|
|
|
},
|
2020-05-03 23:05:17 +02:00
|
|
|
openRoleModal(playerIndex) {
|
2020-05-09 21:47:00 +02:00
|
|
|
const player = this.players[playerIndex];
|
2020-05-12 20:48:00 +02:00
|
|
|
if (this.session.isSpectator && player.role.team === "traveler") return;
|
2020-05-03 23:05:17 +02:00
|
|
|
this.selectedPlayer = playerIndex;
|
|
|
|
this.$store.commit("toggleModal", "role");
|
2020-04-05 22:54:15 +02:00
|
|
|
},
|
2020-05-03 23:05:17 +02:00
|
|
|
removePlayer(playerIndex) {
|
2020-05-12 20:48:00 +02:00
|
|
|
if (this.session.isSpectator) return;
|
2020-05-03 23:05:17 +02:00
|
|
|
if (
|
|
|
|
confirm(
|
|
|
|
`Do you really want to remove ${this.players[playerIndex].name}?`
|
|
|
|
)
|
|
|
|
) {
|
|
|
|
this.$store.commit("players/remove", playerIndex);
|
2020-04-05 22:54:15 +02:00
|
|
|
}
|
2020-05-12 22:22:36 +02:00
|
|
|
},
|
2020-05-19 15:19:19 +02:00
|
|
|
swapPlayer(from, to) {
|
2020-05-12 22:22:36 +02:00
|
|
|
if (to === undefined) {
|
2020-05-19 15:19:19 +02:00
|
|
|
this.cancel();
|
|
|
|
this.swap = from;
|
2020-05-12 22:22:36 +02:00
|
|
|
} else {
|
|
|
|
this.$store.commit("players/swap", [
|
2020-05-19 15:19:19 +02:00
|
|
|
this.swap,
|
2020-05-12 22:22:36 +02:00
|
|
|
this.players.indexOf(to)
|
|
|
|
]);
|
2020-05-19 15:19:19 +02:00
|
|
|
this.cancel();
|
2020-05-12 22:22:36 +02:00
|
|
|
}
|
2020-05-19 15:19:19 +02:00
|
|
|
},
|
|
|
|
movePlayer(from, to) {
|
|
|
|
if (to === undefined) {
|
|
|
|
this.cancel();
|
|
|
|
this.move = from;
|
|
|
|
} else {
|
|
|
|
this.$store.commit("players/move", [
|
|
|
|
this.move,
|
|
|
|
this.players.indexOf(to)
|
|
|
|
]);
|
|
|
|
this.cancel();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
cancel() {
|
|
|
|
this.move = -1;
|
|
|
|
this.swap = -1;
|
|
|
|
this.nominate = -1;
|
2020-04-01 22:57:14 +02:00
|
|
|
}
|
|
|
|
}
|
2020-04-05 19:50:33 +02:00
|
|
|
};
|
2020-04-01 22:57:14 +02:00
|
|
|
</script>
|
|
|
|
|
|
|
|
<style lang="scss">
|
2020-04-05 19:50:33 +02:00
|
|
|
.circle {
|
|
|
|
padding: 0;
|
|
|
|
width: 100%;
|
|
|
|
height: 100%;
|
|
|
|
list-style: none;
|
|
|
|
margin: 0;
|
2020-04-01 22:57:14 +02:00
|
|
|
|
2020-05-12 22:22:36 +02:00
|
|
|
> li {
|
2020-04-05 19:50:33 +02:00
|
|
|
position: absolute;
|
|
|
|
top: 0;
|
|
|
|
left: 50%;
|
|
|
|
height: 50%;
|
|
|
|
transform-origin: 0 100%;
|
|
|
|
text-align: center;
|
2020-04-02 22:23:40 +02:00
|
|
|
|
2020-04-05 19:50:33 +02:00
|
|
|
&:hover {
|
|
|
|
z-index: 25 !important;
|
2020-04-01 22:57:14 +02:00
|
|
|
}
|
|
|
|
|
2020-04-05 19:50:33 +02:00
|
|
|
> * {
|
2020-04-19 22:54:25 +02:00
|
|
|
margin-left: -78px;
|
|
|
|
width: 156px;
|
2020-04-02 22:23:40 +02:00
|
|
|
}
|
|
|
|
}
|
2020-04-05 19:50:33 +02:00
|
|
|
}
|
2020-04-01 22:57:14 +02:00
|
|
|
|
2020-04-05 21:50:06 +02:00
|
|
|
@mixin on-circle($item-count) {
|
|
|
|
$angle: (360 / $item-count);
|
|
|
|
$rot: 0;
|
|
|
|
|
|
|
|
@for $i from 1 through $item-count {
|
|
|
|
&:nth-child(#{$i}) {
|
|
|
|
transform: rotate($rot * 1deg);
|
|
|
|
@if $i - 1 <= $item-count / 2 {
|
|
|
|
z-index: $item-count - $i + 1;
|
2020-04-18 20:05:45 +02:00
|
|
|
} @else {
|
|
|
|
z-index: $i - 1;
|
2020-04-25 22:19:47 +02:00
|
|
|
.ability {
|
2020-04-22 23:07:25 +02:00
|
|
|
right: 120%;
|
2020-04-18 20:05:45 +02:00
|
|
|
left: auto;
|
2020-04-18 20:21:26 +02:00
|
|
|
&:before {
|
2020-04-18 20:05:45 +02:00
|
|
|
border-right-color: transparent;
|
|
|
|
border-left-color: black;
|
|
|
|
right: auto;
|
|
|
|
left: 100%;
|
2020-04-05 21:50:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
> * {
|
|
|
|
transform: rotate($rot * -1deg);
|
|
|
|
}
|
2020-04-08 22:42:51 +02:00
|
|
|
.life,
|
2020-04-10 11:21:27 +02:00
|
|
|
.token,
|
2020-04-22 23:07:25 +02:00
|
|
|
.shroud,
|
|
|
|
.night {
|
2020-04-10 11:21:27 +02:00
|
|
|
transition-delay: ($i - 1) * 50ms;
|
2020-04-08 21:30:55 +02:00
|
|
|
}
|
2020-04-22 21:21:54 +02:00
|
|
|
|
|
|
|
// move reminders closer to the sides of the circle
|
|
|
|
$q: $item-count / 4;
|
|
|
|
$x: $i - 1;
|
|
|
|
@if $x < $q or ($x >= $item-count / 2 and $x < $q * 3) {
|
|
|
|
.player {
|
|
|
|
margin-bottom: -10px + 20px * (1 - ($x % $q / $q));
|
|
|
|
}
|
|
|
|
} @else {
|
|
|
|
.player {
|
|
|
|
margin-bottom: -10px + 20px * ($x % $q / $q);
|
|
|
|
}
|
|
|
|
}
|
2020-04-05 21:50:06 +02:00
|
|
|
}
|
|
|
|
$rot: $rot + $angle;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-05 22:54:15 +02:00
|
|
|
@for $i from 1 through 20 {
|
2020-05-12 22:22:36 +02:00
|
|
|
.circle.size-#{$i} > li {
|
2020-04-05 19:50:33 +02:00
|
|
|
@include on-circle($item-count: $i);
|
2020-04-04 16:14:25 +02:00
|
|
|
}
|
2020-04-05 19:50:33 +02:00
|
|
|
}
|
2020-04-04 16:14:25 +02:00
|
|
|
|
2020-04-05 19:50:33 +02:00
|
|
|
#townsquare {
|
|
|
|
width: 100%;
|
|
|
|
height: 100%;
|
|
|
|
border-radius: 50%;
|
|
|
|
padding: 20px;
|
|
|
|
}
|
2020-04-01 22:57:14 +02:00
|
|
|
|
2020-04-18 21:03:58 +02:00
|
|
|
/***** Demon bluffs *******/
|
|
|
|
.bluffs {
|
|
|
|
position: absolute;
|
|
|
|
bottom: 10px;
|
|
|
|
left: 10px;
|
|
|
|
background: rgba(0, 0, 0, 0.5);
|
|
|
|
border-radius: 10px;
|
|
|
|
border: 3px solid black;
|
|
|
|
filter: drop-shadow(0 4px 6px rgba(0, 0, 0, 0.5));
|
|
|
|
transform-origin: bottom left;
|
|
|
|
transform: scale(1);
|
|
|
|
opacity: 1;
|
|
|
|
transition: all 200ms ease-in-out;
|
2020-04-22 21:21:54 +02:00
|
|
|
|
|
|
|
#townsquare.public & {
|
|
|
|
opacity: 0;
|
|
|
|
transform: scale(0.1);
|
|
|
|
}
|
2020-04-19 22:54:25 +02:00
|
|
|
> svg {
|
|
|
|
position: absolute;
|
|
|
|
top: 10px;
|
|
|
|
right: 10px;
|
|
|
|
cursor: pointer;
|
|
|
|
&:hover {
|
|
|
|
color: red;
|
|
|
|
}
|
2020-04-22 21:21:54 +02:00
|
|
|
#app.screenshot & {
|
|
|
|
display: none;
|
|
|
|
}
|
2020-04-19 22:54:25 +02:00
|
|
|
}
|
2020-04-18 21:03:58 +02:00
|
|
|
h3 {
|
|
|
|
margin-top: 5px;
|
|
|
|
}
|
|
|
|
li {
|
|
|
|
width: 120px;
|
|
|
|
height: 120px;
|
|
|
|
margin: 0 5px;
|
|
|
|
display: inline-block;
|
|
|
|
font-size: 18px;
|
|
|
|
}
|
|
|
|
}
|
2020-04-01 22:57:14 +02:00
|
|
|
</style>
|