diff --git a/composer.json b/composer.json index 1f20634..78aeac0 100644 --- a/composer.json +++ b/composer.json @@ -4,7 +4,8 @@ "type": "project", "require": { "php": ">=8.0", - "symfony/console": "^6.4" + "symfony/console": "^6.4", + "symfony/var-dumper": "^6.4" }, "autoload": { "psr-4": { diff --git a/composer.lock b/composer.lock index e92cf5c..c000065 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "ff92c56914631088226b9b90349a3d85", + "content-hash": "f41a3afdcc806c29e3fe260d3a61b340", "packages": [ { "name": "psr/container", @@ -734,6 +734,94 @@ } ], "time": "2025-09-11T14:32:46+00:00" + }, + { + "name": "symfony/var-dumper", + "version": "v6.4.26", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-dumper.git", + "reference": "cfae1497a2f1eaad78dbc0590311c599c7178d4a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/cfae1497a2f1eaad78dbc0590311c599c7178d4a", + "reference": "cfae1497a2f1eaad78dbc0590311c599c7178d4a", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/console": "<5.4" + }, + "require-dev": { + "symfony/console": "^5.4|^6.0|^7.0", + "symfony/error-handler": "^6.3|^7.0", + "symfony/http-kernel": "^5.4|^6.0|^7.0", + "symfony/process": "^5.4|^6.0|^7.0", + "symfony/uid": "^5.4|^6.0|^7.0", + "twig/twig": "^2.13|^3.0.4" + }, + "bin": [ + "Resources/bin/var-dump-server" + ], + "type": "library", + "autoload": { + "files": [ + "Resources/functions/dump.php" + ], + "psr-4": { + "Symfony\\Component\\VarDumper\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides mechanisms for walking through any arbitrary PHP variable", + "homepage": "https://symfony.com", + "keywords": [ + "debug", + "dump" + ], + "support": { + "source": "https://github.com/symfony/var-dumper/tree/v6.4.26" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-09-25T15:37:27+00:00" } ], "packages-dev": [], diff --git a/save.json b/save.json index 628a026..ef0a1f1 100644 --- a/save.json +++ b/save.json @@ -1 +1 @@ -{"player":{"hp":266,"maxHp":0,"patk":10,"matk":5,"pdef":5,"mdef":3,"crit":5,"critdmg":130,"level":11,"exp":3637,"maxExp":5743,"inventory":[{"name":"玄铁剑","type":"weapon","quality":"common","level":1,"patk":11,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":0,"affixes":[],"desc":"Lv.1 common品质的武器","id":"6930554849acb","quantity":1},{"name":"金疮药","type":"consume","quality":"common","level":1,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":35,"affixes":[],"desc":"Lv.1 common品质的药剂","id":"6930578fb29f6","quantity":84},{"name":"培元丹","type":"consume","quality":"common","level":5,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":61,"affixes":[],"desc":"Lv.5 common品质的药剂","id":"693057959f5c2","quantity":1},{"name":"玄铁剑","type":"weapon","quality":"common","level":1,"patk":10,"matk":1,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":0,"affixes":[],"desc":"Lv.1 common品质的武器","id":"69305a28d318c","quantity":1},{"name":"金疮药","type":"consume","quality":"common","level":1,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":37,"affixes":[],"desc":"Lv.1 common品质的药剂","id":"69305a3d522a2","quantity":1},{"name":"金疮药","type":"consume","quality":"common","level":1,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":36,"affixes":[],"desc":"Lv.1 common品质的药剂","id":"69305a5294bf6","quantity":2},{"name":"回灵丹","type":"consume","quality":"epic","level":5,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":109,"affixes":[],"desc":"Lv.5 epic品质的药剂","id":"69305a6d97942","quantity":1},{"name":"金疮药","type":"consume","quality":"epic","level":3,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":98,"affixes":[],"desc":"Lv.3 epic品质的药剂","id":"69305a7c8d884","quantity":1},{"name":"回灵丹","type":"consume","quality":"common","level":3,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":54,"affixes":[],"desc":"Lv.3 common品质的药剂","id":"69305a7c8d888","quantity":1},{"name":"金疮药","type":"consume","quality":"legendary","level":1,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":132,"affixes":[],"desc":"Lv.1 legendary品质的药剂","id":"69305a7c8d8e4","quantity":2},{"name":"金疮药","type":"consume","quality":"rare","level":1,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":55,"affixes":[],"desc":"Lv.1 rare品质的药剂","id":"69305a8f24bef","quantity":1},{"name":"金疮药","type":"consume","quality":"common","level":1,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":43,"affixes":[],"desc":"Lv.1 common品质的药剂","id":"69305a8f24bf4","quantity":2},{"name":"金疮药","type":"consume","quality":"common","level":5,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":63,"affixes":[],"desc":"Lv.5 common品质的药剂","id":"69305a8f24bf7","quantity":1},{"name":"补气丹","type":"consume","quality":"common","level":5,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":60,"affixes":[],"desc":"Lv.5 common品质的药剂","id":"69305a9fac153","quantity":1},{"name":"皮甲","type":"armor","quality":"common","level":3,"patk":0,"matk":0,"pdef":6,"mdef":1,"hp":0,"crit":0,"critdmg":0,"heal":0,"affixes":[],"desc":"Lv.3 common品质的防具","id":"69305a9fac1df","quantity":1},{"name":"金疮药","type":"consume","quality":"common","level":1,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":42,"affixes":[],"desc":"Lv.1 common品质的药剂","id":"69305aaea31ce","quantity":2},{"name":"培元丹","type":"consume","quality":"rare","level":3,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":71,"affixes":[],"desc":"Lv.3 rare品质的药剂","id":"69305aaea31d4","quantity":2},{"name":"金疮药","type":"consume","quality":"common","level":1,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":39,"affixes":[],"desc":"Lv.1 common品质的药剂","id":"69305aaea31d7","quantity":1},{"name":"铜链","type":"necklace","quality":"rare","level":5,"patk":0,"matk":0,"pdef":8,"mdef":0,"hp":60,"crit":0,"critdmg":0,"heal":0,"affixes":["暴击率 +6"],"desc":"Lv.5 rare品质的项链","id":"69305ac73cf42","quantity":1},{"name":"补气丹","type":"consume","quality":"rare","level":5,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":76,"affixes":[],"desc":"Lv.5 rare品质的药剂","id":"69305ac73cf4d","quantity":1},{"name":"皮甲","type":"armor","quality":"rare","level":3,"patk":0,"matk":0,"pdef":9,"mdef":2,"hp":0,"crit":0,"critdmg":0,"heal":0,"affixes":["物攻 +9"],"desc":"Lv.3 rare品质的防具","id":"69305ad2164f0","quantity":1},{"name":"雷霆锤","type":"weapon","quality":"rare","level":1,"patk":17,"matk":6,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":0,"affixes":["物攻 +3%"],"desc":"Lv.1 rare品质的武器","id":"69305aebd9997","quantity":1},{"name":"铁剑","type":"weapon","quality":"rare","level":5,"patk":15,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":0,"affixes":[],"desc":"Lv.5 common品质的武器","id":"69305aebd999d","quantity":1},{"name":"金疮药","type":"consume","quality":"rare","level":1,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":58,"affixes":[],"desc":"Lv.1 rare品质的药剂","id":"69305b01f12ef","quantity":1},{"name":"金疮药","type":"consume","quality":"epic","level":1,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":92,"affixes":[],"desc":"Lv.1 epic品质的药剂","id":"69305b10e9beb","quantity":1},{"name":"皮甲","type":"armor","quality":"rare","level":3,"patk":0,"matk":0,"pdef":10,"mdef":2,"hp":36,"crit":0,"critdmg":0,"heal":0,"affixes":["生命值 +34"],"desc":"Lv.3 rare品质的防具","id":"69305b10e9c10","quantity":1},{"name":"金疮药","type":"consume","quality":"common","level":3,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":52,"affixes":[],"desc":"Lv.3 common品质的药剂","id":"69305b1d30b2e","quantity":1},{"name":"金疮药","type":"consume","quality":"common","level":1,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":44,"affixes":[],"desc":"Lv.1 common品质的药剂","id":"69305b4ed926f","quantity":2},{"name":"培元丹","type":"consume","quality":"common","level":3,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":50,"affixes":[],"desc":"Lv.3 common品质的药剂","id":"69305b69188e5","quantity":1},{"name":"金疮药","type":"consume","quality":"common","level":3,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":49,"affixes":[],"desc":"Lv.3 common品质的药剂","id":"69305b93d3049","quantity":1},{"name":"筑基丹","type":"consume","quality":"common","level":3,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":51,"affixes":[],"desc":"Lv.3 common品质的药剂","id":"69305b93d30c6","quantity":1},{"name":"青钢剑","type":"weapon","quality":"rare","level":1,"patk":13,"matk":4,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":0,"affixes":["物攻 +7"],"desc":"Lv.1 rare品质的武器","id":"69305bb496214","quantity":1},{"name":"金疮药","type":"consume","quality":"common","level":1,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":40,"affixes":[],"desc":"Lv.1 common品质的药剂","id":"69305bb496228","quantity":1}],"equip":{"weapon":{"name":"烈焰刀","type":"weapon","quality":"legendary","level":1,"patk":35,"matk":50,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":27,"heal":0,"affixes":["暴击率 +7","物攻 +15","魔攻 +8%"],"desc":"Lv.1 legendary品质的武器","id":"693041a47105c","quantity":1,"enhanceLevel":0},"armor":{"name":"皮甲","type":"armor","quality":"legendary","level":3,"patk":0,"matk":0,"pdef":26,"mdef":8,"hp":92,"crit":0,"critdmg":0,"heal":0,"affixes":["物攻 +3%","魔攻 +8%","物防 +16"],"desc":"Lv.3 legendary品质的防具","id":"693044ffc1381","quantity":1,"enhanceLevel":0},"necklace":{"name":"金链","type":"necklace","quality":"rare","level":5,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":57,"crit":0,"critdmg":0,"heal":0,"affixes":["物防 +9"],"desc":"Lv.5 rare品质的项链","id":"693046bc441b6","quantity":1,"enhanceLevel":0}},"spiritStones":3779,"npcFlags":[],"talentPoints":15,"talents":{"hp":12,"patk":0,"matk":0,"pdef":0,"mdef":0,"crit":0,"critdmg":0},"mana":100,"maxMana":100,"spells":[],"spellBooks":{"3":1,"1":48,"10":50},"partners":[{"id":"li_feiyu","name":"厉飞雨","level":16,"exp":542,"maxExp":1135,"equip":{"weapon":{"name":"玄铁剑","type":"weapon","quality":"rare","level":5,"patk":15,"matk":1,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":0,"affixes":["暴击 +5"],"desc":"Lv.5 common品质的武器","id":"693055329e36e","quantity":1}},"talents":{"hp":42,"patk":6,"matk":0,"pdef":0,"mdef":0,"crit":0,"critdmg":0},"talentWeights":{"hp":1,"patk":1,"matk":1,"pdef":1,"mdef":1,"crit":1,"critdmg":1},"mana":100,"maxMana":100,"spells":[],"spellBooks":[],"hp":375,"maxHp":0,"patk":15,"matk":5,"pdef":5,"mdef":3,"crit":10,"critdmg":130}]},"dungeonId":1,"state":2} \ No newline at end of file +{"player":{"hp":0,"maxHp":0,"patk":10,"matk":5,"pdef":5,"mdef":3,"crit":5,"critdmg":130,"level":16,"exp":14282,"maxExp":43606,"inventory":[{"name":"金疮药","type":"consume","quality":"legendary","level":1,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":132,"affixes":[],"desc":"Lv.1 legendary品质的药剂","id":"69305a7c8d8e4","quantity":2},{"name":"金疮药","type":"consume","quality":"legendary","level":1,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":129,"affixes":[],"desc":"Lv.1 legendary品质的药剂","id":"693102c5300fa","quantity":1},{"name":"补气丹","type":"consume","quality":"epic","level":5,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":112,"affixes":[],"desc":"Lv.5 epic品质的药剂","id":"693102f87b75d","quantity":1},{"name":"补气丹","type":"consume","quality":"epic","level":5,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":111,"affixes":[],"desc":"Lv.5 epic品质的药剂","id":"69310388b1ee6","quantity":1},{"name":"筑基丹","type":"consume","quality":"epic","level":10,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":136,"affixes":[],"desc":"Lv.10 epic品质的药剂","id":"69310a735a1a6","quantity":1},{"name":"补气丹","type":"consume","quality":"epic","level":6,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":117,"affixes":[],"desc":"Lv.6 epic品质的药剂","id":"6931103411a86","quantity":1},{"name":"金疮药","type":"consume","quality":"epic","level":6,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":113,"affixes":[],"desc":"Lv.6 epic品质的药剂","id":"693116d542665","quantity":1},{"name":"筑基丹","type":"consume","quality":"legendary","level":6,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":155,"affixes":[],"desc":"Lv.6 legendary品质的药剂","id":"6931172e5d795","quantity":1},{"name":"补气丹","type":"consume","quality":"epic","level":6,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":111,"affixes":[],"desc":"Lv.6 epic品质的药剂","id":"693117f8bb7d1","quantity":2},{"name":"补气丹","type":"consume","quality":"epic","level":6,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":112,"affixes":[],"desc":"Lv.6 epic品质的药剂","id":"6931184c07341","quantity":1},{"name":"回灵丹","type":"consume","quality":"legendary","level":10,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":170,"affixes":[],"desc":"Lv.10 legendary品质的药剂","id":"6931227d7b7f3","quantity":1},{"name":"金疮药","type":"consume","quality":"epic","level":6,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":111,"affixes":[],"desc":"Lv.6 epic品质的药剂","id":"693125ecb54a7","quantity":1},{"name":"回灵丹","type":"consume","quality":"epic","level":10,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":131,"affixes":[],"desc":"Lv.10 epic品质的药剂","id":"693125ecb54e7","quantity":2},{"name":"补气丹","type":"consume","quality":"epic","level":10,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":139,"affixes":[],"desc":"Lv.10 epic品质的药剂","id":"693129f6a8551","quantity":1},{"name":"培元丹","type":"consume","quality":"epic","level":6,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":113,"affixes":[],"desc":"Lv.6 epic品质的药剂","id":"69312ae28d4d6","quantity":1},{"name":"金疮药","type":"consume","quality":"epic","level":11,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":143,"affixes":[],"desc":"Lv.11 epic品质的药剂","id":"69312cd2d281d","quantity":1},{"name":"筑基丹","type":"consume","quality":"legendary","level":15,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":197,"affixes":[],"desc":"Lv.15 legendary品质的药剂","id":"69312d2a34d46","quantity":1},{"name":"金疮药","type":"consume","quality":"rare","level":11,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":114,"affixes":[],"desc":"Lv.11 rare品质的药剂","id":"69312dfd55678","quantity":2},{"name":"筑基丹","type":"consume","quality":"epic","level":15,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":165,"affixes":[],"desc":"Lv.15 epic品质的药剂","id":"69312ec3f285d","quantity":1},{"name":"龙鳞甲","type":"armor","quality":"epic","level":15,"patk":0,"matk":0,"pdef":20,"mdef":15,"hp":0,"crit":0,"critdmg":0,"heal":0,"affixes":[],"desc":"Lv.15 common品质的防具","id":"69312f13848b4","quantity":1},{"name":"筑基丹","type":"consume","quality":"common","level":15,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":113,"affixes":[],"desc":"Lv.15 common品质的药剂","id":"69312f13848f1","quantity":2},{"name":"筑基丹","type":"consume","quality":"rare","level":11,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":112,"affixes":[],"desc":"Lv.11 rare品质的药剂","id":"69312f4a0fc80","quantity":1},{"name":"精钢甲","type":"armor","quality":"epic","level":8,"patk":0,"matk":0,"pdef":37,"mdef":9,"hp":77,"crit":0,"critdmg":0,"heal":0,"affixes":["物防 +7%","魔防 +10%"],"desc":"Lv.8 epic品质的防具","id":"693134abb5060","quantity":1},{"name":"筑基丹","type":"consume","quality":"rare","level":15,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":131,"affixes":[],"desc":"Lv.15 rare品质的药剂","id":"693136a68a0cf","quantity":1},{"name":"筑基丹","type":"consume","quality":"epic","level":15,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":159,"affixes":[],"desc":"Lv.15 epic品质的药剂","id":"693136f3c0cb9","quantity":2},{"name":"筑基丹","type":"consume","quality":"rare","level":15,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":126,"affixes":[],"desc":"Lv.15 rare品质的药剂","id":"693137235becf","quantity":1},{"name":"金疮药","type":"consume","quality":"legendary","level":11,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":180,"affixes":[],"desc":"Lv.11 legendary品质的药剂","id":"69313729491c6","quantity":1},{"name":"筑基丹","type":"consume","quality":"common","level":15,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":112,"affixes":[],"desc":"Lv.15 common品质的药剂","id":"6931384c826e1","quantity":4},{"name":"补气丹","type":"consume","quality":"legendary","level":11,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":183,"affixes":[],"desc":"Lv.11 legendary品质的药剂","id":"69313f9a7e688","quantity":1},{"name":"筑基丹","type":"consume","quality":"rare","level":15,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":128,"affixes":[],"desc":"Lv.15 rare品质的药剂","id":"6931409199364","quantity":2},{"name":"筑基丹","type":"consume","quality":"epic","level":11,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":138,"affixes":[],"desc":"Lv.11 epic品质的药剂","id":"6931410c51c8c","quantity":1},{"name":"培元丹","type":"consume","quality":"rare","level":11,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":111,"affixes":[],"desc":"Lv.11 rare品质的药剂","id":"693141f62e921","quantity":1},{"name":"筑基丹","type":"consume","quality":"rare","level":11,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":110,"affixes":[],"desc":"Lv.11 rare品质的药剂","id":"693142137163b","quantity":1},{"name":"筑基丹","type":"consume","quality":"rare","level":15,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":127,"affixes":[],"desc":"Lv.15 rare品质的药剂","id":"69314250e92fd","quantity":1},{"name":"筑基丹","type":"consume","quality":"common","level":15,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":114,"affixes":[],"desc":"Lv.15 common品质的药剂","id":"693143614614b","quantity":1},{"name":"青钢剑","type":"weapon","quality":"epic","level":15,"patk":29,"matk":45,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":0,"affixes":[],"desc":"Lv.15 common品质的武器","id":"693143c5eda96","quantity":1},{"name":"皮甲","type":"armor","quality":"epic","level":15,"patk":0,"matk":0,"pdef":20,"mdef":15,"hp":0,"crit":0,"critdmg":0,"heal":0,"affixes":["魔防 +21"],"desc":"Lv.15 rare品质的防具","id":"693144565899d","quantity":1},{"name":"铁甲","type":"armor","quality":"epic","level":15,"patk":0,"matk":0,"pdef":20,"mdef":15,"hp":0,"crit":0,"critdmg":0,"heal":0,"affixes":[],"desc":"Lv.15 common品质的防具","id":"69314486acc4a","quantity":1},{"name":"筑基丹","type":"consume","quality":"rare","level":15,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":132,"affixes":[],"desc":"Lv.15 rare品质的药剂","id":"69314486accc8","quantity":1},{"name":"筑基丹","type":"consume","quality":"epic","level":15,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":163,"affixes":[],"desc":"Lv.15 epic品质的药剂","id":"693144e5cf565","quantity":1},{"name":"铁剑","type":"weapon","quality":"epic","level":16,"patk":54,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":25,"heal":0,"affixes":["生命值 +9%","物攻 +8%"],"desc":"Lv.16 epic品质的武器","id":"693147b07e22d","quantity":1},{"name":"筑基丹","type":"consume","quality":"common","level":16,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":118,"affixes":[],"desc":"Lv.16 common品质的药剂","id":"693147b80ef7a","quantity":1},{"name":"回灵丹","type":"consume","quality":"rare","level":16,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":139,"affixes":[],"desc":"Lv.16 rare品质的药剂","id":"69314e4ba835b","quantity":1},{"name":"回灵丹","type":"consume","quality":"epic","level":16,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":163,"affixes":[],"desc":"Lv.16 epic品质的药剂","id":"69314e68282ec","quantity":1},{"name":"雷霆锤","type":"weapon","quality":"epic","level":16,"patk":58,"matk":23,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":27,"heal":0,"affixes":["暴击率 +9%","暴击伤害 +22"],"desc":"Lv.16 epic品质的武器","id":"69314e7aec20e","quantity":1},{"name":"培元丹","type":"consume","quality":"common","level":16,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":110,"affixes":[],"desc":"Lv.16 common品质的药剂","id":"69314e9d57f9c","quantity":1},{"name":"金疮药","type":"consume","quality":"common","level":16,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":111,"affixes":[],"desc":"Lv.16 common品质的药剂","id":"69314ebb6f8c2","quantity":2},{"name":"烈焰刀","type":"weapon","quality":"epic","level":20,"patk":50,"matk":30,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":0,"affixes":[],"desc":"Lv.20 common品质的武器","id":"69315084c9bbd","quantity":1},{"name":"培元丹","type":"consume","quality":"rare","level":16,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":133,"affixes":[],"desc":"Lv.16 rare品质的药剂","id":"693150a4e185f","quantity":1},{"name":"补气丹","type":"consume","quality":"rare","level":16,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":138,"affixes":[],"desc":"Lv.16 rare品质的药剂","id":"693150c506174","quantity":1},{"name":"补气丹","type":"consume","quality":"epic","level":16,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":168,"affixes":[],"desc":"Lv.16 epic品质的药剂","id":"6931510aa6798","quantity":1},{"name":"回灵丹","type":"consume","quality":"rare","level":16,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":137,"affixes":[],"desc":"Lv.16 rare品质的药剂","id":"69315126e25f0","quantity":1},{"name":"筑基丹","type":"consume","quality":"rare","level":30,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":203,"affixes":[],"desc":"Lv.30 rare品质的药剂","id":"6931516d3e2f3","quantity":1},{"name":"布衣","type":"armor","quality":"epic","level":13,"patk":0,"matk":0,"pdef":12,"mdef":12,"hp":92,"crit":0,"critdmg":0,"heal":0,"affixes":["生命值 +162","魔攻 +32"],"desc":"Lv.13 epic品质的防具","id":"693152241d32c","quantity":1},{"name":"补气丹","type":"consume","quality":"common","level":16,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":116,"affixes":[],"desc":"Lv.16 common品质的药剂","id":"69315704db372","quantity":1},{"name":"筑基丹","type":"consume","quality":"common","level":16,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":120,"affixes":[],"desc":"Lv.16 common品质的药剂","id":"6931573a7d21c","quantity":1},{"name":"烈焰刀","type":"weapon","quality":"epic","level":20,"patk":50,"matk":30,"pdef":0,"mdef":0,"hp":0,"crit":10,"critdmg":0,"heal":0,"affixes":["物攻 +10%"],"desc":"Lv.20 rare品质的武器","id":"6931575d1ce4a","quantity":1}],"equip":{"weapon":{"name":"烈焰刀","type":"weapon","quality":"legendary","level":13,"patk":49,"matk":49,"pdef":0,"mdef":0,"hp":0,"crit":13,"critdmg":0,"heal":0,"affixes":["物攻 +8%","暴击伤害 +9%","生命值 +7%"],"desc":"Lv.13 legendary品质的武器","id":"693136a689b5b","quantity":1,"enhanceLevel":8},"armor":{"name":"皮甲","type":"armor","quality":"legendary","level":3,"patk":0,"matk":0,"pdef":26,"mdef":8,"hp":92,"crit":0,"critdmg":0,"heal":0,"affixes":["物攻 +3%","魔攻 +8%","物防 +16"],"desc":"Lv.3 legendary品质的防具","id":"693044ffc1381","quantity":1,"enhanceLevel":7},"necklace":{"name":"金链","type":"necklace","quality":"rare","level":5,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":57,"crit":0,"critdmg":0,"heal":0,"affixes":["物防 +9"],"desc":"Lv.5 rare品质的项链","id":"693046bc441b6","quantity":1,"enhanceLevel":7},"boots":{"name":"幽步靴","type":"boots","quality":"rare","level":8,"patk":0,"matk":0,"pdef":8,"mdef":5,"hp":0,"crit":0,"critdmg":0,"heal":0,"affixes":["物防 +16"],"desc":"Lv.8 rare品质的鞋子","id":"693106c639f68","quantity":1,"enhanceLevel":7},"ring":{"name":"金戒","type":"ring","quality":"rare","level":10,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":10,"critdmg":0,"heal":0,"affixes":["魔攻 +7%"],"desc":"Lv.10 rare品质的戒指","id":"6931168bb01d0","quantity":1,"enhanceLevel":7}},"spiritStones":12220,"npcFlags":[],"talentPoints":0,"talents":{"hp":22,"patk":5,"matk":0,"pdef":0,"mdef":0,"crit":0,"critdmg":0},"mana":43,"maxMana":100,"skillSlots":{"skill1":null,"skill2":null,"skill3":null,"skill4":null},"partners":[{"id":"li_feiyu","name":"厉飞雨","level":24,"exp":7328,"maxExp":29071,"equip":{"weapon":{"name":"烈焰刀","type":"weapon","quality":"legendary","level":1,"patk":35,"matk":50,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":27,"heal":0,"affixes":["暴击率 +7","物攻 +15","魔攻 +8%"],"desc":"Lv.1 legendary品质的武器","id":"69313796a3735","quantity":1,"enhanceLevel":7},"necklace":{"name":"铜链","type":"necklace","quality":"rare","level":5,"patk":0,"matk":0,"pdef":8,"mdef":0,"hp":60,"crit":0,"critdmg":0,"heal":0,"affixes":["暴击率 +6"],"desc":"Lv.5 rare品质的项链","id":"69305ac73cf42","quantity":1},"armor":{"name":"皮甲","type":"armor","quality":"epic","level":13,"patk":0,"matk":0,"pdef":23,"mdef":7,"hp":95,"crit":0,"critdmg":0,"heal":0,"affixes":["物防 +12%","生命值 +12%"],"desc":"Lv.13 epic品质的防具","id":"69312ee919ef6","quantity":1,"enhanceLevel":7},"boots":{"name":"铁靴","type":"boots","quality":"common","level":8,"patk":0,"matk":0,"pdef":4,"mdef":4,"hp":0,"crit":0,"critdmg":0,"heal":0,"affixes":[],"desc":"Lv.8 common品质的鞋子","id":"69310787c6cb5","quantity":1},"ring":{"name":"仙戒","type":"ring","quality":"rare","level":10,"patk":14,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":9,"critdmg":0,"heal":0,"affixes":["暴击伤害 +13"],"desc":"Lv.10 rare品质的戒指","id":"69312a683bc39","quantity":1}},"talents":{"hp":58,"patk":14,"matk":0,"pdef":0,"mdef":0,"crit":0,"critdmg":0},"talentWeights":{"hp":1,"patk":1,"matk":1,"pdef":1,"mdef":1,"crit":1,"critdmg":1},"mana":100,"maxMana":100,"skillSlots":{"skill1":null,"skill2":null,"skill3":null,"skill4":null},"hp":422,"maxHp":0,"patk":15,"matk":5,"pdef":5,"mdef":3,"crit":10,"critdmg":130},{"id":"chen_qiaoqian","name":"陈巧倩","level":12,"exp":2164,"maxExp":8614,"equip":{"armor":{"name":"龙鳞甲","type":"armor","quality":"epic","level":30,"patk":0,"matk":0,"pdef":40,"mdef":30,"hp":0,"crit":0,"critdmg":0,"heal":0,"affixes":[],"desc":"Lv.30 common品质的防具","id":"6931516d3e290","quantity":1},"weapon":{"name":"寒冰剑","type":"weapon","quality":"epic","level":15,"patk":14,"matk":45,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":0,"affixes":[],"desc":"Lv.15 common品质的武器","id":"6931384c826ed","quantity":1,"enhanceLevel":1}},"talents":{"hp":22,"patk":11,"matk":0,"pdef":0,"mdef":0,"crit":0,"critdmg":0},"talentWeights":{"hp":1,"patk":1,"matk":1,"pdef":1,"mdef":1,"crit":1,"critdmg":1},"mana":100,"maxMana":100,"skillSlots":{"skill1":null,"skill2":null,"skill3":null,"skill4":null},"hp":899,"maxHp":500,"patk":40,"matk":60,"pdef":30,"mdef":45,"crit":15,"critdmg":150}]},"dungeonId":4,"state":7} \ No newline at end of file diff --git a/src/Core/Game.php b/src/Core/Game.php index 0cb2656..80ca8eb 100644 --- a/src/Core/Game.php +++ b/src/Core/Game.php @@ -8,7 +8,6 @@ use Game\Modules\Menu; use Game\Modules\Battle; use Game\Modules\StatsPanel; use Game\Modules\NpcPanel; -use Game\Modules\PartnerPanel; use Game\Modules\TalentPanel; use Game\Modules\DungeonSelectPanel; use Game\Modules\EquipmentEnhancePanel; @@ -21,11 +20,9 @@ class Game const STATS = 3; const INVENTORY = 4; const NPC = 5; - const PARTNER = 6; - const TALENT = 7; + const TALENT = 6; + const EQUIPMENT_ENHANCE = 7; const DUNGEON_SELECT = 8; - const EQUIPMENT_ENHANCE = 9; - const SPELL = 10; const EXIT = 0; public Player $player; @@ -100,11 +97,10 @@ class Game } } - // 加载法术数据 + // 加载技能槽位数据 (新法术系统) $this->player->mana = $p['mana'] ?? $this->player->mana; $this->player->maxMana = $p['maxMana'] ?? $this->player->maxMana; - $this->player->spells = $p['spells'] ?? $this->player->spells; - $this->player->spellBooks = $p['spellBooks'] ?? $this->player->spellBooks; + $this->player->skillSlots = $p['skillSlots'] ?? $this->player->skillSlots; $this->dungeonId = $data['dungeonId'] ?? $this->dungeonId; $this->state = self::MENU; @@ -128,8 +124,7 @@ class Game 'talentWeights' => $partner->talentWeights, 'mana' => $partner->mana, 'maxMana' => $partner->maxMana, - 'spells' => $partner->spells, - 'spellBooks' => $partner->spellBooks, + 'skillSlots' => $partner->skillSlots, 'hp' => $partner->hp, 'maxHp' => $partner->maxHp, @@ -164,8 +159,7 @@ class Game 'talents' => $this->player->talents, 'mana' => $this->player->mana, 'maxMana' => $this->player->maxMana, - 'spells' => $this->player->spells, - 'spellBooks' => $this->player->spellBooks, + 'skillSlots' => $this->player->skillSlots, 'partners' => $partnersData, ], 'dungeonId' => $this->dungeonId, @@ -196,18 +190,12 @@ class Game case self::NPC: (new NpcPanel($this))->show(); break; - case self::PARTNER: - (new PartnerPanel($this))->show(); - break; case self::TALENT: (new TalentPanel($this))->show(); break; case self::EQUIPMENT_ENHANCE: (new EquipmentEnhancePanel($this))->show(); break; - case self::SPELL: - (new SpellPanel($this))->show(); - break; case self::EXIT: $this->output->writeln("再见!"); $this->saveState(); diff --git a/src/Core/GameSession.php b/src/Core/GameSession.php index c66ce9b..03fdf26 100644 --- a/src/Core/GameSession.php +++ b/src/Core/GameSession.php @@ -84,16 +84,17 @@ class GameSession case Game::INVENTORY: (new \Game\Modules\InventoryPanel($this->game))->show(); break; + case Game::EQUIPMENT_ENHANCE: + (new \Game\Modules\EquipmentEnhancePanel($this->game))->show(); + break; case Game::NPC: (new \Game\Modules\NpcPanel($this->game))->show(); break; - case Game::PARTNER: - (new \Game\Modules\PartnerPanel($this->game))->show(); - break; case Game::TALENT: (new \Game\Modules\TalentPanel($this->game))->show(); break; case Game::EXIT: + exit; $this->output->writeln("再见!"); $this->game->saveState(); break; diff --git a/src/Core/ItemDisplay.php b/src/Core/ItemDisplay.php index 9ca9150..92ae7ad 100644 --- a/src/Core/ItemDisplay.php +++ b/src/Core/ItemDisplay.php @@ -30,6 +30,7 @@ class ItemDisplay 'ring' => '戒指', 'necklace' => '项链', 'consume' => '消耗品', + 'spell' => '法术', ]; // 属性名称 @@ -42,6 +43,8 @@ class ItemDisplay 'crit' => '暴击', 'critdmg' => '暴伤', 'heal' => '治疗', + 'cost' => '消耗', + 'damage' => '伤害倍率', ]; // 颜色常量 @@ -101,7 +104,11 @@ class ItemDisplay foreach (self::$statNames as $key => $name) { $value = $item[$key] ?? 0; if ($value > 0) { - $stats[] = "{$name}+{$value}"; + if ($key === 'damage') { + $stats[] = "{$name}:{$value}x"; + } else { + $stats[] = "{$name}+{$value}"; + } } } @@ -115,19 +122,61 @@ class ItemDisplay { $lines = []; $enhanceLevel = $item['enhanceLevel'] ?? 0; - $enhanceMultiplier = 1 + ($enhanceLevel * 0.05); + + // 法术强化逻辑不同 + $isSpell = ($item['type'] ?? '') === 'spell'; + + if ($isSpell) { + // 法术强化: 伤害+5%, 消耗-2 + $damageMultiplier = 1 + ($enhanceLevel * 0.05); + $costReduction = $enhanceLevel * 2; + + foreach (self::$statNames as $key => $name) { + $baseValue = $item[$key] ?? 0; + if ($baseValue > 0) { + if ($key === 'damage') { + $finalValue = number_format($baseValue * $damageMultiplier, 2); + if ($enhanceLevel > 0) { + $lines[] = $prefix . self::$cyan . $name . self::$reset . ": " . + self::$white . $baseValue . "x" . self::$reset . " → " . + self::$green . $finalValue . "x" . self::$reset; + } else { + $lines[] = $prefix . self::$cyan . $name . self::$reset . ": " . + self::$green . $baseValue . "x" . self::$reset; + } + } elseif ($key === 'cost') { + $finalValue = max(1, $baseValue - $costReduction); + if ($enhanceLevel > 0) { + $lines[] = $prefix . self::$cyan . $name . self::$reset . ": " . + self::$white . $baseValue . self::$reset . " → " . + self::$green . $finalValue . self::$reset; + } else { + $lines[] = $prefix . self::$cyan . $name . self::$reset . ": " . + self::$green . $baseValue . self::$reset; + } + } else { + // For other stats on spells, just display the base value + $lines[] = $prefix . self::$cyan . $name . self::$reset . ": " . + self::$green . $baseValue . self::$reset; + } + } + } + } else { + // 装备强化逻辑 + $enhanceMultiplier = 1 + ($enhanceLevel * 0.05); - foreach (self::$statNames as $key => $name) { - $baseValue = $item[$key] ?? 0; - if ($baseValue > 0) { - $finalValue = (int)($baseValue * $enhanceMultiplier); - if ($enhanceLevel > 0 && $key !== 'heal') { - $lines[] = $prefix . self::$cyan . $name . self::$reset . ": " . - self::$white . $baseValue . self::$reset . " → " . - self::$green . $finalValue . self::$reset; - } else { - $lines[] = $prefix . self::$cyan . $name . self::$reset . ": " . - self::$green . $baseValue . self::$reset; + foreach (self::$statNames as $key => $name) { + $baseValue = $item[$key] ?? 0; + if ($baseValue > 0) { + $finalValue = (int)($baseValue * $enhanceMultiplier); + if ($enhanceLevel > 0 && $key !== 'heal') { + $lines[] = $prefix . self::$cyan . $name . self::$reset . ": " . + self::$white . $baseValue . self::$reset . " → " . + self::$green . $finalValue . self::$reset; + } else { + $lines[] = $prefix . self::$cyan . $name . self::$reset . ": " . + self::$green . $baseValue . self::$reset; + } } } } diff --git a/src/Data/npcs.php b/src/Data/npcs.php index a3dbcc0..4b7ce39 100644 --- a/src/Data/npcs.php +++ b/src/Data/npcs.php @@ -58,7 +58,18 @@ return [ 'title' => '黄枫谷师姐', 'min_level' => 15, 'desc' => '黄枫谷陈家大小姐,对韩立有一番复杂的情愫。', + 'base_stats' => [ + 'maxHp' => 500, 'patk' => 40, 'matk' => 60, 'pdef' => 30, 'mdef' => 45, 'crit' => 15, 'critdmg' => 150 + ], + // 天赋权重:法术型,偏魔攻和魔防 + 'talent_weights' => [ + 'hp' => 2, 'patk' => 1, 'matk' => 3, 'pdef' => 1, 'mdef' => 2, 'crit' => 2, 'critdmg' => 2 + ], 'actions' => [ + 'recruit' => [ + 'text' => "韩师弟...若你不嫌弃,巧倩愿意与你同行。", + 'cost' => 0, + ], 'talk' => [ 'text' => "韩师弟...你也筑基成功了?\n当年血色禁地一别,没想到还能再见...", ], @@ -74,7 +85,18 @@ return [ 'title' => '阵法奇才', 'min_level' => 20, 'desc' => '精通阵法之道的奇女子,可惜天生龙吟之体,寿元无多。', + 'base_stats' => [ + 'maxHp' => 400, 'patk' => 30, 'matk' => 80, 'pdef' => 25, 'mdef' => 60, 'crit' => 18, 'critdmg' => 160 + ], + // 天赋权重:阵法型,高魔攻和暴击 + 'talent_weights' => [ + 'hp' => 1, 'patk' => 1, 'matk' => 4, 'pdef' => 1, 'mdef' => 2, 'crit' => 3, 'critdmg' => 2 + ], 'actions' => [ + 'recruit' => [ + 'text' => "若韩前辈不嫌弃如音这副病体,如音愿为前辈布阵御敌。", + 'cost' => 0, + ], 'talk' => [ 'text' => "韩前辈,这颠倒五行阵的阵盘我已经修复好了。\n若非前辈当年的千年灵草,如音恐怕早已不在人世...", ], @@ -91,7 +113,18 @@ return [ 'title' => '乱星海女修', 'min_level' => 40, 'desc' => '为了复活师姐妍丽,不惜修炼鬼道秘术的痴情女子。', + 'base_stats' => [ + 'maxHp' => 1200, 'patk' => 100, 'matk' => 120, 'pdef' => 60, 'mdef' => 70, 'crit' => 22, 'critdmg' => 170 + ], + // 天赋权重:鬼道型,均衡发展偏魔攻 + 'talent_weights' => [ + 'hp' => 2, 'patk' => 2, 'matk' => 3, 'pdef' => 1, 'mdef' => 2, 'crit' => 2, 'critdmg' => 2 + ], 'actions' => [ + 'recruit' => [ + 'text' => "韩兄,为了妍丽师姐,元瑶愿与你同行,共闯天下!", + 'cost' => 0, + ], 'talk' => [ 'text' => "韩兄,虚天殿一别,别来无恙。\n为了妍丽师姐,哪怕是刀山火海,我也要闯一闯!", ], @@ -105,10 +138,21 @@ return [ [ 'id' => 'zi_ling', 'name' => '紫灵仙子', - 'title' => '乱星海第一美女', + 'title' => '乌星海第一美女', 'min_level' => 45, 'desc' => '妙音门门主之女,拥有惊世容颜,与韩立关系匪浅。', + 'base_stats' => [ + 'maxHp' => 1500, 'patk' => 90, 'matk' => 140, 'pdef' => 70, 'mdef' => 90, 'crit' => 25, 'critdmg' => 180 + ], + // 天赋权重:音律型,高魔攻和暴击暴伤 + 'talent_weights' => [ + 'hp' => 2, 'patk' => 1, 'matk' => 3, 'pdef' => 1, 'mdef' => 2, 'crit' => 3, 'critdmg' => 3 + ], 'actions' => [ + 'recruit' => [ + 'text' => "韩兄...紫灵愿以此身相报,生死相随。", + 'cost' => 0, + ], 'talk' => [ 'text' => "韩兄...若非你多次相救,紫灵恐怕早已沦为他人玩物。\n这份恩情,紫灵铭记在心。", ], diff --git a/src/Entities/Actor.php b/src/Entities/Actor.php index bac7284..bb506bf 100644 --- a/src/Entities/Actor.php +++ b/src/Entities/Actor.php @@ -21,8 +21,13 @@ class Actor public int $mana = 0; public int $maxMana = 0; - public array $spells = []; - public array $spellBooks = []; + // 技能槽位系统 (新法术系统) + public array $skillSlots = [ + 'skill1' => null, + 'skill2' => null, + 'skill3' => null, + 'skill4' => null, + ]; public array $equip = []; public array $inventory = []; @@ -278,21 +283,4 @@ class Actor } } } - - /** - * Default factory to create an Actor (delegates to Monster by default). - */ - public static function create(int $dungeonId): Actor - { - return Monster::create($dungeonId); - } - - /** - * Default factory to create a group of Actors (delegates to Monster::createGroup). - * @return Actor[] - */ - public static function createGroup(int $dungeonId): array - { - return Monster::createGroup($dungeonId); - } } diff --git a/src/Entities/Item.php b/src/Entities/Item.php index 3603e2e..7a24aa6 100644 --- a/src/Entities/Item.php +++ b/src/Entities/Item.php @@ -236,6 +236,66 @@ class Item return self::createFromSpec($spec, $baseLevel); } + /** + * 创建法术物品 + * @param int $spellId 法术ID (来自 spells.php) + * @param int $level 物品等级 + * @return array 法术物品数组 + */ + public static function createSpell(int $spellId, int $level = 1): array + { + static $spellsData = null; + if ($spellsData === null) { + $spellsData = require __DIR__ . '/../../src/Data/spells.php'; + } + + // 查找法术信息 + $spellInfo = null; + foreach ($spellsData as $category => $spells) { + if (is_array($spells) && $category !== 'quality_levels' && $category !== 'upgrades' && $category !== 'dungeon_spell_drops') { + if (isset($spells[$spellId])) { + $spellInfo = $spells[$spellId]; + break; + } + } + } + + if (!$spellInfo) { + // 默认法术 + return [ + 'id' => uniqid('spell_'), + 'type' => 'spell', + 'name' => '未知法术', + 'quality' => 'common', + 'level' => $level, + 'spellId' => $spellId, + 'enhanceLevel' => 0, + 'damage' => 1.0, + 'cost' => 20, + 'spellType' => 'damage_single', + 'desc' => '未知的法术', + ]; + } + + return [ + 'id' => uniqid('spell_'), + 'type' => 'spell', + 'name' => $spellInfo['name'], + 'quality' => $spellInfo['quality'] ?? 'common', + 'level' => $level, + 'spellId' => $spellId, + 'enhanceLevel' => 0, + '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'] ?? '', + ]; + } + public function toArray(): array { return [ diff --git a/src/Entities/Monster.php b/src/Entities/Monster.php index e690667..413038a 100644 --- a/src/Entities/Monster.php +++ b/src/Entities/Monster.php @@ -60,7 +60,8 @@ class Monster extends Actor // 3. Hydrate monster base stats from maps.php $monster->hydrateFromConfig($selectedMonster); - + $status = $monster->getStats(); + $monster->hp = $status['maxHp']; return $monster; } @@ -109,8 +110,7 @@ class Monster extends Actor } // Create monster from selected config - $monster = new self(); - $monster->hydrateFromConfig($selectedConfig); + $monster = self::create($dungeonId); // Add suffix to distinguish multiple monsters of same type if ($groupSize > 1) { @@ -129,6 +129,7 @@ class Monster extends Actor $this->level = $config['level'] ?? 1; $this->baseHp = $config['hp'] ?? 20; $this->hp = $this->baseHp; + $this->maxHp = $this->baseHp; $this->basePatk = $config['patk'] ?? $config['atk'] ?? 4; $this->patk = $this->basePatk; $this->baseMatk = $config['matk'] ?? 2; @@ -138,10 +139,13 @@ class Monster extends Actor $this->baseMdef = $config['mdef'] ?? 0; $this->mdef = $this->baseMdef; $this->crit = $config['crit'] ?? 5; - $this->critdmg = $config['critdmg'] ?? 150; + $this->critdmg = $config['critdmg'] ?? 130; $this->expReward = $config['exp'] ?? 0; $this->spiritStoneReward = $config['spirit_stones'] ?? 0; + // 根据等级和基础属性分配天赋点 + $this->allocateTalentsByLevel(); + // Drops & Equipment $drops = $config['drops'] ?? []; foreach ($drops as $drop) { @@ -268,4 +272,49 @@ class Monster extends Actor } return $drops; } + + /** + * 根据等级和基础属性分配天赋点和权重 + * 怪物根据等级获得天赋点,并按基础属性的占比分配权重 + */ + private function allocateTalentsByLevel(): void + { + // 每级获得 3 点天赋点(与玩家一致) + $talentPoints = ($this->level - 1) * 3; + + if ($talentPoints <= 0) { + return; + } + + // 计算基础属性的权重比(考虑每点天赋的效果) + // talentBonus 定义了每点天赋对应的属性增益 + $talentBonusMap = [ + 'hp' => 10, + 'patk' => 5, + 'matk' => 4, + 'pdef' => 3, + 'mdef' => 3, + 'crit' => 1, + 'critdmg' => 5, + ]; + + // 计算每个属性的权重(基础属性值 / 天赋加成) + $weights = [ + 'hp' => max(1, (int)($this->baseHp / $talentBonusMap['hp'])), + 'patk' => max(1, (int)($this->basePatk / $talentBonusMap['patk'])), + 'matk' => max(1, (int)($this->baseMatk / $talentBonusMap['matk'])), + 'pdef' => max(1, (int)($this->basePdef / $talentBonusMap['pdef'])), + 'mdef' => max(1, (int)($this->baseMdef / $talentBonusMap['mdef'])), + 'crit' => max(1, (int)($this->crit / $talentBonusMap['crit'])), + 'critdmg' => 0, + ]; + +// dd($weights); + // 设置权重 + $this->talentWeights = $weights; + $this->talentPoints = $talentPoints; + + // 自动按权重分配天赋点 + $this->autoAllocateTalents($talentPoints); + } } \ No newline at end of file diff --git a/src/Entities/Partner.php b/src/Entities/Partner.php index 10d45f0..2e05e99 100644 --- a/src/Entities/Partner.php +++ b/src/Entities/Partner.php @@ -35,11 +35,10 @@ class Partner extends Actor $this->talents = $data['talents'] ?? $this->talents; $this->talentWeights = $data['talentWeights'] ?? $this->talentWeights; - // 加载法术系统数据 + // 加载技能槽位数据 (新法术系统) $this->mana = $data['mana'] ?? $this->mana; $this->maxMana = $data['maxMana'] ?? 100; - $this->spells = $data['spells'] ?? $this->spells; - $this->spellBooks = $data['spellBooks'] ?? $this->spellBooks; + $this->skillSlots = $data['skillSlots'] ?? $this->skillSlots; } /** diff --git a/src/Entities/Player.php b/src/Entities/Player.php index 813f661..aaa9710 100644 --- a/src/Entities/Player.php +++ b/src/Entities/Player.php @@ -45,77 +45,6 @@ class Player extends Actor } - /** - * 学习法术 - */ - public function learnSpell(int $spellId): bool - { - if (!isset($this->spells[$spellId])) { - $this->spells[$spellId] = ['level' => 1]; - return true; - } - return false; - } - - /** - * 升级法术等级 - */ - public function upgradeSpell(int $spellId): bool - { - if (!isset($this->spells[$spellId])) { - return false; - } - $this->spells[$spellId]['level'] = min($this->spells[$spellId]['level'] + 1, 10); - return true; - } - - /** - * 检查是否已学习法术 - */ - public function hasSpell(int $spellId): bool - { - return isset($this->spells[$spellId]); - } - - /** - * 获取法术等级 - */ - public function getSpellLevel(int $spellId): int - { - return $this->spells[$spellId]['level'] ?? 0; - } - - /** - * 添加法术资源书 - */ - public function addSpellBook(int $spellId, int $quantity = 1): void - { - if (!isset($this->spellBooks[$spellId])) { - $this->spellBooks[$spellId] = 0; - } - $this->spellBooks[$spellId] += $quantity; - } - - /** - * 消耗法术资源书 - */ - public function spendSpellBooks(int $spellId, int $quantity = 1): bool - { - if (($this->spellBooks[$spellId] ?? 0) >= $quantity) { - $this->spellBooks[$spellId] -= $quantity; - return true; - } - return false; - } - - /** - * 获取法术资源书数量 - */ - public function getSpellBookCount(int $spellId): int - { - return $this->spellBooks[$spellId] ?? 0; - } - /** * Player特有的经验获取,升级时会恢复生命值 */ diff --git a/src/Modules/Battle.php b/src/Modules/Battle.php index ee761f4..8442fcf 100644 --- a/src/Modules/Battle.php +++ b/src/Modules/Battle.php @@ -119,7 +119,7 @@ class Battle // 初始化同伴HP $this->initPartnerHp(); - while ($this->player->hp > 0) { + while ($this->player->hp >= 0) { Screen::delay(500000); // 创建敌人群组 @@ -237,21 +237,15 @@ class Battle $out->writeln("{$this->cyan}║{$this->reset} {$this->red}💀{$this->reset} {$this->white}{$enemy->name}{$this->reset} {$this->red}[已击败]{$this->reset}"); continue; } - $enemyHpPercent = max(0, $enemy->hp) / $enemy->baseHp; // 使用baseHp作为最大值近似,或者应该在hydrate时保存maxHp - // 实际上Monster没有maxHp属性,hp初始值就是最大值。但在战斗中hp会减少。 - // 我们需要知道最大HP。Monster::create时hp=baseHp+equipHp。 - // 简单起见,假设当前hp <= 初始hp。如果需要精确显示条,应该在Monster类加maxHp。 - // 这里暂时用 $enemy->baseHp + equipHp 估算,或者直接存一个 maxHp。 - // 为了简单,我们假设满血是初始状态。 - // 更好的做法是Monster类加一个maxHp属性。 - // 暂时用 $enemy->hp / $enemy->hp (如果满血) ... 不行。 - // 让我们修改Monster类加maxHp? 或者这里不显示条,只显示数值? - // 或者我们假定 create 出来的 hp 就是 maxHp。 - // $enemy->maxHp = $enemy->hp; // 在create里做最好。 - // 这里先只显示数值吧,或者大概估算。 - - $hpText = max(0, $enemy->hp); - $out->writeln("{$this->cyan}║{$this->reset} {$this->red}👹{$this->reset} {$this->bold}{$enemy->name}{$this->reset} Lv.{$enemy->level} HP: {$this->red}{$hpText}{$this->reset}"); + $enemyStats = $enemy->getStats(); + $enemyMaxHp = $enemyStats['maxHp']; + $enemyHpPercent = $enemyMaxHp > 0 ? $enemy->hp / $enemyMaxHp : 0; + $enemyHpBar = $this->renderHpBar($enemyHpPercent, 15); + $enemyHpText = $enemy->hp . "/" . $enemyMaxHp; + + $out->writeln("{$this->cyan}║{$this->reset} {$this->red}👹{$this->reset} {$this->bold}{$enemy->name}{$this->reset} Lv.{$enemy->level}"); + $out->writeln("{$this->cyan}║{$this->reset} {$enemyHpBar} {$this->white}{$enemyHpText}{$this->reset}"); + $out->writeln("{$this->cyan}║{$this->reset} {$this->yellow}⚔️{$this->reset} {$enemyStats['patk']}/{$enemyStats['matk']} {$this->green}🛡️{$this->reset} {$enemyStats['pdef']}/{$enemyStats['mdef']} {$this->red}💥{$this->reset} {$enemyStats['crit']}/{$enemyStats['critdmg']}%"); } $out->writeln("{$this->cyan}║{$this->reset}"); @@ -329,19 +323,22 @@ class Battle */ private function playerChooseAction(): string { - // 简化:默认使用普通攻击,除非有法术且魔法值充足 - // 为了简化战斗流程,我们先自动选择攻击 - // 在实战中可以添加交互菜单 - - // 检查是否有可以施放的法术 - if (empty($this->player->spells) || $this->player->mana < 15) { + // 检查是否有装备的法术 + $hasSpells = false; + foreach ($this->player->skillSlots as $slot => $spell) { + if ($spell !== null) { + $hasSpells = true; + break; + } + } + + if (!$hasSpells || $this->player->mana < 15) { return 'attack'; } - // 暂时选择法术的概率(可根据需要调整) - // 如果玩家有法术且魔法值充足,50% 概率选择法术 + // 如果玩家有法术且魔法值充足,40% 概率选择法术 $spellChance = rand(1, 100); - if ($spellChance <= 40) { // 40% 概率使用法术 + if ($spellChance <= 40) { return 'spell'; } @@ -355,53 +352,55 @@ class Battle { $stats = $this->player->getStats(); - // 随机选择一个已学的法术 + // 筛选可用法术 $availableSpells = []; - foreach ($this->player->spells as $spellId => $spellData) { - $spellInfo = $this->getSpellInfo($spellId); - if (!$spellInfo) continue; + foreach ($this->player->skillSlots as $slot => $spellItem) { + if ($spellItem === null) continue; - $cost = $spellInfo['cost'] ?? 0; - $upgrades = $this->spellsData['upgrades'] ?? []; - $level = $spellData['level'] ?? 1; - $upgradeInfo = $upgrades[$level] ?? []; - $costReduction = $upgradeInfo['cost_reduction'] ?? 0; - $actualCost = max(1, $cost - $costReduction); + $baseCost = $spellItem['cost'] ?? 20; + $enhanceLevel = $spellItem['enhanceLevel'] ?? 0; + // 强化减少消耗: 每级 -2 + $costReduction = $enhanceLevel * 2; + $actualCost = max(1, $baseCost - $costReduction); if ($this->player->mana >= $actualCost) { - $availableSpells[$spellId] = ['info' => $spellInfo, 'cost' => $actualCost, 'level' => $level]; + $availableSpells[] = [ + 'item' => $spellItem, + 'cost' => $actualCost, + 'level' => $enhanceLevel + ]; } } if (empty($availableSpells)) { // 如果没有可用的法术,改用普通攻击 $out->writeln("{$this->cyan}║{$this->reset} {$this->yellow}✦ 魔法值不足,改为普通攻击{$this->reset}"); - // 递归调用普通攻击 return $this->executePhysicalAttack($out); } // 随机选择一个可用的法术 - $selectedSpellId = array_rand($availableSpells); - $spellData = $availableSpells[$selectedSpellId]; - $spellInfo = $spellData['info']; - $actualCost = $spellData['cost']; - $spellLevel = $spellData['level']; + $selected = $availableSpells[array_rand($availableSpells)]; + $spellItem = $selected['item']; + $actualCost = $selected['cost']; + $enhanceLevel = $selected['level']; // 消耗魔法值 $this->player->spendMana($actualCost); - // 获取法术升级信息 - $upgrades = $this->spellsData['upgrades'] ?? []; - $upgradeInfo = $upgrades[$spellLevel] ?? []; - $damageBonus = $upgradeInfo['damage_bonus'] ?? 0; + // 计算强化加成: 每级 +5% 伤害 + $damageBonus = $enhanceLevel * 5; - $type = $spellInfo['type'] ?? ''; - $name = $spellInfo['name'] ?? '未知法术'; + $type = $spellItem['spellType'] ?? 'damage_single'; + $name = $spellItem['name'] ?? '未知法术'; + + // 构造兼容旧方法的 spellInfo + $spellInfo = $spellItem; + $spellInfo['type'] = $type; // 映射 spellType 到 type 以兼容 if ($type === 'damage_single') { - return $this->castDamageSingleSpell($out, $selectedSpellId, $spellInfo, $stats, $damageBonus, $name); + return $this->castDamageSingleSpell($out, 0, $spellInfo, $stats, $damageBonus, $name); } elseif ($type === 'damage_aoe') { - return $this->castDamageAoeSpell($out, $selectedSpellId, $spellInfo, $stats, $damageBonus, $name); + return $this->castDamageAoeSpell($out, 0, $spellInfo, $stats, $damageBonus, $name); } elseif ($type === 'support') { return $this->castSupportSpell($out, $spellInfo, $stats, $name); } @@ -625,9 +624,9 @@ class Battle } /** - * 生成法术资源书掉落 + * 生成法术物品掉落 (新法术系统) */ - private function generateSpellTomeDrop(Actor $enemy): ?array + private function generateSpellDrop(Actor $enemy): ?array { // 尝试从独立的副本法术映射文件获取(每个副本有自己的法术池) $dungeonId = $this->game->dungeonId; @@ -651,21 +650,9 @@ class Battle // 从法术池中随机选择一个法术ID $spellId = $spellIds[array_rand($spellIds)]; - $spellInfo = $this->getSpellInfo($spellId); - if (!$spellInfo) return null; - - // 创建法术资源书物品 - $tome = [ - 'name' => $spellInfo['name'] . '的法术书', - 'type' => 'spell_tome', - 'quality' => $spellInfo['quality'] ?? 'common', - 'level' => $enemy->level, - 'spell_id' => $spellId, - 'spell_name' => $spellInfo['name'], - 'desc' => "能够学习或升级 {$spellInfo['name']} 的法术资源书", - ]; - - return $tome; + + // 使用 Item::createSpell 创建法术物品 + return \Game\Entities\Item::createSpell($spellId, $enemy->level); } private function playerAttack($out): bool @@ -881,17 +868,13 @@ class Battle } } - // 掉落法术资源书 - $spellTomeDropChance = 15; // 15% 概率掉落法术资源书 - if (rand(1, 100) <= $spellTomeDropChance && !empty($this->spellsData)) { - $spellTome = $this->generateSpellTomeDrop($enemy); - if ($spellTome) { - // 添加到玩家的法术资源书库存 - $spellId = $spellTome['spell_id'] ?? 0; - if ($spellId > 0) { - $this->player->addSpellBook($spellId, 1); - $allDrops[] = $spellTome; - } + // 掉落法术物品 (新法术系统) + $spellDropChance = 15; // 15% 概率掉落法术 + if (rand(1, 100) <= $spellDropChance && !empty($this->spellsData)) { + $spellItem = $this->generateSpellDrop($enemy); + if ($spellItem) { + $this->player->addItem($spellItem); + $allDrops[] = $spellItem; } } } diff --git a/src/Modules/EquipmentEnhancePanel.php b/src/Modules/EquipmentEnhancePanel.php index ff1ecd0..9593b97 100644 --- a/src/Modules/EquipmentEnhancePanel.php +++ b/src/Modules/EquipmentEnhancePanel.php @@ -6,10 +6,11 @@ use Game\Core\ItemDisplay; use Game\Core\Screen; use Game\Core\Colors; use Game\Services\EquipmentEnhancer; +use Game\Entities\Partner; /** * 装备强化面板 - * 允许玩家快速强化库存或装备栏中的任何装备 + * 允许玩家和队友强化装备 */ class EquipmentEnhancePanel { @@ -46,6 +47,62 @@ class EquipmentEnhancePanel $out->writeln("{$this->cyan}║{$this->reset} {$this->white}灵石: {$this->yellow}{$player->spiritStones}{$this->reset}"); $out->writeln("{$this->cyan}╠════════════════════════════════════╣{$this->reset}"); + // 选择强化对象 + $out->writeln("{$this->cyan}║{$this->reset} {$this->bold}选择强化对象:{$this->reset}"); + $out->writeln("{$this->cyan}║{$this->reset} [1] 强化玩家装备"); + + if (!empty($player->partners)) { + $idx = 2; + foreach ($player->partners as $partner) { + $out->writeln("{$this->cyan}║{$this->reset} [{$idx}] 强化 {$partner->name} 的装备"); + $idx++; + } + } + + $out->writeln("{$this->cyan}║{$this->reset} [0] 返回"); + $out->writeln("{$this->cyan}╚════════════════════════════════════╝{$this->reset}"); + + $choice = Screen::input($out, "选择: "); + + if ($choice === '0') { + $this->game->state = Game::MENU; + return; + } + + if ($choice === '1') { + $this->showPlayerEquipment(); + continue; + } + + // 处理队友选择 + $choiceNum = (int)$choice; + $partnerIdx = $choiceNum - 2; + + $partnerList = array_values($player->partners); + if (isset($partnerList[$partnerIdx])) { + $this->showPartnerEquipment($partnerList[$partnerIdx]); + } + } + } + + /** + * 显示玩家装备强化界面 + */ + private function showPlayerEquipment() + { + while (true) { + Screen::clear($this->game->output); + + $out = $this->game->output; + $player = $this->game->player; + + $out->writeln(""); + $out->writeln("{$this->cyan}╔════════════════════════════════════╗{$this->reset}"); + $out->writeln("{$this->cyan}║{$this->reset} {$this->bold}玩家装备强化{$this->reset} {$this->cyan}║{$this->reset}"); + $out->writeln("{$this->cyan}╠════════════════════════════════════╣{$this->reset}"); + $out->writeln("{$this->cyan}║{$this->reset} {$this->white}灵石: {$this->yellow}{$player->spiritStones}{$this->reset}"); + $out->writeln("{$this->cyan}╠════════════════════════════════════╣{$this->reset}"); + // 显示已装备物品 $out->writeln("{$this->cyan}║{$this->reset} {$this->bold}当前装备:{$this->reset}"); @@ -71,7 +128,6 @@ class EquipmentEnhancePanel $out->writeln("{$this->cyan}║{$this->reset} {$this->bold}库存物品:{$this->reset}"); // 显示库存中可强化的物品 - $inventoryStart = $slotIndex; $inventoryItems = []; foreach ($player->inventory as $invIndex => $item) { @@ -97,7 +153,6 @@ class EquipmentEnhancePanel // 处理返回 if ($choice === '0') { - $this->game->state = Game::MENU; return; } @@ -140,6 +195,85 @@ class EquipmentEnhancePanel } } + /** + * 显示队友装备强化界面 + */ + private function showPartnerEquipment(Partner $partner) + { + while (true) { + Screen::clear($this->game->output); + + $out = $this->game->output; + $player = $this->game->player; + + $out->writeln(""); + $out->writeln("{$this->cyan}╔════════════════════════════════════╗{$this->reset}"); + $out->writeln("{$this->cyan}║{$this->reset} {$this->bold}{$partner->name} 的装备强化{$this->reset} {$this->cyan}║{$this->reset}"); + $out->writeln("{$this->cyan}╠════════════════════════════════════╣{$this->reset}"); + $out->writeln("{$this->cyan}║{$this->reset} {$this->white}灵石: {$this->yellow}{$player->spiritStones}{$this->reset}"); + $out->writeln("{$this->cyan}╠════════════════════════════════════╣{$this->reset}"); + + // 显示队友已装备的物品 + $out->writeln("{$this->cyan}║{$this->reset} {$this->bold}当前装备:{$this->reset}"); + + $slots = ['weapon' => '武器', 'armor' => '护甲', 'boots' => '靴子', 'ring' => '戒指', 'necklace' => '项链']; + $equipped = []; + $slotIndex = 1; + + foreach ($slots as $slot => $slotName) { + $item = $partner->equip[$slot] ?? null; + + if ($item) { + $str = ItemDisplay::renderListItem($item); + $out->writeln("{$this->cyan}║[$slotIndex]$str"); + $equipped[$slotIndex] = ['slot' => $slot, 'item' => $item]; + } else { + $out->writeln("{$this->cyan}║{$this->reset} [{$slotIndex}] {$slotName}: {$this->red}未装备{$this->reset}"); + } + + $slotIndex++; + } + + $out->writeln("{$this->cyan}╠════════════════════════════════════╣{$this->reset}"); + $out->writeln("{$this->cyan}║{$this->reset}"); + $out->writeln("{$this->cyan}║{$this->reset} 选择要强化的装备编号或 [0] 返回"); + $out->writeln("{$this->cyan}║{$this->reset} 输入 [info 编号] 查看强化信息"); + $out->writeln("{$this->cyan}╚════════════════════════════════════╝{$this->reset}"); + + $choice = Screen::input($out, "选择: "); + + // 处理返回 + if ($choice === '0') { + return; + } + + // 处理查看信息 + if (strpos($choice, 'info') === 0) { + $parts = explode(' ', $choice); + if (isset($parts[1])) { + $itemIndex = (int)$parts[1]; + $this->showPartnerEnhanceInfo($equipped, $itemIndex); + } + continue; + } + + $itemIndex = (int)$choice; + + // 从装备中强化 + if (isset($equipped[$itemIndex])) { + $this->selectPartnerTargetLevelAndEnhance( + $partner, + $equipped[$itemIndex]['slot'], + $equipped[$itemIndex]['item'] + ); + continue; + } + + $out->writeln("{$this->red}无效选择{$this->reset}"); + Screen::sleep(1); + } + } + /** * 选择目标强化等级并进行强化 */ @@ -216,6 +350,73 @@ class EquipmentEnhancePanel } } + /** + * 为队友选择目标强化等级并进行强化 + */ + private function selectPartnerTargetLevelAndEnhance( + Partner $partner, + string $slot, + array &$item + ) { + $out = $this->game->output; + $player = $this->game->player; + $currentLevel = $item['enhanceLevel'] ?? 0; + + Screen::clear($out); + + $out->writeln(""); + $out->writeln("{$this->cyan}╔════════════════════════════════════╗{$this->reset}"); + $out->writeln("{$this->cyan}║{$this->reset} {$this->bold}强 化 等 级 选 择{$this->reset} {$this->cyan}║{$this->reset}"); + $out->writeln("{$this->cyan}╠════════════════════════════════════╣{$this->reset}"); + + $out->writeln("{$this->cyan}║{$this->reset} 装备: {$item['name']}"); + $out->writeln("{$this->cyan}║{$this->reset} 当前等级: {$this->yellow}+{$currentLevel}{$this->reset}"); + $out->writeln("{$this->cyan}║{$this->reset}"); + $out->writeln("{$this->cyan}║{$this->reset} 可选等级:"); + $out->writeln("{$this->cyan}║{$this->reset}"); + + // 显示可选择的目标等级 + for ($target = $currentLevel + 1; $target <= EquipmentEnhancer::MAX_ENHANCE_LEVEL; $target++) { + $cost = EquipmentEnhancer::getTotalCost($currentLevel, $target); + $canAfford = $player->spiritStones >= $cost ? "{$this->green}✓{$this->reset}" : "{$this->red}✗{$this->reset}"; + $out->writeln("{$this->cyan}║{$this->reset} [{$target}] +{$target} (需要: {$cost} 灵石) {$canAfford}"); + } + + $out->writeln("{$this->cyan}║{$this->reset} [0] 手动强化 (一次一级)"); + $out->writeln("{$this->cyan}║{$this->reset}"); + $out->writeln("{$this->cyan}║{$this->reset} 当前灵石: {$this->yellow}{$player->spiritStones}{$this->reset}"); + $out->writeln("{$this->cyan}╚════════════════════════════════════╝{$this->reset}"); + + $choice = Screen::input($out, "选择目标等级: "); + + if ($choice === '0') { + // 手动强化一次 + $this->enhancePartnerEquipment($partner, $slot, $item); + return; + } + + $targetLevel = (int)$choice; + + // 验证选择有效性 + if ($targetLevel <= $currentLevel || $targetLevel > EquipmentEnhancer::MAX_ENHANCE_LEVEL) { + $out->writeln("{$this->red}无效的目标等级{$this->reset}"); + Screen::sleep(1); + return; + } + + // 检查灵石是否足够 + $totalCost = EquipmentEnhancer::getTotalCost($currentLevel, $targetLevel); + if ($player->spiritStones < $totalCost) { + $lack = $totalCost - $player->spiritStones; + $out->writeln("{$this->red}灵石不足!还需要 {$lack} 灵石{$this->reset}"); + Screen::sleep(1); + return; + } + + // 执行自动强化 + $this->enhancePartnerToLevel($partner, $slot, $item, $targetLevel); + } + /** * 自动强化装备到目标等级 */ @@ -319,6 +520,104 @@ class EquipmentEnhancePanel Screen::pause($out); } + /** + * 为队友自动强化装备到目标等级 + */ + private function enhancePartnerToLevel( + Partner $partner, + string $slot, + array &$item, + int $targetLevel + ) { + $out = $this->game->output; + $player = $this->game->player; + $currentLevel = $item['enhanceLevel'] ?? 0; + $item['enhanceLevel'] = $item['enhanceLevel'] ?? 0; + Screen::clear($out); + + $out->writeln(""); + $out->writeln("{$this->cyan}╔════════════════════════════════════╗{$this->reset}"); + $out->writeln("{$this->cyan}║{$this->reset} {$this->bold}自 动 强 化 中{$this->reset} {$this->cyan}║{$this->reset}"); + $out->writeln("{$this->cyan}╠════════════════════════════════════╣{$this->reset}"); + + $out->writeln("{$this->cyan}║{$this->reset} 装备: {$item['name']}"); + $out->writeln("{$this->cyan}║{$this->reset} 目标: +{$targetLevel}"); + $out->writeln("{$this->cyan}║{$this->reset}"); + + $totalAttempts = 0; + $successCount = 0; + $failureCount = 0; + $downgrades = 0; + $startingSpirits = $player->spiritStones; + + // 循环强化直到达到目标等级或灵石用完 + while ($item['enhanceLevel'] < $targetLevel && $player->spiritStones > 0) { + // 检查下一级是否可以强化(灵石足够) + $config = EquipmentEnhancer::getConfig($item['enhanceLevel']); + if (!$config || $player->spiritStones < $config['cost']) { + break; + } + + $totalAttempts++; + $oldLevel = $item['enhanceLevel']; + + // 执行强化 + $result = EquipmentEnhancer::enhance($item, $player); + + if ($result['success']) { + $successCount++; + $out->writeln("{$this->cyan}║{$this->reset} 第 {$totalAttempts} 次: {$this->green}✓ 成功{$this->reset} +{$oldLevel} → +{$result['newLevel']}"); + } else { + $failureCount++; + if ($result['downgraded']) { + $downgrades++; + $out->writeln("{$this->cyan}║{$this->reset} 第 {$totalAttempts} 次: {$this->red}✗ 失败并降级{$this->reset} +{$oldLevel} → +{$result['newLevel']}"); + } else { + $out->writeln("{$this->cyan}║{$this->reset} 第 {$totalAttempts} 次: {$this->yellow}✗ 失败{$this->reset} 等级保持 +{$oldLevel}"); + } + } + + // 更新队友装备 + $partner->equip[$slot]['enhanceLevel'] = $item['enhanceLevel']; + } + + // 显示最终结果 + $out->writeln("{$this->cyan}║{$this->reset}"); + $out->writeln("{$this->cyan}╠════════════════════════════════════╣{$this->reset}"); + $out->writeln("{$this->cyan}║{$this->reset} {$this->bold}强 化 完 成{$this->reset}"); + $out->writeln("{$this->cyan}╠════════════════════════════════════╣{$this->reset}"); + + $finalLevel = $item['enhanceLevel']; + $spiritUsed = $startingSpirits - $player->spiritStones; + + $out->writeln("{$this->cyan}║{$this->reset} 装备等级: {$this->yellow}+{$currentLevel}{$this->reset} → {$this->yellow}+{$finalLevel}{$this->reset}"); + $out->writeln("{$this->cyan}║{$this->reset} 强化尝试: {$this->yellow}{$totalAttempts}{$this->reset}"); + $out->writeln("{$this->cyan}║{$this->reset} 成功次数: {$this->green}{$successCount}{$this->reset}"); + $out->writeln("{$this->cyan}║{$this->reset} 失败次数: {$this->red}{$failureCount}{$this->reset}"); + if ($downgrades > 0) { + $out->writeln("{$this->cyan}║{$this->reset} 降级次数: {$this->red}{$downgrades}{$this->reset}"); + } + $out->writeln("{$this->cyan}║{$this->reset} 灵石消耗: {$this->yellow}{$spiritUsed}{$this->reset}"); + $out->writeln("{$this->cyan}║{$this->reset} 剩余灵石: {$this->yellow}{$player->spiritStones}{$this->reset}"); + + if ($finalLevel >= $targetLevel) { + $out->writeln("{$this->cyan}║{$this->reset}"); + $out->writeln("{$this->cyan}║{$this->reset} {$this->green}✓ 已达到目标等级!{$this->reset}"); + } elseif ($player->spiritStones <= 0) { + $out->writeln("{$this->cyan}║{$this->reset}"); + $out->writeln("{$this->cyan}║{$this->reset} {$this->yellow}灵石已用完{$this->reset}"); + } else { + $lack = EquipmentEnhancer::getTotalCost($finalLevel, $targetLevel); + $out->writeln("{$this->cyan}║{$this->reset}"); + $out->writeln("{$this->cyan}║{$this->reset} {$this->yellow}灵石不足,还需 {$lack} 灵石{$this->reset}"); + } + + $out->writeln("{$this->cyan}╚════════════════════════════════════╝{$this->reset}"); + + $this->game->saveState(); + Screen::pause($out); + } + /** * 强化已装备的物品(手动一次一级) */ @@ -371,6 +670,51 @@ class EquipmentEnhancePanel Screen::pause($out); } + /** + * 强化队友已装备的物品 + */ + private function enhancePartnerEquipment(Partner $partner, string $slot, array &$item) + { + $out = $this->game->output; + $player = $this->game->player; + + // 使用 EquipmentEnhancer 执行强化 + $result = EquipmentEnhancer::enhance($item, $player); + + // 更新队友装备 + $partner->equip[$slot]['enhanceLevel'] = $item['enhanceLevel']; + + Screen::clear($out); + $out->writeln(""); + $out->writeln("{$this->cyan}╔════════════════════════════════════╗{$this->reset}"); + $out->writeln("{$this->cyan}║{$this->reset} {$this->bold}强 化 结 果{$this->reset} {$this->cyan}║{$this->reset}"); + $out->writeln("{$this->cyan}╚════════════════════════════════════╝{$this->reset}"); + $out->writeln(""); + + if ($result['success']) { + $out->writeln("{$this->green}★ 强化成功!{$this->reset}"); + $out->writeln("{$item['name']} 强化等级提升至 {$this->yellow}+{$result['newLevel']}{$this->reset}"); + } else { + if ($result['cost'] === 0) { + $out->writeln("{$this->red}✗ {$result['message']}{$this->reset}"); + } else { + $out->writeln("{$this->red}✗ 强化失败!{$this->reset}"); + if ($result['downgraded']) { + $out->writeln("{$this->red}{$item['name']} 强化等级下降至 +{$result['newLevel']}{$this->reset}"); + } else { + $out->writeln("强化等级保持不变"); + } + } + } + + $out->writeln(""); + $out->writeln("花费灵石: {$result['cost']}"); + $out->writeln("当前灵石: {$player->spiritStones}"); + + $this->game->saveState(); + Screen::pause($out); + } + /** * 强化库存中的物品 */ @@ -470,4 +814,57 @@ class EquipmentEnhancePanel Screen::pause($out); } + + /** + * 显示队友装备的强化信息 + */ + private function showPartnerEnhanceInfo(array $equipped, int $itemIndex) + { + $out = $this->game->output; + $player = $this->game->player; + + $item = null; + if (isset($equipped[$itemIndex])) { + $item = $equipped[$itemIndex]['item']; + } + + if (!$item) { + return; + } + + Screen::clear($out); + + $currentLevel = $item['enhanceLevel'] ?? 0; + $config = EquipmentEnhancer::getConfig($currentLevel); + + $out->writeln(""); + $out->writeln("{$this->cyan}╔════════════════════════════════════╗{$this->reset}"); + $out->writeln("{$this->cyan}║{$this->reset} {$this->bold}强化信息{$this->reset} {$this->cyan}║{$this->reset}"); + $out->writeln("{$this->cyan}╠════════════════════════════════════╣{$this->reset}"); + + $out->writeln("{$this->cyan}║{$this->reset} 装备: {$item['name']}"); + $out->writeln("{$this->cyan}║{$this->reset} 当前强化: {$this->yellow}+{$currentLevel}{$this->reset}"); + + if ($config) { + $nextBonus = EquipmentEnhancer::getEnhanceBonusPercent($currentLevel + 1); + $out->writeln("{$this->cyan}║{$this->reset}"); + $out->writeln("{$this->cyan}║{$this->reset} 下一级信息:"); + $out->writeln("{$this->cyan}║{$this->reset} 成功率: {$this->yellow}{$config['rate']}%{$this->reset}"); + $out->writeln("{$this->cyan}║{$this->reset} 花费: {$config['cost']} 灵石"); + if ($config['downgrade'] > 0) { + $out->writeln("{$this->cyan}║{$this->reset} 降级率: {$this->red}{$config['downgrade']}%{$this->reset}"); + } + $out->writeln("{$this->cyan}║{$this->reset} 属性加成: {$nextBonus}%"); + } else { + $out->writeln("{$this->cyan}║{$this->reset} {$this->green}✓ 已达最大强化等级{$this->reset}"); + } + + $out->writeln("{$this->cyan}╠════════════════════════════════════╣{$this->reset}"); + $out->writeln("{$this->cyan}║{$this->reset}"); + $out->writeln("{$this->cyan}║{$this->reset} 当前灵石: {$this->yellow}{$player->spiritStones}{$this->reset}"); + $out->writeln("{$this->cyan}║{$this->reset}"); + $out->writeln("{$this->cyan}╚════════════════════════════════════╝{$this->reset}"); + + Screen::pause($out); + } } diff --git a/src/Modules/Menu.php b/src/Modules/Menu.php index 548a46d..0252a45 100644 --- a/src/Modules/Menu.php +++ b/src/Modules/Menu.php @@ -19,10 +19,8 @@ class Menu $out->writeln("[2] 属性面板"); $out->writeln("[3] 背包"); $out->writeln("[4] 拜访故人"); - $out->writeln("[5] 同伴管理"); - $out->writeln("[6] 天赋系统"); - $out->writeln("[7] 装备强化"); - $out->writeln("[8] 法术系统"); + $out->writeln("[5] 天赋系统"); + $out->writeln("[6] 装备强化"); $out->writeln("[0] 退出"); $out->writeln("========================="); @@ -41,17 +39,11 @@ class Menu $this->game->state = Game::NPC; } elseif ($choice == 5) { - $this->game->state = Game::PARTNER; - - } elseif ($choice == 6) { $this->game->state = Game::TALENT; - } elseif ($choice == 7) { + } elseif ($choice == 6) { $this->game->state = Game::EQUIPMENT_ENHANCE; - } elseif ($choice == 8) { - $this->game->state = Game::SPELL; - } elseif ($choice == 0) { $this->game->state = Game::EXIT; diff --git a/src/Modules/NpcPanel.php b/src/Modules/NpcPanel.php index 66fa361..7444748 100644 --- a/src/Modules/NpcPanel.php +++ b/src/Modules/NpcPanel.php @@ -114,7 +114,7 @@ class NpcPanel $this->game->output->writeln("[0] 离开"); $choice = Input::ask($this->game->output, "请选择: "); - + $choice = is_numeric($choice) ? $choice : 0; if ($choice == 0) return; if (isset($actionKeys[$choice - 1])) { diff --git a/src/Modules/PartnerPanel.php b/src/Modules/PartnerPanel.php deleted file mode 100644 index 61f2d07..0000000 --- a/src/Modules/PartnerPanel.php +++ /dev/null @@ -1,288 +0,0 @@ -reset = Colors::RESET; - $this->cyan = Colors::CYAN; - $this->green = Colors::GREEN; - $this->yellow = Colors::YELLOW; - $this->red = Colors::RED; - $this->magenta = Colors::MAGENTA; - $this->white = Colors::WHITE; - } - - public function show() - { - while (true) { - Screen::clear($this->game->output); - $this->game->output->writeln("{$this->cyan}========== 同伴管理 =========={$this->reset}"); - $this->game->output->writeln(""); - - $partners = $this->game->player->partners; - - if (empty($partners)) { - $this->game->output->writeln("{$this->white}暂无同伴,可通过拜访故人招募。{$this->reset}"); - } else { - $idx = 1; - foreach ($partners as $partner) { - $stats = $partner->getStats(); - $this->game->output->writeln("[{$idx}] {$this->magenta}{$partner->name}{$this->reset} Lv.{$partner->level}"); - $this->game->output->writeln(" HP:{$stats['maxHp']} 物攻:{$stats['patk']} 魔攻:{$stats['matk']} 暴击:{$stats['crit']}%"); - $idx++; - } - } - - $this->game->output->writeln(""); - $this->game->output->writeln("{$this->cyan}=============================={$this->reset}"); - $this->game->output->writeln("输入编号查看详情"); - $this->game->output->writeln("[0] 返回"); - - $choice = Input::ask($this->game->output, "请选择: "); - - if ($choice == 0) { - $this->game->state = Game::MENU; - return; - } - - $partnerList = array_values($partners); - if (isset($partnerList[$choice-1])) { - $this->showPartnerDetail($partnerList[$choice-1]); - } - } - } - - private function showPartnerDetail(Partner $partner) - { - while (true) { - Screen::clear($this->game->output); - $stats = $partner->getStats(); - - $this->game->output->writeln("{$this->cyan}========== {$partner->name} =========={$this->reset}"); - $this->game->output->writeln(""); - $this->game->output->writeln("等级: {$this->yellow}Lv.{$partner->level}{$this->reset}"); - $this->game->output->writeln("经验: {$this->cyan}{$partner->exp}/{$partner->maxExp}{$this->reset}"); - $this->game->output->writeln(""); - $this->game->output->writeln("{$this->white}--- 属性 ---{$this->reset}"); - $this->game->output->writeln("生命值: {$this->red}{$stats['hp']}{$this->reset}/{$stats['maxHp']}"); - $this->game->output->writeln("物理攻击: {$this->red}{$stats['patk']}{$this->reset}"); - $this->game->output->writeln("魔法攻击: {$this->cyan}{$stats['matk']}{$this->reset}"); - $this->game->output->writeln("物理防御: {$this->red}{$stats['pdef']}{$this->reset}"); - $this->game->output->writeln("魔法防御: {$this->cyan}{$stats['mdef']}{$this->reset}"); - $this->game->output->writeln("暴击率: {$this->yellow}{$stats['crit']}%{$this->reset}"); - $this->game->output->writeln("暴击伤害: {$this->yellow}{$stats['critdmg']}%{$this->reset}"); - $this->game->output->writeln(""); - - // 显示天赋(自动分配) - $this->game->output->writeln("{$this->white}--- 天赋 (自动) ---{$this->reset}"); - $totalTalentPoints = $partner->getTotalTalentPoints(); - $talentNames = ['hp' => '生命', 'patk' => '物攻', 'matk' => '魔攻', 'pdef' => '物防', 'mdef' => '魔防', 'crit' => '暴击', 'critdmg' => '暴伤']; - $talentParts = []; - foreach ($talentNames as $key => $name) { - if (isset($partner->talents[$key]) && $partner->talents[$key] > 0) { - $talentParts[] = "{$name}:{$partner->talents[$key]}"; - } - } - if (!empty($talentParts)) { - $this->game->output->writeln(implode(" | ", $talentParts)); - } else { - $this->game->output->writeln("{$this->cyan}(尚未分配){$this->reset}"); - } - $this->game->output->writeln(""); - - // 显示装备 - $this->game->output->writeln("{$this->white}--- 装备 ---{$this->reset}"); - $slots = ['weapon' => '武器', 'armor' => '护甲', 'ring' => '戒指', 'boots' => '靴子', 'necklace' => '项链']; - foreach ($slots as $slot => $name) { - $item = $partner->equip[$slot] ?? null; - $slotLines = ItemDisplay::renderSlot($name, $item, ""); - foreach ($slotLines as $line) { - $this->game->output->writeln($line); - } - } - - $this->game->output->writeln(""); - $this->game->output->writeln("{$this->cyan}=============================={$this->reset}"); - $this->game->output->writeln("[1] 装备物品"); - $this->game->output->writeln("[2] 卸下装备"); - $this->game->output->writeln("[3] {$this->red}解散同伴{$this->reset}"); - $this->game->output->writeln("[0] 返回"); - - $choice = Input::ask($this->game->output, "请选择: "); - - switch ($choice) { - case '1': - $this->equipItem($partner); - break; - case '2': - $this->unequipItem($partner); - break; - case '3': - if ($this->dismissPartner($partner)) { - return; - } - break; - case '0': - return; - } - } - } - - private function equipItem(Partner $partner) - { - Screen::clear($this->game->output); - $this->game->output->writeln("{$this->cyan}========== 装备物品 =========={$this->reset}"); - - // 筛选可装备物品 - $equipableItems = []; - foreach ($this->game->player->inventory as $idx => $item) { - $type = $item['type'] ?? ''; - if (in_array($type, ['weapon', 'armor', 'ring', 'boots', 'necklace'])) { - $equipableItems[$idx] = $item; - } - } - - if (empty($equipableItems)) { - $this->game->output->writeln("{$this->white}没有可装备的物品{$this->reset}"); - Screen::pause($this->game->output); - return; - } - - $displayIdx = 1; - $idxMap = []; - foreach ($equipableItems as $realIdx => $item) { - $displayStr = ItemDisplay::renderListItem($item, true, false); - $this->game->output->writeln("[{$displayIdx}] {$displayStr}"); - $idxMap[$displayIdx] = $realIdx; - $displayIdx++; - } - - $this->game->output->writeln("[0] 取消"); - - $choice = Input::ask($this->game->output, "选择装备: "); - - if ($choice == 0) return; - - if (!isset($idxMap[$choice])) { - $this->game->output->writeln("无效选择"); - Screen::sleep(1); - return; - } - - $realIdx = $idxMap[$choice]; - $item = $this->game->player->inventory[$realIdx]; - $slot = $item['type']; - - // 如果该槽位已有装备,先卸下 - if (!empty($partner->equip[$slot])) { - $oldItem = $partner->equip[$slot]; - $this->game->player->addItem($oldItem); - } - - // 装备新物品 - $partner->equip[$slot] = $item; - - // 从背包移除 - unset($this->game->player->inventory[$realIdx]); - $this->game->player->inventory = array_values($this->game->player->inventory); - - $this->game->saveState(); - $this->game->output->writeln("{$this->green}已装备 {$item['name']}!{$this->reset}"); - Screen::pause($this->game->output); - } - - private function unequipItem(Partner $partner) - { - Screen::clear($this->game->output); - $this->game->output->writeln("{$this->cyan}========== 卸下装备 =========={$this->reset}"); - - $slots = ['weapon' => '武器', 'armor' => '护甲', 'ring' => '戒指', 'boots' => '靴子', 'necklace' => '项链']; - $equipped = []; - $idx = 0; - - foreach ($slots as $slot => $name) { - if (!empty($partner->equip[$slot])) { - $item = $partner->equip[$slot]; - $this->game->output->writeln("[{$idx}] {$name}: " . ItemDisplay::formatName($item)); - $equipped[$idx] = $slot; - $idx++; - } - } - - if (empty($equipped)) { - $this->game->output->writeln("{$this->white}没有已装备的物品{$this->reset}"); - Screen::pause($this->game->output); - return; - } - - $this->game->output->writeln("[0] 取消"); - - $choice = Input::ask($this->game->output, "选择卸下: "); - - if ($choice == 0) return; - - if (!isset($equipped[$choice])) { - $this->game->output->writeln("无效选择"); - Screen::sleep(1); - return; - } - - $slot = $equipped[$choice]; - $item = $partner->equip[$slot]; - - // 放回背包 - $this->game->player->addItem($item); - $partner->equip[$slot] = null; - - $this->game->saveState(); - $this->game->output->writeln("{$this->green}已卸下 {$item['name']}!{$this->reset}"); - Screen::pause($this->game->output); - } - - private function dismissPartner(Partner $partner): bool - { - $this->game->output->writeln(""); - $this->game->output->writeln("{$this->red}确定要解散 {$partner->name} 吗?{$this->reset}"); - $this->game->output->writeln("{$this->white}解散后装备将返还背包{$this->reset}"); - - $confirm = Input::ask($this->game->output, "确认解散?[y/n]: "); - - if (strtolower($confirm) !== 'y') { - $this->game->output->writeln("取消解散"); - Screen::sleep(1); - return false; - } - - // 返还装备 - foreach ($partner->equip as $item) { - if (!empty($item)) { - $this->game->player->addItem($item); - } - } - - // 解散同伴 - $this->game->player->dismissPartner($partner->id); - $this->game->saveState(); - - $this->game->output->writeln("{$this->yellow}{$partner->name} 离开了队伍{$this->reset}"); - Screen::pause($this->game->output); - return true; - } -} diff --git a/src/Modules/StatsPanel.php b/src/Modules/StatsPanel.php index af863b2..016d258 100644 --- a/src/Modules/StatsPanel.php +++ b/src/Modules/StatsPanel.php @@ -4,8 +4,11 @@ namespace Game\Modules; use Game\Core\Colors; use Game\Core\Game; use Game\Core\Screen; +use Game\Core\Input; use Game\Core\ItemDisplay; use Game\Services\EquipmentEnhancer; +use Game\Entities\Actor; +use Game\Entities\Partner; class StatsPanel { @@ -50,6 +53,10 @@ class StatsPanel 'legendary' => '传说', ]; + // 当前查看的角色 + private ?Actor $currentActor = null; + private bool $isPlayer = true; + public function __construct(public Game $game) { $this->cyan = Colors::CYAN; $this->yellow = Colors::YELLOW; @@ -70,101 +77,437 @@ class StatsPanel public function show() { - $out = $this->game->output; - Screen::clear($out); + // 默认显示玩家 + $this->currentActor = $this->game->player; + $this->isPlayer = true; + + return $this->showCharacterSelect(); + } - $player = $this->game->player; + /** + * 显示角色选择界面 + */ + private function showCharacterSelect() + { + while (true) { + Screen::clear($this->game->output); + $out = $this->game->output; - // Calculate total stats using the new method - $totalStats = $player->getStats(); - $maxHp = $totalStats['maxHp']; - $totalPatk = $totalStats['patk']; - $totalMatk = $totalStats['matk']; - $totalPdef = $totalStats['pdef']; - $totalMdef = $totalStats['mdef']; - $totalCrit = $totalStats['crit']; - $totalCritdmg = $totalStats['critdmg']; + $out->writeln("{$this->cyan}========== 角色管理 =========={$this->reset}"); + $out->writeln(""); - $currentHp = $player->hp; - $name = "玩家"; - $level = $player->level; - $exp = $player->exp; - $maxExp = $player->maxExp; + // 显示玩家 + $playerStats = $this->game->player->getStats(); + $mark = $this->isPlayer && $this->currentActor === $this->game->player ? "{$this->green}►{$this->reset} " : " "; + $out->writeln("{$mark}[1] {$this->yellow}玩家{$this->reset} Lv.{$this->game->player->level}"); + $out->writeln(" HP:{$playerStats['maxHp']} 物攻:{$playerStats['patk']} 魔攻:{$playerStats['matk']} 暴击:{$playerStats['crit']}%"); - $out->writeln("╔════════════════════════════════════╗"); - $out->writeln("║ {$this->cyan}角色属性面板{$this->reset} ║"); - $out->writeln("╠════════════════════════════════════╣"); + // 显示队友 + $partners = $this->game->player->partners; + if (!empty($partners)) { + $out->writeln(""); + $out->writeln("{$this->white}--- 队友 ---{$this->reset}"); + $idx = 2; + foreach ($partners as $partner) { + $stats = $partner->getStats(); + $mark = !$this->isPlayer && $this->currentActor === $partner ? "{$this->green}►{$this->reset} " : " "; + $out->writeln("{$mark}[{$idx}] {$this->magenta}{$partner->name}{$this->reset} Lv.{$partner->level}"); + $out->writeln(" HP:{$stats['maxHp']} 物攻:{$stats['patk']} 魔攻:{$stats['matk']} 暴击:{$stats['crit']}%"); + $idx++; + } + } - $out->writeln("║ 名称: {$this->yellow}{$name}{$this->reset}"); - $out->writeln("║ 等级: {$level} (XP: {$exp}/{$maxExp})"); - $out->writeln("║ 💰灵石: {$this->green}{$player->spiritStones}{$this->reset}"); - $out->writeln("║ HP: {$this->red}{$currentHp}{$this->reset}/{$maxHp}"); - $out->writeln("║ 物攻: {$this->yellow}{$totalPatk}{$this->reset}"); - $out->writeln("║ 魔攻: {$this->blue}{$totalMatk}{$this->reset}"); - $out->writeln("║ 物防: {$this->yellow}{$totalPdef}{$this->reset}"); - $out->writeln("║ 魔防: {$this->blue}{$totalMdef}{$this->reset}"); - $out->writeln("║ 暴击: {$totalCrit} %"); - $out->writeln("║ 爆伤: {$totalCritdmg} %"); - $out->writeln("╠════════════════════════════════════╣"); - $out->writeln("║ {$this->magenta}装备栏{$this->reset}"); - $out->writeln("╠════════════════════════════════════╣"); + $out->writeln(""); + $out->writeln("{$this->cyan}=============================={$this->reset}"); + $out->writeln("输入编号查看详情"); + $out->writeln("[1] 查看玩家 | [0] 返回主菜单"); - $slotIndex = 1; - $slots = ['weapon', 'armor', 'boots', 'ring', 'necklace']; - $slotNames = [ - 'weapon' => '武器', - 'armor' => '护甲', - 'boots' => '鞋子', - 'ring' => '戒指', - 'necklace' => '项链', - ]; + $choice = Input::ask($out, "请选择: "); + + // Handle 'b' for back to menu + if (strtolower($choice) == 0) { + $this->game->state = Game::MENU; + return; + } + + $choice = is_numeric($choice) ? (int)$choice : 1; - foreach ($slots as $slot) { - $item = $player->equip[$slot] ?? null; - $slotName = $slotNames[$slot]; + if ($choice === 1) { + // 选择0总是选择玩家 + $this->currentActor = $this->game->player; + $this->isPlayer = true; + return $this->showActorStats(); + } elseif ($choice > 0) { + // 选择队友 + $partnerList = array_values($partners); + if (isset($partnerList[$choice - 2])) { + $this->currentActor = $partnerList[$choice - 2]; + $this->isPlayer = false; + return $this->showActorStats(); + } + } + } + } - if ($item) { - $slotLines = ItemDisplay::renderSlot($slotName, $item, "║ [{$slotIndex}] "); - foreach ($slotLines as $i => $line) { - if ($i === 0) { - $out->writeln($line); - } else { - $out->writeln("║ " . substr($line, 6)); // 缩进对齐 + /** + * 显示角色详细属性 + */ + private function showActorStats() + { + while (true) { + Screen::clear($this->game->output); + $out = $this->game->output; + + $actor = $this->currentActor; + $stats = $actor->getStats(); + + $name = $this->isPlayer ? "玩家" : $actor->name; + $nameColor = $this->isPlayer ? $this->yellow : $this->magenta; + + $out->writeln("╔════════════════════════════════════╗"); + $out->writeln("║ {$this->cyan}角色属性面板{$this->reset} ║"); + $out->writeln("╠════════════════════════════════════╣"); + + $out->writeln("║ 名称: {$nameColor}{$name}{$this->reset}"); + $out->writeln("║ 等级: {$actor->level} (XP: {$actor->exp}/{$actor->maxExp})"); + + if ($this->isPlayer) { + $out->writeln("║ 💰灵石: {$this->green}{$this->game->player->spiritStones}{$this->reset}"); + } + + $out->writeln("║ HP: {$this->red}{$stats['hp']}{$this->reset}/{$stats['maxHp']}"); + $out->writeln("║ 物攻: {$this->yellow}{$stats['patk']}{$this->reset}"); + $out->writeln("║ 魔攻: {$this->blue}{$stats['matk']}{$this->reset}"); + $out->writeln("║ 物防: {$this->yellow}{$stats['pdef']}{$this->reset}"); + $out->writeln("║ 魔防: {$this->blue}{$stats['mdef']}{$this->reset}"); + $out->writeln("║ 暴击: {$stats['crit']} %"); + $out->writeln("║ 爆伤: {$stats['critdmg']} %"); + + // 显示天赋信息 + if (!$this->isPlayer) { + $out->writeln("║"); + $out->writeln("║ {$this->white}天赋(自动分配){$this->reset}"); + $talentNames = ['hp' => '生命', 'patk' => '物攻', 'matk' => '魔攻', 'pdef' => '物防', 'mdef' => '魔防', 'crit' => '暴击', 'critdmg' => '暴伤']; + $talentParts = []; + foreach ($talentNames as $key => $tname) { + if (isset($actor->talents[$key]) && $actor->talents[$key] > 0) { + $talentParts[] = "{$tname}:{$actor->talents[$key]}"; } } - } else { - $out->writeln("║ [{$slotIndex}] {$this->cyan}{$slotName}{$this->reset}: " . - Colors::GRAY . '(空)' . Colors::RESET); + if (!empty($talentParts)) { + $talentStr = implode(" ", $talentParts); + $out->writeln("║ {$talentStr}"); + } + } + + $out->writeln("╠════════════════════════════════════╣"); + $out->writeln("║ {$this->magenta}装备栏{$this->reset}"); + $out->writeln("╠════════════════════════════════════╣"); + + $slotIndex = 1; + $slots = ['weapon', 'armor', 'boots', 'ring', 'necklace']; + $slotNames = [ + 'weapon' => '武器', + 'armor' => '护甲', + 'boots' => '鞋子', + 'ring' => '戒指', + 'necklace' => '项链', + ]; + + foreach ($slots as $slot) { + $item = $actor->equip[$slot] ?? null; + $slotName = $slotNames[$slot]; + + if ($item) { + $slotLines = ItemDisplay::renderSlot($slotName, $item, "║ [{$slotIndex}] "); + foreach ($slotLines as $i => $line) { + if ($i === 0) { + $out->writeln($line); + } else { + $out->writeln("║ " . substr($line, 6)); // 缩进对齐 + } + } + } else { + $out->writeln("║ [{$slotIndex}] {$this->cyan}{$slotName}{$this->reset}: " . + Colors::GRAY . '(空)' . Colors::RESET); + } + $slotIndex++; + } + + $out->writeln("╚════════════════════════════════════╝"); + $out->writeln(""); + + // 显示技能槽位 + $out->writeln("╔════════════════════════════════════╗"); + $out->writeln("║ {$this->magenta}技能栏{$this->reset}"); + $out->writeln("╠════════════════════════════════════╣"); + + $skillSlots = ['skill1', 'skill2', 'skill3', 'skill4']; + $skillIndex = 1; + foreach ($skillSlots as $slot) { + $spell = $actor->skillSlots[$slot] ?? null; + if ($spell) { + $slotLines = ItemDisplay::renderSlot("技能{$skillIndex}", $spell, "║ [{$skillIndex}] "); + foreach ($slotLines as $i => $line) { + if ($i === 0) { + $out->writeln($line); + } else { + $out->writeln("║ " . substr($line, 6)); + } + } + } else { + $out->writeln("║ [{$skillIndex}] {$this->cyan}技能{$skillIndex}{$this->reset}: " . Colors::GRAY . '(空)' . Colors::RESET); + } + $skillIndex++; + } + $out->writeln("╚════════════════════════════════════╝"); + $out->writeln(""); + + // 显示操作选项 - 统一玩家和队友的操作 + $out->writeln("[1] 装备物品 | [2] 卸下装备 | [3] 强化装备"); + $out->writeln("[5] 装备技能 | [6] 卸下技能 | [7] 强化技能"); + + if ($this->isPlayer) { + $out->writeln("[s] 切换角色 | [0] 返回"); + } else { + $out->writeln("[4] {$this->red}解散队友{$this->reset} | [s] 切换角色 | [0] 返回"); + } + + $choice = Screen::input($out, "选择操作:"); + + if ($choice == 0 || strtolower($choice) === 's') { + return $this->showCharacterSelect(); + } + + // 统一处理操作 + switch ($choice) { + case '1': + $this->equipItem($actor); + break; + case '2': + $this->unequipItem($actor); + break; + case '3': + $this->enhanceEquipment($actor); + break; + case '4': + if (!$this->isPlayer) { + $this->dismissPartner($actor); + return $this->showCharacterSelect(); // 解散后返回选择界面 + } + break; + case '5': + $this->equipSkill($actor); + break; + case '6': + $this->unequipSkill($actor); + break; + case '7': + $this->enhanceSkill($actor); + break; + } + } + } + + /** + * 为角色装备物品(统一处理玩家和队友) + */ + private function equipItem(Actor $actor) + { + Screen::clear($this->game->output); + $this->game->output->writeln("{$this->cyan}========== 装备物品 =========={$this->reset}"); + + // 筛选可装备物品 + $equipableItems = []; + foreach ($this->game->player->inventory as $idx => $item) { + $type = $item['type'] ?? ''; + if (in_array($type, ['weapon', 'armor', 'ring', 'boots', 'necklace'])) { + $equipableItems[$idx] = $item; } - $slotIndex++; } - $out->writeln("╚════════════════════════════════════╝"); - $out->writeln(""); - $out->writeln("[1-5] 强化装备 | [0] 返回"); - - $choice = Screen::input($out, "选择操作:"); - - if ($choice == 0) { - $this->game->state = Game::MENU; + if (empty($equipableItems)) { + $this->game->output->writeln("{$this->white}没有可装备的物品{$this->reset}"); + Screen::pause($this->game->output); return; } - $choiceInt = intval($choice); - if ($choiceInt >= 1 && $choiceInt <= 5) { - $selectedSlot = $slots[$choiceInt - 1]; - $this->showEnhancePanel($selectedSlot); + $displayIdx = 1; + $idxMap = []; + foreach ($equipableItems as $realIdx => $item) { + $displayStr = ItemDisplay::renderListItem($item, true, false); + $this->game->output->writeln("[{$displayIdx}] {$displayStr}"); + $idxMap[$displayIdx] = $realIdx; + $displayIdx++; } - return $this->show(); + $this->game->output->writeln("[0] 取消"); + + $choice = Input::ask($this->game->output, "选择装备: "); + + if ($choice == 0) return; + + if (!isset($idxMap[$choice])) { + $this->game->output->writeln("无效选择"); + Screen::sleep(1); + return; + } + + $realIdx = $idxMap[$choice]; + $item = $this->game->player->inventory[$realIdx]; + $slot = $item['type']; + + // 如果该槽位已有装备,先卸下 + if (!empty($actor->equip[$slot])) { + $oldItem = $actor->equip[$slot]; + $this->game->player->addItem($oldItem); + } + + // 装备新物品 + $actor->equip[$slot] = $item; + + // 从背包移除 + unset($this->game->player->inventory[$realIdx]); + $this->game->player->inventory = array_values($this->game->player->inventory); + + $this->game->saveState(); + $this->game->output->writeln("{$this->green}已装备 {$item['name']}!{$this->reset}"); + Screen::pause($this->game->output); } - private function showEnhancePanel(string $slot) + /** + * 为角色卸下装备(统一处理玩家和队友) + */ + private function unequipItem(Actor $actor) + { + Screen::clear($this->game->output); + $this->game->output->writeln("{$this->cyan}========== 卸下装备 =========={$this->reset}"); + + $slots = ['weapon' => '武器', 'armor' => '护甲', 'ring' => '戒指', 'boots' => '靴子', 'necklace' => '项链']; + $equipped = []; + $idx = 1; + + foreach ($slots as $slot => $name) { + if (!empty($actor->equip[$slot])) { + $item = $actor->equip[$slot]; + $this->game->output->writeln("[{$idx}] {$name}: " . ItemDisplay::formatName($item)); + $equipped[$idx] = $slot; + $idx++; + } + } + + if (empty($equipped)) { + $this->game->output->writeln("{$this->white}没有已装备的物品{$this->reset}"); + Screen::pause($this->game->output); + return; + } + + $this->game->output->writeln("[0] 取消"); + + $choice = Input::ask($this->game->output, "选择卸下: "); + + if ($choice == 0) return; + + if (!isset($equipped[$choice])) { + $this->game->output->writeln("无效选择"); + Screen::sleep(1); + return; + } + + $slot = $equipped[$choice]; + $item = $actor->equip[$slot]; + + // 放回背包 + $this->game->player->addItem($item); + $actor->equip[$slot] = null; + + $this->game->saveState(); + $this->game->output->writeln("{$this->green}已卸下 {$item['name']}!{$this->reset}"); + Screen::pause($this->game->output); + } + + /** + * 解散队友 + */ + private function dismissPartner(Partner $partner): bool + { + $this->game->output->writeln(""); + $this->game->output->writeln("{$this->red}确定要解散 {$partner->name} 吗?{$this->reset}"); + $this->game->output->writeln("{$this->white}解散后装备将返还背包{$this->reset}"); + + $confirm = Input::ask($this->game->output, "确认解散?[y/n]: "); + + if (strtolower($confirm) !== 'y') { + $this->game->output->writeln("取消解散"); + Screen::sleep(1); + return false; + } + + // 返还装备 + foreach ($partner->equip as $item) { + if (!empty($item)) { + $this->game->player->addItem($item); + } + } + + // 解散同伴 + $this->game->player->dismissPartner($partner->id); + $this->game->saveState(); + + $this->game->output->writeln("{$this->yellow}{$partner->name} 离开了队伍{$this->reset}"); + Screen::pause($this->game->output); + return true; + } + + /** + * 为角色强化装备(统一处理玩家和队友) + */ + private function enhanceEquipment(Actor $actor) + { + Screen::clear($this->game->output); + $this->game->output->writeln("{$this->cyan}========== 装备强化 =========={$this->reset}"); + + $slots = ['weapon' => '武器', 'armor' => '护甲', 'ring' => '戒指', 'boots' => '靴子', 'necklace' => '项链']; + $equipped = []; + $idx = 1; + + foreach ($slots as $slot => $name) { + if (!empty($actor->equip[$slot])) { + $item = $actor->equip[$slot]; + $enhanceLevel = $item['enhanceLevel'] ?? 0; + $this->game->output->writeln("[{$idx}] {$name}: " . ItemDisplay::formatName($item) . " {$this->yellow}+{$enhanceLevel}{$this->reset}"); + $equipped[$idx] = $slot; + $idx++; + } + } + + if (empty($equipped)) { + $this->game->output->writeln("{$this->white}没有已装备的物品{$this->reset}"); + Screen::pause($this->game->output); + return; + } + + $this->game->output->writeln("[0] 取消"); + + $choice = Input::ask($this->game->output, "选择要强化的装备: "); + + if ($choice == 0) return; + + if (!isset($equipped[$choice])) { + $this->game->output->writeln("无效选择"); + Screen::sleep(1); + return; + } + + $slot = $equipped[$choice]; + $this->showEnhancePanel($slot, $actor); + } + + private function showEnhancePanel(string $slot, Actor $actor) { $out = $this->game->output; - $player = $this->game->player; - $item = $player->equip[$slot] ?? null; + $item = $actor->equip[$slot] ?? null; if (!$item) { $out->writeln("该位置没有装备!"); @@ -248,7 +591,7 @@ class StatsPanel } $out->writeln("║ 费用: {$this->yellow}{$cost}{$this->reset} 灵石"); $out->writeln("║"); - $out->writeln("║ 你的灵石: {$this->green}{$player->spiritStones}{$this->reset}"); + $out->writeln("║ 你的灵石: {$this->green}{$this->game->player->spiritStones}{$this->reset}"); $out->writeln("╚════════════════════════════════════╝"); $out->writeln(""); $out->writeln("[1] 强化 | [0] 返回"); @@ -256,20 +599,19 @@ class StatsPanel $choice = Screen::input($out, "选择操作:"); if ($choice == 1) { - $this->doEnhance($slot); + $this->doEnhance($slot, $actor); } } - private function doEnhance(string $slot) + private function doEnhance(string $slot, Actor $actor) { $out = $this->game->output; - $player = $this->game->player; - $item = &$player->equip[$slot]; + $item = &$actor->equip[$slot]; if (!$item) return; // 使用 EquipmentEnhancer 模块执行强化 - $result = EquipmentEnhancer::enhance($item, $player); + $result = EquipmentEnhancer::enhance($item, $this->game->player); // 显示强化结果 $out->writeln(""); @@ -306,4 +648,270 @@ class StatsPanel // 每级增加 5% 属性加成 return $level * 5; } + + /** + * 装备技能 + */ + private function equipSkill(Actor $actor) + { + $out = $this->game->output; + Screen::clear($out); + + // 1. 获取背包中的法术 + $spells = []; + foreach ($this->game->player->inventory as $index => $item) { + if (($item['type'] ?? '') === 'spell') { + $spells[$index] = $item; + } + } + + if (empty($spells)) { + $out->writeln("背包中没有法术!"); + Screen::sleep(1); + return; + } + + // 2. 显示法术列表 + $out->writeln("{$this->cyan}选择要装备的法术:{$this->reset}"); + $spellIndices = []; + $i = 1; + foreach ($spells as $index => $item) { + $out->writeln("[{$i}] " . ItemDisplay::renderListItem($item)); + $spellIndices[$i] = $index; + $i++; + } + $out->writeln("[0] 返回"); + + $choice = Screen::input($out, "请选择: "); + if ($choice == 0 || !isset($spellIndices[$choice])) return; + + $inventoryIndex = $spellIndices[$choice]; + $selectedSpell = $spells[$inventoryIndex]; + + // 3. 选择技能槽位 + Screen::clear($out); + $out->writeln("{$this->cyan}选择技能槽位:{$this->reset}"); + $skillSlots = ['skill1', 'skill2', 'skill3', 'skill4']; + $i = 1; + foreach ($skillSlots as $slot) { + $currentSpell = $actor->skillSlots[$slot] ?? null; + if ($currentSpell) { + $out->writeln("[{$i}] 技能{$i}: " . ItemDisplay::formatName($currentSpell)); + } else { + $out->writeln("[{$i}] 技能{$i}: (空)"); + } + $i++; + } + $out->writeln("[0] 返回"); + + $slotChoice = Screen::input($out, "请选择槽位: "); + if ($slotChoice < 1 || $slotChoice > 4) return; + + $targetSlot = $skillSlots[$slotChoice - 1]; + + // 4. 执行装备 + // 如果槽位已有技能,先卸下 + if (isset($actor->skillSlots[$targetSlot])) { + $this->game->player->addItem($actor->skillSlots[$targetSlot]); + } + + // 装备新技能 + $actor->skillSlots[$targetSlot] = $selectedSpell; + + // 从背包移除 + unset($this->game->player->inventory[$inventoryIndex]); + $this->game->player->inventory = array_values($this->game->player->inventory); + + $out->writeln("{$this->green}装备成功!{$this->reset}"); + $this->game->saveState(); + Screen::sleep(1); + } + + /** + * 卸下技能 + */ + private function unequipSkill(Actor $actor) + { + $out = $this->game->output; + Screen::clear($out); + + $out->writeln("{$this->cyan}选择要卸下的技能:{$this->reset}"); + $skillSlots = ['skill1', 'skill2', 'skill3', 'skill4']; + $hasSkill = false; + $i = 1; + foreach ($skillSlots as $slot) { + $currentSpell = $actor->skillSlots[$slot] ?? null; + if ($currentSpell) { + $out->writeln("[{$i}] 技能{$i}: " . ItemDisplay::formatName($currentSpell)); + $hasSkill = true; + } else { + $out->writeln("[{$i}] 技能{$i}: (空)"); + } + $i++; + } + $out->writeln("[0] 返回"); + + if (!$hasSkill) { + $out->writeln("没有装备任何技能!"); + Screen::sleep(1); + return; + } + + $slotChoice = Screen::input($out, "请选择槽位: "); + if ($slotChoice < 1 || $slotChoice > 4) return; + + $targetSlot = $skillSlots[$slotChoice - 1]; + $spell = $actor->skillSlots[$targetSlot] ?? null; + + if (!$spell) { + $out->writeln("该槽位没有技能!"); + Screen::sleep(1); + return; + } + + // 卸下到背包 + $this->game->player->addItem($spell); + $actor->skillSlots[$targetSlot] = null; + + $out->writeln("{$this->green}卸下成功!{$this->reset}"); + $this->game->saveState(); + Screen::sleep(1); + } + + /** + * 强化技能 + */ + private function enhanceSkill(Actor $actor) + { + $out = $this->game->output; + Screen::clear($out); + + $out->writeln("{$this->cyan}选择要强化的技能:{$this->reset}"); + $skillSlots = ['skill1', 'skill2', 'skill3', 'skill4']; + $equipped = []; + $hasSkill = false; + $i = 1; + foreach ($skillSlots as $slot) { + $spell = $actor->skillSlots[$slot] ?? null; + if ($spell) { + $out->writeln("[{$i}] 技能{$i}: " . ItemDisplay::formatName($spell)); + $equipped[$i] = $slot; + $hasSkill = true; + } else { + $out->writeln("[{$i}] 技能{$i}: (空)"); + } + $i++; + } + $out->writeln("[0] 返回"); + + if (!$hasSkill) { + $out->writeln("没有装备任何技能!"); + Screen::sleep(1); + return; + } + + $choice = Screen::input($out, "请选择: "); + if ($choice == 0 || !isset($equipped[$choice])) return; + + $slot = $equipped[$choice]; + + // 复用 showEnhancePanel,但需要修改 doEnhance 支持技能 + // 为了简单,我们创建一个专门的 showSkillEnhancePanel + $this->showSkillEnhancePanel($slot, $actor); + } + + private function showSkillEnhancePanel(string $slot, Actor $actor) + { + $out = $this->game->output; + $item = $actor->skillSlots[$slot] ?? null; + + if (!$item) return; + + Screen::clear($out); + + $enhanceLevel = $item['enhanceLevel'] ?? 0; + $maxLevel = 15; + + if ($enhanceLevel >= $maxLevel) { + $out->writeln("该技能已达到最高强化等级!"); + Screen::sleep(1); + return; + } + + // 使用与装备相同的强化配置 + $config = $this->enhanceConfig[$enhanceLevel] ?? $this->enhanceConfig[14]; + $successRate = $config['rate']; + $cost = $config['cost']; + $downgradeChance = $config['downgrade']; + + $out->writeln("╔════════════════════════════════════╗"); + $out->writeln("║ {$this->cyan}技能强化{$this->reset} ║"); + $out->writeln("╠════════════════════════════════════╣"); + $out->writeln("║ 技能: " . ItemDisplay::formatName($item)); + $out->writeln("║"); + + // 显示属性变化 + $out->writeln("║ {$this->white}--- 属性预览 ---{$this->reset}"); + $statLines = ItemDisplay::formatStatsDetailed($item, "║ "); + foreach ($statLines as $line) { + $out->writeln($line); + } + + $out->writeln("║"); + $out->writeln("╠════════════════════════════════════╣"); + $out->writeln("║"); + $out->writeln("║ 当前等级: {$this->green}+{$enhanceLevel}{$this->reset}"); + $out->writeln("║"); + $out->writeln("║ ➜ 强化至 {$this->yellow}+".($enhanceLevel + 1)."{$this->reset}"); + $out->writeln("║"); + $out->writeln("║ 成功率: {$this->green}{$successRate}%{$this->reset}"); + if ($downgradeChance > 0) { + $out->writeln("║ 失败掉级概率: {$this->red}{$downgradeChance}%{$this->reset}"); + } + $out->writeln("║ 费用: {$this->yellow}{$cost}{$this->reset} 灵石"); + $out->writeln("║"); + $out->writeln("║ 你的灵石: {$this->green}{$this->game->player->spiritStones}{$this->reset}"); + $out->writeln("╚════════════════════════════════════╝"); + $out->writeln(""); + $out->writeln("[1] 强化 | [0] 返回"); + + $choice = Screen::input($out, "选择操作:"); + + if ($choice == 1) { + $this->doEnhanceSkill($slot, $actor); + } + } + + private function doEnhanceSkill(string $slot, Actor $actor) + { + $out = $this->game->output; + $item = &$actor->skillSlots[$slot]; + + if (!$item) return; + + // 使用 EquipmentEnhancer 模块执行强化 (它应该能处理任何带有 enhanceLevel 的物品) + // 注意: EquipmentEnhancer 可能需要 Item 对象或数组,这里我们传递的是数组引用 + $result = EquipmentEnhancer::enhance($item, $this->game->player); + + $out->writeln(""); + + if ($result['success']) { + $out->writeln("{$this->green}★ 强化成功!{$this->reset}"); + $out->writeln("技能强化等级提升至 {$this->yellow}+{$result['newLevel']}{$this->reset}"); + } else { + if ($result['cost'] === 0) { + $out->writeln("{$this->red}✗ {$result['message']}{$this->reset}"); + } else { + $out->writeln("{$this->red}✗ 强化失败!{$this->reset}"); + if ($result['downgraded']) { + $out->writeln("{$this->red}技能强化等级下降至 +{$result['newLevel']}{$this->reset}"); + } else { + $out->writeln("强化等级保持不变"); + } + } + } + + $this->game->saveState(); + Screen::sleep(1); + } } diff --git a/test/Test.php b/test/Test.php index f8e7afe..a12f3ec 100644 --- a/test/Test.php +++ b/test/Test.php @@ -1,43 +1,6 @@ getStats()); \ No newline at end of file +dd(is_numeric('0')); \ No newline at end of file