diff --git a/src/classes/avatar/core.py b/src/classes/avatar/core.py index f603590..41a0b4c 100644 --- a/src/classes/avatar/core.py +++ b/src/classes/avatar/core.py @@ -257,6 +257,11 @@ class Avatar( from src.classes.avatar.info_presenter import get_other_avatar_info return get_other_avatar_info(self, other_avatar) + def get_desc(self, detailed: bool = False) -> str: + """获取角色的文本描述(包含效果明细)""" + from src.classes.avatar.info_presenter import get_avatar_desc + return get_avatar_desc(self, detailed=detailed) + # ========== 魔法方法 ========== def __post_init__(self): diff --git a/src/classes/avatar/effects_mixin.py b/src/classes/avatar/effects_mixin.py index 57c55d1..7b5789f 100644 --- a/src/classes/avatar/effects_mixin.py +++ b/src/classes/avatar/effects_mixin.py @@ -109,6 +109,51 @@ class EffectsMixin: return merged + def get_effect_breakdown(self: "Avatar") -> list[tuple[str, dict[str, Any]]]: + """ + 获取效果明细,返回 [(来源名称, 生效的效果字典), ...] + 用于 get_desc 展示。 + """ + breakdown = [] + + def _collect(name: str, source_obj): + if source_obj is None: + return + # 1. 评估条件 (when) + evaluated = _evaluate_conditional_effect(source_obj.effects, self) + # 2. 评估动态值 (expressions) + evaluated = self._evaluate_values(evaluated) + + if evaluated: + breakdown.append((name, evaluated)) + + # 按照优先级或逻辑顺序收集 + if self.sect: + _collect(f"宗门【{self.sect.name}】", self.sect) + + if self.technique: + _collect(f"功法【{self.technique.name}】", self.technique) + + if self.root: + _collect("灵根", self.root) + + for p in self.personas: + _collect(f"特质【{p.name}】", p) + + if self.weapon: + _collect(f"兵器【{self.weapon.name}】", self.weapon) + + if self.auxiliary: + _collect(f"辅助【{self.auxiliary.name}】", self.auxiliary) + + if self.spirit_animal: + _collect(f"灵兽【{self.spirit_animal.name}】", self.spirit_animal) + + if self.world.current_phenomenon: + _collect("天地灵机", self.world.current_phenomenon) + + return breakdown + def recalc_effects(self: "Avatar") -> None: """ 重新计算所有长期效果 diff --git a/src/classes/avatar/info_presenter.py b/src/classes/avatar/info_presenter.py index 993bf23..b60c7b3 100644 --- a/src/classes/avatar/info_presenter.py +++ b/src/classes/avatar/info_presenter.py @@ -15,6 +15,18 @@ from src.classes.relation import get_relation_label from src.utils.config import CONFIG +def _get_effects_text(avatar: "Avatar") -> str: + """获取格式化的效果文本""" + from src.utils.effect_desc import format_effects_to_text + breakdown = avatar.get_effect_breakdown() + effect_parts = [] + for source_name, effects in breakdown: + desc_str = format_effects_to_text(effects) + if desc_str: + effect_parts.append(f"[{source_name}] {desc_str}") + return "\n".join(effect_parts) if effect_parts else "无" + + def get_avatar_info(avatar: "Avatar", detailed: bool = False) -> dict: """ 获取 avatar 的信息,返回 dict;根据 detailed 控制信息粒度。 @@ -73,6 +85,10 @@ def get_avatar_info(avatar: "Avatar", detailed: bool = False) -> dict: "兵器": weapon_info, "辅助装备": auxiliary_info, } + + if detailed: + info_dict["当前效果"] = _get_effects_text(avatar) + # 绰号:仅在存在时显示 if avatar.nickname is not None: info_dict["绰号"] = avatar.nickname.value @@ -196,6 +212,9 @@ def get_avatar_structured_info(avatar: "Avatar") -> dict: if avatar.spirit_animal: info["spirit_animal"] = avatar.spirit_animal.get_structured_info() + # 当前效果 + info["当前效果"] = _get_effects_text(avatar) + return info @@ -348,3 +367,31 @@ def get_other_avatar_info(from_avatar: "Avatar", to_avatar: "Avatar") -> str: f"外貌:{to_avatar.appearance.get_info()},功法:{tech},兵器:{weapon},辅助:{aux},HP:{to_avatar.hp}" ) + +def get_avatar_desc(avatar: "Avatar", detailed: bool = False) -> str: + """ + 获取角色的文本描述。 + detailed=True 时包含详细的效果来源分析。 + """ + # 基础描述 + lines = [f"【{avatar.name}】 {avatar.gender} {avatar.age}岁"] + lines.append(f"境界: {avatar.cultivation_progress.get_info()}") + if avatar.sect: + lines.append(f"身份: {avatar.get_sect_str()}") + + if detailed: + lines.append("\n--- 当前效果明细 ---") + breakdown = avatar.get_effect_breakdown() + + from src.utils.effect_desc import format_effects_to_text + + if not breakdown: + lines.append("无额外效果") + else: + for source_name, effects in breakdown: + # 使用现有的 format_effects_to_text 将字典转为中文描述 + desc_str = format_effects_to_text(effects) + if desc_str: + lines.append(f"[{source_name}]: {desc_str}") + + return "\n".join(lines) diff --git a/src/classes/cultivation.py b/src/classes/cultivation.py index b5b7692..5f12472 100644 --- a/src/classes/cultivation.py +++ b/src/classes/cultivation.py @@ -146,7 +146,7 @@ class CultivationProgress: def get_detailed_info(self) -> str: can_break_through = self.can_break_through() - can_break_through_str = "可以突破" if can_break_through else "不可以突破" + can_break_through_str = "需要突破" if can_break_through else "未到瓶颈无需突破" return f"{self.realm.value}{self.stage.value}({self.level}级){can_break_through_str}" def get_info(self) -> str: diff --git a/src/utils/effect_desc.py b/src/utils/effect_desc.py index 71315e4..5158c38 100644 --- a/src/utils/effect_desc.py +++ b/src/utils/effect_desc.py @@ -9,11 +9,12 @@ EFFECT_DESC_MAP = { "extra_dual_cultivation_exp": "双修经验", "extra_breakthrough_success_rate": "突破成功率", "extra_fortune_probability": "奇遇概率", + "extra_misfortune_probability": "霉运概率", "extra_harvest_items": "采集获取物品", "extra_hunt_items": "狩猎获取物品", "extra_item_sell_price_multiplier": "物品出售价格", "extra_weapon_upgrade_chance": "兵器升级概率", - "extra_plunder_multiplier": "掠夺收益", + "extra_plunder_multiplier": "搜刮收益", "extra_catch_success_rate": "捕捉灵兽成功率", "extra_cultivate_exp": "修炼经验", "extra_battle_strength_points": "战力点数", diff --git a/web/src/components/game/panels/info/AvatarDetail.vue b/web/src/components/game/panels/info/AvatarDetail.vue index fdc6f0d..32aed44 100644 --- a/web/src/components/game/panels/info/AvatarDetail.vue +++ b/web/src/components/game/panels/info/AvatarDetail.vue @@ -187,6 +187,21 @@ async function handleClearObjective() {
短期目标
{{ data.short_term_objective || '无' }}
+ + +
+
当前效果
+
+
+
{{ line.match(/^\[(.*?)\]/)?.[1] || '其他' }}
+
{{ line.replace(/^\[.*?\]\s*/, '') }}
+
+
+
@@ -358,4 +373,29 @@ async function handleClearObjective() { display: flex; gap: 10px; } + +.effects-list { + display: flex; + flex-direction: column; + gap: 4px; +} + +.effect-row { + display: flex; + gap: 8px; + font-size: 12px; + align-items: flex-start; +} + +.effect-source { + min-width: 80px; + color: #888; + text-align: right; + flex-shrink: 0; +} + +.effect-content { + color: #aaddff; + flex: 1; +} diff --git a/web/src/types/core.ts b/web/src/types/core.ts index 5984f5a..14dd81c 100644 --- a/web/src/types/core.ts +++ b/web/src/types/core.ts @@ -85,6 +85,9 @@ export interface AvatarDetail extends EntityBase { // 列表数据 items: Item[]; relations: RelationInfo[]; + + // 附加信息 + "当前效果"?: string; } export interface SectInfo extends EffectEntity {