mirror of
https://github.com/unanmed/ginka-generator.git
synced 2026-05-16 06:11:11 +08:00
153 lines
3.8 KiB
TypeScript
153 lines
3.8 KiB
TypeScript
const numMap: Record<number, number> = {
|
|
0: 0, // 空地
|
|
1: 1, // 墙壁
|
|
21: 2, // 钥匙
|
|
27: 3, // 红宝石
|
|
28: 4, // 蓝宝石
|
|
31: 5, // 血瓶
|
|
81: 6, // 门
|
|
201: 7, // 弱怪
|
|
202: 8, // 中怪
|
|
203: 9, // 强怪
|
|
87: 10, // 楼梯
|
|
88: 10, // 楼梯
|
|
91: 11, // 箭头
|
|
92: 11, // 箭头
|
|
93: 11, // 箭头
|
|
94: 11, // 箭头
|
|
53: 12, // 道具
|
|
29: 13, // 绿宝石
|
|
};
|
|
|
|
const apeiriaMap: Record<number, number> = {
|
|
0: 0, // 空地
|
|
1: 1, // 墙壁
|
|
224: 1, // 吸血鬼,视为墙壁
|
|
21: 2, // 黄钥匙
|
|
22: 2, // 蓝钥匙
|
|
23: 2, // 红钥匙
|
|
27: 3, // 红宝石
|
|
28: 4, // 蓝宝石
|
|
29: 13, // 绿宝石
|
|
31: 5, // 红血瓶
|
|
32: 5, // 蓝血瓶
|
|
33: 5, // 绿血瓶
|
|
34: 5, // 黄血瓶
|
|
81: 6, // 门
|
|
201: 7, // 弱怪
|
|
202: 8, // 中怪
|
|
203: 9, // 强怪
|
|
87: 10, // 楼梯
|
|
88: 10, // 楼梯
|
|
161: 11, // 箭头
|
|
162: 11, // 箭头
|
|
163: 11, // 箭头
|
|
164: 11, // 箭头
|
|
53: 12, // 幸运金币
|
|
50: 12, // 飞
|
|
49: 12, // 炸
|
|
47: 12 // 破
|
|
};
|
|
|
|
export interface ApeiriaEnemy {
|
|
hp: number;
|
|
atk: number;
|
|
def: number;
|
|
}
|
|
|
|
function convert(
|
|
map: number[][],
|
|
[x, y, w, h]: [number, number, number, number],
|
|
name: string,
|
|
floorId: string,
|
|
numMap: Record<number, number>
|
|
) {
|
|
const clipped: number[][] = [];
|
|
|
|
for (let nx = x; nx < x + w; nx++) {
|
|
const row: number[] = [];
|
|
for (let ny = y; ny < y + h; ny++) {
|
|
const num = numMap[map[nx][ny]];
|
|
if (num === void 0) {
|
|
console.log(
|
|
`⚠️ 魔塔 ${name} 的楼层 ${floorId} 中出现未知图块类型:${map[nx][ny]}`
|
|
);
|
|
}
|
|
row.push(num ?? 0);
|
|
}
|
|
clipped.push(row);
|
|
}
|
|
|
|
return clipped;
|
|
}
|
|
|
|
function convertApeiriaEnemy(
|
|
map: number[][],
|
|
enemyMap: Record<number, ApeiriaEnemy>
|
|
) {
|
|
const width = map[0].length;
|
|
const height = map.length;
|
|
const enemy = new Set<ApeiriaEnemy>();
|
|
for (let ny = 0; ny < height; ny++) {
|
|
for (let nx = 0; nx < width; nx++) {
|
|
const tile = map[ny][nx];
|
|
if (tile > 200 && tile <= 280 && tile !== 224) {
|
|
// 这些是怪物
|
|
if (enemyMap[tile]) enemy.add(enemyMap[tile]);
|
|
}
|
|
}
|
|
}
|
|
const attrs = [...enemy].map(v => (v.atk + v.def) * v.hp);
|
|
const maxAttr = Math.max(...attrs);
|
|
const minAttr = Math.min(...attrs);
|
|
const delta = maxAttr - minAttr;
|
|
for (let ny = 0; ny < height; ny++) {
|
|
for (let nx = 0; nx < width; nx++) {
|
|
const tile = map[ny][nx];
|
|
if (tile > 200 && tile <= 280 && tile !== 224) {
|
|
// 这些是怪物
|
|
if (enemyMap[tile]) {
|
|
// 替换为弱怪/中怪/强怪
|
|
const enemy = enemyMap[tile];
|
|
const attr = (enemy.atk + enemy.def) * enemy.hp;
|
|
const ad = attr - minAttr;
|
|
if (ad < delta / 3) {
|
|
map[ny][nx] = 201;
|
|
} else if (ad < (delta * 2) / 3) {
|
|
map[ny][nx] = 202;
|
|
} else {
|
|
map[ny][nx] = 203;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return map;
|
|
}
|
|
|
|
export function convertFloor(
|
|
map: number[][],
|
|
clip: [number, number, number, number],
|
|
name: string,
|
|
floorId: string
|
|
) {
|
|
return convert(map, clip, name, floorId, numMap);
|
|
}
|
|
|
|
export function convertApeiriaMap(
|
|
map: number[][],
|
|
clip: [number, number, number, number],
|
|
name: string,
|
|
floorId: string,
|
|
enemyMap: Record<number, ApeiriaEnemy>
|
|
) {
|
|
return convert(
|
|
convertApeiriaEnemy(map, enemyMap),
|
|
clip,
|
|
name,
|
|
floorId,
|
|
apeiriaMap
|
|
);
|
|
}
|