feat(npcs): add campaign NPCs with relation graph and session overlay
Add a dedicated NPC editor window, directed relations, control/presentation avatar overlay, and ru/en help for the new section. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -8,6 +8,10 @@ import type {
|
||||
MaterialsOverlayEvent,
|
||||
MaterialsOverlayState,
|
||||
MediaAsset,
|
||||
NpcId,
|
||||
NpcRelationId,
|
||||
NpcsOverlayEvent,
|
||||
NpcsOverlayState,
|
||||
Project,
|
||||
ProjectId,
|
||||
Scene,
|
||||
@@ -54,6 +58,14 @@ export const ipcChannels = {
|
||||
deleteMaterial: 'project.deleteMaterial',
|
||||
setMaterialsOrder: 'project.setMaterialsOrder',
|
||||
pickMaterialImage: 'project.pickMaterialImage',
|
||||
upsertNpc: 'project.upsertNpc',
|
||||
updateNpcFields: 'project.updateNpcFields',
|
||||
updateNpcPosition: 'project.updateNpcPosition',
|
||||
deleteNpc: 'project.deleteNpc',
|
||||
setNpcsOrder: 'project.setNpcsOrder',
|
||||
pickNpcAvatar: 'project.pickNpcAvatar',
|
||||
upsertNpcRelation: 'project.upsertNpcRelation',
|
||||
deleteNpcRelation: 'project.deleteNpcRelation',
|
||||
importScenePreview: 'project.importScenePreview',
|
||||
clearScenePreview: 'project.clearScenePreview',
|
||||
assetFileUrl: 'project.assetFileUrl',
|
||||
@@ -95,6 +107,10 @@ export const ipcChannels = {
|
||||
sceneDescriptionContent: 'windows.sceneDescriptionContent',
|
||||
openMaterials: 'windows.openMaterials',
|
||||
closeMaterials: 'windows.closeMaterials',
|
||||
openNpcsEditor: 'windows.openNpcsEditor',
|
||||
closeNpcsEditor: 'windows.closeNpcsEditor',
|
||||
openNpcs: 'windows.openNpcs',
|
||||
closeNpcs: 'windows.closeNpcs',
|
||||
},
|
||||
session: {
|
||||
stateChanged: 'session.stateChanged',
|
||||
@@ -109,6 +125,11 @@ export const ipcChannels = {
|
||||
dispatch: 'materialsOverlay.dispatch',
|
||||
stateChanged: 'materialsOverlay.stateChanged',
|
||||
},
|
||||
npcsOverlay: {
|
||||
getState: 'npcsOverlay.getState',
|
||||
dispatch: 'npcsOverlay.dispatch',
|
||||
stateChanged: 'npcsOverlay.stateChanged',
|
||||
},
|
||||
sceneDarkness: {
|
||||
getState: 'sceneDarkness.getState',
|
||||
dispatch: 'sceneDarkness.dispatch',
|
||||
@@ -172,6 +193,7 @@ export type IpcEventMap = {
|
||||
[ipcChannels.session.stateChanged]: { state: SessionState };
|
||||
[ipcChannels.effects.stateChanged]: { state: EffectsState };
|
||||
[ipcChannels.materialsOverlay.stateChanged]: { state: MaterialsOverlayState };
|
||||
[ipcChannels.npcsOverlay.stateChanged]: { state: NpcsOverlayState };
|
||||
[ipcChannels.sceneDarkness.stateChanged]: { state: SceneDarknessState };
|
||||
[ipcChannels.video.stateChanged]: { state: VideoPlaybackState };
|
||||
[ipcChannels.license.statusChanged]: { snapshot: LicenseSnapshot };
|
||||
@@ -274,6 +296,45 @@ export type IpcInvokeMap = {
|
||||
| { canceled: true }
|
||||
| { canceled: false; filePath: string; previewDataUrl: string };
|
||||
};
|
||||
[ipcChannels.project.upsertNpc]: {
|
||||
req: { npcId?: NpcId; name: string; description?: string; filePath?: string };
|
||||
res: { project: Project };
|
||||
};
|
||||
[ipcChannels.project.updateNpcFields]: {
|
||||
req: { npcId: NpcId; name?: string; description?: string };
|
||||
res: { project: Project };
|
||||
};
|
||||
[ipcChannels.project.updateNpcPosition]: {
|
||||
req: { npcId: NpcId; x: number; y: number };
|
||||
res: { project: Project };
|
||||
};
|
||||
[ipcChannels.project.deleteNpc]: {
|
||||
req: { npcId: NpcId };
|
||||
res: { project: Project };
|
||||
};
|
||||
[ipcChannels.project.setNpcsOrder]: {
|
||||
req: { npcIds: NpcId[] };
|
||||
res: { project: Project };
|
||||
};
|
||||
[ipcChannels.project.pickNpcAvatar]: {
|
||||
req: Record<string, never>;
|
||||
res:
|
||||
| { canceled: true }
|
||||
| { canceled: false; filePath: string; previewDataUrl: string };
|
||||
};
|
||||
[ipcChannels.project.upsertNpcRelation]: {
|
||||
req: {
|
||||
relationId?: NpcRelationId;
|
||||
sourceNpcId: NpcId;
|
||||
targetNpcId: NpcId;
|
||||
label: string;
|
||||
};
|
||||
res: { project: Project };
|
||||
};
|
||||
[ipcChannels.project.deleteNpcRelation]: {
|
||||
req: { relationId: NpcRelationId };
|
||||
res: { project: Project };
|
||||
};
|
||||
[ipcChannels.project.importScenePreview]: {
|
||||
req: { sceneId: SceneId; filePath?: string };
|
||||
res: { project: Project; assetId: AssetId | null; background: boolean };
|
||||
@@ -436,6 +497,22 @@ export type IpcInvokeMap = {
|
||||
req: Record<string, never>;
|
||||
res: { ok: true };
|
||||
};
|
||||
[ipcChannels.windows.openNpcsEditor]: {
|
||||
req: Record<string, never>;
|
||||
res: { ok: true };
|
||||
};
|
||||
[ipcChannels.windows.closeNpcsEditor]: {
|
||||
req: Record<string, never>;
|
||||
res: { ok: true };
|
||||
};
|
||||
[ipcChannels.windows.openNpcs]: {
|
||||
req: Record<string, never>;
|
||||
res: { ok: true };
|
||||
};
|
||||
[ipcChannels.windows.closeNpcs]: {
|
||||
req: Record<string, never>;
|
||||
res: { ok: true };
|
||||
};
|
||||
[ipcChannels.materialsOverlay.getState]: {
|
||||
req: Record<string, never>;
|
||||
res: { state: MaterialsOverlayState };
|
||||
@@ -444,6 +521,14 @@ export type IpcInvokeMap = {
|
||||
req: { event: MaterialsOverlayEvent };
|
||||
res: { ok: true };
|
||||
};
|
||||
[ipcChannels.npcsOverlay.getState]: {
|
||||
req: Record<string, never>;
|
||||
res: { state: NpcsOverlayState };
|
||||
};
|
||||
[ipcChannels.npcsOverlay.dispatch]: {
|
||||
req: { event: NpcsOverlayEvent };
|
||||
res: { ok: true };
|
||||
};
|
||||
[ipcChannels.effects.getState]: {
|
||||
req: Record<string, never>;
|
||||
res: { state: EffectsState };
|
||||
@@ -495,6 +580,7 @@ export type LegacyIpcEventMap = {
|
||||
[ipcChannels.session.stateChanged]: { state: SessionState };
|
||||
[ipcChannels.effects.stateChanged]: { state: EffectsState };
|
||||
[ipcChannels.materialsOverlay.stateChanged]: { state: MaterialsOverlayState };
|
||||
[ipcChannels.npcsOverlay.stateChanged]: { state: NpcsOverlayState };
|
||||
[ipcChannels.sceneDarkness.stateChanged]: { state: SceneDarknessState };
|
||||
[ipcChannels.video.stateChanged]: { state: VideoPlaybackState };
|
||||
[ipcChannels.license.statusChanged]: Record<string, never>;
|
||||
|
||||
Reference in New Issue
Block a user