PICK SEA Sprint B: deck stacks, OK btn, card draw, LOCK HAND/DEL — TDD
- _sea_overlay.html: DEAL btn replaced by two .sea-deck-stack--levity/gravity piles; .sea-pos-cover + .sea-pos-cross overlaid on center sig slot; LOCK HAND (disabled) + DEL (.btn-danger) in .sea-form-actions; data-sea-deck-url attr - sea overlay inline JS: _fetchDeck() loads shuffled piles from sea_deck endpoint; stack click → _showOk(); click elsewhere → _hideOk(); OK click → _fillPos() in next spread-order position; DEL → _reset(); LOCK HAND enables at 6 fills - SPREAD_ORDER constants for waite-smith + escape-velocity spread types - sea_deck view: shuffles full equipped deck minus all seated Significators, splits into levity (first half) + gravity (second half) JSON arrays - epic:sea_deck URL registered - sea_partial view: ctx['room'] = room added (fixes NoReverseMatch for sea_deck URL) - _card-deck.scss: .sea-card-slot--filled; .sea-pos-cover/cross absolute overlay; .sea-deck-stack + .sea-stack-face; .sea-form-actions layout; removed old DEAL rule - 9 Sprint B FTs green; 3 Sprint A FTs green; 730 ITs green 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:
@@ -1108,6 +1108,40 @@ def natus_save(request, room_id):
|
||||
return JsonResponse({'id': char.id, 'confirmed': char.is_confirmed})
|
||||
|
||||
|
||||
@login_required
|
||||
def sea_deck(request, room_id):
|
||||
"""Shuffled deck lists (levity + gravity halves) for PICK SEA draw.
|
||||
|
||||
Excludes all Significators already claimed by seated gamers.
|
||||
Returns {levity: [{id, name, arcana, suit, number, levity_qualifier,
|
||||
gravity_qualifier}], gravity: [...]}
|
||||
"""
|
||||
import random as _random
|
||||
room = Room.objects.get(id=room_id)
|
||||
seat = _canonical_user_seat(room, request.user)
|
||||
if seat is None:
|
||||
return HttpResponse(status=403)
|
||||
|
||||
deck = seat.deck_variant
|
||||
if not deck:
|
||||
return JsonResponse({'levity': [], 'gravity': []})
|
||||
|
||||
sig_ids = set(
|
||||
room.table_seats.exclude(significator__isnull=True)
|
||||
.values_list('significator_id', flat=True)
|
||||
)
|
||||
|
||||
available = list(
|
||||
TarotCard.objects.filter(deck_variant=deck)
|
||||
.exclude(id__in=sig_ids)
|
||||
.values('id', 'name', 'arcana', 'suit', 'number',
|
||||
'levity_qualifier', 'gravity_qualifier')
|
||||
)
|
||||
_random.shuffle(available)
|
||||
mid = len(available) // 2
|
||||
return JsonResponse({'levity': available[:mid], 'gravity': available[mid:]})
|
||||
|
||||
|
||||
@login_required
|
||||
def sea_partial(request, room_id):
|
||||
"""Return the rendered sea overlay partial for in-page injection after sky confirm."""
|
||||
@@ -1115,5 +1149,6 @@ def sea_partial(request, room_id):
|
||||
ctx = _role_select_context(room, request.user)
|
||||
if not ctx.get('sky_confirmed'):
|
||||
return HttpResponse(status=403)
|
||||
ctx['room'] = room
|
||||
return render(request, 'apps/gameboard/_partials/_sea_overlay.html', ctx)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user