Merge branch 'master' into marathon-v2
This commit is contained in:
@@ -163,10 +163,13 @@ async def spin_wheel(marathon_id: int, current_user: CurrentUser, db: DbSession)
|
||||
game = random.choice(available_games)
|
||||
|
||||
if game.game_type == GameType.PLAYTHROUGH.value:
|
||||
# Playthrough game - no challenge selection, ignore events
|
||||
# Playthrough game - no challenge selection
|
||||
# Events that apply to playthrough: GOLDEN_HOUR, DOUBLE_RISK, COMMON_ENEMY
|
||||
# Events that DON'T apply: JACKPOT (hard challenges only)
|
||||
is_playthrough = True
|
||||
challenge = None
|
||||
active_event = None # Ignore events for playthrough
|
||||
if active_event and active_event.type == EventType.JACKPOT.value:
|
||||
active_event = None # Jackpot doesn't apply to playthrough
|
||||
else:
|
||||
# Challenges game - select random challenge
|
||||
if not game.challenges:
|
||||
@@ -203,7 +206,7 @@ async def spin_wheel(marathon_id: int, current_user: CurrentUser, db: DbSession)
|
||||
game_id=game.id,
|
||||
is_playthrough=True,
|
||||
status=AssignmentStatus.ACTIVE.value,
|
||||
# No event_type for playthrough
|
||||
event_type=active_event.type if active_event else None,
|
||||
)
|
||||
db.add(assignment)
|
||||
await db.flush() # Get assignment.id for bonus assignments
|
||||
@@ -226,6 +229,8 @@ async def spin_wheel(marathon_id: int, current_user: CurrentUser, db: DbSession)
|
||||
"points": game.playthrough_points,
|
||||
"bonus_challenges_count": len(bonus_challenges),
|
||||
}
|
||||
if active_event:
|
||||
activity_data["event_type"] = active_event.type
|
||||
else:
|
||||
# Regular challenge assignment
|
||||
assignment = Assignment(
|
||||
@@ -325,6 +330,7 @@ async def spin_wheel(marathon_id: int, current_user: CurrentUser, db: DbSession)
|
||||
],
|
||||
can_drop=True,
|
||||
drop_penalty=drop_penalty,
|
||||
event_type=active_event.type if active_event else None,
|
||||
)
|
||||
else:
|
||||
# Return challenge result
|
||||
@@ -348,6 +354,7 @@ async def spin_wheel(marathon_id: int, current_user: CurrentUser, db: DbSession)
|
||||
is_playthrough=False,
|
||||
can_drop=True,
|
||||
drop_penalty=drop_penalty,
|
||||
event_type=active_event.type if active_event else None,
|
||||
)
|
||||
|
||||
|
||||
@@ -373,9 +380,17 @@ async def get_current_assignment(marathon_id: int, current_user: CurrentUser, db
|
||||
# Handle playthrough assignments
|
||||
if assignment.is_playthrough:
|
||||
game = assignment.game
|
||||
active_event = None # No events for playthrough
|
||||
# Use stored event_type for playthrough
|
||||
# All events except JACKPOT apply (DOUBLE_RISK = free drop, others affect points)
|
||||
playthrough_event = None
|
||||
if assignment.event_type and assignment.event_type != EventType.JACKPOT.value:
|
||||
class MockEvent:
|
||||
def __init__(self, event_type):
|
||||
self.type = event_type
|
||||
playthrough_event = MockEvent(assignment.event_type)
|
||||
|
||||
drop_penalty = points_service.calculate_drop_penalty(
|
||||
participant.drop_count, game.playthrough_points, None
|
||||
participant.drop_count, game.playthrough_points, playthrough_event
|
||||
)
|
||||
|
||||
# Build bonus challenges response
|
||||
@@ -425,6 +440,7 @@ async def get_current_assignment(marathon_id: int, current_user: CurrentUser, db
|
||||
completed_at=assignment.completed_at,
|
||||
drop_penalty=drop_penalty,
|
||||
bonus_challenges=bonus_responses,
|
||||
event_type=assignment.event_type,
|
||||
)
|
||||
|
||||
# Regular challenge assignment
|
||||
@@ -459,6 +475,7 @@ async def get_current_assignment(marathon_id: int, current_user: CurrentUser, db
|
||||
started_at=assignment.started_at,
|
||||
completed_at=assignment.completed_at,
|
||||
drop_penalty=drop_penalty,
|
||||
event_type=assignment.event_type,
|
||||
)
|
||||
|
||||
|
||||
@@ -572,19 +589,37 @@ async def complete_assignment(
|
||||
if assignment.is_playthrough:
|
||||
game = assignment.game
|
||||
marathon_id = game.marathon_id
|
||||
base_points = game.playthrough_points
|
||||
base_playthrough_points = game.playthrough_points
|
||||
|
||||
# No events for playthrough
|
||||
total_points, streak_bonus, _ = points_service.calculate_completion_points(
|
||||
base_points, participant.current_streak, None
|
||||
)
|
||||
|
||||
# Calculate bonus points from completed bonus assignments
|
||||
bonus_points = sum(
|
||||
ba.points_earned for ba in assignment.bonus_assignments
|
||||
# Calculate BASE bonus points from completed bonus assignments (before multiplier)
|
||||
base_bonus_points = sum(
|
||||
ba.challenge.points for ba in assignment.bonus_assignments
|
||||
if ba.status == BonusAssignmentStatus.COMPLETED.value
|
||||
)
|
||||
total_points += bonus_points
|
||||
|
||||
# Total base = playthrough + all bonuses
|
||||
total_base_points = base_playthrough_points + base_bonus_points
|
||||
|
||||
# Get event for playthrough (use stored event_type from assignment)
|
||||
# All events except JACKPOT apply to playthrough
|
||||
playthrough_event = None
|
||||
if assignment.event_type and assignment.event_type != EventType.JACKPOT.value:
|
||||
class MockEvent:
|
||||
def __init__(self, event_type):
|
||||
self.type = event_type
|
||||
playthrough_event = MockEvent(assignment.event_type)
|
||||
|
||||
# Apply multiplier to the TOTAL (base + bonuses), then add streak bonus
|
||||
total_points, streak_bonus, event_bonus = points_service.calculate_completion_points(
|
||||
total_base_points, participant.current_streak, playthrough_event
|
||||
)
|
||||
|
||||
# Update bonus assignments to reflect multiplied points for display
|
||||
if playthrough_event:
|
||||
multiplier = points_service.EVENT_MULTIPLIERS.get(playthrough_event.type, 1.0)
|
||||
for ba in assignment.bonus_assignments:
|
||||
if ba.status == BonusAssignmentStatus.COMPLETED.value:
|
||||
ba.points_earned = int(ba.challenge.points * multiplier)
|
||||
|
||||
# Apply boost multiplier from consumable
|
||||
boost_multiplier = consumables_service.get_active_boost_multiplier(participant)
|
||||
@@ -623,8 +658,8 @@ async def complete_assignment(
|
||||
"game": game.title,
|
||||
"is_playthrough": True,
|
||||
"points": total_points,
|
||||
"base_points": base_points,
|
||||
"bonus_points": bonus_points,
|
||||
"base_points": base_playthrough_points,
|
||||
"bonus_points": base_bonus_points,
|
||||
"streak": participant.current_streak,
|
||||
}
|
||||
if is_redo:
|
||||
@@ -633,6 +668,9 @@ async def complete_assignment(
|
||||
activity_data["boost_multiplier"] = boost_multiplier
|
||||
if coins_earned > 0:
|
||||
activity_data["coins_earned"] = coins_earned
|
||||
if playthrough_event:
|
||||
activity_data["event_type"] = playthrough_event.type
|
||||
activity_data["event_bonus"] = event_bonus
|
||||
|
||||
activity = Activity(
|
||||
marathon_id=marathon_id,
|
||||
@@ -836,9 +874,17 @@ async def drop_assignment(assignment_id: int, current_user: CurrentUser, db: DbS
|
||||
game = assignment.game
|
||||
marathon_id = game.marathon_id
|
||||
|
||||
# No events for playthrough
|
||||
# Use stored event_type for drop penalty calculation
|
||||
# DOUBLE_RISK = free drop (0 penalty)
|
||||
playthrough_event = None
|
||||
if assignment.event_type and assignment.event_type != EventType.JACKPOT.value:
|
||||
class MockEvent:
|
||||
def __init__(self, event_type):
|
||||
self.type = event_type
|
||||
playthrough_event = MockEvent(assignment.event_type)
|
||||
|
||||
penalty = points_service.calculate_drop_penalty(
|
||||
participant.drop_count, game.playthrough_points, None
|
||||
participant.drop_count, game.playthrough_points, playthrough_event
|
||||
)
|
||||
|
||||
# Check for shield - if active, no penalty
|
||||
@@ -877,6 +923,9 @@ async def drop_assignment(assignment_id: int, current_user: CurrentUser, db: DbS
|
||||
}
|
||||
if shield_used:
|
||||
activity_data["shield_used"] = True
|
||||
if playthrough_event:
|
||||
activity_data["event_type"] = playthrough_event.type
|
||||
activity_data["free_drop"] = True
|
||||
|
||||
activity = Activity(
|
||||
marathon_id=marathon_id,
|
||||
|
||||
Reference in New Issue
Block a user