mirror of
https://github.com/motajs/template.git
synced 2026-10-17 03:10:17 +08:00
fix(07-13): prune deleted views and empty sourceless points
- deleteEnemy removes the deleted view from point.affectedBy and drops its point.damages entry so lazy refreshIndex never revisits a dead view (IN-01) - deleteMapDamage removes the sourcelessDamage IPointInfo once both damages and affectedBy are empty, keeping markDirtyIndex - add IN-01 regressions: dead-view witness (getDamageWithoutCheck not called) and the two arms of the sourceless empty-point cleanup
This commit is contained in:
parent
cff4291512
commit
c1df1e0116
@ -404,6 +404,35 @@ describe('MapDamage sourceless damage', () => {
|
||||
...fixture.damage.getSeparatedDamage({ x: 3, y: 2 })
|
||||
]).toHaveLength(0);
|
||||
});
|
||||
|
||||
// 验证删除无来源伤害的两条臂:删一条保留剩余,删净后返回空且可再次添加(IN-01 空点清理)
|
||||
it('prunes the sourceless point once every damage is deleted', () => {
|
||||
const fixture = createFixture();
|
||||
fixture.damage.useReducer(fixture.reducer);
|
||||
const first = createInfo(5);
|
||||
const second = createInfo(3);
|
||||
fixture.damage.addMapDamage(fixture.locator, first);
|
||||
fixture.damage.addMapDamage(fixture.locator, second);
|
||||
expect(fixture.damage.getReducedDamage(fixture.locator)?.damage).toBe(
|
||||
8
|
||||
);
|
||||
|
||||
fixture.damage.deleteMapDamage(fixture.locator, first);
|
||||
expect(fixture.damage.getReducedDamage(fixture.locator)?.damage).toBe(
|
||||
3
|
||||
);
|
||||
|
||||
fixture.damage.deleteMapDamage(fixture.locator, second);
|
||||
expect(fixture.damage.getReducedDamage(fixture.locator)).toBeNull();
|
||||
expect([
|
||||
...fixture.damage.getSeparatedDamage(fixture.locator)
|
||||
]).toHaveLength(0);
|
||||
|
||||
fixture.damage.addMapDamage(fixture.locator, createInfo(6));
|
||||
expect(fixture.damage.getReducedDamage(fixture.locator)?.damage).toBe(
|
||||
6
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('MapDamage sourced conversion and reduction', () => {
|
||||
@ -545,6 +574,22 @@ describe('MapDamage sourced conversion and reduction', () => {
|
||||
]).toHaveLength(0);
|
||||
});
|
||||
|
||||
// 验证删除怪物后惰性重算不再触达被删视图(IN-01 的删除端剪除)
|
||||
it('does not rebuild damage from a deleted view after pruning', () => {
|
||||
const fixture = createFixture();
|
||||
fixture.damage.useReducer(fixture.reducer);
|
||||
fixture.damage.useConverter(fixture.converter);
|
||||
const spy = vi.spyOn(fixture.damageView, 'getDamageWithoutCheck');
|
||||
|
||||
fixture.damage.deleteEnemy(fixture.view);
|
||||
|
||||
expect(fixture.damage.getReducedDamage(fixture.locator)).toBeNull();
|
||||
expect(spy).not.toHaveBeenCalled();
|
||||
expect([
|
||||
...fixture.damage.getSeparatedDamage(fixture.locator)
|
||||
]).toHaveLength(0);
|
||||
});
|
||||
|
||||
// 验证伤害来源消失后旧坐标不再返回幽灵伤害(CR-02 视图集变空)
|
||||
it('drops ghost damage when the enemy view set becomes empty', () => {
|
||||
const fixture = createFixture();
|
||||
|
||||
@ -116,6 +116,9 @@ export class MapDamage<TEnemy, THero> implements IMapDamage<TEnemy, THero> {
|
||||
const current = this.sourcelessDamage.get(index);
|
||||
if (!current) return;
|
||||
current.damages.delete(info);
|
||||
if (current.damages.size === 0 && current.affectedBy.size === 0) {
|
||||
this.sourcelessDamage.delete(index);
|
||||
}
|
||||
this.markDirtyIndex(index);
|
||||
}
|
||||
|
||||
@ -157,6 +160,10 @@ export class MapDamage<TEnemy, THero> implements IMapDamage<TEnemy, THero> {
|
||||
affecting.damages.forEach((dam, index) => {
|
||||
this.damageStore.delete(dam);
|
||||
collection.add(index);
|
||||
const point = this.sourcedDamage.get(index);
|
||||
if (!point) return;
|
||||
point.affectedBy.delete(viewItem);
|
||||
point.damages.delete(dam);
|
||||
});
|
||||
this.viewStore.delete(viewItem);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user