mirror of
https://github.com/motajs/template.git
synced 2026-09-12 17:58:51 +08:00
fix(01-10): restore tile defaults and stable event snapshots
- Rebuild raw tile event baselines on construction, set, load, and conversion. - Preserve coordinate-owned point events through dynamic movement and copy save Maps.
This commit is contained in:
parent
a35e1e116d
commit
bcfa1f9467
@ -42,6 +42,21 @@ export class DynamicTile
|
||||
} else {
|
||||
this.tileRaw = data;
|
||||
}
|
||||
this.restoreDefaultEvents();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据当前图块原始数据恢复默认事件并建立干净基准
|
||||
*/
|
||||
private restoreDefaultEvents(): void {
|
||||
this.tileEvent().clear();
|
||||
const data = this.raw();
|
||||
if (data) {
|
||||
for (const [priority, id] of Object.entries(data.events)) {
|
||||
this.tileEvent().set(Number(priority), id);
|
||||
}
|
||||
}
|
||||
this.tileEvent().markPure();
|
||||
}
|
||||
|
||||
num(): number {
|
||||
@ -61,6 +76,7 @@ export class DynamicTile
|
||||
} else {
|
||||
this.tileRaw = data;
|
||||
}
|
||||
this.restoreDefaultEvents();
|
||||
}
|
||||
|
||||
setPos(x: number, y: number): void {
|
||||
@ -98,26 +114,27 @@ export class DynamicTile
|
||||
}
|
||||
|
||||
saveState(): Readonly<IDynamicBlockSave> {
|
||||
const save: IDynamicBlockSave = {
|
||||
num: this.num()
|
||||
};
|
||||
|
||||
if (this.triggers) {
|
||||
save.triggers = this.triggers;
|
||||
let save: IDynamicBlockSave;
|
||||
if (this.tileEvent().dirty()) {
|
||||
save = {
|
||||
num: this.num(),
|
||||
events: new Map(this.tileEvent().get())
|
||||
};
|
||||
} else {
|
||||
save = {
|
||||
num: this.num()
|
||||
};
|
||||
}
|
||||
|
||||
return save;
|
||||
}
|
||||
|
||||
loadState(save: Readonly<IDynamicBlockSave>): void {
|
||||
if (save.triggers) {
|
||||
if (save.triggers.size === 0) {
|
||||
this.useEmptyTrigger();
|
||||
} else {
|
||||
save.triggers.forEach(v => this.addTrigger(v));
|
||||
this.restoreDefaultEvents();
|
||||
if (save.events) {
|
||||
this.tileEvent().clear();
|
||||
for (const [priority, id] of save.events) {
|
||||
this.tileEvent().set(priority, id);
|
||||
}
|
||||
} else {
|
||||
this.clearTrigger();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -50,6 +50,11 @@ export class MapLayer
|
||||
/** 点事件视图,外层 key = y,内层 key = x */
|
||||
private readonly pointEvents: Map<number, Map<number, ILayerEventView>> =
|
||||
new Map();
|
||||
/** 点事件的原始纯基准,外层 key = y,内层 key = x */
|
||||
private readonly pointEventBaselines: Map<
|
||||
number,
|
||||
Map<number, ReadonlyMap<number, string>>
|
||||
> = new Map();
|
||||
/** 动态图块到其当前坐标的映射 */
|
||||
private readonly posTileMap: Map<IDynamicTile, ITileLocator> = new Map();
|
||||
/** 图层脏标记 */
|
||||
@ -131,14 +136,120 @@ export class MapLayer
|
||||
private syncStaticEvent(tile: IDynamicTile, keepEvent: boolean): void {
|
||||
const staticTile = this.getTile(tile.x, tile.y);
|
||||
if (!staticTile) return;
|
||||
staticTile.tileEvent().clear();
|
||||
staticTile.set(staticTile.num());
|
||||
if (keepEvent) {
|
||||
staticTile.tileEvent().clear();
|
||||
for (const [priority, id] of tile.tileEvent().get()) {
|
||||
staticTile.tileEvent().set(priority, id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录尚未保存过的点事件纯基准
|
||||
* @param x 点事件横坐标
|
||||
* @param y 点事件纵坐标
|
||||
* @param eventView 点事件视图
|
||||
*/
|
||||
private capturePointEventBaseline(
|
||||
x: number,
|
||||
y: number,
|
||||
eventView: ILayerEventView
|
||||
): void {
|
||||
const yMap = this.pointEventBaselines.get(y);
|
||||
if (yMap?.has(x)) return;
|
||||
if (eventView.dirty()) return;
|
||||
const target = yMap ?? new Map<number, ReadonlyMap<number, string>>();
|
||||
target.set(x, new Map(eventView.get()));
|
||||
if (!yMap) this.pointEventBaselines.set(y, target);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将所有已创建的点事件视图恢复到原始纯基准
|
||||
*/
|
||||
private resetPointEvents(): void {
|
||||
for (const [y, xMap] of this.pointEvents) {
|
||||
for (const [x, eventView] of xMap) {
|
||||
this.capturePointEventBaseline(x, y, eventView);
|
||||
}
|
||||
}
|
||||
for (const [y, xMap] of this.pointEvents) {
|
||||
for (const [x, eventView] of xMap) {
|
||||
eventView.clear();
|
||||
const baseline = this.pointEventBaselines.get(y)?.get(x);
|
||||
if (baseline) {
|
||||
for (const [priority, id] of baseline) {
|
||||
eventView.set(priority, id);
|
||||
}
|
||||
}
|
||||
eventView.markPure();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 裁剪超出新图层范围的点事件及其纯基准
|
||||
* @param width 新图层宽度
|
||||
* @param height 新图层高度
|
||||
*/
|
||||
private cropPointEvents(width: number, height: number): void {
|
||||
for (const [y, xMap] of this.pointEvents) {
|
||||
if (y >= height) {
|
||||
this.pointEvents.delete(y);
|
||||
continue;
|
||||
}
|
||||
for (const x of xMap.keys()) {
|
||||
if (x >= width) xMap.delete(x);
|
||||
}
|
||||
if (xMap.size === 0) this.pointEvents.delete(y);
|
||||
}
|
||||
for (const [y, xMap] of this.pointEventBaselines) {
|
||||
if (y >= height) {
|
||||
this.pointEventBaselines.delete(y);
|
||||
continue;
|
||||
}
|
||||
for (const x of xMap.keys()) {
|
||||
if (x >= width) xMap.delete(x);
|
||||
}
|
||||
if (xMap.size === 0) this.pointEventBaselines.delete(y);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 收集需要保存的点事件并复制其内部 Map
|
||||
*/
|
||||
private savePointEvents(): Map<number, ReadonlyMap<number, string>> {
|
||||
const pointEvents = new Map<number, ReadonlyMap<number, string>>();
|
||||
for (const [y, xMap] of this.pointEvents) {
|
||||
for (const [x, eventView] of xMap) {
|
||||
if (!eventView.dirty()) continue;
|
||||
const index = this.map.indexer.locToIndex(x, y);
|
||||
pointEvents.set(index, new Map(eventView.get()));
|
||||
}
|
||||
}
|
||||
return pointEvents;
|
||||
}
|
||||
|
||||
/**
|
||||
* 在图层基准上叠加点事件存档
|
||||
* @param save 点事件存档,可省略
|
||||
*/
|
||||
private loadPointEvents(
|
||||
save?: ReadonlyMap<number, ReadonlyMap<number, string>>
|
||||
): void {
|
||||
this.resetPointEvents();
|
||||
if (!save) return;
|
||||
for (const [index, events] of save) {
|
||||
const { x, y } = this.map.indexer.indexToLocator(index);
|
||||
const eventView = this.event(x, y);
|
||||
if (!eventView) continue;
|
||||
eventView.clear();
|
||||
for (const [priority, id] of events) {
|
||||
eventView.set(priority, id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//#region 静态图层操作
|
||||
|
||||
inMap(x: number, y: number): boolean {
|
||||
@ -321,6 +432,7 @@ export class MapLayer
|
||||
const tile = new DynamicTile(num, x, y, this);
|
||||
const location = this.getLocationData(x, y);
|
||||
if (location) {
|
||||
tile.tileEvent().clear();
|
||||
for (const [priority, id] of location.static.tileEvent().get()) {
|
||||
tile.tileEvent().set(priority, id);
|
||||
}
|
||||
@ -479,6 +591,8 @@ export class MapLayer
|
||||
if (!eventView) {
|
||||
eventView = new LayerEventView();
|
||||
xMap.set(x, eventView);
|
||||
} else {
|
||||
this.capturePointEventBaseline(x, y, eventView);
|
||||
}
|
||||
return eventView;
|
||||
}
|
||||
@ -501,7 +615,13 @@ export class MapLayer
|
||||
}
|
||||
|
||||
dirty(): boolean {
|
||||
return this.layerDirty;
|
||||
if (this.layerDirty) return true;
|
||||
for (const xMap of this.pointEvents.values()) {
|
||||
for (const eventView of xMap.values()) {
|
||||
if (eventView.dirty()) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
markDirty(dirty: boolean): void {
|
||||
@ -535,6 +655,7 @@ export class MapLayer
|
||||
return;
|
||||
}
|
||||
this.layerDirty = true;
|
||||
this.cropPointEvents(width, height);
|
||||
this.mapData.expired = true;
|
||||
const before = this.mapArray;
|
||||
const beforeWidth = this.width;
|
||||
@ -571,6 +692,8 @@ export class MapLayer
|
||||
|
||||
resize2(width: number, height: number): void {
|
||||
this.layerDirty = true;
|
||||
this.pointEvents.clear();
|
||||
this.pointEventBaselines.clear();
|
||||
if (this.width === width && this.height === height) {
|
||||
this.empty = true;
|
||||
this.mapArray.fill(0);
|
||||
@ -655,7 +778,8 @@ export class MapLayer
|
||||
height: this.height,
|
||||
fullMap: new Uint32Array(this.mapArray),
|
||||
staticBlocks: this.saveStatics(),
|
||||
dynamicBlocks: this.saveDynamics()
|
||||
dynamicBlocks: this.saveDynamics(),
|
||||
pointEvents: this.savePointEvents()
|
||||
};
|
||||
}
|
||||
|
||||
@ -671,14 +795,16 @@ export class MapLayer
|
||||
height: this.height,
|
||||
fullMap: new Uint32Array(this.mapArray),
|
||||
staticBlocks,
|
||||
dynamicBlocks
|
||||
dynamicBlocks,
|
||||
pointEvents: this.savePointEvents()
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
width: this.width,
|
||||
height: this.height,
|
||||
staticBlocks,
|
||||
dynamicBlocks
|
||||
dynamicBlocks,
|
||||
pointEvents: this.savePointEvents()
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -696,7 +822,8 @@ export class MapLayer
|
||||
height: this.height,
|
||||
rows: this.diffRows(this.refArray),
|
||||
staticBlocks,
|
||||
dynamicBlocks
|
||||
dynamicBlocks,
|
||||
pointEvents: this.savePointEvents()
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
@ -704,7 +831,8 @@ export class MapLayer
|
||||
height: this.height,
|
||||
fullMap: new Uint32Array(this.mapArray),
|
||||
staticBlocks,
|
||||
dynamicBlocks
|
||||
dynamicBlocks,
|
||||
pointEvents: this.savePointEvents()
|
||||
};
|
||||
}
|
||||
} else {
|
||||
@ -712,7 +840,8 @@ export class MapLayer
|
||||
width: this.width,
|
||||
height: this.height,
|
||||
staticBlocks,
|
||||
dynamicBlocks
|
||||
dynamicBlocks,
|
||||
pointEvents: this.savePointEvents()
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -833,6 +962,7 @@ export class MapLayer
|
||||
} else {
|
||||
this.loadNoCompression(save);
|
||||
}
|
||||
this.loadPointEvents(save.pointEvents);
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
228
packages-user/data-base/src/map/mapLifecycle.test.ts
Normal file
228
packages-user/data-base/src/map/mapLifecycle.test.ts
Normal file
@ -0,0 +1,228 @@
|
||||
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;
|
||||
FaceManager: typeof import('@user/data-common').FaceManager;
|
||||
Dir8FaceHandler: typeof import('@user/data-common').Dir8FaceHandler;
|
||||
SaveCompression: typeof import('@user/data-common').SaveCompression;
|
||||
}
|
||||
|
||||
let modules: TestModules;
|
||||
|
||||
beforeAll(async () => {
|
||||
vi.stubGlobal('main', { replayChecking: true });
|
||||
vi.stubGlobal('location', { origin: 'http://localhost' });
|
||||
const mapModule = await import('./mapState');
|
||||
const commonModule = await import('@user/data-common');
|
||||
modules = {
|
||||
MapState: mapModule.MapState,
|
||||
TileStore: commonModule.TileStore,
|
||||
RoleFaceBinder: commonModule.RoleFaceBinder,
|
||||
FaceManager: commonModule.FaceManager,
|
||||
Dir8FaceHandler: commonModule.Dir8FaceHandler,
|
||||
SaveCompression: commonModule.SaveCompression
|
||||
};
|
||||
});
|
||||
|
||||
function createMapState(
|
||||
pointEvents: Record<number, Record<number, string>> = {}
|
||||
) {
|
||||
const tileStore = new modules.TileStore();
|
||||
tileStore.addTile({
|
||||
num: 1,
|
||||
id: 'base',
|
||||
events: { 10: 'base-event' },
|
||||
type: 0,
|
||||
pass: { onlyEvents: false, outPass: 15, inPass: 15 },
|
||||
eventPass: true
|
||||
});
|
||||
tileStore.addTile({
|
||||
num: 2,
|
||||
id: 'alternate',
|
||||
events: { 20: 'alternate-event' },
|
||||
type: 0,
|
||||
pass: { onlyEvents: false, outPass: 15, inPass: 15 },
|
||||
eventPass: true
|
||||
});
|
||||
const faceManager = new modules.FaceManager();
|
||||
faceManager.register(1, new modules.Dir8FaceHandler());
|
||||
const state = {
|
||||
tileStore,
|
||||
itemStore: {},
|
||||
mapStore: {},
|
||||
eventStore: {},
|
||||
roleFace: new modules.RoleFaceBinder(),
|
||||
faceManager,
|
||||
saveSystem: {}
|
||||
};
|
||||
const mapState = new modules.MapState(tileStore, state);
|
||||
const map = mapState.fromRaw({
|
||||
floorId: 'F1',
|
||||
width: 2,
|
||||
map: { 0: [1, 1, 1, 1] },
|
||||
layerAlias: { 0: 'event' },
|
||||
events: { 0: pointEvents }
|
||||
});
|
||||
return { map: map!, layer: map!.getLayerByAlias('event')! };
|
||||
}
|
||||
|
||||
describe('MapLayer tile defaults snapshots conversion and movement', () => {
|
||||
it('tile defaults snapshots conversion and movement', () => {
|
||||
const { layer } = createMapState();
|
||||
const staticTile = layer.getTile(0, 0)!;
|
||||
expect(staticTile.tileEvent().get()).toEqual(
|
||||
new Map([[10, 'base-event']])
|
||||
);
|
||||
expect(staticTile.tileEvent().dirty()).toBe(false);
|
||||
|
||||
staticTile.set(2);
|
||||
expect(staticTile.tileEvent().get()).toEqual(
|
||||
new Map([[20, 'alternate-event']])
|
||||
);
|
||||
expect(staticTile.tileEvent().dirty()).toBe(false);
|
||||
|
||||
const dynamicTile = layer.createDynamic(1, 1, 0);
|
||||
expect(dynamicTile.tileEvent().get()).toEqual(
|
||||
new Map([[10, 'base-event']])
|
||||
);
|
||||
dynamicTile.set(2);
|
||||
expect(dynamicTile.tileEvent().get()).toEqual(
|
||||
new Map([[20, 'alternate-event']])
|
||||
);
|
||||
expect(dynamicTile.tileEvent().dirty()).toBe(false);
|
||||
|
||||
const cleanSave = dynamicTile.saveState();
|
||||
expect(cleanSave.events).toBeUndefined();
|
||||
dynamicTile.loadState(cleanSave);
|
||||
expect(dynamicTile.tileEvent().get()).toEqual(
|
||||
new Map([[20, 'alternate-event']])
|
||||
);
|
||||
expect(dynamicTile.tileEvent().dirty()).toBe(false);
|
||||
|
||||
dynamicTile.tileEvent().set(30, 'override-event');
|
||||
const overrideSave = dynamicTile.saveState();
|
||||
const savedEvents = new Map(overrideSave.events!);
|
||||
dynamicTile.tileEvent().set(30, 'changed-after-save');
|
||||
expect(overrideSave.events).toEqual(savedEvents);
|
||||
dynamicTile.loadState(overrideSave);
|
||||
expect(dynamicTile.tileEvent().get()).toEqual(
|
||||
new Map([
|
||||
[20, 'alternate-event'],
|
||||
[30, 'override-event']
|
||||
])
|
||||
);
|
||||
expect(dynamicTile.tileEvent().dirty()).toBe(true);
|
||||
|
||||
staticTile.set(1);
|
||||
const discardDynamic = layer.transferToDynamic(0, 0)!;
|
||||
discardDynamic.tileEvent().set(30, 'discarded-event');
|
||||
const restoredStatic = layer.transferToStatic(discardDynamic, false)!;
|
||||
expect(restoredStatic.tileEvent().get()).toEqual(
|
||||
new Map([[10, 'base-event']])
|
||||
);
|
||||
expect(restoredStatic.tileEvent().dirty()).toBe(false);
|
||||
|
||||
const keptDynamic = layer.transferToDynamic(1, 0)!;
|
||||
keptDynamic.tileEvent().set(30, 'kept-event');
|
||||
const keptStatic = layer.transferToStatic(keptDynamic, true)!;
|
||||
expect(keptStatic.tileEvent().get()).toEqual(
|
||||
new Map([
|
||||
[10, 'base-event'],
|
||||
[30, 'kept-event']
|
||||
])
|
||||
);
|
||||
expect(keptStatic.tileEvent().dirty()).toBe(true);
|
||||
|
||||
const point = layer.event(0, 1)!;
|
||||
point.set(5, 'point-event');
|
||||
point.markPure();
|
||||
layer.getPointEvent(0, 1);
|
||||
const moving = layer.transferToDynamic(0, 1)!;
|
||||
moving.setPos(1, 1);
|
||||
expect(layer.getPointEvent(0, 1)).toEqual(
|
||||
new Map([[5, 'point-event']])
|
||||
);
|
||||
expect(layer.getPointEvent(1, 1)).toEqual(new Map());
|
||||
});
|
||||
});
|
||||
|
||||
describe('MapLayer point event lifecycle', () => {
|
||||
it('point event lifecycle', () => {
|
||||
const { layer } = createMapState({ 1: { 5: 'raw-point' } });
|
||||
const point = layer.event(1, 0)!;
|
||||
expect(point.dirty()).toBe(false);
|
||||
|
||||
point.set(7, 'runtime-point');
|
||||
expect(layer.dirty()).toBe(true);
|
||||
point.delete(7);
|
||||
expect(point.dirty()).toBe(false);
|
||||
point.set(5, 'changed-point');
|
||||
expect(point.dirty()).toBe(true);
|
||||
point.set(5, 'raw-point');
|
||||
expect(point.dirty()).toBe(false);
|
||||
point.clear();
|
||||
expect(point.dirty()).toBe(true);
|
||||
point.set(5, 'raw-point');
|
||||
expect(point.dirty()).toBe(false);
|
||||
|
||||
const compressionLevels = [
|
||||
modules.SaveCompression.NoCompression,
|
||||
modules.SaveCompression.LowCompression,
|
||||
modules.SaveCompression.HighCompression
|
||||
];
|
||||
for (const compression of compressionLevels) {
|
||||
point.set(7, 'saved-point');
|
||||
const save = layer.saveState(compression);
|
||||
expect(save.pointEvents?.get(1)).toEqual(
|
||||
new Map([
|
||||
[5, 'raw-point'],
|
||||
[7, 'saved-point']
|
||||
])
|
||||
);
|
||||
point.set(7, 'changed-after-save');
|
||||
layer.loadState(save, compression);
|
||||
expect(point.get()).toEqual(
|
||||
new Map([
|
||||
[5, 'raw-point'],
|
||||
[7, 'saved-point']
|
||||
])
|
||||
);
|
||||
expect(point.dirty()).toBe(true);
|
||||
point.set(8, 'after-load');
|
||||
expect(save.pointEvents?.get(1)).toEqual(
|
||||
new Map([
|
||||
[5, 'raw-point'],
|
||||
[7, 'saved-point']
|
||||
])
|
||||
);
|
||||
point.delete(8);
|
||||
}
|
||||
|
||||
point.set(8, 'runtime-only');
|
||||
layer.loadState(
|
||||
{
|
||||
width: 2,
|
||||
height: 2,
|
||||
fullMap: new Uint32Array([1, 1, 1, 1])
|
||||
},
|
||||
modules.SaveCompression.NoCompression
|
||||
);
|
||||
expect(point.get()).toEqual(new Map([[5, 'raw-point']]));
|
||||
expect(point.dirty()).toBe(false);
|
||||
});
|
||||
|
||||
it('resize preserves in-range point events and resize2 clears them', () => {
|
||||
const { layer } = createMapState({
|
||||
0: { 1: 'top-left' },
|
||||
3: { 1: 'bottom-right' }
|
||||
});
|
||||
layer.resize(1, 1);
|
||||
expect(layer.getPointEvent(0, 0)).toEqual(new Map([[1, 'top-left']]));
|
||||
expect(layer.getPointEvent(1, 1)).toBeNull();
|
||||
|
||||
layer.resize2(1, 1);
|
||||
expect(layer.getPointEvent(0, 0)).toEqual(new Map());
|
||||
});
|
||||
});
|
||||
@ -13,6 +13,21 @@ export class StaticTile
|
||||
{
|
||||
constructor(x: number, y: number, layer: IMapLayer) {
|
||||
super(x, y, layer);
|
||||
this.restoreDefaultEvents();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据当前图块原始数据恢复默认事件并建立干净基准
|
||||
*/
|
||||
private restoreDefaultEvents(): void {
|
||||
this.tileEvent().clear();
|
||||
const data = this.raw();
|
||||
if (data) {
|
||||
for (const [priority, id] of Object.entries(data.events)) {
|
||||
this.tileEvent().set(Number(priority), id);
|
||||
}
|
||||
}
|
||||
this.tileEvent().markPure();
|
||||
}
|
||||
|
||||
num(): number {
|
||||
@ -25,6 +40,7 @@ export class StaticTile
|
||||
|
||||
set(num: number): void {
|
||||
this.layer.setBlock(num, this.locator.x, this.locator.y);
|
||||
this.restoreDefaultEvents();
|
||||
}
|
||||
|
||||
toDynamic(): IDynamicTile {
|
||||
@ -32,28 +48,28 @@ export class StaticTile
|
||||
}
|
||||
|
||||
shouldSave(): boolean {
|
||||
return !!this.triggers;
|
||||
return this.tileEvent().dirty();
|
||||
}
|
||||
|
||||
saveState(): Readonly<IStaticBlockSave> {
|
||||
const save: IStaticBlockSave = {};
|
||||
|
||||
if (this.triggers) {
|
||||
save.triggers = this.triggers;
|
||||
let save: IStaticBlockSave;
|
||||
if (this.tileEvent().dirty()) {
|
||||
save = {
|
||||
events: new Map(this.tileEvent().get())
|
||||
};
|
||||
} else {
|
||||
save = {};
|
||||
}
|
||||
|
||||
return save;
|
||||
}
|
||||
|
||||
loadState(save: Readonly<IStaticBlockSave>): void {
|
||||
if (save.triggers) {
|
||||
if (save.triggers.size === 0) {
|
||||
this.useEmptyTrigger();
|
||||
} else {
|
||||
save.triggers.forEach(v => this.addTrigger(v));
|
||||
this.restoreDefaultEvents();
|
||||
if (save.events) {
|
||||
this.tileEvent().clear();
|
||||
for (const [priority, id] of save.events) {
|
||||
this.tileEvent().set(priority, id);
|
||||
}
|
||||
} else {
|
||||
this.clearTrigger();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user