Added quiz new features
This commit is contained in:
@@ -8,6 +8,7 @@ use App\Models\PvpMatch;
|
||||
use App\Traits\BaseApiResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class PvPQuizController extends Controller
|
||||
{
|
||||
@@ -19,12 +20,13 @@ class PvPQuizController extends Controller
|
||||
public function findMatch(Request $request)
|
||||
{
|
||||
$userId = auth()->id();
|
||||
$ticketId = $request->input('ticket_id') ?? 'req_' . Str::random(12);
|
||||
|
||||
// 1. Check if anyone else is waiting in the cache queue
|
||||
$waitingPlayer = Cache::get('pvp_waiting_player');
|
||||
|
||||
// Ensure we don't match the user with themselves
|
||||
if ($waitingPlayer && $waitingPlayer != $userId) {
|
||||
if ($waitingPlayer && $waitingPlayer['user_id'] != $userId) {
|
||||
|
||||
// MATCH FOUND! Remove the waiting player from the queue
|
||||
Cache::forget('pvp_waiting_player');
|
||||
@@ -37,7 +39,7 @@ class PvPQuizController extends Controller
|
||||
|
||||
// Add both players to the match
|
||||
$match->players()->createMany([
|
||||
['user_id' => $waitingPlayer, 'score' => 0],
|
||||
['user_id' => $waitingPlayer['user_id'], 'score' => 0],
|
||||
['user_id' => $userId, 'score' => 0],
|
||||
]);
|
||||
|
||||
@@ -50,23 +52,33 @@ class PvPQuizController extends Controller
|
||||
// Attach questions to the match
|
||||
$match->questions()->attach($questions);
|
||||
|
||||
// TODO (Next Step): Fire a WebSocket Event here to tell Player 1 the match started!
|
||||
|
||||
return $this->success([
|
||||
// Prepare the payload for both players
|
||||
$matchData = [
|
||||
'match_id' => $match->id,
|
||||
'status' => 'matched',
|
||||
'opponent_id' => $waitingPlayer,
|
||||
'questions' => $match->questions()->with('options')->get()->makeHidden(['solution_explanation'])->each(function($q) {
|
||||
$q->options->each->makeHidden(['is_correct']);
|
||||
})
|
||||
], 'موفق', 'حریف پیدا شد! بازی شروع میشود.');
|
||||
];
|
||||
|
||||
// FIRE THE WEBSOCKET EVENT TO PLAYER A!
|
||||
event(new \App\Events\MatchStarted($matchData, $waitingPlayer['ticket_id']));
|
||||
|
||||
// Return the same payload to Player B via standard HTTP response
|
||||
$matchData['opponent_id'] = $waitingPlayer['user_id'];
|
||||
|
||||
return $this->success($matchData, 'موفق', 'حریف پیدا شد! بازی شروع میشود.');
|
||||
}
|
||||
|
||||
// NO MATCH FOUND YET. Put this user in the waiting queue for 30 seconds.
|
||||
Cache::put('pvp_waiting_player', $userId, 30);
|
||||
// NO MATCH FOUND YET. Put Player A in the waiting queue and save their Ticket ID
|
||||
Cache::put('pvp_waiting_player', [
|
||||
'user_id' => $userId,
|
||||
'ticket_id' => $ticketId
|
||||
], 30);
|
||||
|
||||
return $this->success([
|
||||
'status' => 'waiting'
|
||||
'status' => 'waiting',
|
||||
'ticket_id' => $ticketId
|
||||
], 'در حال جستجو', 'در حال یافتن حریف...');
|
||||
}
|
||||
|
||||
@@ -169,28 +181,59 @@ class PvPQuizController extends Controller
|
||||
'winner_id' => $winnerId
|
||||
]);
|
||||
|
||||
// --- NEW: UPDATE GAMIFICATION STATS ---
|
||||
// --- UPDATE GAMIFICATION STATS ---
|
||||
$user1 = \App\Models\User::find($player1->user_id);
|
||||
$user2 = \App\Models\User::find($player2->user_id);
|
||||
|
||||
$user1->increment('duels_played');
|
||||
$user2->increment('duels_played');
|
||||
|
||||
// Give XP and Wins
|
||||
// Give XP, Wins, and update "Win Duel" Quests
|
||||
if ($winnerId) {
|
||||
$winner = \App\Models\User::find($winnerId);
|
||||
$winner->increment('duels_won');
|
||||
$winner->increment('xp', 50); // Winner gets 50 XP
|
||||
|
||||
// NOTE: Here we will later trigger the "duel_win" Daily Quest progress!
|
||||
$duelQuest = $winner->activeQuests()
|
||||
->whereHas('quest', function ($q) {
|
||||
$q->where('quest_type', 'duel_win');
|
||||
})->where('is_completed', false)->first();
|
||||
|
||||
if ($duelQuest) {
|
||||
$duelQuest->increment('current_progress');
|
||||
|
||||
if ($duelQuest->current_progress >= $duelQuest->quest->required_amount) {
|
||||
$duelQuest->update(['is_completed' => true]);
|
||||
$winner->increment('xp', $duelQuest->quest->reward_xp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Loser/Draw gets participation XP
|
||||
$loserId = $winnerId === $user1->id ? $user2->id : $user1->id;
|
||||
\App\Models\User::find($loserId)->increment('xp', 10);
|
||||
|
||||
// TODO: Fire a WebSocket Event to push "Game Over" screen!
|
||||
// Update "Answer Tests" Quest Progress for BOTH players
|
||||
foreach ([$user1, $user2] as $player) {
|
||||
$testQuest = $player->activeQuests()
|
||||
->whereHas('quest', function ($q) {
|
||||
$q->where('quest_type', 'answer_tests');
|
||||
})->where('is_completed', false)->first();
|
||||
|
||||
if ($testQuest) {
|
||||
$testQuest->increment('current_progress', 5); // They both answered 5 questions
|
||||
|
||||
if ($testQuest->current_progress >= $testQuest->quest->required_amount) {
|
||||
$testQuest->update(['is_completed' => true]);
|
||||
$player->increment('xp', $testQuest->quest->reward_xp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIRE THE WEBSOCKET EVENT TO END MATCH!
|
||||
event(new \App\Events\MatchEnded($match->id));
|
||||
}
|
||||
|
||||
/**
|
||||
* STEP 4: Get Final Match Results
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user