Files

152 lines
3.9 KiB
PHP
Raw Permalink Normal View History

2026-06-27 14:38:18 +03:00
<?php
namespace App\Models;
use App\Enums\CrimeDifficulty;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
/**
* @property int $id
* @property string $name
* @property string $slug
* @property string|null $description
* @property CrimeDifficulty $difficulty
* @property float $success_rate
* @property int $reward_min
* @property int $reward_max
* @property int $experience
* @property int $energy_cost
* @property int $nerve_cost
2026-06-27 14:38:18 +03:00
* @property int $cooldown
* @property int|null $requires_level
* @property int|null $location_id
* @property \Illuminate\Support\Carbon $created_at
* @property \Illuminate\Support\Carbon $updated_at
*/
class Crime extends Model
{
use HasFactory;
protected $fillable = [
'name',
'slug',
'description',
'difficulty',
'success_rate',
'reward_min',
'reward_max',
'experience',
'energy_cost',
'nerve_cost',
2026-06-27 14:38:18 +03:00
'cooldown',
'requires_level',
'location_id',
];
protected $casts = [
'difficulty' => CrimeDifficulty::class,
'success_rate' => 'float',
];
/**
* Get the location where this crime can be committed.
*/
public function location(): BelongsTo
{
return $this->belongsTo(Location::class);
}
/**
* Get the crime attempts for this crime.
*/
public function attempts(): HasMany
{
return $this->hasMany(CrimeAttempt::class);
}
/**
* Check if a character can attempt this crime
*/
public function canBeAttemptedBy(Character $character): bool
{
// Check level requirement
if ($this->requires_level && $character->level < $this->requires_level) {
return false;
}
2026-06-27 14:38:18 +03:00
// Check energy
if ($character->energy < $this->energy_cost) {
return false;
}
// Check nerve
if ($character->nerve < $this->nerve_cost) {
return false;
}
2026-06-27 14:38:18 +03:00
// Check location (if crime is location-specific)
if ($this->location_id && $character->location_id !== $this->location_id) {
return false;
}
2026-06-27 14:38:18 +03:00
return true;
}
/**
* Calculate the success rate for a specific character
*/
public function calculateSuccessRate(Character $character): float
{
$baseRate = $this->success_rate;
$difficultyModifier = $this->difficulty->successModifier();
$levelModifier = $character->level * 0.01; // +1% per level
$rate = $baseRate + $difficultyModifier + $levelModifier;
// Clamp between 10% and 95%
return max(0.10, min(0.95, $rate));
}
/**
* Calculate the reward for a successful crime
*/
public function calculateReward(Character $character): int
{
$baseReward = random_int($this->reward_min, $this->reward_max);
$difficultyMultiplier = $this->difficulty->rewardMultiplier();
$levelMultiplier = 1 + ($character->level * 0.01); // +1% per level
return (int) ($baseReward * $difficultyMultiplier * $levelMultiplier);
}
/**
* Calculate the experience reward
*/
public function calculateExperience(Character $character): int
{
$baseExp = $this->experience;
$levelMultiplier = 1 + ($character->level * 0.01);
return (int) ($baseExp * $levelMultiplier);
}
/**
* Get the display name for the difficulty
*/
public function getDifficultyLabelAttribute(): string
{
return $this->difficulty->label();
}
/**
* Get the color class for the difficulty badge
*/
public function getDifficultyColorAttribute(): string
{
return $this->difficulty->color();
}
}