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; } }