|
|
|
@ -1,10 +1,9 @@ |
|
|
|
|
import { nextTick, watch, reactive, ref, computed, onMounted, onUnmounted } from "vue"; |
|
|
|
|
import { reactive, ref, computed, onMounted, toRaw } from "vue"; |
|
|
|
|
import { getQuery, setKirby } from "../../kirby.js"; |
|
|
|
|
import { state } from "../../stateMgr.js"; |
|
|
|
|
import { handleActive, ArrowVerticalKeyHandler, ArrowHorizontalKeyHandler, NumberKeyHandler } from "../../handlers.js"; |
|
|
|
|
import { overlayAndGet, powerStateMachine, overlayAndPop, popLastElem } from "../../componentPromise.js"; |
|
|
|
|
|
|
|
|
|
import { getGameProps, initGame, initStats, storeVisit, formatDate, removeLastVisit, extension, getFinalWinner } from "./logic.js"; |
|
|
|
|
import { getGameProps, initGame, initStats, storeVisit, formatDate, removeLastVisit, extension, getFinalWinner, playerFromUUID } from "./logic.js"; |
|
|
|
|
|
|
|
|
|
const html = (v) => { return v[0] }; |
|
|
|
|
|
|
|
|
@ -19,13 +18,29 @@ const pregame = { |
|
|
|
|
|
|
|
|
|
const selectPlayer = async (i) => { |
|
|
|
|
if (props.active) { |
|
|
|
|
const [result, error] = await overlayAndPop("d-playerSelect", { players: props.page.participants, class:"overlay"}, props.stack); |
|
|
|
|
let [result, error] = await overlayAndPop("d-select", { type: "player", options: props.page.participants, class:"overlay"}, props.stack); |
|
|
|
|
if (error === undefined) { |
|
|
|
|
props.page.players[i] = result; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const selectScorer = async (i) => { |
|
|
|
|
if (props.active) { |
|
|
|
|
const [scorer, error] = await overlayAndPop("d-select", { type: "scorer", options: props.page.participants, class:"overlay"}, props.stack); |
|
|
|
|
if (error === undefined) { |
|
|
|
|
if (scorer.member.length > 1){
|
|
|
|
|
const [captain, err] = await overlayAndPop("d-select", { type: "player", title: "Team Captain", options: [scorer.member[0],scorer.member[1]], class:"overlay"}, props.stack); |
|
|
|
|
if (err !== undefined){ |
|
|
|
|
return selectScorer(i); |
|
|
|
|
} |
|
|
|
|
scorer.member = [captain, scorer.member[0] == captain ? scorer.member[1] : scorer.member[0]]; |
|
|
|
|
} |
|
|
|
|
props.page.scorers[i] = scorer; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const selectX01 = async () => { |
|
|
|
|
if (props.active) { |
|
|
|
|
const [result, error] = await overlayAndPop("d-select", { options: [ "301", "501" ], class:"overlay"}, props.stack); |
|
|
|
@ -44,15 +59,16 @@ const pregame = { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return { selectPlayer, selectX01, selectIn } |
|
|
|
|
return { selectX01, selectIn, selectScorer } |
|
|
|
|
}, |
|
|
|
|
template: html` |
|
|
|
|
<nav class="gamesetup" :disabled="!active"> |
|
|
|
|
<h1>Game Setup</h1> |
|
|
|
|
<div class="menu"> |
|
|
|
|
<!-- <div><span class="label">Name:</span><d-inputElem v-index="active" v-model="game.title"></d-inputElem></div> --> |
|
|
|
|
<div><span class="label">Player 1:</span><d-playerElem v-index="active" @click="selectPlayer(0)" :player="page.players[0]"></d-playerElem></div> |
|
|
|
|
<div><span class="label">Player 2:</span><d-playerElem v-index="active" @click="selectPlayer(1)" :player="page.players[1]"></d-playerElem></div> |
|
|
|
|
<div><span class="label">Scorer 1:</span><d-scorerElem v-index="active" @click="selectScorer(0)" :scorer="page.scorers[0]"></d-scorerElem></div> |
|
|
|
|
<div><span class="label">Scorer 2:</span><d-scorerElem v-index="active" @click="selectScorer(1)" :scorer="page.scorers[1]"></d-scorerElem></div> |
|
|
|
|
|
|
|
|
|
<div><span class="label">X01:</span><d-plainElem v-index="active" @click="selectX01()" :text="page.modus"></d-plainElem></div> |
|
|
|
|
<div><span class="label">In:</span><d-plainElem v-index="active" @click="selectIn()" :text="page.in"></d-plainElem></div> |
|
|
|
|
<!-- <div><span class="label">Best of Sets:</span><d-inputElem v-index="active" v-model="page.sets"></d-inputElem></div> --> |
|
|
|
@ -64,14 +80,15 @@ const pregame = { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
export const bullselect = { |
|
|
|
|
props: ['players','active', 'stack'], |
|
|
|
|
props: ['scorers', 'active', 'stack'], |
|
|
|
|
setup(props, { emit }) { |
|
|
|
|
handleActive(props, [ArrowHorizontalKeyHandler, NumberKeyHandler]); |
|
|
|
|
|
|
|
|
|
const children = computed(() => { |
|
|
|
|
const items = []; |
|
|
|
|
for (let i in props.players){ |
|
|
|
|
const player = props.players[i]; |
|
|
|
|
for (let i in props.scorers){ |
|
|
|
|
const player = props.scorers[i].member[0]; |
|
|
|
|
|
|
|
|
|
items.push({ |
|
|
|
|
component: "d-squareElem", |
|
|
|
|
props: { |
|
|
|
@ -79,7 +96,7 @@ export const bullselect = { |
|
|
|
|
icon: player.img ? player.img : '/assets/img/placeholder_person.png' |
|
|
|
|
}, |
|
|
|
|
onClick: () => { |
|
|
|
|
emit("resolve", player); |
|
|
|
|
emit("resolve", props.scorers[i]); |
|
|
|
|
} |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
@ -123,8 +140,8 @@ const score = { |
|
|
|
|
` |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const player = { |
|
|
|
|
props: ['page', 'id', 'current_stat'], |
|
|
|
|
const scorer = { |
|
|
|
|
props: ['page', 'id', 'current_stat', 'current_leg'], |
|
|
|
|
setup(props) { |
|
|
|
|
const addStats = (stat1, stat2) => { |
|
|
|
|
let res = { |
|
|
|
@ -146,23 +163,17 @@ const player = { |
|
|
|
|
} |
|
|
|
|
const inspect = !!props.page.enddate; |
|
|
|
|
const tourStats = computed(() => { |
|
|
|
|
if (props.page.tournamentStats.length != 2){ |
|
|
|
|
return [ |
|
|
|
|
props.page.stats.stats[0], |
|
|
|
|
props.page.stats.stats[1] |
|
|
|
|
]; |
|
|
|
|
} |
|
|
|
|
if (inspect) { |
|
|
|
|
return [ |
|
|
|
|
props.page.tournamentStats[0], |
|
|
|
|
props.page.tournamentStats[1] |
|
|
|
|
]; |
|
|
|
|
return props.page.tournamentStats; |
|
|
|
|
} |
|
|
|
|
return [ |
|
|
|
|
addStats(props.page.tournamentStats[0], props.page.stats.stats[0]), |
|
|
|
|
addStats(props.page.tournamentStats[1], props.page.stats.stats[1]) |
|
|
|
|
]; |
|
|
|
|
return props.page.tournamentStats.map((s,i) => { |
|
|
|
|
if (s.length == 0){ |
|
|
|
|
return props.page.stats.stats[i]; |
|
|
|
|
} |
|
|
|
|
return addStats(s,props.page.stats.stats[i]) |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
const getAverage = (avg) => { |
|
|
|
|
return avg && avg[1] != 0 ? ((3*avg[0])/avg[1]).toFixed(1) : "-"; |
|
|
|
|
} |
|
|
|
@ -175,59 +186,113 @@ const player = { |
|
|
|
|
} |
|
|
|
|
return "-" |
|
|
|
|
} |
|
|
|
|
const player = computed(() => props.page.players[props.id]) |
|
|
|
|
return { tourStats, getAverage, getCheckout, getMax, player } |
|
|
|
|
|
|
|
|
|
const scorer = ref(props.page.scorers[props.id]); |
|
|
|
|
const allScorerIndices = computed(() => scorer.value.member.map((p) => props.page.stats.stats.map((s) => s.player).indexOf(p.uuid))); |
|
|
|
|
|
|
|
|
|
const currentScorerIdx = computed(() => { |
|
|
|
|
if (scorer.value.member.length == 1){ |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
const idx = props.page.scorers[props.id].member.map((p) => p.uuid).indexOf(props.current_leg.visits.at(-1).player);
|
|
|
|
|
return idx; |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
const tnmStats = computed(() => { |
|
|
|
|
if (currentScorerIdx.value == -1){ |
|
|
|
|
return addStats(tourStats.value[allScorerIndices.value[0]], tourStats.value[allScorerIndices.value[1]]); |
|
|
|
|
} |
|
|
|
|
return tourStats.value[allScorerIndices.value[currentScorerIdx.value]]; |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
const matchStats = computed(() => { |
|
|
|
|
if (currentScorerIdx.value == -1){ |
|
|
|
|
return addStats(props.page.stats.stats[allScorerIndices.value[0]], props.page.stats.stats[allScorerIndices.value[1]]); |
|
|
|
|
} |
|
|
|
|
return props.page.stats.stats[allScorerIndices.value[currentScorerIdx.value]]; |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
const legStats = computed(() => { |
|
|
|
|
if (currentScorerIdx.value == -1){ |
|
|
|
|
return addStats(props.current_stat.stats[allScorerIndices.value[0]], props.current_stat.stats[allScorerIndices.value[1]]); |
|
|
|
|
} |
|
|
|
|
return props.current_stat.stats[allScorerIndices.value[currentScorerIdx.value]]; |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return { tnmStats, matchStats, legStats, getAverage, getCheckout, getMax, scorer, currentScorerIdx } |
|
|
|
|
}, |
|
|
|
|
template: html` |
|
|
|
|
<div class="player"> |
|
|
|
|
<img style="width: 100%" :src="player.img ? player.img : '/assets/img/placeholder_person.png'"> |
|
|
|
|
<h2 class="name">{{ player.forename }} {{ player.surname }}</h2> |
|
|
|
|
<h3 class="nickname">{{ player.nickname }}</h3> |
|
|
|
|
<div class="player" :class="{ 'team': scorer.member.length == 2 }"> |
|
|
|
|
<template v-if="scorer.member.length == 1"> |
|
|
|
|
<img style="width: 100%" :src="scorer.member[0].img ? scorer.member[0].img : '/assets/img/placeholder_person.png'"> |
|
|
|
|
<h2 class="name">{{ scorer.member[0].forename }} {{ scorer.member[0].surname }}</h2> |
|
|
|
|
<h3 class="nickname">{{ scorer.member[0].nickname }}</h3> |
|
|
|
|
</template> |
|
|
|
|
<template v-if="scorer.member.length == 2"> |
|
|
|
|
<div class="team images"> |
|
|
|
|
<img :class="{ 'active': currentScorerIdx == 0, 'inactive': currentScorerIdx == 1 }" :src="scorer.member[0].img ? scorer.member[0].img : '/assets/img/placeholder_person.png'"> |
|
|
|
|
<img :class="{ 'active': currentScorerIdx == 1, 'inactive': currentScorerIdx == 0 }" :src="scorer.member[1].img ? scorer.member[1].img : '/assets/img/placeholder_person.png'"> |
|
|
|
|
</div> |
|
|
|
|
<div class="team titles"> |
|
|
|
|
<div class="title" :class="{ 'active': currentScorerIdx == -1 }"> |
|
|
|
|
<h2 class="name">{{ scorer.member[0].forename }} + {{ scorer.member[1].forename }}</h2> |
|
|
|
|
</div> |
|
|
|
|
<div class="title" :class="{ 'active': currentScorerIdx == 0 }"> |
|
|
|
|
<h2 class="name">{{ scorer.member[0].forename }} {{ scorer.member[0].surname }}</h2> |
|
|
|
|
<h3 class="nickname">{{ scorer.member[0].nickname }}</h3> |
|
|
|
|
</div> |
|
|
|
|
<div class="title" :class="{ 'active': currentScorerIdx == 1 }"> |
|
|
|
|
<h2 class="name">{{ scorer.member[1].forename }} {{ scorer.member[1].surname }}</h2> |
|
|
|
|
<h3 class="nickname">{{ scorer.member[1].nickname }}</h3> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
</template> |
|
|
|
|
<div class="stats"> |
|
|
|
|
<div class="row header"> |
|
|
|
|
<div>Stat</div><div>Tnm</div><div>Match</div><div>Leg</div> |
|
|
|
|
</div> |
|
|
|
|
<div class="row"> |
|
|
|
|
<div>Avg:</div><div> |
|
|
|
|
{{ getAverage(tourStats[id].average) }} |
|
|
|
|
{{ getAverage(tnmStats.average) }} |
|
|
|
|
</div><div> |
|
|
|
|
{{ getAverage(page.stats.stats[id].average) }} |
|
|
|
|
{{ getAverage(matchStats.average) }} |
|
|
|
|
</div><div> |
|
|
|
|
{{ getAverage(current_stat.stats[id].average) }} |
|
|
|
|
{{ getAverage(legStats.average) }} |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
<div class="row"> |
|
|
|
|
<div>First 9:</div><div> |
|
|
|
|
{{ getAverage(tourStats[id].first9) }} |
|
|
|
|
{{ getAverage(tnmStats.first9) }} |
|
|
|
|
</div><div> |
|
|
|
|
{{ getAverage(page.stats.stats[id].first9) }} |
|
|
|
|
{{ getAverage(matchStats.first9) }} |
|
|
|
|
</div><div> |
|
|
|
|
{{ getAverage(current_stat.stats[id].first9) }} |
|
|
|
|
{{ getAverage(legStats.first9) }} |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
<div class="row"> |
|
|
|
|
<div>60+:</div><div>{{ tourStats[id]["60+"] }}</div><div>{{ page.stats.stats[id]["60+"] }}</div><div>{{ current_stat.stats[id]["60+"] }}</div> |
|
|
|
|
<div>60+:</div><div>{{ tnmStats["60+"] }}</div><div>{{ matchStats["60+"] }}</div><div>{{ legStats["60+"] }}</div> |
|
|
|
|
</div> |
|
|
|
|
<div class="row"> |
|
|
|
|
<div>100+:</div><div>{{ tourStats[id]["100+"] }}</div><div>{{ page.stats.stats[id]["100+"] }}</div><div>{{ current_stat.stats[id]["100+"] }}</div> |
|
|
|
|
<div>100+:</div><div>{{ tnmStats["100+"] }}</div><div>{{ matchStats["100+"] }}</div><div>{{ legStats["100+"] }}</div> |
|
|
|
|
</div> |
|
|
|
|
<div class="row"> |
|
|
|
|
<div>140+:</div><div>{{ tourStats[id]["140+"] }}</div><div>{{ page.stats.stats[id]["140+"] }}</div><div>{{ current_stat.stats[id]["140+"] }}</div> |
|
|
|
|
<div>140+:</div><div>{{ tnmStats["140+"] }}</div><div>{{ matchStats["140+"] }}</div><div>{{ legStats["140+"] }}</div> |
|
|
|
|
</div> |
|
|
|
|
<div class="row"> |
|
|
|
|
<div>180:</div><div>{{ tourStats[id]["180"] }}</div><div>{{ page.stats.stats[id]["180"] }}</div><div>{{ current_stat.stats[id]["180"] }}</div> |
|
|
|
|
<div>180:</div><div>{{ tnmStats["180"] }}</div><div>{{ matchStats["180"] }}</div><div>{{ legStats["180"] }}</div> |
|
|
|
|
</div> |
|
|
|
|
<div class="row" v-if="page.in == 'Double'"> |
|
|
|
|
<div>Ch. I. %:</div><div>{{ getCheckout(tourStats[id].checkins) }}%</div><div>{{ getCheckout(page.stats.stats[id].checkins) }}%</div><div>{{ getCheckout(current_stat.stats[id].checkins) }}%</div> |
|
|
|
|
<div>Ch. I. %:</div><div>{{ getCheckout(tnmStats.checkins) }}%</div><div>{{ getCheckout(matchStats.checkins) }}%</div><div>{{ getCheckout(legStats.checkins) }}%</div> |
|
|
|
|
</div> |
|
|
|
|
<div class="row" v-if="page.in == 'Double'"> |
|
|
|
|
<div>Best Ch.:</div><div>{{ getMax(tourStats[id].checkinPoints) }}</div><div>{{ getMax(page.stats.stats[id].checkinPoints) }}</div><div>{{ getMax(current_stat.stats[id].checkinPoints) }}</div> |
|
|
|
|
<div>Best Ch.:</div><div>{{ getMax(tnmStats.checkinPoints) }}</div><div>{{ getMax(matchStats.checkinPoints) }}</div><div>{{ getMax(legStats.checkinPoints) }}</div> |
|
|
|
|
</div> |
|
|
|
|
<div class="row"> |
|
|
|
|
<div>Ch. O. %:</div><div>{{ getCheckout(tourStats[id].checkouts) }}%</div><div>{{ getCheckout(page.stats.stats[id].checkouts) }}%</div><div></div> |
|
|
|
|
<div>Ch. O. %:</div><div>{{ getCheckout(tnmStats.checkouts) }}%</div><div>{{ getCheckout(matchStats.checkouts) }}%</div><div></div> |
|
|
|
|
</div> |
|
|
|
|
<div class="row"> |
|
|
|
|
<div>Best Ch.:</div><div>{{ getMax(tourStats[id].checkoutPoints) }}</div><div>{{ getMax(page.stats.stats[id].checkoutPoints) }}</div><div></div> |
|
|
|
|
<div>Best Ch.:</div><div>{{ getMax(tnmStats.checkoutPoints) }}</div><div>{{ getMax(matchStats.checkoutPoints) }}</div><div></div> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
@ -236,11 +301,15 @@ const player = { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const game = { |
|
|
|
|
props: ['active', 'stack', 'players','current_leg', 'max'], |
|
|
|
|
props: ['active', 'stack', 'scorers', 'current_leg', 'max'], |
|
|
|
|
setup(props, context) { |
|
|
|
|
const visits = computed(() => props.current_leg ? props.current_leg.visits:undefined ); |
|
|
|
|
const getPlayerVisits = (uuid) => { |
|
|
|
|
const vs = visits.value.filter((v) => v.player == uuid); |
|
|
|
|
const visits = computed(() => props.current_leg ? props.current_leg.visits : undefined ); |
|
|
|
|
|
|
|
|
|
const getScorersVisits = (scorer) => { |
|
|
|
|
|
|
|
|
|
// const vs = visits.value.filter((v,i) => i % 2 == props.scorers.map((p) => p.uuid).indexOf(uuid) % 2);
|
|
|
|
|
const vs = visits.value.filter((v,i) => scorer.member.map((p) => p.uuid).indexOf(v.player) != -1); |
|
|
|
|
|
|
|
|
|
if (vs.length < 9) { |
|
|
|
|
for (var i = vs.length; i < 9; i++) { |
|
|
|
|
vs.push({ "sum": "", "toGo":["",""]}) |
|
|
|
@ -251,34 +320,34 @@ const game = { |
|
|
|
|
} |
|
|
|
|
return vs; |
|
|
|
|
} |
|
|
|
|
return { getPlayerVisits } |
|
|
|
|
return { getScorersVisits } |
|
|
|
|
}, |
|
|
|
|
template: html` |
|
|
|
|
<div class="game"> |
|
|
|
|
<div class="headding"> |
|
|
|
|
<div class="headding points player1">Points</div> |
|
|
|
|
<div class="headding toGo player1">ToGo</div> |
|
|
|
|
<div class="headding points scorer1">Points</div> |
|
|
|
|
<div class="headding toGo scorer1">ToGo</div> |
|
|
|
|
<div class="headding rounds">Round</div> |
|
|
|
|
<div class="headding points player2">Points</div> |
|
|
|
|
<div class="headding toGo player2">ToGo</div> |
|
|
|
|
<div class="headding points scorer2">Points</div> |
|
|
|
|
<div class="headding toGo scorer2">ToGo</div> |
|
|
|
|
</div> |
|
|
|
|
<div class="body"> |
|
|
|
|
<div class="points player1"></div> |
|
|
|
|
<div class="toGo player1">{{ max }}</div> |
|
|
|
|
<div class="points scorer1"></div> |
|
|
|
|
<div class="toGo scorer1">{{ max }}</div> |
|
|
|
|
<div class="rounds">0</div> |
|
|
|
|
<div class="points player2"></div> |
|
|
|
|
<div class="toGo player2">{{ max }}</div> |
|
|
|
|
<template v-for="j in [1,2]" v-if="players"> |
|
|
|
|
<template v-for="visit, i in getPlayerVisits(players[j-1].uuid)"> |
|
|
|
|
<div class="points scorer2"></div> |
|
|
|
|
<div class="toGo scorer2">{{ max }}</div> |
|
|
|
|
<template v-for="j in [1,2]" v-if="scorers"> |
|
|
|
|
<template v-for="visit, i in getScorersVisits(scorers[j-1])"> |
|
|
|
|
<template v-if="visit.toGo === undefined"> |
|
|
|
|
<div :class="'points player'+j+' input'"> |
|
|
|
|
<div :class="'points scorer'+j+' input'"> |
|
|
|
|
<slot /> |
|
|
|
|
</div> |
|
|
|
|
<div :class="'toGo player'+j"></div> |
|
|
|
|
<div :class="'toGo scorer'+j"></div> |
|
|
|
|
</template> |
|
|
|
|
<template v-if="visit.toGo !== undefined"> |
|
|
|
|
<div :class="'points player'+j">{{ visit.sum }}</div> |
|
|
|
|
<div :class="'toGo player'+j">{{ visit.toGo[j-1] }}</div> |
|
|
|
|
<div :class="'points scorer'+j">{{ visit.sum }}</div> |
|
|
|
|
<div :class="'toGo scorer'+j">{{ visit.toGo[j-1] }}</div> |
|
|
|
|
</template> |
|
|
|
|
<div class="rounds" v-if="j == 1">{{ (i+1)*3 }}</div> |
|
|
|
|
</template> |
|
|
|
@ -328,7 +397,7 @@ const gameinput = { |
|
|
|
|
const xoi = { |
|
|
|
|
props: ['page', 'active', 'stack', 'inspect', 'watch'], |
|
|
|
|
components: { |
|
|
|
|
"d-player": player, |
|
|
|
|
"d-scorer": scorer, |
|
|
|
|
"d-score": score, |
|
|
|
|
"d-game": game |
|
|
|
|
}, |
|
|
|
@ -342,7 +411,7 @@ const xoi = { |
|
|
|
|
if (props.inspect) { |
|
|
|
|
current_set = computed(() => props.page.game.sets[set_id.value]); |
|
|
|
|
current_leg = computed(() => current_set.value.legs[leg_id.value]); |
|
|
|
|
current_stat = computed( () => props.page.stats?.sets[set_id.value].legs[leg_id.value]); |
|
|
|
|
current_stat = computed(() => props.page.stats?.sets[set_id.value].legs[leg_id.value]); |
|
|
|
|
} |
|
|
|
|
if (props.watch) { |
|
|
|
|
setInterval(async () => { |
|
|
|
@ -352,6 +421,7 @@ const xoi = { |
|
|
|
|
}, 2000); |
|
|
|
|
} |
|
|
|
|
const computedProps = getGameProps(props.page, current_set, current_leg); |
|
|
|
|
|
|
|
|
|
if (!props.inspect) { |
|
|
|
|
current_stat = computed( () => props.page.stats?.sets[props.page.stats.sets.length-1].legs[computedProps.current_set.value.legs.length-1]); |
|
|
|
|
} |
|
|
|
@ -360,21 +430,25 @@ const xoi = { |
|
|
|
|
if (props.inspect || props.watch) { |
|
|
|
|
} else { |
|
|
|
|
const winner = await gameHandler(gamestack, props.stack, props.page, computedProps) |
|
|
|
|
context.emit('resolve', winner); |
|
|
|
|
if (winner === undefined){ |
|
|
|
|
context.emit('reject', winner); |
|
|
|
|
} else { |
|
|
|
|
context.emit('resolve', winner); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
}) |
|
|
|
|
return { ...computedProps, set_id, leg_id, gamestack, inspectstack, current_stat } |
|
|
|
|
}, |
|
|
|
|
template: html` |
|
|
|
|
<div class="xoi"> |
|
|
|
|
<div class="bigToGo one" :class="{'active' : current_player==0 }">{{ current_toGo[0] }}</div> |
|
|
|
|
<div class="bigToGo one" :class="{'active' : current_scorer_idx==0 }">{{ current_toGo[0] }}</div> |
|
|
|
|
<d-score :page="page" :justlegs="page && page.sets == 1" :current_set_points="current_set_points" :current_leg_points="current_leg_points"></d-score> |
|
|
|
|
<div class="bigToGo two" :class="{'active' : current_player==1 }">{{ current_toGo[1] }}</div> |
|
|
|
|
<d-player class="player1" :page="page" :id="0" :current_stat="current_stat"></d-player> |
|
|
|
|
<d-game :active="active" :stack="stack" :players="page.players" :max="page.modus" :current_leg="current_leg" > |
|
|
|
|
<div class="bigToGo two" :class="{'active' : current_scorer_idx==1 }">{{ current_toGo[1] }}</div> |
|
|
|
|
<d-scorer class="scorer1" :page="page" :id="0" :current_stat="current_stat" :current_leg="current_leg"></d-scorer> |
|
|
|
|
<d-game :active="active" :stack="stack" :scorers="page.scorers" :max="page.modus" :current_leg="current_leg" > |
|
|
|
|
<d-renderer :stack="gamestack"></d-renderer> |
|
|
|
|
</d-game> |
|
|
|
|
<d-player class="player2" :page="page" :id="1" :current_stat="current_stat"></d-player> |
|
|
|
|
<d-scorer class="scorer2" :page="page" :id="1" :current_stat="current_stat" :current_leg="current_leg"></d-scorer> |
|
|
|
|
<div class="nav" v-if="inspect"> |
|
|
|
|
<span class="label" v-if="page.sets != 1">Set:</span><d-plainElem :text="set_id+1" v-if="page.sets != 1" v-index="active" @click="set_id = (set_id+1)%page.game.sets.length; leg_id=0"></d-plainElem><span class="label">Leg:</span><d-plainElem style="padding:0.2em 0.5em" :text="leg_id+1" v-index="active" v-autofocus="true" @click="leg_id = (leg_id+1)%current_set.legs.length"></d-plainElem> |
|
|
|
|
</div> |
|
|
|
@ -494,12 +568,27 @@ function refreshGame(id){ |
|
|
|
|
return getQuery(`site.find('${id}')`, { |
|
|
|
|
select: { |
|
|
|
|
game: "page.rounds.parseJSON", |
|
|
|
|
stats: "page.stats.parseJSON" |
|
|
|
|
stats: "page.stats.parseJSON", |
|
|
|
|
tournamentStats: "page.tournamentStats" |
|
|
|
|
} |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
async function reloadGame(page){ |
|
|
|
|
let gs = await refreshGame(page.id); |
|
|
|
|
page.game = gs.game; |
|
|
|
|
page.stats = gs.stats; |
|
|
|
|
page.tournamentStats = gs.tournamentStats; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function getGame(id){ |
|
|
|
|
const playerInfo = { |
|
|
|
|
forename: "page.forename", |
|
|
|
|
surname: "page.surname", |
|
|
|
|
nickname: "page.nickname", |
|
|
|
|
uuid: "page.uuid", |
|
|
|
|
img: "page.pic.toFile?.thumbnail(350).url" |
|
|
|
|
}; |
|
|
|
|
return getQuery(`site.find('${id}')`, { |
|
|
|
|
select: { |
|
|
|
|
title: "page.title", |
|
|
|
@ -515,23 +604,21 @@ function getGame(id){ |
|
|
|
|
enddate: "page.Enddate", |
|
|
|
|
tournamentStats: "page.tournamentStats", |
|
|
|
|
participants: { |
|
|
|
|
query: "page.parent.participants.toPages.sortBy('forename')", |
|
|
|
|
select:{ |
|
|
|
|
forename: "page.forename", |
|
|
|
|
surname: "page.surname", |
|
|
|
|
nickname: "page.nickname", |
|
|
|
|
uuid: "page.uuid", |
|
|
|
|
img: "page.pic.toFile?.url" |
|
|
|
|
query: "page.parent.scorers", |
|
|
|
|
select: { |
|
|
|
|
member: { |
|
|
|
|
query: "structureItem.member.toPages", |
|
|
|
|
select: playerInfo |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
}, |
|
|
|
|
players: { |
|
|
|
|
query: "page.players.toPages", |
|
|
|
|
select:{ |
|
|
|
|
forename: "page.forename", |
|
|
|
|
surname: "page.surname", |
|
|
|
|
nickname: "page.nickname", |
|
|
|
|
uuid: "page.uuid", |
|
|
|
|
img: "page.pic.toFile?.thumbnail(350).url" |
|
|
|
|
scorers: { |
|
|
|
|
query: "page.scorers.toStructure", |
|
|
|
|
select: { |
|
|
|
|
member: { |
|
|
|
|
query: "structureItem.member.toPages", |
|
|
|
|
select: playerInfo |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -544,8 +631,12 @@ function savePregame(page){ |
|
|
|
|
legs: page.legs, |
|
|
|
|
max: page.modus, |
|
|
|
|
in: page.in, |
|
|
|
|
players: page.players.map((p) => p.uuid), |
|
|
|
|
startdate: page.startdate, |
|
|
|
|
scorers: page.scorers.map((s) => { |
|
|
|
|
const copy = Object.assign({},s); |
|
|
|
|
copy.member = copy.member.map((p) => p.uuid) |
|
|
|
|
return copy |
|
|
|
|
}), |
|
|
|
|
startdate: page.startdate ? page.startdate : "", |
|
|
|
|
rounds: page.game ? JSON.stringify(page.game) : "", |
|
|
|
|
stats: page.stats ? JSON.stringify(page.stats) : "" |
|
|
|
|
}); |
|
|
|
@ -555,7 +646,7 @@ function saveGame(page){ |
|
|
|
|
return setKirby(page.id, { |
|
|
|
|
rounds: page.game ? JSON.stringify(page.game) : "", |
|
|
|
|
stats: page.stats ? JSON.stringify(page.stats) : "", |
|
|
|
|
enddate: page.enddate, |
|
|
|
|
enddate: page.enddate ? page.enddate : "", |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -616,11 +707,14 @@ const gameStateMachine = (gamestack, stack, page, computedProps) => { |
|
|
|
|
let [visit, error] = await overlayAndPop("d-gameinput", { input: input }, gamestack); |
|
|
|
|
|
|
|
|
|
if (parseFloat(visit) < 0 ){ |
|
|
|
|
visit = ""+(computedProps.current_toGo.value[computedProps.current_player.value * 1] - parseFloat(visit)*-1); |
|
|
|
|
visit = ""+(computedProps.current_toGo.value[computedProps.current_scorer_idx.value * 1] - parseFloat(visit)*-1); |
|
|
|
|
} |
|
|
|
|
// back/delete last throw
|
|
|
|
|
if (error != undefined) { |
|
|
|
|
const val = removeLastVisit(page); |
|
|
|
|
if (val === undefined) { |
|
|
|
|
return [undefined, undefined]; |
|
|
|
|
} |
|
|
|
|
saveGame(page); |
|
|
|
|
if (val == undefined) return [1, val]; |
|
|
|
|
return [1, val.join(",")]; |
|
|
|
@ -651,9 +745,7 @@ const gameStateMachine = (gamestack, stack, page, computedProps) => { |
|
|
|
|
storeVisit(page, visit.split(","), sum, 3, 0);
|
|
|
|
|
saveGame(page); |
|
|
|
|
return [1, undefined] |
|
|
|
|
} |
|
|
|
|
// checkout:
|
|
|
|
|
if (ret == 0) { |
|
|
|
|
} else if (ret == 0) { |
|
|
|
|
// Checkout: Ask for num Darts
|
|
|
|
|
[numDarts, tries] = await powerStateMachine(checkoutPipeline(stack), stack, /*initState=*/0, /*initInput=*/sum); |
|
|
|
|
} else if (ret == 1) { |
|
|
|
@ -671,9 +763,16 @@ const gameStateMachine = (gamestack, stack, page, computedProps) => { |
|
|
|
|
const winner = getFinalWinner(page); |
|
|
|
|
let name = "DRAW" |
|
|
|
|
if (winner != -2){ |
|
|
|
|
name = page.players[winner].forename; |
|
|
|
|
name = page.scorers[winner].member.map((p) => p.forename).join(" + "); |
|
|
|
|
} |
|
|
|
|
const [answer, error] = await overlayAndPop("d-dialog", gameOverDialog(name, points[1], computedProps.breaks.value), stack); |
|
|
|
|
if (error != undefined) { |
|
|
|
|
extension(page); |
|
|
|
|
const val = removeLastVisit(page); |
|
|
|
|
saveGame(page); |
|
|
|
|
if (val == undefined) return [1, val]; |
|
|
|
|
return [1, val.join(",")]; |
|
|
|
|
} |
|
|
|
|
if (answer == "end") { |
|
|
|
|
saveGame(page); |
|
|
|
|
return [undefined, page.stats.winner]; |
|
|
|
@ -709,7 +808,7 @@ const stateMachine = (stack, page) => { |
|
|
|
|
// Dispatcher
|
|
|
|
|
// Check if in watchmode
|
|
|
|
|
// Check Game State:
|
|
|
|
|
if (page.players.length != 2 || page.startdate === undefined || page.startdate === ""){ |
|
|
|
|
if ( page.scorers.length != 2 || page.startdate === undefined || page.startdate === ""){ |
|
|
|
|
// Pre Game
|
|
|
|
|
return [1, page]; |
|
|
|
|
} else if (page.enddate === undefined || page.enddate === ""){ |
|
|
|
@ -750,23 +849,34 @@ const stateMachine = (stack, page) => { |
|
|
|
|
}, |
|
|
|
|
2: async (page, reGet) => { |
|
|
|
|
// Ask for Bull
|
|
|
|
|
const [result, error] = await overlayAndPop("d-bullselect", { players: page.players}, stack); |
|
|
|
|
const [scorer, error] = await overlayAndPop("d-bullselect", { scorers: page.scorers}, stack); |
|
|
|
|
if (error != undefined) { |
|
|
|
|
page.startdate = undefined; |
|
|
|
|
const ret = await savePregame(page); |
|
|
|
|
return [1, page]; |
|
|
|
|
} |
|
|
|
|
// reorderPlayer
|
|
|
|
|
if (result !== page.players[0]){ |
|
|
|
|
page.players = [page.players[1], page.players[0]]; |
|
|
|
|
// reorder Scorer
|
|
|
|
|
if (scorer !== page.scorers[0]){ |
|
|
|
|
page.scorers = [page.scorers[1], page.scorers[0]]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Setup Game
|
|
|
|
|
initGame(page); |
|
|
|
|
initStats(page); |
|
|
|
|
const ret = await savePregame(page); |
|
|
|
|
await reloadGame(page); |
|
|
|
|
|
|
|
|
|
return [3, page]; |
|
|
|
|
}, |
|
|
|
|
3: async (page, reGet) => { |
|
|
|
|
// In Game
|
|
|
|
|
const [result, error] = await overlayAndPop("d-xoi", { page: page, inspect: false }, stack); |
|
|
|
|
if (error) { |
|
|
|
|
page.game = undefined; |
|
|
|
|
page.stats = undefined; |
|
|
|
|
const ret = await savePregame(page); |
|
|
|
|
return [2, page]; |
|
|
|
|
} |
|
|
|
|
return [4, result]; |
|
|
|
|
}, |
|
|
|
|
4: async (winnerUUID, reGet) => { |
|
|
|
|