Fight together: tag into anyone's fight

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
rope 2026-10-21 22:06:49 +01:00
parent e0e0a824a9
commit 2d2cb16aff
6 changed files with 574 additions and 102 deletions

13
app.py
View file

@ -119,11 +119,15 @@ def player_view(world: dict, player: dict, now: float) -> dict:
"crit": me["crit"], "interval": me["interval"], "block": me["block"], "damage": me["damage"]}
view["perk_costs"] = {perk: game.perk_cost(player, perk) for perk in player["perks"]}
if player["action"]:
action, fight = game.growing(player), player["action"].get("fight")
action, fight = game.growing(player), game.current_fight(world, player)
duration = fight["duration"] if fight else game.action_time(world, player, action)
view["action"] = {**player["action"], "growing": action["id"], "duration": duration}
if fight:
view["action"]["fight"] = game.fight_view(fight)
view["action"]["respawn"] = game.RESPAWN / game.speed(world)
party = game.party_of(world, player)
if party:
view["action"]["with"] = [uid for uid in party["members"] if uid != player["id"]]
# A fight takes as long as it takes: show the average time to a kill.
view["times"] = {action["id"]: (view["fight_odds"][action["id"]]["kill_time"] + game.RESPAWN) / game.speed(world)
if "enemy" in action else game.action_time(world, player, action) for action in game.ACTIONS}
@ -193,6 +197,9 @@ def roster(world: dict, now: float) -> list[dict]:
"levels": {skill: game.skill_level(player, skill) for skill in game.SKILL_IDS},
"doing": action["name"] if action else None,
"skill": action["skill"] if action else None,
# A fight others can tag into, and who's in it together.
"fight": player["action"]["id"] if game.joinable(world, player) and game.offline_limit(world, player) > now else None,
"party": (player["action"] or {}).get("party"),
"garrison": player["garrison"], "donated": player["donated"],
})
return sorted(people, key=lambda p: -p["donated"])
@ -334,6 +341,8 @@ class Handler(BaseHTTPRequestHandler):
return "Bad quantity"
if path == "/api/action":
return game.start_action(world, player, str(body.get("id")), now, once=bool(body.get("once")))
if path == "/api/join":
return game.join_fight(world, player, str(body.get("id")), now)
if path == "/api/order":
return game.post_order(world, player, body.get("kind"), str(item), qty, body.get("provide"),
body.get("reward"), now)
@ -356,7 +365,7 @@ class Handler(BaseHTTPRequestHandler):
player["seen_threat"] = max(player.get("seen_threat", 0), event_id)
return None
if path == "/api/stop":
game.stop(player)
game.drop_out(world, player, now)
return None
if path == "/api/donate":
return game.donate(world, player, item, qty, now)