diff --git a/src/core/index.ts b/src/core/index.ts index e9f29f9..075f320 100644 --- a/src/core/index.ts +++ b/src/core/index.ts @@ -71,6 +71,7 @@ import { texture } from './render/cache'; import { RenderAdapter } from './render/adapter'; import { getMainRenderer } from './render'; import { Layer } from './render/preset/layer'; +import { LayerGroupFloorBinder } from './render/preset/floor'; // ----- 类注册 Mota.register('class', 'AudioPlayer', AudioPlayer); @@ -158,7 +159,8 @@ Mota.register('module', 'Render', { Image, RenderItem, RenderAdapter, - Layer + Layer, + LayerGroupFloorBinder }); main.renderLoaded = true; diff --git a/src/core/render/preset/floor.ts b/src/core/render/preset/floor.ts index 70eb2dd..d019b3e 100644 --- a/src/core/render/preset/floor.ts +++ b/src/core/render/preset/floor.ts @@ -131,8 +131,9 @@ export class LayerGroupFloorBinder this.emit('setBlock', x, y, floor, block); } - private checkLayerExtends(layer: Layer) { + checkLayerExtends(layer: Layer) { const ex = layer.getExtends('floor-binder'); + if (!ex) { const extend = new LayerFloorBinder(this); layer.extends(extend); @@ -147,15 +148,16 @@ export class LayerGroupFloorBinder awake(group: LayerGroup) { this.group = group; + for (const layer of group.layers.values()) { this.checkLayerExtends(layer); } LayerGroupFloorBinder.activedBinder.add(this); } - // onLayerAdd(group: LayerGroup, layer: Layer): void { - // this.checkLayerExtends(layer); - // } + onLayerAdd(group: LayerGroup, layer: Layer): void { + this.checkLayerExtends(layer); + } onDestroy(group: LayerGroup) { LayerGroupFloorBinder.activedBinder.delete(this); @@ -272,6 +274,7 @@ export class LayerFloorBinder implements ILayerRenderExtends { if (group instanceof LayerGroup) { const ex = group.getExtends('floor-binder'); if (ex instanceof LayerGroupFloorBinder) { + ex.checkLayerExtends(layer); this.parent = ex; } } diff --git a/src/core/render/preset/layer.ts b/src/core/render/preset/layer.ts index 8379d2c..2cab014 100644 --- a/src/core/render/preset/layer.ts +++ b/src/core/render/preset/layer.ts @@ -211,7 +211,7 @@ export class LayerGroup extends Container implements IAnimateFrame { addLayer(layer: FloorLayer) { const l = new Layer(); l.layer = layer; - if (l.layer) this.layers.set(l.layer, l); + this.layers.set(layer, l); l.setZIndex(layerZIndex[layer]); this.appendChild(l); @@ -1069,6 +1069,7 @@ export class Layer extends Container { this.renderData = Array(width * height).fill(0); this.autotiles = {}; this.block.size(width, height); + this.block.clearAllCache(); for (const ex of this.extend.values()) { ex.onMapResize?.(this, width, height); diff --git a/src/core/render/preset/viewport.ts b/src/core/render/preset/viewport.ts index 1db9007..5e4429b 100644 --- a/src/core/render/preset/viewport.ts +++ b/src/core/render/preset/viewport.ts @@ -326,15 +326,12 @@ export class FloorViewport implements ILayerGroupRenderExtends { const half = cell / 2; nx = this.nx; ny = this.ny; - const ox = nx * cell; - const oy = ny * cell; + const ox = this.nx * cell - halfWidth + half; + const oy = this.ny * cell - halfHeight + half; core.bigmap.offsetX = ox; core.bigmap.offsetY = oy; - this.group.camera.setTranslate( - -ox + halfWidth - half, - -oy + halfHeight - half - ); + this.group.camera.setTranslate(-ox, -oy); this.group.update(this.group); }); // this.createMoving(); diff --git a/src/game/enemy/damage.ts b/src/game/enemy/damage.ts index 3a76915..f14ff4a 100644 --- a/src/game/enemy/damage.ts +++ b/src/game/enemy/damage.ts @@ -24,6 +24,8 @@ interface HaloType { }; } +type A = Enemy; + export interface EnemyInfo extends Partial { atk: number; def: number; @@ -74,7 +76,7 @@ interface CriticalDamageDelta extends Omit { type HaloFn = (info: EnemyInfo, enemy: EnemyInfo) => void; /** 光环属性 */ -export const haloSpecials: Set = new Set([8, 21, 25, 26, 27, 29]); +export const haloSpecials: Set = new Set([8, 21, 25, 26, 27, 29, 31]); /** 特殊属性对应 */ export const specialValue: Map[]> = new Map(); @@ -643,6 +645,20 @@ export class DamageEnemy { }); } + // 再生光环 + if (special.includes(31)) { + square7.push(e => { + e.hpBuff_ += this.info.hpHalo ?? 0; + }); + this.providedHalo.add(31); + col.haloList.push({ + type: 'square', + data: { x: this.x + dx, y: this.y + dy, d: 7 }, + special: 31, + from: this + }); + } + col.applyHalo( 'square', { x: this.x + dx, y: this.y + dy, d: 7 }, diff --git a/src/game/enemy/special.ts b/src/game/enemy/special.ts index f9b63c1..a1024be 100644 --- a/src/game/enemy/special.ts +++ b/src/game/enemy/special.ts @@ -246,5 +246,12 @@ export const specials: SpecialDeclaration[] = [ )}格。不同怪物间为加算叠加`; }, color: '#FDCD0B' + }, + { + code: 31, + name: '再生光环', + desc: enemy => + `怪物周围7*7范围内的所有怪物(包括自身)生命值提高${enemy.hpHalo}%`, + color: '#85FF99' } ]; diff --git a/src/game/mechanism/misc.ts b/src/game/mechanism/misc.ts index 91a6232..c8f83e9 100644 --- a/src/game/mechanism/misc.ts +++ b/src/game/mechanism/misc.ts @@ -92,12 +92,21 @@ export namespace BluePalace { export const portalMap: PortalMap = new Map(); export const portals: Partial> = { - MT75: [ - { fx: 7, fy: 7, dir: 'left', tx: 9, ty: 9, toDir: 'down' }, - { fx: 5, fy: 11, dir: 'right', tx: 7, ty: 9, toDir: 'up' }, - { fx: 4, fy: 6, dir: 'right', tx: 9, ty: 4, toDir: 'up' }, - { fx: 5, fy: 9, dir: 'right', tx: 3, ty: 7, toDir: 'up' }, - { fx: 7, fy: 5, dir: 'right', tx: 4, ty: 9, toDir: 'up' } + // MT75: [ + // { fx: 7, fy: 7, dir: 'left', tx: 9, ty: 9, toDir: 'down' }, + // { fx: 5, fy: 11, dir: 'right', tx: 7, ty: 9, toDir: 'up' }, + // { fx: 4, fy: 6, dir: 'right', tx: 9, ty: 4, toDir: 'up' }, + // { fx: 5, fy: 9, dir: 'right', tx: 3, ty: 7, toDir: 'up' }, + // { fx: 7, fy: 5, dir: 'right', tx: 4, ty: 9, toDir: 'up' } + // ] + MT76: [ + { fx: 11, fy: 7, dir: 'right', tx: 4, ty: 6, toDir: 'down' }, + { fx: 6, fy: 5, dir: 'left', tx: 8, ty: 13, toDir: 'right' } + ], + MT77: [ + { fx: 2, fy: 9, dir: 'down', tx: 9, ty: 13, toDir: 'right' }, + { fx: 10, fy: 8, dir: 'right', tx: 3, ty: 0, toDir: 'down' }, + { fx: 1, fy: 0, dir: 'down', tx: 8, ty: 1, toDir: 'left' } ] }; loading.once('coreInit', initPortals); @@ -133,11 +142,12 @@ export namespace BluePalace { const [[toFdx, toFdy], [toTdx, toTdy]] = delta[backDir(v.toDir)]; const fx = v.fx + fdx; - const fy = v.fy + fdy; + const fy = v.fy - fdy; const tx = v.fx + tdx; - const ty = v.fy + tdy; + const ty = v.fy - tdy; const index = fx + fy * width; const backIndex = tx + ty * width; + if (index < 0 || backIndex < 0) return; let data = map.get(index); let backData = map.get(backIndex); if (!data) { @@ -155,7 +165,7 @@ export namespace BluePalace { dir: backDir(v.toDir) }; backData[backDir(v.dir)] = { - x: v.tx + toTdx, + x: v.tx - toTdx, y: v.ty + toTdy, dir: v.toDir }; @@ -164,9 +174,9 @@ export namespace BluePalace { p.forEach(v => { const [[fdx, fdy], [tdx, tdy]] = delta[backDir(v.toDir)]; const [[toFdx, toFdy], [toTdx, toTdy]] = delta[v.dir]; - const fx = v.tx + fdx; + const fx = v.tx - fdx; const fy = v.ty + fdy; - const tx = v.tx + tdx; + const tx = v.tx - tdx; const ty = v.ty + tdy; const index = fx + fy * width; const backIndex = tx + ty * width; @@ -189,7 +199,7 @@ export namespace BluePalace { }; backData[backDir(v.toDir)] = { x: v.fx + toTdx, - y: v.fy + toTdy, + y: v.fy - toTdy, dir: v.dir }; }); @@ -198,5 +208,6 @@ export namespace BluePalace { function initPortals() { generatePortalMap(); + console.log(portalMap); } } diff --git a/src/game/system.ts b/src/game/system.ts index 7f132db..a5592a4 100644 --- a/src/game/system.ts +++ b/src/game/system.ts @@ -36,6 +36,7 @@ import type { RenderItem } from '@/core/render/item'; import type { RenderAdapter } from '@/core/render/adapter'; import type { ItemState } from './state/item'; import type { Layer } from '@/core/render/preset/layer'; +import type { LayerGroupFloorBinder } from '@/core/render/preset/floor'; interface ClassInterface { // 渲染进程与游戏进程通用 @@ -116,6 +117,7 @@ interface ModuleInterface { RenderItem: typeof RenderItem; RenderAdapter: typeof RenderAdapter; Layer: typeof Layer; + LayerGroupFloorBinder: typeof LayerGroupFloorBinder; }; State: { ItemState: typeof ItemState; @@ -141,8 +143,8 @@ interface PluginInterface { fly_r: typeof import('../plugin/ui/fly'); chase_r: typeof import('../plugin/chase/chase'); // webglUtils: typeof import('../plugin/webgl/utils'); - shadow_r: typeof import('../plugin/shadow/shadow'); - gameShadow_r: typeof import('../plugin/shadow/gameShadow'); + // shadow_r: typeof import('../plugin/shadow/shadow'); + // gameShadow_r: typeof import('../plugin/shadow/gameShadow'); // achievement: typeof import('../plugin/ui/achievement'); completion_r: typeof import('../plugin/completion'); // path: typeof import('../plugin/fx/path'); @@ -161,11 +163,11 @@ interface PluginInterface { chase_g: typeof import('../plugin/game/chase'); skill_g: typeof import('../plugin/game/skill'); towerBoss_g: typeof import('../plugin/game/towerBoss'); - heroFourFrames_g: typeof import('../plugin/game/fx/heroFourFrames'); + // heroFourFrames_g: typeof import('../plugin/game/fx/heroFourFrames'); rewrite_g: typeof import('../plugin/game/fx/rewrite'); itemDetail_g: typeof import('../plugin/game/fx/itemDetail'); checkBlock_g: typeof import('../plugin/game/enemy/checkblock'); - halo_g: typeof import('../plugin/game/fx/halo'); + // halo_g: typeof import('../plugin/game/fx/halo'); // study_g: typeof import('../plugin/game/study'); } diff --git a/src/plugin/fx/halo.ts b/src/plugin/fx/halo.ts index 7ecd1d6..2d7070d 100644 --- a/src/plugin/fx/halo.ts +++ b/src/plugin/fx/halo.ts @@ -46,7 +46,8 @@ const haloColor: Record = { 25: ['purple'], 26: ['blue'], 27: ['red'], - 29: ['#3CFF49'] + 29: ['#3CFF49'], + 31: ['#51E9FF'] }; class Halo extends Sprite { diff --git a/src/plugin/game/dev/hotReload.js b/src/plugin/game/dev/hotReload.js index 0626e15..8357fec 100644 --- a/src/plugin/game/dev/hotReload.js +++ b/src/plugin/game/dev/hotReload.js @@ -44,7 +44,6 @@ export {}; delete core.status.mapBlockObjs[data]; core.extractBlocks(data); if (data === core.status.floorId) { - core.drawMap(data); let weather = core.getFlag('__weather__', null); if (!weather && core.status.thisMap.weather) weather = core.status.thisMap.weather; @@ -54,6 +53,12 @@ export {}; core.updateStatusBar(true, true); } Mota.require('module', 'Shadow').Shadow.update(true); + const Binder = Mota.require('module', 'Render').LayerGroupFloorBinder; + Binder.activedBinder.forEach(v => { + if (v.getFloor() === core.status.floorId) { + v.updateBindData(); + } + }); console.log(`Floor hot reload: ${data}`); } diff --git a/src/source/cls.d.ts b/src/source/cls.d.ts index 42dfe6b..42306db 100644 --- a/src/source/cls.d.ts +++ b/src/source/cls.d.ts @@ -601,6 +601,22 @@ interface IdToCls { E671: 'enemys'; E672: 'enemys'; E673: 'enemys'; + E674: 'enemys'; + E675: 'enemys'; + E676: 'enemys'; + E677: 'enemys'; + E678: 'enemys'; + E679: 'enemys'; + E680: 'enemys'; + E681: 'enemys'; + E682: 'enemys'; + E683: 'enemys'; + E684: 'enemys'; + E685: 'enemys'; + E686: 'enemys'; + E687: 'enemys'; + E688: 'enemys'; + E689: 'enemys'; X20032: 'tileset'; X20033: 'tileset'; X20034: 'tileset'; diff --git a/src/source/maps.d.ts b/src/source/maps.d.ts index d4e96e1..4010574 100644 --- a/src/source/maps.d.ts +++ b/src/source/maps.d.ts @@ -601,6 +601,22 @@ interface IdToNumber { E671: 671; E672: 672; E673: 673; + E674: 674; + E675: 675; + E676: 676; + E677: 677; + E678: 678; + E679: 679; + E680: 680; + E681: 681; + E682: 682; + E683: 683; + E684: 684; + E685: 685; + E686: 686; + E687: 687; + E688: 688; + E689: 689; X20032: 20032; X20033: 20033; X20034: 20034; @@ -1287,6 +1303,22 @@ interface NumberToId { 671: 'E671'; 672: 'E672'; 673: 'E673'; + 674: 'E674'; + 675: 'E675'; + 676: 'E676'; + 677: 'E677'; + 678: 'E678'; + 679: 'E679'; + 680: 'E680'; + 681: 'E681'; + 682: 'E682'; + 683: 'E683'; + 684: 'E684'; + 685: 'E685'; + 686: 'E686'; + 687: 'E687'; + 688: 'E688'; + 689: 'E689'; 20032: 'X20032'; 20033: 'X20033'; 20034: 'X20034'; diff --git a/src/types/enemy.d.ts b/src/types/enemy.d.ts index 094658f..d302ac8 100644 --- a/src/types/enemy.d.ts +++ b/src/types/enemy.d.ts @@ -29,7 +29,8 @@ type PartialNumbericEnemyProperty = | 'iceHalo' | 'day' | 'night' - | 'melt'; + | 'melt' + | 'hpHalo'; type BooleanEnemyProperty = | 'zoneSquare' @@ -98,6 +99,38 @@ type Enemy = { [P in BooleanEnemyProperty]?: boolean; } & EnemyInfoBase; +interface EnemyInfoBase extends EnemySpecialBase { + /** + * 生命值 + */ + hp: number; + + /** + * 攻击力 + */ + atk: number; + + /** + * 防御力 + */ + def: number; + + /** + * 金币 + */ + money: number; + + /** + * 经验 + */ + exp: number; + + /** + * 加点量 + */ + point: number; +} + /** * 怪物的特殊属性定义 */