2026-06-28 16:35:42 +03:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace App\Services\Game;
|
|
|
|
|
|
|
|
|
|
use App\Models\Character;
|
|
|
|
|
use App\Models\GymSession;
|
|
|
|
|
|
|
|
|
|
class TrainingService
|
|
|
|
|
{
|
|
|
|
|
private const VALID_STATS = ['strength', 'defense', 'speed', 'dexterity'];
|
|
|
|
|
|
|
|
|
|
public function train(Character $character, string $stat): array
|
|
|
|
|
{
|
|
|
|
|
if (!in_array($stat, self::VALID_STATS, true)) {
|
|
|
|
|
return ['success' => false, 'message' => 'Invalid stat.', 'stat_value' => 0];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$energyCost = config('game.gym.energy_cost', 20);
|
|
|
|
|
$dailyCap = config('game.gym.daily_cap', 5);
|
|
|
|
|
$statGain = config('game.gym.stat_gain', 1);
|
|
|
|
|
|
|
|
|
|
if (!$character->hasEnergy($energyCost)) {
|
|
|
|
|
return [
|
|
|
|
|
'success' => false,
|
|
|
|
|
'message' => "Not enough energy ({$energyCost} required).",
|
|
|
|
|
'stat_value' => $character->$stat,
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$sessionsToday = $this->getSessionsToday($character, $stat);
|
|
|
|
|
|
|
|
|
|
if ($sessionsToday >= $dailyCap) {
|
|
|
|
|
return [
|
|
|
|
|
'success' => false,
|
|
|
|
|
'message' => "Daily training cap reached for {$stat} ({$dailyCap} sessions).",
|
|
|
|
|
'stat_value' => $character->$stat,
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Deduct energy
|
|
|
|
|
$character->consumeEnergy($energyCost);
|
|
|
|
|
|
|
|
|
|
// Increment stat
|
|
|
|
|
$character->$stat += $statGain;
|
|
|
|
|
$character->save();
|
|
|
|
|
|
|
|
|
|
// Upsert gym_sessions row
|
|
|
|
|
$session = GymSession::firstOrNew([
|
|
|
|
|
'character_id' => $character->id,
|
|
|
|
|
'stat' => $stat,
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
if (!$session->reset_date || $session->reset_date->lt(today())) {
|
|
|
|
|
$session->sessions_today = 0;
|
|
|
|
|
$session->reset_date = today();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$session->sessions_today += 1;
|
|
|
|
|
$session->save();
|
|
|
|
|
|
|
|
|
|
return [
|
|
|
|
|
'success' => true,
|
|
|
|
|
'message' => ucfirst($stat) . " increased to {$character->$stat}!",
|
|
|
|
|
'stat_value' => $character->$stat,
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function getSessionsToday(Character $character, string $stat): int
|
|
|
|
|
{
|
|
|
|
|
$session = GymSession::where('character_id', $character->id)
|
|
|
|
|
->where('stat', $stat)
|
|
|
|
|
->first();
|
|
|
|
|
|
2026-06-28 16:39:04 +03:00
|
|
|
if (!$session || !$session->reset_date || $session->reset_date->lt(today())) {
|
2026-06-28 16:35:42 +03:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $session->sessions_today;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function getSessionsRemaining(Character $character, string $stat): int
|
|
|
|
|
{
|
|
|
|
|
$cap = config('game.gym.daily_cap', 5);
|
|
|
|
|
return max(0, $cap - $this->getSessionsToday($character, $stat));
|
|
|
|
|
}
|
|
|
|
|
}
|