mirror of
https://github.com/motajs/template.git
synced 2026-09-28 06:00:17 +08:00
fix(07-15): restore modifier bookkeeping when cloning an attribute
- clone() now binds each cloned modifier to the clone, records its modifierName, mirrors the source save flag and recomputes the attribute, matching addModifier's bookkeeping - a cloned attribute can enumerate, index and persist its modifiers, and a cloned modifier's setValue notifies the clone - add the bookkeeping and save-ability regression cases
This commit is contained in:
parent
49116c0784
commit
bb1986508a
@ -1,4 +1,4 @@
|
||||
// 测试 HeroAttribute 构件:基础/最终属性、修饰器增删排序、存盘开关、克隆、自身存读档与告警码 108/109
|
||||
// 测试 HeroAttribute 构件:基础/最终属性、修饰器增删排序、存盘开关、克隆、自身存读档与告警码 108/109、克隆体修饰器簿记与存档开关
|
||||
import { afterAll, describe, expect, it, vi } from 'vitest';
|
||||
import { BaseHeroModifier, HeroAttribute } from './attribute';
|
||||
import { logger } from '@motajs/common';
|
||||
@ -315,6 +315,45 @@ describe('HeroAttribute cloning and progress', () => {
|
||||
expect(attribute.getBaseAttribute('hp')).toBe(100);
|
||||
});
|
||||
|
||||
// 验证克隆体的修饰器可通过遍历、索引定位、setValue 通知与存档四种簿记访问
|
||||
it('keeps the modifier bookkeeping of cloned attributes', () => {
|
||||
const attribute = createNumericAttribute();
|
||||
attribute.addModifier('hp', new TestModifier(5));
|
||||
attribute.addModifier('atk', new TestModifier(3, 10));
|
||||
const clone = attribute.clone();
|
||||
const clonedHp = [...clone.getModifiers('hp')][0];
|
||||
|
||||
expect([...clone.iterateModifiers()].map(v => v[0]).sort()).toEqual([
|
||||
'atk',
|
||||
'hp'
|
||||
]);
|
||||
expect(clone.getModifierIndex(clonedHp)).toBe(0);
|
||||
|
||||
clonedHp.setValue(9);
|
||||
expect(clone.getFinalAttribute('hp')).toBe(109);
|
||||
expect(attribute.getFinalAttribute('hp')).toBe(105);
|
||||
|
||||
expect(
|
||||
clone
|
||||
.saveState(SaveCompression.NoCompression)
|
||||
.modifiers.map(v => v.name)
|
||||
.sort()
|
||||
).toEqual(['atk', 'hp']);
|
||||
});
|
||||
|
||||
// 验证克隆修饰器继承源修饰器的存档开关,不存档的修饰器不进入克隆体存档
|
||||
it('keeps the save-ability of cloned modifiers', () => {
|
||||
const attribute = createNumericAttribute();
|
||||
attribute.addModifier('hp', new TestModifier(5), false);
|
||||
const clone = attribute.clone();
|
||||
const clonedHp = [...clone.getModifiers('hp')][0];
|
||||
|
||||
expect(clone.getModifierSaveEnabled(clonedHp)).toBe(false);
|
||||
expect(
|
||||
clone.saveState(SaveCompression.NoCompression).modifiers
|
||||
).toHaveLength(0);
|
||||
});
|
||||
|
||||
// 验证 catchCalculateProgress 输出计算过程且不修改最终属性
|
||||
it('iterates calculation progress without touching the final value', () => {
|
||||
const attribute = createAttribute();
|
||||
|
||||
@ -306,7 +306,15 @@ export class HeroAttribute<THero> implements IHeroAttribute<THero> {
|
||||
}
|
||||
if (!cloneModifier) return cloned;
|
||||
for (const [name, modifiers] of this.modifier) {
|
||||
const arr: IHeroModifier[] = modifiers.map(v => v.clone());
|
||||
const arr: IHeroModifier[] = modifiers.map(v => {
|
||||
const copy = v.clone();
|
||||
copy.bindAttribute(cloned);
|
||||
cloned.modifierName.set(copy, name);
|
||||
if (!this.getModifierSaveEnabled(v)) {
|
||||
cloned.modifierNosave.add(copy);
|
||||
}
|
||||
return copy;
|
||||
});
|
||||
cloned.modifier.set(name, arr);
|
||||
cloned.recalculateAttribute(name);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user