Feat : Allow granular control over indirectly activated effects
release-tag / release-image (push) Successful in 46s

Testing probably needs to be done
Closes #12
This commit is contained in:
2024-05-17 09:42:44 +02:00
parent 29503982f4
commit 8a688bd2da
3 changed files with 97 additions and 50 deletions
+12 -15
View File
@@ -4,7 +4,9 @@ import { CardEffects, type Effect } from '@/netcode/Effect'
import { CardType } from '@/netcode/Card' import { CardType } from '@/netcode/Card'
const isTurn = computed(() => goStore.self && goStore.current_game?.started && (goStore.self.team == goStore.current_game.current_turn)) const isTurn = computed(() => goStore.self && goStore.current_game?.started && (goStore.self.team == goStore.current_game.current_turn))
const clientStore = useClientSideStore()
const buyableFiregem = computed(() => goStore?.current_game?.gem_stack.at(-1))
</script> </script>
<template> <template>
@@ -16,18 +18,15 @@ const isTurn = computed(() => goStore.self && goStore.current_game?.started && (
<template <template
v-if="isTurn && goStore.self?.turn && c && c.cost && (goStore.self?.turn.gold_reserve ?? 0) >= c.cost"> v-if="isTurn && goStore.self?.turn && c && c.cost && (goStore.self?.turn.gold_reserve ?? 0) >= c.cost">
<button @click.stop="buy(c)">BUY</button> <button @click.stop="buy(c)">BUY</button>
<button <button @click.stop="clientStore.findUseEffect(CardEffects.PLAY_NEXT_CARD_BOUGHT, c);"
@click.stop="useEffect(goStore.self!.turn.effects_availables.find((e: Effect) => (e.effect == CardEffects.PLAY_NEXT_CARD_BOUGHT) && e.usable)!, c)" v-if="clientStore.activatedClientside.find((e: Effect) => (e.effect == CardEffects.PLAY_NEXT_CARD_BOUGHT) && e.usable)">
v-if="goStore.self?.turn.effects_availables.find((e: Effect) => (e.effect == CardEffects.PLAY_NEXT_CARD_BOUGHT) && e.usable)">
BUY IN HAND</button> BUY IN HAND</button>
<button <button @click.stop="clientStore.findUseEffect(CardEffects.STACK_NEXT_CARD_BOUGHT, c)"
@click.stop="useEffect(goStore.self!.turn.effects_availables.find((e: Effect) => (e.effect == CardEffects.STACK_NEXT_CARD_BOUGHT) && e.usable)!, c)" v-if="clientStore.activatedClientside.find((e: Effect) => (e.effect == CardEffects.STACK_NEXT_CARD_BOUGHT) && e.usable)">
v-if="goStore.self?.turn.effects_availables.find((e: Effect) => (e.effect == CardEffects.STACK_NEXT_CARD_BOUGHT) && e.usable)">
BUY IN STACK (generic)</button> BUY IN STACK (generic)</button>
<button <button @click.stop="clientStore.findUseEffect(CardEffects.STACK_NEXT_ACTION_BOUGHT, c)"
@click.stop="useEffect(goStore.self!.turn.effects_availables.find((e: Effect) => (e.effect == CardEffects.STACK_NEXT_ACTION_BOUGHT) && e.usable)!, c)" v-if="clientStore.activatedClientside.find((e: Effect) => (e.effect == CardEffects.STACK_NEXT_ACTION_BOUGHT) && e.usable)">
v-if="c.card_type == CardType.ACTION && goStore.self?.turn.effects_availables.find((e: Effect) => (e.effect == CardEffects.STACK_NEXT_ACTION_BOUGHT) && e.usable)">
BUY IN STACK (actions)</button> BUY IN STACK (actions)</button>
</template> </template>
</CardPreview> </CardPreview>
@@ -39,13 +38,11 @@ const isTurn = computed(() => goStore.self && goStore.current_game?.started && (
<button @click.stop="buy(goStore.current_game.gem_stack.at(-1)!)"> <button @click.stop="buy(goStore.current_game.gem_stack.at(-1)!)">
BUY BUY
</button> </button>
<button <button @click.stop="clientStore.findUseEffect(CardEffects.PLAY_NEXT_CARD_BOUGHT, buyableFiregem)"
@click.stop="useEffect(goStore.self!.turn.effects_availables.find((e: Effect) => (e.effect == CardEffects.PLAY_NEXT_CARD_BOUGHT) && e.usable)!, goStore.current_game.gem_stack.at(-1))" v-if="buyableFiregem && clientStore.activatedClientside.find((e: Effect) => (e.effect == CardEffects.PLAY_NEXT_CARD_BOUGHT) && e.usable)">
v-if="goStore.self?.turn.effects_availables.find((e: Effect) => (e.effect == CardEffects.PLAY_NEXT_CARD_BOUGHT) && e.usable)">
BUY IN HAND</button> BUY IN HAND</button>
<button <button @click.stop="clientStore.findUseEffect(CardEffects.STACK_NEXT_CARD_BOUGHT, buyableFiregem)"
@click.stop="useEffect(goStore.self!.turn.effects_availables.find((e: Effect) => (e.effect == CardEffects.STACK_NEXT_CARD_BOUGHT) && e.usable)!, goStore.current_game.gem_stack.at(-1))" v-if="buyableFiregem && clientStore.activatedClientside.find((e: Effect) => (e.effect == CardEffects.STACK_NEXT_CARD_BOUGHT) && e.usable)">
v-if="goStore.self?.turn.effects_availables.find((e: Effect) => (e.effect == CardEffects.STACK_NEXT_CARD_BOUGHT) && e.usable)">
BUY IN STACK(generic) BUY IN STACK(generic)
</button> </button>
</template> </template>
+31 -35
View File
@@ -15,6 +15,7 @@ import { CardType, type Card } from "~/netcode/Card";
import type { Player } from "~/netcode/Player"; import type { Player } from "~/netcode/Player";
import { CardEffects, type Effect, EffectType } from "@/netcode/Effect"; import { CardEffects, type Effect, EffectType } from "@/netcode/Effect";
import type { Team } from "~/netcode/Team"; import type { Team } from "~/netcode/Team";
import { useClientSideStore } from "~/stores/turn";
export interface Props { export interface Props {
player: Player; player: Player;
@@ -31,28 +32,15 @@ const isSelf = computed(() => props.player.uuid === goStore.self?.uuid);
const isSelfTurn = computed(() => goStore.self?.team === goStore.current_game?.current_turn) const isSelfTurn = computed(() => goStore.self?.team === goStore.current_game?.current_turn)
const isPlayerEnemy = computed(() => goStore.self?.team !== props.player.team) const isPlayerEnemy = computed(() => goStore.self?.team !== props.player.team)
const warningText = ref("Effets restants!") const warningText = ref("Effets restants!")
const clientStore = useClientSideStore()
function run_effect(
effect_type: CardEffects,
target: Player | Card
) {
if (!goStore.self?.turn) {
return
}
const effect = goStore.self?.turn.effects_availables.find((e: Effect) => (e.effect == effect_type) && e.usable);
if (!effect) {
return;
}
useEffect(effect, target);
}
const make_discard = (target: Player) => const make_discard = (target: Player) =>
run_effect(CardEffects.MAKE_DISCARD, target); clientStore.findUseEffect(CardEffects.MAKE_DISCARD, target);
const sacrifice = (target: Card) => run_effect(CardEffects.SACRIFICE, target); const sacrifice = (target: Card) => clientStore.findUseEffect(CardEffects.SACRIFICE, target);
const stun = (target: Card) => run_effect(CardEffects.STUN, target) const stun = (target: Card) => clientStore.findUseEffect(CardEffects.STUN, target)
const restack_discarded_champion = (target: Card) => run_effect(CardEffects.RESTACK_DISCARDED_CHAMPION, target) const restack_discarded_champion = (target: Card) => clientStore.findUseEffect(CardEffects.RESTACK_DISCARDED_CHAMPION, target)
const restack_discarded_card = (target: Card) => run_effect(CardEffects.RESTACK_DISCARDED_CARD, target) const restack_discarded_card = (target: Card) => clientStore.findUseEffect(CardEffects.RESTACK_DISCARDED_CARD, target)
const prepare_champion = (target: Card) => run_effect(CardEffects.PREPARE, target) const prepare_champion = (target: Card) => clientStore.findUseEffect(CardEffects.PREPARE, target)
let warning = ref(false) let warning = ref(false)
@@ -100,6 +88,7 @@ function damage_team_all(team: Team) {
function check_for_guard(player: Player) { function check_for_guard(player: Player) {
return player.board.some(c => c.guard === true) return player.board.some(c => c.guard === true)
} }
</script> </script>
<template> <template>
@@ -119,19 +108,18 @@ function check_for_guard(player: Player) {
<CardPreview :tilted="false" v-if="discard_unwrapped" :card_id="c.card_id" <CardPreview :tilted="false" v-if="discard_unwrapped" :card_id="c.card_id"
v-for="c in props.player.discard_pile"> v-for="c in props.player.discard_pile">
<template v-if="goStore.self?.turn && c && isSelf && isPlayerTurn"> <template v-if="goStore.self?.turn && c && isSelf && isPlayerTurn">
<button <button
v-if="goStore.self?.turn.effects_availables.find((e: Effect) => (e.effect == CardEffects.SACRIFICE) && e.usable)" v-if="clientStore.activatedClientside.find((e: Effect) => (e.effect == CardEffects.SACRIFICE) && e.usable)"
@click.stop="sacrifice(c)"> @click.stop="sacrifice(c)">
SACRIFICE SACRIFICE
</button> </button>
<button <button
v-if="goStore.self?.turn.effects_availables.find((e: Effect) => (e.effect == CardEffects.RESTACK_DISCARDED_CHAMPION) && e.usable)" v-if="clientStore.activatedClientside.find((e: Effect) => (e.effect == CardEffects.RESTACK_DISCARDED_CHAMPION) && e.usable)"
@click.stop="restack_discarded_champion(c)"> @click.stop="restack_discarded_champion(c)">
RESTACK_DISCARDED_CHAMPION RESTACK_DISCARDED_CHAMPION
</button> </button>
<button <button
v-if="goStore.self?.turn.effects_availables.find((e: Effect) => (e.effect == CardEffects.RESTACK_DISCARDED_CARD) && e.usable)" v-if="clientStore.activatedClientside.find((e: Effect) => (e.effect == CardEffects.RESTACK_DISCARDED_CARD) && e.usable)"
@click.stop="restack_discarded_card(c)"> @click.stop="restack_discarded_card(c)">
RESTACK_DISCARDED_CARD RESTACK_DISCARDED_CARD
</button> </button>
@@ -139,7 +127,6 @@ function check_for_guard(player: Player) {
</template> </template>
</CardPreview> </CardPreview>
</div> </div>
</div> </div>
</template> </template>
<div id="player_banner"> <div id="player_banner">
@@ -180,7 +167,7 @@ function check_for_guard(player: Player) {
</button> </button>
<button v-if="goStore.self && isSelfTurn && isPlayerEnemy && goStore.self?.turn" <button v-if="goStore.self && isSelfTurn && isPlayerEnemy && goStore.self?.turn"
@click.stop="make_discard(props.player)" class="make_discard_button" @click.stop="make_discard(props.player)" class="make_discard_button"
:disabled="!goStore.self.turn.effects_availables.find((e: Effect) => (e.effect == CardEffects.MAKE_DISCARD) && e.usable)"> :disabled="!clientStore.activatedClientside.find((e: Effect) => (e.effect == CardEffects.MAKE_DISCARD) && e.usable)">
make Discard make Discard
</button> </button>
</div> </div>
@@ -202,15 +189,24 @@ function check_for_guard(player: Player) {
<template v-if="c && isSelf && isPlayerTurn && props.player.turn"> <template v-if="c && isSelf && isPlayerTurn && props.player.turn">
<!-- Card Locked --> <!-- Card Locked -->
<template v-if="c.uuid in props.player.turn.cards_locked"> <template v-if="c.uuid in props.player.turn.cards_locked">
<template v-for="e in props.player.turn.effects_availables"> <template v-for="e in clientStore.maskedServerEffects">
<button v-if="e.card == c" @click.stop="useEffect(e)" :disabled="!e.usable" <template v-if="e.card == c">
:class="{ 'suicide_effect': e.effect_type == EffectType.SUICIDE }"> <button v-if="!clientStore.effectsHandled.has(e.effect)" @click.stop="useEffect(e)"
EFFECT<br> :disabled="!e.usable"
{{ e.effect + " " + (e.effect_type ?? '') }} :class="{ 'suicide_effect': e.effect_type == EffectType.SUICIDE }">
</button> EFFECT<br>
{{ e.effect + " " + (e.effect_type ?? '') }}
</button>
<button v-if="clientStore.effectsHandled.has(e.effect)"
@click.stop="clientStore.activateEffect(e)" :disabled="!e.usable"
:class="{ 'suicide_effect': e.effect_type == EffectType.SUICIDE }">
EFFECT<br>
{{ e.effect + " " + (e.effect_type ?? '') }}
</button>
</template>
</template> </template>
<button <button
v-if="props.player.turn.effects_availables.find((e: Effect) => (e.effect == CardEffects.PREPARE) && e.usable) && c.card_type == CardType.CHAMPION" v-if="clientStore.activatedClientside.find((e: Effect) => (e.effect == CardEffects.PREPARE) && e.usable) && c.card_type == CardType.CHAMPION"
@click.stop="prepare_champion(c)">PREPARE</button> @click.stop="prepare_champion(c)">PREPARE</button>
</template> </template>
<!-- Card Unlocked --> <!-- Card Unlocked -->
@@ -220,7 +216,7 @@ function check_for_guard(player: Player) {
DISCARD DISCARD
</button> </button>
<button <button
v-if="props.player.turn.effects_availables.find((e: Effect) => (e.effect == CardEffects.SACRIFICE) && e.usable)" v-if="clientStore.activatedClientside.find((e: Effect) => (e.effect == CardEffects.SACRIFICE) && e.usable)"
@click.stop="sacrifice(c)"> @click.stop="sacrifice(c)">
SACRIFICE SACRIFICE
</button> </button>
@@ -238,7 +234,7 @@ function check_for_guard(player: Player) {
DAMAGE ({{ c.health_as_champion }}) DAMAGE ({{ c.health_as_champion }})
</button> </button>
<button class="enemy_action" <button class="enemy_action"
v-if="goStore.self?.turn.effects_availables.find((e: Effect) => (e.effect == CardEffects.STUN) && e.usable)" v-if="clientStore.activatedClientside.find((e: Effect) => (e.effect == CardEffects.STUN) && e.usable)"
@click.stop="stun(c)" :disabled="(check_for_guard(props.player) && !c.guard)"> @click.stop="stun(c)" :disabled="(check_for_guard(props.player) && !c.guard)">
STUN STUN
</button> </button>
+54
View File
@@ -0,0 +1,54 @@
import { defineStore } from "pinia";
import goStore, { useEffect } from "~/netcode";
import type { Card } from "~/netcode/Card";
import { CardEffects, type Effect } from "~/netcode/Effect";
import type { Player } from "~/netcode/Player";
watch(
() => goStore.current_game?.current_turn.uuid,
() => {
useClientSideStore().activatedClientside = []
})
export const useClientSideStore = defineStore("clientside", {
state: () => ({
activatedClientside: [] as Effect[],
effectsHandled: new Set([
CardEffects.MAKE_DISCARD,
CardEffects.PLAY_NEXT_CARD_BOUGHT,
CardEffects.RESTACK_DISCARDED_CARD,
CardEffects.RESTACK_DISCARDED_CHAMPION,
CardEffects.SACRIFICE,
CardEffects.STACK_NEXT_ACTION_BOUGHT,
CardEffects.STACK_NEXT_CARD_BOUGHT,
CardEffects.STUN,
]),
}),
getters: {
maskedServerEffects(state) {
return goStore.self?.turn?.effects_availables.filter(e => !state.activatedClientside.includes(e));
},
},
actions: {
activateEffect(effect: Effect) {
const amount =
goStore.self?.turn?.effects_availables.filter((e) => e == effect)
.length ?? 0;
for (let i = 0; i < amount; i++) {
this.activatedClientside.push(effect);
}
},
useEffect(effect: Effect, target: Player | Card) {
const index = this.activatedClientside.indexOf(effect);
if (index > -1) {
this.activatedClientside.splice(index, 1);
useEffect(effect, target);
}
},
findUseEffect(cardEffect: CardEffects, target: Player | Card) {
const effect = this.activatedClientside.find(e => (e.effect == cardEffect) && e.usable)
if (!effect) { return }
this.useEffect(effect, target)
}
},
});