64 lines
1.8 KiB
TypeScript
64 lines
1.8 KiB
TypeScript
import { ref, computed } from 'vue'
|
|
import type { DefensiveDecision } from '~/types/game'
|
|
|
|
// Module-level singleton state (shared across all consumers)
|
|
const holdRunners = ref<Set<number>>(new Set())
|
|
const infieldDepth = ref<'infield_in' | 'normal' | 'corners_in'>('normal')
|
|
const outfieldDepth = ref<'normal' | 'shallow'>('normal')
|
|
|
|
export function useDefensiveSetup() {
|
|
/** Reactive array of held base numbers (for prop passing) */
|
|
const holdRunnersArray = computed<number[]>(() => Array.from(holdRunners.value).sort())
|
|
|
|
/** Check if a specific base is held */
|
|
function isHeld(base: number): boolean {
|
|
return holdRunners.value.has(base)
|
|
}
|
|
|
|
/** Toggle hold on a base (1, 2, or 3) */
|
|
function toggleHold(base: number) {
|
|
const next = new Set(holdRunners.value)
|
|
if (next.has(base)) {
|
|
next.delete(base)
|
|
} else {
|
|
next.add(base)
|
|
}
|
|
holdRunners.value = next
|
|
}
|
|
|
|
/** Reset all defensive setup to defaults */
|
|
function reset() {
|
|
holdRunners.value = new Set()
|
|
infieldDepth.value = 'normal'
|
|
outfieldDepth.value = 'normal'
|
|
}
|
|
|
|
/** Sync state from an existing DefensiveDecision (e.g. from props/server) */
|
|
function syncFromDecision(decision: DefensiveDecision) {
|
|
holdRunners.value = new Set(decision.hold_runners)
|
|
infieldDepth.value = decision.infield_depth
|
|
outfieldDepth.value = decision.outfield_depth
|
|
}
|
|
|
|
/** Build a DefensiveDecision from current working state */
|
|
function getDecision(): DefensiveDecision {
|
|
return {
|
|
infield_depth: infieldDepth.value,
|
|
outfield_depth: outfieldDepth.value,
|
|
hold_runners: holdRunnersArray.value,
|
|
}
|
|
}
|
|
|
|
return {
|
|
holdRunners,
|
|
holdRunnersArray,
|
|
infieldDepth,
|
|
outfieldDepth,
|
|
isHeld,
|
|
toggleHold,
|
|
reset,
|
|
syncFromDecision,
|
|
getDecision,
|
|
}
|
|
}
|