Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -215,13 +215,17 @@ class GameDatabase:
|
|
| 215 |
conn.commit()
|
| 216 |
return True, None, f"Room full. Joined as spectator."
|
| 217 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 218 |
# Join as player
|
| 219 |
slot = 0 if len(players) == 0 else 1
|
| 220 |
conn.execute("""
|
| 221 |
INSERT INTO players (
|
| 222 |
-
room_id, player_id, name, character_id, player_slot
|
| 223 |
-
) VALUES (?, ?, ?, ?, ?)
|
| 224 |
-
""", (room_id, player_id, name, character_id, slot))
|
| 225 |
|
| 226 |
# If 2 players, start game
|
| 227 |
if slot == 1:
|
|
@@ -364,12 +368,35 @@ class GameDatabase:
|
|
| 364 |
# Game over
|
| 365 |
self._end_game(room_id, conn)
|
| 366 |
else:
|
| 367 |
-
#
|
| 368 |
-
conn.execute("""
|
| 369 |
-
|
| 370 |
-
|
| 371 |
-
|
| 372 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 373 |
|
| 374 |
# Draw new tasks
|
| 375 |
task_ids = random.sample([t['id'] for t in TASKS], 3)
|
|
@@ -465,27 +492,106 @@ class GameDatabase:
|
|
| 465 |
|
| 466 |
# ===== GAME DATA =====
|
| 467 |
CHARACTERS = [
|
| 468 |
-
{"id": "P1", "name": "Workaholic", "desc": "Work +2 VP, but +1 stress/turn"
|
| 469 |
-
|
| 470 |
-
{"id": "
|
| 471 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 472 |
]
|
| 473 |
|
| 474 |
TASKS = [
|
| 475 |
-
|
|
|
|
| 476 |
"solo": {"CP": 7, "HP": 3}, "coop": {"CP": 10}, "reward": 12},
|
| 477 |
{"id": "W2", "name": "Annual Report", "type": "W", "time": 6,
|
| 478 |
"solo": {"CP": 6}, "coop": {"CP": 8}, "reward": 8},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 479 |
{"id": "D1", "name": "Deep Clean Kitchen", "type": "D", "time": 5,
|
| 480 |
"solo": {"HP": 5}, "coop": {"HP": 7}, "reward": 0, "effect": "stress:-2"},
|
| 481 |
{"id": "D2", "name": "Laundry & Organize", "type": "D", "time": 3,
|
| 482 |
"solo": {"HP": 3}, "coop": {"HP": 4}, "reward": 0, "effect": "hp:+2"},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 483 |
{"id": "H1", "name": "Fitness Training", "type": "H", "time": 5,
|
| 484 |
"solo": {"HP": 6}, "coop": {"HP": 8}, "reward": 1, "effect": "hp_max:+1"},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 485 |
{"id": "R1", "name": "Romantic Date", "type": "R", "time": 5,
|
| 486 |
"solo": {"CP": 5}, "coop": {"CP": 7}, "cost": 5, "qol": 3, "effect": "stress:-3"},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 487 |
{"id": "Q2", "name": "Weekend Trip", "type": "Q", "time": 7,
|
| 488 |
"solo": {"HP": 5, "CP": 4}, "coop": {"HP": 9}, "cost": 15, "qol": 7, "effect": "recover_all"},
|
|
|
|
|
|
|
|
|
|
|
|
|
| 489 |
]
|
| 490 |
|
| 491 |
# ===== GLOBAL STATE =====
|
|
@@ -715,7 +821,6 @@ def create_ui():
|
|
| 715 |
gr.Markdown("### Player 1")
|
| 716 |
p1_name = gr.Textbox(label="Name", interactive=False)
|
| 717 |
p1_character = gr.Textbox(label="Character", interactive=False)
|
| 718 |
-
p1_display = gr.JSON(label="Status")
|
| 719 |
with gr.Row():
|
| 720 |
p1_time = gr.Number(label="β° Time", interactive=False)
|
| 721 |
p1_money = gr.Number(label="π° Money", interactive=False)
|
|
@@ -777,7 +882,6 @@ def create_ui():
|
|
| 777 |
gr.Markdown("### Player 2")
|
| 778 |
p2_name = gr.Textbox(label="Name", interactive=False)
|
| 779 |
p2_character = gr.Textbox(label="Character", interactive=False)
|
| 780 |
-
p2_display = gr.JSON(label="Status")
|
| 781 |
with gr.Row():
|
| 782 |
p2_time = gr.Number(label="β° Time", interactive=False)
|
| 783 |
p2_money = gr.Number(label="π° Money", interactive=False)
|
|
@@ -835,56 +939,76 @@ def create_ui():
|
|
| 835 |
return {}, f"β {msg}"
|
| 836 |
|
| 837 |
def refresh_game_state(session):
|
|
|
|
|
|
|
| 838 |
if not session.get('room_id'):
|
| 839 |
-
return
|
| 840 |
|
| 841 |
state = db.get_room_state(session['room_id'])
|
| 842 |
if not state:
|
| 843 |
-
return
|
| 844 |
|
| 845 |
room = state['room']
|
| 846 |
players = state['players']
|
| 847 |
|
| 848 |
# Status
|
| 849 |
status_md = f"""
|
| 850 |
-
**Room:** {session['room_id']} | **Round:** {room['current_round']}/{room['total_rounds']}
|
| 851 |
**Status:** {room['status'].upper()} | **Current Turn:** Player {room['current_turn'] + 1}
|
| 852 |
"""
|
| 853 |
|
| 854 |
if room['status'] == 'finished':
|
| 855 |
-
|
|
|
|
| 856 |
|
| 857 |
-
#
|
| 858 |
p1_data = players[0] if len(players) > 0 else {}
|
| 859 |
p2_data = players[1] if len(players) > 1 else {}
|
| 860 |
|
| 861 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 862 |
task_rows = []
|
|
|
|
| 863 |
for task_id in state['task_ids']:
|
| 864 |
task = next((t for t in TASKS if t['id'] == task_id), None)
|
| 865 |
if task:
|
| 866 |
-
|
| 867 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 868 |
task_rows.append([
|
| 869 |
task['id'], task['name'], task['type'],
|
| 870 |
-
f"{task['time']}h",
|
| 871 |
])
|
| 872 |
-
|
| 873 |
-
# Task dropdown options
|
| 874 |
-
task_options = [(f"{t['id']} - {t['name']}", t['id']) for t in TASKS if t['id'] in state['task_ids']]
|
| 875 |
|
| 876 |
# Spectators
|
| 877 |
spec_md = f"π₯ {len(state['spectators'])} watching: {', '.join(state['spectators'])}" if state['spectators'] else "*No spectators*"
|
| 878 |
|
| 879 |
# Turn indicator
|
| 880 |
if session.get('is_spectator'):
|
| 881 |
-
turn_msg = "ποΈ You are spectating"
|
|
|
|
|
|
|
|
|
|
|
|
|
| 882 |
elif session.get('player_slot') == room['current_turn']:
|
| 883 |
turn_msg = "β
**YOUR TURN!** Take an action below."
|
| 884 |
else:
|
| 885 |
-
turn_msg = "β³
|
| 886 |
|
| 887 |
-
return (status_md, p1_data,
|
|
|
|
| 888 |
|
| 889 |
def execute_rest_handler(session, rest_type):
|
| 890 |
if not session.get('room_id') or session.get('is_spectator'):
|
|
@@ -986,7 +1110,8 @@ def create_ui():
|
|
| 986 |
refresh_btn.click(
|
| 987 |
refresh_game_state,
|
| 988 |
inputs=[session_state],
|
| 989 |
-
outputs=[status_display,
|
|
|
|
| 990 |
spectators_display, your_turn_msg]
|
| 991 |
)
|
| 992 |
|
|
@@ -997,7 +1122,8 @@ def create_ui():
|
|
| 997 |
).then(
|
| 998 |
refresh_game_state,
|
| 999 |
inputs=[session_state],
|
| 1000 |
-
outputs=[status_display,
|
|
|
|
| 1001 |
spectators_display, your_turn_msg]
|
| 1002 |
)
|
| 1003 |
|
|
@@ -1008,7 +1134,8 @@ def create_ui():
|
|
| 1008 |
).then(
|
| 1009 |
refresh_game_state,
|
| 1010 |
inputs=[session_state],
|
| 1011 |
-
outputs=[status_display,
|
|
|
|
| 1012 |
spectators_display, your_turn_msg]
|
| 1013 |
)
|
| 1014 |
|
|
@@ -1019,7 +1146,8 @@ def create_ui():
|
|
| 1019 |
).then(
|
| 1020 |
refresh_game_state,
|
| 1021 |
inputs=[session_state],
|
| 1022 |
-
outputs=[status_display,
|
|
|
|
| 1023 |
spectators_display, your_turn_msg]
|
| 1024 |
)
|
| 1025 |
|
|
@@ -1030,7 +1158,8 @@ def create_ui():
|
|
| 1030 |
).then(
|
| 1031 |
refresh_game_state,
|
| 1032 |
inputs=[session_state],
|
| 1033 |
-
outputs=[status_display,
|
|
|
|
| 1034 |
spectators_display, your_turn_msg]
|
| 1035 |
)
|
| 1036 |
|
|
@@ -1041,7 +1170,8 @@ def create_ui():
|
|
| 1041 |
).then(
|
| 1042 |
refresh_game_state,
|
| 1043 |
inputs=[session_state],
|
| 1044 |
-
outputs=[status_display,
|
|
|
|
| 1045 |
spectators_display, your_turn_msg]
|
| 1046 |
)
|
| 1047 |
|
|
|
|
| 215 |
conn.commit()
|
| 216 |
return True, None, f"Room full. Joined as spectator."
|
| 217 |
|
| 218 |
+
# Apply character starting bonuses
|
| 219 |
+
character = next((c for c in CHARACTERS if c['id'] == character_id), {})
|
| 220 |
+
hp_max = INITIAL_HP + character.get('hp_max_bonus', 0)
|
| 221 |
+
|
| 222 |
# Join as player
|
| 223 |
slot = 0 if len(players) == 0 else 1
|
| 224 |
conn.execute("""
|
| 225 |
INSERT INTO players (
|
| 226 |
+
room_id, player_id, name, character_id, player_slot, hp_max
|
| 227 |
+
) VALUES (?, ?, ?, ?, ?, ?)
|
| 228 |
+
""", (room_id, player_id, name, character_id, slot, hp_max))
|
| 229 |
|
| 230 |
# If 2 players, start game
|
| 231 |
if slot == 1:
|
|
|
|
| 368 |
# Game over
|
| 369 |
self._end_game(room_id, conn)
|
| 370 |
else:
|
| 371 |
+
# Get players for character effects
|
| 372 |
+
players = conn.execute("""
|
| 373 |
+
SELECT * FROM players WHERE room_id = ?
|
| 374 |
+
""", (room_id,)).fetchall()
|
| 375 |
+
|
| 376 |
+
# Reset for next round and apply turn-start character effects
|
| 377 |
+
for player in players:
|
| 378 |
+
character = next((c for c in CHARACTERS if c['id'] == player['character_id']), {})
|
| 379 |
+
|
| 380 |
+
new_stress = player['stress']
|
| 381 |
+
# Workaholic: +1 stress per turn
|
| 382 |
+
if character.get('turn_stress'):
|
| 383 |
+
new_stress += character['turn_stress']
|
| 384 |
+
|
| 385 |
+
# Neat Freak: Check if did any domestic task
|
| 386 |
+
if character.get('no_domestic_stress'):
|
| 387 |
+
completed = json.loads(player.get('completed_tasks', '[]'))
|
| 388 |
+
did_domestic = any(t.startswith('D') for t in completed)
|
| 389 |
+
if not did_domestic:
|
| 390 |
+
new_stress += character['no_domestic_stress']
|
| 391 |
+
|
| 392 |
+
conn.execute("""
|
| 393 |
+
UPDATE players SET
|
| 394 |
+
time = ?,
|
| 395 |
+
has_ended_turn = 0,
|
| 396 |
+
completed_tasks = '[]',
|
| 397 |
+
stress = ?
|
| 398 |
+
WHERE room_id = ? AND player_slot = ?
|
| 399 |
+
""", (INITIAL_TIME, new_stress, room_id, player['player_slot']))
|
| 400 |
|
| 401 |
# Draw new tasks
|
| 402 |
task_ids = random.sample([t['id'] for t in TASKS], 3)
|
|
|
|
| 492 |
|
| 493 |
# ===== GAME DATA =====
|
| 494 |
CHARACTERS = [
|
| 495 |
+
{"id": "P1", "name": "Workaholic", "desc": "Work +2 VP, but +1 stress/turn",
|
| 496 |
+
"work_bonus": 2, "turn_stress": 1},
|
| 497 |
+
{"id": "P2", "name": "Freelancer", "desc": "Work time -2, but coop +1 CP cost",
|
| 498 |
+
"work_time_reduction": 2, "coop_cp_penalty": 1},
|
| 499 |
+
{"id": "P3", "name": "Frugal", "desc": "QoL tasks -2 VP cost",
|
| 500 |
+
"qol_cost_reduction": 2},
|
| 501 |
+
{"id": "P4", "name": "Hedonist", "desc": "QoL +1, but domestic +2 time",
|
| 502 |
+
"qol_bonus": 1, "domestic_time_penalty": 2},
|
| 503 |
+
{"id": "H1", "name": "Neat Freak", "desc": "Domestic success +2 CP, no domestic +2 stress",
|
| 504 |
+
"domestic_cp_bonus": 2, "no_domestic_stress": 2},
|
| 505 |
+
{"id": "H2", "name": "Night Owl", "desc": "Rest HP halved, late work -1 CP",
|
| 506 |
+
"rest_halved": True},
|
| 507 |
+
{"id": "H3", "name": "Fitness Buff", "desc": "Rest +1 HP, HP max +2",
|
| 508 |
+
"rest_hp_bonus": 1, "hp_max_bonus": 2},
|
| 509 |
+
{"id": "H4", "name": "Procrastinator", "desc": "Long tasks +1 time, failure +1 stress",
|
| 510 |
+
"long_task_penalty": 1, "failure_stress": 1},
|
| 511 |
+
{"id": "R1", "name": "Anxious", "desc": "Coop min 3 CP, success -1 stress, failure +2 stress",
|
| 512 |
+
"coop_min_cp": 3, "coop_success_stress": -1, "coop_failure_stress": 2},
|
| 513 |
+
{"id": "R2", "name": "Supporter", "desc": "Partner +1 HP/CP on coop success",
|
| 514 |
+
"support_bonus": True},
|
| 515 |
+
{"id": "R3", "name": "Planner", "desc": "Can force round-up in negotiation",
|
| 516 |
+
"force_roundup": True},
|
| 517 |
+
{"id": "R4", "name": "Social Butterfly", "desc": "Social -1 time, +1 reputation",
|
| 518 |
+
"social_time_reduction": 1, "social_rep_bonus": 1},
|
| 519 |
]
|
| 520 |
|
| 521 |
TASKS = [
|
| 522 |
+
# Work Tasks (W1-W10)
|
| 523 |
+
{"id": "W1", "name": "Core Project", "type": "W", "time": 8,
|
| 524 |
"solo": {"CP": 7, "HP": 3}, "coop": {"CP": 10}, "reward": 12},
|
| 525 |
{"id": "W2", "name": "Annual Report", "type": "W", "time": 6,
|
| 526 |
"solo": {"CP": 6}, "coop": {"CP": 8}, "reward": 8},
|
| 527 |
+
{"id": "W3", "name": "Client Dispute", "type": "W", "time": 5,
|
| 528 |
+
"solo": {"CP": 5}, "coop": {"CP": 7}, "reward": 6},
|
| 529 |
+
{"id": "W4", "name": "Promotion Prep", "type": "W", "time": 7,
|
| 530 |
+
"solo": {"CP": 5, "HP": 4}, "coop": {"CP": 9}, "reward": 10},
|
| 531 |
+
{"id": "W5", "name": "Side Gig", "type": "W", "time": 4,
|
| 532 |
+
"solo": {"CP": 4}, "coop": {"CP": 6}, "reward": 5},
|
| 533 |
+
{"id": "W6", "name": "Learn New Skill", "type": "W", "time": 5,
|
| 534 |
+
"solo": {"CP": 5}, "coop": {"CP": 7}, "reward": 3, "effect": "cp_max:+1"},
|
| 535 |
+
{"id": "W7", "name": "Emergency Emails", "type": "W", "time": 3,
|
| 536 |
+
"solo": {"CP": 3}, "coop": {"CP": 4}, "reward": 4},
|
| 537 |
+
{"id": "W8", "name": "Industry Conference", "type": "W", "time": 6,
|
| 538 |
+
"solo": {"CP": 5, "HP": 3}, "coop": {"CP": 8}, "reward": 7},
|
| 539 |
+
{"id": "W9", "name": "Business Plan", "type": "W", "time": 9,
|
| 540 |
+
"solo": {"CP": 8}, "coop": {"CP": 11}, "reward": 15},
|
| 541 |
+
{"id": "W10", "name": "Expense Reports", "type": "W", "time": 2,
|
| 542 |
+
"solo": {"CP": 2}, "coop": {"CP": 3}, "reward": 2},
|
| 543 |
+
|
| 544 |
+
# Domestic Tasks (D1-D8)
|
| 545 |
{"id": "D1", "name": "Deep Clean Kitchen", "type": "D", "time": 5,
|
| 546 |
"solo": {"HP": 5}, "coop": {"HP": 7}, "reward": 0, "effect": "stress:-2"},
|
| 547 |
{"id": "D2", "name": "Laundry & Organize", "type": "D", "time": 3,
|
| 548 |
"solo": {"HP": 3}, "coop": {"HP": 4}, "reward": 0, "effect": "hp:+2"},
|
| 549 |
+
{"id": "D3", "name": "Pay Bills", "type": "D", "time": 2,
|
| 550 |
+
"solo": {"CP": 2}, "coop": {"CP": 3}, "reward": 0, "effect": "cp:+1"},
|
| 551 |
+
{"id": "D4", "name": "Grocery Shopping", "type": "D", "time": 4,
|
| 552 |
+
"solo": {"HP": 3}, "coop": {"HP": 5}, "reward": 0, "effect": "hp:+1"},
|
| 553 |
+
{"id": "D5", "name": "Take Out Trash", "type": "D", "time": 3,
|
| 554 |
+
"solo": {"HP": 3}, "coop": {"HP": 4}, "reward": 0, "effect": "stress:-1"},
|
| 555 |
+
{"id": "D6", "name": "Fix Appliance", "type": "D", "time": 5,
|
| 556 |
+
"solo": {"HP": 4}, "coop": {"HP": 6}, "reward": 1},
|
| 557 |
+
{"id": "D7", "name": "Tidy Common Area", "type": "D", "time": 4,
|
| 558 |
+
"solo": {"HP": 4}, "coop": {"HP": 5}, "reward": 0, "effect": "stress:-1"},
|
| 559 |
+
{"id": "D8", "name": "Cook Healthy Meal", "type": "D", "time": 3,
|
| 560 |
+
"solo": {"HP": 3}, "coop": {"HP": 4}, "reward": 0, "effect": "hp:+1"},
|
| 561 |
+
|
| 562 |
+
# Health Tasks (H1-H6)
|
| 563 |
{"id": "H1", "name": "Fitness Training", "type": "H", "time": 5,
|
| 564 |
"solo": {"HP": 6}, "coop": {"HP": 8}, "reward": 1, "effect": "hp_max:+1"},
|
| 565 |
+
{"id": "H2", "name": "Deep Meditation", "type": "H", "time": 4,
|
| 566 |
+
"solo": {"CP": 4}, "coop": {"CP": 5}, "reward": 0, "effect": "cp:+3"},
|
| 567 |
+
{"id": "H3", "name": "Annual Checkup", "type": "H", "time": 6,
|
| 568 |
+
"solo": {"HP": 5}, "coop": {"HP": 7}, "reward": 2, "effect": "stress:-2"},
|
| 569 |
+
{"id": "H4", "name": "Emotion Regulation Class", "type": "H", "time": 5,
|
| 570 |
+
"solo": {"CP": 4}, "coop": {"CP": 6}, "reward": 1, "effect": "cp_max:+1"},
|
| 571 |
+
{"id": "H5", "name": "Sleep Schedule Reset", "type": "H", "time": 3,
|
| 572 |
+
"solo": {"HP": 3}, "coop": {"HP": 4}, "reward": 0, "effect": "hp:+4"},
|
| 573 |
+
{"id": "H6", "name": "Personal Alone Time", "type": "H", "time": 2,
|
| 574 |
+
"solo": {"CP": 2}, "coop": {"CP": 3}, "reward": 0, "effect": "stress:-2"},
|
| 575 |
+
|
| 576 |
+
# Relationship & Social Tasks (R1-R2, S1-S2)
|
| 577 |
{"id": "R1", "name": "Romantic Date", "type": "R", "time": 5,
|
| 578 |
"solo": {"CP": 5}, "coop": {"CP": 7}, "cost": 5, "qol": 3, "effect": "stress:-3"},
|
| 579 |
+
{"id": "R2", "name": "Future Planning", "type": "R", "time": 6,
|
| 580 |
+
"solo": {"CP": 6}, "coop": {"CP": 8}, "cost": 3, "qol": 2, "effect": "cp:+1"},
|
| 581 |
+
{"id": "S1", "name": "Host Friends", "type": "S", "time": 4,
|
| 582 |
+
"solo": {"CP": 4}, "coop": {"CP": 6}, "cost": 4, "qol": 1},
|
| 583 |
+
{"id": "S2", "name": "Community Event", "type": "S", "time": 3,
|
| 584 |
+
"solo": {"HP": 3}, "coop": {"HP": 4}, "reward": 0},
|
| 585 |
+
|
| 586 |
+
# QoL Investment Tasks (Q1-Q4)
|
| 587 |
+
{"id": "Q1", "name": "Buy Furniture", "type": "Q", "time": 2,
|
| 588 |
+
"solo": {"HP": 2}, "coop": {"HP": 3}, "cost": 10, "qol": 5},
|
| 589 |
{"id": "Q2", "name": "Weekend Trip", "type": "Q", "time": 7,
|
| 590 |
"solo": {"HP": 5, "CP": 4}, "coop": {"HP": 9}, "cost": 15, "qol": 7, "effect": "recover_all"},
|
| 591 |
+
{"id": "Q3", "name": "Home Upgrade", "type": "Q", "time": 4,
|
| 592 |
+
"solo": {"HP": 3}, "coop": {"HP": 5}, "cost": 8, "qol": 4},
|
| 593 |
+
{"id": "Q4", "name": "Spa Day", "type": "Q", "time": 5,
|
| 594 |
+
"solo": {"HP": 4}, "coop": {"HP": 6}, "cost": 12, "qol": 6, "effect": "stress:-3"},
|
| 595 |
]
|
| 596 |
|
| 597 |
# ===== GLOBAL STATE =====
|
|
|
|
| 821 |
gr.Markdown("### Player 1")
|
| 822 |
p1_name = gr.Textbox(label="Name", interactive=False)
|
| 823 |
p1_character = gr.Textbox(label="Character", interactive=False)
|
|
|
|
| 824 |
with gr.Row():
|
| 825 |
p1_time = gr.Number(label="β° Time", interactive=False)
|
| 826 |
p1_money = gr.Number(label="π° Money", interactive=False)
|
|
|
|
| 882 |
gr.Markdown("### Player 2")
|
| 883 |
p2_name = gr.Textbox(label="Name", interactive=False)
|
| 884 |
p2_character = gr.Textbox(label="Character", interactive=False)
|
|
|
|
| 885 |
with gr.Row():
|
| 886 |
p2_time = gr.Number(label="β° Time", interactive=False)
|
| 887 |
p2_money = gr.Number(label="π° Money", interactive=False)
|
|
|
|
| 939 |
return {}, f"β {msg}"
|
| 940 |
|
| 941 |
def refresh_game_state(session):
|
| 942 |
+
empty_return = ("*No game joined*", "", "", {}, {}, [], gr.Dropdown(choices=[]), "*No spectators*", "")
|
| 943 |
+
|
| 944 |
if not session.get('room_id'):
|
| 945 |
+
return empty_return
|
| 946 |
|
| 947 |
state = db.get_room_state(session['room_id'])
|
| 948 |
if not state:
|
| 949 |
+
return empty_return
|
| 950 |
|
| 951 |
room = state['room']
|
| 952 |
players = state['players']
|
| 953 |
|
| 954 |
# Status
|
| 955 |
status_md = f"""
|
| 956 |
+
**Room:** {session['room_id']} | **Round:** {room['current_round']}/{room['total_rounds']}
|
| 957 |
**Status:** {room['status'].upper()} | **Current Turn:** Player {room['current_turn'] + 1}
|
| 958 |
"""
|
| 959 |
|
| 960 |
if room['status'] == 'finished':
|
| 961 |
+
winner_name = next((p['name'] for p in players if p['player_id'] == room['winner_id']), "Unknown")
|
| 962 |
+
status_md += f"\n\nπ **GAME OVER!** Winner: **{winner_name}**"
|
| 963 |
|
| 964 |
+
# Player data
|
| 965 |
p1_data = players[0] if len(players) > 0 else {}
|
| 966 |
p2_data = players[1] if len(players) > 1 else {}
|
| 967 |
|
| 968 |
+
p1_name = p1_data.get('name', '')
|
| 969 |
+
p1_char = p1_data.get('character_id', '')
|
| 970 |
+
p2_name = p2_data.get('name', '')
|
| 971 |
+
p2_char = p2_data.get('character_id', '')
|
| 972 |
+
|
| 973 |
+
# Tasks with better formatting
|
| 974 |
task_rows = []
|
| 975 |
+
task_options = []
|
| 976 |
for task_id in state['task_ids']:
|
| 977 |
task = next((t for t in TASKS if t['id'] == task_id), None)
|
| 978 |
if task:
|
| 979 |
+
solo_req = ', '.join([f"{k}:{v}" for k, v in task['solo'].items()])
|
| 980 |
+
coop_req = ', '.join([f"{k}:{v}" for k, v in task['coop'].items()])
|
| 981 |
+
|
| 982 |
+
if 'reward' in task and task['reward'] > 0:
|
| 983 |
+
reward_str = f"${task['reward']}"
|
| 984 |
+
elif 'qol' in task:
|
| 985 |
+
reward_str = f"{task['qol']} QoL"
|
| 986 |
+
else:
|
| 987 |
+
reward_str = "Utility"
|
| 988 |
+
|
| 989 |
task_rows.append([
|
| 990 |
task['id'], task['name'], task['type'],
|
| 991 |
+
f"{task['time']}h", solo_req, coop_req, reward_str
|
| 992 |
])
|
| 993 |
+
task_options.append((f"{task['id']} - {task['name']}", task['id']))
|
|
|
|
|
|
|
| 994 |
|
| 995 |
# Spectators
|
| 996 |
spec_md = f"π₯ {len(state['spectators'])} watching: {', '.join(state['spectators'])}" if state['spectators'] else "*No spectators*"
|
| 997 |
|
| 998 |
# Turn indicator
|
| 999 |
if session.get('is_spectator'):
|
| 1000 |
+
turn_msg = "ποΈ **You are spectating** - Refresh to see updates"
|
| 1001 |
+
elif room['status'] == 'waiting':
|
| 1002 |
+
turn_msg = "β³ **Waiting for Player 2 to join...**"
|
| 1003 |
+
elif room['status'] == 'finished':
|
| 1004 |
+
turn_msg = "π **Game Finished!** Check Rankings tab."
|
| 1005 |
elif session.get('player_slot') == room['current_turn']:
|
| 1006 |
turn_msg = "β
**YOUR TURN!** Take an action below."
|
| 1007 |
else:
|
| 1008 |
+
turn_msg = "β³ **Partner's turn...** Click Refresh to see updates."
|
| 1009 |
|
| 1010 |
+
return (status_md, p1_name, p1_char, p1_data, p2_name, p2_char, p2_data,
|
| 1011 |
+
task_rows, gr.Dropdown(choices=task_options, value=None), spec_md, turn_msg)
|
| 1012 |
|
| 1013 |
def execute_rest_handler(session, rest_type):
|
| 1014 |
if not session.get('room_id') or session.get('is_spectator'):
|
|
|
|
| 1110 |
refresh_btn.click(
|
| 1111 |
refresh_game_state,
|
| 1112 |
inputs=[session_state],
|
| 1113 |
+
outputs=[status_display, p1_name, p1_character, p1_display,
|
| 1114 |
+
p2_name, p2_character, p2_display, tasks_display, task_select,
|
| 1115 |
spectators_display, your_turn_msg]
|
| 1116 |
)
|
| 1117 |
|
|
|
|
| 1122 |
).then(
|
| 1123 |
refresh_game_state,
|
| 1124 |
inputs=[session_state],
|
| 1125 |
+
outputs=[status_display, p1_name, p1_character, p1_display,
|
| 1126 |
+
p2_name, p2_character, p2_display, tasks_display, task_select,
|
| 1127 |
spectators_display, your_turn_msg]
|
| 1128 |
)
|
| 1129 |
|
|
|
|
| 1134 |
).then(
|
| 1135 |
refresh_game_state,
|
| 1136 |
inputs=[session_state],
|
| 1137 |
+
outputs=[status_display, p1_name, p1_character, p1_display,
|
| 1138 |
+
p2_name, p2_character, p2_display, tasks_display, task_select,
|
| 1139 |
spectators_display, your_turn_msg]
|
| 1140 |
)
|
| 1141 |
|
|
|
|
| 1146 |
).then(
|
| 1147 |
refresh_game_state,
|
| 1148 |
inputs=[session_state],
|
| 1149 |
+
outputs=[status_display, p1_name, p1_character, p1_display,
|
| 1150 |
+
p2_name, p2_character, p2_display, tasks_display, task_select,
|
| 1151 |
spectators_display, your_turn_msg]
|
| 1152 |
)
|
| 1153 |
|
|
|
|
| 1158 |
).then(
|
| 1159 |
refresh_game_state,
|
| 1160 |
inputs=[session_state],
|
| 1161 |
+
outputs=[status_display, p1_name, p1_character, p1_display,
|
| 1162 |
+
p2_name, p2_character, p2_display, tasks_display, task_select,
|
| 1163 |
spectators_display, your_turn_msg]
|
| 1164 |
)
|
| 1165 |
|
|
|
|
| 1170 |
).then(
|
| 1171 |
refresh_game_state,
|
| 1172 |
inputs=[session_state],
|
| 1173 |
+
outputs=[status_display, p1_name, p1_character, p1_display,
|
| 1174 |
+
p2_name, p2_character, p2_display, tasks_display, task_select,
|
| 1175 |
spectators_display, your_turn_msg]
|
| 1176 |
)
|
| 1177 |
|