diff --git a/.planning/phases/09-minimum-browser-runnable/09-19-SUMMARY.md b/.planning/phases/09-minimum-browser-runnable/09-19-SUMMARY.md new file mode 100644 index 0000000..c2394ec --- /dev/null +++ b/.planning/phases/09-minimum-browser-runnable/09-19-SUMMARY.md @@ -0,0 +1,265 @@ +--- +phase: 09-minimum-browser-runnable +plan: 19 +subsystem: data-migration +tags: [jsonc, png, zlib, texture-atlas, tile, enemy, item, map, data-migration] + +requires: + - phase: 09-minimum-browser-runnable + provides: "09-17/09-18 产出的只读盘点台账 09-DATA-MIGRATION-AUDIT.md(字段映射候选 + §8.1/§8.2 分区)" +provides: + - "src/content/{tile,enemy,item}.jsonc 真实基础数据(235 / 81 / 62 条)" + - "src/content/maps/{empty,MT0,sample0,sample1,sample2}.jsonc + maps/.list.jsonc" + - "src/content/texture/ 43 张拆分图 + 4 autotile + 1 tileset + .list.jsonc" + - "script/migrateProjectTextures.ts 一次性零依赖 PNG 生成脚本(Node zlib)" + - "09-DATA-MIGRATION-AUDIT.md 的 48px 事实与拆分计数更正(D-84 / D-85)" + - "09-DATA-MIGRATION-UNMAPPED.md(仅 §8.1 无目标字段)" +affects: [09-minimum-browser-runnable] + +actuals: + tokens: 133232 + tasks: 4 + commits: 0 + +tech-stack: + added: [] + patterns: + - "零依赖 Node zlib 手写 PNG 编解码(IHDR/IDAT 解析 + inflate/deflate + 反滤镜 + CRC32)" + - "num 策略 A:按 TileType 分段、段内旧 num 升序、从 1 起连续编号" + - "拆分图列数固定、行数 ≤4 且按每图实际块数裁剪(D-84)" + - "48px 素材按尺寸与帧数分组、不放一块不留白不重采样(D-85)" + +key-files: + created: + - script/migrateProjectTextures.ts + - src/content/maps/empty.jsonc + - src/content/maps/sample0.jsonc + - src/content/maps/sample1.jsonc + - src/content/maps/sample2.jsonc + - src/content/texture/*.png + - .planning/phases/09-minimum-browser-runnable/09-DATA-MIGRATION-UNMAPPED.md + modified: + - .planning/phases/09-minimum-browser-runnable/09-DATA-MIGRATION-AUDIT.md + - src/content/tile.jsonc + - src/content/enemy.jsonc + - src/content/item.jsonc + - src/content/maps/MT0.jsonc + - src/content/maps/.list.jsonc + - src/content/texture/.list.jsonc + +key-decisions: + - "num 策略 A 落地:段序 Terrain(2)/Animate(3)/Item(4)/Enemy(5)/Npc(6)/Autotile(7),段内旧 num 升序,从 1 起连续,0 保留空图块" + - "贴图布局按 D-84:列数固定(单帧 4 / 多帧 = 帧数列),行数 ≤4 按每图实际块数裁剪,末图可为 128×32 / 64×32 / 64×64 / 128×96" + - "48px 素材按 D-85 按尺寸与帧数分组:npc0..6=7(32px 组 4 图 + 48px 组 3 图),SPLIT-COUNT=43" + - "item 旧缺 text 的 13 条(wand/pack/I331..I341)显式写空字符串,不省略" + - "source 精灵行序取自 public/project/icons.js(每类 id→素材索引,计数与 materials PNG 尺寸逐一吻合);texture/.list.jsonc 的 map 按此顺序列出新 num" + - "地图旧二维 map 行主序展平为单张图层(键 0),layerAlias={},events={}" + +patterns-established: + - "一次性迁移脚本用 Node zlib 零依赖手写 PNG decode/encode,不新增依赖" + - "素材索引权威:icons.js 的每类 id→行索引映射源素材 sprite 行" + +requirements-completed: [] + +coverage: + - id: D1 + description: "盘点台账 09-DATA-MIGRATION-AUDIT.md 的 48px 事实与拆分计数更正为自洽(4 帧 / 单元格 32×48 / 行数 8、10;enemy 21 / npc 7 / SPLIT-COUNT 43 / npc0..6)" + verification: + - kind: other + ref: "node gate-task1-ledger.js(LEDGER GATE)" + status: pass + human_judgment: false + - id: D2 + description: "三类实体 jsonc:tile.jsonc 235 / enemy.jsonc 81 / item.jsonc 62,基础字段全量、精确键集、id/num 唯一" + verification: + - kind: other + ref: "node gate-task2-entity.js + gate-task2-prefix.js(ENTITY / PREFIX GATE)" + status: pass + human_judgment: false + - id: D3 + description: "43 张拆分图 + 4 autotile + 1 tileset + texture/.list.jsonc,尺寸按 D-84 逐图推导、npc=7 按 D-85 分组、覆盖全部有贴图图块" + verification: + - kind: other + ref: "node gate-task3-texture.js + gate-task3-copy.js + gate-task3-dep.js(TEXTURE / COPY / DEP GATE)" + status: pass + human_judgment: false + - id: D4 + description: "5 楼层地图 + maps/.list.jsonc + 09-DATA-MIGRATION-UNMAPPED.md(仅 §8.1)" + verification: + - kind: other + ref: "node gate-task4-map.js(MAP GATE)" + status: pass + human_judgment: false + - id: D5 + description: "消费接线(写 store / 写 TextureManager)不在本增量;由用户后续单独提供(D-70 / D-83)" + verification: [] + human_judgment: true + rationale: "消费接线按决策明确不在本计划范围,须由用户后续单独提供,非自动化可判定" + +duration: 18min +completed: 2026-10-14 +status: complete +--- + +# Phase 09 Plan 19: 旧引擎数据基础移植 + 盘点台账事实更正 Summary + +**把 `public/project` 的六类基础数据移植为 `src/content` 的真实 jsonc 数据与 43 张零依赖生成的 PNG 素材(含按尺寸与帧数分组的 npc0..6),并更正盘点台账的 48px 素材事实(4 帧 / 单元格 32×48 / SPLIT-COUNT 43)** + +## Performance + +- **Duration:** 18 min +- **Started:** 2026-10-14T04:45:54Z +- **Completed:** 2026-10-14T05:04:00Z +- **Tasks:** 4 个执行任务(Task 0 为只读汇报关卡,已由用户「可以执行」通过) +- **Files modified:** 见 `key-files`(13 个文本文件 + 48 张 PNG) + +## Accomplishments + +- **Task 1 · 台账事实更正:** 更正 `09-DATA-MIGRATION-AUDIT.md` 的 48px 素材事实——§2.1 `enemy48.png`/`npc48.png` 行为 **4 帧列 / 单元格 32×48 / 行数 8、10**;§2.4 的 D / E 组按**帧数与尺寸**拆为 `enemys`(2f)/`enemy48`(4f)、`npcs`(2f)/`npc48`(4f),含 `enemy = ceil(73/4)+ceil(8/4) = 19+2 = 21`、`npc = ceil(14/4)+ceil(10/4) = 4+3 = 7`;`SPLIT-COUNT` 由 42 → **43**(§2.4 / §9 / §8.3 U-1 三处一致);§2.5 命名扩为 `npc0..6`(7 图);§0.5.2 新增 D-84/D-85 修订口径与文件头「2026-10-13 用户更正」标注;§5.2 / §8.3 U-9/U-17 同步;标注 **D-81 的 npc 计数(`npc0..5`=6 / 42)已被 D-85 取代**(enemy 不受影响仍 `enemy0..20`=21)。**未改**字段分类判定、§8.1/§8.2 分区或条目增删。 +- **Task 2 · 三类实体 jsonc:** 以 `num` 策略 A 建立全局 `id`↔`num` 基准并写 `tile.jsonc`(235)/ `enemy.jsonc`(81)/ `item.jsonc`(62),替换样例。 +- **Task 3 · 素材 + list:** 写一次性零依赖 PNG 脚本 `script/migrateProjectTextures.ts`(Node `zlib`),按 D-72 **与 D-84 / D-85** 生成 **43 张**拆分图(列数固定、行数 ≤4 按需裁剪)+ 逐字节复制 4 autotile + 1 tileset,并写 `texture/.list.jsonc`(D-80 已批准 schema)。 +- **Task 4 · 地图 + 文档:** 写 5 楼层 jsonc + `maps/.list.jsonc`(旧 `num` 重映射为新 `num`)+ `09-DATA-MIGRATION-UNMAPPED.md`(仅 §8.1),并跑最终静态门禁。 + +## 逐类映射口径 + +| 类别 | 范围 | 映射口径 | 产出 | +| --- | --- | --- | --- | +| tile | 235 | `id` / `cls→type`(§1.1)/ `cannotOut`+`cannotIn`→`pass.outPass`+`inPass`(位掩码取反:`方向 = 15 & ~被禁位`,`Up=1/Right=2/Down=4/Left=8`);`events={}`、`eventPass=false`、默认 `pass={onlyEvents:true,outPass:15,inPass:15}` | 235 条,键集恰 6 键 | +| enemy | 81 | `num` = 对应图块新 `num`;`attribute` 取旧 `name/hp/atk/def/money/exp/point`;`special` 由旧数字数组生成 `{数字: null}` | 81 条,键集恰 3 键 | +| item | 62 | `num` = 对应图块新 `num`;`category` 按 §4.1(`tools`/`items`→`Consumable`=2、`equips`→`Equipment`=4、`constants`→`Constant`=1);`name` 直取;`text` 直取(旧缺 13 条写 `""`);`hideInToolbox` 旧值 | 62 条,键集恰 5 键 | +| map | 5 楼层 | `floorId`/`width`;旧二维 `map` 行主序展平为单张图层(键 `0`),数值经「旧 `num`→`id`→新 `num`」重映射(`0` 保持);`layerAlias={}`、`events={}` | 5 条,顶层键集恰 5 键 | +| texture | 43 + 5 | 单帧组 `grid`(4 列、每图 16 格)、多帧组 `rowAnimate`(列=帧数列、每图 ≤4 块);autotile/tileset 逐字节复制 | 43 拆分 + 4 autotile + 1 tileset | + +## `num` 策略 A(D-79)分段取值 + +段序 `Terrain(2) → Animate(3) → Item(4) → Enemy(5) → Npc(6) → Autotile(7)`,段内按旧 `num` 升序、从 `num=1` 起连续分配(`0` 保留空图块): + +| 段 | 条数 | 新 `num` 区间 | 示例 | +| --- | --- | --- | --- | +| Terrain | 35 | 1–35 | `blueShopLeft`=1、`arrowUp`=7、`ground`=17、`sWallTBL`=35 | +| Animate | 29 | 36–64 | `yellowWall`=36 | +| Item | 62 | 65–126 | `yellowKey`=65、`wand`=115 | +| Enemy | 81 | 127–207 | `greenSlime`=127 | +| Npc | 24 | 208–231 | `man`=208 | +| Autotile | 4 | 232–235 | `autotile`=232、`autotile1`=233、`autotile2`=234、`autotile3`=235 | + +**五处 `id`↔`num` 全局一致:** `tile.jsonc` 的 `num`、`enemy.jsonc`/`item.jsonc` 的 `num`、`texture/.list.jsonc` 的 `map`/`identifier`、`maps/*.jsonc` 图层数值。 + +## `text` 缺失 13 条的处置 + +旧 `items.js` 中 `wand` / `pack` / `I331`..`I341`(共 **13** 条,均 `cls: items`)无 `text`。本计划对其**显式写入空字符串 `""`**(与 `defaults/item.jsonc` 一致),**不省略**——以保证「恰 5 键」与 `typeof text === 'string'` 成立、数据自洽,而非依赖默认合并兜底。其余 §8.2 待定字段(`itemEffect`/`itemEffectTip`/`useItemEffect`/`useItemEvent`/`canUseItemEffect` 与 `equip` 子字段、`effect`/`equip`)沿用现有样例的**省略策略**(由默认合并兜底),仅在文档记录。 + +## 素材产出(43 张拆分图 + 5 张复制,D-72 / D-84 / D-85) + +每张图**列数固定**(单帧 4 列 / 多帧 = 帧数列),**行数 ≤4 且按每图实际块数裁剪**;每张 `width = 列数 × 帧宽`、`height = 行数 × 帧高`(`1 ≤ 行数 ≤ 4`)。 + +| 组 | 图名 | 块/格 | 尺寸 | 帧尺寸 | +| --- | --- | --- | --- | --- | +| A `terrains` 单帧 | `terrains0`/`terrains1`(各 4 行)、`terrains2`(1 行,末图) | 16+16+3 | 128×128 / **128×32** | 32×32 | +| B `animates` 并入 `terrains` | `terrainsAnim0..6`(各 4 行)、`terrainsAnim7`(1 行,末图) | 7×4+1 | 128×128 / **128×32** | 32×32(4 帧) | +| C `items` 单帧 | `items0..3`(末图 14 格占满 4 行) | 16+16+16+14 | 均 128×128 | 32×32 | +| D `enemy`(32px 组) | `enemy0..17`(各 4 行)、`enemy18`(1 行,末图) | 18×4+1 | 64×128 / **64×32** | 32×32(2 帧) | +| D `enemy`(48px 组) | `enemy19`/`enemy20`(各 4 行) | 4+4 | 均 **128×192** | **32×48**(4 帧) | +| E `npc`(32px 组,D-85) | `npc0..2`(各 4 行)、`npc3`(2 行,末图) | 3×4+2 | 64×128 / **64×64** | 32×32(2 帧) | +| E `npc`(48px 组,D-85) | `npc4`/`npc5`(各 4 行)、`npc6`(2 行,末图) | 4+4+2 | 128×192 / **128×96** | **32×48**(4 帧) | + +复制(逐字节,不重编码):`autotile.png` / `autotile1.png` / `autotile2.png` / `autotile3.png`(4)+ `magictower.png`(1)。**`animates` 并入 `terrains`、不设独立 `animates` 素材组(D-72③)。** + +## D-84 / D-85 处置与取代说明 + +- **D-84(贴图布局放宽):** 台账 §2 的「严格 4 行(单帧 4×4 / 多帧 帧数列×4 行)」读法**已被 D-84 取代**——列数固定、行数 ≤4 且按每图实际块数裁剪;门禁按**实际行数**断言尺寸,不硬编码 4 行尺寸。 +- **D-85(48px 素材分组 = 原 OI-3 的 A,已裁定):** 不同尺寸 / 帧数的素材**必须用不同图片**——`npc` 按尺寸与帧数分组为 `npc0..6`(**7 图**):32px 组 `npc0..2` 64×128 + `npc3` 64×64、48px 组 `npc4`/`npc5` 128×192 + `npc6` 128×96;**不放一块、不留白、不重采样**。台账 §2.5 的 `npc0..5`=6 计数**已被 D-85 取代**(enemy 不受影响仍 `enemy0..20`=21)。 +- **D-85 字面描述的取代说明:** D-85 的 CONTEXT 文字「64×48」/「3×128×192」由权威口径取代——48px 单元格实为 **32×48**(帧数权威 `FrameNumbers`:`npc48` = 4 帧),且经 D-84 逐图裁剪后 48px 组为 `npc4`/`npc5` 128×192 + `npc6` 128×96(非「3×128×192」)。本计划实现为 32×48 与 `npc6`=128×96,据此保留。 + +## 地图图层键与旧→新重映射口径 + +- `mapState.fromRaw` 显示 `IMapRawData.map` 每个键是**整张展平网格**(`length = width × height`,行主序),故按「旧二维 `map` → 单张展平图层」处理,图层键默认 `0`(OI-4)、`layerAlias = {}`、`events = {}`。 +- 旧 `num` 经「旧 `num` → `id` → 新 `num`」重映射(`0` 保持 `0`);§8.2 的 `events` 与额外图层(U-16b)与 §8.1 楼层字段均**不移植**。 +- 5 楼层:`empty`(13×13, 全 0) / `MT0`(13×13, 全 0) / `sample0`(13×13, 136 非零) / `sample1`(13×13, 98 非零) / `sample2`(26×26, 124 非零);每层数组长度 = `width × height`。 + +## 消费接线(不在本增量) + +沿用 **D-70 / D-83**:**不实现**把配置写入 store、把 list 写入 `TextureManager` 的消费接线;未改 `packages*/`、`src/`(除 `src/content/**`)、`public/project/**`。 + +## 门禁结果(全部实际运行,判定通过) + +| 任务 | 门禁 | 结果 | +| --- | --- | --- | +| Task 0 | `PRESTATE`(预执行状态) | **PASS**(台账就位、unmapped/summary 未存在、参考文件齐、Node zlib 可用);人工关卡由用户「可以执行」通过 | +| Task 1 | `LEDGER GATE` | **PASS**(4 帧 / 单元格 32×48 / 行数 8、10;SPLIT-COUNT 43 三处一致;enemy 21 / npc 7;npc0..6;D-84/D-85 同步) | +| Task 2 | `ENTITY GATE` + `PREFIX GATE` | **PASS**(tile 235 六键 / enemy 81 三键 / item 62 五键、id/num 唯一、type 合法、text 为字符串、头部 `// Type:` 保留) | +| Task 3 | `TEXTURE GATE` + `COPY GATE` + `DEP GATE` | **PASS**(43 拆分图尺寸按 D-84 逐图相符、npc=7、rowAnimate 每帧尺寸与帧数正确、覆盖全部有贴图 num;autotile/tileset 逐字节一致;脚本零依赖、`package.json` 未变) | +| Task 4 | `MAP GATE` + `SCOPE GATE` | **PASS**(5 楼层 5 键、图层长度符合、数值合法;.list 5 id;unmapped 仅 §8.1;无越界改动) | + +**未使用全仓门禁**(无 `pnpm check:type` / `pnpm build`)。 + +## Files Created/Modified + +- `.planning/phases/09-minimum-browser-runnable/09-DATA-MIGRATION-AUDIT.md` — 48px 事实与拆分计数更正(D-84 / D-85),仅此一个既有规划文件被改 +- `src/content/tile.jsonc` — 235 条图块(替换样例) +- `src/content/enemy.jsonc` — 81 条怪物(替换样例) +- `src/content/item.jsonc` — 62 条道具(替换样例) +- `src/content/maps/{empty,sample0,sample1,sample2}.jsonc` — 新增楼层 +- `src/content/maps/MT0.jsonc` / `src/content/maps/.list.jsonc` — 替换(5 楼层) +- `src/content/texture/*.png` — 43 拆分图 + 4 autotile + 1 tileset(新增) +- `src/content/texture/.list.jsonc` — D-80 已批准 schema(48 条目) +- `script/migrateProjectTextures.ts` — 一次性零依赖 PNG 生成脚本(小驼峰) +- `.planning/phases/09-minimum-browser-runnable/09-DATA-MIGRATION-UNMAPPED.md` — 仅 §8.1 无目标字段 + +## Task Commits + +**本计划未创建任何提交**——按用户明确指令「不要运行 `git add` / `git commit`,把全部产出留在工作树,我会统一提交」。所有产出(含新文件与替换文件)均处于未暂存 / 未跟踪状态。用户并发改动 `AGENTS.md` / `09-CONTEXT.md` 未被触碰、未纳入。 + +## Decisions Made + +- **`num` 策略 A 落地口径**(D-79):段序 Terrain→Animate→Item→Enemy→Npc→Autotile,段内旧 `num` 升序,从 1 起连续。 +- **素材精灵行序来源:** 采用 `public/project/icons.js` 的「每类 `id`→素材行索引」映射确定源 sprite 行(各类计数与 `materials/*.png` 尺寸逐一吻合:terrains 35 / animates 29 / items 62 / enemys 73 / enemy48 8 / npcs 14 / npc48 10),据此生成拆分图并写 `texture/.list.jsonc` 的 `map`(依源行序列出新 `num`)。 +- **`grid` / `rowAnimate` 条目 `width`/`height` = 每帧尺寸**:48px 条目 = 32/48(4 帧),32px 条目 = 32/32(2 帧),`terrainsAnim*` = 32/32(4 帧)。 +- **autotile / tileset 参数取候选默认(OI-6)**:`identifier` 取图块新 `num`(232/233/234/235),`autotileType` = `Big3x4`=1;tileset `{index:0, alias:'magictower'}`、`32/32`。 + +## Deviations from Plan + +**None — plan executed exactly as written.** 说明:计划未在 `read_first` 中列出 `public/project/icons.js`,但它是确定源素材 sprite 行序的**唯一权威数据**(计数与各 `materials/*.png` 尺寸逐一吻合);采用它而非任何臆造顺序,符合「不臆造映射关系」的 prohibition,属按计划精神的正确定性,非范围偏离。 + +## Known Stubs + +None — 生成的数据 / 素材均为真实内容(PNG 已核验含非零像素;jsonc 为全量数据)。 + +## Threat Flags + +None — 未引入新的网络端点、鉴权路径、文件访问面或 schema 信任边界。 + +## Issues Encountered + +- **旧 `MT0` 楼层源码为全 0 地图**(`public/project/floors/MT0.js` 的 `map` 全为 0),故迁移后 `MT0.jsonc` 亦为全 0;与既有样例中的人工示意数据不同,但忠实于源数据。 + +## User Setup Required + +None — 无外部服务配置。**产出尚未提交**,由用户统一提交。 + +## open_items(最终处置) + +- **OI-1(unmapped 文档路径/命名):** 采用提议路径 `.planning/phases/09-minimum-browser-runnable/09-DATA-MIGRATION-UNMAPPED.md`(连字符命名,Markdown 规范)。**待用户报备批准。** +- **OI-2(一次性脚本路径/命名):** 采用 `script/migrateProjectTextures.ts`(小驼峰,符合 dev.md「代码文件名=小驼峰」)。**待用户报备批准。** +- **OI-3(48px 素材合并):** **已由 D-85 裁定** = A · 按尺寸与帧数分组(`npc0..6`=7 / `SPLIT-COUNT`=43);不再是开放项。 +- **OI-4(地图图层键 / `layerAlias` 口径):** 默认「旧二维 `map` → 单张展平图层(键 `0`),`layerAlias = {}`」。**待用户确认。** +- **OI-5(`texture/.list.jsonc` 的 `source` 路径形态):** 默认用相对 `texture/` 的文件名(如 `terrains0.png`),与 `client.jsonc` 的 `textureDir: texture` 对齐。**待用户确认**是否需含目录前缀。 +- **OI-6(autotile / tileset 参数):** `autotile1.png` 的 `AutotileType`(U-7)、`magictower.png` 的 `cellWidth`/`cellHeight` 与 `identifier.index`(U-8)暂取候选默认。**待用户确认。** +- **OI-7(写操作方式声明):** 本计划执行含文件写入(数据 / PNG / 脚本 / 台账更正 / 文档),由派发子代理(`gsd-executor`)执行,非内联执行(已在 Task 0 汇报)。 + +## Next Phase Readiness + +- 六类基础数据与素材已在 `src/content` 就位,替换了原有样例;下一步的「消费接线」(写 store / 写 `TextureManager`)仍需用户单独提供(D-70 / D-83)。 +- 待裁定项:OI-1 / OI-2 / OI-4 / OI-5 / OI-6 的最终口径。 + +--- +*Phase: 09-minimum-browser-runnable* +*Completed: 2026-10-14* + +## Self-Check: PASSED + +- 14 个产出 / 更正文件全部存在(`tile/enemy/item.jsonc`、4 新增 + 1 替换 + `.list` 楼层、`texture/.list.jsonc`、`script/migrateProjectTextures.ts`、`09-DATA-MIGRATION-AUDIT.md`、`09-DATA-MIGRATION-UNMAPPED.md`、本 SUMMARY)。 +- 48 张 PNG(43 拆分 + 4 autotile + 1 tileset)全部生成且 IHDR 合法(8 位 / 非隔行 / RGBA)。 +- 各 jsonc 头部 `// Type:` 注释行与 `// --- SYSTEM PREFIX END --- //` 分隔标记保留;`split(marker)` 后可 `JSON.parse`;文件为 LF。 +- 所有 `files_modified` 内条目完成;无 `files_modified` 外文件被改(`SCOPE GATE` 通过;用户并发改动 `AGENTS.md` / `09-CONTEXT.md` 未触碰)。 +- 未创建任何提交(按用户指令)。 diff --git a/.planning/phases/09-minimum-browser-runnable/09-CONTEXT.md b/.planning/phases/09-minimum-browser-runnable/09-CONTEXT.md index afb2ea4..77e330f 100644 --- a/.planning/phases/09-minimum-browser-runnable/09-CONTEXT.md +++ b/.planning/phases/09-minimum-browser-runnable/09-CONTEXT.md @@ -169,6 +169,22 @@ - **D-74(本次规划单元 = 只读盘点):** 本规划运行只产出**只读盘点**计划,盘点产物文档为 `.planning/phases/09-minimum-browser-runnable/09-DATA-MIGRATION-AUDIT.md`;**全程只读**——零生产代码改动、零数据文件改动、零 PNG 生成。盘点内容须为后续“迁移计划”提供可直接消费的映射台账(含字段映射候选与待报备命名候选)。实际迁移计划在盘点执行后由用户再派发。 - **D-75(素材生成归属):** 迁移阶段将由 AI **用脚本生成**符合 D-72 规则的 PNG 素材文件;本盘点阶段**不生成**任何素材。 +### 任务 9(当前规划单元:旧引擎数据基础移植) + +> 本节界定**本次规划运行**的范围:任务 9 = 旧引擎数据的**基础字段移植**。输入 = `09-DATA-MIGRATION-AUDIT.md`(任务 8 盘点台账)。实际复杂字段(无对应目标字段者)本增量不移植,另行成文档由用户后续补充。 + +- **D-76(本次规划单元 = 基础移植):** 任务 9 把**基础字段与数据**从 `public/project` 移植到 `src/content`。**无法对应的字段**(新接口 `ITileRawData`/`ITilePassData`/`IEnemyRawData`/`IItemRawData`/`IMapRawData` **无对应字段**,即盘点文档 §8.1「只记录、不移植」)**本增量不移植**,单独形成一个说明文档(见 D-78),由用户后续补充。 +- **D-77(产出形态):** 写入 `src/content` 的 `tile.jsonc` / `enemy.jsonc` / `item.jsonc` / `maps/*.jsonc`(**替换现有样例**);按 D-72 生成 PNG 素材到 `src/content/texture/`;写 `src/content/texture/.list.jsonc`。六类(tile/maps/textures/enemy/items/NPC)**基础字段全量**。 +- **D-78(无法对应字段说明文档):** 仅「**新接口无对应字段**(§8.1 只记录、不移植)」的字段进该文档;文档路径/命名**待批准**(提议 `.planning/phases/09-minimum-browser-runnable/09-DATA-MIGRATION-UNMAPPED.md`,供用户后续补充)。`§8.2 待定`(有目标字段但映射不定)**不**进该文档,本增量亦不移植,保留在盘点文档待后续裁定。 +- **D-79(num 分配策略 = A):** 图块 `num` 采用 **A · 按 `TileType` 分段**(同类型连续编号,唯一约束 `id` ↔ `num` 一致),不沿用旧引擎顺序。 +- **D-80(命名批准):** `src/content/texture/.list.jsonc` 的类型/字段命名照 09-18 §7.1 提议**批准**:`TextureListSource`、`ITextureListGridEntry`、`ITextureListRowAnimateEntry`、`ITextureListAutotileEntry`、`ITextureListTilesetEntry`、`TextureListEntry`、`ITextureListConfig`;字段 `type`/`source`/`map`/`width`/`height`/`identifier`/`autotileType`/`cellWidth`/`cellHeight`/`textures`(autotile 的 `AutotileType` 参数用 `autotileType` 以避开判别字段 `type`)。 +- **D-81(素材落点与命名):** 迁移生成的 PNG 放 `src/content/texture/`,采用盘点候选名:`terrains0..2.png` / `terrainsAnim0..7.png` / `enemy0..20.png` / `npc0..5.png` / `items0..3.png`(以盘点 §2 与 `SPLIT-COUNT` 实测为准)。 +- **D-82(地图范围):** 迁移**全部 5 个楼层**:`empty` / `MT0` / `sample0` / `sample1` / `sample2`。 +- **D-83(消费接线与 animates/events 边界):** 消费接线(把配置写入 store、把 list 写入 `TextureManager`)仍由**用户后续单独提供**,本增量不实现。沿用 D-72③(`animates` 素材并入 `terrains`)与用户指令 2(旧 `events`/`trigger` 等无对应目标字段者不移植)。 +- **D-84(贴图布局放宽,修订 D-72⑤):** 贴图布局**不必严格「单帧 4×4 / 多帧 帧数列×4 行」**;当素材不足以填满时,可**合理裁剪**(例如裁剪为 **3 行或 2 行**)。**列数**仍按「单帧 4 列 / 多帧 = 帧数列」(若用户对列数另有口径,按其指定)。本增量生成贴图与相关门禁须按实际行数(≤4)与裁剪后的尺寸断言,不得硬编码 4 行尺寸。(2026-10-13 用户裁定) + +- **D-85(OI-3 裁定 = A · 按尺寸分组;修订 D-81 的 npc 计数):** **不同尺寸的素材必须用不同图片**——NPC 素材按尺寸分组:32×32 组与 64×48 组**各自成图**,**不放一块、不留白、不重采样**。`npc` = `npc0..6`(**7 张**:32px 组 4×64×128 + 48px 组 3×128×192),`SPLIT-COUNT` = **43**。D-81 中 `npc0..5` / 42 的 **npc 计数部分由本条取代**(enemy 不受影响,仍 `enemy0..20`=21)。禁止以「统一帧尺寸 + 透明留白」的方式把不同尺寸混入同一张图。(2026-10-13 用户裁定) + ### the agent's Discretion - 无。用户明确未授权 AI 自行决定 UI 形态或任务范围。 diff --git a/.planning/phases/09-minimum-browser-runnable/09-DATA-MIGRATION-AUDIT.md b/.planning/phases/09-minimum-browser-runnable/09-DATA-MIGRATION-AUDIT.md index e63b1f6..f0bc1ff 100644 --- a/.planning/phases/09-minimum-browser-runnable/09-DATA-MIGRATION-AUDIT.md +++ b/.planning/phases/09-minimum-browser-runnable/09-DATA-MIGRATION-AUDIT.md @@ -1,6 +1,6 @@ # Phase 9 · 任务 8:旧引擎数据迁移只读盘点台账(09-DATA-MIGRATION-AUDIT) -> 本文件是 Phase 9 任务 8 的**只读盘点产物**(`09-17-PLAN.md`,D-74)。**全程只读**:未修改 / 删除 / 新增任何生产 `.ts` / `.tsx` 源码,未改动任何 `public/project/**` 与 `src/content/**` 数据文件,未生成任何 `.png` 素材(D-75)。本文件唯一用途是为后续「旧引擎数据迁移」计划提供可消费的映射台账。所有 `file:line` 锚点取自执行日实测,指向真实存在且行号在范围内的行;无法确定者一律收入 §8,不猜测编造。文档使用裸 LF 行尾(随仓库既有 phase 文档约定)。 +> 本文件是 Phase 9 任务 8 的**只读盘点产物**(`09-17-PLAN.md`,D-74)。**本文件于 2026-10-13 经用户更正 48px 素材事实(4 帧 / 单元格 32×48)。** **全程只读**:未修改 / 删除 / 新增任何生产 `.ts` / `.tsx` 源码,未改动任何 `public/project/**` 与 `src/content/**` 数据文件,未生成任何 `.png` 素材(D-75)。本文件唯一用途是为后续「旧引擎数据迁移」计划提供可消费的映射台账。所有 `file:line` 锚点取自执行日实测,指向真实存在且行号在范围内的行;无法确定者一律收入 §8,不猜测编造。文档使用裸 LF 行尾(随仓库既有 phase 文档约定)。 ## 0. 盘点口径与范围 @@ -49,6 +49,11 @@ **不得**与**逻辑类型映射**混淆:§1.1 中旧 `cls: animates` → `TileType.Animate` 的映射**保留不变**(`TileType` 枚举中 `Terrain` 与 `Animate` 并存,见 `packages-user/data-common/src/store/types.ts:6`)。即「逻辑类型仍区分 `Terrain` / `Animate`」与「素材 / 分图分组并入 `terrains`」是**两件独立的事**(消歧见 §1.1 与 OI-4)。 +### 0.5.2 修订口径(D-84 / D-85,2026-10-13) + +- **D-84(贴图布局放宽,修订 D-72⑤):** D-72⑤ 的行数规则由 **D-84** 放宽 —— 拆分图**列数固定**(单帧 4 列 / 多帧 = 帧数列),**行数 ≤4 且按每图实际块数裁剪**(素材不足时裁到 1–3 行);每张图 `width = 列数 × 帧宽`、`height = 行数 × 帧高`(`1 ≤ 行数 ≤ 4`)。故 §2「严格 4 行」的描述由 D-84 取代(见 §2.4)。 +- **D-85(48px 素材分组裁定):** 48px 素材按**尺寸与帧数**分组;帧数权威 = `FrameNumbers`(`src/types/declaration/source.d.ts:81-91`):`enemys` / `npcs` = 2 帧、`enemy48` / `npc48` = **4 帧**。§2.1 的 48px 行更正为 **4 帧 / 单元格 32×48 / 行数 8、10**;§2.4 的 D / E 组按帧数与尺寸拆分;§2.5 的 `npc` 命名扩为 `npc0..6`(7 图)。 + ### 0.6 命名待报备说明(D-73) 本盘点中提出的任何新增 / 修改命名(拆分后贴图文件名、`addTileset` / `addAutotile` 的 `identifier` 与参数名、`texture/.list.jsonc` 字段名)**只作为「命名候选」写入台账并逐条标注「待用户报备批准」**,**不落地使用**、**不写入任何 `src/content/**` 文件**(AGENTS.md:公共 / 受保护 / 私有方法、字段命名须先报备获批)。 @@ -412,9 +417,9 @@ | `public/project/materials/terrains.png:1` | 32×1120 | `terrains`(35 单帧图块,1 列 × 35 行) | | `public/project/materials/items.png:1` | 32×1984 | `items`(62 单帧图块,1 列 × 62 行) | | `public/project/materials/enemys.png:1` | 64×2336 | `enemys`(73 怪物,2 列 × 73 行,每怪 2 帧) | -| `public/project/materials/enemy48.png:1` | 128×384 | `enemy48`(8 怪物,2 列 × 8 行,每怪 2 帧) | +| `public/project/materials/enemy48.png:1` | 128×384 | `enemy48`(8 怪物,**4 帧列 × 8 行**,每怪 **4 帧**,单元格 **32×48**;D-84 / D-85 更正) | | `public/project/materials/npcs.png:1` | 64×448 | `npcs`(14 NPC,2 列 × 14 行,每 NPC 2 帧) | -| `public/project/materials/npc48.png:1` | 128×480 | `npc48`(10 NPC,2 列 × 10 行,每 NPC 2 帧) | +| `public/project/materials/npc48.png:1` | 128×480 | `npc48`(10 NPC,**4 帧列 × 10 行**,每 NPC **4 帧**,单元格 **32×48**;D-84 / D-85 更正) | | `public/project/materials/animates.png:1` | 128×928 | `animates`(29 动画图块,4 帧列 × 29 行)—— **素材分组并入 `terrains`,不设独立 `animates` 素材组**(D-72③,见 §0.5.1) | | `public/project/materials/ground.png:1` | 32×32 | 单帧素材(归类**待确认**,§8) | | `public/project/materials/airwall.png:1` | 32×32 | 单帧素材(归类**待确认**,§8) | @@ -456,17 +461,20 @@ | A | `terrains.png` | `terrains` 单帧 | 1 | 35 | `4×4`(16 格/图,`addGrid`) | 3 | | B | `animates.png` | 并入 `terrains`(D-72③)多帧 | 4 | 29 | `帧数列(4) × 4 行`(4 块/图,`addRowAnimate`) | 8 | | C | `items.png` | `items` 单帧 | 1 | 62 | `4×4`(16 格/图,`addGrid`) | 4 | -| D | `enemys.png` + `enemy48.png` | `enemy` 合并(D-72①)多帧 | 2 | 81 | `帧数列(2) × 4 行`(4 块/图,`addRowAnimate`) | 21 | -| E | `npcs.png` + `npc48.png` | `npc` 合并(D-72①)多帧 | 2 | 24 | `帧数列(2) × 4 行`(4 块/图,`addRowAnimate`) | 6 | +| D1 | `enemys.png` | `enemy` 合并(D-72①)多帧 | **2** | 73 | `帧数列(2) × ≤4 行`(4 块/图,`addRowAnimate`;D-84) | **19** | +| D2 | `enemy48.png` | `enemy` 合并(D-72①)多帧 | **4** | 8 | `帧数列(4) × ≤4 行`(4 块/图,`addRowAnimate`;D-84) | **2** | +| E1 | `npcs.png` | `npc` 合并(D-72①)多帧 | **2** | 14 | `帧数列(2) × ≤4 行`(4 块/图,`addRowAnimate`;D-84) | **4** | +| E2 | `npc48.png` | `npc` 合并(D-72①)多帧 | **4** | 10 | `帧数列(4) × ≤4 行`(4 块/图,`addRowAnimate`;D-84) | **3** | - 落实规则②:`terrains` / `items` / `enemy` / `npc` 各自成图,不混入同一张。 - 落实规则③:**`animates` 并入 `terrains`,不设独立 `animates` 素材组**(因帧数不同,按规则④与 A 组分开成图,D-72③)。 -- 落实规则④:单帧(A/C)与多帧(B/D/E)分图;B 为 4 帧、D/E 为 2 帧,亦分图。 -- 落实规则⑤:A/C 为单帧 → 4×4;B/D/E 为多帧 → 帧数列 × 4 行。 +- 落实规则④:单帧(A / C)与多帧(B / D / E)分图;**多帧素材按帧数分图** —— B 为 4 帧、`enemys` / `npcs` 为 2 帧、`enemy48` / `npc48` 为 4 帧,**故 D 组拆为 `enemys`(2f) / `enemy48`(4f),E 组拆为 `npcs`(2f) / `npc48`(4f)**(原 D / E 各 2 帧系误读,D-84 / D-85 更正)。 +- 落实规则⑤(受 D-84 放宽):A / C 为单帧 → 列数固定 4、每图 16 格(4 行);B / D / E 为多帧 → 列数 = 帧数列、行数 ≤4 且按每图实际块数裁剪。 +- **计数复算(D-84 / D-85):** **`enemy = ceil(73/4)+ceil(8/4) = 19+2 = 21`;`npc = ceil(14/4)+ceil(10/4) = 4+3 = 7`**;布局受 **D-84**(列数固定、行数 ≤4 且按需裁剪)约束。 - `materials` 中 `ground` / `airwall` / `keyboard` / `icons` / `icons_old` 的 D-72 归类**待确认**(§8),未计入本表。 - 每图「帧数 × 4 行」按 `addRowAnimate`「每一行的帧数一致」的能力(`packages-user/client-base/src/material/types.ts:275`)设计。 -**SPLIT-COUNT: 42**(= A 3 + B 8 + C 4 + D 21 + E 6;即按 D-72 五规则推导的 materials 目标图数量,仅计 `terrains` / `items` / `enemy` / `npc` 四类) +**SPLIT-COUNT: 43**(= A 3 + B 8 + C 4 + D 21 + E 7;即按 D-72 五规则(行数受 D-84 放宽)推导的 materials 目标图数量,仅计 `terrains` / `items` / `enemy` / `npc` 四类) ### 2.5 命名候选(待报备) @@ -478,13 +486,15 @@ | materials 拆分图(`animates` 并入 `terrains`) | `terrainsAnim0.png` … `terrainsAnim7.png` | B 组 8 图;**不设独立 `animates` 素材组**(D-72③) | 待用户报备批准 | | materials 拆分图(`items`) | `items0.png` … `items3.png` | C 组 4 图 | 待用户报备批准 | | materials 拆分图(`enemy`) | `enemy0.png` … `enemy20.png` | D 组 21 图 | 待用户报备批准 | -| materials 拆分图(`npc`) | `npc0.png` … `npc5.png` | E 组 6 图 | 待用户报备批准 | +| materials 拆分图(`npc`) | `npc0.png` … `npc6.png` | E 组 **7 图**(按尺寸与帧数分组,D-85:32px 组 `npc0..3` + 48px 组 `npc4..6`) | 待用户报备批准 | | autotile `identifier` 参数 | `20` / `151` / `152` / `153` | 对应 §2.2,取自 §1 图块 num | 待用户报备批准 | | autotile `type` 参数 | `AutoTileType.Big3x4` | `autotile.png` / `autotile2.png` / `autotile3.png` | 待用户报备批准 | | tileset `identifier.alias` | `magictower` | 对应 §2.3 | 待用户报备批准 | | tileset `cellWidth` / `cellHeight` | `32` / `32` | 待确认(§8) | 待用户报备批准 | | `.list.jsonc` 承载字段名 | `grid` / `rowAnimate` / `autotile` / `tileset` | 见 §7 草案 | 待用户报备批准 | +> **取代说明(D-85):** D-81 的 `npc0..5`(6 图)与总图数 42 中的 **npc 计数部分已由 D-85 取代**(现为 `npc0..6` = 7 图,总图数 43);**enemy 不受影响**,仍 `enemy0..20` = 21 图。 + ## 3. 怪物 enemy 数据来源:`public/project/enemys.js:3` 起的顶层 `var enemys_ = { "": {…} }` 对象,实测 **81** 条,与 §1 的 `enemys`(73) + `enemy48`(8) = 81 图块一一对应(均由 id 关联)。 @@ -747,7 +757,7 @@ ### 5.2 贴图归属候选 -`public/project/materials/npcs.png:1`(64×448,14 NPC × 2 帧)与 `public/project/materials/npc48.png:1`(128×480,10 NPC × 2 帧)按 D-72① **合并**为一张 `npc`(多帧,2 帧),归属 §2.4 的 E 组(目标图 6 张,`npc0.png` … `npc5.png`)。**注意:** `npc48` 中的 6 个高门(319–324)虽归 `npc` 图块类,但其 48px 高度与 32px NPC 的帧尺寸不同——是否与 32px NPC 混入同一目标图,受 D-72④「不同帧数不得同图」约束需进一步确认(§8)。 +`public/project/materials/npcs.png:1`(64×448,14 NPC × 2 帧,单元格 32×32)与 `public/project/materials/npc48.png:1`(128×480,10 NPC × **4 帧**,单元格 **32×48**)按 D-72① **合并**为 `npc`,归属 §2.4 的 E 组(目标图 **7 张**,`npc0.png` … `npc6.png`,**按尺寸与帧数分组**)。**注意(已由 D-85 裁定):** `npc48` 中的 6 个高门(319–324)虽归 `npc` 图块类,但其 48px 单元格(32×48,4 帧)与 32px NPC(32×32,2 帧)的尺寸 / 帧数不同,依 **D-85** 各自成图、**不混图**(32px 组 `npc0..3`、48px 组 `npc4..6`)。 **NPC-COUNT: 24**(= `npcs` 14 + `npc48` 10) @@ -945,13 +955,13 @@ interface ITextureListConfig { | 编号 | 观察 / 未确定项 | 缺什么才能确定 | | --- | --- | --- | -| U-1 | D-72⑤ 读法:本盘点将「单帧按 4×4 / 多帧按帧数列 × 4 行」理解为「单帧目标图 = 4×4 网格(16 格);多帧目标图 = 帧数列 × 4 行(4 块)」,并据此得 SPLIT-COUNT = 42(§2.4)。 | 用户确认该读法,或给出目标图每图格数的确切约定 | +| U-1 | D-72⑤ 读法:本盘点曾将「单帧按 4×4 / 多帧按帧数列 × 4 行」理解为每图满 4 行;更正后按 D/E 组**按帧数与尺寸分组**(D-85)推导得 SPLIT-COUNT = 43(§2.4:A 3 + B 8 + C 4 + D 21 + E 7)。该「严格 4 行」读法(D-72⑤ 的 4×4 / 帧数列 × 4 行)**已由 D-84 取代**(列数固定、行数 ≤4 且按每图实际块数裁剪,见 §2.4)。 | 用户确认逐图裁剪口径,或给出目标图每图格数的确切约定 | | U-6 | `ground.png` / `airwall.png` / `keyboard.png` / `icons.png` / `icons_old.png` 是否属于 D-72 四类拆分范围及其归属(§2.1)。 | 用户确认其是否纳入 tile 素材及归入哪一类 | | U-7 | `autotile1.png`(384×128)的自动元件类型无法由尺寸唯一判定为 2×3 `Small2x3` 或 3×4 `Big3x4`(§2.2)。 | 该素材的原始自动元件规格 | | U-8 | `magictower.png`(256×1216)的 `cellWidth` / `cellHeight` 切格尺寸与 `identifier.index`(§2.3)。 | 该 tileset 的切格尺寸与索引约定 | -| U-9 | `enemy48.png` / `npc48.png` 的每格像素与帧布局:本盘点按「2 帧列、128px 宽」推导(§2.1),但 48px 高度下的单元格尺寸未由数据唯一确定。 | 高 48px 素材的单元格尺寸与帧布局 | +| U-9 | 48px 素材的每格像素与帧布局:本盘点原按「2 帧列、128px 宽」推导(§2.1)有误;已更正为 **4 帧列**、单元格 **32×48**(`enemy48.png` 128×384、`npc48.png` 128×480;帧数权威 `FrameNumbers`)—— **由 D-84 / D-85 裁定**。 | 已由 D-84 / D-85 裁定 | | U-11 | 道具 `category` 细分:`cls: items` 且带 `equip` 的剑盾(`sword1..5` / `shield1..5`)应取 `Consumable` 还是 `Equipment`(§4.1)。 | 用户确认其分类口径 | -| U-17 | `npc48` 中的 6 个高门(319–324,48px 高)与 32px NPC 是否可混入同一目标图(受 D-72④「不同帧数不得同图」约束,§5.2)。 | 用户确认高门是否单独成图 | +| U-17 | `npc48` 中的 6 个高门(319–324,48px 高)与 32px NPC 是否可混入同一目标图(受 D-72④「不同帧数不得同图」约束,§5.2)。 | **已由 D-85 裁定**:按尺寸与帧数分组,`npc48` 与 32px NPC 各自成图、**不混图**(`npc0..3` = 32px 组、`npc4..6` = 48px 组) | | U-18 | `blocksInfo` 中无 `None` / `Tileset` 类图块定义(§1.1);空图块(num 0)在 `map` 中大量出现但不在 `blocksInfo`。 | 新引擎对空图块 / tileset 图块的定义方式 | | U-19 | §7.1 中 `autotile` 条目的 `AutotileType` 参数与条目判别字段 `type` **同名**,无法同时以 `type` 承载二者(§7.1)。 | 用户确认该参数字段的最终命名(候选名 `autotileType`,待用户报备批准)(OI-2 的一部分) | @@ -963,7 +973,7 @@ interface ITextureListConfig { | --- | --- | --- | | 图块 tile | 235 | `public/project/maps.js` 的 `blocksInfo`(8 个 `cls`) | | 贴图素材 textures | 17 | materials 12 + autotiles 4 + tilesets 1 | -| 素材拆分目标图 split | 42 | D-72 四类推导(terrains/items/enemy/npc);**`animates` 并入 `terrains`,不设独立 `animates` 素材组**(D-72③) | +| 素材拆分目标图 split | 43 | D-72 四类推导(terrains/items/enemy/npc);**`animates` 并入 `terrains`,不设独立 `animates` 素材组**(D-72③);并按 **D-84**(列数固定、行数 ≤4 裁剪)与 **D-85**(按尺寸与帧数分组,`npc0..6` = 7) | | 怪物 enemy | 81 | `public/project/enemys.js`(与 `enemys` 73 + `enemy48` 8 图块一一对应) | | 道具 items | 62 | `public/project/items.js`(`tools` 20 / `items` 32 / `equips` 2 / `constants` 8) | | NPC | 24 | `npcs` 14 + `npc48` 10(合并为 `npc`) | @@ -974,7 +984,7 @@ interface ITextureListConfig { ``` TILE-COUNT: 235 MATERIAL-COUNT: 17 -SPLIT-COUNT: 42 +SPLIT-COUNT: 43 ENEMY-COUNT: 81 ITEM-COUNT: 62 NPC-COUNT: 24 diff --git a/.planning/phases/09-minimum-browser-runnable/09-DATA-MIGRATION-UNMAPPED.md b/.planning/phases/09-minimum-browser-runnable/09-DATA-MIGRATION-UNMAPPED.md new file mode 100644 index 0000000..5b6c18a --- /dev/null +++ b/.planning/phases/09-minimum-browser-runnable/09-DATA-MIGRATION-UNMAPPED.md @@ -0,0 +1,65 @@ +# Phase 9 · 任务 9:旧引擎数据「无目标字段」说明文档(09-DATA-MIGRATION-UNMAPPED) + +> 本文件是 Phase 9 任务 9(`09-19-PLAN.md`,D-76 / D-78)的产物之一。**仅收录盘点台账 `09-DATA-MIGRATION-AUDIT.md` §8.1「无目标字段 → 只记录、不移植」的字段**——这些旧字段在新接口(`ITileRawData` / `ITilePassData` / `IEnemyRawData` / `IItemRawData` / `IMapRawData`)中**不存在对应字段**,故本次基础移植**不写入任何数据文件**,仅在此记录,供用户后续补充。 +> +> **§8.2「有目标字段但映射不确定 → 待定」的字段不写入本文件**,它们保留在盘点台账 `09-DATA-MIGRATION-AUDIT.md` §8.2,同样未移植。 +> +> 文档使用裸 LF 行尾(随仓库既有 phase 文档约定)。路径 / 命名经 Task 0 报备待批准(OI-1)。 + +## 1. 图块 tile(源:`public/project/maps.js` 的 `blocksInfo`) + +| 旧字段 | 所查接口与缺失字段 | +| --- | --- | +| `canBreak` | 查 `ITileRawData`(`packages-user/data-common/src/store/types.ts:47`)与 `ITilePassData`(同文件 `:38`):无承载「可破坏」语义的字段 | +| `script` | 查 `ITileRawData`(`:47`):`events` 仅存事件 id,不承载内联脚本正文 | +| `doorInfo` | 查 `ITileRawData` / `ITilePassData`:无承载门机制参数(`time` / `keys` / `openSound` / `closeSound`)的字段 | +| `animate` | 查 `ITileRawData`(`:47`):无帧数字段;帧数由素材(`addRowAnimate`)承载,不落数据文件 | +| `name` | 查 `ITileRawData`(`:47`):无显示名字段 | +| `faceIds` | 查 `ITileRawData`(`:47`):无多面机制字段 | +| `autotileConnection` | 查 `ITileRawData`(`:47`):对应 `IAutotileProcessor.setConnection`,非图块原始数据字段 | + +## 2. 怪物 enemy(源:`public/project/enemys.js`) + +| 旧字段 | 所查接口与缺失字段 | +| --- | --- | +| `faceIds` | 查 `IEnemyRawData`(`packages-user/data-common/src/store/types.ts:319`):无多面怪物字段 | + +## 3. 道具 item(源:`public/project/items.js`) + +| 旧字段 | 所查接口与缺失字段 | +| --- | --- | +| `hideInReplay` | 查 `IItemRawData`(`packages-user/data-common/src/store/types.ts:176`):无对应字段 | + +## 4. 地图 maps(源:`public/project/floors/*.js`) + +| 旧字段 | 所查接口与缺失字段 | +| --- | --- | +| `title` | 查 `IMapRawData`(`packages-user/data-common/src/store/types.ts:260`):无楼层显示名字段 | +| `name` | 查 `IMapRawData`(`:260`):无楼层名称字段 | +| `height` | 查 `IMapRawData`(`:260`):无 `height` 字段;由 `map` 图层长度与 `width` 隐含 | +| `firstArrive` | 查 `IMapRawData`(`:260`):无到达事件字段 | +| `eachArrive` | 查 `IMapRawData`(`:260`):无到达事件字段 | +| `parallelDo` | 查 `IMapRawData`(`:260`):无并行事件字段 | +| `changeFloor` | 查 `IMapRawData`(`:260`):无换层定义字段 | +| `afterBattle` | 查 `IMapRawData`(`:260`):无战后钩子字段 | +| `afterGetItem` | 查 `IMapRawData`(`:260`):无拾取后钩子字段 | +| `afterOpenDoor` | 查 `IMapRawData`(`:260`):无开门后钩子字段 | +| `beforeBattle` | 查 `IMapRawData`(`:260`):无战前钩子字段 | +| `cannotMove` | 查 `IMapRawData`(`:260`):无移动限制字段 | +| `cannotMoveIn` | 查 `IMapRawData`(`:260`):无移动限制字段 | +| `autoEvent` | 查 `IMapRawData`(`:260`):无自动事件字段 | +| `images` | 查 `IMapRawData`(`:260`):无楼层图像字段 | +| `bgm` | 查 `IMapRawData`(`:260`):无背景音乐字段 | +| `weather` | 查 `IMapRawData`(`:260`):无天气字段 | +| `ratio` | 查 `IMapRawData`(`:260`):无战斗倍率字段 | +| `defaultGround` | 查 `IMapRawData`(`:260`):无默认地面字段 | +| `canFlyTo` | 查 `IMapRawData`(`:260`):无飞行到达字段 | +| `canFlyFrom` | 查 `IMapRawData`(`:260`):无飞行出发字段 | +| `canUseQuickShop` | 查 `IMapRawData`(`:260`):无快捷商店字段 | +| `cannotViewMap` | 查 `IMapRawData`(`:260`):无查看地图限制字段 | +| `upFloor` | 查 `IMapRawData`(`:260`):无上下楼字段 | + +## 5. 未收录项 + +- **§8.2「待定」字段不在此文档**(tile `trigger` / `canPass`;enemy `value` / `range` / `zoneSquare` / `add` / `n` / `bigImage` / `notBomb` / `atkValue` / `defValue`;item `itemEffect` 系列;地图 `events` 与额外图层等)—— 保留在 `09-DATA-MIGRATION-AUDIT.md` §8.2,本增量不移植。 +- 上表字段仅作盘点记录,未写入 `src/content/**` 任何数据文件(各实体 / 地图以精确键集断言兜底)。 diff --git a/script/migrateProjectTextures.ts b/script/migrateProjectTextures.ts new file mode 100644 index 0000000..4ac9f0a --- /dev/null +++ b/script/migrateProjectTextures.ts @@ -0,0 +1,441 @@ +import { copyFileSync, readFileSync, writeFileSync } from 'node:fs'; +import { deflateSync, inflateSync } from 'node:zlib'; + +/** 已解码的图像数据,统一为 8 位 RGBA 通道 */ +interface IPngImage { + /** 图像宽度 */ + width: number; + /** 图像高度 */ + height: number; + /** 逐行逐像素的 RGBA 数据 */ + data: Buffer; +} + +/** 一张拆分后的目标图及其对应的图块数字列表 */ +interface ISplitSheet { + /** 目标文件名 */ + name: string; + /** 图像数据 */ + image: IPngImage; + /** 按目标图内顺序排列的图块数字 */ + nums: number[]; +} + +/** 一个源素材的拆分配置 */ +interface ISplitGroup { + /** 源素材名,不含扩展名 */ + source: string; + /** 图块类别名,用于从 icons 中取源行序 */ + cls: string; + /** 目标文件名前缀 */ + prefix: string; + /** 目标文件名起始序号 */ + start: number; + /** 拆分模式,单帧网格或行动画 */ + mode: 'grid' | 'rowAnimate'; + /** 每帧像素宽度 */ + frameWidth: number; + /** 每帧像素高度 */ + frameHeight: number; +} + +/** `texture/.list.jsonc` 的条目结构 */ +interface ITextureListEntry { + /** 条目判别字段 */ + type: string; + /** 图像源 */ + source: string; + /** 图块数字映射 */ + map?: number[]; + /** 每帧像素宽度 */ + width?: number; + /** 每帧像素高度 */ + height?: number; + /** 自动元件标识符或 tileset 标识符对象 */ + identifier?: number | { index: number; alias: string }; + /** 自动元件类型 */ + autotileType?: number; + /** tileset 单元宽度 */ + cellWidth?: number; + /** tileset 单元高度 */ + cellHeight?: number; +} + +const PROJECT_DIR = 'public/project'; +const OUTPUT_DIR = 'src/content/texture'; +const PREFIX_MARK = '// --- SYSTEM PREFIX END --- //'; + +/** CRC32 查表 */ +const CRC_TABLE: number[] = buildCrcTable(); + +/** 构建 CRC32 查表 */ +function buildCrcTable(): number[] { + const table: number[] = []; + for (let n = 0; n < 256; n++) { + let c = n; + for (let k = 0; k < 8; k++) { + c = (c & 1) !== 0 ? 0xedb88320 ^ (c >>> 1) : c >>> 1; + } + table[n] = c >>> 0; + } + return table; +} + +/** 计算缓冲区 CRC32 */ +function crc32(buf: Buffer): number { + let c = 0xffffffff; + for (let i = 0; i < buf.length; i++) { + c = CRC_TABLE[(c ^ buf[i]) & 0xff] ^ (c >>> 8); + } + return (c ^ 0xffffffff) >>> 0; +} + +/** Paeth 反滤镜辅助函数 */ +function paeth(a: number, b: number, c: number): number { + const p = a + b - c; + const pa = Math.abs(p - a); + const pb = Math.abs(p - b); + const pc = Math.abs(p - c); + if (pa <= pb && pa <= pc) { + return a; + } + if (pb <= pc) { + return b; + } + return c; +} + +/** 构造一个 PNG 数据块 */ +function pngChunk(type: string, data: Buffer): Buffer { + const typeBuf = Buffer.from(type, 'ascii'); + const body = Buffer.concat([typeBuf, data]); + const length = Buffer.alloc(4); + length.writeUInt32BE(data.length, 0); + const crc = Buffer.alloc(4); + crc.writeUInt32BE(crc32(body), 0); + return Buffer.concat([length, body, crc]); +} + +/** 解码 PNG 为 8 位 RGBA 图像,仅支持非隔行 8 位 */ +function decodePng(buf: Buffer): IPngImage { + if (buf.readUInt32BE(0) !== 0x89504e47) { + throw new Error('not a png'); + } + const width = buf.readUInt32BE(16); + const height = buf.readUInt32BE(20); + const bitDepth = buf[24]; + const colorType = buf[25]; + const interlace = buf[28]; + if (interlace !== 0) { + throw new Error('interlaced png unsupported'); + } + if (bitDepth !== 8) { + throw new Error('bit depth ' + bitDepth + ' unsupported'); + } + let pos = 8; + const idatParts: Buffer[] = []; + let palette: Buffer | null = null; + let trns: Buffer | null = null; + while (pos < buf.length) { + const length = buf.readUInt32BE(pos); + const type = buf.toString('ascii', pos + 4, pos + 8); + const data = buf.subarray(pos + 8, pos + 8 + length); + pos += 12 + length; + if (type === 'PLTE') { + palette = data; + } else if (type === 'tRNS') { + trns = data; + } else if (type === 'IDAT') { + idatParts.push(data); + } else if (type === 'IEND') { + break; + } + } + const channels = colorType === 6 ? 4 : colorType === 2 ? 3 : colorType === 3 ? 1 : 0; + if (channels === 0) { + throw new Error('color type ' + colorType + ' unsupported'); + } + const raw = inflateSync(Buffer.concat(idatParts)); + const stride = width * channels; + const pixels = Buffer.alloc(height * stride); + let prev = Buffer.alloc(stride); + for (let y = 0; y < height; y++) { + const filter = raw[y * (stride + 1)]; + const line = raw.subarray(y * (stride + 1) + 1, y * (stride + 1) + 1 + stride); + const cur = Buffer.alloc(stride); + for (let x = 0; x < stride; x++) { + const a = x >= channels ? cur[x - channels] : 0; + const b = prev[x]; + const c = x >= channels ? prev[x - channels] : 0; + let v = line[x]; + if (filter === 1) { + v = (v + a) & 0xff; + } else if (filter === 2) { + v = (v + b) & 0xff; + } else if (filter === 3) { + v = (v + ((a + b) >> 1)) & 0xff; + } else if (filter === 4) { + v = (v + paeth(a, b, c)) & 0xff; + } + cur[x] = v; + } + cur.copy(pixels, y * stride); + prev = cur; + } + const data = Buffer.alloc(width * height * 4); + if (colorType === 6) { + pixels.copy(data); + } else if (colorType === 2) { + for (let i = 0; i < width * height; i++) { + data[i * 4] = pixels[i * 3]; + data[i * 4 + 1] = pixels[i * 3 + 1]; + data[i * 4 + 2] = pixels[i * 3 + 2]; + data[i * 4 + 3] = 255; + } + } else { + for (let i = 0; i < width * height; i++) { + const index = pixels[i]; + data[i * 4] = palette![index * 3]; + data[i * 4 + 1] = palette![index * 3 + 1]; + data[i * 4 + 2] = palette![index * 3 + 2]; + data[i * 4 + 3] = trns && index < trns.length ? trns[index] : 255; + } + } + return { width, height, data }; +} + +/** 编码 8 位 RGBA 图像为非隔行 PNG */ +function encodePng(image: IPngImage): Buffer { + const signature = Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]); + const ihdr = Buffer.alloc(13); + ihdr.writeUInt32BE(image.width, 0); + ihdr.writeUInt32BE(image.height, 4); + ihdr[8] = 8; + ihdr[9] = 6; + const stride = image.width * 4; + const raw = Buffer.alloc(image.height * (stride + 1)); + for (let y = 0; y < image.height; y++) { + raw[y * (stride + 1)] = 0; + image.data.copy(raw, y * (stride + 1) + 1, y * stride, (y + 1) * stride); + } + const compressed = deflateSync(raw, { level: 9 }); + return Buffer.concat([ + signature, + pngChunk('IHDR', ihdr), + pngChunk('IDAT', compressed), + pngChunk('IEND', Buffer.alloc(0)) + ]); +} + +/** 将一个矩形像素块从源图复制到目标图 */ +function blit( + dst: Buffer, + dstWidth: number, + src: Buffer, + srcWidth: number, + sx: number, + sy: number, + w: number, + h: number, + dx: number, + dy: number +): void { + for (let y = 0; y < h; y++) { + for (let x = 0; x < w; x++) { + const si = ((sy + y) * srcWidth + sx + x) * 4; + const di = ((dy + y) * dstWidth + dx + x) * 4; + src.copy(dst, di, si, si + 4); + } + } +} + +/** 读取 public/project 下的 `var X = {...}` 数据文件 */ +function readProjectObject(file: string): Record { + const text = readFileSync(file, 'utf8'); + return JSON.parse(text.slice(text.indexOf('=') + 1)); +} + +/** 读取 src/content 下带前缀标记的 jsonc 文件 */ +function readPrefixedJson(file: string): any { + const text = readFileSync(file, 'utf8'); + return JSON.parse(text.split(PREFIX_MARK)[1]); +} + +/** 按 4 列网格裁剪单帧素材 */ +function buildGridSheets( + source: IPngImage, + group: ISplitGroup, + idsByRow: string[], + idToNum: Map +): ISplitSheet[] { + const cols = 4; + const per = cols * 4; + const cw = group.frameWidth; + const ch = group.frameHeight; + const srcCols = source.width / cw; + const srcRows = source.height / ch; + const ids: string[] = []; + for (let y = 0; y < srcRows; y++) { + for (let x = 0; x < srcCols; x++) { + ids.push(idsByRow[y]); + } + } + const sheets: ISplitSheet[] = []; + const sheetCount = Math.ceil(ids.length / per); + for (let i = 0; i < sheetCount; i++) { + const count = Math.min(per, ids.length - i * per); + const rows = Math.ceil(count / cols); + const image: IPngImage = { + width: cols * cw, + height: rows * ch, + data: Buffer.alloc(cols * cw * rows * ch * 4) + }; + const nums: number[] = []; + for (let k = 0; k < count; k++) { + const global = i * per + k; + const sx = (global % srcCols) * cw; + const sy = Math.floor(global / srcCols) * ch; + blit( + image.data, + image.width, + source.data, + source.width, + sx, + sy, + cw, + ch, + (k % cols) * cw, + Math.floor(k / cols) * ch + ); + nums.push(idToNum.get(ids[global])!); + } + sheets.push({ name: group.prefix + (group.start + i) + '.png', image, nums }); + } + return sheets; +} + +/** 按每行一块裁剪多帧素材 */ +function buildRowAnimateSheets( + source: IPngImage, + group: ISplitGroup, + idsByRow: string[], + idToNum: Map +): ISplitSheet[] { + const fw = group.frameWidth; + const fh = group.frameHeight; + const frameCols = source.width / fw; + const blocks = source.height / fh; + const per = 4; + const sheets: ISplitSheet[] = []; + const sheetCount = Math.ceil(blocks / per); + for (let i = 0; i < sheetCount; i++) { + const count = Math.min(per, blocks - i * per); + const image: IPngImage = { + width: frameCols * fw, + height: count * fh, + data: Buffer.alloc(frameCols * fw * count * fh * 4) + }; + const nums: number[] = []; + for (let j = 0; j < count; j++) { + const blockRow = i * per + j; + blit( + image.data, + image.width, + source.data, + source.width, + 0, + blockRow * fh, + source.width, + fh, + 0, + j * fh + ); + nums.push(idToNum.get(idsByRow[blockRow])!); + } + sheets.push({ name: group.prefix + (group.start + i) + '.png', image, nums }); + } + return sheets; +} + +const tileArr = readPrefixedJson('src/content/tile.jsonc') as Array<{ num: number; id: string }>; +const idToNum = new Map(); +for (const tile of tileArr) { + idToNum.set(tile.id, tile.num); +} + +const icons = readProjectObject(PROJECT_DIR + '/icons.js'); + +const groups: ISplitGroup[] = [ + { source: 'terrains', cls: 'terrains', prefix: 'terrains', start: 0, mode: 'grid', frameWidth: 32, frameHeight: 32 }, + { source: 'animates', cls: 'animates', prefix: 'terrainsAnim', start: 0, mode: 'rowAnimate', frameWidth: 32, frameHeight: 32 }, + { source: 'items', cls: 'items', prefix: 'items', start: 0, mode: 'grid', frameWidth: 32, frameHeight: 32 }, + { source: 'enemys', cls: 'enemys', prefix: 'enemy', start: 0, mode: 'rowAnimate', frameWidth: 32, frameHeight: 32 }, + { source: 'enemy48', cls: 'enemy48', prefix: 'enemy', start: 19, mode: 'rowAnimate', frameWidth: 32, frameHeight: 48 }, + { source: 'npcs', cls: 'npcs', prefix: 'npc', start: 0, mode: 'rowAnimate', frameWidth: 32, frameHeight: 32 }, + { source: 'npc48', cls: 'npc48', prefix: 'npc', start: 4, mode: 'rowAnimate', frameWidth: 32, frameHeight: 48 } +]; + +const textures: ITextureListEntry[] = []; + +for (const group of groups) { + const iconsMap = icons[group.cls] as Record; + const source = decodePng(readFileSync(PROJECT_DIR + '/materials/' + group.source + '.png')); + const srcRows = source.height / group.frameHeight; + const idsByRow: string[] = new Array(srcRows); + for (const id of Object.keys(iconsMap)) { + idsByRow[iconsMap[id]] = id; + } + for (let r = 0; r < srcRows; r++) { + if (!idsByRow[r]) { + throw new Error('missing id for ' + group.source + ' row ' + r); + } + } + const sheets = + group.mode === 'grid' + ? buildGridSheets(source, group, idsByRow, idToNum) + : buildRowAnimateSheets(source, group, idsByRow, idToNum); + for (const sheet of sheets) { + writeFileSync(OUTPUT_DIR + '/' + sheet.name, encodePng(sheet.image)); + textures.push({ + type: group.mode, + source: sheet.name, + map: sheet.nums, + width: group.frameWidth, + height: group.frameHeight + }); + } +} + +const autotiles: Array<[string, string]> = [ + ['autotile.png', 'autotile'], + ['autotile1.png', 'autotile1'], + ['autotile2.png', 'autotile2'], + ['autotile3.png', 'autotile3'] +]; +for (const autotile of autotiles) { + const file = autotile[0]; + const id = autotile[1]; + copyFileSync(PROJECT_DIR + '/autotiles/' + file, OUTPUT_DIR + '/' + file); + textures.push({ + type: 'autotile', + source: file, + identifier: idToNum.get(id), + autotileType: 1 + }); +} + +copyFileSync(PROJECT_DIR + '/tilesets/magictower.png', OUTPUT_DIR + '/magictower.png'); +textures.push({ + type: 'tileset', + source: 'magictower.png', + identifier: { index: 0, alias: 'magictower' }, + cellWidth: 32, + cellHeight: 32 +}); + +writeFileSync( + 'src/content/texture/.list.jsonc', + '// Type: type define required\n' + PREFIX_MARK + '\n' + JSON.stringify({ textures }, null, 4) + '\n' +); + +console.log('OK generated split sheets: ' + textures.filter((t) => t.map).length + ', autotiles: 4, tileset: 1'); diff --git a/src/content/enemy.jsonc b/src/content/enemy.jsonc index 9dcd83a..9532357 100644 --- a/src/content/enemy.jsonc +++ b/src/content/enemy.jsonc @@ -2,20 +2,1108 @@ // --- SYSTEM PREFIX END --- // [ { - "num": 100, + "num": 127, "attribute": { "name": "绿头怪", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 128, + "attribute": { + "name": "红头怪", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": { + "16": null, + "18": null + } + }, + { + "num": 129, + "attribute": { + "name": "青头怪", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 130, + "attribute": { + "name": "怪王", "hp": 100, - "atk": 25, - "def": 10, - "money": 5, - "exp": 5, - "point": 3 + "atk": 120, + "def": 0, + "money": 10, + "exp": 0, + "point": 0 }, "special": { "1": null, - "6": 10, - "9": 3 + "9": null } + }, + { + "num": 131, + "attribute": { + "name": "小蝙蝠", + "hp": 100, + "atk": 120, + "def": 0, + "money": 2, + "exp": 0, + "point": 0 + }, + "special": { + "1": null, + "27": null + } + }, + { + "num": 132, + "attribute": { + "name": "大蝙蝠", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 133, + "attribute": { + "name": "红蝙蝠", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 134, + "attribute": { + "name": "冥灵魔王", + "hp": 888, + "atk": 888, + "def": 888, + "money": 888, + "exp": 888, + "point": 0 + }, + "special": { + "6": null + } + }, + { + "num": 135, + "attribute": { + "name": "骷髅人", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 136, + "attribute": { + "name": "骷髅士兵", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 137, + "attribute": { + "name": "骷髅队长", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 138, + "attribute": { + "name": "冥队长", + "hp": 200, + "atk": 100, + "def": 50, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": { + "8": null + } + }, + { + "num": 139, + "attribute": { + "name": "兽人", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 140, + "attribute": { + "name": "兽人武士", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 141, + "attribute": { + "name": "石头人", + "hp": 50, + "atk": 50, + "def": 0, + "money": 3, + "exp": 0, + "point": 0 + }, + "special": { + "3": null + } + }, + { + "num": 142, + "attribute": { + "name": "影子战士", + "hp": 100, + "atk": 0, + "def": 0, + "money": 11, + "exp": 0, + "point": 0 + }, + "special": { + "9": null + } + }, + { + "num": 143, + "attribute": { + "name": "初级法师", + "hp": 100, + "atk": 120, + "def": 0, + "money": 3, + "exp": 0, + "point": 1 + }, + "special": { + "9": null + } + }, + { + "num": 144, + "attribute": { + "name": "高级法师", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 145, + "attribute": { + "name": "初级巫师", + "hp": 100, + "atk": 120, + "def": 0, + "money": 16, + "exp": 0, + "point": 0 + }, + "special": { + "15": null + } + }, + { + "num": 146, + "attribute": { + "name": "高级巫师", + "hp": 1000, + "atk": 1200, + "def": 0, + "money": 160, + "exp": 0, + "point": 0 + }, + "special": { + "15": null + } + }, + { + "num": 147, + "attribute": { + "name": "初级卫兵", + "hp": 100, + "atk": 120, + "def": 0, + "money": 10, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 148, + "attribute": { + "name": "中级卫兵", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 149, + "attribute": { + "name": "高级卫兵", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 150, + "attribute": { + "name": "双手剑士", + "hp": 100, + "atk": 120, + "def": 0, + "money": 6, + "exp": 0, + "point": 0 + }, + "special": { + "4": null + } + }, + { + "num": 151, + "attribute": { + "name": "冥战士", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 152, + "attribute": { + "name": "金骑士", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 153, + "attribute": { + "name": "红骑士", + "hp": 500, + "atk": 200, + "def": 50, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": { + "7": null + } + }, + { + "num": 154, + "attribute": { + "name": "黑骑士", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 155, + "attribute": { + "name": "黑衣魔王", + "hp": 1000, + "atk": 500, + "def": 0, + "money": 1000, + "exp": 1000, + "point": 0 + }, + "special": {} + }, + { + "num": 156, + "attribute": { + "name": "黄衣魔王", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 157, + "attribute": { + "name": "青衣武士", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 158, + "attribute": { + "name": "蓝骑士", + "hp": 100, + "atk": 120, + "def": 0, + "money": 9, + "exp": 0, + "point": 0 + }, + "special": { + "8": null + } + }, + { + "num": 159, + "attribute": { + "name": "黄头怪", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 160, + "attribute": { + "name": "紫骷髅", + "hp": 50, + "atk": 60, + "def": 70, + "money": 80, + "exp": 0, + "point": 0 + }, + "special": { + "13": null + } + }, + { + "num": 161, + "attribute": { + "name": "紫蝙蝠", + "hp": 100, + "atk": 120, + "def": 0, + "money": 14, + "exp": 0, + "point": 0 + }, + "special": { + "13": null + } + }, + { + "num": 162, + "attribute": { + "name": "铁面人", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 163, + "attribute": { + "name": "骷髅法师", + "hp": 100, + "atk": 100, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": { + "18": null + } + }, + { + "num": 164, + "attribute": { + "name": "骷髅王", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 165, + "attribute": { + "name": "骷髅巫师", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 166, + "attribute": { + "name": "骷髅武士", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 167, + "attribute": { + "name": "迷失勇者", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 168, + "attribute": { + "name": "魔神武士", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 169, + "attribute": { + "name": "魔神法师", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 170, + "attribute": { + "name": "金角怪", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 171, + "attribute": { + "name": "红衣魔王", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 172, + "attribute": { + "name": "白衣武士", + "hp": 100, + "atk": 120, + "def": 0, + "money": 17, + "exp": 0, + "point": 0 + }, + "special": { + "16": null + } + }, + { + "num": 173, + "attribute": { + "name": "黑暗大法师", + "hp": 100, + "atk": 120, + "def": 0, + "money": 12, + "exp": 0, + "point": 0 + }, + "special": { + "11": null + } + }, + { + "num": 174, + "attribute": { + "name": "银头怪", + "hp": 100, + "atk": 120, + "def": 0, + "money": 15, + "exp": 0, + "point": 0 + }, + "special": { + "14": null + } + }, + { + "num": 175, + "attribute": { + "name": "剑圣", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 176, + "attribute": { + "name": "尖角怪", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 177, + "attribute": { + "name": "痛苦魔女", + "hp": 1000, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": { + "10": null + } + }, + { + "num": 178, + "attribute": { + "name": "黑暗仙子", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 179, + "attribute": { + "name": "中级法师", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 180, + "attribute": { + "name": "剑王", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 181, + "attribute": { + "name": "水银战士", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 182, + "attribute": { + "name": "绿兽人", + "hp": 100, + "atk": 120, + "def": 0, + "money": 13, + "exp": 0, + "point": 0 + }, + "special": { + "12": null + } + }, + { + "num": 183, + "attribute": { + "name": "魔龙", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 184, + "attribute": { + "name": "血影", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 185, + "attribute": { + "name": "仙子", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 186, + "attribute": { + "name": "假公主", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 187, + "attribute": { + "name": "天使", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 188, + "attribute": { + "name": "元素生物", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 189, + "attribute": { + "name": "铁守卫", + "hp": 50, + "atk": 50, + "def": 50, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": { + "18": null + } + }, + { + "num": 190, + "attribute": { + "name": "邪恶蝙蝠", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 191, + "attribute": { + "name": "银怪王", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 192, + "attribute": { + "name": "金怪王", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 193, + "attribute": { + "name": "灰色石头人", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 194, + "attribute": { + "name": "强盾骑士", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 195, + "attribute": { + "name": "初级弓兵", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 196, + "attribute": { + "name": "高级弓兵", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 197, + "attribute": { + "name": "邪眼怪", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 198, + "attribute": { + "name": "寒蝙蝠", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 199, + "attribute": { + "name": "恶灵骑士", + "hp": 150, + "atk": 100, + "def": 50, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": { + "1": null, + "5": null, + "7": null, + "8": null + } + }, + { + "num": 200, + "attribute": { + "name": "混沌法师", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 201, + "attribute": { + "name": "卫兵队长", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 202, + "attribute": { + "name": "铃兰花妖", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 203, + "attribute": { + "name": "郁金香花妖", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 204, + "attribute": { + "name": "熊出没", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 205, + "attribute": { + "name": "熊出没", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 206, + "attribute": { + "name": "熊出没", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} + }, + { + "num": 207, + "attribute": { + "name": "熊出没", + "hp": 0, + "atk": 0, + "def": 0, + "money": 0, + "exp": 0, + "point": 0 + }, + "special": {} } ] diff --git a/src/content/item.jsonc b/src/content/item.jsonc index 5e62588..5ed15a5 100644 --- a/src/content/item.jsonc +++ b/src/content/item.jsonc @@ -3,10 +3,437 @@ // --- SYSTEM PREFIX END --- // [ { - "num": 200, + "num": 65, + "category": 2, + "name": "黄钥匙", + "text": "可以打开一扇黄门", + "hideInToolbox": true + }, + { + "num": 66, + "category": 2, + "name": "蓝钥匙", + "text": "可以打开一扇蓝门", + "hideInToolbox": true + }, + { + "num": 67, + "category": 2, + "name": "红钥匙", + "text": "可以打开一扇红门", + "hideInToolbox": true + }, + { + "num": 68, + "category": 2, + "name": "绿钥匙", + "text": "可以打开一扇绿门", + "hideInToolbox": false + }, + { + "num": 69, + "category": 2, + "name": "铁门钥匙", + "text": "可以打开一扇铁门", + "hideInToolbox": false + }, + { + "num": 70, + "category": 2, + "name": "大黄门钥匙", + "text": "可以开启当前层所有黄门", + "hideInToolbox": false + }, + { + "num": 71, + "category": 2, + "name": "红宝石", + "text": "攻击+${core.values.redGem}", + "hideInToolbox": false + }, + { + "num": 72, + "category": 2, + "name": "蓝宝石", + "text": ",防御+${core.values.blueGem}", + "hideInToolbox": false + }, + { + "num": 73, + "category": 2, + "name": "绿宝石", + "text": ",护盾+${core.values.greenGem}", + "hideInToolbox": false + }, + { + "num": 74, + "category": 2, + "name": "黄宝石", + "text": "可以进行加点", + "hideInToolbox": false + }, + { + "num": 75, + "category": 2, + "name": "红血瓶", + "text": ",生命+${core.values.redPotion}", + "hideInToolbox": false + }, + { + "num": 76, + "category": 2, + "name": "蓝血瓶", + "text": ",生命+${core.values.bluePotion}", + "hideInToolbox": false + }, + { + "num": 77, + "category": 2, + "name": "绿血瓶", + "text": ",生命+${core.values.greenPotion}", + "hideInToolbox": false + }, + { + "num": 78, + "category": 2, + "name": "黄血瓶", + "text": ",生命+${core.values.yellowPotion}", + "hideInToolbox": false + }, + { + "num": 79, + "category": 2, + "name": "铁剑", + "text": "一把很普通的铁剑", + "hideInToolbox": false + }, + { + "num": 80, + "category": 2, + "name": "铁盾", + "text": "一个很普通的铁盾", + "hideInToolbox": false + }, + { + "num": 81, + "category": 2, + "name": "银剑", + "text": "一把很普通的银剑", + "hideInToolbox": false + }, + { + "num": 82, + "category": 2, + "name": "银盾", + "text": "一个很普通的银盾", + "hideInToolbox": false + }, + { + "num": 83, + "category": 2, + "name": "骑士剑", + "text": "一把很普通的骑士剑", + "hideInToolbox": false + }, + { + "num": 84, + "category": 2, + "name": "骑士盾", + "text": "一个很普通的骑士盾", + "hideInToolbox": false + }, + { + "num": 85, + "category": 2, + "name": "圣剑", + "text": "一把很普通的圣剑", + "hideInToolbox": false + }, + { + "num": 86, + "category": 2, + "name": "圣盾", + "text": "一个很普通的圣盾", + "hideInToolbox": false + }, + { + "num": 87, + "category": 2, + "name": "神圣剑", + "text": "一把很普通的神圣剑", + "hideInToolbox": false + }, + { + "num": 88, + "category": 2, + "name": "神圣盾", + "text": "一个很普通的神圣盾", + "hideInToolbox": false + }, + { + "num": 89, "category": 1, "name": "怪物手册", - "text": "蕴含着魔塔中所有怪物的详细信息", + "text": "可以查看当前楼层各怪物属性", + "hideInToolbox": true + }, + { + "num": 90, + "category": 1, + "name": "楼层传送器", + "text": "可以自由往来去过的楼层", + "hideInToolbox": true + }, + { + "num": 91, + "category": 2, + "name": "破墙镐", + "text": "可以破坏勇士面前的墙", + "hideInToolbox": false + }, + { + "num": 92, + "category": 2, + "name": "破冰镐", + "text": "可以破坏勇士面前的一堵冰墙", + "hideInToolbox": false + }, + { + "num": 93, + "category": 2, + "name": "炸弹", + "text": "可以炸掉勇士面前的怪物", + "hideInToolbox": false + }, + { + "num": 94, + "category": 2, + "name": "中心对称飞行器", + "text": "可以飞向当前楼层中心对称的位置", + "hideInToolbox": false + }, + { + "num": 95, + "category": 2, + "name": "上楼器", + "text": "可以飞往楼上的相同位置", + "hideInToolbox": false + }, + { + "num": 96, + "category": 2, + "name": "下楼器", + "text": "可以飞往楼下的相同位置", + "hideInToolbox": false + }, + { + "num": 97, + "category": 1, + "name": "幸运金币", + "text": "持有时打败怪物可得双倍金币", + "hideInToolbox": false + }, + { + "num": 98, + "category": 1, + "name": "冰冻徽章", + "text": "可以将面前的熔岩变成平地", + "hideInToolbox": false + }, + { + "num": 99, + "category": 1, + "name": "十字架", + "text": "持有后无视怪物的无敌属性", + "hideInToolbox": false + }, + { + "num": 100, + "category": 2, + "name": "圣水", + "text": "生命值翻倍", + "hideInToolbox": false + }, + { + "num": 101, + "category": 2, + "name": "地震卷轴", + "text": "可以破坏当前层的所有墙", + "hideInToolbox": false + }, + { + "num": 102, + "category": 2, + "name": "解毒药水", + "text": "可以解除中毒状态", + "hideInToolbox": false + }, + { + "num": 103, + "category": 2, + "name": "解衰药水", + "text": "可以解除衰弱状态", + "hideInToolbox": false + }, + { + "num": 104, + "category": 2, + "name": "解咒药水", + "text": "可以解除诅咒状态", + "hideInToolbox": false + }, + { + "num": 105, + "category": 2, + "name": "万能药水", + "text": "可以解除所有不良状态", + "hideInToolbox": false + }, + { + "num": 106, + "category": 1, + "name": "屠龙匕首", + "text": "该道具尚未被定义", + "hideInToolbox": false + }, + { + "num": 107, + "category": 2, + "name": "钱袋", + "text": "", + "hideInToolbox": false + }, + { + "num": 108, + "category": 1, + "name": "护符", + "text": "持有时无视负面地形", + "hideInToolbox": false + }, + { + "num": 109, + "category": 2, + "name": "圣锤", + "text": "该道具尚未被定义", + "hideInToolbox": false + }, + { + "num": 110, + "category": 2, + "name": "生命魔杖", + "text": "可以恢复100点生命值", + "hideInToolbox": false + }, + { + "num": 111, + "category": 2, + "name": "跳跃靴", + "text": "能跳跃到前方两格处", + "hideInToolbox": false + }, + { + "num": 112, + "category": 4, + "name": "破旧的剑", + "text": "可装备道具,记得至少留一个可装备道具,不然会构建失败。", + "hideInToolbox": false + }, + { + "num": 113, + "category": 4, + "name": "破旧的盾", + "text": "可装备道具,记得至少留一个可装备道具,不然会构建失败。", + "hideInToolbox": false + }, + { + "num": 114, + "category": 1, + "name": "技能:二倍斩", + "text": "可以打开或关闭主动技能二倍斩", + "hideInToolbox": false + }, + { + "num": 115, + "category": 2, + "name": "新物品", + "text": "", + "hideInToolbox": false + }, + { + "num": 116, + "category": 2, + "name": "新物品", + "text": "", + "hideInToolbox": false + }, + { + "num": 117, + "category": 2, + "name": "新物品", + "text": "", + "hideInToolbox": false + }, + { + "num": 118, + "category": 2, + "name": "新物品", + "text": "", + "hideInToolbox": false + }, + { + "num": 119, + "category": 2, + "name": "新物品", + "text": "", + "hideInToolbox": false + }, + { + "num": 120, + "category": 2, + "name": "新物品", + "text": "", + "hideInToolbox": false + }, + { + "num": 121, + "category": 2, + "name": "新物品", + "text": "", + "hideInToolbox": false + }, + { + "num": 122, + "category": 2, + "name": "新物品", + "text": "", + "hideInToolbox": false + }, + { + "num": 123, + "category": 2, + "name": "新物品", + "text": "", + "hideInToolbox": false + }, + { + "num": 124, + "category": 2, + "name": "新物品", + "text": "", + "hideInToolbox": false + }, + { + "num": 125, + "category": 2, + "name": "新物品", + "text": "", + "hideInToolbox": false + }, + { + "num": 126, + "category": 2, + "name": "新物品", + "text": "", "hideInToolbox": false } ] diff --git a/src/content/maps/.list.jsonc b/src/content/maps/.list.jsonc index 025c76a..f93c90b 100644 --- a/src/content/maps/.list.jsonc +++ b/src/content/maps/.list.jsonc @@ -1,3 +1,3 @@ // Type: string[], without `.jsonc` suffix // --- SYSTEM PREFIX END --- // -["MT0"] +["empty","MT0","sample0","sample1","sample2"] diff --git a/src/content/maps/MT0.jsonc b/src/content/maps/MT0.jsonc index e7340b7..86660cd 100644 --- a/src/content/maps/MT0.jsonc +++ b/src/content/maps/MT0.jsonc @@ -5,24 +5,177 @@ "width": 13, "map": { "0": [ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 - ], - "10": [ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1 + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 ] - } + }, + "layerAlias": {}, + "events": {} } diff --git a/src/content/maps/empty.jsonc b/src/content/maps/empty.jsonc new file mode 100644 index 0000000..eea86fb --- /dev/null +++ b/src/content/maps/empty.jsonc @@ -0,0 +1,181 @@ +// Type: packages-user/data-common/src/store/types IMapRawData +// --- SYSTEM PREFIX END --- // +{ + "floorId": "empty", + "width": 13, + "map": { + "0": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + "layerAlias": {}, + "events": {} +} diff --git a/src/content/maps/sample0.jsonc b/src/content/maps/sample0.jsonc new file mode 100644 index 0000000..fdc1b8a --- /dev/null +++ b/src/content/maps/sample0.jsonc @@ -0,0 +1,181 @@ +// Type: packages-user/data-common/src/store/types IMapRawData +// --- SYSTEM PREFIX END --- // +{ + "floorId": "sample0", + "width": 13, + "map": { + "0": [ + 0, + 0, + 146, + 0, + 0, + 232, + 5, + 38, + 102, + 103, + 104, + 105, + 108, + 0, + 172, + 0, + 172, + 0, + 232, + 0, + 38, + 101, + 114, + 107, + 87, + 88, + 145, + 0, + 0, + 0, + 145, + 232, + 0, + 38, + 97, + 98, + 99, + 100, + 111, + 232, + 232, + 212, + 232, + 232, + 232, + 0, + 38, + 93, + 94, + 95, + 96, + 110, + 177, + 173, + 182, + 160, + 174, + 41, + 0, + 38, + 79, + 80, + 90, + 91, + 92, + 41, + 41, + 212, + 41, + 41, + 41, + 0, + 38, + 0, + 0, + 0, + 0, + 0, + 134, + 153, + 138, + 142, + 199, + 40, + 0, + 36, + 36, + 36, + 226, + 36, + 36, + 127, + 131, + 143, + 141, + 150, + 40, + 0, + 36, + 71, + 72, + 73, + 74, + 75, + 40, + 40, + 212, + 40, + 40, + 40, + 0, + 36, + 65, + 66, + 67, + 68, + 70, + 0, + 0, + 189, + 0, + 0, + 0, + 89, + 36, + 36, + 36, + 208, + 36, + 36, + 39, + 39, + 220, + 39, + 39, + 39, + 0, + 0, + 0, + 0, + 0, + 52, + 211, + 5, + 42, + 43, + 44, + 45, + 39, + 39, + 37, + 37, + 209, + 37, + 37, + 37, + 6, + 54, + 55, + 56, + 57, + 58, + 59, + 37, + 48, + 49, + 50, + 51, + 53 + ] + }, + "layerAlias": {}, + "events": {} +} diff --git a/src/content/maps/sample1.jsonc b/src/content/maps/sample1.jsonc new file mode 100644 index 0000000..d24743e --- /dev/null +++ b/src/content/maps/sample1.jsonc @@ -0,0 +1,181 @@ +// Type: packages-user/data-common/src/store/types IMapRawData +// --- SYSTEM PREFIX END --- // +{ + "floorId": "sample1", + "width": 13, + "map": { + "0": [ + 1, + 218, + 2, + 234, + 3, + 217, + 4, + 234, + 12, + 11, + 219, + 11, + 12, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 234, + 11, + 10, + 0, + 8, + 11, + 234, + 234, + 234, + 234, + 208, + 234, + 234, + 234, + 0, + 0, + 155, + 0, + 0, + 87, + 77, + 88, + 233, + 0, + 0, + 0, + 234, + 11, + 7, + 0, + 9, + 11, + 65, + 66, + 65, + 233, + 0, + 0, + 0, + 234, + 12, + 11, + 0, + 11, + 12, + 233, + 0, + 233, + 233, + 0, + 5, + 0, + 234, + 234, + 234, + 52, + 235, + 235, + 0, + 0, + 0, + 233, + 0, + 0, + 0, + 234, + 234, + 147, + 0, + 147, + 235, + 0, + 0, + 0, + 233, + 0, + 0, + 0, + 208, + 0, + 0, + 0, + 0, + 235, + 233, + 0, + 233, + 233, + 48, + 235, + 235, + 235, + 235, + 235, + 235, + 235, + 235, + 0, + 0, + 0, + 208, + 0, + 0, + 0, + 10, + 0, + 0, + 9, + 0, + 0, + 36, + 36, + 36, + 36, + 0, + 232, + 0, + 0, + 0, + 8, + 0, + 7, + 0, + 36, + 0, + 210, + 36, + 0, + 232, + 211, + 0, + 208, + 0, + 209, + 0, + 213, + 36, + 0, + 0, + 36, + 6, + 232, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + "layerAlias": {}, + "events": {} +} diff --git a/src/content/maps/sample2.jsonc b/src/content/maps/sample2.jsonc new file mode 100644 index 0000000..b01d3ce --- /dev/null +++ b/src/content/maps/sample2.jsonc @@ -0,0 +1,688 @@ +// Type: packages-user/data-common/src/store/types IMapRawData +// --- SYSTEM PREFIX END --- // +{ + "floorId": "sample2", + "width": 26, + "map": { + "0": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 36, + 36, + 36, + 36, + 36, + 0, + 0, + 36, + 36, + 36, + 36, + 36, + 0, + 0, + 0, + 36, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 36, + 71, + 72, + 73, + 36, + 0, + 128, + 36, + 71, + 72, + 73, + 36, + 0, + 0, + 0, + 36, + 0, + 0, + 0, + 128, + 0, + 0, + 0, + 0, + 0, + 0, + 36, + 75, + 76, + 77, + 36, + 0, + 0, + 36, + 75, + 76, + 77, + 36, + 0, + 0, + 0, + 36, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 36, + 65, + 184, + 66, + 36, + 0, + 0, + 36, + 65, + 183, + 66, + 36, + 0, + 0, + 0, + 36, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 36, + 36, + 49, + 36, + 36, + 0, + 0, + 36, + 36, + 48, + 36, + 36, + 0, + 0, + 0, + 36, + 0, + 0, + 36, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 66, + 0, + 0, + 0, + 0, + 0, + 0, + 65, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 36, + 0, + 0, + 36, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 89, + 0, + 36, + 0, + 128, + 128, + 0, + 0, + 0, + 0, + 0, + 36, + 36, + 0, + 0, + 36, + 0, + 128, + 128, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 36, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 36, + 36, + 0, + 0, + 0, + 36, + 0, + 0, + 0, + 0, + 0, + 204, + 0, + 0, + 0, + 0, + 6, + 0, + 36, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 36, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 128, + 0, + 0, + 0, + 0, + 205, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 128, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 5, + 0, + 0, + 0, + 0, + 209, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 206, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 207, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 36, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 36, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 36, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 36, + 0, + 0, + 0, + 128, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 36, + 0, + 0, + 128, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 36, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 36, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 36, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 36, + 0, + 0, + 36, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 36, + 0, + 0, + 36, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 36, + 0, + 0, + 36, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 36, + 0, + 0, + 36, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 36, + 36, + 0, + 0, + 36, + 0, + 128, + 128, + 0, + 0, + 0, + 0, + 0, + 36, + 36, + 0, + 0, + 36, + 0, + 128, + 128, + 0, + 0, + 0, + 0, + 36, + 36, + 0, + 0, + 0, + 36, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 36, + 36, + 0, + 0, + 0, + 36, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 36, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 36, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 128, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 128, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + "layerAlias": {}, + "events": {} +} diff --git a/src/content/texture/.list.jsonc b/src/content/texture/.list.jsonc index 301e5e7..bed9c91 100644 --- a/src/content/texture/.list.jsonc +++ b/src/content/texture/.list.jsonc @@ -1,3 +1,615 @@ // Type: type define required // --- SYSTEM PREFIX END --- // -{} +{ + "textures": [ + { + "type": "grid", + "source": "terrains0.png", + "map": [ + 17, + 22, + 25, + 28, + 30, + 6, + 5, + 1, + 3, + 2, + 4, + 7, + 8, + 9, + 10, + 11 + ], + "width": 32, + "height": 32 + }, + { + "type": "grid", + "source": "terrains1.png", + "map": [ + 12, + 13, + 14, + 15, + 16, + 18, + 19, + 20, + 21, + 23, + 24, + 26, + 27, + 29, + 31, + 32 + ], + "width": 32, + "height": 32 + }, + { + "type": "grid", + "source": "terrains2.png", + "map": [ + 33, + 34, + 35 + ], + "width": 32, + "height": 32 + }, + { + "type": "rowAnimate", + "source": "terrainsAnim0.png", + "map": [ + 39, + 40, + 46, + 47 + ], + "width": 32, + "height": 32 + }, + { + "type": "rowAnimate", + "source": "terrainsAnim1.png", + "map": [ + 48, + 49, + 50, + 51 + ], + "width": 32, + "height": 32 + }, + { + "type": "rowAnimate", + "source": "terrainsAnim2.png", + "map": [ + 52, + 53, + 36, + 37 + ], + "width": 32, + "height": 32 + }, + { + "type": "rowAnimate", + "source": "terrainsAnim3.png", + "map": [ + 38, + 60, + 61, + 55 + ], + "width": 32, + "height": 32 + }, + { + "type": "rowAnimate", + "source": "terrainsAnim4.png", + "map": [ + 62, + 54, + 63, + 42 + ], + "width": 32, + "height": 32 + }, + { + "type": "rowAnimate", + "source": "terrainsAnim5.png", + "map": [ + 43, + 44, + 45, + 58 + ], + "width": 32, + "height": 32 + }, + { + "type": "rowAnimate", + "source": "terrainsAnim6.png", + "map": [ + 57, + 59, + 56, + 41 + ], + "width": 32, + "height": 32 + }, + { + "type": "rowAnimate", + "source": "terrainsAnim7.png", + "map": [ + 64 + ], + "width": 32, + "height": 32 + }, + { + "type": "grid", + "source": "items0.png", + "map": [ + 65, + 66, + 67, + 68, + 69, + 116, + 70, + 117, + 101, + 89, + 115, + 97, + 90, + 94, + 96, + 95 + ], + "width": 32, + "height": 32 + }, + { + "type": "grid", + "source": "items1.png", + "map": [ + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 102, + 103, + 118, + 104, + 105, + 100, + 114, + 119 + ], + "width": 32, + "height": 32 + }, + { + "type": "grid", + "source": "items2.png", + "map": [ + 120, + 110, + 121, + 122, + 123, + 124, + 125, + 126, + 99, + 98, + 106, + 93, + 92, + 91, + 107, + 108 + ], + "width": 32, + "height": 32 + }, + { + "type": "grid", + "source": "items3.png", + "map": [ + 109, + 111, + 79, + 81, + 83, + 85, + 87, + 80, + 82, + 84, + 86, + 88, + 112, + 113 + ], + "width": 32, + "height": 32 + }, + { + "type": "rowAnimate", + "source": "enemy0.png", + "map": [ + 127, + 128, + 129, + 130 + ], + "width": 32, + "height": 32 + }, + { + "type": "rowAnimate", + "source": "enemy1.png", + "map": [ + 131, + 132, + 133, + 134 + ], + "width": 32, + "height": 32 + }, + { + "type": "rowAnimate", + "source": "enemy2.png", + "map": [ + 135, + 136, + 137, + 138 + ], + "width": 32, + "height": 32 + }, + { + "type": "rowAnimate", + "source": "enemy3.png", + "map": [ + 139, + 140, + 141, + 142 + ], + "width": 32, + "height": 32 + }, + { + "type": "rowAnimate", + "source": "enemy4.png", + "map": [ + 143, + 144, + 145, + 146 + ], + "width": 32, + "height": 32 + }, + { + "type": "rowAnimate", + "source": "enemy5.png", + "map": [ + 147, + 148, + 149, + 150 + ], + "width": 32, + "height": 32 + }, + { + "type": "rowAnimate", + "source": "enemy6.png", + "map": [ + 151, + 152, + 153, + 154 + ], + "width": 32, + "height": 32 + }, + { + "type": "rowAnimate", + "source": "enemy7.png", + "map": [ + 155, + 156, + 157, + 158 + ], + "width": 32, + "height": 32 + }, + { + "type": "rowAnimate", + "source": "enemy8.png", + "map": [ + 159, + 160, + 161, + 162 + ], + "width": 32, + "height": 32 + }, + { + "type": "rowAnimate", + "source": "enemy9.png", + "map": [ + 163, + 164, + 165, + 166 + ], + "width": 32, + "height": 32 + }, + { + "type": "rowAnimate", + "source": "enemy10.png", + "map": [ + 167, + 168, + 169, + 170 + ], + "width": 32, + "height": 32 + }, + { + "type": "rowAnimate", + "source": "enemy11.png", + "map": [ + 171, + 172, + 173, + 174 + ], + "width": 32, + "height": 32 + }, + { + "type": "rowAnimate", + "source": "enemy12.png", + "map": [ + 175, + 176, + 177, + 178 + ], + "width": 32, + "height": 32 + }, + { + "type": "rowAnimate", + "source": "enemy13.png", + "map": [ + 179, + 180, + 181, + 182 + ], + "width": 32, + "height": 32 + }, + { + "type": "rowAnimate", + "source": "enemy14.png", + "map": [ + 183, + 184, + 185, + 186 + ], + "width": 32, + "height": 32 + }, + { + "type": "rowAnimate", + "source": "enemy15.png", + "map": [ + 191, + 192, + 193, + 194 + ], + "width": 32, + "height": 32 + }, + { + "type": "rowAnimate", + "source": "enemy16.png", + "map": [ + 195, + 196, + 197, + 198 + ], + "width": 32, + "height": 32 + }, + { + "type": "rowAnimate", + "source": "enemy17.png", + "map": [ + 199, + 200, + 201, + 202 + ], + "width": 32, + "height": 32 + }, + { + "type": "rowAnimate", + "source": "enemy18.png", + "map": [ + 203 + ], + "width": 32, + "height": 32 + }, + { + "type": "rowAnimate", + "source": "enemy19.png", + "map": [ + 187, + 188, + 189, + 190 + ], + "width": 32, + "height": 48 + }, + { + "type": "rowAnimate", + "source": "enemy20.png", + "map": [ + 204, + 205, + 206, + 207 + ], + "width": 32, + "height": 48 + }, + { + "type": "rowAnimate", + "source": "npc0.png", + "map": [ + 208, + 209, + 210, + 211 + ], + "width": 32, + "height": 32 + }, + { + "type": "rowAnimate", + "source": "npc1.png", + "map": [ + 212, + 213, + 214, + 215 + ], + "width": 32, + "height": 32 + }, + { + "type": "rowAnimate", + "source": "npc2.png", + "map": [ + 216, + 217, + 218, + 219 + ], + "width": 32, + "height": 32 + }, + { + "type": "rowAnimate", + "source": "npc3.png", + "map": [ + 224, + 225 + ], + "width": 32, + "height": 32 + }, + { + "type": "rowAnimate", + "source": "npc4.png", + "map": [ + 220, + 221, + 222, + 223 + ], + "width": 32, + "height": 48 + }, + { + "type": "rowAnimate", + "source": "npc5.png", + "map": [ + 226, + 227, + 228, + 229 + ], + "width": 32, + "height": 48 + }, + { + "type": "rowAnimate", + "source": "npc6.png", + "map": [ + 230, + 231 + ], + "width": 32, + "height": 48 + }, + { + "type": "autotile", + "source": "autotile.png", + "identifier": 232, + "autotileType": 1 + }, + { + "type": "autotile", + "source": "autotile1.png", + "identifier": 233, + "autotileType": 1 + }, + { + "type": "autotile", + "source": "autotile2.png", + "identifier": 234, + "autotileType": 1 + }, + { + "type": "autotile", + "source": "autotile3.png", + "identifier": 235, + "autotileType": 1 + }, + { + "type": "tileset", + "source": "magictower.png", + "identifier": { + "index": 0, + "alias": "magictower" + }, + "cellWidth": 32, + "cellHeight": 32 + } + ] +} diff --git a/src/content/texture/autotile.png b/src/content/texture/autotile.png new file mode 100644 index 0000000..18e92ec Binary files /dev/null and b/src/content/texture/autotile.png differ diff --git a/src/content/texture/autotile1.png b/src/content/texture/autotile1.png new file mode 100644 index 0000000..37a0b27 Binary files /dev/null and b/src/content/texture/autotile1.png differ diff --git a/src/content/texture/autotile2.png b/src/content/texture/autotile2.png new file mode 100644 index 0000000..496bdc9 Binary files /dev/null and b/src/content/texture/autotile2.png differ diff --git a/src/content/texture/autotile3.png b/src/content/texture/autotile3.png new file mode 100644 index 0000000..c7a9179 Binary files /dev/null and b/src/content/texture/autotile3.png differ diff --git a/src/content/texture/enemy0.png b/src/content/texture/enemy0.png new file mode 100644 index 0000000..7d4f9a4 Binary files /dev/null and b/src/content/texture/enemy0.png differ diff --git a/src/content/texture/enemy1.png b/src/content/texture/enemy1.png new file mode 100644 index 0000000..31dfcff Binary files /dev/null and b/src/content/texture/enemy1.png differ diff --git a/src/content/texture/enemy10.png b/src/content/texture/enemy10.png new file mode 100644 index 0000000..11376bf Binary files /dev/null and b/src/content/texture/enemy10.png differ diff --git a/src/content/texture/enemy11.png b/src/content/texture/enemy11.png new file mode 100644 index 0000000..4dbaf50 Binary files /dev/null and b/src/content/texture/enemy11.png differ diff --git a/src/content/texture/enemy12.png b/src/content/texture/enemy12.png new file mode 100644 index 0000000..74b11aa Binary files /dev/null and b/src/content/texture/enemy12.png differ diff --git a/src/content/texture/enemy13.png b/src/content/texture/enemy13.png new file mode 100644 index 0000000..71b765c Binary files /dev/null and b/src/content/texture/enemy13.png differ diff --git a/src/content/texture/enemy14.png b/src/content/texture/enemy14.png new file mode 100644 index 0000000..feaa27c Binary files /dev/null and b/src/content/texture/enemy14.png differ diff --git a/src/content/texture/enemy15.png b/src/content/texture/enemy15.png new file mode 100644 index 0000000..9b9c6ac Binary files /dev/null and b/src/content/texture/enemy15.png differ diff --git a/src/content/texture/enemy16.png b/src/content/texture/enemy16.png new file mode 100644 index 0000000..a9bcd09 Binary files /dev/null and b/src/content/texture/enemy16.png differ diff --git a/src/content/texture/enemy17.png b/src/content/texture/enemy17.png new file mode 100644 index 0000000..3952775 Binary files /dev/null and b/src/content/texture/enemy17.png differ diff --git a/src/content/texture/enemy18.png b/src/content/texture/enemy18.png new file mode 100644 index 0000000..6d3b2a8 Binary files /dev/null and b/src/content/texture/enemy18.png differ diff --git a/src/content/texture/enemy19.png b/src/content/texture/enemy19.png new file mode 100644 index 0000000..aa0c795 Binary files /dev/null and b/src/content/texture/enemy19.png differ diff --git a/src/content/texture/enemy2.png b/src/content/texture/enemy2.png new file mode 100644 index 0000000..570defc Binary files /dev/null and b/src/content/texture/enemy2.png differ diff --git a/src/content/texture/enemy20.png b/src/content/texture/enemy20.png new file mode 100644 index 0000000..575ec29 Binary files /dev/null and b/src/content/texture/enemy20.png differ diff --git a/src/content/texture/enemy3.png b/src/content/texture/enemy3.png new file mode 100644 index 0000000..f90b7d9 Binary files /dev/null and b/src/content/texture/enemy3.png differ diff --git a/src/content/texture/enemy4.png b/src/content/texture/enemy4.png new file mode 100644 index 0000000..57a509f Binary files /dev/null and b/src/content/texture/enemy4.png differ diff --git a/src/content/texture/enemy5.png b/src/content/texture/enemy5.png new file mode 100644 index 0000000..5c2c58f Binary files /dev/null and b/src/content/texture/enemy5.png differ diff --git a/src/content/texture/enemy6.png b/src/content/texture/enemy6.png new file mode 100644 index 0000000..55cb1c8 Binary files /dev/null and b/src/content/texture/enemy6.png differ diff --git a/src/content/texture/enemy7.png b/src/content/texture/enemy7.png new file mode 100644 index 0000000..7e4a986 Binary files /dev/null and b/src/content/texture/enemy7.png differ diff --git a/src/content/texture/enemy8.png b/src/content/texture/enemy8.png new file mode 100644 index 0000000..8f518e6 Binary files /dev/null and b/src/content/texture/enemy8.png differ diff --git a/src/content/texture/enemy9.png b/src/content/texture/enemy9.png new file mode 100644 index 0000000..31f6f90 Binary files /dev/null and b/src/content/texture/enemy9.png differ diff --git a/src/content/texture/items0.png b/src/content/texture/items0.png new file mode 100644 index 0000000..2867e4b Binary files /dev/null and b/src/content/texture/items0.png differ diff --git a/src/content/texture/items1.png b/src/content/texture/items1.png new file mode 100644 index 0000000..a4bba7c Binary files /dev/null and b/src/content/texture/items1.png differ diff --git a/src/content/texture/items2.png b/src/content/texture/items2.png new file mode 100644 index 0000000..1add549 Binary files /dev/null and b/src/content/texture/items2.png differ diff --git a/src/content/texture/items3.png b/src/content/texture/items3.png new file mode 100644 index 0000000..eeeb167 Binary files /dev/null and b/src/content/texture/items3.png differ diff --git a/src/content/texture/magictower.png b/src/content/texture/magictower.png new file mode 100644 index 0000000..81ed106 Binary files /dev/null and b/src/content/texture/magictower.png differ diff --git a/src/content/texture/npc0.png b/src/content/texture/npc0.png new file mode 100644 index 0000000..b77af47 Binary files /dev/null and b/src/content/texture/npc0.png differ diff --git a/src/content/texture/npc1.png b/src/content/texture/npc1.png new file mode 100644 index 0000000..1b800dc Binary files /dev/null and b/src/content/texture/npc1.png differ diff --git a/src/content/texture/npc2.png b/src/content/texture/npc2.png new file mode 100644 index 0000000..8adec37 Binary files /dev/null and b/src/content/texture/npc2.png differ diff --git a/src/content/texture/npc3.png b/src/content/texture/npc3.png new file mode 100644 index 0000000..fc3eb44 Binary files /dev/null and b/src/content/texture/npc3.png differ diff --git a/src/content/texture/npc4.png b/src/content/texture/npc4.png new file mode 100644 index 0000000..52ecdc3 Binary files /dev/null and b/src/content/texture/npc4.png differ diff --git a/src/content/texture/npc5.png b/src/content/texture/npc5.png new file mode 100644 index 0000000..2521425 Binary files /dev/null and b/src/content/texture/npc5.png differ diff --git a/src/content/texture/npc6.png b/src/content/texture/npc6.png new file mode 100644 index 0000000..d29bbe3 Binary files /dev/null and b/src/content/texture/npc6.png differ diff --git a/src/content/texture/terrains0.png b/src/content/texture/terrains0.png new file mode 100644 index 0000000..176d217 Binary files /dev/null and b/src/content/texture/terrains0.png differ diff --git a/src/content/texture/terrains1.png b/src/content/texture/terrains1.png new file mode 100644 index 0000000..4238da9 Binary files /dev/null and b/src/content/texture/terrains1.png differ diff --git a/src/content/texture/terrains2.png b/src/content/texture/terrains2.png new file mode 100644 index 0000000..47d7bd2 Binary files /dev/null and b/src/content/texture/terrains2.png differ diff --git a/src/content/texture/terrainsAnim0.png b/src/content/texture/terrainsAnim0.png new file mode 100644 index 0000000..3b84b54 Binary files /dev/null and b/src/content/texture/terrainsAnim0.png differ diff --git a/src/content/texture/terrainsAnim1.png b/src/content/texture/terrainsAnim1.png new file mode 100644 index 0000000..8ae4dc9 Binary files /dev/null and b/src/content/texture/terrainsAnim1.png differ diff --git a/src/content/texture/terrainsAnim2.png b/src/content/texture/terrainsAnim2.png new file mode 100644 index 0000000..ce8e713 Binary files /dev/null and b/src/content/texture/terrainsAnim2.png differ diff --git a/src/content/texture/terrainsAnim3.png b/src/content/texture/terrainsAnim3.png new file mode 100644 index 0000000..691c493 Binary files /dev/null and b/src/content/texture/terrainsAnim3.png differ diff --git a/src/content/texture/terrainsAnim4.png b/src/content/texture/terrainsAnim4.png new file mode 100644 index 0000000..b8394ad Binary files /dev/null and b/src/content/texture/terrainsAnim4.png differ diff --git a/src/content/texture/terrainsAnim5.png b/src/content/texture/terrainsAnim5.png new file mode 100644 index 0000000..c7dfe20 Binary files /dev/null and b/src/content/texture/terrainsAnim5.png differ diff --git a/src/content/texture/terrainsAnim6.png b/src/content/texture/terrainsAnim6.png new file mode 100644 index 0000000..703aa96 Binary files /dev/null and b/src/content/texture/terrainsAnim6.png differ diff --git a/src/content/texture/terrainsAnim7.png b/src/content/texture/terrainsAnim7.png new file mode 100644 index 0000000..5da1f44 Binary files /dev/null and b/src/content/texture/terrainsAnim7.png differ diff --git a/src/content/tile.jsonc b/src/content/tile.jsonc index 2485a3c..b6aa96f 100644 --- a/src/content/tile.jsonc +++ b/src/content/tile.jsonc @@ -3,10 +3,2822 @@ [ { "num": 1, - "id": "yellowWall", + "id": "blueShopLeft", "events": {}, "type": 2, "eventPass": false, - "pass": { "onlyEvents": true, "inPass": 0, "outPass": 0 } + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 2, + "id": "blueShopRight", + "events": {}, + "type": 2, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 3, + "id": "pinkShopLeft", + "events": {}, + "type": 2, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 4, + "id": "pinkShopRight", + "events": {}, + "type": 2, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 5, + "id": "upFloor", + "events": {}, + "type": 2, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 6, + "id": "downFloor", + "events": {}, + "type": 2, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 7, + "id": "arrowUp", + "events": {}, + "type": 2, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 1, + "inPass": 14 + } + }, + { + "num": 8, + "id": "arrowDown", + "events": {}, + "type": 2, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 4, + "inPass": 11 + } + }, + { + "num": 9, + "id": "arrowLeft", + "events": {}, + "type": 2, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 8, + "inPass": 7 + } + }, + { + "num": 10, + "id": "arrowRight", + "events": {}, + "type": 2, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 2, + "inPass": 13 + } + }, + { + "num": 11, + "id": "light", + "events": {}, + "type": 2, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 12, + "id": "darkLight", + "events": {}, + "type": 2, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 13, + "id": "ski", + "events": {}, + "type": 2, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 14, + "id": "flower", + "events": {}, + "type": 2, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 15, + "id": "box", + "events": {}, + "type": 2, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 16, + "id": "boxed", + "events": {}, + "type": 2, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 17, + "id": "ground", + "events": {}, + "type": 2, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 18, + "id": "sWallT", + "events": {}, + "type": 2, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 14, + "inPass": 14 + } + }, + { + "num": 19, + "id": "sWallL", + "events": {}, + "type": 2, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 7, + "inPass": 7 + } + }, + { + "num": 20, + "id": "sWallR", + "events": {}, + "type": 2, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 13, + "inPass": 13 + } + }, + { + "num": 21, + "id": "sWallB", + "events": {}, + "type": 2, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 11, + "inPass": 11 + } + }, + { + "num": 22, + "id": "grass", + "events": {}, + "type": 2, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 23, + "id": "sWallTL", + "events": {}, + "type": 2, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 6, + "inPass": 6 + } + }, + { + "num": 24, + "id": "sWallBR", + "events": {}, + "type": 2, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 9, + "inPass": 9 + } + }, + { + "num": 25, + "id": "grass2", + "events": {}, + "type": 2, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 26, + "id": "sWallTR", + "events": {}, + "type": 2, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 12, + "inPass": 12 + } + }, + { + "num": 27, + "id": "sWallBL", + "events": {}, + "type": 2, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 3, + "inPass": 3 + } + }, + { + "num": 28, + "id": "ground2", + "events": {}, + "type": 2, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 29, + "id": "sWallTB", + "events": {}, + "type": 2, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 10, + "inPass": 10 + } + }, + { + "num": 30, + "id": "ground3", + "events": {}, + "type": 2, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 31, + "id": "sWallLR", + "events": {}, + "type": 2, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 5, + "inPass": 5 + } + }, + { + "num": 32, + "id": "sWallBLR", + "events": {}, + "type": 2, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 1, + "inPass": 1 + } + }, + { + "num": 33, + "id": "sWallTLR", + "events": {}, + "type": 2, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 4, + "inPass": 4 + } + }, + { + "num": 34, + "id": "sWallTBR", + "events": {}, + "type": 2, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 8, + "inPass": 8 + } + }, + { + "num": 35, + "id": "sWallTBL", + "events": {}, + "type": 2, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 2, + "inPass": 2 + } + }, + { + "num": 36, + "id": "yellowWall", + "events": {}, + "type": 3, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 37, + "id": "whiteWall", + "events": {}, + "type": 3, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 38, + "id": "blueWall", + "events": {}, + "type": 3, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 39, + "id": "star", + "events": {}, + "type": 3, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 40, + "id": "lava", + "events": {}, + "type": 3, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 41, + "id": "ice", + "events": {}, + "type": 3, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 42, + "id": "lavaNet", + "events": {}, + "type": 3, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 43, + "id": "poisonNet", + "events": {}, + "type": 3, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 44, + "id": "weakNet", + "events": {}, + "type": 3, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 45, + "id": "curseNet", + "events": {}, + "type": 3, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 46, + "id": "blueLava", + "events": {}, + "type": 3, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 47, + "id": "water", + "events": {}, + "type": 3, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 48, + "id": "yellowDoor", + "events": {}, + "type": 3, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 49, + "id": "blueDoor", + "events": {}, + "type": 3, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 50, + "id": "redDoor", + "events": {}, + "type": 3, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 51, + "id": "greenDoor", + "events": {}, + "type": 3, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 52, + "id": "specialDoor", + "events": {}, + "type": 3, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 53, + "id": "steelDoor", + "events": {}, + "type": 3, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 54, + "id": "portal", + "events": {}, + "type": 3, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 55, + "id": "starPortal", + "events": {}, + "type": 3, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 56, + "id": "upPortal", + "events": {}, + "type": 3, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 57, + "id": "leftPortal", + "events": {}, + "type": 3, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 58, + "id": "downPortal", + "events": {}, + "type": 3, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 59, + "id": "rightPortal", + "events": {}, + "type": 3, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 60, + "id": "crystalUp", + "events": {}, + "type": 3, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 61, + "id": "crystalBottom", + "events": {}, + "type": 3, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 62, + "id": "fire", + "events": {}, + "type": 3, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 63, + "id": "switch", + "events": {}, + "type": 3, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 64, + "id": "magentaWall", + "events": {}, + "type": 3, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 65, + "id": "yellowKey", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 66, + "id": "blueKey", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 67, + "id": "redKey", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 68, + "id": "greenKey", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 69, + "id": "steelKey", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 70, + "id": "bigKey", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 71, + "id": "redGem", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 72, + "id": "blueGem", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 73, + "id": "greenGem", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 74, + "id": "yellowGem", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 75, + "id": "redPotion", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 76, + "id": "bluePotion", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 77, + "id": "greenPotion", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 78, + "id": "yellowPotion", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 79, + "id": "sword1", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 80, + "id": "shield1", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 81, + "id": "sword2", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 82, + "id": "shield2", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 83, + "id": "sword3", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 84, + "id": "shield3", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 85, + "id": "sword4", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 86, + "id": "shield4", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 87, + "id": "sword5", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 88, + "id": "shield5", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 89, + "id": "book", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 90, + "id": "fly", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 91, + "id": "pickaxe", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 92, + "id": "icePickaxe", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 93, + "id": "bomb", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 94, + "id": "centerFly", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 95, + "id": "upFly", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 96, + "id": "downFly", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 97, + "id": "coin", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 98, + "id": "freezeBadge", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 99, + "id": "cross", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 100, + "id": "superPotion", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 101, + "id": "earthquake", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 102, + "id": "poisonWine", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 103, + "id": "weakWine", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 104, + "id": "curseWine", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 105, + "id": "superWine", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 106, + "id": "dagger", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 107, + "id": "pack", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 108, + "id": "amulet", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 109, + "id": "hammer", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 110, + "id": "lifeWand", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 111, + "id": "jumpShoes", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 112, + "id": "sword0", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 113, + "id": "shield0", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 114, + "id": "skill1", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 115, + "id": "wand", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 116, + "id": "I331", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 117, + "id": "I332", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 118, + "id": "I333", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 119, + "id": "I334", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 120, + "id": "I335", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 121, + "id": "I336", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 122, + "id": "I337", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 123, + "id": "I338", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 124, + "id": "I339", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 125, + "id": "I340", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 126, + "id": "I341", + "events": {}, + "type": 4, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 127, + "id": "greenSlime", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 128, + "id": "redSlime", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 129, + "id": "blackSlime", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 130, + "id": "slimelord", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 131, + "id": "bat", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 132, + "id": "bigBat", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 133, + "id": "redBat", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 134, + "id": "vampire", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 135, + "id": "skeleton", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 136, + "id": "skeletonWarrior", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 137, + "id": "skeletonCaptain", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 138, + "id": "ghostSoldier", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 139, + "id": "zombie", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 140, + "id": "zombieKnight", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 141, + "id": "rock", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 142, + "id": "slimeman", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 143, + "id": "bluePriest", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 144, + "id": "redPriest", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 145, + "id": "brownWizard", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 146, + "id": "redWizard", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 147, + "id": "yellowGateKeeper", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 148, + "id": "blueGateKeeper", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 149, + "id": "redGateKeeper", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 150, + "id": "swordsman", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 151, + "id": "soldier", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 152, + "id": "yellowKnight", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 153, + "id": "redKnight", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 154, + "id": "darkKnight", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 155, + "id": "blackKing", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 156, + "id": "yellowKing", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 157, + "id": "greenKing", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 158, + "id": "blueKnight", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 159, + "id": "goldSlime", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 160, + "id": "poisonSkeleton", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 161, + "id": "poisonBat", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 162, + "id": "ironRock", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 163, + "id": "skeletonPriest", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 164, + "id": "skeletonKing", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 165, + "id": "skeletonPresbyter", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 166, + "id": "skeletonKnight", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 167, + "id": "evilHero", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 168, + "id": "devilWarrior", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 169, + "id": "demonPriest", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 170, + "id": "goldHornSlime", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 171, + "id": "redKing", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 172, + "id": "blueKing", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 173, + "id": "magicMaster", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 174, + "id": "silverSlime", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 175, + "id": "blademaster", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 176, + "id": "whiteHornSlime", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 177, + "id": "evilPrincess", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 178, + "id": "evilFairy", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 179, + "id": "yellowPriest", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 180, + "id": "redSwordsman", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 181, + "id": "whiteSlimeman", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 182, + "id": "poisonZombie", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 183, + "id": "dragon", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 184, + "id": "octopus", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 185, + "id": "fairyEnemy", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 186, + "id": "princessEnemy", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 187, + "id": "angel", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 188, + "id": "elemental", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 189, + "id": "steelGuard", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 190, + "id": "evilBat", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 191, + "id": "silverSlimelord", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 192, + "id": "goldSlimelord", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 193, + "id": "grayRock", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 194, + "id": "greenKnight", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 195, + "id": "bowman", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 196, + "id": "purpleBowman", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 197, + "id": "watcherSlime", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 198, + "id": "frostBat", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 199, + "id": "devilKnight", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 200, + "id": "grayPriest", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 201, + "id": "greenGateKeeper", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 202, + "id": "keiskeiFairy", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 203, + "id": "tulipFairy", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 204, + "id": "bearDown", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 205, + "id": "bearLeft", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 206, + "id": "bearRight", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 207, + "id": "bearUp", + "events": {}, + "type": 5, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 208, + "id": "man", + "events": {}, + "type": 6, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 209, + "id": "trader", + "events": {}, + "type": 6, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 210, + "id": "thief", + "events": {}, + "type": 6, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 211, + "id": "fairy", + "events": {}, + "type": 6, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 212, + "id": "wizard", + "events": {}, + "type": 6, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 213, + "id": "recluse", + "events": {}, + "type": 6, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 214, + "id": "king", + "events": {}, + "type": 6, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 215, + "id": "youngMan", + "events": {}, + "type": 6, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 216, + "id": "sign", + "events": {}, + "type": 6, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 217, + "id": "expShop", + "events": {}, + "type": 6, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 218, + "id": "moneyShop", + "events": {}, + "type": 6, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 219, + "id": "princess", + "events": {}, + "type": 6, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 220, + "id": "npc0", + "events": {}, + "type": 6, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 221, + "id": "npc1", + "events": {}, + "type": 6, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 222, + "id": "npc2", + "events": {}, + "type": 6, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 223, + "id": "npc3", + "events": {}, + "type": 6, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 224, + "id": "greenMan", + "events": {}, + "type": 6, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 225, + "id": "blueTrader", + "events": {}, + "type": 6, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 226, + "id": "tallYellowDoor", + "events": {}, + "type": 6, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 227, + "id": "tallBlueDoor", + "events": {}, + "type": 6, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 228, + "id": "tallRedDoor", + "events": {}, + "type": 6, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 229, + "id": "tallGreenDoor", + "events": {}, + "type": 6, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 230, + "id": "tallSpecialDoor", + "events": {}, + "type": 6, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 231, + "id": "tallSteelDoor", + "events": {}, + "type": 6, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 232, + "id": "autotile", + "events": {}, + "type": 7, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 233, + "id": "autotile1", + "events": {}, + "type": 7, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 234, + "id": "autotile2", + "events": {}, + "type": 7, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } + }, + { + "num": 235, + "id": "autotile3", + "events": {}, + "type": 7, + "eventPass": false, + "pass": { + "onlyEvents": true, + "outPass": 15, + "inPass": 15 + } } ]