mirror of
https://github.com/unanmed/HumanBreak.git
synced 2025-01-19 20:59:37 +08:00
fix: moveAction
This commit is contained in:
parent
a19656e7c1
commit
9597831d74
@ -1858,7 +1858,7 @@ events.prototype._action_changePos = function (data, x, y, prefix) {
|
|||||||
core.clearMap('hero');
|
core.clearMap('hero');
|
||||||
if (!data.loc && data.direction) {
|
if (!data.loc && data.direction) {
|
||||||
core.setHeroLoc('direction', core.turnDirection(data.direction), true);
|
core.setHeroLoc('direction', core.turnDirection(data.direction), true);
|
||||||
core.drawHero();
|
// core.drawHero();
|
||||||
return core.doAction();
|
return core.doAction();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,6 +9,9 @@ import type { Layer, LayerMovingRenderable } from '@/core/render/preset/layer';
|
|||||||
import { BluePalace } from '@/game/mechanism/misc';
|
import { BluePalace } from '@/game/mechanism/misc';
|
||||||
import { backDir } from './utils';
|
import { backDir } from './utils';
|
||||||
import type { TimingFn } from 'mutate-animate';
|
import type { TimingFn } from 'mutate-animate';
|
||||||
|
import EventEmitter from 'eventemitter3';
|
||||||
|
|
||||||
|
// 向后兼容用,会充当两个版本间过渡的作用
|
||||||
|
|
||||||
interface Adapters {
|
interface Adapters {
|
||||||
'hero-adapter'?: RenderAdapter<HeroRenderer>;
|
'hero-adapter'?: RenderAdapter<HeroRenderer>;
|
||||||
@ -17,6 +20,11 @@ interface Adapters {
|
|||||||
layer?: RenderAdapter<Layer>;
|
layer?: RenderAdapter<Layer>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface MoveEvent {
|
||||||
|
stepEnd: [];
|
||||||
|
moveEnd: [];
|
||||||
|
}
|
||||||
|
|
||||||
const adapters: Adapters = {};
|
const adapters: Adapters = {};
|
||||||
|
|
||||||
export function init() {
|
export function init() {
|
||||||
@ -42,6 +50,10 @@ export function init() {
|
|||||||
let moveDir: Dir;
|
let moveDir: Dir;
|
||||||
let stepDir: Dir;
|
let stepDir: Dir;
|
||||||
let moveEnding: Promise<any[]> = Promise.resolve([]);
|
let moveEnding: Promise<any[]> = Promise.resolve([]);
|
||||||
|
let stepEnding: Promise<any[]> = Promise.resolve([]);
|
||||||
|
|
||||||
|
/** 移动事件 */
|
||||||
|
const moveEmit = new EventEmitter<MoveEvent>();
|
||||||
|
|
||||||
/** 传送门信息,下一步传送到哪 */
|
/** 传送门信息,下一步传送到哪 */
|
||||||
let portalData: BluePalace.PortalTo | undefined;
|
let portalData: BluePalace.PortalTo | undefined;
|
||||||
@ -94,23 +106,34 @@ export function init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function readyMove() {
|
async function readyMove(
|
||||||
|
ignoreTerrain: boolean = false,
|
||||||
|
noRoute: boolean = false,
|
||||||
|
inLockControl: boolean = false,
|
||||||
|
callback?: () => void
|
||||||
|
) {
|
||||||
const adapter = adapters['hero-adapter'];
|
const adapter = adapters['hero-adapter'];
|
||||||
if (!adapter) {
|
if (!adapter) {
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
} else {
|
} else {
|
||||||
if (!checkCanMoveStatus()) {
|
if (!ignoreTerrain && !checkCanMoveStatus(callback)) {
|
||||||
|
moveEmit.emit('stepEnd');
|
||||||
continueAfterEnd();
|
continueAfterEnd();
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
await adapter.all('readyMove');
|
await adapter.all('readyMove');
|
||||||
moving = true;
|
moving = true;
|
||||||
stopChian = false;
|
stopChian = false;
|
||||||
startHeroMoveChain();
|
|
||||||
|
startHeroMoveChain(ignoreTerrain, noRoute, inLockControl, callback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function endMove() {
|
/**
|
||||||
|
* 结束移动
|
||||||
|
* @param tryContinue 是否会尝试继续移动,只有在按键操作条件下需要填true,其余填false,默认为true
|
||||||
|
*/
|
||||||
|
async function endMove(tryContinue: boolean = true) {
|
||||||
const adapter = adapters['hero-adapter'];
|
const adapter = adapters['hero-adapter'];
|
||||||
if (!adapter) {
|
if (!adapter) {
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
@ -119,8 +142,9 @@ export function init() {
|
|||||||
stopChian = true;
|
stopChian = true;
|
||||||
moveEnding = adapter.all('endMove');
|
moveEnding = adapter.all('endMove');
|
||||||
await moveEnding;
|
await moveEnding;
|
||||||
|
moveEmit.emit('moveEnd');
|
||||||
moving = false;
|
moving = false;
|
||||||
continueAfterEnd();
|
if (tryContinue) continueAfterEnd();
|
||||||
}
|
}
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
@ -147,19 +171,34 @@ export function init() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function startHeroMoveChain(callback?: () => void) {
|
async function startHeroMoveChain(
|
||||||
|
ignoreTerrain: boolean = false,
|
||||||
|
noRoute: boolean = false,
|
||||||
|
inLockControl: boolean = false,
|
||||||
|
callback?: () => void
|
||||||
|
) {
|
||||||
const adapter = adapters['hero-adapter'];
|
const adapter = adapters['hero-adapter'];
|
||||||
if (!adapter) {
|
if (!adapter) {
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
} else {
|
} else {
|
||||||
while (moving || !stopChian) {
|
while (moving || !stopChian) {
|
||||||
if (stopChian || core.status.lockControl) break;
|
if (stopChian || (!inLockControl && core.status.lockControl)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
stepDir = moveDir;
|
stepDir = moveDir;
|
||||||
|
if (!ignoreTerrain) {
|
||||||
if (!checkCanMoveStatus(callback)) break;
|
if (!checkCanMoveStatus(callback)) break;
|
||||||
if (portal) renderHeroSwap();
|
if (portal) renderHeroSwap();
|
||||||
await adapter.all('move', moveDir);
|
|
||||||
onMoveEnd(false, callback);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stepEnding = adapter.all('move', moveDir);
|
||||||
|
await stepEnding;
|
||||||
|
|
||||||
|
moveEmit.emit('stepEnd');
|
||||||
|
if (!ignoreTerrain) onMoveEnd(false, noRoute, callback);
|
||||||
|
}
|
||||||
|
|
||||||
endMove();
|
endMove();
|
||||||
stopChian = false;
|
stopChian = false;
|
||||||
}
|
}
|
||||||
@ -204,6 +243,7 @@ export function init() {
|
|||||||
core.status.automaticRoute.moveStepBeforeStop = [];
|
core.status.automaticRoute.moveStepBeforeStop = [];
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
core.status.automaticRoute.lastDirection = core.getHeroLoc('direction');
|
core.status.automaticRoute.lastDirection = core.getHeroLoc('direction');
|
||||||
|
|
||||||
if (canMove) core.trigger(nx, ny);
|
if (canMove) core.trigger(nx, ny);
|
||||||
core.drawHero();
|
core.drawHero();
|
||||||
|
|
||||||
@ -214,7 +254,11 @@ export function init() {
|
|||||||
callback?.();
|
callback?.();
|
||||||
}
|
}
|
||||||
|
|
||||||
function onMoveEnd(noPass: boolean, callback?: () => void) {
|
function onMoveEnd(
|
||||||
|
noPass: boolean,
|
||||||
|
noRoute: boolean = false,
|
||||||
|
callback?: () => void
|
||||||
|
) {
|
||||||
if (portal && portalData) {
|
if (portal && portalData) {
|
||||||
const { x, y, dir } = portalData;
|
const { x, y, dir } = portalData;
|
||||||
core.setHeroLoc('x', x);
|
core.setHeroLoc('x', x);
|
||||||
@ -229,7 +273,7 @@ export function init() {
|
|||||||
|
|
||||||
var direction = core.getHeroLoc('direction');
|
var direction = core.getHeroLoc('direction');
|
||||||
core.control._moveAction_popAutomaticRoute();
|
core.control._moveAction_popAutomaticRoute();
|
||||||
core.status.route.push(direction);
|
if (!noRoute) core.status.route.push(direction);
|
||||||
|
|
||||||
core.moveOneStep();
|
core.moveOneStep();
|
||||||
core.checkRouteFolding();
|
core.checkRouteFolding();
|
||||||
@ -376,7 +420,7 @@ export function init() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const step0 = steps.find(v => !v.startsWith('speed')) as Dir2;
|
const step0 = steps.find(v => !v.startsWith('speed')) as Move2;
|
||||||
return { steps, start: step0 };
|
return { steps, start: step0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -431,14 +475,104 @@ export function init() {
|
|||||||
|
|
||||||
Mota.r(() => {
|
Mota.r(() => {
|
||||||
// ----- 勇士移动相关
|
// ----- 勇士移动相关
|
||||||
|
control.prototype.moveAction = async function (callback?: () => void) {
|
||||||
|
// await endMove(false);
|
||||||
|
moveEmit.once('stepEnd', () => {
|
||||||
|
stopChian = true;
|
||||||
|
endMove(false);
|
||||||
|
});
|
||||||
|
readyMove(false, true, true, callback);
|
||||||
|
};
|
||||||
|
|
||||||
control.prototype._moveAction_moving = function (
|
control.prototype._moveAction_moving = function (
|
||||||
callback?: () => void
|
callback?: () => void
|
||||||
) {};
|
) {};
|
||||||
|
|
||||||
|
events.prototype._action_moveAction = function (
|
||||||
|
data: any,
|
||||||
|
x: number,
|
||||||
|
y: number,
|
||||||
|
prefix: any
|
||||||
|
) {
|
||||||
|
if (core.canMoveHero()) {
|
||||||
|
var nx = core.nextX(),
|
||||||
|
ny = core.nextY();
|
||||||
|
// 检查noPass决定是撞击还是移动
|
||||||
|
if (core.noPass(nx, ny)) {
|
||||||
|
core.insertAction([{ type: 'trigger', loc: [nx, ny] }]);
|
||||||
|
} else {
|
||||||
|
// 先移动一格,然后尝试触发事件
|
||||||
|
core.insertAction([
|
||||||
|
{
|
||||||
|
type: 'function',
|
||||||
|
function:
|
||||||
|
'function() { core.moveAction(core.doAction); }',
|
||||||
|
async: true
|
||||||
|
},
|
||||||
|
{ type: '_label' }
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
core.doAction();
|
||||||
|
};
|
||||||
|
|
||||||
|
const validDir = new Set<string>(['left', 'right', 'up', 'down']);
|
||||||
events.prototype.eventMoveHero = async function (
|
events.prototype.eventMoveHero = async function (
|
||||||
steps: string[],
|
steps: string[],
|
||||||
time?: number,
|
time: number = 500,
|
||||||
callback?: () => void
|
callback?: () => void
|
||||||
) {};
|
) {
|
||||||
|
if (moving) return;
|
||||||
|
const { steps: moveSteps, start } = getMoveSteps(steps);
|
||||||
|
if (
|
||||||
|
moveSteps.some(v => !v.startsWith('speed') && !validDir.has(v))
|
||||||
|
) {
|
||||||
|
callback?.();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (start !== 'backward' && start !== 'forward') {
|
||||||
|
moveDir = start as Dir;
|
||||||
|
}
|
||||||
|
core.setHeroLoc('direction', moveDir);
|
||||||
|
|
||||||
|
const speed = core.status.replay.speed;
|
||||||
|
time /= speed;
|
||||||
|
if (speed === 24) time = 1;
|
||||||
|
|
||||||
|
let pointer = -1;
|
||||||
|
const len = moveSteps.length;
|
||||||
|
const list = adapters['hero-adapter']?.items ?? [];
|
||||||
|
const speedMap: Map<HeroRenderer, number> = new Map();
|
||||||
|
list.forEach(v => {
|
||||||
|
speedMap.set(v, v.speed);
|
||||||
|
v.setMoveSpeed(time);
|
||||||
|
});
|
||||||
|
|
||||||
|
let nx = core.status.hero.loc.x;
|
||||||
|
let ny = core.status.hero.loc.y;
|
||||||
|
readyMove(true, true, true);
|
||||||
|
while (++pointer < len) {
|
||||||
|
const dir = moveSteps[pointer];
|
||||||
|
if (dir === 'backward') moveDir = backDir(moveDir);
|
||||||
|
else if (dir.startsWith('speed')) {
|
||||||
|
const speed = parseInt(dir.slice(6));
|
||||||
|
list.forEach(v => v.setMoveSpeed(speed));
|
||||||
|
} else if (dir !== 'forward') {
|
||||||
|
moveDir = dir as Dir;
|
||||||
|
}
|
||||||
|
const { x, y } = core.utils.scan[moveDir];
|
||||||
|
nx += x;
|
||||||
|
ny += y;
|
||||||
|
await new Promise<void>(res => {
|
||||||
|
moveEmit.once('stepEnd', res);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
endMove(false);
|
||||||
|
|
||||||
|
core.setHeroLoc('x', nx);
|
||||||
|
core.setHeroLoc('y', ny);
|
||||||
|
callback?.();
|
||||||
|
};
|
||||||
|
|
||||||
control.prototype.setHeroLoc = function (
|
control.prototype.setHeroLoc = function (
|
||||||
name: 'x' | 'y' | 'direction',
|
name: 'x' | 'y' | 'direction',
|
||||||
@ -452,6 +586,8 @@ export function init() {
|
|||||||
this.gatherFollowers();
|
this.gatherFollowers();
|
||||||
}
|
}
|
||||||
if (name === 'direction') {
|
if (name === 'direction') {
|
||||||
|
moveDir = value as Dir;
|
||||||
|
stepDir = value as Dir;
|
||||||
adapters['hero-adapter']?.sync('turn', value);
|
adapters['hero-adapter']?.sync('turn', value);
|
||||||
} else if (name === 'x') {
|
} else if (name === 'x') {
|
||||||
adapters['hero-adapter']?.sync('setHeroLoc', value);
|
adapters['hero-adapter']?.sync('setHeroLoc', value);
|
||||||
@ -678,6 +814,7 @@ export function init() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const speed = core.status.replay.speed;
|
const speed = core.status.replay.speed;
|
||||||
|
time /= speed;
|
||||||
if (speed === 24) time = 1;
|
if (speed === 24) time = 1;
|
||||||
const block = core.getBlock(x, y);
|
const block = core.getBlock(x, y);
|
||||||
if (!block) {
|
if (!block) {
|
||||||
@ -698,9 +835,11 @@ export function init() {
|
|||||||
callback?.();
|
callback?.();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let stepDir: Dir2 = start;
|
let stepDir: Dir2;
|
||||||
let nx = x;
|
let nx = x;
|
||||||
let ny = y;
|
let ny = y;
|
||||||
|
if (start === 'backward' || start === 'forward') stepDir = 'down';
|
||||||
|
else stepDir = start;
|
||||||
|
|
||||||
const { Layer } = Mota.require('module', 'Render');
|
const { Layer } = Mota.require('module', 'Render');
|
||||||
const moving = Layer.getMovingRenderable(block.id, x, y);
|
const moving = Layer.getMovingRenderable(block.id, x, y);
|
||||||
@ -719,7 +858,7 @@ export function init() {
|
|||||||
const { x, y } = core.utils.scan2[stepDir];
|
const { x, y } = core.utils.scan2[stepDir];
|
||||||
const tx = nx + x;
|
const tx = nx + x;
|
||||||
const ty = ny + y;
|
const ty = ny + y;
|
||||||
await moveRenderable(items[0], moving, time / speed, tx, ty);
|
await moveRenderable(items[0], moving, time, tx, ty);
|
||||||
nx = tx;
|
nx = tx;
|
||||||
ny = ty;
|
ny = ty;
|
||||||
moving.zIndex = ty;
|
moving.zIndex = ty;
|
||||||
@ -787,6 +926,7 @@ export function init() {
|
|||||||
time: number = 500,
|
time: number = 500,
|
||||||
callback?: () => void
|
callback?: () => void
|
||||||
) {
|
) {
|
||||||
|
if (moving) return;
|
||||||
const sx = core.getHeroLoc('x');
|
const sx = core.getHeroLoc('x');
|
||||||
const sy = core.getHeroLoc('y');
|
const sy = core.getHeroLoc('y');
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user