mirror of
https://github.com/unanmed/HumanBreak.git
synced 2025-08-02 23:01:47 +08:00
Compare commits
8 Commits
091a1c76e9
...
b93e286c52
Author | SHA1 | Date | |
---|---|---|---|
b93e286c52 | |||
1b18ce4268 | |||
![]() |
5b24af71b1 | ||
dff0a925e3 | |||
bcf3d33a9c | |||
![]() |
f5a12c4a90 | ||
![]() |
d359563dad | ||
127af11e5e |
@ -1,30 +1,73 @@
|
|||||||
import { ElementLocator, IWheelEvent } from '@motajs/render-core';
|
import { ElementLocator, IWheelEvent } from '@motajs/render-core';
|
||||||
import { DefaultProps } from '@motajs/render-vue';
|
import { DefaultProps } from '@motajs/render-vue';
|
||||||
|
import { Font } from '@motajs/render';
|
||||||
import {
|
import {
|
||||||
GameUI,
|
GameUI,
|
||||||
IUIMountable,
|
IUIMountable,
|
||||||
SetupComponentOptions,
|
SetupComponentOptions,
|
||||||
UIComponentProps
|
UIComponentProps
|
||||||
} from '@motajs/system-ui';
|
} from '@motajs/system-ui';
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent, ref } from 'vue';
|
||||||
import { Page } from '../components';
|
import { Background, Page, PageExpose } from '../components';
|
||||||
import { useKey } from '../use';
|
import { useKey } from '../use';
|
||||||
|
import { MAP_WIDTH, MAP_HEIGHT } from '../shared';
|
||||||
|
|
||||||
export interface SaveProps extends UIComponentProps, DefaultProps {
|
export interface SaveProps extends UIComponentProps, DefaultProps {
|
||||||
loc: ElementLocator;
|
loc: ElementLocator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface SaveBtnProps extends DefaultProps {
|
||||||
|
loc: ElementLocator;
|
||||||
|
index: number;
|
||||||
|
isDelete: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
export type SaveEmits = {
|
export type SaveEmits = {
|
||||||
/** 点击存档时触发 */
|
/** 点击存档时触发 */
|
||||||
emit: (index: number) => void;
|
emit: (index: number) => void;
|
||||||
|
/** 删除存档时触发 */
|
||||||
|
delete: (index: number) => void;
|
||||||
/** 手动点击退出时触发 */
|
/** 手动点击退出时触发 */
|
||||||
exit: () => void;
|
exit: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
const saveProps = {
|
const saveProps = {
|
||||||
props: ['loc', 'controller', 'instance']
|
props: ['loc', 'controller', 'instance'],
|
||||||
|
emits: ['delete', 'emit', 'exit']
|
||||||
} satisfies SetupComponentOptions<SaveProps, SaveEmits, keyof SaveEmits>;
|
} satisfies SetupComponentOptions<SaveProps, SaveEmits, keyof SaveEmits>;
|
||||||
|
|
||||||
|
const saveBtnProps = {
|
||||||
|
props: ['loc', 'index', 'isDelete']
|
||||||
|
} satisfies SetupComponentOptions<SaveBtnProps>;
|
||||||
|
|
||||||
|
export const SaveBtn = defineComponent<SaveBtnProps>(props => {
|
||||||
|
const w = props.loc[2] ?? 200;
|
||||||
|
const text = props.index === -1 ? '自动存档' : `存档${props.index + 1}`;
|
||||||
|
const font = new Font('normal', 18);
|
||||||
|
return () => (
|
||||||
|
<container loc={props.loc}>
|
||||||
|
<text
|
||||||
|
text={text}
|
||||||
|
font={font}
|
||||||
|
loc={[w / 2, 0, void 0, void 0, 0.5, 0]}
|
||||||
|
/>
|
||||||
|
<g-rect
|
||||||
|
loc={[0, 20, w, w]}
|
||||||
|
fill
|
||||||
|
stroke
|
||||||
|
fillStyle="gray"
|
||||||
|
strokeStyle={props.isDelete ? 'red' : 'white'}
|
||||||
|
/>
|
||||||
|
<text
|
||||||
|
text="placeholder"
|
||||||
|
fillStyle="yellow"
|
||||||
|
font={font}
|
||||||
|
loc={[w / 2, w + 20, void 0, void 0, 0.5, 0]}
|
||||||
|
/>
|
||||||
|
</container>
|
||||||
|
);
|
||||||
|
}, saveBtnProps);
|
||||||
|
|
||||||
export const Save = defineComponent<SaveProps, SaveEmits, keyof SaveEmits>(
|
export const Save = defineComponent<SaveProps, SaveEmits, keyof SaveEmits>(
|
||||||
(props, { emit }) => {
|
(props, { emit }) => {
|
||||||
// 这些注释写完之后删了
|
// 这些注释写完之后删了
|
||||||
@ -33,6 +76,13 @@ export const Save = defineComponent<SaveProps, SaveEmits, keyof SaveEmits>(
|
|||||||
// onEmit 事件在点击存档或按键确认时触发
|
// onEmit 事件在点击存档或按键确认时触发
|
||||||
// 存读档执行函数在 ../../utils/saves.ts
|
// 存读档执行函数在 ../../utils/saves.ts
|
||||||
|
|
||||||
|
/** 除自动存档外,每一页容纳的存档数量 */
|
||||||
|
const pageCap = 5;
|
||||||
|
const font = new Font('normal', 18);
|
||||||
|
|
||||||
|
const isDelete = ref(false);
|
||||||
|
const pageRef = ref<PageExpose>();
|
||||||
|
|
||||||
// 参考 ../../action/hotkey.ts 中的按键定义
|
// 参考 ../../action/hotkey.ts 中的按键定义
|
||||||
const [key] = useKey();
|
const [key] = useKey();
|
||||||
key.realize('confirm', () => {});
|
key.realize('confirm', () => {});
|
||||||
@ -40,27 +90,123 @@ export const Save = defineComponent<SaveProps, SaveEmits, keyof SaveEmits>(
|
|||||||
// 其他按键自定义,需要新开一个 save 的 group
|
// 其他按键自定义,需要新开一个 save 的 group
|
||||||
|
|
||||||
const emitSave = (index: number) => {
|
const emitSave = (index: number) => {
|
||||||
emit('emit', index);
|
if (isDelete.value) emit('delete', index);
|
||||||
|
else emit('emit', index);
|
||||||
};
|
};
|
||||||
|
|
||||||
const wheel = (ev: IWheelEvent) => {};
|
const wheel = (ev: IWheelEvent) => {
|
||||||
|
const delta = Math.sign(ev.wheelY);
|
||||||
|
if (ev.ctrlKey) {
|
||||||
|
pageRef.value?.movePage(delta * 10);
|
||||||
|
} else {
|
||||||
|
pageRef.value?.movePage(delta);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return () => <Page loc={props.loc} pages={1000} onWheel={wheel}></Page>;
|
const toggleDelete = () => {
|
||||||
|
isDelete.value = !isDelete.value;
|
||||||
|
};
|
||||||
|
|
||||||
|
const exit = () => {
|
||||||
|
emit('exit');
|
||||||
|
props.controller.close(props.instance);
|
||||||
|
};
|
||||||
|
|
||||||
|
return () => (
|
||||||
|
<container loc={props.loc}>
|
||||||
|
<Background loc={[0, 0, MAP_WIDTH, MAP_HEIGHT]} color="black" />
|
||||||
|
<Page
|
||||||
|
loc={[0, 0, MAP_WIDTH, MAP_HEIGHT - 10]}
|
||||||
|
pages={1000}
|
||||||
|
onWheel={wheel}
|
||||||
|
ref={pageRef}
|
||||||
|
>
|
||||||
|
{(page: number) => (
|
||||||
|
<container loc={[0, 0, MAP_WIDTH, MAP_HEIGHT]}>
|
||||||
|
<SaveBtn
|
||||||
|
loc={[30, 50, 120, 170]}
|
||||||
|
index={-1}
|
||||||
|
isDelete={isDelete.value}
|
||||||
|
onClick={() => emitSave(-1)}
|
||||||
|
cursor="pointer"
|
||||||
|
/>
|
||||||
|
<SaveBtn
|
||||||
|
loc={[180, 50, 120, 170]}
|
||||||
|
index={page * pageCap}
|
||||||
|
isDelete={isDelete.value}
|
||||||
|
onClick={() => emitSave(page * pageCap)}
|
||||||
|
cursor="pointer"
|
||||||
|
/>
|
||||||
|
<SaveBtn
|
||||||
|
loc={[330, 50, 120, 170]}
|
||||||
|
index={page * pageCap + 1}
|
||||||
|
isDelete={isDelete.value}
|
||||||
|
onClick={() => emitSave(page * pageCap + 1)}
|
||||||
|
cursor="pointer"
|
||||||
|
/>
|
||||||
|
<SaveBtn
|
||||||
|
loc={[30, 230, 120, 170]}
|
||||||
|
index={page * pageCap + 2}
|
||||||
|
isDelete={isDelete.value}
|
||||||
|
onClick={() => emitSave(page * pageCap + 2)}
|
||||||
|
cursor="pointer"
|
||||||
|
/>
|
||||||
|
<SaveBtn
|
||||||
|
loc={[180, 230, 120, 170]}
|
||||||
|
index={page * pageCap + 3}
|
||||||
|
isDelete={isDelete.value}
|
||||||
|
onClick={() => emitSave(page * pageCap + 3)}
|
||||||
|
cursor="pointer"
|
||||||
|
/>
|
||||||
|
<SaveBtn
|
||||||
|
loc={[330, 230, 120, 170]}
|
||||||
|
index={page * pageCap + 4}
|
||||||
|
isDelete={isDelete.value}
|
||||||
|
onClick={() => emitSave(page * pageCap + 4)}
|
||||||
|
cursor="pointer"
|
||||||
|
/>
|
||||||
|
</container>
|
||||||
|
)}
|
||||||
|
</Page>
|
||||||
|
<text
|
||||||
|
text="删除模式"
|
||||||
|
font={font}
|
||||||
|
loc={[30, 450, void 0, void 0, 0, 0]}
|
||||||
|
zIndex={10}
|
||||||
|
fillStyle={isDelete.value ? 'red' : 'white'}
|
||||||
|
onClick={toggleDelete}
|
||||||
|
/>
|
||||||
|
<text
|
||||||
|
text="返回游戏"
|
||||||
|
font={font}
|
||||||
|
loc={[450, 450, void 0, void 0, 1, 0]}
|
||||||
|
zIndex={10}
|
||||||
|
onClick={exit}
|
||||||
|
/>
|
||||||
|
</container>
|
||||||
|
);
|
||||||
},
|
},
|
||||||
saveProps
|
saveProps
|
||||||
);
|
);
|
||||||
|
|
||||||
export const SaveUI = new GameUI('save', Save);
|
export const SaveUI = new GameUI('save', Save);
|
||||||
|
|
||||||
|
export interface SaveValidation {
|
||||||
|
readonly valid: boolean;
|
||||||
|
readonly message: string;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 打开存读档界面并让用户选择一个存档。如果用户手动关闭了存档界面,返回 -1,否则返回用户选择的存档索引。
|
* 打开存读档界面并让用户选择一个存档。如果用户手动关闭了存档界面,返回 -2,否则返回用户选择的存档索引。
|
||||||
* 参数参考 {@link SaveProps},事件不可自定义。
|
* 参数参考 {@link SaveProps},事件不可自定义。
|
||||||
*
|
*
|
||||||
* 使用示例:
|
* 使用示例:
|
||||||
* ```ts
|
* ```ts
|
||||||
* const index = await selectSave(props.controller, [0, 0, 416, 416]);
|
* const index = await selectSave(props.controller, [0, 0, 416, 416]);
|
||||||
* if (index === -1) {
|
* if (index === -2) {
|
||||||
* // 如果用户未选择存档,而是关闭了存档。
|
* // 如果用户未选择存档,而是关闭了存档。
|
||||||
|
* } else if (index === -1) {
|
||||||
|
* // 用户选择了自动存档。
|
||||||
* } else {
|
* } else {
|
||||||
* // 用户选择了一个存档。
|
* // 用户选择了一个存档。
|
||||||
* }
|
* }
|
||||||
@ -68,23 +214,34 @@ export const SaveUI = new GameUI('save', Save);
|
|||||||
* @param controller 在哪个控制器上打开
|
* @param controller 在哪个控制器上打开
|
||||||
* @param loc 存读档界面的坐标
|
* @param loc 存读档界面的坐标
|
||||||
* @param props 传递给存读档界面的参数
|
* @param props 传递给存读档界面的参数
|
||||||
* @returns
|
* @returns 选择的存档索引
|
||||||
*/
|
*/
|
||||||
export function selectSave(
|
export function selectSave(
|
||||||
controller: IUIMountable,
|
controller: IUIMountable,
|
||||||
loc: ElementLocator,
|
loc: ElementLocator,
|
||||||
|
validate?: (index: number) => SaveValidation,
|
||||||
props?: SaveProps
|
props?: SaveProps
|
||||||
) {
|
) {
|
||||||
return new Promise<number>(res => {
|
return new Promise<number>(res => {
|
||||||
const instance = controller.open(SaveUI, {
|
const instance = controller.open(SaveUI, {
|
||||||
loc,
|
loc,
|
||||||
...props,
|
...props,
|
||||||
onEmit: index => {
|
onEmit: (index: number) => {
|
||||||
controller.close(instance);
|
if (!validate) {
|
||||||
res(index);
|
controller.close(instance);
|
||||||
|
res(index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const validation = validate(index);
|
||||||
|
if (validation.valid) {
|
||||||
|
controller.close(instance);
|
||||||
|
res(index);
|
||||||
|
} else {
|
||||||
|
core.drawTip(validation.message);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
onExit: () => {
|
onExit: () => {
|
||||||
res(-1);
|
res(-2);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -21,6 +21,9 @@ import { KeyCode } from '@motajs/client-base';
|
|||||||
import { Progress } from '../components/misc';
|
import { Progress } from '../components/misc';
|
||||||
import { generateBinary } from '@motajs/legacy-common';
|
import { generateBinary } from '@motajs/legacy-common';
|
||||||
import { SetupComponentOptions } from '@motajs/system-ui';
|
import { SetupComponentOptions } from '@motajs/system-ui';
|
||||||
|
import { selectSave } from './save';
|
||||||
|
import { mainUIController } from '@user/client-modules';
|
||||||
|
import { STATUS_BAR_WIDTH, MAP_WIDTH, MAP_HEIGHT } from '../shared';
|
||||||
|
|
||||||
interface ToolbarProps extends DefaultProps {
|
interface ToolbarProps extends DefaultProps {
|
||||||
loc?: ElementLocator;
|
loc?: ElementLocator;
|
||||||
@ -84,7 +87,21 @@ export const PlayingToolbar = defineComponent<
|
|||||||
const book = () => core.openBook(true);
|
const book = () => core.openBook(true);
|
||||||
const tool = () => core.openToolbox(true);
|
const tool = () => core.openToolbox(true);
|
||||||
const fly = () => core.useFly(true);
|
const fly = () => core.useFly(true);
|
||||||
const save = () => core.save(true);
|
const save = async () => {
|
||||||
|
const index = await selectSave(mainUIController, [
|
||||||
|
STATUS_BAR_WIDTH,
|
||||||
|
0,
|
||||||
|
MAP_WIDTH,
|
||||||
|
MAP_HEIGHT
|
||||||
|
]);
|
||||||
|
if (index === -2) {
|
||||||
|
// 如果用户未选择存档,而是关闭了存档。
|
||||||
|
console.log('用户关闭了存档界面。');
|
||||||
|
} else {
|
||||||
|
// 用户选择了一个存档。
|
||||||
|
console.log('用户选择在存档位' + index + '保存。');
|
||||||
|
}
|
||||||
|
};
|
||||||
const load = () => core.load(true);
|
const load = () => core.load(true);
|
||||||
const equip = () => core.openEquipbox(true);
|
const equip = () => core.openEquipbox(true);
|
||||||
const shop = () => core.openQuickShop(true);
|
const shop = () => core.openQuickShop(true);
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@motajs/legacy-common": "workspace:*",
|
"@motajs/legacy-common": "workspace:*",
|
||||||
"@user/data-state": "workspace:*",
|
"@user/data-state": "workspace:*",
|
||||||
"@user/data-base": "workspace:*"
|
"@user/data-base": "workspace:*",
|
||||||
|
"@user/data-utils": "workspace:*"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
import {
|
import {
|
||||||
DamageEnemy,
|
DamageEnemy,
|
||||||
ensureFloorDamage,
|
ensureFloorDamage,
|
||||||
getSingleEnemy,
|
|
||||||
getEnemy,
|
getEnemy,
|
||||||
HeroSkill,
|
HeroSkill,
|
||||||
NightSpecial
|
NightSpecial
|
||||||
} from '@user/data-state';
|
} from '@user/data-state';
|
||||||
import { hook, loading } from '@user/data-base';
|
import { hook } from '@user/data-base';
|
||||||
import { Patch, PatchClass } from '@motajs/legacy-common';
|
import { Patch, PatchClass } from '@motajs/legacy-common';
|
||||||
import { isNil } from 'lodash-es';
|
import { isNil } from 'lodash-es';
|
||||||
|
|
||||||
@ -47,7 +46,7 @@ export function patchBattle() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
// 非强制战斗
|
// 非强制战斗
|
||||||
// @ts-ignore
|
// @ts-expect-error 2.c 重构
|
||||||
if (!core.canBattle(x, y) && !force && !core.status.event.id) {
|
if (!core.canBattle(x, y) && !force && !core.status.event.id) {
|
||||||
core.stopSound();
|
core.stopSound();
|
||||||
core.playSound('操作失败');
|
core.playSound('操作失败');
|
||||||
@ -116,7 +115,7 @@ export function patchBattle() {
|
|||||||
core.clearContinueAutomaticRoute();
|
core.clearContinueAutomaticRoute();
|
||||||
|
|
||||||
// 自动存档
|
// 自动存档
|
||||||
var inAction = core.status.event.id == 'action';
|
const inAction = core.status.event.id === 'action';
|
||||||
if (inAction) {
|
if (inAction) {
|
||||||
core.insertAction(beforeBattle, data.x, data.y);
|
core.insertAction(beforeBattle, data.x, data.y);
|
||||||
core.doAction();
|
core.doAction();
|
||||||
@ -131,7 +130,7 @@ export function patchBattle() {
|
|||||||
|
|
||||||
patch2.add('_action_battle', function (data, x, y, prefix) {
|
patch2.add('_action_battle', function (data, x, y, prefix) {
|
||||||
if (data.id) {
|
if (data.id) {
|
||||||
const enemy = getSingleEnemy(data.id as EnemyIds);
|
// const enemy = getSingleEnemy(data.id as EnemyIds);
|
||||||
// todo: 与不在地图上的怪物战斗
|
// todo: 与不在地图上的怪物战斗
|
||||||
} else {
|
} else {
|
||||||
if (data.floorId != core.status.floorId) {
|
if (data.floorId != core.status.floorId) {
|
||||||
@ -256,7 +255,6 @@ export function patchBattle() {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
loading.once('coreInit', patchBattle);
|
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface Enemys {
|
interface Enemys {
|
||||||
|
@ -1,43 +1,49 @@
|
|||||||
|
import { Patch, PatchClass } from '@motajs/legacy-common';
|
||||||
import { EnemyCollection, ensureFloorDamage } from '@user/data-state';
|
import { EnemyCollection, ensureFloorDamage } from '@user/data-state';
|
||||||
import { formatDamage } from '@user/data-utils';
|
import { formatDamage } from '@user/data-utils';
|
||||||
|
|
||||||
export function init() {
|
export function patchDamage() {
|
||||||
core.control.updateDamage = function (
|
const patch = new Patch(PatchClass.Control);
|
||||||
floorId = core.status.floorId,
|
patch.add(
|
||||||
ctx,
|
'updateDamage',
|
||||||
thumbnail: boolean = false
|
function (
|
||||||
) {
|
floorId = core.status.floorId,
|
||||||
if (!floorId || core.status.gameOver || main.mode !== 'play') return;
|
ctx,
|
||||||
const onMap = ctx == null;
|
thumbnail: boolean = false
|
||||||
const floor = core.status.maps[floorId];
|
) {
|
||||||
|
if (!floorId || core.status.gameOver || main.mode !== 'play')
|
||||||
|
return;
|
||||||
|
const onMap = ctx == null;
|
||||||
|
const floor = core.status.maps[floorId];
|
||||||
|
|
||||||
// 没有怪物手册
|
// 没有怪物手册
|
||||||
// if (!core.hasItem('book')) return;
|
// if (!core.hasItem('book')) return;
|
||||||
core.status.damage.posX = core.bigmap.posX;
|
core.status.damage.posX = core.bigmap.posX;
|
||||||
core.status.damage.posY = core.bigmap.posY;
|
core.status.damage.posY = core.bigmap.posY;
|
||||||
if (!onMap) {
|
if (!onMap) {
|
||||||
const width = core.floors[floorId].width,
|
const width = core.floors[floorId].width,
|
||||||
height = core.floors[floorId].height;
|
height = core.floors[floorId].height;
|
||||||
// 地图过大的缩略图不绘制显伤
|
// 地图过大的缩略图不绘制显伤
|
||||||
if (width * height > core.bigmap.threshold) return;
|
if (width * height > core.bigmap.threshold) return;
|
||||||
|
}
|
||||||
|
// 计算伤害
|
||||||
|
ensureFloorDamage(floorId);
|
||||||
|
|
||||||
|
floor.enemy.extract();
|
||||||
|
floor.enemy.calRealAttribute();
|
||||||
|
floor.enemy.calMapDamage();
|
||||||
|
floor.enemy.emit('calculated');
|
||||||
|
core.status.damage.data = [];
|
||||||
|
|
||||||
|
// floor.enemy.render(true);
|
||||||
|
|
||||||
|
// getItemDetail(floorId, onMap); // 宝石血瓶详细信息
|
||||||
|
if (thumbnail) {
|
||||||
|
renderThumbnailDamage(floor.enemy);
|
||||||
|
core.control.drawDamage(ctx, floorId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// 计算伤害
|
);
|
||||||
ensureFloorDamage(floorId);
|
|
||||||
|
|
||||||
floor.enemy.extract();
|
|
||||||
floor.enemy.calRealAttribute();
|
|
||||||
floor.enemy.calMapDamage();
|
|
||||||
floor.enemy.emit('calculated');
|
|
||||||
core.status.damage.data = [];
|
|
||||||
|
|
||||||
// floor.enemy.render(true);
|
|
||||||
|
|
||||||
// getItemDetail(floorId, onMap); // 宝石血瓶详细信息
|
|
||||||
if (thumbnail) {
|
|
||||||
renderThumbnailDamage(floor.enemy);
|
|
||||||
this.drawDamage(ctx, floorId);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderThumbnailDamage(col: EnemyCollection) {
|
function renderThumbnailDamage(col: EnemyCollection) {
|
@ -1,5 +1,7 @@
|
|||||||
import { patchBattle } from './battle';
|
import { patchBattle } from './battle';
|
||||||
|
import { patchDamage } from './damage';
|
||||||
|
|
||||||
export function patchAll() {
|
export function patchAll() {
|
||||||
patchBattle();
|
patchBattle();
|
||||||
|
patchDamage();
|
||||||
}
|
}
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
import { init as initItemDetail } from './itemDetail';
|
|
||||||
|
|
||||||
initItemDetail();
|
|
||||||
|
|
||||||
export * from './itemDetail';
|
|
3
packages-user/types/package.json
Normal file
3
packages-user/types/package.json
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"name": "@user/types"
|
||||||
|
}
|
85
packages-user/types/src/enemy.ts
Normal file
85
packages-user/types/src/enemy.ts
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
export interface IEnemyInfo {}
|
||||||
|
|
||||||
|
export interface IDamageInfo {}
|
||||||
|
|
||||||
|
export interface IDamageEnemy {
|
||||||
|
/** 原始怪物信息 */
|
||||||
|
readonly enemy: Enemy;
|
||||||
|
/** 该怪物所属的怪物列表 */
|
||||||
|
readonly collection: IEnemyCollection | null;
|
||||||
|
/** 怪物横坐标 */
|
||||||
|
readonly x: number | undefined;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取怪物属性信息
|
||||||
|
*/
|
||||||
|
getEnemyInfo(): IEnemyInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取这个怪物的伤害信息
|
||||||
|
*/
|
||||||
|
getDamageInfo(): IDamageInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IMapDamage {
|
||||||
|
/** 伤害类型 */
|
||||||
|
readonly type: string;
|
||||||
|
/** 伤害值 */
|
||||||
|
readonly damage: number;
|
||||||
|
/** 伤害优先级 */
|
||||||
|
readonly priority: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IMapDamageSummary {
|
||||||
|
/** 该点的总伤害 */
|
||||||
|
readonly totalDamage: number;
|
||||||
|
/** 该点的伤害信息 */
|
||||||
|
readonly damages: IMapDamage[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IEnemyCollection {
|
||||||
|
/** 怪物列表,索引为 x + width * y,值表示该点对应的怪物 */
|
||||||
|
readonly list: Map<number, IDamageEnemy>;
|
||||||
|
|
||||||
|
/** 楼层 id */
|
||||||
|
readonly floorId: FloorIds;
|
||||||
|
/** 楼层宽度 */
|
||||||
|
readonly width: number;
|
||||||
|
/** 楼层高度 */
|
||||||
|
readonly height: number;
|
||||||
|
|
||||||
|
/** 地图伤害 */
|
||||||
|
readonly mapDamage: Map<number, IMapDamageSummary>;
|
||||||
|
|
||||||
|
/** 用于计算本怪物列表中怪物信息的勇士属性 */
|
||||||
|
readonly hero: HeroStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取一点的怪物信息,不存在时返回 null
|
||||||
|
* @param x 怪物横坐标
|
||||||
|
* @param y 怪物纵坐标
|
||||||
|
*/
|
||||||
|
getEnemy(x: number, y: number): IDamageEnemy | null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取一点的地图伤害信息,每一点都包含地图伤害对象,传入地图外坐标时返回 null
|
||||||
|
* @param x 横坐标
|
||||||
|
* @param y 纵坐标
|
||||||
|
*/
|
||||||
|
getMapDamage(x: number, y: number): IMapDamageSummary | null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重置此地图的怪物信息,并重新计算
|
||||||
|
*/
|
||||||
|
refresh(): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 复制这个怪物列表,同时将复制后的列表中勇士属性设为指定值
|
||||||
|
* @param status 新的勇士属性
|
||||||
|
*/
|
||||||
|
with(status: HeroStatus): IEnemyCollection;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IDamageSystem {
|
||||||
|
readonly collections: Map<FloorIds, IEnemyCollection>;
|
||||||
|
}
|
1
packages-user/types/src/index.ts
Normal file
1
packages-user/types/src/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from './enemy';
|
@ -161,7 +161,7 @@ export class Logger {
|
|||||||
const n = Math.floor(code / 50) + 1;
|
const n = Math.floor(code / 50) + 1;
|
||||||
const n2 = code % 50;
|
const n2 = code % 50;
|
||||||
const url = `${location.origin}/_docs/logger/warn/warn${n}.html#warn-code-${n2}`;
|
const url = `${location.origin}/_docs/logger/warn/warn${n}.html#warn-code-${n2}`;
|
||||||
console.warn(`[WARNING Code ${code}] ${text}. See ${url}`);
|
console.warn(`[WARNING Code ${code}] ${text} See ${url}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,9 +118,12 @@ export class Patch<T extends PatchClass> {
|
|||||||
const set = this.patched[patchClass];
|
const set = this.patched[patchClass];
|
||||||
const obj = this.getPatchClass(patchClass);
|
const obj = this.getPatchClass(patchClass);
|
||||||
for (const [key, func] of patch.patches) {
|
for (const [key, func] of patch.patches) {
|
||||||
|
// console.log(key);
|
||||||
|
|
||||||
if (set.has(key)) {
|
if (set.has(key)) {
|
||||||
logger.warn(49, patchName[patchClass], key);
|
logger.warn(49, patchName[patchClass], key);
|
||||||
}
|
}
|
||||||
|
set.add(key);
|
||||||
obj[key] = func;
|
obj[key] = func;
|
||||||
}
|
}
|
||||||
this.patchList.delete(patch);
|
this.patchList.delete(patch);
|
||||||
|
@ -49,13 +49,8 @@ async function buildPackages() {
|
|||||||
const dirs = await fs.readdir(packages);
|
const dirs = await fs.readdir(packages);
|
||||||
for (const name of dirs) {
|
for (const name of dirs) {
|
||||||
const dir = path.join(process.cwd(), name);
|
const dir = path.join(process.cwd(), name);
|
||||||
if (name === 'types') {
|
await fs.emptyDir(dir);
|
||||||
await fs.emptyDir(path.join(dir, 'src'));
|
await fs.rmdir(dir);
|
||||||
await fs.rmdir(path.join(dir, 'src'));
|
|
||||||
} else {
|
|
||||||
await fs.emptyDir(dir);
|
|
||||||
await fs.rmdir(dir);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
"packages-user/**/*.ts",
|
"packages-user/**/*.ts",
|
||||||
"packages-user/**/*.d.ts",
|
"packages-user/**/*.d.ts",
|
||||||
"packages-user/**/*.tsx",
|
"packages-user/**/*.tsx",
|
||||||
"types/**/*.d.ts"
|
"src/types/**/*.d.ts"
|
||||||
],
|
],
|
||||||
"references": [{ "path": "./tsconfig.node.json" }]
|
"references": [{ "path": "./tsconfig.node.json" }]
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user