From b97bce3292e1bba75e60fff4149968e59286d723 Mon Sep 17 00:00:00 2001 From: bridge Date: Tue, 23 Sep 2025 00:43:37 +0800 Subject: [PATCH] update readme --- README.md | 4 ++++ src/classes/action.py | 37 +++++++++++++++++++++++------------- src/classes/actions.py | 8 ++------ src/classes/avatar.py | 4 ++-- src/classes/mutual_action.py | 28 +-------------------------- src/front/rendering.py | 10 ++++++---- src/run/run.py | 2 +- static/config.yml | 2 +- 8 files changed, 41 insertions(+), 54 deletions(-) diff --git a/README.md b/README.md index 8a50020..1f40f7b 100644 --- a/README.md +++ b/README.md @@ -119,6 +119,10 @@ - [ ] 世界观设定 - [ ] 背景故事框架 +### 特殊 +- [ ] 夺舍 +- [ ] 重生 + ## 使用方法 ### 运行步骤 diff --git a/src/classes/action.py b/src/classes/action.py index a8e4a86..04dfd07 100644 --- a/src/classes/action.py +++ b/src/classes/action.py @@ -12,6 +12,7 @@ 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 +from src.classes.battle import decide_battle if TYPE_CHECKING: from src.classes.avatar import Avatar @@ -572,16 +573,26 @@ class Sold(DefineAction, ActualActionMixin): return isinstance(region, CityRegion) and bool(self.avatar.items) -ALL_ACTION_CLASSES = [Move, Cultivate, Breakthrough, MoveToRegion, MoveToAvatar, Play, Hunt, Harvest, Sold] -ALL_ACTUAL_ACTION_CLASSES = [Cultivate, Breakthrough, MoveToRegion, MoveToAvatar, Play, Hunt, Harvest, Sold] -ALL_ACTION_NAMES = ["Move", "Cultivate", "Breakthrough", "MoveToRegion", "MoveToAvatar", "Play", "Hunt", "Harvest", "Sold"] -ALL_ACTUAL_ACTION_NAMES = ["Cultivate", "Breakthrough", "MoveToRegion", "MoveToAvatar", "Play", "Hunt", "Harvest", "Sold"] - -ACTION_INFOS = { - action.__name__: { - "comment": action.COMMENT, - "doable_requirements": action.DOABLES_REQUIREMENTS, - "params": action.PARAMS, - } for action in ALL_ACTUAL_ACTION_CLASSES -} -ACTION_INFOS_STR = json.dumps(ACTION_INFOS, ensure_ascii=False) \ No newline at end of file +class Battle(DefineAction, ChunkActionMixin): + COMMENT = "与目标进行对战,判定胜负" + DOABLES_REQUIREMENTS = "任何时候都可以执行" + PARAMS = {"avatar_name": "AvatarName"} + def _execute(self, avatar_name: str) -> None: + target = None + for v in self.world.avatar_manager.avatars.values(): + if v.name == avatar_name: + target = v + break + if target is None: + return + winner, loser, _ = decide_battle(self.avatar, target) + # 简化:失败者HP小额扣减 + if hasattr(loser, "hp"): + loser.hp.reduce(10) + def is_finished(self, avatar_name: str) -> bool: + return True + def get_event(self, avatar_name: str) -> Event: + return Event(self.world.month_stamp, f"{self.avatar.name} 与 {avatar_name} 进行对战") + @property + def is_doable(self) -> bool: + return True diff --git a/src/classes/actions.py b/src/classes/actions.py index 0373f96..6d36d54 100644 --- a/src/classes/actions.py +++ b/src/classes/actions.py @@ -3,8 +3,6 @@ from __future__ import annotations import json from src.classes.action import ( - DefineAction, - ActualActionMixin, Move, Cultivate, Breakthrough, @@ -14,19 +12,19 @@ from src.classes.action import ( Hunt, Harvest, Sold, + Battle, ) from src.classes.mutual_action import ( - MutualAction, DriveAway, AttackInteract, MoveAwayFromAvatar, MoveAwayFromRegion, - Battle, ) ALL_ACTION_CLASSES = [ Move, + Battle, Cultivate, Breakthrough, MoveToRegion, @@ -40,7 +38,6 @@ ALL_ACTION_CLASSES = [ AttackInteract, MoveAwayFromAvatar, MoveAwayFromRegion, - Battle, ] ALL_ACTUAL_ACTION_CLASSES = [ @@ -56,7 +53,6 @@ ALL_ACTUAL_ACTION_CLASSES = [ AttackInteract, MoveAwayFromAvatar, MoveAwayFromRegion, - Battle, ] ALL_ACTION_NAMES = [action.__name__ for action in ALL_ACTION_CLASSES] diff --git a/src/classes/avatar.py b/src/classes/avatar.py index 9230b37..f9a42e4 100644 --- a/src/classes/avatar.py +++ b/src/classes/avatar.py @@ -181,8 +181,8 @@ class Avatar: return False action_name, _ = pair action = self.create_action(action_name) - # 动作的 is_doable 定义为 @property - return bool(getattr(action, "is_doable", True)) + doable = action.is_doable + return doable async def act(self) -> List[Event]: """ diff --git a/src/classes/mutual_action.py b/src/classes/mutual_action.py index e84b25c..6acd65b 100644 --- a/src/classes/mutual_action.py +++ b/src/classes/mutual_action.py @@ -7,7 +7,6 @@ from src.classes.action import DefineAction, ActualActionMixin, LLMAction from src.classes.event import Event from src.utils.llm import get_prompt_and_call_llm from src.utils.config import CONFIG -from src.classes.battle import decide_battle if TYPE_CHECKING: from src.classes.avatar import Avatar @@ -207,29 +206,4 @@ class MoveAwayFromRegion(DefineAction, ActualActionMixin): return Event(self.world.month_stamp, f"{self.avatar.name} 离开 {region}") @property def is_doable(self) -> bool: - return True - - -class Battle(DefineAction, ActualActionMixin): - COMMENT = "与目标进行对战,判定胜负" - DOABLES_REQUIREMENTS = "任何时候都可以执行" - PARAMS = {"avatar_name": "AvatarName"} - def _execute(self, avatar_name: str) -> None: - target = None - for v in self.world.avatar_manager.avatars.values(): - if v.name == avatar_name: - target = v - break - if target is None: - return - winner, loser, _ = decide_battle(self.avatar, target) - # 简化:失败者HP小额扣减 - if hasattr(loser, "hp"): - loser.hp.reduce(10) - def is_finished(self, avatar_name: str) -> bool: - return True - def get_event(self, avatar_name: str) -> Event: - return Event(self.world.month_stamp, f"{self.avatar.name} 与 {avatar_name} 进行对战") - @property - def is_doable(self) -> bool: - return True + return True \ No newline at end of file diff --git a/src/front/rendering.py b/src/front/rendering.py index adb3172..451198b 100644 --- a/src/front/rendering.py +++ b/src/front/rendering.py @@ -112,11 +112,13 @@ def draw_avatars_and_pick_hover( return hovered -def draw_tooltip(pygame_mod, screen, colors, lines: List[str], mouse_x: int, mouse_y: int, font): +def draw_tooltip(pygame_mod, screen, colors, lines: List[str], mouse_x: int, mouse_y: int, font, min_width: Optional[int] = None): padding = 6 spacing = 2 surf_lines = [font.render(t, True, colors["text"]) for t in lines] width = max(s.get_width() for s in surf_lines) + padding * 2 + if min_width is not None: + width = max(width, min_width) height = sum(s.get_height() for s in surf_lines) + padding * 2 + spacing * (len(surf_lines) - 1) x = mouse_x + 12 y = mouse_y + 12 @@ -158,12 +160,12 @@ def draw_tooltip_for_avatar(pygame_mod, screen, colors, font, avatar: Avatar): if avatar.thinking: lines.append("") lines.append("思考:") - thinking_lines = wrap_text(avatar.thinking, 20) + thinking_lines = wrap_text(avatar.thinking, 28) lines.extend(thinking_lines) if getattr(avatar, "objective", None): lines.append("") lines.append("目标:") - objective_lines = wrap_text(avatar.objective, 20) + objective_lines = wrap_text(avatar.objective, 28) lines.extend(objective_lines) # 关系信息 @@ -175,7 +177,7 @@ def draw_tooltip_for_avatar(pygame_mod, screen, colors, font, avatar: Avatar): lines.append(f" {s}") else: lines.append("关系: 无") - draw_tooltip(pygame_mod, screen, colors, lines, *pygame_mod.mouse.get_pos(), font) + draw_tooltip(pygame_mod, screen, colors, lines, *pygame_mod.mouse.get_pos(), font, min_width=260) def draw_tooltip_for_region(pygame_mod, screen, colors, font, region, mouse_x: int, mouse_y: int): diff --git a/src/run/run.py b/src/run/run.py index d62fe2a..7d816f5 100644 --- a/src/run/run.py +++ b/src/run/run.py @@ -95,7 +95,7 @@ def make_avatars(world: World, count: int = 12, current_month_stamp: MonthStamp if len(avatar_list) >= 6: # 师徒(随意指派方向,关系对称) avatar_list[4].set_relation(avatar_list[5], Relation.MASTER_APPRENTICE) - if len(avatar_list) >= 6: + if len(avatar_list) >= 8: # 情侣 avatar_list[6].set_relation(avatar_list[7], Relation.LOVERS) return avatars diff --git a/static/config.yml b/static/config.yml index ce878ea..157a06b 100644 --- a/static/config.yml +++ b/static/config.yml @@ -12,7 +12,7 @@ ai: max_decide_num: 3 game: - init_npc_num: 3 + init_npc_num: 4 npc_birth_rate_per_month: 0.001 df: