finished adding night reminders to fabled

This commit is contained in:
Steffen 2020-11-30 22:04:21 +01:00
parent 02d7002e34
commit f10ff968a6
5 changed files with 206 additions and 142 deletions

View File

@ -148,10 +148,13 @@ body {
body {
font-size: 1.1em;
}
.player .night em {
.night-order em {
width: 30px;
height: 30px;
}
.fabled .night-order.first span {
left: 30px;
}
}
// Medium devices (tablets, less than 992px)
@ -163,10 +166,13 @@ body {
#controls svg {
font-size: 20px;
}
.player .night em {
.night-order em {
width: 20px;
height: 20px;
}
.fabled .night-order.first span {
left: 20px;
}
#townsquare {
padding: 10px;
}

View File

@ -18,7 +18,7 @@
<div class="life" @click="toggleStatus()"></div>
<div
class="night first"
class="night-order first"
v-if="nightOrder.get(player).first && grimoire.isNightOrder"
>
<em>{{ nightOrder.get(player).first }}.</em>
@ -27,7 +27,7 @@
}}</span>
</div>
<div
class="night other"
class="night-order other"
v-if="nightOrder.get(player).other && grimoire.isNightOrder"
>
<em>{{ nightOrder.get(player).other }}.</em>
@ -676,137 +676,11 @@ li.move:not(.from) .player .overlay svg.move {
}
/**** Night reminders ****/
.player .night {
position: absolute;
width: 100%;
z-index: 2;
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;
}
&.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;
}
#app.screenshot & {
display: none;
}
.player .night-order {
z-index: 3;
}
.player.dead .night em {
.player.dead .night-order em {
color: #ddd;
background: linear-gradient(180deg, rgba(0, 0, 0, 1) 0%, gray 100%);
}

View File

@ -56,11 +56,29 @@
</h3>
<ul>
<li
v-for="(fabledRole, index) in fabled"
v-for="(role, index) in fabled"
:key="index"
@click="removeFabled(index)"
>
<Token :role="fabledRole"></Token>
<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>
</li>
</ul>
</div>
@ -71,7 +89,7 @@
</template>
<script>
import { mapState } from "vuex";
import { mapGetters, mapState } from "vuex";
import Player from "./Player";
import Token from "./Token";
import ReminderModal from "./modals/ReminderModal";
@ -85,6 +103,7 @@ export default {
ReminderModal
},
computed: {
...mapGetters({ nightOrder: "players/nightOrder" }),
...mapState(["grimoire", "roles", "session"]),
...mapState("players", ["players", "bluffs", "fabled"])
},
@ -194,6 +213,8 @@ export default {
</script>
<style lang="scss">
@import "../vars.scss";
#townsquare {
width: 100%;
height: 100%;
@ -288,7 +309,7 @@ export default {
.life,
.token,
.shroud,
.night {
.night-order {
transition-delay: ($i - 1) * 50ms;
}
@ -409,6 +430,9 @@ export default {
ul li {
width: 0;
height: 0;
.night-order {
opacity: 0;
}
.token {
border-width: 0;
}
@ -424,6 +448,153 @@ export default {
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;
}
#app.screenshot & {
display: none;
}
// 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 {
opacity: 1;
}

View File

@ -24,7 +24,7 @@ const getters = {
return Math.min(nonTravelers.length, 15);
},
// calculate a Map of player => night order
nightOrder({ players }) {
nightOrder({ players, fabled }) {
const firstNight = [0];
const otherNight = [0];
players.forEach(({ role }) => {
@ -35,6 +35,14 @@ const getters = {
otherNight.push(role.otherNight);
}
});
fabled.forEach(role => {
if (role.firstNight && !firstNight.includes(role.firstNight)) {
firstNight.push(role.firstNight);
}
if (role.otherNight && !otherNight.includes(role.otherNight)) {
otherNight.push(role.otherNight);
}
});
firstNight.sort((a, b) => a - b);
otherNight.sort((a, b) => a - b);
const nightOrder = new Map();
@ -43,6 +51,11 @@ const getters = {
const other = Math.max(otherNight.indexOf(player.role.otherNight), 0);
nightOrder.set(player, { first, other });
});
fabled.forEach(role => {
const first = Math.max(firstNight.indexOf(role.firstNight), 0);
const other = Math.max(otherNight.indexOf(role.otherNight), 0);
nightOrder.set(role, { first, other });
});
return nightOrder;
}
};

View File

@ -18,14 +18,14 @@ module.exports = store => {
}
if (localStorage.bluffs !== undefined) {
JSON.parse(localStorage.bluffs).forEach((role, index) => {
store.commit("setBluff", {
store.commit("players/setBluff", {
index,
role: store.state.roles.get(role) || {}
});
});
}
if (localStorage.fabled !== undefined) {
store.commit("setFabled", {
store.commit("players/setFabled", {
fabled: JSON.parse(localStorage.fabled).map(id =>
store.state.fabled.get(id)
)
@ -88,13 +88,13 @@ module.exports = store => {
localStorage.setItem("roles", JSON.stringify(payload));
}
break;
case "setBluff":
case "players/setBluff":
localStorage.setItem(
"bluffs",
JSON.stringify(state.players.bluffs.map(({ id }) => id))
);
break;
case "setFabled":
case "players/setFabled":
localStorage.setItem(
"fabled",
JSON.stringify(state.players.fabled.map(({ id }) => id))