Старая версия на php5.4 переделанная на php7+. Работает со всеми проклинаемой текстовой строкой параметров предмета data add_s1=4|add_s3=6|add_m1=20|add_m3=25|hpAll=500|итд. Увеличивает каждый существующий на предмете стат на +1, параметр на +3, здоровье\мана на +30. Чем толще заточка тем больше шансов, что следующая провалится.
STAT_NAMES, MF_NAMES, PARAM_NAMES — в идеале вытягивать из базы или из существующего кода. Но помнить, что всё что тут указано будет увеличиваться.
<?php
declare(strict_types=1);
class Sharpen
{
private int $sharp_chance;
private array $itemDataArray;
private bool $status;
private string $item_data_default;
/** === Настройки скрипта. */
/** Базовая стоимость заточки */
public const SHARP_PRICE = 50;
/** На сколько повышаем мф. */
public const SHARP_MF_BONUS = 5;
/** На сколько повышаем статы. */
public const SHARP_STAT_BONUS = 1;
/** На сколько повышаем хиты и ману. */
public const SHARP_PARAM_BONUS = 30;
/** Статы */
private const STAT_NAMES = [
's1' => 'Сила',
's2' => 'Ловкость',
's3' => 'Интуиция',
's4' => 'Выносливость',
's5' => 'Интеллект',
's6' => 'Мудрость',
's7' => 'Духовность',
's8' => 'Воля',
's9' => 'Свобода духа',
's10' => 'Божественность',
's11' => 'Энергия',
];
/** Модификаторы */
private const MF_NAMES = [
'm1' => 'Мф. критического удара (%)',
'm2' => 'Мф. против критического удара (%)',
'm3' => 'Мф. мощности крит. удара (%)',
'm4' => 'Мф. увертывания (%)',
'm5' => 'Мф. против увертывания (%)',
'm6' => 'Мф. контрудара (%)',
'm7' => 'Мф. парирования (%)',
'm8' => 'Мф. блока щитом (%)',
'm9' => 'Мф. удара сквозь броню (%)',
'm14' => 'Мф. абс. критического удара (%)',
'm15' => 'Мф. абс. увертывания (%)',
'm16' => 'Мф. абс. парирования (%)',
'm17' => 'Мф. абс. контрудара (%)',
'm18' => 'Мф. абс. блока щитом (%)',
'm19' => 'Мф. абс. магический промах (%)',
'm20' => 'Мф. удача (%)',
];
/** Параметры */
private const PARAM_NAMES = [
'hpAll' => 'Уровень жизни (HP)',
'mpAll' => 'Уровень маны',
'enAll' => 'Уровень энергии',
];
/** === Конец настроек. */
public function __construct(string $item_data, string $item_data_default)
{
$this->item_data_default = $item_data_default;
$this->itemDataArray = $this->strToArr($item_data);
if (!isset($this->itemDataArray['sharp_level'])) {
$this->itemDataArray['sharp_level'] = 0;
}
$this->sharp_chance = $this->successRateCheck();
}
/**
* Запуск заточки и возврат результата
*/
public function process(): array
{
$this->sharp();
return [
'new_item_data' => $this->arrToStr($this->itemDataArray),
'operation_cost' => self::SHARP_PRICE * $this->itemDataArray['sharp_level'],
'status' => $this->status,
];
}
private function successRateCheck(): int
{
return $this->itemDataArray['sharp_level'] < 10
? 100 - $this->itemDataArray['sharp_level'] * 5
: 5;
}
private function sharp(): void
{
if (mt_rand(0, 100) > $this->sharp_chance) {
$this->resetItem();
$this->status = false;
} else {
$this->updateItem();
$this->status = true;
}
}
private function updateItem(): void
{
$statsArray = $this->arrMaker(self::STAT_NAMES, self::SHARP_STAT_BONUS);
$paramArray = $this->arrMaker(self::PARAM_NAMES, self::SHARP_PARAM_BONUS, false);
$mfArray = $this->arrMaker(self::MF_NAMES, self::SHARP_MF_BONUS);
$finArray = array_merge($statsArray, $paramArray, $mfArray);
$finArray = array_intersect_key($finArray, $this->itemDataArray);
foreach ($finArray as $key => $value) {
$this->itemDataArray[$key] = ($this->itemDataArray[$key] ?? 0) + $value;
}
$this->itemDataArray['sharp_level']++;
}
private function resetItem(): void
{
$this->itemDataArray = $this->strToArr($this->item_data_default);
$this->itemDataArray['sharp_level'] = 0;
}
private function strToArr(string $string): array
{
$arr = [];
foreach (explode('|', $string) as $pair) {
[$k, $v] = array_pad(explode('=', $pair, 2), 2, null);
$arr[$k] = $v === null || $v === '' ? null : $v;
}
return $arr;
}
private function arrToStr(array $array): string
{
return implode('|', array_map(static fn($k, $v) => "$k=$v", array_keys($array), $array));
}
private function arrMaker(array $array, int $values = 0, bool $withPrefix = true): array
{
// К некоторым значениям префикс 'add_' не добавляется!
$keys = $withPrefix
? array_map(static fn($key) => 'add_' . $key, array_keys($array))
: array_keys($array);
return array_fill_keys($keys, $values);
}
}
Проверяем:
$itemData = 'add_s1=4|add_s3=6|add_m1=20|add_m3=25|hpAll=500';
$baseData = 'add_s1=4|add_s3=6|add_m1=20|add_m3=25|hpAll=500';
$cost = 0; $fails = 0; $sharp_level = 0; $uses = 50; $sharp_level_max = 0;
for ($i = 0; $i < $uses; $i++) {
$s = new Sharpen($itemData, $baseData);
$use = $s->process();
$itemData = $use['new_item_data'];
$cost += $use['operation_cost'];
$sharp_level++;
if (!$use['status']) {
$fails++;
$sharp_level = 0;
}
if ($sharp_level > $sharp_level_max) {
$sharp_level_max = $sharp_level;
}
//var_dump($use); - раскомментируй, если хочешь увидеть пошагово.
echo "<p>";
}
echo "Попыток: $i<br>
Уровень заточки: $sharp_level, доходило до $sharp_level_max<br>
Сломаных заточек: $fails<br>
Потраченных денег: $cost<br><br>
Было: $baseData<br>Стало: $itemData";
// Попыток: 50
// Уровень заточки: 4, доходило до 7
// Сломаных заточек: 9
// Потраченных денег: 5800
//
// Было: add_s1=4|add_s3=6|add_m1=20|add_m3=25|hpAll=500
// Стало: add_s1=8|add_s3=10|add_m1=40|add_m3=45|hpAll=620|sharp_level=4