优化
This commit is contained in:
parent
5136e55932
commit
b022abd6a9
|
|
@ -31,6 +31,7 @@ class ItemDisplay
|
||||||
'necklace' => '项链',
|
'necklace' => '项链',
|
||||||
'consume' => '消耗品',
|
'consume' => '消耗品',
|
||||||
'spell' => '法术',
|
'spell' => '法术',
|
||||||
|
'quest_item' => '任务物品',
|
||||||
];
|
];
|
||||||
|
|
||||||
// 属性名称
|
// 属性名称
|
||||||
|
|
@ -84,6 +85,11 @@ class ItemDisplay
|
||||||
*/
|
*/
|
||||||
public static function formatName(array $item): string
|
public static function formatName(array $item): string
|
||||||
{
|
{
|
||||||
|
// 任务物品不显示等级
|
||||||
|
if (($item['type'] ?? '') === 'quest_item') {
|
||||||
|
return self::$magenta . $item['name'] . self::$reset;
|
||||||
|
}
|
||||||
|
|
||||||
$quality = $item['quality'] ?? $item['rarity'] ?? 'common';
|
$quality = $item['quality'] ?? $item['rarity'] ?? 'common';
|
||||||
$color = self::getQualityColor($quality);
|
$color = self::getQualityColor($quality);
|
||||||
$name = ($item['name'] ?? '未知物品') . 'lv.' . $item['level'];
|
$name = ($item['name'] ?? '未知物品') . 'lv.' . $item['level'];
|
||||||
|
|
@ -212,6 +218,17 @@ class ItemDisplay
|
||||||
|
|
||||||
// 主属性(简洁版)或法术信息
|
// 主属性(简洁版)或法术信息
|
||||||
$type = $item['type'] ?? '';
|
$type = $item['type'] ?? '';
|
||||||
|
|
||||||
|
// 特殊处理任务物品
|
||||||
|
if ($type === 'quest_item') {
|
||||||
|
$parts = [];
|
||||||
|
$parts[] = self::$magenta . "【任务物品】" . self::$reset . " {$item['name']}";
|
||||||
|
if ($showType) {
|
||||||
|
$parts[] = self::$gray . "[任务物品]" . self::$reset;
|
||||||
|
}
|
||||||
|
return implode(" ", $parts);
|
||||||
|
}
|
||||||
|
|
||||||
if ($type === 'spell') {
|
if ($type === 'spell') {
|
||||||
// 法术显示由 SpellDisplay 处理(计算方式和基础数值)
|
// 法术显示由 SpellDisplay 处理(计算方式和基础数值)
|
||||||
// 需要导入 SpellDisplay 后使用
|
// 需要导入 SpellDisplay 后使用
|
||||||
|
|
@ -270,6 +287,17 @@ class ItemDisplay
|
||||||
$type = $item['type'] ?? '';
|
$type = $item['type'] ?? '';
|
||||||
$typeName = self::getTypeName($type);
|
$typeName = self::getTypeName($type);
|
||||||
|
|
||||||
|
// 特殊处理任务物品
|
||||||
|
if ($type === 'quest_item') {
|
||||||
|
$lines[] = $linePrefix . self::$magenta . "【任务物品】" . self::$reset . " {$item['name']}";
|
||||||
|
$lines[] = $linePrefix;
|
||||||
|
$lines[] = $linePrefix . "这是一个关键任务物品,";
|
||||||
|
$lines[] = $linePrefix . "用于解锁新的探险区域。";
|
||||||
|
$lines[] = $linePrefix;
|
||||||
|
$lines[] = $linePrefix . "无法装备、无法出售、无法交易。";
|
||||||
|
return $lines;
|
||||||
|
}
|
||||||
|
|
||||||
$enhanceLevel = $item['enhanceLevel'] ?? 0;
|
$enhanceLevel = $item['enhanceLevel'] ?? 0;
|
||||||
|
|
||||||
// 名称行
|
// 名称行
|
||||||
|
|
@ -371,6 +399,11 @@ class ItemDisplay
|
||||||
*/
|
*/
|
||||||
public static function renderDrop(array $item, string $prefix = " "): string
|
public static function renderDrop(array $item, string $prefix = " "): string
|
||||||
{
|
{
|
||||||
|
// 特殊处理任务物品
|
||||||
|
if ($item['type'] === 'quest_item') {
|
||||||
|
return $prefix . "📜 " . self::$magenta . "【任务物品】" . self::$reset . " {$item['name']}";
|
||||||
|
}
|
||||||
|
|
||||||
$quality = $item['quality'] ?? $item['rarity'] ?? 'common';
|
$quality = $item['quality'] ?? $item['rarity'] ?? 'common';
|
||||||
$color = self::getQualityColor($quality);
|
$color = self::getQualityColor($quality);
|
||||||
if ($item['type'] == 'potion_pool'){
|
if ($item['type'] == 'potion_pool'){
|
||||||
|
|
|
||||||
1514
src/Data/maps.php
1514
src/Data/maps.php
File diff suppressed because it is too large
Load Diff
|
|
@ -243,11 +243,11 @@ class Actor
|
||||||
{
|
{
|
||||||
// 多项式公式,避免过度指数增长
|
// 多项式公式,避免过度指数增长
|
||||||
// base: 100 (1级升2级的基础经验)
|
// base: 100 (1级升2级的基础经验)
|
||||||
// linear: 10 * level (线性增长部分)
|
// linear: 100 * level (线性增长部分)
|
||||||
// quadratic: 0.5 * level² (二次增长部分,增长速度比1.2x指数慢得多)
|
// quadratic: level * $level * $level (二次增长部分,增长速度比1.2x指数慢得多)
|
||||||
$base = 100;
|
$base = 100;
|
||||||
$linear = 10 * $level;
|
$linear = 100 * $level;
|
||||||
$quadratic = (int)(0.5 * $level * $level);
|
$quadratic = (int)($level * $level * $level);
|
||||||
|
|
||||||
return $base + $linear + $quadratic;
|
return $base + $linear + $quadratic;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -232,6 +232,24 @@ class Item
|
||||||
return self::createFromSpec($spec, $baseLevel);
|
return self::createFromSpec($spec, $baseLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建任务道具 - 用于地图解锁的特殊物品
|
||||||
|
* @param string $name 任务物品名称
|
||||||
|
* @return array 任务物品数组
|
||||||
|
*/
|
||||||
|
public static function createQuestItem(string $name): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'id' => uniqid('quest_'),
|
||||||
|
'type' => 'quest_item',
|
||||||
|
'name' => $name,
|
||||||
|
'quality' => 'legendary',
|
||||||
|
'level' => 1,
|
||||||
|
'quantity' => 1,
|
||||||
|
'desc' => '关键任务物品,用于解锁新区域',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建法术物品 - 支持新的丰富法术系统
|
* 创建法术物品 - 支持新的丰富法术系统
|
||||||
* @param int $spellId 法术ID
|
* @param int $spellId 法术ID
|
||||||
|
|
|
||||||
|
|
@ -152,6 +152,16 @@ class Monster extends Actor
|
||||||
$type = $drop['type'] ?? '';
|
$type = $drop['type'] ?? '';
|
||||||
$rate = $drop['rate'] ?? 0;
|
$rate = $drop['rate'] ?? 0;
|
||||||
|
|
||||||
|
// 处理任务物品
|
||||||
|
if ($type === 'quest_item') {
|
||||||
|
$item = Item::createQuestItem($drop['name'] ?? '未知道具');
|
||||||
|
$this->dropTable[] = [
|
||||||
|
'item' => $item,
|
||||||
|
'rate' => $rate,
|
||||||
|
];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if ($type === 'consume') {
|
if ($type === 'consume') {
|
||||||
$spec = $drop;
|
$spec = $drop;
|
||||||
unset($spec['rate']);
|
unset($spec['rate']);
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,33 @@ class DungeonSelectPanel
|
||||||
{
|
{
|
||||||
public function __construct(public Game $game) {}
|
public function __construct(public Game $game) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查玩家是否拥有指定物品
|
||||||
|
*/
|
||||||
|
private function hasItem(string $itemName): bool
|
||||||
|
{
|
||||||
|
foreach ($this->game->player->inventory as $item) {
|
||||||
|
if (($item['name'] ?? '') === $itemName) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查玩家是否可以进入某个副本
|
||||||
|
*/
|
||||||
|
private function canEnterDungeon(array $map): bool
|
||||||
|
{
|
||||||
|
// 如果没有key_item要求,可以进入
|
||||||
|
if ($map['key_item'] === null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查玩家是否拥有该钥匙
|
||||||
|
return $this->hasItem($map['key_item']);
|
||||||
|
}
|
||||||
|
|
||||||
public function show()
|
public function show()
|
||||||
{
|
{
|
||||||
Screen::clear($this->game->output);
|
Screen::clear($this->game->output);
|
||||||
|
|
@ -20,8 +47,18 @@ class DungeonSelectPanel
|
||||||
$out->writeln("");
|
$out->writeln("");
|
||||||
|
|
||||||
$maps = require __DIR__ . '/../../src/Data/maps.php';
|
$maps = require __DIR__ . '/../../src/Data/maps.php';
|
||||||
|
$availableMaps = [];
|
||||||
|
|
||||||
|
// 只显示已解锁的地图
|
||||||
foreach ($maps as $id => $map) {
|
foreach ($maps as $id => $map) {
|
||||||
|
if ($this->canEnterDungeon($map)) {
|
||||||
|
$availableMaps[$id] = $map;
|
||||||
$out->writeln("[{$id}] {$map['name']} (Lv.{$map['min_level']})");
|
$out->writeln("[{$id}] {$map['name']} (Lv.{$map['min_level']})");
|
||||||
|
} else {
|
||||||
|
// 显示未解锁的地图
|
||||||
|
$keyItem = $map['key_item'];
|
||||||
|
$out->writeln("[\033[90m{$id}\033[0m] {$map['name']} (未解锁 - 需要: {$keyItem})");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$out->writeln("");
|
$out->writeln("");
|
||||||
|
|
@ -34,12 +71,25 @@ class DungeonSelectPanel
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($maps[$dungeonId])) {
|
// 验证选择的副本是否存在
|
||||||
|
if (!isset($maps[$dungeonId])) {
|
||||||
|
$out->writeln("\033[91m无效副本\033[0m");
|
||||||
|
Screen::sleep(1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$selectedMap = $maps[$dungeonId];
|
||||||
|
|
||||||
|
// 检查是否有权限进入
|
||||||
|
if (!$this->canEnterDungeon($selectedMap)) {
|
||||||
|
$out->writeln("\033[91m该副本尚未解锁!\033[0m");
|
||||||
|
$out->writeln("需要物品: \033[93m{$selectedMap['key_item']}\033[0m");
|
||||||
|
Screen::sleep(2);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 进入副本
|
||||||
$this->game->dungeonId = (int)$dungeonId;
|
$this->game->dungeonId = (int)$dungeonId;
|
||||||
$this->game->state = Game::BATTLE;
|
$this->game->state = Game::BATTLE;
|
||||||
} else {
|
|
||||||
$out->writeln("无效副本");
|
|
||||||
Screen::sleep(1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ class InventoryPanel
|
||||||
'necklace' => '项链',
|
'necklace' => '项链',
|
||||||
'equipment' => '装备',
|
'equipment' => '装备',
|
||||||
'consume' => '消耗品',
|
'consume' => '消耗品',
|
||||||
|
'quest_item' => '任务物品',
|
||||||
];
|
];
|
||||||
|
|
||||||
public function __construct(public Game $game) {}
|
public function __construct(public Game $game) {}
|
||||||
|
|
@ -48,7 +49,8 @@ class InventoryPanel
|
||||||
|
|
||||||
// Filter items by category
|
// Filter items by category
|
||||||
if ($category == 'equipment'){
|
if ($category == 'equipment'){
|
||||||
$items = array_values(array_filter($allItems, fn($item) => $item['type'] !== 'consume'));
|
$items = array_values(array_filter($allItems, fn($item) =>
|
||||||
|
$item['type'] !== 'consume' && $item['type'] !== 'quest_item'));
|
||||||
}else{
|
}else{
|
||||||
$items = $category === 'all'
|
$items = $category === 'all'
|
||||||
? $allItems
|
? $allItems
|
||||||
|
|
@ -157,15 +159,26 @@ class InventoryPanel
|
||||||
$out->writeln("║ 拥有数量: {$quantity}");
|
$out->writeln("║ 拥有数量: {$quantity}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 任务物品不显示售价
|
||||||
|
if ($item['type'] !== 'quest_item') {
|
||||||
// 计算售价
|
// 计算售价
|
||||||
$sellPrice = \Game\Entities\Item::calculateSellPrice($item);
|
$sellPrice = \Game\Entities\Item::calculateSellPrice($item);
|
||||||
$out->writeln("║");
|
$out->writeln("║");
|
||||||
$out->writeln("║ 💰 售价: {$sellPrice} 灵石");
|
$out->writeln("║ 💰 售价: {$sellPrice} 灵石");
|
||||||
|
}
|
||||||
|
|
||||||
$out->writeln("╚════════════════════════════════════════╝");
|
$out->writeln("╚════════════════════════════════════════╝");
|
||||||
$out->writeln("");
|
$out->writeln("");
|
||||||
|
|
||||||
$isEquip = in_array($item['type'], ['weapon', 'armor', 'boots', 'ring', 'necklace']);
|
$isEquip = in_array($item['type'], ['weapon', 'armor', 'boots', 'ring', 'necklace']);
|
||||||
|
$isQuestItem = $item['type'] === 'quest_item';
|
||||||
|
|
||||||
|
if ($isQuestItem) {
|
||||||
|
// 任务物品无法操作
|
||||||
|
$out->writeln("这是一个关键任务物品,无法进行任何操作。");
|
||||||
|
$out->writeln("");
|
||||||
|
$out->writeln("[0] 返回");
|
||||||
|
} else {
|
||||||
if ($isEquip) {
|
if ($isEquip) {
|
||||||
$out->writeln("[1] 装备");
|
$out->writeln("[1] 装备");
|
||||||
} elseif ($item['type'] === 'consume') {
|
} elseif ($item['type'] === 'consume') {
|
||||||
|
|
@ -175,12 +188,15 @@ class InventoryPanel
|
||||||
$out->writeln("[2] 出售");
|
$out->writeln("[2] 出售");
|
||||||
$out->writeln("[3] 丢弃");
|
$out->writeln("[3] 丢弃");
|
||||||
$out->writeln("[0] 返回");
|
$out->writeln("[0] 返回");
|
||||||
|
}
|
||||||
|
|
||||||
$choice = Screen::input($out, "选择操作:");
|
$choice = Screen::input($out, "选择操作:");
|
||||||
|
|
||||||
|
if (!$isQuestItem) {
|
||||||
if ($choice == 1) $this->useItem($item, $inventoryIndex);
|
if ($choice == 1) $this->useItem($item, $inventoryIndex);
|
||||||
if ($choice == 2) $this->sellItem($item, $inventoryIndex);
|
if ($choice == 2) $this->sellItem($item, $inventoryIndex);
|
||||||
if ($choice == 3) $this->dropItem($item, $inventoryIndex);
|
if ($choice == 3) $this->dropItem($item, $inventoryIndex);
|
||||||
|
}
|
||||||
|
|
||||||
return $this->show($page, $category);
|
return $this->show($page, $category);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ use Game\Entities\Item;
|
||||||
require __DIR__ . '/../vendor/autoload.php';
|
require __DIR__ . '/../vendor/autoload.php';
|
||||||
|
|
||||||
$monster = \Game\Entities\Monster::create(6);
|
$monster = \Game\Entities\Monster::create(6);
|
||||||
|
dd($monster->getTotalExpForLevel(10) - $monster->getTotalExpForLevel(9));
|
||||||
dd($monster->getRandomEquipmentDrops(100));
|
dd($monster->getRandomEquipmentDrops(100));
|
||||||
//$player = new \Game\Entities\Player();
|
//$player = new \Game\Entities\Player();
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user