the browser-facing portion of osu!
1<?php
2
3// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the GNU Affero General Public License v3.0.
4// See the LICENCE file in the repository root for full licence text.
5
6declare(strict_types=1);
7
8namespace Database\Factories\Score\Best;
9
10use App\Models\Beatmap;
11use App\Models\User;
12use Database\Factories\Factory;
13
14abstract class ModelFactory extends Factory
15{
16 public function definition(): array
17 {
18 return [
19 'beatmap_id' => fn () => Beatmap::factory()->state([
20 // force playmode to match score type
21 'playmode' => Beatmap::modeInt((new $this->model())->getMode()),
22 ]),
23 'date' => fn () => $this->faker->dateTimeBetween('-5 years'),
24 'enabled_mods' => array_rand_val([0, 16, 24, 64, 72]),
25 'score' => rand(50000, 100000000),
26 'user_id' => fn () => User::factory(),
27 'rank' => array_rand_val(['A', 'S', 'B', 'SH', 'XH', 'X']),
28
29 // depends on beatmap_id
30 'maxcombo' => fn (array $attr) => rand(1, Beatmap::find($attr['beatmap_id'])->countNormal),
31 'pp' => function (array $attr) {
32 $diff = Beatmap::find($attr['beatmap_id'])->difficultyrating;
33
34 return $this->faker->biasedNumberBetween(10, 100) * 1.5 * $diff;
35 },
36
37 // depends on maxcombo
38 'count100' => fn (array $attr) => rand(0, (int) round($attr['maxcombo'] * 0.15)),
39 'count300' => fn (array $attr) => round($attr['maxcombo'] * 0.8),
40 'count50' => fn (array $attr) => rand(0, (int) round($attr['maxcombo'] * 0.05)),
41 'countgeki' => fn (array $attr) => round($attr['maxcombo'] * 0.3),
42 'countkatu' => fn (array $attr) => round($attr['maxcombo'] * 0.05),
43 'countmiss' => fn (array $attr) => round($attr['maxcombo'] * 0.05),
44 ];
45 }
46
47 public function withReplay()
48 {
49 return $this->state([
50 'replay' => true,
51 ])->afterCreating(function ($score) {
52 $score->replayFile()->put('this-is-totally-a-legit-replay');
53 });
54 }
55}