2022-11-19 13:07:42 +08:00
|
|
|
|
///<reference path="../../src/types/core.d.ts" />
|
|
|
|
|
|
2022-11-13 18:02:05 +08:00
|
|
|
|
var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
init: function () {
|
2022-12-29 13:39:40 +08:00
|
|
|
|
this._afterLoadResources = function () {
|
2022-12-30 11:06:46 +08:00
|
|
|
|
if (!main.replayChecking && main.mode === 'play') {
|
|
|
|
|
main.forward();
|
2022-12-29 23:08:44 +08:00
|
|
|
|
core.resetSettings();
|
2023-01-04 11:59:50 +08:00
|
|
|
|
core.plugin.showMarkedEnemy.value = true;
|
2022-12-29 23:08:44 +08:00
|
|
|
|
}
|
2022-12-29 13:39:40 +08:00
|
|
|
|
};
|
2022-11-13 18:02:05 +08:00
|
|
|
|
},
|
2022-11-14 17:11:23 +08:00
|
|
|
|
sprite: function () {
|
2022-11-13 18:02:05 +08:00
|
|
|
|
const sprites = {};
|
|
|
|
|
|
|
|
|
|
// 终于能用es6了(恼
|
|
|
|
|
class Sprite {
|
|
|
|
|
constructor(x, y, w, h, z, reference, name) {
|
|
|
|
|
this.x = x;
|
|
|
|
|
this.y = y;
|
|
|
|
|
this.width = w;
|
|
|
|
|
this.height = h;
|
|
|
|
|
this.zIndex = z;
|
|
|
|
|
this.reference = reference;
|
|
|
|
|
/** @type {HTMLCanvasElement} */
|
|
|
|
|
this.canvas = null;
|
|
|
|
|
/** @type {CanvasRenderingContext2D} */
|
|
|
|
|
this.context = null;
|
|
|
|
|
this.count = 0;
|
|
|
|
|
this.name = name;
|
|
|
|
|
this.key = [];
|
|
|
|
|
this.init();
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-14 17:11:23 +08:00
|
|
|
|
init() {
|
2022-11-13 18:02:05 +08:00
|
|
|
|
const name = this.name || `_sprite_${Sprite.count}`;
|
|
|
|
|
this.name = name;
|
|
|
|
|
if (this.reference === 'window') {
|
|
|
|
|
const canvas = document.createElement('canvas');
|
|
|
|
|
this.canvas = canvas;
|
|
|
|
|
this.context = canvas.getContext('2d');
|
|
|
|
|
canvas.width = this.width;
|
|
|
|
|
canvas.height = this.height;
|
|
|
|
|
canvas.style.width = this.width + 'px';
|
|
|
|
|
canvas.style.height = this.height + 'px';
|
|
|
|
|
canvas.style.position = 'absolute';
|
|
|
|
|
canvas.style.top = this.y + 'px';
|
|
|
|
|
canvas.style.left = this.x + 'px';
|
|
|
|
|
canvas.style.zIndex = this.zIndex.toString();
|
|
|
|
|
document.body.appendChild(canvas);
|
|
|
|
|
} else {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
this.context = core.createCanvas(
|
|
|
|
|
name,
|
|
|
|
|
this.x,
|
|
|
|
|
this.y,
|
|
|
|
|
this.width,
|
|
|
|
|
this.height,
|
|
|
|
|
this.zIndex
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
this.canvas = this.context.canvas;
|
|
|
|
|
this.count = Sprite.count;
|
|
|
|
|
this.canvas.style.pointerEvents = 'auto';
|
|
|
|
|
}
|
|
|
|
|
Sprite.count++;
|
|
|
|
|
sprites[this.name] = this;
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-14 17:11:23 +08:00
|
|
|
|
setCss(css) {
|
2022-11-13 18:02:05 +08:00
|
|
|
|
css = css.replace('\n', ';').replace(';;', ';');
|
|
|
|
|
const effects = css.split(';');
|
|
|
|
|
const canvas = this.canvas;
|
|
|
|
|
effects.forEach(v => {
|
|
|
|
|
const content = v.split(':');
|
|
|
|
|
let name = content[0];
|
|
|
|
|
let value = content[1];
|
2022-11-14 17:11:23 +08:00
|
|
|
|
name = name
|
|
|
|
|
.trim()
|
|
|
|
|
.split('-')
|
|
|
|
|
.reduce((pre, curr, i, a) => {
|
|
|
|
|
if (i === 0 && curr !== '') return curr;
|
|
|
|
|
if (a[0] === '' && i === 1) return curr;
|
|
|
|
|
return pre + curr.toUpperCase()[0] + curr.slice(1);
|
|
|
|
|
}, '');
|
|
|
|
|
if (name in canvas.style) canvas.style[name] = value;
|
2022-11-13 18:02:05 +08:00
|
|
|
|
});
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-14 17:11:23 +08:00
|
|
|
|
move(x, y, isDelta) {
|
|
|
|
|
if (x !== undefined && x !== null) this.x = x;
|
|
|
|
|
if (y !== undefined && y !== null) this.y = y;
|
2022-11-13 18:02:05 +08:00
|
|
|
|
if (this.reference === 'window') {
|
|
|
|
|
var ele = this.canvas;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
ele.style.left =
|
|
|
|
|
x + (isDelta ? parseFloat(ele.style.left) : 0) + 'px';
|
|
|
|
|
ele.style.top =
|
|
|
|
|
y + (isDelta ? parseFloat(ele.style.top) : 0) + 'px';
|
|
|
|
|
} else core.relocateCanvas(this.context, x, y, isDelta);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-14 17:11:23 +08:00
|
|
|
|
resize(w, h, styleOnly) {
|
|
|
|
|
if (w !== undefined && w !== null) this.width = w;
|
|
|
|
|
if (h !== undefined && h !== null) this.height = h;
|
2022-11-13 18:02:05 +08:00
|
|
|
|
if (this.reference === 'window') {
|
|
|
|
|
const ele = this.canvas;
|
|
|
|
|
ele.style.width = w + 'px';
|
|
|
|
|
ele.style.height = h + 'px';
|
|
|
|
|
if (!styleOnly) {
|
|
|
|
|
ele.width = w;
|
|
|
|
|
ele.height = h;
|
|
|
|
|
}
|
2022-11-14 17:11:23 +08:00
|
|
|
|
} else core.resizeCanvas(this.context, w, h, styleOnly);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-14 17:11:23 +08:00
|
|
|
|
rotate(angle, cx, cy) {
|
2022-11-13 18:02:05 +08:00
|
|
|
|
if (this.reference === 'window') {
|
|
|
|
|
const left = this.x;
|
|
|
|
|
const top = this.y;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
this.canvas.style.transformOrigin =
|
|
|
|
|
cx - left + 'px ' + (cy - top) + 'px';
|
2022-11-13 18:02:05 +08:00
|
|
|
|
if (angle === 0) {
|
|
|
|
|
canvas.style.transform = '';
|
|
|
|
|
} else {
|
|
|
|
|
canvas.style.transform = 'rotate(' + angle + 'deg)';
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
core.rotateCanvas(this.context, angle, cx, cy);
|
|
|
|
|
}
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-14 17:11:23 +08:00
|
|
|
|
destroy() {
|
2022-11-13 18:02:05 +08:00
|
|
|
|
if (this.reference === 'window') {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
if (this.canvas) document.body.removeChild(this.canvas);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
} else {
|
|
|
|
|
core.deleteCanvas(this.name);
|
|
|
|
|
}
|
2022-11-14 17:11:23 +08:00
|
|
|
|
this.key?.forEach(v =>
|
|
|
|
|
document.removeEventListener(v[0], v[1])
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
sprites[this.name] = void 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 类似样板registerAction接口,但是是以该sprite的左上角为(0,0)计算的
|
2022-11-14 17:11:23 +08:00
|
|
|
|
* @param {keyof HTMLElementEventMap} type
|
|
|
|
|
* @param {(...param: any[]) => void} handler
|
2022-11-13 18:02:05 +08:00
|
|
|
|
*/
|
2022-11-14 17:11:23 +08:00
|
|
|
|
on(type, handler) {
|
|
|
|
|
if (this.reference !== 'game')
|
|
|
|
|
throw new ReferenceError(
|
|
|
|
|
`当sprite的reference为window时,不可使用该函数`
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
const mouse = [
|
2022-11-14 17:11:23 +08:00
|
|
|
|
'auxclick',
|
|
|
|
|
'click',
|
|
|
|
|
'contextmenu',
|
|
|
|
|
'dblclick',
|
|
|
|
|
'mousedown',
|
|
|
|
|
'mouseup',
|
|
|
|
|
'mouseenter',
|
|
|
|
|
'mouseleave',
|
|
|
|
|
'mousemove',
|
|
|
|
|
'mouseout',
|
|
|
|
|
'mouseover'
|
2022-11-13 18:02:05 +08:00
|
|
|
|
];
|
2022-11-14 17:11:23 +08:00
|
|
|
|
const key = ['keydown', 'keypress', 'keyup'];
|
2022-11-13 18:02:05 +08:00
|
|
|
|
const touch = [
|
2022-11-14 17:11:23 +08:00
|
|
|
|
'touchstart',
|
|
|
|
|
'touchend',
|
|
|
|
|
'touchcancel',
|
|
|
|
|
'touchmove'
|
|
|
|
|
];
|
2022-11-13 18:02:05 +08:00
|
|
|
|
if (mouse.includes(type)) {
|
|
|
|
|
this.addEventListener(type, e => {
|
|
|
|
|
const px = e.offsetX / core.domStyle.scale,
|
|
|
|
|
py = e.offsetY / core.domStyle.scale;
|
|
|
|
|
handler(px, py);
|
2022-11-14 17:11:23 +08:00
|
|
|
|
});
|
2022-11-13 18:02:05 +08:00
|
|
|
|
} else if (type === 'wheel') {
|
|
|
|
|
this.addEventListener('wheel', e => {
|
|
|
|
|
handler(e.deltaY, e.deltaX, e.deltaZ);
|
|
|
|
|
});
|
|
|
|
|
} else if (key.includes(type)) {
|
|
|
|
|
// 键盘事件只能加到document上
|
|
|
|
|
const listener = e => {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
handler(
|
|
|
|
|
e.key,
|
|
|
|
|
e.keyCode,
|
|
|
|
|
e.altKey,
|
|
|
|
|
e.ctrlKey,
|
|
|
|
|
e.shiftKey
|
|
|
|
|
);
|
|
|
|
|
};
|
2022-11-13 18:02:05 +08:00
|
|
|
|
this.key.push([type, listener]);
|
2022-11-14 17:11:23 +08:00
|
|
|
|
document.addEventListener(type, listener);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
} else if (touch.includes(type)) {
|
|
|
|
|
this.addEventListener(type, e => {
|
|
|
|
|
/** @type {TouchList} */
|
|
|
|
|
const touches = e.touches;
|
|
|
|
|
const locs = [];
|
|
|
|
|
for (let i = 0; i < touches.length; i++) {
|
|
|
|
|
const t = touches[i];
|
2022-11-14 17:11:23 +08:00
|
|
|
|
const { x, y } = core.actions._getClickLoc(
|
|
|
|
|
t.clientX,
|
|
|
|
|
t.clientY
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
const px = x / core.domStyle.scale,
|
|
|
|
|
py = y / core.domStyle.scale;
|
|
|
|
|
locs.push([px, py]);
|
|
|
|
|
}
|
|
|
|
|
handler(...locs);
|
2022-11-14 17:11:23 +08:00
|
|
|
|
});
|
2022-11-13 18:02:05 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-14 17:11:23 +08:00
|
|
|
|
addEventListener() {
|
2022-11-13 18:02:05 +08:00
|
|
|
|
this.canvas.addEventListener.apply(this.canvas, arguments);
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-14 17:11:23 +08:00
|
|
|
|
removeEventListener() {
|
2022-11-13 18:02:05 +08:00
|
|
|
|
this.canvas.removeEventListener.apply(this.canvas, arguments);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.getSprite = function (name) {
|
|
|
|
|
const s = sprites[name];
|
|
|
|
|
if (!s) throw new ReferenceError(`不能获得不存在的sprite`);
|
|
|
|
|
return sprites[name];
|
2022-11-14 17:11:23 +08:00
|
|
|
|
};
|
2022-11-13 18:02:05 +08:00
|
|
|
|
|
|
|
|
|
Sprite.count = 0;
|
|
|
|
|
|
|
|
|
|
window.Sprite = Sprite;
|
|
|
|
|
},
|
2022-11-14 17:11:23 +08:00
|
|
|
|
shop: function () {
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 【全局商店】相关的功能
|
2022-11-14 17:11:23 +08:00
|
|
|
|
//
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 打开一个全局商店
|
|
|
|
|
// shopId:要打开的商店id;noRoute:是否不计入录像
|
|
|
|
|
this.openShop = function (shopId, noRoute) {
|
|
|
|
|
var shop = core.status.shops[shopId];
|
|
|
|
|
// Step 1: 检查能否打开此商店
|
|
|
|
|
if (!this.canOpenShop(shopId)) {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.drawTip('该商店尚未开启');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Step 2: (如有必要)记录打开商店的脚本事件
|
|
|
|
|
if (!noRoute) {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.status.route.push('shop:' + shopId);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Step 3: 检查道具商店 or 公共事件
|
|
|
|
|
if (shop.item) {
|
|
|
|
|
if (core.openItemShop) {
|
|
|
|
|
core.openItemShop(shopId);
|
|
|
|
|
} else {
|
|
|
|
|
core.playSound('操作失败');
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.insertAction(
|
|
|
|
|
'道具商店插件不存在!请检查是否存在该插件!'
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (shop.commonEvent) {
|
|
|
|
|
core.insertCommonEvent(shop.commonEvent, shop.args);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-14 17:11:23 +08:00
|
|
|
|
// Step 4: 执行标准公共商店
|
2022-11-13 18:02:05 +08:00
|
|
|
|
core.insertAction(this._convertShop(shop));
|
|
|
|
|
return true;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
};
|
2022-11-13 18:02:05 +08:00
|
|
|
|
|
|
|
|
|
////// 将一个全局商店转变成可预览的公共事件 //////
|
|
|
|
|
this._convertShop = function (shop) {
|
|
|
|
|
return [
|
|
|
|
|
{
|
2022-11-14 17:11:23 +08:00
|
|
|
|
type: 'function',
|
|
|
|
|
function: "() => {core.setFlag('@temp@shop', true);}"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
type: 'while',
|
|
|
|
|
condition: 'true',
|
|
|
|
|
data: [
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 检测能否访问该商店
|
|
|
|
|
{
|
2022-11-14 17:11:23 +08:00
|
|
|
|
type: 'if',
|
|
|
|
|
condition: "core.isShopVisited('" + shop.id + "')",
|
|
|
|
|
true: [
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 可以访问,直接插入执行效果
|
2022-11-14 17:11:23 +08:00
|
|
|
|
{
|
|
|
|
|
type: 'function',
|
|
|
|
|
function:
|
|
|
|
|
"() => { core.plugin._convertShop_replaceChoices('" +
|
|
|
|
|
shop.id +
|
|
|
|
|
"', false) }"
|
|
|
|
|
}
|
2022-11-13 18:02:05 +08:00
|
|
|
|
],
|
2022-11-14 17:11:23 +08:00
|
|
|
|
false: [
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 不能访问的情况下:检测能否预览
|
|
|
|
|
{
|
2022-11-14 17:11:23 +08:00
|
|
|
|
type: 'if',
|
|
|
|
|
condition: shop.disablePreview,
|
|
|
|
|
true: [
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 不可预览,提示并退出
|
2022-11-14 17:11:23 +08:00
|
|
|
|
{ type: 'playSound', name: '操作失败' },
|
|
|
|
|
'当前无法访问该商店!',
|
|
|
|
|
{ type: 'break' }
|
2022-11-13 18:02:05 +08:00
|
|
|
|
],
|
2022-11-14 17:11:23 +08:00
|
|
|
|
false: [
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 可以预览:将商店全部内容进行替换
|
2022-11-14 17:11:23 +08:00
|
|
|
|
{
|
|
|
|
|
type: 'tip',
|
|
|
|
|
text: '当前处于预览模式,不可购买'
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
type: 'function',
|
|
|
|
|
function:
|
|
|
|
|
"() => { core.plugin._convertShop_replaceChoices('" +
|
|
|
|
|
shop.id +
|
|
|
|
|
"', true) }"
|
|
|
|
|
}
|
2022-11-13 18:02:05 +08:00
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
},
|
2022-11-14 17:11:23 +08:00
|
|
|
|
{
|
|
|
|
|
type: 'function',
|
|
|
|
|
function: "() => {core.removeFlag('@temp@shop');}"
|
|
|
|
|
}
|
2022-11-13 18:02:05 +08:00
|
|
|
|
];
|
2022-11-14 17:11:23 +08:00
|
|
|
|
};
|
2022-11-13 18:02:05 +08:00
|
|
|
|
|
|
|
|
|
this._convertShop_replaceChoices = function (shopId, previewMode) {
|
|
|
|
|
var shop = core.status.shops[shopId];
|
2022-11-14 17:11:23 +08:00
|
|
|
|
var choices = (shop.choices || [])
|
|
|
|
|
.filter(choice => {
|
|
|
|
|
if (choice.condition == null || choice.condition == '')
|
|
|
|
|
return true;
|
|
|
|
|
try {
|
|
|
|
|
return core.calValue(choice.condition);
|
|
|
|
|
} catch (e) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.map(choice => {
|
|
|
|
|
var ableToBuy = core.calValue(choice.need);
|
|
|
|
|
return {
|
|
|
|
|
text: choice.text,
|
|
|
|
|
icon: choice.icon,
|
|
|
|
|
color:
|
|
|
|
|
ableToBuy && !previewMode
|
|
|
|
|
? choice.color
|
|
|
|
|
: [153, 153, 153, 1],
|
|
|
|
|
action:
|
|
|
|
|
ableToBuy && !previewMode
|
|
|
|
|
? [{ type: 'playSound', name: '确定' }].concat(
|
|
|
|
|
choice.action
|
|
|
|
|
)
|
|
|
|
|
: [
|
|
|
|
|
{ type: 'playSound', name: '操作失败' },
|
|
|
|
|
{
|
|
|
|
|
type: 'tip',
|
|
|
|
|
text: previewMode
|
|
|
|
|
? '预览模式下不可购买'
|
|
|
|
|
: '购买条件不足'
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
};
|
|
|
|
|
})
|
|
|
|
|
.concat({ text: '离开', action: [{ type: 'break' }] });
|
|
|
|
|
core.insertAction({
|
|
|
|
|
type: 'choices',
|
|
|
|
|
text: shop.text,
|
|
|
|
|
choices: choices
|
|
|
|
|
});
|
|
|
|
|
};
|
2022-11-13 18:02:05 +08:00
|
|
|
|
|
|
|
|
|
/// 是否访问过某个快捷商店
|
|
|
|
|
this.isShopVisited = function (id) {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
if (!core.hasFlag('__shops__')) core.setFlag('__shops__', {});
|
|
|
|
|
var shops = core.getFlag('__shops__');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
if (!shops[id]) shops[id] = {};
|
|
|
|
|
return shops[id].visited;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
};
|
2022-11-13 18:02:05 +08:00
|
|
|
|
|
|
|
|
|
/// 当前应当显示的快捷商店列表
|
|
|
|
|
this.listShopIds = function () {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
return Object.keys(core.status.shops).filter(id => {
|
|
|
|
|
return (
|
|
|
|
|
core.isShopVisited(id) || !core.status.shops[id].mustEnable
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
});
|
2022-11-14 17:11:23 +08:00
|
|
|
|
};
|
2022-11-13 18:02:05 +08:00
|
|
|
|
|
|
|
|
|
/// 是否能够打开某个商店
|
|
|
|
|
this.canOpenShop = function (id) {
|
|
|
|
|
if (this.isShopVisited(id)) return true;
|
|
|
|
|
var shop = core.status.shops[id];
|
|
|
|
|
if (shop.item || shop.commonEvent || shop.mustEnable) return false;
|
|
|
|
|
return true;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
};
|
2022-11-13 18:02:05 +08:00
|
|
|
|
|
|
|
|
|
/// 启用或禁用某个快捷商店
|
|
|
|
|
this.setShopVisited = function (id, visited) {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
if (!core.hasFlag('__shops__')) core.setFlag('__shops__', {});
|
|
|
|
|
var shops = core.getFlag('__shops__');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
if (!shops[id]) shops[id] = {};
|
|
|
|
|
if (visited) shops[id].visited = true;
|
|
|
|
|
else delete shops[id].visited;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
};
|
2022-11-13 18:02:05 +08:00
|
|
|
|
|
|
|
|
|
/// 能否使用快捷商店
|
2022-12-30 00:55:03 +08:00
|
|
|
|
this.canUseQuickShop = function () {
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 如果返回一个字符串,表示不能,字符串为不能使用的提示
|
|
|
|
|
// 返回null代表可以使用
|
|
|
|
|
|
|
|
|
|
// 检查当前楼层的canUseQuickShop选项是否为false
|
|
|
|
|
if (core.status.thisMap.canUseQuickShop === false)
|
|
|
|
|
return '当前楼层不能使用快捷商店。';
|
|
|
|
|
return null;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
};
|
2022-11-13 18:02:05 +08:00
|
|
|
|
|
|
|
|
|
/// 允许商店X键退出
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.registerAction(
|
|
|
|
|
'keyUp',
|
|
|
|
|
'shops',
|
|
|
|
|
keycode => {
|
|
|
|
|
if (
|
|
|
|
|
!core.status.lockControl ||
|
|
|
|
|
!core.hasFlag('@temp@shop') ||
|
|
|
|
|
core.status.event.id != 'action'
|
|
|
|
|
)
|
|
|
|
|
return false;
|
|
|
|
|
if (core.status.event.data.type != 'choices') return false;
|
|
|
|
|
var data = core.status.event.data.current;
|
|
|
|
|
var choices = data.choices;
|
|
|
|
|
var topIndex =
|
|
|
|
|
core.actions.HSIZE -
|
|
|
|
|
parseInt((choices.length - 1) / 2) +
|
|
|
|
|
(core.status.event.ui.offset || 0);
|
|
|
|
|
if (keycode == 88 || keycode == 27) {
|
|
|
|
|
// X, ESC
|
|
|
|
|
core.actions._clickAction(
|
|
|
|
|
core.actions.HSIZE,
|
|
|
|
|
topIndex + choices.length - 1
|
|
|
|
|
);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
if (keycode == 13 || keycode == 32) return true;
|
|
|
|
|
return false;
|
|
|
|
|
},
|
|
|
|
|
60
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
|
|
|
|
|
/// 允许长按空格或回车连续执行操作
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.registerAction(
|
|
|
|
|
'keyDown',
|
|
|
|
|
'shops',
|
|
|
|
|
keycode => {
|
|
|
|
|
if (
|
|
|
|
|
!core.status.lockControl ||
|
|
|
|
|
!core.hasFlag('@temp@shop') ||
|
|
|
|
|
core.status.event.id != 'action'
|
|
|
|
|
)
|
|
|
|
|
return false;
|
|
|
|
|
if (core.status.event.data.type != 'choices') return false;
|
|
|
|
|
var data = core.status.event.data.current;
|
|
|
|
|
var choices = data.choices;
|
|
|
|
|
var topIndex =
|
|
|
|
|
core.actions.HSIZE -
|
|
|
|
|
parseInt((choices.length - 1) / 2) +
|
|
|
|
|
(core.status.event.ui.offset || 0);
|
|
|
|
|
if (keycode == 13 || keycode == 32) {
|
|
|
|
|
// Space, Enter
|
|
|
|
|
core.actions._clickAction(
|
|
|
|
|
core.actions.HSIZE,
|
|
|
|
|
topIndex + core.status.event.selection
|
|
|
|
|
);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
},
|
|
|
|
|
60
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
|
|
|
|
|
// 允许长按屏幕连续执行操作
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.registerAction(
|
|
|
|
|
'longClick',
|
|
|
|
|
'shops',
|
2022-12-30 00:55:03 +08:00
|
|
|
|
(x, y) => {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
if (
|
|
|
|
|
!core.status.lockControl ||
|
|
|
|
|
!core.hasFlag('@temp@shop') ||
|
|
|
|
|
core.status.event.id != 'action'
|
|
|
|
|
)
|
|
|
|
|
return false;
|
|
|
|
|
if (core.status.event.data.type != 'choices') return false;
|
|
|
|
|
var data = core.status.event.data.current;
|
|
|
|
|
var choices = data.choices;
|
|
|
|
|
var topIndex =
|
|
|
|
|
core.actions.HSIZE -
|
|
|
|
|
parseInt((choices.length - 1) / 2) +
|
|
|
|
|
(core.status.event.ui.offset || 0);
|
|
|
|
|
if (
|
|
|
|
|
x >= core.actions.CHOICES_LEFT &&
|
|
|
|
|
x <= core.actions.CHOICES_RIGHT &&
|
|
|
|
|
y >= topIndex &&
|
|
|
|
|
y < topIndex + choices.length
|
|
|
|
|
) {
|
|
|
|
|
core.actions._clickAction(x, y);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
},
|
|
|
|
|
60
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
},
|
2022-11-14 17:11:23 +08:00
|
|
|
|
removeMap: function () {
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 高层塔砍层插件,删除后不会存入存档,不可浏览地图也不可飞到。
|
|
|
|
|
// 推荐用法:
|
|
|
|
|
// 对于超高层或分区域塔,当在1区时将2区以后的地图删除;1区结束时恢复2区,进二区时删除1区地图,以此类推
|
|
|
|
|
// 这样可以大幅减少存档空间,以及加快存读档速度
|
|
|
|
|
|
|
|
|
|
// 删除楼层
|
|
|
|
|
// core.removeMaps("MT1", "MT300") 删除MT1~MT300之间的全部层
|
|
|
|
|
// core.removeMaps("MT10") 只删除MT10层
|
2023-01-05 22:21:40 +08:00
|
|
|
|
this.removeMaps = function (fromId, toId, force) {
|
2022-11-13 18:02:05 +08:00
|
|
|
|
toId = toId || fromId;
|
|
|
|
|
var fromIndex = core.floorIds.indexOf(fromId),
|
|
|
|
|
toIndex = core.floorIds.indexOf(toId);
|
|
|
|
|
if (toIndex < 0) toIndex = core.floorIds.length - 1;
|
|
|
|
|
flags.__visited__ = flags.__visited__ || {};
|
|
|
|
|
flags.__removed__ = flags.__removed__ || [];
|
|
|
|
|
flags.__disabled__ = flags.__disabled__ || {};
|
|
|
|
|
flags.__leaveLoc__ = flags.__leaveLoc__ || {};
|
2023-01-05 22:21:40 +08:00
|
|
|
|
flags.__forceDelete__ ??= {};
|
2023-01-06 21:51:58 +08:00
|
|
|
|
let deleted = false;
|
2022-11-13 18:02:05 +08:00
|
|
|
|
for (var i = fromIndex; i <= toIndex; ++i) {
|
|
|
|
|
var floorId = core.floorIds[i];
|
|
|
|
|
if (core.status.maps[floorId].deleted) continue;
|
|
|
|
|
delete flags.__visited__[floorId];
|
|
|
|
|
flags.__removed__.push(floorId);
|
|
|
|
|
delete flags.__disabled__[floorId];
|
|
|
|
|
delete flags.__leaveLoc__[floorId];
|
2022-11-14 17:11:23 +08:00
|
|
|
|
(core.status.autoEvents || []).forEach(event => {
|
2022-11-13 18:02:05 +08:00
|
|
|
|
if (event.floorId == floorId && event.currentFloor) {
|
|
|
|
|
core.autoEventExecuting(event.symbol, false);
|
|
|
|
|
core.autoEventExecuted(event.symbol, false);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
core.status.maps[floorId].deleted = true;
|
|
|
|
|
core.status.maps[floorId].canFlyTo = false;
|
|
|
|
|
core.status.maps[floorId].canFlyFrom = false;
|
|
|
|
|
core.status.maps[floorId].cannotViewMap = true;
|
2023-01-05 22:21:40 +08:00
|
|
|
|
if (force) {
|
|
|
|
|
core.status.maps[floorId].forceDelete = true;
|
|
|
|
|
flags.__forceDelete__[floorId] = true;
|
|
|
|
|
}
|
2023-01-09 20:36:40 +08:00
|
|
|
|
deleteFlags(floorId);
|
2023-01-06 21:51:58 +08:00
|
|
|
|
deleted = true;
|
|
|
|
|
}
|
|
|
|
|
if (deleted && !main.replayChecking) {
|
|
|
|
|
core.splitArea();
|
2022-11-13 18:02:05 +08:00
|
|
|
|
}
|
2022-11-14 17:11:23 +08:00
|
|
|
|
};
|
2022-11-13 18:02:05 +08:00
|
|
|
|
|
2023-01-09 20:36:40 +08:00
|
|
|
|
function deleteFlags(floorId) {
|
|
|
|
|
delete flags[`jump_${floorId}`];
|
|
|
|
|
delete flags[`inte_${floorId}`];
|
|
|
|
|
delete flags[`loop_${floorId}`];
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 恢复楼层
|
|
|
|
|
// core.resumeMaps("MT1", "MT300") 恢复MT1~MT300之间的全部层
|
|
|
|
|
// core.resumeMaps("MT10") 只恢复MT10层
|
|
|
|
|
this.resumeMaps = function (fromId, toId) {
|
|
|
|
|
toId = toId || fromId;
|
|
|
|
|
var fromIndex = core.floorIds.indexOf(fromId),
|
|
|
|
|
toIndex = core.floorIds.indexOf(toId);
|
|
|
|
|
if (toIndex < 0) toIndex = core.floorIds.length - 1;
|
|
|
|
|
flags.__removed__ = flags.__removed__ || [];
|
|
|
|
|
for (var i = fromIndex; i <= toIndex; ++i) {
|
|
|
|
|
var floorId = core.floorIds[i];
|
|
|
|
|
if (!core.status.maps[floorId].deleted) continue;
|
2023-01-05 22:21:40 +08:00
|
|
|
|
if (
|
|
|
|
|
core.status.maps[floorId].forceDelete ||
|
|
|
|
|
flags.__forceDelete__[floorId]
|
|
|
|
|
)
|
|
|
|
|
continue;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
flags.__removed__ = flags.__removed__.filter(f => {
|
|
|
|
|
return f != floorId;
|
|
|
|
|
});
|
2022-11-13 18:02:05 +08:00
|
|
|
|
core.status.maps[floorId] = core.loadFloor(floorId);
|
|
|
|
|
}
|
2022-11-14 17:11:23 +08:00
|
|
|
|
};
|
2022-11-13 18:02:05 +08:00
|
|
|
|
|
|
|
|
|
// 分区砍层相关
|
2022-11-14 17:11:23 +08:00
|
|
|
|
var inAnyPartition = floorId => {
|
2022-11-13 18:02:05 +08:00
|
|
|
|
var inPartition = false;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
(core.floorPartitions || []).forEach(floor => {
|
2022-11-13 18:02:05 +08:00
|
|
|
|
var fromIndex = core.floorIds.indexOf(floor[0]);
|
|
|
|
|
var toIndex = core.floorIds.indexOf(floor[1]);
|
|
|
|
|
var index = core.floorIds.indexOf(floorId);
|
|
|
|
|
if (fromIndex < 0 || index < 0) return;
|
|
|
|
|
if (toIndex < 0) toIndex = core.floorIds.length - 1;
|
|
|
|
|
if (index >= fromIndex && index <= toIndex) inPartition = true;
|
|
|
|
|
});
|
|
|
|
|
return inPartition;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
};
|
2022-11-13 18:02:05 +08:00
|
|
|
|
|
|
|
|
|
// 分区砍层
|
|
|
|
|
this.autoRemoveMaps = function (floorId) {
|
|
|
|
|
if (main.mode != 'play' || !inAnyPartition(floorId)) return;
|
|
|
|
|
// 根据分区信息自动砍层与恢复
|
2022-11-14 17:11:23 +08:00
|
|
|
|
(core.floorPartitions || []).forEach(floor => {
|
2022-11-13 18:02:05 +08:00
|
|
|
|
var fromIndex = core.floorIds.indexOf(floor[0]);
|
|
|
|
|
var toIndex = core.floorIds.indexOf(floor[1]);
|
|
|
|
|
var index = core.floorIds.indexOf(floorId);
|
|
|
|
|
if (fromIndex < 0 || index < 0) return;
|
|
|
|
|
if (toIndex < 0) toIndex = core.floorIds.length - 1;
|
|
|
|
|
if (index >= fromIndex && index <= toIndex) {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.resumeMaps(
|
|
|
|
|
core.floorIds[fromIndex],
|
|
|
|
|
core.floorIds[toIndex]
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
} else {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.removeMaps(
|
|
|
|
|
core.floorIds[fromIndex],
|
|
|
|
|
core.floorIds[toIndex]
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
}
|
|
|
|
|
});
|
2022-11-14 17:11:23 +08:00
|
|
|
|
};
|
2022-11-13 18:02:05 +08:00
|
|
|
|
},
|
2022-11-14 17:11:23 +08:00
|
|
|
|
fiveLayers: function () {
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 是否启用五图层(增加背景2层和前景2层) 将__enable置为true即会启用;启用后请保存后刷新编辑器
|
|
|
|
|
// 背景层2将会覆盖背景层 被事件层覆盖 前景层2将会覆盖前景层
|
|
|
|
|
// 另外 请注意加入两个新图层 会让大地图的性能降低一些
|
|
|
|
|
// 插件作者:ad
|
|
|
|
|
var __enable = true;
|
|
|
|
|
if (!__enable) return;
|
|
|
|
|
|
|
|
|
|
// 创建新图层
|
2022-11-14 17:11:23 +08:00
|
|
|
|
function createCanvas(name, zIndex) {
|
2022-11-13 18:02:05 +08:00
|
|
|
|
if (!name) return;
|
|
|
|
|
var canvas = document.createElement('canvas');
|
|
|
|
|
canvas.id = name;
|
|
|
|
|
canvas.className = 'gameCanvas';
|
|
|
|
|
// 编辑器模式下设置zIndex会导致加入的图层覆盖优先级过高
|
2022-11-14 17:11:23 +08:00
|
|
|
|
if (main.mode != 'editor') canvas.style.zIndex = zIndex || 0;
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 将图层插入进游戏内容
|
|
|
|
|
document.getElementById('gameDraw').appendChild(canvas);
|
|
|
|
|
var ctx = canvas.getContext('2d');
|
|
|
|
|
core.canvas[name] = ctx;
|
2022-12-30 16:54:50 +08:00
|
|
|
|
|
2022-11-13 18:02:05 +08:00
|
|
|
|
return canvas;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var bg2Canvas = createCanvas('bg2', 20);
|
|
|
|
|
var fg2Canvas = createCanvas('fg2', 63);
|
|
|
|
|
// 大地图适配
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.bigmap.canvas = [
|
|
|
|
|
'bg2',
|
|
|
|
|
'fg2',
|
|
|
|
|
'bg',
|
|
|
|
|
'event',
|
|
|
|
|
'event2',
|
|
|
|
|
'fg',
|
|
|
|
|
'damage'
|
|
|
|
|
];
|
2022-11-13 18:02:05 +08:00
|
|
|
|
core.initStatus.bg2maps = {};
|
|
|
|
|
core.initStatus.fg2maps = {};
|
|
|
|
|
|
|
|
|
|
if (main.mode == 'editor') {
|
|
|
|
|
/*插入编辑器的图层 不做此步新增图层无法在编辑器显示*/
|
|
|
|
|
// 编辑器图层覆盖优先级 eui > efg > fg(前景层) > event2(48*32图块的事件层) > event(事件层) > bg(背景层)
|
|
|
|
|
// 背景层2(bg2) 插入事件层(event)之前(即bg与event之间)
|
2022-11-14 17:11:23 +08:00
|
|
|
|
document
|
|
|
|
|
.getElementById('mapEdit')
|
|
|
|
|
.insertBefore(bg2Canvas, document.getElementById('event'));
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 前景层2(fg2) 插入编辑器前景(efg)之前(即fg之后)
|
2022-11-14 17:11:23 +08:00
|
|
|
|
document
|
|
|
|
|
.getElementById('mapEdit')
|
|
|
|
|
.insertBefore(fg2Canvas, document.getElementById('ebm'));
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 原本有三个图层 从4开始添加
|
|
|
|
|
var num = 4;
|
|
|
|
|
// 新增图层存入editor.dom中
|
|
|
|
|
editor.dom.bg2c = core.canvas.bg2.canvas;
|
|
|
|
|
editor.dom.bg2Ctx = core.canvas.bg2;
|
|
|
|
|
editor.dom.fg2c = core.canvas.fg2.canvas;
|
|
|
|
|
editor.dom.fg2Ctx = core.canvas.fg2;
|
|
|
|
|
editor.dom.maps.push('bg2map', 'fg2map');
|
|
|
|
|
editor.dom.canvas.push('bg2', 'fg2');
|
|
|
|
|
|
|
|
|
|
// 创建编辑器上的按钮
|
2022-11-14 17:11:23 +08:00
|
|
|
|
var createCanvasBtn = name => {
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 电脑端创建按钮
|
|
|
|
|
var input = document.createElement('input');
|
|
|
|
|
// layerMod4/layerMod5
|
|
|
|
|
var id = 'layerMod' + num++;
|
|
|
|
|
// bg2map/fg2map
|
|
|
|
|
var value = name + 'map';
|
|
|
|
|
input.type = 'radio';
|
|
|
|
|
input.name = 'layerMod';
|
|
|
|
|
input.id = id;
|
|
|
|
|
input.value = value;
|
|
|
|
|
editor.dom[id] = input;
|
|
|
|
|
input.onchange = () => {
|
|
|
|
|
editor.uifunctions.setLayerMod(value);
|
2022-11-14 17:11:23 +08:00
|
|
|
|
};
|
2022-11-13 18:02:05 +08:00
|
|
|
|
return input;
|
|
|
|
|
};
|
|
|
|
|
|
2022-11-14 17:11:23 +08:00
|
|
|
|
var createCanvasBtn_mobile = name => {
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 手机端往选择列表中添加子选项
|
|
|
|
|
var input = document.createElement('option');
|
|
|
|
|
var id = 'layerMod' + num++;
|
|
|
|
|
var value = name + 'map';
|
|
|
|
|
input.name = 'layerMod';
|
|
|
|
|
input.value = value;
|
|
|
|
|
editor.dom[id] = input;
|
|
|
|
|
return input;
|
|
|
|
|
};
|
|
|
|
|
if (!editor.isMobile) {
|
|
|
|
|
var input = createCanvasBtn('bg2');
|
|
|
|
|
var input2 = createCanvasBtn('fg2');
|
|
|
|
|
// 获取事件层及其父节点
|
|
|
|
|
var child = document.getElementById('layerMod'),
|
|
|
|
|
parent = child.parentNode;
|
|
|
|
|
// 背景层2插入事件层前
|
|
|
|
|
parent.insertBefore(input, child);
|
|
|
|
|
// 不能直接更改背景层2的innerText 所以创建文本节点
|
|
|
|
|
var txt = document.createTextNode('背2');
|
|
|
|
|
// 插入事件层前(即新插入的背景层2前)
|
|
|
|
|
parent.insertBefore(txt, child);
|
|
|
|
|
// 向最后插入前景层2(即插入前景层后)
|
|
|
|
|
parent.appendChild(input2);
|
|
|
|
|
var txt2 = document.createTextNode('前2');
|
|
|
|
|
parent.appendChild(txt2);
|
|
|
|
|
} else {
|
|
|
|
|
var input = createCanvasBtn_mobile('bg2');
|
|
|
|
|
var input2 = createCanvasBtn_mobile('fg2');
|
|
|
|
|
// 手机端因为是选项 所以可以直接改innerText
|
|
|
|
|
input.innerText = '背景2';
|
|
|
|
|
input2.innerText = '前景2';
|
|
|
|
|
var parent = document.getElementById('layerMod');
|
|
|
|
|
parent.insertBefore(input, parent.children[1]);
|
|
|
|
|
parent.appendChild(input2);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
core.maps._loadFloor_doNotCopy = function () {
|
|
|
|
|
return [
|
2022-11-14 17:11:23 +08:00
|
|
|
|
'firstArrive',
|
|
|
|
|
'eachArrive',
|
|
|
|
|
'blocks',
|
|
|
|
|
'parallelDo',
|
|
|
|
|
'map',
|
|
|
|
|
'bgmap',
|
|
|
|
|
'fgmap',
|
|
|
|
|
'bg2map',
|
|
|
|
|
'fg2map',
|
|
|
|
|
'events',
|
|
|
|
|
'changeFloor',
|
|
|
|
|
'afterBattle',
|
|
|
|
|
'afterGetItem',
|
|
|
|
|
'afterOpenDoor',
|
|
|
|
|
'cannotMove'
|
2022-11-13 18:02:05 +08:00
|
|
|
|
];
|
2022-11-14 17:11:23 +08:00
|
|
|
|
};
|
2022-11-13 18:02:05 +08:00
|
|
|
|
////// 绘制背景和前景层 //////
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.maps._drawBg_draw = function (
|
|
|
|
|
floorId,
|
|
|
|
|
toDrawCtx,
|
|
|
|
|
cacheCtx,
|
|
|
|
|
config
|
|
|
|
|
) {
|
2022-11-13 18:02:05 +08:00
|
|
|
|
config.ctx = cacheCtx;
|
|
|
|
|
core.maps._drawBg_drawBackground(floorId, config);
|
|
|
|
|
// ------ 调整这两行的顺序来控制是先绘制贴图还是先绘制背景图块;后绘制的覆盖先绘制的。
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.maps._drawFloorImages(
|
|
|
|
|
floorId,
|
|
|
|
|
config.ctx,
|
|
|
|
|
'bg',
|
|
|
|
|
null,
|
|
|
|
|
null,
|
|
|
|
|
config.onMap
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
core.maps._drawBgFgMap(floorId, 'bg', config);
|
|
|
|
|
if (config.onMap) {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.drawImage(
|
|
|
|
|
toDrawCtx,
|
|
|
|
|
cacheCtx.canvas,
|
|
|
|
|
core.bigmap.v2 ? -32 : 0,
|
|
|
|
|
core.bigmap.v2 ? -32 : 0
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
core.clearMap('bg2');
|
|
|
|
|
core.clearMap(cacheCtx);
|
|
|
|
|
}
|
|
|
|
|
core.maps._drawBgFgMap(floorId, 'bg2', config);
|
2022-11-14 17:11:23 +08:00
|
|
|
|
if (config.onMap)
|
|
|
|
|
core.drawImage(
|
|
|
|
|
'bg2',
|
|
|
|
|
cacheCtx.canvas,
|
|
|
|
|
core.bigmap.v2 ? -32 : 0,
|
|
|
|
|
core.bigmap.v2 ? -32 : 0
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
config.ctx = toDrawCtx;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
};
|
|
|
|
|
core.maps._drawFg_draw = function (
|
|
|
|
|
floorId,
|
|
|
|
|
toDrawCtx,
|
|
|
|
|
cacheCtx,
|
|
|
|
|
config
|
|
|
|
|
) {
|
2022-11-13 18:02:05 +08:00
|
|
|
|
config.ctx = cacheCtx;
|
|
|
|
|
// ------ 调整这两行的顺序来控制是先绘制贴图还是先绘制前景图块;后绘制的覆盖先绘制的。
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.maps._drawFloorImages(
|
|
|
|
|
floorId,
|
|
|
|
|
config.ctx,
|
|
|
|
|
'fg',
|
|
|
|
|
null,
|
|
|
|
|
null,
|
|
|
|
|
config.onMap
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
core.maps._drawBgFgMap(floorId, 'fg', config);
|
|
|
|
|
if (config.onMap) {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.drawImage(
|
|
|
|
|
toDrawCtx,
|
|
|
|
|
cacheCtx.canvas,
|
|
|
|
|
core.bigmap.v2 ? -32 : 0,
|
|
|
|
|
core.bigmap.v2 ? -32 : 0
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
core.clearMap('fg2');
|
|
|
|
|
core.clearMap(cacheCtx);
|
|
|
|
|
}
|
|
|
|
|
core.maps._drawBgFgMap(floorId, 'fg2', config);
|
2022-11-14 17:11:23 +08:00
|
|
|
|
if (config.onMap)
|
|
|
|
|
core.drawImage(
|
|
|
|
|
'fg2',
|
|
|
|
|
cacheCtx.canvas,
|
|
|
|
|
core.bigmap.v2 ? -32 : 0,
|
|
|
|
|
core.bigmap.v2 ? -32 : 0
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
config.ctx = toDrawCtx;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
};
|
2022-11-13 18:02:05 +08:00
|
|
|
|
////// 移动判定 //////
|
|
|
|
|
core.maps._generateMovableArray_arrays = function (floorId) {
|
|
|
|
|
return {
|
|
|
|
|
bgArray: this.getBgMapArray(floorId),
|
|
|
|
|
fgArray: this.getFgMapArray(floorId),
|
|
|
|
|
eventArray: this.getMapArray(floorId),
|
|
|
|
|
bg2Array: this._getBgFgMapArray('bg2', floorId),
|
|
|
|
|
fg2Array: this._getBgFgMapArray('fg2', floorId)
|
|
|
|
|
};
|
2022-11-14 17:11:23 +08:00
|
|
|
|
};
|
2022-11-13 18:02:05 +08:00
|
|
|
|
},
|
2022-11-14 17:11:23 +08:00
|
|
|
|
itemShop: function () {
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 道具商店相关的插件
|
|
|
|
|
// 可在全塔属性-全局商店中使用「道具商店」事件块进行编辑(如果找不到可以在入口方块中找)
|
|
|
|
|
|
|
|
|
|
var shopId = null; // 当前商店ID
|
|
|
|
|
var type = 0; // 当前正在选中的类型,0买入1卖出
|
|
|
|
|
var selectItem = 0; // 当前正在选中的道具
|
|
|
|
|
var selectCount = 0; // 当前已经选中的数量
|
|
|
|
|
var page = 0;
|
|
|
|
|
var totalPage = 0;
|
|
|
|
|
var totalMoney = 0;
|
|
|
|
|
var list = [];
|
|
|
|
|
var shopInfo = null; // 商店信息
|
|
|
|
|
var choices = []; // 商店选项
|
|
|
|
|
var use = 'money';
|
|
|
|
|
var useText = '金币';
|
|
|
|
|
|
|
|
|
|
var bigFont = core.ui._buildFont(20, false),
|
|
|
|
|
middleFont = core.ui._buildFont(18, false);
|
|
|
|
|
|
|
|
|
|
this._drawItemShop = function () {
|
|
|
|
|
// 绘制道具商店
|
|
|
|
|
|
|
|
|
|
// Step 1: 背景和固定的几个文字
|
|
|
|
|
core.ui._createUIEvent();
|
|
|
|
|
core.clearMap('uievent');
|
|
|
|
|
core.ui.clearUIEventSelector();
|
|
|
|
|
core.setTextAlign('uievent', 'left');
|
|
|
|
|
core.setTextBaseline('uievent', 'top');
|
|
|
|
|
core.fillRect('uievent', 0, 0, 480, 480, 'black');
|
|
|
|
|
core.drawWindowSkin('winskin.png', 'uievent', 0, 0, 480, 64);
|
|
|
|
|
core.drawWindowSkin('winskin.png', 'uievent', 0, 64, 360, 64);
|
|
|
|
|
core.drawWindowSkin('winskin.png', 'uievent', 0, 128, 360, 352);
|
|
|
|
|
core.drawWindowSkin('winskin.png', 'uievent', 360, 64, 120, 64);
|
|
|
|
|
core.drawWindowSkin('winskin.png', 'uievent', 360, 128, 120, 352);
|
|
|
|
|
core.setFillStyle('uievent', 'white');
|
|
|
|
|
core.setStrokeStyle('uievent', 'white');
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.fillText('uievent', '购买', 32, 84, 'white', bigFont);
|
|
|
|
|
core.fillText('uievent', '卖出', 152, 84);
|
|
|
|
|
core.fillText('uievent', '离开', 272, 84);
|
|
|
|
|
core.fillText(
|
|
|
|
|
'uievent',
|
|
|
|
|
'当前' + useText,
|
|
|
|
|
374,
|
|
|
|
|
75,
|
|
|
|
|
null,
|
|
|
|
|
middleFont
|
|
|
|
|
);
|
|
|
|
|
core.setTextAlign('uievent', 'right');
|
|
|
|
|
core.fillText(
|
|
|
|
|
'uievent',
|
|
|
|
|
core.formatBigNumber(core.status.hero.money),
|
|
|
|
|
466,
|
|
|
|
|
100
|
|
|
|
|
);
|
|
|
|
|
core.setTextAlign('uievent', 'left');
|
|
|
|
|
core.ui.drawUIEventSelector(
|
|
|
|
|
1,
|
|
|
|
|
'winskin.png',
|
|
|
|
|
22 + 120 * type,
|
|
|
|
|
76,
|
|
|
|
|
60,
|
|
|
|
|
33
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
if (selectItem != null) {
|
|
|
|
|
core.setTextAlign('uievent', 'center');
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.fillText(
|
|
|
|
|
'uievent',
|
|
|
|
|
type == 0 ? '买入个数' : '卖出个数',
|
|
|
|
|
420,
|
|
|
|
|
360,
|
|
|
|
|
null,
|
|
|
|
|
bigFont
|
|
|
|
|
);
|
|
|
|
|
core.fillText(
|
|
|
|
|
'uievent',
|
|
|
|
|
'< ' + selectCount + ' >',
|
|
|
|
|
420,
|
|
|
|
|
390
|
|
|
|
|
);
|
|
|
|
|
core.fillText('uievent', '确定', 420, 420);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Step 2:获得列表并展示
|
2022-11-14 17:11:23 +08:00
|
|
|
|
list = choices.filter(one => {
|
2022-11-13 18:02:05 +08:00
|
|
|
|
if (one.condition != null && one.condition != '') {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
try {
|
|
|
|
|
if (!core.calValue(one.condition)) return false;
|
|
|
|
|
} catch (e) {}
|
2022-11-13 18:02:05 +08:00
|
|
|
|
}
|
2022-11-14 17:11:23 +08:00
|
|
|
|
return (
|
|
|
|
|
(type == 0 && one.money != null) ||
|
|
|
|
|
(type == 1 && one.sell != null)
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
});
|
|
|
|
|
var per_page = 7;
|
|
|
|
|
totalPage = Math.ceil(list.length / per_page);
|
|
|
|
|
page = Math.floor((selectItem || 0) / per_page) + 1;
|
|
|
|
|
|
|
|
|
|
// 绘制分页
|
|
|
|
|
if (totalPage > 1) {
|
|
|
|
|
var half = 180;
|
|
|
|
|
core.setTextAlign('uievent', 'center');
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.fillText(
|
|
|
|
|
'uievent',
|
|
|
|
|
page + ' / ' + totalPage,
|
|
|
|
|
half,
|
|
|
|
|
450,
|
|
|
|
|
null,
|
|
|
|
|
middleFont
|
|
|
|
|
);
|
|
|
|
|
if (page > 1)
|
|
|
|
|
core.fillText('uievent', '上一页', half - 80, 450);
|
|
|
|
|
if (page < totalPage)
|
|
|
|
|
core.fillText('uievent', '下一页', half + 80, 450);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
}
|
|
|
|
|
core.setTextAlign('uievent', 'left');
|
|
|
|
|
|
|
|
|
|
// 绘制每一项
|
|
|
|
|
var start = (page - 1) * per_page;
|
|
|
|
|
for (var i = 0; i < per_page; ++i) {
|
|
|
|
|
var curr = start + i;
|
|
|
|
|
if (curr >= list.length) break;
|
|
|
|
|
var item = list[curr];
|
|
|
|
|
core.drawIcon('uievent', item.id, 10, 141 + i * 40);
|
|
|
|
|
core.setTextAlign('uievent', 'left');
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.fillText(
|
|
|
|
|
'uievent',
|
|
|
|
|
core.material.items[item.id].name,
|
|
|
|
|
50,
|
|
|
|
|
148 + i * 40,
|
|
|
|
|
null,
|
|
|
|
|
bigFont
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
core.setTextAlign('uievent', 'right');
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.fillText(
|
|
|
|
|
'uievent',
|
|
|
|
|
(type == 0
|
|
|
|
|
? core.calValue(item.money)
|
|
|
|
|
: core.calValue(item.sell)) +
|
|
|
|
|
useText +
|
|
|
|
|
'/个',
|
|
|
|
|
340,
|
|
|
|
|
149 + i * 40,
|
|
|
|
|
null,
|
|
|
|
|
middleFont
|
|
|
|
|
);
|
|
|
|
|
core.setTextAlign('uievent', 'left');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
if (curr == selectItem) {
|
|
|
|
|
// 绘制描述,文字自动放缩
|
2022-11-14 17:11:23 +08:00
|
|
|
|
var text =
|
|
|
|
|
core.material.items[item.id].text || '该道具暂无描述';
|
|
|
|
|
try {
|
|
|
|
|
text = core.replaceText(text);
|
|
|
|
|
} catch (e) {}
|
2022-11-13 18:02:05 +08:00
|
|
|
|
for (var fontSize = 20; fontSize >= 8; fontSize -= 2) {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
var config = {
|
|
|
|
|
left: 10,
|
|
|
|
|
fontSize: fontSize,
|
|
|
|
|
maxWidth: 467
|
|
|
|
|
};
|
2022-11-13 18:02:05 +08:00
|
|
|
|
var height = core.getTextContentHeight(text, config);
|
|
|
|
|
if (height <= 60) {
|
|
|
|
|
config.top = (64 - height) / 2;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.drawTextContent('uievent', text, config);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.ui.drawUIEventSelector(
|
|
|
|
|
2,
|
|
|
|
|
'winskin.png',
|
|
|
|
|
8,
|
|
|
|
|
137 + i * 40,
|
|
|
|
|
343,
|
|
|
|
|
40
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
if (type == 0 && item.number != null) {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.fillText(
|
|
|
|
|
'uievent',
|
|
|
|
|
'存货',
|
|
|
|
|
370,
|
|
|
|
|
152,
|
|
|
|
|
null,
|
|
|
|
|
bigFont
|
|
|
|
|
);
|
|
|
|
|
core.setTextAlign('uievent', 'right');
|
|
|
|
|
core.fillText(
|
|
|
|
|
'uievent',
|
|
|
|
|
item.number,
|
|
|
|
|
470,
|
|
|
|
|
152,
|
|
|
|
|
null,
|
|
|
|
|
null,
|
|
|
|
|
60
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
} else if (type == 1) {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.fillText(
|
|
|
|
|
'uievent',
|
|
|
|
|
'数量',
|
|
|
|
|
370,
|
|
|
|
|
152,
|
|
|
|
|
null,
|
|
|
|
|
bigFont
|
|
|
|
|
);
|
|
|
|
|
core.setTextAlign('uievent', 'right');
|
|
|
|
|
core.fillText(
|
|
|
|
|
'uievent',
|
|
|
|
|
core.itemCount(item.id),
|
|
|
|
|
470,
|
|
|
|
|
152,
|
|
|
|
|
null,
|
|
|
|
|
null,
|
|
|
|
|
40
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
}
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.setTextAlign('uievent', 'left');
|
|
|
|
|
core.fillText('uievent', '预计' + useText, 370, 280);
|
|
|
|
|
core.setTextAlign('uievent', 'right');
|
|
|
|
|
totalMoney =
|
|
|
|
|
selectCount *
|
|
|
|
|
(type == 0
|
|
|
|
|
? core.calValue(item.money)
|
|
|
|
|
: core.calValue(item.sell));
|
|
|
|
|
core.fillText(
|
|
|
|
|
'uievent',
|
|
|
|
|
core.formatBigNumber(totalMoney),
|
|
|
|
|
470,
|
|
|
|
|
310
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
core.setTextAlign('uievent', 'left');
|
|
|
|
|
core.fillText(
|
|
|
|
|
'uievent',
|
|
|
|
|
type == 0 ? '已购次数' : '已卖次数',
|
|
|
|
|
370,
|
|
|
|
|
190
|
|
|
|
|
);
|
|
|
|
|
core.setTextAlign('uievent', 'right');
|
|
|
|
|
core.fillText(
|
|
|
|
|
'uievent',
|
|
|
|
|
(type == 0 ? item.money_count : item.sell_count) || 0,
|
|
|
|
|
470,
|
|
|
|
|
220
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
core.setTextAlign('uievent', 'left');
|
|
|
|
|
core.setTextBaseline('uievent', 'alphabetic');
|
2022-11-14 17:11:23 +08:00
|
|
|
|
};
|
2022-11-13 18:02:05 +08:00
|
|
|
|
|
|
|
|
|
var _add = (item, delta) => {
|
|
|
|
|
if (item == null) return;
|
|
|
|
|
selectCount = core.clamp(
|
2022-11-14 17:11:23 +08:00
|
|
|
|
selectCount + delta,
|
|
|
|
|
0,
|
|
|
|
|
Math.min(
|
|
|
|
|
type == 0
|
|
|
|
|
? Math.floor(
|
|
|
|
|
core.status.hero[use] / core.calValue(item.money)
|
|
|
|
|
)
|
|
|
|
|
: core.itemCount(item.id),
|
|
|
|
|
type == 0 && item.number != null
|
|
|
|
|
? item.number
|
|
|
|
|
: Number.MAX_SAFE_INTEGER
|
|
|
|
|
)
|
2022-11-13 18:02:05 +08:00
|
|
|
|
);
|
2022-11-14 17:11:23 +08:00
|
|
|
|
};
|
2022-11-13 18:02:05 +08:00
|
|
|
|
|
2022-11-14 17:11:23 +08:00
|
|
|
|
var _confirm = item => {
|
2022-11-13 18:02:05 +08:00
|
|
|
|
if (item == null || selectCount == 0) return;
|
|
|
|
|
if (type == 0) {
|
|
|
|
|
core.status.hero[use] -= totalMoney;
|
|
|
|
|
core.getItem(item.id, selectCount);
|
|
|
|
|
if (item.number != null) item.number -= selectCount;
|
|
|
|
|
item.money_count = (item.money_count || 0) + selectCount;
|
|
|
|
|
} else {
|
|
|
|
|
core.status.hero[use] += totalMoney;
|
|
|
|
|
core.removeItem(item.id, selectCount);
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.drawTip(
|
|
|
|
|
'成功卖出' +
|
|
|
|
|
selectCount +
|
|
|
|
|
'个' +
|
|
|
|
|
core.material.items[item.id].name,
|
|
|
|
|
item.id
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
if (item.number != null) item.number += selectCount;
|
|
|
|
|
item.sell_count = (item.sell_count || 0) + selectCount;
|
|
|
|
|
}
|
|
|
|
|
selectCount = 0;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
};
|
2022-11-13 18:02:05 +08:00
|
|
|
|
|
|
|
|
|
this._performItemShopKeyBoard = function (keycode) {
|
|
|
|
|
var item = list[selectItem] || null;
|
|
|
|
|
// 键盘操作
|
|
|
|
|
switch (keycode) {
|
|
|
|
|
case 38: // up
|
|
|
|
|
if (selectItem == null) break;
|
|
|
|
|
if (selectItem == 0) selectItem = null;
|
|
|
|
|
else selectItem--;
|
|
|
|
|
selectCount = 0;
|
|
|
|
|
break;
|
|
|
|
|
case 37: // left
|
|
|
|
|
if (selectItem == null) {
|
|
|
|
|
if (type > 0) type--;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
_add(item, -1);
|
|
|
|
|
break;
|
|
|
|
|
case 39: // right
|
|
|
|
|
if (selectItem == null) {
|
|
|
|
|
if (type < 2) type++;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
_add(item, 1);
|
|
|
|
|
break;
|
|
|
|
|
case 40: // down
|
|
|
|
|
if (selectItem == null) {
|
|
|
|
|
if (list.length > 0) selectItem = 0;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (list.length == 0) break;
|
|
|
|
|
selectItem = Math.min(selectItem + 1, list.length - 1);
|
|
|
|
|
selectCount = 0;
|
|
|
|
|
break;
|
|
|
|
|
case 13:
|
|
|
|
|
case 32: // Enter/Space
|
|
|
|
|
if (selectItem == null) {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
if (type == 2) core.insertAction({ type: 'break' });
|
|
|
|
|
else if (list.length > 0) selectItem = 0;
|
2022-11-13 18:02:05 +08:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
_confirm(item);
|
|
|
|
|
break;
|
|
|
|
|
case 27: // ESC
|
|
|
|
|
if (selectItem == null) {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.insertAction({ type: 'break' });
|
2022-11-13 18:02:05 +08:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
selectItem = null;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2022-11-14 17:11:23 +08:00
|
|
|
|
};
|
2022-11-13 18:02:05 +08:00
|
|
|
|
|
|
|
|
|
this._performItemShopClick = function (px, py) {
|
|
|
|
|
var item = list[selectItem] || null;
|
|
|
|
|
// 鼠标操作
|
|
|
|
|
if (px >= 22 && px <= 82 && py >= 81 && py <= 112) {
|
|
|
|
|
// 买
|
|
|
|
|
if (type != 0) {
|
|
|
|
|
type = 0;
|
|
|
|
|
selectItem = null;
|
|
|
|
|
selectCount = 0;
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (px >= 142 && px <= 202 && py >= 81 && py <= 112) {
|
|
|
|
|
// 卖
|
|
|
|
|
if (type != 1) {
|
|
|
|
|
type = 1;
|
|
|
|
|
selectItem = null;
|
|
|
|
|
selectCount = 0;
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
2022-11-14 17:11:23 +08:00
|
|
|
|
if (px >= 262 && px <= 322 && py >= 81 && py <= 112)
|
|
|
|
|
// 离开
|
|
|
|
|
return core.insertAction({ type: 'break' });
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// <,>
|
|
|
|
|
if (px >= 370 && px <= 395 && py >= 392 && py <= 415)
|
|
|
|
|
return _add(item, -1);
|
|
|
|
|
if (px >= 445 && px <= 470 && py >= 302 && py <= 415)
|
|
|
|
|
return _add(item, 1);
|
|
|
|
|
// 确定
|
|
|
|
|
if (px >= 392 && px <= 443 && py >= 421 && py <= 446)
|
|
|
|
|
return _confirm(item);
|
|
|
|
|
|
|
|
|
|
// 上一页/下一页
|
|
|
|
|
if (px >= 70 && px <= 130 && py >= 450) {
|
|
|
|
|
if (page > 1) {
|
|
|
|
|
selectItem -= 7;
|
|
|
|
|
selectCount = 0;
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (px >= 230 && px <= 290 && py >= 450) {
|
|
|
|
|
if (page < totalPage) {
|
|
|
|
|
selectItem = Math.min(selectItem + 7, list.length - 1);
|
|
|
|
|
selectCount = 0;
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 实际区域
|
|
|
|
|
if (px >= 9 && px <= 351 && py >= 142 && py < 422) {
|
|
|
|
|
if (list.length == 0) return;
|
|
|
|
|
var index = parseInt((py - 142) / 40);
|
|
|
|
|
var newItem = 7 * (page - 1) + index;
|
|
|
|
|
if (newItem >= list.length) newItem = list.length - 1;
|
|
|
|
|
if (newItem != selectItem) {
|
|
|
|
|
selectItem = newItem;
|
|
|
|
|
selectCount = 0;
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
2022-11-14 17:11:23 +08:00
|
|
|
|
};
|
2022-11-13 18:02:05 +08:00
|
|
|
|
|
|
|
|
|
this._performItemShopAction = function () {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
if (flags.type == 0)
|
|
|
|
|
return this._performItemShopKeyBoard(flags.keycode);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
else return this._performItemShopClick(flags.px, flags.py);
|
2022-11-14 17:11:23 +08:00
|
|
|
|
};
|
2022-11-13 18:02:05 +08:00
|
|
|
|
|
|
|
|
|
this.openItemShop = function (itemShopId) {
|
|
|
|
|
shopId = itemShopId;
|
|
|
|
|
type = 0;
|
|
|
|
|
page = 0;
|
|
|
|
|
selectItem = null;
|
|
|
|
|
selectCount = 0;
|
|
|
|
|
core.isShopVisited(itemShopId);
|
|
|
|
|
shopInfo = flags.__shops__[shopId];
|
2022-11-14 17:11:23 +08:00
|
|
|
|
if (shopInfo.choices == null)
|
|
|
|
|
shopInfo.choices = core.clone(
|
|
|
|
|
core.status.shops[shopId].choices
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
choices = shopInfo.choices;
|
|
|
|
|
use = core.status.shops[shopId].use;
|
|
|
|
|
if (use != 'exp') use = 'money';
|
|
|
|
|
useText = use == 'money' ? '金币' : '经验';
|
|
|
|
|
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.insertAction([
|
|
|
|
|
{
|
|
|
|
|
type: 'while',
|
|
|
|
|
condition: 'true',
|
|
|
|
|
data: [
|
|
|
|
|
{
|
|
|
|
|
type: 'function',
|
|
|
|
|
function: '() => { core.plugin._drawItemShop(); }'
|
|
|
|
|
},
|
|
|
|
|
{ type: 'wait' },
|
|
|
|
|
{
|
|
|
|
|
type: 'function',
|
|
|
|
|
function:
|
|
|
|
|
'() => { core.plugin._performItemShopAction(); }'
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
type: 'function',
|
|
|
|
|
function:
|
|
|
|
|
"() => { core.deleteCanvas('uievent'); core.ui.clearUIEventSelector(); }"
|
2022-11-13 18:02:05 +08:00
|
|
|
|
}
|
2022-11-14 17:11:23 +08:00
|
|
|
|
]);
|
|
|
|
|
};
|
2022-12-29 23:08:44 +08:00
|
|
|
|
},
|
|
|
|
|
heroFourFrames: function () {
|
|
|
|
|
// 样板的勇士/跟随者移动时只使用2、4两帧,观感较差。本插件可以将四帧全用上。
|
2022-11-13 18:02:05 +08:00
|
|
|
|
|
2022-12-29 23:08:44 +08:00
|
|
|
|
// 是否启用本插件
|
|
|
|
|
var __enable = true;
|
|
|
|
|
if (!__enable) return;
|
2022-11-13 18:02:05 +08:00
|
|
|
|
|
2022-12-29 23:08:44 +08:00
|
|
|
|
['up', 'down', 'left', 'right'].forEach(one => {
|
|
|
|
|
// 指定中间帧动画
|
|
|
|
|
core.material.icons.hero[one].midFoot = 2;
|
|
|
|
|
});
|
2022-11-13 18:02:05 +08:00
|
|
|
|
|
2022-12-29 23:08:44 +08:00
|
|
|
|
var heroMoving = timestamp => {
|
|
|
|
|
if (core.status.heroMoving <= 0) return;
|
|
|
|
|
if (
|
|
|
|
|
timestamp - core.animateFrame.moveTime >
|
|
|
|
|
core.values.moveSpeed
|
|
|
|
|
) {
|
|
|
|
|
core.animateFrame.leftLeg++;
|
|
|
|
|
core.animateFrame.moveTime = timestamp;
|
2022-11-13 18:02:05 +08:00
|
|
|
|
}
|
2022-12-29 23:08:44 +08:00
|
|
|
|
core.drawHero(
|
|
|
|
|
['stop', 'leftFoot', 'midFoot', 'rightFoot'][
|
|
|
|
|
core.animateFrame.leftLeg % 4
|
|
|
|
|
],
|
|
|
|
|
4 * core.status.heroMoving
|
2022-11-14 17:11:23 +08:00
|
|
|
|
);
|
2022-12-29 23:08:44 +08:00
|
|
|
|
};
|
|
|
|
|
core.registerAnimationFrame('heroMoving', true, heroMoving);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
|
2022-12-29 23:08:44 +08:00
|
|
|
|
core.events._eventMoveHero_moving = function (step, moveSteps) {
|
|
|
|
|
var curr = moveSteps[0];
|
|
|
|
|
var direction = curr[0],
|
|
|
|
|
x = core.getHeroLoc('x'),
|
|
|
|
|
y = core.getHeroLoc('y');
|
|
|
|
|
// ------ 前进/后退
|
|
|
|
|
var o = direction == 'backward' ? -1 : 1;
|
|
|
|
|
if (direction == 'forward' || direction == 'backward')
|
|
|
|
|
direction = core.getHeroLoc('direction');
|
|
|
|
|
var faceDirection = direction;
|
|
|
|
|
if (direction == 'leftup' || direction == 'leftdown')
|
|
|
|
|
faceDirection = 'left';
|
|
|
|
|
if (direction == 'rightup' || direction == 'rightdown')
|
|
|
|
|
faceDirection = 'right';
|
|
|
|
|
core.setHeroLoc('direction', direction);
|
|
|
|
|
if (curr[1] <= 0) {
|
|
|
|
|
core.setHeroLoc('direction', faceDirection);
|
|
|
|
|
moveSteps.shift();
|
|
|
|
|
return true;
|
2022-11-13 18:02:05 +08:00
|
|
|
|
}
|
2022-12-29 23:08:44 +08:00
|
|
|
|
if (step <= 4) core.drawHero('stop', 4 * o * step);
|
|
|
|
|
else if (step <= 8) core.drawHero('leftFoot', 4 * o * step);
|
|
|
|
|
else if (step <= 12) core.drawHero('midFoot', 4 * o * (step - 8));
|
|
|
|
|
else if (step <= 16) core.drawHero('rightFoot', 4 * o * (step - 8)); // if (step == 8) {
|
|
|
|
|
if (step == 8 || step == 16) {
|
|
|
|
|
core.setHeroLoc(
|
|
|
|
|
'x',
|
|
|
|
|
x + o * core.utils.scan2[direction].x,
|
|
|
|
|
true
|
2022-11-14 17:11:23 +08:00
|
|
|
|
);
|
2022-12-29 23:08:44 +08:00
|
|
|
|
core.setHeroLoc(
|
|
|
|
|
'y',
|
|
|
|
|
y + o * core.utils.scan2[direction].y,
|
|
|
|
|
true
|
|
|
|
|
);
|
|
|
|
|
core.updateFollowers();
|
|
|
|
|
curr[1]--;
|
|
|
|
|
if (curr[1] <= 0) moveSteps.shift();
|
|
|
|
|
core.setHeroLoc('direction', faceDirection);
|
|
|
|
|
return step == 16;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
};
|
2022-11-13 18:02:05 +08:00
|
|
|
|
},
|
2022-11-14 17:11:23 +08:00
|
|
|
|
itemDetail: function () {
|
2022-11-13 18:02:05 +08:00
|
|
|
|
core.control.updateDamage = function (floorId, ctx) {
|
|
|
|
|
floorId = floorId || core.status.floorId;
|
|
|
|
|
if (!floorId || core.status.gameOver || main.mode != 'play') return;
|
2023-01-01 11:31:49 +08:00
|
|
|
|
const onMap = ctx == null;
|
2022-11-30 16:42:44 +08:00
|
|
|
|
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 没有怪物手册
|
|
|
|
|
if (!core.hasItem('book')) return;
|
|
|
|
|
core.status.damage.posX = core.bigmap.posX;
|
|
|
|
|
core.status.damage.posY = core.bigmap.posY;
|
|
|
|
|
if (!onMap) {
|
2023-01-01 11:31:49 +08:00
|
|
|
|
const width = core.floors[floorId].width,
|
2022-11-13 18:02:05 +08:00
|
|
|
|
height = core.floors[floorId].height;
|
|
|
|
|
// 地图过大的缩略图不绘制显伤
|
|
|
|
|
if (width * height > core.bigmap.threshold) return;
|
|
|
|
|
}
|
|
|
|
|
this._updateDamage_damage(floorId, onMap);
|
|
|
|
|
this._updateDamage_extraDamage(floorId, onMap);
|
|
|
|
|
core.getItemDetail(floorId); // 宝石血瓶详细信息
|
|
|
|
|
this.drawDamage(ctx);
|
|
|
|
|
};
|
2023-01-01 11:31:49 +08:00
|
|
|
|
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 获取宝石信息 并绘制
|
|
|
|
|
this.getItemDetail = function (floorId) {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
if (!core.getFlag('itemDetail')) return;
|
2023-01-09 23:50:28 +08:00
|
|
|
|
floorId ??= core.status.thisMap.floorId;
|
2023-01-01 11:31:49 +08:00
|
|
|
|
let diff = {};
|
|
|
|
|
const before = core.status.hero;
|
|
|
|
|
const hero = core.clone(core.status.hero);
|
|
|
|
|
const handler = {
|
|
|
|
|
set(target, key, v) {
|
|
|
|
|
diff[key] = v - (target[key] || 0);
|
|
|
|
|
if (!diff[key]) diff[key] = void 0;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
core.status.hero = new Proxy(hero, handler);
|
2022-11-30 16:42:44 +08:00
|
|
|
|
core.status.maps[floorId].blocks.forEach(function (block) {
|
|
|
|
|
if (
|
|
|
|
|
block.event.cls !== 'items' ||
|
2022-12-29 23:56:35 +08:00
|
|
|
|
block.event.id === 'superPotion' ||
|
|
|
|
|
block.disable
|
2022-11-30 16:42:44 +08:00
|
|
|
|
)
|
|
|
|
|
return;
|
2023-01-01 11:31:49 +08:00
|
|
|
|
const x = block.x,
|
2022-11-13 18:02:05 +08:00
|
|
|
|
y = block.y;
|
|
|
|
|
// v2优化,只绘制范围内的部分
|
|
|
|
|
if (core.bigmap.v2) {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
if (
|
|
|
|
|
x < core.bigmap.posX - core.bigmap.extend ||
|
2023-01-01 11:31:49 +08:00
|
|
|
|
x > core.bigmap.posX + core._PX_ + core.bigmap.extend ||
|
2022-11-14 17:11:23 +08:00
|
|
|
|
y < core.bigmap.posY - core.bigmap.extend ||
|
2023-01-01 11:31:49 +08:00
|
|
|
|
y > core.bigmap.posY + core._PY_ + core.bigmap.extend
|
2022-11-14 17:11:23 +08:00
|
|
|
|
) {
|
2022-11-13 18:02:05 +08:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-01-01 11:31:49 +08:00
|
|
|
|
diff = {};
|
|
|
|
|
const id = block.event.id;
|
|
|
|
|
const item = core.material.items[id];
|
2022-11-13 18:02:05 +08:00
|
|
|
|
if (item.cls === 'equips') {
|
|
|
|
|
// 装备也显示
|
2023-01-05 22:21:40 +08:00
|
|
|
|
const diff = core.clone(item.equip.value ?? {});
|
2023-01-01 11:31:49 +08:00
|
|
|
|
const per = item.equip.percentage ?? {};
|
|
|
|
|
for (const name in per) {
|
2022-11-13 18:02:05 +08:00
|
|
|
|
diff[name + 'per'] = per[name].toString() + '%';
|
|
|
|
|
}
|
|
|
|
|
drawItemDetail(diff, x, y);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
// 跟数据统计原理一样 执行效果 前后比较
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.setFlag('__statistics__', true);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
try {
|
|
|
|
|
eval(item.itemEffect);
|
2022-11-14 17:11:23 +08:00
|
|
|
|
} catch (error) {}
|
2022-11-13 18:02:05 +08:00
|
|
|
|
drawItemDetail(diff, x, y);
|
|
|
|
|
});
|
2023-01-01 11:31:49 +08:00
|
|
|
|
core.status.hero = before;
|
|
|
|
|
window.hero = before;
|
|
|
|
|
window.flags = before.flags;
|
2022-11-13 18:02:05 +08:00
|
|
|
|
};
|
2023-01-01 11:31:49 +08:00
|
|
|
|
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 绘制
|
2022-11-14 17:11:23 +08:00
|
|
|
|
function drawItemDetail(diff, x, y) {
|
2023-01-01 11:31:49 +08:00
|
|
|
|
const px = 32 * x + 2,
|
2023-01-09 09:42:28 +08:00
|
|
|
|
py = 32 * y + 31;
|
2023-01-01 11:31:49 +08:00
|
|
|
|
let content = '';
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 获得数据和颜色
|
2023-01-01 11:31:49 +08:00
|
|
|
|
let i = 0;
|
|
|
|
|
for (const name in diff) {
|
2022-11-13 18:02:05 +08:00
|
|
|
|
if (!diff[name]) continue;
|
2023-01-01 11:31:49 +08:00
|
|
|
|
let color = '#fff';
|
|
|
|
|
|
2022-11-13 18:02:05 +08:00
|
|
|
|
if (typeof diff[name] === 'number')
|
2023-01-01 11:31:49 +08:00
|
|
|
|
content = core.formatBigNumber(diff[name], true);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
switch (name) {
|
|
|
|
|
case 'atk':
|
|
|
|
|
case 'atkper':
|
2022-11-14 17:11:23 +08:00
|
|
|
|
color = '#FF7A7A';
|
2022-11-13 18:02:05 +08:00
|
|
|
|
break;
|
|
|
|
|
case 'def':
|
|
|
|
|
case 'defper':
|
2022-11-14 17:11:23 +08:00
|
|
|
|
color = '#00E6F1';
|
2022-11-13 18:02:05 +08:00
|
|
|
|
break;
|
|
|
|
|
case 'mdef':
|
|
|
|
|
case 'mdefper':
|
2022-11-14 17:11:23 +08:00
|
|
|
|
color = '#6EFF83';
|
2022-11-13 18:02:05 +08:00
|
|
|
|
break;
|
|
|
|
|
case 'hp':
|
2022-11-14 17:11:23 +08:00
|
|
|
|
color = '#A4FF00';
|
2022-11-13 18:02:05 +08:00
|
|
|
|
break;
|
|
|
|
|
case 'hpmax':
|
|
|
|
|
case 'hpmaxper':
|
2022-11-14 17:11:23 +08:00
|
|
|
|
color = '#F9FF00';
|
2022-11-13 18:02:05 +08:00
|
|
|
|
break;
|
|
|
|
|
case 'mana':
|
2023-01-01 11:31:49 +08:00
|
|
|
|
color = '#c66';
|
2022-11-13 18:02:05 +08:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
content = diff[name];
|
|
|
|
|
// 绘制
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.status.damage.data.push({
|
|
|
|
|
text: content,
|
|
|
|
|
px: px,
|
|
|
|
|
py: py - 10 * i,
|
|
|
|
|
color: color
|
|
|
|
|
});
|
2022-11-13 18:02:05 +08:00
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
2022-11-14 17:11:23 +08:00
|
|
|
|
skills: function () {
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 所有的主动技能效果
|
|
|
|
|
var ignoreInJump = {
|
|
|
|
|
event: ['X20007', 'X20001', 'X20006', 'X20014', 'X20010', 'X20007'],
|
2022-11-14 17:11:23 +08:00
|
|
|
|
bg: [
|
|
|
|
|
'X20037',
|
|
|
|
|
'X20038',
|
|
|
|
|
'X20039',
|
|
|
|
|
'X20045',
|
|
|
|
|
'X20047',
|
|
|
|
|
'X20053',
|
|
|
|
|
'X20054',
|
|
|
|
|
'X20055',
|
|
|
|
|
'X20067',
|
|
|
|
|
'X20068',
|
|
|
|
|
'X20075',
|
|
|
|
|
'X20076'
|
|
|
|
|
]
|
2022-11-13 18:02:05 +08:00
|
|
|
|
};
|
2023-01-05 22:21:40 +08:00
|
|
|
|
|
|
|
|
|
const jumpIgnoreFloor = ['MT31'];
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 跳跃
|
|
|
|
|
this.jumpSkill = function () {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
if (core.status.floorId.startsWith('tower'))
|
|
|
|
|
return core.drawTip('当无法使用该技能');
|
2023-01-05 22:21:40 +08:00
|
|
|
|
if (
|
|
|
|
|
jumpIgnoreFloor.includes(core.status.floorId) ||
|
|
|
|
|
flags.onChase
|
|
|
|
|
) {
|
|
|
|
|
return core.drawTip('当前楼层无法使用该技能');
|
|
|
|
|
}
|
2022-11-13 18:02:05 +08:00
|
|
|
|
if (!flags.skill2) return;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
if (!flags['jump_' + core.status.floorId])
|
|
|
|
|
flags['jump_' + core.status.floorId] = 0;
|
|
|
|
|
if (
|
|
|
|
|
core.status.floorId == 'MT14' &&
|
|
|
|
|
flags['jump_' + core.status.floorId] == 2 &&
|
|
|
|
|
!flags.MT14Jump
|
|
|
|
|
) {
|
|
|
|
|
if (
|
|
|
|
|
!(
|
|
|
|
|
core.status.hero.loc.x == 77 &&
|
|
|
|
|
core.status.hero.loc.y == 5 &&
|
|
|
|
|
core.status.hero.loc.direction == 'right'
|
|
|
|
|
)
|
|
|
|
|
) {
|
|
|
|
|
return core.drawTip('该地图还有一个必跳的地方,你还没有跳');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
} else flags.MT14Jump = true;
|
|
|
|
|
}
|
2022-11-14 17:11:23 +08:00
|
|
|
|
if (flags['jump_' + core.status.floorId] >= 3)
|
|
|
|
|
return core.drawTip('当前地图使用次数已用完');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
core.autosave();
|
|
|
|
|
var direction = core.status.hero.loc.direction;
|
|
|
|
|
var loc = core.status.hero.loc;
|
|
|
|
|
var checkLoc = {};
|
|
|
|
|
switch (direction) {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
case 'up':
|
2022-11-13 18:02:05 +08:00
|
|
|
|
checkLoc.x = loc.x;
|
|
|
|
|
checkLoc.y = loc.y - 1;
|
|
|
|
|
break;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
case 'right':
|
2022-11-13 18:02:05 +08:00
|
|
|
|
checkLoc.x = loc.x + 1;
|
|
|
|
|
checkLoc.y = loc.y;
|
|
|
|
|
break;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
case 'down':
|
2022-11-13 18:02:05 +08:00
|
|
|
|
checkLoc.x = loc.x;
|
|
|
|
|
checkLoc.y = loc.y + 1;
|
|
|
|
|
break;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
case 'left':
|
2022-11-13 18:02:05 +08:00
|
|
|
|
checkLoc.x = loc.x - 1;
|
|
|
|
|
checkLoc.y = loc.y;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
// 前方是否可通行 或 是怪物
|
|
|
|
|
var cls = core.getBlockCls(checkLoc.x, checkLoc.y);
|
|
|
|
|
var noPass = core.noPass(checkLoc.x, checkLoc.y);
|
|
|
|
|
var id = core.getBlockId(checkLoc.x, checkLoc.y) || '';
|
2022-11-14 17:11:23 +08:00
|
|
|
|
var bgId =
|
|
|
|
|
core.getBlockByNumber(core.getBgNumber(checkLoc.x, checkLoc.y))
|
|
|
|
|
.event.id || '';
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 可以通行
|
2022-11-14 17:11:23 +08:00
|
|
|
|
if (
|
|
|
|
|
!noPass ||
|
|
|
|
|
cls == 'items' ||
|
|
|
|
|
(id.startsWith('X') && !ignoreInJump.event.includes(id)) ||
|
|
|
|
|
(bgId.startsWith('X') && !ignoreInJump.bg.includes(bgId))
|
|
|
|
|
)
|
|
|
|
|
return core.drawTip('当前无法使用技能');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 不是怪物且不可以通行
|
2022-11-14 17:11:23 +08:00
|
|
|
|
if (noPass && !(cls == 'enemys' || cls == 'enemy48')) {
|
|
|
|
|
var toLoc = checkNoPass(
|
|
|
|
|
direction,
|
|
|
|
|
checkLoc.x,
|
|
|
|
|
checkLoc.y,
|
|
|
|
|
true
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
if (!toLoc) return;
|
2023-01-05 22:21:40 +08:00
|
|
|
|
if (flags.chapter <= 1) core.status.hero.hp -= 200 * flags.hard;
|
2022-11-13 18:02:05 +08:00
|
|
|
|
core.updateStatusBar();
|
|
|
|
|
flags['jump_' + core.status.floorId]++;
|
|
|
|
|
if (core.status.hero.hp <= 0) {
|
|
|
|
|
core.status.hero.hp = 0;
|
|
|
|
|
core.updateStatusBar();
|
|
|
|
|
core.events.lose('你跳死了');
|
|
|
|
|
}
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.playSound('015-Jump01.ogg');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
core.insertAction([
|
2022-11-14 17:11:23 +08:00
|
|
|
|
{ type: 'jumpHero', loc: [toLoc.x, toLoc.y], time: 500 }
|
2022-11-13 18:02:05 +08:00
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
// 是怪物
|
2022-11-14 17:11:23 +08:00
|
|
|
|
if (cls == 'enemys' || cls == 'enemy48') {
|
|
|
|
|
var firstNoPass = checkNoPass(
|
|
|
|
|
direction,
|
|
|
|
|
checkLoc.x,
|
|
|
|
|
checkLoc.y,
|
|
|
|
|
false
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
if (!firstNoPass) return;
|
2023-01-06 16:21:17 +08:00
|
|
|
|
if (flags.chapter <= 1) core.status.hero.hp -= 200 * flags.hard;
|
2022-11-13 18:02:05 +08:00
|
|
|
|
core.updateStatusBar();
|
|
|
|
|
flags['jump_' + core.status.floorId]++;
|
|
|
|
|
if (core.status.hero.hp <= 0) {
|
|
|
|
|
core.status.hero.hp = 0;
|
|
|
|
|
core.updateStatusBar();
|
|
|
|
|
core.events.lose('你跳死了');
|
|
|
|
|
}
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.playSound('015-Jump01.ogg');
|
|
|
|
|
core.insertAction([
|
|
|
|
|
{
|
|
|
|
|
type: 'jump',
|
|
|
|
|
from: [checkLoc.x, checkLoc.y],
|
|
|
|
|
to: [firstNoPass.x, firstNoPass.y],
|
|
|
|
|
time: 500,
|
|
|
|
|
keep: true
|
|
|
|
|
}
|
|
|
|
|
]);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
}
|
|
|
|
|
// 检查一条线上的不可通过
|
2022-11-14 17:11:23 +08:00
|
|
|
|
function checkNoPass(direction, x, y, startNo) {
|
2022-11-13 18:02:05 +08:00
|
|
|
|
if (!startNo) startNo = false;
|
|
|
|
|
switch (direction) {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
case 'up':
|
2022-11-13 18:02:05 +08:00
|
|
|
|
y--;
|
|
|
|
|
break;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
case 'right':
|
2022-11-13 18:02:05 +08:00
|
|
|
|
x++;
|
|
|
|
|
break;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
case 'down':
|
2022-11-13 18:02:05 +08:00
|
|
|
|
y++;
|
|
|
|
|
break;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
case 'left':
|
2022-11-13 18:02:05 +08:00
|
|
|
|
x--;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2022-11-14 17:11:23 +08:00
|
|
|
|
if (
|
|
|
|
|
x > core.status.thisMap.width - 1 ||
|
|
|
|
|
y > core.status.thisMap.height - 1 ||
|
|
|
|
|
x < 0 ||
|
|
|
|
|
y < 0
|
|
|
|
|
)
|
|
|
|
|
return core.drawTip('当前无法使用技能');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
var id = core.getBlockId(x, y) || '';
|
|
|
|
|
if (core.getBgNumber(x, y))
|
2022-11-14 17:11:23 +08:00
|
|
|
|
var bgId =
|
|
|
|
|
core.getBlockByNumber(core.getBgNumber(x, y)).event
|
|
|
|
|
.id || '';
|
2022-11-13 18:02:05 +08:00
|
|
|
|
else var bgId = '';
|
2022-11-14 17:11:23 +08:00
|
|
|
|
if (
|
|
|
|
|
core.noPass(x, y) ||
|
|
|
|
|
core.getBlockCls(x, y) == 'items' ||
|
|
|
|
|
(id.startsWith('X') && !ignoreInJump.event.includes(id)) ||
|
|
|
|
|
(bgId.startsWith('X') && !ignoreInJump.bg.includes(bgId)) ||
|
|
|
|
|
core.getBlockCls(x, y) == 'animates'
|
|
|
|
|
)
|
2022-11-13 18:02:05 +08:00
|
|
|
|
return checkNoPass(direction, x, y, true);
|
|
|
|
|
if (!startNo) return checkNoPass(direction, x, y, false);
|
2022-11-14 17:11:23 +08:00
|
|
|
|
return { x: x, y: y };
|
2022-11-13 18:02:05 +08:00
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
},
|
2022-11-14 17:11:23 +08:00
|
|
|
|
towerBoss: function () {
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 智慧boss
|
|
|
|
|
// 变量们
|
|
|
|
|
var stage = 1,
|
|
|
|
|
hp = 10000,
|
|
|
|
|
seconds = 0,
|
|
|
|
|
boomLocs = [], // 随机轰炸
|
|
|
|
|
heroHp;
|
|
|
|
|
// 初始化
|
|
|
|
|
this.initTowerBoss = function () {
|
|
|
|
|
stage = 1;
|
|
|
|
|
hp = 10000;
|
|
|
|
|
seconds = 0;
|
|
|
|
|
heroHp = core.status.hero.hp;
|
|
|
|
|
core.dynamicChangeHp(0, 10000, 10000);
|
|
|
|
|
core.autoFixRouteBoss(true);
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.insertAction([{ type: 'sleep', time: 1000, noSkip: true }]);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
setTimeout(core.bossCore, 1000);
|
|
|
|
|
};
|
|
|
|
|
// 录像自动修正
|
|
|
|
|
this.autoFixRouteBoss = function (isStart) {
|
|
|
|
|
var route = core.status.route;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
if (isStart) {
|
|
|
|
|
// 开始修正 记录当前录像长度
|
2022-11-13 18:02:05 +08:00
|
|
|
|
flags.startFix = route.length - 1;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
// 结束修正 删除录像 并追加跳过步骤
|
|
|
|
|
route.splice(flags.startFix);
|
2022-11-14 17:11:23 +08:00
|
|
|
|
route.push('choices:0');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
delete flags.startFix;
|
|
|
|
|
};
|
|
|
|
|
// 血条
|
|
|
|
|
this.healthBar = function (now, total) {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
var nowLength = (now / total) * 476; // 当前血量下绘制长度
|
|
|
|
|
var color = [
|
|
|
|
|
255 * 2 - (now / total) * 2 * 255,
|
|
|
|
|
(now / total) * 2 * 255,
|
|
|
|
|
0,
|
|
|
|
|
1
|
|
|
|
|
]; // 根据当前血量计算颜色
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 建画布
|
|
|
|
|
if (!core.dymCanvas.healthBar)
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.createCanvas('healthBar', 0, 0, 480, 16, 140);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
else core.clearMap('healthBar');
|
|
|
|
|
// 底
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.fillRect('healthBar', 0, 0, 480, 16, '#bbbbbb');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// css特效
|
2022-11-14 17:11:23 +08:00
|
|
|
|
var style = document.getElementById('healthBar').getContext('2d');
|
|
|
|
|
style.shadowColor = 'rgba(0, 0, 0, 0.8)';
|
2022-11-13 18:02:05 +08:00
|
|
|
|
style.shadowBlur = 5;
|
|
|
|
|
style.shadowOffsetX = 10;
|
|
|
|
|
style.shadowOffsetY = 5;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
style.filter = 'blur(1px)';
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 绘制
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.fillRect('healthBar', 2, 2, nowLength, 12, color);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// css特效
|
2022-11-14 17:11:23 +08:00
|
|
|
|
style.shadowColor = 'rgba(0, 0, 0, 0.5)';
|
2022-11-13 18:02:05 +08:00
|
|
|
|
style.shadowOffsetX = 0;
|
|
|
|
|
style.shadowOffsetY = 0;
|
|
|
|
|
// 绘制边框
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.strokeRect('healthBar', 1, 1, 478, 14, '#ffffff', 2);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 绘制文字
|
2022-11-14 17:11:23 +08:00
|
|
|
|
style.shadowColor = 'rgba(0, 0, 0, 1)';
|
2022-11-13 18:02:05 +08:00
|
|
|
|
style.shadowBlur = 3;
|
|
|
|
|
style.shadowOffsetX = 2;
|
|
|
|
|
style.shadowOffsetY = 1;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
style.filter = 'none';
|
|
|
|
|
core.fillText(
|
|
|
|
|
'healthBar',
|
|
|
|
|
now + '/' + total,
|
|
|
|
|
5,
|
|
|
|
|
13.5,
|
|
|
|
|
'#ffffff',
|
|
|
|
|
'16px normal'
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
};
|
|
|
|
|
// 血量变化
|
|
|
|
|
this.dynamicChangeHp = function (from, to, total) {
|
|
|
|
|
var frame = 0,
|
|
|
|
|
speed = (to - from) / 50,
|
|
|
|
|
now = from;
|
|
|
|
|
var interval = window.setInterval(() => {
|
|
|
|
|
frame++;
|
|
|
|
|
if (frame == 50) {
|
|
|
|
|
clearInterval(interval);
|
|
|
|
|
core.healthBar(to, total);
|
|
|
|
|
}
|
|
|
|
|
now += speed;
|
|
|
|
|
core.healthBar(now, total);
|
|
|
|
|
}, 20);
|
|
|
|
|
};
|
|
|
|
|
// boss说话跳字
|
|
|
|
|
this.skipWord = function (words, x, y, time) {
|
|
|
|
|
x = x || 0;
|
|
|
|
|
y = y || 16;
|
|
|
|
|
time = time || 3000;
|
|
|
|
|
// 创建画布
|
|
|
|
|
if (!core.dymCanvas.words)
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.createCanvas('words', x, y, 480, 24, 135);
|
|
|
|
|
else core.clearMap('words');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
if (flags.wordsTimeOut) clearTimeout(flags.wordsTimeOut);
|
|
|
|
|
core.dynamicCurtain(y, y + 24, time / 3);
|
|
|
|
|
// css
|
2022-11-14 17:11:23 +08:00
|
|
|
|
var style = document.getElementById('words').getContext('2d');
|
|
|
|
|
style.shadowColor = 'rgba(0, 0, 0, 1)';
|
2022-11-13 18:02:05 +08:00
|
|
|
|
style.shadowBlur = 3;
|
|
|
|
|
style.shadowOffsetX = 2;
|
|
|
|
|
style.shadowOffsetY = 1;
|
|
|
|
|
// 一个一个绘制
|
|
|
|
|
skip1(0);
|
|
|
|
|
// 跳字
|
2022-11-14 17:11:23 +08:00
|
|
|
|
function skip1(now) {
|
2022-11-13 18:02:05 +08:00
|
|
|
|
if (parseInt(now) >= words.length) {
|
|
|
|
|
flags.wordsTimeOut = setTimeout(() => {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.deleteCanvas('words');
|
|
|
|
|
core.deleteCanvas('wordsBg');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
}, time);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
var frame = 0,
|
|
|
|
|
blur = 2,
|
|
|
|
|
nx = 4 + now * 24;
|
|
|
|
|
var skip2 = window.setInterval(() => {
|
|
|
|
|
blur -= 0.4;
|
|
|
|
|
frame++;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.clearMap('words', nx, 0, 24, 24);
|
|
|
|
|
style.filter = 'blur(' + blur + 'px)';
|
|
|
|
|
core.fillText(
|
|
|
|
|
'words',
|
|
|
|
|
words[now],
|
|
|
|
|
nx,
|
|
|
|
|
20,
|
|
|
|
|
'#ffffff',
|
|
|
|
|
'22px normal'
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
if (frame == 5) {
|
|
|
|
|
clearInterval(skip2);
|
|
|
|
|
skip1(now + 1);
|
|
|
|
|
}
|
|
|
|
|
}, 20);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
// 匀变速下降背景
|
|
|
|
|
this.dynamicCurtain = function (from, to, time, width) {
|
|
|
|
|
width = width || 480;
|
|
|
|
|
if (!core.dymCanvas.wordsBg)
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.createCanvas('wordsBg', 0, from, width, 24, 130);
|
|
|
|
|
else core.clearMap('wordsBg');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
time /= 1000;
|
|
|
|
|
var ny = from,
|
|
|
|
|
frame = 0,
|
2022-11-14 17:11:23 +08:00
|
|
|
|
a = (2 * (to - from)) / Math.pow(time * 50, 2),
|
2022-11-13 18:02:05 +08:00
|
|
|
|
speed = a * time * 50;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
var style = document.getElementById('wordsBg').getContext('2d');
|
|
|
|
|
style.shadowColor = 'rgba(0, 0, 0, 0.8)';
|
2022-11-13 18:02:05 +08:00
|
|
|
|
var wordsInterval = window.setInterval(() => {
|
|
|
|
|
frame++;
|
|
|
|
|
speed -= a;
|
|
|
|
|
ny += speed;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.clearMap('wordsBg');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
style.shadowBlur = 8;
|
|
|
|
|
style.shadowOffsetY = 2;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.fillRect(
|
|
|
|
|
'wordsBg',
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
width,
|
|
|
|
|
ny - from,
|
|
|
|
|
[180, 180, 180, 0.7]
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
style.shadowBlur = 3;
|
|
|
|
|
style.shadowOffsetY = 0;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.strokeRect(
|
|
|
|
|
'wordsBg',
|
|
|
|
|
1,
|
|
|
|
|
1,
|
|
|
|
|
width - 2,
|
|
|
|
|
ny - from - 2,
|
|
|
|
|
[255, 255, 255, 0.7],
|
|
|
|
|
2
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
if (frame >= time * 50) {
|
|
|
|
|
clearInterval(wordsInterval);
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.clearMap('wordsBg');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
style.shadowBlur = 8;
|
|
|
|
|
style.shadowOffsetY = 2;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.fillRect(
|
|
|
|
|
'wordsBg',
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
width,
|
|
|
|
|
to - from,
|
|
|
|
|
[180, 180, 180, 0.7]
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
style.shadowBlur = 3;
|
|
|
|
|
style.shadowOffsetY = 0;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.strokeRect(
|
|
|
|
|
'wordsBg',
|
|
|
|
|
1,
|
|
|
|
|
1,
|
|
|
|
|
width - 2,
|
|
|
|
|
ny - from - 2,
|
|
|
|
|
[255, 255, 255, 0.7],
|
|
|
|
|
2
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
}
|
|
|
|
|
}, 20);
|
|
|
|
|
};
|
|
|
|
|
// 攻击boss
|
|
|
|
|
this.attackBoss = function () {
|
|
|
|
|
// 每秒钟地面随机出现伤害图块 踩上去攻击boss 500血
|
|
|
|
|
if (flags.canAttack) return;
|
|
|
|
|
if (Math.random() < 0.8) return;
|
|
|
|
|
if (hp > 3500) {
|
|
|
|
|
var nx = Math.floor(Math.random() * 13 + 1),
|
|
|
|
|
ny = Math.floor(Math.random() * 13 + 1);
|
|
|
|
|
} else if (hp > 2000) {
|
|
|
|
|
var nx = Math.floor(Math.random() * 11 + 2),
|
|
|
|
|
ny = Math.floor(Math.random() * 11 + 2);
|
|
|
|
|
} else if (hp > 1000) {
|
|
|
|
|
var nx = Math.floor(Math.random() * 9 + 3),
|
|
|
|
|
ny = Math.floor(Math.random() * 9 + 3);
|
|
|
|
|
} else {
|
|
|
|
|
var nx = Math.floor(Math.random() * 7 + 4),
|
|
|
|
|
ny = Math.floor(Math.random() * 7 + 4);
|
|
|
|
|
}
|
|
|
|
|
// 在地图上显示
|
|
|
|
|
flags.canAttack = true;
|
|
|
|
|
if (!core.dymCanvas.attackBoss)
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.createCanvas('attackBoss', 0, 0, 480, 480, 35);
|
|
|
|
|
else core.clearMap('attackBoss');
|
|
|
|
|
var style = document.getElementById('attackBoss').getContext('2d');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
var frame1 = 0,
|
|
|
|
|
blur = 3,
|
|
|
|
|
scale = 2,
|
|
|
|
|
speed = 0.04,
|
|
|
|
|
a = 0.0008;
|
|
|
|
|
var atkAnimate = window.setInterval(() => {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.clearMap('attackBoss');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
frame1++;
|
|
|
|
|
speed -= a;
|
|
|
|
|
scale -= speed;
|
|
|
|
|
blur -= 0.06;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
style.filter = 'blur(' + blur + 'px)';
|
|
|
|
|
core.strokeCircle(
|
|
|
|
|
'attackBoss',
|
|
|
|
|
nx * 32 + 16,
|
|
|
|
|
ny * 32 + 16,
|
|
|
|
|
16 * scale,
|
|
|
|
|
[255, 150, 150, 0.7],
|
|
|
|
|
4
|
|
|
|
|
);
|
|
|
|
|
core.fillCircle(
|
|
|
|
|
'attackBoss',
|
|
|
|
|
nx * 32 + 16,
|
|
|
|
|
ny * 32 + 16,
|
|
|
|
|
3 * scale,
|
|
|
|
|
[255, 150, 150, 0.7]
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
if (frame1 == 50) {
|
|
|
|
|
clearInterval(atkAnimate);
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.clearMap('attactkBoss');
|
|
|
|
|
style.filter = 'none';
|
|
|
|
|
core.strokeCircle(
|
|
|
|
|
'attackBoss',
|
|
|
|
|
nx * 32 + 16,
|
|
|
|
|
ny * 32 + 16,
|
|
|
|
|
16,
|
|
|
|
|
[255, 150, 150, 0.7],
|
|
|
|
|
4
|
|
|
|
|
);
|
|
|
|
|
core.fillCircle(
|
|
|
|
|
'attackBoss',
|
|
|
|
|
nx * 32 + 16,
|
|
|
|
|
ny * 32 + 16,
|
|
|
|
|
3,
|
|
|
|
|
[255, 150, 150, 0.7]
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
}
|
|
|
|
|
}, 20);
|
|
|
|
|
// 实时检测勇士位置
|
|
|
|
|
var frame2 = 0;
|
|
|
|
|
var atkBoss = window.setInterval(() => {
|
|
|
|
|
frame2++;
|
|
|
|
|
var x = core.status.hero.loc.x,
|
|
|
|
|
y = core.status.hero.loc.y;
|
|
|
|
|
// 2秒超时
|
|
|
|
|
if (frame2 > 100) {
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
delete flags.canAttack;
|
|
|
|
|
}, 4000);
|
|
|
|
|
clearInterval(atkBoss);
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.deleteCanvas('attackBoss');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (nx == x && ny == y) {
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
delete flags.canAttack;
|
|
|
|
|
}, 4000);
|
|
|
|
|
core.dynamicChangeHp(hp, hp - 500, 10000);
|
|
|
|
|
hp -= 500;
|
|
|
|
|
clearInterval(atkBoss);
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.deleteCanvas('attackBoss');
|
|
|
|
|
if (hp > 3500) core.drawAnimate('hand', 7, 1);
|
|
|
|
|
else if (hp > 2000) core.drawAnimate('hand', 7, 2);
|
|
|
|
|
else if (hp > 1000) core.drawAnimate('hand', 7, 3);
|
|
|
|
|
else core.drawAnimate('hand', 7, 4);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}, 20);
|
|
|
|
|
};
|
|
|
|
|
// 核心函数
|
|
|
|
|
this.bossCore = function () {
|
|
|
|
|
var interval = window.setInterval(() => {
|
|
|
|
|
if (stage == 1) {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
if (seconds == 8)
|
2023-01-04 18:34:35 +08:00
|
|
|
|
core.skipWord('智慧之神:果然,你和别人不一样。');
|
2022-11-14 17:11:23 +08:00
|
|
|
|
if (seconds == 12)
|
2023-01-04 18:34:35 +08:00
|
|
|
|
core.skipWord('智慧之神:你知道去躲避那些攻击。');
|
2022-11-14 17:11:23 +08:00
|
|
|
|
if (seconds == 16)
|
2023-01-04 18:34:35 +08:00
|
|
|
|
core.skipWord(
|
|
|
|
|
'智慧之神:之前的那些人总会一头撞上我的攻击,悲剧收场。'
|
|
|
|
|
);
|
2022-11-14 17:11:23 +08:00
|
|
|
|
if (seconds == 20)
|
|
|
|
|
core.skipWord('提示:踩在红圈上可以对智慧之神造成伤害');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
if (seconds > 10) core.attackBoss();
|
|
|
|
|
if (seconds % 10 == 0) core.intelligentArrow();
|
2022-11-14 17:11:23 +08:00
|
|
|
|
if (seconds % 7 == 0 && seconds != 0)
|
|
|
|
|
core.intelligentDoor();
|
2022-11-13 18:02:05 +08:00
|
|
|
|
if (seconds > 20 && seconds % 13 == 0) core.icyMomentem();
|
|
|
|
|
}
|
|
|
|
|
if (stage == 1 && hp <= 7000) {
|
|
|
|
|
stage++;
|
|
|
|
|
seconds = 0;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.skipWord('智慧之神:不错小伙子');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
core.pauseBgm();
|
|
|
|
|
}
|
|
|
|
|
if (stage == 2) {
|
2023-01-04 18:34:35 +08:00
|
|
|
|
if (seconds == 4)
|
|
|
|
|
core.skipWord('智慧之神:你的确拥有智慧。');
|
2022-11-14 17:11:23 +08:00
|
|
|
|
if (seconds == 8)
|
2023-01-04 18:34:35 +08:00
|
|
|
|
core.skipWord('智慧之神:或许你就是那个未来的救星。');
|
2022-11-14 17:11:23 +08:00
|
|
|
|
if (seconds == 12)
|
|
|
|
|
core.skipWord('智慧之神:不过,这场战斗才刚刚开始');
|
|
|
|
|
if (seconds == 25)
|
|
|
|
|
core.skipWord('提示:方形区域均为危险区域');
|
|
|
|
|
if (seconds == 15)
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
core.playSound('thunder.mp3');
|
|
|
|
|
}, 500);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
if (seconds == 16) core.startStage2();
|
|
|
|
|
if (seconds > 20) core.attackBoss();
|
|
|
|
|
if (seconds % 4 == 0 && seconds > 20) core.randomThunder();
|
|
|
|
|
if (seconds > 30 && seconds % 12 == 0) core.ballThunder();
|
|
|
|
|
}
|
|
|
|
|
if (hp <= 3500 && stage == 2) {
|
|
|
|
|
stage++;
|
|
|
|
|
seconds = 0;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.skipWord('智慧之神:不得不说小伙子');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
core.pauseBgm();
|
|
|
|
|
}
|
|
|
|
|
if (stage >= 3) {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
if (seconds == 4)
|
2023-01-04 18:34:35 +08:00
|
|
|
|
core.skipWord('智慧之神:拥有智慧就是不一样。');
|
2022-11-14 17:11:23 +08:00
|
|
|
|
if (seconds == 8)
|
|
|
|
|
core.skipWord('智慧之神:不过,你还得再过我一关!');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
if (seconds == 12) core.startStage3();
|
|
|
|
|
if (seconds == 15) {
|
|
|
|
|
flags.booming = true;
|
|
|
|
|
core.randomBoom();
|
|
|
|
|
}
|
|
|
|
|
if (seconds > 20) core.attackBoss();
|
|
|
|
|
if (seconds > 20 && seconds % 10 == 0) core.chainThunder();
|
|
|
|
|
if (hp == 2000 && stage == 3) {
|
|
|
|
|
stage++;
|
|
|
|
|
flags.booming = false;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.skipWord('智慧之神:还没有结束!');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
core.startStage4();
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
flags.booming = true;
|
|
|
|
|
core.randomBoom();
|
|
|
|
|
}, 5000);
|
|
|
|
|
}
|
|
|
|
|
if (hp == 1000 && stage == 4) {
|
|
|
|
|
stage++;
|
|
|
|
|
flags.booming = false;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.skipWord('智慧之神:还没有结束!!!!!!');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
core.startStage5();
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
flags.booming = true;
|
|
|
|
|
core.randomBoom();
|
|
|
|
|
}, 5000);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (hp == 0) {
|
|
|
|
|
clearInterval(interval);
|
|
|
|
|
clearInterval(flags.boom);
|
|
|
|
|
core.status.hero.hp = heroHp;
|
|
|
|
|
core.autoFixRouteBoss(false);
|
|
|
|
|
delete flags.__bgm__;
|
|
|
|
|
core.pauseBgm();
|
|
|
|
|
core.insertAction([
|
2023-01-04 18:34:35 +08:00
|
|
|
|
'\t[智慧之神,E557]\b[down,7,4]看来你真的会成为那个拯救未来的人。',
|
|
|
|
|
'\t[智慧之神,E557]\b[down,7,4]记住,拥有智慧便可以掌控万物。',
|
|
|
|
|
'\t[低级智人]\b[up,hero]智慧?智慧到底是什么?',
|
|
|
|
|
'\t[智慧之神,E557]\b[down,7,4]最终,你会知道答案的。',
|
|
|
|
|
'\t[智慧之神,E557]\b[down,7,4]继续向东前进吧,那里能找到你想要的答案。',
|
2022-11-14 17:11:23 +08:00
|
|
|
|
{ type: 'openDoor', loc: [13, 6], floorId: 'MT19' },
|
2023-01-04 18:34:35 +08:00
|
|
|
|
'\t[智慧之神,E557]\b[down,7,4]我这就把你送出去',
|
2022-11-14 17:11:23 +08:00
|
|
|
|
{ type: 'setValue', name: 'flag:boss1', value: 'true' },
|
|
|
|
|
{ type: 'changeFloor', floorId: 'MT20', loc: [7, 9] },
|
2023-01-04 18:34:35 +08:00
|
|
|
|
{ type: 'forbidSave' },
|
|
|
|
|
{ type: 'showStatusBar' },
|
2022-11-14 17:11:23 +08:00
|
|
|
|
{
|
|
|
|
|
type: 'function',
|
|
|
|
|
function: '() => {\ncore.deleteAllCanvas();\n}'
|
2023-01-04 18:34:35 +08:00
|
|
|
|
}
|
2022-11-13 18:02:05 +08:00
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
seconds++;
|
|
|
|
|
}, 1000);
|
|
|
|
|
};
|
2022-11-14 17:11:23 +08:00
|
|
|
|
// ------ 第一阶段 10000~7000血 ------ //
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 技能1 智慧之箭 1000伤害
|
|
|
|
|
this.intelligentArrow = function (fromSelf) {
|
|
|
|
|
// 坐标
|
|
|
|
|
var loc = Math.floor(Math.random() * 13 + 1);
|
2022-11-14 17:11:23 +08:00
|
|
|
|
var direction = Math.random() > 0.5 ? 'horizon' : 'vertical';
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 执行次数
|
|
|
|
|
if (!fromSelf) {
|
|
|
|
|
var times = Math.ceil(Math.random() * 8) + 4;
|
|
|
|
|
var nowTime = 1;
|
|
|
|
|
var times1 = window.setInterval(() => {
|
|
|
|
|
core.intelligentArrow(true);
|
|
|
|
|
nowTime++;
|
|
|
|
|
if (nowTime >= times) {
|
|
|
|
|
clearInterval(times1);
|
|
|
|
|
}
|
|
|
|
|
}, 200);
|
|
|
|
|
}
|
|
|
|
|
// 防重复
|
2022-11-14 17:11:23 +08:00
|
|
|
|
if (core.dymCanvas['inteArrow' + loc + direction])
|
|
|
|
|
return core.intelligentArrow(true);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 危险区域
|
|
|
|
|
if (!core.dymCanvas.danger1)
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.createCanvas('danger1', 0, 0, 480, 480, 35);
|
|
|
|
|
if (direction == 'horizon') {
|
2022-11-13 18:02:05 +08:00
|
|
|
|
for (var nx = 1; nx < 14; nx++) {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.fillRect(
|
|
|
|
|
'danger1',
|
|
|
|
|
nx * 32 + 2,
|
|
|
|
|
loc * 32 + 2,
|
|
|
|
|
28,
|
|
|
|
|
28,
|
|
|
|
|
[255, 0, 0, 0.6]
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
for (var ny = 1; ny < 14; ny++) {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.fillRect(
|
|
|
|
|
'danger1',
|
|
|
|
|
loc * 32 + 2,
|
|
|
|
|
ny * 32 + 2,
|
|
|
|
|
28,
|
|
|
|
|
28,
|
|
|
|
|
[255, 0, 0, 0.6]
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// 箭
|
2022-11-14 17:11:23 +08:00
|
|
|
|
if (!core.dymCanvas['inteArrow' + loc + direction])
|
|
|
|
|
core.createCanvas(
|
|
|
|
|
'inteArrow' + loc + direction,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
544,
|
|
|
|
|
544,
|
|
|
|
|
65
|
|
|
|
|
);
|
|
|
|
|
core.clearMap('inteArrow' + loc + direction);
|
|
|
|
|
if (direction == 'horizon')
|
|
|
|
|
core.drawImage(
|
|
|
|
|
'inteArrow' + loc + direction,
|
|
|
|
|
'arrow.png',
|
|
|
|
|
448,
|
|
|
|
|
loc * 32,
|
|
|
|
|
102,
|
|
|
|
|
32
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
else
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.drawImage(
|
|
|
|
|
'inteArrow' + loc + direction,
|
|
|
|
|
'arrow.png',
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
259,
|
|
|
|
|
75,
|
|
|
|
|
loc * 32 - 32,
|
|
|
|
|
480,
|
|
|
|
|
102,
|
|
|
|
|
32,
|
|
|
|
|
Math.PI / 2
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 动画与伤害函数
|
|
|
|
|
setTimeout(() => {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.playSound('arrow.mp3');
|
|
|
|
|
core.deleteCanvas('danger1');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 动画效果
|
|
|
|
|
var nloc = 0,
|
|
|
|
|
speed = 0;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
var damaged = {};
|
2022-11-13 18:02:05 +08:00
|
|
|
|
var skill1 = window.setInterval(() => {
|
|
|
|
|
speed -= 1;
|
|
|
|
|
nloc += speed;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
if (direction == 'horizon')
|
|
|
|
|
core.relocateCanvas(
|
|
|
|
|
'inteArrow' + loc + direction,
|
|
|
|
|
nloc,
|
|
|
|
|
0
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
else
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.relocateCanvas(
|
|
|
|
|
'inteArrow' + loc + direction,
|
|
|
|
|
0,
|
|
|
|
|
nloc
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
if (nloc < -480) {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.deleteCanvas('inteArrow' + loc + direction);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
clearInterval(skill1);
|
|
|
|
|
}
|
|
|
|
|
// 伤害判定
|
|
|
|
|
if (!damaged[loc + direction]) {
|
|
|
|
|
var x = core.status.hero.loc.x,
|
|
|
|
|
y = core.status.hero.loc.y;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
if (direction == 'horizon') {
|
|
|
|
|
if (
|
|
|
|
|
y == loc &&
|
|
|
|
|
Math.floor((480 + nloc) / 32) == x
|
|
|
|
|
) {
|
2022-11-13 18:02:05 +08:00
|
|
|
|
damaged[loc + direction] = true;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.drawHeroAnimate('hand');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
core.status.hero.hp -= 1000;
|
2023-01-05 01:11:06 +08:00
|
|
|
|
core.addPop(x * 32 + 16, y * 32 + 16, -1000);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
core.updateStatusBar();
|
|
|
|
|
if (core.status.hero.hp < 0) {
|
|
|
|
|
clearInterval(skill1);
|
|
|
|
|
core.status.hero.hp = 0;
|
|
|
|
|
core.updateStatusBar();
|
|
|
|
|
core.events.lose();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
if (
|
|
|
|
|
x == loc &&
|
|
|
|
|
Math.floor((480 + nloc) / 32) == y
|
|
|
|
|
) {
|
2022-11-13 18:02:05 +08:00
|
|
|
|
damaged[loc + direction] = true;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.drawHeroAnimate('hand');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
core.status.hero.hp -= 1000;
|
2023-01-05 01:11:06 +08:00
|
|
|
|
core.addPop(x * 32 + 16, y * 32 + 16, -1000);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
core.updateStatusBar();
|
|
|
|
|
if (core.status.hero.hp < 0) {
|
|
|
|
|
clearInterval(skill1);
|
|
|
|
|
core.status.hero.hp = 0;
|
|
|
|
|
core.updateStatusBar();
|
|
|
|
|
core.events.lose();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}, 20);
|
|
|
|
|
}, 3000);
|
|
|
|
|
};
|
|
|
|
|
// 技能2 智慧之门 随机传送
|
|
|
|
|
this.intelligentDoor = function () {
|
|
|
|
|
if (Math.random() < 0.5) return;
|
|
|
|
|
// 随机位置
|
|
|
|
|
var toX = Math.floor(Math.random() * 13) + 1,
|
|
|
|
|
toY = Math.floor(Math.random() * 13) + 1;
|
|
|
|
|
// 在勇士身上绘制动画
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.drawHeroAnimate('magicAtk');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 在目标位置绘制动画
|
2022-11-14 17:11:23 +08:00
|
|
|
|
if (!core.dymCanvas['door' + toX + '_' + toY])
|
|
|
|
|
core.createCanvas('door' + toX + '_' + toY, 0, 0, 480, 480, 35);
|
|
|
|
|
else core.clearMap('door' + toX + '_' + toY);
|
|
|
|
|
var style = document
|
|
|
|
|
.getElementById('door' + toX + '_' + toY)
|
|
|
|
|
.getContext('2d');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
var frame = 0,
|
|
|
|
|
width = 0,
|
|
|
|
|
a = 0.0128,
|
|
|
|
|
speed = 0.64;
|
|
|
|
|
// 动画
|
|
|
|
|
var skill2 = window.setInterval(() => {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
frame++;
|
2022-11-13 18:02:05 +08:00
|
|
|
|
if (frame < 40) return;
|
|
|
|
|
if (frame == 100) {
|
|
|
|
|
clearInterval(skill2);
|
|
|
|
|
// 执行传送
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.insertAction([{ type: 'changePos', loc: [toX, toY] }]);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 删除传送门
|
|
|
|
|
setTimeout(() => {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.deleteCanvas('door' + toX + '_' + toY);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
}, 2000);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
width += speed * 2;
|
|
|
|
|
speed -= a;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.clearMap('door' + toX + '_' + toY);
|
|
|
|
|
style.shadowColor = 'rgba(255, 255, 255, 1)';
|
2022-11-13 18:02:05 +08:00
|
|
|
|
style.shadowBlur = 7;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
style.filter = 'blur(5px)';
|
|
|
|
|
core.fillRect(
|
|
|
|
|
'door' + toX + '_' + toY,
|
|
|
|
|
toX * 32,
|
|
|
|
|
toY * 32 - 24,
|
|
|
|
|
width,
|
|
|
|
|
48,
|
|
|
|
|
[255, 255, 255, 0.7]
|
|
|
|
|
);
|
|
|
|
|
style.shadowColor = 'rgba(0, 0, 0, 0.5)';
|
|
|
|
|
style.filter = 'blur(3px)';
|
|
|
|
|
core.strokeRect(
|
|
|
|
|
'door' + toX + '_' + toY,
|
|
|
|
|
toX * 32,
|
|
|
|
|
toY * 32 - 24,
|
|
|
|
|
width,
|
|
|
|
|
48,
|
|
|
|
|
[255, 255, 255, 0.7],
|
|
|
|
|
3
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
}, 20);
|
|
|
|
|
};
|
|
|
|
|
// 技能3 万冰之势 全屏随机转换滑冰 如果转换时在滑冰上造成5000点伤害
|
|
|
|
|
this.icyMomentem = function () {
|
|
|
|
|
if (flags.haveIce) return;
|
|
|
|
|
if (Math.random() < 0.5) return;
|
|
|
|
|
var times = Math.floor(Math.random() * 100);
|
|
|
|
|
// 防卡 就setInterval吧
|
|
|
|
|
var locs = [],
|
|
|
|
|
now = 0;
|
|
|
|
|
flags.haveIce = true;
|
|
|
|
|
if (!core.dymCanvas.icyMomentem)
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.createCanvas('icyMomentem', 0, 0, 480, 480, 35);
|
|
|
|
|
else core.clearMap('icyMomentem');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
var skill3 = window.setInterval(() => {
|
|
|
|
|
var nx = Math.floor(Math.random() * 13) + 1,
|
|
|
|
|
ny = Math.floor(Math.random() * 13) + 1;
|
|
|
|
|
if (!locs.includes([nx, ny])) {
|
|
|
|
|
locs.push([nx, ny]);
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.fillRect(
|
|
|
|
|
'icyMomentem',
|
|
|
|
|
locs[now][0] * 32 + 2,
|
|
|
|
|
locs[now][1] * 32 + 2,
|
|
|
|
|
28,
|
|
|
|
|
28,
|
|
|
|
|
[150, 150, 255, 0.6]
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
}
|
|
|
|
|
if (now == times) {
|
|
|
|
|
clearInterval(skill3);
|
|
|
|
|
skill3Effect();
|
|
|
|
|
}
|
|
|
|
|
now++;
|
|
|
|
|
}, 20);
|
|
|
|
|
// 动画和伤害函数
|
2022-11-14 17:11:23 +08:00
|
|
|
|
function skill3Effect() {
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 防卡 setInterval
|
|
|
|
|
var index = 0;
|
|
|
|
|
var effect = window.setInterval(() => {
|
|
|
|
|
var x = core.status.hero.loc.x,
|
|
|
|
|
y = core.status.hero.loc.y;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.clearMap(
|
|
|
|
|
'icyMomentem',
|
|
|
|
|
locs[index][0] * 32,
|
|
|
|
|
locs[index][1] * 32,
|
|
|
|
|
32,
|
|
|
|
|
32
|
|
|
|
|
);
|
|
|
|
|
core.setBgFgBlock(
|
|
|
|
|
'bg',
|
|
|
|
|
167,
|
|
|
|
|
locs[index][0],
|
|
|
|
|
locs[index][1]
|
|
|
|
|
);
|
|
|
|
|
core.drawAnimate('ice', locs[index][0], locs[index][1]);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
if (x == locs[index][0] && y == locs[index][1]) {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.drawHeroAnimate('hand');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
core.status.hero.hp -= 5000;
|
2023-01-05 01:11:06 +08:00
|
|
|
|
core.addPop(x * 32 + 16, y * 32 + 16, -5000);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
core.updateStatusBar();
|
|
|
|
|
if (core.status.hero.hp < 0) {
|
|
|
|
|
core.status.hero.hp = 0;
|
|
|
|
|
core.updateStatusBar();
|
|
|
|
|
core.events.lose();
|
|
|
|
|
clearInterval(effect);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (index >= locs.length - 1) {
|
|
|
|
|
clearInterval(effect);
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
deleteIce(locs);
|
|
|
|
|
}, 5000);
|
|
|
|
|
}
|
|
|
|
|
index++;
|
|
|
|
|
}, 50);
|
|
|
|
|
}
|
|
|
|
|
// 删除函数
|
2022-11-14 17:11:23 +08:00
|
|
|
|
function deleteIce(locs) {
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 照样 setInterval
|
|
|
|
|
var index = 0;
|
|
|
|
|
var deleteIce = window.setInterval(() => {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.setBgFgBlock('bg', 0, locs[index][0], locs[index][1]);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
index++;
|
|
|
|
|
if (index >= locs.length) {
|
|
|
|
|
clearInterval(deleteIce);
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.deleteCanvas('icyMomentem');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
setTimeout(() => {
|
|
|
|
|
delete flags.haveIce;
|
|
|
|
|
}, 5000);
|
|
|
|
|
}
|
|
|
|
|
}, 50);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
// ------ 第二阶段 7000~3500 ------ //
|
|
|
|
|
// 开始第二阶段
|
|
|
|
|
this.startStage2 = function () {
|
|
|
|
|
// 闪烁
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.createCanvas('flash', 0, 0, 480, 480, 160);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
var alpha = 0;
|
|
|
|
|
var frame = 0;
|
|
|
|
|
var start1 = window.setInterval(() => {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.clearMap('flash');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
frame++;
|
|
|
|
|
if (frame <= 8) alpha += 0.125;
|
|
|
|
|
else alpha -= 0.01;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.fillRect('flash', 0, 0, 480, 480, [255, 255, 255, alpha]);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
if (alpha == 0) {
|
|
|
|
|
clearInterval(start1);
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.deleteCanvas('flash');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
}
|
|
|
|
|
if (frame == 8) {
|
|
|
|
|
changeWeather();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
// 切换天气
|
2022-11-14 17:11:23 +08:00
|
|
|
|
function changeWeather() {
|
2022-11-13 18:02:05 +08:00
|
|
|
|
core.setWeather();
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.setWeather('rain', 10);
|
|
|
|
|
core.setWeather('fog', 8);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 色调也得换
|
|
|
|
|
core.setCurtain([0, 0, 0, 0.3]);
|
|
|
|
|
// bgm
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.playBgm('towerBoss2.mp3');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
// ----- 打雷相关 ----- //
|
|
|
|
|
// 随机打雷
|
|
|
|
|
this.randomThunder = function () {
|
|
|
|
|
var x = Math.floor(Math.random() * 13) + 1,
|
|
|
|
|
y = Math.floor(Math.random() * 13) + 1,
|
|
|
|
|
power = Math.ceil(Math.random() * 6);
|
|
|
|
|
// 绘制危险区域
|
|
|
|
|
if (!core.dymCanvas.thunderDanger)
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.createCanvas('thunderDanger', 0, 0, 480, 480, 35);
|
|
|
|
|
else core.clearMap('thunderDanger');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 3*3范围
|
|
|
|
|
for (var nx = x - 1; nx <= x + 1; nx++) {
|
|
|
|
|
for (var ny = y - 1; ny <= y + 1; ny++) {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.fillRect(
|
|
|
|
|
'thunderDanger',
|
|
|
|
|
nx * 32 + 2,
|
|
|
|
|
ny * 32 + 2,
|
|
|
|
|
28,
|
|
|
|
|
28,
|
|
|
|
|
[255, 255, 255, 0.6]
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.deleteCanvas('flash');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
setTimeout(() => {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.playSound('thunder.mp3');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
}, 500);
|
|
|
|
|
setTimeout(() => {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.deleteCanvas('thunderDanger');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
core.drawThunder(x, y, power);
|
|
|
|
|
}, 1000);
|
|
|
|
|
};
|
|
|
|
|
// 绘制
|
|
|
|
|
this.drawThunder = function (x, y, power) {
|
|
|
|
|
var route = core.getThunderRoute(x * 32 + 16, y * 32 + 16, power);
|
|
|
|
|
// 开始绘制
|
|
|
|
|
if (!core.dymCanvas.thunder)
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.createCanvas('thunder', 0, 0, 480, 480, 65);
|
|
|
|
|
else core.clearMap('thunder');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
var style = core.dymCanvas.thunder;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
style.shadowColor = 'rgba(220, 220, 255, 1)';
|
2022-11-13 18:02:05 +08:00
|
|
|
|
style.shadowBlur = power;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
style.filter = 'blur(2.5px)';
|
2022-11-13 18:02:05 +08:00
|
|
|
|
for (var num in route) {
|
|
|
|
|
// 一个个绘制
|
|
|
|
|
for (var i = 0; i < route[num].length - 1; i++) {
|
|
|
|
|
var now = route[num][i],
|
|
|
|
|
next = route[num][i + 1];
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.drawLine(
|
|
|
|
|
'thunder',
|
|
|
|
|
now[0],
|
|
|
|
|
now[1],
|
|
|
|
|
next[0],
|
|
|
|
|
next[1],
|
|
|
|
|
'#ffffff',
|
|
|
|
|
2.5
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// 伤害
|
|
|
|
|
core.getThunderDamage(x, y, power);
|
|
|
|
|
// 闪一下
|
|
|
|
|
var frame1 = 0,
|
|
|
|
|
alpha = 0.5;
|
|
|
|
|
if (!core.dymCanvas.flash)
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.createCanvas('flash', 0, 0, 480, 480, 160);
|
|
|
|
|
else core.clearMap('flash');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
var thunderFlash = window.setInterval(() => {
|
|
|
|
|
alpha -= 0.05;
|
|
|
|
|
frame1++;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.clearMap('flash');
|
|
|
|
|
core.fillRect('flash', 0, 0, 480, 480, [255, 255, 255, alpha]);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
if (frame1 >= 10) {
|
|
|
|
|
clearInterval(thunderFlash);
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.deleteCanvas('flash');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 删除闪电
|
|
|
|
|
setTimeout(() => {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.deleteCanvas('thunder');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
}, 700);
|
|
|
|
|
}
|
|
|
|
|
}, 20);
|
|
|
|
|
};
|
|
|
|
|
// 获得雷电路径
|
|
|
|
|
this.getThunderRoute = function (x, y, power) {
|
|
|
|
|
var route = [];
|
|
|
|
|
for (var num = 0; num < power; num++) {
|
|
|
|
|
var nx = x,
|
|
|
|
|
ny = y;
|
|
|
|
|
route[num] = [];
|
|
|
|
|
for (var i = 0; ny >= 0; i++) {
|
|
|
|
|
if (i > 0) {
|
|
|
|
|
nx += Math.random() * 30 - 15;
|
|
|
|
|
ny -= Math.random() * 80 + 30;
|
|
|
|
|
} else {
|
|
|
|
|
nx += Math.random() * 16 - 8;
|
|
|
|
|
ny += Math.random() * 16 - 8;
|
|
|
|
|
}
|
|
|
|
|
route[num].push([nx, ny]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return route;
|
|
|
|
|
};
|
|
|
|
|
// 打雷伤害判定
|
|
|
|
|
this.getThunderDamage = function (x, y, power) {
|
|
|
|
|
var hx = core.status.hero.loc.x,
|
|
|
|
|
hy = core.status.hero.loc.y;
|
|
|
|
|
if (Math.abs(hx - x) <= 1 && Math.abs(hy - y) <= 1) {
|
|
|
|
|
core.status.hero.hp -= 3000 * power;
|
2023-01-05 01:11:06 +08:00
|
|
|
|
core.addPop(x * 32 + 16, y * 32 + 16, -3000 * power);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
core.updateStatusBar();
|
|
|
|
|
if (core.status.hero.hp < 0) {
|
|
|
|
|
core.status.hero.hp = 0;
|
|
|
|
|
core.updateStatusBar();
|
|
|
|
|
core.events.lose();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
// ----- 打雷 END ----- //
|
|
|
|
|
// 球形闪电 横竖
|
|
|
|
|
this.ballThunder = function () {
|
|
|
|
|
// 随机数量
|
|
|
|
|
var times = Math.ceil(Math.random() * 12) + 6;
|
|
|
|
|
var now = 0,
|
|
|
|
|
locs = [];
|
|
|
|
|
// setInterval执行
|
|
|
|
|
var ballThunder = window.setInterval(() => {
|
|
|
|
|
// 画布
|
2022-11-14 17:11:23 +08:00
|
|
|
|
if (!core.dymCanvas['ballThunder' + now])
|
|
|
|
|
core.createCanvas('ballThunder' + now, 0, 0, 480, 480, 35);
|
|
|
|
|
else core.clearMap('ballThunder' + now);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
var nx = Math.floor(Math.random() * 13) + 1,
|
|
|
|
|
ny = Math.floor(Math.random() * 13) + 1;
|
|
|
|
|
// 添加位置 绘制危险区域
|
|
|
|
|
if (!locs.includes([nx, ny])) {
|
|
|
|
|
locs.push([nx, ny]);
|
|
|
|
|
// 横竖都要画
|
|
|
|
|
for (var mx = 1; mx < 14; mx++) {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.fillRect(
|
|
|
|
|
'ballThunder' + now,
|
|
|
|
|
mx * 32 + 2,
|
|
|
|
|
ny * 32 + 2,
|
|
|
|
|
28,
|
|
|
|
|
28,
|
|
|
|
|
[190, 190, 255, 0.6]
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
}
|
|
|
|
|
for (var my = 1; my < 14; my++) {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.fillRect(
|
|
|
|
|
'ballThunder' + now,
|
|
|
|
|
nx * 32 + 2,
|
|
|
|
|
my * 32 + 2,
|
|
|
|
|
28,
|
|
|
|
|
28,
|
|
|
|
|
[190, 190, 255, 0.6]
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
now++;
|
|
|
|
|
if (now >= times) {
|
|
|
|
|
clearInterval(ballThunder);
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
thunderAnimate(locs);
|
|
|
|
|
}, 1000);
|
|
|
|
|
}
|
|
|
|
|
}, 200);
|
|
|
|
|
// 动画 伤害
|
2022-11-14 17:11:23 +08:00
|
|
|
|
function thunderAnimate(locs) {
|
2022-11-13 18:02:05 +08:00
|
|
|
|
var frame = 0;
|
|
|
|
|
// 画布
|
|
|
|
|
if (!core.dymCanvas.ballAnimate)
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.createCanvas('ballAnimate', 0, 0, 480, 480, 65);
|
|
|
|
|
else core.clearMap('ballAnimate');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
var style = core.dymCanvas.ballAnimate;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
style.shadowColor = 'rgba(255, 255, 255, 1)';
|
2022-11-13 18:02:05 +08:00
|
|
|
|
var damaged = [];
|
|
|
|
|
var animate = window.setInterval(() => {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.clearMap('ballAnimate');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
for (var i = 0; i < locs.length; i++) {
|
|
|
|
|
style.shadowBlur = 16 * Math.random();
|
|
|
|
|
// 错开执行动画
|
|
|
|
|
if (frame - 10 * i > 0) {
|
|
|
|
|
var now = frame - 10 * i;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
if (now == 1) core.playSound('electron.mp3');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 动画
|
|
|
|
|
var nx = locs[i][0] * 32 + 16,
|
|
|
|
|
ny = locs[i][1] * 32 + 16;
|
|
|
|
|
if (now <= 2) {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.fillCircle(
|
|
|
|
|
'ballAnimate',
|
|
|
|
|
nx,
|
|
|
|
|
ny,
|
|
|
|
|
16 + 3 * now,
|
|
|
|
|
[255, 255, 255, 0.9]
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
} else {
|
|
|
|
|
// 上
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.fillCircle(
|
|
|
|
|
'ballAnimate',
|
|
|
|
|
nx,
|
|
|
|
|
ny - 4 * now,
|
|
|
|
|
7 + 2 * Math.random(),
|
|
|
|
|
[255, 255, 255, 0.7]
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 下
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.fillCircle(
|
|
|
|
|
'ballAnimate',
|
|
|
|
|
nx,
|
|
|
|
|
ny + 4 * now,
|
|
|
|
|
7 + 2 * Math.random(),
|
|
|
|
|
[255, 255, 255, 0.7]
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 左
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.fillCircle(
|
|
|
|
|
'ballAnimate',
|
|
|
|
|
nx - 4 * now,
|
|
|
|
|
ny,
|
|
|
|
|
7 + 2 * Math.random(),
|
|
|
|
|
[255, 255, 255, 0.7]
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 右
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.fillCircle(
|
|
|
|
|
'ballAnimate',
|
|
|
|
|
nx + 4 * now,
|
|
|
|
|
ny,
|
|
|
|
|
7 + 2 * Math.random(),
|
|
|
|
|
[255, 255, 255, 0.7]
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
}
|
|
|
|
|
// 清除危险区域
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.clearMap(
|
|
|
|
|
'ballThunder' + i,
|
|
|
|
|
nx - 16,
|
|
|
|
|
ny - 16 - 4 * now,
|
|
|
|
|
32,
|
|
|
|
|
32
|
|
|
|
|
);
|
|
|
|
|
core.clearMap(
|
|
|
|
|
'ballThunder' + i,
|
|
|
|
|
nx - 16,
|
|
|
|
|
ny - 16 + 4 * now,
|
|
|
|
|
32,
|
|
|
|
|
32
|
|
|
|
|
);
|
|
|
|
|
core.clearMap(
|
|
|
|
|
'ballThunder' + i,
|
|
|
|
|
nx - 16 - 4 * now,
|
|
|
|
|
ny - 16,
|
|
|
|
|
32,
|
|
|
|
|
32
|
|
|
|
|
);
|
|
|
|
|
core.clearMap(
|
|
|
|
|
'ballThunder' + i,
|
|
|
|
|
nx - 16 + 4 * now,
|
|
|
|
|
ny - 16,
|
|
|
|
|
32,
|
|
|
|
|
32
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 伤害
|
|
|
|
|
if (!damaged[i]) {
|
|
|
|
|
var x = core.status.hero.loc.x,
|
|
|
|
|
y = core.status.hero.loc.y;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
if (
|
|
|
|
|
((Math.floor((nx - 16 - 4 * now) / 32) ==
|
|
|
|
|
x ||
|
|
|
|
|
Math.floor((nx - 16 + 4 * now) / 32) ==
|
|
|
|
|
x) &&
|
|
|
|
|
locs[i][1] == y) ||
|
|
|
|
|
((Math.floor((ny - 16 - 4 * now) / 32) ==
|
|
|
|
|
y ||
|
|
|
|
|
Math.floor((ny - 16 + 4 * now) / 32) ==
|
|
|
|
|
y) &&
|
|
|
|
|
locs[i][0] == x)
|
|
|
|
|
) {
|
|
|
|
|
damaged[i] = true;
|
2022-11-13 18:02:05 +08:00
|
|
|
|
core.status.hero.hp -= 3000;
|
2023-01-05 01:11:06 +08:00
|
|
|
|
core.addPop(
|
|
|
|
|
x * 32 + 16,
|
|
|
|
|
y * 32 + 16,
|
|
|
|
|
-3000
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
core.updateStatusBar();
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.playSound('electron.mp3');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
if (core.status.hero.hp < 0) {
|
|
|
|
|
core.status.hero.hp = 0;
|
|
|
|
|
core.updateStatusBar();
|
|
|
|
|
core.events.lose();
|
|
|
|
|
clearInterval(animate);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// 结束
|
|
|
|
|
if (i == locs.length - 1 && now > 120) {
|
|
|
|
|
clearInterval(animate);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
frame++;
|
|
|
|
|
}, 20);
|
2022-11-14 17:11:23 +08:00
|
|
|
|
}
|
2022-11-13 18:02:05 +08:00
|
|
|
|
};
|
|
|
|
|
// ------ 第三阶段 3500~0 ------ //
|
|
|
|
|
this.startStage3 = function () {
|
|
|
|
|
// 闪烁
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.createCanvas('flash', 0, 0, 480, 480, 160);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
var alpha = 0;
|
|
|
|
|
var frame = 0;
|
|
|
|
|
var start1 = window.setInterval(() => {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.clearMap('flash');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
frame++;
|
|
|
|
|
if (frame <= 8) alpha += 0.125;
|
|
|
|
|
else alpha -= 0.01;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.fillRect('flash', 0, 0, 480, 480, [255, 255, 255, alpha]);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
if (alpha == 0) {
|
|
|
|
|
clearInterval(start1);
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.deleteCanvas('flash');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
}
|
|
|
|
|
if (frame == 8) {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.playSound('thunder.mp3');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
changeTerra();
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.insertAction([{ type: 'changePos', loc: [7, 7] }]);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
// 改变地形
|
2022-11-14 17:11:23 +08:00
|
|
|
|
function changeTerra() {
|
2022-11-13 18:02:05 +08:00
|
|
|
|
for (var nx = 0; nx < 15; nx++) {
|
|
|
|
|
for (var ny = 0; ny < 15; ny++) {
|
|
|
|
|
if (nx == 0 || nx == 14 || ny == 0 || ny == 14) {
|
|
|
|
|
core.removeBlock(nx, ny);
|
|
|
|
|
}
|
2022-11-14 17:11:23 +08:00
|
|
|
|
if (
|
|
|
|
|
(nx == 1 || nx == 13 || ny == 1 || ny == 13) &&
|
|
|
|
|
nx != 0 &&
|
|
|
|
|
nx != 14 &&
|
|
|
|
|
ny != 0 &&
|
|
|
|
|
ny != 14
|
|
|
|
|
) {
|
2022-11-13 18:02:05 +08:00
|
|
|
|
core.setBlock(527, nx, ny);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.createCanvas('tower7', 0, 0, 480, 480, 15);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 画贴图
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.drawImage(
|
|
|
|
|
'tower7',
|
|
|
|
|
'tower7.jpeg',
|
|
|
|
|
360,
|
|
|
|
|
0,
|
|
|
|
|
32,
|
|
|
|
|
480,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
32,
|
|
|
|
|
480
|
|
|
|
|
);
|
|
|
|
|
core.drawImage(
|
|
|
|
|
'tower7',
|
|
|
|
|
'tower7.jpeg',
|
|
|
|
|
840,
|
|
|
|
|
0,
|
|
|
|
|
32,
|
|
|
|
|
480,
|
|
|
|
|
448,
|
|
|
|
|
0,
|
|
|
|
|
32,
|
|
|
|
|
480
|
|
|
|
|
);
|
|
|
|
|
core.drawImage(
|
|
|
|
|
'tower7',
|
|
|
|
|
'tower7.jpeg',
|
|
|
|
|
392,
|
|
|
|
|
0,
|
|
|
|
|
416,
|
|
|
|
|
32,
|
|
|
|
|
32,
|
|
|
|
|
0,
|
|
|
|
|
416,
|
|
|
|
|
32
|
|
|
|
|
);
|
|
|
|
|
core.drawImage(
|
|
|
|
|
'tower7',
|
|
|
|
|
'tower7.jpeg',
|
|
|
|
|
392,
|
|
|
|
|
448,
|
|
|
|
|
416,
|
|
|
|
|
32,
|
|
|
|
|
32,
|
|
|
|
|
448,
|
|
|
|
|
416,
|
|
|
|
|
32
|
|
|
|
|
);
|
|
|
|
|
core.setBlock('E557', 7, 2);
|
|
|
|
|
core.playBgm('towerBoss3.mp3');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
// 进入第四阶段
|
|
|
|
|
this.startStage4 = function () {
|
|
|
|
|
// 闪烁
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.createCanvas('flash', 0, 0, 480, 480, 160);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
var alpha = 0;
|
|
|
|
|
var frame = 0;
|
|
|
|
|
var start1 = window.setInterval(() => {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.clearMap('flash');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
frame++;
|
|
|
|
|
if (frame <= 8) alpha += 0.125;
|
|
|
|
|
else alpha -= 0.01;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.fillRect('flash', 0, 0, 480, 480, [255, 255, 255, alpha]);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
if (alpha == 0) {
|
|
|
|
|
clearInterval(start1);
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.deleteCanvas('flash');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
}
|
|
|
|
|
if (frame == 8) {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.playSound('thunder.mp3');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
changeTerra();
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.insertAction([{ type: 'changePos', loc: [7, 7] }]);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
// 改变地形
|
2022-11-14 17:11:23 +08:00
|
|
|
|
function changeTerra() {
|
2022-11-13 18:02:05 +08:00
|
|
|
|
for (var nx = 1; nx < 14; nx++) {
|
|
|
|
|
for (var ny = 1; ny < 14; ny++) {
|
|
|
|
|
if (nx == 1 || nx == 13 || ny == 1 || ny == 13) {
|
|
|
|
|
core.removeBlock(nx, ny);
|
|
|
|
|
}
|
2022-11-14 17:11:23 +08:00
|
|
|
|
if (
|
|
|
|
|
(nx == 2 || nx == 12 || ny == 2 || ny == 12) &&
|
|
|
|
|
nx != 1 &&
|
|
|
|
|
nx != 13 &&
|
|
|
|
|
ny != 1 &&
|
|
|
|
|
ny != 13
|
|
|
|
|
) {
|
2022-11-13 18:02:05 +08:00
|
|
|
|
core.setBlock(527, nx, ny);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.createCanvas('tower7', 0, 0, 480, 480, 15);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 画贴图
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.drawImage(
|
|
|
|
|
'tower7',
|
|
|
|
|
'tower7.jpeg',
|
|
|
|
|
360,
|
|
|
|
|
0,
|
|
|
|
|
64,
|
|
|
|
|
480,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
64,
|
|
|
|
|
480
|
|
|
|
|
);
|
|
|
|
|
core.drawImage(
|
|
|
|
|
'tower7',
|
|
|
|
|
'tower7.jpeg',
|
|
|
|
|
776,
|
|
|
|
|
0,
|
|
|
|
|
64,
|
|
|
|
|
480,
|
|
|
|
|
416,
|
|
|
|
|
0,
|
|
|
|
|
64,
|
|
|
|
|
480
|
|
|
|
|
);
|
|
|
|
|
core.drawImage(
|
|
|
|
|
'tower7',
|
|
|
|
|
'tower7.jpeg',
|
|
|
|
|
424,
|
|
|
|
|
0,
|
|
|
|
|
352,
|
|
|
|
|
64,
|
|
|
|
|
64,
|
|
|
|
|
0,
|
|
|
|
|
352,
|
|
|
|
|
64
|
|
|
|
|
);
|
|
|
|
|
core.drawImage(
|
|
|
|
|
'tower7',
|
|
|
|
|
'tower7.jpeg',
|
|
|
|
|
424,
|
|
|
|
|
416,
|
|
|
|
|
352,
|
|
|
|
|
64,
|
|
|
|
|
64,
|
|
|
|
|
416,
|
|
|
|
|
352,
|
|
|
|
|
64
|
|
|
|
|
);
|
|
|
|
|
core.setBlock('E557', 7, 3);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
// 进入第五阶段
|
|
|
|
|
this.startStage5 = function () {
|
|
|
|
|
// 闪烁
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.createCanvas('flash', 0, 0, 480, 480, 160);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
var alpha = 0;
|
|
|
|
|
var frame = 0;
|
|
|
|
|
var start1 = window.setInterval(() => {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.clearMap('flash');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
frame++;
|
|
|
|
|
if (frame <= 8) alpha += 0.125;
|
|
|
|
|
else alpha -= 0.01;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.fillRect('flash', 0, 0, 480, 480, [255, 255, 255, alpha]);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
if (alpha == 0) {
|
|
|
|
|
clearInterval(start1);
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.deleteCanvas('flash');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
}
|
|
|
|
|
if (frame == 8) {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.playSound('thunder.mp3');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
changeTerra();
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.insertAction([{ type: 'changePos', loc: [7, 7] }]);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
// 改变地形
|
2022-11-14 17:11:23 +08:00
|
|
|
|
function changeTerra() {
|
2022-11-13 18:02:05 +08:00
|
|
|
|
for (var nx = 2; nx < 13; nx++) {
|
|
|
|
|
for (var ny = 2; ny < 13; ny++) {
|
|
|
|
|
if (nx == 2 || nx == 12 || ny == 2 || ny == 12) {
|
|
|
|
|
core.removeBlock(nx, ny);
|
|
|
|
|
}
|
2022-11-14 17:11:23 +08:00
|
|
|
|
if (
|
|
|
|
|
(nx == 3 || nx == 11 || ny == 3 || ny == 11) &&
|
|
|
|
|
nx != 2 &&
|
|
|
|
|
nx != 12 &&
|
|
|
|
|
ny != 2 &&
|
|
|
|
|
ny != 12
|
|
|
|
|
) {
|
2022-11-13 18:02:05 +08:00
|
|
|
|
core.setBlock(527, nx, ny);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.createCanvas('tower7', 0, 0, 480, 480, 15);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 画贴图
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.drawImage(
|
|
|
|
|
'tower7',
|
|
|
|
|
'tower7.jpeg',
|
|
|
|
|
360,
|
|
|
|
|
0,
|
|
|
|
|
96,
|
|
|
|
|
480,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
96,
|
|
|
|
|
480
|
|
|
|
|
);
|
|
|
|
|
core.drawImage(
|
|
|
|
|
'tower7',
|
|
|
|
|
'tower7.jpeg',
|
|
|
|
|
744,
|
|
|
|
|
0,
|
|
|
|
|
96,
|
|
|
|
|
480,
|
|
|
|
|
384,
|
|
|
|
|
0,
|
|
|
|
|
96,
|
|
|
|
|
480
|
|
|
|
|
);
|
|
|
|
|
core.drawImage(
|
|
|
|
|
'tower7',
|
|
|
|
|
'tower7.jpeg',
|
|
|
|
|
456,
|
|
|
|
|
0,
|
|
|
|
|
288,
|
|
|
|
|
96,
|
|
|
|
|
96,
|
|
|
|
|
0,
|
|
|
|
|
288,
|
|
|
|
|
96
|
|
|
|
|
);
|
|
|
|
|
core.drawImage(
|
|
|
|
|
'tower7',
|
|
|
|
|
'tower7.jpeg',
|
|
|
|
|
456,
|
|
|
|
|
384,
|
|
|
|
|
288,
|
|
|
|
|
96,
|
|
|
|
|
96,
|
|
|
|
|
384,
|
|
|
|
|
288,
|
|
|
|
|
96
|
|
|
|
|
);
|
|
|
|
|
core.setBlock('E557', 7, 4);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
// 链状闪电 随机连接 碰到勇士则受伤
|
|
|
|
|
this.chainThunder = function () {
|
|
|
|
|
// 随机次数
|
|
|
|
|
var times = Math.ceil(Math.random() * 6) + 3;
|
|
|
|
|
// 画布
|
|
|
|
|
if (!core.dymCanvas.chainDanger)
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.createCanvas('chainDanger', 0, 0, 480, 480, 35);
|
|
|
|
|
else core.clearMap('chainDanger');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// setInterval执行
|
|
|
|
|
var locs = [],
|
|
|
|
|
now = 0;
|
|
|
|
|
var chain = window.setInterval(() => {
|
|
|
|
|
if (hp > 2000) {
|
|
|
|
|
var nx = Math.floor(Math.random() * 11) + 2,
|
|
|
|
|
ny = Math.floor(Math.random() * 11) + 2;
|
|
|
|
|
} else if (hp > 1000) {
|
|
|
|
|
var nx = Math.floor(Math.random() * 9) + 3,
|
|
|
|
|
ny = Math.floor(Math.random() * 9) + 3;
|
|
|
|
|
} else {
|
|
|
|
|
var nx = Math.floor(Math.random() * 7) + 4,
|
|
|
|
|
ny = Math.floor(Math.random() * 7) + 4;
|
|
|
|
|
}
|
|
|
|
|
if (!locs.includes([nx, ny])) {
|
|
|
|
|
locs.push([nx, ny]);
|
|
|
|
|
} else return;
|
|
|
|
|
// 危险线
|
|
|
|
|
if (now > 0) {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.drawLine(
|
|
|
|
|
'chainDanger',
|
|
|
|
|
locs[now - 1][0] * 32 + 16,
|
|
|
|
|
locs[now - 1][1] * 32 + 16,
|
|
|
|
|
nx * 32 + 16,
|
|
|
|
|
ny * 32 + 16,
|
|
|
|
|
[220, 100, 255, 0.6],
|
|
|
|
|
3
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
}
|
|
|
|
|
if (now >= times) {
|
|
|
|
|
clearInterval(chain);
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
core.getChainRoute(locs);
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.deleteCanvas('chainDanger');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
}, 1000);
|
|
|
|
|
}
|
|
|
|
|
now++;
|
|
|
|
|
}, 100);
|
|
|
|
|
};
|
|
|
|
|
// 链状闪电 动画
|
|
|
|
|
this.chainAnimate = function (route) {
|
|
|
|
|
if (!route) return core.chainThunder();
|
|
|
|
|
// 画布
|
|
|
|
|
if (!core.dymCanvas.chain)
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.createCanvas('chain', 0, 0, 480, 480, 65);
|
|
|
|
|
else core.clearMap('chain');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
var style = core.dymCanvas.chain;
|
|
|
|
|
style.shadowBlur = 3;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
style.shadowColor = 'rgba(255, 255, 255, 1)';
|
|
|
|
|
style.filter = 'blur(2px)';
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 当然还是setInterval
|
|
|
|
|
var frame = 0,
|
|
|
|
|
now = 0;
|
|
|
|
|
var animate = window.setInterval(() => {
|
|
|
|
|
if (now >= route.length - 1) {
|
|
|
|
|
clearInterval(animate);
|
2022-11-14 17:11:23 +08:00
|
|
|
|
setTimeout(() => {
|
|
|
|
|
core.deleteCanvas('chain');
|
|
|
|
|
}, 1000);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
frame++;
|
|
|
|
|
if (frame % 2 != 0) return;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.drawLine(
|
|
|
|
|
'chain',
|
|
|
|
|
route[now][0],
|
|
|
|
|
route[now][1],
|
|
|
|
|
route[now + 1][0],
|
|
|
|
|
route[now + 1][1],
|
|
|
|
|
'#ffffff',
|
|
|
|
|
3
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 节点
|
|
|
|
|
if (now == 0) {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.fillCircle(
|
|
|
|
|
'chain',
|
|
|
|
|
route[0][0],
|
|
|
|
|
route[0][1],
|
|
|
|
|
7,
|
|
|
|
|
'#ffffff'
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
if (
|
|
|
|
|
(route[now + 1][0] - 16) % 32 == 0 &&
|
|
|
|
|
(route[now + 1][1] - 16) % 32 == 0
|
|
|
|
|
) {
|
|
|
|
|
core.fillCircle(
|
|
|
|
|
'chain',
|
|
|
|
|
route[now + 1][0],
|
|
|
|
|
route[now + 1][1],
|
|
|
|
|
7,
|
|
|
|
|
'#ffffff'
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
}
|
|
|
|
|
// 判断伤害
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.lineDamage(
|
|
|
|
|
route[now][0],
|
|
|
|
|
route[now][1],
|
|
|
|
|
route[now + 1][0],
|
|
|
|
|
route[now + 1][1],
|
|
|
|
|
4000
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
now++;
|
|
|
|
|
}, 20);
|
|
|
|
|
};
|
|
|
|
|
// 链状闪电 获得闪电路径
|
|
|
|
|
this.getChainRoute = function (locs) {
|
|
|
|
|
// 照样用setInterval
|
|
|
|
|
var now = 0,
|
|
|
|
|
routes = [];
|
|
|
|
|
var route = window.setInterval(() => {
|
|
|
|
|
var nx = locs[now][0] * 32 + 16,
|
|
|
|
|
ny = locs[now][1] * 32 + 16;
|
|
|
|
|
var tx = locs[now + 1][0] * 32 + 16,
|
|
|
|
|
ty = locs[now + 1][1] * 32 + 16;
|
|
|
|
|
var dx = tx - nx,
|
|
|
|
|
dy = ty - ny;
|
|
|
|
|
var angle = Math.atan(dy / dx);
|
|
|
|
|
if (dy < 0 && dx < 0) angle += Math.PI;
|
|
|
|
|
if (dx < 0 && dy > 0) angle += Math.PI;
|
|
|
|
|
// 循环 + 随机
|
|
|
|
|
var times = 0;
|
|
|
|
|
while (true) {
|
|
|
|
|
times++;
|
|
|
|
|
nx += Math.random() * 50 * Math.cos(angle);
|
|
|
|
|
ny += Math.random() * 50 * Math.sin(angle);
|
|
|
|
|
routes.push([nx, ny]);
|
2022-11-14 17:11:23 +08:00
|
|
|
|
if (
|
|
|
|
|
Math.sqrt(
|
|
|
|
|
Math.pow(ny - ty, 2) + Math.pow(nx - tx, 2)
|
|
|
|
|
) <= 100
|
|
|
|
|
) {
|
2022-11-13 18:02:05 +08:00
|
|
|
|
routes.push([tx, ty]);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (times >= 20) {
|
|
|
|
|
clearInterval(route);
|
|
|
|
|
routes = null;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
now++;
|
|
|
|
|
if (now >= locs.length - 1) {
|
|
|
|
|
clearInterval(route);
|
|
|
|
|
core.chainAnimate(routes);
|
|
|
|
|
}
|
|
|
|
|
}, 2);
|
|
|
|
|
};
|
|
|
|
|
// 随机轰炸
|
|
|
|
|
this.randomBoom = function () {
|
|
|
|
|
// 停止轰炸
|
|
|
|
|
if (!flags.booming) {
|
|
|
|
|
clearInterval(flags.boom);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
// 根据阶段数 分攻击速率 和范围
|
|
|
|
|
var boomTime;
|
|
|
|
|
var range;
|
|
|
|
|
if (hp > 2000) {
|
|
|
|
|
boomTime = 500;
|
|
|
|
|
range = 11;
|
|
|
|
|
} else if (hp > 1000) {
|
|
|
|
|
boomTime = 400;
|
|
|
|
|
range = 9;
|
|
|
|
|
} else {
|
|
|
|
|
boomTime = 300;
|
|
|
|
|
range = 7;
|
|
|
|
|
}
|
|
|
|
|
// setInterval
|
|
|
|
|
flags.boom = window.setInterval(() => {
|
|
|
|
|
var nx = Math.floor(Math.random() * range) + (15 - range) / 2,
|
|
|
|
|
ny = Math.floor(Math.random() * range) + (15 - range) / 2;
|
|
|
|
|
boomLocs.push([nx, ny, 0]);
|
|
|
|
|
if (!flags.booming) clearInterval(flags.boom);
|
|
|
|
|
}, boomTime);
|
|
|
|
|
// 动画要在这里调用
|
|
|
|
|
core.boomingAnimate();
|
|
|
|
|
};
|
|
|
|
|
// 随机轰炸 动画
|
|
|
|
|
this.boomingAnimate = function () {
|
|
|
|
|
// 直接setInterval
|
|
|
|
|
if (!core.dymCanvas.boom)
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.createCanvas('boom', 0, 0, 480, 480, 65);
|
|
|
|
|
else core.clearMap('boom');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
var boomAnimate = window.setInterval(() => {
|
|
|
|
|
if (boomLocs.length == 0) return;
|
|
|
|
|
if (!flags.booming && boomLocs.length == 0) {
|
|
|
|
|
clearInterval(boomAnimate);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.clearMap('boom');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
boomLocs.forEach((loc, index) => {
|
|
|
|
|
loc[2]++;
|
|
|
|
|
var x = loc[0] * 32 + 16,
|
|
|
|
|
y = loc[1] * 32 + 16;
|
|
|
|
|
if (loc[2] >= 20) {
|
|
|
|
|
var alpha = 1,
|
|
|
|
|
radius = 12;
|
|
|
|
|
} else {
|
|
|
|
|
var radius = 0.12 * Math.pow(20 - loc[2], 2) + 12,
|
|
|
|
|
alpha = Math.max(1, 2 - loc[2] * 0.1);
|
|
|
|
|
}
|
2022-11-14 17:11:23 +08:00
|
|
|
|
var angle = (loc[2] * Math.PI) / 50;
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 开始绘制
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.fillCircle('boom', x, y, 3, [255, 50, 50, alpha]);
|
|
|
|
|
core.strokeCircle(
|
|
|
|
|
'boom',
|
|
|
|
|
x,
|
|
|
|
|
y,
|
|
|
|
|
radius,
|
|
|
|
|
[255, 50, 50, alpha],
|
|
|
|
|
2
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 旋转的线
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.drawLine(
|
|
|
|
|
'boom',
|
|
|
|
|
x + radius * Math.cos(angle),
|
|
|
|
|
y + radius * Math.sin(angle),
|
|
|
|
|
x + (radius + 15) * Math.cos(angle),
|
|
|
|
|
y + (radius + 15) * Math.sin(angle),
|
|
|
|
|
[255, 50, 50, alpha],
|
|
|
|
|
1
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
angle += Math.PI;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.drawLine(
|
|
|
|
|
'boom',
|
|
|
|
|
x + radius * Math.cos(angle),
|
|
|
|
|
y + radius * Math.sin(angle),
|
|
|
|
|
x + (radius + 15) * Math.cos(angle),
|
|
|
|
|
y + (radius + 15) * Math.sin(angle),
|
|
|
|
|
[255, 50, 50, alpha],
|
|
|
|
|
1
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 炸弹 下落
|
|
|
|
|
if (loc[2] > 70) {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
var h =
|
|
|
|
|
y -
|
|
|
|
|
(20 * (85 - loc[2]) +
|
|
|
|
|
2.8 * Math.pow(85 - loc[2], 2));
|
|
|
|
|
core.drawImage(
|
|
|
|
|
'boom',
|
|
|
|
|
'boom.png',
|
|
|
|
|
x - 18,
|
|
|
|
|
h - 80,
|
|
|
|
|
36,
|
|
|
|
|
80
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
}
|
|
|
|
|
if (loc[2] == 85) {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.drawAnimate(
|
|
|
|
|
'explosion1',
|
|
|
|
|
(x - 16) / 32,
|
|
|
|
|
(y - 16) / 32
|
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
boomLocs.splice(index, 1);
|
2022-11-14 17:11:23 +08:00
|
|
|
|
if (boomLocs.length == 0) core.deleteCanvas('boom');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 伤害判定
|
|
|
|
|
var hx = core.status.hero.loc.x,
|
|
|
|
|
hy = core.status.hero.loc.y;
|
|
|
|
|
if (loc[0] == hx && loc[1] == hy) {
|
|
|
|
|
core.status.hero.hp -= 3000;
|
2023-01-05 01:11:06 +08:00
|
|
|
|
core.addPop(x * 32 + 16, y * 32 + 16, -3000);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
core.updateStatusBar();
|
|
|
|
|
if (core.status.hero.hp < 0) {
|
|
|
|
|
core.status.hero.hp = 0;
|
|
|
|
|
core.updateStatusBar();
|
|
|
|
|
core.events.lose();
|
|
|
|
|
clearInterval(boomAnimate);
|
|
|
|
|
flags.booming = false;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}, 20);
|
|
|
|
|
};
|
|
|
|
|
// 直线型伤害判定
|
|
|
|
|
this.lineDamage = function (x1, y1, x2, y2, damage) {
|
|
|
|
|
// 获得勇士坐标
|
|
|
|
|
var x = core.status.hero.loc.x,
|
|
|
|
|
y = core.status.hero.loc.y;
|
|
|
|
|
// 是否可能碰到勇士
|
2022-11-14 17:11:23 +08:00
|
|
|
|
if (
|
|
|
|
|
(x1 < x * 32 - 12 && x2 < x * 32 - 12) ||
|
|
|
|
|
(x1 > x * 32 + 12 && x2 > x * 32 + 12) ||
|
|
|
|
|
(y1 < y * 32 - 16 && y2 < y * 32 - 16) ||
|
|
|
|
|
(y1 > y * 32 + 16 && y2 > y * 32 + 16)
|
|
|
|
|
)
|
|
|
|
|
return;
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 对角线的端点是否在直线异侧 勇士视为24 * 32
|
|
|
|
|
for (var time = 1; time <= 2; time++) {
|
|
|
|
|
// 左下右上
|
|
|
|
|
if (time == 1) {
|
|
|
|
|
var loc1 = [x * 32 - 12, y * 32 + 16],
|
|
|
|
|
loc2 = [x * 32 + 12, y * 32 - 16];
|
|
|
|
|
// 直线方程 y == (y2 - y1) / (x2 - x1) * (x - x1) + y1
|
2022-11-14 17:11:23 +08:00
|
|
|
|
var n1 =
|
|
|
|
|
((y2 - y1) / (x2 - x1)) * (loc1[0] - x1) +
|
|
|
|
|
y1 -
|
|
|
|
|
loc1[1],
|
|
|
|
|
n2 =
|
|
|
|
|
((y2 - y1) / (x2 - x1)) * (loc2[0] - x1) +
|
|
|
|
|
y1 -
|
|
|
|
|
loc2[1];
|
2022-11-13 18:02:05 +08:00
|
|
|
|
if (n1 * n2 <= 0) {
|
|
|
|
|
core.status.hero.hp -= damage;
|
2023-01-05 01:11:06 +08:00
|
|
|
|
core.addPop(x * 32 + 16, y * 32 + 16, -damage);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
core.updateStatusBar();
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.playSound('electron.mp3');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
if (core.status.hero.hp < 0) {
|
|
|
|
|
core.status.hero.hp = 0;
|
|
|
|
|
core.updateStatusBar();
|
|
|
|
|
core.events.lose();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
2022-11-14 17:11:23 +08:00
|
|
|
|
} else {
|
|
|
|
|
// 左上右下
|
2022-11-13 18:02:05 +08:00
|
|
|
|
var loc1 = [x * 32 - 12, y * 32 - 16],
|
|
|
|
|
loc2 = [x * 32 + 12, y * 32 + 16];
|
|
|
|
|
// 直线方程 y == (y2 - y1) / (x2 - x1) * (x - x1) + y1
|
2022-11-14 17:11:23 +08:00
|
|
|
|
var n1 =
|
|
|
|
|
((y2 - y1) / (x2 - x1)) * (loc1[0] - x1) +
|
|
|
|
|
y1 -
|
|
|
|
|
loc1[1],
|
|
|
|
|
n2 =
|
|
|
|
|
((y2 - y1) / (x2 - x1)) * (loc2[0] - x1) +
|
|
|
|
|
y1 -
|
|
|
|
|
loc2[1];
|
2022-11-13 18:02:05 +08:00
|
|
|
|
if (n1 * n2 <= 0) {
|
|
|
|
|
core.status.hero.hp -= damage;
|
2023-01-05 01:11:06 +08:00
|
|
|
|
core.addPop(x * 32 + 16, y * 32 + 16, -damage);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
core.updateStatusBar();
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.playSound('electron.mp3');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
if (core.status.hero.hp < 0) {
|
|
|
|
|
core.status.hero.hp = 0;
|
|
|
|
|
core.updateStatusBar();
|
|
|
|
|
core.events.lose();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
},
|
2022-11-14 17:11:23 +08:00
|
|
|
|
popupDamage: function () {
|
2022-11-13 18:02:05 +08:00
|
|
|
|
// 伤害弹出
|
|
|
|
|
// 复写阻激夹域检测
|
2023-01-05 01:11:06 +08:00
|
|
|
|
control.prototype.checkBlock = function (forceMockery) {
|
2022-11-13 18:02:05 +08:00
|
|
|
|
var x = core.getHeroLoc('x'),
|
|
|
|
|
y = core.getHeroLoc('y'),
|
2022-11-14 17:11:23 +08:00
|
|
|
|
loc = x + ',' + y;
|
2022-11-13 18:02:05 +08:00
|
|
|
|
var damage = core.status.checkBlock.damage[loc];
|
|
|
|
|
if (damage) {
|
2022-12-29 23:08:44 +08:00
|
|
|
|
if (!main.replayChecking)
|
2023-01-01 11:37:30 +08:00
|
|
|
|
core.addPop(
|
|
|
|
|
(x - core.bigmap.offsetX / 32) * 32 + 12,
|
|
|
|
|
(y - core.bigmap.offsetY / 32) * 32 + 20,
|
2023-01-01 22:53:22 +08:00
|
|
|
|
-damage.toString()
|
2023-01-01 11:37:30 +08:00
|
|
|
|
);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
core.status.hero.hp -= damage;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
var text =
|
|
|
|
|
Object.keys(core.status.checkBlock.type[loc] || {}).join(
|
|
|
|
|
','
|
|
|
|
|
) || '伤害';
|
|
|
|
|
core.drawTip('受到' + text + damage + '点');
|
|
|
|
|
core.drawHeroAnimate('zone');
|
2022-11-13 18:02:05 +08:00
|
|
|
|
this._checkBlock_disableQuickShop();
|
|
|
|
|
core.status.hero.statistics.extraDamage += damage;
|
|
|
|
|
if (core.status.hero.hp <= 0) {
|
|
|
|
|
core.status.hero.hp = 0;
|
|
|
|
|
core.updateStatusBar();
|
|
|
|
|
core.events.lose();
|
|
|
|
|
return;
|
|
|
|
|
} else {
|
|
|
|
|
core.updateStatusBar();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
this._checkBlock_repulse(core.status.checkBlock.repulse[loc]);
|
2023-01-05 01:11:06 +08:00
|
|
|
|
checkMockery(loc, forceMockery);
|
2022-11-14 17:11:23 +08:00
|
|
|
|
};
|
2023-01-05 01:11:06 +08:00
|
|
|
|
|
|
|
|
|
control.prototype.moveHero = function (direction, callback) {
|
|
|
|
|
// 如果正在移动,直接return
|
|
|
|
|
if (core.status.heroMoving != 0) return;
|
|
|
|
|
if (core.isset(direction)) core.setHeroLoc('direction', direction);
|
|
|
|
|
|
|
|
|
|
const nx = core.nextX();
|
|
|
|
|
const ny = core.nextY();
|
|
|
|
|
if (core.status.checkBlock.mockery[`${nx},${ny}`]) {
|
|
|
|
|
core.autosave();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (callback) return this.moveAction(callback);
|
|
|
|
|
this._moveHero_moving();
|
|
|
|
|
};
|
|
|
|
|
|
2023-01-05 22:21:40 +08:00
|
|
|
|
/**
|
|
|
|
|
* 电摇嘲讽
|
|
|
|
|
* @param {LocString} loc
|
|
|
|
|
* @param {boolean} force
|
|
|
|
|
*/
|
2023-01-05 01:11:06 +08:00
|
|
|
|
function checkMockery(loc, force) {
|
|
|
|
|
if (core.status.lockControl && !force) return;
|
|
|
|
|
const mockery = core.status.checkBlock.mockery[loc];
|
|
|
|
|
if (mockery) {
|
|
|
|
|
mockery.sort((a, b) =>
|
|
|
|
|
a[0] === b[0] ? a[1] - b[1] : a[0] - b[0]
|
|
|
|
|
);
|
|
|
|
|
const action = [];
|
|
|
|
|
const [tx, ty] = mockery[0];
|
|
|
|
|
let { x, y } = core.status.hero.loc;
|
|
|
|
|
const dir =
|
|
|
|
|
x > tx ? 'left' : x < tx ? 'right' : y > ty ? 'up' : 'down';
|
|
|
|
|
const { x: dx, y: dy } = core.utils.scan[dir];
|
|
|
|
|
|
|
|
|
|
action.push({ type: 'changePos', direction: dir });
|
|
|
|
|
const blocks = core.getMapBlocksObj();
|
|
|
|
|
while (1) {
|
|
|
|
|
x += dx;
|
|
|
|
|
y += dy;
|
|
|
|
|
const block = blocks[`${x},${y}`];
|
|
|
|
|
if (block) {
|
|
|
|
|
block.event.cls === '';
|
|
|
|
|
if (
|
|
|
|
|
[
|
|
|
|
|
'animates',
|
|
|
|
|
'autotile',
|
|
|
|
|
'tileset',
|
|
|
|
|
'npcs',
|
|
|
|
|
'npc48'
|
|
|
|
|
].includes(block.event.cls)
|
|
|
|
|
) {
|
|
|
|
|
action.push(
|
|
|
|
|
{
|
|
|
|
|
type: 'hide',
|
|
|
|
|
loc: [[x, y]],
|
|
|
|
|
remove: true,
|
|
|
|
|
time: 0
|
|
|
|
|
},
|
2023-01-05 22:21:40 +08:00
|
|
|
|
{
|
|
|
|
|
type: 'function',
|
|
|
|
|
function: `function() { core.removeGlobalAnimate(${x}, ${y}) }`
|
|
|
|
|
},
|
2023-01-05 01:11:06 +08:00
|
|
|
|
{
|
|
|
|
|
type: 'animate',
|
|
|
|
|
name: 'hand',
|
|
|
|
|
loc: [x, y],
|
|
|
|
|
async: true
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
if (block.event.cls.startsWith('enemy')) {
|
|
|
|
|
action.push({ type: 'moveAction' });
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
action.push({ type: 'moveAction' });
|
|
|
|
|
if (x === tx && y === ty) break;
|
|
|
|
|
}
|
|
|
|
|
action.push({
|
|
|
|
|
type: 'function',
|
|
|
|
|
function: `function() { core.checkBlock(true); }`
|
|
|
|
|
});
|
|
|
|
|
action.push({ type: 'stopAsync' });
|
|
|
|
|
core.insertAction(action);
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-11-14 17:11:23 +08:00
|
|
|
|
},
|
|
|
|
|
hotReload: function () {
|
|
|
|
|
if (main.mode !== 'play' || main.replayChecking) return;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 发送请求
|
|
|
|
|
* @param {string} url
|
|
|
|
|
* @param {string} type
|
|
|
|
|
* @param {string} data
|
|
|
|
|
* @returns {Promise<string>}
|
|
|
|
|
*/
|
|
|
|
|
async function post(url, type, data) {
|
|
|
|
|
const xhr = new XMLHttpRequest();
|
|
|
|
|
xhr.open(type, url);
|
|
|
|
|
xhr.send(data);
|
|
|
|
|
const res = await new Promise(res => {
|
2022-12-30 00:55:03 +08:00
|
|
|
|
xhr.onload = () => {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
if (xhr.status !== 200) {
|
|
|
|
|
console.error(`hot reload: http ${xhr.status}`);
|
|
|
|
|
res('@error');
|
|
|
|
|
} else res('success');
|
|
|
|
|
};
|
2022-12-30 00:55:03 +08:00
|
|
|
|
xhr.onerror = () => {
|
2022-11-14 17:11:23 +08:00
|
|
|
|
res('@error');
|
|
|
|
|
console.error(`hot reload: error on connection`);
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
if (res === 'success') return xhr.response;
|
|
|
|
|
else return '@error';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 热重载css
|
|
|
|
|
* @param {string} data
|
|
|
|
|
*/
|
|
|
|
|
function reloadCss(data) {
|
2022-12-30 14:14:28 +08:00
|
|
|
|
const css = document.getElementById('mota-css');
|
|
|
|
|
css.remove();
|
|
|
|
|
const link = document.createElement('link');
|
|
|
|
|
link.rel = 'stylesheet';
|
|
|
|
|
link.type = 'text/css';
|
|
|
|
|
link.href = data;
|
|
|
|
|
link.id = 'mota-css';
|
|
|
|
|
document.head.appendChild(link);
|
|
|
|
|
console.log(`css hot reload: ${data}`);
|
2022-11-13 18:02:05 +08:00
|
|
|
|
}
|
2022-11-14 17:11:23 +08:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 热重载楼层
|
|
|
|
|
* @param {string} data
|
|
|
|
|
*/
|
|
|
|
|
async function reloadFloor(data) {
|
2023-01-05 22:21:40 +08:00
|
|
|
|
// 如果被砍层了直接忽略
|
|
|
|
|
if (
|
|
|
|
|
core.status.maps[data].deleted ||
|
|
|
|
|
core.status.maps[data].forceDelete
|
|
|
|
|
)
|
|
|
|
|
return;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
// 首先重新加载main.floors对应的楼层
|
|
|
|
|
await import(`/project/floors/${data}.js?v=${Date.now()}`);
|
|
|
|
|
// 然后写入core.floors并解析
|
|
|
|
|
core.floors[data] = main.floors[data];
|
|
|
|
|
const floor = core.loadFloor(data);
|
|
|
|
|
if (core.isPlaying()) {
|
|
|
|
|
core.status.maps[data] = floor;
|
|
|
|
|
delete core.status.mapBlockObjs[data];
|
|
|
|
|
core.extractBlocks(data);
|
2022-11-16 23:01:23 +08:00
|
|
|
|
if (data === core.status.floorId) {
|
|
|
|
|
core.drawMap(data);
|
2022-12-31 21:44:33 +08:00
|
|
|
|
let weather = core.getFlag('__weather__', null);
|
|
|
|
|
if (!weather && core.status.thisMap.weather)
|
|
|
|
|
weather = core.status.thisMap.weather;
|
|
|
|
|
if (weather) core.setWeather(weather[0], weather[1]);
|
|
|
|
|
else core.setWeather();
|
2022-11-16 23:01:23 +08:00
|
|
|
|
}
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.updateStatusBar(true, true);
|
|
|
|
|
}
|
2022-11-21 20:00:34 +08:00
|
|
|
|
console.log(`floor hot reload: ${data}`);
|
2022-11-14 17:11:23 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 热重载脚本编辑及插件编写
|
|
|
|
|
* @param {string} data
|
|
|
|
|
*/
|
|
|
|
|
async function reloadScript(data) {
|
|
|
|
|
if (data === 'plugins') {
|
|
|
|
|
// 插件编写比较好办
|
|
|
|
|
const before = plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1;
|
|
|
|
|
// 这里不能用动态导入,因为动态导入会变成模块,变量就不是全局的了
|
|
|
|
|
const script = document.createElement('script');
|
|
|
|
|
script.src = `/project/plugins.js?v=${Date.now()}`;
|
|
|
|
|
document.body.appendChild(script);
|
|
|
|
|
await new Promise(res => {
|
|
|
|
|
script.onload = () => res('success');
|
|
|
|
|
});
|
|
|
|
|
const after = plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1;
|
|
|
|
|
// 找到差异的函数
|
|
|
|
|
for (const id in before) {
|
|
|
|
|
const fn = before[id];
|
|
|
|
|
if (typeof fn !== 'function') continue;
|
|
|
|
|
if (fn.toString() !== after[id]?.toString()) {
|
|
|
|
|
try {
|
|
|
|
|
core.plugin[id] = after[id];
|
|
|
|
|
core.plugin[id].call(core.plugin);
|
|
|
|
|
core.updateStatusBar(true, true);
|
|
|
|
|
console.log(`plugin hot reload: ${id}`);
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.error(e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else if (data === 'functions') {
|
|
|
|
|
// 脚本编辑略微麻烦点
|
|
|
|
|
const before = functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a;
|
|
|
|
|
// 这里不能用动态导入,因为动态导入会变成模块,变量就不是全局的了
|
|
|
|
|
const script = document.createElement('script');
|
|
|
|
|
script.src = `/project/functions.js?v=${Date.now()}`;
|
|
|
|
|
document.body.appendChild(script);
|
|
|
|
|
await new Promise(res => {
|
|
|
|
|
script.onload = () => res('success');
|
|
|
|
|
});
|
|
|
|
|
const after = functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a;
|
|
|
|
|
// 找到差异的函数
|
|
|
|
|
for (const mod in before) {
|
|
|
|
|
const fns = before[mod];
|
|
|
|
|
for (const id in fns) {
|
|
|
|
|
const fn = fns[id];
|
|
|
|
|
if (typeof fn !== 'function' || id === 'hasSpecial')
|
|
|
|
|
continue;
|
|
|
|
|
const now = after[mod][id];
|
|
|
|
|
if (fn.toString() !== now.toString()) {
|
|
|
|
|
try {
|
|
|
|
|
if (mod === 'events') {
|
|
|
|
|
core.events.eventdata[id] = now;
|
|
|
|
|
} else if (mod === 'enemys') {
|
|
|
|
|
core.enemys.enemydata[id] = now;
|
|
|
|
|
} else if (mod === 'actions') {
|
|
|
|
|
core.actions.actionsdata[id] = now;
|
|
|
|
|
} else if (mod === 'control') {
|
|
|
|
|
core.control.controldata[id] = now;
|
|
|
|
|
} else if (mod === 'ui') {
|
|
|
|
|
core.ui.uidata[id] = now;
|
|
|
|
|
}
|
|
|
|
|
core.updateStatusBar(true, true);
|
|
|
|
|
console.log(
|
|
|
|
|
`function hot reload: ${mod}.${id}`
|
|
|
|
|
);
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.error(e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 属性热重载,包括全塔属性等
|
|
|
|
|
* @param {string} data
|
|
|
|
|
*/
|
|
|
|
|
async function reloadData(data) {
|
|
|
|
|
const script = document.createElement('script');
|
|
|
|
|
script.src = `/project/${data}.js?v=${Date.now()}`;
|
|
|
|
|
document.body.appendChild(script);
|
|
|
|
|
await new Promise(res => {
|
|
|
|
|
script.onload = () => res('success');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
let after;
|
|
|
|
|
if (data === 'data')
|
|
|
|
|
after = data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d;
|
|
|
|
|
if (data === 'enemys')
|
|
|
|
|
after = enemys_fcae963b_31c9_42b4_b48c_bb48d09f3f80;
|
|
|
|
|
if (data === 'icons')
|
|
|
|
|
after = icons_4665ee12_3a1f_44a4_bea3_0fccba634dc1;
|
|
|
|
|
if (data === 'items')
|
|
|
|
|
after = items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a;
|
|
|
|
|
if (data === 'maps')
|
|
|
|
|
after = maps_90f36752_8815_4be8_b32b_d7fad1d0542e;
|
|
|
|
|
if (data === 'events')
|
|
|
|
|
after = events_c12a15a8_c380_4b28_8144_256cba95f760;
|
|
|
|
|
|
|
|
|
|
if (data === 'enemys') {
|
|
|
|
|
core.enemys.enemys = after;
|
2022-11-21 20:00:34 +08:00
|
|
|
|
for (var enemyId in after) {
|
|
|
|
|
core.enemys.enemys[enemyId].id = enemyId;
|
|
|
|
|
}
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.material.enemys = core.getEnemys();
|
|
|
|
|
} else if (data === 'icons') {
|
|
|
|
|
core.icons.icons = after;
|
|
|
|
|
core.material.icons = core.getIcons();
|
|
|
|
|
} else if (data === 'items') {
|
|
|
|
|
core.items.items = after;
|
2022-11-21 20:00:34 +08:00
|
|
|
|
for (var itemId in after) {
|
|
|
|
|
core.items.items[itemId].id = itemId;
|
|
|
|
|
}
|
2022-11-14 17:11:23 +08:00
|
|
|
|
core.material.items = core.getItems();
|
|
|
|
|
} else if (data === 'maps') {
|
|
|
|
|
core.maps.blocksInfo = after;
|
|
|
|
|
core.status.mapBlockObjs = {};
|
|
|
|
|
core.status.number2block = {};
|
|
|
|
|
Object.values(core.status.maps).forEach(v => delete v.blocks);
|
|
|
|
|
core.extractBlocks();
|
|
|
|
|
core.setWeather(
|
|
|
|
|
core.animateFrame.weather.type,
|
|
|
|
|
core.animateFrame.weather.level
|
|
|
|
|
);
|
|
|
|
|
core.drawMap();
|
|
|
|
|
} else if (data === 'events') {
|
|
|
|
|
core.events.commonEvent = after.commonEvent;
|
|
|
|
|
} else if (data === 'data') {
|
|
|
|
|
location.reload();
|
|
|
|
|
}
|
|
|
|
|
core.updateStatusBar(true, true);
|
|
|
|
|
console.log(`data hot reload: ${data}`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 初始化
|
|
|
|
|
(async function () {
|
|
|
|
|
const data = await post('/reload', 'POST', 'test');
|
|
|
|
|
if (data === '@error') {
|
|
|
|
|
console.log(`未检测到node服务,热重载插件将无法使用`);
|
|
|
|
|
} else {
|
|
|
|
|
console.log(`热重载插件加载成功`);
|
|
|
|
|
// reload
|
|
|
|
|
setInterval(async () => {
|
|
|
|
|
const res = await post('/reload', 'POST');
|
|
|
|
|
if (res === '@error') return;
|
|
|
|
|
if (res === 'true') location.reload();
|
|
|
|
|
else return;
|
|
|
|
|
}, 1000);
|
|
|
|
|
|
|
|
|
|
// hot reload
|
|
|
|
|
setInterval(async () => {
|
|
|
|
|
const res = await post('/hotReload', 'POST');
|
|
|
|
|
const data = res.split('@@');
|
|
|
|
|
data.forEach(v => {
|
|
|
|
|
if (v === '') return;
|
|
|
|
|
const [type, file] = v.split(':');
|
|
|
|
|
if (type === 'css') reloadCss(file);
|
|
|
|
|
if (type === 'data') reloadData(file);
|
|
|
|
|
if (type === 'floor') reloadFloor(file);
|
|
|
|
|
if (type === 'script') reloadScript(file);
|
|
|
|
|
});
|
|
|
|
|
}, 1000);
|
|
|
|
|
}
|
|
|
|
|
})();
|
2022-11-16 23:01:23 +08:00
|
|
|
|
},
|
2022-11-19 13:07:42 +08:00
|
|
|
|
uiChange: function () {
|
2022-11-21 20:00:34 +08:00
|
|
|
|
if (main.replayChecking) return;
|
2022-11-30 16:42:44 +08:00
|
|
|
|
|
2022-12-29 00:26:12 +08:00
|
|
|
|
function updateVueStatusBar() {
|
|
|
|
|
if (main.replayChecking) return;
|
|
|
|
|
core.plugin.statusBarStatus.value =
|
|
|
|
|
!core.plugin.statusBarStatus.value;
|
|
|
|
|
core.checkMarkedEnemy();
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-19 11:30:14 +08:00
|
|
|
|
ui.prototype.drawBook = function () {
|
2022-12-31 21:44:33 +08:00
|
|
|
|
if (!main.replayChecking)
|
|
|
|
|
return (core.plugin.bookOpened.value = true);
|
2022-11-19 13:07:42 +08:00
|
|
|
|
};
|
2022-11-21 20:00:34 +08:00
|
|
|
|
|
|
|
|
|
ui.prototype._drawToolbox = function () {
|
2022-12-31 21:44:33 +08:00
|
|
|
|
if (!core.isReplaying())
|
|
|
|
|
return (core.plugin.toolOpened.value = true);
|
2022-11-21 20:00:34 +08:00
|
|
|
|
};
|
2022-11-30 16:42:44 +08:00
|
|
|
|
|
|
|
|
|
ui.prototype._drawEquipbox = function () {
|
2022-12-31 21:44:33 +08:00
|
|
|
|
if (!core.isReplaying())
|
|
|
|
|
return (core.plugin.equipOpened.value = true);
|
2022-11-30 16:42:44 +08:00
|
|
|
|
};
|
2022-12-28 12:13:52 +08:00
|
|
|
|
|
2023-01-01 22:02:58 +08:00
|
|
|
|
ui.prototype.drawFly = function () {
|
|
|
|
|
if (!core.isReplaying())
|
|
|
|
|
return (core.plugin.flyOpened.value = true);
|
|
|
|
|
};
|
|
|
|
|
|
2022-12-28 12:13:52 +08:00
|
|
|
|
control.prototype.updateStatusBar_update = function () {
|
2023-01-04 16:23:26 +08:00
|
|
|
|
core.control.updateNextFrame = false;
|
2022-12-28 12:13:52 +08:00
|
|
|
|
if (!core.isPlaying() || core.hasFlag('__statistics__')) return;
|
|
|
|
|
core.control.controldata.updateStatusBar();
|
|
|
|
|
if (!core.control.noAutoEvents) core.checkAutoEvents();
|
|
|
|
|
core.control._updateStatusBar_setToolboxIcon();
|
|
|
|
|
core.clearRouteFolding();
|
|
|
|
|
core.control.noAutoEvents = true;
|
|
|
|
|
// 更新vue状态栏
|
2022-12-29 00:26:12 +08:00
|
|
|
|
updateVueStatusBar();
|
2022-12-28 12:13:52 +08:00
|
|
|
|
};
|
2022-12-28 20:34:23 +08:00
|
|
|
|
|
|
|
|
|
control.prototype.showStatusBar = function () {
|
|
|
|
|
if (main.mode == 'editor') return;
|
|
|
|
|
core.removeFlag('hideStatusBar');
|
|
|
|
|
core.plugin.showStatusBar.value = true;
|
|
|
|
|
core.dom.tools.hard.style.display = 'block';
|
|
|
|
|
core.dom.toolBar.style.display = 'block';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
control.prototype.hideStatusBar = function (showToolbox) {
|
|
|
|
|
if (main.mode == 'editor') return;
|
|
|
|
|
|
|
|
|
|
// 如果原本就是隐藏的,则先显示
|
|
|
|
|
if (!core.domStyle.showStatusBar) this.showStatusBar();
|
|
|
|
|
if (core.isReplaying()) showToolbox = true;
|
|
|
|
|
core.plugin.showStatusBar.value = false;
|
|
|
|
|
|
2022-12-30 00:55:03 +08:00
|
|
|
|
var toolItems = core.dom.tools;
|
2022-12-28 20:34:23 +08:00
|
|
|
|
core.setFlag('hideStatusBar', true);
|
|
|
|
|
core.setFlag('showToolbox', showToolbox || null);
|
|
|
|
|
if (
|
|
|
|
|
(!core.domStyle.isVertical && !core.flags.extendToolbar) ||
|
|
|
|
|
!showToolbox
|
|
|
|
|
) {
|
|
|
|
|
for (var i = 0; i < toolItems.length; ++i)
|
|
|
|
|
toolItems[i].style.display = 'none';
|
|
|
|
|
}
|
|
|
|
|
if (!core.domStyle.isVertical && !core.flags.extendToolbar) {
|
|
|
|
|
core.dom.toolBar.style.display = 'none';
|
|
|
|
|
}
|
|
|
|
|
};
|
2022-12-29 19:57:31 +08:00
|
|
|
|
|
|
|
|
|
this.showChapter = function (chapter) {
|
2022-12-31 21:44:33 +08:00
|
|
|
|
if (core.isReplaying()) return;
|
2022-12-29 19:57:31 +08:00
|
|
|
|
core.plugin.chapterContent.value = chapter;
|
|
|
|
|
core.plugin.chapterShowed.value = true;
|
|
|
|
|
};
|
2022-12-30 15:25:58 +08:00
|
|
|
|
|
|
|
|
|
this.openSkill = function () {
|
2022-12-31 21:44:33 +08:00
|
|
|
|
if (core.isReplaying()) return;
|
2022-12-30 15:25:58 +08:00
|
|
|
|
core.plugin.skillOpened.value = true;
|
|
|
|
|
};
|
2022-12-29 23:08:44 +08:00
|
|
|
|
},
|
|
|
|
|
remainEnemy: function () {
|
|
|
|
|
/**
|
|
|
|
|
* 检查漏怪
|
2022-12-29 23:56:35 +08:00
|
|
|
|
* @param {FloorIds[]} floorIds
|
2022-12-29 23:08:44 +08:00
|
|
|
|
*/
|
2022-12-29 23:56:35 +08:00
|
|
|
|
this.checkRemainEnemy = function (floorIds) {
|
|
|
|
|
/**
|
|
|
|
|
* @type {Record<FloorIds, {loc: LocArr, id: EnemyIds}[]>}
|
|
|
|
|
*/
|
|
|
|
|
const enemy = {};
|
|
|
|
|
floorIds.forEach(v => {
|
|
|
|
|
core.extractBlocks(v);
|
|
|
|
|
const blocks = core.status.maps[v].blocks;
|
|
|
|
|
blocks.forEach(block => {
|
2023-01-02 23:30:30 +08:00
|
|
|
|
if (!block.event.cls.startsWith('enemy') || block.disable)
|
|
|
|
|
return;
|
2022-12-29 23:56:35 +08:00
|
|
|
|
/**
|
|
|
|
|
* @type {EnemyIds}
|
|
|
|
|
*/
|
|
|
|
|
const id = block.event.id;
|
|
|
|
|
enemy[v] ??= [];
|
|
|
|
|
const info = enemy[v];
|
|
|
|
|
info.push({ loc: [block.x, block.y], id });
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
return enemy;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 获取剩余怪物字符串
|
|
|
|
|
* @param {FloorIds[]} floorIds
|
|
|
|
|
*/
|
|
|
|
|
this.getRemainEnemyString = function (floorIds) {
|
|
|
|
|
const enemy = this.checkRemainEnemy(floorIds);
|
|
|
|
|
const str = [];
|
|
|
|
|
let now = [];
|
|
|
|
|
for (const floor in enemy) {
|
|
|
|
|
/**
|
|
|
|
|
* @type {{loc: LocArr, id: EnemyIds}[]}
|
|
|
|
|
*/
|
|
|
|
|
const all = enemy[floor];
|
|
|
|
|
/**
|
|
|
|
|
* @type {Record<EnemyIds, number>}
|
|
|
|
|
*/
|
|
|
|
|
const remain = {};
|
|
|
|
|
all.forEach(v => {
|
|
|
|
|
const id = v.id;
|
|
|
|
|
remain[id] ??= 0;
|
|
|
|
|
remain[id]++;
|
|
|
|
|
});
|
|
|
|
|
const title = core.status.maps[floor].title;
|
|
|
|
|
for (const id in remain) {
|
|
|
|
|
const name = core.material.enemys[id].name;
|
|
|
|
|
now.push(`${title}(${floor}): ${name} * ${remain[id]}`);
|
2022-12-30 14:14:28 +08:00
|
|
|
|
if (now.length === 10) {
|
2022-12-29 23:56:35 +08:00
|
|
|
|
str.push(now.join('\n'));
|
|
|
|
|
now = [];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-12-30 14:14:28 +08:00
|
|
|
|
if (now.length > 0) {
|
|
|
|
|
str.push(now.join('\n'));
|
|
|
|
|
str[0] = `当前剩余怪物:\n${str[0]}`;
|
|
|
|
|
}
|
|
|
|
|
|
2022-12-29 23:56:35 +08:00
|
|
|
|
return str;
|
|
|
|
|
};
|
2022-12-30 14:14:28 +08:00
|
|
|
|
},
|
|
|
|
|
replay: function () {
|
|
|
|
|
const replayableSettings = ['autoSkill'];
|
|
|
|
|
|
|
|
|
|
// 注册修改设置的录像操作
|
|
|
|
|
core.registerReplayAction('settings', name => {
|
|
|
|
|
if (!name.startsWith('set:')) return false;
|
|
|
|
|
const [, setting, value] = name.split(':');
|
|
|
|
|
const v = eval(value);
|
|
|
|
|
if (typeof v !== 'boolean') return false;
|
|
|
|
|
if (!replayableSettings.includes(setting)) return false;
|
|
|
|
|
flags[setting] = v;
|
|
|
|
|
return true;
|
|
|
|
|
});
|
2022-12-30 23:28:27 +08:00
|
|
|
|
|
|
|
|
|
core.registerReplayAction('upgradeSkill', name => {
|
|
|
|
|
if (!name.startsWith('skill:')) return false;
|
|
|
|
|
const skill = parseInt(name.slice(6));
|
|
|
|
|
core.upgradeSkill(skill);
|
|
|
|
|
});
|
2023-01-05 22:21:40 +08:00
|
|
|
|
|
|
|
|
|
core.registerReplayAction('study', name => {
|
|
|
|
|
if (!name.startsWith('study:')) return false;
|
|
|
|
|
const [num, x, y] = name
|
|
|
|
|
.slice(6)
|
|
|
|
|
.split(',')
|
|
|
|
|
.map(v => parseInt(v));
|
|
|
|
|
if (!core.canStudySkill(num)) return false;
|
|
|
|
|
const id = core.getBlockId(x, y);
|
|
|
|
|
const enemy = core.getEnemyInfo(id, void 0, x, y);
|
|
|
|
|
if (!enemy.special.includes(num)) return false;
|
|
|
|
|
core.studySkill(enemy, num);
|
|
|
|
|
return true;
|
|
|
|
|
});
|
2022-12-30 15:25:58 +08:00
|
|
|
|
},
|
|
|
|
|
skillTree: function () {
|
|
|
|
|
/**
|
|
|
|
|
* @type {number[]}
|
|
|
|
|
*/
|
2022-12-30 23:28:27 +08:00
|
|
|
|
let levels = [];
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @type {Record<Chapter, Skill[]>}
|
|
|
|
|
*/
|
|
|
|
|
const skills = {
|
|
|
|
|
chapter1: [
|
|
|
|
|
{
|
|
|
|
|
index: 0,
|
|
|
|
|
title: '力量',
|
|
|
|
|
desc: [
|
|
|
|
|
'力量就是根本!可以通过智慧增加力量,每级增加2点攻击。'
|
|
|
|
|
],
|
|
|
|
|
consume: '10 * level + 10',
|
|
|
|
|
front: [],
|
|
|
|
|
loc: [1, 2],
|
|
|
|
|
max: 10,
|
|
|
|
|
effect: ['攻击 + ${level * 2}']
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
index: 1,
|
|
|
|
|
title: '致命一击',
|
|
|
|
|
desc: ['爆发出全部力量攻击敌人,每级增加5点额外攻击。'],
|
|
|
|
|
consume: '30 * level + 30',
|
|
|
|
|
front: [[0, 5]],
|
|
|
|
|
loc: [2, 1],
|
|
|
|
|
max: 10,
|
|
|
|
|
effect: ['额外攻击 + ${level * 5}']
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
index: 2,
|
|
|
|
|
title: '断灭之刃',
|
|
|
|
|
desc: [
|
|
|
|
|
'<span style="color: gold">主动技能,快捷键1</span>,',
|
|
|
|
|
'开启后会在战斗时会额外增加一定量的攻击,但同时减少一定量的防御。'
|
|
|
|
|
],
|
|
|
|
|
consume: '200 * level + 400',
|
|
|
|
|
front: [[1, 5]],
|
|
|
|
|
loc: [4, 1],
|
|
|
|
|
max: 5,
|
|
|
|
|
effect: ['增加${level * 10}%攻击,减少${level * 10}%防御']
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
index: 3,
|
|
|
|
|
title: '坚韧',
|
|
|
|
|
desc: ['由智慧转化出坚韧!每级增加2点防御'],
|
|
|
|
|
consume: '10 * level + 10',
|
|
|
|
|
front: [],
|
|
|
|
|
loc: [1, 4],
|
|
|
|
|
max: 10,
|
|
|
|
|
effect: ['防御 + ${level * 2}']
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
index: 4,
|
|
|
|
|
title: '回春',
|
|
|
|
|
desc: ['让智慧化为治愈之泉水!每级增加1点生命回复'],
|
|
|
|
|
consume: '20 * level + 20',
|
|
|
|
|
front: [[3, 5]],
|
|
|
|
|
loc: [2, 5],
|
|
|
|
|
max: 25,
|
|
|
|
|
effect: ['生命回复 + ${level}']
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
index: 5,
|
|
|
|
|
title: '治愈之泉',
|
|
|
|
|
desc: [
|
|
|
|
|
'让生命变得更多一些吧!每吃50瓶血瓶就增加当前生命回复10%的生命回复'
|
|
|
|
|
],
|
|
|
|
|
consume: '1500',
|
|
|
|
|
front: [[4, 25]],
|
|
|
|
|
loc: [4, 5],
|
|
|
|
|
max: 1,
|
|
|
|
|
effect: ['50瓶血10%生命回复']
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
index: 6,
|
|
|
|
|
title: '坚固之盾',
|
|
|
|
|
desc: ['让护甲更加坚硬一些吧!每级增加10点防御'],
|
|
|
|
|
consume: '50 + level * 50',
|
|
|
|
|
front: [[3, 5]],
|
|
|
|
|
loc: [2, 3],
|
|
|
|
|
max: 10,
|
|
|
|
|
effect: ['防御 + ${level * 10}']
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
index: 7,
|
|
|
|
|
title: '无上之盾',
|
|
|
|
|
desc: [
|
|
|
|
|
'<span style="color: #dd4">第一章终极技能</span>,战斗时智慧会充当等量护盾'
|
|
|
|
|
],
|
2022-12-31 00:32:51 +08:00
|
|
|
|
consume: '2500',
|
2022-12-30 23:28:27 +08:00
|
|
|
|
front: [
|
|
|
|
|
[6, 10],
|
|
|
|
|
[5, 1],
|
|
|
|
|
[2, 2]
|
|
|
|
|
],
|
|
|
|
|
loc: [5, 3],
|
|
|
|
|
max: 1,
|
|
|
|
|
effect: ['战斗时智慧会充当护盾']
|
|
|
|
|
}
|
2023-01-04 22:11:08 +08:00
|
|
|
|
],
|
|
|
|
|
chapter2: [
|
|
|
|
|
{
|
|
|
|
|
index: 8,
|
|
|
|
|
title: '锋利',
|
|
|
|
|
desc: ['让剑变得更加锋利!每级使攻击增加1%(buff式增加)'],
|
|
|
|
|
consume: 'level > 5 ? 50 * level ** 2 : 250 * level + 250',
|
|
|
|
|
front: [],
|
|
|
|
|
loc: [1, 2],
|
|
|
|
|
max: 15,
|
|
|
|
|
effect: ['攻击增加${level}%']
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
index: 9,
|
|
|
|
|
title: '坚硬',
|
|
|
|
|
desc: [
|
|
|
|
|
'让盾牌变得更加坚固!每级使防御增加1%(buff式增加)'
|
|
|
|
|
],
|
|
|
|
|
consume: 'level > 5 ? 50 * level ** 2 : 250 * level + 250',
|
|
|
|
|
front: [],
|
|
|
|
|
loc: [1, 4],
|
|
|
|
|
max: 15,
|
|
|
|
|
effect: ['防御增加${level}%']
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
index: 10,
|
|
|
|
|
title: '铸剑为盾',
|
|
|
|
|
desc: [
|
|
|
|
|
'<span style="color: gold">主动技能,快捷键3</span>,',
|
|
|
|
|
'减少一定的攻击,增加一定的防御'
|
|
|
|
|
],
|
|
|
|
|
consume: '500 * level + 1000',
|
|
|
|
|
front: [[9, 5]],
|
|
|
|
|
loc: [2, 5],
|
|
|
|
|
max: 5,
|
|
|
|
|
effect: [
|
|
|
|
|
'增加${level * 10}%的防御,减少${level * 10}%的攻击'
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
index: 11,
|
|
|
|
|
title: '学习',
|
|
|
|
|
desc: [
|
|
|
|
|
'<span style="color: gold">主动技能</span>,可以消耗500智慧学习一个怪物的技能,',
|
2023-01-06 16:21:17 +08:00
|
|
|
|
'持续5场战斗,每学习一次消耗的智慧点增加250,每次升级使持续的战斗次数增加3次。更多信息可在学习后在百科全书查看。'
|
2023-01-04 22:11:08 +08:00
|
|
|
|
],
|
|
|
|
|
consume: '2500 * level ** 2 + 2500',
|
|
|
|
|
front: [
|
|
|
|
|
[8, 10],
|
|
|
|
|
[12, 5]
|
|
|
|
|
],
|
|
|
|
|
loc: [4, 1],
|
|
|
|
|
max: 6,
|
|
|
|
|
effect: ['学习怪物技能,持续${level * 3 + 2}场战斗']
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
index: 12,
|
|
|
|
|
title: '聪慧',
|
|
|
|
|
desc: [
|
|
|
|
|
'使主角变得更加聪明,每级使绿宝石增加的智慧点上升5%'
|
|
|
|
|
],
|
|
|
|
|
consume:
|
|
|
|
|
'level > 5 ? 100 * level ** 2 : 250 * level + 1250',
|
|
|
|
|
front: [
|
|
|
|
|
[8, 10],
|
|
|
|
|
[9, 10]
|
|
|
|
|
],
|
|
|
|
|
loc: [3, 3],
|
|
|
|
|
max: 20,
|
|
|
|
|
effect: ['增加${level * 5}%绿宝石效果']
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
index: 13,
|
|
|
|
|
title: '治愈',
|
2023-01-05 22:21:40 +08:00
|
|
|
|
desc: [
|
|
|
|
|
'使主角能够更好地回复生命,每级使血瓶的加血量增加2%'
|
|
|
|
|
],
|
2023-01-04 22:11:08 +08:00
|
|
|
|
consume:
|
|
|
|
|
'level > 5 ? 100 * level ** 2 : 250 * level + 1250',
|
|
|
|
|
front: [[10, 3]],
|
|
|
|
|
loc: [4, 5],
|
|
|
|
|
max: 20,
|
|
|
|
|
effect: ['增加${level * 2}%的血瓶回血量']
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
index: 14,
|
|
|
|
|
title: '胜利之号',
|
|
|
|
|
desc: [
|
|
|
|
|
'<span style="color: #dd4">第二章终极技能</span>,',
|
|
|
|
|
'每打一个怪物,勇士在本楼层对怪物造成的伤害便增加1%'
|
|
|
|
|
],
|
|
|
|
|
consume: '15000',
|
|
|
|
|
front: [
|
|
|
|
|
[13, 10],
|
|
|
|
|
[12, 10],
|
|
|
|
|
[11, 3]
|
|
|
|
|
],
|
|
|
|
|
loc: [5, 3],
|
|
|
|
|
max: 1,
|
|
|
|
|
effect: ['每打一个怪,勇士造成的伤害增加1%']
|
|
|
|
|
}
|
2022-12-30 23:28:27 +08:00
|
|
|
|
]
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
core.plugin.skills = skills;
|
|
|
|
|
|
|
|
|
|
this.getSkillFromIndex = function (index) {
|
|
|
|
|
for (const [, skill] of Object.entries(skills)) {
|
|
|
|
|
const s = skill.find(v => v.index === index);
|
|
|
|
|
if (s) return s;
|
|
|
|
|
}
|
|
|
|
|
};
|
2022-12-30 15:25:58 +08:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 获取技能等级
|
|
|
|
|
* @param {number} skill
|
|
|
|
|
*/
|
|
|
|
|
this.getSkillLevel = function (skill) {
|
|
|
|
|
return (levels[skill] ??= 0);
|
|
|
|
|
};
|
2022-12-30 23:28:27 +08:00
|
|
|
|
|
|
|
|
|
this.getSkillConsume = function (skill) {
|
|
|
|
|
return eval(
|
|
|
|
|
this.getSkillFromIndex(skill).consume.replace(
|
|
|
|
|
/level(:\d+)?/g,
|
|
|
|
|
(str, $1) => {
|
|
|
|
|
if ($1) return `core.getSkillLevel(${$1})`;
|
|
|
|
|
else return `core.getSkillLevel(${skill})`;
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
this.openTree = function () {
|
|
|
|
|
if (main.replayChecking) return;
|
|
|
|
|
core.plugin.skillTreeOpened.value = true;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 能否升级某个技能
|
|
|
|
|
* @param {number} skill
|
|
|
|
|
*/
|
|
|
|
|
function canUpgrade(skill) {
|
|
|
|
|
const consume = core.getSkillConsume(skill);
|
|
|
|
|
if (consume > core.status.hero.mdef) return false;
|
|
|
|
|
const level = core.getSkillLevel(skill);
|
|
|
|
|
const s = core.getSkillFromIndex(skill);
|
|
|
|
|
if (level === s.max) return false;
|
|
|
|
|
const front = s.front;
|
|
|
|
|
for (const [skill, level] of front) {
|
|
|
|
|
if (core.getSkillLevel(skill) < level) return false;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 实际升级效果
|
|
|
|
|
* @param {number} skill
|
|
|
|
|
*/
|
|
|
|
|
this.upgradeSkill = function (skill) {
|
|
|
|
|
if (!canUpgrade(skill)) return false;
|
|
|
|
|
switch (skill) {
|
|
|
|
|
case 0: // 力量 +2攻击
|
|
|
|
|
core.status.hero.atk += 2;
|
|
|
|
|
break;
|
|
|
|
|
case 1: // 致命一击 +5额外攻击
|
|
|
|
|
core.status.hero.mana += 5;
|
|
|
|
|
break;
|
|
|
|
|
case 2: // 断灭之刃
|
|
|
|
|
core.setFlag('bladeOn', true);
|
|
|
|
|
break;
|
|
|
|
|
case 3: // 坚韧 +2防御
|
|
|
|
|
core.status.hero.def += 2;
|
|
|
|
|
break;
|
|
|
|
|
case 4: // 回春 +1回复
|
|
|
|
|
core.status.hero.hpmax += 1;
|
|
|
|
|
break;
|
|
|
|
|
case 5: // 治愈之泉
|
|
|
|
|
core.setFlag('spring', true);
|
|
|
|
|
break;
|
|
|
|
|
case 6: // 坚固之盾 +10防御
|
|
|
|
|
core.status.hero.def += 10;
|
|
|
|
|
break;
|
|
|
|
|
case 7: // 无上之盾
|
|
|
|
|
core.setFlag('superSheild', true);
|
|
|
|
|
break;
|
2023-01-04 22:11:08 +08:00
|
|
|
|
case 8: // 锋利 +1%攻击
|
|
|
|
|
core.addBuff('atk', 0.01);
|
|
|
|
|
break;
|
|
|
|
|
case 9: // 锋利 +1%防御
|
|
|
|
|
core.addBuff('def', 0.01);
|
|
|
|
|
break;
|
|
|
|
|
case 10: // 铸剑为盾
|
|
|
|
|
core.setFlag('shieldOn', true);
|
|
|
|
|
break;
|
2023-01-05 22:21:40 +08:00
|
|
|
|
case 11: // 学习
|
|
|
|
|
core.setItem('I565', 1);
|
|
|
|
|
break;
|
2022-12-30 23:28:27 +08:00
|
|
|
|
}
|
|
|
|
|
const consume = core.getSkillConsume(skill);
|
|
|
|
|
core.status.hero.mdef -= consume;
|
|
|
|
|
levels[skill]++;
|
|
|
|
|
core.updateStatusBar();
|
|
|
|
|
return true;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
this.saveSkillTree = function () {
|
|
|
|
|
return levels.slice();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
this.loadSkillTree = function (data) {
|
|
|
|
|
levels = data ?? [];
|
|
|
|
|
};
|
2023-01-04 16:23:26 +08:00
|
|
|
|
},
|
|
|
|
|
loopMap: function () {
|
|
|
|
|
const list = (this.loopMapList = ['tower6']);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 设置循环地图的偏移量
|
|
|
|
|
* @param {number} offset 横向偏移量
|
|
|
|
|
* @param {FloorIds} floorId
|
|
|
|
|
*/
|
|
|
|
|
this.setLoopMap = function (offset, floorId) {
|
|
|
|
|
const floor = core.status.maps[floorId];
|
|
|
|
|
if (offset < 9) {
|
|
|
|
|
moveMap(floor.width - 17, floorId);
|
|
|
|
|
}
|
|
|
|
|
if (offset > floor.width - 9) {
|
|
|
|
|
moveMap(17 - floor.width, floorId);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 当勇士移动时自动设置循环地图
|
|
|
|
|
* @param {FloorIds} floorId
|
|
|
|
|
*/
|
|
|
|
|
this.autoSetLoopMap = function (floorId) {
|
|
|
|
|
this.setLoopMap(core.status.hero.loc.x, floorId);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
this.checkLoopMap = function () {
|
|
|
|
|
if (isLoopMap(core.status.floorId)) {
|
|
|
|
|
this.autoSetLoopMap(core.status.floorId);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 移动地图
|
|
|
|
|
* @param {number} delta
|
|
|
|
|
* @param {FloorIds} floorId
|
|
|
|
|
*/
|
|
|
|
|
function moveMap(delta, floorId) {
|
|
|
|
|
core.extractBlocks(floorId);
|
|
|
|
|
const floor = core.status.maps[floorId];
|
|
|
|
|
core.setHeroLoc('x', core.status.hero.loc.x + delta);
|
|
|
|
|
flags[`loop_${floorId}`] += delta;
|
|
|
|
|
flags[`loop_${floorId}`] %= floor.width;
|
|
|
|
|
const origin = floor.blocks.slice();
|
|
|
|
|
for (let i = 0; i < origin.length; i++) {
|
|
|
|
|
core.removeBlockByIndex(0, floorId);
|
|
|
|
|
core.removeGlobalAnimate(origin[i].x, origin[i].y);
|
|
|
|
|
}
|
|
|
|
|
origin.forEach(v => {
|
|
|
|
|
let to = v.x + delta;
|
|
|
|
|
if (to >= floor.width) to -= floor.width;
|
|
|
|
|
if (to < 0) to += floor.width;
|
|
|
|
|
core.setBlock(v.id, to, v.y, floorId, true);
|
|
|
|
|
core.setMapBlockDisabled(floorId, to, v.y, false);
|
|
|
|
|
});
|
|
|
|
|
core.drawMap();
|
|
|
|
|
core.drawHero();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function isLoopMap(floorId) {
|
|
|
|
|
return list.includes(floorId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
events.prototype._sys_changeFloor = function (data, callback) {
|
|
|
|
|
data = data.event.data;
|
|
|
|
|
let heroLoc = {};
|
|
|
|
|
if (isLoopMap(data.floorId)) {
|
|
|
|
|
const floor = core.status.maps[data.floorId];
|
|
|
|
|
flags[`loop_${data.floorId}`] ??= 0;
|
|
|
|
|
let tx = data.loc[0] + flags[`loop_${data.floorId}`];
|
|
|
|
|
tx %= floor.width;
|
|
|
|
|
if (tx < 0) tx += floor.width;
|
|
|
|
|
heroLoc = {
|
|
|
|
|
x: tx,
|
|
|
|
|
y: data.loc[1]
|
|
|
|
|
};
|
|
|
|
|
} else if (data.loc) heroLoc = { x: data.loc[0], y: data.loc[1] };
|
|
|
|
|
if (data.direction) heroLoc.direction = data.direction;
|
|
|
|
|
if (core.status.event.id != 'action') core.status.event.id = null;
|
|
|
|
|
core.changeFloor(
|
|
|
|
|
data.floorId,
|
|
|
|
|
data.stair,
|
|
|
|
|
heroLoc,
|
|
|
|
|
data.time,
|
|
|
|
|
function () {
|
|
|
|
|
core.replay();
|
|
|
|
|
if (callback) callback();
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
events.prototype.trigger = function (x, y, callback) {
|
|
|
|
|
var _executeCallback = function () {
|
|
|
|
|
// 因为trigger之后还有可能触发其他同步脚本(比如阻激夹域检测)
|
|
|
|
|
// 所以这里强制callback被异步触发
|
|
|
|
|
if (callback) {
|
|
|
|
|
setTimeout(callback, 1); // +1是为了录像检测系统
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
};
|
|
|
|
|
if (core.status.gameOver) return _executeCallback();
|
|
|
|
|
if (core.status.event.id == 'action') {
|
|
|
|
|
core.insertAction(
|
|
|
|
|
{
|
|
|
|
|
type: 'function',
|
|
|
|
|
function:
|
|
|
|
|
'function () { core.events._trigger_inAction(' +
|
|
|
|
|
x +
|
|
|
|
|
',' +
|
|
|
|
|
y +
|
|
|
|
|
'); }',
|
|
|
|
|
async: true
|
|
|
|
|
},
|
|
|
|
|
null,
|
|
|
|
|
null,
|
|
|
|
|
null,
|
|
|
|
|
true
|
|
|
|
|
);
|
|
|
|
|
return _executeCallback();
|
|
|
|
|
}
|
|
|
|
|
if (core.status.event.id) return _executeCallback();
|
|
|
|
|
|
|
|
|
|
let block = core.getBlock(x, y);
|
|
|
|
|
const id = core.status.floorId;
|
|
|
|
|
const loop = isLoopMap(id);
|
2023-01-04 16:42:29 +08:00
|
|
|
|
if (loop && flags[`loop_${id}`] !== 0) {
|
2023-01-04 16:23:26 +08:00
|
|
|
|
if (block && block.event.trigger === 'changeFloor') {
|
|
|
|
|
delete block.event.trigger;
|
|
|
|
|
core.maps._addInfo(block);
|
|
|
|
|
} else {
|
|
|
|
|
const floor = core.status.maps[id];
|
|
|
|
|
let tx = x - flags[`loop_${id}`];
|
|
|
|
|
tx %= floor.width;
|
|
|
|
|
if (tx < 0) tx += floor.width;
|
|
|
|
|
const c = core.floors[id].changeFloor[`${tx},${y}`];
|
|
|
|
|
if (c) {
|
|
|
|
|
const b = { event: {}, x: tx, y };
|
|
|
|
|
b.event.data = c;
|
|
|
|
|
b.event.trigger = 'changeFloor';
|
|
|
|
|
block = b;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (block == null) return _executeCallback();
|
|
|
|
|
|
|
|
|
|
// 执行该点的脚本
|
|
|
|
|
if (block.event.script) {
|
|
|
|
|
core.clearRouteFolding();
|
|
|
|
|
try {
|
|
|
|
|
eval(block.event.script);
|
|
|
|
|
} catch (ee) {
|
|
|
|
|
console.error(ee);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 碰触事件
|
|
|
|
|
if (block.event.event) {
|
|
|
|
|
core.clearRouteFolding();
|
|
|
|
|
core.insertAction(block.event.event, block.x, block.y);
|
|
|
|
|
// 不再执行该点的系统事件
|
|
|
|
|
return _executeCallback();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (block.event.trigger && block.event.trigger != 'null') {
|
|
|
|
|
var noPass = block.event.noPass,
|
|
|
|
|
trigger = block.event.trigger;
|
|
|
|
|
if (noPass) core.clearAutomaticRouteNode(x, y);
|
|
|
|
|
|
|
|
|
|
// 转换楼层能否穿透
|
|
|
|
|
if (
|
|
|
|
|
trigger == 'changeFloor' &&
|
|
|
|
|
!noPass &&
|
|
|
|
|
this._trigger_ignoreChangeFloor(block) &&
|
|
|
|
|
!loop
|
|
|
|
|
)
|
|
|
|
|
return _executeCallback();
|
|
|
|
|
core.status.automaticRoute.moveDirectly = false;
|
|
|
|
|
this.doSystemEvent(trigger, block);
|
|
|
|
|
}
|
|
|
|
|
return _executeCallback();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
maps.prototype._getBgFgMapArray = function (name, floorId, noCache) {
|
|
|
|
|
floorId = floorId || core.status.floorId;
|
|
|
|
|
if (!floorId) return [];
|
|
|
|
|
var width = core.floors[floorId].width;
|
|
|
|
|
var height = core.floors[floorId].height;
|
|
|
|
|
|
|
|
|
|
if (!noCache && core.status[name + 'maps'][floorId])
|
|
|
|
|
return core.status[name + 'maps'][floorId];
|
|
|
|
|
|
|
|
|
|
var arr =
|
|
|
|
|
main.mode == 'editor' &&
|
|
|
|
|
!(window.editor && editor.uievent && editor.uievent.isOpen)
|
|
|
|
|
? core.cloneArray(editor[name + 'map'])
|
|
|
|
|
: null;
|
|
|
|
|
if (arr == null)
|
|
|
|
|
arr = core.cloneArray(core.floors[floorId][name + 'map'] || []);
|
|
|
|
|
|
|
|
|
|
if (isLoopMap(floorId) && window.flags) {
|
|
|
|
|
flags[`loop_${floorId}`] ??= 0;
|
|
|
|
|
arr.forEach(v => {
|
|
|
|
|
core.slide(v, flags[`loop_${floorId}`] % width);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (var y = 0; y < height; ++y) {
|
|
|
|
|
if (arr[y] == null) arr[y] = Array(width).fill(0);
|
|
|
|
|
}
|
|
|
|
|
(core.getFlag('__' + name + 'v__', {})[floorId] || []).forEach(
|
|
|
|
|
function (one) {
|
|
|
|
|
arr[one[1]][one[0]] = one[2] || 0;
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
(core.getFlag('__' + name + 'd__', {})[floorId] || []).forEach(
|
|
|
|
|
function (one) {
|
|
|
|
|
arr[one[1]][one[0]] = 0;
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
if (main.mode == 'editor') {
|
|
|
|
|
for (var x = 0; x < width; x++) {
|
|
|
|
|
for (var y = 0; y < height; y++) {
|
|
|
|
|
arr[y][x] = arr[y][x].idnum || arr[y][x] || 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (core.status[name + 'maps'])
|
|
|
|
|
core.status[name + 'maps'][floorId] = arr;
|
|
|
|
|
return arr;
|
|
|
|
|
};
|
2023-01-05 22:21:40 +08:00
|
|
|
|
},
|
|
|
|
|
study: function () {
|
|
|
|
|
// 负责勇士技能:学习
|
|
|
|
|
const values = {
|
|
|
|
|
1: ['crit'],
|
|
|
|
|
6: ['n'],
|
|
|
|
|
7: ['hungry'],
|
2023-01-06 16:21:17 +08:00
|
|
|
|
8: ['together'],
|
2023-01-05 22:21:40 +08:00
|
|
|
|
10: ['courage'],
|
|
|
|
|
11: ['charge']
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const cannotStudy = [9, 12, 14, 15, 24];
|
|
|
|
|
|
|
|
|
|
this.canStudySkill = function (number) {
|
2023-01-06 16:21:17 +08:00
|
|
|
|
const s = (core.status.hero.special ??= { num: [], last: [] });
|
|
|
|
|
if (core.getSkillLevel(11) === 0) return false;
|
|
|
|
|
if (s.num.length >= 1) return false;
|
|
|
|
|
if (s.num.includes(number)) return false;
|
2023-01-05 22:21:40 +08:00
|
|
|
|
if (cannotStudy.includes(number)) return false;
|
|
|
|
|
return true;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
this.studySkill = function (enemy, number) {
|
|
|
|
|
core.status.hero.special ??= { num: [], last: [] };
|
|
|
|
|
const s = core.status.hero.special;
|
|
|
|
|
const specials = core.getSpecials();
|
|
|
|
|
let special = specials[number - 1][1];
|
|
|
|
|
if (special instanceof Function) special = special(enemy);
|
|
|
|
|
if (!this.canStudySkill(number)) {
|
|
|
|
|
if (!main.replayChecking) {
|
|
|
|
|
core.tip('error', `无法学习${special}`);
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
s.num.push(number);
|
|
|
|
|
s.last.push(core.getSkillLevel(11) * 3 + 2);
|
|
|
|
|
const value = values[number] ?? [];
|
|
|
|
|
for (const key of value) {
|
|
|
|
|
s[key] = enemy[key];
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
this.forgetStudiedSkill = function (num, i) {
|
|
|
|
|
const s = core.status.hero.special;
|
|
|
|
|
const index = i !== void 0 && i !== null ? i : s.num.indexOf(num);
|
|
|
|
|
if (index === -1) return;
|
|
|
|
|
s.num.splice(index, 1);
|
|
|
|
|
s.last.splice(index, 1);
|
|
|
|
|
const value = values[number] ?? [];
|
|
|
|
|
for (const key of value) {
|
|
|
|
|
delete s[key];
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
this.declineStudiedSkill = function () {
|
2023-01-06 16:21:17 +08:00
|
|
|
|
const s = (core.status.hero.special ??= { num: [], last: [] });
|
2023-01-05 22:21:40 +08:00
|
|
|
|
s.last = s.last.map(v => v - 1);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
this.checkStudiedSkill = function () {
|
|
|
|
|
const s = core.status.hero.special;
|
|
|
|
|
for (let i = 0; i < s.last.length; i++) {
|
|
|
|
|
if (s.last[i] <= 0) {
|
|
|
|
|
this.forgetStudiedSkill(void 0, i);
|
|
|
|
|
i--;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
2023-01-06 16:21:17 +08:00
|
|
|
|
},
|
|
|
|
|
haloRange: function () {
|
|
|
|
|
/**
|
|
|
|
|
* 绘制光环范围
|
|
|
|
|
* @param {CanvasRenderingContext2D} ctx
|
|
|
|
|
* @param {boolean} onMap
|
|
|
|
|
*/
|
|
|
|
|
this.drawHalo = function (ctx, onMap) {
|
|
|
|
|
if (main.replayChecking) return;
|
|
|
|
|
if (!core.getLocalStorage('showHalo', true)) return;
|
|
|
|
|
const halo = core.status.checkBlock.halo;
|
|
|
|
|
ctx.save();
|
|
|
|
|
for (const [loc, range] of Object.entries(halo)) {
|
|
|
|
|
const [x, y] = loc.split(',').map(v => parseInt(v));
|
|
|
|
|
for (const r of range) {
|
|
|
|
|
const [type, value, color, border] = r.split(':');
|
|
|
|
|
if (type === 'square') {
|
|
|
|
|
// 正方形光环
|
|
|
|
|
const n = parseInt(value);
|
|
|
|
|
const r = Math.floor(n / 2);
|
|
|
|
|
let left = x - r,
|
|
|
|
|
right = x + r,
|
|
|
|
|
top = y - r,
|
|
|
|
|
bottom = y + r;
|
|
|
|
|
if (onMap && core.bigmap.v2) {
|
|
|
|
|
left -= core.bigmap.posX;
|
|
|
|
|
top -= core.bigmap.posY;
|
|
|
|
|
right -= core.bigmap.posX;
|
|
|
|
|
bottom -= core.bigmap.posY;
|
|
|
|
|
if (
|
|
|
|
|
right < -1 ||
|
|
|
|
|
left > core._PX_ / 32 + 1 ||
|
|
|
|
|
top < -1 ||
|
|
|
|
|
bottom > core._PY_ / 32 + 1
|
|
|
|
|
) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
ctx.fillStyle = color;
|
|
|
|
|
ctx.strokeStyle = border ?? color;
|
|
|
|
|
ctx.lineWidth = 1;
|
2023-01-09 20:36:40 +08:00
|
|
|
|
ctx.globalAlpha = 0.1;
|
2023-01-06 16:21:17 +08:00
|
|
|
|
ctx.fillRect(left * 32, top * 32, n * 32, n * 32);
|
|
|
|
|
ctx.globalAlpha = 0.6;
|
|
|
|
|
ctx.strokeRect(left * 32, top * 32, n * 32, n * 32);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
ctx.restore();
|
|
|
|
|
};
|
2023-01-09 23:50:28 +08:00
|
|
|
|
},
|
|
|
|
|
hero: function () {
|
|
|
|
|
/**
|
|
|
|
|
* 获取勇士在某一点的属性
|
|
|
|
|
* @param {keyof HeroStatus | 'all'} name
|
|
|
|
|
* @param {number} x
|
|
|
|
|
* @param {number} y
|
|
|
|
|
* @param {FloorIds} floorId
|
|
|
|
|
*/
|
|
|
|
|
this.getHeroStatusOn = function (name, x, y, floorId) {
|
|
|
|
|
return this.getRealStatusOf(core.status.hero, name, x, y, floorId);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
this.getHeroStatusOf = function (status, name, x, y, floorId) {
|
|
|
|
|
return getRealStatus(status, name, x, y, floorId);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
function getRealStatus(status, name, x, y, floorId) {
|
|
|
|
|
if (name instanceof Array) {
|
|
|
|
|
return Object.fromEntries(
|
|
|
|
|
name.map(v => [
|
|
|
|
|
v,
|
|
|
|
|
v !== 'all' && getRealStatus(status, v, x, y, floorId)
|
|
|
|
|
])
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (name === 'all') {
|
|
|
|
|
return Object.fromEntries(
|
|
|
|
|
Object.keys(core.status.hero).map(v => [
|
|
|
|
|
v,
|
|
|
|
|
v !== 'all' && getRealStatus(status, v, x, y, floorId)
|
|
|
|
|
])
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let s = status?.[name] ?? core.status.hero[name];
|
|
|
|
|
if (s === null || s === void 0) {
|
|
|
|
|
throw new ReferenceError(
|
|
|
|
|
`Wrong hero status property name is delivered: ${name}`
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
x ??= core.status.hero.loc.x;
|
|
|
|
|
y ??= core.status.hero.loc.y;
|
|
|
|
|
floorId ??= core.status.floorId;
|
|
|
|
|
|
|
|
|
|
// 永夜、极昼
|
|
|
|
|
if (name === 'atk' || name === 'def') {
|
|
|
|
|
s += window.flags?.[`night_${floorId}`] ?? 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// buff
|
|
|
|
|
if (typeof s === 'number') s *= core.getBuff(name);
|
|
|
|
|
|
|
|
|
|
// 取整
|
|
|
|
|
if (typeof s === 'number') s = Math.floor(s);
|
|
|
|
|
return s;
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
pluginUtils: function () {
|
|
|
|
|
/**
|
|
|
|
|
* 滑动数组
|
|
|
|
|
* @param {any[]} arr
|
|
|
|
|
* @param {number} delta
|
|
|
|
|
*/
|
|
|
|
|
this.slide = function (arr, delta) {
|
|
|
|
|
if (delta === 0) return arr;
|
|
|
|
|
delta %= arr.length;
|
|
|
|
|
if (delta > 0) {
|
|
|
|
|
arr.unshift(...arr.splice(arr.length - delta, delta));
|
|
|
|
|
return arr;
|
|
|
|
|
}
|
|
|
|
|
if (delta < 0) {
|
|
|
|
|
arr.push(...arr.splice(0, -delta));
|
|
|
|
|
return arr;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
this.backDir = function (dir) {
|
|
|
|
|
return {
|
|
|
|
|
up: 'down',
|
|
|
|
|
down: 'up',
|
|
|
|
|
left: 'right',
|
|
|
|
|
right: 'left'
|
|
|
|
|
}[dir];
|
|
|
|
|
};
|
2022-11-13 18:02:05 +08:00
|
|
|
|
}
|
2022-11-14 17:11:23 +08:00
|
|
|
|
};
|