feat(city): add airports, ATC agent, luminous signs, and AI model fallback chain
- Add two airports (north/south) with full geometry: runways, taxiways,
aprons, terminals, hangars, stands, and helipads; walkable airport
grounds extend beyond city bounds.
- Introduce ATC AI agent ("Torre de Controle City10") using AI_ATC_MODEL
to generate takeoff clearances; includes dispatch endpoint with
30-second cooldown and deterministic fallback on failure.
- Implement AI model fallback chain: preferred model → AI_FALLBACK_MODEL
before failing, applied in ChatController and PersonTalkController.
- Add luminous sign labels (letreiros) for plazas, beach, food, hospital,
school, city hall, and airports with day/night glow.
- Fix city presence cache: compute is_me per viewer instead of baking
into shared per-second cache to prevent cross-user flag leakage.
- Add tests: AirportTest, CityPresenceTest, SignLabelsTest, and
PersonTalkTest fallback model retry scenario.
This commit is contained in:
@@ -35,8 +35,12 @@ class CityPresenceController extends Controller
|
||||
->first() ?? $city;
|
||||
}
|
||||
|
||||
// Rows are shared across users for one second, so is_me must NOT
|
||||
// be baked into the cached payload — it is computed per viewer
|
||||
// below (otherwise user B sees user A's is_me flags and could see
|
||||
// their own character as a remote citizen).
|
||||
$cacheKey = 'presence.'.$city->id.'.'.now()->timestamp;
|
||||
$citizens = Cache::remember($cacheKey, 1, function () use ($city, $me) {
|
||||
$citizens = Cache::remember($cacheKey, 1, function () use ($city) {
|
||||
return Character::query()
|
||||
->where('city_id', $city->id)
|
||||
->where(function ($q): void {
|
||||
@@ -52,13 +56,18 @@ class CityPresenceController extends Controller
|
||||
'status' => $c->state,
|
||||
'position' => [(float) $c->pos_x, (float) $c->pos_y, (float) $c->pos_z],
|
||||
'is_online' => (bool) $c->is_online,
|
||||
'is_me' => (int) $c->id === (int) $me->id,
|
||||
'owner_name' => $c->user?->name,
|
||||
])
|
||||
->values()
|
||||
->all();
|
||||
});
|
||||
|
||||
$viewerId = (int) $me->id;
|
||||
$citizens = array_map(
|
||||
static fn (array $c): array => $c + ['is_me' => (int) $c['id'] === $viewerId],
|
||||
$citizens
|
||||
);
|
||||
|
||||
return response()->json([
|
||||
'city_id' => $city->id,
|
||||
'server_time' => now()->toIso8601String(),
|
||||
|
||||
Reference in New Issue
Block a user