282 lines
14 KiB
Plaintext
282 lines
14 KiB
Plaintext
(->>
|
|
const err = -> console.error it
|
|
const fetch-log = ->
|
|
fetch it .then (->
|
|
console.log it
|
|
it
|
|
) .catch err
|
|
const $opponent-hand = document.query-selector '#opponent-hand'
|
|
const $own-hand = document.query-selector '#own-hand'
|
|
const $view-card = document.query-selector '#view-card'
|
|
const $view-card-container = document.query-selector '#view-card-container'
|
|
const $param = document.query-selector '#param'
|
|
const $play = document.query-selector '#play'
|
|
const $discard-pile = document.query-selector '#discard-pile'
|
|
const $discard-pile-img = document.query-selector '#discard-pile-img'
|
|
const $discard-pile-count = document.query-selector '#discard-pile-count'
|
|
const $shadow-realm = document.query-selector '#shadow-realm'
|
|
const $shadow-realm-img = document.query-selector '#shadow-realm-img'
|
|
const $shadow-realm-count = document.query-selector '#shadow-realm-count'
|
|
const $deck = document.query-selector '#deck'
|
|
const $deck-count = document.query-selector '#deck-count'
|
|
const $extra = document.query-selector '#extra'
|
|
const [push-param, pop-param] = (->
|
|
param = ""
|
|
clear-param-timer = 0
|
|
setInterval (->
|
|
clear-param-timer-- if clear-param-timer
|
|
param := "" unless clear-param-timer
|
|
$param.inner-text = param && "\xa0#param\xa0"
|
|
), 100
|
|
const push-param = ->
|
|
param += it
|
|
$param.inner-text = "\xa0#param\xa0"
|
|
clear-param-timer := 20
|
|
const pop-full-param = ->
|
|
ret = param
|
|
param := ""
|
|
$param.inner-text = "\xa0#param\xa0"
|
|
if ret == ""
|
|
1
|
|
else
|
|
+ret
|
|
[push-param, pop-full-param]
|
|
)!
|
|
play-id-list = ""
|
|
|
|
const clamp = (n, v, x) -> Math.min (Math.max v, n), x
|
|
const unwrap_uuid = (.replace /^\{|\}$/g '')
|
|
const get-play-size = -> $play.get-bounding-client-rect!
|
|
const gen-array = -> Array.from { length: it }, (_, i) -> i
|
|
const gen-array-of = (it, val) -> Array.from { length: it }, -> val
|
|
const cards = await fetch-log \./cards.json .then (.json!)
|
|
const $make-card = ->
|
|
$img = document.create-element \img
|
|
$img.src = it
|
|
$img
|
|
const $make-blank-card = -> $make-card \./card_back.png
|
|
const gen-opponent-cards$ = ->
|
|
diff = it - $opponent-hand.child-element-count
|
|
switch
|
|
| diff < 0
|
|
while diff++
|
|
$opponent-hand.remove-child $opponent-hand.first-child
|
|
| diff > 0
|
|
$opponent-hand.append ...(gen-array diff .map $make-blank-card)
|
|
| _
|
|
void
|
|
const get-state = ->>
|
|
player-state-json = await fetch \./get_state .then (.text!)
|
|
player-state = JSON.parse player-state-json
|
|
events-json = await fetch \/get_events .then (.text!)
|
|
events = JSON.parse events-json
|
|
play-map = new Map player-state.play.map -> [it.id, it]
|
|
return { player-state-json, player-state, events-json, events, play-map }
|
|
|
|
const show-card$ = (e) ->
|
|
const hide-card$ = ->
|
|
$view-card.style.opacity = 0
|
|
e.target.remove-event-listener \mouseleave hide-card$
|
|
$view-card.src = e.target.get-attribute \data-png
|
|
$view-card.style.opacity = 1
|
|
e.target.add-event-listener \mouseleave hide-card$
|
|
state = await get-state!
|
|
const apply-state$ = ->
|
|
{ player-state } = it
|
|
gen-opponent-cards$ player-state.opponent_cards_in_hand
|
|
if document.body.class-list.contains \my-turn
|
|
document.body.class-list.remove \my-turn if player-state.you != player-state.turn_player
|
|
else
|
|
document.body.class-list.add \my-turn if player-state.you == player-state.turn_player
|
|
$deck-count.inner-text = player-state.deck_size
|
|
if player-state.discard_pile.length
|
|
top-id = player-state.discard_pile[* - 1]
|
|
$discard-pile-img.src = cards[top-id].jpg
|
|
$discard-pile-img.set-attribute \data-png cards[top-id].png
|
|
else
|
|
$discard-pile-img.src = ""
|
|
$discard-pile-count.inner-text = player-state.discard_pile.length
|
|
if player-state.shadow_realm.length
|
|
top-id = player-state.shadow_realm[* - 1]
|
|
$shadow-realm-img.src = cards[top-id].jpg
|
|
$shadow-realm-img.set-attribute \data-png cards[top-id].png
|
|
else
|
|
$shadow-realm-img.src = ""
|
|
$shadow-realm-count.inner-text = player-state.shadow_realm.length
|
|
if $extra.has-attribute \data-pile-type
|
|
const list = switch $extra.get-attribute \data-pile-type
|
|
| \discard => player-state.discard_pile
|
|
| \shadow => player-state.shadow_realm
|
|
| \deck => gen-array-of state.player-state.deck_size, null
|
|
| _ => (console.log that) || []
|
|
open-list list, $extra.get-attribute \data-pile-type
|
|
if player-state.hand.length != $own-hand.children.length
|
|
$own-hand.innerHTML = ''
|
|
player-state.hand.for-each (card-id, index) ->
|
|
card-data = cards[card-id]
|
|
card = $make-card card-data.jpg
|
|
card
|
|
..set-attribute \data-hand-index index
|
|
..set-attribute \data-text card-data.txt
|
|
..set-attribute \data-png card-data.png
|
|
..add-event-listener \mouseenter show-card$
|
|
$own-hand.append-child card
|
|
next-play-id-list = [...player-state.play.map (.play_id)].sort!join \|
|
|
if play-id-list !== next-play-id-list
|
|
$play.innerHTML = ''
|
|
player-state.play.for-each ->
|
|
card-data = cards[unwrap_uuid it.id]
|
|
if it.owner == player-state.you
|
|
relative-y = it.position_y
|
|
else
|
|
relative-y = 100 - it.position_y
|
|
img = $make-card card-data.jpg
|
|
img
|
|
..class-list.add \in-play-card
|
|
..style
|
|
..left = it.position_x + \%
|
|
..top = relative-y + \%
|
|
..set-attribute \data-png card-data.png
|
|
..set-attribute \data-play-id it.play_id
|
|
..set-attribute \data-play-x it.position_x
|
|
..set-attribute \data-play-y relative-y
|
|
..set-attribute \draggable \true
|
|
..set-attribute \data-owner it.owner
|
|
..set-attribute \data-owned it.owner == player-state.you
|
|
..set-attribute \data-tapped it.tapped
|
|
..add-event-listener \mouseenter show-card$
|
|
..add-event-listener \dragstart ->
|
|
it.target.set-attribute \data-start-x it.target.offset-left
|
|
it.target.set-attribute \data-start-y it.target.offset-top
|
|
it.target.set-attribute \data-client-x it.client-x
|
|
it.target.set-attribute \data-client-y it.client-y
|
|
..add-event-listener \dragend ->
|
|
const start-x = +it.target.get-attribute \data-start-x
|
|
const start-y = +it.target.get-attribute \data-start-y
|
|
const start-client-x = +it.target.get-attribute \data-client-x
|
|
const start-client-y = +it.target.get-attribute \data-client-y
|
|
const new-x = it.client-x + (start-x - start-client-x)
|
|
const new-y = it.client-y + (start-y - start-client-y)
|
|
const scale-x = +start-x / +(it.target.get-attribute \data-play-x)
|
|
const scale-y = +start-y / +(it.target.get-attribute \data-play-y)
|
|
const x = clamp 5 Math.round(new-x / scale-x), 95
|
|
const y = clamp 5 Math.round(new-y / scale-y), 95
|
|
it.target.style
|
|
..left = x + \%
|
|
..top = y + \%
|
|
it.target.set-attribute \data-play-x x
|
|
it.target.set-attribute \data-play-y y
|
|
if state.player-state.you == it.target.get-attribute \data-owner
|
|
absolute-y = y
|
|
else
|
|
absolute-y = 100 - y
|
|
fetch-log "./move/#{it.target.get-attribute \data-play-id}/#x/#absolute-y"
|
|
$play.append-child img
|
|
play-id-list := next-play-id-list
|
|
else
|
|
player-state.play.for-each ->
|
|
$element = document.query-selector "[data-play-id=\"#{it.play_id}\"]"
|
|
if it.owner == player-state.you
|
|
relative-y = it.position_y
|
|
else
|
|
relative-y = 100 - it.position_y
|
|
$element.set-attribute \data-tapped it.tapped
|
|
$element.style
|
|
..left = it.position_x + \%
|
|
..top = relative-y + \%
|
|
$element.set-attribute \data-play-x it.position_x
|
|
$element.set-attribute \data-play-y relative-y
|
|
|
|
|
|
apply-state$ state
|
|
|
|
const open-list = (list, list-type) -->
|
|
const $card-list = list.map (card-id, index) ->
|
|
if card-id
|
|
ret = $make-card cards[card-id].jpg
|
|
ret.set-attribute \data-png cards[card-id].png
|
|
ret.set-attribute "data-index" index
|
|
ret.set-attribute "data-list-type" list-type
|
|
ret.add-event-listener \mouseenter show-card$
|
|
ret
|
|
else
|
|
$make-blank-card!
|
|
$extra.innerHTML = ""
|
|
$card-list.for-each -> $extra.append it
|
|
$extra.set-attribute \data-pile-type list-type
|
|
$extra.class-list.remove \hidden
|
|
|
|
$discard-pile-img.add-event-listener \mouseenter show-card$
|
|
$shadow-realm-img.add-event-listener \mouseenter show-card$
|
|
$play.add-event-listener \dragover (.prevent-default!)
|
|
|
|
$discard-pile-img.add-event-listener \click -> open-list state.player-state.discard_pile, \discard
|
|
$shadow-realm-img.add-event-listener \click -> open-list state.player-state.shadow_realm, \shadow
|
|
$deck.add-event-listener \click -> open-list (gen-array-of state.player-state.deck_size, null), \deck
|
|
|
|
set-interval (->>
|
|
const new-state = await get-state!
|
|
unless new-state.player-state-json == state.player-state-json
|
|
apply-state$ new-state
|
|
state := new-state
|
|
window.state = state
|
|
), 1000
|
|
mouse-x = mouse-y = 0
|
|
document
|
|
..add-event-listener \mousemove ->
|
|
mouse-x = it.client-x
|
|
mouse-y = it.client-y
|
|
if mouse-x > window.inner-width * 2 / 3
|
|
$view-card-container.class-list.remove \right
|
|
else if mouse-x < window.inner-width / 3
|
|
$view-card-container.class-list.add \right
|
|
..add-event-listener \keyup ->
|
|
$current-mouse-node = [...document.query-selector-all \:hover][* - 1]
|
|
switch it.key
|
|
| \c => fetch-log "./draw/#{pop-param!}"
|
|
| \e => fetch-log "./pass"
|
|
| \0 \1 \2 \3 \4 \5 \6 \7 \8 \9 => push-param that
|
|
| \t =>
|
|
if $current-mouse-node?.has-attribute \data-hand-index
|
|
fetch-log "./fade/#{$current-mouse-node.get-attribute \data-hand-index}"
|
|
| \y =>
|
|
if $current-mouse-node?.has-attribute \data-hand-index
|
|
fetch-log "./fade_bottom/#{$current-mouse-node.get-attribute \data-hand-index}"
|
|
| ' ' =>
|
|
if $current-mouse-node?.has-attribute \data-hand-index
|
|
fetch-log "./play/#{$current-mouse-node.get-attribute \data-hand-index}"
|
|
else if $current-mouse-node?.has-attribute \data-play-id
|
|
if \true == $current-mouse-node.get-attribute \data-tapped
|
|
$current-mouse-node.set-attribute \data-tapped \false
|
|
else
|
|
$current-mouse-node.set-attribute \data-tapped \true
|
|
fetch-log "./tap/#{$current-mouse-node.get-attribute \data-play-id}"
|
|
else if $current-mouse-node?.has-attribute \data-list-type
|
|
switch $current-mouse-node.get-attribute \data-list-type
|
|
| \discard
|
|
fetch-log "./unkill/#{$current-mouse-node.get-attribute \data-index}"
|
|
| \shadow
|
|
fetch-log "./unbanish/#{$current-mouse-node.get-attribute \data-index}"
|
|
$current-mouse-node.parent-element.remove-child $current-mouse-node
|
|
if !$extra.child-element-count
|
|
$extra.class-list.add \hidden
|
|
$extra.remove-attribute \data-pile-type
|
|
| \r =>
|
|
if $current-mouse-node?.has-attribute \data-play-id
|
|
fetch-log "./bounce/#{$current-mouse-node.get-attribute \data-play-id}"
|
|
| \d =>
|
|
if $current-mouse-node?.has-attribute \data-hand-index
|
|
fetch-log "./discard/#{$current-mouse-node.get-attribute \data-hand-index}"
|
|
else if $current-mouse-node?.has-attribute \data-play-id
|
|
fetch-log "./kill/#{$current-mouse-node.get-attribute \data-play-id}"
|
|
| \s =>
|
|
if $current-mouse-node?.has-attribute \data-hand-index
|
|
fetch-log "./forget/#{$current-mouse-node.get-attribute \data-hand-index}"
|
|
else if $current-mouse-node?.has-attribute \data-play-id
|
|
fetch-log "./banish/#{$current-mouse-node.get-attribute \data-play-id}"
|
|
| \q =>
|
|
$extra.class-list.add \hidden
|
|
$extra.remove-attribute \data-pile-type
|
|
|
|
)!
|