Fix reactive with new system
This commit is contained in:
@@ -1,118 +1,20 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
const cards = useState<{ [key: string]: any }>('cards', () => ({}))
|
|
||||||
const effects = useState<{ [key: string]: any }>('effects', () => ({}))
|
|
||||||
const players = useState<{ [key: string]: any }>('players', () => ({}))
|
|
||||||
const teams = useState<{ [key: string]: any }>('teams', () => ({}))
|
|
||||||
const turns = useState<{ [key: string]: any }>('turns', () => ({}))
|
|
||||||
const self = useState<string>('self')
|
|
||||||
const gameObjects = useState<{ [key: string]: any }>('gameObject', () => ({}))
|
|
||||||
|
|
||||||
const socket = useState<WebSocket>('socket', () => new WebSocket("ws://127.0.0.1:8765"))
|
import goStore, { GameObjectRegister, register, setReady } from '@/netcode';
|
||||||
|
|
||||||
let game = ref<any>({ started: true })
|
|
||||||
let context = ref<string>('login')
|
|
||||||
let username = ref<string>('legonzaur')
|
let username = ref<string>('legonzaur')
|
||||||
|
|
||||||
|
|
||||||
const createObject = {
|
|
||||||
"effect": (data: any) => {
|
|
||||||
effects.value[data.uuid] = data
|
|
||||||
gameObjects.value[data.uuid] = data
|
|
||||||
},
|
|
||||||
"card": (data: any) => {
|
|
||||||
cards.value[data.uuid] = data
|
|
||||||
gameObjects.value[data.uuid] = data
|
|
||||||
},
|
|
||||||
"player": (data: any) => {
|
|
||||||
players.value[data.uuid] = data
|
|
||||||
gameObjects.value[data.uuid] = data
|
|
||||||
},
|
|
||||||
"game": (data: any) => {
|
|
||||||
game.value = data
|
|
||||||
gameObjects.value[data.uuid] = data
|
|
||||||
},
|
|
||||||
"team": (data: any) => {
|
|
||||||
teams.value[data.uuid] = data
|
|
||||||
gameObjects.value[data.uuid] = data
|
|
||||||
},
|
|
||||||
"turn": (data: any) => {
|
|
||||||
turns.value[data.uuid] = data
|
|
||||||
gameObjects.value[data.uuid] = data
|
|
||||||
}
|
|
||||||
} as { [id: string]: (data: Object) => any }
|
|
||||||
|
|
||||||
socket.value.onopen = function (e) {
|
|
||||||
console.log("[open] Connection established");
|
|
||||||
};
|
|
||||||
|
|
||||||
socket.value.onclose = function (event) {
|
|
||||||
if (event.wasClean) {
|
|
||||||
console.warn(`[close] Connection closed cleanly, code=${event.code} reason=${event.reason}`);
|
|
||||||
} else {
|
|
||||||
// e.g. server process killed or network down
|
|
||||||
// event.code is usually 1006 in this case
|
|
||||||
console.error('[close] Connection died');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
socket.value.onerror = function (error) {
|
|
||||||
console.error(error);
|
|
||||||
};
|
|
||||||
|
|
||||||
socket.value.onmessage = function (event) {
|
|
||||||
const data = JSON.parse(event.data)
|
|
||||||
|
|
||||||
|
|
||||||
if (data.type == "create" && data.data_type == "object") {
|
|
||||||
if (!(data.data.object_type in createObject)) {
|
|
||||||
throw new Error(`Object ${data.data.object_type} couldn't be created`)
|
|
||||||
}
|
|
||||||
createObject[data.data.object_type](data.data)
|
|
||||||
} else if (data.type == "update" && data.data_type == "object") {
|
|
||||||
if (!(data.data.uuid in gameObjects.value)) {
|
|
||||||
throw new Error(`Object ${data.data.uuid} doesn't exists`)
|
|
||||||
}
|
|
||||||
gameObjects.value[data.data.uuid] = data.data
|
|
||||||
createObject[data.data.object_type](data.data)
|
|
||||||
} else if (data.type === "context") {
|
|
||||||
context.value = data.data
|
|
||||||
console.log(context.value)
|
|
||||||
} else if (data.type === "set" && data.data_type == "self") {
|
|
||||||
self.value = data.data
|
|
||||||
} else {
|
|
||||||
console.log(data.type, data.data_type, data.data);
|
|
||||||
}
|
|
||||||
|
|
||||||
// if (data.type == "context" && data.data_type == "game_context_id" && data.data == "pregame") {
|
|
||||||
// setTimeout(() => socket.send(JSON.stringify({ type: "ready", data_type: "ready_state", data: true })), 1000)
|
|
||||||
// }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
async function register(username: string) {
|
|
||||||
socket.value.send(JSON.stringify({
|
|
||||||
type: "register",
|
|
||||||
data_type: "username",
|
|
||||||
data: username
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
async function setReady(value: Event) {
|
|
||||||
socket.value.send(JSON.stringify({
|
|
||||||
type: "ready",
|
|
||||||
data_type: "ready_state",
|
|
||||||
data: ((value.target as HTMLInputElement).checked)
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<input v-if="!self && !game.started" type="text" v-model="username">
|
<input v-if="!goStore.self && !goStore.game?.started" type="text" v-model="username">
|
||||||
<button v-if="!self && !game.started" @click="register(username)">LOGIN</button>
|
<button v-if="!goStore.self && !goStore.game?.started" @click="register(username)">LOGIN</button>
|
||||||
<input @change="setReady" v-if="self && !game.started" type="checkbox" id="ready">
|
<input @change="setReady(($event.target as HTMLInputElement).checked)" v-if="goStore.self && !goStore.game?.started"
|
||||||
<label v-if="self && !game.started" for="scales">Ready</label>
|
type="checkbox" id="ready">
|
||||||
|
<label v-if="goStore.self && !goStore.game?.started" for="scales">Ready</label>
|
||||||
<div>
|
<div>
|
||||||
<GameBoard :game="game"></GameBoard>
|
<GameBoard :game="goStore.game"></GameBoard>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,20 +1,20 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import type { Card } from '~/netcode/Card';
|
||||||
|
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
data?: string
|
data?: Card | null
|
||||||
locked?: boolean
|
locked?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = defineProps<Props>()
|
const props = defineProps<Props>()
|
||||||
|
|
||||||
const cards = useState<{ [key: string]: any }>('cards')
|
|
||||||
|
|
||||||
const buttonsElement = ref<HTMLElement | null>(null)
|
const buttonsElement = ref<HTMLElement | null>(null)
|
||||||
const rightClicked = ref(false)
|
const rightClicked = ref(false)
|
||||||
|
|
||||||
function cardClick() {
|
function cardClick() {
|
||||||
if (!props.data) return
|
if (props.data == null) return
|
||||||
console.log(JSON.parse(JSON.stringify(cards.value[props.data].effects)))
|
console.log(JSON.parse(JSON.stringify(props.data.effects)))
|
||||||
}
|
}
|
||||||
|
|
||||||
function contextmenu(e: MouseEvent) {
|
function contextmenu(e: MouseEvent) {
|
||||||
@@ -27,12 +27,11 @@ function contextmenu(e: MouseEvent) {
|
|||||||
<template>
|
<template>
|
||||||
<div :class="`card ${Number(buttonsElement?.childElementCount) > 0 ? 'active' : ''}`" @contextmenu.prevent="false"
|
<div :class="`card ${Number(buttonsElement?.childElementCount) > 0 ? 'active' : ''}`" @contextmenu.prevent="false"
|
||||||
@click.left="cardClick" @click.right="contextmenu">
|
@click.left="cardClick" @click.right="contextmenu">
|
||||||
|
|
||||||
<img :class="`card_image ${rightClicked ? 'outlined' : ''} ${props.locked ? 'locked' : ''}`" v-if="props.data"
|
<img :class="`card_image ${rightClicked ? 'outlined' : ''} ${props.locked ? 'locked' : ''}`" v-if="props.data"
|
||||||
:src="'/cards/' + cards[props.data]?.card_id.toString().padStart(3, '0') + '.jpg'">
|
:src="'/cards/' + data?.card_id?.toString().padStart(3, '0') + '.jpg'">
|
||||||
|
|
||||||
<img :class="`card_image ${rightClicked ? 'outlined' : ''} ${props.locked ? 'locked' : ''}`"
|
<img :class="`card_image ${rightClicked ? 'outlined' : ''} ${props.locked ? 'locked' : ''}`" v-if="!props.data"
|
||||||
v-if="props.data === null" :src="'/cards/background.jpg'">
|
:src="'/cards/background.jpg'">
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import type { Card } from '~/netcode/Card';
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
stack: string[]
|
stack: (Card | null)[]
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
@@ -16,7 +18,7 @@ const wrapped = ref(false)
|
|||||||
<input type="checkbox" v-model="wrapped" />
|
<input type="checkbox" v-model="wrapped" />
|
||||||
<div class="cards_container">
|
<div class="cards_container">
|
||||||
|
|
||||||
<CardPreview v-if="!wrapped" :data="props.stack.at(-1)">
|
<CardPreview v-if="!wrapped" :data="props.stack.at(-1) ?? null">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</CardPreview>
|
</CardPreview>
|
||||||
|
|
||||||
|
|||||||
+10
-30
@@ -1,41 +1,20 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
const props = defineProps(['game'])
|
import goStore, { buy, endTurn } from '@/netcode';
|
||||||
const self = useState<string>('self')
|
|
||||||
const gameObject = useState<{ [key: string]: any }>('gameObject')
|
|
||||||
const cards = useState<{ [key: string]: any }>('cards')
|
|
||||||
const socket = useState<WebSocket>('socket')
|
|
||||||
|
|
||||||
const isTurn = computed(() => self.value && props.game?.started && (gameObject.value[self.value]?.team == props.game.current_turn))
|
const isTurn = computed(() => goStore.self && goStore.game?.started && (goStore.self.team == goStore.game.current_turn))
|
||||||
|
|
||||||
async function buy(cardId: string) {
|
|
||||||
socket.value.send(JSON.stringify({
|
|
||||||
type: "action",
|
|
||||||
data_type: "buy",
|
|
||||||
data: cardId
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
async function endTurn() {
|
|
||||||
socket.value.send(JSON.stringify({
|
|
||||||
type: "action",
|
|
||||||
data_type: "end_turn",
|
|
||||||
data: true
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div @contextmenu.prevent="false">
|
<div @contextmenu.prevent="false">
|
||||||
<button v-if="isTurn" @click="endTurn">END TURN</button>
|
<button v-if="isTurn" @click="endTurn">END TURN</button>
|
||||||
<div v-if="!self"><b>SPECTATOR MODE</b></div>
|
<div v-if="!goStore.self"><b>SPECTATOR MODE</b></div>
|
||||||
<div>
|
<div>
|
||||||
market_amount = {{ props.game.market_stack?.length }}
|
market_amount = {{ goStore.game?.market_stack?.length }}
|
||||||
<br>
|
<br>
|
||||||
market =
|
market =
|
||||||
<div class="cards_container">
|
<div class="cards_container">
|
||||||
|
<CardPreview :data="c" v-for="c in goStore.game?.market">
|
||||||
<CardPreview :data="c" v-for="c in props.game.market">
|
|
||||||
<template v-if="isTurn && c">
|
<template v-if="isTurn && c">
|
||||||
<button @click="buy(c)">BUY</button>
|
<button @click="buy(c)">BUY</button>
|
||||||
<!-- <button @click="buy_in_hand(c)">
|
<!-- <button @click="buy_in_hand(c)">
|
||||||
@@ -50,9 +29,9 @@ async function endTurn() {
|
|||||||
|
|
||||||
<br>
|
<br>
|
||||||
gems =
|
gems =
|
||||||
<CardSlot :stack="props.game.gem_stack">
|
<CardSlot :stack="goStore.game?.gem_stack">
|
||||||
<template v-if="isTurn && props.game.gem_stack.length > 0">
|
<template v-if="isTurn && goStore.game?.gem_stack.length && goStore.game?.gem_stack.length > 0">
|
||||||
<button @click="buy(props.game.gem_stack.at(-1))">
|
<button @click="buy(goStore.game.gem_stack.at(-1)!)">
|
||||||
BUY
|
BUY
|
||||||
</button>
|
</button>
|
||||||
<!-- <button @click="buy_in_hand(props.game.gem_stack.at(-1))">
|
<!-- <button @click="buy_in_hand(props.game.gem_stack.at(-1))">
|
||||||
@@ -65,7 +44,8 @@ async function endTurn() {
|
|||||||
</CardSlot>
|
</CardSlot>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<PlayerList :players="props.game?.players" :current_team="game.current_turn"></PlayerList>
|
<PlayerList>
|
||||||
|
</PlayerList>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,18 +1,11 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import goStore from '@/netcode';
|
||||||
|
|
||||||
export interface Props {
|
|
||||||
players?: string[]
|
|
||||||
current_team?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
|
||||||
players: () => [],
|
|
||||||
})
|
|
||||||
const players = useState<{ [key: string]: any }>('players')
|
const players = useState<{ [key: string]: any }>('players')
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div v-for="player in props.players">
|
<div v-for="[i, p] in goStore.players">
|
||||||
<PlayerSlot :player="players[player]" :current_team="props.current_team" />
|
<PlayerSlot :player="p" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
+32
-71
@@ -1,77 +1,33 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
const props = defineProps(['player', 'current_team'])
|
import goStore, { useEffect, playCard, playAllCards, discard, lockCard } from '~/netcode';
|
||||||
const teams = useState<{ [key: string]: any }>('teams')
|
import type { Card } from '~/netcode/Card';
|
||||||
const effects = useState<{ [key: string]: any }>('effects')
|
import type { Player } from '~/netcode/Player';
|
||||||
const self = useState<string>('self')
|
|
||||||
const turns = useState<{ [key: string]: any }>('turns')
|
|
||||||
const socket = useState<WebSocket>('socket')
|
|
||||||
const isTurn = computed(() => props.player.team == props.current_team)
|
|
||||||
const isSelf = computed(() => props.player.uuid == self.value)
|
|
||||||
|
|
||||||
const selfTurn = computed(() => turns.value[props.player?.turn as string])
|
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 discard_wrapped = ref(false)
|
const discard_wrapped = ref(false)
|
||||||
|
|
||||||
|
|
||||||
function playAllCards() {
|
|
||||||
props.player.hand.forEach((c: any) => {
|
|
||||||
playCard(c)
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function playCard(cardId: string) {
|
|
||||||
socket.value.send(JSON.stringify({
|
|
||||||
type: "action",
|
|
||||||
data_type: "play_card",
|
|
||||||
data: cardId
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
function lockCard(cardId: string) {
|
|
||||||
socket.value.send(JSON.stringify({
|
|
||||||
type: "action",
|
|
||||||
data_type: "lock_card",
|
|
||||||
data: cardId
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
function useEffect(effectId: string, target?: string) {
|
|
||||||
console.log({ effect_id: effectId, target })
|
|
||||||
socket.value.send(JSON.stringify({
|
|
||||||
type: "action",
|
|
||||||
data_type: "use_effect",
|
|
||||||
data: { effect_id: effectId, target }
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
function discard(cardId: string) {
|
|
||||||
socket.value.send(JSON.stringify({
|
|
||||||
type: "action",
|
|
||||||
data_type: "discard",
|
|
||||||
data: cardId
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
function setHealth(event: Event) {
|
|
||||||
socket.value.send(JSON.stringify({
|
|
||||||
type: "temp_action",
|
|
||||||
data_type: "set_health",
|
|
||||||
data: (event.target as HTMLInputElement).value
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div :class="'player ' + (isTurn ? 'turn' : '')">
|
<div :class="'player ' + (isTurn ? 'turn' : '')">
|
||||||
<div id="turn" v-if="turns[props.player?.turn]">
|
<div id="turn" v-if="props.player.turn">
|
||||||
champions_health = {{ turns[props.player?.turn].champions_health }} <br>
|
champions_health = {{ props.player.turn.champions_health }} <br>
|
||||||
heal_reserve = {{ turns[props.player?.turn].heal_reserve }} <br>
|
heal_reserve = {{ props.player.turn.heal_reserve }} <br>
|
||||||
damage_reserve = {{ turns[props.player?.turn].damage_reserve }} <br>
|
damage_reserve = {{ props.player.turn.damage_reserve }} <br>
|
||||||
gold_reserve = {{ turns[props.player?.turn].gold_reserve }} <br>
|
gold_reserve = {{ props.player.turn.gold_reserve }} <br>
|
||||||
discard_markers = {{ turns[props.player?.turn].discard_markers }} <br>
|
discard_markers = {{ props.player.turn.discard_markers }} <br>
|
||||||
effects_availables = <div v-for="e in turns[props.player?.turn].effects_availables" :key="e"
|
effects_availables = <div v-for="e in props.player.turn.effects_availables" :key="e.uuid"
|
||||||
@click="useEffect(e)">
|
@click="useEffect(e)">
|
||||||
{{ effects[e].effect + '*' + 1 }}
|
{{ e.effect + '*' + 1 }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -80,25 +36,30 @@ function setHealth(event: Event) {
|
|||||||
username = <b>{{ props.player.username }}</b>
|
username = <b>{{ props.player.username }}</b>
|
||||||
<br>
|
<br>
|
||||||
health =
|
health =
|
||||||
<template v-if="!isSelf">{{ teams[player.team].health }}</template>
|
<template v-if="!isSelf">{{ player.team.health }}</template>
|
||||||
<input type="number" :value="teams[player.team].health" v-if="isSelf" @change="setHealth" />
|
<!-- <input type="number" :value="player.team.health" v-if="isSelf" @change="setHealth" /> -->
|
||||||
<br>
|
<br>
|
||||||
hand =
|
hand =
|
||||||
<div class="cards_container">
|
<div class="cards_container">
|
||||||
<CardPreview :data="c" v-for="c in props.player.hand">
|
<CardPreview :data="c" v-for="c in props.player.hand">
|
||||||
<button v-if="isSelf && isTurn" @click="playCard(c)">PLAY</button>
|
<button v-if="c && isSelf && isTurn" @click="playCard(c)">PLAY</button>
|
||||||
<button v-if="isSelf && isTurn && selfTurn.discard_markers > 0" @click="discard(c)">DISCARD</button>
|
<button v-if="c && isSelf && isTurn && props.player.turn.discard_markers > 0"
|
||||||
|
@click="discard(c)">DISCARD</button>
|
||||||
</CardPreview>
|
</CardPreview>
|
||||||
</div>
|
</div>
|
||||||
<button v-if="isSelf && isTurn && props.player.hand.length > 1" @click="playAllCards">PLAY
|
<button v-if="isSelf && isTurn && props.player.hand.length > 1"
|
||||||
|
@click="playAllCards(props.player.hand as Card[])">PLAY
|
||||||
ALL</button>
|
ALL</button>
|
||||||
<br>
|
<br>
|
||||||
board =
|
board =
|
||||||
<div class="cards_container">
|
<div class="cards_container">
|
||||||
<CardPreview :data="c" v-for="c in props.player.board"
|
<CardPreview :data="c" v-for="c in props.player.board"
|
||||||
:locked="turns[props.player?.turn].cards_locked.includes(c)">
|
:locked="Object.values(props.player.turn.cards_locked).includes(c)">
|
||||||
<button v-if="isSelf && isTurn && selfTurn.discard_markers > 0" @click="discard(c)">DISCARD</button>
|
<button v-if="isSelf && isTurn && props.player.turn.discard_markers > 0"
|
||||||
<button v-if="isSelf && isTurn && selfTurn.discard_markers == 0" @click="lockCard(c)">LOCK</button>
|
@click="discard(c)">DISCARD</button>
|
||||||
|
<button v-if="isSelf && isTurn && props.player.turn.discard_markers == 0"
|
||||||
|
@click="lockCard(c)">LOCK</button>
|
||||||
|
<button v-if="!isSelf && !isTurn"></button>
|
||||||
</CardPreview>
|
</CardPreview>
|
||||||
</div>
|
</div>
|
||||||
<br>
|
<br>
|
||||||
@@ -112,7 +73,7 @@ function setHealth(event: Event) {
|
|||||||
{{ props.player.discard_pile.length }}
|
{{ props.player.discard_pile.length }}
|
||||||
<input type="checkbox" v-model="discard_wrapped" />
|
<input type="checkbox" v-model="discard_wrapped" />
|
||||||
|
|
||||||
<CardPreview v-if="!discard_wrapped" :data="props.player.discard_pile.at(-1)">
|
<CardPreview v-if="!discard_wrapped" :data="props.player.discard_pile.at(-1) ?? null">
|
||||||
<!-- <button v-if="isSelf && isTurn" @click="play_from_discard(props.player.discard_pile.at(-1))">DRAW</button>
|
<!-- <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
|
<button v-if="isSelf && isTurn" @click="put_on_stack_from_discard(props.player.discard_pile.at(-1))">PUT ON
|
||||||
STACK</button>
|
STACK</button>
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
import type { GameObjectRegister } from "."
|
||||||
|
import type { Effect } from "./Effect"
|
||||||
|
import type { GameObjectNetcode } from "./GameObject"
|
||||||
|
|
||||||
|
enum CardRole {
|
||||||
|
PERSONAL = "personal",
|
||||||
|
MARKET = "market",
|
||||||
|
FIRE_GEM = "fire_gem"
|
||||||
|
}
|
||||||
|
|
||||||
|
enum CardType {
|
||||||
|
HERO = "hero",
|
||||||
|
HERO_ABILITY = "hero_ability",
|
||||||
|
CURRENCY = "currency",
|
||||||
|
WEAPON = "weapon",
|
||||||
|
CHAMPION = "champion",
|
||||||
|
ACTION = "action",
|
||||||
|
ITEM = "item"
|
||||||
|
}
|
||||||
|
|
||||||
|
enum CardFaction {
|
||||||
|
BASE = "base",
|
||||||
|
|
||||||
|
BLUE = "blue",
|
||||||
|
RED = "red",
|
||||||
|
GREEN = "green",
|
||||||
|
YELLOW = "yellow"
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CardNetcode extends GameObjectNetcode {
|
||||||
|
card_id: number
|
||||||
|
sprite: string
|
||||||
|
name: string
|
||||||
|
cost?: number
|
||||||
|
role: CardRole
|
||||||
|
card_type: CardType
|
||||||
|
faction: CardFaction
|
||||||
|
effects: Array<string>
|
||||||
|
defense?: number
|
||||||
|
guard?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Card = Omit<CardNetcode, 'effects'> & {
|
||||||
|
effects: Array<Effect>
|
||||||
|
health_as_champion?: number
|
||||||
|
}
|
||||||
|
export function create_card(input: CardNetcode, register: GameObjectRegister) {
|
||||||
|
const card = new Proxy<any>(input, {
|
||||||
|
get(target: CardNetcode, prop, reciever) {
|
||||||
|
if (prop == "effects") {
|
||||||
|
return target.effects.map((e) => register.effects[e])
|
||||||
|
}
|
||||||
|
if (prop == "health_as_champion") {
|
||||||
|
return Object.values(register.turns).find(e => e.champions_health.has(card))?.champions_health.get(card)
|
||||||
|
}
|
||||||
|
return Reflect.get(target, prop, reciever);
|
||||||
|
},
|
||||||
|
set(target, prop, val, receiver) {
|
||||||
|
return Reflect.set(target, prop, val, receiver);
|
||||||
|
}
|
||||||
|
}) as Card
|
||||||
|
return card
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
import { GameObjectRegister } from "."
|
||||||
|
import type { GameObjectNetcode } from "./GameObject"
|
||||||
|
|
||||||
|
enum CardEffects {
|
||||||
|
GOLD = "gold",
|
||||||
|
DAMAGE = "damage",
|
||||||
|
HEAL = "heal",
|
||||||
|
PERPARE = "prepare",
|
||||||
|
STUN = "stun",
|
||||||
|
SACRIFICE = "sacrifice",
|
||||||
|
DRAW = "draw",
|
||||||
|
DRAW_AND_DISCARD = "draw_and_discard",
|
||||||
|
DISCARD = "discard",
|
||||||
|
RESTACK_DISCARDED_CHAMPION = "restack_discarded_champion",
|
||||||
|
RESTACK_DISCARDED_CARD = "restack_discarded_card",
|
||||||
|
STACK_NEXT_ACTION_BOUGHT = "stack_next_action_bought",
|
||||||
|
STACK_NEXT_CARD_BOUGHT = "stack_next_card_bought",
|
||||||
|
PLAY_NEXT_CARD_BOUGHT = "play_next_card_bought"
|
||||||
|
}
|
||||||
|
|
||||||
|
enum EffectTimes {
|
||||||
|
PER_CHAMPION = "per_champion",
|
||||||
|
PER_OTHER_CHAMPION = "per_other_champion",
|
||||||
|
PER_OTHER_GUARD = "per_other_guard",
|
||||||
|
PER_CARD_OF_SAME_FACTION = "per_card_of_same_faction"
|
||||||
|
}
|
||||||
|
|
||||||
|
enum EffectType {
|
||||||
|
CHAMPION_ACTION = "champion_action",
|
||||||
|
SUICIDE = "suicide",
|
||||||
|
FACTION_COMBO = "faction_combo"
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface EffectNetcode extends GameObjectNetcode {
|
||||||
|
effect: CardEffects
|
||||||
|
amount: number
|
||||||
|
sub_effects: Array<EffectNetcode>
|
||||||
|
mutex: Array<string>
|
||||||
|
effect_type?: EffectType
|
||||||
|
times?: EffectTimes
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Effect = Omit<EffectNetcode, 'sub_effects' | 'mutex'> & {
|
||||||
|
sub_effects: { [key: string]: Effect }
|
||||||
|
mutex: { [key: string]: Effect }
|
||||||
|
}
|
||||||
|
|
||||||
|
export function create_effect(input: EffectNetcode, register: GameObjectRegister) {
|
||||||
|
return new Proxy<any>(input, {
|
||||||
|
get(target, prop, reciever) {
|
||||||
|
if (prop == "sub_effects") {
|
||||||
|
return Object.fromEntries(Object.entries(register.effects).filter(([i, v]) => i in target.sub_effects))
|
||||||
|
}
|
||||||
|
if (prop == "mutex") {
|
||||||
|
return Object.fromEntries(Object.entries(register.effects).filter(([i, v]) => i in target.mutex))
|
||||||
|
}
|
||||||
|
return Reflect.get(target, prop, reciever);
|
||||||
|
},
|
||||||
|
set(target, prop, val, receiver) {
|
||||||
|
return Reflect.set(target, prop, val, receiver);
|
||||||
|
}
|
||||||
|
}) as Effect
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
import { type GameObjectRegister } from "."
|
||||||
|
import { type Team } from "./Team"
|
||||||
|
import { type GameObjectNetcode } from "./GameObject"
|
||||||
|
import type { Card } from "./Card"
|
||||||
|
|
||||||
|
export interface GameNetcode extends GameObjectNetcode {
|
||||||
|
market_stack: Array<string>
|
||||||
|
market: Array<string>
|
||||||
|
gem_stack: Array<string>
|
||||||
|
started: boolean
|
||||||
|
current_turn: string
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export type Game = Omit<GameNetcode, 'market_stack' | 'market' | 'gem_stack' | 'current_turn'> & {
|
||||||
|
market_stack: Array<Card>
|
||||||
|
market: Array<Card | null>
|
||||||
|
gem_stack: Array<Card>
|
||||||
|
current_turn: Team
|
||||||
|
}
|
||||||
|
export function create_game(input: GameNetcode, register: GameObjectRegister) {
|
||||||
|
return new Proxy<any>(input, {
|
||||||
|
get(target, prop, reciever) {
|
||||||
|
if (prop == "market_stack") {
|
||||||
|
return input.market_stack.map(e => register.cards.get(e))
|
||||||
|
}
|
||||||
|
if (prop == "market") {
|
||||||
|
return input.market.map(e => register.cards.get(e))
|
||||||
|
}
|
||||||
|
if (prop == "gem_stack") {
|
||||||
|
return input.gem_stack.map(e => register.cards.get(e))
|
||||||
|
}
|
||||||
|
if (prop == "current_turn") {
|
||||||
|
return register.teams.get(input.current_turn)
|
||||||
|
}
|
||||||
|
return Reflect.get(target, prop, reciever);
|
||||||
|
},
|
||||||
|
set(target, prop, val, receiver) {
|
||||||
|
return Reflect.set(target, prop, val, receiver);
|
||||||
|
}
|
||||||
|
}) as Game
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
export type GameObjectNetcode = {
|
||||||
|
uuid: string
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
import { type GameObjectRegister } from "."
|
||||||
|
import type { Card } from "./Card"
|
||||||
|
import type { GameObjectNetcode } from "./GameObject"
|
||||||
|
import { type Team } from "./Team"
|
||||||
|
import { type Turn } from "./Turn"
|
||||||
|
export interface PlayerNetcode extends GameObjectNetcode {
|
||||||
|
stack_pile: Array<string>
|
||||||
|
discard_pile: Array<string>
|
||||||
|
hand: Array<string>
|
||||||
|
board: Array<string>
|
||||||
|
team: string
|
||||||
|
username: string
|
||||||
|
turn: string
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export type Player = Omit<PlayerNetcode, 'discard_pile' | 'stack_pile' | 'hand' | 'board' | 'team' | 'turn'> & {
|
||||||
|
stack_pile: Array<Card | null>
|
||||||
|
discard_pile: Array<Card>
|
||||||
|
hand: Array<Card | null>
|
||||||
|
board: Array<Card>
|
||||||
|
team: Team
|
||||||
|
turn: Turn
|
||||||
|
}
|
||||||
|
export function create_player(input: PlayerNetcode, register: GameObjectRegister) {
|
||||||
|
return new Proxy<any>(input, {
|
||||||
|
get(target: PlayerNetcode, prop, reciever) {
|
||||||
|
if (prop == "stack_pile") {
|
||||||
|
return target.stack_pile.map(e => register.cards.get(e))
|
||||||
|
}
|
||||||
|
if (prop == "discard_pile") {
|
||||||
|
return target.discard_pile.map(e => register.cards.get(e))
|
||||||
|
}
|
||||||
|
if (prop == "hand") {
|
||||||
|
return target.hand.map(e => register.cards.get(e))
|
||||||
|
}
|
||||||
|
if (prop == "board") {
|
||||||
|
return target.board.map(e => register.cards.get(e))
|
||||||
|
}
|
||||||
|
if (prop == "team") {
|
||||||
|
return register.teams.get(target.team)
|
||||||
|
}
|
||||||
|
if (prop == "turn") {
|
||||||
|
return register.turns.get(target.turn)
|
||||||
|
}
|
||||||
|
return Reflect.get(target, prop, reciever);
|
||||||
|
},
|
||||||
|
set(target, prop, val, receiver) {
|
||||||
|
return Reflect.set(target, prop, val, receiver);
|
||||||
|
}
|
||||||
|
}) as Player
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
import { type GameObjectRegister } from "."
|
||||||
|
import type { GameObjectNetcode } from "./GameObject"
|
||||||
|
import { type Player } from "./Player"
|
||||||
|
|
||||||
|
export interface TeamNetcode extends GameObjectNetcode {
|
||||||
|
health: number
|
||||||
|
color: string
|
||||||
|
name: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Team = TeamNetcode & {
|
||||||
|
players: Array<Player>
|
||||||
|
}
|
||||||
|
|
||||||
|
export function create_team(input: TeamNetcode, register: GameObjectRegister) {
|
||||||
|
const team = new Proxy<any>(input, {
|
||||||
|
get(target: TeamNetcode, prop, reciever) {
|
||||||
|
if (prop == "players") {
|
||||||
|
return Object.values(register.players).filter((p) => p.team == team)
|
||||||
|
}
|
||||||
|
return Reflect.get(target, prop, reciever);
|
||||||
|
},
|
||||||
|
set(target, prop, val, receiver) {
|
||||||
|
return Reflect.set(target, prop, val, receiver);
|
||||||
|
}
|
||||||
|
}) as Team
|
||||||
|
|
||||||
|
return team
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
import { type GameObjectRegister } from "."
|
||||||
|
import type { Card } from "./Card"
|
||||||
|
import { type Effect } from "./Effect"
|
||||||
|
import type { GameObjectNetcode } from "./GameObject"
|
||||||
|
export interface TurnNetcode extends GameObjectNetcode {
|
||||||
|
cards_locked: Array<string>
|
||||||
|
effects_availables: Array<string>
|
||||||
|
champions_health: { [key: string]: string }
|
||||||
|
discard_markers: number
|
||||||
|
damage_reserve: number
|
||||||
|
heal_reserve: number
|
||||||
|
gold_reserve: number
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export type Turn = Omit<TurnNetcode, 'cards_locked' | 'effects_availables' | 'champions_health'> & {
|
||||||
|
cards_locked: { [key: string]: Card }
|
||||||
|
effects_availables: Array<Effect>
|
||||||
|
champions_health: Map<Card, number>
|
||||||
|
}
|
||||||
|
export function create_turn(input: TurnNetcode, register: GameObjectRegister) {
|
||||||
|
return new Proxy<any>(input, {
|
||||||
|
get(target: TurnNetcode, prop, reciever) {
|
||||||
|
if (prop == "card_locked") {
|
||||||
|
return target.cards_locked.map(e => register.cards.get(e))
|
||||||
|
}
|
||||||
|
if (prop == "effects_availables") {
|
||||||
|
return target.effects_availables.map(e => register.effects.get(e))
|
||||||
|
}
|
||||||
|
if (prop == "champions_health") {
|
||||||
|
const healths = new Map()
|
||||||
|
for (const c in target.champions_health) {
|
||||||
|
healths.set(register.cards.get(c), target.champions_health[c])
|
||||||
|
}
|
||||||
|
return healths
|
||||||
|
}
|
||||||
|
return Reflect.get(target, prop, reciever);
|
||||||
|
},
|
||||||
|
set(target, prop, val, receiver) {
|
||||||
|
console.log(isReactive(target))
|
||||||
|
return Reflect.set(target, prop, val, receiver);
|
||||||
|
}
|
||||||
|
}) as Turn
|
||||||
|
}
|
||||||
@@ -0,0 +1,216 @@
|
|||||||
|
import type { RefSymbol } from "@vue/reactivity"
|
||||||
|
import { type Card, create_card, type CardNetcode } from "./Card"
|
||||||
|
import { type Effect, create_effect, type EffectNetcode } from "./Effect"
|
||||||
|
import { type Game, create_game, type GameNetcode } from "./Game"
|
||||||
|
import type { GameObjectNetcode } from "./GameObject"
|
||||||
|
import { type Player, create_player, type PlayerNetcode } from "./Player"
|
||||||
|
import { type Team, create_team, type TeamNetcode } from "./Team"
|
||||||
|
import { type Turn, create_turn } from "./Turn"
|
||||||
|
|
||||||
|
import { isReactive } from "vue"
|
||||||
|
|
||||||
|
export const socket = new WebSocket("ws://127.0.0.1:8765")
|
||||||
|
|
||||||
|
export class GameObjectRegister {
|
||||||
|
|
||||||
|
readonly effects: Map<string, Effect>
|
||||||
|
readonly cards: Map<string, Card>
|
||||||
|
readonly teams: Map<string, Team>
|
||||||
|
readonly players: Map<string, Player>
|
||||||
|
readonly turns: Map<string, Turn>
|
||||||
|
|
||||||
|
context: 'login' | 'pregame' | 'game' = "login"
|
||||||
|
private readonly objects: Map<string, GameObjectNetcode>
|
||||||
|
game?: Game
|
||||||
|
self?: Player
|
||||||
|
constructor() {
|
||||||
|
this.effects = reactive(new Map())
|
||||||
|
this.cards = reactive(new Map())
|
||||||
|
this.teams = reactive(new Map())
|
||||||
|
this.players = reactive(new Map())
|
||||||
|
this.turns = reactive(new Map())
|
||||||
|
|
||||||
|
this.objects = reactive(new Map())
|
||||||
|
}
|
||||||
|
|
||||||
|
update_object(obj: GameObjectNetcode) {
|
||||||
|
Object.assign(this.objects.get(obj.uuid) as GameNetcode, obj)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
createObject = {
|
||||||
|
"effect": (data: EffectNetcode) => {
|
||||||
|
const effect = create_effect(data, this)
|
||||||
|
this.effects.set(data.uuid, effect)
|
||||||
|
this.objects.set(data.uuid, data)
|
||||||
|
},
|
||||||
|
"card": (data: CardNetcode) => {
|
||||||
|
const card = create_card(data, this)
|
||||||
|
this.cards.set(data.uuid, card)
|
||||||
|
this.objects.set(data.uuid, card)
|
||||||
|
},
|
||||||
|
"player": (data: PlayerNetcode) => {
|
||||||
|
const player = create_player(data, this)
|
||||||
|
this.players.set(data.uuid, player)
|
||||||
|
this.objects.set(data.uuid, player)
|
||||||
|
},
|
||||||
|
"team": (data: TeamNetcode) => {
|
||||||
|
const team = create_team(data, this)
|
||||||
|
this.teams.set(data.uuid, team)
|
||||||
|
this.objects.set(data.uuid, team)
|
||||||
|
},
|
||||||
|
"game": (data: GameNetcode) => {
|
||||||
|
this.game = create_game(data, this)
|
||||||
|
this.objects.set(data.uuid, this.game)
|
||||||
|
},
|
||||||
|
"turn": (data: any) => {
|
||||||
|
const turn = create_turn(data, this)
|
||||||
|
this.turns.set(data.uuid, turn)
|
||||||
|
this.objects.set(data.uuid, turn)
|
||||||
|
}
|
||||||
|
} as { [id: string]: (data: any) => any }
|
||||||
|
|
||||||
|
set_self(uuid: string) {
|
||||||
|
this.self = this.players.get(uuid)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const goStore = reactive(new GameObjectRegister())
|
||||||
|
|
||||||
|
|
||||||
|
socket.onopen = function (e) {
|
||||||
|
console.log("[open] Connection established");
|
||||||
|
};
|
||||||
|
|
||||||
|
socket.onclose = function (event) {
|
||||||
|
if (event.wasClean) {
|
||||||
|
console.warn(`[close] Connection closed cleanly, code=${event.code} reason=${event.reason}`);
|
||||||
|
} else {
|
||||||
|
// e.g. server process killed or network down
|
||||||
|
// event.code is usually 1006 in this case
|
||||||
|
console.error('[close] Connection died');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
socket.onerror = function (error) {
|
||||||
|
console.error(error);
|
||||||
|
};
|
||||||
|
|
||||||
|
socket.onmessage = function (event) {
|
||||||
|
const data = JSON.parse(event.data)
|
||||||
|
|
||||||
|
|
||||||
|
if (data.type == "create" && data.data_type == "object") {
|
||||||
|
if (!(data.data.object_type in goStore.createObject)) {
|
||||||
|
throw new Error(`Object ${data.data.object_type} couldn't be created`)
|
||||||
|
}
|
||||||
|
goStore.createObject[data.data.object_type](data.data)
|
||||||
|
} else if (data.type == "update" && data.data_type == "object") {
|
||||||
|
goStore.update_object(data.data)
|
||||||
|
} else if (data.type === "context") {
|
||||||
|
goStore.context = data.data
|
||||||
|
console.log(data.data)
|
||||||
|
} else if (data.type === "set" && data.data_type == "self") {
|
||||||
|
goStore.set_self(data.data)
|
||||||
|
} else {
|
||||||
|
console.log(data.type, data.data_type, data.data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export async function register(username: string) {
|
||||||
|
socket.send(JSON.stringify({
|
||||||
|
type: "register",
|
||||||
|
data_type: "username",
|
||||||
|
data: username
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function login(username: string) {
|
||||||
|
socket.send(JSON.stringify({
|
||||||
|
type: "login",
|
||||||
|
data_type: "username",
|
||||||
|
data: username
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function setReady(value: boolean) {
|
||||||
|
socket.send(JSON.stringify({
|
||||||
|
type: "ready",
|
||||||
|
data_type: "ready_state",
|
||||||
|
data: value
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function buy(card: Card) {
|
||||||
|
socket.send(JSON.stringify({
|
||||||
|
type: "action",
|
||||||
|
data_type: "buy",
|
||||||
|
data: card.uuid
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function endTurn() {
|
||||||
|
socket.send(JSON.stringify({
|
||||||
|
type: "action",
|
||||||
|
data_type: "end_turn",
|
||||||
|
data: true
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
export function playAllCards(cards: Card[]) {
|
||||||
|
cards.forEach((c: any) => {
|
||||||
|
playCard(c)
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export function playCard(card: Card) {
|
||||||
|
console.log(card.uuid)
|
||||||
|
socket.send(JSON.stringify({
|
||||||
|
type: "action",
|
||||||
|
data_type: "play_card",
|
||||||
|
data: card.uuid
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
export function lockCard(card: Card) {
|
||||||
|
socket.send(JSON.stringify({
|
||||||
|
type: "action",
|
||||||
|
data_type: "lock_card",
|
||||||
|
data: card.uuid
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useEffect(effect: Effect, target?: Effect | Card | Player | Team) {
|
||||||
|
console.log({ effect_id: effect.uuid, target: target?.uuid })
|
||||||
|
socket.send(JSON.stringify({
|
||||||
|
type: "action",
|
||||||
|
data_type: "use_effect",
|
||||||
|
data: { effect_id: effect.uuid, target: target?.uuid }
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
export function discard(card: Card) {
|
||||||
|
socket.send(JSON.stringify({
|
||||||
|
type: "action",
|
||||||
|
data_type: "discard",
|
||||||
|
data: card.uuid
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
h
|
||||||
|
export function heal() {
|
||||||
|
socket.send(JSON.stringify({
|
||||||
|
type: "action",
|
||||||
|
data_type: "heal",
|
||||||
|
data: 1
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
export function damage(target: Team) {
|
||||||
|
socket.send(JSON.stringify({
|
||||||
|
type: "action",
|
||||||
|
data_type: "damage",
|
||||||
|
data: target.uuid
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
export default goStore
|
||||||
Reference in New Issue
Block a user