feat(grid): именованные шаблоны сетки кампании
Несколько шаблонов в проекте с ручным сохранением и применением (включает сетку); без автоподстановки. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -84,6 +84,7 @@ function minimalProject(overrides: Partial<Project> = {}): Project {
|
||||
assets: {},
|
||||
campaignAudios: [],
|
||||
materials: [],
|
||||
gridTemplates: [],
|
||||
npcs: [],
|
||||
npcGroups: [],
|
||||
npcRelations: [],
|
||||
|
||||
@@ -13,6 +13,7 @@ import type { AssetId, NpcGroupId, ProjectId, TokenId } from '../types/ids';
|
||||
import {
|
||||
asAssetId,
|
||||
asGraphNodeId,
|
||||
asGridTemplateId,
|
||||
asMaterialId,
|
||||
asNpcGroupId,
|
||||
asNpcId,
|
||||
@@ -23,6 +24,11 @@ import {
|
||||
asTokenId,
|
||||
} from '../types/ids';
|
||||
import { normalizeNpcExternalUrl } from '../types/npcExternalUrl';
|
||||
import {
|
||||
MAX_SCENE_GRID_TEMPLATES,
|
||||
sceneGridTemplateStyleFromGrid,
|
||||
type SceneGridTemplate,
|
||||
} from '../types/sceneGrid';
|
||||
|
||||
import {
|
||||
getConnectedComponent,
|
||||
@@ -318,6 +324,7 @@ export function buildPartialExportProject(
|
||||
assets,
|
||||
campaignAudios: source.campaignAudios.map((a) => ({ ...a })),
|
||||
materials: (source.materials ?? []).map((m) => ({ ...m })),
|
||||
gridTemplates: (source.gridTemplates ?? []).map((t) => ({ ...t })),
|
||||
currentSceneId: mainStart?.sceneId ?? firstSide?.sceneId ?? null,
|
||||
currentGraphNodeId: mainStart?.id ?? firstSide?.id ?? null,
|
||||
};
|
||||
@@ -626,6 +633,28 @@ export function mergeStorylinesIntoProject(
|
||||
materialAssetIds.add(mapped);
|
||||
}
|
||||
|
||||
const gridTemplates = [...(target.gridTemplates ?? [])];
|
||||
const gridTemplateNameKeys = new Set(gridTemplates.map((t) => t.name.trim().toLowerCase()));
|
||||
for (const t of source.gridTemplates ?? []) {
|
||||
if (gridTemplates.length >= MAX_SCENE_GRID_TEMPLATES) break;
|
||||
let name = t.name.trim();
|
||||
if (!name) continue;
|
||||
const baseKey = name.toLowerCase();
|
||||
if (gridTemplateNameKeys.has(baseKey)) {
|
||||
let n = 2;
|
||||
while (gridTemplateNameKeys.has(`${baseKey} (${String(n)})`)) n += 1;
|
||||
name = `${name} (${String(n)})`;
|
||||
}
|
||||
const style = sceneGridTemplateStyleFromGrid(t);
|
||||
const next: SceneGridTemplate = {
|
||||
id: asGridTemplateId(`gt_${generateId()}`),
|
||||
name,
|
||||
...style,
|
||||
};
|
||||
gridTemplates.push(next);
|
||||
gridTemplateNameKeys.add(name.toLowerCase());
|
||||
}
|
||||
|
||||
// Группы только для создаваемых НПС выбранных линий.
|
||||
const npcsToCreate = exportedNpcs.filter((n) => npcResolutionBySource.get(n.id)?.mode !== 'use');
|
||||
const neededGroupIds = collectNpcGroupIdsForNpcs(source.npcGroups ?? [], npcsToCreate);
|
||||
@@ -759,6 +788,7 @@ export function mergeStorylinesIntoProject(
|
||||
assets,
|
||||
campaignAudios,
|
||||
materials,
|
||||
gridTemplates,
|
||||
npcs,
|
||||
npcGroups,
|
||||
npcRelations,
|
||||
|
||||
Reference in New Issue
Block a user