mirror of
https://github.com/motajs/template.git
synced 2026-10-20 13:50:18 +08:00
style(10-11): prettier 格式化中级教程文档
This commit is contained in:
parent
beedb185d1
commit
4f4090d5c5
@ -75,15 +75,15 @@ graph TD
|
||||
|
||||
## 流程步骤与对应文档
|
||||
|
||||
| 步骤 | 做什么 | 对应文档 |
|
||||
|------|--------|----------|
|
||||
| 特殊属性 | 定义怪物的机制与参数 | [特殊属性](./enemy-specials.md) |
|
||||
| 光环 | 影响周围怪物的基础属性或特殊属性 | [怪物光环](./enemy-aura.md) |
|
||||
| 查询 | 读取上下文后调整自身 | [怪物查询](./enemy-query.md) |
|
||||
| 最终效果 | 只调整自身基础属性 | [最终属性效果](./enemy-final.md) |
|
||||
| 伤害计算 | 实现 `f(enemy, hero)` | [伤害计算](./enemy-calculator.md) |
|
||||
| 地图伤害 | 勇士移动时按位置结算伤害 | [地图伤害](./enemy-map-damage.md) |
|
||||
| 战前 / 战后脚本 | 拦截战斗、结算奖励 | [战斗脚本](./enemy-combat-script.md) |
|
||||
| 状态钩子 | 处理中毒、衰弱、重生等状态 | [状态钩子](./enemy-status-hooks.md) |
|
||||
| 步骤 | 做什么 | 对应文档 |
|
||||
| --------------- | -------------------------------- | ------------------------------------ |
|
||||
| 特殊属性 | 定义怪物的机制与参数 | [特殊属性](./enemy-specials.md) |
|
||||
| 光环 | 影响周围怪物的基础属性或特殊属性 | [怪物光环](./enemy-aura.md) |
|
||||
| 查询 | 读取上下文后调整自身 | [怪物查询](./enemy-query.md) |
|
||||
| 最终效果 | 只调整自身基础属性 | [最终属性效果](./enemy-final.md) |
|
||||
| 伤害计算 | 实现 `f(enemy, hero)` | [伤害计算](./enemy-calculator.md) |
|
||||
| 地图伤害 | 勇士移动时按位置结算伤害 | [地图伤害](./enemy-map-damage.md) |
|
||||
| 战前 / 战后脚本 | 拦截战斗、结算奖励 | [战斗脚本](./enemy-combat-script.md) |
|
||||
| 状态钩子 | 处理中毒、衰弱、重生等状态 | [状态钩子](./enemy-status-hooks.md) |
|
||||
|
||||
勇士一侧的属性读写见[勇士属性](./hero-attribute.md)。
|
||||
|
||||
@ -6,13 +6,13 @@
|
||||
|
||||
一个插件实现 `IDataPluginDefine` 接口:
|
||||
|
||||
| 成员 | 说明 |
|
||||
| --- | --- |
|
||||
| `id` | 插件标识符,全局唯一 |
|
||||
| `dependencies` | 依赖的其它插件 **id 字符串数组**,不允许循环依赖 |
|
||||
| `awake(state, dependencies)` | 同步初始化 |
|
||||
| `initialize(state, dependencies)` | 异步初始化 |
|
||||
| `afterLoad(state, dependencies)` | 加载完成后初始化 |
|
||||
| 成员 | 说明 |
|
||||
| --------------------------------- | ------------------------------------------------ |
|
||||
| `id` | 插件标识符,全局唯一 |
|
||||
| `dependencies` | 依赖的其它插件 **id 字符串数组**,不允许循环依赖 |
|
||||
| `awake(state, dependencies)` | 同步初始化 |
|
||||
| `initialize(state, dependencies)` | 异步初始化 |
|
||||
| `afterLoad(state, dependencies)` | 加载完成后初始化 |
|
||||
|
||||
三个时机方法都会收到数据端主对象 `state`,你对数据端的操作都从这里展开(`state` 的获取方式与含义见[数据端总览](./data-state-overview.md))。
|
||||
|
||||
|
||||
@ -55,27 +55,27 @@ class MySystem {
|
||||
|
||||
下表把最常用的对象与接口列在一起——只要拿到了 `state`,就能按表中的方式访问它们:
|
||||
|
||||
| 对象 | 获取方式 | 用途 | 分层 |
|
||||
| --- | --- | --- | --- |
|
||||
| `hero` | `state.hero` | 勇士状态(属性、道具、装备、位置) | L1 |
|
||||
| `maps` | `state.maps` | 楼层集合与楼层激活 | L1 |
|
||||
| `flags` | `state.flags` | 全局可存档变量 | L1 |
|
||||
| `enemyManager` | `state.enemyManager` | 怪物创建与查询 | L1 |
|
||||
| `enemyContext` | `state.enemyContext` | 怪物属性构建与光环 | L2 |
|
||||
| `combat` | `state.combat` | 战斗流程 | L2 |
|
||||
| `eventSystem` | `state.eventSystem` | 地图事件执行 | L2 |
|
||||
| `pathfinding` | `state.pathfinding` | 勇士寻路 | L2 |
|
||||
| `tileStore` | `state.tileStore` | 图块定义存储 | L0 |
|
||||
| `itemStore` | `state.itemStore` | 道具定义存储 | L0 |
|
||||
| `mapStore` | `state.mapStore` | 地图定义存储 | L0 |
|
||||
| `eventStore` | `state.eventStore` | 游戏事件存储 | L0 |
|
||||
| `faceManager` | `state.faceManager` | 朝向管理 | L0 |
|
||||
| `roleFace` | `state.roleFace` | 朝向绑定 | L0 |
|
||||
| `replaySystem` | `state.replaySystem` | 录像系统 | L0 |
|
||||
| `loader` | `state.loader` | 数据端加载对象 | L3 |
|
||||
| `loadManager` | `state.loadManager` | 加载管理器 | L3 |
|
||||
| `getDataPlugin(id)` | `state.getDataPlugin('xxx')` | 取得已加装的插件 | L3 |
|
||||
| `emitTip(...)` | `state.emitTip('提示')` | 通知渲染端提示 | L0 |
|
||||
| 对象 | 获取方式 | 用途 | 分层 |
|
||||
| ------------------- | ---------------------------- | ---------------------------------- | ---- |
|
||||
| `hero` | `state.hero` | 勇士状态(属性、道具、装备、位置) | L1 |
|
||||
| `maps` | `state.maps` | 楼层集合与楼层激活 | L1 |
|
||||
| `flags` | `state.flags` | 全局可存档变量 | L1 |
|
||||
| `enemyManager` | `state.enemyManager` | 怪物创建与查询 | L1 |
|
||||
| `enemyContext` | `state.enemyContext` | 怪物属性构建与光环 | L2 |
|
||||
| `combat` | `state.combat` | 战斗流程 | L2 |
|
||||
| `eventSystem` | `state.eventSystem` | 地图事件执行 | L2 |
|
||||
| `pathfinding` | `state.pathfinding` | 勇士寻路 | L2 |
|
||||
| `tileStore` | `state.tileStore` | 图块定义存储 | L0 |
|
||||
| `itemStore` | `state.itemStore` | 道具定义存储 | L0 |
|
||||
| `mapStore` | `state.mapStore` | 地图定义存储 | L0 |
|
||||
| `eventStore` | `state.eventStore` | 游戏事件存储 | L0 |
|
||||
| `faceManager` | `state.faceManager` | 朝向管理 | L0 |
|
||||
| `roleFace` | `state.roleFace` | 朝向绑定 | L0 |
|
||||
| `replaySystem` | `state.replaySystem` | 录像系统 | L0 |
|
||||
| `loader` | `state.loader` | 数据端加载对象 | L3 |
|
||||
| `loadManager` | `state.loadManager` | 加载管理器 | L3 |
|
||||
| `getDataPlugin(id)` | `state.getDataPlugin('xxx')` | 取得已加装的插件 | L3 |
|
||||
| `emitTip(...)` | `state.emitTip('提示')` | 通知渲染端提示 | L0 |
|
||||
|
||||
```ts
|
||||
const plugin = state.getDataPlugin('main');
|
||||
|
||||
@ -22,23 +22,23 @@
|
||||
|
||||
引擎内置了三类光环,分别处理不同的需求:
|
||||
|
||||
| 光环 | code | 视图类 | priority | 行为 |
|
||||
|------|------|--------|----------|------|
|
||||
| 普通光环 | 23 | `CommonAura` | 10 | 按范围给怪物加 `hp` / `atk` / `def` 百分比 |
|
||||
| 支援 | 24 | `GuardAura` | 5 | 把范围内的怪物登记为支援者,战斗时一起结算 |
|
||||
| 特殊光环 | 26 | `SpecialAura` | 20 | 通过 `SpecialAuraModifier` 给目标添加或修改特殊属性 |
|
||||
| 光环 | code | 视图类 | priority | 行为 |
|
||||
| -------- | ---- | ------------- | -------- | --------------------------------------------------- |
|
||||
| 普通光环 | 23 | `CommonAura` | 10 | 按范围给怪物加 `hp` / `atk` / `def` 百分比 |
|
||||
| 支援 | 24 | `GuardAura` | 5 | 把范围内的怪物登记为支援者,战斗时一起结算 |
|
||||
| 特殊光环 | 26 | `SpecialAura` | 20 | 通过 `SpecialAuraModifier` 给目标添加或修改特殊属性 |
|
||||
|
||||
这三类都在 `src/data/enemy/aura.ts` 中实现,并在 `initializeEnemy` 里通过 `ctx.registerAuraConverter(...)` 注册(`initializeEnemy` 是 `src/data/enemy/initialize.ts` 中集中注册内置怪物功能的入口函数;内置的光环转换器与你自己新增的转换器都从这里注册)。
|
||||
|
||||
普通光环(code 23)的参数接口是 `ISpecial23Value`,下文示例里 `setValue({...})` 传入的就是这几个字段:
|
||||
|
||||
| 字段 | 含义 |
|
||||
|------|------|
|
||||
| `range` | 光环范围值;为 0 时作用于同楼层所有怪物 |
|
||||
| `square` | `true` 为矩形范围,`false` 为十字范围(范围大于 1 时按曼哈顿距离计算) |
|
||||
| `hpBuff` | 目标生命值提升百分比 |
|
||||
| `atkBuff` | 目标攻击力提升百分比 |
|
||||
| `defBuff` | 目标防御力提升百分比 |
|
||||
| 字段 | 含义 |
|
||||
| --------- | ---------------------------------------------------------------------- |
|
||||
| `range` | 光环范围值;为 0 时作用于同楼层所有怪物 |
|
||||
| `square` | `true` 为矩形范围,`false` 为十字范围(范围大于 1 时按曼哈顿距离计算) |
|
||||
| `hpBuff` | 目标生命值提升百分比 |
|
||||
| `atkBuff` | 目标攻击力提升百分比 |
|
||||
| `defBuff` | 目标防御力提升百分比 |
|
||||
|
||||
## 运作方式
|
||||
|
||||
@ -120,7 +120,10 @@ import { ISpecial30Value } from './special';
|
||||
const MANHATTAN_RANGE = new ManhattanRange();
|
||||
const RECT_RANGE = new RectRange();
|
||||
|
||||
export class WeakAuraConverter implements IAuraConverter<IEnemyAttr, IHeroAttr> {
|
||||
export class WeakAuraConverter implements IAuraConverter<
|
||||
IEnemyAttr,
|
||||
IHeroAttr
|
||||
> {
|
||||
shouldConvert(special: ISpecial<any>): boolean {
|
||||
return special.code === 30;
|
||||
}
|
||||
@ -251,7 +254,10 @@ export class ChainAuraModifier implements IEnemySpecialModifier<IEnemyAttr> {
|
||||
}
|
||||
}
|
||||
|
||||
export class ChainAuraConverter implements IAuraConverter<IEnemyAttr, IHeroAttr> {
|
||||
export class ChainAuraConverter implements IAuraConverter<
|
||||
IEnemyAttr,
|
||||
IHeroAttr
|
||||
> {
|
||||
shouldConvert(special: ISpecial<any>): boolean {
|
||||
return special.code === 31;
|
||||
}
|
||||
|
||||
@ -78,7 +78,8 @@ export class ArithmeticCalculator implements IDamageCalculator<
|
||||
handler: IReadonlyEnemyHandler<IEnemyAttr, IHeroAttr>
|
||||
): IEnemyDamageInfoBase {
|
||||
const { enemy, hero } = handler;
|
||||
const heroPerDamage = hero.getFinalAttribute('atk') - enemy.getAttribute('def');
|
||||
const heroPerDamage =
|
||||
hero.getFinalAttribute('atk') - enemy.getAttribute('def');
|
||||
if (heroPerDamage <= 0) {
|
||||
return { damage: Infinity, turn: 0 };
|
||||
}
|
||||
|
||||
@ -40,13 +40,13 @@ state.combat.addCombatScript(new MainCombatScript());
|
||||
|
||||
战斗前后能做事的除了脚本,还有钩子。两者的区别主要在「能不能改变战斗的走向」和「多个监听者如何共存」:
|
||||
|
||||
| 需求 | 用脚本 | 用钩子 |
|
||||
|------|--------|--------|
|
||||
| 决定这场战斗是否发生 | 是,`before` 返回 `false` | 否,`onBeforeCombat` 不能阻止战斗 |
|
||||
| 按固定顺序结算奖励或回血 | 是,用 `priority` 排序 | 顺序不由优先级控制 |
|
||||
| 只响应战斗结果做副作用 | 可以,但不是必须 | 是,`onAfterCombat` 更直接 |
|
||||
| 多个互不影响的监听者 | 不适合,同优先级会冲突 | 适合,多个钩子可以并存 |
|
||||
| 需要和内置脚本一样参与战前拦截 | 是 | 否 |
|
||||
| 需求 | 用脚本 | 用钩子 |
|
||||
| ------------------------------ | ------------------------- | --------------------------------- |
|
||||
| 决定这场战斗是否发生 | 是,`before` 返回 `false` | 否,`onBeforeCombat` 不能阻止战斗 |
|
||||
| 按固定顺序结算奖励或回血 | 是,用 `priority` 排序 | 顺序不由优先级控制 |
|
||||
| 只响应战斗结果做副作用 | 可以,但不是必须 | 是,`onAfterCombat` 更直接 |
|
||||
| 多个互不影响的监听者 | 不适合,同优先级会冲突 | 适合,多个钩子可以并存 |
|
||||
| 需要和内置脚本一样参与战前拦截 | 是 | 否 |
|
||||
|
||||
简单记:**要拦截或按顺序结算,用脚本;只想在战斗前后做附加动作,用钩子。**
|
||||
|
||||
|
||||
@ -26,11 +26,11 @@ state.enemyContext.registerFinalEffect(effect);
|
||||
|
||||
光环、查询、最终效果都在构建计算后怪物时执行,但读取与影响的范围不同。把三者放在一起看,分工就清楚了:
|
||||
|
||||
| 效果 | 读取其他怪物/上下文 | 影响其他怪物 | 典型用途 |
|
||||
|------|---------------------|--------------|----------|
|
||||
| 光环 | 否(只按范围命中) | 是 | 给周围怪物加属性或特殊属性 |
|
||||
| 查询 | 是 | 否(只改自身) | 抱团、同化、号角 |
|
||||
| 最终 | 否 | 否 | 坚固、模仿、仿攻 |
|
||||
| 效果 | 读取其他怪物/上下文 | 影响其他怪物 | 典型用途 |
|
||||
| ---- | ------------------- | -------------- | -------------------------- |
|
||||
| 光环 | 否(只按范围命中) | 是 | 给周围怪物加属性或特殊属性 |
|
||||
| 查询 | 是 | 否(只改自身) | 抱团、同化、号角 |
|
||||
| 最终 | 否 | 否 | 坚固、模仿、仿攻 |
|
||||
|
||||
最终效果可以读取勇士属性(模仿与仿攻都需要),但不会扫描周围怪物,也不会改变其他怪物。
|
||||
|
||||
|
||||
@ -34,13 +34,13 @@ mapDamage?.useConverter(new MainMapDamageConverter());
|
||||
|
||||
`MapDamageType` 定义了 `Unknown`、`Zone`、`Layer`、`Repulse`、`Between` 五种类型。内置视图与转换器在 `src/data/enemy/mapDamage.ts`:
|
||||
|
||||
| 类型 | 视图类 | 内置特殊属性 code | 说明 |
|
||||
|------|--------|-------------------|------|
|
||||
| 领域 | `ZoneDamageView` | 13(`ISpecial13Value`) | 范围内自动减血 |
|
||||
| 夹击 | `BetweenDamageView` | 14 | 两只怪物夹住勇士时扣半血 |
|
||||
| 阻击 | `RepulseDamageView` | 16 | 经过时怪物后退并造成伤害 |
|
||||
| 激光 | `LaserDamageView` | 22 | 同行或同列时造成伤害 |
|
||||
| 捕捉 | `AmbushDamageView` | 25 | 触发强制战斗,本身不造成伤害 |
|
||||
| 类型 | 视图类 | 内置特殊属性 code | 说明 |
|
||||
| ---- | ------------------- | ----------------------- | ---------------------------- |
|
||||
| 领域 | `ZoneDamageView` | 13(`ISpecial13Value`) | 范围内自动减血 |
|
||||
| 夹击 | `BetweenDamageView` | 14 | 两只怪物夹住勇士时扣半血 |
|
||||
| 阻击 | `RepulseDamageView` | 16 | 经过时怪物后退并造成伤害 |
|
||||
| 激光 | `LaserDamageView` | 22 | 同行或同列时造成伤害 |
|
||||
| 捕捉 | `AmbushDamageView` | 25 | 触发强制战斗,本身不造成伤害 |
|
||||
|
||||
表中的 code 就是 `src/data/enemy/special.ts` 里同名内置属性注册的编号,转换器读取的也是同一组编号。要启用某类地图伤害,给怪物挂上对应的内置特殊属性即可,不需要再换算编号或修改转换器。
|
||||
|
||||
@ -71,7 +71,8 @@ map.set(
|
||||
{ damage: 50 },
|
||||
{
|
||||
name: '遮挡激光',
|
||||
desc: special => `同行或同列时造成${special.value.damage}点伤害,被地形遮挡则无效。`,
|
||||
desc: special =>
|
||||
`同行或同列时造成${special.value.damage}点伤害,被地形遮挡则无效。`,
|
||||
color: '#D0A0DD'
|
||||
}
|
||||
)
|
||||
@ -182,7 +183,9 @@ export class BlockedLaserConverter implements IMapDamageConverter<
|
||||
const special = handler.enemy.getSpecial<ISpecial43Value>(43);
|
||||
if (!special) return [];
|
||||
const face = handler.state.faceManager.get(FaceGroup.Dir4)!;
|
||||
return [new BlockedLaserDamageView(context, handler.locator, special, face)];
|
||||
return [
|
||||
new BlockedLaserDamageView(context, handler.locator, special, face)
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -121,14 +121,18 @@ const effect: IEnemySpecialQueryEffect<IEnemyAttr, IHeroAttr> = {
|
||||
add(handler) {
|
||||
const result: ISpecial<any>[] = [];
|
||||
const others = [...ctx.iterateEnemy()]
|
||||
.filter(([, view]) => view.getComputedEnemy() !== handler.enemy)
|
||||
.filter(
|
||||
([, view]) => view.getComputedEnemy() !== handler.enemy
|
||||
)
|
||||
.sort(
|
||||
([a], [b]) =>
|
||||
ctx.indexer.index(a.x, a.y) -
|
||||
ctx.indexer.index(b.x, b.y)
|
||||
);
|
||||
for (const [, view] of others) {
|
||||
for (const special of view.getComputedEnemy().iterateSpecials()) {
|
||||
for (const special of view
|
||||
.getComputedEnemy()
|
||||
.iterateSpecials()) {
|
||||
if (special.code === 41) continue;
|
||||
if (handler.enemy.hasSpecial(special.code)) continue;
|
||||
result.push(special.clone());
|
||||
|
||||
@ -12,35 +12,35 @@
|
||||
|
||||
下表是 `src/data/enemy/special.ts` 里 `map.set(code, ...)` 当前注册的全部内置属性,code 与名称一一对应。判断「某个数字代表哪种机制」时以本表为准:
|
||||
|
||||
| code | 名称 | 参数 |
|
||||
|------|------|------|
|
||||
| 0 | 空 | 无 |
|
||||
| 1 | 先攻 | 无 |
|
||||
| 2 | 魔攻 | 无 |
|
||||
| 3 | 坚固 | 无 |
|
||||
| 4 | n连击 | 每回合攻击次数 |
|
||||
| 5 | 破甲 | 附加伤害百分比 |
|
||||
| 6 | 反击 | 附加伤害百分比 |
|
||||
| 7 | 净化 | 附加伤害倍数 |
|
||||
| 8 | 模仿 | 无 |
|
||||
| 9 | 吸血 | `ISpecial9Value`(比例与是否加到自身) |
|
||||
| 10 | 中毒 | 每步损失生命值 |
|
||||
| 11 | 衰弱 | 攻防下降比例 |
|
||||
| 12 | 诅咒 | 无 |
|
||||
| 13 | 领域 | `ISpecial13Value` |
|
||||
| 14 | 夹击 | 无 |
|
||||
| 15 | 仇恨 | 无 |
|
||||
| 16 | 阻击 | 伤害值 |
|
||||
| 17 | 自爆 | 无 |
|
||||
| 18 | 无敌 | 无 |
|
||||
| 19 | 退化 | `ISpecial19Value`(攻防下降值) |
|
||||
| 20 | 固伤 | 固定伤害值 |
|
||||
| 21 | 重生 | 无 |
|
||||
| 22 | 激光 | 伤害值 |
|
||||
| 23 | 光环 | `ISpecial23Value` |
|
||||
| 24 | 支援 | 无 |
|
||||
| 25 | 捕捉 | 无 |
|
||||
| 26 | 特殊光环 | `ISpecial26Value` |
|
||||
| code | 名称 | 参数 |
|
||||
| ---- | -------- | -------------------------------------- |
|
||||
| 0 | 空 | 无 |
|
||||
| 1 | 先攻 | 无 |
|
||||
| 2 | 魔攻 | 无 |
|
||||
| 3 | 坚固 | 无 |
|
||||
| 4 | n连击 | 每回合攻击次数 |
|
||||
| 5 | 破甲 | 附加伤害百分比 |
|
||||
| 6 | 反击 | 附加伤害百分比 |
|
||||
| 7 | 净化 | 附加伤害倍数 |
|
||||
| 8 | 模仿 | 无 |
|
||||
| 9 | 吸血 | `ISpecial9Value`(比例与是否加到自身) |
|
||||
| 10 | 中毒 | 每步损失生命值 |
|
||||
| 11 | 衰弱 | 攻防下降比例 |
|
||||
| 12 | 诅咒 | 无 |
|
||||
| 13 | 领域 | `ISpecial13Value` |
|
||||
| 14 | 夹击 | 无 |
|
||||
| 15 | 仇恨 | 无 |
|
||||
| 16 | 阻击 | 伤害值 |
|
||||
| 17 | 自爆 | 无 |
|
||||
| 18 | 无敌 | 无 |
|
||||
| 19 | 退化 | `ISpecial19Value`(攻防下降值) |
|
||||
| 20 | 固伤 | 固定伤害值 |
|
||||
| 21 | 重生 | 无 |
|
||||
| 22 | 激光 | 伤害值 |
|
||||
| 23 | 光环 | `ISpecial23Value` |
|
||||
| 24 | 支援 | 无 |
|
||||
| 25 | 捕捉 | 无 |
|
||||
| 26 | 特殊光环 | `ISpecial26Value` |
|
||||
|
||||
地图伤害使用的也是上表的编号:转换器读取领域 13、夹击 14、阻击 16、激光 22、捕捉 25,挂上对应的内置属性就会生效(详见[地图伤害](./enemy-map-damage.md))。
|
||||
|
||||
@ -154,16 +154,16 @@ map.set(
|
||||
|
||||
注册只是让引擎认识这条属性,真正让它生效的代码在别处。`special.ts` 顶部的注释给出了内置属性的实现分工。新增属性时按这张表找落点:
|
||||
|
||||
| 属性类型 | 实现位置 | 说明 |
|
||||
|----------|----------|------|
|
||||
| 调参类(先攻、魔攻、连击、破甲、反击、净化、固伤、仇恨、自爆等) | `src/data/enemy/calculator.ts` 的 `MainDamageCalculator.calculate` | 只改变伤害公式的结果 |
|
||||
| 坚固、模仿 | `src/data/enemy/final.ts` 的 `MainEnemyFinalEffect.apply` | 只修改怪物自身基础属性 |
|
||||
| 领域、夹击、阻击、激光、捕捉 | `src/data/enemy/mapDamage.ts` | 伤害视图 + 转换器 |
|
||||
| 光环、支援、特殊光环 | `src/data/enemy/aura.ts` | 光环视图 + 转换器 |
|
||||
| 中毒的每步效果 | `src/data/enemy/hook.ts` 的 `EnemyMoveHooks.handlePoison` | 移动钩子 |
|
||||
| 中毒的瞬移效果 | `src/data/enemy/hook.ts` 的 `EnemyPathfindingHooks.handlePoison` | 寻路钩子 |
|
||||
| 衰弱 | `src/data/enemy/hook.ts` 的 `EnemyCombatHooks.onAfterCombat` | 战后钩子 + 修饰器 |
|
||||
| 重生 | `src/data/enemy/hook.ts` 的 `EnemyCombatHooks.onAfterCombat` 与 `EnemyChangeFloorHooks.onSetFloor` | 两个钩子协同 |
|
||||
| 属性类型 | 实现位置 | 说明 |
|
||||
| ---------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | ---------------------- |
|
||||
| 调参类(先攻、魔攻、连击、破甲、反击、净化、固伤、仇恨、自爆等) | `src/data/enemy/calculator.ts` 的 `MainDamageCalculator.calculate` | 只改变伤害公式的结果 |
|
||||
| 坚固、模仿 | `src/data/enemy/final.ts` 的 `MainEnemyFinalEffect.apply` | 只修改怪物自身基础属性 |
|
||||
| 领域、夹击、阻击、激光、捕捉 | `src/data/enemy/mapDamage.ts` | 伤害视图 + 转换器 |
|
||||
| 光环、支援、特殊光环 | `src/data/enemy/aura.ts` | 光环视图 + 转换器 |
|
||||
| 中毒的每步效果 | `src/data/enemy/hook.ts` 的 `EnemyMoveHooks.handlePoison` | 移动钩子 |
|
||||
| 中毒的瞬移效果 | `src/data/enemy/hook.ts` 的 `EnemyPathfindingHooks.handlePoison` | 寻路钩子 |
|
||||
| 衰弱 | `src/data/enemy/hook.ts` 的 `EnemyCombatHooks.onAfterCombat` | 战后钩子 + 修饰器 |
|
||||
| 重生 | `src/data/enemy/hook.ts` 的 `EnemyCombatHooks.onAfterCombat` 与 `EnemyChangeFloorHooks.onSetFloor` | 两个钩子协同 |
|
||||
|
||||
具体实现方式分别见[怪物光环](./enemy-aura.md)、[伤害计算](./enemy-calculator.md)、[地图伤害](./enemy-map-damage.md)与[状态钩子](./enemy-status-hooks.md)。
|
||||
|
||||
|
||||
@ -15,11 +15,11 @@
|
||||
|
||||
## 三类内置状态
|
||||
|
||||
| 状态 | 使用的钩子 | 实现位置 | 行为 |
|
||||
|------|------------|----------|------|
|
||||
| 中毒 | `onStepEnd` + `onAfterTeleportTo` | `EnemyMoveHooks` / `EnemyPathfindingHooks` | 读取 `poison` flag,按移动扣血;瞬移时按路径长度处理 |
|
||||
| 衰弱 | `onAfterCombat` + 修饰器 | `EnemyCombatHooks` | 战后取最高虚弱值,用 `PercentageModifier` 降低攻防 |
|
||||
| 重生 | `onAfterCombat` + `onSetFloor` | `EnemyCombatHooks` / `EnemyChangeFloorHooks` | 战后记录 `rebirth` flag;切层时把记录的事件块放回 |
|
||||
| 状态 | 使用的钩子 | 实现位置 | 行为 |
|
||||
| ---- | --------------------------------- | -------------------------------------------- | ---------------------------------------------------- |
|
||||
| 中毒 | `onStepEnd` + `onAfterTeleportTo` | `EnemyMoveHooks` / `EnemyPathfindingHooks` | 读取 `poison` flag,按移动扣血;瞬移时按路径长度处理 |
|
||||
| 衰弱 | `onAfterCombat` + 修饰器 | `EnemyCombatHooks` | 战后取最高虚弱值,用 `PercentageModifier` 降低攻防 |
|
||||
| 重生 | `onAfterCombat` + `onSetFloor` | `EnemyCombatHooks` / `EnemyChangeFloorHooks` | 战后记录 `rebirth` flag;切层时把记录的事件块放回 |
|
||||
|
||||
补充说明:
|
||||
|
||||
|
||||
@ -25,18 +25,18 @@ interface BuiltInFunction<P, E> {
|
||||
|
||||
`func` 的第二个参数是事件环境 `IBlockEventEnv`,里面放的是「这次事件在什么情况下被触发」。常用的字段:
|
||||
|
||||
| 字段 | 说明 |
|
||||
| --- | --- |
|
||||
| `state` | 数据端主对象,一切接口的入口 |
|
||||
| `type` | 事件类型(普通事件 / 点事件 / 图块事件) |
|
||||
| `trigger` | 本次事件的触发器类型 |
|
||||
| `heroLocator` | 触发事件时勇士的位置 |
|
||||
| `heroFloor` | 触发事件时勇士所在楼层 |
|
||||
| `triggerLocator` | 触发者的位置,可能不存在 |
|
||||
| `tile` | 触发事件的图块,可能不存在 |
|
||||
| `layer` | 触发事件的图层,可能不存在 |
|
||||
| `map` | 触发事件的地图,可能不存在 |
|
||||
| `system` | 事件系统对象 |
|
||||
| 字段 | 说明 |
|
||||
| ---------------- | ---------------------------------------- |
|
||||
| `state` | 数据端主对象,一切接口的入口 |
|
||||
| `type` | 事件类型(普通事件 / 点事件 / 图块事件) |
|
||||
| `trigger` | 本次事件的触发器类型 |
|
||||
| `heroLocator` | 触发事件时勇士的位置 |
|
||||
| `heroFloor` | 触发事件时勇士所在楼层 |
|
||||
| `triggerLocator` | 触发者的位置,可能不存在 |
|
||||
| `tile` | 触发事件的图块,可能不存在 |
|
||||
| `layer` | 触发事件的图层,可能不存在 |
|
||||
| `map` | 触发事件的地图,可能不存在 |
|
||||
| `system` | 事件系统对象 |
|
||||
|
||||
其余字段见 API 参考。多数情况下你只需要 `state`:通过它能访问勇士、地图、Flag 等(见[数据端总览](./data-state-overview.md))。
|
||||
|
||||
|
||||
@ -10,17 +10,17 @@ Flag 中的每一项是一个**字段**(`IFlagCommonField`),字段名与
|
||||
|
||||
`IFlagSystem` 提供如下接口:
|
||||
|
||||
| 接口 | 说明 |
|
||||
| --- | --- |
|
||||
| `occupied(field)` | 判断字段是否被占用 |
|
||||
| `setField(field, value)` | 以指定值插入字段,返回字段对象 |
|
||||
| `getField(field)` | 取字段对象,不存在返回 `null` |
|
||||
| `getOrInsert(field, defaultValue)` | 取字段,不存在则以默认值创建 |
|
||||
| `getOrInsertComputed(field, defaultValue)` | 同上,但默认值由函数惰性计算 |
|
||||
| `deleteField(field)` | 删除字段 |
|
||||
| `setFieldValue(field, value)` | 设置字段的值 |
|
||||
| `addFieldValue(field, value)` | 对数字字段增减 |
|
||||
| `getFieldValue(field)` | 取字段的值,不存在返回 `undefined` |
|
||||
| 接口 | 说明 |
|
||||
| -------------------------------------------- | -------------------------------------- |
|
||||
| `occupied(field)` | 判断字段是否被占用 |
|
||||
| `setField(field, value)` | 以指定值插入字段,返回字段对象 |
|
||||
| `getField(field)` | 取字段对象,不存在返回 `null` |
|
||||
| `getOrInsert(field, defaultValue)` | 取字段,不存在则以默认值创建 |
|
||||
| `getOrInsertComputed(field, defaultValue)` | 同上,但默认值由函数惰性计算 |
|
||||
| `deleteField(field)` | 删除字段 |
|
||||
| `setFieldValue(field, value)` | 设置字段的值 |
|
||||
| `addFieldValue(field, value)` | 对数字字段增减 |
|
||||
| `getFieldValue(field)` | 取字段的值,不存在返回 `undefined` |
|
||||
| `getFieldValueDefaults(field, defaultValue)` | 取字段的值,不存在则以默认值创建并返回 |
|
||||
|
||||
`getOrInsertComputed` 只在字段确实不存在时才执行默认值函数,适合默认值计算量较大的场景。`getFieldValue` 没有默认值,需要默认值时用 `getFieldValueDefaults`。
|
||||
|
||||
@ -6,12 +6,12 @@
|
||||
|
||||
一件道具被捡起或使用时会发生什么,取决于它属于哪一类。类别由 `ItemCategory` 定义:
|
||||
|
||||
| 类别 | 含义 | 典型行为 |
|
||||
| --- | --- | --- |
|
||||
| `Constant` | 永久道具 | 使用后不消耗,可以反复使用 |
|
||||
| `Consumable` | 一次性道具 | 使用后消耗一个,用完即消失 |
|
||||
| `Pick` | 即捡即用道具 | 拾取时立刻生效,不进入背包 |
|
||||
| `Equipment` | 装备类道具 | 走装备系统,见[勇士装备](./hero-equipment.md) |
|
||||
| 类别 | 含义 | 典型行为 |
|
||||
| ------------ | ------------ | --------------------------------------------- |
|
||||
| `Constant` | 永久道具 | 使用后不消耗,可以反复使用 |
|
||||
| `Consumable` | 一次性道具 | 使用后消耗一个,用完即消失 |
|
||||
| `Pick` | 即捡即用道具 | 拾取时立刻生效,不进入背包 |
|
||||
| `Equipment` | 装备类道具 | 走装备系统,见[勇士装备](./hero-equipment.md) |
|
||||
|
||||
`Unknown` 表示尚未归类。理解了这四类的差别,就能预判一件道具「什么时候、发生什么」:`Pick` 道具不会进入背包——`addItem` 到 `Pick` 道具时会直接触发它的效果。
|
||||
|
||||
|
||||
@ -20,43 +20,43 @@ const hook = {
|
||||
|
||||
「钩子族」是同一类钩子方法的集合(一个 `interface`)。常用的几族如下,方法名以源码为准:
|
||||
|
||||
| 钩子族 | 所属主对象 | 主要方法 |
|
||||
| --- | --- | --- |
|
||||
| `IDataCommonHooks` | 数据端公共对象 | `onTip` |
|
||||
| `IHeroAttributeHooks` | 勇士属性 | `onUpdateAttribute` |
|
||||
| `IHeroLocationHooks` | 勇士位置 | `onSetPos`、`onSetFloor` |
|
||||
| `IHeroStateHooks` | 勇士状态 | `onBeforeChangeFloor`、`onAfterChangeFloor` |
|
||||
| `IEquipmentStateHooks` | 装备 | `onChangeModifier` |
|
||||
| `IHeroFollowersControllerHooks` | 勇士跟随者 | `onAddFollower`、`onRemoveFollower`、`onGatherFollowers` |
|
||||
| `IObjectMoverHooks` | 移动器 | `onMoveStart`、`onMoveEnd`、`onStepStart`、`onStepEnd`、`onSetPos`、`onSetFaceDir`、`onSetMoveDir` |
|
||||
| `ICombatFlowHooks` | 战斗流程 | `onBeforeCombat`、`onAfterCombat` |
|
||||
| `IGameEventExecutorHooks` | 事件执行器 | `onBeforeExecuteEvent`、`onAfterExecuteEvent` |
|
||||
| `IPathfindingSystemHooks` | 寻路系统 | `onBeforeTeleportTo`、`onAfterTeleportTo` |
|
||||
| `IMapLayerHooks` | 地图图层 | `onResize`、`onUpdateArea`、`onUpdateBlock`、`onOpenDoor`、`onCloseDoor`、`onCreateDynamic`、`onDeleteDynamic`、`onUpdateDynamicPosition` |
|
||||
| `IGameMapHooks` | 地图 | `onChangeBackground`、`onUpdateLayer`、`onResizeLayer` |
|
||||
| `IReplaySystemHooks` | 录像系统 | `onCreateSandbox`、`onRecordCommand` |
|
||||
| `IReplaySandboxHooks` | 录像沙盒 | `onStep`、`onSpeedSet`、`onStartReplay`、`onStopReplay`、`onPauseReplay`、`onResumeReplay` |
|
||||
| 钩子族 | 所属主对象 | 主要方法 |
|
||||
| ------------------------------- | -------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `IDataCommonHooks` | 数据端公共对象 | `onTip` |
|
||||
| `IHeroAttributeHooks` | 勇士属性 | `onUpdateAttribute` |
|
||||
| `IHeroLocationHooks` | 勇士位置 | `onSetPos`、`onSetFloor` |
|
||||
| `IHeroStateHooks` | 勇士状态 | `onBeforeChangeFloor`、`onAfterChangeFloor` |
|
||||
| `IEquipmentStateHooks` | 装备 | `onChangeModifier` |
|
||||
| `IHeroFollowersControllerHooks` | 勇士跟随者 | `onAddFollower`、`onRemoveFollower`、`onGatherFollowers` |
|
||||
| `IObjectMoverHooks` | 移动器 | `onMoveStart`、`onMoveEnd`、`onStepStart`、`onStepEnd`、`onSetPos`、`onSetFaceDir`、`onSetMoveDir` |
|
||||
| `ICombatFlowHooks` | 战斗流程 | `onBeforeCombat`、`onAfterCombat` |
|
||||
| `IGameEventExecutorHooks` | 事件执行器 | `onBeforeExecuteEvent`、`onAfterExecuteEvent` |
|
||||
| `IPathfindingSystemHooks` | 寻路系统 | `onBeforeTeleportTo`、`onAfterTeleportTo` |
|
||||
| `IMapLayerHooks` | 地图图层 | `onResize`、`onUpdateArea`、`onUpdateBlock`、`onOpenDoor`、`onCloseDoor`、`onCreateDynamic`、`onDeleteDynamic`、`onUpdateDynamicPosition` |
|
||||
| `IGameMapHooks` | 地图 | `onChangeBackground`、`onUpdateLayer`、`onResizeLayer` |
|
||||
| `IReplaySystemHooks` | 录像系统 | `onCreateSandbox`、`onRecordCommand` |
|
||||
| `IReplaySandboxHooks` | 录像沙盒 | `onStep`、`onSpeedSet`、`onStartReplay`、`onStopReplay`、`onPauseReplay`、`onResumeReplay` |
|
||||
|
||||
## 需求 → 钩子对照表
|
||||
|
||||
真要动手时,多半是先有一个需求、再去找它对应哪个钩子。下表把常见需求和对应的钩子方法列在一起,照着找即可:
|
||||
|
||||
| 需求 | 对应钩子 |
|
||||
| --- | --- |
|
||||
| 勇士属性变化时做点事 | `IHeroAttributeHooks.onUpdateAttribute` |
|
||||
| 勇士被设置坐标或切换楼层 | `IHeroLocationHooks.onSetPos` / `onSetFloor` |
|
||||
| 需求 | 对应钩子 |
|
||||
| ---------------------------- | --------------------------------------------------------------------------- |
|
||||
| 勇士属性变化时做点事 | `IHeroAttributeHooks.onUpdateAttribute` |
|
||||
| 勇士被设置坐标或切换楼层 | `IHeroLocationHooks.onSetPos` / `onSetFloor` |
|
||||
| 勇士移动开始、结束或每走一步 | `IObjectMoverHooks.onMoveStart` / `onMoveEnd` / `onStepStart` / `onStepEnd` |
|
||||
| 切换楼层前后做过渡处理 | `IHeroStateHooks.onBeforeChangeFloor` / `onAfterChangeFloor` |
|
||||
| 战斗前或战斗后介入 | `ICombatFlowHooks.onBeforeCombat` / `onAfterCombat` |
|
||||
| 事件执行前后介入 | `IGameEventExecutorHooks.onBeforeExecuteEvent` / `onAfterExecuteEvent` |
|
||||
| 地图图块被修改、区域被更新 | `IMapLayerHooks.onUpdateBlock` / `onUpdateArea` |
|
||||
| 开门或关门时做点什么 | `IMapLayerHooks.onOpenDoor` / `onCloseDoor` |
|
||||
| 动态图块被创建或删除 | `IMapLayerHooks.onCreateDynamic` / `onDeleteDynamic` |
|
||||
| 装备的修饰器发生变化 | `IEquipmentStateHooks.onChangeModifier` |
|
||||
| 瞬移寻路前后介入 | `IPathfindingSystemHooks.onBeforeTeleportTo` / `onAfterTeleportTo` |
|
||||
| 录像播放到某一步 | `IReplaySandboxHooks.onStep` |
|
||||
| 录像记录新指令 | `IReplaySystemHooks.onRecordCommand` |
|
||||
| 通知渲染端进行一次提示 | `IDataCommonHooks.onTip` |
|
||||
| 切换楼层前后做过渡处理 | `IHeroStateHooks.onBeforeChangeFloor` / `onAfterChangeFloor` |
|
||||
| 战斗前或战斗后介入 | `ICombatFlowHooks.onBeforeCombat` / `onAfterCombat` |
|
||||
| 事件执行前后介入 | `IGameEventExecutorHooks.onBeforeExecuteEvent` / `onAfterExecuteEvent` |
|
||||
| 地图图块被修改、区域被更新 | `IMapLayerHooks.onUpdateBlock` / `onUpdateArea` |
|
||||
| 开门或关门时做点什么 | `IMapLayerHooks.onOpenDoor` / `onCloseDoor` |
|
||||
| 动态图块被创建或删除 | `IMapLayerHooks.onCreateDynamic` / `onDeleteDynamic` |
|
||||
| 装备的修饰器发生变化 | `IEquipmentStateHooks.onChangeModifier` |
|
||||
| 瞬移寻路前后介入 | `IPathfindingSystemHooks.onBeforeTeleportTo` / `onAfterTeleportTo` |
|
||||
| 录像播放到某一步 | `IReplaySandboxHooks.onStep` |
|
||||
| 录像记录新指令 | `IReplaySystemHooks.onRecordCommand` |
|
||||
| 通知渲染端进行一次提示 | `IDataCommonHooks.onTip` |
|
||||
|
||||
注意区分「切换楼层」相关的两族钩子,它们挂在不同的主对象上:`onSetFloor` 属于 `IHeroLocationHooks`,挂在 `state.hero.location` 上;`onBeforeChangeFloor` / `onAfterChangeFloor` 属于 `IHeroStateHooks`,挂在 `state.hero` 上。
|
||||
|
||||
|
||||
@ -63,15 +63,15 @@
|
||||
|
||||
把上面几节收成一张表,动手前对照一下:
|
||||
|
||||
| 路径 | 用途 | 是否通常需要改动 |
|
||||
| --- | --- | --- |
|
||||
| `src/data/` | 数据端逻辑与结果 | 是,本教程重点 |
|
||||
| `src/client/` | 渲染端画面与交互 | 视需求,交互类需求会改 |
|
||||
| `src/content/` | 游戏内容数据 | 是,配置与内容 |
|
||||
| `src/constant.ts` | 底层核心常量 | 否,一般不动 |
|
||||
| `src/data.ts` | 数据端入口 | 否,一般不动 |
|
||||
| `src/bootstrap.ts` | 启动入口 | 否,一般不动 |
|
||||
| `src/package.json` | 入口包依赖声明 | 否,一般不动 |
|
||||
| `src/styles.less` | 全局样式 | 否,一般不动 |
|
||||
| 路径 | 用途 | 是否通常需要改动 |
|
||||
| ------------------ | ---------------- | ---------------------- |
|
||||
| `src/data/` | 数据端逻辑与结果 | 是,本教程重点 |
|
||||
| `src/client/` | 渲染端画面与交互 | 视需求,交互类需求会改 |
|
||||
| `src/content/` | 游戏内容数据 | 是,配置与内容 |
|
||||
| `src/constant.ts` | 底层核心常量 | 否,一般不动 |
|
||||
| `src/data.ts` | 数据端入口 | 否,一般不动 |
|
||||
| `src/bootstrap.ts` | 启动入口 | 否,一般不动 |
|
||||
| `src/package.json` | 入口包依赖声明 | 否,一般不动 |
|
||||
| `src/styles.less` | 全局样式 | 否,一般不动 |
|
||||
|
||||
想先补齐读写这些文件所需的语法与类型知识,见[代码基础](./code-basics.md)。
|
||||
|
||||
Loading…
Reference in New Issue
Block a user