Better cards stacks and discard view

This commit is contained in:
2024-05-01 15:41:57 +02:00
parent c5380ea89c
commit b56e11f509
6 changed files with 134 additions and 164 deletions
+28 -4
View File
@@ -5,9 +5,13 @@ import type { Card } from '~/netcode/Card';
export interface Props {
data: Card | null | undefined
locked?: boolean
wrapped?: boolean
}
const props = defineProps<Props>()
const props = withDefaults(defineProps<Props>(), {
wrapped: () => false,
})
const emit = defineEmits(["click"])
@@ -24,17 +28,23 @@ function contextmenu(e: MouseEvent) {
buttonsElement.value?.setAttribute("style", `top:${e.clientY + 10}px;left:${e.clientX + 10}px`)
rightClicked.value = true
}
const rotation = ref(0)
onBeforeUpdate(() => {
rotation.value = Math.random() > .5 ? 2 : -2
})
</script>
<template>
<div :class="`card ${Number(buttonsElement?.childElementCount) > 0 ? 'active' : ''}`" @contextmenu.prevent="false"
@click.left="cardClick" @click.right="contextmenu">
<div :class="`card ${Number(buttonsElement?.childElementCount) > 0 ? 'active' : ''} ${wrapped ? 'wrapped' : ''}`"
@contextmenu.prevent="false" @click.left="cardClick" @click.right="contextmenu"
:style="`rotate:${rotation}deg;`">
<img :class="`card_image ${rightClicked ? 'outlined' : ''} ${props.locked ? 'locked' : ''}`" v-if="props.data"
:src="'/cards/' + data?.card_id?.toString().padStart(3, '0') + '.png'">
<img :class="`card_image ${rightClicked ? 'outlined' : ''} ${props.locked ? 'locked' : ''}`" v-if="!props.data"
:src="'/cards/background.png'">
</div>
<div :class="rightClicked ? '' : 'hidden'" id="contextMenu" @click.self.prevent="rightClicked = false">
@@ -46,6 +56,12 @@ function contextmenu(e: MouseEvent) {
</template>
<style scoped>
.card {
transition: 0.025s rotate linear;
transition: max-width .125s linear;
max-width: 256px;
}
.card.active {
cursor: pointer
}
@@ -59,6 +75,14 @@ function contextmenu(e: MouseEvent) {
filter: brightness(0.5);
}
.card.wrapped {
max-width: 10px;
}
.card.wrapped:last-child {
max-width: 256px;
}
.card_image {
max-height: 250px;
}
+11 -13
View File
@@ -14,20 +14,18 @@ const unwrapped = ref(false)
</script>
<template>
{{ props.stack?.length }}
<input type="checkbox" v-model="unwrapped" />
<div class="cards_container">
<CardPreview v-if="!unwrapped && props.stack.length > 0" :data="props.stack.at(-1) ?? null">
<slot></slot>
</CardPreview>
<template v-if="unwrapped" v-for="c in props.stack">
<CardPreview :data="c">
<slot></slot>
</CardPreview>
</template>
<div>
<input type="checkbox" v-model="unwrapped" class="checkbox" />
<div class="cards_container">
<template v-if="props.stack.length > 0" v-for="c in props.stack">
<CardPreview :data="c" :wrapped="!unwrapped">
<slot></slot>
</CardPreview>
</template>
</div>
</div>
</template>
</template>
<style scoped></style>
+28 -25
View File
@@ -14,8 +14,29 @@ const isTurn = computed(() => goStore.self && goStore.game?.started && (goStore.
<div>
market_amount = {{ goStore.game?.market_stack?.length }}
<br>
market =
<div class="cards_container">
<CardSlot :stack="goStore.game?.gem_stack">
<template v-if="isTurn && goStore.game?.gem_stack.length && goStore.game?.gem_stack.length > 0">
<button @click="buy(goStore.game.gem_stack.at(-1)!)">
BUY
</button>
<button
@click="useEffect(goStore.self!.turn.effects_availables.find(e => (e.effect == CardEffects.PLAY_NEXT_CARD_BOUGHT) && e.usable)!, goStore.game.gem_stack.at(-1))"
:disabled="(goStore.self === undefined || goStore.game.gem_stack.at(-1)!.cost === undefined || (goStore.self?.turn.gold_reserve ?? 0) < goStore.game.gem_stack.at(-1)!.cost!) || !goStore.self!.turn.effects_availables.some(e => (e.effect == CardEffects.PLAY_NEXT_CARD_BOUGHT) && e.usable)">
BUY IN HAND</button>
<button
@click="useEffect(goStore.self!.turn.effects_availables.find(e => (e.effect == CardEffects.STACK_NEXT_CARD_BOUGHT) && e.usable)!, goStore.game.gem_stack.at(-1))"
:disabled="(goStore.self === undefined || goStore.game.gem_stack.at(-1)?.cost === undefined || (goStore.self?.turn.gold_reserve ?? 0) < (goStore.game.gem_stack.at(-1)?.cost ?? Infinity)) || !goStore.self!.turn.effects_availables.some(e => (e.effect == CardEffects.STACK_NEXT_CARD_BOUGHT) && e.usable)">
BUY IN STACK (generic)</button>
<!-- <button @click="buy_in_hand(props.game.gem_stack.at(-1))">
BUY IN HAND
</button>
<button @click="buy_on_stack(props.game.gem_stack.at(-1))">
BUY ON STACK
</button> -->
</template>
</CardSlot>
<div class="separator"></div>
<CardPreview :data="c" v-for="c in goStore.game?.market" @click="c && buy(c)">
<template v-if="isTurn && c">
<button @click="buy(c)"
@@ -34,31 +55,9 @@ const isTurn = computed(() => goStore.self && goStore.game?.started && (goStore.
BUY IN STACK (actions)</button>
</template>
</CardPreview>
</div>
<br>
gems =
<CardSlot :stack="goStore.game?.gem_stack">
<template v-if="isTurn && goStore.game?.gem_stack.length && goStore.game?.gem_stack.length > 0">
<button @click="buy(goStore.game.gem_stack.at(-1)!)">
BUY
</button>
<button
@click="useEffect(goStore.self!.turn.effects_availables.find(e => (e.effect == CardEffects.PLAY_NEXT_CARD_BOUGHT) && e.usable)!, goStore.game.gem_stack.at(-1))"
:disabled="(goStore.self === undefined || goStore.game.gem_stack.at(-1)!.cost === undefined || (goStore.self?.turn.gold_reserve ?? 0) < goStore.game.gem_stack.at(-1)!.cost!) || !goStore.self!.turn.effects_availables.some(e => (e.effect == CardEffects.PLAY_NEXT_CARD_BOUGHT) && e.usable)">
BUY IN HAND</button>
<button
@click="useEffect(goStore.self!.turn.effects_availables.find(e => (e.effect == CardEffects.STACK_NEXT_CARD_BOUGHT) && e.usable)!, goStore.game.gem_stack.at(-1))"
:disabled="(goStore.self === undefined || goStore.game.gem_stack.at(-1)?.cost === undefined || (goStore.self?.turn.gold_reserve ?? 0) < (goStore.game.gem_stack.at(-1)?.cost ?? Infinity)) || !goStore.self!.turn.effects_availables.some(e => (e.effect == CardEffects.STACK_NEXT_CARD_BOUGHT) && e.usable)">
BUY IN STACK (generic)</button>
<!-- <button @click="buy_in_hand(props.game.gem_stack.at(-1))">
BUY IN HAND
</button>
<button @click="buy_on_stack(props.game.gem_stack.at(-1))">
BUY ON STACK
</button> -->
</template>
</CardSlot>
</div>
<div>
<PlayerList>
@@ -70,7 +69,11 @@ const isTurn = computed(() => goStore.self && goStore.game?.started && (goStore.
<style>
.cards_container {
display: flex;
flex-direction: row;
flex-direction: row-reverse;
justify-content: center;
}
.separator {
margin-left: 100px;
}
</style>
+1 -1
View File
@@ -7,5 +7,5 @@ import goStore from '@/netcode';
<div v-for="[k, l] in goStore.players">
<PlayerSlot :player="l" v-if="l !== goStore.self" :key="k" />
</div>
<SelfView v-if="goStore.self" :player="goStore.self"></SelfView>
<SelfView v-if="goStore.self"></SelfView>
</template>
+4 -36
View File
@@ -63,8 +63,7 @@ const discard_unwrapped = ref(false)
</div>
<span>effects_availables = <div v-for=" e in props.player.turn.effects_availables ">
<button v-if="e && ![CardEffects.DAMAGE, CardEffects.GOLD, CardEffects.HEAL].includes(e.effect)"
@click="useEffect(e)" :disabled="!e.usable">
<button v-if="e" @click="useEffect(e)" :disabled="!e.usable">
{{ e.effect + ' ' + e.effect_type }}
</button>
@@ -112,46 +111,15 @@ const discard_unwrapped = ref(false)
</CardPreview>
</div>
stack =
<CardSlot :stack="props.player.stack_pile">
<!-- <button v-if="isSelf && isTurn" @click="draw">DRAW</button> -->
</CardSlot>
<br>
discard =
{{ props.player.discard_pile.length }}
<input type="checkbox" v-model="discard_unwrapped" />
<CardPreview v-if="!discard_unwrapped && props.player.discard_pile.length > 0"
:data="props.player.discard_pile.at(-1)">
<!-- <button v-if="isSelf && isTurn" @click="play_from_discard(props.player.discard_pile.at(-1))">DRAW</button>
<button v-if="isSelf && isTurn" @click="put_on_stack_from_discard(props.player.discard_pile.at(-1))">PUT ON
STACK</button> -->
<CardSlot :stack="props.player.discard_pile">
<button v-if="isSelf && isTurn"
:disabled="!goStore.self || !props.player.discard_pile.at(-1) || !props.player.turn.effects_availables.some(e => (e.effect == CardEffects.SACRIFICE) && e.usable) || props.player.discard_pile.at(-1)!.uuid in props.player.turn.cards_locked"
@click="useEffect(goStore.self!.turn.effects_availables.find(e => (e.effect == CardEffects.SACRIFICE) && e.usable)!, props.player.discard_pile.at(-1))">SACRIFICE</button>
</CardPreview>
<template v-if="discard_unwrapped" v-for=" c in props.player.discard_pile ">
<CardPreview :data="c">
<!-- <button v-if="isSelf && isTurn" @click="play_from_discard(c)">DRAW</button>
<button v-if="isSelf && isTurn" @click="put_on_stack_from_discard(c)">PUT ON STACK</button>
-->
<button v-if="isSelf && isTurn && c.card_type == CardType.CHAMPION"
:disabled="!goStore.self || !c || !props.player.turn.effects_availables.some(e => (e.effect == CardEffects.RESTACK_DISCARDED_CHAMPION) && e.usable)"
@click="useEffect(goStore.self!.turn.effects_availables.find(e => (e.effect == CardEffects.RESTACK_DISCARDED_CHAMPION) && e.usable)!, c)">RESTACK
(champion)</button>
<button v-if="isSelf && isTurn"
:disabled="!goStore.self || !c || !props.player.turn.effects_availables.some(e => (e.effect == CardEffects.RESTACK_DISCARDED_CARD) && e.usable)"
@click="useEffect(goStore.self!.turn.effects_availables.find(e => (e.effect == CardEffects.RESTACK_DISCARDED_CARD) && e.usable)!, c)">RESTACK
(card)</button>
<button v-if="isSelf && isTurn"
:disabled="!goStore.self || !c || !props.player.turn.effects_availables.some(e => (e.effect == CardEffects.SACRIFICE) && e.usable)"
@click="useEffect(goStore.self!.turn.effects_availables.find(e => (e.effect == CardEffects.SACRIFICE) && e.usable)!, c)">SACRIFICE</button>
</CardPreview>
</template>
</CardSlot>
</div>
</template>
+62 -85
View File
@@ -1,36 +1,23 @@
<script setup lang="ts">
import goStore, { useEffect, playCard, playAllCards, discard, lockCard, heal, damage_champion, damage_team } from '~/netcode';
import type { Card } from '~/netcode/Card';
import type { Player } from '~/netcode/Player';
import { CardEffects } from '@/netcode/Effect'
import { CardType } from '~/netcode/Card';
export interface Props {
player: Player
}
const props = defineProps<Props>()
const isTurn = computed(() => props.player.team == goStore.game?.current_turn)
const isSelf = computed(() => props.player.uuid == goStore.self?.uuid)
const isTurn = computed(() => goStore.self?.team == goStore.game?.current_turn)
const discard_unwrapped = ref(false)
</script>
<template>
<div :class="'player ' + (isTurn ? 'turn' : '')">
<button @click="heal" v-if="props.player.team == goStore.self?.team"
<button @click="heal" v-if="goStore.self?.team == goStore.self?.team"
:disabled="(goStore.self?.turn.heal_reserve ?? 0) <= 0">
Heal
</button>
<button @click="damage_team(props.player.team)" v-if="props.player.team != goStore.self?.team"
:disabled="(goStore.self?.turn.damage_reserve ?? 0) <= 0">
Damage
</button>
<button v-if="props.player.team != goStore.self?.team"
@click="useEffect(goStore.self?.turn.effects_availables.find(e => (e.effect == CardEffects.DISCARD) && e.usable)!, props.player)"
<button v-if="goStore.self && goStore.self?.team != goStore.self?.team"
@click="useEffect(goStore.self?.turn.effects_availables.find(e => (e.effect == CardEffects.DISCARD) && e.usable)!, goStore.self)"
:disabled="!goStore.self?.turn.effects_availables.some(e => (e.effect == CardEffects.DISCARD) && e.usable)">
make Discard</button>
<div id="turn_data">
@@ -38,42 +25,42 @@ const discard_unwrapped = ref(false)
<div class="turn_icon">
<img src="/images/heal.png" />
<span class="turn_icon_number">
{{ props.player.turn.heal_reserve }}
{{ goStore.self?.turn.heal_reserve }}
</span>
</div>
<div class="turn_icon">
<img src="/images/damage.png" />
<span class="turn_icon_number">
{{ props.player.turn.damage_reserve }}
{{ goStore.self?.turn.damage_reserve }}
</span>
</div>
<div class="turn_icon">
<img src="/images/gold.png" />
<span class="turn_icon_number">
{{ props.player.turn.gold_reserve }}
{{ goStore.self?.turn.gold_reserve }}
</span>
</div>
<div class="turn_icon">
<img src="/images/champion-shield.png" />
<span class="turn_icon_number">
{{ props.player.team.health }}
{{ goStore.self?.team.health }}
</span>
</div>
</div>
<div class="cards_container" id="self_hand">
<button v-if="isSelf && isTurn && props.player.hand.length > 1"
@click="playAllCards(props.player.hand as Card[])">
<button v-if="isTurn && (goStore.self?.hand.length ?? 0) > 1"
@click="playAllCards(goStore.self?.hand as Card[])">
PLAY ALL
</button>
<CardPreview :data="c" v-for=" c in props.player.hand " @click="c && playCard(c)">
<button v-if="c && isSelf && isTurn" @click="playCard(c)">PLAY</button>
<button v-if="c && isSelf && isTurn && props.player.turn.discard_markers > 0"
@click="discard(c)">DISCARD</button>
<CardPreview :data="c" v-for=" c in goStore.self?.hand " @click="c && playCard(c)">
<button v-if="c && isTurn" @click="playCard(c)">PLAY</button>
<button v-if="c && isTurn && (goStore.self?.turn.discard_markers ?? 0) > 0"
@click="discard(c!)">DISCARD</button>
</CardPreview>
</div>
<span>discard_markers = {{ props.player.turn.discard_markers }} <br></span>
<span>effects_availables = <div v-for="e in props.player.turn.effects_availables">
<span>discard_markers = {{ goStore.self?.turn.discard_markers }} <br></span>
<span>effects_availables = <div v-for="e in goStore.self?.turn.effects_availables">
<button @click="useEffect(e)" :disabled="!e.usable">
{{ e.effect + ' ' + e.effect_type }}
</button>
@@ -82,76 +69,73 @@ const discard_unwrapped = ref(false)
<br>
board =
<div class="cards_container">
<CardPreview :data="c" v-for=" c in props.player.board " @click="lockCard(c)"
:locked="c.uuid in props.player.turn.cards_locked">
<button v-if="isSelf && isTurn && props.player.turn.discard_markers > 0"
<CardPreview :data="c" v-for=" c in goStore.self?.board " @click="lockCard(c)"
:locked="c.uuid in (goStore.self?.turn.cards_locked ?? [])">
<button v-if="isTurn && (goStore.self?.turn.discard_markers ?? 0) > 0"
@click="discard(c)">DISCARD</button>
<button v-if="isSelf && isTurn && props.player.turn.discard_markers == 0" @click="lockCard(c)"
:disabled="c.uuid in props.player.turn.cards_locked">
<button v-if="isTurn && goStore.self?.turn.discard_markers == 0" @click="lockCard(c)"
:disabled="c.uuid in goStore.self?.turn.cards_locked">
LOCK
</button>
<button
v-if="isSelf && isTurn && props.player.turn.effects_availables.some(e => (e.effect == CardEffects.SACRIFICE) && e.usable)"
:disabled="!goStore.self || !c || c.uuid in props.player.turn.cards_locked"
v-if="isTurn && goStore.self?.turn.effects_availables.some(e => (e.effect == CardEffects.SACRIFICE) && e.usable)"
:disabled="!goStore.self || !c || c.uuid in goStore.self?.turn.cards_locked"
@click="useEffect(goStore.self!.turn.effects_availables.find(e => (e.effect == CardEffects.SACRIFICE) && e.usable)!, c)">SACRIFICE</button>
<div>{{ c.health_as_champion }}</div>
<button
v-if="!isSelf && !isTurn && goStore.self?.team == goStore.game?.current_turn && (c.health_as_champion ?? 0) > 0"
:disabled="(goStore.self?.turn.damage_reserve ?? 0) <= 0"
@click="damage_champion(c)">DAMAGE</button>
<button
v-if="!isSelf && !isTurn && goStore.self?.team == goStore.game?.current_turn && goStore.self?.turn.effects_availables.some(e => (e.effect == CardEffects.STUN) && e.usable) && (c.health_as_champion ?? 0) > 0"
@click="useEffect(goStore.self!.turn.effects_availables.find(e => (e.effect == CardEffects.STUN) && e.usable)!, c)">STUN</button>
</CardPreview>
</div>
<br>
stack =
<CardSlot :stack="props.player.stack_pile">
<!-- <button v-if="isSelf && isTurn" @click="draw">DRAW</button> -->
</CardSlot>
<br>
discard =
{{ props.player.discard_pile.length }}
<input type="checkbox" v-model="discard_unwrapped" />
<div class="stack_and_discard">
<div>
<input type="checkbox" v-model="discard_unwrapped" />
<div class="cards_container">
<CardPreview v-if="!discard_unwrapped" :data="props.player.discard_pile.at(-1)">
<!-- <button v-if="isSelf && isTurn" @click="play_from_discard(props.player.discard_pile.at(-1))">DRAW</button>
<button v-if="isSelf && isTurn" @click="put_on_stack_from_discard(props.player.discard_pile.at(-1))">PUT ON
STACK</button> -->
<template v-for="c in goStore.self?.discard_pile ">
<CardPreview :data="c" :wrapped="!discard_unwrapped">
<!-- <button v-if="isSelf && isTurn" @click="play_from_discard(c)">DRAW</button>
<button v-if="isSelf && isTurn" @click="put_on_stack_from_discard(c)">PUT ON STACK</button>
-->
<button v-if="isTurn && c.card_type == CardType.CHAMPION"
:disabled="!goStore.self || !c || !goStore.self?.turn.effects_availables.some(e => (e.effect == CardEffects.RESTACK_DISCARDED_CHAMPION) && e.usable)"
@click="useEffect(goStore.self!.turn.effects_availables.find(e => (e.effect == CardEffects.RESTACK_DISCARDED_CHAMPION) && e.usable)!, c)">RESTACK
(champion)</button>
<button v-if="isSelf && isTurn"
:disabled="!goStore.self || !props.player.discard_pile.at(-1) || !props.player.turn.effects_availables.some(e => (e.effect == CardEffects.SACRIFICE) && e.usable) || props.player.discard_pile.at(-1)!.uuid in props.player.turn.cards_locked"
@click="useEffect(goStore.self!.turn.effects_availables.find(e => (e.effect == CardEffects.SACRIFICE) && e.usable)!, props.player.discard_pile.at(-1))">SACRIFICE</button>
</CardPreview>
<button v-if="isTurn"
:disabled="!goStore.self || !c || !goStore.self?.turn.effects_availables.some(e => (e.effect == CardEffects.RESTACK_DISCARDED_CARD) && e.usable)"
@click="useEffect(goStore.self!.turn.effects_availables.find(e => (e.effect == CardEffects.RESTACK_DISCARDED_CARD) && e.usable)!, c)">RESTACK
(card)</button>
<button v-if="isTurn"
:disabled="!goStore.self || !c || !goStore.self?.turn.effects_availables.some(e => (e.effect == CardEffects.SACRIFICE) && e.usable)"
@click="useEffect(goStore.self!.turn.effects_availables.find(e => (e.effect == CardEffects.SACRIFICE) && e.usable)!, c)">SACRIFICE</button>
</CardPreview>
</template>
</div>
</div>
<template v-if="discard_unwrapped" v-for="c in props.player.discard_pile ">
<CardPreview :data="c">
<!-- <button v-if="isSelf && isTurn" @click="play_from_discard(c)">DRAW</button>
<button v-if="isSelf && isTurn" @click="put_on_stack_from_discard(c)">PUT ON STACK</button>
-->
<button v-if="isSelf && isTurn && c.card_type == CardType.CHAMPION"
:disabled="!goStore.self || !c || !props.player.turn.effects_availables.some(e => (e.effect == CardEffects.RESTACK_DISCARDED_CHAMPION) && e.usable)"
@click="useEffect(goStore.self!.turn.effects_availables.find(e => (e.effect == CardEffects.RESTACK_DISCARDED_CHAMPION) && e.usable)!, c)">RESTACK
(champion)</button>
<div class="separator"></div>
<div class="separator"></div>
<button v-if="isSelf && isTurn"
:disabled="!goStore.self || !c || !props.player.turn.effects_availables.some(e => (e.effect == CardEffects.RESTACK_DISCARDED_CARD) && e.usable)"
@click="useEffect(goStore.self!.turn.effects_availables.find(e => (e.effect == CardEffects.RESTACK_DISCARDED_CARD) && e.usable)!, c)">RESTACK
(card)</button>
<button v-if="isSelf && isTurn"
:disabled="!goStore.self || !c || !props.player.turn.effects_availables.some(e => (e.effect == CardEffects.SACRIFICE) && e.usable)"
@click="useEffect(goStore.self!.turn.effects_availables.find(e => (e.effect == CardEffects.SACRIFICE) && e.usable)!, c)">SACRIFICE</button>
</CardPreview>
</template>
<CardSlot :stack="goStore.self?.stack_pile">
<!-- <button v-if="isSelf && isTurn" @click="draw">DRAW</button> -->
</CardSlot>
</div>
</div>
</template>
<style scoped>
.stack_and_discard {
display: flex;
flex-direction: row-reverse;
justify-content: center;
}
.player {
border-top: 5px solid black;
}
@@ -181,14 +165,7 @@ const discard_unwrapped = ref(false)
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
#self_hand {
display: flex;
flex-direction: row-reverse;
flex-wrap: nowrap;
position: fixed;
const stack_unwrapped=ref(false) position: fixed;
right: 60px;
bottom: -50px;
max-width: 100vw;