fix(01-06): wire raw point event ingestion

- Bind serialized point events to the coordinate event view.
- Select the event layer by its event alias and verify the static view stays clean.
This commit is contained in:
unanmed 2026-09-08 23:52:13 +08:00
parent 6f6ed62b1b
commit 564ef25360
2 changed files with 90 additions and 21 deletions

View File

@ -0,0 +1,64 @@
import { beforeAll, describe, expect, it, vi } from 'vitest';
interface TestModules {
MapState: typeof import('./mapState').MapState;
TileStore: typeof import('@user/data-common').TileStore;
RoleFaceBinder: typeof import('@user/data-common').RoleFaceBinder;
logger: typeof import('@motajs/common').logger;
}
let modules: TestModules;
beforeAll(async () => {
vi.stubGlobal('main', { replayChecking: true });
const mapModule = await import('./mapState');
const commonModule = await import('@user/data-common');
const loggerModule = await import('@motajs/common');
modules = {
MapState: mapModule.MapState,
TileStore: commonModule.TileStore,
RoleFaceBinder: commonModule.RoleFaceBinder,
logger: loggerModule.logger
};
});
function createRaw() {
return {
floorId: 'F1',
width: 2,
map: { 0: [1, 1, 1, 1] },
layerAlias: { 0: 'event' },
events: { 0: { 1: { 5: 'point-event' } } }
};
}
function createMapState() {
const tileStore = new modules.TileStore();
const state = {
tileStore,
itemStore: {},
mapStore: {},
eventStore: {},
roleFace: new modules.RoleFaceBinder(),
faceManager: {},
saveSystem: {}
};
return new modules.MapState(tileStore, state);
}
describe('MapState raw event path', () => {
it('raw point events and event layer', () => {
const mapState = createMapState();
const map = mapState.fromRaw(createRaw());
const layer = map?.eventLayer;
expect(layer).toBe(map?.getLayerByAlias('event'));
expect(layer?.getPointEvent(1, 0)).toEqual(
new Map([[5, 'point-event']])
);
expect(layer?.getLocationData(1, 0)?.static.tileEvent().get()).toEqual(
new Map()
);
expect(layer?.event(1, 0)?.dirty()).toBe(false);
});
});

View File

@ -1,4 +1,4 @@
import { isNil, uniq } from 'lodash-es';
import { uniq } from 'lodash-es';
import { IDataCommon, IMapRawData, SaveCompression } from '@user/data-common';
import { ITileStore } from '@user/data-common';
import {
@ -42,14 +42,24 @@ export class MapState implements IMapState {
const entries = Object.entries(raw.map);
for (const [_, map] of Object.entries(raw.map)) {
if (length > 0 && map.length !== length) {
logger.error(60, map.length.toString(), length.toString());
logger.error(
60,
map.length.toString(),
length.toString(),
raw.floorId
);
return null;
} else {
length = map.length;
}
}
if (length % raw.width !== 0) {
logger.error(61, length.toString(), raw.width.toString());
logger.error(
61,
length.toString(),
raw.width.toString(),
raw.floorId
);
return null;
}
@ -58,32 +68,27 @@ export class MapState implements IMapState {
const state = this.createMap(raw.floorId, raw.width, height);
for (const [zIndex, map] of entries) {
const z = Number(zIndex);
if (isNaN(z)) {
logger.error(62, 'IMapRawData.map', String(zIndex));
continue;
}
const layer = state.addLayer();
const alias = raw.layerAlias[z];
layer.setMapRef(new Uint32Array(map));
layer.setZIndex(z);
state.setLayerAlias(layer, alias);
// 设置图块静态触发器
const extra = raw.blockData[z];
for (const [index, data] of Object.entries(extra)) {
// 设置坐标点事件
const events = raw.events[z];
for (const [index, tileEvents] of Object.entries(events)) {
const indexNum = Number(index);
if (isNaN(indexNum)) {
logger.error(62, 'IMapRawData.blockData', String(index));
continue;
}
if (!isNil(data.trigger)) {
const x = indexNum % raw.width;
const y = Math.floor(indexNum / raw.width);
const location = layer.getLocationData(x, y);
if (location) {
location.static.addTrigger(data.trigger);
}
const x = indexNum % raw.width;
const y = Math.floor(indexNum / raw.width);
const eventView = layer.event(x, y)!;
for (const [priority, id] of Object.entries(tileEvents)) {
const priorityNum = Number(priority);
eventView.set(priorityNum, id);
}
eventView.markPure();
}
if (alias === 'event') {
state.setEventLayer(layer);
}
}