This commit is contained in:
bridge
2025-11-22 16:56:03 +08:00
parent c6d1814263
commit 5aaf6abcbb
8 changed files with 26 additions and 21 deletions

View File

@@ -109,7 +109,8 @@ class Conversation(MutualAction):
set_event = Event(
self.world.month_stamp,
f"{target.name}{self.avatar.name} 的关系变为:{relation_display_names.get(rel, str(rel))}",
related_avatars=[self.avatar.id, target.id]
related_avatars=[self.avatar.id, target.id],
is_major=True
)
EventHelper.push_pair(set_event, initiator=self.avatar, target=target, to_sidebar_once=True)
@@ -122,7 +123,8 @@ class Conversation(MutualAction):
cancel_event = Event(
self.world.month_stamp,
f"{target.name}{self.avatar.name} 取消了关系:{relation_display_names.get(rel, str(rel))}",
related_avatars=[self.avatar.id, target.id]
related_avatars=[self.avatar.id, target.id],
is_major=True
)
EventHelper.push_pair(cancel_event, initiator=self.avatar, target=target, to_sidebar_once=True)

View File

@@ -40,8 +40,8 @@ def can_get_nickname(avatar: "Avatar") -> bool:
major_threshold = CONFIG.nickname.major_event_threshold
minor_threshold = CONFIG.nickname.minor_event_threshold
major_events = em.get_major_events_by_avatar(avatar.id)
minor_events = em.get_minor_events_by_avatar(avatar.id)
major_events = em.get_major_events_by_avatar(avatar.id, limit=major_threshold)
minor_events = em.get_minor_events_by_avatar(avatar.id, limit=minor_threshold)
major_count = len(major_events)
minor_count = len(minor_events)
@@ -115,7 +115,7 @@ async def process_avatar_nickname(avatar: "Avatar") -> Optional[Event]:
# 生成事件:角色获得绰号
event = Event(
avatar.world.month_stamp,
f"{avatar.name}在修仙界中闯出名号,被人称为'{nickname}'",
f"{avatar.name}在修仙界中闯出名号,被人称为{nickname}",
related_avatars=[avatar.id],
is_major=True
)

View File

@@ -185,5 +185,8 @@ class AvatarLoadMixin:
# relations需要在外部单独重建因为需要所有avatar都加载完成
avatar.relations = {}
# 加载完成后重新计算effects确保数值正确
avatar.recalc_effects()
return avatar

View File

@@ -20,8 +20,8 @@ ai:
game:
init_npc_num: 6
sect_num: 2 # init_npc_num大于sect_num时会随机选择sect_num个宗门
npc_birth_rate_per_month: 0.001
fortune_probability: 0.001
npc_birth_rate_per_month: 0.01
fortune_probability: 0.005
df:
ids_separator: ";"
@@ -34,8 +34,8 @@ social:
minor_event_context_num: 10 # 小事(短期记忆)展示数量
nickname:
major_event_threshold: 10 # 获得绰号需要的长期事件数量
minor_event_threshold: 50 # 获得绰号需要的短期事件数量
major_event_threshold: 3 # 获得绰号需要的长期事件数量
minor_event_threshold: 20 # 获得绰号需要的短期事件数量
save:
max_events_to_save: 1000

View File

@@ -2,7 +2,7 @@
绰号是修仙界中对一个人物的评价和称谓,要求:
1. 符合修仙世界观,具有仙侠风格
2. 体现角色的特点、行为、性格或事迹
2. 可以有多种不同角度,比如角色的性格、行为、事迹、关系、武器、长相、功法、宗门等
3. 简洁有力朗朗上口、2~5个字
4. 要帅气、有意境、多种多样

View File

@@ -71,7 +71,7 @@ async function handleClearObjective() {
<!-- Stats Grid -->
<div class="stats-grid">
<StatItem label="境界" :value="data.realm" :sub-value="data.level" />
<StatItem label="年龄" :value="formatAge(data.age, data.lifespan)" />
<StatItem label="年龄" :value="`${data.age} / ${data.lifespan}`" />
<StatItem label="HP" :value="formatHp(data.hp.cur, data.hp.max)" />
<StatItem label="MP" :value="formatHp(data.mp.cur, data.mp.max)" />

View File

@@ -26,8 +26,8 @@ const title = computed(() => {
});
const subTitle = computed(() => {
if (uiStore.detailData && 'nickname' in uiStore.detailData) {
return uiStore.detailData.nickname;
if (uiStore.detailData && 'nickname' in uiStore.detailData && uiStore.detailData.nickname) {
return `${uiStore.detailData.nickname}`;
}
return '';
});

View File

@@ -42,12 +42,10 @@ export const useWorldStore = defineStore('world', () => {
if (existing) {
// Merge
next.set(av.id, { ...existing, ...av } as AvatarSummary);
} else {
// Insert (ensure required fields exist if possible, otherwise cast)
// 在 Tick 中出现的新 Avatar 可能是完整的
next.set(av.id, av as AvatarSummary);
changed = true;
}
changed = true;
// Else: ignore. Do NOT insert new avatars from tick updates,
// as tick data is incomplete (position only) and might be from a stale game state (Race Condition).
}
if (changed) {
@@ -66,9 +64,9 @@ export const useWorldStore = defineStore('world', () => {
year: e.year ?? year.value,
month: e.month ?? month.value,
timestamp: (e.year ?? year.value) * 12 + (e.month ?? month.value),
relatedAvatarIds: e.relatedAvatarIds || [],
isMajor: e.isMajor,
isStory: e.isStory
relatedAvatarIds: e.related_avatar_ids || [],
isMajor: e.is_major,
isStory: e.is_story
}));
// 排序并保留最新的 N 条
@@ -80,6 +78,8 @@ export const useWorldStore = defineStore('world', () => {
}
function handleTick(payload: TickPayloadDTO) {
if (!isLoaded.value) return;
setTime(payload.year, payload.month);
if (payload.avatars) updateAvatars(payload.avatars);
if (payload.events) addEvents(payload.events);