Bug fixes

This commit is contained in:
2026-01-08 06:51:15 +07:00
parent 4488a13808
commit 2874b64481
12 changed files with 434 additions and 54 deletions

View File

@@ -1,7 +1,7 @@
"""
Consumables Service - handles consumable items usage (skip, shield, boost, reroll)
"""
from datetime import datetime, timedelta
from datetime import datetime
from fastapi import HTTPException
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
@@ -17,7 +17,6 @@ class ConsumablesService:
"""Service for consumable items"""
# Boost settings
BOOST_DURATION_HOURS = 2
BOOST_MULTIPLIER = 1.5
async def use_skip(
@@ -141,10 +140,10 @@ class ConsumablesService:
marathon: Marathon,
) -> dict:
"""
Activate a Boost - multiplies points for next 2 hours.
Activate a Boost - multiplies points for NEXT complete only.
- Points for completed challenges are multiplied by BOOST_MULTIPLIER
- Duration: BOOST_DURATION_HOURS
- Points for next completed challenge are multiplied by BOOST_MULTIPLIER
- One-time use (consumed on next complete)
Returns: dict with result info
@@ -155,17 +154,13 @@ class ConsumablesService:
raise HTTPException(status_code=400, detail="Consumables are not allowed in this marathon")
if participant.has_active_boost:
raise HTTPException(
status_code=400,
detail=f"Boost already active until {participant.active_boost_expires_at}"
)
raise HTTPException(status_code=400, detail="Boost is already activated")
# Consume boost from inventory
item = await self._consume_item(db, user, ConsumableType.BOOST.value)
# Activate boost
participant.active_boost_multiplier = self.BOOST_MULTIPLIER
participant.active_boost_expires_at = datetime.utcnow() + timedelta(hours=self.BOOST_DURATION_HOURS)
# Activate boost (one-time use)
participant.has_active_boost = True
# Log usage
usage = ConsumableUsage(
@@ -175,8 +170,7 @@ class ConsumablesService:
effect_data={
"type": "boost",
"multiplier": self.BOOST_MULTIPLIER,
"duration_hours": self.BOOST_DURATION_HOURS,
"expires_at": participant.active_boost_expires_at.isoformat(),
"one_time": True,
},
)
db.add(usage)
@@ -185,7 +179,6 @@ class ConsumablesService:
"success": True,
"boost_activated": True,
"multiplier": self.BOOST_MULTIPLIER,
"expires_at": participant.active_boost_expires_at,
}
async def use_reroll(
@@ -299,7 +292,7 @@ class ConsumablesService:
quantity = result.scalar_one_or_none()
return quantity or 0
def consume_shield_on_drop(self, participant: Participant) -> bool:
def consume_shield(self, participant: Participant) -> bool:
"""
Consume shield when dropping (called from wheel.py).
@@ -310,13 +303,17 @@ class ConsumablesService:
return True
return False
def get_active_boost_multiplier(self, participant: Participant) -> float:
def consume_boost_on_complete(self, participant: Participant) -> float:
"""
Get current boost multiplier for participant.
Consume boost when completing assignment (called from wheel.py).
One-time use - boost is consumed after single complete.
Returns: Multiplier value (1.0 if no active boost)
Returns: Multiplier value (BOOST_MULTIPLIER if boost was active, 1.0 otherwise)
"""
return participant.get_boost_multiplier()
if participant.has_active_boost:
participant.has_active_boost = False
return self.BOOST_MULTIPLIER
return 1.0
# Singleton instance