Tighten directional light shadow frustum to follow the player and batch static geometries into merged meshes, reducing draw calls significantly. Expand city world bounds to support 72 blocks and add per-frame performance monitoring instrumentation. BREAKING CHANGE: city bounds changed from ±80 to ±120/±160, update any hardcoded client-side world assumptions.
163 lines
5.4 KiB
PHP
Executable File
163 lines
5.4 KiB
PHP
Executable File
<?php
|
||
|
||
namespace Database\Seeders;
|
||
|
||
use App\Models\Building;
|
||
use App\Models\Character;
|
||
use App\Models\City;
|
||
use App\Models\Job;
|
||
use App\Models\Mission;
|
||
use App\Models\Store;
|
||
use App\Models\User;
|
||
use Illuminate\Database\Seeder;
|
||
|
||
/**
|
||
* Seeds the persistent world: default city, jobs and citizen characters.
|
||
*
|
||
* Backfills users.status for pre-existing accounts and ensures every active
|
||
* user has a character so the platform works after the status migration.
|
||
*/
|
||
class CityWorldSeeder extends Seeder
|
||
{
|
||
/**
|
||
* Seed the world tables.
|
||
*/
|
||
public function run(): void
|
||
{
|
||
$city = City::updateOrCreate(
|
||
['slug' => 'city10'],
|
||
[
|
||
'name' => 'City10',
|
||
// Performance-tuned size: 72 blocks (9 × 8) after the
|
||
// 40-unit road grid and its outer margin are derived from
|
||
// these bounds (layout −160..200 × −160..160).
|
||
'bounds_min_x' => -120,
|
||
'bounds_max_x' => 160,
|
||
'bounds_min_z' => -120,
|
||
'bounds_max_z' => 120,
|
||
'is_active' => true,
|
||
'expansions' => 0,
|
||
],
|
||
);
|
||
|
||
$bakery = Store::where('type', 'bakery')->orderBy('id')->first();
|
||
$market = Store::where('type', 'market')->orderBy('id')->first();
|
||
|
||
Job::updateOrCreate(
|
||
['city_id' => $city->id, 'title' => 'Padeiro'],
|
||
['store_id' => $bakery?->id, 'salary' => 12, 'requires_education' => 0],
|
||
);
|
||
Job::updateOrCreate(
|
||
['city_id' => $city->id, 'title' => 'Operador de mercado'],
|
||
['store_id' => $market?->id, 'salary' => 10, 'requires_education' => 0],
|
||
);
|
||
Job::updateOrCreate(
|
||
['city_id' => $city->id, 'title' => 'Servidor público'],
|
||
['salary' => 15, 'requires_education' => 30],
|
||
);
|
||
Job::updateOrCreate(
|
||
['city_id' => $city->id, 'title' => 'Professor'],
|
||
['salary' => 14, 'requires_education' => 60],
|
||
);
|
||
|
||
// City hospital: accident victims are admitted here for one game hour.
|
||
Building::updateOrCreate(
|
||
[
|
||
'city_id' => $city->id,
|
||
'type' => Building::TYPE_HOSPITAL,
|
||
],
|
||
[
|
||
'owner_character_id' => null,
|
||
'name' => 'Hospital Municipal',
|
||
'pos_x' => 60,
|
||
'pos_z' => -60,
|
||
'width' => 14,
|
||
'depth' => 12,
|
||
'height' => 8,
|
||
'is_complete' => true,
|
||
'build_progress' => 100,
|
||
],
|
||
);
|
||
|
||
// Civic buildings: school and city hall.
|
||
Building::updateOrCreate(
|
||
['city_id' => $city->id, 'type' => 'school'],
|
||
[
|
||
'owner_character_id' => null,
|
||
'name' => 'Escola Municipal',
|
||
'pos_x' => -20,
|
||
'pos_z' => 60,
|
||
'width' => 16,
|
||
'depth' => 12,
|
||
'height' => 7,
|
||
'is_complete' => true,
|
||
'build_progress' => 100,
|
||
],
|
||
);
|
||
Building::updateOrCreate(
|
||
['city_id' => $city->id, 'type' => 'city_hall'],
|
||
[
|
||
'owner_character_id' => null,
|
||
'name' => 'Prefeitura',
|
||
'pos_x' => 20,
|
||
'pos_z' => 60,
|
||
'width' => 18,
|
||
'depth' => 14,
|
||
'height' => 10,
|
||
'is_complete' => true,
|
||
'build_progress' => 100,
|
||
],
|
||
);
|
||
|
||
Mission::updateOrCreate(
|
||
['code' => 'exercise-5'],
|
||
[
|
||
'city_id' => $city->id,
|
||
'title' => 'Shape em dia',
|
||
'description' => 'Complete 5 séries de ginástica nas praças.',
|
||
'metric' => 'exercise_count',
|
||
'target' => 5,
|
||
'reward' => 25,
|
||
'is_active' => true,
|
||
],
|
||
);
|
||
Mission::updateOrCreate(
|
||
['code' => 'build-home'],
|
||
[
|
||
'city_id' => $city->id,
|
||
'title' => 'Lar doce lar',
|
||
'description' => 'Construa a sua primeira casa.',
|
||
'metric' => 'buildings',
|
||
'target' => 1,
|
||
'reward' => 50,
|
||
'is_active' => true,
|
||
],
|
||
);
|
||
Mission::updateOrCreate(
|
||
['code' => 'learn-20'],
|
||
[
|
||
'city_id' => $city->id,
|
||
'title' => 'Estudioso',
|
||
'description' => 'Alcance 20% de educação.',
|
||
'metric' => 'education',
|
||
'target' => 20,
|
||
'reward' => 30,
|
||
'is_active' => true,
|
||
],
|
||
);
|
||
|
||
User::query()->where('is_active', true)->where('status', '!=', User::STATUS_ACTIVE)
|
||
->update(['status' => User::STATUS_ACTIVE]);
|
||
User::query()->where('is_active', false)->where('status', User::STATUS_PENDING)
|
||
->update(['status' => User::STATUS_BANNED]);
|
||
|
||
User::query()->where('status', User::STATUS_ACTIVE)->each(function (User $user) use ($city): void {
|
||
Character::ensureForUser($user, $city);
|
||
});
|
||
|
||
// Backfill fitness columns for characters created before the migration.
|
||
Character::query()->whereNull('health')->update(['health' => 100]);
|
||
Character::query()->whereNull('exercise_count')->update(['exercise_count' => 0]);
|
||
}
|
||
}
|