feat: add JailService and bust-out config keys
Add JailService with bustOut(), sendToJail(), releaseFromJail(), and calculateBustOutChance() methods. Add two config keys (bust_out_stat_multiplier and bust_out_max_chance) to the jail config block. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
68c4bbabd7
commit
799f46a5f2
@@ -0,0 +1,89 @@
|
|||||||
|
<?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;
|
||||||
|
}
|
||||||
|
}
|
||||||
+6
-4
@@ -79,10 +79,12 @@ return [
|
|||||||
|
|
||||||
// Jail system configuration
|
// Jail system configuration
|
||||||
'jail' => [
|
'jail' => [
|
||||||
'sentence_length' => 3600, // 1 hour base sentence
|
'sentence_length' => 3600,
|
||||||
'breakout_chance' => 0.05, // 5% chance to break out per attempt
|
'breakout_chance' => 0.05,
|
||||||
'breakout_cost' => 1000, // Cost to attempt breakout
|
'breakout_cost' => 1000,
|
||||||
'sentence_multiplier' => 1.5, // Sentence increases by 50% for repeat offenses
|
'sentence_multiplier' => 1.5,
|
||||||
|
'bust_out_stat_multiplier' => 0.003, // per combined dex+speed point
|
||||||
|
'bust_out_max_chance' => 0.80, // cap at 80%
|
||||||
],
|
],
|
||||||
|
|
||||||
// Economy configuration
|
// Economy configuration
|
||||||
|
|||||||
Reference in New Issue
Block a user