update readme

This commit is contained in:
bridge
2025-09-23 00:43:37 +08:00
parent a5e04aa80f
commit b97bce3292
8 changed files with 41 additions and 54 deletions

View File

@@ -119,6 +119,10 @@
- [ ] 世界观设定
- [ ] 背景故事框架
### 特殊
- [ ] 夺舍
- [ ] 重生
## 使用方法
### 运行步骤

View File

@@ -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)
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

View File

@@ -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]

View File

@@ -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]:
"""

View File

@@ -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

View File

@@ -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):

View File

@@ -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

View File

@@ -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: