From 81402717b527426c8b8b09e0f2faa27ccd468b26 Mon Sep 17 00:00:00 2001 From: hant Date: Thu, 11 Dec 2025 23:01:30 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- save.json | 85 +-------- src/Data/{recovery.json => consume.json} | 0 src/Data/items_new.json | 2 +- src/Entities/Actor.php | 13 +- src/Entities/Monster.php | 44 +++-- src/Modules/Bag/Consume.php | 229 ++--------------------- src/Modules/Bag/Item.php | 25 ++- src/Modules/Battle.php | 17 +- src/Modules/DungeonSelectPanel.php | 53 +----- src/Modules/Map/Map.php | 53 ++++++ src/Modules/StatsPanel.php | 45 +---- test/Test.php | 19 +- 12 files changed, 132 insertions(+), 453 deletions(-) rename src/Data/{recovery.json => consume.json} (100%) create mode 100644 src/Modules/Map/Map.php diff --git a/save.json b/save.json index b040416..ffc1d0e 100644 --- a/save.json +++ b/save.json @@ -1,84 +1 @@ -{ - "player": { - "hp": 100, - "maxHp": 100, - "patk": 10, - "matk": 10, - "pdef": 10, - "mdef": 10, - "crit": 0, - "critdmg": 110, - "level": 1, - "exp": 0, - "potionPool": 900, - "maxExp": 100, - "inventory": [], - "equip": [], - "spiritStones": 0, - "npcFlags": [], - "talentPoints": 0, - "talents": { - "hp": 0, - "patk": 0, - "matk": 0, - "pdef": 0, - "mdef": 0, - "crit": 0, - "critdmg": 0 - }, - "mana": 60, - "maxMana": 60, - "skillSlots": { - "skill1": null, - "skill2": null, - "skill3": null, - "skill4": null - }, - "partners": [ - { - "id": "li_feiyu", - "name": "厉飞雨", - "level": 1, - "exp": 0, - "maxExp": 201, - "equip": [], - "talents": { - "hp": 0, - "patk": 0, - "matk": 0, - "pdef": 0, - "mdef": 0, - "crit": 0, - "critdmg": 0 - }, - "talentWeights": { - "hp": 1, - "patk": 3, - "matk": 1, - "pdef": 1, - "mdef": 1, - "crit": 3, - "critdmg": 2 - }, - "mana": 60, - "maxMana": 100, - "skillSlots": { - "skill1": null, - "skill2": null, - "skill3": null, - "skill4": null - }, - "hp": 100, - "maxHp": 100, - "patk": 15, - "matk": 5, - "pdef": 5, - "mdef": 3, - "crit": 10, - "critdmg": 130 - } - ] - }, - "dungeonId": 1, - "state": 4 -} \ No newline at end of file +{"player":{"hp":76,"maxHp":100,"patk":10,"matk":10,"pdef":10,"mdef":10,"crit":0,"critdmg":110,"level":9,"exp":953,"potionPool":0,"maxExp":1729,"inventory":[{"name":"草上飞","type":"boots","enhanceLevel":0,"quality":"epic","level":2,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":37,"crit":6,"critdmg":0,"affixes":["魔防 +7","物防 +8"],"desc":"轻便的布靴,习武之人常年穿戴,便于施展轻功提纵之术。","id":"693aca26048ae","quantity":1},{"name":"平安符","type":"necklace","enhanceLevel":0,"quality":"legendary","level":1,"patk":0,"matk":0,"pdef":12,"mdef":0,"hp":44,"crit":0,"critdmg":4,"affixes":["暴击伤害 +4%","魔防 +6%","生命值 +7%"],"desc":"亲人求来的普通符箓,寄托思念,是韩立离家时的随身之物。","id":"693ad52222fbe","quantity":1},{"name":"平安符","type":"necklace","enhanceLevel":0,"quality":"rare","level":2,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":37,"crit":0,"critdmg":9,"affixes":["暴击伤害 +7%"],"desc":"亲人求来的普通符箓,寄托思念,是韩立离家时的随身之物。","id":"693ad53a3b9c4","quantity":1},{"name":"草上飞","type":"boots","enhanceLevel":0,"quality":"rare","level":1,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":23,"crit":0,"critdmg":0,"affixes":["魔防 +2%"],"desc":"轻便的布靴,习武之人常年穿戴,便于施展轻功提纵之术。","id":"693ad53a3b9cf","quantity":1},{"name":"草上飞","type":"boots","enhanceLevel":0,"quality":"rare","level":2,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":37,"crit":4,"critdmg":0,"affixes":["物防 +3"],"desc":"轻便的布靴,习武之人常年穿戴,便于施展轻功提纵之术。","id":"693ad59ee8348","quantity":1},{"name":"掌门指环","type":"ring","enhanceLevel":0,"quality":"epic","level":2,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":4,"critdmg":7,"affixes":["物攻 +3%","暴击率 +6"],"desc":"七玄门掌门信物,象征凡俗权力,对修仙者而言并无灵力。","id":"693ad59ee834c","quantity":1},{"name":"青锋剑","type":"weapon","enhanceLevel":0,"quality":"rare","level":2,"patk":12,"matk":12,"pdef":0,"mdef":0,"hp":0,"crit":9,"critdmg":0,"affixes":["暴击伤害 +2"],"desc":"七玄门江湖利器,锋锐轻快,乃凡人武者梦寐以求的神兵。","id":"693ad5aa2ec41","quantity":1},{"name":"掌门指环","type":"ring","enhanceLevel":0,"quality":"rare","level":1,"patk":0,"matk":5,"pdef":0,"mdef":0,"hp":0,"crit":4,"critdmg":0,"affixes":["物攻 +8%"],"desc":"七玄门掌门信物,象征凡俗权力,对修仙者而言并无灵力。","id":"693ad5b5b5738","quantity":1},{"name":"掌门指环","type":"ring","enhanceLevel":0,"quality":"epic","level":4,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":12,"critdmg":8,"affixes":["暴击率 +8%","物攻 +7"],"desc":"七玄门掌门信物,象征凡俗权力,对修仙者而言并无灵力。","id":"693ad5d62ebde","quantity":1},{"name":"掌门指环","type":"ring","enhanceLevel":0,"quality":"rare","level":2,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":9,"critdmg":0,"affixes":["物攻 +7%"],"desc":"七玄门掌门信物,象征凡俗权力,对修仙者而言并无灵力。","id":"693ad60b8ff2f","quantity":1},{"name":"草上飞","type":"boots","enhanceLevel":0,"quality":"rare","level":3,"patk":0,"matk":0,"pdef":7,"mdef":0,"hp":56,"crit":0,"critdmg":0,"affixes":["暴击率 +4%"],"desc":"轻便的布靴,习武之人常年穿戴,便于施展轻功提纵之术。","id":"693ad64068348","quantity":1},{"name":"平安符","type":"necklace","enhanceLevel":0,"quality":"rare","level":3,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":57,"crit":0,"critdmg":0,"affixes":["暴击率 +3"],"desc":"亲人求来的普通符箓,寄托思念,是韩立离家时的随身之物。","id":"693ad6772b739","quantity":1},{"name":"平安符","type":"necklace","enhanceLevel":0,"quality":"rare","level":3,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":57,"crit":0,"critdmg":0,"affixes":["物防 +5%"],"desc":"亲人求来的普通符箓,寄托思念,是韩立离家时的随身之物。","id":"693ad695dd93f","quantity":1},{"name":"平安符","type":"necklace","enhanceLevel":0,"quality":"rare","level":1,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":26,"crit":0,"critdmg":7,"affixes":["生命值 +8"],"desc":"亲人求来的普通符箓,寄托思念,是韩立离家时的随身之物。","id":"693ad6d875dd1","quantity":1},{"name":"平安符","type":"necklace","enhanceLevel":0,"quality":"epic","level":3,"patk":0,"matk":0,"pdef":0,"mdef":9,"hp":45,"crit":0,"critdmg":0,"affixes":["暴击伤害 +4%","物防 +7%"],"desc":"亲人求来的普通符箓,寄托思念,是韩立离家时的随身之物。","id":"693ad6ee76aa5","quantity":1},{"name":"草上飞","type":"boots","enhanceLevel":0,"quality":"epic","level":4,"patk":0,"matk":0,"pdef":12,"mdef":0,"hp":113,"crit":0,"critdmg":0,"affixes":["物防 +5%","生命值 +8%"],"desc":"轻便的布靴,习武之人常年穿戴,便于施展轻功提纵之术。","id":"693ad7645ebe7","quantity":1},{"name":"平安符","type":"necklace","enhanceLevel":0,"quality":"epic","level":2,"patk":0,"matk":0,"pdef":0,"mdef":8,"hp":57,"crit":0,"critdmg":0,"affixes":["暴击率 +6","生命值 +35"],"desc":"亲人求来的普通符箓,寄托思念,是韩立离家时的随身之物。","id":"693ad8036d0c0","quantity":1},{"name":"草上飞","type":"boots","enhanceLevel":0,"quality":"rare","level":3,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":61,"crit":0,"critdmg":0,"affixes":["物防 +4%"],"desc":"轻便的布靴,习武之人常年穿戴,便于施展轻功提纵之术。","id":"693ad8036d0c6","quantity":1},{"name":"棉铁内甲","type":"armor","enhanceLevel":0,"quality":"rare","level":1,"patk":11,"matk":0,"pdef":0,"mdef":0,"hp":18,"crit":0,"critdmg":0,"affixes":["魔防 +5%"],"desc":"以棉花与铁片编织而成的护身软甲,能有效抵御普通刀剑劈砍。","id":"693ad82061a32","quantity":1},{"name":"平安符","type":"necklace","enhanceLevel":0,"quality":"epic","level":2,"patk":0,"matk":0,"pdef":6,"mdef":0,"hp":40,"crit":0,"critdmg":0,"affixes":["物防 +5","生命值 +2%"],"desc":"亲人求来的普通符箓,寄托思念,是韩立离家时的随身之物。","id":"693ad8469cc0f","quantity":1},{"name":"棉铁内甲","type":"armor","enhanceLevel":0,"quality":"common","level":3,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":62,"crit":0,"critdmg":0,"affixes":[],"desc":"以棉花与铁片编织而成的护身软甲,能有效抵御普通刀剑劈砍。","id":"693adb6aba031","quantity":1},{"name":"草上飞","type":"boots","enhanceLevel":0,"quality":"epic","level":1,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":42,"crit":6,"critdmg":0,"affixes":["魔防 +2%","生命值 +5%"],"desc":"轻便的布靴,习武之人常年穿戴,便于施展轻功提纵之术。","id":"693adb77c0a6c","quantity":1},{"name":"掌门指环","type":"ring","enhanceLevel":0,"quality":"rare","level":1,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":9,"critdmg":0,"affixes":["暴击率 +3"],"desc":"七玄门掌门信物,象征凡俗权力,对修仙者而言并无灵力。","id":"693adb81e96a6","quantity":1},{"name":"草上飞","type":"boots","enhanceLevel":0,"quality":"rare","level":8,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":94,"crit":5,"critdmg":0,"affixes":["暴击率 +4"],"desc":"轻便的布靴,习武之人常年穿戴,便于施展轻功提纵之术。","id":"693adbd16c87d","quantity":1},{"name":"掌门指环","type":"ring","enhanceLevel":0,"quality":"common","level":8,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":3,"critdmg":0,"affixes":[],"desc":"七玄门掌门信物,象征凡俗权力,对修仙者而言并无灵力。","id":"693adbd16c883","quantity":1},{"name":"青锋剑","type":"weapon","enhanceLevel":0,"quality":"common","level":8,"patk":19,"matk":16,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"affixes":[],"desc":"七玄门江湖利器,锋锐轻快,乃凡人武者梦寐以求的神兵。","id":"693adbd16c885","quantity":1},{"name":"草上飞","type":"boots","enhanceLevel":0,"quality":"common","level":8,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":117,"crit":0,"critdmg":0,"affixes":[],"desc":"轻便的布靴,习武之人常年穿戴,便于施展轻功提纵之术。","id":"693adbd16c886","quantity":1},{"name":"掌门指环","type":"ring","enhanceLevel":0,"quality":"common","level":8,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":7,"critdmg":0,"affixes":[],"desc":"七玄门掌门信物,象征凡俗权力,对修仙者而言并无灵力。","id":"693adbd16c887","quantity":1},{"name":"平安符","type":"necklace","enhanceLevel":0,"quality":"common","level":8,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":168,"crit":0,"critdmg":0,"affixes":[],"desc":"亲人求来的普通符箓,寄托思念,是韩立离家时的随身之物。","id":"693adbd16c888","quantity":1},{"name":"草上飞","type":"boots","enhanceLevel":0,"quality":"common","level":1,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":18,"crit":0,"critdmg":0,"affixes":[],"desc":"轻便的布靴,习武之人常年穿戴,便于施展轻功提纵之术。","id":"693adbef303b9","quantity":1},{"name":"平安符","type":"necklace","enhanceLevel":0,"quality":"rare","level":8,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":163,"crit":0,"critdmg":12,"affixes":["暴击伤害 +10%"],"desc":"亲人求来的普通符箓,寄托思念,是韩立离家时的随身之物。","id":"693adbef303bf","quantity":1},{"name":"草上飞","type":"boots","enhanceLevel":0,"quality":"common","level":8,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":89,"crit":0,"critdmg":0,"affixes":[],"desc":"轻便的布靴,习武之人常年穿戴,便于施展轻功提纵之术。","id":"693adc024265a","quantity":1},{"name":"青锋剑","type":"weapon","enhanceLevel":0,"quality":"common","level":8,"patk":15,"matk":19,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"affixes":[],"desc":"七玄门江湖利器,锋锐轻快,乃凡人武者梦寐以求的神兵。","id":"693adc290e13a","quantity":1},{"name":"平安符","type":"necklace","enhanceLevel":0,"quality":"common","level":8,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":105,"crit":0,"critdmg":0,"affixes":[],"desc":"亲人求来的普通符箓,寄托思念,是韩立离家时的随身之物。","id":"693adc290e13e","quantity":1},{"name":"棉铁内甲","type":"armor","enhanceLevel":0,"quality":"common","level":8,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":152,"crit":0,"critdmg":0,"affixes":[],"desc":"以棉花与铁片编织而成的护身软甲,能有效抵御普通刀剑劈砍。","id":"693adc290e142","quantity":1},{"name":"青锋剑","type":"weapon","enhanceLevel":0,"quality":"common","level":1,"patk":9,"matk":4,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"affixes":[],"desc":"七玄门江湖利器,锋锐轻快,乃凡人武者梦寐以求的神兵。","id":"693adc2d2a2d2","quantity":1},{"name":"掌门指环","type":"ring","enhanceLevel":0,"quality":"rare","level":1,"patk":0,"matk":11,"pdef":0,"mdef":0,"hp":0,"crit":7,"critdmg":0,"affixes":["魔攻 +2"],"desc":"七玄门掌门信物,象征凡俗权力,对修仙者而言并无灵力。","id":"693adc2d2a2d7","quantity":1}],"equip":{"weapon":{"name":"青锋剑","type":"weapon","enhanceLevel":0,"quality":"rare","level":3,"patk":16,"matk":12,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"affixes":["暴击率 +3"],"desc":"七玄门江湖利器,锋锐轻快,乃凡人武者梦寐以求的神兵。","id":"693ad36049f77","quantity":1},"boots":{"name":"草上飞","type":"boots","enhanceLevel":0,"quality":"epic","level":4,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":96,"crit":11,"critdmg":0,"affixes":["生命值 +9%","暴击率 +6"],"desc":"轻便的布靴,习武之人常年穿戴,便于施展轻功提纵之术。","id":"693ad73fe2ff0","quantity":1},"armor":{"name":"棉铁内甲","type":"armor","enhanceLevel":0,"quality":"rare","level":8,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":201,"crit":0,"critdmg":0,"affixes":["物防 +5%"],"desc":"以棉花与铁片编织而成的护身软甲,能有效抵御普通刀剑劈砍。","id":"693ad786e550e","quantity":1},"necklace":{"name":"平安符","type":"necklace","enhanceLevel":0,"quality":"epic","level":3,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":69,"crit":0,"critdmg":8,"affixes":["物防 +5","魔防 +9"],"desc":"亲人求来的普通符箓,寄托思念,是韩立离家时的随身之物。","id":"693ad4332b096","quantity":1},"ring":{"name":"掌门指环","type":"ring","enhanceLevel":0,"quality":"epic","level":3,"patk":0,"matk":18,"pdef":0,"mdef":0,"hp":0,"crit":7,"critdmg":0,"affixes":["物攻 +9%","暴击率 +3"],"desc":"七玄门掌门信物,象征凡俗权力,对修仙者而言并无灵力。","id":"693ad3781ba9a","quantity":1}},"spiritStones":1783,"npcFlags":[],"talentPoints":3,"talents":{"hp":9,"patk":12,"matk":0,"pdef":0,"mdef":0,"crit":0,"critdmg":0},"mana":60,"maxMana":60,"skillSlots":{"skill1":null,"skill2":null,"skill3":null,"skill4":null},"partners":[{"id":"li_feiyu","name":"厉飞雨","level":8,"exp":576,"maxExp":1412,"equip":{"weapon":{"name":"青锋剑","type":"weapon","enhanceLevel":0,"quality":"rare","level":2,"patk":13,"matk":13,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"affixes":["暴击伤害 +3"],"desc":"七玄门江湖利器,锋锐轻快,乃凡人武者梦寐以求的神兵。","id":"693ad4753bb91","quantity":1},"boots":{"name":"草上飞","type":"boots","enhanceLevel":0,"quality":"rare","level":8,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":148,"crit":0,"critdmg":0,"affixes":["暴击率 +8%"],"desc":"轻便的布靴,习武之人常年穿戴,便于施展轻功提纵之术。","id":"693ad786e5512","quantity":1},"ring":{"name":"掌门指环","type":"ring","enhanceLevel":0,"quality":"epic","level":3,"patk":0,"matk":0,"pdef":0,"mdef":0,"hp":0,"crit":4,"critdmg":3,"affixes":["暴击伤害 +4","暴击率 +7%"],"desc":"七玄门掌门信物,象征凡俗权力,对修仙者而言并无灵力。","id":"693ad53f717b7","quantity":1},"necklace":{"name":"平安符","type":"necklace","enhanceLevel":0,"quality":"rare","level":3,"patk":0,"matk":0,"pdef":0,"mdef":10,"hp":80,"crit":0,"critdmg":0,"affixes":["暴击率 +9%"],"desc":"亲人求来的普通符箓,寄托思念,是韩立离家时的随身之物。","id":"693ad45f84f12","quantity":1},"armor":{"name":"棉铁内甲","type":"armor","enhanceLevel":0,"quality":"rare","level":8,"patk":0,"matk":0,"pdef":0,"mdef":19,"hp":113,"crit":0,"critdmg":0,"affixes":["物防 +12"],"desc":"以棉花与铁片编织而成的护身软甲,能有效抵御普通刀剑劈砍。","id":"693ad7f49b1b2","quantity":1}},"talents":{"hp":7,"patk":7,"matk":0,"pdef":0,"mdef":0,"crit":7,"critdmg":0},"talentWeights":{"hp":1,"patk":3,"matk":1,"pdef":1,"mdef":1,"crit":3,"critdmg":2},"mana":100,"maxMana":100,"skillSlots":{"skill1":null,"skill2":null,"skill3":null,"skill4":null},"hp":189,"maxHp":100,"patk":15,"matk":5,"pdef":5,"mdef":3,"crit":10,"critdmg":130}]},"dungeonId":1,"state":2} \ No newline at end of file diff --git a/src/Data/recovery.json b/src/Data/consume.json similarity index 100% rename from src/Data/recovery.json rename to src/Data/consume.json diff --git a/src/Data/items_new.json b/src/Data/items_new.json index 77ea2ce..c55a6e1 100644 --- a/src/Data/items_new.json +++ b/src/Data/items_new.json @@ -377,4 +377,4 @@ "type": "necklace" } ] -] \ No newline at end of file +] diff --git a/src/Entities/Actor.php b/src/Entities/Actor.php index 8393d91..a903da8 100644 --- a/src/Entities/Actor.php +++ b/src/Entities/Actor.php @@ -13,8 +13,8 @@ class Actor public int $maxHp = 100; public int $patk = 10; public int $matk = 10; - public int $pdef = 10; - public int $mdef = 10; + public int $pdef = 5; + public int $mdef = 3; public int $crit = 0; public float $critdmg = 110.0; @@ -136,11 +136,10 @@ class Actor public function fullHeal(): void { - if (property_exists($this, 'maxHp')) { - $this->hp = $this->maxHp; - } elseif (property_exists($this, 'baseHp')) { - $this->hp = $this->baseHp; - } + $status = $this->getStats(); + + $this->hp = $status['maxHp']; + } public function recoverMana(int $amount): int diff --git a/src/Entities/Monster.php b/src/Entities/Monster.php index 8656875..52eef22 100644 --- a/src/Entities/Monster.php +++ b/src/Entities/Monster.php @@ -1,6 +1,7 @@ name = '未知怪物'; $monster->expReward = 10; @@ -76,12 +73,8 @@ class Monster extends Actor public static function createGroup(int $dungeonId,$play_level): array { // Load data - static $maps = null; - if ($maps === null) { - $maps = require __DIR__ . '/../../src/Data/maps.php'; - } + $monsterConfig = self::getMasters($dungeonId); - $monsterConfig = $maps[$dungeonId]['monsters'] ?? []; if (empty($monsterConfig)) { return [self::create($dungeonId)]; } @@ -130,7 +123,8 @@ class Monster extends Actor $monster = new self(); // Create monster from selected config $monster->hydrateFromConfig($selectedConfig,$dungeonId); - + $status = $monster->getStats(); + $monster->hp = $status['maxHp']; // Add suffix to distinguish multiple monsters of same type if ($groupSize > 1) { $monster->name .= " (" . ($i) . ")"; @@ -145,6 +139,7 @@ class Monster extends Actor public function hydrateFromConfig(array $config,$dungeonId): void { $this->name = $config['name']; + $this->level = $config['level'] ?? 1; $this->baseHp = $config['hp'] ?? 20; $this->hp = $this->baseHp; @@ -161,7 +156,8 @@ class Monster extends Actor $this->critdmg = $config['critdmg'] ?? 130; $this->expReward = $config['exp'] ?? 0; $this->spiritStoneReward = $config['spirit_stones'] ?? 0; - + $this->is_elite = $config['is_elite'] ?? false; + $this->is_boss = $config['is_boss'] ?? false; // 根据等级和基础属性分配天赋点 $this->allocateTalentsByLevel(); static $allItems = null; @@ -169,12 +165,17 @@ class Monster extends Actor $allItems = json_decode(file_get_contents(__DIR__.'/../Data/items_new.json'),true); } $drops = $config['drops'] ?? []; - $index = ($dungeonId - 1) * 5; - $drops_eq = array_slice($allItems,$index,5); + $drops_eq =$allItems[$dungeonId - 1]; $drops = array_merge($drops,$drops_eq); foreach ($drops as $drop) { $type = $drop['type'] ?? ''; $rate = $drop['rate'] ?? 20; + if ($this->is_elite){ + $rate += 20; + } + if ($this->is_boss){ + $rate += 40; + } if (in_array($type, ['weapon', 'armor', 'boots', 'ring', 'necklace'])) { if (rand(1, 100) > $rate) continue; $spec = $drop; @@ -183,6 +184,7 @@ class Monster extends Actor $this->equip[$type] = $equip; } } + $this->dropTable[] = Consume::createItem($dungeonId,$config['level']); // 为怪物配置法术 $this->generateSpells($config); @@ -246,6 +248,16 @@ class Monster extends Actor } } + private static function getMasters(int $dungeonId) + { + $data = file_get_contents(__DIR__.'/../Data/monster.json'); + $data = json_decode($data,true); +// dd($data); + $monsters = $data["region_{$dungeonId}_monsters"]; + $boss = $data["region_{$dungeonId}_bosses"]; + return array_merge($monsters,$boss); + } + /** * 随机掉落装备物品(从穿着的装备随机掉落) * @param int $dropRate 掉落概率(0-100) diff --git a/src/Modules/Bag/Consume.php b/src/Modules/Bag/Consume.php index ca71ebd..ec4f782 100644 --- a/src/Modules/Bag/Consume.php +++ b/src/Modules/Bag/Consume.php @@ -10,153 +10,19 @@ use Game\Core\Colors; class Consume extends Item { - private static array $typeNames = [ - 'heal_single' => '单体治疗', - 'damage_single' => '单体伤害', - 'damage_aoe' => '群体伤害', - 'heal_aoe' => '群体治疗', - 'support' => '辅助', - ]; - - - - // 计算方式说明 - private static array $calcTypeDescriptions = [ - 'matk' => '基于魔攻', - 'patk' => '基于物攻', - 'hp_percent' => '基于最大生命值百分比', - 'hybrid' => '基于(魔攻+物攻)混合', - 'crit_heal' => '暴击率影响治疗效果', - 'crit_damage' => '暴击伤害系数影响伤害', - 'crit_aoe' => '暴击率影响范围伤害', - 'defense' => '基于防御属性', - 'def_pierce' => '防御穿透伤害', - 'status_bonus' => '目标状态加成伤害', - 'enemy_count_bonus' => '敌人数量加成伤害', - 'dispersed_damage' => '伤害分散到所有敌人', - 'smart_heal' => '智能治疗(优先低血量)', - 'hp_missing' => '基于缺失生命值', - 'low_def_bonus' => '对低防御敌人伤害加成', - 'matk_scaled' => '随敌人数量加成', - 'team_sync' => '基于队伍规模', - ]; - /** - * 创建法术物品 - 支持新的丰富法术系统 - * @param int $spellId 法术ID - * @param int $level 物品等级 - * @return array 法术物品数组 - */ - public static function createItem(int $spellId, int $level = 1): array + public static function createItem(int $dungeonId, int $level = 1): array { - static $spellsData = null; - if ($spellsData === null) { - $spellsData = require __DIR__ . '/../../../src/Data/spells.php'; - } - - // 随机品质 - $roll = rand(1, 100); -// $roll = 100; - if ($roll <= 70) $quality = 'common'; - elseif ($roll <= 90) $quality = 'rare'; - elseif ($roll <= 98) $quality = 'epic'; - else $quality = 'legendary'; - // 查找法术信息 - $spellInfo = null; - foreach ($spellsData as $category => $spells) { - if (is_array($spells) && !in_array($category, ['quality_levels', 'upgrades', 'dungeon_spell_drops', 'quality_drop_rates', 'spells_by_quality'])) { - if (isset($spells[$spellId])) { - $spellInfo = $spells[$spellId]; - break; - } - } - } - - if (!$spellInfo) { - // 默认法术 - return [ - 'id' => uniqid('spell_'), - 'type' => 'spell', - 'name' => '未知法术', - 'quality' => $quality, - 'level' => $level, - 'spellId' => $spellId, - 'enhanceLevel' => 0, - 'calc_type' => 'matk', - 'cost' => 20, - 'spellType' => 'damage_single', - 'desc' => '未知的法术', - ]; - } - - // 品质映射到数组索引 (common=0, rare=1, epic=2, legendary=3) - $qualityIndex = match ($quality) { - 'common' => 0, - 'rare' => 1, - 'epic' => 2, - 'legendary' => 3, - default => 0, - }; - - // 提取品质相关的参数 - $healRatio = $spellInfo['heal_ratio'][$qualityIndex] ?? ($spellInfo['heal_ratio'][0] ?? 0); - $damageRatio = $spellInfo['damage_ratio'][$qualityIndex] ?? ($spellInfo['damage_ratio'][0] ?? 1.0); - $healBase = $spellInfo['heal_base'][$qualityIndex] ?? ($spellInfo['heal_base'][0] ?? 0); - $critBonus = $spellInfo['crit_bonus'][$qualityIndex] ?? ($spellInfo['crit_bonus'][0] ?? 0); - $critDmgBonus = $spellInfo['crit_dmg_bonus'][$qualityIndex] ?? ($spellInfo['crit_dmg_bonus'][0] ?? 0); - $enemyCountBonus = $spellInfo['enemy_count_bonus'][$qualityIndex] ?? ($spellInfo['enemy_count_bonus'][0] ?? 0); - $dispersion = $spellInfo['dispersion'][$qualityIndex] ?? ($spellInfo['dispersion'][0] ?? 1.0); - $teamBonus = $spellInfo['team_bonus'][$qualityIndex] ?? ($spellInfo['team_bonus'][0] ?? 0); - $priorityBonus = $spellInfo['priority_bonus'][$qualityIndex] ?? ($spellInfo['priority_bonus'][0] ?? 0); - - // 计算基础伤害值(根据法术模板的基础值和成长系数) - $baseValue = 0; - $growth = 0; - if (isset($spellInfo['base']) && isset($spellInfo['growth'])) { - $baseArray = $spellInfo['base']; - - $growthArray = $spellInfo['growth']; - - // 确保索引在范围内 - if (is_array($baseArray) && is_array($growthArray)) { - $baseValue = $baseArray[$qualityIndex] ?? ($baseArray[0] ?? 0); - $growth = $growthArray[$qualityIndex] ?? ($growthArray[0] ?? 0); - - // 应用计算公式:finalValue = baseValue + (level * growth) + randomBonus - $randomBonus = rand(0, max(1, (int)($baseValue * 3))); - $finalBaseValue = (int)($baseValue + ($level * $growth * 10) + $randomBonus); - } else { - $finalBaseValue = 0; - } - } else { - $finalBaseValue = 0; - } + $data = file_get_contents(__DIR__.'/../../Data/consume.json'); + $data = json_decode($data,true); + $name = $data[$dungeonId]['name']; + $heal = $level * 10 * 3; return [ - 'id' => uniqid('spell_'), - 'type' => 'spell', - 'name' => $spellInfo['name'], - 'quality' => $quality, - 'level' => $level, - 'spellId' => $spellId, - 'enhanceLevel' => 0, - 'calc_type' => $spellInfo['calc_type'] ?? 'matk', - 'cost' => $spellInfo['cost'] ?? 20, - 'spellType' => $spellInfo['type'] ?? 'damage_single', - 'desc' => $spellInfo['desc'] ?? '', - - // 品质参数 - 'heal_ratio' => $healRatio, - 'damage_ratio' => $damageRatio, - 'heal_base' => $healBase, - 'crit_bonus' => $critBonus, - 'crit_dmg_bonus' => $critDmgBonus, - 'enemy_count_bonus' => $enemyCountBonus, - 'dispersion' => $dispersion, - 'team_bonus' => $teamBonus, - 'priority_bonus' => $priorityBonus, - // 基础伤害值(已计算) - 'base' => $finalBaseValue, - 'growth' => $growth, + 'id' => uniqid('consume_'), + 'type' => 'consume', + 'rate' => 30, + 'heal' => $heal, + 'name' => $name, ]; } @@ -171,84 +37,11 @@ class Consume extends Item public static function getLineShow($item): string { - $parts = []; - $spell = $item; - // 名称(带品质颜色和强化) - $parts[] = self::formatName($spell); - - // 法术类型 - $spellType = $spell['spellType'] ?? $spell['type'] ?? 'unknown'; - $typeName = self::$typeNames[$spellType]; - $parts[] = Colors::GRAY . "[{$typeName}]" . Colors::RESET; - - // 计算方式 - $calcType = $spell['calc_type'] ?? 'matk'; - $calcDesc = self::getCalcTypeDescription($calcType); - $ratio = $spell['damage_ratio']; - $parts[] = Colors::GRAY . "{$calcDesc} x $ratio" . Colors::RESET; - // 基础值 - $base = $spell['base'] ?? 0; - $parts[] = Colors::YELLOW . "基础:{$base}" . Colors::RESET; - - // 消耗 - $cost = $spell['cost'] ?? 0; - $enhanceLevel = $spell['enhanceLevel'] ?? 0; - $actualCost = max(1, $cost - ($enhanceLevel * 2)); - if ($enhanceLevel > 0) { - $parts[] = Colors::CYAN . "消耗:{$actualCost}(原:{$cost})" . Colors::RESET; - } else { - $parts[] = Colors::CYAN . "消耗:{$cost}" . Colors::RESET; - } - - return implode(" ", $parts); - } - - public static function getCalcTypeDescription(string $calcType): string - { - return self::$calcTypeDescriptions[$calcType] ?? $calcType; - } - - public static function formatName(array $spell): string - { - $quality = $spell['quality'] ?? 'common'; - $color = Colors::getColor($quality); - $name = $spell['name'] ?? '未知法术'; - $level = $spell['level'] ?? 1; - - $enhanceLevel = $spell['enhanceLevel'] ?? 0; - $enhanceStr = $enhanceLevel > 0 ? Colors::YELLOW . "+{$enhanceLevel}" . Colors::RESET : ""; - - return $color . $name . Colors::RESET . " Lv.{$level}" . $enhanceStr; + return $item['name'] . '+' .$item['heal']; } public static function getDetailShow($item): array { return []; } - - protected static function getBaseValue(string $quality, string $type, int $level,bool $isMain = true): float - { - $qualityMultiplier = match ($quality) { - 'legendary' => 2.0, - 'epic' => 1.5, - 'rare' => 1.2, - default => 1.0 - }; - - $base = rand(2*$level, 8*$level); - $multiplier = match ($type) { - 'heal_single' => [1.5, 2], - 'damage_single' => [1.5, 2], - 'damage_aoe' => [1.0, 1.3], - 'heal_aoe' => [1.0, 1.3], - default => [1, 1.1] - }; - $random = random_int(1, 10); - $multiplier = ($multiplier[1] - $multiplier[0]) * $random / 10 + $multiplier[0]; - if ($isMain){ - return floor(($base + ($level * $multiplier)) * $qualityMultiplier); - }else{ - return floor(($base + ($level * $multiplier)) * $qualityMultiplier / 5 * 3); - } - } } diff --git a/src/Modules/Bag/Item.php b/src/Modules/Bag/Item.php index 6fe9b94..401dc68 100644 --- a/src/Modules/Bag/Item.php +++ b/src/Modules/Bag/Item.php @@ -2,6 +2,8 @@ namespace Game\Modules\Bag; +use Game\Core\Colors; + /** * Simple representation of an equipment/consumable item. */ @@ -11,6 +13,7 @@ abstract class Item public string $type; // weapon, armor, consume public string $quality; // common, rare, epic, legendary public string $desc = ''; + public abstract function toArray(): array; public abstract static function getLineShow($item): string; @@ -21,25 +24,31 @@ abstract class Item public static function show($item): string { - if ($item['type'] == 'spell'){ + if (!$item) { + return '无'; + } + if ($item['type'] == 'potion_pool') { + return Colors::GREEN.'小绿瓶+'.$item['heal'].Colors::RESET; + } else if ($item['type'] == 'spell') { return Spell::getLineShow($item); - }elseif($item['type'] == 'quest'){ + } elseif ($item['type'] == 'quest') { return Quest::getLineShow($item); - }elseif ($item['type'] == 'consume'){ + } elseif ($item['type'] == 'consume') { return Consume::getLineShow($item); - }else{ + } else { return Equipment::getLineShow($item); } } + public static function calcPrice($item): int { - if ($item['type'] == 'spell'){ + if ($item['type'] == 'spell') { return Spell::calculateSellPrice($item); - }elseif($item['type'] == 'quest'){ + } elseif ($item['type'] == 'quest') { return Quest::calculateSellPrice($item); - }elseif ($item['type'] == 'consume'){ + } elseif ($item['type'] == 'consume') { return Consume::calculateSellPrice($item); - }else{ + } else { return Equipment::calculateSellPrice($item); } } diff --git a/src/Modules/Battle.php b/src/Modules/Battle.php index e694da7..be54b33 100644 --- a/src/Modules/Battle.php +++ b/src/Modules/Battle.php @@ -2,18 +2,14 @@ namespace Game\Modules; use Game\Core\Game; -use Game\Core\Input; use Game\Core\Screen; -use Game\Core\ItemDisplay; -use Game\Core\SpellDisplay; use Game\Core\SpellCalculator; use Game\Core\Colors; -use Game\Core\WebInput; use Game\Entities\Player; use Game\Entities\Actor; use Game\Entities\Monster; use Game\Entities\Partner; -use Game\Modules\Bag\Equipment; +use Game\Modules\Bag\Item; class Battle { @@ -132,7 +128,7 @@ class Battle } while ($this->player->hp > 0) { - Screen::delay(500000, $out); + Screen::delay(500000); // 创建敌人群组 $this->enemies = Monster::createGroup($this->game->dungeonId,$this->player->level); @@ -1061,7 +1057,6 @@ class Battle foreach ($this->enemies as $enemy) { $totalExp += $enemy->expReward; $totalStones += $enemy->spiritStoneReward; - // 掉落 - 从怪物穿着的装备随机掉落(50%概率) foreach ($enemy->getRandomEquipmentDrops(50) as $item) { $this->player->addItem($item); @@ -1077,7 +1072,7 @@ class Battle // 掉落 - 从掉落表中随机掉落物品 foreach ($enemy->dropTable as $drop) { if (rand(1, 100) <= $drop['rate']) { - $item = $drop['item']; + $item = $drop; // 如果是回复品(消耗品且有heal属性),直接添加到小绿瓶池 if ($item['type'] === 'consume' && isset($item['heal']) && $item['heal'] > 0) { $this->player->addPotionPool($item['heal']); @@ -1088,10 +1083,6 @@ class Battle 'heal' => $item['heal'], 'quantity' => 1 ]; - } else { - // 其他物品正常添加到背包 - $this->player->addItem($item); - $allDrops[] = $item; } } } @@ -1139,7 +1130,7 @@ class Battle if (!empty($allDrops)) { $out->writeln("{$this->yellow}║{$this->reset} {$this->white}掉落:{$this->reset}"); foreach ($allDrops as $item) { - $out->writeln(Equipment::getLineShow($item)); + $out->writeln(Item::show($item)); } } diff --git a/src/Modules/DungeonSelectPanel.php b/src/Modules/DungeonSelectPanel.php index 9ff289d..f17e9e1 100644 --- a/src/Modules/DungeonSelectPanel.php +++ b/src/Modules/DungeonSelectPanel.php @@ -4,38 +4,12 @@ namespace Game\Modules; use Game\Core\Screen; use Game\Core\Input; use Game\Core\Game; +use Game\Modules\Map\Map; class DungeonSelectPanel { public function __construct(public Game $game) {} - /** - * 检查玩家是否拥有指定物品 - */ - private function hasItem(string $itemName): bool - { - foreach ($this->game->player->inventory as $item) { - if (($item['name'] ?? '') === $itemName) { - return true; - } - } - return false; - } - - /** - * 检查玩家是否可以进入某个副本 - */ - private function canEnterDungeon(array $map): bool - { - // 如果没有key_item要求,可以进入 - if ($map['key_item'] === null) { - return true; - } - - // 检查玩家是否拥有该钥匙 - return $this->hasItem($map['key_item']); - } - public function show() { Screen::clear($this->game->output); @@ -46,19 +20,11 @@ class DungeonSelectPanel $out->writeln("╚════════════════════════════════════╝"); $out->writeln(""); - $maps = require __DIR__ . '/../../src/Data/maps.php'; - $availableMaps = []; - + $map = new Map($this->game); + $maps = $map->getMaps(); // 只显示已解锁的地图 foreach ($maps as $id => $map) { - if ($this->canEnterDungeon($map)) { - $availableMaps[$id] = $map; - $out->writeln("[{$id}] {$map['name']} (Lv.{$map['min_level']})"); - } else { - // 显示未解锁的地图 - $keyItem = $map['key_item']; - $out->writeln("[\033[90m{$id}\033[0m] {$map['name']} (未解锁 - 需要: {$keyItem})"); - } + $out->writeln("[{$id}] {$map['name']}"); } $out->writeln(""); @@ -77,17 +43,6 @@ class DungeonSelectPanel Screen::sleep(1); return; } - - $selectedMap = $maps[$dungeonId]; - - // 检查是否有权限进入 - if (!$this->canEnterDungeon($selectedMap)) { - $out->writeln("\033[91m该副本尚未解锁!\033[0m"); - $out->writeln("需要物品: \033[93m{$selectedMap['key_item']}\033[0m"); - Screen::sleep(2); - return; - } - // 进入副本 $this->game->dungeonId = (int)$dungeonId; $this->game->state = Game::BATTLE; diff --git a/src/Modules/Map/Map.php b/src/Modules/Map/Map.php new file mode 100644 index 0000000..23822bc --- /dev/null +++ b/src/Modules/Map/Map.php @@ -0,0 +1,53 @@ +game = $game; + $data = file_get_contents(__DIR__.'/../../Data/map.json'); + $this->map = json_decode($data,true); + + } + + public function getMaps() + { + $res = []; + $i = 0; + foreach ($this->map as $item){ + if ($this->canEnterDungeon($item)){ + $res [++$i] = $item; + } + } + return $res; + } + + + private function canEnterDungeon(array $map): bool + { + // 如果没有key_item要求,可以进入 + if ($map['key_item'] === null) { + return true; + } + + // 检查玩家是否拥有该钥匙 + return $this->hasItem($map['key_item']); + } + + private function hasItem(string $itemName): bool + { + foreach ($this->game->player->inventory as $item) { + if (($item['name'] ?? '') === $itemName) { + return true; + } + } + return false; + } +} \ No newline at end of file diff --git a/src/Modules/StatsPanel.php b/src/Modules/StatsPanel.php index 9a5d764..07bd289 100644 --- a/src/Modules/StatsPanel.php +++ b/src/Modules/StatsPanel.php @@ -216,34 +216,12 @@ class StatsPanel $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(Item::show($item)); } $out->writeln("╚════════════════════════════════════╝"); @@ -255,23 +233,10 @@ class StatsPanel $out->writeln("╠════════════════════════════════════╣"); $skillSlots = ['skill1', 'skill2', 'skill3', 'skill4']; - $skillIndex = 1; + foreach ($skillSlots as $slot) { $spell = $actor->skillSlots[$slot] ?? null; - if ($spell) { - // 法术使用 SpellDisplay 显示 - $slotLines = SpellDisplay::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(Item::show($spell)); } $out->writeln("╚════════════════════════════════════╝"); $out->writeln(""); @@ -399,7 +364,7 @@ class StatsPanel $displayIdx = 1; $idxMap = []; foreach ($equipableItems as $realIdx => $item) { - $displayStr = Item::show($equipableItems); + $displayStr = Item::show($item); $this->game->output->writeln("[{$displayIdx}] {$displayStr}"); $idxMap[$displayIdx] = $realIdx; $displayIdx++; diff --git a/test/Test.php b/test/Test.php index b4303ae..4f7da29 100644 --- a/test/Test.php +++ b/test/Test.php @@ -2,27 +2,12 @@ use Game\Modules\Bag\Equipment; use Game\Modules\Bag\Spell; -use Game\Modules\Skill\Enums\DamageType; -use Game\Modules\Skill\Factories\EffectFactory; require __DIR__ . '/../vendor/autoload.php'; -// 效果使用示例 - -// 创建伤害效果 -$damageEffect = EffectFactory::createEffect([ - 'type' => 'damage', - 'id' => 'fire_ball_damage', - 'name' => '火球术伤害', - 'damage_type' => DamageType::FIRE->value, - 'value' => 150, // 150% 攻击力伤害 - 'is_percentage' => true, - 'crit_chance' => 0.1, - 'crit_multiplier' => 2.0, - 'duration' => 0 // 立即效果 -]); -dd($damageEffect); +$res = \Game\Entities\Monster::create(1); +dd($res);