mirror of
https://github.com/motajs/template.git
synced 2026-11-01 14:14:30 +08:00
docs(10-27): U8 修订(章节锚点 + compareEquip 语义)
- U8-02: equipment-system.md 装备对比改为空槽语义,删除逐键回退表与相对现役装备说法 - U8-01: 5 处跨文档章节引用补标题锚点;指向整篇的链接保持不变 - 10-27-USER-REVIEW.md 记录批次 F 并留高级 I/中级锚点审计待办
This commit is contained in:
1 parent
77f5b3aa19
commit
3d2d375302
5 files changed
+44
-31
No files matched your search
@@ -96,7 +96,7 @@ function loadEnemySave(state: ICoreState, save: Map<string, unknown>): void {
|
||||
}
|
||||
```
|
||||
|
||||
只补 `@system/enemy` 还不够:勇士属性也可能从旧档读入,两个存档键都要按各自的新字段做一次迁移。勇士侧的写法见[新增勇士属性](./adding-hero-attribute.md)的「旧存档迁移」。
|
||||
只补 `@system/enemy` 还不够:勇士属性也可能从旧档读入,两个存档键都要按各自的新字段做一次迁移。勇士侧的写法见[新增勇士属性的「旧存档迁移」](./adding-hero-attribute.md#旧存档迁移)。
|
||||
|
||||
## 读取与修改
|
||||
|
||||
@@ -123,7 +123,7 @@ function setArmor(view: IEnemyView<IEnemyAttr>): void {
|
||||
}
|
||||
```
|
||||
|
||||
直接改原始怪物后必须 `markDirty()`。少了这一步,`getComputedEnemy()` 仍然返回旧结果,伤害也不会变。更完整的刷新时机见[怪物上下文与战斗深入](./enemy-context-and-combat.md)。
|
||||
直接改原始怪物后必须 `markDirty()`。少了这一步,`getComputedEnemy()` 仍然返回旧结果,伤害也不会变。更完整的刷新时机见[怪物上下文与战斗深入的「局部刷新与全量重建」](./enemy-context-and-combat.md#局部刷新与全量重建)。
|
||||
|
||||
## 接入伤害计算
|
||||
|
||||
@@ -338,7 +338,7 @@ export class ArmorFinalEffect implements IEnemyFinalEffect<
|
||||
state.enemyContext.registerFinalEffect(new ArmorFinalEffect());
|
||||
```
|
||||
|
||||
内置的 `MainEnemyFinalEffect`(`src/data/enemy/final.ts`)已经在 `initializeEnemy` 里注册;自写效果是追加执行,不是替换。最终效果与光环、查询的时序关系见[怪物上下文与战斗深入](./enemy-context-and-combat.md)。
|
||||
内置的 `MainEnemyFinalEffect`(`src/data/enemy/final.ts`)已经在 `initializeEnemy` 里注册;自写效果是追加执行,不是替换。最终效果与光环、查询的时序关系见[怪物上下文与战斗深入的「与光环、查询、最终的交互」](./enemy-context-and-combat.md#与光环、查询、最终的交互)。
|
||||
|
||||
## 编辑器与图鉴
|
||||
|
||||
|
||||
@@ -157,28 +157,18 @@ function unequipSlot(state: ICoreState, index: number): number | undefined {
|
||||
|
||||
## 装备对比
|
||||
|
||||
`compareEquip(equipA, equipB, slot)` 返回「装备 A 时属性减装备 B 时属性」的差值。`equipA` 与 `equipB` 传实例 `uid`,传 `-1` 表示该侧没有装备;`slot` 只接受槽位索引。
|
||||
`compareEquip(equipA, equipB, slot)` 把目标槽当作空槽,分别模拟「只穿 A」与「只穿 B」时的最终属性,返回两者之差:A 的最终属性减 B 的最终属性。`equipA` 与 `equipB` 传实例 `uid`,传 `-1` 表示该侧没有装备;`slot` 只接受槽位索引。
|
||||
|
||||
内部会克隆当前属性,先移除该槽现有装备的修饰器,再把 A、B 分别挂到这个克隆上模拟。真实属性不会被修改。返回值的键只包含 A 或 B 涉及的属性。
|
||||
它不考虑目标槽当前穿着什么,也不关心 A、B 是否穿在别的槽上:A、B 只是临时挂到克隆属性上试算,真实属性不会被修改。A 与 B 也可以就是目标槽上的现役装备,结果仍是它们各自与空槽叠加后的差值。
|
||||
|
||||
差值并不总是两份模拟直接相减:某一侧没有提供某个键时,该侧会回退到**当前真实最终属性**(`this.attribute.getFinalAttribute(key)`,仍包含目标槽上的现役装备)。逐键规则如下:
|
||||
|
||||
| A 提供该键 | B 提供该键 | 差值 |
|
||||
| ---------- | ---------- | ---------------------------------- |
|
||||
| 是 | 是 | 「空槽模拟 + A」−「空槽模拟 + B」 |
|
||||
| 是 | 否 | 「空槽模拟 + A」− 当前真实最终属性 |
|
||||
| 否 | 是 | 当前真实最终属性 −「空槽模拟 + B」 |
|
||||
|
||||
表里的「空槽模拟」指克隆属性先移除目标槽现役装备的修饰器,再挂上 A 或 B。目标槽为空时,当前真实最终属性就是空槽基线,三种情况都退化为 A − B。传 `-1` 表示该侧没有装备:目标槽为空时,`compareEquip(a, -1, slot)` 是 A 相对空槽的提升;目标槽已有装备 X 时,它得到的是 A 相对 X 的差值(A − X),**不是**相对空槽。反过来 `compareEquip(-1, b, slot)` 会得到 X − B,符号容易看反,按需要的方向选择参数顺序。
|
||||
|
||||
A 与 B 要么就是目标槽上的现役装备,要么完全不装备。**不要把它们穿在另一个槽上**:那样它们的修饰器会同时留在基线(当前属性)和模拟里,被重复计入。
|
||||
返回值的键只包含 A 或 B 涉及的属性;两者都没涉及的属性不会出现。
|
||||
|
||||
```ts
|
||||
import { IHeroAttr } from '@user/data-common';
|
||||
import { ICoreState } from '@user/data-state';
|
||||
|
||||
/**
|
||||
* 比较两件武器相对当前 0 号槽的表现。
|
||||
* 比较两件武器在 0 号槽的表现(按空槽模拟)。
|
||||
* 正数表示 A 更高,负数表示 B 更高。
|
||||
*/
|
||||
function compareWeapons(state: ICoreState, a: number, b: number): void {
|
||||
@@ -190,7 +180,7 @@ function compareWeapons(state: ICoreState, a: number, b: number): void {
|
||||
}
|
||||
```
|
||||
|
||||
返回值里不会出现 A、B 都没涉及的属性;某一侧缺失的键按上面的回退规则处理。需要「某件装备相对空槽」的差值时,先确保目标槽为空,再传 `-1` 作为另一侧。
|
||||
需要「某件装备相对空槽」的差值时,把另一侧传 `-1` 即可。
|
||||
|
||||
## 排序器
|
||||
|
||||
@@ -353,7 +343,7 @@ function verifyEquipment(state: ICoreState): void {
|
||||
- **不要缩短已使用的 `slots`**:`equips` 以槽位索引为键,缩短数组会留下看不见但仍生效的槽位。先卸下再改。
|
||||
- **读档会重建实例**:`HeroEquipsStore.loadState` 先清空再按存档重建,旧实例对象不再代表当前状态。读档后按 `uid` 重新 `get`,不要长期缓存实例引用。
|
||||
- **`compareEquip` 两侧都为空时**返回 `{}` 并告警(code 195),不会抛错;`slot` 只接受索引。
|
||||
- **`compareEquip` 的基线是当前属性减去目标槽现役装备**:A 或 B 可以就是目标槽上的现役装备,也可以完全未装备;**不要**把它们穿在另一个槽上,否则修饰器会在基线里再算一次。缺失的一侧回退到当前真实最终属性,所以目标槽有装备时,`-1` 得到的是「相对现役装备」而不是「相对空槽」。
|
||||
- **`compareEquip` 按空槽比较**:目标槽当前穿什么不影响结果;某一侧传 `-1` 表示该侧空槽。
|
||||
- **排序器不影响装备槽**:它只决定 `instances()` 与 `instancesOf()` 的展示顺序;`getEquipped` 与 `getEquips` 永远按槽位顺序。
|
||||
- **`getModifiers()` 返回实时迭代器**:不要把它保存到回调之外;需要留存时先转成数组。
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ async function moveTileAndObserveEvents(
|
||||
}
|
||||
```
|
||||
|
||||
`keepEvent` 只决定是否把源静态图块的图块事件复制到动态实例;不论取值如何,源静态图块的图块事件都会被清空。细节见[静态图块与动态图块](./static-vs-dynamic-tiles.md)的「双向转换」。
|
||||
`keepEvent` 只决定是否把源静态图块的图块事件复制到动态实例;不论取值如何,源静态图块的图块事件都会被清空。细节见[静态图块与动态图块的「双向转换」](./static-vs-dynamic-tiles.md#双向转换)。
|
||||
|
||||
## 事件视图接口
|
||||
|
||||
|
||||
@@ -206,7 +206,7 @@ async function verifyTileConversion(
|
||||
- 落点出现同数字的静态图块;
|
||||
- 如果落点已有静态图块,`toStaticIfSafe` 会返回 `null`,落点不会变化,动态图块仍停在落点。想看到完整结果,先把落点清空,或换一个空格测试。
|
||||
|
||||
图块事件在转换中的复制结果由 `keepEvent` 决定,具体验证见[点事件与图块事件](./point-and-tile-events.md)。
|
||||
图块事件在转换中的复制结果由 `keepEvent` 决定,具体验证见[点事件与图块事件的「怎么验证」](./point-and-tile-events.md#怎么验证)。
|
||||
|
||||
## 边界与注意
|
||||
|
||||
|
||||
Reference in new issue
Block a user