roomId)) { return; } $config = GameConfig::forGame('horse_racing')?->params ?? []; $betSeconds = (int) ($config['bet_window_seconds'] ?? 90); $horseCount = (int) ($config['horse_count'] ?? 4); $minBet = (int) ($config['min_bet'] ?? 100); $maxBet = (int) ($config['max_bet'] ?? 100000); $seedPool = (int) ($config['seed_pool'] ?? 0); $now = now(); $closesAt = $now->copy()->addSeconds($betSeconds); // 生成参赛马匹 $horses = HorseRace::generateHorses($horseCount); // 创建新场次 $race = HorseRace::create([ 'room_id' => $this->roomId, 'status' => 'betting', 'bet_opens_at' => $now, 'bet_closes_at' => $closesAt, 'horses' => $horses, 'total_pool' => $seedPool, ]); // 广播开赛事件 broadcast(new HorseRaceOpened($race)); // 公屏系统公告 $horseList = implode(' ', array_map( fn ($h) => "{$h['emoji']}{$h['name']}", $horses )); $quickOpenButton = ''; $content = "🐎 第 #{$race->id} 场开赛:{$horseList},{$betSeconds} 秒下注,".number_format($minBet).'~'.number_format($maxBet).' 金币。'.$quickOpenButton; $msg = [ 'id' => $chatState->nextMessageId($this->roomId), 'room_id' => $this->roomId, 'from_user' => '系统传音', 'to_user' => '大家', 'content' => $content, 'is_secret' => false, 'font_color' => '#16a34a', 'action' => '大声宣告', 'sent_at' => $now->toDateTimeString(), ]; $chatState->pushMessage($this->roomId, $msg); broadcast(new MessageSent($this->roomId, $msg)); SaveMessageJob::dispatch($msg); // 押注截止后触发跑马 & 结算任务 RunHorseRaceJob::dispatch($race)->delay($closesAt); } }