From 38cb4ab15e5720bc43c1e46a754b7e2985bed60d Mon Sep 17 00:00:00 2001 From: bridge Date: Tue, 16 Sep 2025 23:21:13 +0800 Subject: [PATCH] add hp mp --- README.md | 4 +- src/classes/action.py | 27 ++++++++++++ src/classes/avatar.py | 13 +++++- src/classes/hp_and_mp.py | 88 ++++++++++++++++++++++++++++++++++++++++ src/front/rendering.py | 2 + src/run/run.py | 2 +- 6 files changed, 131 insertions(+), 5 deletions(-) create mode 100644 src/classes/hp_and_mp.py diff --git a/README.md b/README.md index 8e59994..8813d12 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ - ✅ 灵根系统 - ✅ 基础移动动作 - ✅ 角色性格 -- [ ] 灵光一闪 & 缘法 +- [ ] 灵光一闪 & 机缘 - [ ] 角色突破机制:动态的突破成功概率、不同突破结果和效果 - [ ] 角色关系系统 - [ ] 角色特殊能力 @@ -53,7 +53,7 @@ - [ ] 技能学习系统: - [ ] 可学习技能 - [ ] 个人技(灵活融入代码) - - [ ] 生活职业(丹药、阵法、种植、铸造etc) + - [ ] 生活职业(丹药、阵法、种植、铸造etc,配合特殊prompt和信息空间) - [ ] 凡人角色支持 - [ ] 天骄系统(更强能力,更强AI) diff --git a/src/classes/action.py b/src/classes/action.py index 177c319..b4b71c1 100644 --- a/src/classes/action.py +++ b/src/classes/action.py @@ -11,6 +11,7 @@ from src.classes.region import Region, CultivateRegion, NormalRegion, CityRegion from src.classes.event import Event, NULL_EVENT from src.classes.item import Item, items_by_name from src.classes.prices import prices +from src.classes.hp_and_mp import HP_MAX_BY_REALM, MP_MAX_BY_REALM if TYPE_CHECKING: from src.classes.avatar import Avatar @@ -298,7 +299,33 @@ class Breakthrough(DefineAction, ActualActionMixin): assert self.avatar.cultivation_progress.can_break_through() success_rate = self.calc_success_rate() if random.random() < success_rate: + old_realm = self.avatar.cultivation_progress.realm self.avatar.cultivation_progress.break_through() + new_realm = self.avatar.cultivation_progress.realm + + # 突破成功时更新HP和MP的最大值 + if new_realm != old_realm: + self._update_hp_mp_on_breakthrough(new_realm) + + def _update_hp_mp_on_breakthrough(self, new_realm): + """ + 突破境界时更新HP和MP的最大值并完全恢复 + + Args: + new_realm: 新的境界 + """ + new_max_hp = HP_MAX_BY_REALM.get(new_realm, 100) + new_max_mp = MP_MAX_BY_REALM.get(new_realm, 100) + + # 计算增加的最大值 + hp_increase = new_max_hp - self.avatar.hp.max + mp_increase = new_max_mp - self.avatar.mp.max + + # 更新最大值并恢复相应的当前值 + self.avatar.hp.add_max(hp_increase) + self.avatar.hp.recover(hp_increase) # 突破时完全恢复HP + self.avatar.mp.add_max(mp_increase) + self.avatar.mp.recover(mp_increase) # 突破时完全恢复MP def get_event(self) -> Event: """ diff --git a/src/classes/avatar.py b/src/classes/avatar.py index 3012a96..5a7a88a 100644 --- a/src/classes/avatar.py +++ b/src/classes/avatar.py @@ -18,6 +18,7 @@ from src.classes.typings import ACTION_NAME, ACTION_PARAMS, ACTION_PAIR, ACTION_ from src.classes.persona import Persona, personas_by_id from src.classes.item import Item from src.classes.magic_stone import MagicStone +from src.classes.hp_and_mp import HP, MP, HP_MAX_BY_REALM, MP_MAX_BY_REALM from src.utils.id_generator import get_avatar_id from src.utils.config import CONFIG @@ -62,12 +63,20 @@ class Avatar: objective: str = "" magic_stone: MagicStone = field(default_factory=lambda: MagicStone(0)) # 灵石,即货币 items: dict[Item, int] = field(default_factory=dict) + hp: HP = field(default_factory=lambda: HP(0, 0)) # 将在__post_init__中初始化 + mp: MP = field(default_factory=lambda: MP(0, 0)) # 将在__post_init__中初始化 def __post_init__(self): """ - 在Avatar创建后自动初始化tile + 在Avatar创建后自动初始化tile和HP/MP """ self.tile = self.world.map.get_tile(self.pos_x, self.pos_y) + + # 根据当前境界初始化HP和MP + max_hp = HP_MAX_BY_REALM.get(self.cultivation_progress.realm, 100) + max_mp = MP_MAX_BY_REALM.get(self.cultivation_progress.realm, 100) + self.hp = HP(max_hp, max_hp) + self.mp = MP(max_mp, max_mp) def __hash__(self) -> int: return hash(self.id) @@ -77,7 +86,7 @@ class Avatar: 获取avatar的详细信息 尽量多打一些,因为会用来给LLM进行决策 """ - return f"Avatar(id={self.id}, 性别={self.gender}, 年龄={self.age}, name={self.name}, 区域={self.tile.region.name}, 灵根={self.root.value}, 境界={self.cultivation_progress})" + return f"Avatar(id={self.id}, 性别={self.gender}, 年龄={self.age}, name={self.name}, 区域={self.tile.region.name}, 灵根={self.root.value}, 境界={self.cultivation_progress}, HP={self.hp}, MP={self.mp})" def __str__(self) -> str: return self.get_info() diff --git a/src/classes/hp_and_mp.py b/src/classes/hp_and_mp.py new file mode 100644 index 0000000..b187a04 --- /dev/null +++ b/src/classes/hp_and_mp.py @@ -0,0 +1,88 @@ +from dataclasses import dataclass + +from src.classes.cultivation import Realm + +@dataclass +class HP: + """ + 血量。 + 会因为战斗,天灾或者其他原因降低cur。 + 会随时间或者服用丹药等补充cur。 + 会因为突破境界,服用丹药等增加max。 + """ + max: int + cur: int + + def reduce(self, value_2_reduce:int) -> bool: + self.cur -= value_2_reduce + is_alive = True + if self.cur < 0: + is_alive = False + return is_alive + + def recover(self, value_2_recover:int) -> bool: + self.cur += value_2_recover + if self.cur > self.max: + self.cur = self.max + return True + + def add_max(self, value_2_add:int) -> bool: + self.max += value_2_add + return True + + def __str__(self) -> str: + return f"{self.cur}/{self.max}" + + def __repr__(self) -> str: + return self.__str__() + +HP_MAX_BY_REALM = { + Realm.Qi_Refinement: 100, + Realm.Foundation_Establishment: 200, + Realm.Core_Formation: 300, + Realm.Nascent_Soul: 400, +} + + +@dataclass +class MP: + """ + 灵力 + 会因为战斗而消耗cur。 + 会随时间或者服用丹药等补充cur。 + 会因为突破境界,服用丹药等增加max。 + """ + max: int + cur: int + + def can_cast(self, value_2_cast:int) -> bool: + return self.cur >= value_2_cast + + def reduce(self, value_2_reduce:int) -> bool: + self.cur -= value_2_reduce + if self.cur < 0: + self.cur = 0 + return True + + def recover(self, value_2_recover:int) -> bool: + self.cur += value_2_recover + if self.cur > self.max: + self.cur = self.max + return True + + def __str__(self) -> str: + return f"{self.cur}/{self.max}" + + def __repr__(self) -> str: + return self.__str__() + + def add_max(self, value_2_add:int) -> bool: + self.max += value_2_add + return True + +MP_MAX_BY_REALM = { + Realm.Qi_Refinement: 100, + Realm.Foundation_Establishment: 200, + Realm.Core_Formation: 300, + Realm.Nascent_Soul: 400, +} \ No newline at end of file diff --git a/src/front/rendering.py b/src/front/rendering.py index 452bada..50ad848 100644 --- a/src/front/rendering.py +++ b/src/front/rendering.py @@ -126,6 +126,8 @@ def draw_tooltip_for_avatar(pygame_mod, screen, colors, font, avatar: Avatar): f"性别: {avatar.gender}", f"年龄: {avatar.age}", f"境界: {str(avatar.cultivation_progress)}", + f"HP: {avatar.hp}", + f"MP: {avatar.mp}", f"灵根: {avatar.root.value}", f"个性: {avatar.persona.name}", f"位置: ({avatar.pos_x}, {avatar.pos_y})", diff --git a/src/run/run.py b/src/run/run.py index 889479e..db57284 100644 --- a/src/run/run.py +++ b/src/run/run.py @@ -108,7 +108,7 @@ async def main(): simulator=sim, tile_size=19, # 减小20%的tile大小 (24 * 0.8 ≈ 19) margin=8, - step_interval_ms=350, + step_interval_ms=750, window_title="Cultivation World — Front Demo", sidebar_width=350, # 新增:设置侧边栏宽度 )