diff --git a/src/classes/ai.py b/src/classes/ai.py
index 4fa7e80..3122259 100644
--- a/src/classes/ai.py
+++ b/src/classes/ai.py
@@ -99,6 +99,16 @@ class LLMAI(AI):
avatar_thinking = r.get("avatar_thinking", r.get("thinking", ""))
short_term_objective = r.get("short_term_objective", "")
+
+ # 更新情绪
+ from src.classes.emotions import EmotionType
+ raw_emotion = r.get("current_emotion", "平静")
+ try:
+ # 尝试通过 value (中文) 获取枚举
+ avatar.emotion = EmotionType(raw_emotion)
+ except ValueError:
+ avatar.emotion = EmotionType.CALM
+
results[avatar] = (pairs, avatar_thinking, short_term_objective)
return results
diff --git a/src/classes/avatar/core.py b/src/classes/avatar/core.py
index ba56206..186c20c 100644
--- a/src/classes/avatar/core.py
+++ b/src/classes/avatar/core.py
@@ -37,6 +37,7 @@ from src.classes.appearance import Appearance, get_random_appearance
from src.classes.spirit_animal import SpiritAnimal
from src.classes.long_term_objective import LongTermObjective
from src.classes.nickname_data import Nickname
+from src.classes.emotions import EmotionType
from src.utils.config import CONFIG
# Mixin 导入
@@ -106,6 +107,7 @@ class Avatar(
auxiliary: Optional[Auxiliary] = None
spirit_animal: Optional[SpiritAnimal] = None
nickname: Optional[Nickname] = None
+ emotion: EmotionType = EmotionType.CALM
custom_pic_id: Optional[int] = None
is_dead: bool = False
diff --git a/src/classes/avatar/info_presenter.py b/src/classes/avatar/info_presenter.py
index 57a1b78..ab3957e 100644
--- a/src/classes/avatar/info_presenter.py
+++ b/src/classes/avatar/info_presenter.py
@@ -12,6 +12,7 @@ if TYPE_CHECKING:
from src.classes.battle import get_base_strength
from src.classes.relation import get_relation_label
+from src.classes.emotions import EMOTION_EMOJIS, EmotionType
from src.utils.config import CONFIG
@@ -84,6 +85,7 @@ def get_avatar_info(avatar: "Avatar", detailed: bool = False) -> dict:
"外貌": appearance_info,
"兵器": weapon_info,
"辅助装备": auxiliary_info,
+ "情绪": avatar.emotion.value,
}
if detailed:
@@ -109,6 +111,8 @@ def get_avatar_structured_info(avatar: "Avatar") -> dict:
获取结构化的角色信息,用于前端展示和交互。
"""
# 基础信息
+ emoji = EMOTION_EMOJIS.get(avatar.emotion, EMOTION_EMOJIS[EmotionType.CALM])
+
info = {
"id": avatar.id,
"name": avatar.name,
@@ -121,6 +125,11 @@ def get_avatar_structured_info(avatar: "Avatar") -> dict:
"alignment": str(avatar.alignment) if avatar.alignment else "未知",
"magic_stone": avatar.magic_stone.value,
"base_battle_strength": int(get_base_strength(avatar)),
+ "emotion": {
+ "name": avatar.emotion.value,
+ "emoji": emoji,
+ "desc": avatar.emotion.value
+ },
"thinking": avatar.thinking,
"short_term_objective": avatar.short_term_objective,
"long_term_objective": avatar.long_term_objective.content if avatar.long_term_objective else "",
diff --git a/src/classes/emotions.py b/src/classes/emotions.py
new file mode 100644
index 0000000..3105279
--- /dev/null
+++ b/src/classes/emotions.py
@@ -0,0 +1,27 @@
+from enum import Enum
+
+class EmotionType(Enum):
+ CALM = "平静"
+ HAPPY = "开心"
+ ANGRY = "愤怒"
+ SAD = "悲伤"
+ FEARFUL = "恐惧"
+ SURPRISED = "惊讶"
+ ANTICIPATING = "期待"
+ DISGUSTED = "厌恶"
+ CONFUSED = "疑惑"
+ TIRED = "疲惫"
+
+# 情绪对应的 Emoji 配置
+EMOTION_EMOJIS = {
+ EmotionType.CALM: "😌",
+ EmotionType.HAPPY: "😄",
+ EmotionType.ANGRY: "😡",
+ EmotionType.SAD: "😢",
+ EmotionType.FEARFUL: "😨",
+ EmotionType.SURPRISED: "😲",
+ EmotionType.ANTICIPATING: "🤩",
+ EmotionType.DISGUSTED: "🤢",
+ EmotionType.CONFUSED: "😕",
+ EmotionType.TIRED: "😫",
+}
diff --git a/src/sim/load/avatar_load_mixin.py b/src/sim/load/avatar_load_mixin.py
index 9fcdcb4..e1cf7b4 100644
--- a/src/sim/load/avatar_load_mixin.py
+++ b/src/sim/load/avatar_load_mixin.py
@@ -155,6 +155,14 @@ class AvatarLoadMixin:
from src.classes.nickname_data import Nickname
avatar.nickname = Nickname.from_dict(data.get("nickname"))
+ # 恢复情绪
+ from src.classes.emotions import EmotionType
+ emotion_str = data.get("emotion", "平静")
+ try:
+ avatar.emotion = EmotionType(emotion_str)
+ except ValueError:
+ avatar.emotion = EmotionType.CALM
+
# 恢复死亡状态
avatar.is_dead = data.get("is_dead", False)
avatar.death_info = data.get("death_info")
diff --git a/src/sim/save/avatar_save_mixin.py b/src/sim/save/avatar_save_mixin.py
index 2567b37..b233f79 100644
--- a/src/sim/save/avatar_save_mixin.py
+++ b/src/sim/save/avatar_save_mixin.py
@@ -91,6 +91,7 @@ class AvatarSaveMixin:
"persona_ids": [p.id for p in self.personas] if self.personas else [],
"appearance": self.appearance.level,
"nickname": self.nickname.to_dict() if self.nickname else None,
+ "emotion": self.emotion.value,
"is_dead": self.is_dead,
"death_info": self.death_info,
diff --git a/static/game_configs/persona.csv b/static/game_configs/persona.csv
index 5441271..6db5dd9 100644
--- a/static/game_configs/persona.csv
+++ b/static/game_configs/persona.csv
@@ -61,3 +61,4 @@ id,name,exclusion_names,desc,rarity,condition,effects
59,扫把星,福缘深厚;气运之子,天生霉运缠身,喝凉水都塞牙。虽然活着不易,但也磨练了心性。,N,,"{extra_misfortune_probability: 0.005, extra_item_sell_price_multiplier: -0.1}"
60,大器晚成,,早年修行多舛,霉运连连;但若能坚持至金丹元婴,便可否极泰来,气运亨通。,SR,,"[{when: 'avatar.cultivation_progress.realm.value in [""练气"", ""筑基""]', extra_misfortune_probability: 0.005}, {when: 'avatar.cultivation_progress.realm.value in [""金丹"", ""元婴""]', extra_fortune_probability: 0.01}]"
61,炼器师,好斗,精通炼器之道,对材料敏锐,擅长铸造法宝。你认为法宝是修行的关键,战斗并非你的专长。,R,,{extra_cast_success_rate: 0.15}
+62,情绪化,理性;淡漠,你的情绪波动很大,极易受外界事件影响而改变心情,做事也更随心所欲。,N,,
diff --git a/static/templates/ai.txt b/static/templates/ai.txt
index ab46f26..bd81141 100644
--- a/static/templates/ai.txt
+++ b/static/templates/ai.txt
@@ -12,6 +12,7 @@
{{
{avatar_name}: {{
"avatar_thinking": ... // 从角色角度,以第一人称视角,简单清晰的描述想法
+ "current_emotion": ... // 从以下列表中选择一个最符合当前心情的词:平静、开心、愤怒、悲伤、恐惧、惊讶、期待、厌恶、疑惑、疲惫
"short_term_objective": ..., // 角色接下来一段时间的短期目标
"action_name_params_pairs": list[Tuple[action_name, action_params]] // 一次性决定未来的5~10个动作,按顺序执行
}}
diff --git a/web/src/components/game/panels/info/AvatarDetail.vue b/web/src/components/game/panels/info/AvatarDetail.vue
index 65f8d80..0d2b45d 100644
--- a/web/src/components/game/panels/info/AvatarDetail.vue
+++ b/web/src/components/game/panels/info/AvatarDetail.vue
@@ -109,6 +109,11 @@ async function handleClearObjective() {
+
diff --git a/web/src/types/core.ts b/web/src/types/core.ts
index 995b085..c141922 100644
--- a/web/src/types/core.ts
+++ b/web/src/types/core.ts
@@ -64,6 +64,13 @@ export interface AvatarDetail extends EntityBase {
magic_stone: number;
base_battle_strength: number;
+ // 情绪
+ emotion: {
+ name: string;
+ emoji: string;
+ desc: string;
+ };
+
// 属性与资质
alignment: string;
alignment_detail?: EffectEntity;