Compare commits
12
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dd4a938632 | ||
|
|
d8aa87cf97 | ||
|
|
79e28b5006 | ||
|
|
e1784dffca | ||
|
|
39e4855b91 | ||
|
|
c30d23e45f | ||
|
|
c3bb7d555c | ||
|
|
d0ebd3746e | ||
|
|
f0387cebc8 | ||
|
|
a330806afe | ||
|
|
25672130cd | ||
|
|
a6490fc180 |
@@ -1,10 +1,46 @@
|
|||||||
{
|
{
|
||||||
|
"prepare":{
|
||||||
|
"title":"Prepare",
|
||||||
|
"description":"Repeat a champion's effects"
|
||||||
|
},
|
||||||
|
"stun":{
|
||||||
|
"title":"Stun",
|
||||||
|
"description":"Stun (kill) an ennemy's champion"
|
||||||
|
},
|
||||||
"sacrifice":{
|
"sacrifice":{
|
||||||
"title": "Sacrifice",
|
"title": "Sacrifice",
|
||||||
"description": "Destroy a card, forever"
|
"description": "Destroy a card, forever"
|
||||||
},
|
},
|
||||||
|
"discard":{
|
||||||
|
"title":"Discard",
|
||||||
|
"description":"Oops ! You must put a card in your discard..."
|
||||||
|
},
|
||||||
"make_discard":{
|
"make_discard":{
|
||||||
"title": "Make Discard",
|
"title": "Make Discard",
|
||||||
"description": "Give a fuck to your opponent"
|
"description": "Give a fuck to your opponent"
|
||||||
|
},
|
||||||
|
"restack_discarded_champion":{
|
||||||
|
"title":"Restack Discarded Champion",
|
||||||
|
"description":"Take a champion from your discard and put it on top of your stack"
|
||||||
|
},
|
||||||
|
"restack_discarded_card":{
|
||||||
|
"title":"Restack Discarded Card",
|
||||||
|
"description":"Take a card from your discard and put it on top of your stack"
|
||||||
|
},
|
||||||
|
"stack_next_action_bought":{
|
||||||
|
"title":"Stack Next Action Bought",
|
||||||
|
"description":"When you buy an action, you may put it on top of your stack"
|
||||||
|
},
|
||||||
|
"stack_next_card_bought":{
|
||||||
|
"title":"Stack Next Card Bought",
|
||||||
|
"description":"When you buy a card, you may put it on top of your stack"
|
||||||
|
},
|
||||||
|
"play_next_card_bought":{
|
||||||
|
"title":"Play Next Card Bought",
|
||||||
|
"description":"When you buy a card, you may put it in play"
|
||||||
|
},
|
||||||
|
"draw_and_discard":{
|
||||||
|
"title":"Draw And Discard",
|
||||||
|
"description":"You may draw a card, then discard a card"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -54,7 +54,7 @@ const shuffleAnimationSpeed = computed(
|
|||||||
() => settingsStore.animationSpeed * 2 + "ms"
|
() => settingsStore.animationSpeed * 2 + "ms"
|
||||||
);
|
);
|
||||||
|
|
||||||
function populateContainer() {}
|
function populateContainer() { }
|
||||||
|
|
||||||
// const rotate = ref(false);
|
// const rotate = ref(false);
|
||||||
// async function shuffleContainer() {
|
// async function shuffleContainer() {
|
||||||
@@ -64,7 +64,7 @@ function populateContainer() {}
|
|||||||
// await delay(settingsStore.animationSpeed * 2);
|
// await delay(settingsStore.animationSpeed * 2);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
function getCardsPosition(cards: string) {}
|
function getCardsPosition(cards: string) { }
|
||||||
|
|
||||||
const animationCallbacks = ref<Array<() => void>>([]);
|
const animationCallbacks = ref<Array<() => void>>([]);
|
||||||
|
|
||||||
@@ -132,41 +132,23 @@ function discardCardClick(card: Card) {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div class="cards_container" :class="{ wrapped, rotate: container.shuffling }">
|
||||||
class="cards_container"
|
|
||||||
:class="{ wrapped, rotate: container.shuffling }"
|
|
||||||
>
|
|
||||||
<TransitionGroup name="list">
|
<TransitionGroup name="list">
|
||||||
<GameCard
|
<GameCard @click="$emit('cardClick', c._id)" @effectClick="$emit('effectClick', c._id, $event)"
|
||||||
@click="$emit('cardClick', c._id)"
|
v-for="(c, i) in cards" :cardId="c?.cardId" :uuid="c._id" :wrapped="wrapped" :key="c?._id || i" :locked="locked ||
|
||||||
@effectClick="$emit('effectClick', c._id, $event)"
|
|
||||||
v-for="(c, i) in cards"
|
|
||||||
:cardId="c?.cardId"
|
|
||||||
:uuid="c._id"
|
|
||||||
:wrapped="wrapped"
|
|
||||||
:key="c?._id || i"
|
|
||||||
:locked="
|
|
||||||
locked ||
|
|
||||||
!playingTurn ||
|
!playingTurn ||
|
||||||
playingTurn?.cardsLocked.includes(c._id.toString())
|
playingTurn?.cardsLocked.includes(c._id.toString())
|
||||||
"
|
" :used_effects_indexes="c?.effects?.reduce((prev, e, i) => {
|
||||||
:used_effects_indexes="c?.effects?.reduce( (prev,e, i)=>{
|
if (playingTurn?.lockedEffects.includes(e._id)) {
|
||||||
if(playingTurn?.lockedEffects.includes(e._id)){
|
prev.push(i)
|
||||||
prev.push(i)
|
}
|
||||||
}
|
return prev
|
||||||
return prev
|
}, [] as number[])" :noEffects="noEffects" :discardable="discardable">
|
||||||
},[] as number[])"
|
|
||||||
:noEffects="noEffects"
|
|
||||||
:discardable="discardable"
|
|
||||||
>
|
|
||||||
<template v-for="t in tokens">
|
<template v-for="t in tokens">
|
||||||
<GameToken
|
<GameToken :token="t" @useToken="tokenClick(t, c)" v-if="
|
||||||
:token="t"
|
((t.effect == CardEffects.SACRIFICE &&
|
||||||
@useToken="tokenClick(t, c)"
|
playingTurn &&
|
||||||
v-if="
|
!playingTurn?.cardsLocked.includes(c._id.toString())) ||
|
||||||
(t.effect == CardEffects.SACRIFICE &&
|
|
||||||
playingTurn &&
|
|
||||||
!playingTurn?.cardsLocked.includes(c._id.toString())) ||
|
|
||||||
(t.effect == CardEffects.PREPARE &&
|
(t.effect == CardEffects.PREPARE &&
|
||||||
c.cardType == CardType.CHAMPION) ||
|
c.cardType == CardType.CHAMPION) ||
|
||||||
(t.effect == CardEffects.STACK_NEXT_ACTION_BOUGHT &&
|
(t.effect == CardEffects.STACK_NEXT_ACTION_BOUGHT &&
|
||||||
@@ -180,24 +162,16 @@ function discardCardClick(card: Card) {
|
|||||||
(t.effect == CardEffects.RESTACK_DISCARDED_ACTION &&
|
(t.effect == CardEffects.RESTACK_DISCARDED_ACTION &&
|
||||||
c.cardType == CardType.ACTION) ||
|
c.cardType == CardType.ACTION) ||
|
||||||
(t.effect == CardEffects.RESTACK_DISCARDED_CHAMPION &&
|
(t.effect == CardEffects.RESTACK_DISCARDED_CHAMPION &&
|
||||||
c.cardType == CardType.CHAMPION)
|
c.cardType == CardType.CHAMPION)) && ((wrapped && i == (cards.length - 1)) || !wrapped)
|
||||||
"
|
"></GameToken>
|
||||||
></GameToken>
|
|
||||||
</template>
|
</template>
|
||||||
<button
|
<button v-if="championsKillable && c.cardType == CardType.CHAMPION" @click.stop="damageChampionClick(c)"
|
||||||
v-if="championsKillable && c.cardType == CardType.CHAMPION"
|
@mousedown.left.stop="">
|
||||||
@click.stop="damageChampionClick(c)"
|
|
||||||
@mousedown.left.stop=""
|
|
||||||
>
|
|
||||||
Damage
|
Damage
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button v-if="
|
||||||
v-if="
|
discardable && !playingTurn?.cardsLocked.includes(c._id.toString())
|
||||||
discardable && !playingTurn?.cardsLocked.includes(c._id.toString())
|
" @mousedown.left.stop="" @click.stop="discardCardClick(c)">
|
||||||
"
|
|
||||||
@mousedown.left.stop=""
|
|
||||||
@click.stop="discardCardClick(c)"
|
|
||||||
>
|
|
||||||
Discard
|
Discard
|
||||||
</button>
|
</button>
|
||||||
</GameCard>
|
</GameCard>
|
||||||
@@ -255,7 +229,7 @@ function discardCardClick(card: Card) {
|
|||||||
max-height: 10px;
|
max-height: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.empty > .card_image {
|
.empty>.card_image {
|
||||||
filter: brightness(0.5);
|
filter: brightness(0.5);
|
||||||
max-height: 250px;
|
max-height: 250px;
|
||||||
}
|
}
|
||||||
@@ -269,6 +243,7 @@ use * use[data-effect-id="0"] {
|
|||||||
.cards_container .card #background rect:first-child {
|
.cards_container .card #background rect:first-child {
|
||||||
stroke-width: 0;
|
stroke-width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cards_container .card.wrapped #background rect:first-child {
|
.cards_container .card.wrapped #background rect:first-child {
|
||||||
stroke-width: 1px;
|
stroke-width: 1px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,15 +20,22 @@ const props = defineProps<Props>();
|
|||||||
|
|
||||||
const isVisible = ref(false);
|
const isVisible = ref(false);
|
||||||
|
|
||||||
const discardTokens = computed(() =>
|
const discardTokens = computed(() => {
|
||||||
props.game.currentTurn.tokens.filter((t) =>
|
// Only check for tokens if it's current player's turn
|
||||||
[
|
const team = props.game.teams.find((t) => t._id == props.game.currentTurn.currentTeam);
|
||||||
CardEffects.RESTACK_DISCARDED_ACTION,
|
if (team?.players.some(p => p._id == props.player._id)) {
|
||||||
CardEffects.RESTACK_DISCARDED_CARD,
|
return props.game.currentTurn.tokens.filter((t) =>
|
||||||
CardEffects.RESTACK_DISCARDED_CHAMPION,
|
[
|
||||||
CardEffects.SACRIFICE,
|
CardEffects.RESTACK_DISCARDED_ACTION,
|
||||||
].includes(t.effect)
|
CardEffects.RESTACK_DISCARDED_CARD,
|
||||||
)
|
CardEffects.RESTACK_DISCARDED_CHAMPION,
|
||||||
|
CardEffects.SACRIFICE,
|
||||||
|
].includes(t.effect)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
function tokenClick({ card, token }: { card: Card; token: Effect }) {
|
function tokenClick({ card, token }: { card: Card; token: Effect }) {
|
||||||
@@ -45,43 +52,21 @@ function openDiscard() {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div id="discard">
|
<div id="discard">
|
||||||
<GameCardGrouped
|
<GameCardGrouped @cardClick="openDiscard" :container="player.discard" :wrapped="true" :no-effects="true">
|
||||||
@cardClick="openDiscard"
|
|
||||||
:container="player.discard"
|
|
||||||
:wrapped="true"
|
|
||||||
:no-effects="true"
|
|
||||||
>
|
|
||||||
</GameCardGrouped>
|
</GameCardGrouped>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div class="discard-animations discard-background"
|
||||||
class="discard-animations discard-background"
|
:class="{ visible: isVisible, fullscreen: settingsStore.discardFullscreen }" @click.stop="isVisible = false"></div>
|
||||||
:class="{ visible: isVisible, fullscreen: settingsStore.discardFullscreen }"
|
<div class="discard-animations discard-menu"
|
||||||
@click.stop="isVisible = false"
|
:class="{ visible: isVisible, fullscreen: settingsStore.discardFullscreen }" @click.stop="isVisible = false">
|
||||||
></div>
|
|
||||||
<div
|
|
||||||
class="discard-animations discard-menu"
|
|
||||||
:class="{ visible: isVisible, fullscreen: settingsStore.discardFullscreen }"
|
|
||||||
@click.stop="isVisible = false"
|
|
||||||
>
|
|
||||||
<span>Discard of {{ player.user.username }}</span>
|
<span>Discard of {{ player.user.username }}</span>
|
||||||
<button
|
<button class="discard-fullscreen-btn" @click.stop="
|
||||||
class="discard-fullscreen-btn"
|
settingsStore.discardFullscreen = !settingsStore.discardFullscreen
|
||||||
@click.stop="
|
">
|
||||||
settingsStore.discardFullscreen = !settingsStore.discardFullscreen
|
|
||||||
"
|
|
||||||
>
|
|
||||||
TOGGLE FULLSCREEN
|
TOGGLE FULLSCREEN
|
||||||
</button>
|
</button>
|
||||||
<GameCardGrouped
|
<GameCardGrouped :container="player.discard" :wrapped="false" :hidden="false" :tokens="discardTokens"
|
||||||
:container="player.discard"
|
:noEffects="true" :playingTurn="game.currentTurn" :locked="true" @tokenClick="tokenClick"></GameCardGrouped>
|
||||||
:wrapped="false"
|
|
||||||
:hidden="false"
|
|
||||||
:tokens="discardTokens"
|
|
||||||
:noEffects="true"
|
|
||||||
:playingTurn="game.currentTurn"
|
|
||||||
:locked="true"
|
|
||||||
@tokenClick="tokenClick"
|
|
||||||
></GameCardGrouped>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -89,6 +74,7 @@ function openDiscard() {
|
|||||||
span {
|
span {
|
||||||
background: white;
|
background: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.discard-fullscreen-btn {
|
.discard-fullscreen-btn {
|
||||||
pointer-events: all;
|
pointer-events: all;
|
||||||
}
|
}
|
||||||
@@ -96,6 +82,7 @@ span {
|
|||||||
.discard-animations {
|
.discard-animations {
|
||||||
transition: 0.3s all var(--animation-curve);
|
transition: 0.3s all var(--animation-curve);
|
||||||
}
|
}
|
||||||
|
|
||||||
.discard-background {
|
.discard-background {
|
||||||
transition: 0.3s all linear;
|
transition: 0.3s all linear;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
@@ -145,7 +132,7 @@ span {
|
|||||||
left: 0%;
|
left: 0%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.discard-menu > .cards_container {
|
.discard-menu>.cards_container {
|
||||||
pointer-events: all;
|
pointer-events: all;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
padding: 30px;
|
padding: 30px;
|
||||||
@@ -154,7 +141,7 @@ span {
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.discard-menu.fullscreen > .cards_container {
|
.discard-menu.fullscreen>.cards_container {
|
||||||
max-width: 50%;
|
max-width: 50%;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -52,12 +52,19 @@ const isSelf = computed(
|
|||||||
);
|
);
|
||||||
const isSelfTurn = computed(() => isSelf && isPlayerTurn);
|
const isSelfTurn = computed(() => isSelf && isPlayerTurn);
|
||||||
|
|
||||||
const cardTokens = computed(() =>
|
const cardTokens = computed(() => {
|
||||||
props.game.currentTurn.tokens.filter(
|
if (!isPlayerTurn.value) {
|
||||||
(t) =>
|
return props.game.currentTurn.tokens.filter((t) => t.effect == CardEffects.STUN);
|
||||||
[CardEffects.PREPARE, CardEffects.STUN].includes(t.effect) ||
|
}
|
||||||
(CardEffects.SACRIFICE == t.effect && isSelf)
|
else {
|
||||||
)
|
return props.game.currentTurn.tokens.filter(
|
||||||
|
(t) =>
|
||||||
|
[CardEffects.PREPARE, CardEffects.SACRIFICE].includes(t.effect)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const warningText = ref("Effets restants!");
|
const warningText = ref("Effets restants!");
|
||||||
@@ -171,21 +178,10 @@ function discardCardClick(card: Card) {
|
|||||||
</div> -->
|
</div> -->
|
||||||
<!-- <br /> -->
|
<!-- <br /> -->
|
||||||
|
|
||||||
<GameCardGrouped
|
<GameCardGrouped :container="player.board" :wrapped="false" :playingTurn="props.game.currentTurn"
|
||||||
:container="player.board"
|
@cardClick="boardCardClick" @effectClick="effectClick" :tokens="cardTokens" @tokenClick="tokenClick"
|
||||||
:wrapped="false"
|
:championsKillable="!isSelf && isSelfTurn.value" :discardable="(player.fuckUMarkers > 0 || player.discardMarkers > 0) && isSelf
|
||||||
:playingTurn="props.game.currentTurn"
|
" @damageChampionClick="damageChampionClick" @discardCardClick="discardCardClick">
|
||||||
@cardClick="boardCardClick"
|
|
||||||
@effectClick="effectClick"
|
|
||||||
:tokens="cardTokens"
|
|
||||||
@tokenClick="tokenClick"
|
|
||||||
:championsKillable="!isSelf && isSelfTurn.value"
|
|
||||||
:discardable="
|
|
||||||
(player.fuckUMarkers > 0 || player.discardMarkers > 0) && isSelf
|
|
||||||
"
|
|
||||||
@damageChampionClick="damageChampionClick"
|
|
||||||
@discardCardClick="discardCardClick"
|
|
||||||
>
|
|
||||||
</GameCardGrouped>
|
</GameCardGrouped>
|
||||||
<br />
|
<br />
|
||||||
<!-- <div class="cards_container"> -->
|
<!-- <div class="cards_container"> -->
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { useAuthStore } from "#imports";
|
import { useAuthStore } from "#imports";
|
||||||
|
|
||||||
|
const validPaths = ["/login", "/lobby", "/rules", "/test"];
|
||||||
export default defineNuxtRouteMiddleware(async (to, from) => {
|
export default defineNuxtRouteMiddleware(async (to, from) => {
|
||||||
const authStore = useAuthStore();
|
const authStore = useAuthStore();
|
||||||
const config = useRuntimeConfig();
|
const config = useRuntimeConfig();
|
||||||
@@ -37,17 +38,13 @@ export default defineNuxtRouteMiddleware(async (to, from) => {
|
|||||||
if (to.path.startsWith("/game")) {
|
if (to.path.startsWith("/game")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (to.path == "/login") {
|
if (to.path == "/logout") {
|
||||||
|
// const session = useCookie("heron.session");
|
||||||
|
// session.value = null;
|
||||||
|
// return navigateTo("/lobby");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (to.path == "/lobby") {
|
if (validPaths.includes(to.path)) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (to.path == "/rules") {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (to.path == "/test") {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// In a real app you would probably not redirect every route to `/`
|
// In a real app you would probably not redirect every route to `/`
|
||||||
|
|||||||
+7
-2
@@ -188,10 +188,15 @@ export const handlers: {
|
|||||||
consumeEffect: async (data: any) => {
|
consumeEffect: async (data: any) => {
|
||||||
console.warn("consumeEffect not implemented");
|
console.warn("consumeEffect not implemented");
|
||||||
},
|
},
|
||||||
endGame: async () => {
|
endGame: async (data: any, { game }) => {
|
||||||
alert("game ended");
|
const winningPlayers = game.teams
|
||||||
|
.find((t) => t._id == data.winner)
|
||||||
|
?.players.map((p) => p.user.username)
|
||||||
|
.join(", ");
|
||||||
|
alert(`game ended. Winner : ${winningPlayers}`);
|
||||||
},
|
},
|
||||||
delete: async () => {
|
delete: async () => {
|
||||||
alert("game deleted");
|
alert("game deleted");
|
||||||
|
navigateTo("/lobby");
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
Generated
+4284
-4721
File diff suppressed because it is too large
Load Diff
+6
-4
@@ -4,8 +4,10 @@
|
|||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"cards-gen": "sh -c 'docker run --rm --pull=always -v ./assets/images/cards/heron-svg:/app/output/heron git.legonzaur.fr/heronfief/cards-gen:main' && sudo chown -R $USER:$USER ./assets/images/cards/heron-svg",
|
"cards-gen": "sh -c 'docker run --rm --pull=always -v ./assets/images/cards/heron-svg:/app/output/heron git.legonzaur.fr/heronfief/cards-gen:main' && sudo chown -R $USER:$USER ./assets/images/cards/heron-svg",
|
||||||
"pull-images": "sh -c 'docker run --rm --pull=always -v ./public/img:/repo/images/skins git.legonzaur.fr/heronfief/cards-gen:main cp -r img/skins/ /repo/images/skins' && sudo chown -R $USER:$USER ./public/",
|
"tokens-gen": "sh -c 'docker run --rm --pull=always -v ./assets/images/tokens:/app/output/heron git.legonzaur.fr/heronfief/tokens-gen:main' && sudo chown -R $USER:$USER ./assets/images/tokens",
|
||||||
"fetch": "npm run cards-gen && npm run pull-images",
|
"pull-token-images": "sh -c 'docker run --rm --pull=always -v ./public/img:/repo/images/tokens git.legonzaur.fr/heronfief/tokens-gen:main cp -r img/icon/ /repo/images/tokens' && sudo chown -R $USER:$USER ./public/",
|
||||||
|
"pull-card-images": "sh -c 'docker run --rm --pull=always -v ./public/img:/repo/images/skins git.legonzaur.fr/heronfief/cards-gen:main cp -r img/skins/ /repo/images/skins' && sudo chown -R $USER:$USER ./public/",
|
||||||
|
"fetch": "npm run cards-gen && npm run pull-card-images && npm run tokens-gen && npm run pull-token-images",
|
||||||
"build": "nuxt build",
|
"build": "nuxt build",
|
||||||
"dev": "nuxt dev",
|
"dev": "nuxt dev",
|
||||||
"generate": "nuxt generate",
|
"generate": "nuxt generate",
|
||||||
@@ -15,12 +17,12 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@pinia/nuxt": "^0.5.1",
|
"@pinia/nuxt": "^0.5.1",
|
||||||
"gsap": "^3.12.5",
|
"gsap": "^3.12.5",
|
||||||
"nuxt": "^3.11.2",
|
|
||||||
"pinia": "^2.1.7",
|
"pinia": "^2.1.7",
|
||||||
"vue": "^3.4.21",
|
"vue": "^3.4.21",
|
||||||
"vue-router": "^4.3.0"
|
"vue-router": "^4.3.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@pinia-plugin-persistedstate/nuxt": "^1.2.0"
|
"@pinia-plugin-persistedstate/nuxt": "^1.2.0",
|
||||||
|
"nuxt": "^3.14.1592"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+26
-78
@@ -10,7 +10,6 @@ import {
|
|||||||
leaveGame,
|
leaveGame,
|
||||||
surrender,
|
surrender,
|
||||||
} from "~/netcode";
|
} from "~/netcode";
|
||||||
import { delay } from "~/netcode/events";
|
|
||||||
import {
|
import {
|
||||||
type Container,
|
type Container,
|
||||||
type Effect,
|
type Effect,
|
||||||
@@ -28,7 +27,6 @@ const gameId = route.query.id;
|
|||||||
|
|
||||||
const {
|
const {
|
||||||
data: game,
|
data: game,
|
||||||
pending,
|
|
||||||
error,
|
error,
|
||||||
refresh,
|
refresh,
|
||||||
execute,
|
execute,
|
||||||
@@ -184,80 +182,43 @@ onUnmounted(() => {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div @contextmenu.prevent="false" id="game_board">
|
<div @contextmenu.prevent="false" id="game_board">
|
||||||
<AnimatedBackground
|
<AnimatedBackground @ready="loaded = true" :isTurn="isTurn ?? false"></AnimatedBackground>
|
||||||
@ready="loaded = true"
|
|
||||||
:isTurn="isTurn ?? false"
|
|
||||||
></AnimatedBackground>
|
|
||||||
<ClientOnly>
|
<ClientOnly>
|
||||||
<template v-if="game && focusedPlayer && playerList">
|
<template v-if="game && focusedPlayer && playerList">
|
||||||
<!-- <Transition name="slide-left" mode="out-in"> -->
|
<!-- <Transition name="slide-left" mode="out-in"> -->
|
||||||
<div id="stack_discard" :key="focusedPlayer?._id">
|
<div id="stack_discard" :key="focusedPlayer?._id">
|
||||||
<div id="stack">
|
<div id="stack">
|
||||||
<GameCardGrouped
|
<GameCardGrouped :container="focusedPlayer.stack" :wrapped="true" :hidden="true">
|
||||||
:container="focusedPlayer.stack"
|
|
||||||
:wrapped="true"
|
|
||||||
:hidden="true"
|
|
||||||
>
|
|
||||||
</GameCardGrouped>
|
</GameCardGrouped>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<GameOverlayDiscard
|
<GameOverlayDiscard :game="game" :player="focusedPlayer"></GameOverlayDiscard>
|
||||||
:game="game"
|
|
||||||
:player="focusedPlayer"
|
|
||||||
></GameOverlayDiscard>
|
|
||||||
</div>
|
</div>
|
||||||
<!-- </Transition> -->
|
<!-- </Transition> -->
|
||||||
|
|
||||||
<GameMarket
|
<GameMarket :game="game" :market="game.market" :fire_gems="game.fireGems" :marketStack="game.marketStack">
|
||||||
:game="game"
|
|
||||||
:market="game.market"
|
|
||||||
:fire_gems="game.fireGems"
|
|
||||||
:marketStack="game.marketStack"
|
|
||||||
>
|
|
||||||
</GameMarket>
|
</GameMarket>
|
||||||
<div>
|
<div>
|
||||||
<GameToken
|
<GameToken :token="t" v-for="t in game.currentTurn.tokens" @useToken="useTokenClick"></GameToken>
|
||||||
:token="t"
|
|
||||||
v-for="t in game.currentTurn.tokens"
|
|
||||||
@useToken="useTokenClick"
|
|
||||||
></GameToken>
|
|
||||||
</div>
|
</div>
|
||||||
<div id="player_list_container">
|
<div id="player_list_container">
|
||||||
<div id="player_list">
|
<div id="player_list">
|
||||||
<GamePlayerListElement
|
<GamePlayerListElement v-for="p in playerList" :player="p" :game="game" @click="focusPlayer(p)"
|
||||||
v-for="p in playerList"
|
:focused="focusedPlayer == p" :is-self-turn="isTurn" :self="selfPlayer == p">
|
||||||
:player="p"
|
|
||||||
:game="game"
|
|
||||||
@click="focusPlayer(p)"
|
|
||||||
:focused="focusedPlayer == p"
|
|
||||||
:is-self-turn="isTurn"
|
|
||||||
:self="selfPlayer == p"
|
|
||||||
>
|
|
||||||
</GamePlayerListElement>
|
</GamePlayerListElement>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="current_player">
|
<div id="current_player">
|
||||||
<Transition name="slide-left" mode="out-in">
|
<Transition name="slide-left" mode="out-in">
|
||||||
<GamePlayerSlot
|
<GamePlayerSlot v-if="focusedPlayer" :player="focusedPlayer" :game="game" :key="focusedPlayer._id">
|
||||||
v-if="focusedPlayer"
|
</GamePlayerSlot>
|
||||||
:player="focusedPlayer"
|
|
||||||
:game="game"
|
|
||||||
:key="focusedPlayer._id"
|
|
||||||
></GamePlayerSlot>
|
|
||||||
</Transition>
|
</Transition>
|
||||||
</div>
|
</div>
|
||||||
<GameModalResultDialog
|
<GameModalResultDialog :isVisible="showResults" :won="isWinner" :players="playerList"
|
||||||
:isVisible="showResults"
|
@close="showResults = false">
|
||||||
:won="isWinner"
|
|
||||||
:players="playerList"
|
|
||||||
@close="showResults = false"
|
|
||||||
>
|
|
||||||
</GameModalResultDialog>
|
</GameModalResultDialog>
|
||||||
<GamePlayerSelf
|
<GamePlayerSelf v-if="selfPlayer" :container="selfPlayer.hand"></GamePlayerSelf>
|
||||||
v-if="selfPlayer"
|
|
||||||
:container="selfPlayer.hand"
|
|
||||||
></GamePlayerSelf>
|
|
||||||
</template>
|
</template>
|
||||||
</ClientOnly>
|
</ClientOnly>
|
||||||
|
|
||||||
@@ -265,51 +226,37 @@ onUnmounted(() => {
|
|||||||
<footer>
|
<footer>
|
||||||
<div>
|
<div>
|
||||||
<GameModalOptionsDialog></GameModalOptionsDialog>
|
<GameModalOptionsDialog></GameModalOptionsDialog>
|
||||||
<GameModalConfigureDialog
|
<ClientOnly>
|
||||||
v-if="game && game.owner.userId == authStore.selfUser.userId"
|
<GameModalConfigureDialog v-if="game && game.owner.userId == authStore.selfUser.userId" :game="game">
|
||||||
:game="game"
|
</GameModalConfigureDialog>
|
||||||
></GameModalConfigureDialog>
|
</ClientOnly>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ClientOnly>
|
<ClientOnly v-if="game">
|
||||||
<div id="turn_buttons" v-if="game">
|
<div id="turn_buttons">
|
||||||
<template v-if="game.started">
|
<template v-if="game.started">
|
||||||
<button
|
<button id="end_turn" class="end_turn_button turn_icon" :class="{ hidden: !isTurn }"
|
||||||
id="end_turn"
|
@click="endTurn(game._id)" v-if="isTurn">
|
||||||
class="end_turn_button turn_icon"
|
|
||||||
:class="{ hidden: !isTurn }"
|
|
||||||
@click="endTurn(game._id)"
|
|
||||||
v-if="isTurn"
|
|
||||||
>
|
|
||||||
END TURN
|
END TURN
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="authStore.logged">
|
<template v-else-if="authStore.logged">
|
||||||
<template v-if="game.owner.userId == authStore.selfUser.userId">
|
<template v-if="game.owner.userId == authStore.selfUser.userId">
|
||||||
<button
|
<button class="end_turn_button turn_icon" @click="startGame(game._id)">
|
||||||
class="end_turn_button turn_icon"
|
|
||||||
@click="startGame(game._id)"
|
|
||||||
>
|
|
||||||
Start game
|
Start game
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<button
|
<button class="end_turn_button turn_icon" @click="joinGame(game._id)" v-else-if="!selfPlayer">
|
||||||
class="end_turn_button turn_icon"
|
|
||||||
@click="joinGame(game._id)"
|
|
||||||
v-else-if="!selfPlayer"
|
|
||||||
>
|
|
||||||
Join game
|
Join game
|
||||||
</button>
|
</button>
|
||||||
<button v-else @click="leaveGame(game._id)">Leave game</button>
|
<button v-else @click="leaveGame(game._id)">Leave game</button>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<button
|
<button v-if="game.started && selfPlayer && game.owner._id != selfPlayer.user._id" class="red"
|
||||||
v-if="game && game.started && selfPlayer"
|
@click="surrender(game._id)">
|
||||||
class="red"
|
|
||||||
@click="surrender(game._id)"
|
|
||||||
>
|
|
||||||
Surrender
|
Surrender
|
||||||
</button>
|
</button>
|
||||||
<button @click="navigateTo('/lobby')">Return to lobby</button>
|
<button @click="navigateTo('/lobby')">Return to lobby</button>
|
||||||
@@ -329,6 +276,7 @@ footer {
|
|||||||
/* background: red; */
|
/* background: red; */
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
|
||||||
#game_status {
|
#game_status {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
|
|||||||
+5
-1
@@ -74,10 +74,14 @@ onUnmounted(() => {
|
|||||||
<div class="background">
|
<div class="background">
|
||||||
<header>
|
<header>
|
||||||
<ClientOnly>
|
<ClientOnly>
|
||||||
|
<template v-if="authStore.logged">
|
||||||
<GamePlayerIcon
|
<GamePlayerIcon
|
||||||
v-if="authStore.logged"
|
|
||||||
:user="(authStore.selfUser as User)"
|
:user="(authStore.selfUser as User)"
|
||||||
/>
|
/>
|
||||||
|
<button @click="navigateTo('/logout')">Logout</button>
|
||||||
|
</template>
|
||||||
|
|
||||||
<button v-else @click="navigateTo('/login')">Login</button>
|
<button v-else @click="navigateTo('/login')">Login</button>
|
||||||
</ClientOnly>
|
</ClientOnly>
|
||||||
</header>
|
</header>
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
const route = useRoute();
|
||||||
|
const config = useRuntimeConfig();
|
||||||
|
|
||||||
|
const code = route.query.code;
|
||||||
|
|
||||||
|
navigateTo(config.public.endpoint + "/logout", { external: true });
|
||||||
|
</script>
|
||||||
@@ -4,7 +4,7 @@ export const cards = {} as Record<string, Component>;
|
|||||||
export const tokens = {} as Record<string, Component>;
|
export const tokens = {} as Record<string, Component>;
|
||||||
|
|
||||||
export async function compileCards() {
|
export async function compileCards() {
|
||||||
const svgs = import.meta.glob("@/assets/images/cards/heron-svg/*.svg", {
|
const svgs = import.meta.glob("./assets/images/cards/heron-svg/*.svg", {
|
||||||
eager: true,
|
eager: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -64,7 +64,7 @@ export async function compileCards() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function compileTokens() {
|
export async function compileTokens() {
|
||||||
const svgs = import.meta.glob("@/assets/images/tokens/*.svg", {
|
const svgs = import.meta.glob("./assets/images/tokens/*.svg", {
|
||||||
eager: true,
|
eager: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user