diff --git a/.prettierignore b/.prettierignore index 7cd1be8..57b150d 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,2 +1,2 @@ vite.config.ts -public/project/*.js \ No newline at end of file +public/project/data.js \ No newline at end of file diff --git a/public/libs/events.js b/public/libs/events.js index 66d9954..3d367fe 100644 --- a/public/libs/events.js +++ b/public/libs/events.js @@ -1,7 +1,6 @@ +'use strict'; -"use strict"; - -function events () { +function events() { this._init(); } @@ -11,20 +10,20 @@ events.prototype._init = function () { this.commonEvent = events_c12a15a8_c380_4b28_8144_256cba95f760.commonEvent; this.systemEvents = {}; this.actions = {}; -} +}; // ------ 初始化,开始和结束 ------ // /// 初始化游戏 events.prototype.resetGame = function (hero, hard, floorId, maps, values) { this.eventdata.resetGame(hero, hard, floorId, maps, values); -} +}; ////// 游戏开始事件 ////// events.prototype.startGame = function (hard, seed, route, callback) { main.dom.levelChooseButtons.style.display = 'none'; main.dom.startButtonGroup.style.display = 'none'; - hard = hard || ""; + hard = hard || ''; if (main.mode != 'play') return; @@ -32,24 +31,27 @@ events.prototype.startGame = function (hard, seed, route, callback) { if (core.flags.startUsingCanvas || route != null) { core.dom.startPanel.style.display = 'none'; this._startGame_start(hard, seed, route, callback); - } - else { + } else { core.hideStartAnimate(function () { core.events._startGame_start(hard, seed, route, callback); }); } -} +}; events.prototype._startGame_start = function (hard, seed, route, callback) { - core.resetGame(core.firstData.hero, hard, null, core.cloneArray(core.initStatus.maps)); + core.resetGame( + core.firstData.hero, + hard, + null, + core.cloneArray(core.initStatus.maps) + ); core.setHeroLoc('x', -1); core.setHeroLoc('y', -1); if (seed != null && seed > 0) { core.setFlag('__seed__', seed); core.setFlag('__rand__', seed); - } - else core.utils.__init_seed(); + } else core.utils.__init_seed(); core.clearStatusBar(); var todo = []; @@ -58,14 +60,17 @@ events.prototype._startGame_start = function (hard, seed, route, callback) { core.dom.musicBtn.style.display = 'block'; core.push(todo, core.firstData.startCanvas); } - core.push(todo, { "type": "function", "function": "function() { core.events._startGame_setHard(); }" }) + core.push(todo, { + type: 'function', + function: 'function() { core.events._startGame_setHard(); }' + }); core.push(todo, core.firstData.startText); this.insertAction(todo, null, null, function () { core.events._startGame_afterStart(callback); }); if (route != null) core.startReplay(route); -} +}; events.prototype._startGame_setHard = function () { // 根据难度设置flag:hard @@ -81,17 +86,23 @@ events.prototype._startGame_setHard = function () { }); core.setFlag('hard', hardValue || 0); core.setFlag('__hardColor__', hardColor); -} +}; events.prototype._startGame_afterStart = function (callback) { core.ui.closePanel(); - core.changeFloor(core.firstData.floorId, null, core.firstData.hero.loc, null, function () { - // 插入一个空事件避免直接回放录像出错 - core.insertAction([]); - if (callback) callback(); - }); + core.changeFloor( + core.firstData.floorId, + null, + core.firstData.hero.loc, + null, + function () { + // 插入一个空事件避免直接回放录像出错 + core.insertAction([]); + if (callback) callback(); + } + ); this._startGame_upload(); -} +}; events.prototype._startGame_upload = function () { // Upload @@ -104,46 +115,48 @@ events.prototype._startGame_upload = function () { formData.append('hardCode', core.getFlag('hard', 0)); formData.append('base64', 1); - core.utils.http("POST", "/games/upload.php", formData); -} + core.utils.http('POST', '/games/upload.php', formData); +}; ////// 游戏获胜事件 ////// events.prototype.win = function (reason, norank, noexit) { if (!noexit) core.status.gameOver = true; return this.eventdata.win(reason, norank, noexit); -} +}; ////// 游戏失败事件 ////// events.prototype.lose = function (reason) { - if (core.isReplaying()) return core.control._replay_error(reason, function () { core.lose(reason); }); + if (core.isReplaying()) + return core.control._replay_error(reason, function () { + core.lose(reason); + }); core.status.gameOver = true; return this.eventdata.lose(reason); -} +}; ////// 游戏结束 ////// events.prototype.gameOver = function (ending, fromReplay, norank) { if (!core.status.extraEvent) { core.clearMap('all'); core.deleteAllCanvas(); - core.dom.gif2.innerHTML = ""; + core.dom.gif2.innerHTML = ''; core.setWeather(); } core.ui.closePanel(); if (main.isCompetition && ending != null) { - if (ending == "") ending = "恭喜通关"; - ending += "[比赛]"; + if (ending == '') ending = '恭喜通关'; + ending += '[比赛]'; } var reason = null; - if (fromReplay) reason = "录像回放完毕!"; - else if (core.hasFlag("debug")) reason = "\t[系统提示]调试模式下无法上传成绩"; + if (fromReplay) reason = '录像回放完毕!'; + else if (core.hasFlag('debug')) + reason = '\t[系统提示]调试模式下无法上传成绩'; - if (reason != null) - core.drawText(reason, core.restart); - else - this._gameOver_confirmUpload(ending, norank); -} + if (reason != null) core.drawText(reason, core.restart); + else this._gameOver_confirmUpload(ending, norank); +}; events.prototype._gameOver_confirmUpload = function (ending, norank) { core.ui.closePanel(); @@ -152,25 +165,32 @@ events.prototype._gameOver_confirmUpload = function (ending, norank) { this._gameOver_confirmDownload(ending); return; } - core.ui.drawConfirmBox("你想记录你的ID和成绩吗?", function () { - if (main.isCompetition) { - core.events._gameOver_doUpload("", ending, norank); + core.ui.drawConfirmBox( + '你想记录你的ID和成绩吗?', + function () { + if (main.isCompetition) { + core.events._gameOver_doUpload('', ending, norank); + } else { + var id = core.getCookie('id') || ''; + var hint = + '请输入你的ID:\n(登录状态下输入数字用户编号可成为蓝名成绩并计入用户通关数)'; + if (id) + hint = + '请输入你的ID:\n(输入数字用户编号' + + id + + '可成为蓝名成绩并计入用户通关数)'; + core.myprompt(hint, id, function (username) { + core.events._gameOver_doUpload(username, ending, norank); + }); + } + }, + function () { + if (main.isCompetition) + core.events._gameOver_confirmDownload(ending); + else core.events._gameOver_doUpload(null, ending, norank); } - else { - var id = core.getCookie('id') || ""; - var hint = "请输入你的ID:\n(登录状态下输入数字用户编号可成为蓝名成绩并计入用户通关数)"; - if (id) hint = "请输入你的ID:\n(输入数字用户编号" + id + "可成为蓝名成绩并计入用户通关数)"; - core.myprompt(hint, id, function (username) { - core.events._gameOver_doUpload(username, ending, norank); - }); - } - }, function () { - if (main.isCompetition) - core.events._gameOver_confirmDownload(ending); - else - core.events._gameOver_doUpload(null, ending, norank); - }) -} + ); +}; events.prototype._gameOver_doUpload = function (username, ending, norank) { var hp = core.status.hero.hp; @@ -183,7 +203,7 @@ events.prototype._gameOver_doUpload = function (username, ending, norank) { formData.append('version', core.firstData.version); formData.append('platform', core.platform.string); formData.append('hard', core.encodeBase64(core.status.hard)); - formData.append('username', core.encodeBase64(username || "")); + formData.append('username', core.encodeBase64(username || '')); formData.append('ending', core.encodeBase64(ending)); formData.append('lv', core.status.hero.lv); formData.append('hp', Math.min(hp, Math.pow(2, 63))); @@ -195,35 +215,46 @@ events.prototype._gameOver_doUpload = function (username, ending, norank) { formData.append('steps', core.status.hero.steps); formData.append('norank', norank ? 1 : 0); formData.append('seed', core.getFlag('__seed__')); - formData.append('totalTime', Math.floor(core.status.hero.statistics.totalTime / 1000)); + formData.append( + 'totalTime', + Math.floor(core.status.hero.statistics.totalTime / 1000) + ); formData.append('route', core.encodeRoute(core.status.route)); formData.append('base64', 1); if (main.isCompetition) - core.http("POST", "/games/competition/upload.php", formData); - else - core.http("POST", "/games/upload.php", formData); + core.http('POST', '/games/competition/upload.php', formData); + else core.http('POST', '/games/upload.php', formData); core.events._gameOver_confirmDownload(ending); -} +}; events.prototype._gameOver_confirmDownload = function (ending) { core.ui.closePanel(); - core.ui.drawConfirmBox("你想下载录像吗?", function () { - var obj = { - 'name': core.firstData.name, - 'version': core.firstData.version, - 'hard': core.status.hard, - 'seed': core.getFlag('__seed__'), - 'route': core.encodeRoute(core.status.route) + core.ui.drawConfirmBox( + '你想下载录像吗?', + function () { + var obj = { + name: core.firstData.name, + version: core.firstData.version, + hard: core.status.hard, + seed: core.getFlag('__seed__'), + route: core.encodeRoute(core.status.route) + }; + core.download( + core.firstData.name + + '_' + + core.formatDate2(new Date()) + + '.h5route', + LZString.compressToBase64(JSON.stringify(obj)) + ); + core.events._gameOver_askRate(ending); + }, + function () { + core.events._gameOver_askRate(ending); } - core.download(core.firstData.name + "_" + core.formatDate2(new Date()) + ".h5route", - LZString.compressToBase64(JSON.stringify(obj))); - core.events._gameOver_askRate(ending); - }, function () { - core.events._gameOver_askRate(ending); - }); -} + ); +}; events.prototype._gameOver_askRate = function (ending) { core.ui.closePanel(); @@ -245,48 +276,59 @@ events.prototype._gameOver_askRate = function (ending) { } core.status.event.selection = 0; - core.ui.drawConfirmBox("你想读取自动存档么?", function () { - core.ui.closePanel(); - core.doSL("autoSave", "load"); - }, function () { - core.ui.closePanel(); - core.restart(); - }); + core.ui.drawConfirmBox( + '你想读取自动存档么?', + function () { + core.ui.closePanel(); + core.doSL('autoSave', 'load'); + }, + function () { + core.ui.closePanel(); + core.restart(); + } + ); return; } - core.ui.drawConfirmBox("恭喜通关!你想查看榜单、评论,\n以及评分和标色投票吗?", function () { - if (core.platform.isPC) { - window.open("/tower/?name=" + core.firstData.name, "_blank"); + core.ui.drawConfirmBox( + '恭喜通关!你想查看榜单、评论,\n以及评分和标色投票吗?', + function () { + if (core.platform.isPC) { + window.open('/tower/?name=' + core.firstData.name, '_blank'); + core.restart(); + } else { + window.location.href = '/tower/?name=' + core.firstData.name; + } + }, + function () { core.restart(); } - else { - window.location.href = "/tower/?name=" + core.firstData.name; - } - }, function () { - core.restart(); - }); -} + ); +}; ////// 重新开始游戏;此函数将回到标题页面 ////// events.prototype.restart = function () { core.showStartAnimate(); core.playBgm(main.startBgm); -} +}; ////// 询问是否需要重新开始 ////// events.prototype.confirmRestart = function () { core.playSound('打开界面'); core.status.event.selection = 1; - core.ui.drawConfirmBox("你确定要返回标题页面吗?", function () { - core.playSound('确定'); - core.ui.closePanel(); - core.restart(); - }, function () { - core.playSound('取消'); - core.ui.closePanel(); - }); -} + core.ui.drawConfirmBox( + '你确定要返回标题页面吗?', + function () { + core.playSound('确定'); + core.ui.closePanel(); + core.restart(); + }, + function () { + core.playSound('取消'); + core.ui.closePanel(); + } + ); +}; // ------ 系统事件的处理 ------ // @@ -294,12 +336,12 @@ events.prototype.confirmRestart = function () { // type为事件名,func为事件的处理函数,可接受(data, callback)参数 events.prototype.registerSystemEvent = function (type, func) { this.systemEvents[type] = func; -} +}; ////// 注销一个系统事件 ////// events.prototype.unregisterSystemEvent = function (type) { delete this.systemEvents[type]; -} +}; ////// 执行一个系统事件 ////// events.prototype.doSystemEvent = function (type, data, callback) { @@ -307,16 +349,15 @@ events.prototype.doSystemEvent = function (type, data, callback) { if (this.systemEvents[type]) { try { return core.doFunc(this.systemEvents[type], this, data, callback); - } - catch (e) { + } catch (e) { console.error(e); - console.error("ERROR in systemEvents[" + type + "]"); + console.error('ERROR in systemEvents[' + type + ']'); } } - if (this["_sys_" + type]) return this["_sys_" + type](data, callback); - console.error("未知的系统事件: " + type + "!"); + if (this['_sys_' + type]) return this['_sys_' + type](data, callback); + console.error('未知的系统事件: ' + type + '!'); if (callback) callback(); -} +}; ////// 触发(x,y)点的事件 ////// events.prototype.trigger = function (x, y, callback) { @@ -324,14 +365,28 @@ events.prototype.trigger = function (x, y, callback) { // 因为trigger之后还有可能触发其他同步脚本(比如阻激夹域检测) // 所以这里强制callback被异步触发 if (callback) { - setTimeout(callback, 1); // +1是为了录像检测系统 + setTimeout(callback, 1); // +1是为了录像检测系统 } return; - } + }; if (core.status.gameOver) return _executeCallback(); if (core.status.event.id == 'action') { - core.insertAction({ "type": "function", "function": "function () { core.events._trigger_inAction(" + x + "," + y + "); }", "async": true }, - null, null, null, true); + core.insertAction( + { + type: 'function', + function: + 'function () { core.events._trigger_inAction(' + + x + + ',' + + y + + '); }', + async: true + }, + null, + null, + null, + true + ); return _executeCallback(); } if (core.status.event.id) return _executeCallback(); @@ -344,7 +399,9 @@ events.prototype.trigger = function (x, y, callback) { core.clearRouteFolding(); try { eval(block.event.script); - } catch (ee) { console.error(ee) } + } catch (ee) { + console.error(ee); + } } // 碰触事件 @@ -356,17 +413,22 @@ events.prototype.trigger = function (x, y, callback) { } if (block.event.trigger && block.event.trigger != 'null') { - var noPass = block.event.noPass, trigger = block.event.trigger; + var noPass = block.event.noPass, + trigger = block.event.trigger; if (noPass) core.clearAutomaticRouteNode(x, y); // 转换楼层能否穿透 - if (trigger == 'changeFloor' && !noPass && this._trigger_ignoreChangeFloor(block)) + if ( + trigger == 'changeFloor' && + !noPass && + this._trigger_ignoreChangeFloor(block) + ) return _executeCallback(); core.status.automaticRoute.moveDirectly = false; this.doSystemEvent(trigger, block); } return _executeCallback(); -} +}; events.prototype._trigger_inAction = function (x, y) { if (core.status.gameOver || core.status.event.id != 'action') return; @@ -377,7 +439,9 @@ events.prototype._trigger_inAction = function (x, y) { // 执行该点的脚本 try { eval(block.event.script); - } catch (ee) { console.error(ee) } + } catch (ee) { + console.error(ee); + } // 碰触事件 if (block.event.event) { @@ -391,14 +455,13 @@ events.prototype._trigger_inAction = function (x, y) { this.setEvents(null, x, y); if (block.event.trigger == 'action') { this.insertAction(block.event.data); - } - else { + } else { this.doSystemEvent(block.event.trigger, block, core.doAction); return; } } return core.doAction(); -} +}; events.prototype._trigger_ignoreChangeFloor = function (block) { var able = core.flags.ignoreChangeFloor; @@ -408,18 +471,20 @@ events.prototype._trigger_ignoreChangeFloor = function (block) { if (core.isReplaying()) { if (core.status.replay.toReplay[0] == 'no') { core.status.replay.toReplay.shift(); - core.status.route.push("no"); + core.status.route.push('no'); return true; } - } - else if (core.status.automaticRoute.autoHeroMove - || core.status.automaticRoute.autoStep < core.status.automaticRoute.autoStepRoutes.length) { - core.status.route.push("no"); + } else if ( + core.status.automaticRoute.autoHeroMove || + core.status.automaticRoute.autoStep < + core.status.automaticRoute.autoStepRoutes.length + ) { + core.status.route.push('no'); return true; } } return false; -} +}; events.prototype._sys_battle = function (data, callback) { // 检查是否需要改变朝向 @@ -435,10 +500,16 @@ events.prototype._sys_battle = function (data, callback) { // 检查战前事件 var beforeBattle = []; - core.push(beforeBattle, core.floors[core.status.floorId].beforeBattle[data.x + "," + data.y]); - core.push(beforeBattle, (core.material.enemys[data.event.id] || {}).beforeBattle); + core.push( + beforeBattle, + core.floors[core.status.floorId].beforeBattle[data.x + ',' + data.y] + ); + core.push( + beforeBattle, + (core.material.enemys[data.event.id] || {}).beforeBattle + ); if (beforeBattle.length > 0) { - core.push(beforeBattle, [{ "type": "battle", "x": data.x, "y": data.y }]); + core.push(beforeBattle, [{ type: 'battle', x: data.x, y: data.y }]); core.clearContinueAutomaticRoute(); // 自动存档 @@ -453,7 +524,7 @@ events.prototype._sys_battle = function (data, callback) { } else { this.battle(data.event.id, data.x, data.y, false, callback); } -} +}; ////// 战斗 ////// events.prototype.battle = function (id, x, y, force, callback) { @@ -464,7 +535,7 @@ events.prototype.battle = function (id, x, y, force, callback) { if (!core.enemys.canBattle(id, x, y) && !force && !core.status.event.id) { core.stopSound(); core.playSound('操作失败'); - core.drawTip("你打不过此怪物!", id); + core.drawTip('你打不过此怪物!', id); return core.clearContinueAutomaticRoute(callback); } // 自动存档 @@ -475,24 +546,24 @@ events.prototype.battle = function (id, x, y, force, callback) { // 战后事件 this.afterBattle(id, x, y); if (callback) callback(); -} +}; ////// 战斗前触发的事件 ////// events.prototype.beforeBattle = function (enemyId, x, y) { - return this.eventdata.beforeBattle(enemyId, x, y) -} + return this.eventdata.beforeBattle(enemyId, x, y); +}; ////// 战斗结束后触发的事件 ////// events.prototype.afterBattle = function (enemyId, x, y) { return this.eventdata.afterBattle(enemyId, x, y); -} +}; events.prototype._sys_openDoor = function (data, callback) { this.openDoor(data.x, data.y, true, function () { core.replay(); if (callback) callback(); }); -} +}; ////// 开门 ////// events.prototype.openDoor = function (x, y, needKey, callback) { @@ -517,24 +588,26 @@ events.prototype.openDoor = function (x, y, needKey, callback) { } else { this._openDoor_animate(block, x, y, callback); } -} +}; events.prototype._openDoor_check = function (block, x, y, needKey) { var clearAndReturn = function () { core.clearContinueAutomaticRoute(); return false; - } + }; if (block == null || block.event == null) return clearAndReturn(); var id = block.event.id; // 是否存在门或暗墙 - if (core.material.icons.animates[id] == null && core.material.icons.npc48[id] == null) { + if ( + core.material.icons.animates[id] == null && + core.material.icons.npc48[id] == null + ) { return clearAndReturn(); } - if (id == 'steelDoor' && core.flags.steelDoorWithoutKey) - needKey = false; + if (id == 'steelDoor' && core.flags.steelDoorWithoutKey) needKey = false; var doorInfo = block.event.doorInfo; if (doorInfo == null) return clearAndReturn(); // Check all keys @@ -542,30 +615,38 @@ events.prototype._openDoor_check = function (block, x, y, needKey) { if (needKey) { for (var keyName in keyInfo) { var keyValue = keyInfo[keyName]; - if (keyName.endsWith(':o')) keyName = keyName.substring(0, keyName.length - 2); + if (keyName.endsWith(':o')) + keyName = keyName.substring(0, keyName.length - 2); // --- 如果是一个不存在的道具,则直接认为无法开启 if (!core.material.items[keyName]) { core.stopSound(); core.playSound('操作失败'); - core.drawTip("无法开启此门"); + core.drawTip('无法开启此门'); return clearAndReturn(); } if (core.itemCount(keyName) < keyValue) { core.stopSound(); core.playSound('操作失败'); - core.drawTip("你的" + ((core.material.items[keyName] || {}).name || "钥匙") + "不足!", null, true); + core.drawTip( + '你的' + + ((core.material.items[keyName] || {}).name || '钥匙') + + '不足!', + null, + true + ); return false; } } if (!core.status.event.id) core.autosave(true); for (var keyName in keyInfo) { - if (!keyName.endsWith(':o')) core.removeItem(keyName, keyInfo[keyName]); + if (!keyName.endsWith(':o')) + core.removeItem(keyName, keyInfo[keyName]); } } core.playSound(doorInfo.openSound); return true; -} +}; events.prototype._openDoor_animate = function (block, x, y, callback) { var blockInfo = core.getBlockInfo(block); @@ -588,31 +669,36 @@ events.prototype._openDoor_animate = function (block, x, y, callback) { core.status.replay.animate = false; core.events.afterOpenDoor(block.event.id, x, y); if (callback) callback(); - } + }; - var animate = window.setInterval(function () { - blockInfo.posX++; - if (blockInfo.posX == 4) { - clearInterval(animate); - delete core.animateFrame.asyncId[animate]; - cb(); - return; - } - core.maps._drawBlockInfo(blockInfo, x, y); - }, core.status.replay.speed == 24 ? 1 : speed / Math.max(core.status.replay.speed, 1)); + var animate = window.setInterval( + function () { + blockInfo.posX++; + if (blockInfo.posX == 4) { + clearInterval(animate); + delete core.animateFrame.asyncId[animate]; + cb(); + return; + } + core.maps._drawBlockInfo(blockInfo, x, y); + }, + core.status.replay.speed == 24 + ? 1 + : speed / Math.max(core.status.replay.speed, 1) + ); core.animateFrame.lastAsyncId = animate; core.animateFrame.asyncId[animate] = cb; -} +}; ////// 开一个门后触发的事件 ////// events.prototype.afterOpenDoor = function (doorId, x, y) { return this.eventdata.afterOpenDoor(doorId, x, y); -} +}; events.prototype._sys_getItem = function (data, callback) { this.getItem(data.event.id, 1, data.x, data.y, false, callback); -} +}; ////// 获得某个物品 ////// events.prototype.getItem = function (id, num, x, y, isGentleClick, callback) { @@ -621,46 +707,66 @@ events.prototype.getItem = function (id, num, x, y, isGentleClick, callback) { core.removeBlock(x, y); core.items.getItemEffect(id, num); var text = '获得 ' + core.material.items[id].name; - if (num > 1) text += "x" + num; - if (itemCls === 'items' && num == 1) text += core.items.getItemEffectTip(id); + if (num > 1) text += 'x' + num; + if (itemCls === 'items' && num == 1) + text += core.items.getItemEffectTip(id); core.drawTip(text, id); // --- 首次获得道具的提示 - if (!core.hasFlag("__itemHint__")) core.setFlag("__itemHint__", []); - var itemHint = core.getFlag("__itemHint__"); - if (core.flags.itemFirstText && itemHint.indexOf(id) < 0 && itemCls != 'items') { - var hint = core.material.items[id].text || "该道具暂无描述"; + if (!core.hasFlag('__itemHint__')) core.setFlag('__itemHint__', []); + var itemHint = core.getFlag('__itemHint__'); + if ( + core.flags.itemFirstText && + itemHint.indexOf(id) < 0 && + itemCls != 'items' + ) { + var hint = core.material.items[id].text || '该道具暂无描述'; try { hint = core.replaceText(hint); - } catch (e) { } + } catch (e) {} if (!core.status.event.id || core.status.event.id == 'action') { - core.insertAction("\t[" + core.material.items[id].name + "," + id + "]" + hint + "\n" - + (id.endsWith('Key') ? "(钥匙类道具,遇到对应的门时自动打开)" - : itemCls == 'tools' ? "(消耗类道具,请按T在道具栏使用)" - : itemCls == 'constants' ? "(永久类道具,请按T在道具栏使用)" - : itemCls == 'equips' ? "(装备类道具,请按Q在装备栏进行装备)" : "")); + core.insertAction( + '\t[' + + core.material.items[id].name + + ',' + + id + + ']' + + hint + + '\n' + + (id.endsWith('Key') + ? '(钥匙类道具,遇到对应的门时自动打开)' + : itemCls == 'tools' + ? '(消耗类道具,请按T在道具栏使用)' + : itemCls == 'constants' + ? '(永久类道具,请按T在道具栏使用)' + : itemCls == 'equips' + ? '(装备类道具,请按Q在装备栏进行装备)' + : '') + ); } itemHint.push(id); } this.afterGetItem(id, x, y, isGentleClick); if (callback) callback(); -} +}; events.prototype.afterGetItem = function (id, x, y, isGentleClick) { this.eventdata.afterGetItem(id, x, y, isGentleClick); -} +}; ////// 获得面前的物品(轻按) ////// events.prototype.getNextItem = function (noRoute) { if (core.isMoving() || !core.flags.enableGentleClick) return false; if (this._canGetNextItem()) return this._getNextItem(null, noRoute); - var directions = ["up", "down", "left", "right"].filter(function (dir) { + var directions = ['up', 'down', 'left', 'right'].filter(function (dir) { return core.events._canGetNextItem(dir); }); - return directions.length > 0 ? this._getNextItem(directions[0], noRoute) : false; -} + return directions.length > 0 + ? this._getNextItem(directions[0], noRoute) + : false; +}; events.prototype._canGetNextItem = function (direction) { direction = direction || core.getHeroLoc('direction'); @@ -668,32 +774,43 @@ events.prototype._canGetNextItem = function (direction) { var nx = core.getHeroLoc('x') + core.utils.scan[direction].x; var ny = core.getHeroLoc('y') + core.utils.scan[direction].y; var block = core.getBlock(nx, ny); - return block != null && !block.event.script && !block.event.event && block.event.trigger == 'getItem'; -} + return ( + block != null && + !block.event.script && + !block.event.event && + block.event.trigger == 'getItem' + ); +}; events.prototype._getNextItem = function (direction, noRoute) { direction = direction || core.getHeroLoc('direction'); var nx = core.getHeroLoc('x') + core.utils.scan[direction].x; var ny = core.getHeroLoc('y') + core.utils.scan[direction].y; - if (!noRoute) core.status.route.push("getNext"); + if (!noRoute) core.status.route.push('getNext'); this.getItem(core.getBlockId(nx, ny), 1, nx, ny, true); return true; -} +}; events.prototype._sys_changeFloor = function (data, callback) { data = data.event.data; var heroLoc = {}; - if (data.loc) heroLoc = { 'x': data.loc[0], 'y': data.loc[1] }; + if (data.loc) heroLoc = { x: data.loc[0], y: data.loc[1] }; if (data.direction) heroLoc.direction = data.direction; if (core.status.event.id != 'action') core.status.event.id = null; core.changeFloor(data.floorId, data.stair, heroLoc, data.time, function () { core.replay(); if (callback) callback(); }); -} +}; ////// 楼层切换 ////// -events.prototype.changeFloor = function (floorId, stair, heroLoc, time, callback) { +events.prototype.changeFloor = function ( + floorId, + stair, + heroLoc, + time, + callback +) { var info = this._changeFloor_getInfo(floorId, stair, heroLoc, time); if (info == null) { if (callback) callback(); @@ -711,24 +828,29 @@ events.prototype.changeFloor = function (floorId, stair, heroLoc, time, callback core.interval.onDownInterval = 'tmp'; this._changeFloor_beforeChange(info, callback); -} +}; -events.prototype._changeFloor_getInfo = function (floorId, stair, heroLoc, time) { +events.prototype._changeFloor_getInfo = function ( + floorId, + stair, + heroLoc, + time +) { floorId = floorId || core.status.floorId; if (floorId == ':before') { var index = core.floorIds.indexOf(core.status.floorId); if (index > 0) floorId = core.floorIds[index - 1]; else floorId = core.status.floorId; - } - else if (floorId == ':next') { + } else if (floorId == ':next') { var index = core.floorIds.indexOf(core.status.floorId); - if (index < core.floorIds.length - 1) floorId = core.floorIds[index + 1]; + if (index < core.floorIds.length - 1) + floorId = core.floorIds[index + 1]; else floorId = core.status.floorId; } else if (floorId == ':now') { floorId = core.status.floorId; } if (!core.status.maps[floorId]) { - console.error("不存在的楼层:" + floorId); + console.error('不存在的楼层:' + floorId); return null; } @@ -739,22 +861,21 @@ events.prototype._changeFloor_getInfo = function (floorId, stair, heroLoc, time) return { floorId: floorId, time: time, - heroLoc: core.clone(this._changeFloor_getHeroLoc(floorId, stair, heroLoc)) + heroLoc: core.clone( + this._changeFloor_getHeroLoc(floorId, stair, heroLoc) + ) }; -} +}; events.prototype._changeFloor_getHeroLoc = function (floorId, stair, heroLoc) { - if (!heroLoc) - heroLoc = core.clone(core.status.hero.loc); + if (!heroLoc) heroLoc = core.clone(core.status.hero.loc); if (stair) { // --- 对称 - if (stair == ':now') - heroLoc = core.clone(core.status.hero.loc); + if (stair == ':now') heroLoc = core.clone(core.status.hero.loc); else if (stair == ':symmetry') { heroLoc.x = core.bigmap.width - 1 - core.getHeroLoc('x'); heroLoc.y = core.bigmap.height - 1 - core.getHeroLoc('y'); - } - else if (stair == ':symmetry_x') + } else if (stair == ':symmetry_x') heroLoc.x = core.bigmap.width - 1 - core.getHeroLoc('x'); else if (stair == ':symmetry_y') heroLoc.y = core.bigmap.height - 1 - core.getHeroLoc('y'); @@ -762,8 +883,7 @@ events.prototype._changeFloor_getHeroLoc = function (floorId, stair, heroLoc) { else if (core.status.maps[floorId][stair]) { heroLoc.x = core.status.maps[floorId][stair][0]; heroLoc.y = core.status.maps[floorId][stair][1]; - } - else { + } else { core.extractBlocks(floorId); var blocks = core.status.maps[floorId].blocks; for (var i in blocks) { @@ -776,34 +896,37 @@ events.prototype._changeFloor_getHeroLoc = function (floorId, stair, heroLoc) { } } ['x', 'y', 'direction'].forEach(function (name) { - if (heroLoc[name] == null) - heroLoc[name] = core.getHeroLoc(name); + if (heroLoc[name] == null) heroLoc[name] = core.getHeroLoc(name); }); return heroLoc; -} +}; events.prototype._changeFloor_beforeChange = function (info, callback) { this._changeFloor_playSound(); // 需要 setTimeout 执行,不然会出错 window.setTimeout(function () { - if (info.time == 0) - core.events._changeFloor_changing(info, callback); + if (info.time == 0) core.events._changeFloor_changing(info, callback); else - core.showWithAnimate(core.dom.floorMsgGroup, info.time / 2, function () { - core.events._changeFloor_changing(info, callback); - }); - }, 25) -} + core.showWithAnimate( + core.dom.floorMsgGroup, + info.time / 2, + function () { + core.events._changeFloor_changing(info, callback); + } + ); + }, 25); +}; events.prototype._changeFloor_playSound = function () { // 播放换层音效 - if (core.hasFlag('__fromLoad__')) // 是否是读档造成的切换 + if (core.hasFlag('__fromLoad__')) + // 是否是读档造成的切换 core.playSound('读档'); - else if (core.hasFlag('__isFlying__')) // 是否是楼传造成的切换 + else if (core.hasFlag('__isFlying__')) + // 是否是楼传造成的切换 core.playSound('飞行器'); - else - core.playSound('上下楼'); -} + else core.playSound('上下楼'); +}; events.prototype._changeFloor_changing = function (info, callback) { this.changingFloor(info.floorId, info.heroLoc); @@ -813,13 +936,16 @@ events.prototype._changeFloor_changing = function (info, callback) { core.drawHero(); core.setFlag('__lockViewport__', __lockViewport__); - if (info.time == 0) - this._changeFloor_afterChange(info, callback); + if (info.time == 0) this._changeFloor_afterChange(info, callback); else - core.hideWithAnimate(core.dom.floorMsgGroup, info.time / 4, function () { - core.events._changeFloor_afterChange(info, callback); - }); -} + core.hideWithAnimate( + core.dom.floorMsgGroup, + info.time / 4, + function () { + core.events._changeFloor_afterChange(info, callback); + } + ); +}; events.prototype._changeFloor_afterChange = function (info, callback) { if (!info.locked) core.unlockControl(); @@ -827,34 +953,34 @@ events.prototype._changeFloor_afterChange = function (info, callback) { core.events.afterChangeFloor(info.floorId); if (callback) callback(); -} +}; events.prototype.changingFloor = function (floorId, heroLoc) { this.eventdata.changingFloor(floorId, heroLoc); -} +}; ////// 转换楼层结束的事件 ////// events.prototype.afterChangeFloor = function (floorId) { if (main.mode != 'play') return; return this.eventdata.afterChangeFloor(floorId); -} +}; ////// 是否到达过某个楼层 ////// events.prototype.hasVisitedFloor = function (floorId) { - if (!core.hasFlag("__visited__")) core.setFlag("__visited__", {}); - return core.getFlag("__visited__")[floorId] || false; -} + if (!core.hasFlag('__visited__')) core.setFlag('__visited__', {}); + return core.getFlag('__visited__')[floorId] || false; +}; ////// 到达某楼层 ////// events.prototype.visitFloor = function (floorId) { - if (!core.hasFlag("__visited__")) core.setFlag("__visited__", {}); - core.getFlag("__visited__")[floorId] = true; -} + if (!core.hasFlag('__visited__')) core.setFlag('__visited__', {}); + core.getFlag('__visited__')[floorId] = true; +}; events.prototype._sys_pushBox = function (data, callback) { this.pushBox(data); if (callback) callback(); -} +}; ////// 推箱子 ////// events.prototype.pushBox = function (data) { @@ -862,7 +988,8 @@ events.prototype.pushBox = function (data) { // 判断还能否前进,看看是否存在事件 var direction = core.getHeroLoc('direction'), - nx = data.x + core.utils.scan[direction].x, ny = data.y + core.utils.scan[direction].y; + nx = data.x + core.utils.scan[direction].x, + ny = data.y + core.utils.scan[direction].y; // 检测能否推上去 if (!core.canMoveHero()) return; @@ -879,53 +1006,59 @@ events.prototype.pushBox = function (data) { core.setBlock(nextId == null ? 'box' : 'boxed', nx, ny); - if (data.event.id == 'box') - core.removeBlock(data.x, data.y); - else - core.setBlock('flower', data.x, data.y); + if (data.event.id == 'box') core.removeBlock(data.x, data.y); + else core.setBlock('flower', data.x, data.y); // 勇士前进一格,然后触发推箱子后事件 core.insertAction([ - { "type": "moveAction" }, - { "type": "function", "function": "function() { core.afterPushBox(); }" } + { type: 'moveAction' }, + { type: 'function', function: 'function() { core.afterPushBox(); }' } ]); -} +}; ////// 推箱子后的事件 ////// events.prototype.afterPushBox = function () { return this.eventdata.afterPushBox(); -} +}; events.prototype._sys_ski = function (data, callback) { - core.insertAction(["V2.6后,请将滑冰放在背景层!"], data.x, data.y); + core.insertAction(['V2.6后,请将滑冰放在背景层!'], data.x, data.y); if (callback) callback(); -} +}; /// 当前是否在冰上 events.prototype.onSki = function (number) { if (number == null) number = core.getBgNumber(); var block = core.getBlockByNumber(number); return block && block.event && block.event.trigger == 'ski'; -} +}; events.prototype._sys_action = function (data, callback) { - var ev = core.clone(data.event.data), ex = data.x, ey = data.y; + var ev = core.clone(data.event.data), + ex = data.x, + ey = data.y; // 检查是否需要改变朝向 if (ex == core.nextX() && ey == core.nextY()) { - var dir = core.turnDirection(":back"); - var id = data.event.id, toId = (data.event.faceIds || {})[dir]; + var dir = core.turnDirection(':back'); + var id = data.event.id, + toId = (data.event.faceIds || {})[dir]; if (toId && id != toId) { var number = core.getNumberById(toId); - if (number > 0) - core.setBlock(number, ex, ey); + if (number > 0) core.setBlock(number, ex, ey); } } this.insertAction(ev, ex, ey, callback); -} +}; events.prototype._sys_custom = function (data, callback) { - core.insertAction(["请使用\r[yellow]core.registerSystemEvent('custom', func)\r来处理自己添加的系统触发器!"], - data.x, data.y, callback); -} + core.insertAction( + [ + "请使用\r[yellow]core.registerSystemEvent('custom', func)\r来处理自己添加的系统触发器!" + ], + data.x, + data.y, + callback + ); +}; // ------ 自定义事件的处理 ------ // @@ -934,12 +1067,12 @@ events.prototype._sys_custom = function (data, callback) { // data为事件内容,x和y为当前点坐标(可为null),prefix为当前点前缀 events.prototype.registerEvent = function (type, func) { this.actions[type] = func; -} +}; ////// 注销一个自定义事件 events.prototype.unregisterEvent = function (type) { delete this.actions[type]; -} +}; ////// 执行一个自定义事件 events.prototype.doEvent = function (data, x, y, prefix) { @@ -947,24 +1080,24 @@ events.prototype.doEvent = function (data, x, y, prefix) { if (this.actions[type]) { try { return core.doFunc(this.actions[type], this, data, x, y, prefix); - } - catch (e) { + } catch (e) { console.error(e); - console.error("ERROR in actions[" + type + "]"); + console.error('ERROR in actions[' + type + ']'); } } - if (this["_action_" + type]) return this["_action_" + type](data, x, y, prefix); - core.insertAction("未知的自定义事件: " + type + "!"); + if (this['_action_' + type]) + return this['_action_' + type](data, x, y, prefix); + core.insertAction('未知的自定义事件: ' + type + '!'); core.doAction(); -} +}; events.prototype.setEvents = function (list, x, y, callback) { var data = core.status.event.data || {}; if (list) { var l = core.clone(list); if (!(l instanceof Array)) l = [l]; - l.push({ "type": "_label" }); - data.list = [{ todo: l, total: core.clone(l), condition: "false" }]; + l.push({ type: '_label' }); + data.list = [{ todo: l, total: core.clone(l), condition: 'false' }]; // 结束所有正在执行的自动事件 if (list.length == 0) { core.status.autoEvents.forEach(function (autoEvent) { @@ -979,7 +1112,7 @@ events.prototype.setEvents = function (list, x, y, callback) { if (!data.locStack) data.locStack = []; core.status.event.id = 'action'; core.status.event.data = data; -} +}; ////// 开始执行一系列自定义事件 ////// events.prototype.startEvents = function (list, x, y, callback) { @@ -993,7 +1126,7 @@ events.prototype.startEvents = function (list, x, y, callback) { core.lockControl(); core.doAction(); }); -} +}; ////// 执行当前自定义事件列表中的下一个事件 ////// events.prototype.doAction = function () { @@ -1009,22 +1142,26 @@ events.prototype.doAction = function () { core.clearUI(); var floorId = core.status.event.data.floorId || core.status.floorId; // 当前点坐标和前缀 - var x = core.status.event.data.x, y = core.status.event.data.y; - var prefix = [floorId || ":f", x != null ? x : "x", y != null ? y : "y"].join("@"); + var x = core.status.event.data.x, + y = core.status.event.data.y; + var prefix = [ + floorId || ':f', + x != null ? x : 'x', + y != null ? y : 'y' + ].join('@'); var current = core.status.event.data.list[0]; if (this._popEvents(current, prefix)) return; // 当前要执行的事件 var data = current.todo.shift(); core.status.event.data.current = data; - if (typeof data == "string") - data = { "type": "text", "text": data }; + if (typeof data == 'string') data = { type: 'text', text: data }; // 该事件块已经被禁用 if (data._disabled) return core.doAction(); data.floorId = data.floorId || floorId; core.status.event.data.type = data.type; this.doEvent(data, x, y, prefix); return; -} +}; events.prototype._doAction_finishEvents = function () { if (core.status.event.id != 'action') return true; @@ -1042,25 +1179,26 @@ events.prototype._doAction_finishEvents = function () { return true; } return false; -} +}; events.prototype._popEvents = function (current, prefix) { - if (current.todo.length == 0) { // current list is empty - if (core.calValue(current.condition, prefix)) { // check condition + if (current.todo.length == 0) { + // current list is empty + if (core.calValue(current.condition, prefix)) { + // check condition current.todo = core.clone(current.total); - } - else { + } else { core.status.event.data.list.shift(); // remove stack } core.doAction(); return true; } return false; -} +}; ////// 往当前事件列表之前或之后添加一个或多个事件 ////// events.prototype.insertAction = function (action, x, y, callback, addToLast) { - if (core.hasFlag("__statistics__")) return; + if (core.hasFlag('__statistics__')) return; if (core.status.gameOver) return; if (!action) return; core.clearRouteFolding(); @@ -1069,8 +1207,7 @@ events.prototype.insertAction = function (action, x, y, callback, addToLast) { if (core.status.event.id != 'action') { this.startEvents(action, x, y, callback); - } - else { + } else { if (addToLast) { var list = core.status.event.data.list[0].todo; var index = 0; @@ -1080,14 +1217,20 @@ events.prototype.insertAction = function (action, x, y, callback, addToLast) { break; } } - } - else core.unshift(core.status.event.data.list[0].todo, action); + } else core.unshift(core.status.event.data.list[0].todo, action); this.setEvents(null, x, y, callback); } -} +}; ////// 往当前事件列表之前或之后添加一个公共事件 ////// -events.prototype.insertCommonEvent = function (name, args, x, y, callback, addToLast) { +events.prototype.insertCommonEvent = function ( + name, + args, + x, + y, + callback, + addToLast +) { var commonEvent = this.getCommonEvent(name); if (!commonEvent) { if (callback) callback(); @@ -1099,20 +1242,27 @@ events.prototype.insertCommonEvent = function (name, args, x, y, callback, addTo if (args instanceof Array) { for (var i = 0; i < args.length; ++i) { try { - if (args[i] != null) - core.setFlag('arg' + (i + 1), args[i]); - } catch (ee) { console.error(ee) } + if (args[i] != null) core.setFlag('arg' + (i + 1), args[i]); + } catch (ee) { + console.error(ee); + } } } - this.insertAction({ "type": "dowhile", "condition": "false", "data": commonEvent }, x, y, callback, addToLast); -} + this.insertAction( + { type: 'dowhile', condition: 'false', data: commonEvent }, + x, + y, + callback, + addToLast + ); +}; ////// 获得一个公共事件 ////// events.prototype.getCommonEvent = function (name) { if (!name || typeof name !== 'string') return null; return this.commonEvent[name] || null; -} +}; ////// 恢复一个事件 ////// events.prototype.recoverEvents = function (data) { @@ -1127,22 +1277,30 @@ events.prototype.recoverEvents = function (data) { return true; } return false; -} +}; ////// 检测自动事件 ////// events.prototype.checkAutoEvents = function () { // 只有在无操作或事件流中才能执行自动事件! - if (!core.isPlaying() || (core.status.lockControl && core.status.event.id != 'action')) return; + if ( + !core.isPlaying() || + (core.status.lockControl && core.status.event.id != 'action') + ) + return; if (core.hasFlag('__doNotCheckAutoEvents__')) return; - var todo = [], delay = []; + var todo = [], + delay = []; core.status.autoEvents.forEach(function (autoEvent) { - var symbol = autoEvent.symbol, x = autoEvent.x, y = autoEvent.y, floorId = autoEvent.floorId; + var symbol = autoEvent.symbol, + x = autoEvent.x, + y = autoEvent.y, + floorId = autoEvent.floorId; // 不在当前楼层 or 已经执行过 or 已被分区 or 正在执行中 if (autoEvent.currentFloor && floorId != core.status.floorId) return; if (!autoEvent.multiExecute && core.autoEventExecuted(symbol)) return; if ((flags.__removed__ || []).indexOf(floorId) >= 0) return; if (core.autoEventExecuting(symbol)) return; - var prefix = floorId + "@" + x + "@" + y; + var prefix = floorId + '@' + x + '@' + y; try { if (!core.calValue(autoEvent.condition, prefix)) return; } catch (e) { @@ -1156,31 +1314,42 @@ events.prototype.checkAutoEvents = function () { if (x == null && y == null) { event = [ // 用do-while(0)包一层防止break影响事件流 - { "type": "dowhile", "condition": "false", "data": autoEvent.data }, + { type: 'dowhile', condition: 'false', data: autoEvent.data }, { - "type": "function", "function": - "function() { core.autoEventExecuting('" + symbol + "', false); }" + type: 'function', + function: + "function() { core.autoEventExecuting('" + + symbol + + "', false); }" } ]; } else { event = [ { - "type": "function", "function": - "function() { core.pushEventLoc(" + x + ", " + y + ", '" + floorId + "' ); }" + type: 'function', + function: + 'function() { core.pushEventLoc(' + + x + + ', ' + + y + + ", '" + + floorId + + "' ); }" }, // 用do-while(0)包一层防止break影响事件流 - { "type": "dowhile", "condition": "false", "data": autoEvent.data }, + { type: 'dowhile', condition: 'false', data: autoEvent.data }, { - "type": "function", "function": - "function() { core.popEventLoc(); core.autoEventExecuting('" + symbol + "', false); }" + type: 'function', + function: + "function() { core.popEventLoc(); core.autoEventExecuting('" + + symbol + + "', false); }" } ]; } - if (autoEvent.delayExecute) - delay.push(event); - else - core.push(todo, event); + if (autoEvent.delayExecute) delay.push(event); + else core.push(todo, event); }); if (todo.length == 0 && delay.length == 0) return; @@ -1194,28 +1363,31 @@ events.prototype.checkAutoEvents = function () { core.insertAction(delay.slice(1)); } } - -} +}; events.prototype.autoEventExecuting = function (symbol, value) { var aei = core.getFlag('__aei__', []); if (value == null) return aei.indexOf(symbol) >= 0; else { - aei = aei.filter(function (one) { return one != symbol; }); + aei = aei.filter(function (one) { + return one != symbol; + }); if (value) aei.push(symbol); core.setFlag('__aei__', aei); } -} +}; events.prototype.autoEventExecuted = function (symbol, value) { var aed = core.getFlag('__aed__', []); if (value == null) return aed.indexOf(symbol) >= 0; else { - aed = aed.filter(function (one) { return one != symbol; }); + aed = aed.filter(function (one) { + return one != symbol; + }); if (value) aed.push(symbol); core.setFlag('__aed__', aed); } -} +}; events.prototype.pushEventLoc = function (x, y, floorId) { if (core.status.event.id != 'action') return; @@ -1227,7 +1399,7 @@ events.prototype.pushEventLoc = function (x, y, floorId) { core.status.event.data.x = x; core.status.event.data.y = y; core.status.event.data.floorId = floorId; -} +}; events.prototype.popEventLoc = function () { if (core.status.event.id != 'action') return; @@ -1237,7 +1409,7 @@ events.prototype.popEventLoc = function () { core.status.event.data.y = loc.y; core.status.event.data.floorId = loc.floorId; } -} +}; events.prototype.precompile = function (data) { var array = this.__precompile_getArray(); @@ -1251,8 +1423,8 @@ events.prototype.precompile = function (data) { return data; } if (data && data.type) { - if (this["_precompile_" + data.type]) { - data = this["_precompile_" + data.type](data); + if (this['_precompile_' + data.type]) { + data = this['_precompile_' + data.type](data); } if (array.texts.indexOf(data.type) >= 0) { data.text = this.__precompile_text(data.text); @@ -1272,41 +1444,86 @@ events.prototype.precompile = function (data) { if (data.type in array.others) { array.others[data.type].forEach(function (field) { data[field] = core.replaceValue(data[field]); - }) + }); } } return data; -} +}; events.prototype.__precompile_getArray = function () { var texts = [ - "text", "autoText", "scrollText", "tip", "textImage", "input", "input2", - "choices", "confirm", "fillText", "fillBoldText", "drawTextContent" + 'text', + 'autoText', + 'scrollText', + 'tip', + 'textImage', + 'input', + 'input2', + 'choices', + 'confirm', + 'fillText', + 'fillBoldText', + 'drawTextContent' ]; var locs = [ - "show", "hide", "setBlock", "setBlockOpacity", "showFloorImg", "hideFloorImg", "showBgFgMap", - "hideBgFgMap", "setBgFgBlock", "animate", "setViewport", "move", "jumoHero", - "changeFloor", "changePos", "showTextImage", "showGif", "openDoor", - "closeDoor", "battle", "trigger", "insert", "setEnemyOnPoint", "resetEnemyOnPoint" + 'show', + 'hide', + 'setBlock', + 'setBlockOpacity', + 'showFloorImg', + 'hideFloorImg', + 'showBgFgMap', + 'hideBgFgMap', + 'setBgFgBlock', + 'animate', + 'setViewport', + 'move', + 'jumoHero', + 'changeFloor', + 'changePos', + 'showTextImage', + 'showGif', + 'openDoor', + 'closeDoor', + 'battle', + 'trigger', + 'insert', + 'setEnemyOnPoint', + 'resetEnemyOnPoint' ]; var values = [ - "setValue", "setEnemy", "setEnemyOnPoint", "setEquip", "setFloor", "setGlobalValue", + 'setValue', + 'setEnemy', + 'setEnemyOnPoint', + 'setEquip', + 'setFloor', + 'setGlobalValue' ]; var uievents = [ - "clearMap", "fillText", "fillBoldText", "fillRect", "strokeRect", "fillEllipse", "strokeEllipse", - "fillArc", "strokeArc", "drawIcon", "drawSelector", "drawBackground", + 'clearMap', + 'fillText', + 'fillBoldText', + 'fillRect', + 'strokeRect', + 'fillEllipse', + 'strokeEllipse', + 'fillArc', + 'strokeArc', + 'drawIcon', + 'drawSelector', + 'drawBackground' ]; var others = { - "fillEllipse": ["a", "b", "angle"], - "strokeEllipse": ["a", "b", "angle"], - "fillRect": ["radius", "angle"], - "strokeRect": ["radius", "angle"], - "fillArc": ["r", "start", "end"], - "strokeArc": ["r", "start", "end"], - "drawLine": ["x1", "y1", "x2", "y2"], - "drawArrow": ["x1", "y1", "x2", "y2"], - "drawImage": ["x", "y", "w", "h", "x1", "y1", "w1", "h1", "angle"], - "drawTextContent": ["left", "top"], + fillEllipse: ['a', 'b', 'angle'], + strokeEllipse: ['a', 'b', 'angle'], + fillRect: ['radius', 'angle'], + strokeRect: ['radius', 'angle'], + fillArc: ['r', 'start', 'end'], + strokeArc: ['r', 'start', 'end'], + drawLine: ['x1', 'y1', 'x2', 'y2'], + drawArrow: ['x1', 'y1', 'x2', 'y2'], + drawImage: ['x', 'y', 'w', 'h', 'x1', 'y1', 'w1', 'h1', 'angle'], + drawTextContent: ['left', 'top'] }; return { texts: texts, @@ -1315,14 +1532,14 @@ events.prototype.__precompile_getArray = function () { uievents: uievents, others: others }; -} +}; events.prototype.__precompile_text = function (text) { if (typeof text != 'string') return text; return text.replace(/\${(.*?)}/g, function (word, value) { - return "${" + core.replaceValue(value) + "}"; + return '${' + core.replaceValue(value) + '}'; }); -} +}; events.prototype.__precompile_array = function (value) { if (typeof value == 'string') { @@ -1335,7 +1552,7 @@ events.prototype.__precompile_array = function (value) { } } return value; -} +}; // ------ 样板提供的的自定义事件 ------ // @@ -1345,7 +1562,7 @@ events.prototype.__action_checkReplaying = function () { return true; } return false; -} +}; events.prototype.__action_getLoc = function (loc, x, y, prefix) { if (loc) { @@ -1353,33 +1570,37 @@ events.prototype.__action_getLoc = function (loc, x, y, prefix) { y = core.calValue(loc[1], prefix); } return [x, y]; -} +}; events.prototype.__action_getHeroLoc = function (loc, prefix) { - return this.__action_getLoc(loc, core.getHeroLoc('x'), core.getHeroLoc('y'), prefix); -} + return this.__action_getLoc( + loc, + core.getHeroLoc('x'), + core.getHeroLoc('y'), + prefix + ); +}; events.prototype.__action_getLoc2D = function (loc, x, y, prefix) { if (!(loc && loc[0] instanceof Array)) loc = [this.__action_getLoc(loc, x, y, prefix)]; return loc; -} +}; events.prototype.__action_doAsyncFunc = function (isAsync, func) { var parameters = Array.prototype.slice.call(arguments, 2); if (isAsync) { func.apply(this, parameters); core.doAction(); - } - else { + } else { func.apply(this, parameters.concat(core.doAction)); } -} +}; events.prototype._action_text = function (data, x, y, prefix) { if (this.__action_checkReplaying()) return; data.text = core.replaceText(data.text, prefix); - var ctx = data.code ? ('__text__' + data.code) : null;; + var ctx = data.code ? '__text__' + data.code : null; data.ctx = ctx; if (core.getContextByName(ctx) && !data.showAll) { core.ui._animateUI('hide', ctx, function () { @@ -1396,103 +1617,138 @@ events.prototype._action_text = function (data, x, y, prefix) { if (data.async) core.doAction(); }); } -} +}; events.prototype._action_moveTextBox = function (data, x, y, prefix) { if (this.__action_checkReplaying()) return; - this.__action_doAsyncFunc(data.async, core.moveTextBox, - data.code, this.__action_getLoc(data.loc, x, y, prefix), data.relative, data.moveMode, data.time); -} + this.__action_doAsyncFunc( + data.async, + core.moveTextBox, + data.code, + this.__action_getLoc(data.loc, x, y, prefix), + data.relative, + data.moveMode, + data.time + ); +}; events.prototype._action_clearTextBox = function (data, x, y, prefix) { if (this.__action_checkReplaying()) return; core.clearTextBox(data.code, core.doAction); -} +}; events.prototype._action_autoText = function (data, x, y, prefix) { if (this.__action_checkReplaying()) return; data.text = core.replaceText(data.text, prefix); core.ui.drawTextBox(data.text); setTimeout(core.doAction, data.time || 3000); -} +}; events.prototype._action_scrollText = function (data, x, y, prefix) { if (this.__action_checkReplaying()) return; data.text = core.replaceText(data.text, prefix); - this.__action_doAsyncFunc(data.async, core.drawScrollText, data.text, data.time || 5000, data.lineHeight || 1.4); -} + this.__action_doAsyncFunc( + data.async, + core.drawScrollText, + data.text, + data.time || 5000, + data.lineHeight || 1.4 + ); +}; events.prototype._action_comment = function (data, x, y, prefix) { core.doAction(); -} +}; events.prototype._action__label = function (data, x, y, prefix) { core.doAction(); -} +}; events.prototype._action_setText = function (data, x, y, prefix) { this.setTextAttribute(data); core.doAction(); -} +}; events.prototype._action_tip = function (data, x, y, prefix) { core.drawTip(core.replaceText(data.text, prefix), data.icon); core.doAction(); -} +}; events.prototype._action_show = function (data, x, y, prefix) { data.loc = this.__action_getLoc2D(data.loc, x, y, prefix); if (data.time > 0 && data.floorId == core.status.floorId) { - this.__action_doAsyncFunc(data.async, core.animateBlock, data.loc, 'show', data.time); - } - else { + this.__action_doAsyncFunc( + data.async, + core.animateBlock, + data.loc, + 'show', + data.time + ); + } else { data.loc.forEach(function (t) { core.showBlock(t[0], t[1], data.floorId); }); core.doAction(); } -} +}; events.prototype._action_hide = function (data, x, y, prefix) { data.loc = this.__action_getLoc2D(data.loc, x, y, prefix); if (data.time > 0 && data.floorId == core.status.floorId) { - this.__action_doAsyncFunc(data.async, core.animateBlock, data.loc, data.remove ? 'remove' : 'hide', data.time); - } - else { + this.__action_doAsyncFunc( + data.async, + core.animateBlock, + data.loc, + data.remove ? 'remove' : 'hide', + data.time + ); + } else { data.loc.forEach(function (t) { if (data.remove) core.removeBlock(t[0], t[1], data.floorId); else core.hideBlock(t[0], t[1], data.floorId); }); core.doAction(); } -} +}; events.prototype._action_setBlock = function (data, x, y, prefix) { data.loc = this.__action_getLoc2D(data.loc, x, y, prefix); data.time = data.time || 0; data.floorId = data.floorId || core.status.floorId; if (data.time > 0 && data.floorId == core.status.floorId) { - this.__action_doAsyncFunc(data.async, core.animateSetBlocks, data.number, data.loc, data.floorId, data.time); + this.__action_doAsyncFunc( + data.async, + core.animateSetBlocks, + data.number, + data.loc, + data.floorId, + data.time + ); } else { data.loc.forEach(function (loc) { core.setBlock(data.number, loc[0], loc[1], data.floorId); }); core.doAction(); } -} +}; events.prototype._action_setBlockOpacity = function (data, x, y, prefix) { data.loc = this.__action_getLoc2D(data.loc, x, y, prefix); if (data.time > 0 && data.floorId == core.status.floorId) { - this.__action_doAsyncFunc(data.async, core.animateBlock, data.loc, data.opacity, data.time); - } - else { + this.__action_doAsyncFunc( + data.async, + core.animateBlock, + data.loc, + data.opacity, + data.time + ); + } else { data.loc.forEach(function (t) { core.setBlockOpacity(data.opacity, t[0], t[1], data.floorId); }); core.doAction(); } -} +}; events.prototype._action_setBlockFilter = function (data, x, y, prefix) { data.loc = this.__action_getLoc2D(data.loc, x, y, prefix); @@ -1500,7 +1756,7 @@ events.prototype._action_setBlockFilter = function (data, x, y, prefix) { core.setBlockFilter(data, t[0], t[1], data.floorId); }); core.doAction(); -} +}; events.prototype._action_turnBlock = function (data, x, y, prefix) { data.loc = this.__action_getLoc2D(data.loc, x, y, prefix); @@ -1508,23 +1764,41 @@ events.prototype._action_turnBlock = function (data, x, y, prefix) { core.turnBlock(data.direction, t[0], t[1], data.floorId); }); core.doAction(); -} +}; events.prototype._action_showFloorImg = function (data, x, y, prefix) { - core.maps.showFloorImage(this.__action_getLoc2D(data.loc, x, y, prefix), data.floorId, core.doAction); -} + core.maps.showFloorImage( + this.__action_getLoc2D(data.loc, x, y, prefix), + data.floorId, + core.doAction + ); +}; events.prototype._action_hideFloorImg = function (data, x, y, prefix) { - core.maps.hideFloorImage(this.__action_getLoc2D(data.loc, x, y, prefix), data.floorId, core.doAction); -} + core.maps.hideFloorImage( + this.__action_getLoc2D(data.loc, x, y, prefix), + data.floorId, + core.doAction + ); +}; events.prototype._action_showBgFgMap = function (data, x, y, prefix) { - core.maps.showBgFgMap(data.name, this.__action_getLoc2D(data.loc, x, y, prefix), data.floorId, core.doAction) -} + core.maps.showBgFgMap( + data.name, + this.__action_getLoc2D(data.loc, x, y, prefix), + data.floorId, + core.doAction + ); +}; events.prototype._action_hideBgFgMap = function (data, x, y, prefix) { - core.maps.hideBgFgMap(data.name, this.__action_getLoc2D(data.loc, x, y, prefix), data.floorId, core.doAction); -} + core.maps.hideBgFgMap( + data.name, + this.__action_getLoc2D(data.loc, x, y, prefix), + data.floorId, + core.doAction + ); +}; events.prototype._action_setBgFgBlock = function (data, x, y, prefix) { data.loc = this.__action_getLoc2D(data.loc, x, y, prefix); @@ -1532,110 +1806,175 @@ events.prototype._action_setBgFgBlock = function (data, x, y, prefix) { core.setBgFgBlock(data.name, data.number, t[0], t[1], data.floorId); }); core.doAction(); -} +}; events.prototype._action_follow = function (data, x, y, prefix) { this.follow(data.name); core.doAction(); -} +}; events.prototype._action_unfollow = function (data, x, y, prefix) { this.unfollow(data.name); core.doAction(); -} +}; events.prototype._action_animate = function (data, x, y, prefix) { if (data.loc == 'hero') { this.__action_doAsyncFunc(data.async, core.drawHeroAnimate, data.name); } else { data.loc = this.__action_getLoc(data.loc, x, y, prefix); - this.__action_doAsyncFunc(data.async, core.drawAnimate, data.name, data.loc[0], data.loc[1], data.alignWindow); + this.__action_doAsyncFunc( + data.async, + core.drawAnimate, + data.name, + data.loc[0], + data.loc[1], + data.alignWindow + ); } -} +}; events.prototype._action_stopAnimate = function (data, x, y, prefix) { core.stopAnimate(null, data.doCallback); core.doAction(); -} +}; events.prototype._action_setViewport = function (data, x, y, prefix) { if (data.dxy != null) { - data.loc = [core.bigmap.offsetX / 32 + (core.calValue(data.dxy[0], prefix) || 0), core.bigmap.offsetY / 32 + (core.calValue(data.dxy[1], prefix) || 0)]; + data.loc = [ + core.bigmap.offsetX / 32 + + (core.calValue(data.dxy[0], prefix) || 0), + core.bigmap.offsetY / 32 + (core.calValue(data.dxy[1], prefix) || 0) + ]; } else if (data.loc == null) { - data.loc = [core.getHeroLoc('x') - core._HALF_WIDTH_, core.getHeroLoc('y') - core._HALF_HEIGHT_]; + data.loc = [ + core.getHeroLoc('x') - core._HALF_WIDTH_, + core.getHeroLoc('y') - core._HALF_HEIGHT_ + ]; } else { data.loc = this.__action_getLoc(data.loc, x, y, prefix); } - this.__action_doAsyncFunc(data.async, core.moveViewport, data.loc[0], data.loc[1], data.moveMode, data.time); -} + this.__action_doAsyncFunc( + data.async, + core.moveViewport, + data.loc[0], + data.loc[1], + data.moveMode, + data.time + ); +}; events.prototype._action_lockViewport = function (data, x, y, prefix) { core.setFlag('__lockViewport__', data.lock || null); core.doAction(); -} +}; events.prototype._action_move = function (data, x, y, prefix) { var loc = this.__action_getLoc(data.loc, x, y, prefix); - this.__action_doAsyncFunc(data.async, core.moveBlock, loc[0], loc[1], data.steps, data.time, data.keep); -} + this.__action_doAsyncFunc( + data.async, + core.moveBlock, + loc[0], + loc[1], + data.steps, + data.time, + data.keep + ); +}; events.prototype._action_moveAction = function (data, x, y, prefix) { // 检查下一个点是否可通行 if (core.canMoveHero()) { - var nx = core.nextX(), ny = core.nextY(); + var nx = core.nextX(), + ny = core.nextY(); // 检查noPass决定是撞击还是移动 if (core.noPass(nx, ny)) { - core.insertAction([ - { "type": "trigger", "loc": [nx, ny] } - ]); + core.insertAction([{ type: 'trigger', loc: [nx, ny] }]); } else { // 先移动一格,然后尝试触发事件 core.insertAction([ - { "type": "moveHero", "steps": ["forward"] }, - { "type": "function", "function": "function() { core.moveOneStep(core.doAction); }", "async": true }, - { "type": "_label" }, + { type: 'moveHero', steps: ['forward'] }, + { + type: 'function', + function: 'function() { core.moveOneStep(core.doAction); }', + async: true + }, + { type: '_label' } ]); } } core.doAction(); -} +}; events.prototype._action_moveHero = function (data, x, y, prefix) { - this.__action_doAsyncFunc(data.async, core.eventMoveHero, data.steps, data.time); -} + this.__action_doAsyncFunc( + data.async, + core.eventMoveHero, + data.steps, + data.time + ); +}; events.prototype._action_jump = function (data, x, y, prefix) { - var from = this.__action_getLoc(data.from, x, y, prefix), to; + var from = this.__action_getLoc(data.from, x, y, prefix), + to; if (data.dxy) { - to = [from[0] + (core.calValue(data.dxy[0], prefix) || 0), from[1] + (core.calValue(data.dxy[1], prefix) || 0)]; + to = [ + from[0] + (core.calValue(data.dxy[0], prefix) || 0), + from[1] + (core.calValue(data.dxy[1], prefix) || 0) + ]; } else { to = this.__action_getLoc(data.to, x, y, prefix); } - this.__action_doAsyncFunc(data.async, core.jumpBlock, from[0], from[1], to[0], to[1], data.time, data.keep); -} + this.__action_doAsyncFunc( + data.async, + core.jumpBlock, + from[0], + from[1], + to[0], + to[1], + data.time, + data.keep + ); +}; events.prototype._precompile_jump = function (data) { data.from = this.__precompile_array(data.from); data.to = this.__precompile_array(data.to); data.dxy = this.__precompile_array(data.dxy); return data; -} +}; events.prototype._action_jumpHero = function (data, x, y, prefix) { var loc; if (data.dxy) { - loc = [core.getHeroLoc('x') + (core.calValue(data.dxy[0], prefix) || 0), core.getHeroLoc('y') + (core.calValue(data.dxy[1], prefix) || 0)]; + loc = [ + core.getHeroLoc('x') + (core.calValue(data.dxy[0], prefix) || 0), + core.getHeroLoc('y') + (core.calValue(data.dxy[1], prefix) || 0) + ]; } else { loc = this.__action_getHeroLoc(data.loc, prefix); } - this.__action_doAsyncFunc(data.async, core.jumpHero, loc[0], loc[1], data.time); -} + this.__action_doAsyncFunc( + data.async, + core.jumpHero, + loc[0], + loc[1], + data.time + ); +}; events.prototype._action_changeFloor = function (data, x, y, prefix) { var loc = this.__action_getHeroLoc(data.loc, prefix); var heroLoc = { x: loc[0], y: loc[1], direction: data.direction }; - core.changeFloor(data.floorId, data.stair, heroLoc, data.time, core.doAction); -} + core.changeFloor( + data.floorId, + data.stair, + heroLoc, + data.time, + core.doAction + ); +}; events.prototype._action_changePos = function (data, x, y, prefix) { core.clearMap('hero'); @@ -1648,156 +1987,235 @@ events.prototype._action_changePos = function (data, x, y, prefix) { var loc = this.__action_getHeroLoc(data.loc, prefix); core.setHeroLoc('x', loc[0]); core.setHeroLoc('y', loc[1]); - if (data.direction) core.setHeroLoc('direction', core.turnDirection(data.direction)); + if (data.direction) + core.setHeroLoc('direction', core.turnDirection(data.direction)); core.drawHero(); core.doAction(); -} +}; events.prototype._action_showImage = function (data, x, y, prefix) { if (core.isReplaying()) data.time = 0; - this.__action_doAsyncFunc(data.async || data.time == 0, core.showImage, - data.code, data.image + (data.reverse || ''), data.sloc, data.loc, data.opacity, data.time); -} + this.__action_doAsyncFunc( + data.async || data.time == 0, + core.showImage, + data.code, + data.image + (data.reverse || ''), + data.sloc, + data.loc, + data.opacity, + data.time + ); +}; events.prototype._precompile_showImage = function (data) { data.sloc = this.__precompile_array(data.sloc); data.loc = this.__precompile_array(data.loc); return data; -} +}; events.prototype._action_showTextImage = function (data, x, y, prefix) { var loc = this.__action_getLoc(data.loc, 0, 0, prefix); if (core.isReplaying()) data.time = 0; data.text = core.replaceText(data.text, prefix); - var __tmpName = (Math.random() + "_" + Math.random()).replace(/\./g, "") + ".png"; + var __tmpName = + (Math.random() + '_' + Math.random()).replace(/\./g, '') + '.png'; core.material.images.images[__tmpName] = core.ui.textImage(data.text); - this.__action_doAsyncFunc(data.async || data.time == 0, core.showImage, - data.code, __tmpName + (data.reverse || ""), null, loc, data.opacity, data.time); + this.__action_doAsyncFunc( + data.async || data.time == 0, + core.showImage, + data.code, + __tmpName + (data.reverse || ''), + null, + loc, + data.opacity, + data.time + ); delete core.material.images.images[__tmpName]; -} +}; events.prototype._action_hideImage = function (data, x, y, prefix) { if (core.isReplaying()) data.time = 0; - this.__action_doAsyncFunc(data.async || data.time == 0, core.hideImage, data.code, data.time); -} + this.__action_doAsyncFunc( + data.async || data.time == 0, + core.hideImage, + data.code, + data.time + ); +}; events.prototype._action_showGif = function (data, x, y, prefix) { var loc = this.__action_getLoc(data.loc, 0, 0, prefix); this.showGif(data.name, loc[0], loc[1]); core.doAction(); -} +}; events.prototype._action_moveImage = function (data, x, y, prefix) { if (this.__action_checkReplaying()) return; - this.__action_doAsyncFunc(data.async, core.moveImage, data.code, data.to, data.opacity, data.moveMode, data.time); -} + this.__action_doAsyncFunc( + data.async, + core.moveImage, + data.code, + data.to, + data.opacity, + data.moveMode, + data.time + ); +}; events.prototype._precompile_moveImage = function (data) { data.to = this.__precompile_array(data.to); return data; -} +}; events.prototype._action_rotateImage = function (data, x, y, prefix) { if (this.__action_checkReplaying()) return; - this.__action_doAsyncFunc(data.async, core.rotateImage, data.code, data.center, data.angle, data.moveMode, data.time); -} + this.__action_doAsyncFunc( + data.async, + core.rotateImage, + data.code, + data.center, + data.angle, + data.moveMode, + data.time + ); +}; events.prototype._precompile_rotateImage = function (data) { data.center = this.__precompile_array(data.center); return data; -} +}; events.prototype._action_scaleImage = function (data, x, y, prefix) { if (this.__action_checkReplaying()) return; - this.__action_doAsyncFunc(data.async, core.scaleImage, data.code, data.center, data.scale, data.moveMode, data.time); -} + this.__action_doAsyncFunc( + data.async, + core.scaleImage, + data.code, + data.center, + data.scale, + data.moveMode, + data.time + ); +}; events.prototype._precompile_scaleImage = function (data) { data.center = this.__precompile_array(data.center); return data; -} +}; events.prototype._action_setCurtain = function (data, x, y, prefix) { if (data.async) { - core.setCurtain(data.color || core.status.thisMap.color, data.time, data.moveMode); - if (data.color == null || data.keep) core.setFlag('__color__', data.color || null); + core.setCurtain( + data.color || core.status.thisMap.color, + data.time, + data.moveMode + ); + if (data.color == null || data.keep) + core.setFlag('__color__', data.color || null); core.doAction(); + } else { + core.setCurtain( + data.color || core.status.thisMap.color, + data.time, + data.moveMode, + function () { + if (data.color == null || data.keep) + core.setFlag('__color__', data.color || null); + core.doAction(); + } + ); } - else { - core.setCurtain(data.color || core.status.thisMap.color, data.time, data.moveMode, function () { - if (data.color == null || data.keep) core.setFlag('__color__', data.color || null); - core.doAction(); - }); - } -} +}; events.prototype._action_screenFlash = function (data, x, y, prefix) { - this.__action_doAsyncFunc(data.async, core.screenFlash, data.color, data.time, data.times, data.moveMode); -} + this.__action_doAsyncFunc( + data.async, + core.screenFlash, + data.color, + data.time, + data.times, + data.moveMode + ); +}; events.prototype._action_setWeather = function (data, x, y, prefix) { core.setWeather(data.name, data.level); - if (data.keep && ['rain', 'snow', 'sun', 'fog', 'cloud'].indexOf(data.name) >= 0) + if ( + data.keep && + ['rain', 'snow', 'sun', 'fog', 'cloud'].indexOf(data.name) >= 0 + ) core.setFlag('__weather__', [data.name, data.level]); else core.removeFlag('__weather__'); core.doAction(); -} +}; events.prototype._action_openDoor = function (data, x, y, prefix) { var loc = this.__action_getLoc(data.loc, x, y, prefix); var floorId = data.floorId; if (floorId == core.status.floorId) { - this.__action_doAsyncFunc(data.async, core.openDoor, loc[0], loc[1], data.needKey); - } - else { + this.__action_doAsyncFunc( + data.async, + core.openDoor, + loc[0], + loc[1], + data.needKey + ); + } else { core.removeBlock(loc[0], loc[1], floorId); core.doAction(); } -} +}; events.prototype._action_closeDoor = function (data, x, y, prefix) { var loc = this.__action_getLoc(data.loc, x, y, prefix); - this.__action_doAsyncFunc(data.async, core.closeDoor, loc[0], loc[1], data.id); -} + this.__action_doAsyncFunc( + data.async, + core.closeDoor, + loc[0], + loc[1], + data.id + ); +}; events.prototype._action_useItem = function (data, x, y, prefix) { // 考虑到可能覆盖楼传事件的问题,这里不对fly进行检查。 if (data.id != 'book' && core.canUseItem(data.id)) { core.useItem(data.id, true, core.doAction); - } - else { + } else { core.playSound('操作失败'); - core.drawTip("当前无法使用" + ((core.material.items[data.id] || {}).name || "未知道具")); + core.drawTip( + '当前无法使用' + + ((core.material.items[data.id] || {}).name || '未知道具') + ); core.doAction(); } -} +}; events.prototype._action_loadEquip = function (data, x, y, prefix) { core.loadEquip(data.id); core.doAction(); -} +}; events.prototype._action_unloadEquip = function (data, x, y, prefix) { core.unloadEquip(data.pos); core.doAction(); -} +}; events.prototype._action_openShop = function (data, x, y, prefix) { core.setShopVisited(data.id, true); if (data.open) core.openShop(data.id, true); core.doAction(); -} +}; events.prototype._action_disableShop = function (data, x, y, prefix) { core.setShopVisited(data.id, false); core.doAction(); -} +}; events.prototype._action_battle = function (data, x, y, prefix) { if (data.id) { this.battle(data.id, null, null, true, core.doAction); - } - else { + } else { if (data.floorId != core.status.floorId) { core.doAction(); return; @@ -1805,62 +2223,64 @@ events.prototype._action_battle = function (data, x, y, prefix) { var loc = this.__action_getLoc(data.loc, x, y, prefix); this.battle(null, loc[0], loc[1], true, core.doAction); } -} +}; events.prototype._action_trigger = function (data, x, y, prefix) { var loc = this.__action_getLoc(data.loc, x, y, prefix); this._trigger_inAction(loc[0], loc[1]); -} +}; events.prototype._action_insert = function (data, x, y, prefix) { - if (data.name) { // 公共事件 + if (data.name) { + // 公共事件 core.insertCommonEvent(data.name, data.args); - } - else { + } else { // 设置参数 if (data.args instanceof Array) { for (var i = 0; i < data.args.length; ++i) { try { if (data.args[i] != null) core.setFlag('arg' + (i + 1), data.args[i]); - } catch (ee) { console.error(ee) } + } catch (ee) { + console.error(ee); + } } } var loc = this.__action_getLoc(data.loc, x, y, prefix); core.setFlag('arg0', loc); var floorId = data.floorId; - var which = data.which || "events"; - var event = (core.floors[floorId][which] || [])[loc[0] + "," + loc[1]]; + var which = data.which || 'events'; + var event = (core.floors[floorId][which] || [])[loc[0] + ',' + loc[1]]; if (event) this.insertAction(event.data || event); } core.doAction(); -} +}; events.prototype._action_playBgm = function (data, x, y, prefix) { core.playBgm(data.name, data.startTime || 0); - core.setFlag("__bgm__", data.keep ? data.name : null); + core.setFlag('__bgm__', data.keep ? data.name : null); core.doAction(); -} +}; events.prototype._action_pauseBgm = function (data, x, y, prefix) { core.pauseBgm(); core.doAction(); -} +}; events.prototype._action_resumeBgm = function (data, x, y, prefix) { core.resumeBgm(data.resume); core.doAction(); -} +}; events.prototype._action_loadBgm = function (data, x, y, prefix) { core.loadBgm(data.name); core.doAction(); -} +}; events.prototype._action_freeBgm = function (data, x, y, prefix) { core.freeBgm(data.name); core.doAction(); -} +}; events.prototype._action_playSound = function (data, x, y, prefix) { if (data.stop) core.stopSound(); @@ -1870,23 +2290,28 @@ events.prototype._action_playSound = function (data, x, y, prefix) { core.playSound(data.name, data.pitch); core.doAction(); } -} +}; events.prototype._action_stopSound = function (data, x, y, prefix) { core.stopSound(); core.doAction(); -} +}; events.prototype._action_setVolume = function (data, x, y, prefix) { data.value = core.clamp(parseInt(data.value) / 100, 0, 1); - core.setFlag("__volume__", data.value); - this.__action_doAsyncFunc(data.async, core.setVolume, data.value, data.time || 0); -} + core.setFlag('__volume__', data.value); + this.__action_doAsyncFunc( + data.async, + core.setVolume, + data.value, + data.time || 0 + ); +}; events.prototype._action_setBgmSpeed = function (data, x, y, prefix) { core.setBgmSpeed(data.value, data.pitch || false); core.doAction(); -} +}; events.prototype._action_setValue = function (data, x, y, prefix) { this.setValue(data.name, data.operator, data.value, prefix); @@ -1900,25 +2325,41 @@ events.prototype._action_setValue = function (data, x, y, prefix) { } } core.doAction(); -} +}; events.prototype._action_addValue = function (data, x, y, prefix) { data.operator = '+='; this._action_setValue(data, x, y, prefix); -} +}; events.prototype._action_setEnemy = function (data, x, y, prefix) { - this.setEnemy(data.id, data.name, data.value, data.operator, prefix, data.norefresh); + this.setEnemy( + data.id, + data.name, + data.value, + data.operator, + prefix, + data.norefresh + ); core.doAction(); -} +}; events.prototype._action_setEnemyOnPoint = function (data, x, y, prefix) { var loc = this.__action_getLoc2D(data.loc, x, y, prefix); loc.forEach(function (one) { - core.setEnemyOnPoint(one[0], one[1], data.floorId, data.name, data.value, data.operator, prefix, data.norefresh); + core.setEnemyOnPoint( + one[0], + one[1], + data.floorId, + data.name, + data.value, + data.operator, + prefix, + data.norefresh + ); }); core.doAction(); -} +}; events.prototype._action_resetEnemyOnPoint = function (data, x, y, prefix) { var loc = this.__action_getLoc2D(data.loc, x, y, prefix); @@ -1926,153 +2367,188 @@ events.prototype._action_resetEnemyOnPoint = function (data, x, y, prefix) { core.resetEnemyOnPoint(one[0], one[1], data.floorId, data.norefresh); }); core.doAction(); -} +}; events.prototype._precompile_moveEnemyOnPoint = function (data) { data.from = this.__precompile_array(data.from); data.to = this.__precompile_array(data.to); data.dxy = this.__precompile_array(data.dxy); return data; -} +}; events.prototype._action_moveEnemyOnPoint = function (data, x, y, prefix) { - var from = this.__action_getLoc(data.from, x, y, prefix), to; + var from = this.__action_getLoc(data.from, x, y, prefix), + to; if (data.dxy) { - to = [from[0] + (core.calValue(data.dxy[0], prefix) || 0), from[1] + (core.calValue(data.dxy[1], prefix) || 0)]; + to = [ + from[0] + (core.calValue(data.dxy[0], prefix) || 0), + from[1] + (core.calValue(data.dxy[1], prefix) || 0) + ]; } else { to = this.__action_getLoc(data.to, x, y, prefix); } - this.moveEnemyOnPoint(from[0], from[1], to[0], to[1], data.floorId, data.norefresh); + this.moveEnemyOnPoint( + from[0], + from[1], + to[0], + to[1], + data.floorId, + data.norefresh + ); core.doAction(); -} +}; events.prototype._action_setEquip = function (data, x, y, prefix) { - core.setEquip(data.id, data.valueType, data.name, data.value, data.operator, prefix); + core.setEquip( + data.id, + data.valueType, + data.name, + data.value, + data.operator, + prefix + ); core.doAction(); -} +}; events.prototype._action_setFloor = function (data, x, y, prefix) { this.setFloorInfo(data.name, data.value, data.floorId, prefix); core.doAction(); -} +}; events.prototype._action_setGlobalAttribute = function (data, x, y, prefix) { this.setGlobalAttribute(data.name, data.value); core.doAction(); -} +}; events.prototype._action_setGlobalValue = function (data, x, y, prefix) { core.values[data.name] = data.value; core.doAction(); -} +}; events.prototype._action_setGlobalFlag = function (data, x, y, prefix) { this.setGlobalFlag(data.name, data.value); core.doAction(); -} +}; events.prototype._action_setNameMap = function (data, x, y, floorId) { this.setNameMap(data.name, data.value); core.doAction(); -} +}; events.prototype._action_setHeroIcon = function (data, x, y, prefix) { this.setHeroIcon(data.name, data.noDraw); core.doAction(); -} +}; events.prototype._action_input = function (data, x, y, prefix) { - this.__action_getInput(core.replaceText(data.text, prefix), false, function (value) { - value = parseInt(value) || 0; // 允许负整数 - core.status.route.push("input:" + value); - core.setFlag("input", value); - core.doAction(); - }); -} + this.__action_getInput( + core.replaceText(data.text, prefix), + false, + function (value) { + value = parseInt(value) || 0; // 允许负整数 + core.status.route.push('input:' + value); + core.setFlag('input', value); + core.doAction(); + } + ); +}; events.prototype._action_input2 = function (data, x, y, prefix) { - this.__action_getInput(core.replaceText(data.text, prefix), true, function (value) { - value = value || ""; - core.status.route.push("input2:" + core.encodeBase64(value)); - core.setFlag("input", value); - core.doAction(); - }); -} + this.__action_getInput( + core.replaceText(data.text, prefix), + true, + function (value) { + value = value || ''; + core.status.route.push('input2:' + core.encodeBase64(value)); + core.setFlag('input', value); + core.doAction(); + } + ); +}; events.prototype.__action_getInput = function (hint, isText, callback) { - var value, prefix = isText ? "input2:" : "input:"; + var value, + prefix = isText ? 'input2:' : 'input:'; if (core.isReplaying()) { var action = core.status.replay.toReplay.shift(); try { if (action.indexOf(prefix) != 0) { - console.warn("警告!当前需要一个 " + prefix + " 项,实际为 " + action); + console.warn( + '警告!当前需要一个 ' + prefix + ' 项,实际为 ' + action + ); core.status.replay.toReplay.unshift(action); return callback(isText ? '' : 0); } if (isText) value = core.decodeBase64(action.substring(7)); else value = parseInt(action.substring(6)); callback(value); - } - catch (e) { + } catch (e) { core.control._replay_error(action); return; } - } - else { + } else { core.myprompt(core.replaceText(hint), null, callback); } -} +}; events.prototype._action_if = function (data, x, y, prefix) { if (core.calValue(data.condition, prefix)) - core.events.insertAction(data["true"]) - else - core.events.insertAction(data["false"]) + core.events.insertAction(data['true']); + else core.events.insertAction(data['false']); core.doAction(); -} +}; events.prototype._precompile_if = function (data) { data.condition = core.replaceValue(data.condition); - data["true"] = this.precompile(data["true"]); - data["false"] = this.precompile(data["false"]); + data['true'] = this.precompile(data['true']); + data['false'] = this.precompile(data['false']); return data; -} +}; events.prototype._action_switch = function (data, x, y, prefix) { - var key = core.calValue(data.condition, prefix) + var key = core.calValue(data.condition, prefix); var list = []; for (var i = 0; i < data.caseList.length; i++) { if (data.caseList[i]._disabled) continue; - var condition = data.caseList[i]["case"]; - if (condition == "default" || core.calValue(condition, prefix) === key) { + var condition = data.caseList[i]['case']; + if ( + condition == 'default' || + core.calValue(condition, prefix) === key + ) { core.push(list, data.caseList[i].action); - if (!data.caseList[i].nobreak) - break; + if (!data.caseList[i].nobreak) break; } } core.insertAction(list); core.doAction(); -} +}; events.prototype._precompile_switch = function (data) { data.condition = core.replaceValue(data.condition); for (var i = 0; i < data.caseList.length; i++) { - data.caseList[i]["case"] = core.replaceValue(data.caseList[i]["case"]); + data.caseList[i]['case'] = core.replaceValue(data.caseList[i]['case']); data.caseList[i].action = this.precompile(data.caseList[i].action); } return data; -} +}; events.prototype._action_choices = function (data, x, y, prefix) { data.choices = data.choices.filter(function (x) { if (x._disabled) return false; if (x.condition == null || x.condition == '') return true; - try { return core.calValue(x.condition, prefix); } catch (e) { return true; } - }) + try { + return core.calValue(x.condition, prefix); + } catch (e) { + return true; + } + }); if (data.choices.length == 0) return this.doAction(); if (core.isReplaying()) { var action = core.status.replay.toReplay.shift(); - if (action.indexOf('choices:') == 0 && !(action == 'choices:none' && !data.timeout)) { + if ( + action.indexOf('choices:') == 0 && + !(action == 'choices:none' && !data.timeout) + ) { var index = action.substring(8); if (!this.__action_choices_replaying(data, index)) { core.control._replay_error(action); @@ -2082,24 +2558,34 @@ events.prototype._action_choices = function (data, x, y, prefix) { // 容错录像 if (main.replayChecking) { // 录像验证系统中选最后一项 - if (action != 'choices:none') core.status.replay.toReplay.unshift(action); // 首先归还刚才读出的下一步操作 + if (action != 'choices:none') + core.status.replay.toReplay.unshift(action); // 首先归还刚才读出的下一步操作 core.events.__action_choices_replaying(data, -1); } else { // 正常游戏中弹窗选择 - core.myprompt('录像回放出错!当前需要执行选择项但录像中未记录。\n如需修复请输入您要选的项(从0起),点击取消将不会修复。', 0, function (value) { - if (value == null) { - core.control._replay_error(action); - return; + core.myprompt( + '录像回放出错!当前需要执行选择项但录像中未记录。\n如需修复请输入您要选的项(从0起),点击取消将不会修复。', + 0, + function (value) { + if (value == null) { + core.control._replay_error(action); + return; + } + if (action != 'choices:none') + core.status.replay.toReplay.unshift(action); // 首先归还刚才读出的下一步操作 + core.events.__action_choices_replaying( + data, + ((parseInt(value) || 0) + data.choices.length) % + data.choices.length + ); } - if (action != 'choices:none') core.status.replay.toReplay.unshift(action); // 首先归还刚才读出的下一步操作 - core.events.__action_choices_replaying(data, ((parseInt(value) || 0) + data.choices.length) % data.choices.length); - }); + ); } } } else { if (data.timeout) { core.status.event.interval = setTimeout(function () { - core.status.route.push("choices:none"); + core.status.route.push('choices:none'); core.setFlag('timeout', 0); core.doAction(); }, data.timeout); @@ -2108,11 +2594,15 @@ events.prototype._action_choices = function (data, x, y, prefix) { } for (var i = 0; i < data.choices.length; i++) { if (typeof data.choices[i] === 'string') - data.choices[i] = { "text": data.choices[i] }; + data.choices[i] = { text: data.choices[i] }; data.choices[i].text = core.replaceText(data.choices[i].text, prefix); } - core.ui.drawChoices(core.replaceText(data.text, prefix), data.choices, data.width); -} + core.ui.drawChoices( + core.replaceText(data.text, prefix), + data.choices, + data.width + ); +}; events.prototype.__action_choices_replaying = function (data, index) { var selection = index; @@ -2128,42 +2618,59 @@ events.prototype.__action_choices_replaying = function (data, index) { selection %= 100; } else core.setFlag('timeout', 0); core.status.event.selection = selection; - setTimeout(function () { - core.status.route.push("choices:" + index); - if (selection != 'none') { - // 检查 - var choice = data.choices[selection]; - if (choice.need != null && choice.need != '' && !core.calValue(choice.need)) { - // 无法选择此项 - core.control._replay_error("无法选择项:" + index); - return; - } else { - core.insertAction(choice.action); + setTimeout( + function () { + core.status.route.push('choices:' + index); + if (selection != 'none') { + // 检查 + var choice = data.choices[selection]; + if ( + choice.need != null && + choice.need != '' && + !core.calValue(choice.need) + ) { + // 无法选择此项 + core.control._replay_error('无法选择项:' + index); + return; + } else { + core.insertAction(choice.action); + } } - } - core.doAction(); - }, core.status.replay.speed == 24 ? 1 : 750 / Math.max(1, core.status.replay.speed)); + core.doAction(); + }, + core.status.replay.speed == 24 + ? 1 + : 750 / Math.max(1, core.status.replay.speed) + ); return true; -} +}; events.prototype._precompile_choices = function (data) { if (!(data.choices instanceof Array)) return data; for (var i = 0; i < data.choices.length; ++i) { - data.choices[i].condition = core.replaceValue(data.choices[i].condition); + data.choices[i].condition = core.replaceValue( + data.choices[i].condition + ); data.choices[i].text = this.__precompile_text(data.choices[i].text); data.choices[i].action = this.precompile(data.choices[i].action); } return data; -} +}; events.prototype._action_confirm = function (data, x, y, prefix) { data.text = core.replaceText(data.text, prefix); - core.status.event.ui = { "text": data.text, "yes": data.yes, "no": data.no }; + core.status.event.ui = { text: data.text, yes: data.yes, no: data.no }; if (core.isReplaying()) { var action = core.status.replay.toReplay.shift(); - if (action.indexOf('choices:') == 0 && !(action == 'choices:none' && !data.timeout)) { + if ( + action.indexOf('choices:') == 0 && + !(action == 'choices:none' && !data.timeout) + ) { var index = action.substring(8); - if (index == 'none' || ((index = parseInt(index)) >= 0) && index % 100 < 2) { + if ( + index == 'none' || + ((index = parseInt(index)) >= 0 && index % 100 < 2) + ) { this.__action_confirm_replaying(data, index); } else { core.control._replay_error(action); @@ -2171,15 +2678,15 @@ events.prototype._action_confirm = function (data, x, y, prefix) { } } else { // 录像中未记录选了哪个,则选默认值,而不是直接报错 - if (action != 'choices:none') core.status.replay.toReplay.unshift(action); - this.__action_confirm_replaying(data, data["default"] ? 0 : 1); + if (action != 'choices:none') + core.status.replay.toReplay.unshift(action); + this.__action_confirm_replaying(data, data['default'] ? 0 : 1); } - } - else { - core.status.event.selection = data["default"] ? 0 : 1; + } else { + core.status.event.selection = data['default'] ? 0 : 1; if (data.timeout) { core.status.event.interval = setTimeout(function () { - core.status.route.push("choices:none"); + core.status.route.push('choices:none'); core.setFlag('timeout', 0); core.doAction(); }, data.timeout); @@ -2187,7 +2694,7 @@ events.prototype._action_confirm = function (data, x, y, prefix) { core.status.event.timeout = new Date().getTime() + (data.timeout || 0); } core.ui.drawConfirmBox(data.text); -} +}; events.prototype.__action_confirm_replaying = function (data, index) { if (index != 'none') { @@ -2196,21 +2703,26 @@ events.prototype.__action_confirm_replaying = function (data, index) { index %= 100; } else core.setFlag('timeout', 0); core.status.event.selection = index; - setTimeout(function () { - core.status.route.push("choices:" + index); - if (index != 'none') { - if (index == 0) core.insertAction(data.yes); - else core.insertAction(data.no); - } - core.doAction(); - }, core.status.replay.speed == 24 ? 1 : 750 / Math.max(1, core.status.replay.speed)); -} + setTimeout( + function () { + core.status.route.push('choices:' + index); + if (index != 'none') { + if (index == 0) core.insertAction(data.yes); + else core.insertAction(data.no); + } + core.doAction(); + }, + core.status.replay.speed == 24 + ? 1 + : 750 / Math.max(1, core.status.replay.speed) + ); +}; events.prototype._precompile_confirm = function (data) { data.yes = this.precompile(data.yes); data.no = this.precompile(data.no); return data; -} +}; events.prototype._action_for = function (data, x, y, prefix) { // Only support temp:A @@ -2221,8 +2733,14 @@ events.prototype._action_for = function (data, x, y, prefix) { var from = core.calValue(data.from); var to = core.calValue(data.to); var step = core.calValue(data.step); - if (typeof from != 'number' || typeof to != 'number' || typeof step != 'number') { - core.insertAction('循环遍历事件要求【起始点】【终止点】【每步】仅能是数字!'); + if ( + typeof from != 'number' || + typeof to != 'number' || + typeof step != 'number' + ) { + core.insertAction( + '循环遍历事件要求【起始点】【终止点】【每步】仅能是数字!' + ); return core.doAction(); } // 首次判定 @@ -2237,19 +2755,33 @@ events.prototype._action_for = function (data, x, y, prefix) { var stepName = '@temp@for-step@' + letter; core.setFlag(toName, data.to); core.setFlag(stepName, data.step); - var condition = "(function () {" + - "var to = core.calValue(core.getFlag('" + toName + "'));" + - "var step = core.calValue(core.getFlag('" + stepName + "'));" + + var condition = + '(function () {' + + "var to = core.calValue(core.getFlag('" + + toName + + "'));" + + "var step = core.calValue(core.getFlag('" + + stepName + + "'));" + "if (typeof step != 'number' || typeof to != 'number') return false;" + - "if (step == 0) return true;" + - "var currentValue = core.getFlag('@temp@" + letter + "');" + - "currentValue += step;" + - "core.setFlag('@temp@" + letter + "', currentValue);" + - "if (step > 0) { return currentValue <= to; }" + - "else { return currentValue >= to; }" + - "})()"; - return this._action_dowhile({ "condition": condition, "data": data.data }, x, y, prefix); -} + 'if (step == 0) return true;' + + "var currentValue = core.getFlag('@temp@" + + letter + + "');" + + 'currentValue += step;' + + "core.setFlag('@temp@" + + letter + + "', currentValue);" + + 'if (step > 0) { return currentValue <= to; }' + + 'else { return currentValue >= to; }' + + '})()'; + return this._action_dowhile( + { condition: condition, data: data.data }, + x, + y, + prefix + ); +}; events.prototype._precompile_for = function (data) { data.from = core.replaceValue(data.from); @@ -2257,7 +2789,7 @@ events.prototype._precompile_for = function (data) { data.step = core.replaceValue(data.step); data.data = this.precompile(data.data); return data; -} +}; events.prototype._action_forEach = function (data, x, y, prefix) { // Only support temp:A @@ -2267,53 +2799,67 @@ events.prototype._action_forEach = function (data, x, y, prefix) { } var listName = '@temp@forEach@' + data.name.substring(5); core.setFlag(listName, core.clone(data.list)); - var condition = "(function () {" + - "var list = core.getFlag('" + listName + "', []);" + - "if (list.length == 0) return false;" + - "core.setFlag('@temp@'+'" + data.name.substring(5) + "', list.shift());" + - "return true;" + - "})()"; - return this._action_while({ "condition": condition, "data": data.data }, x, y, prefix); -} + var condition = + '(function () {' + + "var list = core.getFlag('" + + listName + + "', []);" + + 'if (list.length == 0) return false;' + + "core.setFlag('@temp@'+'" + + data.name.substring(5) + + "', list.shift());" + + 'return true;' + + '})()'; + return this._action_while( + { condition: condition, data: data.data }, + x, + y, + prefix + ); +}; events.prototype._precompile_forEach = function (data) { data.data = this.precompile(data.data); return data; -} +}; events.prototype._action_while = function (data, x, y, prefix) { if (core.calValue(data.condition, prefix)) { var list = core.clone(data.data); if (!(list instanceof Array)) list = [list]; - list.push({ "type": "_label" }); - core.unshift(core.status.event.data.list, - { "todo": list, "total": core.clone(list), "condition": data.condition } - ); + list.push({ type: '_label' }); + core.unshift(core.status.event.data.list, { + todo: list, + total: core.clone(list), + condition: data.condition + }); } core.doAction(); -} +}; events.prototype._precompile_while = function (data) { data.condition = core.replaceValue(data.condition); data.data = this.precompile(data.data); return data; -} +}; events.prototype._action_dowhile = function (data, x, y, prefix) { var list = core.clone(data.data); if (!(list instanceof Array)) list = [list]; - list.push({ "type": "_label" }); - core.unshift(core.status.event.data.list, - { "todo": list, "total": core.clone(list), "condition": data.condition } - ); + list.push({ type: '_label' }); + core.unshift(core.status.event.data.list, { + todo: list, + total: core.clone(list), + condition: data.condition + }); core.doAction(); -} +}; events.prototype._precompile_dowhile = function (data) { data.condition = core.replaceValue(data.condition); data.data = this.precompile(data.data); return data; -} +}; events.prototype._action_break = function (data, x, y, prefix) { var n = data.n || 1; @@ -2322,7 +2868,7 @@ events.prototype._action_break = function (data, x, y, prefix) { core.status.event.data.list.shift(); } core.doAction(); -} +}; events.prototype._action_continue = function (data, x, y, prefix) { var n = data.n || 1; @@ -2332,143 +2878,163 @@ events.prototype._action_continue = function (data, x, y, prefix) { } if (core.status.event.data.list.length > 1) { if (core.calValue(core.status.event.data.list[0].condition, prefix)) { - core.status.event.data.list[0].todo = core.clone(core.status.event.data.list[0].total); - } - else { + core.status.event.data.list[0].todo = core.clone( + core.status.event.data.list[0].total + ); + } else { core.status.event.data.list.shift(); } } core.doAction(); -} +}; events.prototype._action_win = function (data, x, y, prefix) { this.win(core.replaceText(data.reason, prefix), data.norank, data.noexit); -} +}; events.prototype._action_lose = function (data, x, y, prefix) { this.lose(core.replaceText(data.reason, prefix)); -} +}; events.prototype._action_restart = function (data, x, y, prefix) { core.restart(); -} +}; events.prototype._action_function = function (data, x, y, prefix) { - var func = data["function"]; + var func = data['function']; try { - if (typeof func == "string" && func.indexOf("function") == 0) { + if (typeof func == 'string' && func.indexOf('function') == 0) { eval('(' + func + ')()'); } } catch (e) { console.error(e); } - if (!data.async) - core.doAction(); -} + if (!data.async) core.doAction(); +}; events.prototype._action_update = function (data, x, y, prefix) { core.updateStatusBar(data.doNotCheckAutoEvents, true); core.doAction(); -} +}; events.prototype._action_showStatusBar = function (data, x, y, prefix) { core.showStatusBar(); core.doAction(); -} +}; events.prototype._action_hideStatusBar = function (data, x, y, prefix) { core.hideStatusBar(data.toolbox); core.doAction(); -} +}; events.prototype._action_showHero = function (data, x, y, prefix) { data.opacity = 1; return this._action_setHeroOpacity(data, x, y, prefix); -} +}; events.prototype._action_hideHero = function (data, x, y, prefix) { data.opacity = 0; return this._action_setHeroOpacity(data, x, y, prefix); -} +}; events.prototype._action_setHeroOpacity = function (data, x, y, prefix) { data.time = data.time || 0; if (data.opacity == null) data.opacity = 1; if (data.time > 0) { - this.__action_doAsyncFunc(data.async, core.setHeroOpacity, data.opacity, data.moveMode, data.time); + this.__action_doAsyncFunc( + data.async, + core.setHeroOpacity, + data.opacity, + data.moveMode, + data.time + ); } else { core.setFlag('__heroOpacity__', data.opacity); core.drawHero(); core.doAction(); } -} +}; events.prototype._action_vibrate = function (data, x, y, prefix) { - this.__action_doAsyncFunc(data.async, core.vibrate, data.direction, data.time, data.speed, data.power); -} + this.__action_doAsyncFunc( + data.async, + core.vibrate, + data.direction, + data.time, + data.speed, + data.power + ); +}; events.prototype._action_sleep = function (data, x, y, prefix) { - core.timeout.sleepTimeout = setTimeout(function () { - core.timeout.sleepTimeout = null; - core.doAction(); - }, core.isReplaying() ? Math.min(data.time, 20) : data.time); -} + core.timeout.sleepTimeout = setTimeout( + function () { + core.timeout.sleepTimeout = null; + core.doAction(); + }, + core.isReplaying() ? Math.min(data.time, 20) : data.time + ); +}; events.prototype._action_wait = function (data, x, y, prefix) { if (core.isReplaying()) { var code = core.status.replay.toReplay.shift(); - if (code.indexOf("input:") == 0 && !(code == "input:none" && !data.timeout)) { - if (code == "input:none") { - core.status.route.push("input:none"); - core.setFlag("type", -1); - core.setFlag("timeout", 0); + if ( + code.indexOf('input:') == 0 && + !(code == 'input:none' && !data.timeout) + ) { + if (code == 'input:none') { + core.status.route.push('input:none'); + core.setFlag('type', -1); + core.setFlag('timeout', 0); this.__action_wait_afterGet(data); return core.doAction(); } else { var value = parseInt(code.substring(6)); - core.status.route.push("input:" + value); + core.status.route.push('input:' + value); this.__action_wait_getValue(value); - if (this.__action_wait_afterGet(data) || !data.forceChild) return core.doAction(); + if (this.__action_wait_afterGet(data) || !data.forceChild) + return core.doAction(); } } core.control._replay_error(code); return; } else if (data.timeout) { core.status.event.interval = setTimeout(function () { - core.status.route.push("input:none"); - core.setFlag("type", -1); - core.setFlag("timeout", 0); + core.status.route.push('input:none'); + core.setFlag('type', -1); + core.setFlag('timeout', 0); core.events.__action_wait_afterGet(data); core.doAction(); }, data.timeout); } core.status.event.timeout = new Date().getTime() + (data.timeout || 0); -} +}; events.prototype.__action_wait_getValue = function (value) { - core.setFlag("timeout", Math.floor(value / 1e8) || 0); + core.setFlag('timeout', Math.floor(value / 1e8) || 0); value %= 1e8; if (value >= 1000000) { core.setFlag('type', 1); - var px = parseInt((value - 1000000) / 1000), py = value % 1000; + var px = parseInt((value - 1000000) / 1000), + py = value % 1000; core.setFlag('px', px); core.setFlag('py', py); core.setFlag('x', parseInt(px / 32)); core.setFlag('y', parseInt(py / 32)); - } - else if (value >= 10000) { + } else if (value >= 10000) { core.setFlag('type', 1); - var x = parseInt((value - 10000) / 100), y = value % 100; + var x = parseInt((value - 10000) / 100), + y = value % 100; core.setFlag('px', 32 * x + 16); core.setFlag('py', 32 * y + 16); core.setFlag('x', x); core.setFlag('y', y); - } - else if (value > 0) { + } else if (value > 0) { core.setFlag('type', 0); core.setFlag('keycode', value); } -} +}; events.prototype.__action_wait_afterGet = function (data) { if (!data.data) return false; @@ -2477,96 +3043,108 @@ events.prototype.__action_wait_afterGet = function (data) { var found = false; data.data.forEach(function (one) { if (one._disabled || stop) return; - if (one["case"] == "keyboard" && core.getFlag("type") == 0) { - (one.keycode + "").split(",").forEach(function (keycode) { - if (core.getFlag("keycode", 0) == keycode) { + if (one['case'] == 'keyboard' && core.getFlag('type') == 0) { + (one.keycode + '').split(',').forEach(function (keycode) { + if (core.getFlag('keycode', 0) == keycode) { found = true; core.push(todo, one.action); - if (one["break"]) stop = true; + if (one['break']) stop = true; } }); } - if (one["case"] == "mouse" && one.px instanceof Array - && one.py instanceof Array && core.getFlag("type") == 1) { + if ( + one['case'] == 'mouse' && + one.px instanceof Array && + one.py instanceof Array && + core.getFlag('type') == 1 + ) { var pxmin = core.calValue(one.px[0]); var pxmax = core.calValue(one.px[1]); var pymin = core.calValue(one.py[0]); var pymax = core.calValue(one.py[1]); - var px = core.getFlag("px", 0), py = core.getFlag("py", 0); + var px = core.getFlag('px', 0), + py = core.getFlag('py', 0); if (px >= pxmin && px <= pxmax && py >= pymin && py <= pymax) { found = true; core.push(todo, one.action); - if (one["break"]) stop = true; + if (one['break']) stop = true; } } - if (one["case"] == "condition") { + if (one['case'] == 'condition') { var condition = false; - try { condition = core.calValue(one.condition); } catch (e) { } + try { + condition = core.calValue(one.condition); + } catch (e) {} if (condition) { found = true; core.push(todo, one.action); - if (one["break"]) stop = true; + if (one['break']) stop = true; } } - if (one["case"] == "timeout" && core.getFlag("type") == -1) { + if (one['case'] == 'timeout' && core.getFlag('type') == -1) { found = true; core.push(todo, one.action); - if (one["break"]) stop = true; + if (one['break']) stop = true; } - }) + }); if (found) { core.insertAction(todo); return true; } return false; -} +}; events.prototype._precompile_wait = function (data) { if (data.data) { data.data.forEach(function (v) { if (v.px != null) v.px = this.__precompile_array(v.px); if (v.py != null) v.py = this.__precompile_array(v.py); - if (v.condition != null) v.condition = this.__precompile_array(v.condition); + if (v.condition != null) + v.condition = this.__precompile_array(v.condition); v.action = this.precompile(v.action); }, this); } return data; -} +}; events.prototype._action_waitAsync = function (data, x, y, prefix) { var test = window.setInterval(function () { - if (!core.hasAsync() - && (data.excludeAnimates || core.isReplaying() || core.getPlayingAnimates().length == 0) - && (!data.includeSounds || core.isReplaying() || core.getPlayingSounds().length == 0)) { + if ( + !core.hasAsync() && + (data.excludeAnimates || + core.isReplaying() || + core.getPlayingAnimates().length == 0) && + (!data.includeSounds || + core.isReplaying() || + core.getPlayingSounds().length == 0) + ) { clearInterval(test); core.doAction(); } }, 50 / core.status.replay.speed); -} +}; events.prototype._action_stopAsync = function (data, x, y, prefix) { core.stopAsync(); core.doAction(); -} +}; events.prototype._action_callBook = function (data, x, y, prefix) { if (core.isReplaying() || !core.hasItem('book')) { core.doAction(); - } - else { + } else { var e = core.clone(core.status.event.data); core.ui.closePanel(); core.openBook(); core.status.event.interval = e; } -} +}; events.prototype._action_callSave = function (data, x, y, prefix) { - if (core.isReplaying() || core.hasFlag("__events__")) { - core.removeFlag("__events__"); + if (core.isReplaying() || core.hasFlag('__events__')) { + core.removeFlag('__events__'); core.doAction(); - } - else { + } else { var e = core.clone(core.status.event.data); core.ui.closePanel(); var forbidSave = core.hasFlag('__forbidSave__'); @@ -2575,7 +3153,7 @@ events.prototype._action_callSave = function (data, x, y, prefix) { if (forbidSave) core.setFlag('__forbidSave__', true); core.status.event.interval = e; } -} +}; events.prototype._action_autoSave = function (data, x, y, prefix) { var forbidSave = core.hasFlag('__forbidSave__'); @@ -2583,12 +3161,12 @@ events.prototype._action_autoSave = function (data, x, y, prefix) { core.autosave(data.removeLast); if (forbidSave) core.setFlag('__forbidSave__', true); core.doAction(); -} +}; events.prototype._action_forbidSave = function (data, x, y, prefix) { core.setFlag('__forbidSave__', data.forbid || null); core.doAction(); -} +}; events.prototype._action_callLoad = function (data, x, y, prefix) { if (this.__action_checkReplaying()) return; @@ -2596,22 +3174,22 @@ events.prototype._action_callLoad = function (data, x, y, prefix) { core.ui.closePanel(); core.load(); core.status.event.interval = e; -} +}; events.prototype._action_exit = function (data, x, y, prefix) { this.setEvents([]); core.doAction(); -} +}; events.prototype._action_previewUI = function (data, x, y, prefix) { this.insertAction(data.action); core.doAction(); -} +}; events.prototype._precompile_previewUI = function (data) { data.action = this.precompile(data.action); return data; -} +}; events.prototype.__action_doUIEvent = function (data) { this.__action_doUIEvent_doOne(data); @@ -2623,7 +3201,7 @@ events.prototype.__action_doUIEvent = function (data) { else break; } core.doAction(); -} +}; events.prototype.__action_doUIEvent_doOne = function (data) { if (core.ui['_uievent_' + data.type]) { @@ -2631,100 +3209,100 @@ events.prototype.__action_doUIEvent_doOne = function (data) { return true; } return false; -} +}; events.prototype._action_clearMap = function (data, x, y, prefix) { this.__action_doUIEvent(data); -} +}; events.prototype._action_fillText = function (data, x, y, prefix) { data.text = core.replaceText(data.text, prefix); this.__action_doUIEvent(data); -} +}; events.prototype._action_fillBoldText = function (data, x, y, prefix) { data.text = core.replaceText(data.text, prefix); this.__action_doUIEvent(data); -} +}; events.prototype._action_fillRect = function (data, x, y, prefix) { this.__action_doUIEvent(data); -} +}; events.prototype._action_fillPolygon = function (data, x, y, prefix) { this.__action_doUIEvent(data); -} +}; events.prototype._precompile_fillPolygon = function (data) { data.nodes = this.__precompile_array(data.nodes); return data; -} +}; events.prototype._action_strokeRect = function (data, x, y, prefix) { this.__action_doUIEvent(data); -} +}; events.prototype._action_strokePolygon = function (data, x, y, prefix) { this.__action_doUIEvent(data); -} +}; events.prototype._precompile_strokePolygon = function (data) { data.nodes = this.__precompile_array(data.nodes); return data; -} +}; events.prototype._action_fillEllipse = function (data, x, y, prefix) { this.__action_doUIEvent(data); -} +}; events.prototype._action_strokeEllipse = function (data, x, y, prefix) { this.__action_doUIEvent(data); -} +}; events.prototype._action_fillArc = function (data, x, y, prefix) { this.__action_doUIEvent(data); -} +}; events.prototype._action_strokeArc = function (data, x, y, prefix) { this.__action_doUIEvent(data); -} +}; events.prototype._action_drawLine = function (data, x, y, prefix) { this.__action_doUIEvent(data); -} +}; events.prototype._action_drawArrow = function (data, x, y, prefix) { this.__action_doUIEvent(data); -} +}; events.prototype._action_setAttribute = function (data, x, y, prefix) { this.__action_doUIEvent(data); -} +}; events.prototype._action_setFilter = function (data, x, y, prefix) { this.__action_doUIEvent(data); -} +}; events.prototype._action_drawImage = function (data, x, y, prefix) { this.__action_doUIEvent(data); -} +}; events.prototype._action_drawIcon = function (data, x, y, prefix) { this.__action_doUIEvent(data); -} +}; events.prototype._action_drawSelector = function (data, x, y, prefix) { this.__action_doUIEvent(data); -} +}; events.prototype._action_drawBackground = function (data, x, y, prefix) { this.__action_doUIEvent(data); -} +}; events.prototype._action_drawTextContent = function (data, x, y, prefix) { data.text = core.replaceText(data.text, prefix); this.__action_doUIEvent(data); -} +}; // ------ 点击状态栏图标所进行的一些操作 ------ // @@ -2737,24 +3315,27 @@ events.prototype._checkStatus = function (name, fromUserAction, checkItem) { if (fromUserAction && core.status.lockControl) return false; if (checkItem && !core.hasItem(name)) { core.playSound('操作失败'); - core.drawTip("你没有" + core.material.items[name].name, name); + core.drawTip('你没有' + core.material.items[name].name, name); return false; } if (core.isMoving()) { core.playSound('操作失败'); - core.drawTip("请先停止勇士行动"); + core.drawTip('请先停止勇士行动'); return false; } core.lockControl(); core.status.event.id = name; return true; -} +}; ////// 点击怪物手册时的打开操作 ////// events.prototype.openBook = function (fromUserAction) { if (core.isReplaying()) return; // 如果能恢复事件(从callBook事件触发) - if (core.status.event.id == 'book' && core.events.recoverEvents(core.status.event.interval)) + if ( + core.status.event.id == 'book' && + core.events.recoverEvents(core.status.event.interval) + ) return; // 当前是book,且从“浏览地图”打开 if (core.status.event.id == 'book' && core.status.event.ui) { @@ -2770,7 +3351,7 @@ events.prototype.openBook = function (fromUserAction) { if (!this._checkStatus('book', fromUserAction, true)) return; core.playSound('打开界面'); core.useItem('book', true); -} +}; ////// 点击楼层传送器时的打开操作 ////// events.prototype.useFly = function (fromUserAction) { @@ -2780,7 +3361,10 @@ events.prototype.useFly = function (fromUserAction) { if (!core.hasItem('fly')) { core.playSound('操作失败'); core.drawTip('你没有' + core.material.items['fly'].name, 'fly'); - } else if (!core.canUseItem('fly') || (core.flags.flyNearStair && !core.nearStair())) { + } else if ( + !core.canUseItem('fly') || + (core.flags.flyNearStair && !core.nearStair()) + ) { core.playSound('操作失败'); core.drawTip('无法传送到当前层', 'fly'); } else { @@ -2792,7 +3376,10 @@ events.prototype.useFly = function (fromUserAction) { if (!this._checkStatus('fly', fromUserAction, true)) return; if (core.flags.flyNearStair && !core.nearStair()) { core.playSound('操作失败'); - core.drawTip("只有在楼梯边才能使用" + core.material.items['fly'].name, 'fly'); + core.drawTip( + '只有在楼梯边才能使用' + core.material.items['fly'].name, + 'fly' + ); core.unlockControl(); core.status.event.data = null; core.status.event.id = null; @@ -2800,7 +3387,7 @@ events.prototype.useFly = function (fromUserAction) { } if (!core.canUseItem('fly')) { core.playSound('操作失败'); - core.drawTip(core.material.items['fly'].name + "好像失效了", 'fly'); + core.drawTip(core.material.items['fly'].name + '好像失效了', 'fly'); core.unlockControl(); core.status.event.data = null; core.status.event.id = null; @@ -2809,11 +3396,11 @@ events.prototype.useFly = function (fromUserAction) { core.playSound('打开界面'); core.useItem('fly', true); return; -} +}; events.prototype.flyTo = function (toId, callback) { return this.eventdata.flyTo(toId, callback); -} +}; ////// 点击装备栏时的打开操作 ////// events.prototype.openEquipbox = function (fromUserAction) { @@ -2821,7 +3408,7 @@ events.prototype.openEquipbox = function (fromUserAction) { if (!this._checkStatus('equipbox', fromUserAction)) return; core.playSound('打开界面'); core.ui._drawEquipbox(); -} +}; ////// 点击工具栏时的打开操作 ////// events.prototype.openToolbox = function (fromUserAction) { @@ -2829,7 +3416,7 @@ events.prototype.openToolbox = function (fromUserAction) { if (!this._checkStatus('toolbox', fromUserAction)) return; core.playSound('打开界面'); core.ui._drawToolbox(); -} +}; ////// 点击快捷商店按钮时的打开操作 ////// events.prototype.openQuickShop = function (fromUserAction) { @@ -2837,7 +3424,7 @@ events.prototype.openQuickShop = function (fromUserAction) { if (Object.keys(core.status.shops).length == 0) { core.playSound('操作失败'); - core.drawTip("本游戏没有快捷商店!"); + core.drawTip('本游戏没有快捷商店!'); return; } @@ -2847,7 +3434,7 @@ events.prototype.openQuickShop = function (fromUserAction) { if (core.status.event.id != null) return; if (!core.canOpenShop(shopId)) { core.playSound('操作失败'); - core.drawTip("当前无法打开快捷商店!"); + core.drawTip('当前无法打开快捷商店!'); return; } var message = core.canUseQuickShop(shopId); @@ -2862,13 +3449,13 @@ events.prototype.openQuickShop = function (fromUserAction) { if (!this._checkStatus('selectShop', fromUserAction)) return; core.ui._drawQuickShop(); -} +}; events.prototype.openKeyBoard = function (fromUserAction) { if (core.isReplaying()) return; if (!this._checkStatus('keyBoard', fromUserAction)) return; core.ui._drawKeyBoard(); -} +}; ////// 点击保存按钮时的打开操作 ////// events.prototype.save = function (fromUserAction) { @@ -2878,52 +3465,59 @@ events.prototype.save = function (fromUserAction) { core.drawTip('当前禁止存档'); return; } - if (core.status.event.id == 'save' && core.events.recoverEvents(core.status.event.interval)) + if ( + core.status.event.id == 'save' && + core.events.recoverEvents(core.status.event.interval) + ) return; if (!this._checkStatus('save', fromUserAction)) return; var saveIndex = core.saves.saveIndex; - var page = parseInt((saveIndex - 1) / 5), offset = saveIndex - 5 * page; + var page = parseInt((saveIndex - 1) / 5), + offset = saveIndex - 5 * page; core.playSound('打开界面'); core.ui._drawSLPanel(10 * page + offset); -} +}; ////// 点击读取按钮时的打开操作 ////// events.prototype.load = function (fromUserAction) { if (core.isReplaying()) return; var saveIndex = core.saves.saveIndex; - var page = parseInt((saveIndex - 1) / 5), offset = saveIndex - 5 * page; + var page = parseInt((saveIndex - 1) / 5), + offset = saveIndex - 5 * page; // 游戏开始前读档 if (!core.isPlaying()) { core.dom.startPanel.style.display = 'none'; core.clearStatus(); core.clearMap('all'); - core.status.event = { 'id': 'load', 'data': null }; + core.status.event = { id: 'load', data: null }; core.status.lockControl = true; core.playSound('打开界面'); core.ui._drawSLPanel(10 * page + offset); return; } - if (core.status.event.id == 'load' && core.events.recoverEvents(core.status.event.interval)) + if ( + core.status.event.id == 'load' && + core.events.recoverEvents(core.status.event.interval) + ) return; if (!this._checkStatus('load', fromUserAction)) return; core.playSound('打开界面'); core.ui._drawSLPanel(10 * page + offset); -} +}; ////// 点击设置按钮时的操作 ////// events.prototype.openSettings = function (fromUserAction) { if (core.isReplaying()) return; - if (!this._checkStatus('settings', fromUserAction)) - return; + if (!this._checkStatus('settings', fromUserAction)) return; core.playSound('打开界面'); core.ui._drawSettings(); -} +}; // ------ 一些事件的具体执行过程 ------ // events.prototype.hasAsync = function () { return Object.keys(core.animateFrame.asyncId).length > 0; -} +}; ////// 立刻停止所有异步事件 ////// events.prototype.stopAsync = function () { @@ -2936,30 +3530,29 @@ events.prototype.stopAsync = function () { callbacks.forEach(function (cb) { if (cb && cb instanceof Function) cb(); }); -} +}; events.prototype.hasAsyncAnimate = function () { return (core.status.animateObjs || []).length > 0; -} +}; ////// 跟随 ////// events.prototype.follow = function (name) { name = core.getMappedName(name); if (core.material.images.images[name]) { - core.status.hero.followers.push({ "name": name }); + core.status.hero.followers.push({ name: name }); core.gatherFollowers(); core.clearMap('hero'); core.drawHero(); } core.clearRouteFolding(); -} +}; ////// 取消跟随 ////// events.prototype.unfollow = function (name) { if (!name) { core.status.hero.followers = []; - } - else { + } else { name = core.getMappedName(name); for (var i = 0; i < core.status.hero.followers.length; i++) { if (core.status.hero.followers[i].name == name) { @@ -2972,27 +3565,54 @@ events.prototype.unfollow = function (name) { core.clearMap('hero'); core.drawHero(); core.clearRouteFolding(); -} +}; -events.prototype._updateValueByOperator = function (value, originValue, operator) { +events.prototype._updateValueByOperator = function ( + value, + originValue, + operator +) { switch (operator) { - case '+=': value = originValue + value; break; - case '-=': value = originValue - value; break; - case '*=': value = originValue * value; break; - case '/=': value = originValue / value; break; - case '**=': value = Math.pow(originValue, value); break; - case '//=': value = Math.trunc(originValue / value); break; - case '%=': value = originValue % value; break; - case 'min=': value = Math.min(originValue, value); break; - case 'max=': value = Math.max(originValue, value); break; - default: break; + case '+=': + value = originValue + value; + break; + case '-=': + value = originValue - value; + break; + case '*=': + value = originValue * value; + break; + case '/=': + value = originValue / value; + break; + case '**=': + value = Math.pow(originValue, value); + break; + case '//=': + value = Math.trunc(originValue / value); + break; + case '%=': + value = originValue % value; + break; + case 'min=': + value = Math.min(originValue, value); + break; + case 'max=': + value = Math.max(originValue, value); + break; + default: + break; } return value; -} +}; ////// 数值操作 ////// events.prototype.setValue = function (name, operator, value, prefix) { - value = this._updateValueByOperator(core.calValue(value, prefix), core.calValue(name, prefix), operator); + value = this._updateValueByOperator( + core.calValue(value, prefix), + core.calValue(name, prefix), + operator + ); this._setValue_setStatus(name, value); this._setValue_setBuff(name, value); this._setValue_setItem(name, value); @@ -3000,104 +3620,144 @@ events.prototype.setValue = function (name, operator, value, prefix) { this._setValue_setSwitch(name, value, prefix); this._setValue_setTemp(name, value, prefix); this._setValue_setGlobal(name, value); -} +}; events.prototype._setValue_setStatus = function (name, value) { - if (name.indexOf("status:") !== 0) return; + if (name.indexOf('status:') !== 0) return; core.setStatus(name.substring(7), value); -} +}; events.prototype._setValue_setBuff = function (name, value) { if (name.indexOf('buff:') !== 0) return; core.setBuff(name.substring(5), value); -} +}; events.prototype._setValue_setItem = function (name, value) { - if (name.indexOf("item:") !== 0) return; - var itemId = name.substring(5), count = core.itemCount(itemId); + if (name.indexOf('item:') !== 0) return; + var itemId = name.substring(5), + count = core.itemCount(itemId); if (value > count) core.getItem(itemId, value - count); else core.setItem(itemId, value); -} +}; events.prototype._setValue_setFlag = function (name, value) { - if (name.indexOf("flag:") !== 0) return; + if (name.indexOf('flag:') !== 0) return; core.setFlag(name.substring(5), value); -} +}; events.prototype._setValue_setSwitch = function (name, value, prefix) { - if (name.indexOf("switch:") !== 0) return; - core.setFlag((prefix || ":f@x@y") + "@" + name.substring(7), value); -} + if (name.indexOf('switch:') !== 0) return; + core.setFlag((prefix || ':f@x@y') + '@' + name.substring(7), value); +}; events.prototype._setValue_setTemp = function (name, value) { - if (name.indexOf("temp:") !== 0) return; - core.setFlag("@temp@" + name.substring(5), value); -} + if (name.indexOf('temp:') !== 0) return; + core.setFlag('@temp@' + name.substring(5), value); +}; events.prototype._setValue_setGlobal = function (name, value) { - if (name.indexOf("global:") !== 0) return; + if (name.indexOf('global:') !== 0) return; core.setGlobal(name.substring(7), value); -} +}; ////// 设置一个怪物属性 ////// -events.prototype.setEnemy = function (id, name, value, operator, prefix, norefresh) { +events.prototype.setEnemy = function ( + id, + name, + value, + operator, + prefix, + norefresh +) { if (!core.hasFlag('enemyInfo')) { core.setFlag('enemyInfo', {}); } var enemyInfo = core.getFlag('enemyInfo'); if (!enemyInfo[id]) enemyInfo[id] = {}; - if (typeof value === 'string' && name == 'name') value = value.replace(/\r/g, '\\r'); - value = this._updateValueByOperator(core.calValue(value, prefix), (core.material.enemys[id] || {})[name], operator); + if (typeof value === 'string' && name == 'name') + value = value.replace(/\r/g, '\\r'); + value = this._updateValueByOperator( + core.calValue(value, prefix), + (core.material.enemys[id] || {})[name], + operator + ); enemyInfo[id][name] = value; (core.material.enemys[id] || {})[name] = core.clone(value); if (!norefresh) core.updateStatusBar(); -} +}; ////// 设置某个点上的怪物属性 ////// -events.prototype.setEnemyOnPoint = function (x, y, floorId, name, value, operator, prefix, norefresh) { +events.prototype.setEnemyOnPoint = function ( + x, + y, + floorId, + name, + value, + operator, + prefix, + norefresh +) { floorId = floorId || core.status.floorId; var block = core.getBlock(x, y, floorId); if (block == null) return; if (block.event.cls.indexOf('enemy') != 0) return; var enemy = core.material.enemys[block.event.id]; if (enemy == null) return; - if (typeof value === 'string' && name == 'name') value = value.replaceAll(/\r/g, '\\r'); - value = this._updateValueByOperator(core.calValue(value, prefix), core.getEnemyValue(enemy, name, x, y, floorId), operator); + if (typeof value === 'string' && name == 'name') + value = value.replaceAll(/\r/g, '\\r'); + value = this._updateValueByOperator( + core.calValue(value, prefix), + core.getEnemyValue(enemy, name, x, y, floorId), + operator + ); flags.enemyOnPoint = flags.enemyOnPoint || {}; flags.enemyOnPoint[floorId] = flags.enemyOnPoint[floorId] || {}; - flags.enemyOnPoint[floorId][x + "," + y] = flags.enemyOnPoint[floorId][x + "," + y] || {}; - flags.enemyOnPoint[floorId][x + "," + y][name] = value; + flags.enemyOnPoint[floorId][x + ',' + y] = + flags.enemyOnPoint[floorId][x + ',' + y] || {}; + flags.enemyOnPoint[floorId][x + ',' + y][name] = value; if (!norefresh) core.updateStatusBar(); -} +}; ////// 重置某个点上的怪物属性 ////// events.prototype.resetEnemyOnPoint = function (x, y, floorId, norefresh) { - delete ((flags.enemyOnPoint || {})[floorId || core.status.floorId] || {})[x + "," + y]; + delete ((flags.enemyOnPoint || {})[floorId || core.status.floorId] || {})[ + x + ',' + y + ]; if (!norefresh) core.updateStatusBar(); -} +}; ////// 将某个点上已经设置的怪物属性移动到其他点 ////// -events.prototype.moveEnemyOnPoint = function (fromX, fromY, toX, toY, floorId, norefresh) { +events.prototype.moveEnemyOnPoint = function ( + fromX, + fromY, + toX, + toY, + floorId, + norefresh +) { floorId = floorId || core.status.floorId; - if (((flags.enemyOnPoint || {})[floorId] || {})[fromX + "," + fromY]) { - flags.enemyOnPoint[floorId][toX + "," + toY] = flags.enemyOnPoint[floorId][fromX + "," + fromY]; - delete flags.enemyOnPoint[floorId][fromX + "," + fromY]; + if (((flags.enemyOnPoint || {})[floorId] || {})[fromX + ',' + fromY]) { + flags.enemyOnPoint[floorId][toX + ',' + toY] = + flags.enemyOnPoint[floorId][fromX + ',' + fromY]; + delete flags.enemyOnPoint[floorId][fromX + ',' + fromY]; if (!norefresh) core.updateStatusBar(); } -} +}; ////// 设置楼层属性 ////// events.prototype.setFloorInfo = function (name, value, floorId, prefix) { floorId = floorId || core.status.floorId; core.status.maps[floorId][name] = value; core.updateStatusBar(); -} +}; ////// 设置全塔属性 ////// events.prototype.setGlobalAttribute = function (name, value) { if (typeof value == 'string') { - if ((value.charAt(0) == '"' && value.charAt(value.length - 1) == '"') - || (value.charAt(0) == "'" && value.charAt(value.length - 1) == "'")) + if ( + (value.charAt(0) == '"' && value.charAt(value.length - 1) == '"') || + (value.charAt(0) == "'" && value.charAt(value.length - 1) == "'") + ) value = value.substring(1, value.length - 1); // --- 检查 [] if (value.charAt(0) == '[' && value.charAt(value.length - 1) == ']') @@ -3110,40 +3770,52 @@ events.prototype.setGlobalAttribute = function (name, value) { core.status.globalAttribute[name] = value; core.setFlag('globalAttribute', core.status.globalAttribute); core.resize(); -} +}; ////// 设置全局开关 ////// events.prototype.setGlobalFlag = function (name, value) { - var flags = core.getFlag("globalFlags", {}); + var flags = core.getFlag('globalFlags', {}); if (name.startsWith('s:')) { name = name.substring(2); - var statusBarItems = core.flags.statusBarItems.filter(function (v) { return v != name; }); + var statusBarItems = core.flags.statusBarItems.filter(function (v) { + return v != name; + }); if (value) statusBarItems.push(name); core.flags.statusBarItems = statusBarItems; flags.statusBarItems = core.clone(statusBarItems); } else { flags[name] = core.flags[name] = value; } - core.setFlag("globalFlags", flags); + core.setFlag('globalFlags', flags); core.resize(); - if (name == 'blurFg') - core.redrawMap(); -} + if (name == 'blurFg') core.redrawMap(); +}; ////// 设置文件别名 ////// events.prototype.setNameMap = function (name, value) { if (!core.hasFlag('__nameMap__')) core.setFlag('__nameMap__', {}); flags.__nameMap__[name] = value; -} +}; ////// 设置剧情文本的属性 ////// events.prototype.setTextAttribute = function (data) { if (!core.isPlaying()) return; - ["position", "offset", "align", "bold", "titlefont", "textfont", "lineHeight", "time", "letterSpacing", "animateTime"].forEach(function (t) { + [ + 'position', + 'offset', + 'align', + 'bold', + 'titlefont', + 'textfont', + 'lineHeight', + 'time', + 'letterSpacing', + 'animateTime' + ].forEach(function (t) { if (data[t] != null) core.status.textAttribute[t] = data[t]; }); - ["background", "title", "text"].forEach(function (t) { - if ((data[t] instanceof Array) && data[t].length >= 3) { + ['background', 'title', 'text'].forEach(function (t) { + if (data[t] instanceof Array && data[t].length >= 3) { if (data[t].length == 3) data[t].push(1); core.status.textAttribute[t] = data[t]; } @@ -3155,10 +3827,18 @@ events.prototype.setTextAttribute = function (data) { } } }); - if (main.mode == 'play') core.setFlag('textAttribute', core.status.textAttribute); -} + if (main.mode == 'play') + core.setFlag('textAttribute', core.status.textAttribute); +}; -events.prototype.moveTextBox = function (code, loc, relative, moveMode, time, callback) { +events.prototype.moveTextBox = function ( + code, + loc, + relative, + moveMode, + time, + callback +) { var ctx = core.getContextByName('__text__' + code); if (!ctx) { if (callback) callback(); @@ -3166,8 +3846,8 @@ events.prototype.moveTextBox = function (code, loc, relative, moveMode, time, ca } var sx = parseInt(ctx.canvas.getAttribute('_text_left')) || 0; var sy = parseInt(ctx.canvas.getAttribute('_text_top')) || 0; - var dx = relative ? loc[0] : (loc[0] - sx); - var dy = relative ? loc[1] : (loc[1] - sy); + var dx = relative ? loc[0] : loc[0] - sx; + var dy = relative ? loc[1] : loc[1] - sy; var ox = parseInt(ctx.canvas.getAttribute('_left')) || 0; var oy = parseInt(ctx.canvas.getAttribute('_top')) || 0; @@ -3180,21 +3860,32 @@ events.prototype.moveTextBox = function (code, loc, relative, moveMode, time, ca } var moveInfo = { - sx: sx, sy: sy, dx: dx, dy: dy, ox: ox, oy: oy, - moveMode: moveMode, time: time / Math.max(core.status.replay.speed, 1) + sx: sx, + sy: sy, + dx: dx, + dy: dy, + ox: ox, + oy: oy, + moveMode: moveMode, + time: time / Math.max(core.status.replay.speed, 1) }; this._moveTextBox_moving(ctx, moveInfo, callback); -} +}; events.prototype._moveTextBox_moving = function (ctx, moveInfo, callback) { - var step = 0, steps = moveInfo.time / 10; + var step = 0, + steps = moveInfo.time / 10; if (steps <= 0) steps = 1; var moveFunc = core.applyEasing(moveInfo.moveMode); var animate = setInterval(function () { step++; var dx = moveInfo.dx * moveFunc(step / steps); var dy = moveInfo.dy * moveFunc(step / steps); - core.relocateCanvas(ctx, parseInt(moveInfo.ox + dx), parseInt(moveInfo.oy + dy)); + core.relocateCanvas( + ctx, + parseInt(moveInfo.ox + dx), + parseInt(moveInfo.oy + dy) + ); ctx.canvas.setAttribute('_text_left', moveInfo.sx + dx); ctx.canvas.setAttribute('_text_top', moveInfo.sy + dy); if (step == steps) { @@ -3206,13 +3897,18 @@ events.prototype._moveTextBox_moving = function (ctx, moveInfo, callback) { core.animateFrame.lastAsyncId = animate; core.animateFrame.asyncId[animate] = callback; -} +}; ////// 清除对话框 ////// events.prototype.clearTextBox = function (code, callback) { if (code == null) { - code = Object.keys(core.dymCanvas).filter(function (one) { return one.startsWith('__text__') }) - .map(function (one) { return one.substring('__text__'.length); }) + code = Object.keys(core.dymCanvas) + .filter(function (one) { + return one.startsWith('__text__'); + }) + .map(function (one) { + return one.substring('__text__'.length); + }); } if (!(code instanceof Array)) code = [code]; @@ -3230,13 +3926,16 @@ events.prototype.clearTextBox = function (code, callback) { }); }; _work(); -} +}; ////// 关门 ////// events.prototype.closeDoor = function (x, y, id, callback) { - id = id || ""; - if ((core.material.icons.animates[id] == null && core.material.icons.npc48[id] == null) - || core.getBlock(x, y) != null) { + id = id || ''; + if ( + (core.material.icons.animates[id] == null && + core.material.icons.npc48[id] == null) || + core.getBlock(x, y) != null + ) { if (callback) callback(); return; } @@ -3257,29 +3956,46 @@ events.prototype.closeDoor = function (x, y, id, callback) { core.setBlock(id, x, y); core.showBlock(x, y); if (callback) callback(); - } + }; - var animate = window.setInterval(function () { - blockInfo.posX--; - if (blockInfo.posX < 0) { - clearInterval(animate); - delete core.animateFrame.asyncId[animate]; - cb(); - return; - } - core.maps._drawBlockInfo(blockInfo, x, y); - }, core.status.replay.speed == 24 ? 1 : speed / Math.max(core.status.replay.speed, 1)); + var animate = window.setInterval( + function () { + blockInfo.posX--; + if (blockInfo.posX < 0) { + clearInterval(animate); + delete core.animateFrame.asyncId[animate]; + cb(); + return; + } + core.maps._drawBlockInfo(blockInfo, x, y); + }, + core.status.replay.speed == 24 + ? 1 + : speed / Math.max(core.status.replay.speed, 1) + ); core.animateFrame.lastAsyncId = animate; core.animateFrame.asyncId[animate] = cb; -} +}; ////// 显示图片 ////// -events.prototype.showImage = function (code, image, sloc, loc, opacityVal, time, callback) { +events.prototype.showImage = function ( + code, + image, + sloc, + loc, + opacityVal, + time, + callback +) { var imageName = null; if (typeof image == 'string') { imageName = image; - if (image.endsWith(':x') || image.endsWith(':y') || image.endsWith(':o')) { + if ( + image.endsWith(':x') || + image.endsWith(':y') || + image.endsWith(':o') + ) { image = image.substring(0, image.length - 2); } image = core.getMappedName(image); @@ -3290,20 +4006,35 @@ events.prototype.showImage = function (code, image, sloc, loc, opacityVal, time, return; } sloc = sloc || []; - var sx = core.calValue(sloc[0]) || 0, sy = core.calValue(sloc[1]) || 0; - var sw = core.calValue(sloc[2]), sh = core.calValue(sloc[3]); + var sx = core.calValue(sloc[0]) || 0, + sy = core.calValue(sloc[1]) || 0; + var sw = core.calValue(sloc[2]), + sh = core.calValue(sloc[3]); if (sw == null) sw = image.width; if (sh == null) sh = image.height; loc = loc || []; - var x = core.calValue(loc[0]) || 0, y = core.calValue(loc[1]) || 0; - var w = core.calValue(loc[2]), h = core.calValue(loc[3]); + var x = core.calValue(loc[0]) || 0, + y = core.calValue(loc[1]) || 0; + var w = core.calValue(loc[2]), + h = core.calValue(loc[3]); if (w == null) w = sw; if (h == null) h = sh; var zIndex = code + 100; time = time || 0; - var name = "image" + zIndex; + var name = 'image' + zIndex; var ctx = core.createCanvas(name, x, y, w, h, zIndex); - core.drawImage(ctx, imageName == null ? image : imageName, sx, sy, sw, sh, 0, 0, w, h); + core.drawImage( + ctx, + imageName == null ? image : imageName, + sx, + sy, + sw, + sh, + 0, + 0, + w, + h + ); if (time == 0) { core.setOpacity(name, opacityVal); if (callback) callback(); @@ -3311,12 +4042,12 @@ events.prototype.showImage = function (code, image, sloc, loc, opacityVal, time, } core.setOpacity(name, 0); this.moveImage(code, null, opacityVal, null, time, callback); -} +}; ////// 隐藏图片 ////// events.prototype.hideImage = function (code, time, callback) { time = time || 0; - var name = "image" + (code + 100); + var name = 'image' + (code + 100); if (time == 0 || !core.dymCanvas[name]) { core.deleteCanvas(name); if (callback) callback(); @@ -3326,12 +4057,19 @@ events.prototype.hideImage = function (code, time, callback) { core.deleteCanvas(name); if (callback) callback(); }); -} +}; ////// 移动图片 ////// -events.prototype.moveImage = function (code, to, opacityVal, moveMode, time, callback) { +events.prototype.moveImage = function ( + code, + to, + opacityVal, + moveMode, + time, + callback +) { to = to || []; - var name = "image" + (code + 100); + var name = 'image' + (code + 100); if (!core.dymCanvas[name]) { if (callback) callback(); return; @@ -3339,13 +4077,15 @@ events.prototype.moveImage = function (code, to, opacityVal, moveMode, time, cal var getOrDefault = function (a, b) { a = core.calValue(a); return a != null ? a : b; - } + }; var canvas = core.dymCanvas[name].canvas; - var fromX = parseFloat(canvas.getAttribute("_left")), - fromY = parseFloat(canvas.getAttribute("_top")), - toX = getOrDefault(to[0], fromX), toY = getOrDefault(to[1], fromY); + var fromX = parseFloat(canvas.getAttribute('_left')), + fromY = parseFloat(canvas.getAttribute('_top')), + toX = getOrDefault(to[0], fromX), + toY = getOrDefault(to[1], fromY); - var opacity = parseFloat(canvas.style.opacity), toOpacity = getOrDefault(opacityVal, opacity); + var opacity = parseFloat(canvas.style.opacity), + toOpacity = getOrDefault(opacityVal, opacity); if (!time) { core.relocateCanvas(name, toX, toY); @@ -3354,18 +4094,36 @@ events.prototype.moveImage = function (code, to, opacityVal, moveMode, time, cal return; } - this._moveImage_moving(name, { - fromX: fromX, fromY: fromY, toX: toX, toY: toY, opacity: opacity, toOpacity: toOpacity, - moveMode: moveMode, time: time / Math.max(core.status.replay.speed, 1) - }, callback) -} + this._moveImage_moving( + name, + { + fromX: fromX, + fromY: fromY, + toX: toX, + toY: toY, + opacity: opacity, + toOpacity: toOpacity, + moveMode: moveMode, + time: time / Math.max(core.status.replay.speed, 1) + }, + callback + ); +}; events.prototype._moveImage_moving = function (name, moveInfo, callback) { - var per_time = 10, step = 0, steps = parseInt(moveInfo.time / per_time); + var per_time = 10, + step = 0, + steps = parseInt(moveInfo.time / per_time); if (steps <= 0) steps = 1; - var fromX = moveInfo.fromX, fromY = moveInfo.fromY, toX = moveInfo.toX, toY = moveInfo.toY, - opacity = moveInfo.opacity, toOpacity = moveInfo.toOpacity; - var currX = fromX, currY = fromY, currOpacity = opacity; + var fromX = moveInfo.fromX, + fromY = moveInfo.fromY, + toX = moveInfo.toX, + toY = moveInfo.toY, + opacity = moveInfo.opacity, + toOpacity = moveInfo.toOpacity; + var currX = fromX, + currY = fromY, + currOpacity = opacity; var moveFunc = core.applyEasing(moveInfo.moveMode); var animate = setInterval(function () { step++; @@ -3383,18 +4141,26 @@ events.prototype._moveImage_moving = function (name, moveInfo, callback) { core.animateFrame.lastAsyncId = animate; core.animateFrame.asyncId[animate] = callback; -} +}; ////// 旋转图片 ////// -events.prototype.rotateImage = function (code, center, angle, moveMode, time, callback) { +events.prototype.rotateImage = function ( + code, + center, + angle, + moveMode, + time, + callback +) { center = center || []; - var name = "image" + (code + 100); + var name = 'image' + (code + 100); if (!core.dymCanvas[name]) { if (callback) callback(); return; } var canvas = core.dymCanvas[name].canvas; - var centerX = core.calValue(center[0]), centerY = core.calValue(center[1]); + var centerX = core.calValue(center[0]), + centerY = core.calValue(center[1]); var fromAngle = parseFloat(canvas.getAttribute('_angle')) || 0; @@ -3405,20 +4171,32 @@ events.prototype.rotateImage = function (code, center, angle, moveMode, time, ca } var rotateInfo = { - fromAngle: fromAngle, angle: angle, centerX: centerX, centerY: centerY, - moveMode: moveMode, time: time / Math.max(core.status.replay.speed, 1) - } + fromAngle: fromAngle, + angle: angle, + centerX: centerX, + centerY: centerY, + moveMode: moveMode, + time: time / Math.max(core.status.replay.speed, 1) + }; this._rotateImage_rotating(name, rotateInfo, callback); -} +}; events.prototype._rotateImage_rotating = function (name, rotateInfo, callback) { - var per_time = 10, step = 0, steps = parseInt(rotateInfo.time / per_time); + var per_time = 10, + step = 0, + steps = parseInt(rotateInfo.time / per_time); if (steps <= 0) steps = 1; var moveFunc = core.applyEasing(rotateInfo.moveMode); var animate = setInterval(function () { step++; - var currAngle = rotateInfo.fromAngle + rotateInfo.angle * moveFunc(step / steps); - core.rotateCanvas(name, currAngle, rotateInfo.centerX, rotateInfo.centerY); + var currAngle = + rotateInfo.fromAngle + rotateInfo.angle * moveFunc(step / steps); + core.rotateCanvas( + name, + currAngle, + rotateInfo.centerX, + rotateInfo.centerY + ); if (step == steps) { delete core.animateFrame.asyncId[animate]; clearInterval(animate); @@ -3428,12 +4206,19 @@ events.prototype._rotateImage_rotating = function (name, rotateInfo, callback) { core.animateFrame.lastAsyncId = animate; core.animateFrame.asyncId[animate] = callback; -} +}; ////// 放缩一张图片 ////// -events.prototype.scaleImage = function (code, center, scale, moveMode, time, callback) { +events.prototype.scaleImage = function ( + code, + center, + scale, + moveMode, + time, + callback +) { center = center || []; - var name = "image" + (code + 100); + var name = 'image' + (code + 100); if (!core.dymCanvas[name]) { if (callback) callback(); return; @@ -3444,26 +4229,45 @@ events.prototype.scaleImage = function (code, center, scale, moveMode, time, cal currScale = parseFloat(ctx.canvas.getAttribute('_scale')); } var ratio = ctx.canvas.hasAttribute('isHD') ? core.domStyle.ratio : 1; - var width = ctx.canvas.width / ratio, height = ctx.canvas.height / ratio; - var currLeft = parseFloat(ctx.canvas.getAttribute("_left")); - var currTop = parseFloat(ctx.canvas.getAttribute("_top")); - var centerX = core.calValue(center[0]), centerY = core.calValue(center[1]); + var width = ctx.canvas.width / ratio, + height = ctx.canvas.height / ratio; + var currLeft = parseFloat(ctx.canvas.getAttribute('_left')); + var currTop = parseFloat(ctx.canvas.getAttribute('_top')); + var centerX = core.calValue(center[0]), + centerY = core.calValue(center[1]); if (centerX == null || centerY == null) { - centerX = currLeft + width * currScale / 2; - centerY = currTop + height * currScale / 2; + centerX = currLeft + (width * currScale) / 2; + centerY = currTop + (height * currScale) / 2; } var scaleInfo = { - x: (currLeft - centerX) / currScale, y: (currTop - centerY) / currScale, centerX: centerX, centerY: centerY, - width: width, height: height, currScale: currScale, scale: scale, moveMode: moveMode, time: time - } + x: (currLeft - centerX) / currScale, + y: (currTop - centerY) / currScale, + centerX: centerX, + centerY: centerY, + width: width, + height: height, + currScale: currScale, + scale: scale, + moveMode: moveMode, + time: time + }; this._scaleImage_scale(ctx, scaleInfo, callback); -} +}; events.prototype._scaleInfo_scale = function (ctx, scaleInfo, scale) { - core.resizeCanvas(ctx, scaleInfo.width * scale, scaleInfo.height * scale, true); - core.relocateCanvas(ctx, scaleInfo.centerX + scaleInfo.x * scale, scaleInfo.centerY + scaleInfo.y * scale); + core.resizeCanvas( + ctx, + scaleInfo.width * scale, + scaleInfo.height * scale, + true + ); + core.relocateCanvas( + ctx, + scaleInfo.centerX + scaleInfo.x * scale, + scaleInfo.centerY + scaleInfo.y * scale + ); ctx.canvas.setAttribute('_scale', scale); -} +}; events.prototype._scaleImage_scale = function (ctx, scaleInfo, callback) { if (!scaleInfo.time) { @@ -3472,13 +4276,17 @@ events.prototype._scaleImage_scale = function (ctx, scaleInfo, callback) { return; } - var per_time = 10, step = 0, steps = parseInt(scaleInfo.time / per_time); + var per_time = 10, + step = 0, + steps = parseInt(scaleInfo.time / per_time); if (steps <= 0) steps = 1; var moveFunc = core.applyEasing(scaleInfo.moveMode); var animate = setInterval(function () { step++; - var scale = scaleInfo.currScale + (scaleInfo.scale - scaleInfo.currScale) * moveFunc(step / steps); + var scale = + scaleInfo.currScale + + (scaleInfo.scale - scaleInfo.currScale) * moveFunc(step / steps); core.events._scaleInfo_scale(ctx, scaleInfo, scale); if (step == steps) { delete core.animateFrame.asyncId[animate]; @@ -3489,7 +4297,7 @@ events.prototype._scaleImage_scale = function (ctx, scaleInfo, callback) { core.animateFrame.lastAsyncId = animate; core.animateFrame.asyncId[animate] = callback; -} +}; ////// 绘制或取消一张gif图片 ////// events.prototype.showGif = function (name, x, y) { @@ -3499,24 +4307,24 @@ events.prototype.showGif = function (name, x, y) { var gif = new Image(); gif.src = image.src; gif.style.position = 'absolute'; - gif.style.left = x * core.domStyle.scale + "px"; - gif.style.top = y * core.domStyle.scale + "px"; - gif.style.width = image.width * core.domStyle.scale + "px"; - gif.style.height = image.height * core.domStyle.scale + "px"; + gif.style.left = x * core.domStyle.scale + 'px'; + gif.style.top = y * core.domStyle.scale + 'px'; + gif.style.width = image.width * core.domStyle.scale + 'px'; + gif.style.height = image.height * core.domStyle.scale + 'px'; core.dom.gif2.appendChild(gif); + } else { + core.dom.gif2.innerHTML = ''; } - else { - core.dom.gif2.innerHTML = ""; - } -} +}; ////// 淡入淡出音乐 ////// events.prototype.setVolume = function (value, time, callback) { var set = function (value) { core.musicStatus.designVolume = value; if (core.musicStatus.playingBgm) - core.material.bgms[core.musicStatus.playingBgm].volume = core.musicStatus.userVolume * core.musicStatus.designVolume; - } + core.material.bgms[core.musicStatus.playingBgm].volume = + core.musicStatus.userVolume * core.musicStatus.designVolume; + }; if (!time || time < 100) { set(value); if (callback) callback(); @@ -3524,11 +4332,13 @@ events.prototype.setVolume = function (value, time, callback) { } var currVolume = core.musicStatus.designVolume; time /= Math.max(core.status.replay.speed, 1); - var per_time = 10, step = 0, steps = parseInt(time / per_time); + var per_time = 10, + step = 0, + steps = parseInt(time / per_time); if (steps <= 0) steps = 1; var animate = setInterval(function () { step++; - set(currVolume + (value - currVolume) * step / steps); + set(currVolume + ((value - currVolume) * step) / steps); if (step >= steps) { delete core.animateFrame.asyncId[animate]; clearInterval(animate); @@ -3538,7 +4348,7 @@ events.prototype.setVolume = function (value, time, callback) { core.animateFrame.lastAsyncId = animate; core.animateFrame.asyncId[animate] = callback; -} +}; ////// 画面震动 ////// events.prototype.vibrate = function (direction, time, speed, power, callback) { @@ -3549,21 +4359,36 @@ events.prototype.vibrate = function (direction, time, speed, power, callback) { if (!time) time = 1000; speed = speed || 10; power = power || 10; - var shakeInfo = { duration: parseInt(time / 10), speed: speed, power: power, direction: 1, shake: 0 }; + var shakeInfo = { + duration: parseInt(time / 10), + speed: speed, + power: power, + direction: 1, + shake: 0 + }; if (direction == 'random') { - direction = ['horizontal', 'vertical', 'diagonal1', 'diagonal2'][Math.floor(Math.random() * 4)]; + direction = ['horizontal', 'vertical', 'diagonal1', 'diagonal2'][ + Math.floor(Math.random() * 4) + ]; } var cb = function () { core.addGameCanvasTranslate(0, 0); if (callback) callback(); - } + }; var animate = setInterval(function () { core.events._vibrate_update(shakeInfo); switch (direction) { - case 'vertical': core.addGameCanvasTranslate(0, shakeInfo.shake); break; - case 'diagonal1': core.addGameCanvasTranslate(shakeInfo.shake, shakeInfo.shake); break; - case 'diagonal2': core.addGameCanvasTranslate(-shakeInfo.shake, shakeInfo.shake); break; - default: core.addGameCanvasTranslate(shakeInfo.shake, 0); + case 'vertical': + core.addGameCanvasTranslate(0, shakeInfo.shake); + break; + case 'diagonal1': + core.addGameCanvasTranslate(shakeInfo.shake, shakeInfo.shake); + break; + case 'diagonal2': + core.addGameCanvasTranslate(-shakeInfo.shake, shakeInfo.shake); + break; + default: + core.addGameCanvasTranslate(shakeInfo.shake, 0); } if (shakeInfo.duration === 0 && shakeInfo.shake == 0) { delete core.animateFrame.asyncId[animate]; @@ -3574,12 +4399,15 @@ events.prototype.vibrate = function (direction, time, speed, power, callback) { core.animateFrame.lastAsyncId = animate; core.animateFrame.asyncId[animate] = cb; -} +}; events.prototype._vibrate_update = function (shakeInfo) { if (shakeInfo.duration >= 1 || shakeInfo.shake != 0) { - var delta = shakeInfo.speed * shakeInfo.direction / 6; - if (shakeInfo.duration <= 1 && shakeInfo.shake * (shakeInfo.shake + delta) < 0) { + var delta = (shakeInfo.speed * shakeInfo.direction) / 6; + if ( + shakeInfo.duration <= 1 && + shakeInfo.shake * (shakeInfo.shake + delta) < 0 + ) { shakeInfo.shake = 0; } else { shakeInfo.shake += delta; @@ -3591,62 +4419,92 @@ events.prototype._vibrate_update = function (shakeInfo) { shakeInfo.direction = 1; } if (shakeInfo.duration >= 1) { - shakeInfo.duration -= 1 + shakeInfo.duration -= 1; } } -} +}; /////// 使用事件让勇士移动。这个函数将不会触发任何事件 ////// events.prototype.eventMoveHero = function (steps, time, callback) { time = time || core.values.moveSpeed; - var step = 0, moveSteps = (steps || []).map(function (t) { - return [t.split(':')[0], parseInt(t.split(':')[1] || "1")]; - }).filter(function (t) { - return ['up', 'down', 'left', 'right', 'forward', 'backward', 'leftup', 'leftdown', 'rightup', 'rightdown', 'speed'].indexOf(t[0]) >= 0 - && !(t[0] == 'speed' && t[1] < 16); - }); + var step = 0, + moveSteps = (steps || []) + .map(function (t) { + return [t.split(':')[0], parseInt(t.split(':')[1] || '1')]; + }) + .filter(function (t) { + return ( + [ + 'up', + 'down', + 'left', + 'right', + 'forward', + 'backward', + 'leftup', + 'leftdown', + 'rightup', + 'rightdown', + 'speed' + ].indexOf(t[0]) >= 0 && !(t[0] == 'speed' && t[1] < 16) + ); + }); core.status.heroMoving = -1; var _run = function () { var cb = function () { core.status.heroMoving = 0; core.drawHero(); if (callback) callback(); - } + }; - var animate = window.setInterval(function () { - if (moveSteps.length == 0) { - delete core.animateFrame.asyncId[animate]; - clearInterval(animate); - cb(); - } - else { - if (step == 0 && moveSteps[0][0] == 'speed' && moveSteps[0][1] >= 16) { - time = moveSteps[0][1]; - moveSteps.shift(); - clearInterval(animate); + var animate = window.setInterval( + function () { + if (moveSteps.length == 0) { delete core.animateFrame.asyncId[animate]; - _run(); + clearInterval(animate); + cb(); + } else { + if ( + step == 0 && + moveSteps[0][0] == 'speed' && + moveSteps[0][1] >= 16 + ) { + time = moveSteps[0][1]; + moveSteps.shift(); + clearInterval(animate); + delete core.animateFrame.asyncId[animate]; + _run(); + } else if ( + core.events._eventMoveHero_moving(++step, moveSteps) + ) + step = 0; } - else if (core.events._eventMoveHero_moving(++step, moveSteps)) - step = 0; - } - }, core.status.replay.speed == 24 ? 1 : time / 8 / core.status.replay.speed); + }, + core.status.replay.speed == 24 + ? 1 + : time / 8 / core.status.replay.speed + ); core.animateFrame.lastAsyncId = animate; core.animateFrame.asyncId[animate] = cb; - } + }; _run(); -} +}; events.prototype._eventMoveHero_moving = function (step, moveSteps) { var curr = moveSteps[0]; - var direction = curr[0], x = core.getHeroLoc('x'), y = core.getHeroLoc('y'); + var direction = curr[0], + x = core.getHeroLoc('x'), + y = core.getHeroLoc('y'); // ------ 前进/后退 var o = direction == 'backward' ? -1 : 1; - if (direction == 'forward' || direction == 'backward') direction = core.getHeroLoc('direction'); + if (direction == 'forward' || direction == 'backward') + direction = core.getHeroLoc('direction'); var faceDirection = direction; - if (direction == 'leftup' || direction == 'leftdown') faceDirection = 'left'; - if (direction == 'rightup' || direction == 'rightdown') faceDirection = 'right'; + if (direction == 'leftup' || direction == 'leftdown') + faceDirection = 'left'; + if (direction == 'rightup' || direction == 'rightdown') + faceDirection = 'right'; core.setHeroLoc('direction', direction); if (curr[1] <= 0) { core.setHeroLoc('direction', faceDirection); @@ -3655,8 +4513,7 @@ events.prototype._eventMoveHero_moving = function (step, moveSteps) { } if (step <= 4) { core.drawHero('leftFoot', 4 * o * step); - } - else if (step <= 8) { + } else if (step <= 8) { core.drawHero('rightFoot', 4 * o * step); } if (step == 8) { @@ -3669,14 +4526,16 @@ events.prototype._eventMoveHero_moving = function (step, moveSteps) { return true; } return false; -} +}; ////// 勇士跳跃事件 ////// events.prototype.jumpHero = function (ex, ey, time, callback) { - var sx = core.getHeroLoc('x'), sy = core.getHeroLoc('y'); + var sx = core.getHeroLoc('x'), + sy = core.getHeroLoc('y'); if (ex == null) ex = sx; if (ey == null) ey = sy; - var sx = core.status.hero.loc.x, sy = core.status.hero.loc.y; + var sx = core.status.hero.loc.x, + sy = core.status.hero.loc.y; if (!core.isset(ex)) ex = sx; if (!core.isset(ey)) ey = sy; var jumpInfo = core.maps.__generateJumpInfo(sx, sy, ex, ey, time || 500); @@ -3685,7 +4544,7 @@ events.prototype.jumpHero = function (ex, ey, time, callback) { jumpInfo.height = core.material.icons.hero.height; this._jumpHero_doJump(jumpInfo, callback); -} +}; events.prototype._jumpHero_doJump = function (jumpInfo, callback) { var cb = function () { @@ -3694,12 +4553,11 @@ events.prototype._jumpHero_doJump = function (jumpInfo, callback) { core.status.heroMoving = 0; core.drawHero(); if (callback) callback(); - } + }; core.status.heroMoving = -1; var animate = window.setInterval(function () { - if (jumpInfo.jump_count > 0) - core.events._jumpHero_jumping(jumpInfo) + if (jumpInfo.jump_count > 0) core.events._jumpHero_jumping(jumpInfo); else { delete core.animateFrame.asyncId[animate]; clearInterval(animate); @@ -3709,23 +4567,26 @@ events.prototype._jumpHero_doJump = function (jumpInfo, callback) { core.animateFrame.lastAsyncId = animate; core.animateFrame.asyncId[animate] = cb; -} +}; events.prototype._jumpHero_jumping = function (jumpInfo) { core.clearMap('hero'); core.maps.__updateJumpInfo(jumpInfo); var x = core.getHeroLoc('x'), y = core.getHeroLoc('y'); - var nowx = jumpInfo.px, nowy = jumpInfo.py, width = jumpInfo.width || 32, height = jumpInfo.height; + var nowx = jumpInfo.px, + nowy = jumpInfo.py, + width = jumpInfo.width || 32, + height = jumpInfo.height; core.drawHero('stop', { x: nowx - 32 * x, y: nowy - 32 * y }); -} +}; ////// 设置角色行走图 ////// events.prototype.setHeroIcon = function (name, noDraw) { name = core.getMappedName(name); var img = core.material.images.images[name]; if (!img) { - console.error("找不到图片: " + img); + console.error('找不到图片: ' + img); return; } if (core.material.images.hero == img) return; @@ -3735,7 +4596,7 @@ events.prototype.setHeroIcon = function (name, noDraw) { core.material.icons.hero.height = img.height / 4; core.control.updateHeroIcon(name); if (!noDraw) core.drawHero(); -} +}; ////// 检查升级事件 ////// events.prototype.checkLvUp = function () { @@ -3746,13 +4607,17 @@ events.prototype.checkLvUp = function () { actions = actions.concat(next); } if (actions.length > 0) core.insertAction(actions); -} +}; events.prototype._checkLvUp_check = function () { - if (core.flags.statusBarItems.indexOf('enableLevelUp') < 0 || !core.firstData.levelUp - || core.status.hero.lv >= core.firstData.levelUp.length) return null; + if ( + core.flags.statusBarItems.indexOf('enableLevelUp') < 0 || + !core.firstData.levelUp || + core.status.hero.lv >= core.firstData.levelUp.length + ) + return null; // 计算下一个所需要的数值 - var next = (core.firstData.levelUp[core.status.hero.lv] || {}); + var next = core.firstData.levelUp[core.status.hero.lv] || {}; var need = core.calValue(next.need); if (need == null) return null; if (core.status.hero.exp >= need) { @@ -3762,7 +4627,7 @@ events.prototype._checkLvUp_check = function () { return next.action || []; } return null; -} +}; ////// 尝试使用道具 ////// events.prototype.tryUseItem = function (itemId) { @@ -3783,6 +4648,6 @@ events.prototype.tryUseItem = function (itemId) { core.useItem(itemId); } else { core.playSound('操作失败'); - core.drawTip("当前无法使用" + core.material.items[itemId].name, itemId); + core.drawTip('当前无法使用' + core.material.items[itemId].name, itemId); } -} +}; diff --git a/public/project/functions.js b/public/project/functions.js index 98a5f78..d181ab0 100644 --- a/public/project/functions.js +++ b/public/project/functions.js @@ -1,3 +1,5 @@ +/// + var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = { events: { resetGame: function (hero, hard, floorId, maps, values) { diff --git a/public/project/plugins.js b/public/project/plugins.js index 53755ad..de27e68 100644 --- a/public/project/plugins.js +++ b/public/project/plugins.js @@ -1,3 +1,5 @@ +/// + var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = { init: function () { this._afterLoadResources = function () {}; @@ -1369,6 +1371,1332 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = { return false; }; }, + minimap: function () { + // 该插件可自定义空间很大,自定义内容请看注释 + + // ------------------------- 安装说明 ------------------------- // + // 先安装基于canvas的sprite化插件(2.10.0以上自带) + // 确保自己的编辑器已安装造塔群内的编辑器升级压缩包(在HTML5魔塔样板文件夹内,2.10.1以上样板自带) + // 再将以下代码复制进插件中 + // 提供的api请看以this.xxx = function开头的函数,函数前会有函数说明及参数说明,调用时只需core.plugin.xxx(参数)即可 + + // ------------------------- 使用说明 ------------------------- // + /* + * 直接复制进插件中,然后添加一个快捷键或道具效果为core.plugin.drawFlyMap()即可使用,不需额外设置 + * 楼层id中不要出现下划线 + * 该插件具体功能有: + * 1.绘制区域内的地图 + * 2.可以拖动地图 + * 3.点击地图可直接传送至目标地图,同时降低背景的不透明度,方便观察 + * 4.滚轮或双指可以放缩绘制内容 + * 5.放缩较大时,绘制地图的缩略图,可能会比较卡,但移动不会卡 + * 6.整合漏怪检测,如果想忽略怪物,请在下方改动或用脚本修改core.plugin.ignoreEnemies,类型为数组 + * 7.整合区域显示,所有单独或连在一起的地图会被视为一个区域 + * 8.键盘操作,上下左右移动 + */ + + // ------------------------- 插件说明 ------------------------- // + /* + * 该插件注释极其详细,可以帮助那些想要提升代码力,但实力有不足的作者 + * 注意!!!该插件难度极大,没有代码底力的不建议研究 + * 该插件涉及部分较为高级的算法,如bfs + */ + + // 录像验证直接干掉这个插件 + if (main.replayChecking || main.mode === 'editor') return; + + // ----- 不可自定义 杂七杂八的变量 + /** @type {{[x: string]: BFSResult}} */ + let mapCache = {}; // 地图缓存 + let drawCache = {}; // 绘制信息缓存 + let status = 'none'; // 当前的绘制状态 + /** @type {{[x: string]: Sprite}} */ + let sprites = {}; // 当前所有的sprite + /** @type {{[x: string]: Sprite}} */ + let canDrag = {}; // 可以拖拽的sprite + /** @type {{[x: string]: Button}} */ + let areaSprite = {}; // 区域列表对应的sprite + let clicking = false; // 是否正在点击,用于拖拽判定 + let drawingMap = ''; // 正在绘制的中心楼层 + let nowScale = 0; // 当前绘制的放缩比例 + let lastTouch = {}; // 上一次的单点点击信息 + let lastLength = 0; // 手机端缩放时上一次的两指间距离 + let nowDepth = 0; // 当前的遍历深度 + let drawedThumbnail = {}; // 已经绘制过的缩略图 + let moved = false; // 鼠标按下后是否移动了 + let noBorder = false; // 是否是无边框拼接模式 + let lastScale = 0; // 上一次缩放,用于优化缩略图绘制 + let showEnemy = false; // 是否显示漏怪 + let areaPage = 0; // 区域显示的当前页数 + let nowArea = 0; // 当前区域index + let selecting = ''; // 选择时当前正在选择的地图 + + // ---- 不可自定义,常量 + /** @type {Area} */ + let areas = []; // 区域信息 + const perPage = Math.floor((core._PY_ - 60) / 30); // 区域的每页显示数量 + + // ---- 可自定义,默认的切换地图的图块id + const defaultChange = { + left: 'leftPortal', // 左箭头 + up: 'upPortal', // 上箭头 + right: 'rightPortal', // 右箭头 + down: 'downPortal', // 下箭头 + upFloor: 'upFloor', // 上楼 + downFloor: 'downFloor' // 下楼 + }; + // ---- 可自定义,默认数值 + const defaultValue = { + font: 'Verdana', // 默认字体 + scale: 3, // 默认地图缩放比例 + depth: Infinity // 默认的遍历深度 + }; + + // ---- 不可自定义,计算数据 + const dirData = { + up: [1, 0], + down: [-1, 0], + left: [0, 1], + right: [0, -1], + upFloor: [0, 0], + downFloor: [0, 0] + }; + + let ignoreEnemies = (this.ignoreEnemies = []); + + let allChangeEntries = Object.entries(defaultChange); + + const reset = core.events.resetGame; + core.events.resetGame = function () { + reset.apply(core.events, arguments); + areas = []; + // 获取所有分区,使用异步函数,保证不会卡顿 + // 原理是用bfs扫,将所有连在一起的地图合并成一个区域 + (async function () { + let all = core.floorIds.slice(); + const scanned = { [all[0]]: true }; + while (all.length > 0) { + let now = all.shift(); + if (core.status.maps[now].deleted) continue; + if (!now) return; + await new Promise(res => { + const result = bfsSearch(now, Infinity, true); + mapCache[`${now}_Infinity_false`] = result; + areas.push({ + name: core.floors[now].title, + maps: result.order + }); + for (const map of result.order) { + scanned[map] = true; + all = all.filter(v => !result.order.includes(v)); + } + res('success'); + }); + } + })(); + }; + + /** 工具按钮 */ + class Button extends Sprite { + constructor( + name, + x, + y, + w, + h, + text, + fontSize = '20px', + transition = true + ) { + const btn = super(x, y, w, h, 1050, 'game', name); + this.css(transition); + setTimeout(() => btn.setCss(`opacity: 1;`), 50); + const ctx = btn.context; + ctx.textAlign = 'center'; + ctx.textBaseline = 'middle'; + core.fillText( + ctx, + text, + w / 2, + h / 2, + '#fff', + `${fontSize} normal`, + w - 10 + ); + sprites[name] = btn; + } + + css(transition) { + this.setCss( + 'transition: opacity 0.6s linear, transform 0.2s linear;' + + 'background-color: #aaa;' + + 'box-shadow: 0px 0px 0px black;' + + (transition ? 'opacity: 0;' : '') + + 'filter: drop-shadow(1px 1px 2px black);' + + 'box-shadow: 0px 0px 4px black;' + + 'cursor: pointer;' + ); + } + } + + /** 背景 */ + class Back extends Sprite { + constructor(name, x, y, w, h, z, color) { + const sprite = super(x, y, w, h, z, 'game', name); + sprites[name] = sprite; + this.setCss(`transition: all 0.6s linear;`); + setTimeout(() => { + this.setCss(`background-color: ${color};`); + }, 50); + } + } + + /** + * 获取绘制信息 + * @param {string?} center 中心地图id + * @param {number?} depth 搜索深度 + * @param {boolean?} noCache 是否不使用缓存 + * @returns {MapDrawInfo} + */ + this.getMapDrawInfo = function ( + center = core.status.floorId, + depth = defaultValue.depth, + noCache = false + ) { + nowDepth = depth; + drawingMap = center; + const id = `${center}_${depth}_${noBorder}`; + // 检查缓存 + if (drawCache[id] && !noCache) return drawCache[id]; + const map = bfsSearch(center, depth, noCache); + mapCache[id] = map; + const res = getDrawInfo(map.res, center, map.order); + res.upOrDown = map.upOrDown; + drawCache[id] = res; + return res; + }; + + /** + * 绘制大地图,可拖动、滚轮缩放、点击对应位置可以楼传等 + * @param {string} floorId 中心地图的id + * @param {number} depth 遍历深度 + * @param {boolean} noCache 是否不使用缓存 + * @param {number} scale 绘制的缩放比例 + */ + this.drawFlyMap = function ( + floorId = core.status.floorId, + depth = defaultValue.depth, + noCache = false, + scale = defaultValue.scale + ) { + if (core.isReplaying()) return; + + // 把区域页码归零 + nowArea = areas.findIndex(v => + v.maps.includes(core.status.floorId) + ); + areaPage = 0; + nowScale = scale; + selecting = floorId; + const info = this.getMapDrawInfo(floorId, depth, noCache); + if (status !== 'scale' && status !== 'border') { + drawBack(); + drawTools(); + } + drawMap(info, scale); + status = 'flyMap'; + core.lockControl(); + core.canvas.data.canvas.style.zIndex = '990'; + }; + + /** + * 获得某个区域的剩余怪物 + * @param {string} floorId 区域包含的地图或要扫描的地图 + * @param {boolean} area 是否扫描整个区域 + * @returns {RemainEnemy} 怪物总数、所在地图、位置 + * 返回值格式:{ + * rough: 每种怪物的数量及所有怪物的总数,为字符串,每个怪物独占一行 + * detail: 每个怪物的所在位置,每个怪物独占一行,以每20个整合成字符串,为字符串数组形式 + * data: 怪物数量的原始信息,格式为{ 楼层id: { 'x,y': 怪物id } } + * } + */ + this.getRemainEnemy = function ( + floorId = core.status.floorId, + area = false + ) { + const res = bfsSearch(floorId, Infinity, true); + // 整合怪物总数 + /** @type {{[x: string]: number}} */ + const category = {}; + const toShow = area ? res.order : [floorId]; + const strArr = []; + const add = (...num) => num.reduce((pre, cur) => pre + cur, 0); + const name = id => core.material.enemys[id].name; + const title = id => core.status.maps[id].title; + for (const id of toShow) { + const enemies = res.enemies[id]; + Object.values(enemies).forEach(v => { + // 编辑器不支持 ??=,悲 + category[v] = category[v] ?? 0; + category[v]++; + }); + // 每个怪物的信息 + strArr.push( + ...Object.entries(enemies).map( + v => + `${name(v[1])} 楼层:${title( + id + )},楼层id:${id},坐标:${v[0]}` + ) + ); + } + // 输出字符串 + const all = `当前${area ? '区域' : '地图'}中剩余怪物数量:${add( + ...Object.values(category) + )}`; + const classified = Object.entries(category).map( + v => `${name(v[0])} × ${v[1]}` + ).join`\n`; + const detail = []; + while (strArr.length > 0) { + detail.push(strArr.splice(0, 20).join`\n`); + } + return { + rough: `${all}\n${classified}`, + detail, + data: res.enemies + }; + }; + + /** + * 广度优先搜索搜索地图路径 + * @param {string} center 中心地图的id + * @param {number} depth 搜索深度 + * @param {boolean} noCache 是否不使用缓存 + * @returns {BFSResult} 格式:floorId_x_y_dir: floorId_x_y + */ + function bfsSearch(center, depth, noCache) { + // 检查缓存 + const id = `${center}_${depth}_${noBorder}`; + if (mapCache[id] && !noCache) return mapCache[id]; + const used = { [center]: true }; // 搜索过的楼层 + let queue = []; + let stack = [center]; // 当前栈 + let nowDepth = -1; + const mapOrder = [center]; // 遍历顺序,顺便还能记录遍历了哪些楼层 + + const res = {}; // 输出结果,格式:floorId_x_y_dir: floorId_x_y + const enemies = {}; + const upOrDown = {}; + + // 开始循环搜索 + while (nowDepth < depth && stack.length > 0) { + const now = stack.shift(); // 当前id + if (core.status.maps[now].deleted) continue; + const blocks = core.getMapBlocksObj(now); // 获取当前地图的每点的事件 + enemies[now] = {}; + // 遍历,获取可以传送的点,只检测绿点事件,因此可用红点事件进行传送来实现分区功能 + for (const i in blocks) { + const block = blocks[i]; + // 整合漏怪检测,所以要检测怪物 + if (block.event.trigger === 'battle') { + const id = block.event.id; + if (ignoreEnemies.includes(id)) continue; + else enemies[now][i] = block.event.id; + continue; + } + // 检测触发器是否为切换楼层,不是则直接跳过 + if (block.event.trigger !== 'changeFloor') continue; + const dirEntries = allChangeEntries.find( + v => v[1] === block.event.id + ); + // 如果不是那六种传送门,直接忽略 + if (!dirEntries) continue; + const data = block.event.data; + const dir = dirEntries[0]; + const route = `${now}_${i.replace(',', '_')}_${dir}`; + const target = `${data.floorId}_${data.loc.join('_')}`; + if (!used[data.floorId]) { + if (dir === 'upFloor' || dir === 'downFloor') { + upOrDown[now] = upOrDown[id] ?? []; + upOrDown[now].push(dir); + } + queue.push(data.floorId); // 没有搜索过,则加入栈中 + mapOrder.push(data.floorId); + used[data.floorId] = true; + } + res[route] = target; + } + if (stack.length === 0) { + stack = queue; + queue = []; + nowDepth++; + } + if (stack.length === 0 && queue.length === 0) break; + } + return { res, order: mapOrder, enemies, upOrDown }; + } + + /** + * 提供地图的绘制信息 + * @param {{[x: string]: string}} map 要绘制的地图,格式:floorId_x_y_dir: floorId_x_y + * @param {string} center 中心地图的id + * @param {string[]} order 遍历顺序 + * @returns {MapDrawInfo} 地图的绘制信息 + */ + function getDrawInfo(map, center, order) { + // 先根据地图id分类,从而确定每个地图连接哪些地图,同时方便处理 + const links = {}; + for (const i in map) { + const splitted = i.split('_'); + const id = splitted[0]; + if (!links[id]) links[id] = {}; + links[id][i] = map[i]; + } + // 分类完毕,然后根据连接点先计算出各个地图的坐标,然后再进行判断 + const centerFloor = core.status.maps[center]; + const visitedCenter = core.hasVisitedFloor(center); + const locs = { + // 格式:[中心x, 中心y, 宽, 高, 是否到达过] + [center]: [ + 0, + 0, + centerFloor.width, + centerFloor.height, + visitedCenter + ] + }; + const lines = {}; // 地图间的连线 + // 可以上楼下楼的地图 + const upOrDown = {}; + for (const id of order) { + const now = links[id]; + // 遍历每一个地图的连接情况 + for (const from in now) { + const to = now[from]; + // 先根据from to计算物理位置 + const fromData = from.split('_'), + toData = to.split('_'); + const dir = fromData[3]; + if (dir === 'upFloor' || dir === 'downFloor') continue; + if (!defaultChange[dir]) continue; + const v = dirData[dir][1], // 竖直数值 + h = dirData[dir][0], // 水平数值 + ha = Math.abs(h), + va = Math.abs(v); + const fx = parseInt(fromData[1]), // fromX + fy = parseInt(fromData[2]), // fromY + tx = parseInt(toData[1]), // toX + ty = parseInt(toData[2]), // toY + ff = id, // fromFloorId + tf = toData[0]; // toFloorId + const fromFloor = core.status.maps[ff], + toFloor = core.status.maps[tf]; + const fhw = Math.floor(fromFloor.width / 2), // fromFloorHalfWidth + fhh = Math.floor(fromFloor.height / 2), + thw = Math.floor(toFloor.width / 2), + thh = Math.floor(toFloor.height / 2); + const fLoc = locs[id] ?? [0, 0]; + if (!locs[ff]) continue; + let x, y; + const dis = noBorder ? 1 : 5; + if (locs && locs[tf]) { + x = locs[tf][0]; + y = locs[tf][1]; + } else { + // 计算坐标,公式可以通过画图推断出 + x = + fLoc[0] - + ha * (fhw - fx + tx - thw) - + v * (fhw + thw + dis); + y = + fLoc[1] - + va * (fhh - fy + ty - thh) - + h * (fhh + thh + dis); + } + locs[tf] = locs[tf] ?? [ + x, + y, + toFloor.width, + toFloor.height, + core.hasVisitedFloor(tf) + ]; + // 添加连线 + lines[`${from}_${to}`] = [ + [ + fx - fhw + locs[ff][0], + fy - fhh + locs[ff][1], + x + tx - thw, + y + ty - thh + ] + ]; + } + } + // 获取地图绘制需要的长宽 + let width = 0, + height = 0; + let left, right, up, down; + for (const id in locs) { + const [x, y, w, h] = locs[id]; + if (left === void 0) { + left = right = x; + up = down = y; + } + left = Math.min(x - w / 2 - 1, left); + right = Math.max(x + w / 2 + 1, right); + up = Math.min(y - h / 2 - 1, up); + down = Math.max(y + h / 2 + 1, down); + } + width = right - left; + height = down - up; + // 所有地图和连线向右下移动,避免绘制出现问题 + for (const id in locs) { + const loc = locs[id]; + loc[0] -= left; // 这时候left和up是负值,所以要减 + loc[1] -= up; + } + for (const route in lines) { + const line = lines[route]; + for (const node of line) { + node[0] -= left; + node[1] -= up; + node[2] -= left; + node[3] -= up; + } + } + + return { locs, lines, width, height, layer: upOrDown }; + } + + /** 绘制背景 */ + function drawBack() { + if (status !== 'none') return; + new Back( + '__map_back__', + 0, + 0, + core._PX_, + core._PY_, + 175, + 'rgba(0, 0, 0, 0.9)' + ); + const listen = new Sprite( + 0, + 0, + core._PX_, + core._PY_, + 1000, + 'game', + '__map_listen__' + ); + addDrag(listen); + const exit = new Button( + '__map_exit__', + core._PX_ - 64, + core._PY_ - 26, + 60, + 22, + '退出' + ); + exit.addEventListener('click', close); + sprites.listen = listen; + } + + /** 绘制工具栏 */ + function drawTools() { + new Back( + '__map_toolback__', + 0, + core._PY_ - 30, + core._PX_, + 30, + 600, + 'rgba(200, 200, 200, 0.9)' + ); + // 无边框 + const border = new Button( + '__map_border__', + core._PX_ - 150, + core._PY_ - 26, + 60, + 22, + '边框' + ); + border.addEventListener('click', changeBorder); + // 怪物数量 + const enemy = new Button( + '__map_enemy__', + core._PX_ - 240, + core._PY_ - 26, + 60, + 22, + '怪物' + ); + enemy.addEventListener('click', triggerEnemy); + // 区域显示 + const area = new Back( + '__map_areasback__', + core._PX_ - 80, + 0, + 80, + core._PY_ - 30, + 550, + 'rgba(200, 200, 200, 0.9)' + ); + drawAreaList(); + core.drawLine( + area.context, + 0, + core._PY_ - 30, + 80, + core._PY_ - 30, + '#222', + 2 + ); + } + + /** 绘制区域列表 */ + function drawAreaList(transition = true) { + const start = perPage * areaPage; + Object.values(areaSprite).forEach(v => v.destroy()); + areaSprite = {}; + for (let i = start; i < start + perPage && areas[i]; i++) { + const n = i % perPage; + const { name, maps } = areas[i]; + const btn = new Button( + `_area_${maps[0]}`, + core._PX_ - 75, + 4 + 30 * n, + 70, + 22, + name, + '16px', + transition + ); + areaSprite[maps[0]] = btn; + if (i === nowArea) btn.setCss(`border: 2px solid gold;`); + btn.addEventListener('click', e => { + if (i === nowArea) return; + changeArea(i); + }); + } + // 上一页下一页 + if (areaPage > 0) { + const last = new Button( + '_area_last_', + core._PX_ - 75, + core._PY_ - 50, + 30, + 16, + '上一页', + '14px', + transition + ); + areaSprite._area_last_ = last; + last.addEventListener('click', e => { + areaPage--; + drawAreaList(false); + }); + } + if (areaPage < Math.floor(areas.length / perPage)) { + const next = new Button( + '_area_next_', + core._PX_ - 35, + core._PY_ - 50, + 30, + 16, + '下一页', + '14px', + transition + ); + areaSprite._area_next_ = next; + next.addEventListener('click', e => { + areaPage++; + drawAreaList(false); + }); + } + } + + /** + * 绘制大地图 + * @param {MapDrawInfo} info 地图绘制信息 + * @param {number} scale 地图的绘制比例 + */ + function drawMap(info, scale = defaultValue.scale) { + if (status === 'flyMap') return; + const PX = core._PX_, + PY = core._PY_; + const w = info.width * scale, + h = info.height * scale; + const id = `__flyMap__`; + const cx = PX / 2 - w / 2, + cy = PY / 2 - h / 2; + const map = new Sprite(cx, cy, w, h, 500, 'game', id); + sprites[id] = map; + canDrag[id] = map; + map.canvas.className = 'fly-map'; + const ctx = map.context; + core.clearMap(ctx); + if (!noBorder) { + const drawed = {}; // 绘制过的线 + // 先绘制连线 + const lines = info.lines; + for (const route in lines) { + const line = lines[route]; + for (const node of line) { + const from = `${node[0]},${node[1]}`, + to = `${node[2]},${node[3]}`; + if (drawed[`${from}-${to}`] || drawed[`${to}-${from}`]) + continue; + drawed[`${from}-${to}`] = true; + let lineWidth = scale / 2; + core.drawLine( + ctx, + node[0] * scale, + node[1] * scale, + node[2] * scale, + node[3] * scale, + '#fff', + lineWidth + ); + } + } + // 再绘制楼层 + const locs = info.locs; + for (const id in locs) { + const loc = locs[id]; + let color = '#000'; + if (!loc[4]) color = '#f0f'; + const [x, y, w, h] = loc.map( + v => typeof v === 'number' && v * scale + ); + let dx = 0, + dy = 0; // 避免绘图误差 + if (loc[2] % 2 === 0) dx = 0.5 * scale; + if (loc[3] % 2 === 0) dy = 0.5 * scale; + const fx = x - w / 2 - dx, + fy = y - h / 2 - dy; + core.fillRect(ctx, fx, fy, w, h, color); + if (id === selecting) + core.strokeRect(ctx, fx, fy, w, h, 'gold', scale / 2); + else core.strokeRect(ctx, fx, fy, w, h, '#fff', scale / 2); + const layer = info.upOrDown[id]; + const min = Math.min(w, h); + if (layer?.includes('upFloor')) + core.drawIcon( + ctx, + defaultChange.upFloor, + fx, + fy, + min / 3, + min / 3 + ); + if (layer?.includes('downFloor')) + core.drawIcon( + ctx, + defaultChange.downFloor, + fx + w - min / 3, + fy + h - min / 3, + min / 3, + min / 3 + ); + // 显示漏怪数量 + if (showEnemy) { + ctx.textAlign = 'center'; + ctx.textBaseline = 'middle'; + const c = `${drawingMap}_${nowDepth}_${noBorder}`; + const n = Object.keys(mapCache[c].enemies[id]).length; + color = '#3f3'; + if (n > 0) color = '#fff'; + if (n > 10) color = '#fc3'; + if (n > 20) color = '#f22'; + ctx.shadowBlur = 0.6 * nowScale; + ctx.shadowColor = '#000'; + core.fillText( + ctx, + `怪物数量:${n}`, + x, + y, + color, + `${2 * nowScale}px normal` + ); + ctx.shadowBlur = 0; + } + } + } + checkThumbnail(); + } + + /** + * 重新绘制缩略图 + * @param {Sprite} sprite + * @param {string} floor + */ + function drawThumbnail(sprite, floor, x, y, w, h) { + const ctx = sprite.context; + const scale = nowScale; + core.drawThumbnail(floor, void 0, { + ctx: ctx, + x: x - w / 2, + y: y - h / 2, + damage: true, + all: true, + size: Math.max(w, h) / Math.max(core._PX_, core._PY_), + fromMap: true + }); + const color = floor === core.status.floorId ? 'gold' : '#fff'; + if (!noBorder) + core.strokeRect( + ctx, + x - w / 2, + y - h / 2, + w, + h, + color, + scale / 2 + ); + } + + /** 检查是否需要绘制缩略图 */ + function checkThumbnail() { + const id = `${drawingMap}_${nowDepth}_${noBorder}`; + const locs = drawCache[id].locs; + const map = canDrag[`__flyMap__`]; + for (const id in locs) { + const loc = locs[id]; + const scale = nowScale; + const [x, y, w, h] = loc.map( + v => typeof v === 'number' && v * scale + ); + let dx = 0, + dy = 0; // 避免绘图误差 + if (loc[2] % 2 === 0) dx = 0.5 * scale; + if (loc[3] % 2 === 0) dy = 0.5 * scale; + if ( + !drawedThumbnail[id] && + x + map.x > 0 && + x + map.x < core._PX_ && + y + map.y > 0 && + y + map.y < core._PY_ + ) { + if (!noBorder && core.hasVisitedFloor(id) && scale > 5) { + drawThumbnail(map, id, x - dx, y - dy, w, h); + drawedThumbnail[id] = true; + } + if (noBorder) { + drawThumbnail(map, id, x - dx, y - dy, w, h); + drawedThumbnail[id] = true; + if (!core.hasVisitedFloor(id)) + core.fillRect( + map.context, + x - dx - w / 2, + y - dy - h / 2, + w, + h, + 'rgba(255,0,255,0.2)' + ); + } + } + } + // 如果是无边框模式,那就只绘制当前地图的边框 + if (noBorder) { + const loc = locs[selecting]; + const scale = nowScale; + if (loc) { + const [x, y, w, h] = loc.map( + v => typeof v === 'number' && v * scale + ); + core.strokeRect( + map.context, + x - w / 2, + y - h / 2, + w, + h, + 'gold', + scale / 2 + ); + } + } + } + + /** 检查点击点是否在以x,y为中心的某一矩形中 */ + function inRect(x, y, w, h, px, py) { + x -= w / 2; + y -= h / 2; + return px > x && px < x + w && py > y && py < y + h; + } + + /** 测试画布是否超过上限,摘自https://github.com/jhildenbiddle/canvas-size */ + function canvasTest(size) { + const width = Math.max(Math.ceil(size[0]), 1); + const height = Math.max(Math.ceil(size[1]), 1); + if (width === 0 || height === 0) return true; + const fill = [width - 1, height - 1, 1, 1]; + let cropCvs, testCvs; + cropCvs = document.createElement('canvas'); + cropCvs.width = 1; + cropCvs.height = 1; + testCvs = document.createElement('canvas'); + testCvs.width = width; + testCvs.height = height; + const cropCtx = cropCvs.getContext('2d'); + const testCtx = testCvs.getContext('2d'); + if (testCtx) { + testCtx.fillRect.apply(testCtx, fill); + cropCtx.drawImage( + testCvs, + width - 1, + height - 1, + 1, + 1, + 0, + 0, + 1, + 1 + ); + } + const isTestPass = + cropCtx && cropCtx.getImageData(0, 0, 1, 1).data[3] !== 0; + return isTestPass; + } + + /** 检查浏览器限制 */ + function checkMaximum(before, scale) { + for (const id in canDrag) { + const sprite = canDrag[id]; + const rate = scale / before; + const w = sprite.width * rate * core.domStyle.scale, + h = sprite.height * rate * core.domStyle.scale; + const valid = canvasTest([w, h]); + if (!valid) { + core.drawTip('画布大小将超过浏览器限制!请勿继续放大!'); + return true; + } + } + return false; + } + + /** 关闭事件 */ + function close() { + document.body.removeEventListener('keyup', keyboard); + Object.values(sprites).forEach(v => { + v.setCss('transition: opacity 0.6s linear;'); + }); + setTimeout(() => { + Object.values(sprites).forEach(v => { + v.setCss('opacity: 0;'); + }); + }, 50); + setTimeout(() => { + core.unlockControl(); + Object.values(sprites).forEach(v => { + v.destroy(); + }); + drawedThumbnail = {}; + sprites = {}; + canDrag = {}; + status = 'none'; + core.canvas.data.canvas.style.zIndex = '170'; + }, 650); + } + + /** + * 点击地图事件,尝试楼层传送 + * @param {MouseEvent} e + */ + function clickMap(e) { + if (moved) return (moved = false); + const { x, y } = core.actions._getClickLoc(e.clientX, e.clientY); + let px = x / core.domStyle.scale, + py = y / core.domStyle.scale; + const scale = nowScale; + const id = `${drawingMap}_${nowDepth}_${noBorder}`; + const locs = drawCache[id].locs; + const sprite = canDrag.__flyMap__; + px -= sprite.x; + py -= sprite.y; + for (const id in locs) { + const loc = locs[id]; + const [x, y, w, h] = loc.map( + v => typeof v === 'number' && v * scale + ); + if (inRect(x, y, w, h, px, py)) { + return flyTo(id); + } + } + } + + /** 飞向某个楼层 */ + function flyTo(id) { + if (!core.hasItem('fly')) return core.drawTip('你没有楼层传送器'); + sprites.__map_back__.setCss('opacity: 0.2;'); + return core.flyTo(id, () => + setTimeout(() => { + if (sprites.__map_back__) core.lockControl(); + }, 100) + ); + } + + /** + * 拖拽事件 + * @param {MouseEvent} e + */ + function drag(e) { + if (!clicking) return; + const scale = core.domStyle.scale; + moveEle(e.movementX / scale, e.movementY / scale); + } + + /** + * 手机端点击拖动事件 + * @param {TouchEvent} e + * @this {HTMLCanvasElement} + */ + function touchDrag(e) { + moved = true; + const scale = core.domStyle.scale; + if (e.touches.length === 1) { + // 拖拽 + const info = e.touches[0]; + if (!lastTouch[this.id]) { + lastTouch[this.id] = [info.clientX, info.clientY]; + return; + } + const { clientX: x, clientY: y } = info; + const dx = x - lastTouch[this.id][0], + dy = y - lastTouch[this.id][1]; + moveEle(dx / scale, dy / scale); + lastTouch[this.id] = [info.clientX, info.clientY]; + } else if (e.touches.length >= 2) { + // 双指放缩 + const first = e.touches[0], + second = e.touches[1]; + const dx = first.clientX - second.clientX, + dy = first.clientY - second.clientY; + if (lastLength === 0) { + lastLength = Math.sqrt(dx * dx + dy * dy); + return; + } + let cx = (first.clientX + second.clientX) / 2, + cy = (first.clientY + second.clientY) / 2; + const { x, y } = core.actions._getClickLoc(cx, cy); + const mx = x / scale; + const my = y / scale; + const length = Math.sqrt(dx * dx + dy * dy); + const delta = (lastLength / length) ** (1 / 3); + const info = {}; + for (const id in canDrag) { + const sprite = canDrag[id]; + const sx = sprite.x + sprite.width / 2, + sy = sprite.y + sprite.height / 2; + const dx = sx - mx, + dy = sy - my; + info[id] = [mx + dx * delta, my + dy * delta]; + } + scaleMap(delta * nowScale, info); + } + } + + /** + * 滚轮缩放 + * @param {WheelEvent} e + */ + function wheel(e) { + const delta = 1 - Math.sign(e.deltaY) / 10; + const { x, y } = core.actions._getClickLoc(e.clientX, e.clientY); + const scale = core.domStyle.scale; + const mx = x / scale, + my = y / scale; + const info = {}; + for (const id in canDrag) { + const sprite = canDrag[id]; + const cx = sprite.x + sprite.width / 2, + cy = sprite.y + sprite.height / 2; + const dx = cx - mx, + dy = cy - my; + info[id] = [mx + dx * delta, my + dy * delta]; + } + scaleMap(delta * nowScale, info); + } + + /** 切换边框 */ + function changeBorder() { + noBorder = !noBorder; + redraw('border'); + } + + /** 切换是否显示漏怪数量 */ + function triggerEnemy() { + showEnemy = !showEnemy; + redraw('enemy'); + } + + /** 改变区域 */ + function changeArea(index) { + nowArea = index; + drawAreaList(false); + drawedThumbnail = {}; + status = 'area'; + nowScale = defaultValue.scale; + drawMap(core.plugin.getMapDrawInfo(areas[index].maps[0])); + } + + /** 重绘 */ + function redraw(id, px, py, move = true) { + const { x, y } = canDrag.__flyMap__; + status = id; + drawedThumbnail = {}; + drawMap( + core.plugin.getMapDrawInfo(drawingMap, nowDepth, true), + nowScale + ); + if (move) canDrag.__flyMap__.move(px ?? x, py ?? y); + checkThumbnail(); + } + + /** + * 拖拽时移动需要元素 + * @param {string} dx + * @param {string} dy + */ + function moveEle(dx, dy) { + moved = true; + for (const id in canDrag) { + const sprite = canDrag[id]; + const ctx = sprite.context; + sprite.x += dx; + sprite.y += dy; + core.relocateCanvas(ctx, dx, dy, true); + } + checkThumbnail(); + } + + /** + * 缩放绘制地图 + * @param {number} target 目标缩放比例 + * @param {{[x: string]: [number, number]}} info 缩放后的sprite位置数据 + */ + function scaleMap(target, info) { + // 检查浏览器限制 + if (checkMaximum(nowScale, target)) return; + clearTimeout(lastScale); + const [x, y] = info.__flyMap__; + // 先直接修改style,延迟200ms再绘制,进行性能优化 + const sprite = canDrag.__flyMap__; + const rate = target / nowScale; + nowScale = target; + sprite.resize(sprite.width * rate, sprite.height * rate, true); + sprite.move(x - sprite.width / 2, y - sprite.height / 2); + lastScale = setTimeout(() => { + redraw('scale', x - sprite.width / 2, y - sprite.height / 2); + }, 200); + } + + /** 键盘操作 + * @param {KeyboardEvent} e + */ + function keyboard(e) { + if ( + e.key === 'Enter' || + e.key === 'C' || + e.key === 'c' || + e.key === ' ' + ) { + return flyTo(selecting); + } else if (e.key === 'Escape' || e.key === 'x' || e.key === 'X') { + return close(); + } else if (e.key.startsWith('Arrow')) { + const dir = e.key.slice(5).toLowerCase(); + // 获取目标楼层 + const res = + mapCache[`${drawingMap}_${nowDepth}_${noBorder}`].res; + const key = Object.keys(res).find(v => { + const [floorId, x, y, d] = v.split('_'); + return floorId === selecting && d === dir; + }); + if (!key) return; + const target = res[key].split('_')[0]; + selecting = target; + redraw('key'); + } + } + + /** + * 给需要的元素添加拖拽等事件 + * @param {HTMLCanvasElement} ele + */ + function addDrag(ele) { + ele.addEventListener('wheel', wheel); + ele.addEventListener('mousemove', drag); + ele.addEventListener('touchmove', touchDrag); + ele.addEventListener('click', clickMap); + ele.addEventListener('mousedown', () => { + clicking = true; + }); + ele.addEventListener('mouseup', () => { + clicking = false; + }); + ele.addEventListener('touchend', () => { + lastTouch = {}; + lastLength = 0; + }); + document.body.addEventListener('keyup', keyboard); + } + + maps.prototype._drawThumbnail_drawToTarget = function ( + floorId, + options + ) { + const ctx = core.getContextByName(options.ctx); + if (ctx == null) return; + const x = options.x || 0, + y = options.y || 0, + size = options.size || 1; + // size的含义改为(0,1]范围的系数以适配长方形,默认为1,楼传为3/4,SL界面为0.3 + let w = Math.ceil(size * core._PX_), + h = Math.ceil(size * core._PY_); + // 特判是否为编辑器,编辑器中长宽均采用core.js的遗留正方形像素边长,以保证下面的绘制正常 + if (main.mode == 'editor') w = h = size * core.__PIXELS__; + const width = core.floors[floorId].width, + height = core.floors[floorId].height; + let centerX = options.centerX, + centerY = options.centerY; + if (centerX == null) centerX = Math.floor(width / 2); + if (centerY == null) centerY = Math.floor(height / 2); + const tempCanvas = core.bigmap.tempCanvas; + + if (options.all) { + const tempWidth = tempCanvas.canvas.width, + tempHeight = tempCanvas.canvas.height; + // 绘制全景图 + if (tempWidth <= tempHeight) { + const realHeight = h, + realWidth = (realHeight * tempWidth) / tempHeight; + const side = (w - realWidth) / 2; + if (options.fromMap) { + return core.drawImage( + ctx, + tempCanvas.canvas, + 0, + 0, + tempWidth, + tempHeight, + x, + y, + realWidth, + realHeight + ); + } + core.fillRect(ctx, x, y, side, realHeight, '#000000'); + core.fillRect(ctx, x + w - side, y, side, realHeight); + core.drawImage( + ctx, + tempCanvas.canvas, + 0, + 0, + tempWidth, + tempHeight, + x + side, + y, + realWidth, + realHeight + ); + } else { + const realWidth = w, + realHeight = (realWidth * tempHeight) / tempWidth; + const side = (h - realHeight) / 2; + if (options.fromMap) { + return core.drawImage( + ctx, + tempCanvas.canvas, + 0, + 0, + tempWidth, + tempHeight, + x, + y, + realWidth, + realHeight + ); + } + core.fillRect(ctx, x, y, realWidth, side, '#000000'); + core.fillRect(ctx, x, y + h - side, realWidth, side); + core.drawImage( + ctx, + tempCanvas.canvas, + 0, + 0, + tempWidth, + tempHeight, + x, + y + side, + realWidth, + realHeight + ); + } + } else { + // 只绘制可见窗口 + let pw = core._PX_, + ph = core._PY_, + hw = core._HALF_WIDTH_, + hh = core._HALF_HEIGHT_, + W = core._WIDTH_, + H = core._HEIGHT_; + const ratio = core.domStyle.isVertical + ? core.domStyle.ratio + : core.domStyle.scale; + if (main.mode == 'editor') { + pw = ph = core.__PIXELS__; + hw = hh = core.__HALF_SIZE__; + W = H = core.__SIZE__; + } + if (options.v2) { + core.drawImage( + ctx, + tempCanvas.canvas, + 0, + 0, + pw * ratio, + ph * ratio, + x, + y, + w, + h + ); + } else { + const offsetX = core.clamp(centerX - hw, 0, width - W), + offsetY = core.clamp(centerY - hh, 0, height - H); + if (options.noHD) { + core.drawImage( + ctx, + tempCanvas.canvas, + offsetX * 32, + offsetY * 32, + pw, + ph, + x, + y, + w, + h + ); + return; + } + core.drawImage( + ctx, + tempCanvas.canvas, + offsetX * 32 * ratio, + offsetY * 32 * ratio, + pw * ratio, + ph * ratio, + x, + y, + w, + h + ); + } + } + }; + }, fixed: function () { return; // 该插件可自定义空间很大,可自定义内容请看注释 @@ -9312,9 +10640,9 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = { return res; } }, - "uiChange": function () { + uiChange: function () { ui.prototype.drawBook = function () { - return core.plugin.bookOpened.value = true; - } + return (core.plugin.bookOpened.value = true); + }; } }; diff --git a/src/panel/enemyCritical.vue b/src/panel/enemyCritical.vue index 262a7d6..4f5a237 100644 --- a/src/panel/enemyCritical.vue +++ b/src/panel/enemyCritical.vue @@ -68,14 +68,15 @@ import { computed, onMounted, ref, watch } from 'vue'; import { getCriticalDamage, getDefDamage } from '../plugin/book'; import Chart, { ChartConfiguration } from 'chart.js/auto'; import { has, setCanvasSize } from '../plugin/utils'; +import { debounce } from 'lodash'; const critical = ref(); const def = ref(); const enemy = core.plugin.bookDetailEnemy; -const originCri = getCriticalDamage(enemy); -const originDef = getDefDamage(enemy); +let originCri = getCriticalDamage(enemy); +let originDef = getDefDamage(enemy); // 当前数据 const allCri = ref(originCri); @@ -93,8 +94,8 @@ const ratio = core.status.thisMap.ratio; const nowDamage = computed(() => { const dam = core.getDamageInfo(enemy, { - atk: core.status.hero.atk + addAtk.value, - def: core.status.hero.def + addDef.value + atk: core.status.hero.atk + addAtk.value * ratio, + def: core.status.hero.def + addDef.value * ratio }); if (!has(dam)) return ['???', '???']; if (!has(originDamage)) return [-dam.damage, dam.damage]; @@ -104,11 +105,30 @@ const nowDamage = computed(() => { function generateChart(ele: HTMLCanvasElement, data: [number, number][]) { const config: ChartConfiguration = { type: 'line', - data: generateData(data) + data: generateData(data), + options: { + elements: { + point: { + radius: 5, + hoverRadius: 7 + } + }, + scales: { + y: { + grid: { + color: '#ddd3' + } + } + } + } }; return new Chart(ele, config); } +/** + * 生成图表数据 + * @param data 数据 + */ function generateData(data: [number, number][]) { return { datasets: [ @@ -117,19 +137,29 @@ function generateData(data: [number, number][]) { data: data.map(v => v[1]) } ], - labels: data.map(v => v[0]) + labels: data.map(v => Math.round(v[0] / ratio)) }; } -function update(atk: Chart, def: Chart) { - allCri.value = getCriticalDamage(enemy, addAtk.value, addDef.value); - allDef.value = getDefDamage(enemy, addDef.value, addAtk.value); +const update = debounce((atk: Chart, def: Chart) => { + allCri.value = getCriticalDamage( + enemy, + addAtk.value * ratio, + addDef.value * ratio + ); + allDef.value = getDefDamage( + enemy, + addDef.value * ratio, + addAtk.value * ratio + ); + if (allCri.value.length > originCri.length) originCri = allCri.value; + if (allDef.value.length > originDef.length) originDef = allDef.value; atk.data = generateData(allCri.value); def.data = generateData(allDef.value); atk.update('resize'); def.update('resize'); -} +}, 200); onMounted(() => { const div = document.getElementById('critical-main') as HTMLDivElement; diff --git a/src/plugin/book.tsx b/src/plugin/book.tsx index a308353..c3d0390 100644 --- a/src/plugin/book.tsx +++ b/src/plugin/book.tsx @@ -56,7 +56,9 @@ export function getDefDamage( let origin: number | undefined; let last = 0; - for (let i = 0; i <= 100; i++) { + const max = 100 - Math.floor(addDef / ratio); + + for (let i = 0; i <= max; i++) { const dam = core.getDamageInfo(enemy, { def: core.status.hero.def + ratio * i + addDef, atk: core.status.hero.atk + addAtk @@ -77,6 +79,11 @@ export function getDefDamage( last = dam.damage; res.push([ratio * i + addDef, dam.damage]); } + + if ((res.at(-1)?.[1] ?? 1) <= 0) { + res.push([res.at(-1)![0] + 1, 0]); + } + return res; } @@ -95,16 +102,18 @@ export function getCriticalDamage( let origin: number | undefined; let last = 0; - for (let i = 0; i <= 100; i++) { + const max = 100 - Math.floor(addAtk / ratio); + + for (let i = 0; i <= max; i++) { const dam = core.getDamageInfo(enemy, { atk: core.status.hero.atk + ratio * i + addAtk, def: core.status.hero.def + addDef }); - if (i === 0) { + if (res.length === 0) { origin = dam?.damage; if (has(origin)) { - res.push([addAtk, origin]); + res.push([addAtk + i * ratio, origin]); last = origin; } continue; @@ -112,10 +121,14 @@ export function getCriticalDamage( if (!has(dam)) continue; if (dam.damage === origin) continue; if (dam.damage === res.at(-1)?.[1]) continue; - if (dam.damage <= 0) break; + if (last <= 0) break; last = dam.damage; res.push([ratio * i + addAtk, dam.damage]); } + if ((res.at(-1)?.[1] ?? 1) <= 0) { + res.push([res.at(-1)![0] + 1, 0]); + } + return res; } diff --git a/src/plugin/uiController.ts b/src/plugin/uiController.ts index 2494e0a..31292a7 100644 --- a/src/plugin/uiController.ts +++ b/src/plugin/uiController.ts @@ -21,9 +21,8 @@ export default function init() { showApp(); } else { const index = uiStack.value.findIndex(v => v === com); - uiStack.value.splice(index); - if (uiStack.value.length === 0) { - hideApp(); + if (uiStack.value.length === 1) { + hideApp(index); } } }); @@ -38,9 +37,10 @@ async function showApp() { core.lockControl(); } -async function hideApp() { +async function hideApp(index: number) { app.style.opacity = '0'; await sleep(600); + uiStack.value.splice(index, 1); app.style.display = 'none'; core.unlockControl(); } diff --git a/src/types/core.d.ts b/src/types/core.d.ts index 440033c..c6c699f 100644 --- a/src/types/core.d.ts +++ b/src/types/core.d.ts @@ -1,3 +1,16 @@ +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// + type Core = { /** 地图的格子宽度 */ readonly _WIDTH_: number; diff --git a/src/ui/book.vue b/src/ui/book.vue index c759feb..a9f0a07 100644 --- a/src/ui/book.vue +++ b/src/ui/book.vue @@ -1,12 +1,17 @@