adventure: let a player act from the web, not just read about it
The equip queue proved the reverse pipe works. This gives it verbs that play the game: pull out of a run from the adventurer page, take today's bout from the war room. Its own table and its own poll, not more actions on equip_orders. Every column of that table is equip vocabulary (item, slot, tier) and these verbs act on the character rather than on something it is carrying. Nothing in a request names an adventurer. The session maps to one localpart and a localpart to one adventurer, so Pete resolves the character itself and there is no id on the wire to forge. The panel's copy is kept honest by the verdict: an applied action hides the offer it has just spent, a refusal puts the button back. Watching it run is what put that there, along with the strip's layout — gogobee answers a bout with a whole sentence of damage, which the equip strip's two-column row squeezed into a column and wrapped the verb. Claude-Session: https://claude.ai/code/session_012bxpQQJDjC1mTtLN3VVtBQ
This commit is contained in:
+26
-1
@@ -82,6 +82,18 @@ type SiegePastView struct {
|
||||
type siegePage struct {
|
||||
pageData
|
||||
Siege SiegeView
|
||||
// The viewer's own standing in the muster, when they are signed in and have
|
||||
// an adventurer. This is the only personal thing on an otherwise wholly
|
||||
// public page, and it exists to hang one button off: the war room is where
|
||||
// somebody realises the town needs them, so it is where they should be able
|
||||
// to answer.
|
||||
//
|
||||
// YouFought reads a snapshot up to two minutes old, so it decides what the
|
||||
// page OFFERS and never what the game allows — a bout taken in Matrix inside
|
||||
// that window comes back from gogobee as rejected_already_fought, which is
|
||||
// the honest answer and the one the strip shows.
|
||||
YouOnBoard bool
|
||||
YouFought bool
|
||||
}
|
||||
|
||||
// handleSiegeIngest replaces the war room with gogobee's latest snapshot.
|
||||
@@ -153,11 +165,24 @@ func (s *Server) handleSiegePage(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
base := s.base(r)
|
||||
base.Active = "adventure"
|
||||
view := s.siege()
|
||||
page := siegePage{pageData: base, Siege: view}
|
||||
if base.User != nil {
|
||||
if token, ok := storage.SelfToken(buyerLocalpart(base.User)); ok {
|
||||
page.YouOnBoard = true
|
||||
for _, d := range view.Fought {
|
||||
if d.Token == token {
|
||||
page.YouFought = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Unlike the who page this one is NOT noindex: it names a boss and a town,
|
||||
// and the defender list is character names that are already public on the
|
||||
// board. There is nothing here that ties a page to a person more than
|
||||
// /adventure already does.
|
||||
s.render(w, "siege", siegePage{pageData: base, Siege: s.siege()})
|
||||
s.render(w, "siege", page)
|
||||
}
|
||||
|
||||
// handleSiegeAPI serves the war room as JSON for the page's own re-poll. This
|
||||
|
||||
Reference in New Issue
Block a user