diff --git a/docs/intermediate/hero-equipment.md b/docs/intermediate/hero-equipment.md new file mode 100644 index 0000000..f573bd9 --- /dev/null +++ b/docs/intermediate/hero-equipment.md @@ -0,0 +1,64 @@ +# 勇士装备 + +勇士的装备系统分两部分:`state.hero.equip` 管理**装备槽**(哪件装备穿在哪一栏),`state.hero.items.equipment` 是**装备实例仓库**(管理所有已获得的装备实例)。本篇介绍如何用这两组接口。 + +## 装备槽(IHeroEquipment) + +`state.hero.equip` 提供: + +- `slots`:装备槽位数组,每一项是这一栏的名称; +- `setSlots(slots)`:设置装备槽; +- `canEquipTo(uid, slot)`:判断某件装备能否装备到指定槽,返回 `EquipStatus`; +- `equip(uid, slot, autoUnload?)`:把装备穿上; +- `unequip(slot)`:卸下指定槽的装备; +- `equipped(uid)`:查询某装备是否处于装备状态; +- `getEquipped(slot)`:取指定槽的装备 uid; +- `getEquips()`:按槽位顺序取所有已装备实例。 + +`slot` 可以传装备槽索引(数字)或槽位名称(字符串)。`EquipStatus` 有三个取值:`CanEquip`(可以直接装备)、`CannotEquip`(不能装备)、`NeedReplace`(需要替换槽位上的装备)。 + +`equip` 的 `autoUnload` 参数默认为 `true`:当要装备的装备当前穿在别的槽上时,自动把它从原槽卸下。`equip` 与 `unequip` 都会返回被卸下的装备 uid(没有则为 `undefined`)。 + +```ts +const uid = state.hero.items.equipment.add('sword'); + +state.hero.equip.equip(uid, 0); +const off = state.hero.equip.unequip(0); +``` + +## 装备实例仓库(IHeroEquipsStore) + +`state.hero.items.equipment` 提供: + +- `add(item)`:获得一件装备道具、创建实例,返回新实例的 uid; +- `delete(uid)`:移除指定装备实例; +- `get(uid)`:取指定装备实例的状态,与是否装备无关; +- `instancesOf(equip)`:取某件装备的所有实例; +- `instances()`:取当前所有装备实例; +- `count(item)`:取某件装备的实例总数。 + +```ts +const instances = state.hero.items.equipment.instancesOf('sword'); +const total = state.hero.items.equipment.count('sword'); +``` + +## 装备的加成 + +每件装备实例(`IEquipmentState`)对勇士属性提供**数值加成**与**百分比加成**,分别通过 `getValue` / `getPercentage` 读取,`setValue` / `setPercentage` 修改。这两类加成本质上就是[勇士属性](./hero-attribute.md)中的修饰器:装备时把对应的 `ValueModifier` / `PercentageModifier` 挂到勇士属性上,卸下时移除,因此不必手动维护加成数值。 + +```ts +const equipState = state.hero.items.equipment.get(uid); +equipState?.setValue('atk', 12); +const atkBonus = equipState?.getValue('atk') ?? 0; +``` + +## 比较装备 + +`compareEquip(equipA, equipB, slot)` 用于比较两件装备在指定装备槽上的表现,返回「装备 A 时属性 − 装备 B 时属性」的差值。传入 `-1` 表示该侧无装备,可用来比较「某件装备相对空槽」的提升。 + +```ts +const diff = state.hero.equip.compareEquip(uid, -1, 0); +// diff.atk 即装备这件装备相对空槽的攻击提升 +``` + +装备道具本身来自道具定义,见[勇士道具](./hero-items.md);想从 `state` 出发找到这些对象,见[数据端总览](./data-state-overview.md)。 diff --git a/docs/intermediate/hero-location.md b/docs/intermediate/hero-location.md new file mode 100644 index 0000000..07fb84a --- /dev/null +++ b/docs/intermediate/hero-location.md @@ -0,0 +1,41 @@ +# 勇士位置 + +勇士位置(`state.hero.location`)记录当前坐标、朝向与所在楼层。本篇只讲如何**获取**这些信息。 + +## 当前坐标 + +```ts +const x = state.hero.location.x; +const y = state.hero.location.y; +``` + +`x`、`y` 为勇士当前的横、纵坐标。 + +## 当前朝向 + +朝向通过 `getCurrentFaceDirection()` 获取,返回 `FaceDirection`(`Left`、`Up`、`Right`、`Down` 等): + +```ts +const dir = state.hero.location.getCurrentFaceDirection(); +``` + +`state.hero.getLocation()` 会返回一个包含 `x`、`y`、`direction` 的位置对象(`IFacedTileLocator`),适合一次性取走当前坐标与朝向: + +```ts +const loc = state.hero.getLocation(); +// loc.x、loc.y、loc.direction +``` + +## 当前楼层 + +勇士所在的楼层通过 `floorId` 与 `map` 获取: + +- `floorId`:当前楼层 id,`undefined` 表示不处于任何楼层; +- `map`:当前楼层对象(`IGameMap`),`null` 表示不处于任何楼层。 + +```ts +const floorId = state.hero.location.floorId; +const map = state.hero.location.map; +``` + +楼层的结构与激活状态见[地图结构](./map-structure.md);想从 `state` 出发找到勇士与地图对象,见[数据端总览](./data-state-overview.md)。 diff --git a/docs/intermediate/map-structure.md b/docs/intermediate/map-structure.md new file mode 100644 index 0000000..0427162 --- /dev/null +++ b/docs/intermediate/map-structure.md @@ -0,0 +1,52 @@ +# 地图结构 + +地图在数据端分成三层:**楼层集合**(`state.maps`)、**楼层**(`IGameMap`)与**图层**(`IMapLayer`)。本篇说明这三层的关系与常用接口。 + +## 楼层集合(IMapState) + +`state.maps` 管理所有楼层: + +- `maps`:所有楼层 id 的有序数组; +- `getMap(id)`:取指定 id 的楼层,不存在返回 `null`; +- `getActiveMap(id)`:取指定 id 的**已激活**楼层,未激活返回 `null`; +- `isMapActive(id)`:判断指定楼层是否激活; +- `setMapActiveStatus(id, active)`:设置楼层激活状态; +- `iterateAllMaps()`:迭代所有楼层。 + +```ts +const floor = state.maps.getMap('floor-1'); +for (const [id, map] of state.maps.iterateAllMaps()) { + // id 为楼层 id,map 为楼层对象 +} +``` + +## 楼层激活(active) + +每个楼层(`IGameMap`)都有 `active` 表示是否激活。**只有已激活的楼层才会进入存档**——`IMapState` 的存档仅包含已激活楼层。`getActiveMap(id)` 只返回已激活的楼层,迭代可用 `iterateActiveMaps()` / `iterateInactiveMaps()`。 + +```ts +state.maps.setMapActiveStatus('floor-1', true); +const active = state.maps.getActiveMap('floor-1'); +``` + +## 楼层(IGameMap) + +一个楼层对象包含: + +- `floorId`:楼层 id; +- `layerList`:本楼层的所有图层; +- `eventLayer`:本楼层的默认事件层; +- `tileStore`:本楼层共享的图块定义存储; +- `width`、`height`:地图宽高; +- `active`:是否激活。 + +## 图层(IMapLayer) + +`layerList` 中的每个图层(`IMapLayer`)都有: + +- `alias`:图层别名; +- `width`、`height`:图层宽高。 + +**事件层本质就是一个图层**:`eventLayer` 的类型同样是 `IMapLayer`,因此对图层的操作同样适用于事件层。图块的读写见[地图图块](./map-tiles.md)。 + +想从 `state` 出发找到地图对象,见[数据端总览](./data-state-overview.md);勇士当前所在楼层见[勇士位置](./hero-location.md)。