mirror of
https://github.com/motajs/template.git
synced 2026-11-03 15:34:31 +08:00
feat: 勇士撞击行为
This commit is contained in:
1 parent
0508dfb9e4
commit
c4bcecdf8a
12 files changed
+380
-254
No files matched your search
@@ -1,73 +1,18 @@
|
||||
import { ITileLocator } from '@motajs/common';
|
||||
import { FaceDirection, PassBit } from '@user/data-common';
|
||||
import { IHeroState, IStateBase, ITerrainPassChecker } from '@user/data-base';
|
||||
import {
|
||||
IHeroState,
|
||||
IMapStore,
|
||||
IPassCheckerHandler,
|
||||
ITerrainPassChecker
|
||||
} from '@user/data-base';
|
||||
import { isNil } from 'lodash-es';
|
||||
|
||||
export class DefaultPassChecker implements ITerrainPassChecker {
|
||||
constructor(
|
||||
readonly state: IStateBase,
|
||||
readonly maps: IMapStore,
|
||||
readonly hero: IHeroState<unknown>
|
||||
) {}
|
||||
|
||||
canPass(
|
||||
locator: ITileLocator,
|
||||
direction: FaceDirection,
|
||||
floorId: string | undefined
|
||||
): boolean {
|
||||
if (isNil(floorId)) return false;
|
||||
if (
|
||||
direction === FaceDirection.LeftDown ||
|
||||
direction === FaceDirection.LeftUp ||
|
||||
direction === FaceDirection.RightDown ||
|
||||
direction === FaceDirection.RightUp
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const layerState = this.state.maps.getLayerState(floorId);
|
||||
if (!layerState) return false;
|
||||
const eventLayer = layerState.eventLayer;
|
||||
if (!eventLayer) return false;
|
||||
|
||||
const { x, y } = locator;
|
||||
const face = this.hero.location.mover.faceHandler;
|
||||
const { x: dx, y: dy } = face.movement(direction);
|
||||
const nx = x + dx;
|
||||
const ny = y + dy;
|
||||
const opposite = face.opposite(direction);
|
||||
const leaveMask = this.directionToPassBit(direction);
|
||||
const enterMask = this.directionToPassBit(opposite);
|
||||
|
||||
let canLeave = true;
|
||||
let canEnter = true;
|
||||
|
||||
const eventCurr = eventLayer.getLocationData(x, y);
|
||||
const eventNext = eventLayer.getLocationData(nx, ny);
|
||||
if (eventCurr && eventCurr.raw) {
|
||||
canLeave = !!(leaveMask & eventCurr.raw.pass.outPass);
|
||||
}
|
||||
if (eventNext && eventNext.raw) {
|
||||
canEnter = !!(enterMask & eventNext.raw.pass.inPass);
|
||||
}
|
||||
|
||||
if (!canLeave || !canEnter) return false;
|
||||
|
||||
for (const layer of layerState.layerList) {
|
||||
if (layer === eventLayer) continue;
|
||||
const curr = layer.getLocationData(x, y);
|
||||
const next = layer.getLocationData(nx, ny);
|
||||
if (curr && curr.raw && curr.raw.pass.onlyEvents) {
|
||||
canLeave = !!(leaveMask & curr.raw.pass.outPass);
|
||||
}
|
||||
if (next && next.raw && next.raw.pass.onlyEvents) {
|
||||
canEnter = !!(enterMask & next.raw.pass.inPass);
|
||||
}
|
||||
if (!canLeave || !canEnter) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将朝向转换为对应的通行性位掩码。
|
||||
* @param dir 朝向
|
||||
@@ -86,4 +31,87 @@ export class DefaultPassChecker implements ITerrainPassChecker {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
inBound(x: number, y: number, floorId: string | undefined): boolean {
|
||||
if (isNil(floorId)) return false;
|
||||
const layerState = this.maps.getLayerState(floorId);
|
||||
if (!layerState) return false;
|
||||
const { width, height } = layerState;
|
||||
return x >= 0 && y >= 0 && x < width && y < height;
|
||||
}
|
||||
|
||||
canPass(handler: IPassCheckerHandler): boolean {
|
||||
const { currLoc, nextLoc, direction, floorId, face } = handler;
|
||||
if (isNil(floorId)) return false;
|
||||
|
||||
// 四角朝向直接判定为可通行
|
||||
if (
|
||||
direction === FaceDirection.LeftDown ||
|
||||
direction === FaceDirection.LeftUp ||
|
||||
direction === FaceDirection.RightDown ||
|
||||
direction === FaceDirection.RightUp
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const layerState = this.maps.getLayerState(floorId);
|
||||
if (!layerState) return false;
|
||||
const eventLayer = layerState.eventLayer;
|
||||
if (!eventLayer) return false;
|
||||
|
||||
const { x, y } = currLoc;
|
||||
const { x: nx, y: ny } = nextLoc;
|
||||
|
||||
const opposite = face.opposite(direction);
|
||||
const leaveMask = this.directionToPassBit(direction);
|
||||
const enterMask = this.directionToPassBit(opposite);
|
||||
|
||||
let canLeave = true;
|
||||
let canEnter = true;
|
||||
|
||||
// 判断事件层
|
||||
const curr = eventLayer.getLocationData(x, y);
|
||||
const next = eventLayer.getLocationData(nx, ny);
|
||||
if (curr && curr.raw) {
|
||||
canLeave = !!(leaveMask & curr.raw.pass.outPass);
|
||||
}
|
||||
if (next && next.raw) {
|
||||
canEnter = !!(enterMask & next.raw.pass.inPass);
|
||||
}
|
||||
|
||||
if (!canLeave || !canEnter) return false;
|
||||
|
||||
// 判断其他层
|
||||
for (const layer of layerState.layerList) {
|
||||
if (layer === eventLayer) continue;
|
||||
const curr = layer.getLocationData(x, y);
|
||||
const next = layer.getLocationData(nx, ny);
|
||||
let canLeave = true;
|
||||
let canEnter = true;
|
||||
if (curr && curr.raw && curr.raw.pass.onlyEvents) {
|
||||
canLeave = !!(leaveMask & curr.raw.pass.outPass);
|
||||
}
|
||||
if (next && next.raw && next.raw.pass.onlyEvents) {
|
||||
canEnter = !!(enterMask & next.raw.pass.inPass);
|
||||
}
|
||||
if (!canLeave || !canEnter) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
shouldHit(handler: IPassCheckerHandler): boolean {
|
||||
const { nextLoc, floorId } = handler;
|
||||
if (isNil(floorId)) return false;
|
||||
const layerState = this.maps.getLayerState(floorId);
|
||||
if (!layerState) return false;
|
||||
const eventLayer = layerState.eventLayer;
|
||||
if (!eventLayer) return false;
|
||||
|
||||
const { x: nx, y: ny } = nextLoc;
|
||||
|
||||
const next = eventLayer.getLocationData(nx, ny);
|
||||
if (!next || !next.raw) return false;
|
||||
return !next.raw.eventPass;
|
||||
}
|
||||
}
|
||||
@@ -36,25 +36,22 @@ export class TileLegacyBridge implements ITileLegacyConverter<LegacyTileData> {
|
||||
|
||||
private getPass(num: number, legacy: LegacyTileData): ITilePassData {
|
||||
if (num === 0) {
|
||||
// 空图块
|
||||
return {
|
||||
onlyEvents: true,
|
||||
inPass: 0b1111,
|
||||
outPass: 0b1111
|
||||
};
|
||||
} else if (num === 17) {
|
||||
// 空气墙
|
||||
return {
|
||||
onlyEvents: false,
|
||||
inPass: 0b0000,
|
||||
outPass: 0b0000
|
||||
};
|
||||
} else {
|
||||
if (legacy.noPass) {
|
||||
return {
|
||||
onlyEvents: true,
|
||||
inPass: 0b0000,
|
||||
outPass: 0b1111
|
||||
};
|
||||
} else if (legacy.cannotIn && legacy.cannotOut) {
|
||||
// 正常图块
|
||||
if (legacy.cannotIn && legacy.cannotOut) {
|
||||
let inPass = 0b1111;
|
||||
let outPass = 0b1111;
|
||||
if (legacy.cannotIn.includes('up')) {
|
||||
@@ -102,7 +99,8 @@ export class TileLegacyBridge implements ITileLegacyConverter<LegacyTileData> {
|
||||
id: legacy.id,
|
||||
trigger: -1,
|
||||
type: this.getTileType(num, legacy),
|
||||
pass: this.getPass(num, legacy)
|
||||
pass: this.getPass(num, legacy),
|
||||
eventPass: !legacy.noPass
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user