townsquare/src/components/TownSquare.vue

648 lines
15 KiB
Vue
Raw Normal View History

2020-04-01 20:57:14 +00:00
<template>
<div
id="townsquare"
class="square"
:class="{
public: grimoire.isPublic,
2020-06-03 20:25:23 +00:00
spectator: session.isSpectator,
vote: session.nomination
}"
>
<ul class="circle" :class="['size-' + players.length]">
<Player
2020-04-05 19:50:06 +00:00
v-for="(player, index) in players"
:key="index"
2020-04-05 17:50:33 +00:00
:player="player"
2020-05-30 22:18:31 +00:00
@trigger="handleTrigger(index, $event)"
:class="{
2020-05-19 13:19:19 +00:00
from: Math.max(swap, move, nominate) === index,
swap: swap > -1,
move: move > -1,
nominate: nominate > -1
2020-05-12 20:22:36 +00:00
}"
></Player>
</ul>
2020-05-03 21:05:17 +00:00
<div
class="bluffs"
v-if="players.length"
ref="bluffs"
:class="{ closed: !isBluffsOpen }"
>
<h3>
<span v-if="session.isSpectator">Other characters</span>
<span v-else>Demon bluffs</span>
<font-awesome-icon icon="times-circle" @click.stop="toggleBluffs" />
<font-awesome-icon icon="plus-circle" @click.stop="toggleBluffs" />
</h3>
2020-04-18 19:03:58 +00:00
<ul>
2020-04-05 17:50:33 +00:00
<li
v-for="index in bluffSize"
2020-05-03 21:05:17 +00:00
:key="index"
@click="openRoleModal(index * -1)"
2020-04-05 17:50:33 +00:00
>
<Token :role="bluffs[index - 1]"></Token>
</li>
</ul>
2020-05-03 21:05:17 +00:00
</div>
2020-05-02 19:33:44 +00:00
<div class="fabled" :class="{ closed: !isFabledOpen }" v-if="fabled.length">
2020-07-23 11:52:53 +00:00
<h3>
<span>Fabled</span>
<font-awesome-icon icon="times-circle" @click.stop="toggleFabled" />
<font-awesome-icon icon="plus-circle" @click.stop="toggleFabled" />
</h3>
<ul>
<li
v-for="(role, index) in fabled"
2020-07-23 11:52:53 +00:00
:key="index"
2020-08-09 19:28:38 +00:00
@click="removeFabled(index)"
2020-07-23 11:52:53 +00:00
>
<div
class="night-order first"
v-if="nightOrder.get(role).first && grimoire.isNightOrder"
>
<em>{{ nightOrder.get(role).first }}.</em>
<span v-if="role.firstNightReminder">{{
role.firstNightReminder
}}</span>
</div>
<div
class="night-order other"
v-if="nightOrder.get(role).other && grimoire.isNightOrder"
>
<em>{{ nightOrder.get(role).other }}.</em>
<span v-if="role.otherNightReminder">{{
role.otherNightReminder
}}</span>
</div>
<Token :role="role"></Token>
2020-07-23 11:52:53 +00:00
</li>
</ul>
</div>
2020-05-03 21:05:17 +00:00
<ReminderModal :player-index="selectedPlayer"></ReminderModal>
<RoleModal :player-index="selectedPlayer"></RoleModal>
</div>
2020-04-01 20:57:14 +00:00
</template>
<script>
import { mapGetters, mapState } from "vuex";
2020-04-05 17:50:33 +00:00
import Player from "./Player";
import Token from "./Token";
2020-05-03 21:05:17 +00:00
import ReminderModal from "./modals/ReminderModal";
import RoleModal from "./modals/RoleModal";
2020-04-01 20:57:14 +00:00
2020-04-05 17:50:33 +00:00
export default {
components: {
2020-05-03 21:05:17 +00:00
Player,
Token,
2020-05-03 21:05:17 +00:00
RoleModal,
ReminderModal
2020-04-05 17:50:33 +00:00
},
2020-05-03 21:05:17 +00:00
computed: {
...mapGetters({ nightOrder: "players/nightOrder" }),
...mapState(["grimoire", "roles", "session"]),
...mapState("players", ["players", "bluffs", "fabled"])
},
2020-04-05 17:50:33 +00:00
data() {
return {
2020-05-03 21:05:17 +00:00
selectedPlayer: 0,
bluffSize: 3,
2020-05-19 13:19:19 +00:00
swap: -1,
move: -1,
nominate: -1,
2020-07-23 11:52:53 +00:00
isBluffsOpen: true,
isFabledOpen: true
2020-04-05 17:50:33 +00:00
};
},
methods: {
toggleBluffs() {
this.isBluffsOpen = !this.isBluffsOpen;
},
2020-07-23 11:52:53 +00:00
toggleFabled() {
this.isFabledOpen = !this.isFabledOpen;
},
2020-08-09 19:28:38 +00:00
removeFabled(index) {
if (this.session.isSpectator) return;
this.$store.commit("players/setFabled", { index });
2020-08-09 19:28:38 +00:00
},
2020-05-30 22:18:31 +00:00
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);
}
},
2020-05-03 21:05:17 +00:00
openReminderModal(playerIndex) {
this.selectedPlayer = playerIndex;
this.$store.commit("toggleModal", "reminder");
2020-04-05 17:50:33 +00:00
},
2020-05-03 21:05:17 +00:00
openRoleModal(playerIndex) {
const player = this.players[playerIndex];
if (this.session.isSpectator && player && player.role.team === "traveler")
return;
2020-05-03 21:05:17 +00:00
this.selectedPlayer = playerIndex;
this.$store.commit("toggleModal", "role");
},
2020-05-03 21:05:17 +00:00
removePlayer(playerIndex) {
v2.13.0 (#168) * add support for custom fabled (closes #110) * 2.13.0 * show custom fabled first * add recordVoteHistory & clearVoteHistory to session menu * Update CHANGELOG.md * socket part of toggle recordVoteHistory analogous to isNight * remove accidental * Add files via upload * add custom fabled * Add option to reduce night animations to save power. * add fallback icon for fabled * changelog * disable all animations now * linter * 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 * hide rounded corners on maximized modals (barely visible anyway) * ST always sees vote history i.e. toggle affects only players * empty block at night * avoid clashing with seat icon * nlc: toggle within session.js * lint * minor * Use proper "Exile" terminology for exile * Add info about "Banishment"->"Exile" to CHANGELOG * requested changes * remove direct ST control of block * player menu order * move block/night logic from socket to menu * minor fix to previous * on block -> marked * requested changes * requested change Co-authored-by: Steffen <steffen@baumgart.biz> * fix players being moved or removed during a nomination (closes #164) add vue linter * let's try adding a lint error * linter adjusted * it's working! * requested change record marked player id in session * feedback implemented npm audit * prepare develop branch * adjust linter config * revert version bump * fixes & visuals * Update CHANGELOG.md * restore old lint command (fixes #170) * minor fix default * show jinxed interactions on character reference modal * 2.13.0 * changelog Co-authored-by: nicfreeman1209 <nicfreeman1209@gmail.com> Co-authored-by: nicfreeman1209 <14160941+nicfreeman1209@users.noreply.github.com> Co-authored-by: Adrian Irving-Beer <wisq@wisq.net> Co-authored-by: Andrew Conant <emptierset@gmail.com>
2021-05-15 18:07:54 +00:00
if (this.session.isSpectator || this.session.lockedVote) return;
2020-05-03 21:05:17 +00:00
if (
confirm(
`Do you really want to remove ${this.players[playerIndex].name}?`
)
) {
v2.13.0 (#168) * add support for custom fabled (closes #110) * 2.13.0 * show custom fabled first * add recordVoteHistory & clearVoteHistory to session menu * Update CHANGELOG.md * socket part of toggle recordVoteHistory analogous to isNight * remove accidental * Add files via upload * add custom fabled * Add option to reduce night animations to save power. * add fallback icon for fabled * changelog * disable all animations now * linter * 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 * hide rounded corners on maximized modals (barely visible anyway) * ST always sees vote history i.e. toggle affects only players * empty block at night * avoid clashing with seat icon * nlc: toggle within session.js * lint * minor * Use proper "Exile" terminology for exile * Add info about "Banishment"->"Exile" to CHANGELOG * requested changes * remove direct ST control of block * player menu order * move block/night logic from socket to menu * minor fix to previous * on block -> marked * requested changes * requested change Co-authored-by: Steffen <steffen@baumgart.biz> * fix players being moved or removed during a nomination (closes #164) add vue linter * let's try adding a lint error * linter adjusted * it's working! * requested change record marked player id in session * feedback implemented npm audit * prepare develop branch * adjust linter config * revert version bump * fixes & visuals * Update CHANGELOG.md * restore old lint command (fixes #170) * minor fix default * show jinxed interactions on character reference modal * 2.13.0 * changelog Co-authored-by: nicfreeman1209 <nicfreeman1209@gmail.com> Co-authored-by: nicfreeman1209 <14160941+nicfreeman1209@users.noreply.github.com> Co-authored-by: Adrian Irving-Beer <wisq@wisq.net> Co-authored-by: Andrew Conant <emptierset@gmail.com>
2021-05-15 18:07:54 +00:00
const { nomination } = this.session;
if (nomination) {
if (nomination.includes(playerIndex)) {
// abort vote if removed player is either nominator or nominee
this.$store.commit("session/nomination");
} else if (
nomination[0] > playerIndex ||
nomination[1] > playerIndex
) {
// update nomination array if removed player has lower index
this.$store.commit("session/setNomination", [
nomination[0] > playerIndex ? nomination[0] - 1 : nomination[0],
nomination[1] > playerIndex ? nomination[1] - 1 : nomination[1]
]);
}
}
2020-05-03 21:05:17 +00:00
this.$store.commit("players/remove", playerIndex);
}
2020-05-12 20:22:36 +00:00
},
2020-05-19 13:19:19 +00:00
swapPlayer(from, to) {
v2.13.0 (#168) * add support for custom fabled (closes #110) * 2.13.0 * show custom fabled first * add recordVoteHistory & clearVoteHistory to session menu * Update CHANGELOG.md * socket part of toggle recordVoteHistory analogous to isNight * remove accidental * Add files via upload * add custom fabled * Add option to reduce night animations to save power. * add fallback icon for fabled * changelog * disable all animations now * linter * 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 * hide rounded corners on maximized modals (barely visible anyway) * ST always sees vote history i.e. toggle affects only players * empty block at night * avoid clashing with seat icon * nlc: toggle within session.js * lint * minor * Use proper "Exile" terminology for exile * Add info about "Banishment"->"Exile" to CHANGELOG * requested changes * remove direct ST control of block * player menu order * move block/night logic from socket to menu * minor fix to previous * on block -> marked * requested changes * requested change Co-authored-by: Steffen <steffen@baumgart.biz> * fix players being moved or removed during a nomination (closes #164) add vue linter * let's try adding a lint error * linter adjusted * it's working! * requested change record marked player id in session * feedback implemented npm audit * prepare develop branch * adjust linter config * revert version bump * fixes & visuals * Update CHANGELOG.md * restore old lint command (fixes #170) * minor fix default * show jinxed interactions on character reference modal * 2.13.0 * changelog Co-authored-by: nicfreeman1209 <nicfreeman1209@gmail.com> Co-authored-by: nicfreeman1209 <14160941+nicfreeman1209@users.noreply.github.com> Co-authored-by: Adrian Irving-Beer <wisq@wisq.net> Co-authored-by: Andrew Conant <emptierset@gmail.com>
2021-05-15 18:07:54 +00:00
if (this.session.isSpectator || this.session.lockedVote) return;
2020-05-12 20:22:36 +00:00
if (to === undefined) {
2020-05-19 13:19:19 +00:00
this.cancel();
this.swap = from;
2020-05-12 20:22:36 +00:00
} else {
v2.13.0 (#168) * add support for custom fabled (closes #110) * 2.13.0 * show custom fabled first * add recordVoteHistory & clearVoteHistory to session menu * Update CHANGELOG.md * socket part of toggle recordVoteHistory analogous to isNight * remove accidental * Add files via upload * add custom fabled * Add option to reduce night animations to save power. * add fallback icon for fabled * changelog * disable all animations now * linter * 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 * hide rounded corners on maximized modals (barely visible anyway) * ST always sees vote history i.e. toggle affects only players * empty block at night * avoid clashing with seat icon * nlc: toggle within session.js * lint * minor * Use proper "Exile" terminology for exile * Add info about "Banishment"->"Exile" to CHANGELOG * requested changes * remove direct ST control of block * player menu order * move block/night logic from socket to menu * minor fix to previous * on block -> marked * requested changes * requested change Co-authored-by: Steffen <steffen@baumgart.biz> * fix players being moved or removed during a nomination (closes #164) add vue linter * let's try adding a lint error * linter adjusted * it's working! * requested change record marked player id in session * feedback implemented npm audit * prepare develop branch * adjust linter config * revert version bump * fixes & visuals * Update CHANGELOG.md * restore old lint command (fixes #170) * minor fix default * show jinxed interactions on character reference modal * 2.13.0 * changelog Co-authored-by: nicfreeman1209 <nicfreeman1209@gmail.com> Co-authored-by: nicfreeman1209 <14160941+nicfreeman1209@users.noreply.github.com> Co-authored-by: Adrian Irving-Beer <wisq@wisq.net> Co-authored-by: Andrew Conant <emptierset@gmail.com>
2021-05-15 18:07:54 +00:00
if (this.session.nomination) {
// update nomination if one of the involved players is swapped
const swapTo = this.players.indexOf(to);
const updatedNomination = this.session.nomination.map(nom => {
if (nom === this.swap) return swapTo;
if (nom === swapTo) return this.swap;
return nom;
});
if (
this.session.nomination[0] !== updatedNomination[0] ||
this.session.nomination[1] !== updatedNomination[1]
) {
this.$store.commit("session/setNomination", updatedNomination);
}
}
2020-05-12 20:22:36 +00:00
this.$store.commit("players/swap", [
2020-05-19 13:19:19 +00:00
this.swap,
2020-05-12 20:22:36 +00:00
this.players.indexOf(to)
]);
2020-05-19 13:19:19 +00:00
this.cancel();
2020-05-12 20:22:36 +00:00
}
2020-05-19 13:19:19 +00:00
},
movePlayer(from, to) {
v2.13.0 (#168) * add support for custom fabled (closes #110) * 2.13.0 * show custom fabled first * add recordVoteHistory & clearVoteHistory to session menu * Update CHANGELOG.md * socket part of toggle recordVoteHistory analogous to isNight * remove accidental * Add files via upload * add custom fabled * Add option to reduce night animations to save power. * add fallback icon for fabled * changelog * disable all animations now * linter * 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 * hide rounded corners on maximized modals (barely visible anyway) * ST always sees vote history i.e. toggle affects only players * empty block at night * avoid clashing with seat icon * nlc: toggle within session.js * lint * minor * Use proper "Exile" terminology for exile * Add info about "Banishment"->"Exile" to CHANGELOG * requested changes * remove direct ST control of block * player menu order * move block/night logic from socket to menu * minor fix to previous * on block -> marked * requested changes * requested change Co-authored-by: Steffen <steffen@baumgart.biz> * fix players being moved or removed during a nomination (closes #164) add vue linter * let's try adding a lint error * linter adjusted * it's working! * requested change record marked player id in session * feedback implemented npm audit * prepare develop branch * adjust linter config * revert version bump * fixes & visuals * Update CHANGELOG.md * restore old lint command (fixes #170) * minor fix default * show jinxed interactions on character reference modal * 2.13.0 * changelog Co-authored-by: nicfreeman1209 <nicfreeman1209@gmail.com> Co-authored-by: nicfreeman1209 <14160941+nicfreeman1209@users.noreply.github.com> Co-authored-by: Adrian Irving-Beer <wisq@wisq.net> Co-authored-by: Andrew Conant <emptierset@gmail.com>
2021-05-15 18:07:54 +00:00
if (this.session.isSpectator || this.session.lockedVote) return;
2020-05-19 13:19:19 +00:00
if (to === undefined) {
this.cancel();
this.move = from;
} else {
v2.13.0 (#168) * add support for custom fabled (closes #110) * 2.13.0 * show custom fabled first * add recordVoteHistory & clearVoteHistory to session menu * Update CHANGELOG.md * socket part of toggle recordVoteHistory analogous to isNight * remove accidental * Add files via upload * add custom fabled * Add option to reduce night animations to save power. * add fallback icon for fabled * changelog * disable all animations now * linter * 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 * hide rounded corners on maximized modals (barely visible anyway) * ST always sees vote history i.e. toggle affects only players * empty block at night * avoid clashing with seat icon * nlc: toggle within session.js * lint * minor * Use proper "Exile" terminology for exile * Add info about "Banishment"->"Exile" to CHANGELOG * requested changes * remove direct ST control of block * player menu order * move block/night logic from socket to menu * minor fix to previous * on block -> marked * requested changes * requested change Co-authored-by: Steffen <steffen@baumgart.biz> * fix players being moved or removed during a nomination (closes #164) add vue linter * let's try adding a lint error * linter adjusted * it's working! * requested change record marked player id in session * feedback implemented npm audit * prepare develop branch * adjust linter config * revert version bump * fixes & visuals * Update CHANGELOG.md * restore old lint command (fixes #170) * minor fix default * show jinxed interactions on character reference modal * 2.13.0 * changelog Co-authored-by: nicfreeman1209 <nicfreeman1209@gmail.com> Co-authored-by: nicfreeman1209 <14160941+nicfreeman1209@users.noreply.github.com> Co-authored-by: Adrian Irving-Beer <wisq@wisq.net> Co-authored-by: Andrew Conant <emptierset@gmail.com>
2021-05-15 18:07:54 +00:00
if (this.session.nomination) {
// update nomination if it is affected by the move
const moveTo = this.players.indexOf(to);
const updatedNomination = this.session.nomination.map(nom => {
if (nom === this.move) return moveTo;
if (nom > this.move && nom <= moveTo) return nom - 1;
if (nom < this.move && nom >= moveTo) return nom + 1;
return nom;
});
if (
this.session.nomination[0] !== updatedNomination[0] ||
this.session.nomination[1] !== updatedNomination[1]
) {
this.$store.commit("session/setNomination", updatedNomination);
}
}
2020-05-19 13:19:19 +00:00
this.$store.commit("players/move", [
this.move,
this.players.indexOf(to)
]);
this.cancel();
}
},
2020-05-31 21:42:08 +00:00
nominatePlayer(from, to) {
v2.13.0 (#168) * add support for custom fabled (closes #110) * 2.13.0 * show custom fabled first * add recordVoteHistory & clearVoteHistory to session menu * Update CHANGELOG.md * socket part of toggle recordVoteHistory analogous to isNight * remove accidental * Add files via upload * add custom fabled * Add option to reduce night animations to save power. * add fallback icon for fabled * changelog * disable all animations now * linter * 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 * hide rounded corners on maximized modals (barely visible anyway) * ST always sees vote history i.e. toggle affects only players * empty block at night * avoid clashing with seat icon * nlc: toggle within session.js * lint * minor * Use proper "Exile" terminology for exile * Add info about "Banishment"->"Exile" to CHANGELOG * requested changes * remove direct ST control of block * player menu order * move block/night logic from socket to menu * minor fix to previous * on block -> marked * requested changes * requested change Co-authored-by: Steffen <steffen@baumgart.biz> * fix players being moved or removed during a nomination (closes #164) add vue linter * let's try adding a lint error * linter adjusted * it's working! * requested change record marked player id in session * feedback implemented npm audit * prepare develop branch * adjust linter config * revert version bump * fixes & visuals * Update CHANGELOG.md * restore old lint command (fixes #170) * minor fix default * show jinxed interactions on character reference modal * 2.13.0 * changelog Co-authored-by: nicfreeman1209 <nicfreeman1209@gmail.com> Co-authored-by: nicfreeman1209 <14160941+nicfreeman1209@users.noreply.github.com> Co-authored-by: Adrian Irving-Beer <wisq@wisq.net> Co-authored-by: Andrew Conant <emptierset@gmail.com>
2021-05-15 18:07:54 +00:00
if (this.session.isSpectator || this.session.lockedVote) return;
2020-06-05 20:46:54 +00:00
if (to === undefined) {
2020-05-31 21:42:08 +00:00
this.cancel();
if (from !== this.nominate) {
this.nominate = from;
}
} else {
const nomination = [this.nominate, this.players.indexOf(to)];
this.$store.commit("session/nomination", { nomination });
2020-05-31 21:42:08 +00:00
this.cancel();
}
},
2020-05-19 13:19:19 +00:00
cancel() {
this.move = -1;
this.swap = -1;
this.nominate = -1;
2020-04-01 20:57:14 +00:00
}
}
2020-04-05 17:50:33 +00:00
};
2020-04-01 20:57:14 +00:00
</script>
<style lang="scss">
@import "../vars.scss";
2020-06-10 22:37:17 +00:00
#townsquare {
width: 100%;
height: 100%;
padding: 20px;
display: flex;
align-items: center;
align-content: center;
justify-content: center;
}
2020-04-05 17:50:33 +00:00
.circle {
padding: 0;
width: 100%;
height: 100%;
list-style: none;
margin: 0;
2020-04-01 20:57:14 +00:00
2020-05-12 20:22:36 +00:00
> li {
2020-04-05 17:50:33 +00:00
position: absolute;
left: 50%;
height: 50%;
transform-origin: 0 100%;
pointer-events: none;
2020-04-02 20:23:40 +00:00
2020-04-05 17:50:33 +00:00
&:hover {
z-index: 25 !important;
2020-04-01 20:57:14 +00:00
}
2020-06-07 21:43:26 +00:00
> .player {
margin-left: -50%;
width: 100%;
pointer-events: all;
2020-06-07 21:43:26 +00:00
}
> .reminder {
margin-left: -25%;
width: 50%;
pointer-events: all;
2020-04-02 20:23:40 +00:00
}
}
2020-04-05 17:50:33 +00:00
}
2020-04-01 20:57:14 +00:00
2020-04-05 19:50:06 +00:00
@mixin on-circle($item-count) {
$angle: (360 / $item-count);
$rot: 0;
// rotation and tooltip placement
2020-04-05 19:50:06 +00:00
@for $i from 1 through $item-count {
&:nth-child(#{$i}) {
transform: rotate($rot * 1deg);
@if $i - 1 <= $item-count / 2 {
// first half of players
2020-04-05 19:50:06 +00:00
z-index: $item-count - $i + 1;
// open menu on the left
.player > .menu {
left: auto;
right: 110%;
margin-right: 15px;
&:before {
border-left-color: black;
border-right-color: transparent;
right: auto;
left: 100%;
}
}
.fold-enter-active,
.fold-leave-active {
transform-origin: right center;
}
.fold-enter,
.fold-leave-to {
transform: perspective(200px) rotateY(-90deg);
}
// show ability tooltip on the left
2020-04-25 20:19:47 +00:00
.ability {
2020-04-22 21:07:25 +00:00
right: 120%;
left: auto;
2020-04-18 18:21:26 +00:00
&:before {
border-right-color: transparent;
border-left-color: black;
right: auto;
left: 100%;
2020-04-05 19:50:06 +00:00
}
}
.pronouns {
left: 110%;
right: auto;
&:before {
border-left-color: transparent;
border-right-color: black;
left: auto;
right: 100%;
}
}
} @else {
// second half of players
z-index: $i - 1;
2020-04-05 19:50:06 +00:00
}
2020-04-05 19:50:06 +00:00
> * {
transform: rotate($rot * -1deg);
}
// animation cascade
2020-04-08 20:42:51 +00:00
.life,
2020-04-10 09:21:27 +00:00
.token,
2020-04-22 21:07:25 +00:00
.shroud,
.night-order,
.seat {
animation-delay: ($i - 1) * 50ms;
2020-04-10 09:21:27 +00:00
transition-delay: ($i - 1) * 50ms;
2020-04-08 19:30:55 +00:00
}
2020-04-22 19:21:54 +00: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 {
2020-06-10 22:37:17 +00:00
margin-bottom: -10% + 20% * (1 - ($x % $q / $q));
2020-04-22 19:21:54 +00:00
}
} @else {
.player {
2020-06-10 22:37:17 +00:00
margin-bottom: -10% + 20% * ($x % $q / $q);
2020-04-22 19:21:54 +00:00
}
}
2020-04-05 19:50:06 +00:00
}
$rot: $rot + $angle;
}
}
@for $i from 1 through 20 {
2020-05-12 20:22:36 +00:00
.circle.size-#{$i} > li {
2020-04-05 17:50:33 +00:00
@include on-circle($item-count: $i);
}
2020-04-05 17:50:33 +00:00
}
2020-07-23 11:52:53 +00:00
/***** Demon bluffs / Fabled *******/
#townsquare > .bluffs,
#townsquare > .fabled {
2020-04-18 19:03:58 +00:00
position: absolute;
2020-07-23 11:52:53 +00:00
&.bluffs {
bottom: 10px;
}
&.fabled {
top: 10px;
}
2020-04-18 19:03:58 +00:00
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;
z-index: 50;
2020-04-22 19:21:54 +00:00
2020-04-19 20:54:25 +00:00
> svg {
position: absolute;
top: 10px;
right: 10px;
cursor: pointer;
&:hover {
color: red;
}
}
2020-04-18 19:03:58 +00:00
h3 {
margin: 5px 1vh 0;
display: flex;
align-items: center;
align-content: center;
justify-content: center;
span {
flex-grow: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
svg {
cursor: pointer;
flex-grow: 0;
&.fa-times-circle {
margin-left: 1vh;
}
&.fa-plus-circle {
margin-left: 1vh;
display: none;
}
&:hover path {
fill: url(#demon);
stroke-width: 30px;
stroke: white;
}
}
2020-04-18 19:03:58 +00:00
}
2020-06-10 22:37:17 +00:00
ul {
display: flex;
align-items: center;
justify-content: center;
2020-06-10 22:37:17 +00:00
li {
width: 14vh;
height: 14vh;
margin: 0 0.5%;
display: inline-block;
transition: all 250ms;
}
}
&.closed {
svg.fa-times-circle {
display: none;
}
svg.fa-plus-circle {
display: block;
}
ul li {
width: 0;
height: 0;
.night-order {
opacity: 0;
}
2020-08-09 19:28:38 +00:00
.token {
border-width: 0;
}
2020-06-10 22:37:17 +00:00
}
2020-04-18 19:03:58 +00:00
}
}
2020-08-09 19:28:38 +00:00
#townsquare.public > .bluffs {
opacity: 0;
transform: scale(0.1);
}
2020-08-09 19:28:38 +00:00
.fabled ul li .token:before {
content: " ";
opacity: 0;
transition: opacity 250ms;
background-image: url("../assets/icons/x.png");
z-index: 2;
}
/**** Night reminders ****/
.night-order {
position: absolute;
width: 100%;
cursor: pointer;
opacity: 1;
transition: opacity 200ms;
display: flex;
top: 0;
align-items: center;
pointer-events: none;
&:after {
content: " ";
display: block;
padding-top: 100%;
}
#townsquare.public & {
opacity: 0;
pointer-events: none;
}
&:hover ~ .token .ability {
opacity: 0;
}
span {
display: flex;
position: absolute;
padding: 5px 10px 5px 30px;
width: 350px;
z-index: 25;
font-size: 70%;
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));
text-align: left;
align-items: center;
opacity: 0;
transition: opacity 200ms ease-in-out;
&:before {
transform: rotate(-90deg);
transform-origin: center top;
left: -98px;
top: 50%;
font-size: 100%;
position: absolute;
font-weight: bold;
text-align: center;
width: 200px;
}
&:after {
content: " ";
border: 10px solid transparent;
width: 0;
height: 0;
position: absolute;
}
}
&.first span {
right: 120%;
background: linear-gradient(
to right,
$townsfolk 0%,
rgba(0, 0, 0, 0.5) 20%
);
&:before {
content: "First Night";
}
&:after {
border-left-color: $townsfolk;
margin-left: 3px;
left: 100%;
}
}
&.other span {
left: 120%;
background: linear-gradient(to right, $demon 0%, rgba(0, 0, 0, 0.5) 20%);
&:before {
content: "Other Nights";
}
&:after {
right: 100%;
margin-right: 3px;
border-right-color: $demon;
}
}
em {
font-style: normal;
position: absolute;
width: 40px;
height: 40px;
border-radius: 50%;
border: 3px solid black;
filter: drop-shadow(0 0 6px rgba(0, 0, 0, 0.5));
font-weight: bold;
opacity: 1;
pointer-events: all;
transition: opacity 200ms;
display: flex;
justify-content: center;
align-items: center;
z-index: 3;
}
&.first em {
left: -10%;
background: linear-gradient(180deg, rgba(0, 0, 0, 1) 0%, $townsfolk 100%);
}
&.other em {
right: -10%;
background: linear-gradient(180deg, rgba(0, 0, 0, 1) 0%, $demon 100%);
}
em:hover + span {
opacity: 1;
}
// adjustment for fabled
.fabled &.first {
span {
right: auto;
left: 40px;
&:after {
left: auto;
right: 100%;
margin-left: 0;
margin-right: 3px;
border-left-color: transparent;
border-right-color: $townsfolk;
}
}
}
}
#townsquare:not(.spectator) .fabled ul li:hover .token:before {
2020-08-09 19:28:38 +00:00
opacity: 1;
}
2020-04-01 20:57:14 +00:00
</style>