MatchStatus::class, ]; public function creator(): BelongsTo { return $this->belongsTo(User::class, 'creator_user_id'); } public function matchConfiguration(): BelongsTo { return $this->belongsTo(MatchConfiguration::class); } public function players(): BelongsToMany { return $this->belongsToMany(User::class)->withPivot('side')->withTimestamps(); } public function addQueuedPlayer(QueuedPlayer $player): void { DB::transaction(function () use ($player){ $this->players()->attach($player->user, ['side' => $player->side->value]); foreach ($player->followingUsers as $followingUser) { $this->players()->attach($followingUser->user, ['side' => $followingUser->side->value]); $followingUser->delete(); } $player->delete(); }); } public function determineHost(): void { $hunter = $this->players()->firstWhere('side', '=', MatchmakingSide::Hunter->value); $this->creator()->associate($hunter); $this->save(); } /** * Get the number of needed players to fill the game. * * @return MatchmakingPlayerCount */ public function remainingPlayerCount(): MatchmakingPlayerCount { $players = $this->players; $currentHunterCount = 0; $currentRunnerCount = 0; foreach ($players as $player) { if($player->pivot->side === MatchmakingSide::Hunter->value) ++$currentHunterCount; else ++$currentRunnerCount; } $config = $this->matchConfiguration; if($config === null) return new MatchmakingPlayerCount(); return new MatchmakingPlayerCount( $config->hunters - $currentHunterCount, $config->runners - $currentRunnerCount, ); } public function archiveGame(Faction $dominantFaction): void { $archived = new ArchivedGame(); $archived->id = $this->id; $archived->dominant_faction = $dominantFaction; $archived->chat_messages = Cache::get(ModerationController::CHAT_CACHE_KEY . $this->id, []); $archived->save(); } }