Files

89 lines
2.6 KiB
PHP
Raw Permalink Normal View History

<?php
namespace App\Services\Game;
use App\Models\Character;
class JailService
{
/**
* Calculate bust-out success chance for a character (0.0 to 1.0).
*/
public function calculateBustOutChance(Character $character): float
{
$base = config('game.jail.breakout_chance', 0.05);
$multiplier = config('game.jail.bust_out_stat_multiplier', 0.003);
$cap = config('game.jail.bust_out_max_chance', 0.80);
return min($cap, $base + ($character->dexterity + $character->speed) * $multiplier);
}
/**
* Attempt to bust out of jail.
*
* Deducts breakout_cost cash regardless of outcome.
* On success: releases character immediately.
* On failure: multiplies remaining sentence by sentence_multiplier.
*
* @return array{success: bool, message: string}
*/
public function bustOut(Character $character): array
{
$cost = config('game.jail.breakout_cost', 1000);
if ($character->money < $cost) {
return [
'success' => false,
'message' => 'You need $' . number_format($cost) . ' to attempt a bust-out.',
];
}
$character->money -= $cost;
$successRate = $this->calculateBustOutChance($character);
$roll = random_int(0, 9999) / 10000;
if ($roll <= $successRate) {
$this->releaseFromJail($character);
$character->save();
return [
'success' => true,
'message' => "You escaped! You're free.",
];
}
// Failure: extend sentence
$multiplier = config('game.jail.sentence_multiplier', 1.5);
$remaining = max(0, $character->in_jail_until->diffInSeconds(now()));
$extended = (int) ceil($remaining * $multiplier);
$character->in_jail_until = now()->addSeconds($extended);
$character->save();
$newReleaseTime = $character->in_jail_until->diffForHumans();
return [
'success' => false,
'message' => "Bust failed — your sentence was extended to {$newReleaseTime}.",
];
}
/**
* Send a character to jail for the given number of seconds.
*/
public function sendToJail(Character $character, int $seconds): void
{
$character->status = 'in_jail';
$character->in_jail_until = now()->addSeconds($seconds);
$character->save();
}
/**
* Release a character from jail immediately.
*/
public function releaseFromJail(Character $character): void
{
$character->status = 'active';
$character->in_jail_until = null;
}
}