fix: address final review findings — nerve consume ordering, character init, seeder costs, dead column

- Consume nerve before energy in CrimeService so energy is never lost when nerve is insufficient
- Initialize nerve/max_nerve from config in CharacterController::store (same pattern as energy/health)
- Add nerve_cost to all CrimeSeeder entries proportional to difficulty (1-5 range)
- Remove nerve_regen_at from Character $fillable/$casts/@property — column exists but is not yet wired up

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Doar Mihai
2026-06-28 17:09:21 +03:00
co-authored by Claude Sonnet 4.6
parent 439f6740c0
commit 3e6a84503d
4 changed files with 19 additions and 11 deletions
@@ -74,6 +74,8 @@ class CharacterController extends Controller
'max_energy' => config('game.energy.max', 100), 'max_energy' => config('game.energy.max', 100),
'health' => config('game.health.start_amount', 100), 'health' => config('game.health.start_amount', 100),
'max_health' => config('game.health.max', 100), 'max_health' => config('game.health.max', 100),
'nerve' => config('game.nerve.start_amount', 100),
'max_nerve' => config('game.nerve.max', 100),
'strength' => 5, 'strength' => 5,
'defense' => 5, 'defense' => 5,
'speed' => 5, 'speed' => 5,
-3
View File
@@ -21,7 +21,6 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
* @property int $max_energy * @property int $max_energy
* @property int $nerve * @property int $nerve
* @property int $max_nerve * @property int $max_nerve
* @property \Illuminate\Support\Carbon|null $nerve_regen_at
* @property int $health * @property int $health
* @property int $max_health * @property int $max_health
* @property int $strength * @property int $strength
@@ -53,7 +52,6 @@ class Character extends Model
'max_energy', 'max_energy',
'nerve', 'nerve',
'max_nerve', 'max_nerve',
'nerve_regen_at',
'health', 'health',
'max_health', 'max_health',
'strength', 'strength',
@@ -72,7 +70,6 @@ class Character extends Model
'in_hospital_until' => 'datetime', 'in_hospital_until' => 'datetime',
'in_jail_until' => 'datetime', 'in_jail_until' => 'datetime',
'last_action_at' => 'datetime', 'last_action_at' => 'datetime',
'nerve_regen_at' => 'datetime',
'status' => CharacterStatus::class, 'status' => CharacterStatus::class,
]; ];
+5 -5
View File
@@ -37,16 +37,16 @@ class CrimeService
throw new \Exception('Character cannot perform actions right now.'); throw new \Exception('Character cannot perform actions right now.');
} }
// Consume nerve first so energy is never deducted if nerve is insufficient
if (!$this->nerveService->consume($character, $crime->nerve_cost)) {
throw new \Exception('Not enough nerve to attempt this crime.');
}
// Consume energy // Consume energy
if (!$this->energyService->consume($character, $crime->energy_cost, 'crime')) { if (!$this->energyService->consume($character, $crime->energy_cost, 'crime')) {
throw new \Exception('Not enough energy to attempt this crime.'); throw new \Exception('Not enough energy to attempt this crime.');
} }
// Consume nerve
if (!$this->nerveService->consume($character, $crime->nerve_cost)) {
throw new \Exception('Not enough nerve to attempt this crime.');
}
// Calculate success rate // Calculate success rate
$successRate = $crime->calculateSuccessRate($character); $successRate = $crime->calculateSuccessRate($character);
$isSuccess = random_int(0, 9999) / 10000 <= $successRate; $isSuccess = random_int(0, 9999) / 10000 <= $successRate;
+9
View File
@@ -29,6 +29,7 @@ class CrimeSeeder extends Seeder
'reward_max' => 500, 'reward_max' => 500,
'experience' => 50, 'experience' => 50,
'energy_cost' => 10, 'energy_cost' => 10,
'nerve_cost' => 1,
'cooldown' => 60, 'cooldown' => 60,
'requires_level' => 1, 'requires_level' => 1,
'location_id' => $downtown?->id ?? null, 'location_id' => $downtown?->id ?? null,
@@ -43,6 +44,7 @@ class CrimeSeeder extends Seeder
'reward_max' => 1500, 'reward_max' => 1500,
'experience' => 100, 'experience' => 100,
'energy_cost' => 15, 'energy_cost' => 15,
'nerve_cost' => 2,
'cooldown' => 120, 'cooldown' => 120,
'requires_level' => 3, 'requires_level' => 3,
'location_id' => $downtown?->id ?? null, 'location_id' => $downtown?->id ?? null,
@@ -57,6 +59,7 @@ class CrimeSeeder extends Seeder
'reward_max' => 1000, 'reward_max' => 1000,
'experience' => 75, 'experience' => 75,
'energy_cost' => 12, 'energy_cost' => 12,
'nerve_cost' => 1,
'cooldown' => 120, 'cooldown' => 120,
'requires_level' => 1, 'requires_level' => 1,
'location_id' => $downtown?->id ?? null, 'location_id' => $downtown?->id ?? null,
@@ -73,6 +76,7 @@ class CrimeSeeder extends Seeder
'reward_max' => 3000, 'reward_max' => 3000,
'experience' => 150, 'experience' => 150,
'energy_cost' => 20, 'energy_cost' => 20,
'nerve_cost' => 2,
'cooldown' => 180, 'cooldown' => 180,
'requires_level' => 5, 'requires_level' => 5,
'location_id' => $industrial?->id ?? null, 'location_id' => $industrial?->id ?? null,
@@ -87,6 +91,7 @@ class CrimeSeeder extends Seeder
'reward_max' => 5000, 'reward_max' => 5000,
'experience' => 200, 'experience' => 200,
'energy_cost' => 25, 'energy_cost' => 25,
'nerve_cost' => 3,
'cooldown' => 300, 'cooldown' => 300,
'requires_level' => 8, 'requires_level' => 8,
'location_id' => $industrial?->id ?? null, 'location_id' => $industrial?->id ?? null,
@@ -103,6 +108,7 @@ class CrimeSeeder extends Seeder
'reward_max' => 8000, 'reward_max' => 8000,
'experience' => 250, 'experience' => 250,
'energy_cost' => 30, 'energy_cost' => 30,
'nerve_cost' => 3,
'cooldown' => 300, 'cooldown' => 300,
'requires_level' => 10, 'requires_level' => 10,
'location_id' => $waterfront?->id ?? null, 'location_id' => $waterfront?->id ?? null,
@@ -117,6 +123,7 @@ class CrimeSeeder extends Seeder
'reward_max' => 15000, 'reward_max' => 15000,
'experience' => 400, 'experience' => 400,
'energy_cost' => 40, 'energy_cost' => 40,
'nerve_cost' => 5,
'cooldown' => 600, 'cooldown' => 600,
'requires_level' => 15, 'requires_level' => 15,
'location_id' => $waterfront?->id ?? null, 'location_id' => $waterfront?->id ?? null,
@@ -133,6 +140,7 @@ class CrimeSeeder extends Seeder
'reward_max' => 4000, 'reward_max' => 4000,
'experience' => 120, 'experience' => 120,
'energy_cost' => 20, 'energy_cost' => 20,
'nerve_cost' => 2,
'cooldown' => 180, 'cooldown' => 180,
'requires_level' => 5, 'requires_level' => 5,
'location_id' => null, 'location_id' => null,
@@ -147,6 +155,7 @@ class CrimeSeeder extends Seeder
'reward_max' => 6000, 'reward_max' => 6000,
'experience' => 200, 'experience' => 200,
'energy_cost' => 25, 'energy_cost' => 25,
'nerve_cost' => 3,
'cooldown' => 300, 'cooldown' => 300,
'requires_level' => 7, 'requires_level' => 7,
'location_id' => null, 'location_id' => null,