feat(world): add persistent citizen simulation with needs, jobs, and social features
- Adds Character model with survival needs (hunger, thirst, energy) and state machine - Implements city:tick world ticker for offline progression every minute - Adds city territory expansion and building construction system - Introduces job economy, inventory, and transaction audit trail - Adds social graph (friends, marriage, children) and character chat - Implements admin approval workflow for new registrations - Adds hospital admission system for traffic accidents - Includes comprehensive feature tests and world seeders
This commit is contained in:
+51
-1
@@ -8,6 +8,7 @@ use Illuminate\Database\Eloquent\Attributes\Hidden;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasOne;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Laravel\Sanctum\HasApiTokens;
|
||||
@@ -19,7 +20,7 @@ use Laravel\Sanctum\HasApiTokens;
|
||||
* acceptance of versioned legal documents (Terms, Privacy, Cookies)
|
||||
* required by the Brazilian LGPD.
|
||||
*/
|
||||
#[Fillable(['name', 'email', 'password', 'role', 'locale', 'is_active'])]
|
||||
#[Fillable(['name', 'email', 'password', 'role', 'status', 'locale', 'is_active'])]
|
||||
#[Hidden(['password', 'remember_token'])]
|
||||
class User extends Authenticatable
|
||||
{
|
||||
@@ -40,6 +41,37 @@ class User extends Authenticatable
|
||||
*/
|
||||
public const ROLE_USER = 'user';
|
||||
|
||||
/**
|
||||
* Account registered but not yet approved by an administrator.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public const STATUS_PENDING = 'pending';
|
||||
|
||||
/**
|
||||
* Account approved and able to enter the platform.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public const STATUS_ACTIVE = 'active';
|
||||
|
||||
/**
|
||||
* Account blocked by an administrator.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public const STATUS_BANNED = 'banned';
|
||||
|
||||
/**
|
||||
* In-world character belonging to this user.
|
||||
*
|
||||
* @return HasOne<Character, $this>
|
||||
*/
|
||||
public function character(): HasOne
|
||||
{
|
||||
return $this->hasOne(Character::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores owned by this user.
|
||||
*
|
||||
@@ -80,6 +112,14 @@ class User extends Authenticatable
|
||||
return $this->role === self::ROLE_ADMIN;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the account has been approved by an administrator.
|
||||
*/
|
||||
public function isApproved(): bool
|
||||
{
|
||||
return $this->status === self::STATUS_ACTIVE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the user accepted every current legal document version.
|
||||
*/
|
||||
@@ -96,6 +136,16 @@ class User extends Authenticatable
|
||||
return $currentIds->diff($acceptedIds)->isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Keep the legacy is_active flag mirrored from status on save.
|
||||
*/
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::saving(function (self $user): void {
|
||||
$user->is_active = $user->status === self::STATUS_ACTIVE;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attributes that should be cast.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user