Feat : add most token effects

This commit is contained in:
2024-07-14 00:05:55 +02:00
parent b1c9644941
commit 3c5b30be9e
6 changed files with 166 additions and 11 deletions
+36 -9
View File
@@ -1,10 +1,12 @@
<script setup lang="ts"> <script setup lang="ts">
import { delay } from "~/netcode/events"; import { delay } from "~/netcode/events";
import type { import {
Card, CardEffects,
Container, CardType,
Effect, type Card,
PlayingTurn, type Container,
type Effect,
type PlayingTurn,
} from "~/netcode/interfaces"; } from "~/netcode/interfaces";
import TokenComponent from "./tokens/TokenComponent.vue"; import TokenComponent from "./tokens/TokenComponent.vue";
@@ -15,6 +17,7 @@ export interface Props {
hidden?: boolean; hidden?: boolean;
noEffects?: boolean; noEffects?: boolean;
tokens?: Effect[]; tokens?: Effect[];
championsKillable?: boolean;
} }
const props = withDefaults(defineProps<Props>(), { const props = withDefaults(defineProps<Props>(), {
@@ -22,6 +25,7 @@ const props = withDefaults(defineProps<Props>(), {
hidden: () => false, hidden: () => false,
noEffects: () => false, noEffects: () => false,
tokens: () => [], tokens: () => [],
championsKillable: () => false,
}); });
const emit = defineEmits(["cardClick", "effectClick", "tokenClick"]); const emit = defineEmits(["cardClick", "effectClick", "tokenClick"]);
@@ -110,6 +114,8 @@ const interval = ref<ReturnType<typeof setInterval>>();
function tokenClick(token: Effect, card: Card) { function tokenClick(token: Effect, card: Card) {
emit("tokenClick", { token, card }); emit("tokenClick", { token, card });
} }
function damageChampion() {}
</script> </script>
<template> <template>
@@ -121,15 +127,15 @@ function tokenClick(token: Effect, card: Card) {
<CardPreview <CardPreview
@click="$emit('cardClick', c._id)" @click="$emit('cardClick', c._id)"
@effectClick="$emit('effectClick', c._id, $event)" @effectClick="$emit('effectClick', c._id, $event)"
v-for="c in cards" v-for="(c, i) in cards"
:card_id="c.cardId" :card_id="c?.cardId"
:wrapped="wrapped" :wrapped="wrapped"
:key="c._id" :key="c?._id || i"
:card="c" :card="c"
:locked=" :locked="
!playingTurn || playingTurn?.cardsLocked.includes(c._id.toString()) !playingTurn || 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)
} }
@@ -141,8 +147,29 @@ function tokenClick(token: Effect, card: Card) {
<TokenComponent <TokenComponent
:token="t" :token="t"
@useToken="tokenClick(t, c)" @useToken="tokenClick(t, c)"
v-if="
!(
t.effect == CardEffects.SACRIFICE &&
(!playingTurn ||
playingTurn?.cardsLocked.includes(c._id.toString()))
) &&
!(
t.effect == CardEffects.PREPARE &&
c.cardType == CardType.CHAMPION
) &&
!(
t.effect == CardEffects.STACK_NEXT_ACTION_BOUGHT &&
c.cardType != CardType.ACTION
) &&
t.effect == CardEffects.STUN &&
c.cardType == CardType.CHAMPION &&
championsKillable
"
></TokenComponent> ></TokenComponent>
</template> </template>
<button v-if="championsKillable && c.cardType == CardType.CHAMPION">
Damage
</button>
</CardPreview> </CardPreview>
</TransitionGroup> </TransitionGroup>
<!-- <img :class="`card_image`" :src="'/cards/background.png'" draggable="false"> --> <!-- <img :class="`card_image`" :src="'/cards/background.png'" draggable="false"> -->
+38 -1
View File
@@ -1,5 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import type { Game, Player } from "~/netcode/interfaces"; import { damagePlayer, makeDiscard } from "~/netcode";
import { CardEffects, type Game, type Player } from "~/netcode/interfaces";
const emit = defineEmits(["click"]); const emit = defineEmits(["click"]);
@@ -15,6 +16,24 @@ const props = withDefaults(defineProps<Props>(), {
isTurn: () => false, isTurn: () => false,
self: () => false, self: () => false,
}); });
const authStore = useAuthStore();
const playerList = computed(() =>
props.game!.teams.reduce((acc, t) => acc.concat(t.players), [] as Player[])
);
const selfPlayer = computed(() =>
authStore.logged
? playerList.value?.find((p) => p.user.userId == authStore.selfUser.userId)
: undefined
);
function makeDiscardClick() {
makeDiscard(props.game._id, props.player._id);
}
function damage() {
damagePlayer(props.game._id, props.player._id, 1);
}
</script> </script>
<template> <template>
@@ -48,6 +67,24 @@ const props = withDefaults(defineProps<Props>(), {
<PlayerStats :game="props.game" :player="props.player"> </PlayerStats> <PlayerStats :game="props.game" :player="props.player"> </PlayerStats>
<!-- </template> --> <!-- </template> -->
</div> </div>
<button
v-if="
game.currentTurn.tokens.some(
(t) => t.effect == CardEffects.MAKE_DISCARD
) &&
props.player._id != selfPlayer?._id &&
!isTurn
"
@click.stop="makeDiscardClick"
>
Make Discard
</button>
<button
v-if="props.player._id != selfPlayer?._id && !isTurn"
@click.stop="damage"
>
Damage
</button>
</div> </div>
</div> </div>
</template> </template>
+4 -1
View File
@@ -52,7 +52,9 @@ const isSelfTurn = computed(() => isSelf && isPlayerTurn);
const cardTokens = computed(() => const cardTokens = computed(() =>
props.game.currentTurn.tokens.filter((t) => props.game.currentTurn.tokens.filter((t) =>
[CardEffects.SACRIFICE, CardEffects.PREPARE].includes(t.effect) [CardEffects.SACRIFICE, CardEffects.PREPARE, CardEffects.STUN].includes(
t.effect
)
) )
); );
@@ -196,6 +198,7 @@ function tokenClick({ card, token }: { card: Card; token: Effect }) {
@effectClick="effectClick" @effectClick="effectClick"
:tokens="cardTokens" :tokens="cardTokens"
@tokenClick="tokenClick" @tokenClick="tokenClick"
:championsKillable="!isSelf && isSelfTurn.value"
> >
</CardsGrouped> </CardsGrouped>
+56
View File
@@ -153,3 +153,59 @@ export async function lockEffect(game: string, effectId: string) {
} }
); );
} }
export async function makeDiscard(
game: string,
playerId: string,
amount: number = 1
) {
const config = useRuntimeConfig();
await $fetch(
new URL(
`games/${game}/turn/makeDiscard/${playerId}`,
config.public.endpoint
).href,
{
method: "POST",
credentials: "include",
}
);
}
export async function damagePlayer(
game: string,
playerId: string,
amount: number = 1
) {
const config = useRuntimeConfig();
await $fetch(
new URL(
`games/${game}/turn/damagePlayer/${playerId}`,
config.public.endpoint
).href,
{
method: "POST",
credentials: "include",
body: { amount },
}
);
}
export async function damageChampion(
game: string,
playerId: string,
cardId: string
) {
const config = useRuntimeConfig();
await $fetch(
new URL(
`games/${game}/turn/damageChampion/${cardId}`,
config.public.endpoint
).href,
{
method: "POST",
credentials: "include",
body: { playerId },
}
);
}
+11
View File
@@ -41,6 +41,16 @@ export enum CardEffects {
PICK_FACTION = "pick_faction", PICK_FACTION = "pick_faction",
} }
export enum CardType {
HERO = "hero",
HERO_ABILITY = "hero_ability",
CURRENCY = "currency",
WEAPON = "weapon",
CHAMPION = "champion",
ACTION = "action",
ITEM = "item",
}
export interface GameObject { export interface GameObject {
_id: string; _id: string;
} }
@@ -95,5 +105,6 @@ export interface Effect extends GameObject {
} }
export interface Card extends GameObject { export interface Card extends GameObject {
cardId: number; cardId: number;
cardType: CardType;
effects: Effect[]; effects: Effect[];
} }
+21
View File
@@ -4,6 +4,7 @@ import { subscribe } from "~/netcode";
import { delay } from "~/netcode/events"; import { delay } from "~/netcode/events";
import { type Container, type Game, type Player } from "~/netcode/interfaces"; import { type Container, type Game, type Player } from "~/netcode/interfaces";
import { playSound } from "~/helpers/audioHelpers"; import { playSound } from "~/helpers/audioHelpers";
import TokenComponent from "~/components/tokens/TokenComponent.vue";
const config = useRuntimeConfig(); const config = useRuntimeConfig();
const settingsStore = useSettingsStore(); const settingsStore = useSettingsStore();
@@ -211,6 +212,20 @@ eventSource.addEventListener("message", async (message) => {
console.log(`adding health amount : ` + data.operation); console.log(`adding health amount : ` + data.operation);
team.health = data.health; team.health = data.health;
}); });
} else if (data.type == "killTeam") {
queueAction(async () => {
const index = game.value?.teams.findIndex((t) => t._id == data.teamId);
if (!index) {
console.error("team index not found. Desyncs might happen");
await refresh();
return;
}
game.value?.teams.splice(index, 1);
});
} else if (data.type == "endGame") {
queueAction(async () => {
alert("game Ended");
});
} }
}); });
@@ -314,6 +329,12 @@ onUnmounted(() => {
:fire_gems="game.fireGems" :fire_gems="game.fireGems"
:marketStack="game.marketStack" :marketStack="game.marketStack"
></MarketCards> ></MarketCards>
<div>
<TokenComponent
:token="t"
v-for="t in game.currentTurn.tokens"
></TokenComponent>
</div>
<div id="player_list_container"> <div id="player_list_container">
<div id="player_list"> <div id="player_list">
<PlayerListElement <PlayerListElement