diff --git a/README.md b/README.md index fb671ae..7f1b0db 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,29 @@ -# Template +# Модификация предметов. +Модуль модификации предметов для `LegBK`. + +На вход подаются: +- `$item_data`: Текущие параметры конкретного предмета. В базе LegBK можно искать по запросу +```sql +SELECT `data` FROM items_users WHERE ... +``` +- `$item_data_default`: Параметры по умолчанию для предмета такого типа. На эти параметры будет сброшен предмет в случае провала операции. В базе LegBK можно искать по запросу +```sql +SELECT `data` FROM items_main_data WHERE items_id = ... +``` + +На выходе двумерный массив: +```php +[ + 'new_item_data' => string, + 'operation_cost' => integer, + 'status' => integer, +] +``` +1. Новые параметры предмета. +1. Стоимость услуги. +1. Статус успеха операции. + +--- + +Написано на `PHP 5.4`. \ No newline at end of file diff --git a/src/Sharpen.php b/src/Sharpen.php new file mode 100644 index 0000000..e4ba033 --- /dev/null +++ b/src/Sharpen.php @@ -0,0 +1,237 @@ + 'Сила', + 's2' => 'Ловкость', + 's3' => 'Интуиция', + 's4' => 'Выносливость', + 's5' => 'Интеллект', + 's6' => 'Мудрость', + 's7' => 'Духовность', + 's8' => 'Воля', + 's9' => 'Свобода духа', + 's10' => 'Божественность', + 's11' => 'Энергия', + ]; + } + + private static function getMfNames() + { + return [ + 'm1' => 'Мф. критического удара (%)', + 'm2' => 'Мф. против критического удара (%)', + 'm3' => 'Мф. мощности крит. удара (%)', + 'm4' => 'Мф. увертывания (%)', + 'm5' => 'Мф. против увертывания (%)', + 'm6' => 'Мф. контрудара (%)', + 'm7' => 'Мф. парирования (%)', + 'm8' => 'Мф. блока щитом (%)', + 'm9' => 'Мф. удара сквозь броню (%)', + 'm14' => 'Мф. абс. критического удара (%)', + 'm15' => 'Мф. абс. увертывания (%)', + 'm16' => 'Мф. абс. парирования (%)', + 'm17' => 'Мф. абс. контрудара (%)', + 'm18' => 'Мф. абс. блока щитом (%)', + 'm19' => 'Мф. абс. магический промах (%)', + 'm20' => 'Мф. удача (%)', + ]; + } + + private static function getParamNames() + { + return [ + 'hpAll' => 'Уровень жизни (HP)', + 'mpAll' => 'Уровень маны', + 'enAll' => 'Уровень энергии', + ]; + } + + /** === Конец настроек. */ + + /** + * Sharpen constructor. + * + * @param string $item_data Текущие параметры конкретного предмета. + * @param string $item_data_default Параметры по умолчанию для предмета такого типа. + * + */ + public function __construct($item_data, $item_data_default) + { + $this->item_data = $item_data; + $this->item_data_default = $item_data_default; + $this->itemDataArray = $this->strToArr($this->item_data); + + /** + * Если ключа нет, значит предмет ещё не бывал в модификации. + * Введена, чтобы не прописывать значение в базе руками в каждом предмете. + */ + if (!array_key_exists('sharp_level', $this->itemDataArray)) { + $this->itemDataArray['sharp_level'] = 0; + } + + $this->sharp_chance = $this->successRateCheck(); + + /** Заточка. + * Возвращает INT значение успешности операции SUCCESS или ERROR. + * Константы меняются в конфигурации. + */ + $this->sharp(); + + /** Конечная стоимость заточки: базовая цена умноженная на следующий уровень заточки.*/ + return [ + 'new_item_data' => $this->arrToStr($this->itemDataArray), + 'operation_cost' => self::SHARP_PRICE * $this->itemDataArray['sharp_level'], + 'status' => $this->status, + ]; + } + + /** Подсчёт шанса успешной заточки. Каждый уровень заточки снижает шанс успеха на 5%. 5% - абсолютный минимум. + * @return float|int + */ + private function successRateCheck() + { + return $this->itemDataArray['sharp_level'] < 10 ? 100 - $this->itemDataArray['sharp_level'] * 5 : 5; + } + + /** Событие заточки. + */ + private function sharp() + { + /** Заточка не удалась, сброс параметров предмета до базового уровня. */ + if (mt_rand(0, 100) > $this->sharp_chance) { + $this->resetItem(); + $this->status = self::ERROR; + } else { + $this->updateItem(); + $this->status = self::SUCCESS; + } + } + + /** Повышение статов, параметров и модификаторов (логика). + * + */ + private function updateItem() + { + /** Массивы элементов, которые будут меняться. + * Уже со значениями, которые будут прибавляться к существующим. + * Значения суммируются со старыми. Размер увеличивается в конфиге. + */ + $statsArray = $this->arrMaker(self::getStatNames(), self::SHARP_STAT_BONUS); + $paramArray = $this->arrMaker(self::getParamNames(), self::SHARP_PARAM_BONUS); + $mfArray = $this->arrMaker(self::getMfNames(), self::SHARP_MF_BONUS); + + /** Конечный массив всех изменяемых значений. + * Если нужно больше гибкости, можно вручную перезаписывать значения, которые будут суммироваться. + * Например: $finArray['add_some_var'] = 5 - перезапишет или добавит соответствующий элемент. + */ + $finArray = $statsArray + $paramArray + $mfArray; + + $finArray = array_intersect_key($finArray, $this->itemDataArray); + /** Объединение массивов. */ + foreach ($finArray as $key => $value) { + if (empty($this->itemDataArray[$key])) { + $this->itemDataArray[$key] = $value; + } else { + $this->itemDataArray[$key] += $value; + } + } + + /** Повышаем уровень заточки.*/ + $this->itemDataArray['sharp_level'] += 1; + } + + private function resetItem() + { + /** Массив значений предмета по умолчанию. */ + $this->itemDataArray = $this->strToArr($this->item_data_default); + /** Сброс уровня заточки. */ + $this->itemDataArray['sharp_level'] = 0; + $this->itemDataArray['mf_stats'] = 0; + $this->itemDataArray['mf_mod'] = 0; + $this->itemDataArray['upgrade'] = 0; + } + + /** Конвертирует строку вида "a=1|b=2|c=3" в ассоциатвный массив ['a'=>1,'b'=>2,'c'=>3]. + * + * @param $string + * + * @return array + */ + private function strToArr($string) + { + $arr = []; + $toArr = explode("|", $string); + for ($i = 0; $i < count($toArr); $i++) { + $kv = explode("=", $toArr[$i]); + // Пусть страдает тот, кто пишет в базу ключ без значения как параметр. + if (empty($kv[1])) { + $arr[$kv[0]] = null; + } else { + $arr[$kv[0]] = $kv[1]; + } + } + return $arr; + } + + /** Конвертирует ассоциатвный массив вида ['a'=>1,'b'=>2,'c'=>3] в строку "a=1|b=2|c=3". + * + * @param array $array + * + * @return string + */ + private function arrToStr(array $array) + { + $temp = []; + foreach ($array as $k => $v) { + $temp[] = $k . '=' . $v; + } + return implode("|", $temp); + } + + /** Берёт ключи входящего массива, добавляет к ним необходимый для записи в БД "add_" + * и возвращает массив со значениями, переданными в $values. + * + * @param $array + * @param int $values + * + * @return array + */ + private function arrMaker($array, $values = 0) + { + return array_map(function () use ($values) { + return $values; + }, array_flip(array_map(function ($key) { + return 'add_' . $key; + }, array_keys($array)))); + } +} \ No newline at end of file