diff --git a/extensions/localSave.js b/extensions/localSave.js
index 061d5c17..8a4eb22a 100644
--- a/extensions/localSave.js
+++ b/extensions/localSave.js
@@ -8,7 +8,7 @@
(function () {
// 将这一行改成 false 可以禁用本拓展
- var __enabled = true;
+ var __enabled = false;
if (window.jsinterface || !window.fs || !__enabled) return;
diff --git a/libs/control.js b/libs/control.js
index 9d4f05cd..e77c5409 100644
--- a/libs/control.js
+++ b/libs/control.js
@@ -1,3609 +1,3617 @@
-///
-
-/*
-control.js:游戏主要逻辑控制
-主要负责status相关内容,以及各种变量获取/存储
-寻路算法和人物行走也在此文件内
- */
-
-"use strict";
-
-function control () {
- this._init();
-}
-
-control.prototype._init = function () {
- this.controldata = functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a.control;
- this.renderFrameFuncs = [];
- this.replayActions = [];
- this.weathers = {};
- this.resizes = [];
- this.noAutoEvents = true;
- // --- 注册系统的animationFrame
- this.registerAnimationFrame("totalTime", false, this._animationFrame_totalTime);
- this.registerAnimationFrame("autoSave", true, this._animationFrame_autoSave);
- this.registerAnimationFrame("globalAnimate", true, this._animationFrame_globalAnimate);
- this.registerAnimationFrame("animate", true, this._animationFrame_animate);
- this.registerAnimationFrame("heroMoving", true, this._animationFrame_heroMoving);
- this.registerAnimationFrame("weather", true, this._animationFrame_weather);
- this.registerAnimationFrame("tip", true, this._animateFrame_tip);
- this.registerAnimationFrame("parallelDo", false, this._animationFrame_parallelDo);
- // --- 注册系统的天气
- this.registerWeather("rain", this._weather_rain, this._animationFrame_weather_rain);
- this.registerWeather("snow", this._weather_snow, this._animationFrame_weather_snow);
- this.registerWeather("fog", this._weather_fog, this.__animateFrame_weather_image);
- this.registerWeather("cloud", this._weather_cloud, this.__animateFrame_weather_image);
- this.registerWeather("sun", this._weather_sun, this._animationFrame_weather_sun);
- // --- 注册系统的replay
- this.registerReplayAction("move", this._replayAction_move);
- this.registerReplayAction("item", this._replayAction_item);
- this.registerReplayAction("equip", this._replayAction_equip);
- this.registerReplayAction("unEquip", this._replayAction_unEquip);
- this.registerReplayAction("saveEquip", this._replayAction_saveEquip);
- this.registerReplayAction("loadEquip", this._replayAction_loadEquip);
- this.registerReplayAction("fly", this._replayAction_fly);
- this.registerReplayAction("shop", this._replayAction_shop);
- this.registerReplayAction("turn", this._replayAction_turn);
- this.registerReplayAction("getNext", this._replayAction_getNext);
- this.registerReplayAction("moveDirectly", this._replayAction_moveDirectly);
- this.registerReplayAction("key", this._replayAction_key);
- this.registerReplayAction("click", this._replayAction_click);
- this.registerReplayAction("ignoreInput", this._replayAction_ignoreInput);
- this.registerReplayAction("no", this._replayAction_no);
- // --- 注册系统的resize
- this.registerResize("gameGroup", this._resize_gameGroup);
- this.registerResize("canvas", this._resize_canvas);
- this.registerResize("statusBar", this._resize_statusBar);
- this.registerResize("status", this._resize_status);
- this.registerResize("toolBar", this._resize_toolBar);
- this.registerResize("tools", this._resize_tools);
-}
-
-// ------ requestAnimationFrame 相关 ------ //
-
-////// 注册一个 animationFrame //////
-// name:名称,可用来作为注销使用;needPlaying:是否只在游戏运行时才执行(在标题界面不执行)
-// func:要执行的函数,或插件中的函数名;可接受timestamp(从页面加载完毕到当前所经过的时间)作为参数
-control.prototype.registerAnimationFrame = function (name, needPlaying, func) {
- this.unregisterAnimationFrame(name);
- this.renderFrameFuncs.push({ name: name, needPlaying: needPlaying, func: func });
-}
-
-////// 注销一个 animationFrame //////
-control.prototype.unregisterAnimationFrame = function (name) {
- this.renderFrameFuncs = this.renderFrameFuncs.filter(function (x) { return x.name != name; });
-}
-
-////// 设置requestAnimationFrame //////
-control.prototype._setRequestAnimationFrame = function () {
- this._checkRequestAnimationFrame();
- core.animateFrame.totalTime = Math.max(core.animateFrame.totalTime, core.getLocalStorage('totalTime', 0));
- var loop = function (timestamp) {
- core.control.renderFrameFuncs.forEach(function (b) {
- if (b.func) {
- try {
- if (core.isPlaying() || !b.needPlaying)
- core.doFunc(b.func, core.control, timestamp);
- }
- catch (e) {
- console.error(e);
- console.error("ERROR in requestAnimationFrame[" + b.name + "]:已自动注销该项。");
- core.unregisterAnimationFrame(b.name);
- }
- }
- })
- window.requestAnimationFrame(loop);
- }
- window.requestAnimationFrame(loop);
-}
-
-control.prototype._checkRequestAnimationFrame = function () {
- (function () {
- var lastTime = 0;
- var vendors = ['webkit', 'moz'];
- for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
- window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];
- window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || // Webkit中此取消方法的名字变了
- window[vendors[x] + 'CancelRequestAnimationFrame'];
- }
-
- if (!window.requestAnimationFrame) {
- window.requestAnimationFrame = function (callback, element) {
- var currTime = new Date().getTime();
- var timeToCall = Math.max(0, 16.7 - (currTime - lastTime));
- var id = window.setTimeout(function () {
- callback(currTime + timeToCall);
- }, timeToCall);
- lastTime = currTime + timeToCall;
- return id;
- };
- }
- if (!window.cancelAnimationFrame) {
- window.cancelAnimationFrame = function (id) {
- clearTimeout(id);
- };
- }
- }());
-}
-
-control.prototype._animationFrame_totalTime = function (timestamp) {
- core.animateFrame.totalTime += timestamp - core.animateFrame.totalTimeStart;
- core.animateFrame.totalTimeStart = timestamp;
- if (core.isPlaying()) {
- core.status.hero.statistics.totalTime = core.animateFrame.totalTime;
- core.status.hero.statistics.currTime += timestamp - (core.status.hero.statistics.start || timestamp);
- core.status.hero.statistics.start = timestamp;
- }
-}
-
-control.prototype._animationFrame_autoSave = function (timestamp) {
- if (timestamp - core.saves.autosave.time <= 5000) return;
- core.control.checkAutosave();
- core.saves.autosave.time = timestamp;
-}
-
-control.prototype._animationFrame_globalAnimate = function (timestamp) {
- if (timestamp - core.animateFrame.globalTime <= core.values.animateSpeed) return;
- core.status.globalAnimateStatus++;
- if (core.status.floorId) {
- // Global Animate
- core.status.globalAnimateObjs.forEach(function (block) {
- core.drawBlock(block, core.status.globalAnimateStatus);
- });
-
- // Global floor images
- core.maps._drawFloorImages(core.status.floorId, core.canvas.bg, 'bg', core.status.floorAnimateObjs || [], core.status.globalAnimateStatus);
- core.maps._drawFloorImages(core.status.floorId, core.canvas.fg, 'fg', core.status.floorAnimateObjs || [], core.status.globalAnimateStatus);
-
- // Global Autotile Animate
- core.status.autotileAnimateObjs.forEach(function (block) {
- core.maps._drawAutotileAnimate(block, core.status.globalAnimateStatus);
- });
-
- // Global hero animate
- if ((core.status.hero || {}).animate && core.status.heroMoving == 0 && main.mode == 'play' && !core.status.preview.enabled) {
- core.drawHero('stop', null, core.status.globalAnimateStatus);
- }
- }
- // Box animate
- core.drawBoxAnimate();
- core.animateFrame.globalTime = timestamp;
-}
-
-control.prototype._animationFrame_animate = function (timestamp) {
- if (timestamp - core.animateFrame.animateTime < 50 || !core.status.animateObjs || core.status.animateObjs.length == 0) return;
- core.clearMap('animate');
- // 更新帧
- for (var i = 0; i < core.status.animateObjs.length; i++) {
- var obj = core.status.animateObjs[i];
- if (obj.index == obj.animate.frames.length) {
- (function (callback) {
- setTimeout(function () {
- if (callback) callback();
- });
- })(obj.callback);
- }
- }
- core.status.animateObjs = core.status.animateObjs.filter(function (obj) {
- return obj.index < obj.animate.frames.length;
- });
- core.status.animateObjs.forEach(function (obj) {
- if (obj.hero) {
- core.maps._drawAnimateFrame('animate', obj.animate, core.status.heroCenter.px, core.status.heroCenter.py, obj.index++);
- } else {
- core.maps._drawAnimateFrame('animate', obj.animate, obj.centerX, obj.centerY, obj.index++);
- }
- });
- core.animateFrame.animateTime = timestamp;
-}
-
-control.prototype._animationFrame_heroMoving = function (timestamp) {
- if (core.status.heroMoving <= 0) return;
- // 换腿
- if (timestamp - core.animateFrame.moveTime > core.values.moveSpeed) {
- core.animateFrame.leftLeg = !core.animateFrame.leftLeg;
- core.animateFrame.moveTime = timestamp;
- }
- core.drawHero(core.animateFrame.leftLeg ? 'leftFoot' : 'rightFoot', 4 * core.status.heroMoving);
-}
-
-control.prototype._animationFrame_weather = function (timestamp) {
- var weather = core.animateFrame.weather, type = weather.type;
- if (!core.dymCanvas.weather || !core.control.weathers[type] || !core.control.weathers[type].frameFunc) return;
- try {
- core.doFunc(core.control.weathers[type].frameFunc, core.control, timestamp, core.animateFrame.weather.level);
- } catch (e) {
- console.error(e);
- console.error("ERROR in weather[" + type + "]:已自动注销该项。");
- core.unregisterWeather(type);
- }
-}
-
-control.prototype._animationFrame_weather_rain = function (timestamp, level) {
- if (timestamp - core.animateFrame.weather.time < 30) return;
- var ctx = core.dymCanvas.weather, ox = core.bigmap.offsetX, oy = core.bigmap.offsetY;
- core.clearMap('weather');
- ctx.strokeStyle = 'rgba(174,194,224,0.8)';
- ctx.lineWidth = 1;
- ctx.lineCap = 'round';
-
- core.animateFrame.weather.nodes.forEach(function (p) {
- ctx.beginPath();
- ctx.moveTo(p.x - ox, p.y - oy);
- ctx.lineTo(p.x + p.l * p.xs - ox, p.y + p.l * p.ys - oy);
- ctx.stroke();
-
- p.x += p.xs;
- p.y += p.ys;
- if (p.x > core.bigmap.width * 32 || p.y > core.bigmap.height * 32) {
- p.x = Math.random() * core.bigmap.width * 32;
- p.y = -10;
- }
-
- });
-
- ctx.fill();
- core.animateFrame.weather.time = timestamp;
-}
-
-control.prototype._animationFrame_weather_snow = function (timestamp, level) {
- if (timestamp - core.animateFrame.weather.time < 30) return;
- var ctx = core.dymCanvas.weather, ox = core.bigmap.offsetX, oy = core.bigmap.offsetY;
- core.clearMap('weather');
- ctx.fillStyle = "rgba(255, 255, 255, 0.8)";
- ctx.beginPath();
- core.animateFrame.weather.data = core.animateFrame.weather.data || 0;
- core.animateFrame.weather.data += 0.01;
-
- var angle = core.animateFrame.weather.data;
- core.animateFrame.weather.nodes.forEach(function (p) {
- ctx.moveTo(p.x - ox, p.y - oy);
- ctx.arc(p.x - ox, p.y - oy, p.r, 0, Math.PI * 2, true);
- // update
- p.x += Math.sin(angle) * core.animateFrame.weather.level;
- p.y += Math.cos(angle + p.d) + 1 + p.r / 2;
- if (p.x > core.bigmap.width * 32 + 5 || p.x < -5 || p.y > core.bigmap.height * 32) {
- if (Math.random() > 1 / 3) {
- p.x = Math.random() * core.bigmap.width * 32;
- p.y = -10;
- }
- else {
- if (Math.sin(angle) > 0)
- p.x = -5;
- else
- p.x = core.bigmap.width * 32 + 5;
- p.y = Math.random() * core.bigmap.height * 32;
- }
- }
- });
- ctx.fill();
- core.animateFrame.weather.time = timestamp;
-}
-
-control.prototype.__animateFrame_weather_image = function (timestamp, level) {
- if (timestamp - core.animateFrame.weather.time < 30) return;
- var node = core.animateFrame.weather.nodes[0];
- var image = node.image;
- if (!image) return;
- core.clearMap('weather');
- core.setAlpha('weather', node.level / 500);
- var wind = 1.5;
- var width = image.width, height = image.height;
- node.x += node.dx * wind;
- node.y += (2 * node.dy - 1) * wind;
- if (node.x + 3 * width <= core.__PIXELS__) {
- node.x += 4 * width;
- while (node.x > 0) node.x -= width;
- }
- node.dy += node.delta;
- if (node.dy >= 1) {
- node.delta = -0.001;
- } else if (node.dy <= 0) {
- node.delta = 0.001;
- }
- if (node.y + 3 * height <= core.__PIXELS__) {
- node.y += 4 * height;
- while (node.y > 0) node.y -= height;
- }
- else if (node.y >= 0) {
- node.y -= height;
- }
- for (var i = 0; i < 3; ++i) {
- for (var j = 0; j < 3; ++j) {
- if (node.x + (i + 1) * width <= 0 || node.x + i * width >= core.__PIXELS__
- || node.y + (j + 1) * height <= 0 || node.y + j * height >= core.__PIXELS__)
- continue;
- core.drawImage('weather', image, node.x + i * width, node.y + j * height);
- }
- }
- core.setAlpha('weather', 1);
- core.animateFrame.weather.time = timestamp;
-}
-
-control.prototype._animationFrame_weather_sun = function (timestamp, level) {
- if (timestamp - core.animateFrame.weather.time < 30) return;
- var node = core.animateFrame.weather.nodes[0];
- var opacity = node.opacity + node.delta;
- if (opacity > level / 10 + 0.3 || opacity < level / 10 - 0.3)
- node.delta = -node.delta;
- node.opacity = opacity;
- core.setOpacity('weather', core.clamp(opacity, 0, 1));
- core.animateFrame.weather.time = timestamp;
-}
-
-control.prototype._animateFrame_tip = function (timestamp) {
- if (core.animateFrame.tip == null) return;
- var tip = core.animateFrame.tip;
- if (timestamp - tip.time <= 30) return;
- var delta = timestamp - tip.time;
- tip.time = timestamp;
-
- core.setFont('data', "16px Arial");
- core.setTextAlign('data', 'left');
- core.clearMap('data', 0, 0, core.__PIXELS__, 50);
- core.ui._drawTip_drawOne(tip);
- if (tip.stage == 1) {
- tip.opacity += 0.05;
- if (tip.opacity >= 0.6) {
- tip.stage = 2;
- tip.displayTime = 0;
- }
- } else if (tip.stage == 2) {
- tip.displayTime += delta;
- if (tip.displayTime >= 1000) tip.stage = 3;
- } else tip.opacity -= 0.05;
-
- if (tip.opacity <= 0) {
- core.animateFrame.tip = null;
- }
-}
-
-control.prototype._animationFrame_parallelDo = function (timestamp) {
- core.control.controldata.parallelDo(timestamp);
-}
-
-// ------ 标题界面的处理 ------ //
-
-////// 显示游戏开始界面 //////
-control.prototype.showStartAnimate = function (noAnimate, callback) {
- this._showStartAnimate_resetDom();
- if (core.flags.startUsingCanvas || noAnimate)
- return this._showStartAnimate_finished(core.flags.startUsingCanvas, callback);
- core.hideWithAnimate(core.dom.startTop, 20, function () {
- core.control._showStartAnimate_finished(false, callback);
- });
-}
-
-control.prototype._showStartAnimate_resetDom = function () {
- core.dom.startPanel.style.opacity = 1;
- core.dom.startPanel.style.display = "block";
- core.dom.startTop.style.opacity = 1;
- core.dom.startTop.style.display = "block";
- core.dom.startButtonGroup.style.display = 'none';
- core.dom.startButtons.style.display = 'block';
- core.dom.levelChooseButtons.style.display = 'none';
- core.status.played = false;
- core.clearStatus();
- core.clearMap('all');
- core.dom.musicBtn.style.display = 'block';
- core.setMusicBtn();
- // 重置音量
- core.events.setVolume(1, 0);
- core.updateStatusBar();
-}
-
-control.prototype._showStartAnimate_finished = function (start, callback) {
- core.dom.startTop.style.display = 'none';
- core.dom.startButtonGroup.style.display = 'block';
- main.selectedButton = null;
- main.selectButton(0);
- if (start) core.startGame();
- if (callback) callback();
-}
-
-////// 隐藏游戏开始界面 //////
-control.prototype.hideStartAnimate = function (callback) {
- core.hideWithAnimate(core.dom.startPanel, 20, callback);
-}
-
-////// 游戏是否已经开始 //////
-control.prototype.isPlaying = function () {
- return core.status.played;
-}
-
-////// 清除游戏状态和数据 //////
-control.prototype.clearStatus = function () {
- // 停止各个Timeout和Interval
- for (var i in core.timeout) {
- clearTimeout(core.timeout[i]);
- core.timeout[i] = null;
- }
- for (var i in core.interval) {
- clearInterval(core.interval[i]);
- core.interval[i] = null;
- }
- core.status = {};
- core.clearStatusBar();
- core.deleteAllCanvas();
- core.status.played = false;
-}
-
-control.prototype._initStatistics = function (totalTime) {
- if (!core.isset(core.status.hero.statistics))
- core.status.hero.statistics = {
- 'totalTime': totalTime,
- 'currTime': 0,
- 'hp': 0,
- "battle": 0,
- 'money': 0,
- 'exp': 0,
- 'battleDamage': 0,
- 'poisonDamage': 0,
- 'extraDamage': 0,
- 'moveDirectly': 0,
- 'ignoreSteps': 0,
- }
-}
-
-// ------ 自动寻路,人物行走 ------ //
-
-////// 清除自动寻路路线 //////
-control.prototype.clearAutomaticRouteNode = function (x, y) {
- core.clearMap('route', x * 32 + 5 - core.status.automaticRoute.offsetX, y * 32 + 5 - core.status.automaticRoute.offsetY, 27, 27);
-}
-
-////// 停止自动寻路操作 //////
-control.prototype.stopAutomaticRoute = function () {
- if (!core.status.played) return;
- core.status.automaticRoute.autoHeroMove = false;
- core.status.automaticRoute.autoStep = 0;
- core.status.automaticRoute.destStep = 0;
- core.status.automaticRoute.movedStep = 0;
- core.status.automaticRoute.autoStepRoutes = [];
- core.status.automaticRoute.destX = null;
- core.status.automaticRoute.destY = null;
- core.status.automaticRoute.lastDirection = null;
- core.status.heroStop = true;
- if (core.status.automaticRoute.moveStepBeforeStop.length == 0)
- core.deleteCanvas('route');
-}
-
-////// 保存剩下的寻路,并停止 //////
-control.prototype.saveAndStopAutomaticRoute = function () {
- var automaticRoute = core.status.automaticRoute;
- if (automaticRoute.moveStepBeforeStop.length == 0) {
- automaticRoute.moveStepBeforeStop = automaticRoute.autoStepRoutes.slice(automaticRoute.autoStep - 1);
- if (automaticRoute.moveStepBeforeStop.length >= 1)
- automaticRoute.moveStepBeforeStop[0].step -= automaticRoute.movedStep;
- }
- this.stopAutomaticRoute();
-}
-
-////// 继续剩下的自动寻路操作 //////
-control.prototype.continueAutomaticRoute = function () {
- // 此函数只应由events.afterOpenDoor和events.afterBattle调用
- var moveStep = core.status.automaticRoute.moveStepBeforeStop;
- //core.status.automaticRoute.moveStepBeforeStop = [];
- if (moveStep.length === 0 || (moveStep.length === 1 && moveStep[0].step === 1)) {
- core.status.automaticRoute.moveStepBeforeStop = [];
- }
- else {
- core.setAutoHeroMove(moveStep);
- }
-}
-
-////// 清空剩下的自动寻路列表 //////
-control.prototype.clearContinueAutomaticRoute = function (callback) {
- core.deleteCanvas('route');
- core.status.automaticRoute.moveStepBeforeStop = [];
- if (callback) callback();
-}
-
-////// 设置自动寻路路线 //////
-control.prototype.setAutomaticRoute = function (destX, destY, stepPostfix) {
- if (!core.status.played || core.status.lockControl) return;
- if (this._setAutomaticRoute_isMoving(destX, destY)) return;
- if (this._setAutomaticRoute_isTurning(destX, destY, stepPostfix)) return;
- if (this._setAutomaticRoute_clickMoveDirectly(destX, destY, stepPostfix)) return;
- // 找寻自动寻路路线
- var moveStep = core.automaticRoute(destX, destY);
- if (moveStep.length == 0 && (destX != core.status.hero.loc.x || destY != core.status.hero.loc.y || stepPostfix.length == 0))
- return;
- moveStep = moveStep.concat(stepPostfix);
- core.status.automaticRoute.destX = destX;
- core.status.automaticRoute.destY = destY;
- this._setAutomaticRoute_drawRoute(moveStep);
- this._setAutomaticRoute_setAutoSteps(moveStep);
- // 立刻移动
- core.setAutoHeroMove();
-}
-
-control.prototype._setAutomaticRoute_isMoving = function (destX, destY) {
- if (core.status.automaticRoute.autoHeroMove) {
- var lastX = core.status.automaticRoute.destX, lastY = core.status.automaticRoute.destY;
- core.stopAutomaticRoute();
- // 双击瞬移
- if (lastX == destX && lastY == destY) {
- core.status.automaticRoute.moveDirectly = true;
- setTimeout(function () {
- if (core.status.automaticRoute.moveDirectly && core.status.heroMoving == 0) {
- core.control.tryMoveDirectly(destX, destY);
- }
- core.status.automaticRoute.moveDirectly = false;
- }, core.values.moveSpeed);
- }
- return true;
- }
- return false;
-}
-
-control.prototype._setAutomaticRoute_isTurning = function (destX, destY, stepPostfix) {
- if (destX == core.status.hero.loc.x && destY == core.status.hero.loc.y && stepPostfix.length == 0) {
- if (core.timeout.turnHeroTimeout == null) {
- var routeLength = core.status.route.length;
- core.timeout.turnHeroTimeout = setTimeout(function () {
- if (core.status.route.length == routeLength) core.turnHero();
- clearTimeout(core.timeout.turnHeroTimeout);
- core.timeout.turnHeroTimeout = null;
- }, 250);
- }
- else {
- clearTimeout(core.timeout.turnHeroTimeout);
- core.timeout.turnHeroTimeout = null;
- core.getNextItem();
- }
- return true;
- }
- if (core.timeout.turnHeroTimeout != null) return true;
- return false;
-}
-
-control.prototype._setAutomaticRoute_clickMoveDirectly = function (destX, destY, stepPostfix) {
- // 单击瞬间移动
- if (core.status.heroStop && core.status.heroMoving == 0) {
- if (stepPostfix.length <= 1 && !core.hasFlag('__noClickMove__') && core.control.tryMoveDirectly(destX, destY))
- return true;
- }
- return false;
-}
-
-control.prototype._setAutomaticRoute_drawRoute = function (moveStep) {
- // 计算绘制区域的宽高,并尽可能小的创建route层
- var sx = core.bigmap.width * 32, sy = core.bigmap.height * 32, dx = 0, dy = 0;
- moveStep.forEach(function (t) {
- sx = Math.min(sx, t.x * 32); dx = Math.max(dx, t.x * 32);
- sy = Math.min(sy, t.y * 32); dy = Math.max(dy, t.y * 32);
- });
- core.status.automaticRoute.offsetX = sx;
- core.status.automaticRoute.offsetY = sy;
- var ctx = core.createCanvas('route', sx - core.bigmap.offsetX, sy - core.bigmap.offsetY, dx - sx + 32, dy - sy + 32, 95);
- ctx.fillStyle = '#bfbfbf';
- ctx.strokeStyle = '#bfbfbf';
- ctx.lineWidth = 8;
- for (var m = 0; m < moveStep.length; m++) {
- if (m == moveStep.length - 1) {
- ctx.fillRect(moveStep[m].x * 32 + 10 - sx, moveStep[m].y * 32 + 10 - sy, 12, 12);
- }
- else {
- ctx.beginPath();
- var cx = moveStep[m].x * 32 + 16 - sx, cy = moveStep[m].y * 32 + 16 - sy;
- var currDir = moveStep[m].direction, nextDir = moveStep[m + 1].direction;
- ctx.moveTo(cx - core.utils.scan[currDir].x * 11, cy - core.utils.scan[currDir].y * 11);
- ctx.lineTo(cx, cy);
- ctx.lineTo(cx + core.utils.scan[nextDir].x * 11, cy + core.utils.scan[nextDir].y * 11);
- ctx.stroke();
- }
- }
-}
-
-control.prototype._setAutomaticRoute_setAutoSteps = function (moveStep) {
- // 路线转autoStepRoutes
- var step = 0, currStep = null;
- moveStep.forEach(function (t) {
- var dir = t.direction;
- if (currStep == null || currStep == dir)
- step++;
- else {
- core.status.automaticRoute.autoStepRoutes.push({ 'direction': currStep, 'step': step });
- step = 1;
- }
- currStep = dir;
- });
- core.status.automaticRoute.autoStepRoutes.push({ 'direction': currStep, 'step': step });
-}
-
-////// 设置勇士的自动行走路线 //////
-control.prototype.setAutoHeroMove = function (steps) {
- steps = steps || core.status.automaticRoute.autoStepRoutes;
- if (steps.length == 0) return;
- core.status.automaticRoute.autoStepRoutes = steps;
- core.status.automaticRoute.autoHeroMove = true;
- core.status.automaticRoute.autoStep = 1;
- core.status.automaticRoute.destStep = steps[0].step;
- core.moveHero(steps[0].direction);
-}
-
-////// 设置行走的效果动画 //////
-control.prototype.setHeroMoveInterval = function (callback) {
- if (core.status.heroMoving > 0) return;
- if (core.status.replay.speed == 24) {
- if (callback) callback();
- return;
- }
-
- core.status.heroMoving = 1;
-
- var toAdd = 1;
- if (core.status.replay.speed > 3) toAdd = 2;
- if (core.status.replay.speed > 6) toAdd = 4;
- if (core.status.replay.speed > 12) toAdd = 8;
-
- core.interval.heroMoveInterval = window.setInterval(function () {
- core.status.heroMoving += toAdd;
- if (core.status.heroMoving >= 8) {
- clearInterval(core.interval.heroMoveInterval);
- core.status.heroMoving = 0;
- if (callback) callback();
- }
- }, core.values.moveSpeed / 8 * toAdd / core.status.replay.speed);
-}
-
-////// 每移动一格后执行的事件 //////
-control.prototype.moveOneStep = function (callback) {
- return this.controldata.moveOneStep(callback);
-}
-
-////// 实际每一步的行走过程 //////
-control.prototype.moveAction = function (callback) {
- if (core.status.heroMoving > 0) return;
- var noPass = core.noPass(core.nextX(), core.nextY()), canMove = core.canMoveHero();
- // 下一个点如果不能走
- if (noPass || !canMove) return this._moveAction_noPass(canMove, callback);
- this._moveAction_moving(callback);
-}
-
-control.prototype._moveAction_noPass = function (canMove, callback) {
- core.status.route.push(core.getHeroLoc('direction'));
- core.status.automaticRoute.moveStepBeforeStop = [];
- core.status.automaticRoute.lastDirection = core.getHeroLoc('direction');
- if (canMove) core.trigger(core.nextX(), core.nextY());
- core.drawHero();
-
- if (core.status.automaticRoute.moveStepBeforeStop.length == 0) {
- core.clearContinueAutomaticRoute();
- core.stopAutomaticRoute();
- }
- if (callback) callback();
-}
-
-control.prototype._moveAction_moving = function (callback) {
- core.setHeroMoveInterval(function () {
- core.setHeroLoc('x', core.nextX(), true);
- core.setHeroLoc('y', core.nextY(), true);
-
- var direction = core.getHeroLoc('direction');
- core.control._moveAction_popAutomaticRoute();
- core.status.route.push(direction);
-
- core.moveOneStep();
- core.checkRouteFolding();
- if (callback) callback();
- });
-}
-
-control.prototype._moveAction_popAutomaticRoute = function () {
- var automaticRoute = core.status.automaticRoute;
- // 检查自动寻路是否被弹出
- if (automaticRoute.autoHeroMove) {
- automaticRoute.movedStep++;
- automaticRoute.lastDirection = core.getHeroLoc('direction');
- if (automaticRoute.destStep == automaticRoute.movedStep) {
- if (automaticRoute.autoStep == automaticRoute.autoStepRoutes.length) {
- core.clearContinueAutomaticRoute();
- core.stopAutomaticRoute();
- }
- else {
- automaticRoute.movedStep = 0;
- automaticRoute.destStep = automaticRoute.autoStepRoutes[automaticRoute.autoStep].step;
- core.setHeroLoc('direction', automaticRoute.autoStepRoutes[automaticRoute.autoStep].direction);
- core.status.automaticRoute.autoStep++;
- }
- }
- }
-}
-
-////// 让勇士开始移动 //////
-control.prototype.moveHero = function (direction, callback) {
- // 如果正在移动,直接return
- if (core.status.heroMoving != 0) return;
- if (core.isset(direction))
- core.setHeroLoc('direction', direction);
-
- if (callback) return this.moveAction(callback);
- this._moveHero_moving();
-}
-
-control.prototype._moveHero_moving = function () {
- // ------ 我已经看不懂这个函数了,反正好用就行23333333
- core.status.heroStop = false;
- core.status.automaticRoute.moveDirectly = false;
- var move = function () {
- if (!core.status.heroStop) {
- if (core.hasFlag('debug') && core.status.ctrlDown) {
- if (core.status.heroMoving != 0) return;
- // 检测是否穿出去
- var nx = core.nextX(), ny = core.nextY();
- if (nx < 0 || nx >= core.bigmap.width || ny < 0 || ny >= core.bigmap.height) return;
- core.eventMoveHero([core.getHeroLoc('direction')], core.values.moveSpeed, move);
- }
- else {
- core.moveAction();
- setTimeout(move, 50);
- }
- }
- }
- move();
-}
-
-////// 当前是否正在移动 //////
-control.prototype.isMoving = function () {
- return !core.status.heroStop || core.status.heroMoving > 0;
-}
-
-////// 停止勇士的一切行动,等待勇士行动结束后,再执行callback //////
-control.prototype.waitHeroToStop = function (callback) {
- var lastDirection = core.status.automaticRoute.lastDirection;
- core.stopAutomaticRoute();
- core.clearContinueAutomaticRoute();
- if (callback) {
- core.status.replay.animate = true;
- core.lockControl();
- core.status.automaticRoute.moveDirectly = false;
- setTimeout(function () {
- core.status.replay.animate = false;
- if (core.isset(lastDirection))
- core.setHeroLoc('direction', lastDirection);
- core.drawHero();
- callback();
- }, core.status.replay.speed == 24 ? 1 : 30);
- }
-}
-
-////// 转向 //////
-control.prototype.turnHero = function (direction) {
- if (direction) {
- core.setHeroLoc('direction', direction);
- core.drawHero();
- core.status.route.push("turn:" + direction);
- return;
- }
- core.setHeroLoc('direction', core.turnDirection(':right'));
- core.drawHero();
- core.status.route.push("turn");
- core.checkRouteFolding();
-}
-
-////// 瞬间移动 //////
-control.prototype.moveDirectly = function (destX, destY, ignoreSteps) {
- return this.controldata.moveDirectly(destX, destY, ignoreSteps);
-}
-
-////// 尝试瞬间移动 //////
-control.prototype.tryMoveDirectly = function (destX, destY) {
- if (this.nearHero(destX, destY)) return false;
- var canMoveArray = core.maps.generateMovableArray();
- var dirs = [[destX, destY], [destX - 1, destY, "right"], [destX, destY - 1, "down"], [destX, destY + 1, "up"], [destX + 1, destY, "left"]];
- var canMoveDirectlyArray = core.canMoveDirectlyArray(dirs, canMoveArray);
-
- for (var i = 0; i < dirs.length; ++i) {
- var d = dirs[i], dx = d[0], dy = d[1], dir = d[2];
- if (dx < 0 || dx >= core.bigmap.width || dy < 0 || dy >= core.bigmap.height) continue;
- if (dir && !core.inArray(canMoveArray[dx][dy], dir)) continue;
- if (canMoveDirectlyArray[i] < 0) continue;
- if (core.control.moveDirectly(dx, dy, canMoveDirectlyArray[i])) {
- if (dir) core.moveHero(dir, function () { });
- return true;
- }
- }
- return false;
-}
-
-////// 绘制勇士 //////
-control.prototype.drawHero = function (status, offset, frame) {
- if (!core.isPlaying() || !core.status.floorId || core.status.gameOver) return;
- var x = core.getHeroLoc('x'), y = core.getHeroLoc('y'), direction = core.getHeroLoc('direction');
- status = status || 'stop';
- if (!offset) offset = 0;
-
- var way = core.utils.scan2[direction];
- var dx = way.x, dy = way.y;
- var offsetX = typeof offset == 'number' ? dx * offset : (offset.x || 0);
- var offsetY = typeof offset == 'number' ? dy * offset : (offset.y || 0);
- offset = { x: offsetX, y: offsetY, offset: offset };
-
- core.clearAutomaticRouteNode(x + dx, y + dy);
- core.clearMap('hero');
- core.status.heroCenter.px = 32 * x + offsetX + 16;
- core.status.heroCenter.py = 32 * y + offsetY + 32 - core.material.icons.hero.height / 2;
-
- // 重置hero层画布
- core.setGameCanvasTranslate('hero', 0, 0);
- delete core.canvas.hero._px;
- delete core.canvas.hero._py;
- core.status.preview.enabled = false;
- if (!core.hasFlag('__lockViewport__')) {
- this._drawHero_updateViewport(x, y, offset);
- }
-
- this._drawHero_draw(direction, x, y, status, offset, frame);
-}
-
-control.prototype._drawHero_updateViewport = function (x, y, offset) {
- core.bigmap.offsetX = core.clamp((x - core.__HALF_SIZE__) * 32 + offset.x, 0, 32 * core.bigmap.width - core.__PIXELS__);
- core.bigmap.offsetY = core.clamp((y - core.__HALF_SIZE__) * 32 + offset.y, 0, 32 * core.bigmap.height - core.__PIXELS__);
- core.control.updateViewport();
-}
-
-control.prototype._drawHero_draw = function (direction, x, y, status, offset, frame) {
- offset = offset || { x: 0, y: 0, offset: 0, px: 0, py: 0 };
- var opacity = core.setAlpha('hero', core.getFlag('__heroOpacity__', 1))
- this._drawHero_getDrawObjs(direction, x, y, status, offset).forEach(function (block) {
- core.drawImage('hero', block.img, (block.heroIcon[block.status] + (frame || 0)) % 4 * block.width,
- block.heroIcon.loc * block.height, block.width, block.height,
- block.posx + (32 - block.width) / 2, block.posy + 32 - block.height, block.width, block.height);
- });
- core.setAlpha('hero', opacity);
-}
-
-control.prototype._drawHero_getDrawObjs = function (direction, x, y, status, offset) {
- var heroIconArr = core.material.icons.hero, drawObjs = [], index = 0;
- drawObjs.push({
- "img": core.material.images.hero,
- "width": core.material.icons.hero.width || 32,
- "height": core.material.icons.hero.height,
- "heroIcon": heroIconArr[direction],
- "posx": x * 32 - core.bigmap.offsetX + offset.x,
- "posy": y * 32 - core.bigmap.offsetY + offset.y,
- "status": status,
- "index": index++,
- });
- if (typeof offset.offset == 'number') {
- core.status.hero.followers.forEach(function (t) {
- drawObjs.push({
- "img": core.material.images.images[t.name],
- "width": core.material.images.images[t.name].width / 4,
- "height": core.material.images.images[t.name].height / 4,
- "heroIcon": heroIconArr[t.direction],
- "posx": 32 * t.x - core.bigmap.offsetX + (t.stop ? 0 : core.utils.scan2[t.direction].x * Math.abs(offset.offset)),
- "posy": 32 * t.y - core.bigmap.offsetY + (t.stop ? 0 : core.utils.scan2[t.direction].y * Math.abs(offset.offset)),
- "status": t.stop ? "stop" : status,
- "index": index++
- });
- });
- }
- return drawObjs.sort(function (a, b) {
- return a.posy == b.posy ? b.index - a.index : a.posy - b.posy;
- });
-}
-
-control.prototype.setHeroOpacity = function (opacity, moveMode, time, callback) {
- time = time || 0;
- if (time == 0) {
- core.setFlag('__heroOpacity__', opacity);
- core.drawHero();
- if (callback) callback();
- return;
- }
- time /= Math.max(core.status.replay.speed, 1)
-
- var fromOpacity = core.getFlag('__heroOpacity__', 1);
- var step = 0, steps = parseInt(time / 10);
- if (steps <= 0) steps = 1;
- var moveFunc = core.applyEasing(moveMode);
-
- var animate = setInterval(function () {
- step++;
- core.setFlag('__heroOpacity__', fromOpacity + (opacity - fromOpacity) * moveFunc(step / steps));
- core.drawHero();
- if (step == steps) {
- delete core.animateFrame.asyncId[animate];
- clearInterval(animate);
- if (callback) callback();
- }
- }, 10);
-
- core.animateFrame.lastAsyncId = animate;
- core.animateFrame.asyncId[animate] = callback;
-}
-
-// ------ 画布、位置、阻激夹域,显伤 ------ //
-
-////// 设置画布偏移
-control.prototype.setGameCanvasTranslate = function (canvas, x, y) {
- var c = core.dom.gameCanvas[canvas];
- x = x * core.domStyle.scale;
- y = y * core.domStyle.scale;
- c.style.transform = 'translate(' + x + 'px,' + y + 'px)';
- c.style.webkitTransform = 'translate(' + x + 'px,' + y + 'px)';
- c.style.OTransform = 'translate(' + x + 'px,' + y + 'px)';
- c.style.MozTransform = 'translate(' + x + 'px,' + y + 'px)';
- if (main.mode === 'editor' && editor.isMobile) {
- c.style.transform = 'translate(' + (x / core.__PIXELS__ * 96) + 'vw,' + (y / core.__PIXELS__ * 96) + 'vw)';
- c.style.webkitTransform = 'translate(' + (x / core.__PIXELS__ * 96) + 'vw,' + (y / core.__PIXELS__ * 96) + 'vw)';
- c.style.OTransform = 'translate(' + (x / core.__PIXELS__ * 96) + 'vw,' + (y / core.__PIXELS__ * 96) + 'vw)';
- c.style.MozTransform = 'translate(' + (x / core.__PIXELS__ * 96) + 'vw,' + (y / core.__PIXELS__ * 96) + 'vw)';
- }
-};
-
-////// 加减画布偏移
-control.prototype.addGameCanvasTranslate = function (x, y) {
- for (var ii = 0, canvas; canvas = core.dom.gameCanvas[ii]; ii++) {
- var id = canvas.getAttribute('id');
- if (id == 'ui' || id == 'data') continue; // UI层和data层不移动
- var offsetX = x, offsetY = y;
- if (core.bigmap.canvas.indexOf(id) >= 0) {
- if (core.bigmap.v2) {
- offsetX -= (core.bigmap.offsetX - 32 * core.bigmap.posX) + 32;
- offsetY -= (core.bigmap.offsetY - 32 * core.bigmap.posY) + 32;
- } else {
- offsetX -= core.bigmap.offsetX;
- offsetY -= core.bigmap.offsetY;
- }
- }
- core.control.setGameCanvasTranslate(id, offsetX, offsetY);
- }
-}
-
-////// 更新视野范围 //////
-control.prototype.updateViewport = function () {
- // 当前是否应该重绘?
- if (core.bigmap.v2) {
- if (core.bigmap.offsetX >= core.bigmap.posX * 32 + 32
- || core.bigmap.offsetX <= core.bigmap.posX * 32 - 32
- || core.bigmap.offsetY >= core.bigmap.posY * 32 + 32
- || core.bigmap.offsetY <= core.bigmap.posY * 32 - 32) {
- core.bigmap.posX = parseInt(core.bigmap.offsetX / 32);
- core.bigmap.posY = parseInt(core.bigmap.offsetY / 32);
- core.redrawMap();
- }
- } else {
- core.bigmap.posX = core.bigmap.posY = 0;
- }
- var offsetX = core.bigmap.v2 ? -(core.bigmap.offsetX - 32 * core.bigmap.posX) - 32 : -core.bigmap.offsetX;
- var offsetY = core.bigmap.v2 ? -(core.bigmap.offsetY - 32 * core.bigmap.posY) - 32 : -core.bigmap.offsetY;
-
- core.bigmap.canvas.forEach(function (cn) {
- core.control.setGameCanvasTranslate(cn, offsetX, offsetY);
- });
- // ------ 路线
- core.relocateCanvas('route', core.status.automaticRoute.offsetX - core.bigmap.offsetX, core.status.automaticRoute.offsetY - core.bigmap.offsetY);
- // ------ 所有的大怪物也都需要重定位
- for (var one in core.dymCanvas) {
- if (one.startsWith('_bigImage_')) {
- var ox = core.dymCanvas[one].canvas.getAttribute('_ox');
- var oy = core.dymCanvas[one].canvas.getAttribute('_oy');
- if (ox != null && oy != null) {
- core.relocateCanvas(one, parseInt(ox) - core.bigmap.offsetX, parseInt(oy) - core.bigmap.offsetY);
- }
- }
- }
-
-}
-
-////// 设置视野范围 //////
-control.prototype.setViewport = function (px, py) {
- var originOffsetX = core.bigmap.offsetX, originOffsetY = core.bigmap.offsetY;
- core.bigmap.offsetX = core.clamp(px, 0, 32 * core.bigmap.width - core.__PIXELS__);
- core.bigmap.offsetY = core.clamp(py, 0, 32 * core.bigmap.height - core.__PIXELS__);
- this.updateViewport();
- // ------ hero层也需要!
- var px = parseFloat(core.canvas.hero._px) || 0;
- var py = parseFloat(core.canvas.hero._py) || 0;
- px += originOffsetX - core.bigmap.offsetX;
- py += originOffsetY - core.bigmap.offsetY;
- core.control.setGameCanvasTranslate('hero', px, py);
- core.canvas.hero._px = px;
- core.canvas.hero._py = py;
-}
-
-////// 移动视野范围 //////
-control.prototype.moveViewport = function (x, y, moveMode, time, callback) {
- time = time || 0;
- time /= Math.max(core.status.replay.speed, 1)
- var per_time = 10, step = 0, steps = parseInt(time / per_time);
- if (steps <= 0) {
- this.setViewport(32 * x, 32 * y);
- if (callback) callback();
- return;
- }
- var px = core.clamp(32 * x, 0, 32 * core.bigmap.width - core.__PIXELS__);
- var py = core.clamp(32 * y, 0, 32 * core.bigmap.height - core.__PIXELS__);
- var cx = core.bigmap.offsetX;
- var cy = core.bigmap.offsetY;
- var moveFunc = core.applyEasing(moveMode);
-
- var animate = window.setInterval(function () {
- step++;
- core.setViewport(cx + moveFunc(step / steps) * (px - cx), cy + moveFunc(step / steps) * (py - cy));
- if (step == steps) {
- delete core.animateFrame.asyncId[animate];
- clearInterval(animate);
- core.setViewport(px, py);
- if (callback) callback();
- }
- }, per_time);
-
- core.animateFrame.lastAsyncId = animate;
- core.animateFrame.asyncId[animate] = callback;
-}
-
-////// 获得勇士面对位置的x坐标 //////
-control.prototype.nextX = function (n) {
- if (n == null) n = 1;
- return core.getHeroLoc('x') + core.utils.scan[core.getHeroLoc('direction')].x * n;
-}
-
-////// 获得勇士面对位置的y坐标 //////
-control.prototype.nextY = function (n) {
- if (n == null) n = 1;
- return core.getHeroLoc('y') + core.utils.scan[core.getHeroLoc('direction')].y * n;
-}
-
-////// 某个点是否在勇士旁边 //////
-control.prototype.nearHero = function (x, y, n) {
- if (n == null) n = 1;
- return Math.abs(x - core.getHeroLoc('x')) + Math.abs(y - core.getHeroLoc('y')) <= n;
-}
-
-////// 聚集跟随者 //////
-control.prototype.gatherFollowers = function () {
- var x = core.getHeroLoc('x'), y = core.getHeroLoc('y'), dir = core.getHeroLoc('direction');
- core.status.hero.followers.forEach(function (t) {
- t.x = x;
- t.y = y;
- t.stop = true;
- t.direction = dir;
- });
-}
-
-////// 更新跟随者坐标 //////
-control.prototype.updateFollowers = function () {
- core.status.hero.followers.forEach(function (t) {
- if (!t.stop) {
- t.x += core.utils.scan2[t.direction].x;
- t.y += core.utils.scan2[t.direction].y;
- }
- })
-
- var nowx = core.getHeroLoc('x'), nowy = core.getHeroLoc('y');
- core.status.hero.followers.forEach(function (t) {
- t.stop = true;
- var dx = nowx - t.x, dy = nowy - t.y;
- for (var dir in core.utils.scan2) {
- if (core.utils.scan2[dir].x == dx && core.utils.scan2[dir].y == dy) {
- t.stop = false;
- t.direction = dir;
- }
- }
- nowx = t.x; nowy = t.y;
- })
-}
-
-////// 瞬移更新跟随者坐标 //////
-control.prototype._moveDirectyFollowers = function (x, y) {
- var route = core.automaticRoute(x, y);
- if (route.length == 0) route = [{ x: x, y: y, direction: core.getHeroLoc('direction') }];
-
- var nowx = x, nowy = y;
- for (var i = 0; i < core.status.hero.followers.length; ++i) {
- var t = core.status.hero.followers[i];
- var index = route.length - i - 2;
- if (index < 0) index = 0;
- t.stop = true;
- t.x = route[index].x;
- t.y = route[index].y;
- t.direction = route[index].direction;
- var dx = nowx - t.x, dy = nowy - t.y;
- for (var dir in core.utils.scan2) {
- if (core.utils.scan2[dir].x == dx && core.utils.scan2[dir].y == dy) {
- t.stop = false;
- t.direction = dir;
- }
- }
- nowx = t.x; nowy = t.y;
- }
-}
-
-////// 更新领域、夹击、阻击的伤害地图 //////
-control.prototype.updateCheckBlock = function (floorId) {
- return this.controldata.updateCheckBlock(floorId);
-}
-
-////// 检查并执行领域、夹击、阻击事件 //////
-
-control.prototype.battleWithChase = function () {
- const [hx, hy] = [core.getHeroLoc('x'), core.getHeroLoc('y')];
- const scan = core.utils.scan;
- const actions = [];
- for (const dir in scan) {
- const [nx, ny] = [hx + scan[dir].x, hy + scan[dir].y];
- const blockId = core.getBlockId(nx, ny);
- if (core.hasSpecial(blockId, 28)) {
- actions.push({
- "type": "function", "function": "function() { " +
- "core.battle('" + blockId + "', " + nx + "," + ny + ", true, core.doAction); " +
- "}", "async": true
- });
- }
- }
- if (actions.length > 0) core.insertAction(actions);
- core.doAction();
-}
-
-control.prototype.checkBlock = function () {
- var x = core.getHeroLoc('x'), y = core.getHeroLoc('y'), loc = x + "," + y;
- var damage = core.status.checkBlock.damage[loc];
- if (damage) {
- core.status.hero.hp -= damage;
- var text = (Object.keys(core.status.checkBlock.type[loc] || {}).join(",")) || "伤害";
- core.drawTip("受到" + text + damage + "点");
- core.drawHeroAnimate("zone");
- this._checkBlock_disableQuickShop();
- core.status.hero.statistics.extraDamage += damage;
- if (core.status.hero.hp <= 0) {
- core.status.hero.hp = 0;
- core.updateStatusBar(false, true);
- core.events.lose();
- return;
- } else {
- core.updateStatusBar(false, true);
- }
- }
- let actions = [];
-
- const ambushAction = this._checkBlock_ambush(core.status.checkBlock.ambush[loc]);
- if (ambushAction.length > 0) core.push(actions, ambushAction);
-
- const repulseAction =this._checkBlock_repulse(core.status.checkBlock.repulse[loc]);
- if (repulseAction.length > 0) core.push(actions, repulseAction);
-
- // 追猎需要等待阻击完成,避免发生碰撞导致怪物消失
- const chaseAction = this._checkBlock_chase(core.status.checkBlock.chase[loc]);
- if (chaseAction.length > 0) {
- core.push(actions, chaseAction);
- core.push(actions,
- { "type": "function", "async": true, "function": "function(){\ncore.battleWithChase();\n}" }
- );
- }
- if (actions.length > 0) core.insertAction(actions);
-}
-
-control.prototype._checkBlock_disableQuickShop = function () {
- // 禁用快捷商店
- if (core.flags.disableShopOnDamage) {
- Object.keys(core.status.shops).forEach(function (shopId) {
- core.setShopVisited(shopId, false);
- });
- }
-}
-
-////// 阻击 //////
-control.prototype._checkBlock_repulse = function (repulse) {
- if (!repulse || repulse.length == 0) return [];
- var actions = [];
- repulse.forEach(function (t) {
- actions.push({ "type": "move", "loc": [t[0], t[1]], "steps": [t[3]], "time": 100, "keep": true, "async": true });
- });
- if (actions.length>0) actions.push({ "type": "waitAsync" });
- return actions;
-}
-
-////// 捕捉 //////
-control.prototype._checkBlock_ambush = function (ambush) {
- if (!ambush || ambush.length == 0) return [];
- // 捕捉效果
- let actions = [];
- ambush.forEach(function (t) {
- actions.push({ "type": "move", "loc": [t[0], t[1]], "steps": [t[3]], "time": 100, "keep": false, "async": true });
- });
- if (actions.length>0) actions.push({ "type": "waitAsync" });
- // 强制战斗
- ambush.forEach(function (t) {
- actions.push({
- "type": "function", "function": "function() { " +
- "core.battle('" + t[2] + "', " + t[0] + "," + t[1] + ", true, core.doAction); " +
- "}", "async": true
- });
- });
- return actions;
-}
-
-////// 追猎 //////
-control.prototype._checkBlock_chase = function (chase) {
- if (!chase || chase.length == 0) return [];
- var actions = [];
- const reverseDir = { 'up': 'down', 'down': 'up', 'left': 'right', 'right': 'left' };
- console.log(chase);
-
- chase.forEach(function (info) {
- const { x, y, dir } = info;
- const [aimx, aimy] = [x + core.utils.scan[dir].x, y + core.utils.scan[dir].y];
- console.log(aimx,aimy);
- // 可与敌人,物品换位
- actions.push({
- "type": "if", "condition": "!core.getBlock(" + aimx + "," + aimy + ")",
- "true": [
- { "type": "move", "loc": [x, y], "time": 100, "keep": true, "async": true, "steps": [dir + ":1"] },
- { "type": "waitAsync", "excludeAnimates": true },
- ],
- "false": [
- {
- "type": "if", "condition": "[\"items\",\"enemys\",\"enemy48\"].includes(core.getBlockCls("+ aimx + "," + aimy + "))",
- "true": [
- { "type": "move", "loc": [x, y], "time": 100, "keep": true, "async": true, "steps": [dir + ":1"] },
- { "type": "move", "loc": [aimx, aimy], "time": 100, "keep": true, "async": true, "steps": [reverseDir[dir] + ":1"] },
- { "type": "waitAsync", "excludeAnimates": true },
- ]
- },
- ]
- });
- });
- if (actions.length > 0) actions.push({ "type": "waitAsync" });
- return actions;
-}
-
-////// 更新全地图显伤 //////
-control.prototype.updateDamage = function (floorId, ctx) {
- floorId = floorId || core.status.floorId;
- if (!floorId || core.status.gameOver || main.mode != 'play') return;
- var onMap = ctx == null;
-
- // 没有怪物手册
- if (!core.hasItem('book')) return;
- core.status.damage.posX = core.bigmap.posX;
- core.status.damage.posY = core.bigmap.posY;
- if (!onMap) {
- var width = core.floors[floorId].width, height = core.floors[floorId].height;
- // 地图过大的缩略图不绘制显伤
- if (width * height > core.bigmap.threshold) return;
- }
- this._updateDamage_damage(floorId, onMap);
- this._updateDamage_extraDamage(floorId, onMap);
- this.drawDamage(ctx);
-}
-
-control.prototype._updateDamage_damage = function (floorId, onMap) {
- core.status.damage.data = [];
- if (!core.flags.displayEnemyDamage && !core.flags.displayExtraDamage) return;
-
- core.extractBlocks(floorId);
- core.status.maps[floorId].blocks.forEach(function (block) {
- var x = block.x, y = block.y;
-
- // v2优化,只绘制范围内的部分
- if (onMap && core.bigmap.v2) {
- if (x < core.bigmap.posX - core.bigmap.extend || x > core.bigmap.posX + core.__SIZE__ + core.bigmap.extend
- || y < core.bigmap.posY - core.bigmap.extend || y > core.bigmap.posY + core.__SIZE__ + core.bigmap.extend) {
- return;
- }
- }
-
- if (!block.disable && block.event.cls.indexOf('enemy') == 0 && block.event.displayDamage !== false) {
- if (core.flags.displayEnemyDamage) {
- var damageString = core.enemys.getDamageString(block.event.id, x, y, floorId);
- core.status.damage.data.push({ text: damageString.damage, px: 32 * x + 1, py: 32 * (y + 1) - 1, color: damageString.color });
- }
- if (core.flags.displayCritical) {
- var critical = core.enemys.nextCriticals(block.event.id, 1, x, y, floorId);
- critical = core.formatBigNumber((critical[0] || [])[0], true);
- if (critical == '???') critical = '?';
- core.status.damage.data.push({ text: critical, px: 32 * x + 1, py: 32 * (y + 1) - 11, color: '#FFFFFF' });
- }
- }
- });
-}
-
-control.prototype._updateDamage_extraDamage = function (floorId, onMap) {
- core.status.damage.extraData = [];
- if (!core.flags.displayExtraDamage) return;
-
- var width = core.floors[floorId].width, height = core.floors[floorId].height;
- var startX = onMap && core.bigmap.v2 ? Math.max(0, core.bigmap.posX - core.bigmap.extend) : 0;
- var endX = onMap && core.bigmap.v2 ? Math.min(width, core.bigmap.posX + core.__SIZE__ + core.bigmap.extend + 1) : width;
- var startY = onMap && core.bigmap.v2 ? Math.max(0, core.bigmap.posY - core.bigmap.extend) : 0;
- var endY = onMap && core.bigmap.v2 ? Math.min(height, core.bigmap.posY + core.__SIZE__ + core.bigmap.extend + 1) : height;
-
- for (var x = startX; x < endX; x++) {
- for (var y = startY; y < endY; y++) {
- var alpha = 1;
- if (core.noPass(x, y, floorId)) {
- if (core.flags.extraDamageType == 2) alpha = 0;
- else if (core.flags.extraDamageType == 1) alpha = 0.6;
- }
- var damage = core.status.checkBlock.damage[x + "," + y] || 0;
- if (damage > 0) { // 该点伤害
- damage = core.formatBigNumber(damage, true);
- core.status.damage.extraData.push({ text: damage, px: 32 * x + 16, py: 32 * (y + 1) - 14, color: '#ffaa33', alpha: alpha });
- }
- else { // 检查捕捉
- if (core.status.checkBlock.ambush[x + "," + y]) {
- core.status.damage.extraData.push({ text: '!', px: 32 * x + 16, py: 32 * (y + 1) - 14, color: '#ffaa33', alpha: alpha });
- }
- }
- }
- }
-}
-
-////// 重绘地图显伤 //////
-control.prototype.drawDamage = function (ctx) {
- if (core.status.gameOver || !core.status.damage || main.mode != 'play') return;
- var onMap = false;
- if (ctx == null) {
- ctx = core.canvas.damage;
- core.clearMap('damage');
- onMap = true;
- }
-
- if (onMap && core.bigmap.v2) {
- // 检查是否需要重算...
- if (Math.abs(core.bigmap.posX - core.status.damage.posX) >= core.bigmap.extend - 1
- || Math.abs(core.bigmap.posY - core.status.damage.posY) >= core.bigmap.extend - 1) {
- return this.updateDamage();
- }
- }
- return this._drawDamage_draw(ctx, onMap);
-}
-
-control.prototype._drawDamage_draw = function (ctx, onMap) {
- if (!core.hasItem('book')) return;
-
- core.setFont(ctx, "bold 11px Arial");
- core.setTextAlign(ctx, 'left');
- core.status.damage.data.forEach(function (one) {
- var px = one.px, py = one.py;
- if (onMap && core.bigmap.v2) {
- px -= core.bigmap.posX * 32;
- py -= core.bigmap.posY * 32;
- if (px < -32 * 2 || px > core.__PIXELS__ + 32 || py < -32 || py > core.__PIXELS__ + 32)
- return;
- }
- core.fillBoldText(ctx, one.text, px, py, one.color);
- });
-
- core.setTextAlign(ctx, 'center');
- core.status.damage.extraData.forEach(function (one) {
- var px = one.px, py = one.py;
- if (onMap && core.bigmap.v2) {
- px -= core.bigmap.posX * 32;
- py -= core.bigmap.posY * 32;
- if (px < -32 || px > core.__PIXELS__ + 32 || py < -32 || py > core.__PIXELS__ + 32)
- return;
- }
- var alpha = core.setAlpha(ctx, one.alpha);
- core.fillBoldText(ctx, one.text, px, py, one.color);
- core.setAlpha(ctx, alpha);
- });
-}
-
-// ------ 录像相关 ------ //
-
-////// 选择录像文件 //////
-control.prototype.chooseReplayFile = function () {
- core.readFile(function (obj) {
- if (obj.name != core.firstData.name) return alert("存档和游戏不一致!");
- if (!obj.route) return alert("无效的录像!");
- var _replay = function () {
- core.startGame(core.flags.startUsingCanvas ? '' : obj.hard || '', obj.seed, core.decodeRoute(obj.route));
- }
- if (obj.version && obj.version != core.firstData.version) {
- core.myconfirm("游戏版本不一致!\n你仍然想播放录像吗?", _replay);
- return;
- }
- _replay();
- }, null, ".h5route");
-}
-
-////// 开始播放 //////
-control.prototype.startReplay = function (list) {
- if (!core.isPlaying()) return;
- core.status.replay.replaying = true;
- core.status.replay.pausing = true;
- core.status.replay.failed = false;
- core.status.replay.speed = 1.0;
- core.status.replay.toReplay = core.cloneArray(list);
- core.status.replay.totalList = core.status.route.concat(list);
- core.status.replay.steps = 0;
- core.status.replay.save = [];
- core.createCanvas('replay', 0, core.__PIXELS__ - 40, core.__PIXELS__, 40, 199);
- core.setOpacity('replay', 0.6);
- this._replay_drawProgress();
- core.updateStatusBar(false, true);
- core.drawTip("开始播放");
- this.replay();
-}
-
-////// 更改播放状态 //////
-control.prototype.triggerReplay = function () {
- if (core.status.replay.pausing) this.resumeReplay();
- else this.pauseReplay();
-}
-
-////// 暂停播放 //////
-control.prototype.pauseReplay = function () {
- if (!core.isPlaying() || !core.isReplaying()) return;
- core.status.replay.pausing = true;
- core.updateStatusBar(false, true);
- core.drawTip("暂停播放");
-}
-
-////// 恢复播放 //////
-control.prototype.resumeReplay = function () {
- if (!core.isPlaying() || !core.isReplaying()) return;
- if (core.isMoving() || core.status.replay.animate || core.status.event.id) {
- core.playSound('操作失败');
- return core.drawTip("请等待当前事件的处理结束");
- }
- core.status.replay.pausing = false;
- core.updateStatusBar(false, true);
- core.drawTip("恢复播放");
- core.replay();
-}
-
-////// 单步播放 //////
-control.prototype.stepReplay = function () {
- if (!core.isPlaying() || !core.isReplaying()) return;
- if (!core.status.replay.pausing) {
- core.playSound('操作失败');
- return core.drawTip("请先暂停录像");
- }
- if (core.isMoving() || core.status.replay.animate || core.status.event.id) {
- core.playSound('操作失败');
- return core.drawTip("请等待当前事件的处理结束");
- }
- core.replay(true);
-}
-
-////// 加速播放 //////
-control.prototype.speedUpReplay = function () {
- if (!core.isPlaying() || !core.isReplaying()) return;
- var speeds = [0.2, 0.5, 1, 2, 3, 6, 12, 24];
- for (var i = speeds.length - 2; i >= 0; i--) {
- if (speeds[i] <= core.status.replay.speed) {
- core.status.replay.speed = speeds[i + 1];
- break;
- }
- }
- core.drawTip("x" + core.status.replay.speed + "倍");
-}
-
-////// 减速播放 //////
-control.prototype.speedDownReplay = function () {
- if (!core.isPlaying() || !core.isReplaying()) return;
- var speeds = [0.2, 0.5, 1, 2, 3, 6, 12, 24];
- for (var i = 1; i <= speeds.length; i++) {
- if (speeds[i] >= core.status.replay.speed) {
- core.status.replay.speed = speeds[i - 1];
- break;
- }
- }
- core.drawTip("x" + core.status.replay.speed + "倍");
-}
-
-////// 设置播放速度 //////
-control.prototype.setReplaySpeed = function (speed) {
- if (!core.isPlaying() || !core.isReplaying()) return;
- core.status.replay.speed = speed;
- core.drawTip("x" + core.status.replay.speed + "倍");
-}
-
-////// 停止播放 //////
-control.prototype.stopReplay = function (force) {
- if (!core.isPlaying()) return;
- if (!core.isReplaying() && !force) return;
- core.status.replay.toReplay = [];
- core.status.replay.totalList = [];
- core.status.replay.replaying = false;
- core.status.replay.pausing = false;
- core.status.replay.failed = false;
- core.status.replay.speed = 1.0;
- core.status.replay.steps = 0;
- core.status.replay.save = [];
- core.deleteCanvas('replay');
- core.updateStatusBar(false, true);
- core.drawTip("停止播放并恢复游戏");
-}
-
-////// 回退 //////
-control.prototype.rewindReplay = function () {
- if (!core.isPlaying() || !core.isReplaying()) return;
- if (!core.status.replay.pausing) {
- core.playSound('操作失败');
- return core.drawTip("请先暂停录像");
- }
- if (core.isMoving() || core.status.replay.animate || core.status.event.id) {
- core.playSound('操作失败');
- return core.drawTip("请等待当前事件的处理结束");
- }
- if (core.status.replay.save.length == 0) {
- core.playSound('操作失败');
- return core.drawTip("无法再回到上一个节点");
- }
- var save = core.status.replay.save, data = save.pop();
- core.loadData(data.data, function () {
- core.removeFlag('__fromLoad__');
- core.status.replay = {
- "replaying": true,
- "pausing": true,
- "animate": false,
- "toReplay": data.replay.toReplay,
- "totalList": data.replay.totalList,
- "speed": core.status.replay.speed,
- "steps": data.replay.steps,
- "save": save
- }
- core.createCanvas('replay', 0, core.__PIXELS__ - 40, core.__PIXELS__, 40, 199);
- core.setOpacity('replay', 0.6);
- core.control._replay_drawProgress();
- core.updateStatusBar(false, true);
- core.drawTip("成功回退到上一个节点");
- });
-}
-
-////// 回放时存档 //////
-control.prototype._replay_SL = function () {
- if (!core.isPlaying() || !core.isReplaying()) return;
- if (!core.status.replay.pausing) {
- core.playSound('操作失败');
- return core.drawTip("请先暂停录像");
- }
- if (core.isMoving() || core.status.replay.animate || core.status.event.id) {
- core.playSound('操作失败');
- return core.drawTip("请等待当前事件的处理结束");
- }
- if (core.hasFlag('__forbidSave__')) {
- core.playSound('操作失败');
- return core.drawTip('当前禁止存档');
- }
- this._replay_hideProgress();
-
- core.lockControl();
- core.status.event.id = 'save';
- var saveIndex = core.saves.saveIndex;
- var page = parseInt((saveIndex - 1) / 5), offset = saveIndex - 5 * page;
-
- core.ui._drawSLPanel(10 * page + offset);
-}
-
-////// 回放时查看怪物手册 //////
-control.prototype._replay_book = function () {
- if (!core.isPlaying() || !core.isReplaying()) return;
- if (!core.status.replay.pausing) {
- core.playSound('操作失败');
- return core.drawTip("请先暂停录像");
- }
- if (core.isMoving() || core.status.replay.animate || (core.status.event.id && core.status.event.id != 'viewMaps')) {
- core.playSound('操作失败');
- return core.drawTip("请等待当前事件的处理结束");
- }
- if (!core.hasItem('book')) {
- core.playSound('操作失败');
- return core.drawTip('你没有' + core.material.items['book'].name, 'book');
- }
- this._replay_hideProgress();
-
- // 从“浏览地图”页面打开
- if (core.status.event.id == 'viewMaps')
- core.status.event.ui = core.status.event.data;
-
- core.lockControl();
- core.status.event.id = 'book';
- core.useItem('book', true);
-}
-
-////// 回放录像时浏览地图 //////
-control.prototype._replay_viewMap = function () {
- if (!core.isPlaying() || !core.isReplaying()) return;
- if (!core.status.replay.pausing) {
- core.playSound('操作失败');
- return core.drawTip("请先暂停录像");
- }
- if (core.isMoving() || core.status.replay.animate || core.status.event.id) {
- core.playSound('操作失败');
- return core.drawTip("请等待当前事件的处理结束");
- }
- this._replay_hideProgress();
-
- core.lockControl();
- core.status.event.id = 'viewMaps';
- core.ui._drawViewMaps();
-}
-
-control.prototype._replay_toolbox = function () {
- if (!core.isPlaying() || !core.isReplaying()) return;
- if (!core.status.replay.pausing) {
- core.playSound('操作失败');
- return core.drawTip("请先暂停录像");
- }
- if (core.isMoving() || core.status.replay.animate || core.status.event.id) {
- core.playSound('操作失败');
- return core.drawTip("请等待当前事件的处理结束");
- }
- this._replay_hideProgress();
-
- core.lockControl();
- core.status.event.id = 'toolbox';
- core.ui._drawToolbox();
-}
-
-control.prototype._replay_equipbox = function () {
- if (!core.isPlaying() || !core.isReplaying()) return;
- if (!core.status.replay.pausing) {
- core.playSound('操作失败');
- return core.drawTip("请先暂停录像");
- }
- if (core.isMoving() || core.status.replay.animate || core.status.event.id) {
- core.playSound('操作失败');
- return core.drawTip("请等待当前事件的处理结束");
- }
- this._replay_hideProgress();
-
- core.lockControl();
- core.status.event.id = 'equipbox';
- core.ui._drawEquipbox();
-}
-
-////// 是否正在播放录像 //////
-control.prototype.isReplaying = function () {
- return (core.status.replay || {}).replaying;
-}
-
-////// 回放 //////
-control.prototype.replay = function (force) {
- if (!core.isPlaying() || !core.isReplaying()
- || core.status.replay.animate || core.status.event.id || core.status.replay.failed) return;
- if (core.status.replay.pausing && !force) return;
- this._replay_drawProgress();
- if (core.status.replay.toReplay.length == 0)
- return this._replay_finished();
- this._replay_save();
- var action = core.status.replay.toReplay.shift();
- if (this._doReplayAction(action)) return;
- this._replay_error(action);
-}
-
-////// 注册一个录像行为 //////
-// name:自定义名称,可用于注销使用
-// func:具体执行录像的函数,可为一个函数或插件中的函数名;
-// 需要接受一个action参数,代表录像回放时的下一个操作
-// func返回true代表成功处理了此录像行为,false代表没有处理此录像行为。
-control.prototype.registerReplayAction = function (name, func) {
- this.unregisterReplayAction(name);
- this.replayActions.push({ name: name, func: func });
-}
-
-////// 注销一个录像行为 //////
-control.prototype.unregisterReplayAction = function (name) {
- this.replayActions = this.replayActions.filter(function (b) { return b.name != name; });
-}
-
-////// 执行录像行为,会在注册的函数中依次执行直到得到true为止 //////
-control.prototype._doReplayAction = function (action) {
- for (var i in this.replayActions) {
- try {
- if (core.doFunc(this.replayActions[i].func, this, action)) return true;
- } catch (e) {
- console.error(e);
- console.error("ERROR in replayActions[" + this.replayActions[i].name + "]:已自动注销该项。");
- core.unregisterReplayAction(this.replayActions[i].name);
- }
- }
- return false;
-}
-
-control.prototype._replay_finished = function () {
- core.status.replay.replaying = false;
- core.status.replay.failed = false;
- core.status.event.selection = 0;
- var str = "录像播放完毕,你想退出播放吗?";
- if (core.status.route.length != core.status.replay.totalList.length
- || core.subarray(core.status.route, core.status.replay.totalList) == null) {
- str = "录像播放完毕,但记录不一致。\n请检查录像播放时的二次记录问题。\n你想退出播放吗?";
- }
- core.ui.drawConfirmBox(str, function () {
- core.ui.closePanel();
- core.stopReplay(true);
- }, function () {
- core.status.replay.replaying = true;
- core.ui.closePanel();
- core.pauseReplay();
- });
-}
-
-control.prototype._replay_save = function () {
- core.status.replay.steps++;
- if (core.status.replay.steps % 40 == 1) {
- if (core.status.replay.save.length == 30)
- core.status.replay.save.shift();
- core.status.replay.save.push({
- "data": core.saveData(), "replay": {
- "totalList": core.cloneArray(core.status.replay.totalList),
- "toReplay": core.cloneArray(core.status.replay.toReplay),
- "steps": core.status.replay.steps
- }
- });
- }
-}
-
-control.prototype._replay_error = function (action, callback) {
- core.ui.closePanel();
- core.status.replay.replaying = false;
- core.status.replay.failed = true;
- var len = core.status.replay.toReplay.length;
- var prevList = core.status.replay.totalList.slice(-len - 11, -len - 1);
- var nextList = core.status.replay.toReplay.slice(0, 10);
- console.log("录像文件出错,当前操作:" + action);
- console.log("之前的10个操作是:\n" + prevList.toString());
- console.log("接下来10个操作是:\n" + nextList.toString());
- core.ui.drawConfirmBox("录像文件出错,你想回到上个节点吗?", function () {
- core.status.replay.failed = false;
- core.ui.closePanel();
- if (core.status.replay.save.length > 0) {
- core.status.replay.replaying = true;
- core.status.replay.pausing = true;
- core.rewindReplay();
- }
- else {
- core.playSound('操作失败');
- core.stopReplay(true);
- core.drawTip("无法回到上一个节点");
- if (callback) callback();
- }
- }, function () {
- core.status.replay.failed = false;
- core.ui.closePanel();
- core.stopReplay(true);
- if (callback) callback();
- });
-}
-
-control.prototype._replay_hideProgress = function () {
- if (core.dymCanvas.replay) core.dymCanvas.replay.canvas.style.display = 'none';
-}
-
-control.prototype._replay_drawProgress = function () {
- if (!core.dymCanvas.replay) return;
- if (core.dymCanvas.replay.canvas.style.display == 'none') core.dymCanvas.replay.canvas.style.display = 'block';
- var total = core.status.replay.totalList.length, left = total - core.status.replay.toReplay.length;
- var content = '播放进度:' + left + ' / ' + total + '(' + (left / total * 100).toFixed(2) + '%)';
- var width = 26 + core.calWidth('replay', content, "16px Arial");
- core.clearMap('replay');
- core.fillRect('replay', 0, 0, width, 40, '#000000');
- core.fillText('replay', content, 16, 27, '#FFFFFF');
-}
-
-control.prototype.__replay_getTimeout = function () {
- if (core.status.replay.speed == 24) return 0;
- return 750 / Math.max(1, core.status.replay.speed);
-}
-
-control.prototype._replayAction_move = function (action) {
- if (["up", "down", "left", "right"].indexOf(action) < 0) return false;
- core.moveHero(action, core.replay);
- return true;
-}
-
-control.prototype._replayAction_item = function (action) {
- if (action.indexOf("item:") != 0) return false;
- var itemId = action.substring(5);
- if (!core.canUseItem(itemId)) return false;
- if (core.material.items[itemId].hideInReplay || core.status.replay.speed == 24) {
- core.useItem(itemId, false, core.replay);
- return true;
- }
- var tools = core.getToolboxItems('tools'),
- constants = core.getToolboxItems('constants');
- var index, per = core.__SIZE__ - 1;
- if ((index = tools.indexOf(itemId)) >= 0) {
- core.status.event.data = { "toolsPage": Math.floor(index / per) + 1, "constantsPage": 1 };
- index = index % per;
- }
- else if ((index = constants.indexOf(itemId)) >= 0) {
- core.status.event.data = { "toolsPage": 1, "constantsPage": Math.floor(index / per) + 1 };
- index = index % per + per;
- }
- if (index < 0) return false;
- core.ui._drawToolbox(index);
- setTimeout(function () {
- core.ui.closePanel();
- core.useItem(itemId, false, core.replay);
- }, core.control.__replay_getTimeout());
- return true;
-}
-
-control.prototype._replayAction_equip = function (action) {
- if (action.indexOf("equip:") != 0) return false;
- var equipId = action.substring(6);
- var ownEquipment = core.getToolboxItems('equips');
- var index = ownEquipment.indexOf(equipId), per = core.__SIZE__ - 1;
- if (index < 0) {
- core.removeFlag('__doNotCheckAutoEvents__');
- return false;
- }
-
- var cb = function () {
- var next = core.status.replay.toReplay[0] || "";
- if (!next.startsWith('equip:') && !next.startsWith('unEquip:')) {
- core.removeFlag('__doNotCheckAutoEvents__');
- core.checkAutoEvents();
- }
- core.replay();
- }
- core.setFlag('__doNotCheckAutoEvents__', true);
-
- core.status.route.push(action);
- if (core.material.items[equipId].hideInReplay || core.status.replay.speed == 24) {
- core.loadEquip(equipId, cb);
- return true;
- }
- core.status.event.data = { "page": Math.floor(index / per) + 1, "selectId": null };
- index = index % per + per;
- core.ui._drawEquipbox(index);
- setTimeout(function () {
- core.ui.closePanel();
- core.loadEquip(equipId, cb);
- }, core.control.__replay_getTimeout());
- return true;
-}
-
-control.prototype._replayAction_unEquip = function (action) {
- if (action.indexOf("unEquip:") != 0) return false;
- var equipType = parseInt(action.substring(8));
- if (!core.isset(equipType)) {
- core.removeFlag('__doNotCheckAutoEvents__');
- return false;
- }
-
- var cb = function () {
- var next = core.status.replay.toReplay[0] || "";
- if (!next.startsWith('equip:') && !next.startsWith('unEquip:')) {
- core.removeFlag('__doNotCheckAutoEvents__');
- core.checkAutoEvents();
- }
- core.replay();
- }
- core.setFlag('__doNotCheckAutoEvents__', true);
-
- core.ui._drawEquipbox(equipType);
- core.status.route.push(action);
- if (core.status.replay.speed == 24) {
- core.unloadEquip(equipType, cb);
- return true;
- }
- setTimeout(function () {
- core.ui.closePanel();
- core.unloadEquip(equipType, cb);
- }, core.control.__replay_getTimeout());
- return true;
-}
-
-control.prototype._replayAction_saveEquip = function (action) {
- if (action.indexOf('saveEquip:') != 0) return false;
- core.quickSaveEquip(parseInt(action.substring(10)));
- core.replay();
- return true;
-}
-
-control.prototype._replayAction_loadEquip = function (action) {
- if (action.indexOf('loadEquip:') != 0) return false;
- core.quickLoadEquip(parseInt(action.substring(10)));
- core.replay();
- return true;
-}
-
-control.prototype._replayAction_fly = function (action) {
- if (action.indexOf("fly:") != 0) return false;
- var floorId = action.substring(4);
- var toIndex = core.floorIds.indexOf(floorId);
- if (!core.canUseItem('fly') || (core.flags.flyNearStair && !core.nearStair())) return false;
- core.ui.drawFly(toIndex);
- if (core.status.replay.speed == 24) {
- if (!core.flyTo(floorId, core.replay))
- core.control._replay_error(action);
- return true;
- }
- setTimeout(function () {
- if (!core.flyTo(floorId, core.replay))
- core.control._replay_error(action);
- }, core.control.__replay_getTimeout());
- return true;
-}
-
-control.prototype._replayAction_shop = function (action) {
- if (action.indexOf("shop:") != 0) return false;
- var shopId = action.substring(5);
- if (core.canUseQuickShop(shopId) != null || !core.canOpenShop(shopId)) {
- this._replay_error(shopId);
- return true;
- }
- core.openShop(shopId, false);
- core.replay();
- return true;
-}
-
-control.prototype._replayAction_turn = function (action) {
- if (action != 'turn' && action.indexOf('turn:') != 0) return false;
- if (action == 'turn') core.turnHero();
- else core.turnHero(action.substring(5));
- core.replay();
- return true;
-}
-
-control.prototype._replayAction_getNext = function (action) {
- if (action != "getNext") return false;
- core.getNextItem();
- core.replay();
- return true;
-}
-
-control.prototype._replayAction_moveDirectly = function (action) {
- if (action.indexOf("move:") != 0) return false;
-
- var pos = action.substring(5).split(":");
- var x = parseInt(pos[0]), y = parseInt(pos[1]);
- var nowx = core.getHeroLoc('x'), nowy = core.getHeroLoc('y');
- var ignoreSteps = core.canMoveDirectly(x, y);
- if (!core.moveDirectly(x, y, ignoreSteps)) return false;
- if (core.status.replay.speed == 24) {
- core.replay();
- return true;
- }
-
- core.ui.drawArrow('ui', 32 * nowx + 16 - core.bigmap.offsetX, 32 * nowy + 16 - core.bigmap.offsetY,
- 32 * x + 16 - core.bigmap.offsetX, 32 * y + 16 - core.bigmap.offsetY, '#FF0000', 3);
- var timeout = this.__replay_getTimeout();
- if (ignoreSteps < 10) timeout = timeout * ignoreSteps / 10;
- setTimeout(function () {
- core.clearMap('ui');
- core.replay();
- }, timeout);
- return true;
-}
-
-control.prototype._replayAction_key = function (action) {
- if (action.indexOf("key:") != 0) return false;
- core.actions.keyUp(parseInt(action.substring(4)), false, true);
- core.replay();
- return true;
-}
-
-control.prototype._replayAction_click = function (action) {
- if (action.indexOf("click:") != 0) return false;
- var p = action.split(":");
- if (p.length != 4) return false;
- core.actions.doRegisteredAction("onStatusBarClick", parseInt(p[2]), parseInt(p[3]), parseInt(p[1]));
- core.replay();
- return true;
-}
-
-control.prototype._replayAction_ignoreInput = function (action) {
- if (action.indexOf('input:') == 0 || action.indexOf('input2:') == 0 || action.indexOf('choices:') == 0 || action.indexOf('random:') == 0) {
- console.warn('警告!录像播放中出现了未知的 ' + action + '!');
- core.replay();
- return true;
- }
- return false;
-}
-
-control.prototype._replayAction_no = function (action) {
- if (action != 'no') return false;
- core.status.route.push(action);
- core.replay();
- return true;
-}
-
-// ------ 存读档相关 ------ //
-
-////// 自动存档 //////
-control.prototype.autosave = function (removeLast) {
- if (core.hasFlag('__forbidSave__')) return;
- var x = null;
- if (removeLast) {
- x = core.status.route.pop();
- core.status.route.push("turn:" + core.getHeroLoc('direction'));
- }
- if (core.status.event.id == 'action') // 事件中的自动存档
- core.setFlag("__events__", core.clone(core.status.event.data));
- if (core.saves.autosave.data == null) {
- core.saves.autosave.data = [];
- }
- core.saves.autosave.data.splice(core.saves.autosave.now, 0, core.saveData());
- core.saves.autosave.now += 1;
- if (core.saves.autosave.data.length > core.saves.autosave.max) {
- if (core.saves.autosave.now < core.saves.autosave.max / 2)
- core.saves.autosave.data.pop();
- else {
- core.saves.autosave.data.shift();
- core.saves.autosave.now = core.saves.autosave.now - 1;
- }
- }
- core.saves.autosave.updated = true;
- core.saves.ids[0] = true;
- core.removeFlag("__events__");
- if (removeLast) {
- core.status.route.pop();
- if (x) core.status.route.push(x);
- }
-}
-
-/////// 实际进行自动存档 //////
-control.prototype.checkAutosave = function () {
- if (!core.animateFrame || !core.saves || !core.saves.autosave) return;
- core.setLocalStorage('totalTime', core.animateFrame.totalTime);
- var autosave = core.saves.autosave;
- if (autosave.data == null || !autosave.updated || !autosave.storage) return;
- autosave.updated = false;
- if (autosave.data.length >= 1) {
- core.setLocalForage("autoSave", autosave.data[autosave.now - 1]);
- }
-}
-
-////// 实际进行存读档事件 //////
-control.prototype.doSL = function (id, type) {
- switch (type) {
- case 'save': this._doSL_save(id); break;
- case 'load': this._doSL_load(id, this._doSL_load_afterGet); break;
- case 'reload': this._doSL_reload(id, this._doSL_load_afterGet); break;
- case 'replayLoad': this._doSL_load(id, this._doSL_replayLoad_afterGet); break;
- case 'replayRemain': this._doSL_load(id, this._doSL_replayRemain_afterGet); break;
- case 'replaySince': this._doSL_load(id, this._doSL_replaySince_afterGet); break;
- }
-}
-
-control.prototype._doSL_save = function (id) {
- if (id == 'autoSave') {
- core.playSound('操作失败');
- return core.drawTip('不能覆盖自动存档!');
- }
- // 在事件中的存档
- if (core.status.event.interval != null)
- core.setFlag("__events__", core.status.event.interval);
- var data = core.saveData();
- if (core.isReplaying() && core.status.replay.toReplay.length > 0) {
- data.__toReplay__ = core.encodeRoute(core.status.replay.toReplay);
- }
- core.setLocalForage("save" + id, data, function () {
- core.saves.saveIndex = id;
- core.setLocalStorage('saveIndex', core.saves.saveIndex);
- // 恢复事件
- if (!core.events.recoverEvents(core.status.event.interval))
- core.ui.closePanel();
- core.playSound('存档');
- core.drawTip('存档成功!');
- }, function (err) {
- console.error(err);
- alert("存档失败,错误信息:\n" + err);
- });
- core.removeFlag("__events__");
- return;
-}
-
-control.prototype._doSL_load = function (id, callback) {
- if (id == 'autoSave' && core.saves.autosave.data != null) {
- core.saves.autosave.now -= 1;
- var data = core.saves.autosave.data.splice(core.saves.autosave.now, 1)[0];
- if (core.isPlaying() && !core.status.gameOver) {
- core.control.autosave(0);
- core.saves.autosave.now -= 1;
- }
- if (core.saves.autosave.now == 0) {
- core.saves.autosave.data.unshift(core.clone(data));
- core.saves.autosave.now += 1;
- }
- callback(id, data);
- }
- else {
- core.getLocalForage(id == 'autoSave' ? id : "save" + id, null, function (data) {
- if (id == 'autoSave' && data != null) {
- core.saves.autosave.data = data;
- if (!(core.saves.autosave.data instanceof Array)) {
- core.saves.autosave.data = [core.saves.autosave.data];
- }
- core.saves.autosave.now = core.saves.autosave.data.length;
- return core.control._doSL_load(id, callback);
- }
- callback(id, data);
- }, function (err) {
- console.error(err);
- alert("无效的存档");
- })
- }
- return;
-}
-
-control.prototype._doSL_reload = function (id, callback) {
- if (core.saves.autosave.data != null && core.saves.autosave.now < core.saves.autosave.data.length) {
- var data = core.saves.autosave.data.splice(core.saves.autosave.now, 1)[0];
- core.control.autosave(false);
- callback(id, data);
- }
- return;
-}
-
-control.prototype._doSL_load_afterGet = function (id, data) {
- if (!data) return alert("无效的存档");
- var _replay = function () {
- core.startGame(data.hard, data.hero.flags.__seed__, core.decodeRoute(data.route));
- };
- if (data.version != core.firstData.version) {
- core.myconfirm("存档版本不匹配!\n你想回放此存档的录像吗?\n可以随时停止录像播放以继续游戏。", _replay);
- return;
- }
- if (data.hero.flags.__events__ && data.guid != core.getGuid()) {
- core.myconfirm("此存档可能存在风险,你想要播放录像么?", _replay);
- return;
- }
- core.ui.closePanel();
- core.loadData(data, function () {
- core.removeFlag('__fromLoad__');
- core.drawTip("读档成功");
- if (id != "autoSave") {
- core.saves.saveIndex = id;
- core.setLocalStorage('saveIndex', core.saves.saveIndex);
- }
- });
-}
-
-control.prototype._doSL_replayLoad_afterGet = function (id, data) {
- if (!data) {
- core.playSound('操作失败');
- return core.drawTip("无效的存档");
- }
- if (data.version != core.firstData.version) {
- core.playSound('操作失败');
- return core.drawTip("存档版本不匹配");
- }
- if (data.hero.flags.__events__ && data.guid != core.getGuid()) {
- core.playSound('操作失败');
- return core.drawTip("此存档可能存在风险,无法读档");
- }
- var route = core.subarray(core.status.route, core.decodeRoute(data.route));
- if (route == null) {
- core.playSound('操作失败');
- return core.drawTip("无法从此存档回放录像");
- }
- core.loadData(data, function () {
- core.removeFlag('__fromLoad__');
- core.startReplay(route);
- core.drawTip("回退到存档节点");
- });
-}
-
-control.prototype._doSL_replayRemain_afterGet = function (id, data) {
- if (!data) {
- core.playSound('操作失败');
- return core.drawTip("无效的存档");
- }
- var route = core.decodeRoute(data.route);
- if (core.status.tempRoute) {
- var remainRoute = core.subarray(route, core.status.tempRoute);
- if (remainRoute == null)
- return alert("无法接续播放录像!\n该存档必须是前一个选择的存档的后续内容。");
- delete core.status.tempRoute;
- core.ui.closePanel();
- core.startReplay(remainRoute);
- core.drawTip("接续播放录像");
- return;
- }
- else if (data.floorId != core.status.floorId || data.hero.loc.x != core.getHeroLoc('x') || data.hero.loc.y != core.getHeroLoc('y'))
- return alert("楼层或坐标不一致!");
-
- core.status.tempRoute = route;
- core.ui.closePanel();
- core.drawText("\t[步骤2]请选择第二个存档。\n\r[yellow]该存档必须是前一个存档的后续。\r\n将尝试播放到此存档。", function () {
- core.status.event.id = 'replayRemain';
- core.lockControl();
- var saveIndex = core.saves.saveIndex;
- var page = parseInt((saveIndex - 1) / 5), offset = saveIndex - 5 * page;
- core.ui._drawSLPanel(10 * page + offset);
- });
-}
-
-control.prototype._doSL_replaySince_afterGet = function (id, data) {
- if (data.floorId != core.status.floorId || data.hero.loc.x != core.getHeroLoc('x') || data.hero.loc.y != core.getHeroLoc('y'))
- return alert("楼层或坐标不一致!");
- if (!data.__toReplay__) return alert('该存档没有剩余录像!');
- core.ui.closePanel();
- core.startReplay(core.decodeRoute(data.__toReplay__));
- core.drawTip("播放存档剩余录像");
- return;
-}
-
-////// 同步存档到服务器 //////
-control.prototype.syncSave = function (type) {
- core.ui.drawWaiting("正在同步,请稍候...");
- var callback = function (saves) {
- core.control._syncSave_http(type, saves);
- }
- if (type == 'all') core.getAllSaves(callback);
- else core.getSave(core.saves.saveIndex, callback);
-}
-
-control.prototype._syncSave_http = function (type, saves) {
- if (!saves) return core.drawText("没有要同步的存档");
- var formData = new FormData();
- formData.append('type', 'save');
- formData.append('name', core.firstData.name);
- formData.append('data', LZString.compressToBase64(JSON.stringify(saves)));
- formData.append('shorten', '1');
-
- core.http("POST", "/games/sync.php", formData, function (data) {
- var response = JSON.parse(data);
- if (response.code < 0) {
- core.drawText("出错啦!\n无法同步存档到服务器。\n错误原因:" + response.msg);
- }
- else {
- core.drawText((type == 'all' ? "所有存档" : "存档" + core.saves.saveIndex) + "同步成功!\n\n您的存档编号+密码: \r[yellow]"
- + response.code + response.msg
- + "\r\n\n请牢记以上信息(如截图等),在从服务器\n同步存档时使用。\n\r[yellow]另外请注意,存档同步只会保存一个月的时间。\r")
- }
- }, function (e) {
- core.drawText("出错啦!\n无法同步存档到服务器。\n错误原因:" + e);
- })
-}
-
-////// 从服务器加载存档 //////
-control.prototype.syncLoad = function () {
- core.myprompt("请输入存档编号+密码", null, function (idpassword) {
- if (!idpassword) return core.ui._drawSyncSave();
- if (!/^\d{6}\w{4}$/.test(idpassword) && !/^\d{4}\w{3}$/.test(idpassword)) {
- core.drawText("不合法的存档编号+密码!");
- return;
- }
- core.ui.drawWaiting("正在同步,请稍候...");
- if (idpassword.length == 7) {
- core.control._syncLoad_http(idpassword.substring(0, 4), idpassword.substring(4));
- } else {
- core.control._syncLoad_http(idpassword.substring(0, 6), idpassword.substring(6));
- }
- });
-}
-
-control.prototype._syncLoad_http = function (id, password) {
- var formData = new FormData();
- formData.append('type', 'load');
- formData.append('name', core.firstData.name);
- formData.append('id', id);
- formData.append('password', password);
-
- core.http("POST", "/games/sync.php", formData, function (data) {
- var response = JSON.parse(data);
- if (response.code == 0) {
- var msg = null;
- try {
- msg = JSON.parse(LZString.decompressFromBase64(response.msg));
- } catch (e) { }
- if (!msg) {
- try {
- msg = JSON.parse(response.msg);
- } catch (e) { }
- }
- if (msg) {
- core.control._syncLoad_write(msg);
- } else {
- core.drawText("出错啦!\n存档解析失败!");
- }
- }
- else {
- core.drawText("出错啦!\n无法从服务器同步存档。\n错误原因:" + response.msg);
- }
- }, function (e) {
- core.drawText("出错啦!\n无法从服务器同步存档。\n错误原因:" + e);
- });
-}
-
-control.prototype._syncLoad_write = function (data) {
- if (data instanceof Array) {
- core.status.event.selection = 1;
- core.ui.drawConfirmBox("所有本地存档都将被覆盖,确认?", function () {
- for (var i = 1; i <= 5 * (main.savePages || 30); i++) {
- if (i <= data.length)
- core.setLocalForage("save" + i, data[i - 1]);
- else if (core.saves.ids[i])
- core.removeLocalForage("save" + i);
- }
- core.ui.closePanel();
- core.drawText("同步成功!\n你的本地所有存档均已被覆盖。");
- }, function () {
- core.status.event.selection = 0;
- core.ui._drawSyncSave();
- });
- }
- else {
- // 只覆盖单存档
- core.setLocalForage("save" + core.saves.saveIndex, data, function () {
- core.drawText("同步成功!\n单存档已覆盖至存档" + core.saves.saveIndex);
- });
- }
-}
-
-////// 存档到本地 //////
-control.prototype.saveData = function () {
- return this.controldata.saveData();
-}
-
-////// 从本地读档 //////
-control.prototype.loadData = function (data, callback) {
- return this.controldata.loadData(data, callback);
-}
-
-control.prototype.getSave = function (index, callback) {
- if (index == 0) {
- // --- 自动存档先从缓存中获取
- if (core.saves.autosave.data != null)
- callback(core.saves.autosave.data);
- else {
- core.getLocalForage("autoSave", null, function (data) {
- if (data != null) {
- core.saves.autosave.data = data;
- if (!(core.saves.autosave.data instanceof Array)) {
- core.saves.autosave.data = [core.saves.autosave.data];
- }
- core.saves.autosave.now = core.saves.autosave.data.length;
- }
- callback(core.saves.autosave.data);
- }, function (err) {
- console.error(err);
- callback(null);
- });
- }
- return;
- }
- core.getLocalForage("save" + index, null, function (data) {
- if (callback) callback(data);
- }, function (err) {
- console.error(err);
- if (callback) callback(null);
- });
-}
-
-control.prototype.getSaves = function (ids, callback) {
- if (!(ids instanceof Array)) return this.getSave(ids, callback);
- var count = ids.length, data = {};
- for (var i = 0; i < ids.length; ++i) {
- (function (i) {
- core.getSave(ids[i], function (result) {
- data[i] = result;
- if (Object.keys(data).length == count)
- callback(data);
- })
- })(i);
- }
-}
-
-control.prototype.getAllSaves = function (callback) {
- var ids = Object.keys(core.saves.ids).filter(function (x) { return x != 0; })
- .sort(function (a, b) { return a - b; }), saves = [];
- this.getSaves(ids, function (data) {
- for (var i = 0; i < ids.length; ++i) {
- if (data[i] != null)
- saves.push(data[i]);
- }
- callback(saves);
- });
-}
-
-////// 获得所有存在存档的存档位 //////
-control.prototype.getSaveIndexes = function (callback) {
- var indexes = {};
- core.keysLocalForage(function (err, keys) {
- if (err) {
- console.error(err);
- return callback(indexes);
- }
- keys.forEach(function (key) {
- core.control._getSaveIndexes_getIndex(indexes, key);
- });
- callback(indexes);
- });
-}
-
-control.prototype._getSaveIndexes_getIndex = function (indexes, name) {
- var e = new RegExp('^' + core.firstData.name + "_(save\\d+|autoSave)$").exec(name);
- if (e) {
- if (e[1] == 'autoSave') indexes[0] = true;
- else indexes[parseInt(e[1].substring(4))] = true;
- }
-}
-
-////// 判断某个存档位是否存在存档 //////
-control.prototype.hasSave = function (index) {
- return core.saves.ids[index] || false;
-}
-
-////// 删除某个存档
-control.prototype.removeSave = function (index, callback) {
- if (index == 0 || index == "autoSave") {
- index = "autoSave";
- core.removeLocalForage(index, function () {
- core.saves.autosave.data = null;
- core.saves.autosave.updated = false;
- if (callback) callback();
- });
- return;
- }
- core.removeLocalForage("save" + index, function () {
- core.saves.favorite = core.saves.favorite.filter(function (i) { return core.hasSave(i); });
- delete core.saves.favoriteName[index];
- core.control._updateFavoriteSaves();
- if (callback) callback();
- }, function () {
- core.playSound('操作失败');
- core.drawTip("无法删除存档!");
- if (callback) callback();
- });
-}
-
-////// 读取收藏信息
-control.prototype._loadFavoriteSaves = function () {
- core.saves.favorite = core.getLocalStorage("favorite", []);
- // --- 移除不存在的收藏
- core.saves.favorite = core.saves.favorite.filter(function (i) { return core.hasSave(i); });
- core.saves.favoriteName = core.getLocalStorage("favoriteName", {});
-}
-
-control.prototype._updateFavoriteSaves = function () {
- core.setLocalStorage("favorite", core.saves.favorite);
- core.setLocalStorage("favoriteName", core.saves.favoriteName);
-}
-
-// ------ 属性,状态,位置,buff,变量,锁定控制等 ------ //
-
-////// 设置勇士属性 //////
-control.prototype.setStatus = function (name, value) {
- if (!core.status.hero) return;
- if (name == 'x' || name == 'y' || name == 'direction')
- this.setHeroLoc(name, value);
- else
- core.status.hero[name] = value;
-}
-
-////// 增减勇士属性 //////
-control.prototype.addStatus = function (name, value) {
- this.setStatus(name, this.getStatus(name) + value);
-}
-
-////// 获得勇士属性 //////
-control.prototype.getStatus = function (name) {
- if (!core.status.hero) return null;
- if (name == 'x' || name == 'y' || name == 'direction')
- return this.getHeroLoc(name);
- if (main.mode == 'editor' && !core.hasFlag('__statistics__')) {
- return data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.firstData.hero[name];
- }
- return core.status.hero[name];
-}
-
-////// 从status中获得属性,如果不存在则从勇士属性中获取 //////
-control.prototype.getStatusOrDefault = function (status, name) {
- if (status && name in status)
- return Math.floor(status[name]);
- return Math.floor(this.getStatus(name));
-}
-
-////// 获得勇士实际属性(增幅后的) //////
-control.prototype.getRealStatus = function (name) {
- return this.getRealStatusOrDefault(null, name);
-}
-
-////// 从status中获得实际属性(增幅后的),如果不存在则从勇士属性中获取 //////
-control.prototype.getRealStatusOrDefault = function (status, name) {
- return Math.floor(this.getStatusOrDefault(status, name) * this.getBuff(name));
-}
-
-////// 获得勇士原始属性(无装备和衰弱影响) //////
-control.prototype.getNakedStatus = function (name) {
- var value = this.getStatus(name);
- if (value == null) return value;
- // 装备增幅
- core.status.hero.equipment.forEach(function (v) {
- if (!v || !(core.material.items[v] || {}).equip) return;
- value -= core.material.items[v].equip.value[name] || 0;
- });
- // 衰弱扣除
- if (core.hasFlag('weak') && core.values.weakValue >= 1 && (name == 'atk' || name == 'def')) {
- value += core.values.weakValue;
- }
- return value;
-}
-
-////// 获得某个属性的名字 //////
-control.prototype.getStatusLabel = function (name) {
- if (this.controldata.getStatusLabel) {
- return this.controldata.getStatusLabel(name) || name;
- }
- return {
- name: "名称", lv: "等级", hpmax: "生命上限", hp: "生命", manamax: "魔力上限", mana: "魔力",
- atk: "攻击", def: "防御", mdef: "护盾", money: "金币", exp: "经验", point: "加点", steps: "步数"
- }[name] || name;
-}
-
-////// 设置某个属性的增幅值 //////
-control.prototype.setBuff = function (name, value) {
- // 仅保留三位有效buff值
- value = parseFloat(value.toFixed(3));
- this.setFlag('__' + name + '_buff__', value);
-}
-
-////// 加减某个属性的增幅值 //////
-control.prototype.addBuff = function (name, value) {
- var buff = this.getBuff(name) + value;
- // 仅保留三位有效buff值
- buff = parseFloat(buff.toFixed(3));
- this.setFlag('__' + name + '_buff__', buff);
-}
-
-////// 获得某个属性的增幅值 //////
-control.prototype.getBuff = function (name) {
- return core.getFlag('__' + name + '_buff__', 1);
-}
-
-////// 获得或移除毒衰咒效果 //////
-control.prototype.triggerDebuff = function (action, type) {
- return this.controldata.triggerDebuff(action, type);
-}
-
-////// 设置勇士的位置 //////
-control.prototype.setHeroLoc = function (name, value, noGather) {
- if (!core.status.hero) return;
- core.status.hero.loc[name] = value;
- if ((name == 'x' || name == 'y') && !noGather) {
- this.gatherFollowers();
- }
-}
-
-////// 获得勇士的位置 //////
-control.prototype.getHeroLoc = function (name) {
- if (!core.status.hero) return;
- if (main.mode == 'editor') {
- if (name == null) return data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.firstData.hero.loc;
- return data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.firstData.hero.loc[name];
- }
- if (name == null) return core.status.hero.loc;
- return core.status.hero.loc[name];
-}
-
-////// 获得某个等级的名称 //////
-control.prototype.getLvName = function (lv) {
- if (!core.status.hero) return null;
- if (lv == null) lv = core.status.hero.lv;
- return ((core.firstData.levelUp || [])[lv - 1] || {}).title || lv;
-}
-
-////// 获得下个等级所需经验;如果不存在下个等级,返回null。 //////
-control.prototype.getNextLvUpNeed = function () {
- if (!core.status.hero) return null;
- if (core.status.hero.lv >= core.firstData.levelUp.length) return null;
- var need = core.calValue(core.firstData.levelUp[core.status.hero.lv].need);
- if (core.flags.statusBarItems.indexOf('levelUpLeftMode') >= 0)
- return Math.max(need - core.getStatus('exp'), 0);
- else return need;
-}
-
-////// 设置某个自定义变量或flag //////
-control.prototype.setFlag = function (name, value) {
- if (value == null) return this.removeFlag(name);
- if (!core.status.hero) return;
- core.status.hero.flags[name] = value;
-}
-
-////// 增加某个flag数值 //////
-control.prototype.addFlag = function (name, value) {
- if (!core.status.hero) return;
- core.setFlag(name, core.getFlag(name, 0) + value);
-}
-
-////// 获得某个自定义变量或flag //////
-control.prototype.getFlag = function (name, defaultValue) {
- if (!core.status.hero) return defaultValue;
- var value = core.status.hero.flags[name];
- return value != null ? value : defaultValue;
-}
-
-////// 是否存在某个自定义变量或flag,且值为true //////
-control.prototype.hasFlag = function (name) {
- return !!core.getFlag(name);
-}
-
-////// 删除某个自定义变量或flag //////
-control.prototype.removeFlag = function (name) {
- if (!core.status.hero) return;
- delete core.status.hero.flags[name];
-}
-
-////// 获得某个点的独立开关 //////
-control.prototype.getSwitch = function (x, y, floorId, name, defaultValue) {
- var prefix = [floorId || core.status.floorId || ":f", x != null ? x : "x", y != null ? y : "y"].join("@");
- return this.getFlag(prefix + "@" + name, defaultValue);
-}
-
-////// 设置某个点的独立开关 //////
-control.prototype.setSwitch = function (x, y, floorId, name, value) {
- var prefix = [floorId || core.status.floorId || ":f", x != null ? x : "x", y != null ? y : "y"].join("@");
- return this.setFlag(prefix + "@" + name, value);
-}
-
-////// 增加某个点的独立开关 //////
-control.prototype.addSwitch = function (x, y, floorId, name, value) {
- var prefix = [floorId || core.status.floorId || ":f", x != null ? x : "x", y != null ? y : "y"].join("@");
- return this.addFlag(prefix + "@" + name, value);
-}
-
-////// 判定某个点的独立开关 //////
-control.prototype.hasSwitch = function (x, y, floorId, name) {
- var prefix = [floorId || core.status.floorId || ":f", x != null ? x : "x", y != null ? y : "y"].join("@");
- return this.hasFlag(prefix + "@" + name);
-}
-
-////// 删除某个点的独立开关 //////
-control.prototype.removeSwitch = function (x, y, floorId, name) {
- var prefix = [floorId || core.status.floorId || ":f", x != null ? x : "x", y != null ? y : "y"].join("@");
- return this.removeFlag(prefix + "@" + name);
-}
-
-////// 锁定状态栏,常常用于事件处理 //////
-control.prototype.lockControl = function () {
- core.status.lockControl = true;
-}
-
-////// 解锁状态栏 //////
-control.prototype.unlockControl = function () {
- core.status.lockControl = false;
-}
-
-////// 开启debug模式 //////
-control.prototype.debug = function () {
- core.setFlag('debug', true);
- core.drawText("\t[调试模式开启]此模式下按住Ctrl键(或Ctrl+Shift键)可以穿墙并忽略一切事件。\n此模式下将无法上传成绩。");
-}
-
-control.prototype._bindRoutePush = function () {
- core.status.route.push = function (element) {
- // 忽视移动、转向、瞬移
- if (["up", "down", "left", "right", "turn"].indexOf(element) < 0 && !element.startsWith("move:")) {
- core.clearRouteFolding();
- }
- Array.prototype.push.call(core.status.route, element);
- }
-}
-
-////// 清除录像折叠信息 //////
-control.prototype.clearRouteFolding = function () {
- core.status.routeFolding = {};
-}
-
-////// 检查录像折叠 //////
-control.prototype.checkRouteFolding = function () {
- // 未开启、未开始游戏、录像播放中、正在事件中:不执行
- if (!core.flags.enableRouteFolding || !core.isPlaying() || core.isReplaying() || core.status.event.id) {
- return this.clearRouteFolding();
- }
- var hero = core.clone(core.status.hero, function (name, value) {
- return name != 'steps' && typeof value == 'number';
- });
- var index = [core.getHeroLoc('x'), core.getHeroLoc('y'), core.getHeroLoc('direction').charAt(0)].join(',');
- core.status.routeFolding = core.status.routeFolding || {};
- if (core.status.routeFolding[index]) {
- var one = core.status.routeFolding[index];
- if (core.same(one.hero, hero) && one.length < core.status.route.length) {
- Object.keys(core.status.routeFolding).forEach(function (v) {
- if (core.status.routeFolding[v].length >= one.length) delete core.status.routeFolding[v];
- });
- core.status.route = core.status.route.slice(0, one.length);
- this._bindRoutePush();
- }
- }
- core.status.routeFolding[index] = { hero: hero, length: core.status.route.length };
-}
-
-// ------ 天气,色调,BGM ------ //
-
-control.prototype.getMappedName = function (name) {
- return core.getFlag('__nameMap__', {})[name] || (main.nameMap || {})[name] || name;
-}
-
-////// 更改天气效果 //////
-control.prototype.setWeather = function (type, level) {
- // 非雨雪
- if (type == null || !this.weathers[type]) {
- core.deleteCanvas('weather')
- core.animateFrame.weather.type = null;
- core.animateFrame.weather.nodes = [];
- return;
- }
- if (level == null) level = core.animateFrame.weather.level;
- level = core.clamp(parseInt(level) || 5, 1, 10);
- // 当前天气:则忽略
- if (type == core.animateFrame.weather.type && level == core.animateFrame.weather.level) return;
-
- // 计算当前的宽高
- core.createCanvas('weather', 0, 0, core.__PIXELS__, core.__PIXELS__, 80);
- core.setOpacity('weather', 1.0);
- core.animateFrame.weather.type = type;
- core.animateFrame.weather.level = level;
- core.animateFrame.weather.nodes = [];
- try {
- core.doFunc(this.weathers[type].initFunc, this, level);
- } catch (e) {
- console.error(e);
- console.error("ERROR in weather[" + type + "]:已自动注销该项。");
- core.unregisterWeather(type);
- }
-}
-
-////// 注册一个天气 //////
-// name为天气类型,如 sun, rain, snow 等
-// initFunc 为设置为此天气时的初始化,接受level参数
-// frameFunc 为该天气下每帧的效果,接受和timestamp参数(从页面加载完毕到当前经过的时间)
-control.prototype.registerWeather = function (name, initFunc, frameFunc) {
- this.unregisterWeather(name);
- this.weathers[name] = { initFunc: initFunc, frameFunc: frameFunc };
-}
-
-////// 取消注册一个天气 //////
-control.prototype.unregisterWeather = function (name) {
- delete this.weathers[name];
- if (core.animateFrame.weather.type == name) {
- this.setWeather(null);
- }
-}
-
-control.prototype._weather_rain = function (level) {
- var number = level * parseInt(20 * core.bigmap.width * core.bigmap.height / (core.__SIZE__ * core.__SIZE__));
- for (var a = 0; a < number; a++) {
- core.animateFrame.weather.nodes.push({
- 'x': Math.random() * core.bigmap.width * 32,
- 'y': Math.random() * core.bigmap.height * 32,
- 'l': Math.random() * 2.5,
- 'xs': -4 + Math.random() * 4 + 2,
- 'ys': Math.random() * 10 + 10
- })
- }
-}
-
-control.prototype._weather_snow = function (level) {
- var number = level * parseInt(20 * core.bigmap.width * core.bigmap.height / (core.__SIZE__ * core.__SIZE__));
- for (var a = 0; a < number; a++) {
- core.animateFrame.weather.nodes.push({
- 'x': Math.random() * core.bigmap.width * 32,
- 'y': Math.random() * core.bigmap.height * 32,
- 'r': Math.random() * 5 + 1,
- 'd': Math.random() * Math.min(level, 200),
- })
- }
-}
-
-control.prototype._weather_fog = function (level) {
- if (!core.animateFrame.weather.fog) return;
- core.animateFrame.weather.nodes = [{
- 'image': core.animateFrame.weather.fog,
- 'level': 40 * level,
- 'x': 0,
- 'y': -core.__PIXELS__ / 2,
- 'dx': -Math.random() * 1.5,
- 'dy': Math.random(),
- 'delta': 0.001,
- }];
-}
-
-control.prototype._weather_cloud = function (level) {
- if (!core.animateFrame.weather.cloud) return;
- core.animateFrame.weather.nodes = [{
- 'image': core.animateFrame.weather.cloud,
- 'level': 40 * level,
- 'x': 0,
- 'y': -core.__PIXELS__ / 2,
- 'dx': -Math.random() * 1.5,
- 'dy': Math.random(),
- 'delta': 0.001,
- }];
-}
-
-control.prototype._weather_sun = function (level) {
- if (!core.animateFrame.weather.sun) return;
- // 直接绘制
- core.clearMap('weather');
- core.drawImage('weather', core.animateFrame.weather.sun, 0, 0, core.animateFrame.weather.sun.width, core.animateFrame.weather.sun.height, 0, 0, core.__PIXELS__, core.__PIXELS__);
- core.setOpacity('weather', level / 10);
- core.animateFrame.weather.nodes = [{ opacity: level / 10, delta: 0.01 }];
-}
-
-////// 更改画面色调 //////
-control.prototype.setCurtain = function (color, time, moveMode, callback) {
- if (time == null) time = 750;
- if (time <= 0) time = 0;
- if (!core.status.curtainColor)
- core.status.curtainColor = [0, 0, 0, 0];
- if (!color) color = [0, 0, 0, 0];
- if (color[3] == null) color[3] = 1;
- color[3] = core.clamp(color[3], 0, 1);
-
- if (time == 0) {
- // 直接变色
- core.clearMap('curtain');
- core.fillRect('curtain', 0, 0, core.__PIXELS__, core.__PIXELS__, core.arrayToRGBA(color));
- core.status.curtainColor = color;
- if (callback) callback();
- return;
- }
-
- this._setCurtain_animate(core.status.curtainColor, color, time, moveMode, callback);
-}
-
-control.prototype._setCurtain_animate = function (nowColor, color, time, moveMode, callback) {
- time /= Math.max(core.status.replay.speed, 1)
- var per_time = 10, step = 0, steps = parseInt(time / per_time);
- if (steps <= 0) steps = 1;
- var curr = nowColor;
- var moveFunc = core.applyEasing(moveMode);
-
- var cb = function () {
- core.status.curtainColor = curr;
- if (callback) callback();
- }
- var animate = setInterval(function () {
- step++;
- curr = [
- nowColor[0] + (color[0] - nowColor[0]) * moveFunc(step / steps),
- nowColor[1] + (color[1] - nowColor[1]) * moveFunc(step / steps),
- nowColor[2] + (color[2] - nowColor[2]) * moveFunc(step / steps),
- nowColor[3] + (color[3] - nowColor[3]) * moveFunc(step / steps),
- ]
- core.clearMap('curtain');
- core.fillRect('curtain', 0, 0, core.__PIXELS__, core.__PIXELS__, core.arrayToRGBA(curr));
- if (step == steps) {
- delete core.animateFrame.asyncId[animate];
- clearInterval(animate);
- cb();
- }
- }, per_time);
-
- core.animateFrame.lastAsyncId = animate;
- core.animateFrame.asyncId[animate] = cb;
-}
-
-////// 画面闪烁 //////
-control.prototype.screenFlash = function (color, time, times, moveMode, callback) {
- times = times || 1;
- time = time / 3;
- var nowColor = core.clone(core.status.curtainColor);
- core.setCurtain(color, time, moveMode, function () {
- core.setCurtain(nowColor, time * 2, moveMode, function () {
- if (times > 1)
- core.screenFlash(color, time * 3, times - 1, moveMode, callback);
- else {
- if (callback) callback();
- }
- });
- });
-}
-
-////// 播放背景音乐 //////
-control.prototype.playBgm = function (bgm, startTime) {
- bgm = core.getMappedName(bgm);
- if (main.mode != 'play' || !core.material.bgms[bgm]) return;
- // 如果不允许播放
- if (!core.musicStatus.bgmStatus) {
- try {
- core.musicStatus.playingBgm = bgm;
- core.musicStatus.lastBgm = bgm;
- core.material.bgms[bgm].pause();
- }
- catch (e) {
- console.error(e);
- }
- return;
- }
- this.setMusicBtn();
-
- try {
- this._playBgm_play(bgm, startTime);
- }
- catch (e) {
- console.log("无法播放BGM " + bgm);
- console.error(e);
- core.musicStatus.playingBgm = null;
- }
-}
-
-control.prototype._playBgm_play = function (bgm, startTime) {
- // 如果当前正在播放,且和本BGM相同,直接忽略
- if (core.musicStatus.playingBgm == bgm && !core.material.bgms[core.musicStatus.playingBgm].paused) {
- return;
- }
- // 如果正在播放中,暂停
- if (core.musicStatus.playingBgm) {
- core.material.bgms[core.musicStatus.playingBgm].pause();
- }
- // 缓存BGM
- core.loader.loadBgm(bgm);
- // 播放当前BGM
- core.material.bgms[bgm].volume = core.musicStatus.userVolume * core.musicStatus.designVolume;
- core.material.bgms[bgm].currentTime = startTime || 0;
- core.material.bgms[bgm].play();
- core.musicStatus.playingBgm = bgm;
- core.musicStatus.lastBgm = bgm;
- core.setBgmSpeed(100);
-}
-
-///// 设置当前背景音乐的播放速度 //////
-control.prototype.setBgmSpeed = function (speed, usePitch) {
- var bgm = core.musicStatus.playingBgm;
- if (main.mode != 'play' || !core.material.bgms[bgm]) return;
- bgm = core.material.bgms[bgm];
- if (speed < 30 || speed > 300) return;
- bgm.playbackRate = speed / 100;
- core.musicStatus.bgmSpeed = speed;
-
- if (bgm.preservesPitch != null) {
- if (bgm.__preservesPitch == null) bgm.__preservesPitch = bgm.preservesPitch;
- if (usePitch == null) bgm.preservesPitch = bgm.__preservesPitch;
- else if (usePitch) bgm.preservesPitch = false;
- else bgm.preservesPitch = true;
- core.musicStatus.bgmUsePitch = usePitch;
- }
-}
-
-////// 暂停背景音乐的播放 //////
-control.prototype.pauseBgm = function () {
- if (main.mode != 'play') return;
- try {
- if (core.musicStatus.playingBgm) {
- core.musicStatus.pauseTime = core.material.bgms[core.musicStatus.playingBgm].currentTime;
- core.material.bgms[core.musicStatus.playingBgm].pause();
- core.musicStatus.playingBgm = null;
- }
- }
- catch (e) {
- console.log("无法暂停BGM");
- console.error(e);
- }
- this.setMusicBtn();
-}
-
-////// 恢复背景音乐的播放 //////
-control.prototype.resumeBgm = function (resumeTime) {
- if (main.mode != 'play') return;
- try {
- var speed = core.musicStatus.bgmSpeed;
- var usePitch = core.musicStatus.bgmUsePitch;
- core.playBgm(core.musicStatus.playingBgm || core.musicStatus.lastBgm || main.startBgm,
- resumeTime ? core.musicStatus.pauseTime : 0);
- if (resumeTime) {
- core.setBgmSpeed(speed, usePitch);
- }
- }
- catch (e) {
- console.log("无法恢复BGM");
- console.error(e);
- }
- this.setMusicBtn();
-}
-
-control.prototype.setMusicBtn = function () {
- if (core.musicStatus.bgmStatus)
- core.dom.musicBtn.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAMAAADzN3VRAAABWVBMVEX///9iYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmL///8AAAC5ubn+/v6xsbEtLS0MDAxmZmZoaGhvb2/c3Nzd3d38/Pz9/f0oKCgpKSl0dHR1dXW6urrb29v7+/v09PTv7+/39/cgICACAgImJibh4eGFhYWGhoaHh4eOjo5paWm7u7vDw8PMzMwyMjI7OztAQEDe3t5FRUVMTEzj4+Pl5eXm5ubp6enr6+tcXFzi4uL19fVeXl74+PgjIyNkZGQGBgaSkpKYmJiampqenp4DAwMwMDBnZ2cICAivr68eHh63t7cLCwsSEhLw8PBhYWEUFBQVFRXNzc3Pz8/Z2dna2toaGhqkpKSlpaWpqamrq6tFOUNAAAAAc3RSTlMAAwQFBhUWGxwkJSYyO0dISVBRUmpvj5CSk5SVoaOlpqiysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKyA0IuUgAAAVdJREFUeF5NkVVbw0AQRTcQrLR4IIEGcidJoaUuQHF3d3d3+P/CkuxCzss8nG++mbnDBJXhNt2CpbeFK1kQpSEKidlc8S9qdATRa6UIdQMoxEpDA0Ov3wUAPfW+qLWACydNv9zMrzkJwPK6FB3oHyOfXfuNxvoBQ+GmBYinhHB77TmiVBxoYUw1AYcEq332AS8OYKosAuTT0nza9uU2USYPRJgGxEiSOFywJ3mNARozgBJJzkfLvfu8JgGDWcC9FEsjWzR+y80gYDEAA8QZ3N6kmP1Fs3fEASB7pob7Hh+Wz5L0ci17Or05J7bH6B6dZv05XWK3rG+myV05Ert592Qo55sPuoIr7hEZHHtieIPWy0RU9DLwc3Mnck/vi8/E8XNrDWQtEVnL/ySKMrv0jPwPp870fprcyYifmiEmqGpHkI5q9ofSFIUk2qiwIGpEMyxYhhZRRcMPz89RJ2s9W8wAAAAASUVORK5CYII=";
- else
- core.dom.musicBtn.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAMAAADzN3VRAAABYlBMVEX///9iYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmL////8/PwAAABmZmZoaGihoaGioqKxsbG5ubnb29vc3Nzd3d3h4eHi4uL9/f3+/v4tLS1nZ2d0dHSUlJSenp66uroMDAz7+/spKSkoKCgUFBRpaWkVFRVvb291dXU7OzuVlZWYmJhkZGQgICAjIyOkpKQCAgK3t7cGBgbv7++pqamrq6seHh4mJiZhYWGamprp6enr6+saGhpeXl7j4+Pl5eXm5uZKSkrw8PD09PT19fW7u7vDw8PMzMwICAgwMDAyMjILCwtAQECGhoaHh4eBgYGFhYUSEhJXV1dZWVlcXFyOjo6SkpLNzc339/fPz8/Z2dna2tqTk5OlpaWxOPeTAAAAdnRSTlMAAwQFBhUWGxwkJSYyO0dISVBRUmpvj5CSk5SVoaOlpqiysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKyNuo+uwAAAWJJREFUeF5NkmV34zAQReUm7WbTuJBNunY3bvXGDjNTkZkZlpn5/9eR5FPfbzr3jGb0RkwRiMQMDm7EIgHmRxtLwMOaHHoQjwz4MUKeCM8AWMrmd7u7f/aXAMyOShHiQD1n04DtN5e5FMBFlSauIsm585dKi4CpuSYKJIv1tBDVmvOSqJgEoowFLSBHaQh10XHWiCgHWEGmAw2blPrvOK/KRJUGoLM4kCVSKrWz7HwgoiwQZyaQJ0+9PvxV23BNATAZB25IqX9b3+jTW9fcApwB6NLgUD5NY3mPXnwmFwBezff1ztzRFzTp94FXMy36HDuCa2RafdnnmZqtL818Gl9/qNnEeyrUk2aTPiKj3qMyWBVi/YSuWq5qiwxkbtX3vYWzdz/l8M0k8ERlvViiB1Ygslb7SbVtJezncj+Cx5bYaeGuonZqhZlieAp+no74/s5EAh6JcY35Cepxk4ObcT3IJPe/1lKsDpFCFQAAAABJRU5ErkJggg==";
-}
-
-////// 更改背景音乐的播放 //////
-control.prototype.triggerBgm = function () {
- if (main.mode != 'play') return;
-
- core.musicStatus.bgmStatus = !core.musicStatus.bgmStatus;
- if (core.musicStatus.bgmStatus)
- this.resumeBgm();
- else
- this.pauseBgm();
- core.setLocalStorage('bgmStatus', core.musicStatus.bgmStatus);
-}
-
-////// 播放音频 //////
-control.prototype.playSound = function (sound, pitch, callback) {
- sound = core.getMappedName(sound);
- if (main.mode != 'play' || !core.musicStatus.soundStatus || !core.material.sounds[sound]) return;
- try {
- if (core.musicStatus.audioContext != null) {
- var source = core.musicStatus.audioContext.createBufferSource();
- source.__name = sound;
- source.buffer = core.material.sounds[sound];
- source.connect(core.musicStatus.gainNode);
- var id = setTimeout(null);
- if (pitch && pitch >= 30 && pitch <= 300) {
- source.playbackRate.setValueAtTime(pitch / 100, 0);
- }
- source.onended = function () {
- delete core.musicStatus.playingSounds[id];
- if (callback) callback();
- }
- core.musicStatus.playingSounds[id] = source;
- if (source.start) source.start(0);
- else if (source.noteOn) source.noteOn(0);
- return id;
- }
- else {
- core.material.sounds[sound].volume = core.musicStatus.userVolume;
- core.material.sounds[sound].play();
- if (callback) callback();
- }
- }
- catch (e) {
- console.log("无法播放SE " + sound);
- console.error(e);
- }
-}
-
-////// 停止所有音频 //////
-control.prototype.stopSound = function (id) {
- if (id == null) {
- Object.keys(core.musicStatus.playingSounds).forEach(function (id) {
- core.control.stopSound(id);
- });
- return;
- }
- var source = core.musicStatus.playingSounds[id];
- if (!source) return;
- try {
- if (source.stop) source.stop();
- else if (source.noteOff) source.noteOff();
- }
- catch (e) {
- console.error(e);
- }
- delete core.musicStatus.playingSounds[id];
-}
-
-////// 获得当前正在播放的所有(指定)音效的id列表 //////
-control.prototype.getPlayingSounds = function (name) {
- name = core.getMappedName(name);
- return Object.keys(core.musicStatus.playingSounds).filter(function (one) {
- return name == null || core.musicStatus.playingSounds[one].__name == name
- });
-}
-
-////// 检查bgm状态 //////
-control.prototype.checkBgm = function () {
- core.playBgm(core.musicStatus.playingBgm || main.startBgm);
-}
-
-///// 设置屏幕放缩 //////
-control.prototype.setDisplayScale = function (delta) {
- var index = core.domStyle.availableScale.indexOf(core.domStyle.scale);
- if (index < 0) return;
- index = (index + delta + core.domStyle.availableScale.length) % core.domStyle.availableScale.length;
- core.domStyle.scale = core.domStyle.availableScale[index];
- core.setLocalStorage('scale', core.domStyle.scale);
- core.resize();
-}
-
-// ------ 状态栏,工具栏等相关 ------ //
-
-////// 清空状态栏 //////
-control.prototype.clearStatusBar = function () {
- Object.keys(core.statusBar).forEach(function (e) {
- if (core.statusBar[e].innerHTML != null) {
- core.statusBar[e].innerHTML = " ";
- core.statusBar[e].removeAttribute('_style');
- core.statusBar[e].removeAttribute('_value');
- }
- })
- core.statusBar.image.book.style.opacity = 0.3;
- if (!core.flags.equipboxButton)
- core.statusBar.image.fly.style.opacity = 0.3;
-}
-
-////// 更新状态栏 //////
-control.prototype.updateStatusBar = function (doNotCheckAutoEvents, immediate) {
- if (immediate) {
- return this.updateStatusBar_update();
- }
- if (!doNotCheckAutoEvents) this.noAutoEvents = false;
- if (core.isReplaying()) return this.updateStatusBar_update();
- requestAnimationFrame(this.updateStatusBar_update)
-}
-
-control.prototype.updateStatusBar_update = function () {
- 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;
-}
-
-control.prototype._updateStatusBar_setToolboxIcon = function () {
- if (core.isReplaying()) {
- core.statusBar.image.book.src = core.status.replay.pausing ? core.statusBar.icons.play.src : core.statusBar.icons.pause.src;
- core.statusBar.image.book.style.opacity = 1;
- core.statusBar.image.fly.src = core.statusBar.icons.stop.src;
- core.statusBar.image.fly.style.opacity = 1;
- core.statusBar.image.toolbox.src = core.statusBar.icons.rewind.src;
- core.statusBar.image.keyboard.src = core.statusBar.icons.book.src;
- core.statusBar.image.shop.src = core.statusBar.icons.floor.src;
- core.statusBar.image.save.src = core.statusBar.icons.speedDown.src;
- core.statusBar.image.save.style.opacity = 1;
- core.statusBar.image.load.src = core.statusBar.icons.speedUp.src;
- core.statusBar.image.settings.src = core.statusBar.icons.save.src;
- }
- else {
- core.statusBar.image.book.src = core.statusBar.icons.book.src;
- core.statusBar.image.book.style.opacity = core.hasItem('book') ? 1 : 0.3;
- if (!core.flags.equipboxButton) {
- core.statusBar.image.fly.src = core.statusBar.icons.fly.src;
- core.statusBar.image.fly.style.opacity = core.hasItem('fly') ? 1 : 0.3;
- }
- else {
- core.statusBar.image.fly.src = core.statusBar.icons.equipbox.src;
- core.statusBar.image.fly.style.opacity = 1;
- }
- core.statusBar.image.toolbox.src = core.statusBar.icons.toolbox.src;
- core.statusBar.image.keyboard.src = core.statusBar.icons.keyboard.src;
- core.statusBar.image.shop.src = core.statusBar.icons.shop.src;
- core.statusBar.image.save.src = core.statusBar.icons.save.src;
- core.statusBar.image.save.style.opacity = core.hasFlag('__forbidSave__') ? 0.3 : 1;
- core.statusBar.image.load.src = core.statusBar.icons.load.src;
- core.statusBar.image.settings.src = core.statusBar.icons.settings.src;
- }
-}
-
-control.prototype.showStatusBar = function () {
- if (main.mode == 'editor') return;
- if (core.domStyle.showStatusBar) return;
- var statusItems = core.dom.status;
- core.domStyle.showStatusBar = true;
- core.removeFlag('hideStatusBar');
- // 显示
- for (var i = 0; i < statusItems.length; ++i)
- statusItems[i].style.opacity = 1;
- this.setToolbarButton(false);
- 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;
-
- var statusItems = core.dom.status, toolItems = core.dom.tools;
- core.domStyle.showStatusBar = false;
- core.setFlag('hideStatusBar', true);
- core.setFlag('showToolbox', showToolbox || null);
- // 隐藏
- for (var i = 0; i < statusItems.length; ++i)
- statusItems[i].style.opacity = 0;
- 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';
- }
-}
-
-////// 更新状态栏的勇士图标 //////
-control.prototype.updateHeroIcon = function (name) {
- name = name || "hero.png";
- if (core.statusBar.icons.name == name) return;
- core.statusBar.icons.name = name;
-
- var image = core.material.images.hero;
- // 全身图
- var w = core.material.icons.hero.width || 32;
- var h = core.material.icons.hero.height || 48;
- var ratio = Math.min(w / h, 1), width = 32 * ratio, left = 16 - width / 2;
-
- var canvas = document.createElement("canvas");
- var ctx = canvas.getContext("2d");
- canvas.width = 32;
- canvas.height = 32;
- core.drawImage(ctx, image, 0, 0, w, h, left, 0, width, 32);
-
- core.statusBar.image.name.src = canvas.toDataURL("image/png");
-}
-
-////// 改变工具栏为按钮1-8 //////
-control.prototype.setToolbarButton = function (useButton) {
- if (!core.domStyle.showStatusBar) {
- // 隐藏状态栏时检查竖屏
- if (!core.domStyle.isVertical && !core.flags.extendToolbar) {
- for (var i = 0; i < core.dom.tools.length; ++i)
- core.dom.tools[i].style.display = 'none';
- return;
- }
- if (!core.hasFlag('showToolbox')) return;
- else core.dom.tools.hard.style.display = 'block';
- }
-
- if (useButton == null) useButton = core.domStyle.toolbarBtn;
- if ((!core.domStyle.isVertical && !core.flags.extendToolbar) || core.isReplaying()) useButton = false;
- core.domStyle.toolbarBtn = useButton;
-
- if (useButton) {
- ["book", "fly", "toolbox", "keyboard", "shop", "save", "load", "settings"].forEach(function (t) {
- core.statusBar.image[t].style.display = 'none';
- });
- ["btn1", "btn2", "btn3", "btn4", "btn5", "btn6", "btn7", "btn8"].forEach(function (t) {
- core.statusBar.image[t].style.display = 'block';
- })
- main.statusBar.image.btn8.style.filter = core.getLocalStorage('altKey') ? 'sepia(1) contrast(1.5)' : '';
- }
- else {
- ["btn1", "btn2", "btn3", "btn4", "btn5", "btn6", "btn7", "btn8"].forEach(function (t) {
- core.statusBar.image[t].style.display = 'none';
- });
- ["book", "fly", "toolbox", "save", "load", "settings"].forEach(function (t) {
- core.statusBar.image[t].style.display = 'block';
- });
- core.statusBar.image.keyboard.style.display
- = core.statusBar.image.shop.style.display
- = core.domStyle.isVertical || core.flags.extendToolbar ? "block" : "none";
- }
-}
-
-////// ------ resize处理 ------ //
-
-control.prototype._shouldDisplayStatus = function (id) {
- if (id == null) {
- var toDraw = [], status = core.dom.status;
- for (var i = 0; i < status.length; ++i) {
- var dom = core.dom.status[i], idCol = dom.id;
- if (idCol.indexOf("Col") != idCol.length - 3) continue;
- var id = idCol.substring(0, idCol.length - 3);
- if (!this._shouldDisplayStatus(id)) continue;
- toDraw.push(id);
- }
- return toDraw;
- }
- var obj = {};
- core.flags.statusBarItems.forEach(function (v) { obj[v] = true; })
- switch (id) {
- case 'floor': return obj.enableFloor;
- case 'name': return obj.enableName;
- case 'lv': return obj.enableLv;
- case 'hp': return obj.enableHP;
- case 'hpmax': return obj.enableHPMax;
- case 'mana': return obj.enableMana;
- case 'atk': return obj.enableAtk;
- case 'def': return obj.enableDef;
- case 'mdef': return obj.enableMDef;
- case 'money': return obj.enableMoney;
- case 'exp': return obj.enableExp && !obj.levelUpLeftMode;
- case 'up': return obj.enableLevelUp;
- case 'skill': return obj.enableSkill;
- case 'key': return obj.enableKeys;
- case 'pzf': return obj.enablePZF;
- case 'debuff': return obj.enableDebuff;
- default: return true;
- }
-}
-
-////// 注册一个resize函数 //////
-// name为名称,可供注销使用
-// func可以是一个函数,或者是插件中的函数名;可以接受obj参数,详见resize函数。
-control.prototype.registerResize = function (name, func) {
- this.unregisterResize(name);
- this.resizes.push({ name: name, func: func });
-}
-
-////// 注销一个resize函数 //////
-control.prototype.unregisterResize = function (name) {
- this.resizes = this.resizes.filter(function (b) { return b.name != name; });
-}
-
-control.prototype._doResize = function (obj) {
- for (var i in this.resizes) {
- try {
- if (core.doFunc(this.resizes[i].func, this, obj)) return true;
- } catch (e) {
- console.error(e);
- console.error("ERROR in resizes[" + this.resizes[i].name + "]:已自动注销该项。");
- this.unregisterResize(this.resizes[i].name);
- }
- }
- return false;
-}
-
-////// 屏幕分辨率改变后重新自适应 //////
-control.prototype.resize = function () {
- if (main.mode == 'editor') return;
- var clientWidth = main.dom.body.clientWidth, clientHeight = main.dom.body.clientHeight;
- var CANVAS_WIDTH = core.__PIXELS__, BAR_WIDTH = Math.round(core.__PIXELS__ * 0.31);
- var BORDER = 3;
- var extendToolbar = core.flags.extendToolbar;
-
- var horizontalMaxRatio = (clientHeight - 2 * BORDER - (extendToolbar ? BORDER : 0)) / (CANVAS_WIDTH + (extendToolbar ? 38 : 0));
-
- if (clientWidth - 3 * BORDER >= CANVAS_WIDTH + BAR_WIDTH || (clientWidth > clientHeight && horizontalMaxRatio < 1)) {
- // 横屏
- core.domStyle.isVertical = false;
-
- core.domStyle.availableScale = [];
- [1, 1.25, 1.5, 1.75, 2, 2.25, 2.5].forEach(function (v) {
- if (clientWidth - 3 * BORDER >= v * (CANVAS_WIDTH + BAR_WIDTH) && horizontalMaxRatio >= v) {
- core.domStyle.availableScale.push(v);
- }
- });
- if (core.domStyle.availableScale.indexOf(core.domStyle.scale) < 0) {
- core.domStyle.scale = Math.min(1, horizontalMaxRatio);
- }
- }
- else {
- // 竖屏
- core.domStyle.isVertical = true;
- core.domStyle.scale = Math.min((clientWidth - 2 * BORDER) / CANVAS_WIDTH);
- core.domStyle.availableScale = [];
- extendToolbar = false;
- }
-
- var statusDisplayArr = this._shouldDisplayStatus(), count = statusDisplayArr.length;
- var statusCanvas = core.flags.statusCanvas, statusCanvasRows = core.values.statusCanvasRowsOnMobile || 3;
- var col = statusCanvas ? statusCanvasRows : Math.ceil(count / 3);
- if (col > 5) {
- if (statusCanvas) alert("自绘状态栏的在竖屏下的行数应不超过5!");
- else alert("当前状态栏数目(" + count + ")大于15,请调整到不超过15以避免手机端出现显示问题。");
- }
- var globalAttribute = core.status.globalAttribute || core.initStatus.globalAttribute;
-
- var obj = {
- clientWidth: clientWidth,
- clientHeight: clientHeight,
- CANVAS_WIDTH: CANVAS_WIDTH,
- BORDER: BORDER,
- BAR_WIDTH: BAR_WIDTH,
- TOOLBAR_HEIGHT: 38,
- outerSize: CANVAS_WIDTH * core.domStyle.scale + 2 * BORDER,
- globalAttribute: globalAttribute,
- border: '3px ' + core.arrayToRGBA(globalAttribute.borderColor) + ' solid',
- statusDisplayArr: statusDisplayArr,
- count: count,
- col: col,
- statusBarHeightInVertical: core.domStyle.isVertical ? (32 * col + 6) * core.domStyle.scale + 2 * BORDER : 0,
- toolbarHeightInVertical: core.domStyle.isVertical ? 38 * core.domStyle.scale + 2 * BORDER : 0,
- extendToolbar: extendToolbar,
- is15x15: core.__SIZE__ == 15
- };
-
- this._doResize(obj);
- this.setToolbarButton();
- core.updateStatusBar();
-}
-
-control.prototype._resize_gameGroup = function (obj) {
- var startBackground = core.domStyle.isVertical ? (main.styles.startVerticalBackground || main.styles.startBackground) : main.styles.startBackground;
- if (main.dom.startBackground.getAttribute('__src__') != startBackground) {
- main.dom.startBackground.setAttribute('__src__', startBackground);
- main.dom.startBackground.src = startBackground;
- }
-
- var gameGroup = core.dom.gameGroup;
- var totalWidth, totalHeight;
- if (core.domStyle.isVertical) {
- totalWidth = obj.outerSize;
- totalHeight = obj.outerSize + obj.statusBarHeightInVertical + obj.toolbarHeightInVertical
- }
- else {
- totalWidth = obj.outerSize + obj.BAR_WIDTH * core.domStyle.scale + obj.BORDER;
- totalHeight = obj.outerSize + (obj.extendToolbar ? obj.TOOLBAR_HEIGHT * core.domStyle.scale + obj.BORDER : 0);
- }
- gameGroup.style.width = totalWidth + "px";
- gameGroup.style.height = totalHeight + "px";
- gameGroup.style.left = (obj.clientWidth - totalWidth) / 2 + "px";
- gameGroup.style.top = (obj.clientHeight - totalHeight) / 2 + "px";
- // floorMsgGroup
- var floorMsgGroup = core.dom.floorMsgGroup;
- floorMsgGroup.style = obj.globalAttribute.floorChangingStyle;
- floorMsgGroup.style.width = obj.outerSize - 2 * obj.BORDER + "px";
- floorMsgGroup.style.height = totalHeight - 2 * obj.BORDER + "px";
- floorMsgGroup.style.fontSize = 16 * core.domStyle.scale + "px";
- // startPanel
- core.dom.startPanel.style.fontSize = 16 * core.domStyle.scale + "px";
- // musicBtn
- if (core.domStyle.isVertical || core.domStyle.scale < 1) {
- core.dom.musicBtn.style.right = core.dom.musicBtn.style.bottom = "3px";
- }
- else {
- core.dom.musicBtn.style.right = (obj.clientWidth - totalWidth) / 2 + "px";
- core.dom.musicBtn.style.bottom = (obj.clientHeight - totalHeight) / 2 - 27 + "px";
- }
-}
-
-control.prototype._resize_canvas = function (obj) {
- var innerSize = (obj.CANVAS_WIDTH * core.domStyle.scale) + "px";
- if (!core.isPlaying()) {
- for (var i = 0; i < core.dom.gameCanvas.length; ++i) {
- var ctx = core.dom.gameCanvas[i].getContext('2d');
- core.resizeCanvas(ctx, core.__PIXELS__, core.__PIXELS__);
- core.dom.gameCanvas[i].style.width = core.dom.gameCanvas[i].style.height = innerSize;
- }
- } else {
- requestAnimationFrame(function () {
- for (var i = 0; i < core.dom.gameCanvas.length; ++i)
- core.dom.gameCanvas[i].style.width = core.dom.gameCanvas[i].style.height = innerSize;
- });
- }
- core.dom.gif.style.width = core.dom.gif.style.height = innerSize;
- core.dom.gif2.style.width = core.dom.gif2.style.height = innerSize;
- core.dom.gameDraw.style.width = core.dom.gameDraw.style.height = innerSize;
- core.dom.gameDraw.style.top = obj.statusBarHeightInVertical + "px";
- core.dom.gameDraw.style.right = 0;
- core.dom.gameDraw.style.border = obj.border;
- // resize bigmap
- core.bigmap.canvas.forEach(function (cn) {
- var ratio = core.canvas[cn].canvas.hasAttribute('isHD') ? core.domStyle.ratio : 1;
- core.canvas[cn].canvas.style.width = core.canvas[cn].canvas.width / ratio * core.domStyle.scale + "px";
- core.canvas[cn].canvas.style.height = core.canvas[cn].canvas.height / ratio * core.domStyle.scale + "px";
- });
- // resize dynamic canvas
- if (!core.isPlaying()) {
- for (var name in core.dymCanvas) {
- var ctx = core.dymCanvas[name], canvas = ctx.canvas;
- // core.maps._setHDCanvasSize(ctx, parseFloat(canvas.getAttribute('_width')), parseFloat(canvas.getAttribute('_height')));
- canvas.style.left = parseFloat(canvas.getAttribute("_left")) * core.domStyle.scale + "px";
- canvas.style.top = parseFloat(canvas.getAttribute("_top")) * core.domStyle.scale + "px";
- var scale = canvas.getAttribute('_scale') || 1;
- core.resizeCanvas(canvas, canvas.width * scale / core.domStyle.scale, canvas.height * scale / core.domStyle.scale);
- }
- } else {
- for (var name in core.dymCanvas) {
- var ctx = core.dymCanvas[name], canvas = ctx.canvas;
- var ratio = canvas.hasAttribute('isHD') ? core.domStyle.ratio : 1;
- canvas.style.width = canvas.width / ratio * core.domStyle.scale + "px";
- canvas.style.height = canvas.height / ratio * core.domStyle.scale + "px";
- canvas.style.left = parseFloat(canvas.getAttribute("_left")) * core.domStyle.scale + "px";
- canvas.style.top = parseFloat(canvas.getAttribute("_top")) * core.domStyle.scale + "px";
- }
- }
- // resize next
- main.dom.next.style.width = main.dom.next.style.height = 5 * core.domStyle.scale + "px";
- main.dom.next.style.borderBottomWidth = main.dom.next.style.borderRightWidth = 4 * core.domStyle.scale + "px";
-}
-
-control.prototype._resize_statusBar = function (obj) {
- // statusBar
- var statusBar = core.dom.statusBar;
- if (core.domStyle.isVertical) {
- statusBar.style.width = obj.outerSize + "px";
- statusBar.style.height = obj.statusBarHeightInVertical + "px";
- statusBar.style.background = obj.globalAttribute.statusTopBackground;
- statusBar.style.fontSize = 16 * core.domStyle.scale + "px";
- }
- else {
- statusBar.style.width = (obj.BAR_WIDTH * core.domStyle.scale + obj.BORDER) + "px";
- statusBar.style.height = obj.outerSize + (obj.extendToolbar ? obj.TOOLBAR_HEIGHT * core.domStyle.scale + obj.BORDER : 0) + "px";
- statusBar.style.background = obj.globalAttribute.statusLeftBackground;
- // --- 计算文字大小
- if (obj.extendToolbar) {
- statusBar.style.fontSize = 16 * core.domStyle.scale + "px";
- } else {
- statusBar.style.fontSize = 16 * Math.min(1, (core.__HALF_SIZE__ + 3) / obj.count) * core.domStyle.scale + "px";
- }
- }
- statusBar.style.display = 'block';
- statusBar.style.borderTop = statusBar.style.borderLeft = obj.border;
- statusBar.style.borderRight = core.domStyle.isVertical ? obj.border : '';
- statusBar.style.borderBottom = core.domStyle.isVertical ? '' : obj.border;
- // 自绘状态栏
- if (core.domStyle.isVertical) {
- core.dom.statusCanvas.style.width = obj.CANVAS_WIDTH * core.domStyle.scale + "px";
- core.dom.statusCanvas.style.height = obj.statusBarHeightInVertical - 3 + "px";
- core.maps._setHDCanvasSize(core.dom.statusCanvasCtx, obj.CANVAS_WIDTH, obj.col * 32 + 9);
- }
- else {
- core.dom.statusCanvas.style.width = obj.BAR_WIDTH * core.domStyle.scale + "px";
- core.dom.statusCanvas.style.height = obj.outerSize - 2 * obj.BORDER + (obj.extendToolbar ? obj.TOOLBAR_HEIGHT * core.domStyle.scale + obj.BORDER : 0) + "px";
- core.maps._setHDCanvasSize(core.dom.statusCanvasCtx, obj.BAR_WIDTH, obj.CANVAS_WIDTH + (obj.extendToolbar ? obj.TOOLBAR_HEIGHT + obj.BORDER : 0));
- }
- core.dom.statusCanvas.style.display = core.flags.statusCanvas ? "block" : "none";
-}
-
-control.prototype._resize_status = function (obj) {
- var statusHeight;
- if (core.domStyle.isVertical) {
- statusHeight = 32 * core.domStyle.scale * 0.8;
- } else {
- statusHeight = (obj.extendToolbar ? core.__SIZE__ : core.__HALF_SIZE__ + 3) / obj.count * 32 * core.domStyle.scale * 0.8;
- }
- // status
- for (var i = 0; i < core.dom.status.length; ++i) {
- var id = core.dom.status[i].id, style = core.dom.status[i].style;
- if (id.endsWith("Col")) id = id.substring(0, id.length - 3);
- style.display = core.flags.statusCanvas || obj.statusDisplayArr.indexOf(id) < 0 ? 'none' : 'block';
- style.margin = 3 * core.domStyle.scale + "px";
- style.height = statusHeight + "px";
- style.maxWidth = obj.BAR_WIDTH * core.domStyle.scale * (core.domStyle.isVertical ? 0.95 : 1) + obj.BORDER + "px";
- if (obj.is15x15 && !core.domStyle.isVertical)
- style.marginLeft = 11 * core.domStyle.scale + "px";
- }
- // statusLabels, statusTexts
- for (var i = 0; i < core.dom.statusLabels.length; ++i) {
- core.dom.statusLabels[i].style.lineHeight = statusHeight + "px";
- core.dom.statusLabels[i].style.marginLeft = 6 * core.domStyle.scale + "px";
- }
- for (var i = 0; i < core.dom.statusTexts.length; ++i) {
- core.dom.statusTexts[i].style.color = core.arrayToRGBA(obj.globalAttribute.statusBarColor);
- }
- // keys
- if (core.flags.statusBarItems.indexOf('enableGreenKey') >= 0) {
- core.dom.keyCol.style.fontSize = '0.75em';
- core.statusBar.greenKey.style.display = '';
- } else {
- core.dom.keyCol.style.fontSize = '';
- core.statusBar.greenKey.style.display = 'none';
- }
-}
-
-control.prototype._resize_toolBar = function (obj) {
- // toolBar
- var toolBar = core.dom.toolBar;
- if (core.domStyle.isVertical) {
- toolBar.style.left = 0;
- toolBar.style.right = "";
- toolBar.style.width = obj.outerSize + "px";
- toolBar.style.top = obj.statusBarHeightInVertical + obj.outerSize + "px";
- toolBar.style.height = obj.toolbarHeightInVertical + "px";
- toolBar.style.background = obj.globalAttribute.toolsBackground;
- }
- else {
- if (obj.extendToolbar) {
- toolBar.style.left = "";
- toolBar.style.right = 0;
- toolBar.style.width = obj.outerSize + "px";
- toolBar.style.top = obj.outerSize + "px";
- toolBar.style.height = obj.TOOLBAR_HEIGHT * core.domStyle.scale + obj.BORDER + "px";
- toolBar.style.background = obj.globalAttribute.toolsBackground;
- } else {
- toolBar.style.left = 0;
- toolBar.style.right = "";
- toolBar.style.width = obj.BAR_WIDTH * core.domStyle.scale + obj.BORDER + "px";
- toolBar.style.top = 0.718 * obj.outerSize + "px";
- toolBar.style.height = 0.281 * obj.outerSize + "px";
- toolBar.style.background = 'transparent';
- }
- }
- toolBar.style.borderLeft = obj.border;
- toolBar.style.borderRight = toolBar.style.borderBottom = core.domStyle.isVertical || obj.extendToolbar ? obj.border : '';
- toolBar.style.fontSize = 16 * core.domStyle.scale + "px";
-
- if (!core.domStyle.showStatusBar && !core.domStyle.isVertical && !obj.extendToolbar) {
- toolBar.style.display = 'none';
- } else {
- toolBar.style.display = 'block';
- }
-}
-
-control.prototype._resize_tools = function (obj) {
- var toolsHeight = 32 * core.domStyle.scale * ((core.domStyle.isVertical || obj.extendToolbar) && !obj.is15x15 ? 0.95 : 1);
- var toolsMarginLeft;
- if (core.domStyle.isVertical || obj.extendToolbar)
- toolsMarginLeft = (core.__HALF_SIZE__ - 3) * 3 * core.domStyle.scale;
- else
- toolsMarginLeft = (obj.BAR_WIDTH * core.domStyle.scale - 9 - toolsHeight * 3) / 4;
- for (var i = 0; i < core.dom.tools.length; ++i) {
- var style = core.dom.tools[i].style;
- style.height = toolsHeight + "px";
- style.marginLeft = toolsMarginLeft + "px";
- style.marginTop = 3 * core.domStyle.scale + "px"
- }
- core.dom.hard.style.lineHeight = toolsHeight + "px";
- if (core.domStyle.isVertical || obj.extendToolbar) {
- core.dom.hard.style.width = obj.outerSize - 9 * toolsMarginLeft - 8.5 * toolsHeight - 12 + "px";
- }
- else {
- core.dom.hard.style.width = obj.BAR_WIDTH * core.domStyle.scale - 9 - 2 * toolsMarginLeft + "px";
- if (!obj.is15x15) core.dom.hard.style.marginTop = 0;
- }
-}
+///
+
+/*
+control.js:游戏主要逻辑控制
+主要负责status相关内容,以及各种变量获取/存储
+寻路算法和人物行走也在此文件内
+ */
+
+"use strict";
+
+function control () {
+ this._init();
+}
+
+control.prototype._init = function () {
+ this.controldata = functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a.control;
+ this.renderFrameFuncs = [];
+ this.replayActions = [];
+ this.weathers = {};
+ this.resizes = [];
+ this.noAutoEvents = true;
+ // --- 注册系统的animationFrame
+ this.registerAnimationFrame("totalTime", false, this._animationFrame_totalTime);
+ this.registerAnimationFrame("autoSave", true, this._animationFrame_autoSave);
+ this.registerAnimationFrame("globalAnimate", true, this._animationFrame_globalAnimate);
+ this.registerAnimationFrame("animate", true, this._animationFrame_animate);
+ this.registerAnimationFrame("heroMoving", true, this._animationFrame_heroMoving);
+ this.registerAnimationFrame("weather", true, this._animationFrame_weather);
+ this.registerAnimationFrame("tip", true, this._animateFrame_tip);
+ this.registerAnimationFrame("parallelDo", false, this._animationFrame_parallelDo);
+ // --- 注册系统的天气
+ this.registerWeather("rain", this._weather_rain, this._animationFrame_weather_rain);
+ this.registerWeather("snow", this._weather_snow, this._animationFrame_weather_snow);
+ this.registerWeather("fog", this._weather_fog, this.__animateFrame_weather_image);
+ this.registerWeather("cloud", this._weather_cloud, this.__animateFrame_weather_image);
+ this.registerWeather("sun", this._weather_sun, this._animationFrame_weather_sun);
+ // --- 注册系统的replay
+ this.registerReplayAction("move", this._replayAction_move);
+ this.registerReplayAction("item", this._replayAction_item);
+ this.registerReplayAction("equip", this._replayAction_equip);
+ this.registerReplayAction("unEquip", this._replayAction_unEquip);
+ this.registerReplayAction("saveEquip", this._replayAction_saveEquip);
+ this.registerReplayAction("loadEquip", this._replayAction_loadEquip);
+ this.registerReplayAction("fly", this._replayAction_fly);
+ this.registerReplayAction("shop", this._replayAction_shop);
+ this.registerReplayAction("turn", this._replayAction_turn);
+ this.registerReplayAction("getNext", this._replayAction_getNext);
+ this.registerReplayAction("moveDirectly", this._replayAction_moveDirectly);
+ this.registerReplayAction("key", this._replayAction_key);
+ this.registerReplayAction("click", this._replayAction_click);
+ this.registerReplayAction("ignoreInput", this._replayAction_ignoreInput);
+ this.registerReplayAction("no", this._replayAction_no);
+ // --- 注册系统的resize
+ this.registerResize("gameGroup", this._resize_gameGroup);
+ this.registerResize("canvas", this._resize_canvas);
+ this.registerResize("statusBar", this._resize_statusBar);
+ this.registerResize("status", this._resize_status);
+ this.registerResize("toolBar", this._resize_toolBar);
+ this.registerResize("tools", this._resize_tools);
+}
+
+// ------ requestAnimationFrame 相关 ------ //
+
+////// 注册一个 animationFrame //////
+// name:名称,可用来作为注销使用;needPlaying:是否只在游戏运行时才执行(在标题界面不执行)
+// func:要执行的函数,或插件中的函数名;可接受timestamp(从页面加载完毕到当前所经过的时间)作为参数
+control.prototype.registerAnimationFrame = function (name, needPlaying, func) {
+ this.unregisterAnimationFrame(name);
+ this.renderFrameFuncs.push({ name: name, needPlaying: needPlaying, func: func });
+}
+
+////// 注销一个 animationFrame //////
+control.prototype.unregisterAnimationFrame = function (name) {
+ this.renderFrameFuncs = this.renderFrameFuncs.filter(function (x) { return x.name != name; });
+}
+
+////// 设置requestAnimationFrame //////
+control.prototype._setRequestAnimationFrame = function () {
+ this._checkRequestAnimationFrame();
+ core.animateFrame.totalTime = Math.max(core.animateFrame.totalTime, core.getLocalStorage('totalTime', 0));
+ var loop = function (timestamp) {
+ core.control.renderFrameFuncs.forEach(function (b) {
+ if (b.func) {
+ try {
+ if (core.isPlaying() || !b.needPlaying)
+ core.doFunc(b.func, core.control, timestamp);
+ }
+ catch (e) {
+ console.error(e);
+ console.error("ERROR in requestAnimationFrame[" + b.name + "]:已自动注销该项。");
+ core.unregisterAnimationFrame(b.name);
+ }
+ }
+ })
+ window.requestAnimationFrame(loop);
+ }
+ window.requestAnimationFrame(loop);
+}
+
+control.prototype._checkRequestAnimationFrame = function () {
+ (function () {
+ var lastTime = 0;
+ var vendors = ['webkit', 'moz'];
+ for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
+ window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];
+ window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || // Webkit中此取消方法的名字变了
+ window[vendors[x] + 'CancelRequestAnimationFrame'];
+ }
+
+ if (!window.requestAnimationFrame) {
+ window.requestAnimationFrame = function (callback, element) {
+ var currTime = new Date().getTime();
+ var timeToCall = Math.max(0, 16.7 - (currTime - lastTime));
+ var id = window.setTimeout(function () {
+ callback(currTime + timeToCall);
+ }, timeToCall);
+ lastTime = currTime + timeToCall;
+ return id;
+ };
+ }
+ if (!window.cancelAnimationFrame) {
+ window.cancelAnimationFrame = function (id) {
+ clearTimeout(id);
+ };
+ }
+ }());
+}
+
+control.prototype._animationFrame_totalTime = function (timestamp) {
+ core.animateFrame.totalTime += timestamp - core.animateFrame.totalTimeStart;
+ core.animateFrame.totalTimeStart = timestamp;
+ if (core.isPlaying()) {
+ core.status.hero.statistics.totalTime = core.animateFrame.totalTime;
+ core.status.hero.statistics.currTime += timestamp - (core.status.hero.statistics.start || timestamp);
+ core.status.hero.statistics.start = timestamp;
+ }
+}
+
+control.prototype._animationFrame_autoSave = function (timestamp) {
+ if (timestamp - core.saves.autosave.time <= 5000) return;
+ core.control.checkAutosave();
+ core.saves.autosave.time = timestamp;
+}
+
+control.prototype._animationFrame_globalAnimate = function (timestamp) {
+ if (timestamp - core.animateFrame.globalTime <= core.values.animateSpeed) return;
+ core.status.globalAnimateStatus++;
+ if (core.status.floorId) {
+ // Global Animate
+ core.status.globalAnimateObjs.forEach(function (block) {
+ core.drawBlock(block, core.status.globalAnimateStatus);
+ });
+
+ // Global floor images
+ core.maps._drawFloorImages(core.status.floorId, core.canvas.bg, 'bg', core.status.floorAnimateObjs || [], core.status.globalAnimateStatus);
+ core.maps._drawFloorImages(core.status.floorId, core.canvas.fg, 'fg', core.status.floorAnimateObjs || [], core.status.globalAnimateStatus);
+
+ // Global Autotile Animate
+ core.status.autotileAnimateObjs.forEach(function (block) {
+ core.maps._drawAutotileAnimate(block, core.status.globalAnimateStatus);
+ });
+
+ // Global hero animate
+ if ((core.status.hero || {}).animate && core.status.heroMoving == 0 && main.mode == 'play' && !core.status.preview.enabled) {
+ core.drawHero('stop', null, core.status.globalAnimateStatus);
+ }
+ }
+ // Box animate
+ core.drawBoxAnimate();
+ core.animateFrame.globalTime = timestamp;
+}
+
+control.prototype._animationFrame_animate = function (timestamp) {
+ if (timestamp - core.animateFrame.animateTime < 50 || !core.status.animateObjs || core.status.animateObjs.length == 0) return;
+ core.clearMap('animate');
+ // 更新帧
+ for (var i = 0; i < core.status.animateObjs.length; i++) {
+ var obj = core.status.animateObjs[i];
+ if (obj.index == obj.animate.frames.length) {
+ (function (callback) {
+ setTimeout(function () {
+ if (callback) callback();
+ });
+ })(obj.callback);
+ }
+ }
+ core.status.animateObjs = core.status.animateObjs.filter(function (obj) {
+ return obj.index < obj.animate.frames.length;
+ });
+ core.status.animateObjs.forEach(function (obj) {
+ if (obj.hero) {
+ core.maps._drawAnimateFrame('animate', obj.animate, core.status.heroCenter.px, core.status.heroCenter.py, obj.index++);
+ } else {
+ core.maps._drawAnimateFrame('animate', obj.animate, obj.centerX, obj.centerY, obj.index++);
+ }
+ });
+ core.animateFrame.animateTime = timestamp;
+}
+
+control.prototype._animationFrame_heroMoving = function (timestamp) {
+ if (core.status.heroMoving <= 0) return;
+ // 换腿
+ if (timestamp - core.animateFrame.moveTime > core.values.moveSpeed) {
+ core.animateFrame.leftLeg = !core.animateFrame.leftLeg;
+ core.animateFrame.moveTime = timestamp;
+ }
+ core.drawHero(core.animateFrame.leftLeg ? 'leftFoot' : 'rightFoot', 4 * core.status.heroMoving);
+}
+
+control.prototype._animationFrame_weather = function (timestamp) {
+ var weather = core.animateFrame.weather, type = weather.type;
+ if (!core.dymCanvas.weather || !core.control.weathers[type] || !core.control.weathers[type].frameFunc) return;
+ try {
+ core.doFunc(core.control.weathers[type].frameFunc, core.control, timestamp, core.animateFrame.weather.level);
+ } catch (e) {
+ console.error(e);
+ console.error("ERROR in weather[" + type + "]:已自动注销该项。");
+ core.unregisterWeather(type);
+ }
+}
+
+control.prototype._animationFrame_weather_rain = function (timestamp, level) {
+ if (timestamp - core.animateFrame.weather.time < 30) return;
+ var ctx = core.dymCanvas.weather, ox = core.bigmap.offsetX, oy = core.bigmap.offsetY;
+ core.clearMap('weather');
+ ctx.strokeStyle = 'rgba(174,194,224,0.8)';
+ ctx.lineWidth = 1;
+ ctx.lineCap = 'round';
+
+ core.animateFrame.weather.nodes.forEach(function (p) {
+ ctx.beginPath();
+ ctx.moveTo(p.x - ox, p.y - oy);
+ ctx.lineTo(p.x + p.l * p.xs - ox, p.y + p.l * p.ys - oy);
+ ctx.stroke();
+
+ p.x += p.xs;
+ p.y += p.ys;
+ if (p.x > core.bigmap.width * 32 || p.y > core.bigmap.height * 32) {
+ p.x = Math.random() * core.bigmap.width * 32;
+ p.y = -10;
+ }
+
+ });
+
+ ctx.fill();
+ core.animateFrame.weather.time = timestamp;
+}
+
+control.prototype._animationFrame_weather_snow = function (timestamp, level) {
+ if (timestamp - core.animateFrame.weather.time < 30) return;
+ var ctx = core.dymCanvas.weather, ox = core.bigmap.offsetX, oy = core.bigmap.offsetY;
+ core.clearMap('weather');
+ ctx.fillStyle = "rgba(255, 255, 255, 0.8)";
+ ctx.beginPath();
+ core.animateFrame.weather.data = core.animateFrame.weather.data || 0;
+ core.animateFrame.weather.data += 0.01;
+
+ var angle = core.animateFrame.weather.data;
+ core.animateFrame.weather.nodes.forEach(function (p) {
+ ctx.moveTo(p.x - ox, p.y - oy);
+ ctx.arc(p.x - ox, p.y - oy, p.r, 0, Math.PI * 2, true);
+ // update
+ p.x += Math.sin(angle) * core.animateFrame.weather.level;
+ p.y += Math.cos(angle + p.d) + 1 + p.r / 2;
+ if (p.x > core.bigmap.width * 32 + 5 || p.x < -5 || p.y > core.bigmap.height * 32) {
+ if (Math.random() > 1 / 3) {
+ p.x = Math.random() * core.bigmap.width * 32;
+ p.y = -10;
+ }
+ else {
+ if (Math.sin(angle) > 0)
+ p.x = -5;
+ else
+ p.x = core.bigmap.width * 32 + 5;
+ p.y = Math.random() * core.bigmap.height * 32;
+ }
+ }
+ });
+ ctx.fill();
+ core.animateFrame.weather.time = timestamp;
+}
+
+control.prototype.__animateFrame_weather_image = function (timestamp, level) {
+ if (timestamp - core.animateFrame.weather.time < 30) return;
+ var node = core.animateFrame.weather.nodes[0];
+ var image = node.image;
+ if (!image) return;
+ core.clearMap('weather');
+ core.setAlpha('weather', node.level / 500);
+ var wind = 1.5;
+ var width = image.width, height = image.height;
+ node.x += node.dx * wind;
+ node.y += (2 * node.dy - 1) * wind;
+ if (node.x + 3 * width <= core.__PIXELS__) {
+ node.x += 4 * width;
+ while (node.x > 0) node.x -= width;
+ }
+ node.dy += node.delta;
+ if (node.dy >= 1) {
+ node.delta = -0.001;
+ } else if (node.dy <= 0) {
+ node.delta = 0.001;
+ }
+ if (node.y + 3 * height <= core.__PIXELS__) {
+ node.y += 4 * height;
+ while (node.y > 0) node.y -= height;
+ }
+ else if (node.y >= 0) {
+ node.y -= height;
+ }
+ for (var i = 0; i < 3; ++i) {
+ for (var j = 0; j < 3; ++j) {
+ if (node.x + (i + 1) * width <= 0 || node.x + i * width >= core.__PIXELS__
+ || node.y + (j + 1) * height <= 0 || node.y + j * height >= core.__PIXELS__)
+ continue;
+ core.drawImage('weather', image, node.x + i * width, node.y + j * height);
+ }
+ }
+ core.setAlpha('weather', 1);
+ core.animateFrame.weather.time = timestamp;
+}
+
+control.prototype._animationFrame_weather_sun = function (timestamp, level) {
+ if (timestamp - core.animateFrame.weather.time < 30) return;
+ var node = core.animateFrame.weather.nodes[0];
+ var opacity = node.opacity + node.delta;
+ if (opacity > level / 10 + 0.3 || opacity < level / 10 - 0.3)
+ node.delta = -node.delta;
+ node.opacity = opacity;
+ core.setOpacity('weather', core.clamp(opacity, 0, 1));
+ core.animateFrame.weather.time = timestamp;
+}
+
+control.prototype._animateFrame_tip = function (timestamp) {
+ if (core.animateFrame.tip == null) return;
+ var tip = core.animateFrame.tip;
+ if (timestamp - tip.time <= 30) return;
+ var delta = timestamp - tip.time;
+ tip.time = timestamp;
+
+ core.setFont('data', "16px Arial");
+ core.setTextAlign('data', 'left');
+ core.clearMap('data', 0, 0, core.__PIXELS__, 50);
+ core.ui._drawTip_drawOne(tip);
+ if (tip.stage == 1) {
+ tip.opacity += 0.05;
+ if (tip.opacity >= 0.6) {
+ tip.stage = 2;
+ tip.displayTime = 0;
+ }
+ } else if (tip.stage == 2) {
+ tip.displayTime += delta;
+ if (tip.displayTime >= 1000) tip.stage = 3;
+ } else tip.opacity -= 0.05;
+
+ if (tip.opacity <= 0) {
+ core.animateFrame.tip = null;
+ }
+}
+
+control.prototype._animationFrame_parallelDo = function (timestamp) {
+ core.control.controldata.parallelDo(timestamp);
+}
+
+// ------ 标题界面的处理 ------ //
+
+////// 显示游戏开始界面 //////
+control.prototype.showStartAnimate = function (noAnimate, callback) {
+ this._showStartAnimate_resetDom();
+ if (core.flags.startUsingCanvas || noAnimate)
+ return this._showStartAnimate_finished(core.flags.startUsingCanvas, callback);
+ core.hideWithAnimate(core.dom.startTop, 20, function () {
+ core.control._showStartAnimate_finished(false, callback);
+ });
+}
+
+control.prototype._showStartAnimate_resetDom = function () {
+ core.dom.startPanel.style.opacity = 1;
+ core.dom.startPanel.style.display = "block";
+ core.dom.startTop.style.opacity = 1;
+ core.dom.startTop.style.display = "block";
+ core.dom.startButtonGroup.style.display = 'none';
+ core.dom.startButtons.style.display = 'block';
+ core.dom.levelChooseButtons.style.display = 'none';
+ core.status.played = false;
+ core.clearStatus();
+ core.clearMap('all');
+ core.dom.musicBtn.style.display = 'block';
+ core.setMusicBtn();
+ // 重置音量
+ core.events.setVolume(1, 0);
+ core.updateStatusBar();
+}
+
+control.prototype._showStartAnimate_finished = function (start, callback) {
+ core.dom.startTop.style.display = 'none';
+ core.dom.startButtonGroup.style.display = 'block';
+ main.selectedButton = null;
+ main.selectButton(0);
+ if (start) core.startGame();
+ if (callback) callback();
+}
+
+////// 隐藏游戏开始界面 //////
+control.prototype.hideStartAnimate = function (callback) {
+ core.hideWithAnimate(core.dom.startPanel, 20, callback);
+}
+
+////// 游戏是否已经开始 //////
+control.prototype.isPlaying = function () {
+ return core.status.played;
+}
+
+////// 清除游戏状态和数据 //////
+control.prototype.clearStatus = function () {
+ // 停止各个Timeout和Interval
+ for (var i in core.timeout) {
+ clearTimeout(core.timeout[i]);
+ core.timeout[i] = null;
+ }
+ for (var i in core.interval) {
+ clearInterval(core.interval[i]);
+ core.interval[i] = null;
+ }
+ core.status = {};
+ core.clearStatusBar();
+ core.deleteAllCanvas();
+ core.status.played = false;
+}
+
+control.prototype._initStatistics = function (totalTime) {
+ if (!core.isset(core.status.hero.statistics))
+ core.status.hero.statistics = {
+ 'totalTime': totalTime,
+ 'currTime': 0,
+ 'hp': 0,
+ "battle": 0,
+ 'money': 0,
+ 'exp': 0,
+ 'battleDamage': 0,
+ 'poisonDamage': 0,
+ 'extraDamage': 0,
+ 'moveDirectly': 0,
+ 'ignoreSteps': 0,
+ }
+}
+
+// ------ 自动寻路,人物行走 ------ //
+
+////// 清除自动寻路路线 //////
+control.prototype.clearAutomaticRouteNode = function (x, y) {
+ core.clearMap('route', x * 32 + 5 - core.status.automaticRoute.offsetX, y * 32 + 5 - core.status.automaticRoute.offsetY, 27, 27);
+}
+
+////// 停止自动寻路操作 //////
+control.prototype.stopAutomaticRoute = function () {
+ if (!core.status.played) return;
+ core.status.automaticRoute.autoHeroMove = false;
+ core.status.automaticRoute.autoStep = 0;
+ core.status.automaticRoute.destStep = 0;
+ core.status.automaticRoute.movedStep = 0;
+ core.status.automaticRoute.autoStepRoutes = [];
+ core.status.automaticRoute.destX = null;
+ core.status.automaticRoute.destY = null;
+ core.status.automaticRoute.lastDirection = null;
+ core.status.heroStop = true;
+ if (core.status.automaticRoute.moveStepBeforeStop.length == 0)
+ core.deleteCanvas('route');
+}
+
+////// 保存剩下的寻路,并停止 //////
+control.prototype.saveAndStopAutomaticRoute = function () {
+ var automaticRoute = core.status.automaticRoute;
+ if (automaticRoute.moveStepBeforeStop.length == 0) {
+ automaticRoute.moveStepBeforeStop = automaticRoute.autoStepRoutes.slice(automaticRoute.autoStep - 1);
+ if (automaticRoute.moveStepBeforeStop.length >= 1)
+ automaticRoute.moveStepBeforeStop[0].step -= automaticRoute.movedStep;
+ }
+ this.stopAutomaticRoute();
+}
+
+////// 继续剩下的自动寻路操作 //////
+control.prototype.continueAutomaticRoute = function () {
+ // 此函数只应由events.afterOpenDoor和events.afterBattle调用
+ var moveStep = core.status.automaticRoute.moveStepBeforeStop;
+ //core.status.automaticRoute.moveStepBeforeStop = [];
+ if (moveStep.length === 0 || (moveStep.length === 1 && moveStep[0].step === 1)) {
+ core.status.automaticRoute.moveStepBeforeStop = [];
+ }
+ else {
+ core.setAutoHeroMove(moveStep);
+ }
+}
+
+////// 清空剩下的自动寻路列表 //////
+control.prototype.clearContinueAutomaticRoute = function (callback) {
+ core.deleteCanvas('route');
+ core.status.automaticRoute.moveStepBeforeStop = [];
+ if (callback) callback();
+}
+
+////// 设置自动寻路路线 //////
+control.prototype.setAutomaticRoute = function (destX, destY, stepPostfix) {
+ if (!core.status.played || core.status.lockControl) return;
+ if (this._setAutomaticRoute_isMoving(destX, destY)) return;
+ if (this._setAutomaticRoute_isTurning(destX, destY, stepPostfix)) return;
+ if (this._setAutomaticRoute_clickMoveDirectly(destX, destY, stepPostfix)) return;
+ // 找寻自动寻路路线
+ var moveStep = core.automaticRoute(destX, destY);
+ if (moveStep.length == 0 && (destX != core.status.hero.loc.x || destY != core.status.hero.loc.y || stepPostfix.length == 0))
+ return;
+ moveStep = moveStep.concat(stepPostfix);
+ core.status.automaticRoute.destX = destX;
+ core.status.automaticRoute.destY = destY;
+ this._setAutomaticRoute_drawRoute(moveStep);
+ this._setAutomaticRoute_setAutoSteps(moveStep);
+ // 立刻移动
+ core.setAutoHeroMove();
+}
+
+control.prototype._setAutomaticRoute_isMoving = function (destX, destY) {
+ if (core.status.automaticRoute.autoHeroMove) {
+ var lastX = core.status.automaticRoute.destX, lastY = core.status.automaticRoute.destY;
+ core.stopAutomaticRoute();
+ // 双击瞬移
+ if (lastX == destX && lastY == destY) {
+ core.status.automaticRoute.moveDirectly = true;
+ setTimeout(function () {
+ if (core.status.automaticRoute.moveDirectly && core.status.heroMoving == 0) {
+ core.control.tryMoveDirectly(destX, destY);
+ }
+ core.status.automaticRoute.moveDirectly = false;
+ }, core.values.moveSpeed);
+ }
+ return true;
+ }
+ return false;
+}
+
+control.prototype._setAutomaticRoute_isTurning = function (destX, destY, stepPostfix) {
+ if (destX == core.status.hero.loc.x && destY == core.status.hero.loc.y && stepPostfix.length == 0) {
+ if (core.timeout.turnHeroTimeout == null) {
+ var routeLength = core.status.route.length;
+ core.timeout.turnHeroTimeout = setTimeout(function () {
+ if (core.status.route.length == routeLength) core.turnHero();
+ clearTimeout(core.timeout.turnHeroTimeout);
+ core.timeout.turnHeroTimeout = null;
+ }, 250);
+ }
+ else {
+ clearTimeout(core.timeout.turnHeroTimeout);
+ core.timeout.turnHeroTimeout = null;
+ core.getNextItem();
+ }
+ return true;
+ }
+ if (core.timeout.turnHeroTimeout != null) return true;
+ return false;
+}
+
+control.prototype._setAutomaticRoute_clickMoveDirectly = function (destX, destY, stepPostfix) {
+ // 单击瞬间移动
+ if (core.status.heroStop && core.status.heroMoving == 0) {
+ if (stepPostfix.length <= 1 && !core.hasFlag('__noClickMove__') && core.control.tryMoveDirectly(destX, destY))
+ return true;
+ }
+ return false;
+}
+
+control.prototype._setAutomaticRoute_drawRoute = function (moveStep) {
+ // 计算绘制区域的宽高,并尽可能小的创建route层
+ var sx = core.bigmap.width * 32, sy = core.bigmap.height * 32, dx = 0, dy = 0;
+ moveStep.forEach(function (t) {
+ sx = Math.min(sx, t.x * 32); dx = Math.max(dx, t.x * 32);
+ sy = Math.min(sy, t.y * 32); dy = Math.max(dy, t.y * 32);
+ });
+ core.status.automaticRoute.offsetX = sx;
+ core.status.automaticRoute.offsetY = sy;
+ var ctx = core.createCanvas('route', sx - core.bigmap.offsetX, sy - core.bigmap.offsetY, dx - sx + 32, dy - sy + 32, 95);
+ ctx.fillStyle = '#bfbfbf';
+ ctx.strokeStyle = '#bfbfbf';
+ ctx.lineWidth = 8;
+ for (var m = 0; m < moveStep.length; m++) {
+ if (m == moveStep.length - 1) {
+ ctx.fillRect(moveStep[m].x * 32 + 10 - sx, moveStep[m].y * 32 + 10 - sy, 12, 12);
+ }
+ else {
+ ctx.beginPath();
+ var cx = moveStep[m].x * 32 + 16 - sx, cy = moveStep[m].y * 32 + 16 - sy;
+ var currDir = moveStep[m].direction, nextDir = moveStep[m + 1].direction;
+ ctx.moveTo(cx - core.utils.scan[currDir].x * 11, cy - core.utils.scan[currDir].y * 11);
+ ctx.lineTo(cx, cy);
+ ctx.lineTo(cx + core.utils.scan[nextDir].x * 11, cy + core.utils.scan[nextDir].y * 11);
+ ctx.stroke();
+ }
+ }
+}
+
+control.prototype._setAutomaticRoute_setAutoSteps = function (moveStep) {
+ // 路线转autoStepRoutes
+ var step = 0, currStep = null;
+ moveStep.forEach(function (t) {
+ var dir = t.direction;
+ if (currStep == null || currStep == dir)
+ step++;
+ else {
+ core.status.automaticRoute.autoStepRoutes.push({ 'direction': currStep, 'step': step });
+ step = 1;
+ }
+ currStep = dir;
+ });
+ core.status.automaticRoute.autoStepRoutes.push({ 'direction': currStep, 'step': step });
+}
+
+////// 设置勇士的自动行走路线 //////
+control.prototype.setAutoHeroMove = function (steps) {
+ steps = steps || core.status.automaticRoute.autoStepRoutes;
+ if (steps.length == 0) return;
+ core.status.automaticRoute.autoStepRoutes = steps;
+ core.status.automaticRoute.autoHeroMove = true;
+ core.status.automaticRoute.autoStep = 1;
+ core.status.automaticRoute.destStep = steps[0].step;
+ core.moveHero(steps[0].direction);
+}
+
+////// 设置行走的效果动画 //////
+control.prototype.setHeroMoveInterval = function (callback) {
+ if (core.status.heroMoving > 0) return;
+ if (core.status.replay.speed == 24) {
+ if (callback) callback();
+ return;
+ }
+
+ core.status.heroMoving = 1;
+
+ var toAdd = 1;
+ if (core.status.replay.speed > 3) toAdd = 2;
+ if (core.status.replay.speed > 6) toAdd = 4;
+ if (core.status.replay.speed > 12) toAdd = 8;
+
+ core.interval.heroMoveInterval = window.setInterval(function () {
+ core.status.heroMoving += toAdd;
+ if (core.status.heroMoving >= 8) {
+ clearInterval(core.interval.heroMoveInterval);
+ core.status.heroMoving = 0;
+ if (callback) callback();
+ }
+ }, core.values.moveSpeed / 8 * toAdd / core.status.replay.speed);
+}
+
+////// 每移动一格后执行的事件 //////
+control.prototype.moveOneStep = function (callback) {
+ return this.controldata.moveOneStep(callback);
+}
+
+////// 实际每一步的行走过程 //////
+control.prototype.moveAction = function (callback) {
+ if (core.status.heroMoving > 0) return;
+ var noPass = core.noPass(core.nextX(), core.nextY()), canMove = core.canMoveHero();
+ // 下一个点如果不能走
+ if (noPass || !canMove) return this._moveAction_noPass(canMove, callback);
+ this._moveAction_moving(callback);
+}
+
+control.prototype._moveAction_noPass = function (canMove, callback) {
+ core.status.route.push(core.getHeroLoc('direction'));
+ core.status.automaticRoute.moveStepBeforeStop = [];
+ core.status.automaticRoute.lastDirection = core.getHeroLoc('direction');
+ if (canMove) core.trigger(core.nextX(), core.nextY());
+ core.drawHero();
+
+ if (core.status.automaticRoute.moveStepBeforeStop.length == 0) {
+ core.clearContinueAutomaticRoute();
+ core.stopAutomaticRoute();
+ }
+ if (callback) callback();
+}
+
+control.prototype._moveAction_moving = function (callback) {
+ core.setHeroMoveInterval(function () {
+ core.setHeroLoc('x', core.nextX(), true);
+ core.setHeroLoc('y', core.nextY(), true);
+
+ var direction = core.getHeroLoc('direction');
+ core.control._moveAction_popAutomaticRoute();
+ core.status.route.push(direction);
+
+ core.moveOneStep();
+ core.checkRouteFolding();
+ if (callback) callback();
+ });
+}
+
+control.prototype._moveAction_popAutomaticRoute = function () {
+ var automaticRoute = core.status.automaticRoute;
+ // 检查自动寻路是否被弹出
+ if (automaticRoute.autoHeroMove) {
+ automaticRoute.movedStep++;
+ automaticRoute.lastDirection = core.getHeroLoc('direction');
+ if (automaticRoute.destStep == automaticRoute.movedStep) {
+ if (automaticRoute.autoStep == automaticRoute.autoStepRoutes.length) {
+ core.clearContinueAutomaticRoute();
+ core.stopAutomaticRoute();
+ }
+ else {
+ automaticRoute.movedStep = 0;
+ automaticRoute.destStep = automaticRoute.autoStepRoutes[automaticRoute.autoStep].step;
+ core.setHeroLoc('direction', automaticRoute.autoStepRoutes[automaticRoute.autoStep].direction);
+ core.status.automaticRoute.autoStep++;
+ }
+ }
+ }
+}
+
+////// 让勇士开始移动 //////
+control.prototype.moveHero = function (direction, callback) {
+ // 如果正在移动,直接return
+ if (core.status.heroMoving != 0) return;
+ if (core.isset(direction))
+ core.setHeroLoc('direction', direction);
+
+ if (callback) return this.moveAction(callback);
+ this._moveHero_moving();
+}
+
+control.prototype._moveHero_moving = function () {
+ // ------ 我已经看不懂这个函数了,反正好用就行23333333
+ core.status.heroStop = false;
+ core.status.automaticRoute.moveDirectly = false;
+ var move = function () {
+ if (!core.status.heroStop) {
+ if (core.hasFlag('debug') && core.status.ctrlDown) {
+ if (core.status.heroMoving != 0) return;
+ // 检测是否穿出去
+ var nx = core.nextX(), ny = core.nextY();
+ if (nx < 0 || nx >= core.bigmap.width || ny < 0 || ny >= core.bigmap.height) return;
+ core.eventMoveHero([core.getHeroLoc('direction')], core.values.moveSpeed, move);
+ }
+ else {
+ core.moveAction();
+ setTimeout(move, 50);
+ }
+ }
+ }
+ move();
+}
+
+////// 当前是否正在移动 //////
+control.prototype.isMoving = function () {
+ return !core.status.heroStop || core.status.heroMoving > 0;
+}
+
+////// 停止勇士的一切行动,等待勇士行动结束后,再执行callback //////
+control.prototype.waitHeroToStop = function (callback) {
+ var lastDirection = core.status.automaticRoute.lastDirection;
+ core.stopAutomaticRoute();
+ core.clearContinueAutomaticRoute();
+ if (callback) {
+ core.status.replay.animate = true;
+ core.lockControl();
+ core.status.automaticRoute.moveDirectly = false;
+ setTimeout(function () {
+ core.status.replay.animate = false;
+ if (core.isset(lastDirection))
+ core.setHeroLoc('direction', lastDirection);
+ core.drawHero();
+ callback();
+ }, core.status.replay.speed == 24 ? 1 : 30);
+ }
+}
+
+////// 转向 //////
+control.prototype.turnHero = function (direction) {
+ if (direction) {
+ core.setHeroLoc('direction', direction);
+ core.drawHero();
+ core.status.route.push("turn:" + direction);
+ return;
+ }
+ core.setHeroLoc('direction', core.turnDirection(':right'));
+ core.drawHero();
+ core.status.route.push("turn");
+ core.checkRouteFolding();
+}
+
+////// 瞬间移动 //////
+control.prototype.moveDirectly = function (destX, destY, ignoreSteps) {
+ return this.controldata.moveDirectly(destX, destY, ignoreSteps);
+}
+
+////// 尝试瞬间移动 //////
+control.prototype.tryMoveDirectly = function (destX, destY) {
+ if (this.nearHero(destX, destY)) return false;
+ var canMoveArray = core.maps.generateMovableArray();
+ var dirs = [[destX, destY], [destX - 1, destY, "right"], [destX, destY - 1, "down"], [destX, destY + 1, "up"], [destX + 1, destY, "left"]];
+ var canMoveDirectlyArray = core.canMoveDirectlyArray(dirs, canMoveArray);
+
+ for (var i = 0; i < dirs.length; ++i) {
+ var d = dirs[i], dx = d[0], dy = d[1], dir = d[2];
+ if (dx < 0 || dx >= core.bigmap.width || dy < 0 || dy >= core.bigmap.height) continue;
+ if (dir && !core.inArray(canMoveArray[dx][dy], dir)) continue;
+ if (canMoveDirectlyArray[i] < 0) continue;
+ if (core.control.moveDirectly(dx, dy, canMoveDirectlyArray[i])) {
+ if (dir) core.moveHero(dir, function () { });
+ return true;
+ }
+ }
+ return false;
+}
+
+////// 绘制勇士 //////
+control.prototype.drawHero = function (status, offset, frame) {
+ if (!core.isPlaying() || !core.status.floorId || core.status.gameOver) return;
+ var x = core.getHeroLoc('x'), y = core.getHeroLoc('y'), direction = core.getHeroLoc('direction');
+ status = status || 'stop';
+ if (!offset) offset = 0;
+
+ var way = core.utils.scan2[direction];
+ var dx = way.x, dy = way.y;
+ var offsetX = typeof offset == 'number' ? dx * offset : (offset.x || 0);
+ var offsetY = typeof offset == 'number' ? dy * offset : (offset.y || 0);
+ offset = { x: offsetX, y: offsetY, offset: offset };
+
+ core.clearAutomaticRouteNode(x + dx, y + dy);
+ core.clearMap('hero');
+ core.status.heroCenter.px = 32 * x + offsetX + 16;
+ core.status.heroCenter.py = 32 * y + offsetY + 32 - core.material.icons.hero.height / 2;
+
+ // 重置hero层画布
+ core.setGameCanvasTranslate('hero', 0, 0);
+ delete core.canvas.hero._px;
+ delete core.canvas.hero._py;
+ core.status.preview.enabled = false;
+ if (!core.hasFlag('__lockViewport__')) {
+ this._drawHero_updateViewport(x, y, offset);
+ }
+
+ this._drawHero_draw(direction, x, y, status, offset, frame);
+}
+
+control.prototype._drawHero_updateViewport = function (x, y, offset) {
+ core.bigmap.offsetX = core.clamp((x - core.__HALF_SIZE__) * 32 + offset.x, 0, 32 * core.bigmap.width - core.__PIXELS__);
+ core.bigmap.offsetY = core.clamp((y - core.__HALF_SIZE__) * 32 + offset.y, 0, 32 * core.bigmap.height - core.__PIXELS__);
+ core.control.updateViewport();
+}
+
+control.prototype._drawHero_draw = function (direction, x, y, status, offset, frame) {
+ offset = offset || { x: 0, y: 0, offset: 0, px: 0, py: 0 };
+ var opacity = core.setAlpha('hero', core.getFlag('__heroOpacity__', 1))
+ this._drawHero_getDrawObjs(direction, x, y, status, offset).forEach(function (block) {
+ core.drawImage('hero', block.img, (block.heroIcon[block.status] + (frame || 0)) % 4 * block.width,
+ block.heroIcon.loc * block.height, block.width, block.height,
+ block.posx + (32 - block.width) / 2, block.posy + 32 - block.height, block.width, block.height);
+ });
+ core.setAlpha('hero', opacity);
+}
+
+control.prototype._drawHero_getDrawObjs = function (direction, x, y, status, offset) {
+ var heroIconArr = core.material.icons.hero, drawObjs = [], index = 0;
+ drawObjs.push({
+ "img": core.material.images.hero,
+ "width": core.material.icons.hero.width || 32,
+ "height": core.material.icons.hero.height,
+ "heroIcon": heroIconArr[direction],
+ "posx": x * 32 - core.bigmap.offsetX + offset.x,
+ "posy": y * 32 - core.bigmap.offsetY + offset.y,
+ "status": status,
+ "index": index++,
+ });
+ if (typeof offset.offset == 'number') {
+ core.status.hero.followers.forEach(function (t) {
+ drawObjs.push({
+ "img": core.material.images.images[t.name],
+ "width": core.material.images.images[t.name].width / 4,
+ "height": core.material.images.images[t.name].height / 4,
+ "heroIcon": heroIconArr[t.direction],
+ "posx": 32 * t.x - core.bigmap.offsetX + (t.stop ? 0 : core.utils.scan2[t.direction].x * Math.abs(offset.offset)),
+ "posy": 32 * t.y - core.bigmap.offsetY + (t.stop ? 0 : core.utils.scan2[t.direction].y * Math.abs(offset.offset)),
+ "status": t.stop ? "stop" : status,
+ "index": index++
+ });
+ });
+ }
+ return drawObjs.sort(function (a, b) {
+ return a.posy == b.posy ? b.index - a.index : a.posy - b.posy;
+ });
+}
+
+control.prototype.setHeroOpacity = function (opacity, moveMode, time, callback) {
+ time = time || 0;
+ if (time == 0) {
+ core.setFlag('__heroOpacity__', opacity);
+ core.drawHero();
+ if (callback) callback();
+ return;
+ }
+ time /= Math.max(core.status.replay.speed, 1)
+
+ var fromOpacity = core.getFlag('__heroOpacity__', 1);
+ var step = 0, steps = parseInt(time / 10);
+ if (steps <= 0) steps = 1;
+ var moveFunc = core.applyEasing(moveMode);
+
+ var animate = setInterval(function () {
+ step++;
+ core.setFlag('__heroOpacity__', fromOpacity + (opacity - fromOpacity) * moveFunc(step / steps));
+ core.drawHero();
+ if (step == steps) {
+ delete core.animateFrame.asyncId[animate];
+ clearInterval(animate);
+ if (callback) callback();
+ }
+ }, 10);
+
+ core.animateFrame.lastAsyncId = animate;
+ core.animateFrame.asyncId[animate] = callback;
+}
+
+// ------ 画布、位置、阻激夹域,显伤 ------ //
+
+////// 设置画布偏移
+control.prototype.setGameCanvasTranslate = function (canvas, x, y) {
+ var c = core.dom.gameCanvas[canvas];
+ x = x * core.domStyle.scale;
+ y = y * core.domStyle.scale;
+ c.style.transform = 'translate(' + x + 'px,' + y + 'px)';
+ c.style.webkitTransform = 'translate(' + x + 'px,' + y + 'px)';
+ c.style.OTransform = 'translate(' + x + 'px,' + y + 'px)';
+ c.style.MozTransform = 'translate(' + x + 'px,' + y + 'px)';
+ if (main.mode === 'editor' && editor.isMobile) {
+ c.style.transform = 'translate(' + (x / core.__PIXELS__ * 96) + 'vw,' + (y / core.__PIXELS__ * 96) + 'vw)';
+ c.style.webkitTransform = 'translate(' + (x / core.__PIXELS__ * 96) + 'vw,' + (y / core.__PIXELS__ * 96) + 'vw)';
+ c.style.OTransform = 'translate(' + (x / core.__PIXELS__ * 96) + 'vw,' + (y / core.__PIXELS__ * 96) + 'vw)';
+ c.style.MozTransform = 'translate(' + (x / core.__PIXELS__ * 96) + 'vw,' + (y / core.__PIXELS__ * 96) + 'vw)';
+ }
+};
+
+////// 加减画布偏移
+control.prototype.addGameCanvasTranslate = function (x, y) {
+ for (var ii = 0, canvas; canvas = core.dom.gameCanvas[ii]; ii++) {
+ var id = canvas.getAttribute('id');
+ if (id == 'ui' || id == 'data') continue; // UI层和data层不移动
+ var offsetX = x, offsetY = y;
+ if (core.bigmap.canvas.indexOf(id) >= 0) {
+ if (core.bigmap.v2) {
+ offsetX -= (core.bigmap.offsetX - 32 * core.bigmap.posX) + 32;
+ offsetY -= (core.bigmap.offsetY - 32 * core.bigmap.posY) + 32;
+ } else {
+ offsetX -= core.bigmap.offsetX;
+ offsetY -= core.bigmap.offsetY;
+ }
+ }
+ core.control.setGameCanvasTranslate(id, offsetX, offsetY);
+ }
+}
+
+////// 更新视野范围 //////
+control.prototype.updateViewport = function () {
+ // 当前是否应该重绘?
+ if (core.bigmap.v2) {
+ if (core.bigmap.offsetX >= core.bigmap.posX * 32 + 32
+ || core.bigmap.offsetX <= core.bigmap.posX * 32 - 32
+ || core.bigmap.offsetY >= core.bigmap.posY * 32 + 32
+ || core.bigmap.offsetY <= core.bigmap.posY * 32 - 32) {
+ core.bigmap.posX = parseInt(core.bigmap.offsetX / 32);
+ core.bigmap.posY = parseInt(core.bigmap.offsetY / 32);
+ core.redrawMap();
+ }
+ } else {
+ core.bigmap.posX = core.bigmap.posY = 0;
+ }
+ var offsetX = core.bigmap.v2 ? -(core.bigmap.offsetX - 32 * core.bigmap.posX) - 32 : -core.bigmap.offsetX;
+ var offsetY = core.bigmap.v2 ? -(core.bigmap.offsetY - 32 * core.bigmap.posY) - 32 : -core.bigmap.offsetY;
+
+ core.bigmap.canvas.forEach(function (cn) {
+ core.control.setGameCanvasTranslate(cn, offsetX, offsetY);
+ });
+ // ------ 路线
+ core.relocateCanvas('route', core.status.automaticRoute.offsetX - core.bigmap.offsetX, core.status.automaticRoute.offsetY - core.bigmap.offsetY);
+ // ------ 所有的大怪物也都需要重定位
+ for (var one in core.dymCanvas) {
+ if (one.startsWith('_bigImage_')) {
+ var ox = core.dymCanvas[one].canvas.getAttribute('_ox');
+ var oy = core.dymCanvas[one].canvas.getAttribute('_oy');
+ if (ox != null && oy != null) {
+ core.relocateCanvas(one, parseInt(ox) - core.bigmap.offsetX, parseInt(oy) - core.bigmap.offsetY);
+ }
+ }
+ }
+
+}
+
+////// 设置视野范围 //////
+control.prototype.setViewport = function (px, py) {
+ var originOffsetX = core.bigmap.offsetX, originOffsetY = core.bigmap.offsetY;
+ core.bigmap.offsetX = core.clamp(px, 0, 32 * core.bigmap.width - core.__PIXELS__);
+ core.bigmap.offsetY = core.clamp(py, 0, 32 * core.bigmap.height - core.__PIXELS__);
+ this.updateViewport();
+ // ------ hero层也需要!
+ var px = parseFloat(core.canvas.hero._px) || 0;
+ var py = parseFloat(core.canvas.hero._py) || 0;
+ px += originOffsetX - core.bigmap.offsetX;
+ py += originOffsetY - core.bigmap.offsetY;
+ core.control.setGameCanvasTranslate('hero', px, py);
+ core.canvas.hero._px = px;
+ core.canvas.hero._py = py;
+}
+
+////// 移动视野范围 //////
+control.prototype.moveViewport = function (x, y, moveMode, time, callback) {
+ time = time || 0;
+ time /= Math.max(core.status.replay.speed, 1)
+ var per_time = 10, step = 0, steps = parseInt(time / per_time);
+ if (steps <= 0) {
+ this.setViewport(32 * x, 32 * y);
+ if (callback) callback();
+ return;
+ }
+ var px = core.clamp(32 * x, 0, 32 * core.bigmap.width - core.__PIXELS__);
+ var py = core.clamp(32 * y, 0, 32 * core.bigmap.height - core.__PIXELS__);
+ var cx = core.bigmap.offsetX;
+ var cy = core.bigmap.offsetY;
+ var moveFunc = core.applyEasing(moveMode);
+
+ var animate = window.setInterval(function () {
+ step++;
+ core.setViewport(cx + moveFunc(step / steps) * (px - cx), cy + moveFunc(step / steps) * (py - cy));
+ if (step == steps) {
+ delete core.animateFrame.asyncId[animate];
+ clearInterval(animate);
+ core.setViewport(px, py);
+ if (callback) callback();
+ }
+ }, per_time);
+
+ core.animateFrame.lastAsyncId = animate;
+ core.animateFrame.asyncId[animate] = callback;
+}
+
+////// 获得勇士面对位置的x坐标 //////
+control.prototype.nextX = function (n) {
+ if (n == null) n = 1;
+ return core.getHeroLoc('x') + core.utils.scan[core.getHeroLoc('direction')].x * n;
+}
+
+////// 获得勇士面对位置的y坐标 //////
+control.prototype.nextY = function (n) {
+ if (n == null) n = 1;
+ return core.getHeroLoc('y') + core.utils.scan[core.getHeroLoc('direction')].y * n;
+}
+
+////// 某个点是否在勇士旁边 //////
+control.prototype.nearHero = function (x, y, n) {
+ if (n == null) n = 1;
+ return Math.abs(x - core.getHeroLoc('x')) + Math.abs(y - core.getHeroLoc('y')) <= n;
+}
+
+////// 聚集跟随者 //////
+control.prototype.gatherFollowers = function () {
+ var x = core.getHeroLoc('x'), y = core.getHeroLoc('y'), dir = core.getHeroLoc('direction');
+ core.status.hero.followers.forEach(function (t) {
+ t.x = x;
+ t.y = y;
+ t.stop = true;
+ t.direction = dir;
+ });
+}
+
+////// 更新跟随者坐标 //////
+control.prototype.updateFollowers = function () {
+ core.status.hero.followers.forEach(function (t) {
+ if (!t.stop) {
+ t.x += core.utils.scan2[t.direction].x;
+ t.y += core.utils.scan2[t.direction].y;
+ }
+ })
+
+ var nowx = core.getHeroLoc('x'), nowy = core.getHeroLoc('y');
+ core.status.hero.followers.forEach(function (t) {
+ t.stop = true;
+ var dx = nowx - t.x, dy = nowy - t.y;
+ for (var dir in core.utils.scan2) {
+ if (core.utils.scan2[dir].x == dx && core.utils.scan2[dir].y == dy) {
+ t.stop = false;
+ t.direction = dir;
+ }
+ }
+ nowx = t.x; nowy = t.y;
+ })
+}
+
+////// 瞬移更新跟随者坐标 //////
+control.prototype._moveDirectyFollowers = function (x, y) {
+ var route = core.automaticRoute(x, y);
+ if (route.length == 0) route = [{ x: x, y: y, direction: core.getHeroLoc('direction') }];
+
+ var nowx = x, nowy = y;
+ for (var i = 0; i < core.status.hero.followers.length; ++i) {
+ var t = core.status.hero.followers[i];
+ var index = route.length - i - 2;
+ if (index < 0) index = 0;
+ t.stop = true;
+ t.x = route[index].x;
+ t.y = route[index].y;
+ t.direction = route[index].direction;
+ var dx = nowx - t.x, dy = nowy - t.y;
+ for (var dir in core.utils.scan2) {
+ if (core.utils.scan2[dir].x == dx && core.utils.scan2[dir].y == dy) {
+ t.stop = false;
+ t.direction = dir;
+ }
+ }
+ nowx = t.x; nowy = t.y;
+ }
+}
+
+////// 更新领域、夹击、阻击的伤害地图 //////
+control.prototype.updateCheckBlock = function (floorId) {
+ return this.controldata.updateCheckBlock(floorId);
+}
+
+////// 检查并执行领域、夹击、阻击事件 //////
+
+control.prototype.battleWithChase = function () {
+ const { x: hx, y: hy } = core.status.hero.loc;
+ const scan = core.utils.scan;
+ const actions = [];
+
+ for (const dir in scan) {
+ const [nx, ny] = [hx + scan[dir].x, hy + scan[dir].y];
+ const blockId = core.getBlockId(nx, ny);
+ if (core.hasSpecial(blockId, 28)) {
+ actions.push({
+ "type": "function", "function": "function() { " +
+ "core.battle('" + blockId + "', " + nx + "," + ny + ", true, core.doAction); " +
+ "}", "async": true
+ });
+ }
+ }
+ if (actions.length > 0) core.insertAction(actions);
+ core.doAction();
+}
+
+control.prototype.checkBlock = function () {
+ var x = core.getHeroLoc('x'), y = core.getHeroLoc('y'), loc = x + "," + y;
+ var damage = core.status.checkBlock.damage[loc];
+ if (damage) {
+ core.status.hero.hp -= damage;
+ var text = (Object.keys(core.status.checkBlock.type[loc] || {}).join(",")) || "伤害";
+ core.drawTip("受到" + text + damage + "点");
+ core.drawHeroAnimate("zone");
+ this._checkBlock_disableQuickShop();
+ core.status.hero.statistics.extraDamage += damage;
+ if (core.status.hero.hp <= 0) {
+ core.status.hero.hp = 0;
+ core.updateStatusBar(false, true);
+ core.events.lose();
+ return;
+ } else {
+ core.updateStatusBar(false, true);
+ }
+ }
+ let actions = [];
+
+ const ambushAction = this._checkBlock_ambush(core.status.checkBlock.ambush[loc]);
+ if (ambushAction.length > 0) core.push(actions, ambushAction);
+
+ const repulseAction = this._checkBlock_repulse(core.status.checkBlock.repulse[loc]);
+ if (repulseAction.length > 0) core.push(actions, repulseAction);
+
+ // 追猎需要等待阻击完成,避免发生碰撞导致怪物消失 先清理四周追猎,追猎移动,再清理一轮四周的追猎
+ const currChase = core.status.checkBlock.chase[loc];
+ if (currChase && currChase.length > 0) {
+ core.push(actions, { "type": "function", "async": true, "function": "function(){\ncore.battleWithChase();\n}" });
+ }
+ const chaseAction = this._checkBlock_chase(currChase);
+ if (chaseAction.length > 0) core.push(actions, chaseAction);
+ if (currChase && currChase.length > 0) {
+ core.push(actions, { "type": "function", "async": true, "function": "function(){\ncore.battleWithChase();\n}" });
+ }
+ if (actions.length > 0) core.insertAction(actions);
+}
+
+control.prototype._checkBlock_disableQuickShop = function () {
+ // 禁用快捷商店
+ if (core.flags.disableShopOnDamage) {
+ Object.keys(core.status.shops).forEach(function (shopId) {
+ core.setShopVisited(shopId, false);
+ });
+ }
+}
+
+////// 阻击 //////
+control.prototype._checkBlock_repulse = function (repulse) {
+ if (!repulse || repulse.length == 0) return [];
+ var actions = [];
+ repulse.forEach(function (t) {
+ actions.push({ "type": "move", "loc": [t[0], t[1]], "steps": [t[3]], "time": 100, "keep": true, "async": true });
+ });
+ if (actions.length>0) actions.push({ "type": "waitAsync" });
+ return actions;
+}
+
+////// 捕捉 //////
+control.prototype._checkBlock_ambush = function (ambush) {
+ if (!ambush || ambush.length == 0) return [];
+ // 捕捉效果
+ let actions = [];
+ ambush.forEach(function (t) {
+ actions.push({ "type": "move", "loc": [t[0], t[1]], "steps": [t[3]], "time": 100, "keep": false, "async": true });
+ });
+ if (actions.length>0) actions.push({ "type": "waitAsync" });
+ // 强制战斗
+ ambush.forEach(function (t) {
+ actions.push({
+ "type": "function", "function": "function() { " +
+ "core.battle('" + t[2] + "', " + t[0] + "," + t[1] + ", true, core.doAction); " +
+ "}", "async": true
+ });
+ });
+ return actions;
+}
+
+////// 追猎 //////
+control.prototype._checkBlock_chase = function (chase) {
+ if (!chase || chase.length === 0) return [];
+ var actions = [];
+ const { x: hx, y: hy } = core.status.hero.loc;
+ const reverseDir = { 'up': 'down', 'down': 'up', 'left': 'right', 'right': 'left' };
+ chase = chase.sort((a, b) => {
+ const { x: ax, y: ay } = a;
+ const { x: bx, y: by } = b;
+ return Math.abs(ax - hx) + Math.abs(ay - hy) - Math.abs(bx - hx) - Math.abs(by - hy);
+ })
+ chase.forEach((currChaseInfo) => {
+ const { x, y, dir } = currChaseInfo;
+ const [aimx, aimy] = [x + core.utils.scan[dir].x, y + core.utils.scan[dir].y];
+ // 可与敌人,物品换位
+ if (!(aimx === hx && aimy === hy)) {
+ actions.push({
+ "type": "if", "condition": "!core.getBlock(" + aimx + "," + aimy + ")",
+ "true": [
+ { "type": "move", "loc": [x, y], "time": 100, "keep": true, "async": true, "steps": [dir + ":1"] },
+ ],
+ "false": [
+ {
+ "type": "if", "condition": "[\"items\",\"enemys\",\"enemy48\"].includes(core.getBlockCls(" + aimx + "," + aimy + "))",
+ "true": [
+ { "type": "move", "loc": [x, y], "time": 100, "keep": true, "async": true, "steps": [dir + ":1"] },
+ { "type": "move", "loc": [aimx, aimy], "time": 100, "keep": true, "async": true, "steps": [reverseDir[dir] + ":1"] },
+ { "type": "waitAsync", "excludeAnimates": true },
+ ]
+ },
+ ]
+ });
+ }
+ })
+
+ if (actions.length > 0) actions.push({ "type": "waitAsync" });
+ return actions;
+}
+
+////// 更新全地图显伤 //////
+control.prototype.updateDamage = function (floorId, ctx) {
+ floorId = floorId || core.status.floorId;
+ if (!floorId || core.status.gameOver || main.mode != 'play') return;
+ var onMap = ctx == null;
+
+ // 没有怪物手册
+ if (!core.hasItem('book')) return;
+ core.status.damage.posX = core.bigmap.posX;
+ core.status.damage.posY = core.bigmap.posY;
+ if (!onMap) {
+ var width = core.floors[floorId].width, height = core.floors[floorId].height;
+ // 地图过大的缩略图不绘制显伤
+ if (width * height > core.bigmap.threshold) return;
+ }
+ this._updateDamage_damage(floorId, onMap);
+ this._updateDamage_extraDamage(floorId, onMap);
+ this.drawDamage(ctx);
+}
+
+control.prototype._updateDamage_damage = function (floorId, onMap) {
+ core.status.damage.data = [];
+ if (!core.flags.displayEnemyDamage && !core.flags.displayExtraDamage) return;
+
+ core.extractBlocks(floorId);
+ core.status.maps[floorId].blocks.forEach(function (block) {
+ var x = block.x, y = block.y;
+
+ // v2优化,只绘制范围内的部分
+ if (onMap && core.bigmap.v2) {
+ if (x < core.bigmap.posX - core.bigmap.extend || x > core.bigmap.posX + core.__SIZE__ + core.bigmap.extend
+ || y < core.bigmap.posY - core.bigmap.extend || y > core.bigmap.posY + core.__SIZE__ + core.bigmap.extend) {
+ return;
+ }
+ }
+
+ if (!block.disable && block.event.cls.indexOf('enemy') == 0 && block.event.displayDamage !== false) {
+ if (core.flags.displayEnemyDamage) {
+ var damageString = core.enemys.getDamageString(block.event.id, x, y, floorId);
+ core.status.damage.data.push({ text: damageString.damage, px: 32 * x + 1, py: 32 * (y + 1) - 1, color: damageString.color });
+ }
+ if (core.flags.displayCritical) {
+ var critical = core.enemys.nextCriticals(block.event.id, 1, x, y, floorId);
+ critical = core.formatBigNumber((critical[0] || [])[0], true);
+ if (critical == '???') critical = '?';
+ core.status.damage.data.push({ text: critical, px: 32 * x + 1, py: 32 * (y + 1) - 11, color: '#FFFFFF' });
+ }
+ }
+ });
+}
+
+control.prototype._updateDamage_extraDamage = function (floorId, onMap) {
+ core.status.damage.extraData = [];
+ if (!core.flags.displayExtraDamage) return;
+
+ var width = core.floors[floorId].width, height = core.floors[floorId].height;
+ var startX = onMap && core.bigmap.v2 ? Math.max(0, core.bigmap.posX - core.bigmap.extend) : 0;
+ var endX = onMap && core.bigmap.v2 ? Math.min(width, core.bigmap.posX + core.__SIZE__ + core.bigmap.extend + 1) : width;
+ var startY = onMap && core.bigmap.v2 ? Math.max(0, core.bigmap.posY - core.bigmap.extend) : 0;
+ var endY = onMap && core.bigmap.v2 ? Math.min(height, core.bigmap.posY + core.__SIZE__ + core.bigmap.extend + 1) : height;
+
+ for (var x = startX; x < endX; x++) {
+ for (var y = startY; y < endY; y++) {
+ var alpha = 1;
+ if (core.noPass(x, y, floorId)) {
+ if (core.flags.extraDamageType == 2) alpha = 0;
+ else if (core.flags.extraDamageType == 1) alpha = 0.6;
+ }
+ var damage = core.status.checkBlock.damage[x + "," + y] || 0;
+ if (damage > 0) { // 该点伤害
+ damage = core.formatBigNumber(damage, true);
+ core.status.damage.extraData.push({ text: damage, px: 32 * x + 16, py: 32 * (y + 1) - 14, color: '#ffaa33', alpha: alpha });
+ }
+ else { // 检查捕捉
+ if (core.status.checkBlock.ambush[x + "," + y]) {
+ core.status.damage.extraData.push({ text: '!', px: 32 * x + 16, py: 32 * (y + 1) - 14, color: '#ffaa33', alpha: alpha });
+ }
+ }
+ }
+ }
+}
+
+////// 重绘地图显伤 //////
+control.prototype.drawDamage = function (ctx) {
+ if (core.status.gameOver || !core.status.damage || main.mode != 'play') return;
+ var onMap = false;
+ if (ctx == null) {
+ ctx = core.canvas.damage;
+ core.clearMap('damage');
+ onMap = true;
+ }
+
+ if (onMap && core.bigmap.v2) {
+ // 检查是否需要重算...
+ if (Math.abs(core.bigmap.posX - core.status.damage.posX) >= core.bigmap.extend - 1
+ || Math.abs(core.bigmap.posY - core.status.damage.posY) >= core.bigmap.extend - 1) {
+ return this.updateDamage();
+ }
+ }
+ return this._drawDamage_draw(ctx, onMap);
+}
+
+control.prototype._drawDamage_draw = function (ctx, onMap) {
+ if (!core.hasItem('book')) return;
+
+ core.setFont(ctx, "bold 11px Arial");
+ core.setTextAlign(ctx, 'left');
+ core.status.damage.data.forEach(function (one) {
+ var px = one.px, py = one.py;
+ if (onMap && core.bigmap.v2) {
+ px -= core.bigmap.posX * 32;
+ py -= core.bigmap.posY * 32;
+ if (px < -32 * 2 || px > core.__PIXELS__ + 32 || py < -32 || py > core.__PIXELS__ + 32)
+ return;
+ }
+ core.fillBoldText(ctx, one.text, px, py, one.color);
+ });
+
+ core.setTextAlign(ctx, 'center');
+ core.status.damage.extraData.forEach(function (one) {
+ var px = one.px, py = one.py;
+ if (onMap && core.bigmap.v2) {
+ px -= core.bigmap.posX * 32;
+ py -= core.bigmap.posY * 32;
+ if (px < -32 || px > core.__PIXELS__ + 32 || py < -32 || py > core.__PIXELS__ + 32)
+ return;
+ }
+ var alpha = core.setAlpha(ctx, one.alpha);
+ core.fillBoldText(ctx, one.text, px, py, one.color);
+ core.setAlpha(ctx, alpha);
+ });
+}
+
+// ------ 录像相关 ------ //
+
+////// 选择录像文件 //////
+control.prototype.chooseReplayFile = function () {
+ core.readFile(function (obj) {
+ if (obj.name != core.firstData.name) return alert("存档和游戏不一致!");
+ if (!obj.route) return alert("无效的录像!");
+ var _replay = function () {
+ core.startGame(core.flags.startUsingCanvas ? '' : obj.hard || '', obj.seed, core.decodeRoute(obj.route));
+ }
+ if (obj.version && obj.version != core.firstData.version) {
+ core.myconfirm("游戏版本不一致!\n你仍然想播放录像吗?", _replay);
+ return;
+ }
+ _replay();
+ }, null, ".h5route");
+}
+
+////// 开始播放 //////
+control.prototype.startReplay = function (list) {
+ if (!core.isPlaying()) return;
+ core.status.replay.replaying = true;
+ core.status.replay.pausing = true;
+ core.status.replay.failed = false;
+ core.status.replay.speed = 1.0;
+ core.status.replay.toReplay = core.cloneArray(list);
+ core.status.replay.totalList = core.status.route.concat(list);
+ core.status.replay.steps = 0;
+ core.status.replay.save = [];
+ core.createCanvas('replay', 0, core.__PIXELS__ - 40, core.__PIXELS__, 40, 199);
+ core.setOpacity('replay', 0.6);
+ this._replay_drawProgress();
+ core.updateStatusBar(false, true);
+ core.drawTip("开始播放");
+ this.replay();
+}
+
+////// 更改播放状态 //////
+control.prototype.triggerReplay = function () {
+ if (core.status.replay.pausing) this.resumeReplay();
+ else this.pauseReplay();
+}
+
+////// 暂停播放 //////
+control.prototype.pauseReplay = function () {
+ if (!core.isPlaying() || !core.isReplaying()) return;
+ core.status.replay.pausing = true;
+ core.updateStatusBar(false, true);
+ core.drawTip("暂停播放");
+}
+
+////// 恢复播放 //////
+control.prototype.resumeReplay = function () {
+ if (!core.isPlaying() || !core.isReplaying()) return;
+ if (core.isMoving() || core.status.replay.animate || core.status.event.id) {
+ core.playSound('操作失败');
+ return core.drawTip("请等待当前事件的处理结束");
+ }
+ core.status.replay.pausing = false;
+ core.updateStatusBar(false, true);
+ core.drawTip("恢复播放");
+ core.replay();
+}
+
+////// 单步播放 //////
+control.prototype.stepReplay = function () {
+ if (!core.isPlaying() || !core.isReplaying()) return;
+ if (!core.status.replay.pausing) {
+ core.playSound('操作失败');
+ return core.drawTip("请先暂停录像");
+ }
+ if (core.isMoving() || core.status.replay.animate || core.status.event.id) {
+ core.playSound('操作失败');
+ return core.drawTip("请等待当前事件的处理结束");
+ }
+ core.replay(true);
+}
+
+////// 加速播放 //////
+control.prototype.speedUpReplay = function () {
+ if (!core.isPlaying() || !core.isReplaying()) return;
+ var speeds = [0.2, 0.5, 1, 2, 3, 6, 12, 24];
+ for (var i = speeds.length - 2; i >= 0; i--) {
+ if (speeds[i] <= core.status.replay.speed) {
+ core.status.replay.speed = speeds[i + 1];
+ break;
+ }
+ }
+ core.drawTip("x" + core.status.replay.speed + "倍");
+}
+
+////// 减速播放 //////
+control.prototype.speedDownReplay = function () {
+ if (!core.isPlaying() || !core.isReplaying()) return;
+ var speeds = [0.2, 0.5, 1, 2, 3, 6, 12, 24];
+ for (var i = 1; i <= speeds.length; i++) {
+ if (speeds[i] >= core.status.replay.speed) {
+ core.status.replay.speed = speeds[i - 1];
+ break;
+ }
+ }
+ core.drawTip("x" + core.status.replay.speed + "倍");
+}
+
+////// 设置播放速度 //////
+control.prototype.setReplaySpeed = function (speed) {
+ if (!core.isPlaying() || !core.isReplaying()) return;
+ core.status.replay.speed = speed;
+ core.drawTip("x" + core.status.replay.speed + "倍");
+}
+
+////// 停止播放 //////
+control.prototype.stopReplay = function (force) {
+ if (!core.isPlaying()) return;
+ if (!core.isReplaying() && !force) return;
+ core.status.replay.toReplay = [];
+ core.status.replay.totalList = [];
+ core.status.replay.replaying = false;
+ core.status.replay.pausing = false;
+ core.status.replay.failed = false;
+ core.status.replay.speed = 1.0;
+ core.status.replay.steps = 0;
+ core.status.replay.save = [];
+ core.deleteCanvas('replay');
+ core.updateStatusBar(false, true);
+ core.drawTip("停止播放并恢复游戏");
+}
+
+////// 回退 //////
+control.prototype.rewindReplay = function () {
+ if (!core.isPlaying() || !core.isReplaying()) return;
+ if (!core.status.replay.pausing) {
+ core.playSound('操作失败');
+ return core.drawTip("请先暂停录像");
+ }
+ if (core.isMoving() || core.status.replay.animate || core.status.event.id) {
+ core.playSound('操作失败');
+ return core.drawTip("请等待当前事件的处理结束");
+ }
+ if (core.status.replay.save.length == 0) {
+ core.playSound('操作失败');
+ return core.drawTip("无法再回到上一个节点");
+ }
+ var save = core.status.replay.save, data = save.pop();
+ core.loadData(data.data, function () {
+ core.removeFlag('__fromLoad__');
+ core.status.replay = {
+ "replaying": true,
+ "pausing": true,
+ "animate": false,
+ "toReplay": data.replay.toReplay,
+ "totalList": data.replay.totalList,
+ "speed": core.status.replay.speed,
+ "steps": data.replay.steps,
+ "save": save
+ }
+ core.createCanvas('replay', 0, core.__PIXELS__ - 40, core.__PIXELS__, 40, 199);
+ core.setOpacity('replay', 0.6);
+ core.control._replay_drawProgress();
+ core.updateStatusBar(false, true);
+ core.drawTip("成功回退到上一个节点");
+ });
+}
+
+////// 回放时存档 //////
+control.prototype._replay_SL = function () {
+ if (!core.isPlaying() || !core.isReplaying()) return;
+ if (!core.status.replay.pausing) {
+ core.playSound('操作失败');
+ return core.drawTip("请先暂停录像");
+ }
+ if (core.isMoving() || core.status.replay.animate || core.status.event.id) {
+ core.playSound('操作失败');
+ return core.drawTip("请等待当前事件的处理结束");
+ }
+ if (core.hasFlag('__forbidSave__')) {
+ core.playSound('操作失败');
+ return core.drawTip('当前禁止存档');
+ }
+ this._replay_hideProgress();
+
+ core.lockControl();
+ core.status.event.id = 'save';
+ var saveIndex = core.saves.saveIndex;
+ var page = parseInt((saveIndex - 1) / 5), offset = saveIndex - 5 * page;
+
+ core.ui._drawSLPanel(10 * page + offset);
+}
+
+////// 回放时查看怪物手册 //////
+control.prototype._replay_book = function () {
+ if (!core.isPlaying() || !core.isReplaying()) return;
+ if (!core.status.replay.pausing) {
+ core.playSound('操作失败');
+ return core.drawTip("请先暂停录像");
+ }
+ if (core.isMoving() || core.status.replay.animate || (core.status.event.id && core.status.event.id != 'viewMaps')) {
+ core.playSound('操作失败');
+ return core.drawTip("请等待当前事件的处理结束");
+ }
+ if (!core.hasItem('book')) {
+ core.playSound('操作失败');
+ return core.drawTip('你没有' + core.material.items['book'].name, 'book');
+ }
+ this._replay_hideProgress();
+
+ // 从“浏览地图”页面打开
+ if (core.status.event.id == 'viewMaps')
+ core.status.event.ui = core.status.event.data;
+
+ core.lockControl();
+ core.status.event.id = 'book';
+ core.useItem('book', true);
+}
+
+////// 回放录像时浏览地图 //////
+control.prototype._replay_viewMap = function () {
+ if (!core.isPlaying() || !core.isReplaying()) return;
+ if (!core.status.replay.pausing) {
+ core.playSound('操作失败');
+ return core.drawTip("请先暂停录像");
+ }
+ if (core.isMoving() || core.status.replay.animate || core.status.event.id) {
+ core.playSound('操作失败');
+ return core.drawTip("请等待当前事件的处理结束");
+ }
+ this._replay_hideProgress();
+
+ core.lockControl();
+ core.status.event.id = 'viewMaps';
+ core.ui._drawViewMaps();
+}
+
+control.prototype._replay_toolbox = function () {
+ if (!core.isPlaying() || !core.isReplaying()) return;
+ if (!core.status.replay.pausing) {
+ core.playSound('操作失败');
+ return core.drawTip("请先暂停录像");
+ }
+ if (core.isMoving() || core.status.replay.animate || core.status.event.id) {
+ core.playSound('操作失败');
+ return core.drawTip("请等待当前事件的处理结束");
+ }
+ this._replay_hideProgress();
+
+ core.lockControl();
+ core.status.event.id = 'toolbox';
+ core.ui._drawToolbox();
+}
+
+control.prototype._replay_equipbox = function () {
+ if (!core.isPlaying() || !core.isReplaying()) return;
+ if (!core.status.replay.pausing) {
+ core.playSound('操作失败');
+ return core.drawTip("请先暂停录像");
+ }
+ if (core.isMoving() || core.status.replay.animate || core.status.event.id) {
+ core.playSound('操作失败');
+ return core.drawTip("请等待当前事件的处理结束");
+ }
+ this._replay_hideProgress();
+
+ core.lockControl();
+ core.status.event.id = 'equipbox';
+ core.ui._drawEquipbox();
+}
+
+////// 是否正在播放录像 //////
+control.prototype.isReplaying = function () {
+ return (core.status.replay || {}).replaying;
+}
+
+////// 回放 //////
+control.prototype.replay = function (force) {
+ if (!core.isPlaying() || !core.isReplaying()
+ || core.status.replay.animate || core.status.event.id || core.status.replay.failed) return;
+ if (core.status.replay.pausing && !force) return;
+ this._replay_drawProgress();
+ if (core.status.replay.toReplay.length == 0)
+ return this._replay_finished();
+ this._replay_save();
+ var action = core.status.replay.toReplay.shift();
+ if (this._doReplayAction(action)) return;
+ this._replay_error(action);
+}
+
+////// 注册一个录像行为 //////
+// name:自定义名称,可用于注销使用
+// func:具体执行录像的函数,可为一个函数或插件中的函数名;
+// 需要接受一个action参数,代表录像回放时的下一个操作
+// func返回true代表成功处理了此录像行为,false代表没有处理此录像行为。
+control.prototype.registerReplayAction = function (name, func) {
+ this.unregisterReplayAction(name);
+ this.replayActions.push({ name: name, func: func });
+}
+
+////// 注销一个录像行为 //////
+control.prototype.unregisterReplayAction = function (name) {
+ this.replayActions = this.replayActions.filter(function (b) { return b.name != name; });
+}
+
+////// 执行录像行为,会在注册的函数中依次执行直到得到true为止 //////
+control.prototype._doReplayAction = function (action) {
+ for (var i in this.replayActions) {
+ try {
+ if (core.doFunc(this.replayActions[i].func, this, action)) return true;
+ } catch (e) {
+ console.error(e);
+ console.error("ERROR in replayActions[" + this.replayActions[i].name + "]:已自动注销该项。");
+ core.unregisterReplayAction(this.replayActions[i].name);
+ }
+ }
+ return false;
+}
+
+control.prototype._replay_finished = function () {
+ core.status.replay.replaying = false;
+ core.status.replay.failed = false;
+ core.status.event.selection = 0;
+ var str = "录像播放完毕,你想退出播放吗?";
+ if (core.status.route.length != core.status.replay.totalList.length
+ || core.subarray(core.status.route, core.status.replay.totalList) == null) {
+ str = "录像播放完毕,但记录不一致。\n请检查录像播放时的二次记录问题。\n你想退出播放吗?";
+ }
+ core.ui.drawConfirmBox(str, function () {
+ core.ui.closePanel();
+ core.stopReplay(true);
+ }, function () {
+ core.status.replay.replaying = true;
+ core.ui.closePanel();
+ core.pauseReplay();
+ });
+}
+
+control.prototype._replay_save = function () {
+ core.status.replay.steps++;
+ if (core.status.replay.steps % 40 == 1) {
+ if (core.status.replay.save.length == 30)
+ core.status.replay.save.shift();
+ core.status.replay.save.push({
+ "data": core.saveData(), "replay": {
+ "totalList": core.cloneArray(core.status.replay.totalList),
+ "toReplay": core.cloneArray(core.status.replay.toReplay),
+ "steps": core.status.replay.steps
+ }
+ });
+ }
+}
+
+control.prototype._replay_error = function (action, callback) {
+ core.ui.closePanel();
+ core.status.replay.replaying = false;
+ core.status.replay.failed = true;
+ var len = core.status.replay.toReplay.length;
+ var prevList = core.status.replay.totalList.slice(-len - 11, -len - 1);
+ var nextList = core.status.replay.toReplay.slice(0, 10);
+ console.log("录像文件出错,当前操作:" + action);
+ console.log("之前的10个操作是:\n" + prevList.toString());
+ console.log("接下来10个操作是:\n" + nextList.toString());
+ core.ui.drawConfirmBox("录像文件出错,你想回到上个节点吗?", function () {
+ core.status.replay.failed = false;
+ core.ui.closePanel();
+ if (core.status.replay.save.length > 0) {
+ core.status.replay.replaying = true;
+ core.status.replay.pausing = true;
+ core.rewindReplay();
+ }
+ else {
+ core.playSound('操作失败');
+ core.stopReplay(true);
+ core.drawTip("无法回到上一个节点");
+ if (callback) callback();
+ }
+ }, function () {
+ core.status.replay.failed = false;
+ core.ui.closePanel();
+ core.stopReplay(true);
+ if (callback) callback();
+ });
+}
+
+control.prototype._replay_hideProgress = function () {
+ if (core.dymCanvas.replay) core.dymCanvas.replay.canvas.style.display = 'none';
+}
+
+control.prototype._replay_drawProgress = function () {
+ if (!core.dymCanvas.replay) return;
+ if (core.dymCanvas.replay.canvas.style.display == 'none') core.dymCanvas.replay.canvas.style.display = 'block';
+ var total = core.status.replay.totalList.length, left = total - core.status.replay.toReplay.length;
+ var content = '播放进度:' + left + ' / ' + total + '(' + (left / total * 100).toFixed(2) + '%)';
+ var width = 26 + core.calWidth('replay', content, "16px Arial");
+ core.clearMap('replay');
+ core.fillRect('replay', 0, 0, width, 40, '#000000');
+ core.fillText('replay', content, 16, 27, '#FFFFFF');
+}
+
+control.prototype.__replay_getTimeout = function () {
+ if (core.status.replay.speed == 24) return 0;
+ return 750 / Math.max(1, core.status.replay.speed);
+}
+
+control.prototype._replayAction_move = function (action) {
+ if (["up", "down", "left", "right"].indexOf(action) < 0) return false;
+ core.moveHero(action, core.replay);
+ return true;
+}
+
+control.prototype._replayAction_item = function (action) {
+ if (action.indexOf("item:") != 0) return false;
+ var itemId = action.substring(5);
+ if (!core.canUseItem(itemId)) return false;
+ if (core.material.items[itemId].hideInReplay || core.status.replay.speed == 24) {
+ core.useItem(itemId, false, core.replay);
+ return true;
+ }
+ var tools = core.getToolboxItems('tools'),
+ constants = core.getToolboxItems('constants');
+ var index, per = core.__SIZE__ - 1;
+ if ((index = tools.indexOf(itemId)) >= 0) {
+ core.status.event.data = { "toolsPage": Math.floor(index / per) + 1, "constantsPage": 1 };
+ index = index % per;
+ }
+ else if ((index = constants.indexOf(itemId)) >= 0) {
+ core.status.event.data = { "toolsPage": 1, "constantsPage": Math.floor(index / per) + 1 };
+ index = index % per + per;
+ }
+ if (index < 0) return false;
+ core.ui._drawToolbox(index);
+ setTimeout(function () {
+ core.ui.closePanel();
+ core.useItem(itemId, false, core.replay);
+ }, core.control.__replay_getTimeout());
+ return true;
+}
+
+control.prototype._replayAction_equip = function (action) {
+ if (action.indexOf("equip:") != 0) return false;
+ var equipId = action.substring(6);
+ var ownEquipment = core.getToolboxItems('equips');
+ var index = ownEquipment.indexOf(equipId), per = core.__SIZE__ - 1;
+ if (index < 0) {
+ core.removeFlag('__doNotCheckAutoEvents__');
+ return false;
+ }
+
+ var cb = function () {
+ var next = core.status.replay.toReplay[0] || "";
+ if (!next.startsWith('equip:') && !next.startsWith('unEquip:')) {
+ core.removeFlag('__doNotCheckAutoEvents__');
+ core.checkAutoEvents();
+ }
+ core.replay();
+ }
+ core.setFlag('__doNotCheckAutoEvents__', true);
+
+ core.status.route.push(action);
+ if (core.material.items[equipId].hideInReplay || core.status.replay.speed == 24) {
+ core.loadEquip(equipId, cb);
+ return true;
+ }
+ core.status.event.data = { "page": Math.floor(index / per) + 1, "selectId": null };
+ index = index % per + per;
+ core.ui._drawEquipbox(index);
+ setTimeout(function () {
+ core.ui.closePanel();
+ core.loadEquip(equipId, cb);
+ }, core.control.__replay_getTimeout());
+ return true;
+}
+
+control.prototype._replayAction_unEquip = function (action) {
+ if (action.indexOf("unEquip:") != 0) return false;
+ var equipType = parseInt(action.substring(8));
+ if (!core.isset(equipType)) {
+ core.removeFlag('__doNotCheckAutoEvents__');
+ return false;
+ }
+
+ var cb = function () {
+ var next = core.status.replay.toReplay[0] || "";
+ if (!next.startsWith('equip:') && !next.startsWith('unEquip:')) {
+ core.removeFlag('__doNotCheckAutoEvents__');
+ core.checkAutoEvents();
+ }
+ core.replay();
+ }
+ core.setFlag('__doNotCheckAutoEvents__', true);
+
+ core.ui._drawEquipbox(equipType);
+ core.status.route.push(action);
+ if (core.status.replay.speed == 24) {
+ core.unloadEquip(equipType, cb);
+ return true;
+ }
+ setTimeout(function () {
+ core.ui.closePanel();
+ core.unloadEquip(equipType, cb);
+ }, core.control.__replay_getTimeout());
+ return true;
+}
+
+control.prototype._replayAction_saveEquip = function (action) {
+ if (action.indexOf('saveEquip:') != 0) return false;
+ core.quickSaveEquip(parseInt(action.substring(10)));
+ core.replay();
+ return true;
+}
+
+control.prototype._replayAction_loadEquip = function (action) {
+ if (action.indexOf('loadEquip:') != 0) return false;
+ core.quickLoadEquip(parseInt(action.substring(10)));
+ core.replay();
+ return true;
+}
+
+control.prototype._replayAction_fly = function (action) {
+ if (action.indexOf("fly:") != 0) return false;
+ var floorId = action.substring(4);
+ var toIndex = core.floorIds.indexOf(floorId);
+ if (!core.canUseItem('fly') || (core.flags.flyNearStair && !core.nearStair())) return false;
+ core.ui.drawFly(toIndex);
+ if (core.status.replay.speed == 24) {
+ if (!core.flyTo(floorId, core.replay))
+ core.control._replay_error(action);
+ return true;
+ }
+ setTimeout(function () {
+ if (!core.flyTo(floorId, core.replay))
+ core.control._replay_error(action);
+ }, core.control.__replay_getTimeout());
+ return true;
+}
+
+control.prototype._replayAction_shop = function (action) {
+ if (action.indexOf("shop:") != 0) return false;
+ var shopId = action.substring(5);
+ if (core.canUseQuickShop(shopId) != null || !core.canOpenShop(shopId)) {
+ this._replay_error(shopId);
+ return true;
+ }
+ core.openShop(shopId, false);
+ core.replay();
+ return true;
+}
+
+control.prototype._replayAction_turn = function (action) {
+ if (action != 'turn' && action.indexOf('turn:') != 0) return false;
+ if (action == 'turn') core.turnHero();
+ else core.turnHero(action.substring(5));
+ core.replay();
+ return true;
+}
+
+control.prototype._replayAction_getNext = function (action) {
+ if (action != "getNext") return false;
+ core.getNextItem();
+ core.replay();
+ return true;
+}
+
+control.prototype._replayAction_moveDirectly = function (action) {
+ if (action.indexOf("move:") != 0) return false;
+
+ var pos = action.substring(5).split(":");
+ var x = parseInt(pos[0]), y = parseInt(pos[1]);
+ var nowx = core.getHeroLoc('x'), nowy = core.getHeroLoc('y');
+ var ignoreSteps = core.canMoveDirectly(x, y);
+ if (!core.moveDirectly(x, y, ignoreSteps)) return false;
+ if (core.status.replay.speed == 24) {
+ core.replay();
+ return true;
+ }
+
+ core.ui.drawArrow('ui', 32 * nowx + 16 - core.bigmap.offsetX, 32 * nowy + 16 - core.bigmap.offsetY,
+ 32 * x + 16 - core.bigmap.offsetX, 32 * y + 16 - core.bigmap.offsetY, '#FF0000', 3);
+ var timeout = this.__replay_getTimeout();
+ if (ignoreSteps < 10) timeout = timeout * ignoreSteps / 10;
+ setTimeout(function () {
+ core.clearMap('ui');
+ core.replay();
+ }, timeout);
+ return true;
+}
+
+control.prototype._replayAction_key = function (action) {
+ if (action.indexOf("key:") != 0) return false;
+ core.actions.keyUp(parseInt(action.substring(4)), false, true);
+ core.replay();
+ return true;
+}
+
+control.prototype._replayAction_click = function (action) {
+ if (action.indexOf("click:") != 0) return false;
+ var p = action.split(":");
+ if (p.length != 4) return false;
+ core.actions.doRegisteredAction("onStatusBarClick", parseInt(p[2]), parseInt(p[3]), parseInt(p[1]));
+ core.replay();
+ return true;
+}
+
+control.prototype._replayAction_ignoreInput = function (action) {
+ if (action.indexOf('input:') == 0 || action.indexOf('input2:') == 0 || action.indexOf('choices:') == 0 || action.indexOf('random:') == 0) {
+ console.warn('警告!录像播放中出现了未知的 ' + action + '!');
+ core.replay();
+ return true;
+ }
+ return false;
+}
+
+control.prototype._replayAction_no = function (action) {
+ if (action != 'no') return false;
+ core.status.route.push(action);
+ core.replay();
+ return true;
+}
+
+// ------ 存读档相关 ------ //
+
+////// 自动存档 //////
+control.prototype.autosave = function (removeLast) {
+ if (core.hasFlag('__forbidSave__')) return;
+ var x = null;
+ if (removeLast) {
+ x = core.status.route.pop();
+ core.status.route.push("turn:" + core.getHeroLoc('direction'));
+ }
+ if (core.status.event.id == 'action') // 事件中的自动存档
+ core.setFlag("__events__", core.clone(core.status.event.data));
+ if (core.saves.autosave.data == null) {
+ core.saves.autosave.data = [];
+ }
+ core.saves.autosave.data.splice(core.saves.autosave.now, 0, core.saveData());
+ core.saves.autosave.now += 1;
+ if (core.saves.autosave.data.length > core.saves.autosave.max) {
+ if (core.saves.autosave.now < core.saves.autosave.max / 2)
+ core.saves.autosave.data.pop();
+ else {
+ core.saves.autosave.data.shift();
+ core.saves.autosave.now = core.saves.autosave.now - 1;
+ }
+ }
+ core.saves.autosave.updated = true;
+ core.saves.ids[0] = true;
+ core.removeFlag("__events__");
+ if (removeLast) {
+ core.status.route.pop();
+ if (x) core.status.route.push(x);
+ }
+}
+
+/////// 实际进行自动存档 //////
+control.prototype.checkAutosave = function () {
+ if (!core.animateFrame || !core.saves || !core.saves.autosave) return;
+ core.setLocalStorage('totalTime', core.animateFrame.totalTime);
+ var autosave = core.saves.autosave;
+ if (autosave.data == null || !autosave.updated || !autosave.storage) return;
+ autosave.updated = false;
+ if (autosave.data.length >= 1) {
+ core.setLocalForage("autoSave", autosave.data[autosave.now - 1]);
+ }
+}
+
+////// 实际进行存读档事件 //////
+control.prototype.doSL = function (id, type) {
+ switch (type) {
+ case 'save': this._doSL_save(id); break;
+ case 'load': this._doSL_load(id, this._doSL_load_afterGet); break;
+ case 'reload': this._doSL_reload(id, this._doSL_load_afterGet); break;
+ case 'replayLoad': this._doSL_load(id, this._doSL_replayLoad_afterGet); break;
+ case 'replayRemain': this._doSL_load(id, this._doSL_replayRemain_afterGet); break;
+ case 'replaySince': this._doSL_load(id, this._doSL_replaySince_afterGet); break;
+ }
+}
+
+control.prototype._doSL_save = function (id) {
+ if (id == 'autoSave') {
+ core.playSound('操作失败');
+ return core.drawTip('不能覆盖自动存档!');
+ }
+ // 在事件中的存档
+ if (core.status.event.interval != null)
+ core.setFlag("__events__", core.status.event.interval);
+ var data = core.saveData();
+ if (core.isReplaying() && core.status.replay.toReplay.length > 0) {
+ data.__toReplay__ = core.encodeRoute(core.status.replay.toReplay);
+ }
+ core.setLocalForage("save" + id, data, function () {
+ core.saves.saveIndex = id;
+ core.setLocalStorage('saveIndex', core.saves.saveIndex);
+ // 恢复事件
+ if (!core.events.recoverEvents(core.status.event.interval))
+ core.ui.closePanel();
+ core.playSound('存档');
+ core.drawTip('存档成功!');
+ }, function (err) {
+ console.error(err);
+ alert("存档失败,错误信息:\n" + err);
+ });
+ core.removeFlag("__events__");
+ return;
+}
+
+control.prototype._doSL_load = function (id, callback) {
+ if (id == 'autoSave' && core.saves.autosave.data != null) {
+ core.saves.autosave.now -= 1;
+ var data = core.saves.autosave.data.splice(core.saves.autosave.now, 1)[0];
+ if (core.isPlaying() && !core.status.gameOver) {
+ core.control.autosave(0);
+ core.saves.autosave.now -= 1;
+ }
+ if (core.saves.autosave.now == 0) {
+ core.saves.autosave.data.unshift(core.clone(data));
+ core.saves.autosave.now += 1;
+ }
+ callback(id, data);
+ }
+ else {
+ core.getLocalForage(id == 'autoSave' ? id : "save" + id, null, function (data) {
+ if (id == 'autoSave' && data != null) {
+ core.saves.autosave.data = data;
+ if (!(core.saves.autosave.data instanceof Array)) {
+ core.saves.autosave.data = [core.saves.autosave.data];
+ }
+ core.saves.autosave.now = core.saves.autosave.data.length;
+ return core.control._doSL_load(id, callback);
+ }
+ callback(id, data);
+ }, function (err) {
+ console.error(err);
+ alert("无效的存档");
+ })
+ }
+ return;
+}
+
+control.prototype._doSL_reload = function (id, callback) {
+ if (core.saves.autosave.data != null && core.saves.autosave.now < core.saves.autosave.data.length) {
+ var data = core.saves.autosave.data.splice(core.saves.autosave.now, 1)[0];
+ core.control.autosave(false);
+ callback(id, data);
+ }
+ return;
+}
+
+control.prototype._doSL_load_afterGet = function (id, data) {
+ if (!data) return alert("无效的存档");
+ var _replay = function () {
+ core.startGame(data.hard, data.hero.flags.__seed__, core.decodeRoute(data.route));
+ };
+ if (data.version != core.firstData.version) {
+ core.myconfirm("存档版本不匹配!\n你想回放此存档的录像吗?\n可以随时停止录像播放以继续游戏。", _replay);
+ return;
+ }
+ if (data.hero.flags.__events__ && data.guid != core.getGuid()) {
+ core.myconfirm("此存档可能存在风险,你想要播放录像么?", _replay);
+ return;
+ }
+ core.ui.closePanel();
+ core.loadData(data, function () {
+ core.removeFlag('__fromLoad__');
+ core.drawTip("读档成功");
+ if (id != "autoSave") {
+ core.saves.saveIndex = id;
+ core.setLocalStorage('saveIndex', core.saves.saveIndex);
+ }
+ });
+}
+
+control.prototype._doSL_replayLoad_afterGet = function (id, data) {
+ if (!data) {
+ core.playSound('操作失败');
+ return core.drawTip("无效的存档");
+ }
+ if (data.version != core.firstData.version) {
+ core.playSound('操作失败');
+ return core.drawTip("存档版本不匹配");
+ }
+ if (data.hero.flags.__events__ && data.guid != core.getGuid()) {
+ core.playSound('操作失败');
+ return core.drawTip("此存档可能存在风险,无法读档");
+ }
+ var route = core.subarray(core.status.route, core.decodeRoute(data.route));
+ if (route == null) {
+ core.playSound('操作失败');
+ return core.drawTip("无法从此存档回放录像");
+ }
+ core.loadData(data, function () {
+ core.removeFlag('__fromLoad__');
+ core.startReplay(route);
+ core.drawTip("回退到存档节点");
+ });
+}
+
+control.prototype._doSL_replayRemain_afterGet = function (id, data) {
+ if (!data) {
+ core.playSound('操作失败');
+ return core.drawTip("无效的存档");
+ }
+ var route = core.decodeRoute(data.route);
+ if (core.status.tempRoute) {
+ var remainRoute = core.subarray(route, core.status.tempRoute);
+ if (remainRoute == null)
+ return alert("无法接续播放录像!\n该存档必须是前一个选择的存档的后续内容。");
+ delete core.status.tempRoute;
+ core.ui.closePanel();
+ core.startReplay(remainRoute);
+ core.drawTip("接续播放录像");
+ return;
+ }
+ else if (data.floorId != core.status.floorId || data.hero.loc.x != core.getHeroLoc('x') || data.hero.loc.y != core.getHeroLoc('y'))
+ return alert("楼层或坐标不一致!");
+
+ core.status.tempRoute = route;
+ core.ui.closePanel();
+ core.drawText("\t[步骤2]请选择第二个存档。\n\r[yellow]该存档必须是前一个存档的后续。\r\n将尝试播放到此存档。", function () {
+ core.status.event.id = 'replayRemain';
+ core.lockControl();
+ var saveIndex = core.saves.saveIndex;
+ var page = parseInt((saveIndex - 1) / 5), offset = saveIndex - 5 * page;
+ core.ui._drawSLPanel(10 * page + offset);
+ });
+}
+
+control.prototype._doSL_replaySince_afterGet = function (id, data) {
+ if (data.floorId != core.status.floorId || data.hero.loc.x != core.getHeroLoc('x') || data.hero.loc.y != core.getHeroLoc('y'))
+ return alert("楼层或坐标不一致!");
+ if (!data.__toReplay__) return alert('该存档没有剩余录像!');
+ core.ui.closePanel();
+ core.startReplay(core.decodeRoute(data.__toReplay__));
+ core.drawTip("播放存档剩余录像");
+ return;
+}
+
+////// 同步存档到服务器 //////
+control.prototype.syncSave = function (type) {
+ core.ui.drawWaiting("正在同步,请稍候...");
+ var callback = function (saves) {
+ core.control._syncSave_http(type, saves);
+ }
+ if (type == 'all') core.getAllSaves(callback);
+ else core.getSave(core.saves.saveIndex, callback);
+}
+
+control.prototype._syncSave_http = function (type, saves) {
+ if (!saves) return core.drawText("没有要同步的存档");
+ var formData = new FormData();
+ formData.append('type', 'save');
+ formData.append('name', core.firstData.name);
+ formData.append('data', LZString.compressToBase64(JSON.stringify(saves)));
+ formData.append('shorten', '1');
+
+ core.http("POST", "/games/sync.php", formData, function (data) {
+ var response = JSON.parse(data);
+ if (response.code < 0) {
+ core.drawText("出错啦!\n无法同步存档到服务器。\n错误原因:" + response.msg);
+ }
+ else {
+ core.drawText((type == 'all' ? "所有存档" : "存档" + core.saves.saveIndex) + "同步成功!\n\n您的存档编号+密码: \r[yellow]"
+ + response.code + response.msg
+ + "\r\n\n请牢记以上信息(如截图等),在从服务器\n同步存档时使用。\n\r[yellow]另外请注意,存档同步只会保存一个月的时间。\r")
+ }
+ }, function (e) {
+ core.drawText("出错啦!\n无法同步存档到服务器。\n错误原因:" + e);
+ })
+}
+
+////// 从服务器加载存档 //////
+control.prototype.syncLoad = function () {
+ core.myprompt("请输入存档编号+密码", null, function (idpassword) {
+ if (!idpassword) return core.ui._drawSyncSave();
+ if (!/^\d{6}\w{4}$/.test(idpassword) && !/^\d{4}\w{3}$/.test(idpassword)) {
+ core.drawText("不合法的存档编号+密码!");
+ return;
+ }
+ core.ui.drawWaiting("正在同步,请稍候...");
+ if (idpassword.length == 7) {
+ core.control._syncLoad_http(idpassword.substring(0, 4), idpassword.substring(4));
+ } else {
+ core.control._syncLoad_http(idpassword.substring(0, 6), idpassword.substring(6));
+ }
+ });
+}
+
+control.prototype._syncLoad_http = function (id, password) {
+ var formData = new FormData();
+ formData.append('type', 'load');
+ formData.append('name', core.firstData.name);
+ formData.append('id', id);
+ formData.append('password', password);
+
+ core.http("POST", "/games/sync.php", formData, function (data) {
+ var response = JSON.parse(data);
+ if (response.code == 0) {
+ var msg = null;
+ try {
+ msg = JSON.parse(LZString.decompressFromBase64(response.msg));
+ } catch (e) { }
+ if (!msg) {
+ try {
+ msg = JSON.parse(response.msg);
+ } catch (e) { }
+ }
+ if (msg) {
+ core.control._syncLoad_write(msg);
+ } else {
+ core.drawText("出错啦!\n存档解析失败!");
+ }
+ }
+ else {
+ core.drawText("出错啦!\n无法从服务器同步存档。\n错误原因:" + response.msg);
+ }
+ }, function (e) {
+ core.drawText("出错啦!\n无法从服务器同步存档。\n错误原因:" + e);
+ });
+}
+
+control.prototype._syncLoad_write = function (data) {
+ if (data instanceof Array) {
+ core.status.event.selection = 1;
+ core.ui.drawConfirmBox("所有本地存档都将被覆盖,确认?", function () {
+ for (var i = 1; i <= 5 * (main.savePages || 30); i++) {
+ if (i <= data.length)
+ core.setLocalForage("save" + i, data[i - 1]);
+ else if (core.saves.ids[i])
+ core.removeLocalForage("save" + i);
+ }
+ core.ui.closePanel();
+ core.drawText("同步成功!\n你的本地所有存档均已被覆盖。");
+ }, function () {
+ core.status.event.selection = 0;
+ core.ui._drawSyncSave();
+ });
+ }
+ else {
+ // 只覆盖单存档
+ core.setLocalForage("save" + core.saves.saveIndex, data, function () {
+ core.drawText("同步成功!\n单存档已覆盖至存档" + core.saves.saveIndex);
+ });
+ }
+}
+
+////// 存档到本地 //////
+control.prototype.saveData = function () {
+ return this.controldata.saveData();
+}
+
+////// 从本地读档 //////
+control.prototype.loadData = function (data, callback) {
+ return this.controldata.loadData(data, callback);
+}
+
+control.prototype.getSave = function (index, callback) {
+ if (index == 0) {
+ // --- 自动存档先从缓存中获取
+ if (core.saves.autosave.data != null)
+ callback(core.saves.autosave.data);
+ else {
+ core.getLocalForage("autoSave", null, function (data) {
+ if (data != null) {
+ core.saves.autosave.data = data;
+ if (!(core.saves.autosave.data instanceof Array)) {
+ core.saves.autosave.data = [core.saves.autosave.data];
+ }
+ core.saves.autosave.now = core.saves.autosave.data.length;
+ }
+ callback(core.saves.autosave.data);
+ }, function (err) {
+ console.error(err);
+ callback(null);
+ });
+ }
+ return;
+ }
+ core.getLocalForage("save" + index, null, function (data) {
+ if (callback) callback(data);
+ }, function (err) {
+ console.error(err);
+ if (callback) callback(null);
+ });
+}
+
+control.prototype.getSaves = function (ids, callback) {
+ if (!(ids instanceof Array)) return this.getSave(ids, callback);
+ var count = ids.length, data = {};
+ for (var i = 0; i < ids.length; ++i) {
+ (function (i) {
+ core.getSave(ids[i], function (result) {
+ data[i] = result;
+ if (Object.keys(data).length == count)
+ callback(data);
+ })
+ })(i);
+ }
+}
+
+control.prototype.getAllSaves = function (callback) {
+ var ids = Object.keys(core.saves.ids).filter(function (x) { return x != 0; })
+ .sort(function (a, b) { return a - b; }), saves = [];
+ this.getSaves(ids, function (data) {
+ for (var i = 0; i < ids.length; ++i) {
+ if (data[i] != null)
+ saves.push(data[i]);
+ }
+ callback(saves);
+ });
+}
+
+////// 获得所有存在存档的存档位 //////
+control.prototype.getSaveIndexes = function (callback) {
+ var indexes = {};
+ core.keysLocalForage(function (err, keys) {
+ if (err) {
+ console.error(err);
+ return callback(indexes);
+ }
+ keys.forEach(function (key) {
+ core.control._getSaveIndexes_getIndex(indexes, key);
+ });
+ callback(indexes);
+ });
+}
+
+control.prototype._getSaveIndexes_getIndex = function (indexes, name) {
+ var e = new RegExp('^' + core.firstData.name + "_(save\\d+|autoSave)$").exec(name);
+ if (e) {
+ if (e[1] == 'autoSave') indexes[0] = true;
+ else indexes[parseInt(e[1].substring(4))] = true;
+ }
+}
+
+////// 判断某个存档位是否存在存档 //////
+control.prototype.hasSave = function (index) {
+ return core.saves.ids[index] || false;
+}
+
+////// 删除某个存档
+control.prototype.removeSave = function (index, callback) {
+ if (index == 0 || index == "autoSave") {
+ index = "autoSave";
+ core.removeLocalForage(index, function () {
+ core.saves.autosave.data = null;
+ core.saves.autosave.updated = false;
+ if (callback) callback();
+ });
+ return;
+ }
+ core.removeLocalForage("save" + index, function () {
+ core.saves.favorite = core.saves.favorite.filter(function (i) { return core.hasSave(i); });
+ delete core.saves.favoriteName[index];
+ core.control._updateFavoriteSaves();
+ if (callback) callback();
+ }, function () {
+ core.playSound('操作失败');
+ core.drawTip("无法删除存档!");
+ if (callback) callback();
+ });
+}
+
+////// 读取收藏信息
+control.prototype._loadFavoriteSaves = function () {
+ core.saves.favorite = core.getLocalStorage("favorite", []);
+ // --- 移除不存在的收藏
+ core.saves.favorite = core.saves.favorite.filter(function (i) { return core.hasSave(i); });
+ core.saves.favoriteName = core.getLocalStorage("favoriteName", {});
+}
+
+control.prototype._updateFavoriteSaves = function () {
+ core.setLocalStorage("favorite", core.saves.favorite);
+ core.setLocalStorage("favoriteName", core.saves.favoriteName);
+}
+
+// ------ 属性,状态,位置,buff,变量,锁定控制等 ------ //
+
+////// 设置勇士属性 //////
+control.prototype.setStatus = function (name, value) {
+ if (!core.status.hero) return;
+ if (name == 'x' || name == 'y' || name == 'direction')
+ this.setHeroLoc(name, value);
+ else
+ core.status.hero[name] = value;
+}
+
+////// 增减勇士属性 //////
+control.prototype.addStatus = function (name, value) {
+ this.setStatus(name, this.getStatus(name) + value);
+}
+
+////// 获得勇士属性 //////
+control.prototype.getStatus = function (name) {
+ if (!core.status.hero) return null;
+ if (name == 'x' || name == 'y' || name == 'direction')
+ return this.getHeroLoc(name);
+ if (main.mode == 'editor' && !core.hasFlag('__statistics__')) {
+ return data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.firstData.hero[name];
+ }
+ return core.status.hero[name];
+}
+
+////// 从status中获得属性,如果不存在则从勇士属性中获取 //////
+control.prototype.getStatusOrDefault = function (status, name) {
+ if (status && name in status)
+ return Math.floor(status[name]);
+ return Math.floor(this.getStatus(name));
+}
+
+////// 获得勇士实际属性(增幅后的) //////
+control.prototype.getRealStatus = function (name) {
+ return this.getRealStatusOrDefault(null, name);
+}
+
+////// 从status中获得实际属性(增幅后的),如果不存在则从勇士属性中获取 //////
+control.prototype.getRealStatusOrDefault = function (status, name) {
+ return Math.floor(this.getStatusOrDefault(status, name) * this.getBuff(name));
+}
+
+////// 获得勇士原始属性(无装备和衰弱影响) //////
+control.prototype.getNakedStatus = function (name) {
+ var value = this.getStatus(name);
+ if (value == null) return value;
+ // 装备增幅
+ core.status.hero.equipment.forEach(function (v) {
+ if (!v || !(core.material.items[v] || {}).equip) return;
+ value -= core.material.items[v].equip.value[name] || 0;
+ });
+ // 衰弱扣除
+ if (core.hasFlag('weak') && core.values.weakValue >= 1 && (name == 'atk' || name == 'def')) {
+ value += core.values.weakValue;
+ }
+ return value;
+}
+
+////// 获得某个属性的名字 //////
+control.prototype.getStatusLabel = function (name) {
+ if (this.controldata.getStatusLabel) {
+ return this.controldata.getStatusLabel(name) || name;
+ }
+ return {
+ name: "名称", lv: "等级", hpmax: "生命上限", hp: "生命", manamax: "魔力上限", mana: "魔力",
+ atk: "攻击", def: "防御", mdef: "护盾", money: "金币", exp: "经验", point: "加点", steps: "步数"
+ }[name] || name;
+}
+
+////// 设置某个属性的增幅值 //////
+control.prototype.setBuff = function (name, value) {
+ // 仅保留三位有效buff值
+ value = parseFloat(value.toFixed(3));
+ this.setFlag('__' + name + '_buff__', value);
+}
+
+////// 加减某个属性的增幅值 //////
+control.prototype.addBuff = function (name, value) {
+ var buff = this.getBuff(name) + value;
+ // 仅保留三位有效buff值
+ buff = parseFloat(buff.toFixed(3));
+ this.setFlag('__' + name + '_buff__', buff);
+}
+
+////// 获得某个属性的增幅值 //////
+control.prototype.getBuff = function (name) {
+ return core.getFlag('__' + name + '_buff__', 1);
+}
+
+////// 获得或移除毒衰咒效果 //////
+control.prototype.triggerDebuff = function (action, type) {
+ return this.controldata.triggerDebuff(action, type);
+}
+
+////// 设置勇士的位置 //////
+control.prototype.setHeroLoc = function (name, value, noGather) {
+ if (!core.status.hero) return;
+ core.status.hero.loc[name] = value;
+ if ((name == 'x' || name == 'y') && !noGather) {
+ this.gatherFollowers();
+ }
+}
+
+////// 获得勇士的位置 //////
+control.prototype.getHeroLoc = function (name) {
+ if (!core.status.hero) return;
+ if (main.mode == 'editor') {
+ if (name == null) return data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.firstData.hero.loc;
+ return data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.firstData.hero.loc[name];
+ }
+ if (name == null) return core.status.hero.loc;
+ return core.status.hero.loc[name];
+}
+
+////// 获得某个等级的名称 //////
+control.prototype.getLvName = function (lv) {
+ if (!core.status.hero) return null;
+ if (lv == null) lv = core.status.hero.lv;
+ return ((core.firstData.levelUp || [])[lv - 1] || {}).title || lv;
+}
+
+////// 获得下个等级所需经验;如果不存在下个等级,返回null。 //////
+control.prototype.getNextLvUpNeed = function () {
+ if (!core.status.hero) return null;
+ if (core.status.hero.lv >= core.firstData.levelUp.length) return null;
+ var need = core.calValue(core.firstData.levelUp[core.status.hero.lv].need);
+ if (core.flags.statusBarItems.indexOf('levelUpLeftMode') >= 0)
+ return Math.max(need - core.getStatus('exp'), 0);
+ else return need;
+}
+
+////// 设置某个自定义变量或flag //////
+control.prototype.setFlag = function (name, value) {
+ if (value == null) return this.removeFlag(name);
+ if (!core.status.hero) return;
+ core.status.hero.flags[name] = value;
+}
+
+////// 增加某个flag数值 //////
+control.prototype.addFlag = function (name, value) {
+ if (!core.status.hero) return;
+ core.setFlag(name, core.getFlag(name, 0) + value);
+}
+
+////// 获得某个自定义变量或flag //////
+control.prototype.getFlag = function (name, defaultValue) {
+ if (!core.status.hero) return defaultValue;
+ var value = core.status.hero.flags[name];
+ return value != null ? value : defaultValue;
+}
+
+////// 是否存在某个自定义变量或flag,且值为true //////
+control.prototype.hasFlag = function (name) {
+ return !!core.getFlag(name);
+}
+
+////// 删除某个自定义变量或flag //////
+control.prototype.removeFlag = function (name) {
+ if (!core.status.hero) return;
+ delete core.status.hero.flags[name];
+}
+
+////// 获得某个点的独立开关 //////
+control.prototype.getSwitch = function (x, y, floorId, name, defaultValue) {
+ var prefix = [floorId || core.status.floorId || ":f", x != null ? x : "x", y != null ? y : "y"].join("@");
+ return this.getFlag(prefix + "@" + name, defaultValue);
+}
+
+////// 设置某个点的独立开关 //////
+control.prototype.setSwitch = function (x, y, floorId, name, value) {
+ var prefix = [floorId || core.status.floorId || ":f", x != null ? x : "x", y != null ? y : "y"].join("@");
+ return this.setFlag(prefix + "@" + name, value);
+}
+
+////// 增加某个点的独立开关 //////
+control.prototype.addSwitch = function (x, y, floorId, name, value) {
+ var prefix = [floorId || core.status.floorId || ":f", x != null ? x : "x", y != null ? y : "y"].join("@");
+ return this.addFlag(prefix + "@" + name, value);
+}
+
+////// 判定某个点的独立开关 //////
+control.prototype.hasSwitch = function (x, y, floorId, name) {
+ var prefix = [floorId || core.status.floorId || ":f", x != null ? x : "x", y != null ? y : "y"].join("@");
+ return this.hasFlag(prefix + "@" + name);
+}
+
+////// 删除某个点的独立开关 //////
+control.prototype.removeSwitch = function (x, y, floorId, name) {
+ var prefix = [floorId || core.status.floorId || ":f", x != null ? x : "x", y != null ? y : "y"].join("@");
+ return this.removeFlag(prefix + "@" + name);
+}
+
+////// 锁定状态栏,常常用于事件处理 //////
+control.prototype.lockControl = function () {
+ core.status.lockControl = true;
+}
+
+////// 解锁状态栏 //////
+control.prototype.unlockControl = function () {
+ core.status.lockControl = false;
+}
+
+////// 开启debug模式 //////
+control.prototype.debug = function () {
+ core.setFlag('debug', true);
+ core.drawText("\t[调试模式开启]此模式下按住Ctrl键(或Ctrl+Shift键)可以穿墙并忽略一切事件。\n此模式下将无法上传成绩。");
+}
+
+control.prototype._bindRoutePush = function () {
+ core.status.route.push = function (element) {
+ // 忽视移动、转向、瞬移
+ if (["up", "down", "left", "right", "turn"].indexOf(element) < 0 && !element.startsWith("move:")) {
+ core.clearRouteFolding();
+ }
+ Array.prototype.push.call(core.status.route, element);
+ }
+}
+
+////// 清除录像折叠信息 //////
+control.prototype.clearRouteFolding = function () {
+ core.status.routeFolding = {};
+}
+
+////// 检查录像折叠 //////
+control.prototype.checkRouteFolding = function () {
+ // 未开启、未开始游戏、录像播放中、正在事件中:不执行
+ if (!core.flags.enableRouteFolding || !core.isPlaying() || core.isReplaying() || core.status.event.id) {
+ return this.clearRouteFolding();
+ }
+ var hero = core.clone(core.status.hero, function (name, value) {
+ return name != 'steps' && typeof value == 'number';
+ });
+ var index = [core.getHeroLoc('x'), core.getHeroLoc('y'), core.getHeroLoc('direction').charAt(0)].join(',');
+ core.status.routeFolding = core.status.routeFolding || {};
+ if (core.status.routeFolding[index]) {
+ var one = core.status.routeFolding[index];
+ if (core.same(one.hero, hero) && one.length < core.status.route.length) {
+ Object.keys(core.status.routeFolding).forEach(function (v) {
+ if (core.status.routeFolding[v].length >= one.length) delete core.status.routeFolding[v];
+ });
+ core.status.route = core.status.route.slice(0, one.length);
+ this._bindRoutePush();
+ }
+ }
+ core.status.routeFolding[index] = { hero: hero, length: core.status.route.length };
+}
+
+// ------ 天气,色调,BGM ------ //
+
+control.prototype.getMappedName = function (name) {
+ return core.getFlag('__nameMap__', {})[name] || (main.nameMap || {})[name] || name;
+}
+
+////// 更改天气效果 //////
+control.prototype.setWeather = function (type, level) {
+ // 非雨雪
+ if (type == null || !this.weathers[type]) {
+ core.deleteCanvas('weather')
+ core.animateFrame.weather.type = null;
+ core.animateFrame.weather.nodes = [];
+ return;
+ }
+ if (level == null) level = core.animateFrame.weather.level;
+ level = core.clamp(parseInt(level) || 5, 1, 10);
+ // 当前天气:则忽略
+ if (type == core.animateFrame.weather.type && level == core.animateFrame.weather.level) return;
+
+ // 计算当前的宽高
+ core.createCanvas('weather', 0, 0, core.__PIXELS__, core.__PIXELS__, 80);
+ core.setOpacity('weather', 1.0);
+ core.animateFrame.weather.type = type;
+ core.animateFrame.weather.level = level;
+ core.animateFrame.weather.nodes = [];
+ try {
+ core.doFunc(this.weathers[type].initFunc, this, level);
+ } catch (e) {
+ console.error(e);
+ console.error("ERROR in weather[" + type + "]:已自动注销该项。");
+ core.unregisterWeather(type);
+ }
+}
+
+////// 注册一个天气 //////
+// name为天气类型,如 sun, rain, snow 等
+// initFunc 为设置为此天气时的初始化,接受level参数
+// frameFunc 为该天气下每帧的效果,接受和timestamp参数(从页面加载完毕到当前经过的时间)
+control.prototype.registerWeather = function (name, initFunc, frameFunc) {
+ this.unregisterWeather(name);
+ this.weathers[name] = { initFunc: initFunc, frameFunc: frameFunc };
+}
+
+////// 取消注册一个天气 //////
+control.prototype.unregisterWeather = function (name) {
+ delete this.weathers[name];
+ if (core.animateFrame.weather.type == name) {
+ this.setWeather(null);
+ }
+}
+
+control.prototype._weather_rain = function (level) {
+ var number = level * parseInt(20 * core.bigmap.width * core.bigmap.height / (core.__SIZE__ * core.__SIZE__));
+ for (var a = 0; a < number; a++) {
+ core.animateFrame.weather.nodes.push({
+ 'x': Math.random() * core.bigmap.width * 32,
+ 'y': Math.random() * core.bigmap.height * 32,
+ 'l': Math.random() * 2.5,
+ 'xs': -4 + Math.random() * 4 + 2,
+ 'ys': Math.random() * 10 + 10
+ })
+ }
+}
+
+control.prototype._weather_snow = function (level) {
+ var number = level * parseInt(20 * core.bigmap.width * core.bigmap.height / (core.__SIZE__ * core.__SIZE__));
+ for (var a = 0; a < number; a++) {
+ core.animateFrame.weather.nodes.push({
+ 'x': Math.random() * core.bigmap.width * 32,
+ 'y': Math.random() * core.bigmap.height * 32,
+ 'r': Math.random() * 5 + 1,
+ 'd': Math.random() * Math.min(level, 200),
+ })
+ }
+}
+
+control.prototype._weather_fog = function (level) {
+ if (!core.animateFrame.weather.fog) return;
+ core.animateFrame.weather.nodes = [{
+ 'image': core.animateFrame.weather.fog,
+ 'level': 40 * level,
+ 'x': 0,
+ 'y': -core.__PIXELS__ / 2,
+ 'dx': -Math.random() * 1.5,
+ 'dy': Math.random(),
+ 'delta': 0.001,
+ }];
+}
+
+control.prototype._weather_cloud = function (level) {
+ if (!core.animateFrame.weather.cloud) return;
+ core.animateFrame.weather.nodes = [{
+ 'image': core.animateFrame.weather.cloud,
+ 'level': 40 * level,
+ 'x': 0,
+ 'y': -core.__PIXELS__ / 2,
+ 'dx': -Math.random() * 1.5,
+ 'dy': Math.random(),
+ 'delta': 0.001,
+ }];
+}
+
+control.prototype._weather_sun = function (level) {
+ if (!core.animateFrame.weather.sun) return;
+ // 直接绘制
+ core.clearMap('weather');
+ core.drawImage('weather', core.animateFrame.weather.sun, 0, 0, core.animateFrame.weather.sun.width, core.animateFrame.weather.sun.height, 0, 0, core.__PIXELS__, core.__PIXELS__);
+ core.setOpacity('weather', level / 10);
+ core.animateFrame.weather.nodes = [{ opacity: level / 10, delta: 0.01 }];
+}
+
+////// 更改画面色调 //////
+control.prototype.setCurtain = function (color, time, moveMode, callback) {
+ if (time == null) time = 750;
+ if (time <= 0) time = 0;
+ if (!core.status.curtainColor)
+ core.status.curtainColor = [0, 0, 0, 0];
+ if (!color) color = [0, 0, 0, 0];
+ if (color[3] == null) color[3] = 1;
+ color[3] = core.clamp(color[3], 0, 1);
+
+ if (time == 0) {
+ // 直接变色
+ core.clearMap('curtain');
+ core.fillRect('curtain', 0, 0, core.__PIXELS__, core.__PIXELS__, core.arrayToRGBA(color));
+ core.status.curtainColor = color;
+ if (callback) callback();
+ return;
+ }
+
+ this._setCurtain_animate(core.status.curtainColor, color, time, moveMode, callback);
+}
+
+control.prototype._setCurtain_animate = function (nowColor, color, time, moveMode, callback) {
+ time /= Math.max(core.status.replay.speed, 1)
+ var per_time = 10, step = 0, steps = parseInt(time / per_time);
+ if (steps <= 0) steps = 1;
+ var curr = nowColor;
+ var moveFunc = core.applyEasing(moveMode);
+
+ var cb = function () {
+ core.status.curtainColor = curr;
+ if (callback) callback();
+ }
+ var animate = setInterval(function () {
+ step++;
+ curr = [
+ nowColor[0] + (color[0] - nowColor[0]) * moveFunc(step / steps),
+ nowColor[1] + (color[1] - nowColor[1]) * moveFunc(step / steps),
+ nowColor[2] + (color[2] - nowColor[2]) * moveFunc(step / steps),
+ nowColor[3] + (color[3] - nowColor[3]) * moveFunc(step / steps),
+ ]
+ core.clearMap('curtain');
+ core.fillRect('curtain', 0, 0, core.__PIXELS__, core.__PIXELS__, core.arrayToRGBA(curr));
+ if (step == steps) {
+ delete core.animateFrame.asyncId[animate];
+ clearInterval(animate);
+ cb();
+ }
+ }, per_time);
+
+ core.animateFrame.lastAsyncId = animate;
+ core.animateFrame.asyncId[animate] = cb;
+}
+
+////// 画面闪烁 //////
+control.prototype.screenFlash = function (color, time, times, moveMode, callback) {
+ times = times || 1;
+ time = time / 3;
+ var nowColor = core.clone(core.status.curtainColor);
+ core.setCurtain(color, time, moveMode, function () {
+ core.setCurtain(nowColor, time * 2, moveMode, function () {
+ if (times > 1)
+ core.screenFlash(color, time * 3, times - 1, moveMode, callback);
+ else {
+ if (callback) callback();
+ }
+ });
+ });
+}
+
+////// 播放背景音乐 //////
+control.prototype.playBgm = function (bgm, startTime) {
+ bgm = core.getMappedName(bgm);
+ if (main.mode != 'play' || !core.material.bgms[bgm]) return;
+ // 如果不允许播放
+ if (!core.musicStatus.bgmStatus) {
+ try {
+ core.musicStatus.playingBgm = bgm;
+ core.musicStatus.lastBgm = bgm;
+ core.material.bgms[bgm].pause();
+ }
+ catch (e) {
+ console.error(e);
+ }
+ return;
+ }
+ this.setMusicBtn();
+
+ try {
+ this._playBgm_play(bgm, startTime);
+ }
+ catch (e) {
+ console.log("无法播放BGM " + bgm);
+ console.error(e);
+ core.musicStatus.playingBgm = null;
+ }
+}
+
+control.prototype._playBgm_play = function (bgm, startTime) {
+ // 如果当前正在播放,且和本BGM相同,直接忽略
+ if (core.musicStatus.playingBgm == bgm && !core.material.bgms[core.musicStatus.playingBgm].paused) {
+ return;
+ }
+ // 如果正在播放中,暂停
+ if (core.musicStatus.playingBgm) {
+ core.material.bgms[core.musicStatus.playingBgm].pause();
+ }
+ // 缓存BGM
+ core.loader.loadBgm(bgm);
+ // 播放当前BGM
+ core.material.bgms[bgm].volume = core.musicStatus.userVolume * core.musicStatus.designVolume;
+ core.material.bgms[bgm].currentTime = startTime || 0;
+ core.material.bgms[bgm].play();
+ core.musicStatus.playingBgm = bgm;
+ core.musicStatus.lastBgm = bgm;
+ core.setBgmSpeed(100);
+}
+
+///// 设置当前背景音乐的播放速度 //////
+control.prototype.setBgmSpeed = function (speed, usePitch) {
+ var bgm = core.musicStatus.playingBgm;
+ if (main.mode != 'play' || !core.material.bgms[bgm]) return;
+ bgm = core.material.bgms[bgm];
+ if (speed < 30 || speed > 300) return;
+ bgm.playbackRate = speed / 100;
+ core.musicStatus.bgmSpeed = speed;
+
+ if (bgm.preservesPitch != null) {
+ if (bgm.__preservesPitch == null) bgm.__preservesPitch = bgm.preservesPitch;
+ if (usePitch == null) bgm.preservesPitch = bgm.__preservesPitch;
+ else if (usePitch) bgm.preservesPitch = false;
+ else bgm.preservesPitch = true;
+ core.musicStatus.bgmUsePitch = usePitch;
+ }
+}
+
+////// 暂停背景音乐的播放 //////
+control.prototype.pauseBgm = function () {
+ if (main.mode != 'play') return;
+ try {
+ if (core.musicStatus.playingBgm) {
+ core.musicStatus.pauseTime = core.material.bgms[core.musicStatus.playingBgm].currentTime;
+ core.material.bgms[core.musicStatus.playingBgm].pause();
+ core.musicStatus.playingBgm = null;
+ }
+ }
+ catch (e) {
+ console.log("无法暂停BGM");
+ console.error(e);
+ }
+ this.setMusicBtn();
+}
+
+////// 恢复背景音乐的播放 //////
+control.prototype.resumeBgm = function (resumeTime) {
+ if (main.mode != 'play') return;
+ try {
+ var speed = core.musicStatus.bgmSpeed;
+ var usePitch = core.musicStatus.bgmUsePitch;
+ core.playBgm(core.musicStatus.playingBgm || core.musicStatus.lastBgm || main.startBgm,
+ resumeTime ? core.musicStatus.pauseTime : 0);
+ if (resumeTime) {
+ core.setBgmSpeed(speed, usePitch);
+ }
+ }
+ catch (e) {
+ console.log("无法恢复BGM");
+ console.error(e);
+ }
+ this.setMusicBtn();
+}
+
+control.prototype.setMusicBtn = function () {
+ if (core.musicStatus.bgmStatus)
+ core.dom.musicBtn.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAMAAADzN3VRAAABWVBMVEX///9iYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmL///8AAAC5ubn+/v6xsbEtLS0MDAxmZmZoaGhvb2/c3Nzd3d38/Pz9/f0oKCgpKSl0dHR1dXW6urrb29v7+/v09PTv7+/39/cgICACAgImJibh4eGFhYWGhoaHh4eOjo5paWm7u7vDw8PMzMwyMjI7OztAQEDe3t5FRUVMTEzj4+Pl5eXm5ubp6enr6+tcXFzi4uL19fVeXl74+PgjIyNkZGQGBgaSkpKYmJiampqenp4DAwMwMDBnZ2cICAivr68eHh63t7cLCwsSEhLw8PBhYWEUFBQVFRXNzc3Pz8/Z2dna2toaGhqkpKSlpaWpqamrq6tFOUNAAAAAc3RSTlMAAwQFBhUWGxwkJSYyO0dISVBRUmpvj5CSk5SVoaOlpqiysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKyA0IuUgAAAVdJREFUeF5NkVVbw0AQRTcQrLR4IIEGcidJoaUuQHF3d3d3+P/CkuxCzss8nG++mbnDBJXhNt2CpbeFK1kQpSEKidlc8S9qdATRa6UIdQMoxEpDA0Ov3wUAPfW+qLWACydNv9zMrzkJwPK6FB3oHyOfXfuNxvoBQ+GmBYinhHB77TmiVBxoYUw1AYcEq332AS8OYKosAuTT0nza9uU2USYPRJgGxEiSOFywJ3mNARozgBJJzkfLvfu8JgGDWcC9FEsjWzR+y80gYDEAA8QZ3N6kmP1Fs3fEASB7pob7Hh+Wz5L0ci17Or05J7bH6B6dZv05XWK3rG+myV05Ert592Qo55sPuoIr7hEZHHtieIPWy0RU9DLwc3Mnck/vi8/E8XNrDWQtEVnL/ySKMrv0jPwPp870fprcyYifmiEmqGpHkI5q9ofSFIUk2qiwIGpEMyxYhhZRRcMPz89RJ2s9W8wAAAAASUVORK5CYII=";
+ else
+ core.dom.musicBtn.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAMAAADzN3VRAAABYlBMVEX///9iYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmL////8/PwAAABmZmZoaGihoaGioqKxsbG5ubnb29vc3Nzd3d3h4eHi4uL9/f3+/v4tLS1nZ2d0dHSUlJSenp66uroMDAz7+/spKSkoKCgUFBRpaWkVFRVvb291dXU7OzuVlZWYmJhkZGQgICAjIyOkpKQCAgK3t7cGBgbv7++pqamrq6seHh4mJiZhYWGamprp6enr6+saGhpeXl7j4+Pl5eXm5uZKSkrw8PD09PT19fW7u7vDw8PMzMwICAgwMDAyMjILCwtAQECGhoaHh4eBgYGFhYUSEhJXV1dZWVlcXFyOjo6SkpLNzc339/fPz8/Z2dna2tqTk5OlpaWxOPeTAAAAdnRSTlMAAwQFBhUWGxwkJSYyO0dISVBRUmpvj5CSk5SVoaOlpqiysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKyNuo+uwAAAWJJREFUeF5NkmV34zAQReUm7WbTuJBNunY3bvXGDjNTkZkZlpn5/9eR5FPfbzr3jGb0RkwRiMQMDm7EIgHmRxtLwMOaHHoQjwz4MUKeCM8AWMrmd7u7f/aXAMyOShHiQD1n04DtN5e5FMBFlSauIsm585dKi4CpuSYKJIv1tBDVmvOSqJgEoowFLSBHaQh10XHWiCgHWEGmAw2blPrvOK/KRJUGoLM4kCVSKrWz7HwgoiwQZyaQJ0+9PvxV23BNATAZB25IqX9b3+jTW9fcApwB6NLgUD5NY3mPXnwmFwBezff1ztzRFzTp94FXMy36HDuCa2RafdnnmZqtL818Gl9/qNnEeyrUk2aTPiKj3qMyWBVi/YSuWq5qiwxkbtX3vYWzdz/l8M0k8ERlvViiB1Ygslb7SbVtJezncj+Cx5bYaeGuonZqhZlieAp+no74/s5EAh6JcY35Cepxk4ObcT3IJPe/1lKsDpFCFQAAAABJRU5ErkJggg==";
+}
+
+////// 更改背景音乐的播放 //////
+control.prototype.triggerBgm = function () {
+ if (main.mode != 'play') return;
+
+ core.musicStatus.bgmStatus = !core.musicStatus.bgmStatus;
+ if (core.musicStatus.bgmStatus)
+ this.resumeBgm();
+ else
+ this.pauseBgm();
+ core.setLocalStorage('bgmStatus', core.musicStatus.bgmStatus);
+}
+
+////// 播放音频 //////
+control.prototype.playSound = function (sound, pitch, callback) {
+ sound = core.getMappedName(sound);
+ if (main.mode != 'play' || !core.musicStatus.soundStatus || !core.material.sounds[sound]) return;
+ try {
+ if (core.musicStatus.audioContext != null) {
+ var source = core.musicStatus.audioContext.createBufferSource();
+ source.__name = sound;
+ source.buffer = core.material.sounds[sound];
+ source.connect(core.musicStatus.gainNode);
+ var id = setTimeout(null);
+ if (pitch && pitch >= 30 && pitch <= 300) {
+ source.playbackRate.setValueAtTime(pitch / 100, 0);
+ }
+ source.onended = function () {
+ delete core.musicStatus.playingSounds[id];
+ if (callback) callback();
+ }
+ core.musicStatus.playingSounds[id] = source;
+ if (source.start) source.start(0);
+ else if (source.noteOn) source.noteOn(0);
+ return id;
+ }
+ else {
+ core.material.sounds[sound].volume = core.musicStatus.userVolume;
+ core.material.sounds[sound].play();
+ if (callback) callback();
+ }
+ }
+ catch (e) {
+ console.log("无法播放SE " + sound);
+ console.error(e);
+ }
+}
+
+////// 停止所有音频 //////
+control.prototype.stopSound = function (id) {
+ if (id == null) {
+ Object.keys(core.musicStatus.playingSounds).forEach(function (id) {
+ core.control.stopSound(id);
+ });
+ return;
+ }
+ var source = core.musicStatus.playingSounds[id];
+ if (!source) return;
+ try {
+ if (source.stop) source.stop();
+ else if (source.noteOff) source.noteOff();
+ }
+ catch (e) {
+ console.error(e);
+ }
+ delete core.musicStatus.playingSounds[id];
+}
+
+////// 获得当前正在播放的所有(指定)音效的id列表 //////
+control.prototype.getPlayingSounds = function (name) {
+ name = core.getMappedName(name);
+ return Object.keys(core.musicStatus.playingSounds).filter(function (one) {
+ return name == null || core.musicStatus.playingSounds[one].__name == name
+ });
+}
+
+////// 检查bgm状态 //////
+control.prototype.checkBgm = function () {
+ core.playBgm(core.musicStatus.playingBgm || main.startBgm);
+}
+
+///// 设置屏幕放缩 //////
+control.prototype.setDisplayScale = function (delta) {
+ var index = core.domStyle.availableScale.indexOf(core.domStyle.scale);
+ if (index < 0) return;
+ index = (index + delta + core.domStyle.availableScale.length) % core.domStyle.availableScale.length;
+ core.domStyle.scale = core.domStyle.availableScale[index];
+ core.setLocalStorage('scale', core.domStyle.scale);
+ core.resize();
+}
+
+// ------ 状态栏,工具栏等相关 ------ //
+
+////// 清空状态栏 //////
+control.prototype.clearStatusBar = function () {
+ Object.keys(core.statusBar).forEach(function (e) {
+ if (core.statusBar[e].innerHTML != null) {
+ core.statusBar[e].innerHTML = " ";
+ core.statusBar[e].removeAttribute('_style');
+ core.statusBar[e].removeAttribute('_value');
+ }
+ })
+ core.statusBar.image.book.style.opacity = 0.3;
+ if (!core.flags.equipboxButton)
+ core.statusBar.image.fly.style.opacity = 0.3;
+}
+
+////// 更新状态栏 //////
+control.prototype.updateStatusBar = function (doNotCheckAutoEvents, immediate) {
+ if (immediate) {
+ return this.updateStatusBar_update();
+ }
+ if (!doNotCheckAutoEvents) this.noAutoEvents = false;
+ if (core.isReplaying()) return this.updateStatusBar_update();
+ requestAnimationFrame(this.updateStatusBar_update)
+}
+
+control.prototype.updateStatusBar_update = function () {
+ 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;
+}
+
+control.prototype._updateStatusBar_setToolboxIcon = function () {
+ if (core.isReplaying()) {
+ core.statusBar.image.book.src = core.status.replay.pausing ? core.statusBar.icons.play.src : core.statusBar.icons.pause.src;
+ core.statusBar.image.book.style.opacity = 1;
+ core.statusBar.image.fly.src = core.statusBar.icons.stop.src;
+ core.statusBar.image.fly.style.opacity = 1;
+ core.statusBar.image.toolbox.src = core.statusBar.icons.rewind.src;
+ core.statusBar.image.keyboard.src = core.statusBar.icons.book.src;
+ core.statusBar.image.shop.src = core.statusBar.icons.floor.src;
+ core.statusBar.image.save.src = core.statusBar.icons.speedDown.src;
+ core.statusBar.image.save.style.opacity = 1;
+ core.statusBar.image.load.src = core.statusBar.icons.speedUp.src;
+ core.statusBar.image.settings.src = core.statusBar.icons.save.src;
+ }
+ else {
+ core.statusBar.image.book.src = core.statusBar.icons.book.src;
+ core.statusBar.image.book.style.opacity = core.hasItem('book') ? 1 : 0.3;
+ if (!core.flags.equipboxButton) {
+ core.statusBar.image.fly.src = core.statusBar.icons.fly.src;
+ core.statusBar.image.fly.style.opacity = core.hasItem('fly') ? 1 : 0.3;
+ }
+ else {
+ core.statusBar.image.fly.src = core.statusBar.icons.equipbox.src;
+ core.statusBar.image.fly.style.opacity = 1;
+ }
+ core.statusBar.image.toolbox.src = core.statusBar.icons.toolbox.src;
+ core.statusBar.image.keyboard.src = core.statusBar.icons.keyboard.src;
+ core.statusBar.image.shop.src = core.statusBar.icons.shop.src;
+ core.statusBar.image.save.src = core.statusBar.icons.save.src;
+ core.statusBar.image.save.style.opacity = core.hasFlag('__forbidSave__') ? 0.3 : 1;
+ core.statusBar.image.load.src = core.statusBar.icons.load.src;
+ core.statusBar.image.settings.src = core.statusBar.icons.settings.src;
+ }
+}
+
+control.prototype.showStatusBar = function () {
+ if (main.mode == 'editor') return;
+ if (core.domStyle.showStatusBar) return;
+ var statusItems = core.dom.status;
+ core.domStyle.showStatusBar = true;
+ core.removeFlag('hideStatusBar');
+ // 显示
+ for (var i = 0; i < statusItems.length; ++i)
+ statusItems[i].style.opacity = 1;
+ this.setToolbarButton(false);
+ 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;
+
+ var statusItems = core.dom.status, toolItems = core.dom.tools;
+ core.domStyle.showStatusBar = false;
+ core.setFlag('hideStatusBar', true);
+ core.setFlag('showToolbox', showToolbox || null);
+ // 隐藏
+ for (var i = 0; i < statusItems.length; ++i)
+ statusItems[i].style.opacity = 0;
+ 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';
+ }
+}
+
+////// 更新状态栏的勇士图标 //////
+control.prototype.updateHeroIcon = function (name) {
+ name = name || "hero.png";
+ if (core.statusBar.icons.name == name) return;
+ core.statusBar.icons.name = name;
+
+ var image = core.material.images.hero;
+ // 全身图
+ var w = core.material.icons.hero.width || 32;
+ var h = core.material.icons.hero.height || 48;
+ var ratio = Math.min(w / h, 1), width = 32 * ratio, left = 16 - width / 2;
+
+ var canvas = document.createElement("canvas");
+ var ctx = canvas.getContext("2d");
+ canvas.width = 32;
+ canvas.height = 32;
+ core.drawImage(ctx, image, 0, 0, w, h, left, 0, width, 32);
+
+ core.statusBar.image.name.src = canvas.toDataURL("image/png");
+}
+
+////// 改变工具栏为按钮1-8 //////
+control.prototype.setToolbarButton = function (useButton) {
+ if (!core.domStyle.showStatusBar) {
+ // 隐藏状态栏时检查竖屏
+ if (!core.domStyle.isVertical && !core.flags.extendToolbar) {
+ for (var i = 0; i < core.dom.tools.length; ++i)
+ core.dom.tools[i].style.display = 'none';
+ return;
+ }
+ if (!core.hasFlag('showToolbox')) return;
+ else core.dom.tools.hard.style.display = 'block';
+ }
+
+ if (useButton == null) useButton = core.domStyle.toolbarBtn;
+ if ((!core.domStyle.isVertical && !core.flags.extendToolbar) || core.isReplaying()) useButton = false;
+ core.domStyle.toolbarBtn = useButton;
+
+ if (useButton) {
+ ["book", "fly", "toolbox", "keyboard", "shop", "save", "load", "settings"].forEach(function (t) {
+ core.statusBar.image[t].style.display = 'none';
+ });
+ ["btn1", "btn2", "btn3", "btn4", "btn5", "btn6", "btn7", "btn8"].forEach(function (t) {
+ core.statusBar.image[t].style.display = 'block';
+ })
+ main.statusBar.image.btn8.style.filter = core.getLocalStorage('altKey') ? 'sepia(1) contrast(1.5)' : '';
+ }
+ else {
+ ["btn1", "btn2", "btn3", "btn4", "btn5", "btn6", "btn7", "btn8"].forEach(function (t) {
+ core.statusBar.image[t].style.display = 'none';
+ });
+ ["book", "fly", "toolbox", "save", "load", "settings"].forEach(function (t) {
+ core.statusBar.image[t].style.display = 'block';
+ });
+ core.statusBar.image.keyboard.style.display
+ = core.statusBar.image.shop.style.display
+ = core.domStyle.isVertical || core.flags.extendToolbar ? "block" : "none";
+ }
+}
+
+////// ------ resize处理 ------ //
+
+control.prototype._shouldDisplayStatus = function (id) {
+ if (id == null) {
+ var toDraw = [], status = core.dom.status;
+ for (var i = 0; i < status.length; ++i) {
+ var dom = core.dom.status[i], idCol = dom.id;
+ if (idCol.indexOf("Col") != idCol.length - 3) continue;
+ var id = idCol.substring(0, idCol.length - 3);
+ if (!this._shouldDisplayStatus(id)) continue;
+ toDraw.push(id);
+ }
+ return toDraw;
+ }
+ var obj = {};
+ core.flags.statusBarItems.forEach(function (v) { obj[v] = true; })
+ switch (id) {
+ case 'floor': return obj.enableFloor;
+ case 'name': return obj.enableName;
+ case 'lv': return obj.enableLv;
+ case 'hp': return obj.enableHP;
+ case 'hpmax': return obj.enableHPMax;
+ case 'mana': return obj.enableMana;
+ case 'atk': return obj.enableAtk;
+ case 'def': return obj.enableDef;
+ case 'mdef': return obj.enableMDef;
+ case 'money': return obj.enableMoney;
+ case 'exp': return obj.enableExp && !obj.levelUpLeftMode;
+ case 'up': return obj.enableLevelUp;
+ case 'skill': return obj.enableSkill;
+ case 'key': return obj.enableKeys;
+ case 'pzf': return obj.enablePZF;
+ case 'debuff': return obj.enableDebuff;
+ default: return true;
+ }
+}
+
+////// 注册一个resize函数 //////
+// name为名称,可供注销使用
+// func可以是一个函数,或者是插件中的函数名;可以接受obj参数,详见resize函数。
+control.prototype.registerResize = function (name, func) {
+ this.unregisterResize(name);
+ this.resizes.push({ name: name, func: func });
+}
+
+////// 注销一个resize函数 //////
+control.prototype.unregisterResize = function (name) {
+ this.resizes = this.resizes.filter(function (b) { return b.name != name; });
+}
+
+control.prototype._doResize = function (obj) {
+ for (var i in this.resizes) {
+ try {
+ if (core.doFunc(this.resizes[i].func, this, obj)) return true;
+ } catch (e) {
+ console.error(e);
+ console.error("ERROR in resizes[" + this.resizes[i].name + "]:已自动注销该项。");
+ this.unregisterResize(this.resizes[i].name);
+ }
+ }
+ return false;
+}
+
+////// 屏幕分辨率改变后重新自适应 //////
+control.prototype.resize = function () {
+ if (main.mode == 'editor') return;
+ var clientWidth = main.dom.body.clientWidth, clientHeight = main.dom.body.clientHeight;
+ var CANVAS_WIDTH = core.__PIXELS__, BAR_WIDTH = Math.round(core.__PIXELS__ * 0.31);
+ var BORDER = 3;
+ var extendToolbar = core.flags.extendToolbar;
+
+ var horizontalMaxRatio = (clientHeight - 2 * BORDER - (extendToolbar ? BORDER : 0)) / (CANVAS_WIDTH + (extendToolbar ? 38 : 0));
+
+ if (clientWidth - 3 * BORDER >= CANVAS_WIDTH + BAR_WIDTH || (clientWidth > clientHeight && horizontalMaxRatio < 1)) {
+ // 横屏
+ core.domStyle.isVertical = false;
+
+ core.domStyle.availableScale = [];
+ [1, 1.25, 1.5, 1.75, 2, 2.25, 2.5].forEach(function (v) {
+ if (clientWidth - 3 * BORDER >= v * (CANVAS_WIDTH + BAR_WIDTH) && horizontalMaxRatio >= v) {
+ core.domStyle.availableScale.push(v);
+ }
+ });
+ if (core.domStyle.availableScale.indexOf(core.domStyle.scale) < 0) {
+ core.domStyle.scale = Math.min(1, horizontalMaxRatio);
+ }
+ }
+ else {
+ // 竖屏
+ core.domStyle.isVertical = true;
+ core.domStyle.scale = Math.min((clientWidth - 2 * BORDER) / CANVAS_WIDTH);
+ core.domStyle.availableScale = [];
+ extendToolbar = false;
+ }
+
+ var statusDisplayArr = this._shouldDisplayStatus(), count = statusDisplayArr.length;
+ var statusCanvas = core.flags.statusCanvas, statusCanvasRows = core.values.statusCanvasRowsOnMobile || 3;
+ var col = statusCanvas ? statusCanvasRows : Math.ceil(count / 3);
+ if (col > 5) {
+ if (statusCanvas) alert("自绘状态栏的在竖屏下的行数应不超过5!");
+ else alert("当前状态栏数目(" + count + ")大于15,请调整到不超过15以避免手机端出现显示问题。");
+ }
+ var globalAttribute = core.status.globalAttribute || core.initStatus.globalAttribute;
+
+ var obj = {
+ clientWidth: clientWidth,
+ clientHeight: clientHeight,
+ CANVAS_WIDTH: CANVAS_WIDTH,
+ BORDER: BORDER,
+ BAR_WIDTH: BAR_WIDTH,
+ TOOLBAR_HEIGHT: 38,
+ outerSize: CANVAS_WIDTH * core.domStyle.scale + 2 * BORDER,
+ globalAttribute: globalAttribute,
+ border: '3px ' + core.arrayToRGBA(globalAttribute.borderColor) + ' solid',
+ statusDisplayArr: statusDisplayArr,
+ count: count,
+ col: col,
+ statusBarHeightInVertical: core.domStyle.isVertical ? (32 * col + 6) * core.domStyle.scale + 2 * BORDER : 0,
+ toolbarHeightInVertical: core.domStyle.isVertical ? 38 * core.domStyle.scale + 2 * BORDER : 0,
+ extendToolbar: extendToolbar,
+ is15x15: core.__SIZE__ == 15
+ };
+
+ this._doResize(obj);
+ this.setToolbarButton();
+ core.updateStatusBar();
+}
+
+control.prototype._resize_gameGroup = function (obj) {
+ var startBackground = core.domStyle.isVertical ? (main.styles.startVerticalBackground || main.styles.startBackground) : main.styles.startBackground;
+ if (main.dom.startBackground.getAttribute('__src__') != startBackground) {
+ main.dom.startBackground.setAttribute('__src__', startBackground);
+ main.dom.startBackground.src = startBackground;
+ }
+
+ var gameGroup = core.dom.gameGroup;
+ var totalWidth, totalHeight;
+ if (core.domStyle.isVertical) {
+ totalWidth = obj.outerSize;
+ totalHeight = obj.outerSize + obj.statusBarHeightInVertical + obj.toolbarHeightInVertical
+ }
+ else {
+ totalWidth = obj.outerSize + obj.BAR_WIDTH * core.domStyle.scale + obj.BORDER;
+ totalHeight = obj.outerSize + (obj.extendToolbar ? obj.TOOLBAR_HEIGHT * core.domStyle.scale + obj.BORDER : 0);
+ }
+ gameGroup.style.width = totalWidth + "px";
+ gameGroup.style.height = totalHeight + "px";
+ gameGroup.style.left = (obj.clientWidth - totalWidth) / 2 + "px";
+ gameGroup.style.top = (obj.clientHeight - totalHeight) / 2 + "px";
+ // floorMsgGroup
+ var floorMsgGroup = core.dom.floorMsgGroup;
+ floorMsgGroup.style = obj.globalAttribute.floorChangingStyle;
+ floorMsgGroup.style.width = obj.outerSize - 2 * obj.BORDER + "px";
+ floorMsgGroup.style.height = totalHeight - 2 * obj.BORDER + "px";
+ floorMsgGroup.style.fontSize = 16 * core.domStyle.scale + "px";
+ // startPanel
+ core.dom.startPanel.style.fontSize = 16 * core.domStyle.scale + "px";
+ // musicBtn
+ if (core.domStyle.isVertical || core.domStyle.scale < 1) {
+ core.dom.musicBtn.style.right = core.dom.musicBtn.style.bottom = "3px";
+ }
+ else {
+ core.dom.musicBtn.style.right = (obj.clientWidth - totalWidth) / 2 + "px";
+ core.dom.musicBtn.style.bottom = (obj.clientHeight - totalHeight) / 2 - 27 + "px";
+ }
+}
+
+control.prototype._resize_canvas = function (obj) {
+ var innerSize = (obj.CANVAS_WIDTH * core.domStyle.scale) + "px";
+ if (!core.isPlaying()) {
+ for (var i = 0; i < core.dom.gameCanvas.length; ++i) {
+ var ctx = core.dom.gameCanvas[i].getContext('2d');
+ core.resizeCanvas(ctx, core.__PIXELS__, core.__PIXELS__);
+ core.dom.gameCanvas[i].style.width = core.dom.gameCanvas[i].style.height = innerSize;
+ }
+ } else {
+ requestAnimationFrame(function () {
+ for (var i = 0; i < core.dom.gameCanvas.length; ++i)
+ core.dom.gameCanvas[i].style.width = core.dom.gameCanvas[i].style.height = innerSize;
+ });
+ }
+ core.dom.gif.style.width = core.dom.gif.style.height = innerSize;
+ core.dom.gif2.style.width = core.dom.gif2.style.height = innerSize;
+ core.dom.gameDraw.style.width = core.dom.gameDraw.style.height = innerSize;
+ core.dom.gameDraw.style.top = obj.statusBarHeightInVertical + "px";
+ core.dom.gameDraw.style.right = 0;
+ core.dom.gameDraw.style.border = obj.border;
+ // resize bigmap
+ core.bigmap.canvas.forEach(function (cn) {
+ var ratio = core.canvas[cn].canvas.hasAttribute('isHD') ? core.domStyle.ratio : 1;
+ core.canvas[cn].canvas.style.width = core.canvas[cn].canvas.width / ratio * core.domStyle.scale + "px";
+ core.canvas[cn].canvas.style.height = core.canvas[cn].canvas.height / ratio * core.domStyle.scale + "px";
+ });
+ // resize dynamic canvas
+ if (!core.isPlaying()) {
+ for (var name in core.dymCanvas) {
+ var ctx = core.dymCanvas[name], canvas = ctx.canvas;
+ // core.maps._setHDCanvasSize(ctx, parseFloat(canvas.getAttribute('_width')), parseFloat(canvas.getAttribute('_height')));
+ canvas.style.left = parseFloat(canvas.getAttribute("_left")) * core.domStyle.scale + "px";
+ canvas.style.top = parseFloat(canvas.getAttribute("_top")) * core.domStyle.scale + "px";
+ var scale = canvas.getAttribute('_scale') || 1;
+ core.resizeCanvas(canvas, canvas.width * scale / core.domStyle.scale, canvas.height * scale / core.domStyle.scale);
+ }
+ } else {
+ for (var name in core.dymCanvas) {
+ var ctx = core.dymCanvas[name], canvas = ctx.canvas;
+ var ratio = canvas.hasAttribute('isHD') ? core.domStyle.ratio : 1;
+ canvas.style.width = canvas.width / ratio * core.domStyle.scale + "px";
+ canvas.style.height = canvas.height / ratio * core.domStyle.scale + "px";
+ canvas.style.left = parseFloat(canvas.getAttribute("_left")) * core.domStyle.scale + "px";
+ canvas.style.top = parseFloat(canvas.getAttribute("_top")) * core.domStyle.scale + "px";
+ }
+ }
+ // resize next
+ main.dom.next.style.width = main.dom.next.style.height = 5 * core.domStyle.scale + "px";
+ main.dom.next.style.borderBottomWidth = main.dom.next.style.borderRightWidth = 4 * core.domStyle.scale + "px";
+}
+
+control.prototype._resize_statusBar = function (obj) {
+ // statusBar
+ var statusBar = core.dom.statusBar;
+ if (core.domStyle.isVertical) {
+ statusBar.style.width = obj.outerSize + "px";
+ statusBar.style.height = obj.statusBarHeightInVertical + "px";
+ statusBar.style.background = obj.globalAttribute.statusTopBackground;
+ statusBar.style.fontSize = 16 * core.domStyle.scale + "px";
+ }
+ else {
+ statusBar.style.width = (obj.BAR_WIDTH * core.domStyle.scale + obj.BORDER) + "px";
+ statusBar.style.height = obj.outerSize + (obj.extendToolbar ? obj.TOOLBAR_HEIGHT * core.domStyle.scale + obj.BORDER : 0) + "px";
+ statusBar.style.background = obj.globalAttribute.statusLeftBackground;
+ // --- 计算文字大小
+ if (obj.extendToolbar) {
+ statusBar.style.fontSize = 16 * core.domStyle.scale + "px";
+ } else {
+ statusBar.style.fontSize = 16 * Math.min(1, (core.__HALF_SIZE__ + 3) / obj.count) * core.domStyle.scale + "px";
+ }
+ }
+ statusBar.style.display = 'block';
+ statusBar.style.borderTop = statusBar.style.borderLeft = obj.border;
+ statusBar.style.borderRight = core.domStyle.isVertical ? obj.border : '';
+ statusBar.style.borderBottom = core.domStyle.isVertical ? '' : obj.border;
+ // 自绘状态栏
+ if (core.domStyle.isVertical) {
+ core.dom.statusCanvas.style.width = obj.CANVAS_WIDTH * core.domStyle.scale + "px";
+ core.dom.statusCanvas.style.height = obj.statusBarHeightInVertical - 3 + "px";
+ core.maps._setHDCanvasSize(core.dom.statusCanvasCtx, obj.CANVAS_WIDTH, obj.col * 32 + 9);
+ }
+ else {
+ core.dom.statusCanvas.style.width = obj.BAR_WIDTH * core.domStyle.scale + "px";
+ core.dom.statusCanvas.style.height = obj.outerSize - 2 * obj.BORDER + (obj.extendToolbar ? obj.TOOLBAR_HEIGHT * core.domStyle.scale + obj.BORDER : 0) + "px";
+ core.maps._setHDCanvasSize(core.dom.statusCanvasCtx, obj.BAR_WIDTH, obj.CANVAS_WIDTH + (obj.extendToolbar ? obj.TOOLBAR_HEIGHT + obj.BORDER : 0));
+ }
+ core.dom.statusCanvas.style.display = core.flags.statusCanvas ? "block" : "none";
+}
+
+control.prototype._resize_status = function (obj) {
+ var statusHeight;
+ if (core.domStyle.isVertical) {
+ statusHeight = 32 * core.domStyle.scale * 0.8;
+ } else {
+ statusHeight = (obj.extendToolbar ? core.__SIZE__ : core.__HALF_SIZE__ + 3) / obj.count * 32 * core.domStyle.scale * 0.8;
+ }
+ // status
+ for (var i = 0; i < core.dom.status.length; ++i) {
+ var id = core.dom.status[i].id, style = core.dom.status[i].style;
+ if (id.endsWith("Col")) id = id.substring(0, id.length - 3);
+ style.display = core.flags.statusCanvas || obj.statusDisplayArr.indexOf(id) < 0 ? 'none' : 'block';
+ style.margin = 3 * core.domStyle.scale + "px";
+ style.height = statusHeight + "px";
+ style.maxWidth = obj.BAR_WIDTH * core.domStyle.scale * (core.domStyle.isVertical ? 0.95 : 1) + obj.BORDER + "px";
+ if (obj.is15x15 && !core.domStyle.isVertical)
+ style.marginLeft = 11 * core.domStyle.scale + "px";
+ }
+ // statusLabels, statusTexts
+ for (var i = 0; i < core.dom.statusLabels.length; ++i) {
+ core.dom.statusLabels[i].style.lineHeight = statusHeight + "px";
+ core.dom.statusLabels[i].style.marginLeft = 6 * core.domStyle.scale + "px";
+ }
+ for (var i = 0; i < core.dom.statusTexts.length; ++i) {
+ core.dom.statusTexts[i].style.color = core.arrayToRGBA(obj.globalAttribute.statusBarColor);
+ }
+ // keys
+ if (core.flags.statusBarItems.indexOf('enableGreenKey') >= 0) {
+ core.dom.keyCol.style.fontSize = '0.75em';
+ core.statusBar.greenKey.style.display = '';
+ } else {
+ core.dom.keyCol.style.fontSize = '';
+ core.statusBar.greenKey.style.display = 'none';
+ }
+}
+
+control.prototype._resize_toolBar = function (obj) {
+ // toolBar
+ var toolBar = core.dom.toolBar;
+ if (core.domStyle.isVertical) {
+ toolBar.style.left = 0;
+ toolBar.style.right = "";
+ toolBar.style.width = obj.outerSize + "px";
+ toolBar.style.top = obj.statusBarHeightInVertical + obj.outerSize + "px";
+ toolBar.style.height = obj.toolbarHeightInVertical + "px";
+ toolBar.style.background = obj.globalAttribute.toolsBackground;
+ }
+ else {
+ if (obj.extendToolbar) {
+ toolBar.style.left = "";
+ toolBar.style.right = 0;
+ toolBar.style.width = obj.outerSize + "px";
+ toolBar.style.top = obj.outerSize + "px";
+ toolBar.style.height = obj.TOOLBAR_HEIGHT * core.domStyle.scale + obj.BORDER + "px";
+ toolBar.style.background = obj.globalAttribute.toolsBackground;
+ } else {
+ toolBar.style.left = 0;
+ toolBar.style.right = "";
+ toolBar.style.width = obj.BAR_WIDTH * core.domStyle.scale + obj.BORDER + "px";
+ toolBar.style.top = 0.718 * obj.outerSize + "px";
+ toolBar.style.height = 0.281 * obj.outerSize + "px";
+ toolBar.style.background = 'transparent';
+ }
+ }
+ toolBar.style.borderLeft = obj.border;
+ toolBar.style.borderRight = toolBar.style.borderBottom = core.domStyle.isVertical || obj.extendToolbar ? obj.border : '';
+ toolBar.style.fontSize = 16 * core.domStyle.scale + "px";
+
+ if (!core.domStyle.showStatusBar && !core.domStyle.isVertical && !obj.extendToolbar) {
+ toolBar.style.display = 'none';
+ } else {
+ toolBar.style.display = 'block';
+ }
+}
+
+control.prototype._resize_tools = function (obj) {
+ var toolsHeight = 32 * core.domStyle.scale * ((core.domStyle.isVertical || obj.extendToolbar) && !obj.is15x15 ? 0.95 : 1);
+ var toolsMarginLeft;
+ if (core.domStyle.isVertical || obj.extendToolbar)
+ toolsMarginLeft = (core.__HALF_SIZE__ - 3) * 3 * core.domStyle.scale;
+ else
+ toolsMarginLeft = (obj.BAR_WIDTH * core.domStyle.scale - 9 - toolsHeight * 3) / 4;
+ for (var i = 0; i < core.dom.tools.length; ++i) {
+ var style = core.dom.tools[i].style;
+ style.height = toolsHeight + "px";
+ style.marginLeft = toolsMarginLeft + "px";
+ style.marginTop = 3 * core.domStyle.scale + "px"
+ }
+ core.dom.hard.style.lineHeight = toolsHeight + "px";
+ if (core.domStyle.isVertical || obj.extendToolbar) {
+ core.dom.hard.style.width = obj.outerSize - 9 * toolsMarginLeft - 8.5 * toolsHeight - 12 + "px";
+ }
+ else {
+ core.dom.hard.style.width = obj.BAR_WIDTH * core.domStyle.scale - 9 - 2 * toolsMarginLeft + "px";
+ if (!obj.is15x15) core.dom.hard.style.marginTop = 0;
+ }
+}