setup_sig_session: wire deck contributions; _room_deck_variant replaces owner.equipped_deck
- setup_sig_session: drop _ensure_earthman() (deck seeded by migration); set deck_variant=earthman on all TableSeats; users get unlocked_decks add but equipped_deck=None (seat owns the deck); docstring documents role-pair mapping - _room_deck_variant(room): new helper looks up deck from any seated deck_variant, falls back to owner.equipped_deck for legacy rooms - sig_deck_cards / _sig_unique_cards: use _room_deck_variant instead of owner.equipped_deck — sig cards now work even when users have unequipped their deck after role confirmation Code architected by Disco DeDisco <discodedisco@outlook.com> Git commit message Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -421,6 +421,19 @@ class SigReservation(models.Model):
|
|||||||
|
|
||||||
# ── Significator deck helpers ─────────────────────────────────────────────────
|
# ── Significator deck helpers ─────────────────────────────────────────────────
|
||||||
|
|
||||||
|
def _room_deck_variant(room):
|
||||||
|
"""Return the DeckVariant in use for this room.
|
||||||
|
|
||||||
|
Looks up the deck committed to any TableSeat in the room (all seats share the
|
||||||
|
same deck per game). Falls back to the room owner's equipped_deck for rooms
|
||||||
|
created before deck contribution was wired.
|
||||||
|
"""
|
||||||
|
seat = room.table_seats.filter(deck_variant__isnull=False).first()
|
||||||
|
if seat:
|
||||||
|
return seat.deck_variant
|
||||||
|
return room.owner.equipped_deck
|
||||||
|
|
||||||
|
|
||||||
def sig_deck_cards(room):
|
def sig_deck_cards(room):
|
||||||
"""Return 36 TarotCard objects forming the Significator deck (18 unique × 2).
|
"""Return 36 TarotCard objects forming the Significator deck (18 unique × 2).
|
||||||
|
|
||||||
@@ -429,7 +442,7 @@ def sig_deck_cards(room):
|
|||||||
NC/EC pair → MAJOR arcana numbers 0 and 1: 2 unique
|
NC/EC pair → MAJOR arcana numbers 0 and 1: 2 unique
|
||||||
Total: 18 unique × 2 (levity + gravity piles) = 36 cards.
|
Total: 18 unique × 2 (levity + gravity piles) = 36 cards.
|
||||||
"""
|
"""
|
||||||
deck_variant = room.owner.equipped_deck
|
deck_variant = _room_deck_variant(room)
|
||||||
if deck_variant is None:
|
if deck_variant is None:
|
||||||
return []
|
return []
|
||||||
wands_crowns = list(TarotCard.objects.filter(
|
wands_crowns = list(TarotCard.objects.filter(
|
||||||
@@ -455,7 +468,7 @@ def sig_deck_cards(room):
|
|||||||
|
|
||||||
def _sig_unique_cards(room):
|
def _sig_unique_cards(room):
|
||||||
"""Return the 18 unique TarotCard objects that form one sig pile."""
|
"""Return the 18 unique TarotCard objects that form one sig pile."""
|
||||||
deck_variant = room.owner.equipped_deck
|
deck_variant = _room_deck_variant(room)
|
||||||
if deck_variant is None:
|
if deck_variant is None:
|
||||||
return []
|
return []
|
||||||
wands_crowns = list(TarotCard.objects.filter(
|
wands_crowns = list(TarotCard.objects.filter(
|
||||||
|
|||||||
@@ -2,8 +2,13 @@
|
|||||||
Management command for manual multi-user sig-select testing.
|
Management command for manual multi-user sig-select testing.
|
||||||
|
|
||||||
Creates (or reuses) a room with all 6 gate slots filled, roles assigned,
|
Creates (or reuses) a room with all 6 gate slots filled, roles assigned,
|
||||||
and table_status=SIG_SELECT. Prints one pre-auth URL per gamer so you can
|
deck contributions wired, and table_status=SIG_SELECT. Prints one pre-auth
|
||||||
paste them into 6 Firefox Multi-Account Container tabs.
|
URL per gamer so you can paste them into 6 Firefox Multi-Account Container tabs.
|
||||||
|
|
||||||
|
Deck contribution by role pair (same segment, levity vs gravity pole):
|
||||||
|
PC & BC → Brands + Crowns (levity / gravity)
|
||||||
|
SC & AC → Blades + Grails (levity / gravity)
|
||||||
|
NC & EC → Trumps (levity / gravity)
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
python src/manage.py setup_sig_session
|
python src/manage.py setup_sig_session
|
||||||
@@ -15,7 +20,7 @@ from django.contrib.auth import BACKEND_SESSION_KEY, HASH_SESSION_KEY, SESSION_K
|
|||||||
from django.contrib.sessions.backends.db import SessionStore
|
from django.contrib.sessions.backends.db import SessionStore
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
|
|
||||||
from apps.epic.models import DeckVariant, GateSlot, Room, TableSeat, TarotCard
|
from apps.epic.models import DeckVariant, GateSlot, Room, TableSeat
|
||||||
from apps.lyric.models import User
|
from apps.lyric.models import User
|
||||||
|
|
||||||
|
|
||||||
@@ -31,28 +36,6 @@ GAMERS = [
|
|||||||
ROLES = ["PC", "NC", "EC", "SC", "AC", "BC"]
|
ROLES = ["PC", "NC", "EC", "SC", "AC", "BC"]
|
||||||
|
|
||||||
|
|
||||||
def _ensure_earthman():
|
|
||||||
"""Return (or create) the Earthman DeckVariant with enough sig-deck cards seeded."""
|
|
||||||
earthman, _ = DeckVariant.objects.get_or_create(
|
|
||||||
slug="earthman",
|
|
||||||
defaults={"name": "Earthman Deck", "card_count": 108, "is_default": True},
|
|
||||||
)
|
|
||||||
_NAME = {11: "Maid", 12: "Jack", 13: "Queen", 14: "King"}
|
|
||||||
for suit in ("WANDS", "PENTACLES", "SWORDS", "CUPS"):
|
|
||||||
for number in (11, 12, 13, 14):
|
|
||||||
TarotCard.objects.get_or_create(
|
|
||||||
deck_variant=earthman,
|
|
||||||
slug=f"{_NAME[number].lower()}-of-{suit.lower()}-em",
|
|
||||||
defaults={
|
|
||||||
"arcana": "MINOR",
|
|
||||||
"suit": suit,
|
|
||||||
"number": number,
|
|
||||||
"name": f"{_NAME[number]} of {suit.capitalize()}",
|
|
||||||
},
|
|
||||||
)
|
|
||||||
return earthman
|
|
||||||
|
|
||||||
|
|
||||||
def _make_session(user):
|
def _make_session(user):
|
||||||
session = SessionStore()
|
session = SessionStore()
|
||||||
session[SESSION_KEY] = str(user.pk)
|
session[SESSION_KEY] = str(user.pk)
|
||||||
@@ -71,7 +54,7 @@ class Command(BaseCommand):
|
|||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
base_url = options["base_url"].rstrip("/")
|
base_url = options["base_url"].rstrip("/")
|
||||||
earthman = _ensure_earthman()
|
earthman = DeckVariant.objects.get(slug="earthman")
|
||||||
|
|
||||||
# ── Users ────────────────────────────────────────────────────────────
|
# ── Users ────────────────────────────────────────────────────────────
|
||||||
users = []
|
users = []
|
||||||
@@ -79,9 +62,11 @@ class Command(BaseCommand):
|
|||||||
user, _ = User.objects.get_or_create(email=email)
|
user, _ = User.objects.get_or_create(email=email)
|
||||||
user.is_staff = True
|
user.is_staff = True
|
||||||
user.is_superuser = True
|
user.is_superuser = True
|
||||||
if not user.equipped_deck:
|
# Deck will be assigned to seat below; ensure it's in unlocked_decks
|
||||||
user.equipped_deck = earthman
|
# but leave equipped_deck=None (seat assignment owns it)
|
||||||
|
user.equipped_deck = None
|
||||||
user.save()
|
user.save()
|
||||||
|
user.unlocked_decks.add(earthman)
|
||||||
users.append(user)
|
users.append(user)
|
||||||
|
|
||||||
# ── Room ─────────────────────────────────────────────────────────────
|
# ── Room ─────────────────────────────────────────────────────────────
|
||||||
@@ -104,11 +89,21 @@ class Command(BaseCommand):
|
|||||||
room.gate_status = Room.OPEN
|
room.gate_status = Room.OPEN
|
||||||
room.save()
|
room.save()
|
||||||
|
|
||||||
# ── Table seats + roles ──────────────────────────────────────────────
|
# ── Table seats + roles + deck contributions ─────────────────────────
|
||||||
|
# PC/NC/SC → levity pole; BC/EC/AC → gravity pole.
|
||||||
|
# Each role pair shares a deck segment:
|
||||||
|
# PC & BC → Brands + Crowns
|
||||||
|
# SC & AC → Blades + Grails
|
||||||
|
# NC & EC → Trumps
|
||||||
for i, (user, role) in enumerate(zip(users, ROLES), start=1):
|
for i, (user, role) in enumerate(zip(users, ROLES), start=1):
|
||||||
TableSeat.objects.update_or_create(
|
TableSeat.objects.update_or_create(
|
||||||
room=room, slot_number=i,
|
room=room, slot_number=i,
|
||||||
defaults={"gamer": user, "role": role, "role_revealed": True},
|
defaults={
|
||||||
|
"gamer": user,
|
||||||
|
"role": role,
|
||||||
|
"role_revealed": True,
|
||||||
|
"deck_variant": earthman,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
room.table_status = Room.SIG_SELECT
|
room.table_status = Room.SIG_SELECT
|
||||||
|
|||||||
Reference in New Issue
Block a user