update death

This commit is contained in:
bridge
2025-12-01 02:05:11 +08:00
parent f047251c0d
commit 39f158bbe8
18 changed files with 185 additions and 66 deletions

View File

@@ -11,8 +11,12 @@ const emit = defineEmits<{
(e: 'avatarSelected', payload: { type: 'avatar'; id: string; name?: string }): void
}>()
const visibleAvatars = computed(() => {
return worldStore.avatarList.filter(a => !a.is_dead)
})
const avatarOffsets = computed(() => {
return calculateVisualOffsets(worldStore.avatarList)
return calculateVisualOffsets(visibleAvatars.value)
})
function handleAvatarSelect(payload: { type: 'avatar'; id: string; name?: string }) {
@@ -23,7 +27,7 @@ function handleAvatarSelect(payload: { type: 'avatar'; id: string; name?: string
<template>
<container sortable-children>
<AnimatedAvatar
v-for="avatar in worldStore.avatarList"
v-for="avatar in visibleAvatars"
:key="avatar.id"
:avatar="avatar"
:tile-size="TILE_SIZE"

View File

@@ -67,10 +67,13 @@ async function handleClearObjective() {
/>
<!-- Actions Bar -->
<div class="actions-bar">
<div class="actions-bar" v-if="!data.is_dead">
<button class="btn primary" @click="showObjectiveModal = true">设定目标</button>
<button class="btn" @click="handleClearObjective">清空目标</button>
</div>
<div class="dead-banner" v-else>
已故 ({{ data.death_info?.reason || '未知原因' }})
</div>
<div class="content-scroll">
<!-- Stats Grid -->
@@ -212,6 +215,17 @@ async function handleClearObjective() {
margin-bottom: 12px;
}
.dead-banner {
background: #4a1a1a;
color: #ffaaaa;
padding: 8px;
border-radius: 4px;
text-align: center;
font-size: 13px;
margin-bottom: 12px;
border: 1px solid #7a2a2a;
}
.content-scroll {
flex: 1;
overflow-y: auto;

View File

@@ -9,7 +9,10 @@ const eventListRef = ref<HTMLElement | null>(null)
const filterOptions = computed(() => [
{ label: '所有人', value: 'all' },
...worldStore.avatarList.map(avatar => ({ label: avatar.name ?? avatar.id, value: avatar.id }))
...worldStore.avatarList.map(avatar => ({
label: (avatar.name ?? avatar.id) + (avatar.is_dead ? ' (已故)' : ''),
value: avatar.id
}))
])
const filteredEvents = computed(() => {

View File

@@ -117,32 +117,17 @@ export const useWorldStore = defineStore('world', () => {
setTime(payload.year, payload.month);
// 检查并处理死亡事件,移除已死亡的角色
if (payload.events && Array.isArray(payload.events)) {
const deathEvents = (payload.events as any[]).filter((e: any) => {
const c = e.content || '';
return c.includes('身亡') || c.includes('老死');
});
if (deathEvents.length > 0) {
const next = new Map(avatars.value);
let changed = false;
for (const de of deathEvents) {
if (de.related_avatar_ids && Array.isArray(de.related_avatar_ids)) {
for (const id of de.related_avatar_ids) {
if (next.has(id)) {
next.delete(id);
changed = true;
}
}
}
}
if (changed) {
avatars.value = next;
}
}
}
// if (payload.events && Array.isArray(payload.events)) {
// const deathEvents = (payload.events as any[]).filter((e: any) => {
// const c = e.content || '';
// return c.includes('身亡') || c.includes('老死');
// });
//
// if (deathEvents.length > 0) {
// // 旧逻辑:主动删除死人。现在改为软删除,后端会在 avatars 更新中推送 is_dead 状态,
// // 所以这里不再需要主动操作。前端展示层根据 is_dead 决定是否隐藏。
// }
// }
if (payload.avatars) updateAvatars(payload.avatars);
if (payload.events) addEvents(payload.events);

View File

@@ -37,6 +37,7 @@ export interface AvatarSummary extends EntityBase, Coordinates {
action?: string;
gender?: string;
pic_id?: number;
is_dead?: boolean;
}
export interface AvatarDetail extends EntityBase {
@@ -46,6 +47,12 @@ export interface AvatarDetail extends EntityBase {
lifespan: number;
nickname?: string;
appearance: string; // 外貌描述
is_dead?: boolean;
death_info?: {
time: number;
reason: string;
location: [number, number];
};
// 修行状态
realm: string;