notify.gno
2.88 Kb · 86 lines
1package arena
2
3import (
4 "chain"
5 "strconv"
6
7 "gno.land/r/nym-gfanton001/gnotif/v1"
8)
9
10// self is the arena's package path; a deploy under another path changes it.
11var self string
12
13// pagePath is where the page lives on its origin, the start of every trigger's link; the
14// registry accepts only a link that starts with "/".
15const pagePath = "/gnomepit/"
16
17// init sets the arena's three gnotif triggers and keeps no handle, so they stay as set
18// for this deploy. A Turn or Ended event carries the address it notifies in "to", so a
19// browser opts in with its wallet's address; a Board event notifies every browser that
20// opted in.
21func init(cur realm) {
22 self = cur.PkgPath()
23 me := cur.Sub(gnotif.Subpath)
24 h := gnotif.Open(cross(me))
25 h.Set(cross(me), "turn", gnotif.Trigger{Event: "Turn", Param: "to", Title: "Your move in Gnomepit", Body: "{text}", Link: pagePath + "#match={match}"})
26 h.Set(cross(me), "ended", gnotif.Trigger{Event: "Ended", Param: "to", Title: "Match over", Body: "{text}", Link: pagePath + "#match={match}"})
27 h.Set(cross(me), "board", gnotif.Trigger{Event: "Board", Title: "Gnomepit challenges", Body: "{text}", Link: pagePath})
28}
29
30// tell emits kind to player about match id. It emits nothing when player made the call,
31// so an event never names its caller.
32func tell(kind string, player, caller address, id int, text string) {
33 if player == caller {
34 return
35 }
36 chain.Emit(kind, "to", player.String(), "match", strconv.Itoa(id), "text", text)
37}
38
39// tellBoard emits Board about match id, whose change altered the open-challenge list. It
40// names no address, so a caller cannot aim it at one player's browser.
41func tellBoard(id int, text string) {
42 chain.Emit("Board", "match", strconv.Itoa(id), "text", text)
43}
44
45// tellEnded sends Ended to each player of the finished match m, numbered id, but caller,
46// one event each, since gnotif reads only the first value of a repeated attribute.
47func tellEnded(m record, id int, caller address) {
48 tell("Ended", m.challenger, caller, id, endText(m, 0))
49 if m.acceptor != m.challenger {
50 tell("Ended", m.acceptor, caller, id, endText(m, 1))
51 }
52}
53
54// endText says how m ended to the player on side.
55func endText(m record, side int) string {
56 won := m.result == "a" && side == 0 || m.result == "b" && side == 1
57 switch m.reason {
58 case "hp":
59 last := m.hp[plansMade(m.plans[0])-1]
60 score := strconv.Itoa(last[side]) + " to " + strconv.Itoa(last[1-side]) + "."
61 switch {
62 case m.result == "draw":
63 return "Draw on HP, " + score
64 case won:
65 return "You won on HP, " + score
66 }
67 return "You lost on HP, " + score
68 case "knockout":
69 switch {
70 case m.result == "draw":
71 return "Both gnomes fell: a draw."
72 case won:
73 return "You won by knockout."
74 }
75 return "You lost by knockout."
76 case "resign":
77 if won {
78 return "Your opponent resigned. You won."
79 }
80 return "You resigned."
81 }
82 if won {
83 return "You won by forfeit."
84 }
85 return "You lost by forfeit."
86}