Compare commits

..

No commits in common. "c2a2e93ff38b619a8782fbe9924f3b79bbc68c99" and "9d9af5f96c431e26d0a40399833f709a8599deaf" have entirely different histories.

15 changed files with 298 additions and 1929 deletions

556
save.json

File diff suppressed because one or more lines are too long

View File

@ -115,50 +115,6 @@ class ItemDisplay
return $stats ? self::$green . "(" . implode(" ", $stats) . ")" . self::$reset : "";
}
/**
* 格式化法术的简洁信息(用于列表显示)
*/
public static function formatSpellCompact(array $spell): string
{
$calcType = $spell['calc_type'] ?? 'matk';
$spellType = $spell['spellType'] ?? $spell['type'] ?? 'unknown';
$calcTypeMap = [
'matk' => '魔攻',
'patk' => '物攻',
'hybrid' => '混合',
'hp_percent' => 'HP%',
'crit_heal' => '暴治',
'crit_damage' => '暴伤',
'defense' => '防御',
'low_def_bonus' => '克低防',
'matk_scaled' => '群伤',
'dispersed_damage' => '分散伤',
'crit_aoe' => '暴范',
'smart_heal' => '智能治',
'hp_missing' => '缺血治',
'team_sync' => '队伍同步',
];
$calcDesc = $calcTypeMap[$calcType] ?? $calcType;
// 根据法术类型显示基础数值
$valueStr = '';
if ($spellType === 'damage_single' || $spellType === 'damage_aoe') {
$damageRatio = $spell['damage_ratio'] ?? [1.2, 1.6, 2.0, 2.6];
$qualityIndex = self::getQualityIndex($spell['quality'] ?? 'common');
$ratio = $damageRatio[$qualityIndex] ?? 1.0;
$valueStr = self::$green . "{$ratio}x" . self::$reset;
} elseif ($spellType === 'heal_single' || $spellType === 'heal_aoe') {
$healRatio = $spell['heal_ratio'] ?? [0.5, 0.8, 1.2, 1.8];
$qualityIndex = self::getQualityIndex($spell['quality'] ?? 'common');
$ratio = $healRatio[$qualityIndex] ?? 0.5;
$valueStr = self::$green . "{$ratio}x" . self::$reset;
}
return self::$cyan . "[{$calcDesc}]" . self::$reset . ($valueStr ? " " . $valueStr : "");
}
/**
* 格式化主属性(多行详细版)
*/
@ -269,29 +225,17 @@ class ItemDisplay
$parts[] = self::$gray . "[{$typeName}]" . self::$reset;
}
// 主属性(简洁版)或法术信息
$type = $item['type'] ?? '';
if ($type === 'spell') {
// 显示法术的计算方式和基础数值
$spellInfo = self::formatSpellCompact($item);
if ($spellInfo) {
$parts[] = $spellInfo;
}
} else {
// 显示装备的属性
$statsStr = self::formatStatsCompact($item);
if ($statsStr) {
$parts[] = $statsStr;
}
// 主属性(简洁版)
$statsStr = self::formatStatsCompact($item);
if ($statsStr) {
$parts[] = $statsStr;
}
// 词条数量提示(仅限装备)
if ($type !== 'spell') {
$affixes = $item['affixes'] ?? [];
if (!empty($affixes)) {
$count = count($affixes);
$parts[] = self::$cyan . implode(',',$affixes);
}
// 词条数量提示
$affixes = $item['affixes'] ?? [];
if (!empty($affixes)) {
$count = count($affixes);
$parts[] = self::$cyan . implode(',',$affixes);
}
return implode(" ", $parts);
@ -331,51 +275,6 @@ class ItemDisplay
$lines[] = $linePrefix;
// 法术特殊显示
if ($type === 'spell') {
$lines[] = $linePrefix . self::$white . "--- 法术信息 ---" . self::$reset;
$spellType = $item['spellType'] ?? $item['type'] ?? 'unknown';
$calcType = $item['calc_type'] ?? 'unknown';
// 计算方式映射
$calcTypeMap = [
'matk' => '基于魔攻',
'patk' => '基于物攻',
'hp_percent' => '基于最大生命值百分比',
'hybrid' => '基于(魔攻+物攻)混合',
'crit_heal' => '暴击率影响治疗效果',
'crit_damage' => '暴击伤害系数影响伤害',
'crit_aoe' => '暴击率影响范围伤害',
'defense' => '基于防御属性',
'low_def_bonus' => '对低防御敌人伤害加成',
'matk_scaled' => '随敌人数量加成',
'dispersed_damage' => '伤害分散到所有敌人',
'smart_heal' => '智能治疗(优先低血量)',
'hp_missing' => '基于缺失生命值',
'team_sync' => '基于队伍规模',
];
$calcDesc = $calcTypeMap[$calcType] ?? $calcType;
$lines[] = $linePrefix . " 计算方式: " . self::$cyan . $calcDesc . self::$reset;
// 基础数值
if ($spellType === 'damage_single' || $spellType === 'damage_aoe') {
$damageRatio = $item['damage_ratio'] ?? [1.2, 1.6, 2.0, 2.6];
$qualityIndex = self::getQualityIndex($quality);
$ratio = $damageRatio[$qualityIndex] ?? 1.0;
$lines[] = $linePrefix . " 伤害倍数: " . self::$green . $ratio . "x" . self::$reset;
} elseif ($spellType === 'heal_single' || $spellType === 'heal_aoe') {
$healRatio = $item['heal_ratio'] ?? [0.5, 0.8, 1.2, 1.8];
$healBase = $item['heal_base'] ?? [20, 40, 70, 120];
$qualityIndex = self::getQualityIndex($quality);
$ratio = $healRatio[$qualityIndex] ?? 0.5;
$base = $healBase[$qualityIndex] ?? 20;
$lines[] = $linePrefix . " 治疗系数: " . self::$green . $ratio . "x + " . $base . self::$reset;
}
$lines[] = $linePrefix;
}
// 主属性
$lines[] = $linePrefix . self::$white . "--- 主属性 ---" . self::$reset;
$statLines = self::formatStatsDetailed($item, $linePrefix . " ");
@ -412,73 +311,19 @@ class ItemDisplay
$lines = [];
if ($item) {
$type = $item['type'] ?? '';
// 第一行:槽位名 + 装备/法术名
// 第一行:槽位名 + 装备名
$lines[] = $linePrefix . self::$cyan . $slotName . self::$reset . ": " . self::formatName($item);
if ($type === 'spell') {
// 法术显示:计算方式和基础数值
$calcType = $item['calc_type'] ?? 'matk';
$spellType = $item['spellType'] ?? $item['type'] ?? 'unknown';
// 第二行:主属性
$statsStr = self::formatStatsCompact($item);
if ($statsStr) {
$lines[] = $linePrefix . " " . $statsStr;
}
// 计算方式的完整描述
$calcTypeDescMap = [
'matk' => '基于魔攻',
'patk' => '基于物攻',
'hybrid' => '混合伤害',
'hp_percent' => '基于HP%',
'crit_heal' => '暴击治疗',
'crit_damage' => '暴击伤害',
'defense' => '基于防御',
'low_def_bonus' => '克低防',
'matk_scaled' => '群体伤害',
'dispersed_damage' => '分散伤害',
'crit_aoe' => '暴击范围',
'smart_heal' => '智能治疗',
'hp_missing' => '缺血治疗',
'team_sync' => '队伍同步',
];
$calcDesc = $calcTypeDescMap[$calcType] ?? $calcType;
$lines[] = $linePrefix . " " . self::$white . "计算: " . self::$green . $calcDesc . self::$reset;
// 显示基础数值
if ($spellType === 'damage_single' || $spellType === 'damage_aoe') {
$damageRatio = $item['damage_ratio'] ?? [1.2, 1.6, 2.0, 2.6];
$qualityIndex = self::getQualityIndex($item['quality'] ?? 'common');
$ratio = $damageRatio[$qualityIndex] ?? 1.0;
$lines[] = $linePrefix . " " . self::$white . "倍数: " . self::$yellow . "{$ratio}x" . self::$reset;
} elseif ($spellType === 'heal_single' || $spellType === 'heal_aoe') {
$healRatio = $item['heal_ratio'] ?? [0.5, 0.8, 1.2, 1.8];
$healBase = $item['heal_base'] ?? [20, 40, 70, 120];
$qualityIndex = self::getQualityIndex($item['quality'] ?? 'common');
$ratio = $healRatio[$qualityIndex] ?? 0.5;
$base = $healBase[$qualityIndex] ?? 20;
$lines[] = $linePrefix . " " . self::$white . "治疗: " . self::$yellow . "{$ratio}x + {$base}" . self::$reset;
}
// 显示消耗
$cost = $item['cost'] ?? 0;
$enhanceLevel = $item['enhanceLevel'] ?? 0;
$actualCost = max(1, $cost - ($enhanceLevel * 2));
if ($enhanceLevel > 0) {
$lines[] = $linePrefix . " " . self::$white . "消耗: " . self::$yellow . "{$cost}" . self::$reset . "" . self::$green . "{$actualCost}" . self::$reset;
} else {
$lines[] = $linePrefix . " " . self::$white . "消耗: " . self::$green . "{$actualCost}" . self::$reset;
}
} else {
// 装备显示:属性和词条
$statsStr = self::formatStatsCompact($item);
if ($statsStr) {
$lines[] = $linePrefix . " " . $statsStr;
}
// 词条
$affixes = $item['affixes'] ?? [];
foreach ($affixes as $affix) {
$lines[] = $linePrefix . " " . self::$yellow . "" . self::$reset . " " . $affix;
}
// 第三行及之后:词条
$affixes = $item['affixes'] ?? [];
foreach ($affixes as $affix) {
$lines[] = $linePrefix . " " . self::$yellow . "" . self::$reset . " " . $affix;
}
} else {
$lines[] = $linePrefix . self::$cyan . $slotName . self::$reset . ": " .
@ -517,18 +362,4 @@ class ItemDisplay
return $prefix . "" . $color . $name . self::$reset . $enhanceStr . $statsStr . $affixStr;
}
/**
* 根据品质获取数组索引
*/
private static function getQualityIndex(string $quality): int
{
return match($quality) {
'common' => 0,
'rare' => 1,
'epic' => 2,
'legendary' => 3,
default => 0,
};
}
}

View File

@ -1,380 +0,0 @@
<?php
namespace Game\Core;
/**
* 法术显示工具类 - 统一管理法术信息的展示
*/
class SpellDisplay
{
// 法术类型名称
private static array $typeNames = [
'heal_single' => '单体治疗',
'damage_single' => '单体伤害',
'damage_aoe' => '群体伤害',
'heal_aoe' => '群体治疗',
'support' => '辅助',
];
// 计算方式说明
private static array $calcTypeDescriptions = [
'matk' => '基于魔攻',
'patk' => '基于物攻',
'hp_percent' => '基于最大生命值百分比',
'hybrid' => '基于(魔攻+物攻)混合',
'crit_heal' => '暴击率影响治疗效果',
'crit_damage' => '暴击伤害系数影响伤害',
'crit_aoe' => '暴击率影响范围伤害',
'defense' => '基于防御属性',
'low_def_bonus' => '对低防御敌人伤害加成',
'matk_scaled' => '随敌人数量加成',
'dispersed_damage' => '伤害分散到所有敌人',
'smart_heal' => '智能治疗(优先低血量)',
'hp_missing' => '基于缺失生命值',
'team_sync' => '基于队伍规模',
];
// 品质颜色
private static array $qualityColors = [
'common' => Colors::WHITE,
'rare' => Colors::BLUE,
'epic' => Colors::MAGENTA,
'legendary' => Colors::YELLOW,
];
// 品质名称
private static array $qualityNames = [
'common' => '普通',
'rare' => '稀有',
'epic' => '史诗',
'legendary' => '传奇',
];
// 颜色常量
private static string $reset = Colors::RESET;
private static string $yellow = Colors::YELLOW;
private static string $green = Colors::GREEN;
private static string $cyan = Colors::CYAN;
private static string $white = Colors::WHITE;
private static string $gray = Colors::GRAY;
private static string $magenta = Colors::MAGENTA;
private static string $blue = Colors::BLUE;
/**
* 获取法术品质颜色
*/
public static function getQualityColor(string $quality): string
{
return self::$qualityColors[$quality] ?? self::$white;
}
/**
* 获取法术品质名称
*/
public static function getQualityName(string $quality): string
{
return self::$qualityNames[$quality] ?? '普通';
}
/**
* 获取法术类型名称
*/
public static function getTypeName(string $type): string
{
return self::$typeNames[$type] ?? $type;
}
/**
* 获取计算方式描述
*/
public static function getCalcTypeDescription(string $calcType): string
{
return self::$calcTypeDescriptions[$calcType] ?? $calcType;
}
/**
* 格式化法术名称(带品质颜色和等级)
*/
public static function formatName(array $spell): string
{
$quality = $spell['quality'] ?? 'common';
$color = self::getQualityColor($quality);
$name = $spell['name'] ?? '未知法术';
$level = $spell['level'] ?? 1;
$enhanceLevel = $spell['enhanceLevel'] ?? 0;
$enhanceStr = $enhanceLevel > 0 ? self::$yellow . "+{$enhanceLevel}" . self::$reset : "";
return $color . $name . self::$reset . " Lv.{$level}" . $enhanceStr;
}
/**
* 格式化法术简要信息(用于列表)
*/
public static function renderListItem(array $spell): string
{
$parts = [];
// 名称(带品质颜色和强化)
$parts[] = self::formatName($spell);
// 法术类型
$spellType = $spell['spellType'] ?? $spell['type'] ?? 'unknown';
$typeName = self::getTypeName($spellType);
$parts[] = self::$gray . "[{$typeName}]" . self::$reset;
// 消耗和基本描述
$cost = $spell['cost'] ?? 0;
$parts[] = self::$cyan . "消耗:{$cost}" . self::$reset;
return implode(" ", $parts);
}
/**
* 格式化法术详细信息(用于详情面板)
* 返回多行数组
*/
public static function renderDetail(array $spell, string $linePrefix = ""): array
{
$lines = [];
$quality = $spell['quality'] ?? 'common';
$qualityColor = self::getQualityColor($quality);
$qualityName = self::getQualityName($quality);
$spellType = $spell['spellType'] ?? $spell['type'] ?? 'unknown';
$typeName = self::getTypeName($spellType);
$calcType = $spell['calc_type'] ?? 'unknown';
$calcTypeDesc = self::getCalcTypeDescription($calcType);
$enhanceLevel = $spell['enhanceLevel'] ?? 0;
$spellId = $spell['spellId'] ?? 'unknown';
// 名称行
$lines[] = $linePrefix . self::formatName($spell);
$lines[] = $linePrefix;
// 基本信息
$lines[] = $linePrefix . "品质: " . $qualityColor . $qualityName . self::$reset;
$lines[] = $linePrefix . "类型: " . self::$white . $typeName . self::$reset;
$lines[] = $linePrefix . "法术ID: " . self::$gray . $spellId . self::$reset;
$lines[] = $linePrefix;
// 强化信息
if ($enhanceLevel > 0) {
$damageBonus = $enhanceLevel * 5;
$costReduction = $enhanceLevel * 2;
$lines[] = $linePrefix . "强化: " . self::$yellow . "+{$enhanceLevel}" . self::$reset .
self::$gray . " (伤害+{$damageBonus}% 消耗-{$costReduction})" . self::$reset;
$lines[] = $linePrefix;
}
// 计算方式
$lines[] = $linePrefix . self::$cyan . "━━ 基础数值 ━━" . self::$reset;
$lines[] = $linePrefix . "计算方式: " . self::$green . $calcTypeDesc . self::$reset;
// 根据法术类型显示不同的基础数值
if ($spellType === 'heal_single' || $spellType === 'heal_aoe') {
$lines[] = self::formatHealValues($spell, $linePrefix, $enhanceLevel);
} elseif ($spellType === 'damage_single' || $spellType === 'damage_aoe') {
$lines[] = self::formatDamageValues($spell, $linePrefix, $enhanceLevel);
}
$lines[] = $linePrefix;
// 消耗信息
$baseCost = $spell['cost'] ?? 20;
$actualCost = max(1, $baseCost - ($enhanceLevel * 2));
if ($enhanceLevel > 0) {
$lines[] = $linePrefix . "魔法消耗: " . self::$white . $baseCost . self::$reset .
"" . self::$green . $actualCost . self::$reset;
} else {
$lines[] = $linePrefix . "魔法消耗: " . self::$green . $baseCost . self::$reset;
}
$lines[] = $linePrefix;
// 描述
$desc = $spell['desc'] ?? '';
if ($desc) {
$lines[] = $linePrefix . self::$gray . $desc . self::$reset;
}
return $lines;
}
/**
* 格式化治疗法术的基础数值
*/
private static function formatHealValues(array $spell, string $linePrefix, int $enhanceLevel): string
{
$calcType = $spell['calc_type'] ?? 'matk';
$healRatio = $spell['heal_ratio'] ?? [0.5, 0.8, 1.2, 1.8];
$healBase = $spell['heal_base'] ?? [20, 40, 70, 120];
$qualityIndex = self::getQualityIndex($spell['quality'] ?? 'common');
$ratio = $healRatio[$qualityIndex] ?? 0.5;
$base = $healBase[$qualityIndex] ?? 20;
$lines = "";
match($calcType) {
'matk' => $lines = self::formatMatkHeal($ratio, $base, $linePrefix, $enhanceLevel),
'hp_percent' => $lines = self::formatHpPercentHeal($ratio, $linePrefix),
'hybrid' => $lines = self::formatHybridHeal($ratio, $base, $linePrefix, $enhanceLevel),
'hp_missing' => $lines = self::formatHpMissingHeal($ratio, $linePrefix),
'crit_heal' => $lines = self::formatCritHeal($ratio, $base, $spell['crit_bonus'] ?? [0.5, 0.7, 1.0, 1.5], $linePrefix, $enhanceLevel),
'defense' => $lines = self::formatDefenseHeal($ratio, $base, $linePrefix, $enhanceLevel),
default => $lines = $linePrefix . "基础治疗: " . self::$green . "{$ratio}x魔攻 + {$base}" . self::$reset,
};
return $lines;
}
/**
* 格式化伤害法术的基础数值
*/
private static function formatDamageValues(array $spell, string $linePrefix, int $enhanceLevel): string
{
$calcType = $spell['calc_type'] ?? 'matk';
$damageRatio = $spell['damage_ratio'] ?? [1.2, 1.6, 2.0, 2.6];
$qualityIndex = self::getQualityIndex($spell['quality'] ?? 'common');
$ratio = $damageRatio[$qualityIndex] ?? 1.2;
if ($calcType === 'matk') {
return $linePrefix . "伤害倍数: " . self::$green . "{$ratio}x魔攻" . self::$reset;
} elseif ($calcType === 'patk') {
return $linePrefix . "伤害倍数: " . self::$green . "{$ratio}x物攻" . self::$reset;
} elseif ($calcType === 'hybrid') {
return $linePrefix . "伤害倍数: " . self::$green . "{$ratio}x(魔攻+物攻)" . self::$reset;
} elseif ($calcType === 'crit_damage') {
$critBonus = $spell['crit_dmg_bonus'] ?? [0.3, 0.5, 0.8, 1.2];
$bonus = $critBonus[$qualityIndex] ?? 0.3;
return $linePrefix . "伤害倍数: " . self::$green . "{$ratio}x物攻" . self::$reset . "\n" .
$linePrefix . "暴击加成: " . self::$yellow . "{$bonus}x暴伤系数" . self::$reset;
} elseif ($calcType === 'low_def_bonus') {
return $linePrefix . "伤害倍数: " . self::$green . "{$ratio}x物攻(低防御加成)" . self::$reset;
} elseif ($calcType === 'matk_scaled') {
$enemyBonus = $spell['enemy_count_bonus'] ?? [0.1, 0.15, 0.2, 0.3];
$bonus = $enemyBonus[$qualityIndex] ?? 0.1;
return $linePrefix . "伤害倍数: " . self::$green . "{$ratio}x魔攻" . self::$reset . "\n" .
$linePrefix . "敌人数加成: " . self::$yellow . "+" . ($bonus*100) . "%/敌人" . self::$reset;
} elseif ($calcType === 'dispersed_damage') {
$dispersion = $spell['dispersion'] ?? [0.8, 0.75, 0.7, 0.65];
$disp = $dispersion[$qualityIndex] ?? 0.8;
return $linePrefix . "伤害倍数: " . self::$green . "{$ratio}x魔攻" . self::$reset . "\n" .
$linePrefix . "分散系数: " . self::$yellow . "{$disp}(敌人越多衰减越严重)" . self::$reset;
} elseif ($calcType === 'crit_aoe') {
$critBonus = $spell['crit_bonus'] ?? [0.4, 0.6, 0.9, 1.3];
$bonus = $critBonus[$qualityIndex] ?? 0.4;
return $linePrefix . "伤害倍数: " . self::$green . "{$ratio}x魔攻" . self::$reset . "\n" .
$linePrefix . "暴击影响: " . self::$yellow . "{$bonus}x暴击率" . self::$reset;
}
return $linePrefix . "伤害倍数: " . self::$green . "{$ratio}x" . self::$reset;
}
/**
* 格式化魔攻治疗
*/
private static function formatMatkHeal(float $ratio, float $base, string $linePrefix, int $enhanceLevel): string
{
$healBonus = $enhanceLevel * 5;
if ($enhanceLevel > 0) {
return $linePrefix . "恢复量: " . self::$green . "{$ratio}x魔攻 + {$base}" . self::$reset .
" " . self::$yellow . "(+{$healBonus}%)" . self::$reset;
}
return $linePrefix . "恢复量: " . self::$green . "{$ratio}x魔攻 + {$base}" . self::$reset;
}
/**
* 格式化生命值百分比治疗
*/
private static function formatHpPercentHeal(float $ratio, string $linePrefix): string
{
return $linePrefix . "恢复量: " . self::$green . ($ratio * 100) . "% 最大生命值" . self::$reset;
}
/**
* 格式化混合治疗
*/
private static function formatHybridHeal(float $ratio, float $base, string $linePrefix, int $enhanceLevel): string
{
$healBonus = $enhanceLevel * 5;
if ($enhanceLevel > 0) {
return $linePrefix . "恢复量: " . self::$green . "{$ratio}x(魔攻+物攻) + {$base}" . self::$reset .
" " . self::$yellow . "(+{$healBonus}%)" . self::$reset;
}
return $linePrefix . "恢复量: " . self::$green . "{$ratio}x(魔攻+物攻) + {$base}" . self::$reset;
}
/**
* 格式化缺失生命值治疗
*/
private static function formatHpMissingHeal(float $ratio, string $linePrefix): string
{
return $linePrefix . "恢复量: " . self::$green . ($ratio * 100) . "% 缺失生命值" . self::$reset;
}
/**
* 格式化暴击治疗
*/
private static function formatCritHeal(float $ratio, float $base, array $critBonus, string $linePrefix, int $enhanceLevel): string
{
$qualityIndex = self::getQualityIndex(0);
$bonus = $critBonus[$qualityIndex] ?? 0.5;
$healBonus = $enhanceLevel * 5;
$result = $linePrefix . "恢复量: " . self::$green . "{$ratio}x魔攻 + {$base}" . self::$reset;
$result .= "\n" . $linePrefix . "暴击系数: " . self::$yellow . "{$bonus}x暴击率加成" . self::$reset;
if ($enhanceLevel > 0) {
$result .= "\n" . $linePrefix . "强化加成: " . self::$yellow . "+{$healBonus}%" . self::$reset;
}
return $result;
}
/**
* 格式化防御治疗
*/
private static function formatDefenseHeal(float $ratio, float $base, string $linePrefix, int $enhanceLevel): string
{
$healBonus = $enhanceLevel * 5;
if ($enhanceLevel > 0) {
return $linePrefix . "恢复量: " . self::$green . "{$ratio}x(物防+魔防) + {$base}" . self::$reset .
" " . self::$yellow . "(+{$healBonus}%)" . self::$reset;
}
return $linePrefix . "恢复量: " . self::$green . "{$ratio}x(物防+魔防) + {$base}" . self::$reset;
}
/**
* 根据品质获取数组索引
*/
private static function getQualityIndex(string $quality): int
{
return match($quality) {
'common' => 0,
'rare' => 1,
'epic' => 2,
'legendary' => 3,
default => 0,
};
}
/**
* 渲染战斗中的法术简洁信息
*/
public static function renderBattleInfo(array $spell, string $prefix = " "): string
{
$quality = $spell['quality'] ?? 'common';
$color = self::getQualityColor($quality);
$name = $spell['name'] ?? '未知法术';
$cost = $spell['cost'] ?? 20;
$enhanceLevel = $spell['enhanceLevel'] ?? 0;
$calcType = $spell['calc_type'] ?? 'unknown';
$calcDesc = self::getCalcTypeDescription($calcType);
$enhanceStr = $enhanceLevel > 0 ? self::$yellow . "+{$enhanceLevel}" . self::$reset : "";
return $prefix . $color . $name . self::$reset . $enhanceStr .
" [消耗:{$cost} {$calcDesc}]";
}
}

View File

@ -1,25 +1,14 @@
<?php
/**
* 地牢法术掉落池配置 - 重构版本
* 参考装备的掉落方式
*
* 定义各地牢可以掉落的法术类型
* 在掉落时会根据品质概率从相应的法术类型中选择具体的法术ID
*
* 法术类型:
* - heal_single: 单体治疗
* - damage_single: 单体伤害
* - damage_aoe: 群体伤害
* - heal_aoe: 群体治疗
*/
// Per-dungeon spell pools
return [
1 => ['heal_single', 'damage_single', 'damage_aoe'], // 七玄门 (Lv.1-5)
2 => ['damage_single', 'damage_aoe', 'heal_aoe'], // 太南谷 (Lv.5-10)
3 => ['heal_single', 'heal_aoe'], // 血色禁地 (Lv.10-15)
4 => ['damage_single', 'damage_aoe'], // 黄枫谷 (Lv.15-20)
5 => ['damage_single', 'heal_aoe'], // 燕翎堡 (Lv.20-30)
6 => ['damage_single', 'heal_aoe'], // 越京皇宫 (Lv.30-40)
7 => ['damage_aoe'], // 乱星海-魁星岛 (Lv.40-50)
8 => ['damage_aoe', 'heal_single', 'heal_aoe'], // 虚天殿 (Lv.50-60)
9 => ['damage_single', 'damage_aoe', 'heal_single'], // 外星海 (Lv.60+)
1 => [1, 10],
2 => [2, 3, 11],
3 => [20, 21],
4 => [12],
5 => [4],
6 => [5, 22],
7 => [13],
8 => [13, 22],
9 => [5, 13],
// others can be added later
];

View File

@ -109,9 +109,6 @@ return [
['type' => 'weapon', 'name' => '铁刀', 'rate' => 10] + $weaponTemplate,
['type' => 'consume', 'name' => '金疮药', 'rate' => 30, 'heal' => 30],
],
'spells' => [
['id' => 10, 'name' => '柔拳', 'rate' => 25],
],
'weight' => 60,
],
[
@ -128,10 +125,6 @@ return [
['type' => 'armor', 'name' => '皮甲', 'rate' => 10] + $armorTemplate,
['type' => 'consume', 'name' => '黄龙丹', 'rate' => 25, 'heal' => 50],
],
'spells' => [
['id' => 10, 'name' => '刀气切割', 'rate' => 30],
['id' => 20, 'name' => '寒冰爆裂', 'rate' => 25],
],
'minions' => [
['name' => '野狼帮帮众', 'hp' => 30, 'patk' => 5, 'matk' => 2, 'pdef' => 0, 'mdef' => 0, 'exp' => 10, 'count' => 2],
],
@ -152,10 +145,8 @@ return [
['type' => 'necklace', 'name' => '长生锁', 'rate' => 15] + $necklaceTemplate,
['type' => 'consume', 'name' => '清灵散', 'rate' => 40, 'heal' => 80],
],
'spells' => [
['id' => 1, 'name' => '妙手回春', 'rate' => 30],
['id' => 2, 'name' => '舍身救人', 'rate' => 25],
['id' => 30, 'name' => '集体治疗', 'rate' => 20],
'minions' => [
['name' => '铁奴', 'hp' => 80, 'patk' => 12, 'pdef' => 8, 'exp' => 30, 'count' => 1],
],
'weight' => 10,
],
@ -180,10 +171,6 @@ return [
['type' => 'weapon', 'name' => '法器残片', 'rate' => 15] + $weaponTemplate,
['type' => 'consume', 'name' => '辟谷丹', 'rate' => 30, 'heal' => 60],
],
'spells' => [
['id' => 10, 'name' => '初级火焰术', 'rate' => 30],
['id' => 11, 'name' => '寒冰之术', 'rate' => 25],
],
'weight' => 50,
],
[
@ -200,10 +187,6 @@ return [
['type' => 'armor', 'name' => '青布衫', 'rate' => 15] + $armorTemplate,
['type' => 'boots', 'name' => '神行靴', 'rate' => 10] + $bootsTemplate,
],
'spells' => [
['id' => 10, 'name' => '火焰冲击', 'rate' => 30],
['id' => 30, 'name' => '防护光环', 'rate' => 25],
],
'weight' => 35,
],
[
@ -221,12 +204,6 @@ return [
['type' => 'ring', 'name' => '储物戒', 'rate' => 15] + $ringTemplate,
['type' => 'consume', 'name' => '合气丹', 'rate' => 30, 'heal' => 100],
],
'spells' => [
['id' => 10, 'name' => '炎火术', 'rate' => 30],
['id' => 11, 'name' => '冰魄术', 'rate' => 25],
['id' => 12, 'name' => '雷刹术', 'rate' => 20],
['id' => 20, 'name' => '冰暴术', 'rate' => 15],
],
'weight' => 15,
],
],
@ -249,10 +226,6 @@ return [
'drops' => [
['type' => 'consume', 'name' => '紫猴花', 'rate' => 25, 'heal' => 120],
],
'spells' => [
['id' => 10, 'name' => '兽火喷射', 'rate' => 30],
['id' => 20, 'name' => '野兽嚎叫', 'rate' => 25],
],
'weight' => 50,
],
[
@ -269,11 +242,6 @@ return [
['type' => 'weapon', 'name' => '月刃', 'rate' => 15] + $weaponTemplate,
['type' => 'armor', 'name' => '掩月法袍', 'rate' => 15] + $armorTemplate,
],
'spells' => [
['id' => 11, 'name' => '月影冰术', 'rate' => 30],
['id' => 20, 'name' => '月光雹', 'rate' => 25],
['id' => 1, 'name' => '月华治愈', 'rate' => 20],
],
'weight' => 35,
],
[
@ -291,13 +259,6 @@ return [
['type' => 'armor', 'name' => '墨蛟甲', 'quality' => 'epic', 'pdef' => 20, 'mdef' => 15, 'rate' => 15],
['type' => 'consume', 'name' => '筑基丹', 'rate' => 50, 'heal' => 500],
],
'spells' => [
['id' => 11, 'name' => '墨液冰锥', 'rate' => 30],
['id' => 20, 'name' => '墨蛟冰雹', 'rate' => 25],
['id' => 22, 'name' => '墨影流星', 'rate' => 20],
['id' => 30, 'name' => '蛟龙防御', 'rate' => 15],
['id' => 1, 'name' => '生命恢复', 'rate' => 10],
],
'weight' => 15,
],
],
@ -324,10 +285,6 @@ return [
['type' => 'weapon', 'name' => '黄枫剑', 'rate' => 15] + $weaponTemplate,
['type' => 'consume', 'name' => '黄龙丹', 'rate' => 30, 'heal' => 150],
],
'spells' => [
['id' => 10, 'name' => '黄枫剑气', 'rate' => 30],
['id' => 30, 'name' => '枫叶守护', 'rate' => 25],
],
'weight' => 50,
],
[
@ -344,11 +301,6 @@ return [
['type' => 'armor', 'name' => '执法甲', 'rate' => 15] + $armorTemplate,
['type' => 'boots', 'name' => '执法靴', 'rate' => 12] + $bootsTemplate,
],
'spells' => [
['id' => 10, 'name' => '执法烈火', 'rate' => 30],
['id' => 20, 'name' => '冰雨惩罚', 'rate' => 25],
['id' => 30, 'name' => '铁血护盾', 'rate' => 20],
],
'weight' => 35,
],
[
@ -366,13 +318,6 @@ return [
['type' => 'ring', 'name' => '传音符', 'rate' => 20] + $ringTemplate,
['type' => 'consume', 'name' => '定颜丹', 'rate' => 10, 'heal' => 800],
],
'spells' => [
['id' => 13, 'name' => '烈焰焚天', 'rate' => 30],
['id' => 22, 'name' => '流星雨击', 'rate' => 25],
['id' => 32, 'name' => '圣灵保护', 'rate' => 20],
['id' => 1, 'name' => '疗伤术', 'rate' => 15],
['id' => 30, 'name' => '大地庇护', 'rate' => 10],
],
'weight' => 15,
],
],
@ -396,10 +341,6 @@ return [
['type' => 'weapon', 'name' => '魔刃', 'rate' => 15] + $weaponTemplate,
['type' => 'consume', 'name' => '血煞丹', 'rate' => 30, 'heal' => 200],
],
'spells' => [
['id' => 10, 'name' => '邪火燎原', 'rate' => 30],
['id' => 20, 'name' => '魔冰风暴', 'rate' => 25],
],
'weight' => 50,
],
[
@ -416,11 +357,6 @@ return [
['type' => 'armor', 'name' => '鬼灵衣', 'rate' => 15] + $armorTemplate,
['type' => 'necklace', 'name' => '聚魂珠', 'rate' => 12] + $necklaceTemplate,
],
'spells' => [
['id' => 11, 'name' => '冥界冰刺', 'rate' => 30],
['id' => 21, 'name' => '炎爆诅咒', 'rate' => 25],
['id' => 34, 'name' => '幽冥护盾', 'rate' => 20],
],
'weight' => 35,
],
[
@ -438,13 +374,6 @@ return [
['type' => 'armor', 'name' => '血灵甲', 'quality' => 'epic', 'pdef' => 40, 'mdef' => 30, 'rate' => 20],
['type' => 'consume', 'name' => '血灵丹', 'rate' => 30, 'heal' => 1000],
],
'spells' => [
['id' => 12, 'name' => '王蝉鸣雷', 'rate' => 30],
['id' => 23, 'name' => '灭世风暴', 'rate' => 25],
['id' => 24, 'name' => '末日火雨', 'rate' => 20],
['id' => 35, 'name' => '血魔复生', 'rate' => 15],
['id' => 4, 'name' => '生命泉涌', 'rate' => 10],
],
'weight' => 15,
],
],
@ -468,10 +397,6 @@ return [
['type' => 'weapon', 'name' => '金瓜锤', 'rate' => 15] + $weaponTemplate,
['type' => 'armor', 'name' => '金甲', 'rate' => 15] + $armorTemplate,
],
'spells' => [
['id' => 13, 'name' => '帝王烈焰', 'rate' => 30],
['id' => 30, 'name' => '皇权庇护', 'rate' => 25],
],
'weight' => 50,
],
[
@ -488,11 +413,6 @@ return [
['type' => 'weapon', 'name' => '血刀', 'rate' => 18] + $weaponTemplate,
['type' => 'consume', 'name' => '狂暴丹', 'rate' => 30, 'heal' => 400],
],
'spells' => [
['id' => 14, 'name' => '诛仙剑气', 'rate' => 30],
['id' => 24, 'name' => '末日炼狱', 'rate' => 25],
['id' => 35, 'name' => '血魂同盟', 'rate' => 20],
],
'weight' => 35,
],
[
@ -510,13 +430,6 @@ return [
['type' => 'consume', 'name' => '虚天鼎碎片', 'rate' => 10, 'heal' => 2000], // 剧情物品作为高回复药
['type' => 'ring', 'name' => '黑煞戒', 'rate' => 20] + $ringTemplate,
],
'spells' => [
['id' => 15, 'name' => '狂暴邪斩', 'rate' => 30],
['id' => 25, 'name' => '狂风灭世', 'rate' => 25],
['id' => 33, 'name' => '仙界诅咒', 'rate' => 20],
['id' => 35, 'name' => '血煞永生', 'rate' => 15],
['id' => 6, 'name' => '暗夜疗愈', 'rate' => 10],
],
'weight' => 15,
],
],
@ -543,10 +456,6 @@ return [
['type' => 'weapon', 'name' => '骨棒', 'rate' => 15] + $weaponTemplate,
['type' => 'consume', 'name' => '海灵液', 'rate' => 30, 'heal' => 500],
],
'spells' => [
['id' => 20, 'name' => '海洋冰雹', 'rate' => 30],
['id' => 25, 'name' => '波涛斩击', 'rate' => 25],
],
'weight' => 50,
],
[
@ -563,10 +472,6 @@ return [
['type' => 'armor', 'name' => '鱼鳞甲', 'rate' => 15] + $armorTemplate,
['type' => 'necklace', 'name' => '避水珠', 'rate' => 12] + $necklaceTemplate,
],
'spells' => [
['id' => 21, 'name' => '炎爆水雾', 'rate' => 30],
['id' => 30, 'name' => '水灵庇护', 'rate' => 25],
],
'weight' => 35,
],
[
@ -584,12 +489,6 @@ return [
['type' => 'boots', 'name' => '踏浪靴', 'rate' => 15] + $bootsTemplate,
['type' => 'consume', 'name' => '降尘丹', 'rate' => 25, 'heal' => 1500],
],
'spells' => [
['id' => 22, 'name' => '水系流星', 'rate' => 30],
['id' => 23, 'name' => '沧海风暴', 'rate' => 25],
['id' => 35, 'name' => '灵魂共鸣', 'rate' => 20],
['id' => 31, 'name' => '海王光环', 'rate' => 15],
],
'weight' => 15,
],
],
@ -613,10 +512,6 @@ return [
['type' => 'weapon', 'name' => '傀儡弓', 'rate' => 15] + $weaponTemplate,
['type' => 'consume', 'name' => '灵石乳', 'rate' => 30, 'heal' => 800],
],
'spells' => [
['id' => 12, 'name' => '傀儡雷击', 'rate' => 30],
['id' => 30, 'name' => '机械护盾', 'rate' => 25],
],
'weight' => 50,
],
[
@ -633,11 +528,6 @@ return [
['type' => 'armor', 'name' => '灵力护盾', 'rate' => 15] + $armorTemplate,
['type' => 'ring', 'name' => '分身戒', 'rate' => 12] + $ringTemplate,
],
'spells' => [
['id' => 14, 'name' => '剑仙降临', 'rate' => 30],
['id' => 23, 'name' => '灭世寂灭', 'rate' => 25],
['id' => 32, 'name' => '圣灵恩惠', 'rate' => 20],
],
'weight' => 35,
],
[
@ -655,13 +545,6 @@ return [
['type' => 'consume', 'name' => '补天丹', 'rate' => 10, 'heal' => 3000],
['type' => 'necklace', 'name' => '虚天鼎', 'quality' => 'legendary', 'hp' => 2000, 'rate' => 5],
],
'spells' => [
['id' => 15, 'name' => '极阴邪斩', 'rate' => 30],
['id' => 24, 'name' => '末世冰狱', 'rate' => 25],
['id' => 33, 'name' => '仙界救赎', 'rate' => 20],
['id' => 35, 'name' => '永恒诅咒', 'rate' => 15],
['id' => 3, 'name' => '活力恢复', 'rate' => 10],
],
'weight' => 15,
],
],
@ -685,10 +568,6 @@ return [
['type' => 'weapon', 'name' => '妖骨剑', 'rate' => 15] + $weaponTemplate,
['type' => 'consume', 'name' => '妖丹', 'rate' => 40, 'heal' => 1000],
],
'spells' => [
['id' => 11, 'name' => '妖冰刃', 'rate' => 30],
['id' => 20, 'name' => '妖兽雹', 'rate' => 25],
],
'weight' => 50,
],
[
@ -705,11 +584,6 @@ return [
['type' => 'armor', 'name' => '雷鲸皮', 'rate' => 15] + $armorTemplate,
['type' => 'boots', 'name' => '风雷靴', 'rate' => 12] + $bootsTemplate,
],
'spells' => [
['id' => 12, 'name' => '雷鲸怒雷', 'rate' => 30],
['id' => 21, 'name' => '风暴洪流', 'rate' => 25],
['id' => 34, 'name' => '深海护盾', 'rate' => 20],
],
'weight' => 35,
],
[
@ -727,13 +601,6 @@ return [
['type' => 'armor', 'name' => '金蛟鳞甲', 'quality' => 'legendary', 'pdef' => 180, 'mdef' => 120, 'rate' => 15],
['type' => 'consume', 'name' => '九曲灵参', 'rate' => 10, 'heal' => 5000],
],
'spells' => [
['id' => 15, 'name' => '蛟龙狂暴', 'rate' => 30],
['id' => 25, 'name' => '雷风灭世', 'rate' => 25],
['id' => 33, 'name' => '龙王救赎', 'rate' => 20],
['id' => 35, 'name' => '蛟龙之力', 'rate' => 15],
['id' => 2, 'name' => '生命转移', 'rate' => 10],
],
'weight' => 15,
],
],
@ -760,10 +627,6 @@ return [
['type' => 'weapon', 'name' => '狼牙匕', 'rate' => 15] + $weaponTemplate,
['type' => 'consume', 'name' => '灵液', 'rate' => 30, 'heal' => 1200],
],
'spells' => [
['id' => 10, 'name' => '狼焰咆哮', 'rate' => 30],
['id' => 20, 'name' => '月光寒冰', 'rate' => 25],
],
'weight' => 50,
],
[
@ -780,11 +643,6 @@ return [
['type' => 'armor', 'name' => '长老法袍', 'rate' => 15] + $armorTemplate,
['type' => 'ring', 'name' => '长老戒', 'rate' => 12] + $ringTemplate,
],
'spells' => [
['id' => 13, 'name' => '长老烈焰', 'rate' => 30],
['id' => 22, 'name' => '宗门流星', 'rate' => 25],
['id' => 31, 'name' => '宗门护盾', 'rate' => 20],
],
'weight' => 35,
],
[
@ -802,13 +660,6 @@ return [
['type' => 'necklace', 'name' => '定魂珠', 'rate' => 15] + $necklaceTemplate,
['type' => 'consume', 'name' => '培婴丹', 'rate' => 25, 'heal' => 3000],
],
'spells' => [
['id' => 14, 'name' => '剑仙之意', 'rate' => 30],
['id' => 24, 'name' => '风云诀', 'rate' => 25],
['id' => 33, 'name' => '救赎之力', 'rate' => 20],
['id' => 2, 'name' => '生命同盟', 'rate' => 15],
['id' => 32, 'name' => '圣灵护佑', 'rate' => 10],
],
'weight' => 15,
],
],
@ -832,10 +683,6 @@ return [
['type' => 'weapon', 'name' => '魔魂刀', 'rate' => 15] + $weaponTemplate,
['type' => 'consume', 'name' => '魔髓钻', 'rate' => 20, 'heal' => 2000],
],
'spells' => [
['id' => 14, 'name' => '古魔剑意', 'rate' => 30],
['id' => 21, 'name' => '魔火爆裂', 'rate' => 25],
],
'weight' => 50,
],
[
@ -852,11 +699,6 @@ return [
['type' => 'armor', 'name' => '太乙银精甲', 'rate' => 15] + $armorTemplate,
['type' => 'boots', 'name' => '虚空靴', 'rate' => 12] + $bootsTemplate,
],
'spells' => [
['id' => 23, 'name' => '空间风暴', 'rate' => 30],
['id' => 35, 'name' => '虚空之力', 'rate' => 25],
['id' => 30, 'name' => '空间护盾', 'rate' => 20],
],
'weight' => 35,
],
[
@ -874,13 +716,6 @@ return [
['type' => 'armor', 'name' => '魔龙甲', 'quality' => 'legendary', 'pdef' => 350, 'mdef' => 250, 'rate' => 15],
['type' => 'consume', 'name' => '万年灵乳', 'rate' => 20, 'heal' => 8000],
],
'spells' => [
['id' => 15, 'name' => '古魔灭世', 'rate' => 30],
['id' => 25, 'name' => '狂风魔力', 'rate' => 25],
['id' => 34, 'name' => '古魔护盾', 'rate' => 20],
['id' => 35, 'name' => '魔界永恒', 'rate' => 15],
['id' => 4, 'name' => '魔泉生命', 'rate' => 10],
],
'weight' => 15,
],
],
@ -907,10 +742,6 @@ return [
['type' => 'weapon', 'name' => '晶砖', 'rate' => 15] + $weaponTemplate,
['type' => 'consume', 'name' => '灵烛果', 'rate' => 30, 'heal' => 3000],
],
'spells' => [
['id' => 13, 'name' => '晶体烈焰', 'rate' => 30],
['id' => 20, 'name' => '灵山冰雹', 'rate' => 25],
],
'weight' => 50,
],
[
@ -927,11 +758,6 @@ return [
['type' => 'armor', 'name' => '银翅甲', 'rate' => 15] + $armorTemplate,
['type' => 'necklace', 'name' => '夜叉链', 'rate' => 12] + $necklaceTemplate,
],
'spells' => [
['id' => 14, 'name' => '夜叉剑术', 'rate' => 30],
['id' => 23, 'name' => '虚空风暴', 'rate' => 25],
['id' => 35, 'name' => '天罚之力', 'rate' => 20],
],
'weight' => 35,
],
[
@ -949,13 +775,6 @@ return [
['type' => 'ring', 'name' => '雪晶珠', 'quality' => 'legendary', 'crit' => 15, 'rate' => 15],
['type' => 'consume', 'name' => '回阳水', 'rate' => 10, 'heal' => 10000],
],
'spells' => [
['id' => 15, 'name' => '元刹灭世', 'rate' => 30],
['id' => 25, 'name' => '永恒灭亡', 'rate' => 25],
['id' => 33, 'name' => '圣祖救赎', 'rate' => 20],
['id' => 34, 'name' => '永生护盾', 'rate' => 15],
['id' => 5, 'name' => '暴击疗愈', 'rate' => 10],
],
'weight' => 15,
],
],
@ -979,10 +798,6 @@ return [
['type' => 'weapon', 'name' => '虚空爪', 'rate' => 15] + $weaponTemplate,
['type' => 'boots', 'name' => '破空靴', 'rate' => 12] + $bootsTemplate,
],
'spells' => [
['id' => 12, 'name' => '虚空雷击', 'rate' => 30],
['id' => 20, 'name' => '虚空冰雹', 'rate' => 25],
],
'weight' => 50,
],
[
@ -999,11 +814,6 @@ return [
['type' => 'armor', 'name' => '风暴甲', 'rate' => 15] + $armorTemplate,
['type' => 'consume', 'name' => '空间晶石', 'rate' => 30, 'heal' => 5000],
],
'spells' => [
['id' => 23, 'name' => '灭世空间', 'rate' => 30],
['id' => 25, 'name' => '永恒风暴', 'rate' => 25],
['id' => 35, 'name' => '空间之力', 'rate' => 20],
],
'weight' => 35,
],
[
@ -1021,13 +831,6 @@ return [
['type' => 'armor', 'name' => '五行甲', 'quality' => 'legendary', 'pdef' => 1000, 'mdef' => 1000, 'rate' => 20],
['type' => 'consume', 'name' => '飞升令', 'rate' => 100, 'heal' => 99999], // 象征性物品
],
'spells' => [
['id' => 15, 'name' => '凤凰灭世', 'rate' => 30],
['id' => 25, 'name' => '冰凤风暴', 'rate' => 25],
['id' => 33, 'name' => '永恒救赎', 'rate' => 20],
['id' => 35, 'name' => '凤凰之力', 'rate' => 15],
['id' => 6, 'name' => '援护之术', 'rate' => 10],
],
'weight' => 15,
],
],

View File

@ -1,313 +1,138 @@
<?php
/**
* 法术系统配置 - 丰富版本
* 法术分为四类:单体治疗、单体伤害、群体伤害、群体治疗
* 每个法术有独立的计算方式和品质参数
* 参考装备的品质系统 (common, rare, epic, legendary)
* 法术系统配置
* 定义所有可用的法术及其属性
*/
return [
// ============ 单体治疗法术 (heal_single) ============
'heal_single' => [
// 1. 治愈术 - 魔攻型 (恢复 = 魔攻 × 倍数 + 基础值)
1 => [
'name' => '治愈术',
'type' => 'heal_single',
'calc_type' => 'matk', // 计算方式:纯魔攻
'cost' => 15,
'level_req' => 1,
'desc' => '恢复自己或队友的生命值,效果与魔攻相关',
// 品质参数:[common, rare, epic, legendary]
'heal_ratio' => [0.5, 0.8, 1.2, 1.8], // 魔攻倍数
'heal_base' => [20, 40, 70, 120], // 基础治疗值
],
// 2. 及时救难 - 生命值百分比型 (恢复 = 自己最大生命值 × 百分比)
2 => [
'name' => '及时救难',
'type' => 'heal_single',
'calc_type' => 'hp_percent', // 计算方式:最大生命值百分比
'cost' => 20,
'level_req' => 5,
'desc' => '将自己的部分生命值转移给队友',
'heal_ratio' => [0.3, 0.4, 0.5, 0.6], // 最大生命值百分比
],
// 3. 活力术 - 混合型 (恢复 = (魔攻 + 物攻) × 倍数 + 基础值)
3 => [
'name' => '活力术',
'type' => 'heal_single',
'calc_type' => 'hybrid', // 计算方式:魔攻 + 物攻混合
'cost' => 25,
'level_req' => 12,
'desc' => '结合物理和魔法的治疗法术',
'heal_ratio' => [0.3, 0.5, 0.7, 1.0], // (魔攻+物攻) 倍数
'heal_base' => [15, 30, 50, 80],
],
// 4. 生命之泉 - 基于当前生命值缺口 (恢复 = 缺失血量 × 百分比)
4 => [
'name' => '生命之泉',
'type' => 'heal_single',
'calc_type' => 'hp_missing', // 计算方式:缺失生命值百分比
'cost' => 30,
'level_req' => 18,
'desc' => '根据队友缺失的生命值比例进行治疗',
'heal_ratio' => [0.4, 0.55, 0.7, 0.85], // 缺失生命值百分比
],
// 5. 暴击治疗 - 与暴击率相关 (恢复 = 魔攻 × 倍数 × (1 + 暴击率×特殊系数))
5 => [
'name' => '暴击治疗',
'type' => 'heal_single',
'calc_type' => 'crit_heal', // 计算方式:与暴击率相关
'cost' => 28,
'level_req' => 22,
'desc' => '暴击率越高,治疗效果越强',
'heal_ratio' => [0.4, 0.65, 0.95, 1.4], // 基础魔攻倍数
'crit_bonus' => [0.5, 0.7, 1.0, 1.5], // 暴击率加成系数
],
// 6. 援护术 - 基于防御属性 (恢复 = (物防+魔防) × 倍数 + 固定值)
6 => [
'name' => '援护术',
'type' => 'heal_single',
'calc_type' => 'defense', // 计算方式:基于防御属性
'cost' => 22,
'level_req' => 15,
'desc' => '根据防御力进行治疗,防御越高效果越好',
'heal_ratio' => [0.8, 1.2, 1.8, 2.5], // (物防+魔防) 倍数
'heal_base' => [10, 20, 35, 60],
],
],
// ============ 单体伤害法术 (damage_single) ============
// 单体伤害法术
'damage_single' => [
// 10. 火球术 - 魔攻型 (伤害 = 魔攻 × 倍数)
10 => [
1 => [
'name' => '火球术',
'type' => 'damage_single',
'calc_type' => 'matk',
'quality' => 'common',
'cost' => 20,
'damage' => 1.2, // 伤害倍数 = 魔攻 * damage
'level_req' => 1,
'desc' => '发出一团火球,对单个敌人造成伤害',
'damage_ratio' => [1.2, 1.6, 2.0, 2.6],
'desc' => '发出一团火球,攻击单个敌人',
],
// 11. 冰锥术 - 魔攻型
11 => [
2 => [
'name' => '冰锥术',
'type' => 'damage_single',
'calc_type' => 'matk',
'cost' => 22,
'level_req' => 6,
'quality' => 'rare',
'cost' => 25,
'damage' => 1.3,
'level_req' => 5,
'desc' => '凝聚寒冰之力,发出锐利冰锥',
'damage_ratio' => [1.3, 1.8, 2.2, 3.0],
],
// 12. 雷击术 - 物攻型 (伤害 = 物攻 × 倍数)
12 => [
3 => [
'name' => '雷击术',
'type' => 'damage_single',
'calc_type' => 'patk',
'cost' => 24,
'quality' => 'rare',
'cost' => 30,
'damage' => 1.5,
'level_req' => 10,
'desc' => '召唤雷电直击单个敌人,与物攻相关',
'damage_ratio' => [1.4, 1.9, 2.3, 3.2],
'desc' => '召唤雷电直击单个敌人',
],
// 13. 烈焰焚天 - 混合型 (伤害 = (魔攻 + 物攻) × 倍数)
13 => [
4 => [
'name' => '烈焰焚天',
'type' => 'damage_single',
'calc_type' => 'hybrid',
'cost' => 35,
'level_req' => 18,
'desc' => '释放强大的火焰,伤害与双攻相关',
'damage_ratio' => [0.8, 1.1, 1.5, 2.0],
'quality' => 'epic',
'cost' => 45,
'damage' => 1.8,
'level_req' => 20,
'desc' => '释放强大的火焰,对单个敌人造成巨大伤害',
],
// 14. 诛仙剑气 - 物攻 + 暴击型 (伤害 = 物攻 × 倍数 × (1 + 暴击伤害系数))
14 => [
5 => [
'name' => '诛仙剑气',
'type' => 'damage_single',
'calc_type' => 'crit_damage',
'cost' => 40,
'level_req' => 28,
'desc' => '凝聚剑意,暴击伤害系数越高效果越强',
'damage_ratio' => [1.5, 2.0, 2.6, 3.5],
'crit_dmg_bonus' => [0.3, 0.5, 0.8, 1.2], // 暴击伤害加成系数
],
// 15. 狂暴斩 - 低防御有加成 (伤害 = 物攻 × 倍数 × (1 + (100-敌人防御百分比)×系数))
15 => [
'name' => '狂暴斩',
'type' => 'damage_single',
'calc_type' => 'low_def_bonus',
'cost' => 32,
'level_req' => 20,
'desc' => '攻击防御低的敌人伤害更高',
'damage_ratio' => [1.1, 1.5, 2.0, 2.7],
'quality' => 'legendary',
'cost' => 60,
'damage' => 2.2,
'level_req' => 35,
'desc' => '凝聚剑意,发出致命一击',
],
],
// ============ 群体伤害法术 (damage_aoe) ============
// AOE伤害法术
'damage_aoe' => [
// 20. 冰雹术 - 魔攻型 (每敌伤害 = 魔攻 × 倍数)
20 => [
10 => [
'name' => '冰雹术',
'type' => 'damage_aoe',
'calc_type' => 'matk',
'quality' => 'common',
'cost' => 35,
'level_req' => 5,
'damage' => 0.8, // 对每个敌人的伤害倍数较低,但打全体
'level_req' => 8,
'desc' => '召唤冰雹,攻击所有敌人',
'damage_ratio' => [0.7, 1.0, 1.3, 1.7],
],
// 21. 炎爆术 - 魔攻型,随敌人数量加成
21 => [
11 => [
'name' => '炎爆术',
'type' => 'damage_aoe',
'calc_type' => 'matk_scaled',
'cost' => 40,
'level_req' => 12,
'desc' => '引发连锁爆炸,敌人越多伤害加成越高',
'damage_ratio' => [0.8, 1.1, 1.4, 1.9],
'enemy_count_bonus' => [0.1, 0.15, 0.2, 0.3], // 每增加一个敌人增加的伤害百分比
'quality' => 'rare',
'cost' => 45,
'damage' => 0.95,
'level_req' => 15,
'desc' => '引发连锁爆炸,对所有敌人造成伤害',
],
// 22. 流星雨 - 混合型 (每敌伤害 = (魔攻 + 物攻) × 倍数)
22 => [
12 => [
'name' => '流星雨',
'type' => 'damage_aoe',
'calc_type' => 'hybrid',
'cost' => 50,
'level_req' => 20,
'quality' => 'epic',
'cost' => 60,
'damage' => 1.1,
'level_req' => 25,
'desc' => '召唤流星坠落,轰击全体敌人',
'damage_ratio' => [0.6, 0.85, 1.15, 1.55],
],
// 23. 灭世风暴 - 基于暴击率 (每敌伤害 = 魔攻 × 倍数 × (1 + 暴击率×系数))
23 => [
13 => [
'name' => '灭世风暴',
'type' => 'damage_aoe',
'calc_type' => 'crit_aoe',
'cost' => 60,
'level_req' => 30,
'desc' => '引发天地异变,暴击率影响范围伤害',
'damage_ratio' => [0.9, 1.2, 1.6, 2.2],
'crit_bonus' => [0.4, 0.6, 0.9, 1.3],
],
// 24. 末日火雨 - 敌人越多伤害越低,但每个敌人都会受伤
24 => [
'name' => '末日火雨',
'type' => 'damage_aoe',
'calc_type' => 'dispersed_damage',
'cost' => 55,
'level_req' => 25,
'desc' => '魔法能量分散到所有敌人,敌人越多分散越严重',
'damage_ratio' => [1.8, 2.5, 3.2, 4.0],
'dispersion' => [0.8, 0.75, 0.7, 0.65], // 随敌人数量衰减系数
],
// 25. 狂风斩 - 基于物攻 (每敌伤害 = 物攻 × 倍数)
25 => [
'name' => '狂风斩',
'type' => 'damage_aoe',
'calc_type' => 'patk',
'cost' => 45,
'level_req' => 16,
'desc' => '挥出狂暴的风刃,基于物攻伤害',
'damage_ratio' => [0.9, 1.2, 1.6, 2.1],
'quality' => 'legendary',
'cost' => 80,
'damage' => 1.3,
'level_req' => 40,
'desc' => '引发天地异变,对所有敌人造成毁灭性伤害',
],
],
// ============ 群体治疗法术 (heal_aoe) ============
'heal_aoe' => [
// 30. 神圣庇护 - 魔攻型 (每人恢复 = 魔攻 × 倍数 + 基础值)
30 => [
// 辅助法术(恢复、增益)
'support' => [
20 => [
'name' => '治愈术',
'type' => 'support',
'subtype' => 'heal',
'quality' => 'common',
'cost' => 15,
'heal' => 0.5, // 恢复量倍数 = 魔攻 * heal + 基础值
'heal_base' => 20,
'level_req' => 3,
'desc' => '恢复自己或队友的生命值',
],
21 => [
'name' => '神圣庇护',
'type' => 'heal_aoe',
'calc_type' => 'matk',
'cost' => 30,
'level_req' => 8,
'desc' => '为所有队员增加防护,恢复生命值',
'heal_ratio' => [0.3, 0.5, 0.75, 1.0],
'heal_base' => [15, 30, 50, 75],
'type' => 'support',
'subtype' => 'defend',
'quality' => 'rare',
'cost' => 25,
'defense_boost' => 30, // 增加固定防御值
'duration' => 3, // 持续回合数(如果支持的话)
'level_req' => 12,
'desc' => '增加自己或队友的防御力',
],
// 31. 恢复光环 - 生命值百分比型 (每人恢复 = 自己最大生命值 × 百分比)
31 => [
22 => [
'name' => '恢复光环',
'type' => 'heal_aoe',
'calc_type' => 'hp_percent',
'cost' => 35,
'level_req' => 14,
'desc' => '释放温暖的光芒,基于自己的最大生命值恢复队员',
'heal_ratio' => [0.2, 0.3, 0.4, 0.5],
],
// 32. 圣灵之力 - 混合型 (每人恢复 = (魔攻 + 物攻) × 倍数)
32 => [
'name' => '圣灵之力',
'type' => 'heal_aoe',
'calc_type' => 'hybrid',
'cost' => 45,
'level_req' => 22,
'desc' => '强大的群体治疗,恢复所有队员',
'heal_ratio' => [0.25, 0.4, 0.6, 0.85],
'heal_base' => [10, 20, 35, 55],
],
// 33. 仙界救赎 - 智能治疗(优先治疗血量少的队员)
33 => [
'name' => '仙界救赎',
'type' => 'heal_aoe',
'calc_type' => 'smart_heal',
'cost' => 55,
'level_req' => 32,
'desc' => '至高的救赎之力,优先治疗血量较低的队员',
'heal_ratio' => [0.4, 0.6, 0.9, 1.3],
'heal_base' => [25, 45, 70, 110],
'priority_bonus' => [0.2, 0.3, 0.4, 0.5], // 血量越少加成越多
],
// 34. 护盾术 - 基于防御属性 (每人恢复 = (物防+魔防) × 倍数)
34 => [
'name' => '护盾术',
'type' => 'heal_aoe',
'calc_type' => 'defense',
'cost' => 40,
'level_req' => 18,
'desc' => '根据防御力为队员恢复生命值',
'heal_ratio' => [0.5, 0.75, 1.1, 1.5],
'heal_base' => [8, 16, 28, 45],
],
// 35. 团队共鸣 - 基于队伍状态 (每人恢复 = 魔攻 × 倍数 × (队员数量系数))
35 => [
'name' => '团队共鸣',
'type' => 'heal_aoe',
'calc_type' => 'team_sync',
'cost' => 38,
'level_req' => 20,
'desc' => '队员越多,治疗效果越强',
'heal_ratio' => [0.35, 0.55, 0.8, 1.1],
'team_bonus' => [0.2, 0.3, 0.45, 0.6], // 每增加一个队员增加的治疗百分比
'type' => 'support',
'subtype' => 'heal_all',
'quality' => 'epic',
'cost' => 50,
'heal' => 0.6,
'heal_base' => 40,
'level_req' => 30,
'desc' => '为所有队员恢复生命值',
],
],
// ============ 品质掉落概率 ============
'quality_drop_rates' => [
'common' => 70, // 普通法术 70% 掉落概率
'rare' => 20, // 稀有法术 20% 掉落概率
'epic' => 8, // 史诗法术 8% 掉落概率
'legendary' => 2, // 传奇法术 2% 掉落概率
],
// ============ 法术品质对应的学习资源书数量 ============
// 法术品质对应的学习资源书数量
'quality_levels' => [
'common' => 1, // 普通资源书可学习普通法术
'rare' => 2, // 稀有资源书可学习稀有法术
@ -315,59 +140,32 @@ return [
'legendary' => 4, // 传奇资源书可学习传奇法术
],
// ============ 法术升级系统 ============
// 法术升级系统
'upgrades' => [
// 每个等级需要的资源书数量和属性提升
1 => ['cost' => 0, 'bonus' => 0, 'cost_reduction' => 0],
2 => ['cost' => 2, 'bonus' => 10, 'cost_reduction' => 2],
3 => ['cost' => 3, 'bonus' => 20, 'cost_reduction' => 4],
4 => ['cost' => 4, 'bonus' => 30, 'cost_reduction' => 6],
5 => ['cost' => 5, 'bonus' => 40, 'cost_reduction' => 8],
6 => ['cost' => 6, 'bonus' => 50, 'cost_reduction' => 10],
7 => ['cost' => 8, 'bonus' => 60, 'cost_reduction' => 12],
8 => ['cost' => 10, 'bonus' => 70, 'cost_reduction' => 14],
9 => ['cost' => 12, 'bonus' => 80, 'cost_reduction' => 16],
10 => ['cost' => 15, 'bonus' => 100, 'cost_reduction' => 20],
// level => ['cost' => 资源书数量, 'damage_bonus' => 伤害加成%, 'cost_reduction' => 消耗减少]
1 => ['cost' => 0, 'damage_bonus' => 0, 'cost_reduction' => 0],
2 => ['cost' => 2, 'damage_bonus' => 10, 'cost_reduction' => 2],
3 => ['cost' => 3, 'damage_bonus' => 20, 'cost_reduction' => 4],
4 => ['cost' => 4, 'damage_bonus' => 30, 'cost_reduction' => 6],
5 => ['cost' => 5, 'damage_bonus' => 40, 'cost_reduction' => 8],
6 => ['cost' => 6, 'damage_bonus' => 50, 'cost_reduction' => 10],
7 => ['cost' => 8, 'damage_bonus' => 60, 'cost_reduction' => 12],
8 => ['cost' => 10, 'damage_bonus' => 70, 'cost_reduction' => 14],
9 => ['cost' => 12, 'damage_bonus' => 80, 'cost_reduction' => 16],
10 => ['cost' => 15, 'damage_bonus' => 100, 'cost_reduction' => 20],
],
// ============ 地牢法术掉落映射 ============
// 地牢法术掉落映射 - 定义各地牢的法术资源书掉落池
'dungeon_spell_drops' => [
1 => ['heal_single', 'damage_single', 'damage_aoe'], // 七玄门 (Lv.1-5)
2 => ['damage_single', 'damage_aoe', 'heal_aoe'], // 太南谷 (Lv.5-10)
3 => ['heal_single', 'heal_aoe'], // 血色禁地 (Lv.10-15)
4 => ['damage_single', 'damage_aoe'], // 黄枫谷 (Lv.15-20)
5 => ['damage_single', 'heal_aoe'], // 燕翎堡 (Lv.20-30)
6 => ['damage_single', 'heal_aoe'], // 越京皇宫 (Lv.30-40)
7 => ['damage_aoe'], // 乱星海-魁星岛 (Lv.40-50)
8 => ['damage_aoe', 'heal_single', 'heal_aoe'], // 虚天殿 (Lv.50-60)
9 => ['damage_single', 'damage_aoe', 'heal_single'], // 外星海 (Lv.60+)
],
// ============ 按法术类型和品质分类 ============
'spells_by_quality' => [
'common' => [
'heal_single' => [1],
'damage_single' => [10],
'damage_aoe' => [20],
'heal_aoe' => [30],
],
'rare' => [
'heal_single' => [2, 3],
'damage_single' => [11, 12],
'damage_aoe' => [21, 22],
'heal_aoe' => [31, 32],
],
'epic' => [
'heal_single' => [4, 5],
'damage_single' => [13, 14],
'damage_aoe' => [23, 24],
'heal_aoe' => [33, 34],
],
'legendary' => [
'heal_single' => [6],
'damage_single' => [15],
'damage_aoe' => [25],
'heal_aoe' => [35],
],
1 => [1, 10], // 七玄门 (Lv.1-5): 火球术、冰雹术
2 => [2, 3, 11], // 太南谷 (Lv.5-10): 冰锥术、雷击术、炎爆术
3 => [20, 21], // 血色禁地 (Lv.10-15): 治愈术、神圣庇护
4 => [12], // 黄枫谷 (Lv.15-20): 流星雨
5 => [4], // 燕翎堡 (Lv.20-30): 烈焰焚天
6 => [5, 22], // 越京皇宫 (Lv.30-40): 诛仙剑气、恢复光环
7 => [13], // 乱星海-魁星岛 (Lv.40-50): 灭世风暴
8 => [13, 22], // 虚天殿 (Lv.50-60): 灭世风暴、恢复光环
9 => [5, 13], // 外星海 (Lv.60+): 诛仙剑气、灭世风暴
],
];

View File

@ -9,17 +9,17 @@ class Actor
public int $exp = 0;
public int $maxExp = 100;
public int $hp = 100;
public int $maxHp = 100;
public int $patk = 10;
public int $matk = 10;
public int $pdef = 10;
public int $mdef = 10;
public int $hp = 0;
public int $maxHp = 0;
public int $patk = 0;
public int $matk = 0;
public int $pdef = 0;
public int $mdef = 0;
public int $crit = 0;
public float $critdmg = 110.0;
public int $mana = 100;
public int $maxMana = 100;
public int $mana = 0;
public int $maxMana = 0;
// 技能槽位系统 (新法术系统)
public array $skillSlots = [

View File

@ -87,6 +87,9 @@ class Item
$growth = $typeConfig['growth'] ?? 0;
$item->heal = $baseStats[$qualityIndex] + ($level * $growth) + rand(0, 10);
$item->desc = "Lv.{$level} {$quality}品质的药剂";
} elseif ($type === 'spell_tome') {
// 法术资源书特殊处理
$item->desc = "Lv.{$level} {$quality}品质的法术资源书";
} else {
// 检查是否有特定物品配置
$specificConfig = $typeConfig['specific_config'][$item->name] ?? [];
@ -234,13 +237,12 @@ class Item
}
/**
* 创建法术物品 - 支持新的丰富法术系统
* @param int $spellId 法术ID
* @param string $quality 品质 (common, rare, epic, legendary)
* 创建法术物品
* @param int $spellId 法术ID (来自 spells.php)
* @param int $level 物品等级
* @return array 法术物品数组
*/
public static function createSpell(int $spellId, string $quality = 'common', int $level = 1): array
public static function createSpell(int $spellId, int $level = 1): array
{
static $spellsData = null;
if ($spellsData === null) {
@ -250,7 +252,7 @@ class Item
// 查找法术信息
$spellInfo = null;
foreach ($spellsData as $category => $spells) {
if (is_array($spells) && !in_array($category, ['quality_levels', 'upgrades', 'dungeon_spell_drops', 'quality_drop_rates', 'spells_by_quality'])) {
if (is_array($spells) && $category !== 'quality_levels' && $category !== 'upgrades' && $category !== 'dungeon_spell_drops') {
if (isset($spells[$spellId])) {
$spellInfo = $spells[$spellId];
break;
@ -264,60 +266,33 @@ class Item
'id' => uniqid('spell_'),
'type' => 'spell',
'name' => '未知法术',
'quality' => $quality,
'quality' => 'common',
'level' => $level,
'spellId' => $spellId,
'enhanceLevel' => 0,
'calc_type' => 'matk',
'damage' => 1.0,
'cost' => 20,
'spellType' => 'damage_single',
'desc' => '未知的法术',
];
}
// 品质映射到数组索引 (common=0, rare=1, epic=2, legendary=3)
$qualityIndex = match($quality) {
'common' => 0,
'rare' => 1,
'epic' => 2,
'legendary' => 3,
default => 0,
};
// 提取品质相关的参数
$healRatio = $spellInfo['heal_ratio'][$qualityIndex] ?? ($spellInfo['heal_ratio'][0] ?? 0);
$damageRatio = $spellInfo['damage_ratio'][$qualityIndex] ?? ($spellInfo['damage_ratio'][0] ?? 1.0);
$healBase = $spellInfo['heal_base'][$qualityIndex] ?? ($spellInfo['heal_base'][0] ?? 0);
$critBonus = $spellInfo['crit_bonus'][$qualityIndex] ?? ($spellInfo['crit_bonus'][0] ?? 0);
$critDmgBonus = $spellInfo['crit_dmg_bonus'][$qualityIndex] ?? ($spellInfo['crit_dmg_bonus'][0] ?? 0);
$enemyCountBonus = $spellInfo['enemy_count_bonus'][$qualityIndex] ?? ($spellInfo['enemy_count_bonus'][0] ?? 0);
$dispersion = $spellInfo['dispersion'][$qualityIndex] ?? ($spellInfo['dispersion'][0] ?? 1.0);
$teamBonus = $spellInfo['team_bonus'][$qualityIndex] ?? ($spellInfo['team_bonus'][0] ?? 0);
$priorityBonus = $spellInfo['priority_bonus'][$qualityIndex] ?? ($spellInfo['priority_bonus'][0] ?? 0);
return [
'id' => uniqid('spell_'),
'type' => 'spell',
'name' => $spellInfo['name'],
'quality' => $quality,
'quality' => $spellInfo['quality'] ?? 'common',
'level' => $level,
'spellId' => $spellId,
'enhanceLevel' => 0,
'calc_type' => $spellInfo['calc_type'] ?? 'matk',
'damage' => $spellInfo['damage'] ?? 1.0,
'cost' => $spellInfo['cost'] ?? 20,
'spellType' => $spellInfo['type'] ?? 'damage_single',
'subtype' => $spellInfo['subtype'] ?? null,
'heal' => $spellInfo['heal'] ?? 0,
'heal_base' => $spellInfo['heal_base'] ?? 0,
'defense_boost' => $spellInfo['defense_boost'] ?? 0,
'desc' => $spellInfo['desc'] ?? '',
// 品质参数
'heal_ratio' => $healRatio,
'damage_ratio' => $damageRatio,
'heal_base' => $healBase,
'crit_bonus' => $critBonus,
'crit_dmg_bonus' => $critDmgBonus,
'enemy_count_bonus' => $enemyCountBonus,
'dispersion' => $dispersion,
'team_bonus' => $teamBonus,
'priority_bonus' => $priorityBonus,
];
}

View File

@ -17,9 +17,6 @@ class Monster extends Actor
// Monster特有的掉落表
public array $dropTable = [];
// Monster穿着的法术类似 $equip
public array $spells = [];
public static function create(int $dungeonId): self
{
// Load data
@ -149,7 +146,7 @@ class Monster extends Actor
// 根据等级和基础属性分配天赋点
$this->allocateTalentsByLevel();
// Drops & Equipment & Spells
// Drops & Equipment
$drops = $config['drops'] ?? [];
foreach ($drops as $drop) {
$type = $drop['type'] ?? '';
@ -165,6 +162,47 @@ class Monster extends Actor
];
continue;
}
if ($type === 'spell') {
// Chance to include this spell tome in drop table
if (rand(1, 100) > $rate) continue;
// spell drop spec should include 'spell_id' (or 'id') to identify the spell
$spellId = $drop['spell_id'] ?? ($drop['id'] ?? null);
if ($spellId !== null) {
static $spellsData = null;
if ($spellsData === null) {
$spellsData = require __DIR__ . '/../../src/Data/spells.php';
}
$spellInfo = null;
foreach ($spellsData as $cat => $list) {
if (!is_array($list) || in_array($cat, ['quality_levels','upgrades'])) continue;
if (isset($list[$spellId])) { $spellInfo = $list[$spellId]; break; }
}
// Scale tome level by monster level (e.g., level tiers of 5)
$tomeLevel = max(1, min(10, (int)ceil($this->level / 5)));
$tome = [
'name' => ($spellInfo['name'] ?? ('法术#' . $spellId)) . '的法术书',
'type' => 'spell_tome',
'quality' => $spellInfo['quality'] ?? ($drop['quality'] ?? 'common'),
'level' => $tomeLevel,
'spell_id' => $spellId,
'spell_name' => $spellInfo['name'] ?? null,
'desc' => $drop['desc'] ?? ('能够学习或提升 ' . ($spellInfo['name'] ?? '未知法术')),
];
// Add to drop table with given rate
$this->dropTable[] = [
'item' => $tome,
'rate' => $rate,
];
}
continue;
}
if (in_array($type, ['weapon', 'armor', 'boots', 'ring', 'necklace'])) {
if (rand(1, 100) > $rate) continue;
$spec = $drop;
@ -174,73 +212,46 @@ class Monster extends Actor
}
}
// 为怪物配置法术
$this->generateSpells($config);
$this->applyEquipmentStats();
}
/**
* 为怪物随机生成法术(穿着法术,类似装备)
* 配置示例 1: 'spells' => [1, 3, 10] - 随机从这些法术ID中选择
* 配置示例 2: 'spells' => [
* ['id' => 1, 'name' => '治愈术'],
* ['id' => 10, 'name' => '火焰术'],
* ['id' => 30, 'name' => '防御法术'],
* ] - 为怪物分配具体的法术(可选指定名称)
* 应用装备属性加成到怪物属性
*/
private function generateSpells(array $config): void
// Monster-specific application of equipment is handled by Actor::getStats; applyEquipmentStats remains for legacy callers
public function applyEquipmentStats(): void
{
$spellConfigs = $config['spells'] ?? [];
$this->hp = $this->baseHp;
$this->patk = $this->basePatk;
$this->matk = $this->baseMatk;
$this->pdef = $this->basePdef;
$this->mdef = $this->baseMdef;
if (empty($spellConfigs)) {
return;
foreach ($this->equip as $item) {
if (empty($item)) continue;
$this->hp += $item['hp'] ?? 0;
$this->patk += $item['patk'] ?? $item['atk'] ?? 0;
$this->matk += $item['matk'] ?? 0;
$this->pdef += $item['pdef'] ?? $item['def'] ?? 0;
$this->mdef += $item['mdef'] ?? 0;
$this->crit += $item['crit'] ?? 0;
$this->critdmg += $item['critdmg'] ?? 0;
}
}
static $spellsData = null;
if ($spellsData === null) {
$spellsData = require __DIR__ . '/../../src/Data/spells.php';
}
// 处理两种配置格式
$selectedSpells = [];
// 格式2: 配置数组 [['id' => 1, 'name' => '治愈术', 'rate' => 30]]
foreach ($spellConfigs as $spellConfig) {
if (is_array($spellConfig) && isset($spellConfig['id'])) {
$selectedSpells[] = [
'id' => $spellConfig['id'],
'name' => $spellConfig['name'] ?? null,
'rate' => $spellConfig['rate'] ?? 30, // 默认30%掉落概率
];
/**
* 获取怪物装备的物品列表(用于战斗胜利时掉落)
* @return array
*/
public function getEquippedItems(): array
{
$items = [];
foreach ($this->equip as $item) {
if (!empty($item)) {
$items[] = $item;
}
}
foreach ($selectedSpells as $spellConfig) {
$spellId = $spellConfig['id'];
$customName = $spellConfig['name'] ?? null;
$dropRate = $spellConfig['rate'] ?? 30;
// 随机决定法术品质70% 普通, 20% 稀有, 8% 史诗, 2% 传奇
$roll = rand(1, 100);
if ($roll <= 70) $quality = 'common';
elseif ($roll <= 90) $quality = 'rare';
elseif ($roll <= 98) $quality = 'epic';
else $quality = 'legendary';
// 创建法术物品
$spell = Item::createSpell($spellId, $quality, $this->level);
// 如果提供了自定义名称,则覆盖默认名称
if ($customName) {
$spell['name'] = $customName;
}
// 添加掉落概率信息到法术对象
$spell['dropRate'] = $dropRate;
// 存储到 spells 数组
$this->spells[] = $spell;
}
return $items;
}
/**
@ -262,29 +273,6 @@ class Monster extends Actor
return $drops;
}
/**
* 随机掉落法术(从穿着的法术随机掉落)
* 使用每个法术配置的掉落概率,如果未指定则使用默认值
* @param int $defaultRate 默认掉落概率0-100当法术未指定rate时使用
* @return array 掉落的法术列表
*/
public function getRandomSpellDrops(int $defaultRate = 50): array
{
$drops = [];
foreach ($this->spells as $spell) {
if (!empty($spell)) {
// 优先使用法术配置的掉落概率,否则使用默认值
$spellDropRate = $spell['dropRate'] ?? $defaultRate;
// 每个法术有独立的掉落概率
if (rand(1, 100) <= $spellDropRate) {
$drops[] = $spell;
}
}
}
return $drops;
}
/**
* 根据等级和基础属性分配天赋点和权重
* 怪物根据等级获得天赋点,并按基础属性的占比分配权重

View File

@ -56,7 +56,8 @@ class Player extends Actor
$this->exp -= $this->maxExp;
$this->maxExp = (int)($this->maxExp * 1.5);
$this->talentPoints += 3;
// 升级获得天赋点每级3点并通过 autoAllocateTalents 自动分配
$this->autoAllocateTalents(3);
// 升级时恢复全部生命值
$this->fullHeal();

View File

@ -5,7 +5,6 @@ use Game\Core\Game;
use Game\Core\Input;
use Game\Core\Screen;
use Game\Core\ItemDisplay;
use Game\Core\SpellDisplay;
use Game\Core\Colors;
use Game\Entities\Player;
use Game\Entities\Actor;
@ -388,7 +387,7 @@ class Battle
// 消耗魔法值
$this->player->spendMana($actualCost);
// 计算强化加成: 每级 +5% 伤害或治疗
// 计算强化加成: 每级 +5% 伤害
$damageBonus = $enhanceLevel * 5;
$type = $spellItem['spellType'] ?? 'damage_single';
@ -402,12 +401,7 @@ class Battle
return $this->castDamageSingleSpell($out, 0, $spellInfo, $stats, $damageBonus, $name);
} elseif ($type === 'damage_aoe') {
return $this->castDamageAoeSpell($out, 0, $spellInfo, $stats, $damageBonus, $name);
} elseif ($type === 'heal_single') {
return $this->castHealSingleSpell($out, $spellInfo, $stats, $damageBonus, $name);
} elseif ($type === 'heal_aoe') {
return $this->castHealAoeSpell($out, $spellInfo, $stats, $damageBonus, $name);
} elseif ($type === 'support') {
// 兼容旧版本的 support 类型
return $this->castSupportSpell($out, $spellInfo, $stats, $name);
}
@ -430,16 +424,8 @@ class Battle
if (!$target) return true;
// 显示法术基础信息
$calcType = $spellInfo['calc_type'] ?? 'matk';
$calcDesc = SpellDisplay::getCalcTypeDescription($calcType);
$cost = $spellInfo['cost'] ?? 20;
$actualCost = max(1, $cost - (($spellInfo['enhanceLevel'] ?? 0) * 2));
$quality = $spellInfo['quality'] ?? 'common';
$qualityColor = SpellDisplay::getQualityColor($quality);
// 计算法术伤害
$baseDamageMultiplier = $spellInfo['damage_ratio'][$this->getQualityIndex($quality)] ?? ($spellInfo['damage'] ?? 1.0);
$baseDamageMultiplier = $spellInfo['damage'] ?? 1.0;
$actualDamageMultiplier = $baseDamageMultiplier * (1 + $damageBonus / 100);
$baseDamage = (int)($stats['matk'] * $actualDamageMultiplier);
@ -451,16 +437,14 @@ class Battle
$critRate = $stats['crit'];
$isCrit = rand(1, 100) <= $critRate;
// 显示法术施放信息
$out->writeln("{$this->cyan}{$this->reset} {$this->magenta}{$this->reset} 你施放 {$qualityColor}{$name}{$this->reset}");
$out->writeln("{$this->cyan}{$this->reset} {$this->white}计算方式: {$calcDesc} | 消耗: {$actualCost} | 倍数: {$baseDamageMultiplier}x{$this->reset}");
if ($isCrit) {
$critDmg = $stats['critdmg'];
$damage = (int)($damage * ($critDmg / 100));
$out->writeln("{$this->cyan}{$this->reset} {$this->magenta}{$this->red}{$this->bold}暴击!{$this->reset} 造成 {$this->red}{$damage}{$this->reset} 点魔法伤害!");
$out->writeln("{$this->cyan}{$this->reset} {$this->magenta}{$this->reset} 你施放 {$name}... {$this->red}{$this->bold}暴击!{$this->reset}");
$out->writeln("{$this->cyan}{$this->reset} {$this->magenta}✨ 造成 {$damage} 点魔法伤害!{$this->reset}");
} else {
$out->writeln("{$this->cyan}{$this->reset} {$this->magenta}✨ 造成 {$this->green}{$damage}{$this->reset} 点魔法伤害");
$out->writeln("{$this->cyan}{$this->reset} {$this->magenta}{$this->reset} 你施放 {$name}...");
$out->writeln("{$this->cyan}{$this->reset} {$this->magenta}✨ 造成 {$damage} 点魔法伤害{$this->reset}");
}
$target->hp -= $damage;
@ -484,20 +468,11 @@ class Battle
*/
private function castDamageAoeSpell($out, int $spellId, array $spellInfo, array $stats, int $damageBonus, string $name): bool
{
// 显示法术基础信息
$calcType = $spellInfo['calc_type'] ?? 'matk';
$calcDesc = SpellDisplay::getCalcTypeDescription($calcType);
$cost = $spellInfo['cost'] ?? 20;
$actualCost = max(1, $cost - (($spellInfo['enhanceLevel'] ?? 0) * 2));
$quality = $spellInfo['quality'] ?? 'common';
$qualityColor = SpellDisplay::getQualityColor($quality);
$out->writeln("{$this->cyan}{$this->reset} {$this->magenta}{$this->reset} 你施放 {$qualityColor}{$name}{$this->reset}");
$out->writeln("{$this->cyan}{$this->reset} {$this->white}计算方式: {$calcDesc} | 消耗: {$actualCost}{$this->reset}");
$out->writeln("{$this->cyan}{$this->reset} {$this->magenta}{$this->reset} 你施放 {$name}...");
$out->writeln("{$this->cyan}{$this->reset} {$this->magenta}✨ 魔法在整个战场爆炸!{$this->reset}");
// 计算法术伤害
$baseDamageMultiplier = $spellInfo['damage_ratio'][$this->getQualityIndex($quality)] ?? ($spellInfo['damage'] ?? 0.8);
$baseDamageMultiplier = $spellInfo['damage'] ?? 0.8;
$actualDamageMultiplier = $baseDamageMultiplier * (1 + $damageBonus / 100);
$allEnemiesDefeated = true;
@ -536,90 +511,13 @@ class Battle
return false;
}
/**
* 施放单体治疗法术
*/
private function castHealSingleSpell($out, array $spellInfo, array $stats, int $healBonus, string $name): bool
{
// 显示法术基础信息
$calcType = $spellInfo['calc_type'] ?? 'matk';
$calcDesc = SpellDisplay::getCalcTypeDescription($calcType);
$cost = $spellInfo['cost'] ?? 20;
$quality = $spellInfo['quality'] ?? 'common';
$qualityColor = SpellDisplay::getQualityColor($quality);
$actualCost = max(1, $cost - (($spellInfo['enhanceLevel'] ?? 0) * 2));
$out->writeln("{$this->cyan}{$this->reset} {$this->green}{$this->reset} 你施放 {$qualityColor}{$name}{$this->reset}");
$out->writeln("{$this->cyan}{$this->reset} {$this->white}计算方式: {$calcDesc} | 消耗: {$actualCost}{$this->reset}");
$heal = $spellInfo['heal'] ?? 0.5;
$healBase = $spellInfo['heal_base'] ?? 20;
$healAmount = (int)($stats['matk'] * $heal + $healBase);
// 应用治疗加成
$healAmount = (int)($healAmount * (1 + $healBonus / 100));
$actualHeal = $this->player->heal($healAmount);
$out->writeln("{$this->cyan}{$this->reset} {$this->green}💚 恢复了 {$actualHeal} 点生命值{$this->reset}");
return false;
}
/**
* 施放群体治疗法术
*/
private function castHealAoeSpell($out, array $spellInfo, array $stats, int $healBonus, string $name): bool
{
// 显示法术基础信息
$calcType = $spellInfo['calc_type'] ?? 'matk';
$calcDesc = SpellDisplay::getCalcTypeDescription($calcType);
$cost = $spellInfo['cost'] ?? 20;
$quality = $spellInfo['quality'] ?? 'common';
$qualityColor = SpellDisplay::getQualityColor($quality);
$actualCost = max(1, $cost - (($spellInfo['enhanceLevel'] ?? 0) * 2));
$out->writeln("{$this->cyan}{$this->reset} {$this->green}{$this->reset} 你施放 {$qualityColor}{$name}{$this->reset}");
$out->writeln("{$this->cyan}{$this->reset} {$this->white}计算方式: {$calcDesc} | 消耗: {$actualCost}{$this->reset}");
$heal = $spellInfo['heal'] ?? 0.5;
$healBase = $spellInfo['heal_base'] ?? 20;
$healAmount = (int)($stats['matk'] * $heal + $healBase);
// 应用治疗加成
$healAmount = (int)($healAmount * (1 + $healBonus / 100));
$actualHeal = $this->player->heal($healAmount);
$out->writeln("{$this->cyan}{$this->reset} {$this->green}💚 你恢复了 {$actualHeal} 点生命值{$this->reset}");
// 同伴也恢复
$alivePartners = $this->getAlivePartners();
foreach ($alivePartners as $partner) {
$partnerHeal = (int)($healAmount * 0.8); // 同伴恢复量为玩家的80%
$actualPartnerHeal = $partner->heal($partnerHeal);
$this->partnerHp[$partner->id] = $partner->hp;
$out->writeln("{$this->cyan}{$this->reset} {$this->green}💚 {$partner->name} 恢复了 {$actualPartnerHeal} 点生命值{$this->reset}");
}
return false;
}
/**
* 施放辅助法术
*/
private function castSupportSpell($out, array $spellInfo, array $stats, string $name): bool
{
// 显示法术基础信息
$quality = $spellInfo['quality'] ?? 'common';
$qualityColor = SpellDisplay::getQualityColor($quality);
$cost = $spellInfo['cost'] ?? 20;
$actualCost = max(1, $cost - (($spellInfo['enhanceLevel'] ?? 0) * 2));
$out->writeln("{$this->cyan}{$this->reset} {$this->cyan}{$this->reset} 你施放 {$qualityColor}{$name}{$this->reset}");
$out->writeln("{$this->cyan}{$this->reset} {$this->white}消耗: {$actualCost}{$this->reset}");
$subtype = $spellInfo['subtype'] ?? '';
if ($subtype === 'heal' || $subtype === 'heal_all') {
if ($subtype === 'heal') {
// 恢复自己
@ -726,17 +624,35 @@ class Battle
}
/**
* 根据品质获取数组索引
* 生成法术物品掉落 (新法术系统)
*/
private function getQualityIndex(string $quality): int
private function generateSpellDrop(Actor $enemy): ?array
{
return match($quality) {
'common' => 0,
'rare' => 1,
'epic' => 2,
'legendary' => 3,
default => 0,
};
// 尝试从独立的副本法术映射文件获取(每个副本有自己的法术池)
$dungeonId = $this->game->dungeonId;
$spellIds = null;
$dungeonSpellFile = __DIR__ . '/../../src/Data/dungeon_spells.php';
if (file_exists($dungeonSpellFile)) {
$dungeonMap = require $dungeonSpellFile;
$spellIds = $dungeonMap[$dungeonId] ?? null;
}
// 回退到全局配置里的 dungeon_spell_drops
if (empty($spellIds)) {
$dungeonSpellDrops = $this->spellsData['dungeon_spell_drops'] ?? [];
$spellIds = $dungeonSpellDrops[$dungeonId] ?? null;
}
if (empty($spellIds) || !is_array($spellIds)) {
return null;
}
// 从法术池中随机选择一个法术ID
$spellId = $spellIds[array_rand($spellIds)];
// 使用 Item::createSpell 创建法术物品
return \Game\Entities\Item::createSpell($spellId, $enemy->level);
}
private function playerAttack($out): bool
@ -940,25 +856,27 @@ class Battle
$totalExp += $enemy->expReward;
$totalStones += $enemy->spiritStoneReward;
// 掉落 - 从怪物穿着的装备随机掉落50%概率)
// 掉落 - 从怪物穿着的装备随机掉落
foreach ($enemy->getRandomEquipmentDrops(50) as $item) {
$this->player->addItem($item);
$allDrops[] = $item;
}
// 掉落 - 从怪物穿着的法术随机掉落50%概率)
foreach ($enemy->getRandomSpellDrops(50) as $spell) {
$this->player->addItem($spell);
$allDrops[] = $spell;
}
// 掉落 - 从掉落表中随机掉落物品
foreach ($enemy->dropTable as $drop) {
if (rand(1, 100) <= $drop['rate']) {
$this->player->addItem($drop['item']);
$allDrops[] = $drop['item'];
}
}
// 掉落法术物品 (新法术系统)
$spellDropChance = 15; // 15% 概率掉落法术
if (rand(1, 100) <= $spellDropChance && !empty($this->spellsData)) {
$spellItem = $this->generateSpellDrop($enemy);
if ($spellItem) {
$this->player->addItem($spellItem);
$allDrops[] = $spellItem;
}
}
}
// 经验

View File

@ -4,7 +4,6 @@ namespace Game\Modules;
use Game\Core\Game;
use Game\Core\Screen;
use Game\Core\ItemDisplay;
use Game\Core\SpellDisplay;
use Game\Core\Colors;
class InventoryPanel
@ -594,7 +593,7 @@ class InventoryPanel
foreach ($player->inventory as $index => $item) {
$quality = $item['quality'] ?? $item['rarity'] ?? 'common';
$isEquipment = in_array($item['type'], ['weapon', 'armor', 'ring', 'necklace', 'boots','spell']);
$isEquipment = in_array($item['type'], ['weapon', 'armor', 'ring', 'necklace', 'boots']);
if ($isEquipment && in_array($quality, $qualitiesToSell)) {
$price = \Game\Entities\Item::calculateSellPrice($item);

View File

@ -212,16 +212,18 @@ class SpellPanel
$actualDamage = $damage * (1 + $damageBonus / 100);
$out->writeln("伤害倍数: {$this->yellow}" . number_format($damage, 2) . "{$this->reset}{$this->green}" . number_format($actualDamage, 2) . "x{$this->reset}");
$out->writeln("效果: {$this->magenta}对所有敌人造成魔法伤害{$this->reset}");
} elseif ($type === 'heal_single') {
$heal = $spellInfo['heal'] ?? 0.5;
$healBase = $spellInfo['heal_base'] ?? 20;
$out->writeln("恢复效果: {$this->green}魔攻 x {$heal} + {$healBase}{$this->reset}");
$out->writeln("效果: {$this->magenta}恢复单个目标的生命值{$this->reset}");
} elseif ($type === 'heal_aoe') {
$heal = $spellInfo['heal'] ?? 0.5;
$healBase = $spellInfo['heal_base'] ?? 20;
$out->writeln("恢复效果: {$this->green}魔攻 x {$heal} + {$healBase}{$this->reset}");
$out->writeln("效果: {$this->magenta}恢复所有队员的生命值{$this->reset}");
} elseif ($type === 'support') {
$subtype = $spellInfo['subtype'] ?? '';
if ($subtype === 'heal' || $subtype === 'heal_all') {
$heal = $spellInfo['heal'] ?? 0.5;
$healBase = $spellInfo['heal_base'] ?? 20;
$out->writeln("恢复效果: {$this->green}魔攻 x {$heal} + {$healBase}{$this->reset}");
$out->writeln("效果: {$this->magenta}恢复生命值{$this->reset}");
} elseif ($subtype === 'defend') {
$defenseBoos = $spellInfo['defense_boost'] ?? 0;
$out->writeln("防御增加: {$this->green}+{$defenseBoos}{$this->reset}");
$out->writeln("效果: {$this->magenta}增加防御力{$this->reset}");
}
}
$out->writeln("");
@ -243,7 +245,7 @@ class SpellPanel
// 获取所有可学习的法术(按品质分类)
$allSpells = [];
foreach ($spellsData as $category => $spells) {
if (is_array($spells) && !in_array($category, ['quality_levels', 'upgrades', 'dungeon_spell_drops', 'quality_drop_rates', 'spells_by_quality'])) {
if (is_array($spells) && $category !== 'quality_levels' && $category !== 'upgrades') {
foreach ($spells as $spellId => $spellInfo) {
if (is_numeric($spellId)) {
$allSpells[$spellId] = $spellInfo;
@ -457,7 +459,7 @@ class SpellPanel
private function getSpellInfo(int $spellId, array $spellsData): ?array
{
foreach ($spellsData as $category => $spells) {
if (is_array($spells) && !in_array($category, ['quality_levels', 'upgrades', 'dungeon_spell_drops', 'quality_drop_rates', 'spells_by_quality'])) {
if (is_array($spells) && $category !== 'quality_levels' && $category !== 'upgrades') {
if (isset($spells[$spellId])) {
return $spells[$spellId];
}

View File

@ -6,7 +6,6 @@ use Game\Core\Game;
use Game\Core\Screen;
use Game\Core\Input;
use Game\Core\ItemDisplay;
use Game\Core\SpellDisplay;
use Game\Services\EquipmentEnhancer;
use Game\Entities\Actor;
use Game\Entities\Partner;

View File

@ -1,6 +1,6 @@
<?php
require __DIR__ . '/../vendor/autoload.php';
$monster = \Game\Entities\Monster::create(1);
$monster = \Game\Entities\Monster::createGroup(2);
dd($monster->getRandomSpellDrops());
dd(is_numeric('0'));