diff --git a/_server/MotaAction.g4 b/_server/MotaAction.g4 index 53d2fbb..fd95279 100644 --- a/_server/MotaAction.g4 +++ b/_server/MotaAction.g4 @@ -965,8 +965,7 @@ action | animationDrawable_s | over_s | overlist_s - | playStereo_s - | moveStereo_s + | cgtextList_s | pass_s ; @@ -1125,22 +1124,33 @@ overtextEmpty var code = []; return code; */; +cgtextList_s + : '切换剧情文本库' EvalString Newline + + +/* cgtextList_s +tooltip : cgtextList:设置cg剧情文本库 +helpUrl : /_docs/#/instruction +default : ["chapter0"] +var code = '{"type": "cgtextList", "textList":"'+EvalString_0+'"},\n'; +return code; +*/; cgtext_s - : '背景' EvalString? '回忆滤镜' Bool? '移除对话框' Bool? '头像' EvalString?'名字' EvalString?'坐标PX' Number'打字间隔' Int? BGNL? Newline + : '背景' EvalString? '回忆滤镜' Bool? '移除对话框' Bool? '剧情库序列' Int '头像' EvalString?'坐标PX' Number'打字间隔' Int? BGNL? Newline '自动等待时长' Int '音频文件(需在全塔属性——使用音效注册)'EvalString? BGNL? Newline - EvalString? BGNL? Newline textcgDrawingList+? Newline + textcgDrawingList+? Newline /* cgtext_s tooltip : cgtext:显示一段包含cg的文字(剧情) helpUrl : /_docs/#/instruction allImages : ['EvalString_0','EvalString_1'] -allSounds : ['EvalString_3'] -default : ["bg_5043.webp",false,"face_050445.webp",false,"菲奥奈",-300,0,2000,"","这句话显示在对话框内",[{ "name":"tati_050145a.webp" , "px": 100,"filter":false }]] +allSounds : ['EvalString_2'] +default : ["bg_5043.webp",false,false,0,"face_050445.webp",-300,0,2000,"","这句话显示在对话框内",[{ "name":"tati_050145a.webp" , "px": 100,"filter":false }]] var head ='{ "name": "'+EvalString_1+'", "px": '+Number_0+' }' var list=',"bodyList": [\n'+textcgDrawingList_0.slice(0,-1)+'\n]' -var code = '{"type": "cgtext", "bg":"'+EvalString_0+'","memory":'+Bool_0+',"WindowSkin":'+Bool_1+',"head":'+head+' ,"name":"'+EvalString_2+'","time":'+Int_0+',"wait":'+Int_1+',"sound":"'+EvalString_3+'","text": "'+EvalString_4+'"'+list+' },\n'; +var code = '{"type": "cgtext", "bg":"'+EvalString_0+'","memory":'+Bool_0+',"WindowSkin":'+Bool_1+',"head":'+head+' ,"index":"'+Int_0+'","time":'+Int_1+',"wait":'+Int_2+',"sound":"'+EvalString_2+'"'+list+' },\n'; return code; */; textcgDrawingList @@ -3078,38 +3088,7 @@ var code = '{"type": "playSound", "name": "'+EvalString_0+'"'+Bool_0+IntString_0 return code; */; -playStereo_s - : '播放音效(立体音)' EvalString '左声道音量' Int '右声道音量' Int '启用立体音' Bool? Newline - -/* playStereo_s -tooltip : playSound: 播放音效(立体音) -helpUrl : /_docs/#/instruction -default : ["item.mp3",1,1,true] -colour : this.imageColor -allSounds : ['EvalString_0'] -material : ["./project/sounds/", "EvalString_0"] - -var code = '{"type": "playStereo", "name": "'+EvalString_0+'", "left": '+Int_0+', "right": '+Int_1+', "split": '+Bool_0+'},\n'; -return code; -*/; - -moveStereo_s - : '播放渐变音效(立体音)' EvalString '左声道音量' Int '右声道音量' Int '启用立体音' Bool? BGNL? Newline - '左声道目标音量' Int '右声道目标音量' Int '渐变时长'Int Newline - - -/* moveStereo_s -tooltip : playSound: 播放渐变音效(立体音) -helpUrl : /_docs/#/instruction -default : ["item.mp3",1,1,true,10,10,1000] -colour : this.imageColor -allSounds : ['EvalString_0'] -material : ["./project/sounds/", "EvalString_0"] - -var code = '{"type": "moveStereo", "name": "'+EvalString_0+'", "left": '+Int_0+', "right": '+Int_1+', "split": '+Bool_0+', "leftTo": '+Int_2+', "rightTo": '+Int_3+', "time": '+Int_4+'},\n'; -return code; -*/; playSound_1_s : '播放系统音效' NameMap_List '停止之前音效' Bool? '音调' IntString? '等待播放完毕' Bool? Newline diff --git a/_server/MotaActionParser.js b/_server/MotaActionParser.js index 99a0213..18f7066 100644 --- a/_server/MotaActionParser.js +++ b/_server/MotaActionParser.js @@ -542,6 +542,12 @@ MotaActionParser = function () { ); } break; + case "cgtextList": + this.next = MotaActionBlocks["cgtextList_s"].xmlText([ + data.textList, + this.next, + ]); + break; case "cgtext": // cg对话框 var buildcgDrawing = function (obj) { obj = MotaActionFunctions.processcgDrawing(obj || []); @@ -563,13 +569,12 @@ MotaActionParser = function () { data.bg, data.memory, data.WindowSkin, + data.index, data.head.name, - data.name || "", data.head.px || -300, data.time, data.wait, data.sound, - data.text, buildcgDrawing(data.bodyList), this.next, ]); @@ -1520,27 +1525,6 @@ MotaActionParser = function () { ]); } break; - case "playStereo": - this.next = MotaActionBlocks["playStereo_s"].xmlText([ - data.name, - data.left, - data.right, - data.split || true, - this.next, - ]); - break; - case "moveStereo": - this.next = MotaActionBlocks["moveStereo_s"].xmlText([ - data.name, - data.left, - data.right, - data.split || true, - data.leftTo, - data.rightTo, - data.time, - this.next, - ]); - break; case "playSound": var knownItems = MotaActionBlocks["NameMap_List"].options.map(function ( one diff --git a/libs/control.js b/libs/control.js index c6e4f30..93b4a0a 100644 --- a/libs/control.js +++ b/libs/control.js @@ -1,4 +1,3 @@ - /* control.js:游戏主要逻辑控制 主要负责status相关内容,以及各种变量获取/存储 @@ -7,57 +6,93 @@ control.js:游戏主要逻辑控制 "use strict"; -function control () { - this._init(); +function control() { + this._init(); } control.prototype._init = function () { - this.controldata = functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a.control; - this.renderFrameFuncs = []; - this.replayActions = []; - this.weathers = {}; - this.resizes = []; - this.noAutoEvents = true; - this.updateNextFrame = false; - // --- 注册系统的animationFrame - this.registerAnimationFrame("totalTime", false, this._animationFrame_totalTime); - this.registerAnimationFrame("autoSave", true, this._animationFrame_autoSave); - this.registerAnimationFrame("globalAnimate", true, this._animationFrame_globalAnimate); - this.registerAnimationFrame("animate", true, this._animationFrame_animate); - this.registerAnimationFrame("heroMoving", true, this._animationFrame_heroMoving); - this.registerAnimationFrame("weather", true, this._animationFrame_weather); - this.registerAnimationFrame("tip", true, this._animateFrame_tip); - this.registerAnimationFrame("parallelDo", false, this._animationFrame_parallelDo); - // --- 注册系统的天气 - this.registerWeather("rain", this._weather_rain, this._animationFrame_weather_rain); - this.registerWeather("snow", this._weather_snow, this._animationFrame_weather_snow); - this.registerWeather("fog", this._weather_fog, this.__animateFrame_weather_image); - this.registerWeather("cloud", this._weather_cloud, this.__animateFrame_weather_image); - this.registerWeather("sun", this._weather_sun, this._animationFrame_weather_sun); - // --- 注册系统的replay - this.registerReplayAction("move", this._replayAction_move); - this.registerReplayAction("item", this._replayAction_item); - this.registerReplayAction("equip", this._replayAction_equip); - this.registerReplayAction("unEquip", this._replayAction_unEquip); - this.registerReplayAction("saveEquip", this._replayAction_saveEquip); - this.registerReplayAction("loadEquip", this._replayAction_loadEquip); - this.registerReplayAction("fly", this._replayAction_fly); - this.registerReplayAction("shop", this._replayAction_shop); - this.registerReplayAction("turn", this._replayAction_turn); - this.registerReplayAction("getNext", this._replayAction_getNext); - this.registerReplayAction("moveDirectly", this._replayAction_moveDirectly); - this.registerReplayAction("key", this._replayAction_key); - this.registerReplayAction("click", this._replayAction_click); - this.registerReplayAction("ignoreInput", this._replayAction_ignoreInput); - this.registerReplayAction("no", this._replayAction_no); - // --- 注册系统的resize - this.registerResize("gameGroup", this._resize_gameGroup); - this.registerResize("canvas", this._resize_canvas); - this.registerResize("statusBar", this._resize_statusBar); - this.registerResize("status", this._resize_status); - this.registerResize("toolBar", this._resize_toolBar); - this.registerResize("tools", this._resize_tools); -} + this.controldata = functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a.control; + this.renderFrameFuncs = []; + this.replayActions = []; + this.weathers = {}; + this.resizes = []; + this.noAutoEvents = true; + this.updateNextFrame = false; + // --- 注册系统的animationFrame + this.registerAnimationFrame( + "totalTime", + false, + this._animationFrame_totalTime + ); + this.registerAnimationFrame("autoSave", true, this._animationFrame_autoSave); + this.registerAnimationFrame( + "globalAnimate", + true, + this._animationFrame_globalAnimate + ); + this.registerAnimationFrame("animate", true, this._animationFrame_animate); + this.registerAnimationFrame( + "heroMoving", + true, + this._animationFrame_heroMoving + ); + this.registerAnimationFrame("weather", true, this._animationFrame_weather); + this.registerAnimationFrame("tip", true, this._animateFrame_tip); + this.registerAnimationFrame( + "parallelDo", + false, + this._animationFrame_parallelDo + ); + // --- 注册系统的天气 + this.registerWeather( + "rain", + this._weather_rain, + this._animationFrame_weather_rain + ); + this.registerWeather( + "snow", + this._weather_snow, + this._animationFrame_weather_snow + ); + this.registerWeather( + "fog", + this._weather_fog, + this.__animateFrame_weather_image + ); + this.registerWeather( + "cloud", + this._weather_cloud, + this.__animateFrame_weather_image + ); + this.registerWeather( + "sun", + this._weather_sun, + this._animationFrame_weather_sun + ); + // --- 注册系统的replay + this.registerReplayAction("move", this._replayAction_move); + this.registerReplayAction("item", this._replayAction_item); + this.registerReplayAction("equip", this._replayAction_equip); + this.registerReplayAction("unEquip", this._replayAction_unEquip); + this.registerReplayAction("saveEquip", this._replayAction_saveEquip); + this.registerReplayAction("loadEquip", this._replayAction_loadEquip); + this.registerReplayAction("fly", this._replayAction_fly); + this.registerReplayAction("shop", this._replayAction_shop); + this.registerReplayAction("turn", this._replayAction_turn); + this.registerReplayAction("getNext", this._replayAction_getNext); + this.registerReplayAction("moveDirectly", this._replayAction_moveDirectly); + this.registerReplayAction("key", this._replayAction_key); + this.registerReplayAction("click", this._replayAction_click); + this.registerReplayAction("ignoreInput", this._replayAction_ignoreInput); + this.registerReplayAction("no", this._replayAction_no); + // --- 注册系统的resize + this.registerResize("gameGroup", this._resize_gameGroup); + this.registerResize("canvas", this._resize_canvas); + this.registerResize("statusBar", this._resize_statusBar); + this.registerResize("status", this._resize_status); + this.registerResize("toolBar", this._resize_toolBar); + this.registerResize("tools", this._resize_tools); +}; // ------ requestAnimationFrame 相关 ------ // @@ -65,1542 +100,1938 @@ control.prototype._init = function () { // name:名称,可用来作为注销使用;needPlaying:是否只在游戏运行时才执行(在标题界面不执行) // func:要执行的函数,或插件中的函数名;可接受timestamp(从页面加载完毕到当前所经过的时间)作为参数 control.prototype.registerAnimationFrame = function (name, needPlaying, func) { - this.unregisterAnimationFrame(name); - this.renderFrameFuncs.push({ name: name, needPlaying: needPlaying, func: func }); -} + this.unregisterAnimationFrame(name); + this.renderFrameFuncs.push({ + name: name, + needPlaying: needPlaying, + func: func, + }); +}; ////// 注销一个 animationFrame ////// control.prototype.unregisterAnimationFrame = function (name) { - this.renderFrameFuncs = this.renderFrameFuncs.filter(function (x) { return x.name != name; }); -} + this.renderFrameFuncs = this.renderFrameFuncs.filter(function (x) { + return x.name != name; + }); +}; ////// 设置requestAnimationFrame ////// control.prototype._setRequestAnimationFrame = function () { - this._checkRequestAnimationFrame(); - core.animateFrame.totalTime = Math.max(core.animateFrame.totalTime, core.getLocalStorage('totalTime', 0)); - var loop = function (timestamp) { - core.control.renderFrameFuncs.forEach(function (b) { - if (b.func) { - try { - if (core.isPlaying() || !b.needPlaying) - core.doFunc(b.func, core.control, timestamp); - } - catch (e) { - console.error(e); - console.error("ERROR in requestAnimationFrame[" + b.name + "]:已自动注销该项。"); - core.unregisterAnimationFrame(b.name); - } - } - }) - window.requestAnimationFrame(loop); - } + this._checkRequestAnimationFrame(); + core.animateFrame.totalTime = Math.max( + core.animateFrame.totalTime, + core.getLocalStorage("totalTime", 0) + ); + var loop = function (timestamp) { + core.control.renderFrameFuncs.forEach(function (b) { + if (b.func) { + try { + if (core.isPlaying() || !b.needPlaying) + core.doFunc(b.func, core.control, timestamp); + } catch (e) { + console.error(e); + console.error( + "ERROR in requestAnimationFrame[" + b.name + "]:已自动注销该项。" + ); + core.unregisterAnimationFrame(b.name); + } + } + }); window.requestAnimationFrame(loop); -} + }; + window.requestAnimationFrame(loop); +}; control.prototype._checkRequestAnimationFrame = function () { - (function () { - var lastTime = 0; - var vendors = ['webkit', 'moz']; - for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { - window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame']; - window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || // Webkit中此取消方法的名字变了 - window[vendors[x] + 'CancelRequestAnimationFrame']; - } + (function () { + var lastTime = 0; + var vendors = ["webkit", "moz"]; + for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { + window.requestAnimationFrame = + window[vendors[x] + "RequestAnimationFrame"]; + window.cancelAnimationFrame = + window[vendors[x] + "CancelAnimationFrame"] || // Webkit中此取消方法的名字变了 + window[vendors[x] + "CancelRequestAnimationFrame"]; + } - if (!window.requestAnimationFrame) { - window.requestAnimationFrame = function (callback, element) { - var currTime = new Date().getTime(); - var timeToCall = Math.max(0, 16.7 - (currTime - lastTime)); - var id = window.setTimeout(function () { - callback(currTime + timeToCall); - }, timeToCall); - lastTime = currTime + timeToCall; - return id; - }; - } - if (!window.cancelAnimationFrame) { - window.cancelAnimationFrame = function (id) { - clearTimeout(id); - }; - } - }()); -} + if (!window.requestAnimationFrame) { + window.requestAnimationFrame = function (callback, element) { + var currTime = new Date().getTime(); + var timeToCall = Math.max(0, 16.7 - (currTime - lastTime)); + var id = window.setTimeout(function () { + callback(currTime + timeToCall); + }, timeToCall); + lastTime = currTime + timeToCall; + return id; + }; + } + if (!window.cancelAnimationFrame) { + window.cancelAnimationFrame = function (id) { + clearTimeout(id); + }; + } + })(); +}; control.prototype._animationFrame_totalTime = function (timestamp) { - core.animateFrame.totalTime += timestamp - core.animateFrame.totalTimeStart; - core.animateFrame.totalTimeStart = timestamp; - if (core.isPlaying()) { - core.status.hero.statistics.totalTime = core.animateFrame.totalTime; - core.status.hero.statistics.currTime += timestamp - (core.status.hero.statistics.start || timestamp); - core.status.hero.statistics.start = timestamp; - } -} + core.animateFrame.totalTime += timestamp - core.animateFrame.totalTimeStart; + core.animateFrame.totalTimeStart = timestamp; + if (core.isPlaying()) { + core.status.hero.statistics.totalTime = core.animateFrame.totalTime; + core.status.hero.statistics.currTime += + timestamp - (core.status.hero.statistics.start || timestamp); + core.status.hero.statistics.start = timestamp; + } +}; control.prototype._animationFrame_autoSave = function (timestamp) { - if (timestamp - core.saves.autosave.time <= 5000) return; - core.control.checkAutosave(); - core.saves.autosave.time = timestamp; -} + if (timestamp - core.saves.autosave.time <= 5000) return; + core.control.checkAutosave(); + core.saves.autosave.time = timestamp; +}; control.prototype._animationFrame_globalAnimate = function (timestamp) { - if (timestamp - core.animateFrame.globalTime <= core.values.animateSpeed) return; - core.status.globalAnimateStatus++; - if (core.status.floorId) { - // Global Animate - core.status.globalAnimateObjs.forEach(function (block) { - core.drawBlock(block, core.status.globalAnimateStatus); - }); + if (timestamp - core.animateFrame.globalTime <= core.values.animateSpeed) + return; + core.status.globalAnimateStatus++; + if (core.status.floorId) { + // Global Animate + core.status.globalAnimateObjs.forEach(function (block) { + core.drawBlock(block, core.status.globalAnimateStatus); + }); - // Global floor images - core.maps._drawFloorImages(core.status.floorId, core.canvas.bg, 'bg', core.status.floorAnimateObjs || [], core.status.globalAnimateStatus); - core.maps._drawFloorImages(core.status.floorId, core.canvas.fg, 'fg', core.status.floorAnimateObjs || [], core.status.globalAnimateStatus); + // Global floor images + core.maps._drawFloorImages( + core.status.floorId, + core.canvas.bg, + "bg", + core.status.floorAnimateObjs || [], + core.status.globalAnimateStatus + ); + core.maps._drawFloorImages( + core.status.floorId, + core.canvas.fg, + "fg", + core.status.floorAnimateObjs || [], + core.status.globalAnimateStatus + ); - // Global Autotile Animate - core.status.autotileAnimateObjs.forEach(function (block) { - core.maps._drawAutotileAnimate(block, core.status.globalAnimateStatus); - }); + // Global Autotile Animate + core.status.autotileAnimateObjs.forEach(function (block) { + core.maps._drawAutotileAnimate(block, core.status.globalAnimateStatus); + }); - // Global hero animate - if ((core.status.hero || {}).animate && core.status.heroMoving == 0 && main.mode == 'play' && !core.status.preview.enabled) { - core.drawHero('stop', null, core.status.globalAnimateStatus); - } + // Global hero animate + if ( + (core.status.hero || {}).animate && + core.status.heroMoving == 0 && + main.mode == "play" && + !core.status.preview.enabled + ) { + core.drawHero("stop", null, core.status.globalAnimateStatus); } - // Box animate - core.drawBoxAnimate(); - core.animateFrame.globalTime = timestamp; -} + } + // Box animate + core.drawBoxAnimate(); + core.animateFrame.globalTime = timestamp; +}; control.prototype._animationFrame_animate = function (timestamp) { - if (timestamp - core.animateFrame.animateTime < 50 || !core.status.animateObjs || core.status.animateObjs.length == 0) return; - core.clearMap('animate'); - // 更新帧 - for (var i = 0; i < core.status.animateObjs.length; i++) { - var obj = core.status.animateObjs[i]; - if (obj.index == obj.animate.frames.length) { - (function (callback) { - setTimeout(function () { - if (callback) callback(); - }); - })(obj.callback); - } + if ( + timestamp - core.animateFrame.animateTime < 50 || + !core.status.animateObjs || + core.status.animateObjs.length == 0 + ) + return; + core.clearMap("animate"); + // 更新帧 + for (var i = 0; i < core.status.animateObjs.length; i++) { + var obj = core.status.animateObjs[i]; + if (obj.index == obj.animate.frames.length) { + (function (callback) { + setTimeout(function () { + if (callback) callback(); + }); + })(obj.callback); } - core.status.animateObjs = core.status.animateObjs.filter(function (obj) { - return obj.index < obj.animate.frames.length; - }); - core.status.animateObjs.forEach(function (obj) { - if (obj.hero) { - core.maps._drawAnimateFrame('animate', obj.animate, core.status.heroCenter.px, core.status.heroCenter.py, obj.index++); - } else { - core.maps._drawAnimateFrame('animate', obj.animate, obj.centerX, obj.centerY, obj.index++); - } - }); - core.animateFrame.animateTime = timestamp; -} + } + core.status.animateObjs = core.status.animateObjs.filter(function (obj) { + return obj.index < obj.animate.frames.length; + }); + core.status.animateObjs.forEach(function (obj) { + if (obj.hero) { + core.maps._drawAnimateFrame( + "animate", + obj.animate, + core.status.heroCenter.px, + core.status.heroCenter.py, + obj.index++ + ); + } else { + core.maps._drawAnimateFrame( + "animate", + obj.animate, + obj.centerX, + obj.centerY, + obj.index++ + ); + } + }); + core.animateFrame.animateTime = timestamp; +}; control.prototype._animationFrame_heroMoving = function (timestamp) { - if (core.status.heroMoving <= 0) return; - // 换腿 - if (timestamp - core.animateFrame.moveTime > core.values.moveSpeed) { - core.animateFrame.leftLeg = !core.animateFrame.leftLeg; - core.animateFrame.moveTime = timestamp; - } - core.drawHero(core.animateFrame.leftLeg ? 'leftFoot' : 'rightFoot', 4 * core.status.heroMoving); -} + if (core.status.heroMoving <= 0) return; + // 换腿 + if (timestamp - core.animateFrame.moveTime > core.values.moveSpeed) { + core.animateFrame.leftLeg = !core.animateFrame.leftLeg; + core.animateFrame.moveTime = timestamp; + } + core.drawHero( + core.animateFrame.leftLeg ? "leftFoot" : "rightFoot", + 4 * core.status.heroMoving + ); +}; control.prototype._animationFrame_weather = function (timestamp) { - var weather = core.animateFrame.weather, type = weather.type; - if (!core.dymCanvas.weather || !core.control.weathers[type] || !core.control.weathers[type].frameFunc) return; - try { - core.doFunc(core.control.weathers[type].frameFunc, core.control, timestamp, core.animateFrame.weather.level); - } catch (e) { - console.error(e); - console.error("ERROR in weather[" + type + "]:已自动注销该项。"); - core.unregisterWeather(type); - } -} + var weather = core.animateFrame.weather, + type = weather.type; + if ( + !core.dymCanvas.weather || + !core.control.weathers[type] || + !core.control.weathers[type].frameFunc + ) + return; + try { + core.doFunc( + core.control.weathers[type].frameFunc, + core.control, + timestamp, + core.animateFrame.weather.level + ); + } catch (e) { + console.error(e); + console.error("ERROR in weather[" + type + "]:已自动注销该项。"); + core.unregisterWeather(type); + } +}; control.prototype._animationFrame_weather_rain = function (timestamp, level) { - if (timestamp - core.animateFrame.weather.time < 30) return; - var ctx = core.dymCanvas.weather, ox = core.bigmap.offsetX, oy = core.bigmap.offsetY; - core.clearMap('weather'); - ctx.strokeStyle = 'rgba(174,194,224,0.8)'; - ctx.lineWidth = 1; - ctx.lineCap = 'round'; + if (timestamp - core.animateFrame.weather.time < 30) return; + var ctx = core.dymCanvas.weather, + ox = core.bigmap.offsetX, + oy = core.bigmap.offsetY; + core.clearMap("weather"); + ctx.strokeStyle = "rgba(174,194,224,0.8)"; + ctx.lineWidth = 1; + ctx.lineCap = "round"; - core.animateFrame.weather.nodes.forEach(function (p) { - ctx.beginPath(); - ctx.moveTo(p.x - ox, p.y - oy); - ctx.lineTo(p.x + p.l * p.xs - ox, p.y + p.l * p.ys - oy); - ctx.stroke(); + core.animateFrame.weather.nodes.forEach(function (p) { + ctx.beginPath(); + ctx.moveTo(p.x - ox, p.y - oy); + ctx.lineTo(p.x + p.l * p.xs - ox, p.y + p.l * p.ys - oy); + ctx.stroke(); - p.x += p.xs; - p.y += p.ys; - if (p.x > core.bigmap.width * 32 || p.y > core.bigmap.height * 32) { - p.x = Math.random() * core.bigmap.width * 32; - p.y = -10; - } + p.x += p.xs; + p.y += p.ys; + if (p.x > core.bigmap.width * 32 || p.y > core.bigmap.height * 32) { + p.x = Math.random() * core.bigmap.width * 32; + p.y = -10; + } + }); - }); - - ctx.fill(); - core.animateFrame.weather.time = timestamp; -} + ctx.fill(); + core.animateFrame.weather.time = timestamp; +}; control.prototype._animationFrame_weather_snow = function (timestamp, level) { - if (timestamp - core.animateFrame.weather.time < 30) return; - var ctx = core.dymCanvas.weather, ox = core.bigmap.offsetX, oy = core.bigmap.offsetY; - core.clearMap('weather'); - ctx.fillStyle = "rgba(255, 255, 255, 0.8)"; - ctx.beginPath(); - core.animateFrame.weather.data = core.animateFrame.weather.data || 0; - core.animateFrame.weather.data += 0.01; + if (timestamp - core.animateFrame.weather.time < 30) return; + var ctx = core.dymCanvas.weather, + ox = core.bigmap.offsetX, + oy = core.bigmap.offsetY; + core.clearMap("weather"); + ctx.fillStyle = "rgba(255, 255, 255, 0.8)"; + ctx.beginPath(); + core.animateFrame.weather.data = core.animateFrame.weather.data || 0; + core.animateFrame.weather.data += 0.01; - var angle = core.animateFrame.weather.data; - core.animateFrame.weather.nodes.forEach(function (p) { - ctx.moveTo(p.x - ox, p.y - oy); - ctx.arc(p.x - ox, p.y - oy, p.r, 0, Math.PI * 2, true); - // update - p.x += Math.sin(angle) * core.animateFrame.weather.level; - p.y += Math.cos(angle + p.d) + 1 + p.r / 2; - if (p.x > core.bigmap.width * 32 + 5 || p.x < -5 || p.y > core.bigmap.height * 32) { - if (Math.random() > 1 / 3) { - p.x = Math.random() * core.bigmap.width * 32; - p.y = -10; - } - else { - if (Math.sin(angle) > 0) - p.x = -5; - else - p.x = core.bigmap.width * 32 + 5; - p.y = Math.random() * core.bigmap.height * 32; - } - } - }); - ctx.fill(); - core.animateFrame.weather.time = timestamp; -} + var angle = core.animateFrame.weather.data; + core.animateFrame.weather.nodes.forEach(function (p) { + ctx.moveTo(p.x - ox, p.y - oy); + ctx.arc(p.x - ox, p.y - oy, p.r, 0, Math.PI * 2, true); + // update + p.x += Math.sin(angle) * core.animateFrame.weather.level; + p.y += Math.cos(angle + p.d) + 1 + p.r / 2; + if ( + p.x > core.bigmap.width * 32 + 5 || + p.x < -5 || + p.y > core.bigmap.height * 32 + ) { + if (Math.random() > 1 / 3) { + p.x = Math.random() * core.bigmap.width * 32; + p.y = -10; + } else { + if (Math.sin(angle) > 0) p.x = -5; + else p.x = core.bigmap.width * 32 + 5; + p.y = Math.random() * core.bigmap.height * 32; + } + } + }); + ctx.fill(); + core.animateFrame.weather.time = timestamp; +}; control.prototype.__animateFrame_weather_image = function (timestamp, level) { - if (timestamp - core.animateFrame.weather.time < 30) return; - var node = core.animateFrame.weather.nodes[0]; - var image = node.image; - if (!image) return; - core.clearMap('weather'); - core.setAlpha('weather', node.level / 500); - var wind = 1.5; - var width = image.width, height = image.height; - node.x += node.dx * wind; - node.y += (2 * node.dy - 1) * wind; - if (node.x + 3 * width <= core._PX_) { - node.x += 4 * width; - while (node.x > 0) node.x -= width; + if (timestamp - core.animateFrame.weather.time < 30) return; + var node = core.animateFrame.weather.nodes[0]; + var image = node.image; + if (!image) return; + core.clearMap("weather"); + core.setAlpha("weather", node.level / 500); + var wind = 1.5; + var width = image.width, + height = image.height; + node.x += node.dx * wind; + node.y += (2 * node.dy - 1) * wind; + if (node.x + 3 * width <= core._PX_) { + node.x += 4 * width; + while (node.x > 0) node.x -= width; + } + node.dy += node.delta; + if (node.dy >= 1) { + node.delta = -0.001; + } else if (node.dy <= 0) { + node.delta = 0.001; + } + if (node.y + 3 * height <= core._PY_) { + node.y += 4 * height; + while (node.y > 0) node.y -= height; + } else if (node.y >= 0) { + node.y -= height; + } + for (var i = 0; i < 3; ++i) { + for (var j = 0; j < 3; ++j) { + if ( + node.x + (i + 1) * width <= 0 || + node.x + i * width >= core._PX_ || + node.y + (j + 1) * height <= 0 || + node.y + j * height >= core._PY_ + ) + continue; + core.drawImage("weather", image, node.x + i * width, node.y + j * height); } - node.dy += node.delta; - if (node.dy >= 1) { - node.delta = -0.001; - } else if (node.dy <= 0) { - node.delta = 0.001; - } - if (node.y + 3 * height <= core._PY_) { - node.y += 4 * height; - while (node.y > 0) node.y -= height; - } - else if (node.y >= 0) { - node.y -= height; - } - for (var i = 0; i < 3; ++i) { - for (var j = 0; j < 3; ++j) { - if (node.x + (i + 1) * width <= 0 || node.x + i * width >= core._PX_ - || node.y + (j + 1) * height <= 0 || node.y + j * height >= core._PY_) - continue; - core.drawImage('weather', image, node.x + i * width, node.y + j * height); - } - } - core.setAlpha('weather', 1); - core.animateFrame.weather.time = timestamp; -} + } + core.setAlpha("weather", 1); + core.animateFrame.weather.time = timestamp; +}; control.prototype._animationFrame_weather_sun = function (timestamp, level) { - if (timestamp - core.animateFrame.weather.time < 30) return; - var node = core.animateFrame.weather.nodes[0]; - var opacity = node.opacity + node.delta; - if (opacity > level / 10 + 0.3 || opacity < level / 10 - 0.3) - node.delta = -node.delta; - node.opacity = opacity; - core.setOpacity('weather', core.clamp(opacity, 0, 1)); - core.animateFrame.weather.time = timestamp; -} + if (timestamp - core.animateFrame.weather.time < 30) return; + var node = core.animateFrame.weather.nodes[0]; + var opacity = node.opacity + node.delta; + if (opacity > level / 10 + 0.3 || opacity < level / 10 - 0.3) + node.delta = -node.delta; + node.opacity = opacity; + core.setOpacity("weather", core.clamp(opacity, 0, 1)); + core.animateFrame.weather.time = timestamp; +}; control.prototype._animateFrame_tip = function (timestamp) { - if (core.animateFrame.tip == null) return; - var tip = core.animateFrame.tip; - if (timestamp - tip.time <= 30) return; - var delta = timestamp - tip.time; - tip.time = timestamp; + if (core.animateFrame.tip == null) return; + var tip = core.animateFrame.tip; + if (timestamp - tip.time <= 30) return; + var delta = timestamp - tip.time; + tip.time = timestamp; - core.setFont('data', "16px Arial"); - core.setTextAlign('data', 'left'); - core.clearMap('data', 0, 0, core._PX_, 50); - core.ui._drawTip_drawOne(tip); - if (tip.stage == 1) { - tip.opacity += 0.05; - if (tip.opacity >= 0.6) { - tip.stage = 2; - tip.displayTime = 0; - } - } else if (tip.stage == 2) { - tip.displayTime += delta; - if (tip.displayTime >= 1000) tip.stage = 3; - } else tip.opacity -= 0.05; - - if (tip.opacity <= 0) { - core.animateFrame.tip = null; + core.setFont("data", "16px Arial"); + core.setTextAlign("data", "left"); + core.clearMap("data", 0, 0, core._PX_, 50); + core.ui._drawTip_drawOne(tip); + if (tip.stage == 1) { + tip.opacity += 0.05; + if (tip.opacity >= 0.6) { + tip.stage = 2; + tip.displayTime = 0; } -} + } else if (tip.stage == 2) { + tip.displayTime += delta; + if (tip.displayTime >= 1000) tip.stage = 3; + } else tip.opacity -= 0.05; + + if (tip.opacity <= 0) { + core.animateFrame.tip = null; + } +}; control.prototype._animationFrame_parallelDo = function (timestamp) { - core.control.controldata.parallelDo(timestamp); -} + core.control.controldata.parallelDo(timestamp); +}; // ------ 标题界面的处理 ------ // ////// 显示游戏开始界面 ////// control.prototype.showStartAnimate = function (noAnimate, callback) { - this._showStartAnimate_resetDom(); - if (core.flags.startUsingCanvas || noAnimate) - return this._showStartAnimate_finished(core.flags.startUsingCanvas, callback); - core.hideWithAnimate(core.dom.startTop, 20, function () { - core.control._showStartAnimate_finished(false, callback); - }); -} + this._showStartAnimate_resetDom(); + if (core.flags.startUsingCanvas || noAnimate) + return this._showStartAnimate_finished( + core.flags.startUsingCanvas, + callback + ); + core.hideWithAnimate(core.dom.startTop, 20, function () { + core.control._showStartAnimate_finished(false, callback); + }); +}; control.prototype._showStartAnimate_resetDom = function () { - core.dom.startPanel.style.opacity = 1; - core.dom.startPanel.style.display = "block"; - core.dom.startTop.style.opacity = 1; - core.dom.startTop.style.display = "block"; - core.dom.startButtonGroup.style.display = 'none'; - core.dom.startButtons.style.display = 'block'; - core.dom.levelChooseButtons.style.display = 'none'; - core.status.played = false; - core.clearStatus(); - core.clearMap('all'); - core.dom.musicBtn.style.display = 'block'; - core.setMusicBtn(); - // 重置音量 - core.events.setVolume(1, 0); - core.updateStatusBar(); -} + core.dom.startPanel.style.opacity = 1; + core.dom.startPanel.style.display = "block"; + core.dom.startTop.style.opacity = 1; + core.dom.startTop.style.display = "block"; + core.dom.startButtonGroup.style.display = "none"; + core.dom.startButtons.style.display = "block"; + core.dom.levelChooseButtons.style.display = "none"; + core.status.played = false; + core.clearStatus(); + core.clearMap("all"); + core.dom.musicBtn.style.display = "block"; + core.setMusicBtn(); + // 重置音量 + core.events.setVolume(1, 0); + core.updateStatusBar(); +}; control.prototype._showStartAnimate_finished = function (start, callback) { - core.dom.startTop.style.display = 'none'; - core.dom.startButtonGroup.style.display = 'block'; - main.selectedButton = null; - main.selectButton(0); - if (start) core.startGame(); - if (callback) callback(); -} + core.dom.startTop.style.display = "none"; + core.dom.startButtonGroup.style.display = "block"; + main.selectedButton = null; + main.selectButton(0); + if (start) core.startGame(); + if (callback) callback(); +}; ////// 隐藏游戏开始界面 ////// control.prototype.hideStartAnimate = function (callback) { - core.hideWithAnimate(core.dom.startPanel, 20, callback); -} + core.hideWithAnimate(core.dom.startPanel, 20, callback); +}; ////// 游戏是否已经开始 ////// control.prototype.isPlaying = function () { - return core.status.played; -} + return core.status.played; +}; ////// 清除游戏状态和数据 ////// control.prototype.clearStatus = function () { - // 停止各个Timeout和Interval - for (var i in core.timeout) { - clearTimeout(core.timeout[i]); - core.timeout[i] = null; - } - for (var i in core.interval) { - clearInterval(core.interval[i]); - core.interval[i] = null; - } - core.status = {}; - core.clearStatusBar(); - core.deleteAllCanvas(); - core.status.played = false; -} + // 停止各个Timeout和Interval + for (var i in core.timeout) { + clearTimeout(core.timeout[i]); + core.timeout[i] = null; + } + for (var i in core.interval) { + clearInterval(core.interval[i]); + core.interval[i] = null; + } + core.status = {}; + core.clearStatusBar(); + core.deleteAllCanvas(); + core.status.played = false; +}; control.prototype._initStatistics = function (totalTime) { - if (!core.isset(core.status.hero.statistics)) - core.status.hero.statistics = { - 'totalTime': totalTime, - 'currTime': 0, - 'hp': 0, - "battle": 0, - 'money': 0, - 'exp': 0, - 'battleDamage': 0, - 'poisonDamage': 0, - 'extraDamage': 0, - 'moveDirectly': 0, - 'ignoreSteps': 0, - } -} + if (!core.isset(core.status.hero.statistics)) + core.status.hero.statistics = { + totalTime: totalTime, + currTime: 0, + hp: 0, + battle: 0, + money: 0, + exp: 0, + battleDamage: 0, + poisonDamage: 0, + extraDamage: 0, + moveDirectly: 0, + ignoreSteps: 0, + }; +}; // ------ 自动寻路,人物行走 ------ // ////// 清除自动寻路路线 ////// control.prototype.clearAutomaticRouteNode = function (x, y) { - core.clearMap('route', x * 32 + 5 - core.status.automaticRoute.offsetX, y * 32 + 5 - core.status.automaticRoute.offsetY, 27, 27); -} + core.clearMap( + "route", + x * 32 + 5 - core.status.automaticRoute.offsetX, + y * 32 + 5 - core.status.automaticRoute.offsetY, + 27, + 27 + ); +}; ////// 停止自动寻路操作 ////// control.prototype.stopAutomaticRoute = function () { - if (!core.status.played) return; - core.status.automaticRoute.autoHeroMove = false; - core.status.automaticRoute.autoStep = 0; - core.status.automaticRoute.destStep = 0; - core.status.automaticRoute.movedStep = 0; - core.status.automaticRoute.autoStepRoutes = []; - core.status.automaticRoute.destX = null; - core.status.automaticRoute.destY = null; - core.status.automaticRoute.lastDirection = null; - core.status.heroStop = true; - if (core.status.automaticRoute.moveStepBeforeStop.length == 0) - core.deleteCanvas('route'); -} + if (!core.status.played) return; + core.status.automaticRoute.autoHeroMove = false; + core.status.automaticRoute.autoStep = 0; + core.status.automaticRoute.destStep = 0; + core.status.automaticRoute.movedStep = 0; + core.status.automaticRoute.autoStepRoutes = []; + core.status.automaticRoute.destX = null; + core.status.automaticRoute.destY = null; + core.status.automaticRoute.lastDirection = null; + core.status.heroStop = true; + if (core.status.automaticRoute.moveStepBeforeStop.length == 0) + core.deleteCanvas("route"); +}; ////// 保存剩下的寻路,并停止 ////// control.prototype.saveAndStopAutomaticRoute = function () { - var automaticRoute = core.status.automaticRoute; - if (automaticRoute.moveStepBeforeStop.length == 0) { - automaticRoute.moveStepBeforeStop = automaticRoute.autoStepRoutes.slice(automaticRoute.autoStep - 1); - if (automaticRoute.moveStepBeforeStop.length >= 1) - automaticRoute.moveStepBeforeStop[0].step -= automaticRoute.movedStep; - } - this.stopAutomaticRoute(); -} + var automaticRoute = core.status.automaticRoute; + if (automaticRoute.moveStepBeforeStop.length == 0) { + automaticRoute.moveStepBeforeStop = automaticRoute.autoStepRoutes.slice( + automaticRoute.autoStep - 1 + ); + if (automaticRoute.moveStepBeforeStop.length >= 1) + automaticRoute.moveStepBeforeStop[0].step -= automaticRoute.movedStep; + } + this.stopAutomaticRoute(); +}; ////// 继续剩下的自动寻路操作 ////// control.prototype.continueAutomaticRoute = function () { - // 此函数只应由events.afterOpenDoor和events.afterBattle调用 - var moveStep = core.status.automaticRoute.moveStepBeforeStop; - //core.status.automaticRoute.moveStepBeforeStop = []; - if (moveStep.length === 0 || (moveStep.length === 1 && moveStep[0].step === 1)) { - core.status.automaticRoute.moveStepBeforeStop = []; - } - else { - core.setAutoHeroMove(moveStep); - } -} + // 此函数只应由events.afterOpenDoor和events.afterBattle调用 + var moveStep = core.status.automaticRoute.moveStepBeforeStop; + //core.status.automaticRoute.moveStepBeforeStop = []; + if ( + moveStep.length === 0 || + (moveStep.length === 1 && moveStep[0].step === 1) + ) { + core.status.automaticRoute.moveStepBeforeStop = []; + } else { + core.setAutoHeroMove(moveStep); + } +}; ////// 清空剩下的自动寻路列表 ////// control.prototype.clearContinueAutomaticRoute = function (callback) { - core.deleteCanvas('route'); - core.status.automaticRoute.moveStepBeforeStop = []; - if (callback) callback(); -} + core.deleteCanvas("route"); + core.status.automaticRoute.moveStepBeforeStop = []; + if (callback) callback(); +}; ////// 设置自动寻路路线 ////// control.prototype.setAutomaticRoute = function (destX, destY, stepPostfix) { - if (!core.status.played || core.status.lockControl) return; - if (this._setAutomaticRoute_isMoving(destX, destY)) return; - if (this._setAutomaticRoute_isTurning(destX, destY, stepPostfix)) return; - if (this._setAutomaticRoute_clickMoveDirectly(destX, destY, stepPostfix)) return; - // 找寻自动寻路路线 - var moveStep = core.automaticRoute(destX, destY); - if (moveStep.length == 0 && (destX != core.status.hero.loc.x || destY != core.status.hero.loc.y || stepPostfix.length == 0)) - return; - moveStep = moveStep.concat(stepPostfix); - core.status.automaticRoute.destX = destX; - core.status.automaticRoute.destY = destY; - this._setAutomaticRoute_drawRoute(moveStep); - this._setAutomaticRoute_setAutoSteps(moveStep); - // 立刻移动 - core.setAutoHeroMove(); -} + if (!core.status.played || core.status.lockControl) return; + if (this._setAutomaticRoute_isMoving(destX, destY)) return; + if (this._setAutomaticRoute_isTurning(destX, destY, stepPostfix)) return; + if (this._setAutomaticRoute_clickMoveDirectly(destX, destY, stepPostfix)) + return; + // 找寻自动寻路路线 + var moveStep = core.automaticRoute(destX, destY); + if ( + moveStep.length == 0 && + (destX != core.status.hero.loc.x || + destY != core.status.hero.loc.y || + stepPostfix.length == 0) + ) + return; + moveStep = moveStep.concat(stepPostfix); + core.status.automaticRoute.destX = destX; + core.status.automaticRoute.destY = destY; + this._setAutomaticRoute_drawRoute(moveStep); + this._setAutomaticRoute_setAutoSteps(moveStep); + // 立刻移动 + core.setAutoHeroMove(); +}; control.prototype._setAutomaticRoute_isMoving = function (destX, destY) { - if (core.status.automaticRoute.autoHeroMove) { - var lastX = core.status.automaticRoute.destX, lastY = core.status.automaticRoute.destY; - core.stopAutomaticRoute(); - // 双击瞬移 - if (lastX == destX && lastY == destY) { - core.status.automaticRoute.moveDirectly = true; - setTimeout(function () { - if (core.status.automaticRoute.moveDirectly && core.status.heroMoving == 0) { - core.control.tryMoveDirectly(destX, destY); - } - core.status.automaticRoute.moveDirectly = false; - }, core.values.moveSpeed); + if (core.status.automaticRoute.autoHeroMove) { + var lastX = core.status.automaticRoute.destX, + lastY = core.status.automaticRoute.destY; + core.stopAutomaticRoute(); + // 双击瞬移 + if (lastX == destX && lastY == destY) { + core.status.automaticRoute.moveDirectly = true; + setTimeout(function () { + if ( + core.status.automaticRoute.moveDirectly && + core.status.heroMoving == 0 + ) { + core.control.tryMoveDirectly(destX, destY); } - return true; + core.status.automaticRoute.moveDirectly = false; + }, core.values.moveSpeed); } - return false; -} + return true; + } + return false; +}; -control.prototype._setAutomaticRoute_isTurning = function (destX, destY, stepPostfix) { - if (destX == core.status.hero.loc.x && destY == core.status.hero.loc.y && stepPostfix.length == 0) { - if (core.timeout.turnHeroTimeout == null) { - var routeLength = core.status.route.length; - core.timeout.turnHeroTimeout = setTimeout(function () { - if (core.status.route.length == routeLength) core.turnHero(); - clearTimeout(core.timeout.turnHeroTimeout); - core.timeout.turnHeroTimeout = null; - }, 250); - } - else { - clearTimeout(core.timeout.turnHeroTimeout); - core.timeout.turnHeroTimeout = null; - core.getNextItem(); - } - return true; +control.prototype._setAutomaticRoute_isTurning = function ( + destX, + destY, + stepPostfix +) { + if ( + destX == core.status.hero.loc.x && + destY == core.status.hero.loc.y && + stepPostfix.length == 0 + ) { + if (core.timeout.turnHeroTimeout == null) { + var routeLength = core.status.route.length; + core.timeout.turnHeroTimeout = setTimeout(function () { + if (core.status.route.length == routeLength) core.turnHero(); + clearTimeout(core.timeout.turnHeroTimeout); + core.timeout.turnHeroTimeout = null; + }, 250); + } else { + clearTimeout(core.timeout.turnHeroTimeout); + core.timeout.turnHeroTimeout = null; + core.getNextItem(); } - if (core.timeout.turnHeroTimeout != null) return true; - return false; -} + return true; + } + if (core.timeout.turnHeroTimeout != null) return true; + return false; +}; -control.prototype._setAutomaticRoute_clickMoveDirectly = function (destX, destY, stepPostfix) { - // 单击瞬间移动 - if (core.status.heroStop && core.status.heroMoving == 0) { - if (stepPostfix.length <= 1 && !core.hasFlag('__noClickMove__') && core.control.tryMoveDirectly(destX, destY)) - return true; - } - return false; -} +control.prototype._setAutomaticRoute_clickMoveDirectly = function ( + destX, + destY, + stepPostfix +) { + // 单击瞬间移动 + if (core.status.heroStop && core.status.heroMoving == 0) { + if ( + stepPostfix.length <= 1 && + !core.hasFlag("__noClickMove__") && + core.control.tryMoveDirectly(destX, destY) + ) + return true; + } + return false; +}; control.prototype._setAutomaticRoute_drawRoute = function (moveStep) { - // 计算绘制区域的宽高,并尽可能小的创建route层 - var sx = core.bigmap.width * 32, sy = core.bigmap.height * 32, dx = 0, dy = 0; - moveStep.forEach(function (t) { - sx = Math.min(sx, t.x * 32); dx = Math.max(dx, t.x * 32); - sy = Math.min(sy, t.y * 32); dy = Math.max(dy, t.y * 32); - }); - core.status.automaticRoute.offsetX = sx; - core.status.automaticRoute.offsetY = sy; - var ctx = core.createCanvas('route', sx - core.bigmap.offsetX, sy - core.bigmap.offsetY, dx - sx + 32, dy - sy + 32, 95); - ctx.fillStyle = '#bfbfbf'; - ctx.strokeStyle = '#bfbfbf'; - ctx.lineWidth = 8; - for (var m = 0; m < moveStep.length; m++) { - if (m == moveStep.length - 1) { - ctx.fillRect(moveStep[m].x * 32 + 10 - sx, moveStep[m].y * 32 + 10 - sy, 12, 12); - } - else { - ctx.beginPath(); - var cx = moveStep[m].x * 32 + 16 - sx, cy = moveStep[m].y * 32 + 16 - sy; - var currDir = moveStep[m].direction, nextDir = moveStep[m + 1].direction; - ctx.moveTo(cx - core.utils.scan[currDir].x * 11, cy - core.utils.scan[currDir].y * 11); - ctx.lineTo(cx, cy); - ctx.lineTo(cx + core.utils.scan[nextDir].x * 11, cy + core.utils.scan[nextDir].y * 11); - ctx.stroke(); - } + // 计算绘制区域的宽高,并尽可能小的创建route层 + var sx = core.bigmap.width * 32, + sy = core.bigmap.height * 32, + dx = 0, + dy = 0; + moveStep.forEach(function (t) { + sx = Math.min(sx, t.x * 32); + dx = Math.max(dx, t.x * 32); + sy = Math.min(sy, t.y * 32); + dy = Math.max(dy, t.y * 32); + }); + core.status.automaticRoute.offsetX = sx; + core.status.automaticRoute.offsetY = sy; + var ctx = core.createCanvas( + "route", + sx - core.bigmap.offsetX, + sy - core.bigmap.offsetY, + dx - sx + 32, + dy - sy + 32, + 95 + ); + ctx.fillStyle = "#bfbfbf"; + ctx.strokeStyle = "#bfbfbf"; + ctx.lineWidth = 8; + for (var m = 0; m < moveStep.length; m++) { + if (m == moveStep.length - 1) { + ctx.fillRect( + moveStep[m].x * 32 + 10 - sx, + moveStep[m].y * 32 + 10 - sy, + 12, + 12 + ); + } else { + ctx.beginPath(); + var cx = moveStep[m].x * 32 + 16 - sx, + cy = moveStep[m].y * 32 + 16 - sy; + var currDir = moveStep[m].direction, + nextDir = moveStep[m + 1].direction; + ctx.moveTo( + cx - core.utils.scan[currDir].x * 11, + cy - core.utils.scan[currDir].y * 11 + ); + ctx.lineTo(cx, cy); + ctx.lineTo( + cx + core.utils.scan[nextDir].x * 11, + cy + core.utils.scan[nextDir].y * 11 + ); + ctx.stroke(); } -} + } +}; control.prototype._setAutomaticRoute_setAutoSteps = function (moveStep) { - // 路线转autoStepRoutes - var step = 0, currStep = null; - moveStep.forEach(function (t) { - var dir = t.direction; - if (currStep == null || currStep == dir) - step++; - else { - core.status.automaticRoute.autoStepRoutes.push({ 'direction': currStep, 'step': step }); - step = 1; - } - currStep = dir; - }); - core.status.automaticRoute.autoStepRoutes.push({ 'direction': currStep, 'step': step }); -} + // 路线转autoStepRoutes + var step = 0, + currStep = null; + moveStep.forEach(function (t) { + var dir = t.direction; + if (currStep == null || currStep == dir) step++; + else { + core.status.automaticRoute.autoStepRoutes.push({ + direction: currStep, + step: step, + }); + step = 1; + } + currStep = dir; + }); + core.status.automaticRoute.autoStepRoutes.push({ + direction: currStep, + step: step, + }); +}; ////// 设置勇士的自动行走路线 ////// control.prototype.setAutoHeroMove = function (steps) { - steps = steps || core.status.automaticRoute.autoStepRoutes; - if (steps.length == 0) return; - core.status.automaticRoute.autoStepRoutes = steps; - core.status.automaticRoute.autoHeroMove = true; - core.status.automaticRoute.autoStep = 1; - core.status.automaticRoute.destStep = steps[0].step; - core.moveHero(steps[0].direction); -} + steps = steps || core.status.automaticRoute.autoStepRoutes; + if (steps.length == 0) return; + core.status.automaticRoute.autoStepRoutes = steps; + core.status.automaticRoute.autoHeroMove = true; + core.status.automaticRoute.autoStep = 1; + core.status.automaticRoute.destStep = steps[0].step; + core.moveHero(steps[0].direction); +}; ////// 设置行走的效果动画 ////// control.prototype.setHeroMoveInterval = function (callback) { - if (core.status.heroMoving > 0) return; - if (core.status.replay.speed == 24) { - if (callback) callback(); - return; + if (core.status.heroMoving > 0) return; + if (core.status.replay.speed == 24) { + if (callback) callback(); + return; + } + + core.status.heroMoving = 1; + + var toAdd = 1; + if (core.status.replay.speed > 3) toAdd = 2; + if (core.status.replay.speed > 6) toAdd = 4; + if (core.status.replay.speed > 12) toAdd = 8; + + core.interval.heroMoveInterval = window.setInterval(function () { + core.status.heroMoving += toAdd; + if (core.status.heroMoving >= 8) { + clearInterval(core.interval.heroMoveInterval); + core.status.heroMoving = 0; + if (callback) callback(); } - - core.status.heroMoving = 1; - - var toAdd = 1; - if (core.status.replay.speed > 3) toAdd = 2; - if (core.status.replay.speed > 6) toAdd = 4; - if (core.status.replay.speed > 12) toAdd = 8; - - core.interval.heroMoveInterval = window.setInterval(function () { - core.status.heroMoving += toAdd; - if (core.status.heroMoving >= 8) { - clearInterval(core.interval.heroMoveInterval); - core.status.heroMoving = 0; - if (callback) callback(); - } - }, core.values.moveSpeed / 8 * toAdd / core.status.replay.speed); -} + }, ((core.values.moveSpeed / 8) * toAdd) / core.status.replay.speed); +}; ////// 每移动一格后执行的事件 ////// control.prototype.moveOneStep = function (callback) { - return this.controldata.moveOneStep(callback); -} + return this.controldata.moveOneStep(callback); +}; ////// 实际每一步的行走过程 ////// control.prototype.moveAction = function (callback) { - if (core.status.heroMoving > 0) return; - var noPass = core.noPass(core.nextX(), core.nextY()), canMove = core.canMoveHero(); - // 下一个点如果不能走 - if (noPass || !canMove) return this._moveAction_noPass(canMove, callback); - this._moveAction_moving(callback); -} + if (core.status.heroMoving > 0) return; + var noPass = core.noPass(core.nextX(), core.nextY()), + canMove = core.canMoveHero(); + // 下一个点如果不能走 + if (noPass || !canMove) return this._moveAction_noPass(canMove, callback); + this._moveAction_moving(callback); +}; control.prototype._moveAction_noPass = function (canMove, callback) { - core.status.route.push(core.getHeroLoc('direction')); - core.status.automaticRoute.moveStepBeforeStop = []; - core.status.automaticRoute.lastDirection = core.getHeroLoc('direction'); - if (canMove) core.trigger(core.nextX(), core.nextY()); - core.drawHero(); + core.status.route.push(core.getHeroLoc("direction")); + core.status.automaticRoute.moveStepBeforeStop = []; + core.status.automaticRoute.lastDirection = core.getHeroLoc("direction"); + if (canMove) core.trigger(core.nextX(), core.nextY()); + core.drawHero(); - if (core.status.automaticRoute.moveStepBeforeStop.length == 0) { - core.clearContinueAutomaticRoute(); - core.stopAutomaticRoute(); - } - if (callback) callback(); -} + if (core.status.automaticRoute.moveStepBeforeStop.length == 0) { + core.clearContinueAutomaticRoute(); + core.stopAutomaticRoute(); + } + if (callback) callback(); +}; control.prototype._moveAction_moving = function (callback) { - core.setHeroMoveInterval(function () { - core.setHeroLoc('x', core.nextX(), true); - core.setHeroLoc('y', core.nextY(), true); + core.setHeroMoveInterval(function () { + core.setHeroLoc("x", core.nextX(), true); + core.setHeroLoc("y", core.nextY(), true); - var direction = core.getHeroLoc('direction'); - core.control._moveAction_popAutomaticRoute(); - core.status.route.push(direction); + var direction = core.getHeroLoc("direction"); + core.control._moveAction_popAutomaticRoute(); + core.status.route.push(direction); - core.moveOneStep(); - core.checkRouteFolding(); - if (callback) callback(); - }); -} + core.moveOneStep(); + core.checkRouteFolding(); + if (callback) callback(); + }); +}; control.prototype._moveAction_popAutomaticRoute = function () { - var automaticRoute = core.status.automaticRoute; - // 检查自动寻路是否被弹出 - if (automaticRoute.autoHeroMove) { - automaticRoute.movedStep++; - automaticRoute.lastDirection = core.getHeroLoc('direction'); - if (automaticRoute.destStep == automaticRoute.movedStep) { - if (automaticRoute.autoStep == automaticRoute.autoStepRoutes.length) { - core.clearContinueAutomaticRoute(); - core.stopAutomaticRoute(); - } - else { - automaticRoute.movedStep = 0; - automaticRoute.destStep = automaticRoute.autoStepRoutes[automaticRoute.autoStep].step; - core.setHeroLoc('direction', automaticRoute.autoStepRoutes[automaticRoute.autoStep].direction); - core.status.automaticRoute.autoStep++; - } - } + var automaticRoute = core.status.automaticRoute; + // 检查自动寻路是否被弹出 + if (automaticRoute.autoHeroMove) { + automaticRoute.movedStep++; + automaticRoute.lastDirection = core.getHeroLoc("direction"); + if (automaticRoute.destStep == automaticRoute.movedStep) { + if (automaticRoute.autoStep == automaticRoute.autoStepRoutes.length) { + core.clearContinueAutomaticRoute(); + core.stopAutomaticRoute(); + } else { + automaticRoute.movedStep = 0; + automaticRoute.destStep = + automaticRoute.autoStepRoutes[automaticRoute.autoStep].step; + core.setHeroLoc( + "direction", + automaticRoute.autoStepRoutes[automaticRoute.autoStep].direction + ); + core.status.automaticRoute.autoStep++; + } } -} + } +}; ////// 让勇士开始移动 ////// control.prototype.moveHero = function (direction, callback) { - // 如果正在移动,直接return - if (core.status.heroMoving != 0) return; - if (core.isset(direction)) - core.setHeroLoc('direction', direction); + // 如果正在移动,直接return + if (core.status.heroMoving != 0) return; + if (core.isset(direction)) core.setHeroLoc("direction", direction); - if (callback) return this.moveAction(callback); - this._moveHero_moving(); -} + if (callback) return this.moveAction(callback); + this._moveHero_moving(); +}; control.prototype._moveHero_moving = function () { - // ------ 我已经看不懂这个函数了,反正好用就行23333333 - core.status.heroStop = false; - core.status.automaticRoute.moveDirectly = false; - var move = function () { - if (!core.status.heroStop) { - if (core.hasFlag('debug') && core.status.ctrlDown) { - if (core.status.heroMoving != 0) return; - // 检测是否穿出去 - var nx = core.nextX(), ny = core.nextY(); - if (nx < 0 || nx >= core.bigmap.width || ny < 0 || ny >= core.bigmap.height) return; - core.eventMoveHero([core.getHeroLoc('direction')], core.values.moveSpeed, move); - } - else { - core.moveAction(); - setTimeout(move, 50); - } - } + // ------ 我已经看不懂这个函数了,反正好用就行23333333 + core.status.heroStop = false; + core.status.automaticRoute.moveDirectly = false; + var move = function () { + if (!core.status.heroStop) { + if (core.hasFlag("debug") && core.status.ctrlDown) { + if (core.status.heroMoving != 0) return; + // 检测是否穿出去 + var nx = core.nextX(), + ny = core.nextY(); + if ( + nx < 0 || + nx >= core.bigmap.width || + ny < 0 || + ny >= core.bigmap.height + ) + return; + core.eventMoveHero( + [core.getHeroLoc("direction")], + core.values.moveSpeed, + move + ); + } else { + core.moveAction(); + setTimeout(move, 50); + } } - move(); -} + }; + move(); +}; ////// 当前是否正在移动 ////// control.prototype.isMoving = function () { - return !core.status.heroStop || core.status.heroMoving > 0; -} + return !core.status.heroStop || core.status.heroMoving > 0; +}; ////// 停止勇士的一切行动,等待勇士行动结束后,再执行callback ////// control.prototype.waitHeroToStop = function (callback) { - var lastDirection = core.status.automaticRoute.lastDirection; - core.stopAutomaticRoute(); - core.clearContinueAutomaticRoute(); - if (callback) { - core.status.replay.animate = true; - core.lockControl(); - core.status.automaticRoute.moveDirectly = false; - setTimeout(function () { - core.status.replay.animate = false; - if (core.isset(lastDirection)) - core.setHeroLoc('direction', lastDirection); - core.drawHero(); - callback(); - }, core.status.replay.speed == 24 ? 1 : 30); - } -} + var lastDirection = core.status.automaticRoute.lastDirection; + core.stopAutomaticRoute(); + core.clearContinueAutomaticRoute(); + if (callback) { + core.status.replay.animate = true; + core.lockControl(); + core.status.automaticRoute.moveDirectly = false; + setTimeout( + function () { + core.status.replay.animate = false; + if (core.isset(lastDirection)) + core.setHeroLoc("direction", lastDirection); + core.drawHero(); + callback(); + }, + core.status.replay.speed == 24 ? 1 : 30 + ); + } +}; ////// 转向 ////// control.prototype.turnHero = function (direction) { - if (direction) { - core.setHeroLoc('direction', direction); - core.drawHero(); - core.status.route.push("turn:" + direction); - return; - } - core.setHeroLoc('direction', core.turnDirection(':right')); + if (direction) { + core.setHeroLoc("direction", direction); core.drawHero(); - core.status.route.push("turn"); - core.checkRouteFolding(); -} + core.status.route.push("turn:" + direction); + return; + } + core.setHeroLoc("direction", core.turnDirection(":right")); + core.drawHero(); + core.status.route.push("turn"); + core.checkRouteFolding(); +}; ////// 瞬间移动 ////// control.prototype.moveDirectly = function (destX, destY, ignoreSteps) { - return this.controldata.moveDirectly(destX, destY, ignoreSteps); -} + return this.controldata.moveDirectly(destX, destY, ignoreSteps); +}; ////// 尝试瞬间移动 ////// control.prototype.tryMoveDirectly = function (destX, destY) { - if (this.nearHero(destX, destY)) return false; - var canMoveArray = core.maps.generateMovableArray(); - var dirs = [[destX, destY], [destX - 1, destY, "right"], [destX, destY - 1, "down"], [destX, destY + 1, "up"], [destX + 1, destY, "left"]]; - var canMoveDirectlyArray = core.canMoveDirectlyArray(dirs, canMoveArray); + if (this.nearHero(destX, destY)) return false; + var canMoveArray = core.maps.generateMovableArray(); + var dirs = [ + [destX, destY], + [destX - 1, destY, "right"], + [destX, destY - 1, "down"], + [destX, destY + 1, "up"], + [destX + 1, destY, "left"], + ]; + var canMoveDirectlyArray = core.canMoveDirectlyArray(dirs, canMoveArray); - for (var i = 0; i < dirs.length; ++i) { - var d = dirs[i], dx = d[0], dy = d[1], dir = d[2]; - if (dx < 0 || dx >= core.bigmap.width || dy < 0 || dy >= core.bigmap.height) continue; - if (dir && !core.inArray(canMoveArray[dx][dy], dir)) continue; - if (canMoveDirectlyArray[i] < 0) continue; - if (core.control.moveDirectly(dx, dy, canMoveDirectlyArray[i])) { - if (dir) core.moveHero(dir, function () { }); - return true; - } + for (var i = 0; i < dirs.length; ++i) { + var d = dirs[i], + dx = d[0], + dy = d[1], + dir = d[2]; + if (dx < 0 || dx >= core.bigmap.width || dy < 0 || dy >= core.bigmap.height) + continue; + if (dir && !core.inArray(canMoveArray[dx][dy], dir)) continue; + if (canMoveDirectlyArray[i] < 0) continue; + if (core.control.moveDirectly(dx, dy, canMoveDirectlyArray[i])) { + if (dir) core.moveHero(dir, function () {}); + return true; } - return false; -} + } + return false; +}; ////// 绘制勇士 ////// control.prototype.drawHero = function (status, offset, frame) { - if (!core.isPlaying() || !core.status.floorId || core.status.gameOver) return; - var x = core.getHeroLoc('x'), y = core.getHeroLoc('y'), direction = core.getHeroLoc('direction'); - status = status || 'stop'; - if (!offset) offset = 0; + if (!core.isPlaying() || !core.status.floorId || core.status.gameOver) return; + var x = core.getHeroLoc("x"), + y = core.getHeroLoc("y"), + direction = core.getHeroLoc("direction"); + status = status || "stop"; + if (!offset) offset = 0; - var way = core.utils.scan2[direction]; - var dx = way.x, dy = way.y; - var offsetX = typeof offset == 'number' ? dx * offset : (offset.x || 0); - var offsetY = typeof offset == 'number' ? dy * offset : (offset.y || 0); - offset = { x: offsetX, y: offsetY, offset: offset }; + var way = core.utils.scan2[direction]; + var dx = way.x, + dy = way.y; + var offsetX = typeof offset == "number" ? dx * offset : offset.x || 0; + var offsetY = typeof offset == "number" ? dy * offset : offset.y || 0; + offset = { x: offsetX, y: offsetY, offset: offset }; - core.clearAutomaticRouteNode(x + dx, y + dy); - core.clearMap('hero'); - core.status.heroCenter.px = 32 * x + offsetX + 16; - core.status.heroCenter.py = 32 * y + offsetY + 32 - core.material.icons.hero.height / 2; + core.clearAutomaticRouteNode(x + dx, y + dy); + core.clearMap("hero"); + core.status.heroCenter.px = 32 * x + offsetX + 16; + core.status.heroCenter.py = + 32 * y + offsetY + 32 - core.material.icons.hero.height / 2; - // 重置hero层画布 - core.setGameCanvasTranslate('hero', 0, 0); - delete core.canvas.hero._px; - delete core.canvas.hero._py; - core.status.preview.enabled = false; - if (!core.hasFlag('__lockViewport__')) { - this._drawHero_updateViewport(x, y, offset); - } + // 重置hero层画布 + core.setGameCanvasTranslate("hero", 0, 0); + delete core.canvas.hero._px; + delete core.canvas.hero._py; + core.status.preview.enabled = false; + if (!core.hasFlag("__lockViewport__")) { + this._drawHero_updateViewport(x, y, offset); + } - this._drawHero_draw(direction, x, y, status, offset, frame); -} + this._drawHero_draw(direction, x, y, status, offset, frame); +}; control.prototype._drawHero_updateViewport = function (x, y, offset) { - core.bigmap.offsetX = core.clamp((x - core._HALF_WIDTH_) * 32 + offset.x, 0, Math.max(32 * core.bigmap.width - core._PX_, 0)); - core.bigmap.offsetY = core.clamp((y - core._HALF_HEIGHT_) * 32 + offset.y, 0, Math.max(32 * core.bigmap.height - core._PY_, 0)); - core.control.updateViewport(); -} + core.bigmap.offsetX = core.clamp( + (x - core._HALF_WIDTH_) * 32 + offset.x, + 0, + Math.max(32 * core.bigmap.width - core._PX_, 0) + ); + core.bigmap.offsetY = core.clamp( + (y - core._HALF_HEIGHT_) * 32 + offset.y, + 0, + Math.max(32 * core.bigmap.height - core._PY_, 0) + ); + core.control.updateViewport(); +}; -control.prototype._drawHero_draw = function (direction, x, y, status, offset, frame) { - offset = offset || { x: 0, y: 0, offset: 0, px: 0, py: 0 }; - var opacity = core.setAlpha('hero', core.getFlag('__heroOpacity__', 1)) - this._drawHero_getDrawObjs(direction, x, y, status, offset).forEach(function (block) { - core.drawImage('hero', block.img, (block.heroIcon[block.status] + (frame || 0)) % 4 * block.width, - block.heroIcon.loc * block.height, block.width, block.height, - block.posx + (32 - block.width) / 2, block.posy + 32 - block.height, block.width, block.height); - }); - core.setAlpha('hero', opacity); -} +control.prototype._drawHero_draw = function ( + direction, + x, + y, + status, + offset, + frame +) { + offset = offset || { x: 0, y: 0, offset: 0, px: 0, py: 0 }; + var opacity = core.setAlpha("hero", core.getFlag("__heroOpacity__", 1)); + this._drawHero_getDrawObjs(direction, x, y, status, offset).forEach(function ( + block + ) { + core.drawImage( + "hero", + block.img, + ((block.heroIcon[block.status] + (frame || 0)) % 4) * block.width, + block.heroIcon.loc * block.height, + block.width, + block.height, + block.posx + (32 - block.width) / 2, + block.posy + 32 - block.height, + block.width, + block.height + ); + }); + core.setAlpha("hero", opacity); +}; -control.prototype._drawHero_getDrawObjs = function (direction, x, y, status, offset) { - var heroIconArr = core.material.icons.hero, drawObjs = [], index = 0; - drawObjs.push({ - "img": core.material.images.hero, - "width": core.material.icons.hero.width || 32, - "height": core.material.icons.hero.height, - "heroIcon": heroIconArr[direction], - "posx": x * 32 - core.bigmap.offsetX + offset.x, - "posy": y * 32 - core.bigmap.offsetY + offset.y, - "status": status, - "index": index++, +control.prototype._drawHero_getDrawObjs = function ( + direction, + x, + y, + status, + offset +) { + var heroIconArr = core.material.icons.hero, + drawObjs = [], + index = 0; + drawObjs.push({ + img: core.material.images.hero, + width: core.material.icons.hero.width || 32, + height: core.material.icons.hero.height, + heroIcon: heroIconArr[direction], + posx: x * 32 - core.bigmap.offsetX + offset.x, + posy: y * 32 - core.bigmap.offsetY + offset.y, + status: status, + index: index++, + }); + if (typeof offset.offset == "number") { + core.status.hero.followers.forEach(function (t) { + drawObjs.push({ + img: core.material.images.images[t.name], + width: core.material.images.images[t.name].width / 4, + height: core.material.images.images[t.name].height / 4, + heroIcon: heroIconArr[t.direction], + posx: + 32 * t.x - + core.bigmap.offsetX + + (t.stop + ? 0 + : core.utils.scan2[t.direction].x * Math.abs(offset.offset)), + posy: + 32 * t.y - + core.bigmap.offsetY + + (t.stop + ? 0 + : core.utils.scan2[t.direction].y * Math.abs(offset.offset)), + status: t.stop ? "stop" : status, + index: index++, + }); }); - if (typeof offset.offset == 'number') { - core.status.hero.followers.forEach(function (t) { - drawObjs.push({ - "img": core.material.images.images[t.name], - "width": core.material.images.images[t.name].width / 4, - "height": core.material.images.images[t.name].height / 4, - "heroIcon": heroIconArr[t.direction], - "posx": 32 * t.x - core.bigmap.offsetX + (t.stop ? 0 : core.utils.scan2[t.direction].x * Math.abs(offset.offset)), - "posy": 32 * t.y - core.bigmap.offsetY + (t.stop ? 0 : core.utils.scan2[t.direction].y * Math.abs(offset.offset)), - "status": t.stop ? "stop" : status, - "index": index++ - }); - }); + } + return drawObjs.sort(function (a, b) { + return a.posy == b.posy ? b.index - a.index : a.posy - b.posy; + }); +}; + +control.prototype.setHeroOpacity = function ( + opacity, + moveMode, + time, + callback +) { + time = time || 0; + if (time == 0) { + core.setFlag("__heroOpacity__", opacity); + core.drawHero(); + if (callback) callback(); + return; + } + time /= Math.max(core.status.replay.speed, 1); + + var fromOpacity = core.getFlag("__heroOpacity__", 1); + var step = 0, + steps = parseInt(time / 10); + if (steps <= 0) steps = 1; + var moveFunc = core.applyEasing(moveMode); + + var animate = setInterval(function () { + step++; + core.setFlag( + "__heroOpacity__", + fromOpacity + (opacity - fromOpacity) * moveFunc(step / steps) + ); + core.drawHero(); + if (step == steps) { + delete core.animateFrame.asyncId[animate]; + clearInterval(animate); + if (callback) callback(); } - return drawObjs.sort(function (a, b) { - return a.posy == b.posy ? b.index - a.index : a.posy - b.posy; - }); -} + }, 10); -control.prototype.setHeroOpacity = function (opacity, moveMode, time, callback) { - time = time || 0; - if (time == 0) { - core.setFlag('__heroOpacity__', opacity); - core.drawHero(); - if (callback) callback(); - return; - } - time /= Math.max(core.status.replay.speed, 1) - - var fromOpacity = core.getFlag('__heroOpacity__', 1); - var step = 0, steps = parseInt(time / 10); - if (steps <= 0) steps = 1; - var moveFunc = core.applyEasing(moveMode); - - var animate = setInterval(function () { - step++; - core.setFlag('__heroOpacity__', fromOpacity + (opacity - fromOpacity) * moveFunc(step / steps)); - core.drawHero(); - if (step == steps) { - delete core.animateFrame.asyncId[animate]; - clearInterval(animate); - if (callback) callback(); - } - }, 10); - - core.animateFrame.lastAsyncId = animate; - core.animateFrame.asyncId[animate] = callback; -} + core.animateFrame.lastAsyncId = animate; + core.animateFrame.asyncId[animate] = callback; +}; // ------ 画布、位置、阻激夹域,显伤 ------ // ////// 设置画布偏移 control.prototype.setGameCanvasTranslate = function (canvas, x, y) { - var c = core.dom.gameCanvas[canvas]; - x = x * core.domStyle.scale; - y = y * core.domStyle.scale; - c.style.transform = 'translate(' + x + 'px,' + y + 'px)'; - c.style.webkitTransform = 'translate(' + x + 'px,' + y + 'px)'; - c.style.OTransform = 'translate(' + x + 'px,' + y + 'px)'; - c.style.MozTransform = 'translate(' + x + 'px,' + y + 'px)'; - if (main.mode === 'editor' && editor.isMobile) { - c.style.transform = 'translate(' + (x / core._PX_ * 96) + 'vw,' + (y / core._PY_ * 96) + 'vw)'; - c.style.webkitTransform = 'translate(' + (x / core._PX_ * 96) + 'vw,' + (y / core._PY_ * 96) + 'vw)'; - c.style.OTransform = 'translate(' + (x / core._PX_ * 96) + 'vw,' + (y / core._PY_ * 96) + 'vw)'; - c.style.MozTransform = 'translate(' + (x / core._PX_ * 96) + 'vw,' + (y / core._PY_ * 96) + 'vw)'; - } + var c = core.dom.gameCanvas[canvas]; + x = x * core.domStyle.scale; + y = y * core.domStyle.scale; + c.style.transform = "translate(" + x + "px," + y + "px)"; + c.style.webkitTransform = "translate(" + x + "px," + y + "px)"; + c.style.OTransform = "translate(" + x + "px," + y + "px)"; + c.style.MozTransform = "translate(" + x + "px," + y + "px)"; + if (main.mode === "editor" && editor.isMobile) { + c.style.transform = + "translate(" + + (x / core._PX_) * 96 + + "vw," + + (y / core._PY_) * 96 + + "vw)"; + c.style.webkitTransform = + "translate(" + + (x / core._PX_) * 96 + + "vw," + + (y / core._PY_) * 96 + + "vw)"; + c.style.OTransform = + "translate(" + + (x / core._PX_) * 96 + + "vw," + + (y / core._PY_) * 96 + + "vw)"; + c.style.MozTransform = + "translate(" + + (x / core._PX_) * 96 + + "vw," + + (y / core._PY_) * 96 + + "vw)"; + } }; ////// 加减画布偏移 control.prototype.addGameCanvasTranslate = function (x, y) { - for (var ii = 0, canvas; canvas = core.dom.gameCanvas[ii]; ii++) { - var id = canvas.getAttribute('id'); - if (id == 'ui' || id == 'data') continue; // UI层和data层不移动 - var offsetX = x, offsetY = y; - if (core.bigmap.canvas.indexOf(id) >= 0) { - if (core.bigmap.v2) { - offsetX -= (core.bigmap.offsetX - 32 * core.bigmap.posX) + 32; - offsetY -= (core.bigmap.offsetY - 32 * core.bigmap.posY) + 32; - } else { - offsetX -= core.bigmap.offsetX; - offsetY -= core.bigmap.offsetY; - } - } - core.control.setGameCanvasTranslate(id, offsetX, offsetY); + for (var ii = 0, canvas; (canvas = core.dom.gameCanvas[ii]); ii++) { + var id = canvas.getAttribute("id"); + if (id == "ui" || id == "data") continue; // UI层和data层不移动 + var offsetX = x, + offsetY = y; + if (core.bigmap.canvas.indexOf(id) >= 0) { + if (core.bigmap.v2) { + offsetX -= core.bigmap.offsetX - 32 * core.bigmap.posX + 32; + offsetY -= core.bigmap.offsetY - 32 * core.bigmap.posY + 32; + } else { + offsetX -= core.bigmap.offsetX; + offsetY -= core.bigmap.offsetY; + } } -} + core.control.setGameCanvasTranslate(id, offsetX, offsetY); + } +}; ////// 更新视野范围 ////// control.prototype.updateViewport = function () { - // 当前是否应该重绘? - if (core.bigmap.v2) { - if (core.bigmap.offsetX >= core.bigmap.posX * 32 + 32 - || core.bigmap.offsetX <= core.bigmap.posX * 32 - 32 - || core.bigmap.offsetY >= core.bigmap.posY * 32 + 32 - || core.bigmap.offsetY <= core.bigmap.posY * 32 - 32) { - core.bigmap.posX = parseInt(core.bigmap.offsetX / 32); - core.bigmap.posY = parseInt(core.bigmap.offsetY / 32); - core.redrawMap(); - } - } else { - core.bigmap.posX = core.bigmap.posY = 0; + // 当前是否应该重绘? + if (core.bigmap.v2) { + if ( + core.bigmap.offsetX >= core.bigmap.posX * 32 + 32 || + core.bigmap.offsetX <= core.bigmap.posX * 32 - 32 || + core.bigmap.offsetY >= core.bigmap.posY * 32 + 32 || + core.bigmap.offsetY <= core.bigmap.posY * 32 - 32 + ) { + core.bigmap.posX = parseInt(core.bigmap.offsetX / 32); + core.bigmap.posY = parseInt(core.bigmap.offsetY / 32); + core.redrawMap(); } - var offsetX = core.bigmap.v2 ? -(core.bigmap.offsetX - 32 * core.bigmap.posX) - 32 : -core.bigmap.offsetX; - var offsetY = core.bigmap.v2 ? -(core.bigmap.offsetY - 32 * core.bigmap.posY) - 32 : -core.bigmap.offsetY; + } else { + core.bigmap.posX = core.bigmap.posY = 0; + } + var offsetX = core.bigmap.v2 + ? -(core.bigmap.offsetX - 32 * core.bigmap.posX) - 32 + : -core.bigmap.offsetX; + var offsetY = core.bigmap.v2 + ? -(core.bigmap.offsetY - 32 * core.bigmap.posY) - 32 + : -core.bigmap.offsetY; - core.bigmap.canvas.forEach(function (cn) { - core.control.setGameCanvasTranslate(cn, offsetX, offsetY); - }); - // ------ 路线 - core.relocateCanvas('route', core.status.automaticRoute.offsetX - core.bigmap.offsetX, core.status.automaticRoute.offsetY - core.bigmap.offsetY); - // ------ 所有的大怪物也都需要重定位 - for (var one in core.dymCanvas) { - if (one.startsWith('_bigImage_')) { - var ox = core.dymCanvas[one].canvas.getAttribute('_ox'); - var oy = core.dymCanvas[one].canvas.getAttribute('_oy'); - if (ox != null && oy != null) { - core.relocateCanvas(one, parseInt(ox) - core.bigmap.offsetX, parseInt(oy) - core.bigmap.offsetY); - } - } + core.bigmap.canvas.forEach(function (cn) { + core.control.setGameCanvasTranslate(cn, offsetX, offsetY); + }); + // ------ 路线 + core.relocateCanvas( + "route", + core.status.automaticRoute.offsetX - core.bigmap.offsetX, + core.status.automaticRoute.offsetY - core.bigmap.offsetY + ); + // ------ 所有的大怪物也都需要重定位 + for (var one in core.dymCanvas) { + if (one.startsWith("_bigImage_")) { + var ox = core.dymCanvas[one].canvas.getAttribute("_ox"); + var oy = core.dymCanvas[one].canvas.getAttribute("_oy"); + if (ox != null && oy != null) { + core.relocateCanvas( + one, + parseInt(ox) - core.bigmap.offsetX, + parseInt(oy) - core.bigmap.offsetY + ); + } } - -} + } +}; ////// 设置视野范围 ////// control.prototype.setViewport = function (px, py) { - var originOffsetX = core.bigmap.offsetX, originOffsetY = core.bigmap.offsetY; - core.bigmap.offsetX = core.clamp(px, 0, 32 * core.bigmap.width - core._PX_); - core.bigmap.offsetY = core.clamp(py, 0, 32 * core.bigmap.height - core._PY_); - this.updateViewport(); - // ------ hero层也需要! - var px = parseFloat(core.canvas.hero._px) || 0; - var py = parseFloat(core.canvas.hero._py) || 0; - px += originOffsetX - core.bigmap.offsetX; - py += originOffsetY - core.bigmap.offsetY; - core.control.setGameCanvasTranslate('hero', px, py); - core.canvas.hero._px = px; - core.canvas.hero._py = py; -} + var originOffsetX = core.bigmap.offsetX, + originOffsetY = core.bigmap.offsetY; + core.bigmap.offsetX = core.clamp(px, 0, 32 * core.bigmap.width - core._PX_); + core.bigmap.offsetY = core.clamp(py, 0, 32 * core.bigmap.height - core._PY_); + this.updateViewport(); + // ------ hero层也需要! + var px = parseFloat(core.canvas.hero._px) || 0; + var py = parseFloat(core.canvas.hero._py) || 0; + px += originOffsetX - core.bigmap.offsetX; + py += originOffsetY - core.bigmap.offsetY; + core.control.setGameCanvasTranslate("hero", px, py); + core.canvas.hero._px = px; + core.canvas.hero._py = py; +}; ////// 移动视野范围 ////// control.prototype.moveViewport = function (x, y, moveMode, time, callback) { - time = time || 0; - time /= Math.max(core.status.replay.speed, 1) - var per_time = 10, step = 0, steps = parseInt(time / per_time); - if (steps <= 0) { - this.setViewport(32 * x, 32 * y); - if (callback) callback(); - return; + time = time || 0; + time /= Math.max(core.status.replay.speed, 1); + var per_time = 10, + step = 0, + steps = parseInt(time / per_time); + if (steps <= 0) { + this.setViewport(32 * x, 32 * y); + if (callback) callback(); + return; + } + var px = core.clamp(32 * x, 0, 32 * core.bigmap.width - core._PX_); + var py = core.clamp(32 * y, 0, 32 * core.bigmap.height - core._PY_); + var cx = core.bigmap.offsetX; + var cy = core.bigmap.offsetY; + var moveFunc = core.applyEasing(moveMode); + + var animate = window.setInterval(function () { + step++; + core.setViewport( + cx + moveFunc(step / steps) * (px - cx), + cy + moveFunc(step / steps) * (py - cy) + ); + if (step == steps) { + delete core.animateFrame.asyncId[animate]; + clearInterval(animate); + core.setViewport(px, py); + if (callback) callback(); } - var px = core.clamp(32 * x, 0, 32 * core.bigmap.width - core._PX_); - var py = core.clamp(32 * y, 0, 32 * core.bigmap.height - core._PY_); - var cx = core.bigmap.offsetX; - var cy = core.bigmap.offsetY; - var moveFunc = core.applyEasing(moveMode); + }, per_time); - var animate = window.setInterval(function () { - step++; - core.setViewport(cx + moveFunc(step / steps) * (px - cx), cy + moveFunc(step / steps) * (py - cy)); - if (step == steps) { - delete core.animateFrame.asyncId[animate]; - clearInterval(animate); - core.setViewport(px, py); - if (callback) callback(); - } - }, per_time); - - core.animateFrame.lastAsyncId = animate; - core.animateFrame.asyncId[animate] = callback; -} + core.animateFrame.lastAsyncId = animate; + core.animateFrame.asyncId[animate] = callback; +}; ////// 获得勇士面对位置的x坐标 ////// control.prototype.nextX = function (n) { - if (n == null) n = 1; - return core.getHeroLoc('x') + core.utils.scan[core.getHeroLoc('direction')].x * n; -} + if (n == null) n = 1; + return ( + core.getHeroLoc("x") + core.utils.scan[core.getHeroLoc("direction")].x * n + ); +}; ////// 获得勇士面对位置的y坐标 ////// control.prototype.nextY = function (n) { - if (n == null) n = 1; - return core.getHeroLoc('y') + core.utils.scan[core.getHeroLoc('direction')].y * n; -} + if (n == null) n = 1; + return ( + core.getHeroLoc("y") + core.utils.scan[core.getHeroLoc("direction")].y * n + ); +}; ////// 某个点是否在勇士旁边 ////// control.prototype.nearHero = function (x, y, n) { - if (n == null) n = 1; - return Math.abs(x - core.getHeroLoc('x')) + Math.abs(y - core.getHeroLoc('y')) <= n; -} + if (n == null) n = 1; + return ( + Math.abs(x - core.getHeroLoc("x")) + Math.abs(y - core.getHeroLoc("y")) <= n + ); +}; ////// 聚集跟随者 ////// control.prototype.gatherFollowers = function () { - var x = core.getHeroLoc('x'), y = core.getHeroLoc('y'), dir = core.getHeroLoc('direction'); - core.status.hero.followers.forEach(function (t) { - t.x = x; - t.y = y; - t.stop = true; - t.direction = dir; - }); -} + var x = core.getHeroLoc("x"), + y = core.getHeroLoc("y"), + dir = core.getHeroLoc("direction"); + core.status.hero.followers.forEach(function (t) { + t.x = x; + t.y = y; + t.stop = true; + t.direction = dir; + }); +}; ////// 更新跟随者坐标 ////// control.prototype.updateFollowers = function () { - core.status.hero.followers.forEach(function (t) { - if (!t.stop) { - t.x += core.utils.scan2[t.direction].x; - t.y += core.utils.scan2[t.direction].y; - } - }) + core.status.hero.followers.forEach(function (t) { + if (!t.stop) { + t.x += core.utils.scan2[t.direction].x; + t.y += core.utils.scan2[t.direction].y; + } + }); - var nowx = core.getHeroLoc('x'), nowy = core.getHeroLoc('y'); - core.status.hero.followers.forEach(function (t) { - t.stop = true; - var dx = nowx - t.x, dy = nowy - t.y; - for (var dir in core.utils.scan2) { - if (core.utils.scan2[dir].x == dx && core.utils.scan2[dir].y == dy) { - t.stop = false; - t.direction = dir; - } - } - nowx = t.x; nowy = t.y; - }) -} + var nowx = core.getHeroLoc("x"), + nowy = core.getHeroLoc("y"); + core.status.hero.followers.forEach(function (t) { + t.stop = true; + var dx = nowx - t.x, + dy = nowy - t.y; + for (var dir in core.utils.scan2) { + if (core.utils.scan2[dir].x == dx && core.utils.scan2[dir].y == dy) { + t.stop = false; + t.direction = dir; + } + } + nowx = t.x; + nowy = t.y; + }); +}; ////// 瞬移更新跟随者坐标 ////// control.prototype._moveDirectyFollowers = function (x, y) { - var route = core.automaticRoute(x, y); - if (route.length == 0) route = [{ x: x, y: y, direction: core.getHeroLoc('direction') }]; + var route = core.automaticRoute(x, y); + if (route.length == 0) + route = [{ x: x, y: y, direction: core.getHeroLoc("direction") }]; - var nowx = x, nowy = y; - for (var i = 0; i < core.status.hero.followers.length; ++i) { - var t = core.status.hero.followers[i]; - var index = route.length - i - 2; - if (index < 0) index = 0; - t.stop = true; - t.x = route[index].x; - t.y = route[index].y; - t.direction = route[index].direction; - var dx = nowx - t.x, dy = nowy - t.y; - for (var dir in core.utils.scan2) { - if (core.utils.scan2[dir].x == dx && core.utils.scan2[dir].y == dy) { - t.stop = false; - t.direction = dir; - } - } - nowx = t.x; nowy = t.y; + var nowx = x, + nowy = y; + for (var i = 0; i < core.status.hero.followers.length; ++i) { + var t = core.status.hero.followers[i]; + var index = route.length - i - 2; + if (index < 0) index = 0; + t.stop = true; + t.x = route[index].x; + t.y = route[index].y; + t.direction = route[index].direction; + var dx = nowx - t.x, + dy = nowy - t.y; + for (var dir in core.utils.scan2) { + if (core.utils.scan2[dir].x == dx && core.utils.scan2[dir].y == dy) { + t.stop = false; + t.direction = dir; + } } -} + nowx = t.x; + nowy = t.y; + } +}; ////// 更新领域、夹击、阻击的伤害地图 ////// control.prototype.updateCheckBlock = function (floorId) { - return this.controldata.updateCheckBlock(floorId); -} + return this.controldata.updateCheckBlock(floorId); +}; ////// 检查并执行领域、夹击、阻击事件 ////// control.prototype.checkBlock = function () { - var x = core.getHeroLoc('x'), y = core.getHeroLoc('y'), loc = x + "," + y; - var damage = core.status.checkBlock.damage[loc]; - if (damage) { - core.status.hero.hp -= damage; - var text = (Object.keys(core.status.checkBlock.type[loc] || {}).join(",")) || "伤害"; - core.drawTip("受到" + text + damage + "点"); - core.drawHeroAnimate("zone"); - this._checkBlock_disableQuickShop(); - core.status.hero.statistics.extraDamage += damage; - if (core.status.hero.hp <= 0) { - core.status.hero.hp = 0; - core.updateStatusBar(false, true); - core.events.lose(); - return; - } else { - core.updateStatusBar(false, true); - } + var x = core.getHeroLoc("x"), + y = core.getHeroLoc("y"), + loc = x + "," + y; + var damage = core.status.checkBlock.damage[loc]; + if (damage) { + core.status.hero.hp -= damage; + var text = + Object.keys(core.status.checkBlock.type[loc] || {}).join(",") || "伤害"; + core.drawTip("受到" + text + damage + "点"); + core.drawHeroAnimate("zone"); + this._checkBlock_disableQuickShop(); + core.status.hero.statistics.extraDamage += damage; + if (core.status.hero.hp <= 0) { + core.status.hero.hp = 0; + core.updateStatusBar(false, true); + core.events.lose(); + return; + } else { + core.updateStatusBar(false, true); } - this._checkBlock_ambush(core.status.checkBlock.ambush[loc]); - this._checkBlock_repulse(core.status.checkBlock.repulse[loc]); -} + } + this._checkBlock_ambush(core.status.checkBlock.ambush[loc]); + this._checkBlock_repulse(core.status.checkBlock.repulse[loc]); +}; control.prototype._checkBlock_disableQuickShop = function () { - // 禁用快捷商店 - if (core.flags.disableShopOnDamage) { - Object.keys(core.status.shops).forEach(function (shopId) { - core.setShopVisited(shopId, false); - }); - } -} + // 禁用快捷商店 + if (core.flags.disableShopOnDamage) { + Object.keys(core.status.shops).forEach(function (shopId) { + core.setShopVisited(shopId, false); + }); + } +}; ////// 阻击 ////// control.prototype._checkBlock_repulse = function (repulse) { - if (!repulse || repulse.length == 0) return; - var actions = []; - repulse.forEach(function (t) { - actions.push({ "type": "move", "loc": [t[0], t[1]], "steps": [t[3]], "time": 250, "keep": true, "async": true }); + if (!repulse || repulse.length == 0) return; + var actions = []; + repulse.forEach(function (t) { + actions.push({ + type: "move", + loc: [t[0], t[1]], + steps: [t[3]], + time: 250, + keep: true, + async: true, }); - actions.push({ "type": "waitAsync" }); - core.insertAction(actions); -} + }); + actions.push({ type: "waitAsync" }); + core.insertAction(actions); +}; ////// 捕捉 ////// control.prototype._checkBlock_ambush = function (ambush) { - if (!ambush || ambush.length == 0) return; - // 捕捉效果 - var actions = []; - ambush.forEach(function (t) { - actions.push({ "type": "move", "loc": [t[0], t[1]], "steps": [t[3]], "time": 250, "keep": false, "async": true }); + if (!ambush || ambush.length == 0) return; + // 捕捉效果 + var actions = []; + ambush.forEach(function (t) { + actions.push({ + type: "move", + loc: [t[0], t[1]], + steps: [t[3]], + time: 250, + keep: false, + async: true, }); - actions.push({ "type": "waitAsync" }); - // 强制战斗 - ambush.forEach(function (t) { - actions.push({ - "type": "function", "function": "function() { " + - "core.battle('" + t[2] + "', " + t[0] + "," + t[1] + ", true, core.doAction); " + - "}", "async": true - }); + }); + actions.push({ type: "waitAsync" }); + // 强制战斗 + ambush.forEach(function (t) { + actions.push({ + type: "function", + function: + "function() { " + + "core.battle('" + + t[2] + + "', " + + t[0] + + "," + + t[1] + + ", true, core.doAction); " + + "}", + async: true, }); - core.insertAction(actions); -} + }); + core.insertAction(actions); +}; ////// 更新全地图显伤 ////// control.prototype.updateDamage = function (floorId, ctx) { - floorId = floorId || core.status.floorId; - if (!floorId || core.status.gameOver || main.mode != 'play') return; - var onMap = ctx == null; + floorId = floorId || core.status.floorId; + if (!floorId || core.status.gameOver || main.mode != "play") return; + var onMap = ctx == null; - // 没有怪物手册 - if (!core.hasItem('book')) return; - core.status.damage.posX = core.bigmap.posX; - core.status.damage.posY = core.bigmap.posY; - if (!onMap) { - var width = core.floors[floorId].width, height = core.floors[floorId].height; - // 地图过大的缩略图不绘制显伤 - if (width * height > core.bigmap.threshold) return; - } - this._updateDamage_damage(floorId, onMap); - this._updateDamage_extraDamage(floorId, onMap); - this.drawDamage(ctx); -} + // 没有怪物手册 + if (!core.hasItem("book")) return; + core.status.damage.posX = core.bigmap.posX; + core.status.damage.posY = core.bigmap.posY; + if (!onMap) { + var width = core.floors[floorId].width, + height = core.floors[floorId].height; + // 地图过大的缩略图不绘制显伤 + if (width * height > core.bigmap.threshold) return; + } + this._updateDamage_damage(floorId, onMap); + this._updateDamage_extraDamage(floorId, onMap); + this.drawDamage(ctx); +}; control.prototype._updateDamage_damage = function (floorId, onMap) { - core.status.damage.data = []; - if (!core.flags.displayEnemyDamage && !core.flags.displayExtraDamage) return; + core.status.damage.data = []; + if (!core.flags.displayEnemyDamage && !core.flags.displayExtraDamage) return; - core.extractBlocks(floorId); - core.status.maps[floorId].blocks.forEach(function (block) { - var x = block.x, y = block.y; + core.extractBlocks(floorId); + core.status.maps[floorId].blocks.forEach(function (block) { + var x = block.x, + y = block.y; - // v2优化,只绘制范围内的部分 - if (onMap && core.bigmap.v2) { - if (x < core.bigmap.posX - core.bigmap.extend || x > core.bigmap.posX + core._WIDTH_ + core.bigmap.extend - || y < core.bigmap.posY - core.bigmap.extend || y > core.bigmap.posY + core._HEIGHT_ + core.bigmap.extend) { - return; - } - } + // v2优化,只绘制范围内的部分 + if (onMap && core.bigmap.v2) { + if ( + x < core.bigmap.posX - core.bigmap.extend || + x > core.bigmap.posX + core._WIDTH_ + core.bigmap.extend || + y < core.bigmap.posY - core.bigmap.extend || + y > core.bigmap.posY + core._HEIGHT_ + core.bigmap.extend + ) { + return; + } + } - if (!block.disable && block.event.cls.indexOf('enemy') == 0 && block.event.displayDamage !== false) { - if (core.flags.displayEnemyDamage) { - var damageString = core.enemys.getDamageString(block.event.id, x, y, floorId); - core.status.damage.data.push({ text: damageString.damage, px: 32 * x + 1, py: 32 * (y + 1) - 1, color: damageString.color }); - } - if (core.flags.displayCritical) { - var critical = core.enemys.nextCriticals(block.event.id, 1, x, y, floorId); - critical = core.formatBigNumber((critical[0] || [])[0], true); - if (critical == '???') critical = '?'; - core.status.damage.data.push({ text: critical, px: 32 * x + 1, py: 32 * (y + 1) - 11, color: '#FFFFFF' }); - } - } - }); -} + if ( + !block.disable && + block.event.cls.indexOf("enemy") == 0 && + block.event.displayDamage !== false + ) { + if (core.flags.displayEnemyDamage) { + var damageString = core.enemys.getDamageString( + block.event.id, + x, + y, + floorId + ); + core.status.damage.data.push({ + text: damageString.damage, + px: 32 * x + 1, + py: 32 * (y + 1) - 1, + color: damageString.color, + }); + } + if (core.flags.displayCritical) { + var critical = core.enemys.nextCriticals( + block.event.id, + 1, + x, + y, + floorId + ); + critical = core.formatBigNumber((critical[0] || [])[0], true); + if (critical == "???") critical = "?"; + core.status.damage.data.push({ + text: critical, + px: 32 * x + 1, + py: 32 * (y + 1) - 11, + color: "#FFFFFF", + }); + } + } + }); +}; control.prototype._updateDamage_extraDamage = function (floorId, onMap) { - core.status.damage.extraData = []; - if (!core.flags.displayExtraDamage) return; + core.status.damage.extraData = []; + if (!core.flags.displayExtraDamage) return; - var width = core.floors[floorId].width, height = core.floors[floorId].height; - var startX = onMap && core.bigmap.v2 ? Math.max(0, core.bigmap.posX - core.bigmap.extend) : 0; - var endX = onMap && core.bigmap.v2 ? Math.min(width, core.bigmap.posX + core._WIDTH_ + core.bigmap.extend + 1) : width; - var startY = onMap && core.bigmap.v2 ? Math.max(0, core.bigmap.posY - core.bigmap.extend) : 0; - var endY = onMap && core.bigmap.v2 ? Math.min(height, core.bigmap.posY + core._HEIGHT_ + core.bigmap.extend + 1) : height; + var width = core.floors[floorId].width, + height = core.floors[floorId].height; + var startX = + onMap && core.bigmap.v2 + ? Math.max(0, core.bigmap.posX - core.bigmap.extend) + : 0; + var endX = + onMap && core.bigmap.v2 + ? Math.min( + width, + core.bigmap.posX + core._WIDTH_ + core.bigmap.extend + 1 + ) + : width; + var startY = + onMap && core.bigmap.v2 + ? Math.max(0, core.bigmap.posY - core.bigmap.extend) + : 0; + var endY = + onMap && core.bigmap.v2 + ? Math.min( + height, + core.bigmap.posY + core._HEIGHT_ + core.bigmap.extend + 1 + ) + : height; - for (var x = startX; x < endX; x++) { - for (var y = startY; y < endY; y++) { - var alpha = 1; - if (core.noPass(x, y, floorId)) { - if (core.flags.extraDamageType == 2) alpha = 0; - else if (core.flags.extraDamageType == 1) alpha = 0.6; - } - var damage = core.status.checkBlock.damage[x + "," + y] || 0; - if (damage > 0) { // 该点伤害 - damage = core.formatBigNumber(damage, true); - core.status.damage.extraData.push({ text: damage, px: 32 * x + 16, py: 32 * (y + 1) - 14, color: '#ffaa33', alpha: alpha }); - } - else { // 检查捕捉 - if (core.status.checkBlock.ambush[x + "," + y]) { - core.status.damage.extraData.push({ text: '!', px: 32 * x + 16, py: 32 * (y + 1) - 14, color: '#ffaa33', alpha: alpha }); - } - } + for (var x = startX; x < endX; x++) { + for (var y = startY; y < endY; y++) { + var alpha = 1; + if (core.noPass(x, y, floorId)) { + if (core.flags.extraDamageType == 2) alpha = 0; + else if (core.flags.extraDamageType == 1) alpha = 0.6; + } + var damage = core.status.checkBlock.damage[x + "," + y] || 0; + if (damage > 0) { + // 该点伤害 + damage = core.formatBigNumber(damage, true); + core.status.damage.extraData.push({ + text: damage, + px: 32 * x + 16, + py: 32 * (y + 1) - 14, + color: "#ffaa33", + alpha: alpha, + }); + } else { + // 检查捕捉 + if (core.status.checkBlock.ambush[x + "," + y]) { + core.status.damage.extraData.push({ + text: "!", + px: 32 * x + 16, + py: 32 * (y + 1) - 14, + color: "#ffaa33", + alpha: alpha, + }); } + } } -} + } +}; ////// 重绘地图显伤 ////// control.prototype.drawDamage = function (ctx) { - if (core.status.gameOver || !core.status.damage || main.mode != 'play') return; - var onMap = false; - if (ctx == null) { - ctx = core.canvas.damage; - core.clearMap('damage'); - onMap = true; - } + if (core.status.gameOver || !core.status.damage || main.mode != "play") + return; + var onMap = false; + if (ctx == null) { + ctx = core.canvas.damage; + core.clearMap("damage"); + onMap = true; + } - if (onMap && core.bigmap.v2) { - // 检查是否需要重算... - if (Math.abs(core.bigmap.posX - core.status.damage.posX) >= core.bigmap.extend - 1 - || Math.abs(core.bigmap.posY - core.status.damage.posY) >= core.bigmap.extend - 1) { - return this.updateDamage(); - } + if (onMap && core.bigmap.v2) { + // 检查是否需要重算... + if ( + Math.abs(core.bigmap.posX - core.status.damage.posX) >= + core.bigmap.extend - 1 || + Math.abs(core.bigmap.posY - core.status.damage.posY) >= + core.bigmap.extend - 1 + ) { + return this.updateDamage(); } - return this._drawDamage_draw(ctx, onMap); -} + } + return this._drawDamage_draw(ctx, onMap); +}; control.prototype._drawDamage_draw = function (ctx, onMap) { - if (!core.hasItem('book')) return; + if (!core.hasItem("book")) return; - core.setFont(ctx, "bold 11px Arial"); - core.setTextAlign(ctx, 'left'); - core.status.damage.data.forEach(function (one) { - var px = one.px, py = one.py; - if (onMap && core.bigmap.v2) { - px -= core.bigmap.posX * 32; - py -= core.bigmap.posY * 32; - if (px < -32 * 2 || px > core._PX_ + 32 || py < -32 || py > core._PY_ + 32) - return; - } - core.fillBoldText(ctx, one.text, px, py, one.color); - }); + core.setFont(ctx, "bold 11px Arial"); + core.setTextAlign(ctx, "left"); + core.status.damage.data.forEach(function (one) { + var px = one.px, + py = one.py; + if (onMap && core.bigmap.v2) { + px -= core.bigmap.posX * 32; + py -= core.bigmap.posY * 32; + if ( + px < -32 * 2 || + px > core._PX_ + 32 || + py < -32 || + py > core._PY_ + 32 + ) + return; + } + core.fillBoldText(ctx, one.text, px, py, one.color); + }); - core.setTextAlign(ctx, 'center'); - core.status.damage.extraData.forEach(function (one) { - var px = one.px, py = one.py; - if (onMap && core.bigmap.v2) { - px -= core.bigmap.posX * 32; - py -= core.bigmap.posY * 32; - if (px < -32 || px > core._PX_ + 32 || py < -32 || py > core._PY_ + 32) - return; - } - var alpha = core.setAlpha(ctx, one.alpha); - core.fillBoldText(ctx, one.text, px, py, one.color); - core.setAlpha(ctx, alpha); - }); -} + core.setTextAlign(ctx, "center"); + core.status.damage.extraData.forEach(function (one) { + var px = one.px, + py = one.py; + if (onMap && core.bigmap.v2) { + px -= core.bigmap.posX * 32; + py -= core.bigmap.posY * 32; + if (px < -32 || px > core._PX_ + 32 || py < -32 || py > core._PY_ + 32) + return; + } + var alpha = core.setAlpha(ctx, one.alpha); + core.fillBoldText(ctx, one.text, px, py, one.color); + core.setAlpha(ctx, alpha); + }); +}; // ------ 录像相关 ------ // ////// 选择录像文件 ////// control.prototype.chooseReplayFile = function () { - core.readFile(function (obj) { - if (obj.name != core.firstData.name) return alert("存档和游戏不一致!"); - if (!obj.route) return alert("无效的录像!"); - var _replay = function () { - core.startGame(core.flags.startUsingCanvas ? '' : obj.hard || '', obj.seed, core.decodeRoute(obj.route)); - } - if (obj.version && obj.version != core.firstData.version) { - core.myconfirm("游戏版本不一致!\n你仍然想播放录像吗?", _replay); - return; - } - _replay(); - }, null, ".h5route"); -} + core.readFile( + function (obj) { + if (obj.name != core.firstData.name) return alert("存档和游戏不一致!"); + if (!obj.route) return alert("无效的录像!"); + var _replay = function () { + core.startGame( + core.flags.startUsingCanvas ? "" : obj.hard || "", + obj.seed, + core.decodeRoute(obj.route) + ); + }; + if (obj.version && obj.version != core.firstData.version) { + core.myconfirm("游戏版本不一致!\n你仍然想播放录像吗?", _replay); + return; + } + _replay(); + }, + null, + ".h5route" + ); +}; ////// 开始播放 ////// control.prototype.startReplay = function (list) { - if (!core.isPlaying()) return; - core.status.replay.replaying = true; - core.status.replay.pausing = true; - core.status.replay.failed = false; - core.status.replay.speed = 1.0; - core.status.replay.toReplay = core.cloneArray(list); - core.status.replay.totalList = core.status.route.concat(list); - core.status.replay.steps = 0; - core.status.replay.save = []; - core.createCanvas('replay', 0, core._PY_ - 40, core._PX_, 40, 199); - core.setOpacity('replay', 0.6); - this._replay_drawProgress(); - core.updateStatusBar(false, true); - core.drawTip("开始播放"); - this.replay(); -} + if (!core.isPlaying()) return; + core.status.replay.replaying = true; + core.status.replay.pausing = true; + core.status.replay.failed = false; + core.status.replay.speed = 1.0; + core.status.replay.toReplay = core.cloneArray(list); + core.status.replay.totalList = core.status.route.concat(list); + core.status.replay.steps = 0; + core.status.replay.save = []; + core.createCanvas("replay", 0, core._PY_ - 40, core._PX_, 40, 199); + core.setOpacity("replay", 0.6); + this._replay_drawProgress(); + core.updateStatusBar(false, true); + core.drawTip("开始播放"); + this.replay(); +}; ////// 更改播放状态 ////// control.prototype.triggerReplay = function () { - if (core.status.replay.pausing) this.resumeReplay(); - else this.pauseReplay(); -} + if (core.status.replay.pausing) this.resumeReplay(); + else this.pauseReplay(); +}; ////// 暂停播放 ////// control.prototype.pauseReplay = function () { - if (!core.isPlaying() || !core.isReplaying()) return; - core.status.replay.pausing = true; - core.updateStatusBar(false, true); - core.drawTip("暂停播放"); -} + if (!core.isPlaying() || !core.isReplaying()) return; + core.status.replay.pausing = true; + core.updateStatusBar(false, true); + core.drawTip("暂停播放"); +}; ////// 恢复播放 ////// control.prototype.resumeReplay = function () { - if (!core.isPlaying() || !core.isReplaying()) return; - if (core.isMoving() || core.status.replay.animate || core.status.event.id) { - core.playSound('操作失败'); - return core.drawTip("请等待当前事件的处理结束"); - } - core.status.replay.pausing = false; - core.updateStatusBar(false, true); - core.drawTip("恢复播放"); - core.replay(); -} + if (!core.isPlaying() || !core.isReplaying()) return; + if (core.isMoving() || core.status.replay.animate || core.status.event.id) { + core.playSound("操作失败"); + return core.drawTip("请等待当前事件的处理结束"); + } + core.status.replay.pausing = false; + core.updateStatusBar(false, true); + core.drawTip("恢复播放"); + core.replay(); +}; ////// 单步播放 ////// control.prototype.stepReplay = function () { - if (!core.isPlaying() || !core.isReplaying()) return; - if (!core.status.replay.pausing) { - core.playSound('操作失败'); - return core.drawTip("请先暂停录像"); - } - if (core.isMoving() || core.status.replay.animate || core.status.event.id) { - core.playSound('操作失败'); - return core.drawTip("请等待当前事件的处理结束"); - } - core.replay(true); -} + if (!core.isPlaying() || !core.isReplaying()) return; + if (!core.status.replay.pausing) { + core.playSound("操作失败"); + return core.drawTip("请先暂停录像"); + } + if (core.isMoving() || core.status.replay.animate || core.status.event.id) { + core.playSound("操作失败"); + return core.drawTip("请等待当前事件的处理结束"); + } + core.replay(true); +}; ////// 加速播放 ////// control.prototype.speedUpReplay = function () { - if (!core.isPlaying() || !core.isReplaying()) return; - var speeds = [0.2, 0.5, 1, 2, 3, 6, 12, 24]; - for (var i = speeds.length - 2; i >= 0; i--) { - if (speeds[i] <= core.status.replay.speed) { - core.status.replay.speed = speeds[i + 1]; - break; - } + if (!core.isPlaying() || !core.isReplaying()) return; + var speeds = [0.2, 0.5, 1, 2, 3, 6, 12, 24]; + for (var i = speeds.length - 2; i >= 0; i--) { + if (speeds[i] <= core.status.replay.speed) { + core.status.replay.speed = speeds[i + 1]; + break; } - core.drawTip("x" + core.status.replay.speed + "倍"); -} + } + core.drawTip("x" + core.status.replay.speed + "倍"); +}; ////// 减速播放 ////// control.prototype.speedDownReplay = function () { - if (!core.isPlaying() || !core.isReplaying()) return; - var speeds = [0.2, 0.5, 1, 2, 3, 6, 12, 24]; - for (var i = 1; i <= speeds.length; i++) { - if (speeds[i] >= core.status.replay.speed) { - core.status.replay.speed = speeds[i - 1]; - break; - } + if (!core.isPlaying() || !core.isReplaying()) return; + var speeds = [0.2, 0.5, 1, 2, 3, 6, 12, 24]; + for (var i = 1; i <= speeds.length; i++) { + if (speeds[i] >= core.status.replay.speed) { + core.status.replay.speed = speeds[i - 1]; + break; } - core.drawTip("x" + core.status.replay.speed + "倍"); -} + } + core.drawTip("x" + core.status.replay.speed + "倍"); +}; ////// 设置播放速度 ////// control.prototype.setReplaySpeed = function (speed) { - if (!core.isPlaying() || !core.isReplaying()) return; - core.status.replay.speed = speed; - core.drawTip("x" + core.status.replay.speed + "倍"); -} + if (!core.isPlaying() || !core.isReplaying()) return; + core.status.replay.speed = speed; + core.drawTip("x" + core.status.replay.speed + "倍"); +}; ////// 停止播放 ////// control.prototype.stopReplay = function (force) { - if (!core.isPlaying()) return; - if (!core.isReplaying() && !force) return; - core.status.replay.toReplay = []; - core.status.replay.totalList = []; - core.status.replay.replaying = false; - core.status.replay.pausing = false; - core.status.replay.failed = false; - core.status.replay.speed = 1.0; - core.status.replay.steps = 0; - core.status.replay.save = []; - core.deleteCanvas('replay'); - core.updateStatusBar(false, true); - core.drawTip("停止播放并恢复游戏"); -} + if (!core.isPlaying()) return; + if (!core.isReplaying() && !force) return; + core.status.replay.toReplay = []; + core.status.replay.totalList = []; + core.status.replay.replaying = false; + core.status.replay.pausing = false; + core.status.replay.failed = false; + core.status.replay.speed = 1.0; + core.status.replay.steps = 0; + core.status.replay.save = []; + core.deleteCanvas("replay"); + core.updateStatusBar(false, true); + core.drawTip("停止播放并恢复游戏"); +}; ////// 回退 ////// control.prototype.rewindReplay = function () { - if (!core.isPlaying() || !core.isReplaying()) return; - if (!core.status.replay.pausing) { - core.playSound('操作失败'); - return core.drawTip("请先暂停录像"); - } - if (core.isMoving() || core.status.replay.animate || core.status.event.id) { - core.playSound('操作失败'); - return core.drawTip("请等待当前事件的处理结束"); - } - if (core.status.replay.save.length == 0) { - core.playSound('操作失败'); - return core.drawTip("无法再回到上一个节点"); - } - var save = core.status.replay.save, data = save.pop(); - core.loadData(data.data, function () { - core.removeFlag('__fromLoad__'); - core.status.replay = { - "replaying": true, - "pausing": true, - "animate": false, - "toReplay": data.replay.toReplay, - "totalList": data.replay.totalList, - "speed": core.status.replay.speed, - "steps": data.replay.steps, - "save": save - } - core.createCanvas('replay', 0, core._PY_ - 40, core._PX_, 40, 199); - core.setOpacity('replay', 0.6); - core.control._replay_drawProgress(); - core.updateStatusBar(false, true); - core.drawTip("成功回退到上一个节点"); - }); -} + if (!core.isPlaying() || !core.isReplaying()) return; + if (!core.status.replay.pausing) { + core.playSound("操作失败"); + return core.drawTip("请先暂停录像"); + } + if (core.isMoving() || core.status.replay.animate || core.status.event.id) { + core.playSound("操作失败"); + return core.drawTip("请等待当前事件的处理结束"); + } + if (core.status.replay.save.length == 0) { + core.playSound("操作失败"); + return core.drawTip("无法再回到上一个节点"); + } + var save = core.status.replay.save, + data = save.pop(); + core.loadData(data.data, function () { + core.removeFlag("__fromLoad__"); + core.status.replay = { + replaying: true, + pausing: true, + animate: false, + toReplay: data.replay.toReplay, + totalList: data.replay.totalList, + speed: core.status.replay.speed, + steps: data.replay.steps, + save: save, + }; + core.createCanvas("replay", 0, core._PY_ - 40, core._PX_, 40, 199); + core.setOpacity("replay", 0.6); + core.control._replay_drawProgress(); + core.updateStatusBar(false, true); + core.drawTip("成功回退到上一个节点"); + }); +}; ////// 回放时存档 ////// control.prototype._replay_SL = function () { - if (!core.isPlaying() || !core.isReplaying()) return; - if (!core.status.replay.pausing) { - core.playSound('操作失败'); - return core.drawTip("请先暂停录像"); - } - if (core.isMoving() || core.status.replay.animate || core.status.event.id) { - core.playSound('操作失败'); - return core.drawTip("请等待当前事件的处理结束"); - } - if (core.hasFlag('__forbidSave__')) { - core.playSound('操作失败'); - return core.drawTip('当前禁止存档'); - } - this._replay_hideProgress(); + if (!core.isPlaying() || !core.isReplaying()) return; + if (!core.status.replay.pausing) { + core.playSound("操作失败"); + return core.drawTip("请先暂停录像"); + } + if (core.isMoving() || core.status.replay.animate || core.status.event.id) { + core.playSound("操作失败"); + return core.drawTip("请等待当前事件的处理结束"); + } + if (core.hasFlag("__forbidSave__")) { + core.playSound("操作失败"); + return core.drawTip("当前禁止存档"); + } + this._replay_hideProgress(); - core.lockControl(); - core.status.event.id = 'save'; - var saveIndex = core.saves.saveIndex; - var page = parseInt((saveIndex - 1) / 5), offset = saveIndex - 5 * page; + core.lockControl(); + core.status.event.id = "save"; + var saveIndex = core.saves.saveIndex; + var page = parseInt((saveIndex - 1) / 5), + offset = saveIndex - 5 * page; - core.ui._drawSLPanel(10 * page + offset); -} + core.ui._drawSLPanel(10 * page + offset); +}; ////// 回放时查看怪物手册 ////// control.prototype._replay_book = function () { - if (!core.isPlaying() || !core.isReplaying()) return; - if (!core.status.replay.pausing) { - core.playSound('操作失败'); - return core.drawTip("请先暂停录像"); - } - if (core.isMoving() || core.status.replay.animate || (core.status.event.id && core.status.event.id != 'viewMaps')) { - core.playSound('操作失败'); - return core.drawTip("请等待当前事件的处理结束"); - } - if (!core.hasItem('book')) { - core.playSound('操作失败'); - return core.drawTip('你没有' + core.material.items['book'].name, 'book'); - } - this._replay_hideProgress(); + if (!core.isPlaying() || !core.isReplaying()) return; + if (!core.status.replay.pausing) { + core.playSound("操作失败"); + return core.drawTip("请先暂停录像"); + } + if ( + core.isMoving() || + core.status.replay.animate || + (core.status.event.id && core.status.event.id != "viewMaps") + ) { + core.playSound("操作失败"); + return core.drawTip("请等待当前事件的处理结束"); + } + if (!core.hasItem("book")) { + core.playSound("操作失败"); + return core.drawTip("你没有" + core.material.items["book"].name, "book"); + } + this._replay_hideProgress(); - // 从“浏览地图”页面打开 - if (core.status.event.id == 'viewMaps') - core.status.event.ui = core.status.event.data; + // 从“浏览地图”页面打开 + if (core.status.event.id == "viewMaps") + core.status.event.ui = core.status.event.data; - core.lockControl(); - core.status.event.id = 'book'; - core.useItem('book', true); -} + core.lockControl(); + core.status.event.id = "book"; + core.useItem("book", true); +}; ////// 回放录像时浏览地图 ////// control.prototype._replay_viewMap = function () { - if (!core.isPlaying() || !core.isReplaying()) return; - if (!core.status.replay.pausing) { - core.playSound('操作失败'); - return core.drawTip("请先暂停录像"); - } - if (core.isMoving() || core.status.replay.animate || core.status.event.id) { - core.playSound('操作失败'); - return core.drawTip("请等待当前事件的处理结束"); - } - this._replay_hideProgress(); + if (!core.isPlaying() || !core.isReplaying()) return; + if (!core.status.replay.pausing) { + core.playSound("操作失败"); + return core.drawTip("请先暂停录像"); + } + if (core.isMoving() || core.status.replay.animate || core.status.event.id) { + core.playSound("操作失败"); + return core.drawTip("请等待当前事件的处理结束"); + } + this._replay_hideProgress(); - core.lockControl(); - core.status.event.id = 'viewMaps'; - core.ui._drawViewMaps(); -} + core.lockControl(); + core.status.event.id = "viewMaps"; + core.ui._drawViewMaps(); +}; control.prototype._replay_toolbox = function () { - if (!core.isPlaying() || !core.isReplaying()) return; - if (!core.status.replay.pausing) { - core.playSound('操作失败'); - return core.drawTip("请先暂停录像"); - } - if (core.isMoving() || core.status.replay.animate || core.status.event.id) { - core.playSound('操作失败'); - return core.drawTip("请等待当前事件的处理结束"); - } - this._replay_hideProgress(); + if (!core.isPlaying() || !core.isReplaying()) return; + if (!core.status.replay.pausing) { + core.playSound("操作失败"); + return core.drawTip("请先暂停录像"); + } + if (core.isMoving() || core.status.replay.animate || core.status.event.id) { + core.playSound("操作失败"); + return core.drawTip("请等待当前事件的处理结束"); + } + this._replay_hideProgress(); - core.lockControl(); - core.status.event.id = 'toolbox'; - core.ui._drawToolbox(); -} + core.lockControl(); + core.status.event.id = "toolbox"; + core.ui._drawToolbox(); +}; control.prototype._replay_equipbox = function () { - if (!core.isPlaying() || !core.isReplaying()) return; - if (!core.status.replay.pausing) { - core.playSound('操作失败'); - return core.drawTip("请先暂停录像"); - } - if (core.isMoving() || core.status.replay.animate || core.status.event.id) { - core.playSound('操作失败'); - return core.drawTip("请等待当前事件的处理结束"); - } - this._replay_hideProgress(); + if (!core.isPlaying() || !core.isReplaying()) return; + if (!core.status.replay.pausing) { + core.playSound("操作失败"); + return core.drawTip("请先暂停录像"); + } + if (core.isMoving() || core.status.replay.animate || core.status.event.id) { + core.playSound("操作失败"); + return core.drawTip("请等待当前事件的处理结束"); + } + this._replay_hideProgress(); - core.lockControl(); - core.status.event.id = 'equipbox'; - core.ui._drawEquipbox(); -} + core.lockControl(); + core.status.event.id = "equipbox"; + core.ui._drawEquipbox(); +}; ////// 是否正在播放录像 ////// control.prototype.isReplaying = function () { - return (core.status.replay || {}).replaying; -} + return (core.status.replay || {}).replaying; +}; ////// 回放 ////// control.prototype.replay = function (force) { - if (!core.isPlaying() || !core.isReplaying() - || core.status.replay.animate || core.status.event.id || core.status.replay.failed) return; - if (core.status.replay.pausing && !force) return; - this._replay_drawProgress(); - if (core.status.replay.toReplay.length == 0) - return this._replay_finished(); - this._replay_save(); - var action = core.status.replay.toReplay.shift(); - if (this._doReplayAction(action)) return; - this._replay_error(action); -} + if ( + !core.isPlaying() || + !core.isReplaying() || + core.status.replay.animate || + core.status.event.id || + core.status.replay.failed + ) + return; + if (core.status.replay.pausing && !force) return; + this._replay_drawProgress(); + if (core.status.replay.toReplay.length == 0) return this._replay_finished(); + this._replay_save(); + var action = core.status.replay.toReplay.shift(); + if (this._doReplayAction(action)) return; + this._replay_error(action); +}; ////// 注册一个录像行为 ////// // name:自定义名称,可用于注销使用 @@ -1608,1958 +2039,2394 @@ control.prototype.replay = function (force) { // 需要接受一个action参数,代表录像回放时的下一个操作 // func返回true代表成功处理了此录像行为,false代表没有处理此录像行为。 control.prototype.registerReplayAction = function (name, func) { - this.unregisterReplayAction(name); - this.replayActions.push({ name: name, func: func }); -} + this.unregisterReplayAction(name); + this.replayActions.push({ name: name, func: func }); +}; ////// 注销一个录像行为 ////// control.prototype.unregisterReplayAction = function (name) { - this.replayActions = this.replayActions.filter(function (b) { return b.name != name; }); -} + this.replayActions = this.replayActions.filter(function (b) { + return b.name != name; + }); +}; ////// 执行录像行为,会在注册的函数中依次执行直到得到true为止 ////// control.prototype._doReplayAction = function (action) { - for (var i in this.replayActions) { - try { - if (core.doFunc(this.replayActions[i].func, this, action)) return true; - } catch (e) { - console.error(e); - console.error("ERROR in replayActions[" + this.replayActions[i].name + "]:已自动注销该项。"); - core.unregisterReplayAction(this.replayActions[i].name); - } + for (var i in this.replayActions) { + try { + if (core.doFunc(this.replayActions[i].func, this, action)) return true; + } catch (e) { + console.error(e); + console.error( + "ERROR in replayActions[" + + this.replayActions[i].name + + "]:已自动注销该项。" + ); + core.unregisterReplayAction(this.replayActions[i].name); } - return false; -} + } + return false; +}; control.prototype._replay_finished = function () { - core.status.replay.replaying = false; - core.status.replay.failed = false; - core.status.event.selection = 0; - var str = "录像播放完毕,你想退出播放吗?"; - if (core.status.route.length != core.status.replay.totalList.length - || core.subarray(core.status.route, core.status.replay.totalList) == null) { - str = "录像播放完毕,但记录不一致。\n请检查录像播放时的二次记录问题。\n你想退出播放吗?"; + core.status.replay.replaying = false; + core.status.replay.failed = false; + core.status.event.selection = 0; + var str = "录像播放完毕,你想退出播放吗?"; + if ( + core.status.route.length != core.status.replay.totalList.length || + core.subarray(core.status.route, core.status.replay.totalList) == null + ) { + str = + "录像播放完毕,但记录不一致。\n请检查录像播放时的二次记录问题。\n你想退出播放吗?"; + } + core.ui.drawConfirmBox( + str, + function () { + core.ui.closePanel(); + core.stopReplay(true); + }, + function () { + core.status.replay.replaying = true; + core.ui.closePanel(); + core.pauseReplay(); } - core.ui.drawConfirmBox(str, function () { - core.ui.closePanel(); - core.stopReplay(true); - }, function () { - core.status.replay.replaying = true; - core.ui.closePanel(); - core.pauseReplay(); - }); -} + ); +}; control.prototype._replay_save = function () { - core.status.replay.steps++; - if (core.status.replay.steps % 40 == 1) { - if (core.status.replay.save.length == 30) - core.status.replay.save.shift(); - core.status.replay.save.push({ - "data": core.saveData(), "replay": { - "totalList": core.cloneArray(core.status.replay.totalList), - "toReplay": core.cloneArray(core.status.replay.toReplay), - "steps": core.status.replay.steps - } - }); - } -} + core.status.replay.steps++; + if (core.status.replay.steps % 40 == 1) { + if (core.status.replay.save.length == 30) core.status.replay.save.shift(); + core.status.replay.save.push({ + data: core.saveData(), + replay: { + totalList: core.cloneArray(core.status.replay.totalList), + toReplay: core.cloneArray(core.status.replay.toReplay), + steps: core.status.replay.steps, + }, + }); + } +}; control.prototype._replay_error = function (action, callback) { - core.ui.closePanel(); - core.status.replay.replaying = false; - core.status.replay.failed = true; - var len = core.status.replay.toReplay.length; - var prevList = core.status.replay.totalList.slice(-len - 11, -len - 1); - var nextList = core.status.replay.toReplay.slice(0, 10); - console.log("录像文件出错,当前操作:" + action); - console.log("之前的10个操作是:\n" + prevList.toString()); - console.log("接下来10个操作是:\n" + nextList.toString()); - core.ui.drawConfirmBox("录像文件出错,你想回到上个节点吗?", function () { - core.status.replay.failed = false; - core.ui.closePanel(); - if (core.status.replay.save.length > 0) { - core.status.replay.replaying = true; - core.status.replay.pausing = true; - core.rewindReplay(); - } - else { - core.playSound('操作失败'); - core.stopReplay(true); - core.drawTip("无法回到上一个节点"); - if (callback) callback(); - } - }, function () { - core.status.replay.failed = false; - core.ui.closePanel(); + core.ui.closePanel(); + core.status.replay.replaying = false; + core.status.replay.failed = true; + var len = core.status.replay.toReplay.length; + var prevList = core.status.replay.totalList.slice(-len - 11, -len - 1); + var nextList = core.status.replay.toReplay.slice(0, 10); + console.log("录像文件出错,当前操作:" + action); + console.log("之前的10个操作是:\n" + prevList.toString()); + console.log("接下来10个操作是:\n" + nextList.toString()); + core.ui.drawConfirmBox( + "录像文件出错,你想回到上个节点吗?", + function () { + core.status.replay.failed = false; + core.ui.closePanel(); + if (core.status.replay.save.length > 0) { + core.status.replay.replaying = true; + core.status.replay.pausing = true; + core.rewindReplay(); + } else { + core.playSound("操作失败"); core.stopReplay(true); + core.drawTip("无法回到上一个节点"); if (callback) callback(); - }); -} + } + }, + function () { + core.status.replay.failed = false; + core.ui.closePanel(); + core.stopReplay(true); + if (callback) callback(); + } + ); +}; control.prototype._replay_hideProgress = function () { - if (core.dymCanvas.replay) core.dymCanvas.replay.canvas.style.display = 'none'; -} + if (core.dymCanvas.replay) + core.dymCanvas.replay.canvas.style.display = "none"; +}; control.prototype._replay_drawProgress = function () { - if (!core.dymCanvas.replay) return; - if (core.dymCanvas.replay.canvas.style.display == 'none') core.dymCanvas.replay.canvas.style.display = 'block'; - var total = core.status.replay.totalList.length, left = total - core.status.replay.toReplay.length; - var content = '播放进度:' + left + ' / ' + total + '(' + (left / total * 100).toFixed(2) + '%)'; - var width = 26 + core.calWidth('replay', content, "16px Arial"); - core.clearMap('replay'); - core.fillRect('replay', 0, 0, width, 40, '#000000'); - core.fillText('replay', content, 16, 27, '#FFFFFF'); -} + if (!core.dymCanvas.replay) return; + if (core.dymCanvas.replay.canvas.style.display == "none") + core.dymCanvas.replay.canvas.style.display = "block"; + var total = core.status.replay.totalList.length, + left = total - core.status.replay.toReplay.length; + var content = + "播放进度:" + + left + + " / " + + total + + "(" + + ((left / total) * 100).toFixed(2) + + "%)"; + var width = 26 + core.calWidth("replay", content, "16px Arial"); + core.clearMap("replay"); + core.fillRect("replay", 0, 0, width, 40, "#000000"); + core.fillText("replay", content, 16, 27, "#FFFFFF"); +}; control.prototype.__replay_getTimeout = function () { - if (core.status.replay.speed == 24) return 0; - return 750 / Math.max(1, core.status.replay.speed); -} + if (core.status.replay.speed == 24) return 0; + return 750 / Math.max(1, core.status.replay.speed); +}; control.prototype._replayAction_move = function (action) { - if (["up", "down", "left", "right"].indexOf(action) < 0) return false; - core.moveHero(action, core.replay); - return true; -} + if (["up", "down", "left", "right"].indexOf(action) < 0) return false; + core.moveHero(action, core.replay); + return true; +}; control.prototype._replayAction_item = function (action) { - if (action.indexOf("item:") != 0) return false; - var itemId = action.substring(5); - if (!core.canUseItem(itemId)) return false; - if (core.material.items[itemId].hideInReplay || core.status.replay.speed == 24) { - core.useItem(itemId, false, core.replay); - return true; - } - var tools = core.getToolboxItems('tools'), - constants = core.getToolboxItems('constants'); - var index, per = core._WIDTH_ - 1; - if ((index = tools.indexOf(itemId)) >= 0) { - core.status.event.data = { "toolsPage": Math.floor(index / per) + 1, "constantsPage": 1 }; - index = index % per; - } - else if ((index = constants.indexOf(itemId)) >= 0) { - core.status.event.data = { "toolsPage": 1, "constantsPage": Math.floor(index / per) + 1 }; - index = index % per + per; - } - if (index < 0) return false; - core.ui._drawToolbox(index); - setTimeout(function () { - core.ui.closePanel(); - core.useItem(itemId, false, core.replay); - }, core.control.__replay_getTimeout()); + if (action.indexOf("item:") != 0) return false; + var itemId = action.substring(5); + if (!core.canUseItem(itemId)) return false; + if ( + core.material.items[itemId].hideInReplay || + core.status.replay.speed == 24 + ) { + core.useItem(itemId, false, core.replay); return true; -} + } + var tools = core.getToolboxItems("tools"), + constants = core.getToolboxItems("constants"); + var index, + per = core._WIDTH_ - 1; + if ((index = tools.indexOf(itemId)) >= 0) { + core.status.event.data = { + toolsPage: Math.floor(index / per) + 1, + constantsPage: 1, + }; + index = index % per; + } else if ((index = constants.indexOf(itemId)) >= 0) { + core.status.event.data = { + toolsPage: 1, + constantsPage: Math.floor(index / per) + 1, + }; + index = (index % per) + per; + } + if (index < 0) return false; + core.ui._drawToolbox(index); + setTimeout(function () { + core.ui.closePanel(); + core.useItem(itemId, false, core.replay); + }, core.control.__replay_getTimeout()); + return true; +}; control.prototype._replayAction_equip = function (action) { - if (action.indexOf("equip:") != 0) return false; - var equipId = action.substring(6); - var ownEquipment = core.getToolboxItems('equips'); - var index = ownEquipment.indexOf(equipId), per = core._WIDTH_ - 1; - if (index < 0) { - core.removeFlag('__doNotCheckAutoEvents__'); - return false; - } + if (action.indexOf("equip:") != 0) return false; + var equipId = action.substring(6); + var ownEquipment = core.getToolboxItems("equips"); + var index = ownEquipment.indexOf(equipId), + per = core._WIDTH_ - 1; + if (index < 0) { + core.removeFlag("__doNotCheckAutoEvents__"); + return false; + } - var cb = function () { - var next = core.status.replay.toReplay[0] || ""; - if (!next.startsWith('equip:') && !next.startsWith('unEquip:')) { - core.removeFlag('__doNotCheckAutoEvents__'); - core.checkAutoEvents(); - } - core.replay(); + var cb = function () { + var next = core.status.replay.toReplay[0] || ""; + if (!next.startsWith("equip:") && !next.startsWith("unEquip:")) { + core.removeFlag("__doNotCheckAutoEvents__"); + core.checkAutoEvents(); } - core.setFlag('__doNotCheckAutoEvents__', true); + core.replay(); + }; + core.setFlag("__doNotCheckAutoEvents__", true); - core.status.route.push(action); - if (core.material.items[equipId].hideInReplay || core.status.replay.speed == 24) { - core.loadEquip(equipId, cb); - return true; - } - core.status.event.data = { "page": Math.floor(index / per) + 1, "selectId": null }; - index = index % per + per; - core.ui._drawEquipbox(index); - setTimeout(function () { - core.ui.closePanel(); - core.loadEquip(equipId, cb); - }, core.control.__replay_getTimeout()); + core.status.route.push(action); + if ( + core.material.items[equipId].hideInReplay || + core.status.replay.speed == 24 + ) { + core.loadEquip(equipId, cb); return true; -} + } + core.status.event.data = { + page: Math.floor(index / per) + 1, + selectId: null, + }; + index = (index % per) + per; + core.ui._drawEquipbox(index); + setTimeout(function () { + core.ui.closePanel(); + core.loadEquip(equipId, cb); + }, core.control.__replay_getTimeout()); + return true; +}; control.prototype._replayAction_unEquip = function (action) { - if (action.indexOf("unEquip:") != 0) return false; - var equipType = parseInt(action.substring(8)); - if (!core.isset(equipType)) { - core.removeFlag('__doNotCheckAutoEvents__'); - return false; - } + if (action.indexOf("unEquip:") != 0) return false; + var equipType = parseInt(action.substring(8)); + if (!core.isset(equipType)) { + core.removeFlag("__doNotCheckAutoEvents__"); + return false; + } - var cb = function () { - var next = core.status.replay.toReplay[0] || ""; - if (!next.startsWith('equip:') && !next.startsWith('unEquip:')) { - core.removeFlag('__doNotCheckAutoEvents__'); - core.checkAutoEvents(); - } - core.replay(); + var cb = function () { + var next = core.status.replay.toReplay[0] || ""; + if (!next.startsWith("equip:") && !next.startsWith("unEquip:")) { + core.removeFlag("__doNotCheckAutoEvents__"); + core.checkAutoEvents(); } - core.setFlag('__doNotCheckAutoEvents__', true); + core.replay(); + }; + core.setFlag("__doNotCheckAutoEvents__", true); - core.ui._drawEquipbox(equipType); - core.status.route.push(action); - if (core.status.replay.speed == 24) { - core.unloadEquip(equipType, cb); - return true; - } - setTimeout(function () { - core.ui.closePanel(); - core.unloadEquip(equipType, cb); - }, core.control.__replay_getTimeout()); + core.ui._drawEquipbox(equipType); + core.status.route.push(action); + if (core.status.replay.speed == 24) { + core.unloadEquip(equipType, cb); return true; -} + } + setTimeout(function () { + core.ui.closePanel(); + core.unloadEquip(equipType, cb); + }, core.control.__replay_getTimeout()); + return true; +}; control.prototype._replayAction_saveEquip = function (action) { - if (action.indexOf('saveEquip:') != 0) return false; - core.quickSaveEquip(parseInt(action.substring(10))); - core.replay(); - return true; -} + if (action.indexOf("saveEquip:") != 0) return false; + core.quickSaveEquip(parseInt(action.substring(10))); + core.replay(); + return true; +}; control.prototype._replayAction_loadEquip = function (action) { - if (action.indexOf('loadEquip:') != 0) return false; - core.quickLoadEquip(parseInt(action.substring(10))); - core.replay(); - return true; -} + if (action.indexOf("loadEquip:") != 0) return false; + core.quickLoadEquip(parseInt(action.substring(10))); + core.replay(); + return true; +}; control.prototype._replayAction_fly = function (action) { - if (action.indexOf("fly:") != 0) return false; - var floorId = action.substring(4); - var toIndex = core.floorIds.indexOf(floorId); - if (!core.canUseItem('fly') || (core.flags.flyNearStair && !core.nearStair())) return false; - core.ui.drawFly(toIndex); - if (core.status.replay.speed == 24) { - if (!core.flyTo(floorId, core.replay)) - core.control._replay_error(action); - return true; - } - setTimeout(function () { - if (!core.flyTo(floorId, core.replay)) - core.control._replay_error(action); - }, core.control.__replay_getTimeout()); + if (action.indexOf("fly:") != 0) return false; + var floorId = action.substring(4); + var toIndex = core.floorIds.indexOf(floorId); + if ( + !core.canUseItem("fly") || + (core.flags.flyNearStair && !core.nearStair() && !flags.canMoveFloor) + ) + return false; + core.ui.drawFly(toIndex); + if (core.status.replay.speed == 24) { + if (!core.flyTo(floorId, core.replay)) core.control._replay_error(action); return true; -} + } + setTimeout(function () { + if (!core.flyTo(floorId, core.replay)) core.control._replay_error(action); + }, core.control.__replay_getTimeout()); + return true; +}; control.prototype._replayAction_shop = function (action) { - if (action.indexOf("shop:") != 0) return false; - var shopId = action.substring(5); - if (core.canUseQuickShop(shopId) != null || !core.canOpenShop(shopId)) { - this._replay_error(shopId); - return true; - } - core.openShop(shopId, false); - core.replay(); + if (action.indexOf("shop:") != 0) return false; + var shopId = action.substring(5); + if (core.canUseQuickShop(shopId) != null || !core.canOpenShop(shopId)) { + this._replay_error(shopId); return true; -} + } + core.openShop(shopId, false); + core.replay(); + return true; +}; control.prototype._replayAction_turn = function (action) { - if (action != 'turn' && action.indexOf('turn:') != 0) return false; - if (action == 'turn') core.turnHero(); - else core.turnHero(action.substring(5)); - core.replay(); - return true; -} + if (action != "turn" && action.indexOf("turn:") != 0) return false; + if (action == "turn") core.turnHero(); + else core.turnHero(action.substring(5)); + core.replay(); + return true; +}; control.prototype._replayAction_getNext = function (action) { - if (action != "getNext") return false; - core.getNextItem(); - core.replay(); - return true; -} + if (action != "getNext") return false; + core.getNextItem(); + core.replay(); + return true; +}; control.prototype._replayAction_moveDirectly = function (action) { - if (action.indexOf("move:") != 0) return false; - // 忽略连续的瞬移事件;如果大地图某一边超过计算范围则不合并 - if (!core.hasFlag('poison') && core.status.thisMap.width < 2 * core.bigmap.extend + core._WIDTH_ - && core.status.thisMap.height < 2 * core.bigmap.extend + core._HEIGHT_) { - while (core.status.replay.toReplay.length > 0 && - core.status.replay.toReplay[0].indexOf('move:') == 0) { - core.status.route.push(action); - action = core.status.replay.toReplay.shift(); - } + if (action.indexOf("move:") != 0) return false; + // 忽略连续的瞬移事件;如果大地图某一边超过计算范围则不合并 + if ( + !core.hasFlag("poison") && + core.status.thisMap.width < 2 * core.bigmap.extend + core._WIDTH_ && + core.status.thisMap.height < 2 * core.bigmap.extend + core._HEIGHT_ + ) { + while ( + core.status.replay.toReplay.length > 0 && + core.status.replay.toReplay[0].indexOf("move:") == 0 + ) { + core.status.route.push(action); + action = core.status.replay.toReplay.shift(); } + } - var pos = action.substring(5).split(":"); - var x = parseInt(pos[0]), y = parseInt(pos[1]); - var nowx = core.getHeroLoc('x'), nowy = core.getHeroLoc('y'); - var ignoreSteps = core.canMoveDirectly(x, y); - if (!core.moveDirectly(x, y, ignoreSteps)) return false; - if (core.status.replay.speed == 24) { - core.replay(); - return true; - } - - core.ui.drawArrow('ui', 32 * nowx + 16 - core.bigmap.offsetX, 32 * nowy + 16 - core.bigmap.offsetY, - 32 * x + 16 - core.bigmap.offsetX, 32 * y + 16 - core.bigmap.offsetY, '#FF0000', 3); - var timeout = this.__replay_getTimeout(); - if (ignoreSteps < 10) timeout = timeout * ignoreSteps / 10; - setTimeout(function () { - core.clearMap('ui'); - core.replay(); - }, timeout); + var pos = action.substring(5).split(":"); + var x = parseInt(pos[0]), + y = parseInt(pos[1]); + var nowx = core.getHeroLoc("x"), + nowy = core.getHeroLoc("y"); + var ignoreSteps = core.canMoveDirectly(x, y); + if (!core.moveDirectly(x, y, ignoreSteps)) return false; + if (core.status.replay.speed == 24) { + core.replay(); return true; -} + } + + core.ui.drawArrow( + "ui", + 32 * nowx + 16 - core.bigmap.offsetX, + 32 * nowy + 16 - core.bigmap.offsetY, + 32 * x + 16 - core.bigmap.offsetX, + 32 * y + 16 - core.bigmap.offsetY, + "#FF0000", + 3 + ); + var timeout = this.__replay_getTimeout(); + if (ignoreSteps < 10) timeout = (timeout * ignoreSteps) / 10; + setTimeout(function () { + core.clearMap("ui"); + core.replay(); + }, timeout); + return true; +}; control.prototype._replayAction_key = function (action) { - if (action.indexOf("key:") != 0) return false; - core.actions.keyUp(parseInt(action.substring(4)), false, true); - core.replay(); - return true; -} + if (action.indexOf("key:") != 0) return false; + core.actions.keyUp(parseInt(action.substring(4)), false, true); + core.replay(); + return true; +}; control.prototype._replayAction_click = function (action) { - if (action.indexOf("click:") != 0) return false; - var p = action.split(":"); - if (p.length != 4) return false; - core.actions.doRegisteredAction("onStatusBarClick", parseInt(p[2]), parseInt(p[3]), parseInt(p[1])); - core.replay(); - return true; -} + if (action.indexOf("click:") != 0) return false; + var p = action.split(":"); + if (p.length != 4) return false; + core.actions.doRegisteredAction( + "onStatusBarClick", + parseInt(p[2]), + parseInt(p[3]), + parseInt(p[1]) + ); + core.replay(); + return true; +}; control.prototype._replayAction_ignoreInput = function (action) { - if (action.indexOf('input:') == 0 || action.indexOf('input2:') == 0 || action.indexOf('choices:') == 0 || action.indexOf('random:') == 0) { - console.warn('警告!录像播放中出现了未知的 ' + action + '!'); - core.replay(); - return true; - } - return false; -} - -control.prototype._replayAction_no = function (action) { - if (action != 'no') return false; - core.status.route.push(action); + if ( + action.indexOf("input:") == 0 || + action.indexOf("input2:") == 0 || + action.indexOf("choices:") == 0 || + action.indexOf("random:") == 0 + ) { + console.warn("警告!录像播放中出现了未知的 " + action + "!"); core.replay(); return true; -} + } + return false; +}; + +control.prototype._replayAction_no = function (action) { + if (action != "no") return false; + core.status.route.push(action); + core.replay(); + return true; +}; // ------ 存读档相关 ------ // ////// 自动存档 ////// control.prototype.autosave = function (removeLast) { - if (core.hasFlag('__forbidSave__')) return; - var x = null; - if (removeLast) { - x = core.status.route.pop(); - core.status.route.push("turn:" + core.getHeroLoc('direction')); + if (core.hasFlag("__forbidSave__")) return; + var x = null; + if (removeLast) { + x = core.status.route.pop(); + core.status.route.push("turn:" + core.getHeroLoc("direction")); + } + if (core.status.event.id == "action" && !removeLast) + // 事件中自动存档,读档后是否回到事件触发前 + core.setFlag("__events__", core.clone(core.status.event.data)); + if (core.saves.autosave.data == null) { + core.saves.autosave.data = []; + } + core.saves.autosave.data.splice(core.saves.autosave.now, 0, core.saveData()); + core.saves.autosave.now += 1; + if (core.saves.autosave.data.length > core.saves.autosave.max) { + if (core.saves.autosave.now < core.saves.autosave.max / 2) + core.saves.autosave.data.pop(); + else { + core.saves.autosave.data.shift(); + core.saves.autosave.now = core.saves.autosave.now - 1; } - if (core.status.event.id == 'action' && !removeLast) // 事件中自动存档,读档后是否回到事件触发前 - core.setFlag("__events__", core.clone(core.status.event.data)); - if (core.saves.autosave.data == null) { - core.saves.autosave.data = []; - } - core.saves.autosave.data.splice(core.saves.autosave.now, 0, core.saveData()); - core.saves.autosave.now += 1; - if (core.saves.autosave.data.length > core.saves.autosave.max) { - if (core.saves.autosave.now < core.saves.autosave.max / 2) - core.saves.autosave.data.pop(); - else { - core.saves.autosave.data.shift(); - core.saves.autosave.now = core.saves.autosave.now - 1; - } - } - core.saves.autosave.updated = true; - core.saves.ids[0] = true; - core.removeFlag("__events__"); - if (removeLast) { - core.status.route.pop(); - if (x) core.status.route.push(x); - } -} + } + core.saves.autosave.updated = true; + core.saves.ids[0] = true; + core.removeFlag("__events__"); + if (removeLast) { + core.status.route.pop(); + if (x) core.status.route.push(x); + } +}; /////// 实际进行自动存档 ////// control.prototype.checkAutosave = function () { - if (!core.animateFrame || !core.saves || !core.saves.autosave) return; - core.setLocalStorage('totalTime', core.animateFrame.totalTime); - var autosave = core.saves.autosave; - if (autosave.data == null || !autosave.updated || !autosave.storage) return; - autosave.updated = false; - if (autosave.data.length >= 1) { - core.setLocalForage("autoSave", autosave.data[autosave.now - 1]); - } -} + if (!core.animateFrame || !core.saves || !core.saves.autosave) return; + core.setLocalStorage("totalTime", core.animateFrame.totalTime); + var autosave = core.saves.autosave; + if (autosave.data == null || !autosave.updated || !autosave.storage) return; + autosave.updated = false; + if (autosave.data.length >= 1) { + core.setLocalForage("autoSave", autosave.data[autosave.now - 1]); + } +}; ////// 实际进行存读档事件 ////// control.prototype.doSL = function (id, type) { - switch (type) { - case 'save': this._doSL_save(id); break; - case 'load': this._doSL_load(id, this._doSL_load_afterGet); break; - case 'reload': this._doSL_reload(id, this._doSL_load_afterGet); break; - case 'replayLoad': this._doSL_load(id, this._doSL_replayLoad_afterGet); break; - case 'replayRemain': this._doSL_load(id, this._doSL_replayRemain_afterGet); break; - case 'replaySince': this._doSL_load(id, this._doSL_replaySince_afterGet); break; - } -} + switch (type) { + case "save": + this._doSL_save(id); + break; + case "load": + this._doSL_load(id, this._doSL_load_afterGet); + break; + case "reload": + this._doSL_reload(id, this._doSL_load_afterGet); + break; + case "replayLoad": + this._doSL_load(id, this._doSL_replayLoad_afterGet); + break; + case "replayRemain": + this._doSL_load(id, this._doSL_replayRemain_afterGet); + break; + case "replaySince": + this._doSL_load(id, this._doSL_replaySince_afterGet); + break; + } +}; control.prototype._doSL_save = function (id) { - if (id == 'autoSave') { - core.playSound('操作失败'); - return core.drawTip('不能覆盖自动存档!'); + if (id == "autoSave") { + core.playSound("操作失败"); + return core.drawTip("不能覆盖自动存档!"); + } + // 在事件中的存档 + if (core.status.event.interval != null) + core.setFlag("__events__", core.status.event.interval); + var data = core.saveData(); + if (core.isReplaying() && core.status.replay.toReplay.length > 0) { + data.__toReplay__ = core.encodeRoute(core.status.replay.toReplay); + } + core.setLocalForage( + "save" + id, + data, + function () { + core.saves.saveIndex = id; + core.setLocalStorage("saveIndex", core.saves.saveIndex); + // 恢复事件 + if (!core.events.recoverEvents(core.status.event.interval)) + core.ui.closePanel(); + core.playSound("存档"); + core.drawTip("存档成功!"); + }, + function (err) { + console.error(err); + alert("存档失败,错误信息:\n" + err); } - // 在事件中的存档 - if (core.status.event.interval != null) - core.setFlag("__events__", core.status.event.interval); - var data = core.saveData(); - if (core.isReplaying() && core.status.replay.toReplay.length > 0) { - data.__toReplay__ = core.encodeRoute(core.status.replay.toReplay); - } - core.setLocalForage("save" + id, data, function () { - core.saves.saveIndex = id; - core.setLocalStorage('saveIndex', core.saves.saveIndex); - // 恢复事件 - if (!core.events.recoverEvents(core.status.event.interval)) - core.ui.closePanel(); - core.playSound('存档'); - core.drawTip('存档成功!'); - }, function (err) { - console.error(err); - alert("存档失败,错误信息:\n" + err); - }); - core.removeFlag("__events__"); - return; -} + ); + core.removeFlag("__events__"); + return; +}; control.prototype._doSL_load = function (id, callback) { - if (id == 'autoSave' && core.saves.autosave.data != null) { - core.saves.autosave.now -= 1; - var data = core.saves.autosave.data.splice(core.saves.autosave.now, 1)[0]; - if (core.isPlaying() && !core.status.gameOver) { - core.control.autosave(0); - core.saves.autosave.now -= 1; - } - if (core.saves.autosave.now == 0) { - core.saves.autosave.data.unshift(core.clone(data)); - core.saves.autosave.now += 1; + if (id == "autoSave" && core.saves.autosave.data != null) { + core.saves.autosave.now -= 1; + var data = core.saves.autosave.data.splice(core.saves.autosave.now, 1)[0]; + if (core.isPlaying() && !core.status.gameOver) { + core.control.autosave(0); + core.saves.autosave.now -= 1; + } + if (core.saves.autosave.now == 0) { + core.saves.autosave.data.unshift(core.clone(data)); + core.saves.autosave.now += 1; + } + callback(id, data); + } else { + core.getLocalForage( + id == "autoSave" ? id : "save" + id, + null, + function (data) { + if (id == "autoSave" && data != null) { + core.saves.autosave.data = data; + if (!(core.saves.autosave.data instanceof Array)) { + core.saves.autosave.data = [core.saves.autosave.data]; + } + core.saves.autosave.now = core.saves.autosave.data.length; + return core.control._doSL_load(id, callback); } callback(id, data); - } - else { - core.getLocalForage(id == 'autoSave' ? id : "save" + id, null, function (data) { - if (id == 'autoSave' && data != null) { - core.saves.autosave.data = data; - if (!(core.saves.autosave.data instanceof Array)) { - core.saves.autosave.data = [core.saves.autosave.data]; - } - core.saves.autosave.now = core.saves.autosave.data.length; - return core.control._doSL_load(id, callback); - } - callback(id, data); - }, function (err) { - console.error(err); - alert("无效的存档"); - }) - } - return; -} + }, + function (err) { + console.error(err); + alert("无效的存档"); + } + ); + } + return; +}; control.prototype._doSL_reload = function (id, callback) { - if (core.saves.autosave.data != null && core.saves.autosave.now < core.saves.autosave.data.length) { - var data = core.saves.autosave.data.splice(core.saves.autosave.now, 1)[0]; - core.control.autosave(false); - callback(id, data); - } - return; -} + if ( + core.saves.autosave.data != null && + core.saves.autosave.now < core.saves.autosave.data.length + ) { + var data = core.saves.autosave.data.splice(core.saves.autosave.now, 1)[0]; + core.control.autosave(false); + callback(id, data); + } + return; +}; control.prototype._doSL_load_afterGet = function (id, data) { - if (!data) return alert("无效的存档"); - var _replay = function () { - core.startGame(data.hard, data.hero.flags.__seed__, core.decodeRoute(data.route)); - }; - if (data.version != core.firstData.version) { - core.myconfirm("存档版本不匹配!\n你想回放此存档的录像吗?\n可以随时停止录像播放以继续游戏。", _replay); - return; + if (!data) return alert("无效的存档"); + var _replay = function () { + core.startGame( + data.hard, + data.hero.flags.__seed__, + core.decodeRoute(data.route) + ); + }; + if (data.version != core.firstData.version) { + core.myconfirm( + "存档版本不匹配!\n你想回放此存档的录像吗?\n可以随时停止录像播放以继续游戏。", + _replay + ); + return; + } + if (data.hero.flags.__events__ && data.guid != core.getGuid()) { + core.myconfirm("此存档可能存在风险,你想要播放录像么?", _replay); + return; + } + core.ui.closePanel(); + core.loadData(data, function () { + core.removeFlag("__fromLoad__"); + core.drawTip("读档成功"); + if (id != "autoSave") { + core.saves.saveIndex = id; + core.setLocalStorage("saveIndex", core.saves.saveIndex); } - if (data.hero.flags.__events__ && data.guid != core.getGuid()) { - core.myconfirm("此存档可能存在风险,你想要播放录像么?", _replay); - return; - } - core.ui.closePanel(); - core.loadData(data, function () { - core.removeFlag('__fromLoad__'); - core.drawTip("读档成功"); - if (id != "autoSave") { - core.saves.saveIndex = id; - core.setLocalStorage('saveIndex', core.saves.saveIndex); - } - }); -} + }); +}; control.prototype._doSL_replayLoad_afterGet = function (id, data) { - if (!data) { - core.playSound('操作失败'); - return core.drawTip("无效的存档"); - } - if (data.version != core.firstData.version) { - core.playSound('操作失败'); - return core.drawTip("存档版本不匹配"); - } - if (data.hero.flags.__events__ && data.guid != core.getGuid()) { - core.playSound('操作失败'); - return core.drawTip("此存档可能存在风险,无法读档"); - } - var route = core.subarray(core.status.route, core.decodeRoute(data.route)); - if (route == null) { - core.playSound('操作失败'); - return core.drawTip("无法从此存档回放录像"); - } - core.loadData(data, function () { - core.removeFlag('__fromLoad__'); - core.startReplay(route); - core.drawTip("回退到存档节点"); - }); -} + if (!data) { + core.playSound("操作失败"); + return core.drawTip("无效的存档"); + } + if (data.version != core.firstData.version) { + core.playSound("操作失败"); + return core.drawTip("存档版本不匹配"); + } + if (data.hero.flags.__events__ && data.guid != core.getGuid()) { + core.playSound("操作失败"); + return core.drawTip("此存档可能存在风险,无法读档"); + } + var route = core.subarray(core.status.route, core.decodeRoute(data.route)); + if (route == null) { + core.playSound("操作失败"); + return core.drawTip("无法从此存档回放录像"); + } + core.loadData(data, function () { + core.removeFlag("__fromLoad__"); + core.startReplay(route); + core.drawTip("回退到存档节点"); + }); +}; control.prototype._doSL_replayRemain_afterGet = function (id, data) { - if (!data) { - core.playSound('操作失败'); - return core.drawTip("无效的存档"); - } - var route = core.decodeRoute(data.route); - if (core.status.tempRoute) { - var remainRoute = core.subarray(route, core.status.tempRoute); - if (remainRoute == null) - return alert("无法接续播放录像!\n该存档必须是前一个选择的存档的后续内容。"); - delete core.status.tempRoute; - core.ui.closePanel(); - core.startReplay(remainRoute); - core.drawTip("接续播放录像"); - return; - } - else if (data.floorId != core.status.floorId || data.hero.loc.x != core.getHeroLoc('x') || data.hero.loc.y != core.getHeroLoc('y')) - return alert("楼层或坐标不一致!"); - - core.status.tempRoute = route; + if (!data) { + core.playSound("操作失败"); + return core.drawTip("无效的存档"); + } + var route = core.decodeRoute(data.route); + if (core.status.tempRoute) { + var remainRoute = core.subarray(route, core.status.tempRoute); + if (remainRoute == null) + return alert( + "无法接续播放录像!\n该存档必须是前一个选择的存档的后续内容。" + ); + delete core.status.tempRoute; core.ui.closePanel(); - core.drawText("\t[步骤2]请选择第二个存档。\n\r[yellow]该存档必须是前一个存档的后续。\r\n将尝试播放到此存档。", function () { - core.status.event.id = 'replayRemain'; - core.lockControl(); - var saveIndex = core.saves.saveIndex; - var page = parseInt((saveIndex - 1) / 5), offset = saveIndex - 5 * page; - core.ui._drawSLPanel(10 * page + offset); - }); -} + core.startReplay(remainRoute); + core.drawTip("接续播放录像"); + return; + } else if ( + data.floorId != core.status.floorId || + data.hero.loc.x != core.getHeroLoc("x") || + data.hero.loc.y != core.getHeroLoc("y") + ) + return alert("楼层或坐标不一致!"); + + core.status.tempRoute = route; + core.ui.closePanel(); + core.drawText( + "\t[步骤2]请选择第二个存档。\n\r[yellow]该存档必须是前一个存档的后续。\r\n将尝试播放到此存档。", + function () { + core.status.event.id = "replayRemain"; + core.lockControl(); + var saveIndex = core.saves.saveIndex; + var page = parseInt((saveIndex - 1) / 5), + offset = saveIndex - 5 * page; + core.ui._drawSLPanel(10 * page + offset); + } + ); +}; control.prototype._doSL_replaySince_afterGet = function (id, data) { - if (data.floorId != core.status.floorId || data.hero.loc.x != core.getHeroLoc('x') || data.hero.loc.y != core.getHeroLoc('y')) - return alert("楼层或坐标不一致!"); - if (!data.__toReplay__) return alert('该存档没有剩余录像!'); - core.ui.closePanel(); - core.startReplay(core.decodeRoute(data.__toReplay__)); - core.drawTip("播放存档剩余录像"); - return; -} + if ( + data.floorId != core.status.floorId || + data.hero.loc.x != core.getHeroLoc("x") || + data.hero.loc.y != core.getHeroLoc("y") + ) + return alert("楼层或坐标不一致!"); + if (!data.__toReplay__) return alert("该存档没有剩余录像!"); + core.ui.closePanel(); + core.startReplay(core.decodeRoute(data.__toReplay__)); + core.drawTip("播放存档剩余录像"); + return; +}; ////// 同步存档到服务器 ////// control.prototype.syncSave = function (type) { - core.ui.drawWaiting("正在同步,请稍候..."); - var callback = function (saves) { - core.control._syncSave_http(type, saves); - } - if (type == 'all') core.getAllSaves(callback); - else core.getSave(core.saves.saveIndex, callback); -} + core.ui.drawWaiting("正在同步,请稍候..."); + var callback = function (saves) { + core.control._syncSave_http(type, saves); + }; + if (type == "all") core.getAllSaves(callback); + else core.getSave(core.saves.saveIndex, callback); +}; control.prototype._syncSave_http = function (type, saves) { - if (!saves) return core.drawText("没有要同步的存档"); - var formData = new FormData(); - formData.append('type', 'save'); - formData.append('name', core.firstData.name); - formData.append('data', LZString.compressToBase64(JSON.stringify(saves))); - formData.append('shorten', '1'); + if (!saves) return core.drawText("没有要同步的存档"); + var formData = new FormData(); + formData.append("type", "save"); + formData.append("name", core.firstData.name); + formData.append("data", LZString.compressToBase64(JSON.stringify(saves))); + formData.append("shorten", "1"); - core.http("POST", "/games/sync.php", formData, function (data) { - var response = JSON.parse(data); - if (response.code < 0) { - core.drawText("出错啦!\n无法同步存档到服务器。\n错误原因:" + response.msg); - } - else { - core.drawText((type == 'all' ? "所有存档" : "存档" + core.saves.saveIndex) + "同步成功!\n\n您的存档编号+密码: \r[yellow]" - + response.code + response.msg - + "\r\n\n请牢记以上信息(如截图等),在从服务器\n同步存档时使用。\n\r[yellow]另外请注意,存档同步只会保存一个月的时间。\r") - } - }, function (e) { - core.drawText("出错啦!\n无法同步存档到服务器。\n错误原因:" + e); - }) -} + core.http( + "POST", + "/games/sync.php", + formData, + function (data) { + var response = JSON.parse(data); + if (response.code < 0) { + core.drawText( + "出错啦!\n无法同步存档到服务器。\n错误原因:" + response.msg + ); + } else { + core.drawText( + (type == "all" ? "所有存档" : "存档" + core.saves.saveIndex) + + "同步成功!\n\n您的存档编号+密码: \r[yellow]" + + response.code + + response.msg + + "\r\n\n请牢记以上信息(如截图等),在从服务器\n同步存档时使用。\n\r[yellow]另外请注意,存档同步只会保存一个月的时间。\r" + ); + } + }, + function (e) { + core.drawText("出错啦!\n无法同步存档到服务器。\n错误原因:" + e); + } + ); +}; ////// 从服务器加载存档 ////// control.prototype.syncLoad = function () { - core.myprompt("请输入存档编号+密码", null, function (idpassword) { - if (!idpassword) return core.ui._drawSyncSave(); - if (!/^\d{6}\w{4}$/.test(idpassword) && !/^\d{4}\w{3}$/.test(idpassword)) { - core.drawText("不合法的存档编号+密码!"); - return; - } - core.ui.drawWaiting("正在同步,请稍候..."); - if (idpassword.length == 7) { - core.control._syncLoad_http(idpassword.substring(0, 4), idpassword.substring(4)); - } else { - core.control._syncLoad_http(idpassword.substring(0, 6), idpassword.substring(6)); - } - }); -} + core.myprompt("请输入存档编号+密码", null, function (idpassword) { + if (!idpassword) return core.ui._drawSyncSave(); + if (!/^\d{6}\w{4}$/.test(idpassword) && !/^\d{4}\w{3}$/.test(idpassword)) { + core.drawText("不合法的存档编号+密码!"); + return; + } + core.ui.drawWaiting("正在同步,请稍候..."); + if (idpassword.length == 7) { + core.control._syncLoad_http( + idpassword.substring(0, 4), + idpassword.substring(4) + ); + } else { + core.control._syncLoad_http( + idpassword.substring(0, 6), + idpassword.substring(6) + ); + } + }); +}; control.prototype._syncLoad_http = function (id, password) { - var formData = new FormData(); - formData.append('type', 'load'); - formData.append('name', core.firstData.name); - formData.append('id', id); - formData.append('password', password); + var formData = new FormData(); + formData.append("type", "load"); + formData.append("name", core.firstData.name); + formData.append("id", id); + formData.append("password", password); - core.http("POST", "/games/sync.php", formData, function (data) { - var response = JSON.parse(data); - if (response.code == 0) { - var msg = null; - try { - msg = JSON.parse(LZString.decompressFromBase64(response.msg)); - } catch (e) { } - if (!msg) { - try { - msg = JSON.parse(response.msg); - } catch (e) { } - } - if (msg) { - core.control._syncLoad_write(msg); - } else { - core.drawText("出错啦!\n存档解析失败!"); - } + core.http( + "POST", + "/games/sync.php", + formData, + function (data) { + var response = JSON.parse(data); + if (response.code == 0) { + var msg = null; + try { + msg = JSON.parse(LZString.decompressFromBase64(response.msg)); + } catch (e) {} + if (!msg) { + try { + msg = JSON.parse(response.msg); + } catch (e) {} } - else { - core.drawText("出错啦!\n无法从服务器同步存档。\n错误原因:" + response.msg); + if (msg) { + core.control._syncLoad_write(msg); + } else { + core.drawText("出错啦!\n存档解析失败!"); } - }, function (e) { - core.drawText("出错啦!\n无法从服务器同步存档。\n错误原因:" + e); - }); -} + } else { + core.drawText( + "出错啦!\n无法从服务器同步存档。\n错误原因:" + response.msg + ); + } + }, + function (e) { + core.drawText("出错啦!\n无法从服务器同步存档。\n错误原因:" + e); + } + ); +}; control.prototype._syncLoad_write = function (data) { - if (data instanceof Array) { - core.status.event.selection = 1; - core.ui.drawConfirmBox("所有本地存档都将被覆盖,确认?", function () { - for (var i = 1; i <= 5 * (main.savePages || 30); i++) { - if (i <= data.length) - core.setLocalForage("save" + i, data[i - 1]); - else if (core.saves.ids[i]) - core.removeLocalForage("save" + i); - } - core.ui.closePanel(); - core.drawText("同步成功!\n你的本地所有存档均已被覆盖。"); - }, function () { - core.status.event.selection = 0; - core.ui._drawSyncSave(); - }); - } - else { - // 只覆盖单存档 - core.setLocalForage("save" + core.saves.saveIndex, data, function () { - core.drawText("同步成功!\n单存档已覆盖至存档" + core.saves.saveIndex); - }); - } -} + if (data instanceof Array) { + core.status.event.selection = 1; + core.ui.drawConfirmBox( + "所有本地存档都将被覆盖,确认?", + function () { + for (var i = 1; i <= 5 * (main.savePages || 30); i++) { + if (i <= data.length) core.setLocalForage("save" + i, data[i - 1]); + else if (core.saves.ids[i]) core.removeLocalForage("save" + i); + } + core.ui.closePanel(); + core.drawText("同步成功!\n你的本地所有存档均已被覆盖。"); + }, + function () { + core.status.event.selection = 0; + core.ui._drawSyncSave(); + } + ); + } else { + // 只覆盖单存档 + core.setLocalForage("save" + core.saves.saveIndex, data, function () { + core.drawText("同步成功!\n单存档已覆盖至存档" + core.saves.saveIndex); + }); + } +}; ////// 存档到本地 ////// control.prototype.saveData = function () { - return this.controldata.saveData(); -} + return this.controldata.saveData(); +}; ////// 从本地读档 ////// control.prototype.loadData = function (data, callback) { - return this.controldata.loadData(data, callback); -} + return this.controldata.loadData(data, callback); +}; control.prototype.getSave = function (index, callback) { - if (index == 0) { - // --- 自动存档先从缓存中获取 - if (core.saves.autosave.data != null) - callback(core.saves.autosave.data); - else { - core.getLocalForage("autoSave", null, function (data) { - if (data != null) { - core.saves.autosave.data = data; - if (!(core.saves.autosave.data instanceof Array)) { - core.saves.autosave.data = [core.saves.autosave.data]; - } - core.saves.autosave.now = core.saves.autosave.data.length; - } - callback(core.saves.autosave.data); - }, function (err) { - console.error(err); - callback(null); - }); + if (index == 0) { + // --- 自动存档先从缓存中获取 + if (core.saves.autosave.data != null) callback(core.saves.autosave.data); + else { + core.getLocalForage( + "autoSave", + null, + function (data) { + if (data != null) { + core.saves.autosave.data = data; + if (!(core.saves.autosave.data instanceof Array)) { + core.saves.autosave.data = [core.saves.autosave.data]; + } + core.saves.autosave.now = core.saves.autosave.data.length; + } + callback(core.saves.autosave.data); + }, + function (err) { + console.error(err); + callback(null); } - return; + ); } - core.getLocalForage("save" + index, null, function (data) { - if (callback) callback(data); - }, function (err) { - console.error(err); - if (callback) callback(null); - }); -} + return; + } + core.getLocalForage( + "save" + index, + null, + function (data) { + if (callback) callback(data); + }, + function (err) { + console.error(err); + if (callback) callback(null); + } + ); +}; control.prototype.getSaves = function (ids, callback) { - if (!(ids instanceof Array)) return this.getSave(ids, callback); - var count = ids.length, data = {}; - for (var i = 0; i < ids.length; ++i) { - (function (i) { - core.getSave(ids[i], function (result) { - data[i] = result; - if (Object.keys(data).length == count) - callback(data); - }) - })(i); - } -} + if (!(ids instanceof Array)) return this.getSave(ids, callback); + var count = ids.length, + data = {}; + for (var i = 0; i < ids.length; ++i) { + (function (i) { + core.getSave(ids[i], function (result) { + data[i] = result; + if (Object.keys(data).length == count) callback(data); + }); + })(i); + } +}; control.prototype.getAllSaves = function (callback) { - var ids = Object.keys(core.saves.ids).filter(function (x) { return x != 0; }) - .sort(function (a, b) { return a - b; }), saves = []; - this.getSaves(ids, function (data) { - for (var i = 0; i < ids.length; ++i) { - if (data[i] != null) - saves.push(data[i]); - } - callback(saves); - }); -} + var ids = Object.keys(core.saves.ids) + .filter(function (x) { + return x != 0; + }) + .sort(function (a, b) { + return a - b; + }), + saves = []; + this.getSaves(ids, function (data) { + for (var i = 0; i < ids.length; ++i) { + if (data[i] != null) saves.push(data[i]); + } + callback(saves); + }); +}; ////// 获得所有存在存档的存档位 ////// control.prototype.getSaveIndexes = function (callback) { - var indexes = {}; - core.keysLocalForage(function (err, keys) { - if (err) { - console.error(err); - return callback(indexes); - } - keys.forEach(function (key) { - core.control._getSaveIndexes_getIndex(indexes, key); - }); - callback(indexes); + var indexes = {}; + core.keysLocalForage(function (err, keys) { + if (err) { + console.error(err); + return callback(indexes); + } + keys.forEach(function (key) { + core.control._getSaveIndexes_getIndex(indexes, key); }); -} + callback(indexes); + }); +}; control.prototype._getSaveIndexes_getIndex = function (indexes, name) { - var e = new RegExp('^' + core.firstData.name + "_(save\\d+|autoSave)$").exec(name); - if (e) { - if (e[1] == 'autoSave') indexes[0] = true; - else indexes[parseInt(e[1].substring(4))] = true; - } -} + var e = new RegExp("^" + core.firstData.name + "_(save\\d+|autoSave)$").exec( + name + ); + if (e) { + if (e[1] == "autoSave") indexes[0] = true; + else indexes[parseInt(e[1].substring(4))] = true; + } +}; ////// 判断某个存档位是否存在存档 ////// control.prototype.hasSave = function (index) { - return core.saves.ids[index] || false; -} + return core.saves.ids[index] || false; +}; ////// 删除某个存档 control.prototype.removeSave = function (index, callback) { - if (index == 0 || index == "autoSave") { - index = "autoSave"; - core.removeLocalForage(index, function () { - core.saves.autosave.data = null; - core.saves.autosave.updated = false; - if (callback) callback(); - }); - return; - } - core.removeLocalForage("save" + index, function () { - core.saves.favorite = core.saves.favorite.filter(function (i) { return core.hasSave(i); }); - delete core.saves.favoriteName[index]; - core.control._updateFavoriteSaves(); - if (callback) callback(); - }, function () { - core.playSound('操作失败'); - core.drawTip("无法删除存档!"); - if (callback) callback(); + if (index == 0 || index == "autoSave") { + index = "autoSave"; + core.removeLocalForage(index, function () { + core.saves.autosave.data = null; + core.saves.autosave.updated = false; + if (callback) callback(); }); -} + return; + } + core.removeLocalForage( + "save" + index, + function () { + core.saves.favorite = core.saves.favorite.filter(function (i) { + return core.hasSave(i); + }); + delete core.saves.favoriteName[index]; + core.control._updateFavoriteSaves(); + if (callback) callback(); + }, + function () { + core.playSound("操作失败"); + core.drawTip("无法删除存档!"); + if (callback) callback(); + } + ); +}; ////// 读取收藏信息 control.prototype._loadFavoriteSaves = function () { - core.saves.favorite = core.getLocalStorage("favorite", []); - // --- 移除不存在的收藏 - core.saves.favorite = core.saves.favorite.filter(function (i) { return core.hasSave(i); }); - core.saves.favoriteName = core.getLocalStorage("favoriteName", {}); -} + core.saves.favorite = core.getLocalStorage("favorite", []); + // --- 移除不存在的收藏 + core.saves.favorite = core.saves.favorite.filter(function (i) { + return core.hasSave(i); + }); + core.saves.favoriteName = core.getLocalStorage("favoriteName", {}); +}; control.prototype._updateFavoriteSaves = function () { - core.setLocalStorage("favorite", core.saves.favorite); - core.setLocalStorage("favoriteName", core.saves.favoriteName); -} + core.setLocalStorage("favorite", core.saves.favorite); + core.setLocalStorage("favoriteName", core.saves.favoriteName); +}; // ------ 属性,状态,位置,buff,变量,锁定控制等 ------ // ////// 设置勇士属性 ////// control.prototype.setStatus = function (name, value) { - if (!core.status.hero) return; - if (name == 'x' || name == 'y' || name == 'direction') - this.setHeroLoc(name, value); - else - core.status.hero[name] = value; -} + if (!core.status.hero) return; + if (name == "x" || name == "y" || name == "direction") + this.setHeroLoc(name, value); + else core.status.hero[name] = value; +}; ////// 增减勇士属性 ////// control.prototype.addStatus = function (name, value) { - this.setStatus(name, this.getStatus(name) + value); -} + this.setStatus(name, this.getStatus(name) + value); +}; ////// 获得勇士属性 ////// control.prototype.getStatus = function (name) { - if (!core.status.hero) return null; - if (name == 'x' || name == 'y' || name == 'direction') - return this.getHeroLoc(name); - if (main.mode == 'editor' && !core.hasFlag('__statistics__')) { - return data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.firstData.hero[name]; - } - return core.status.hero[name]; -} + if (!core.status.hero) return null; + if (name == "x" || name == "y" || name == "direction") + return this.getHeroLoc(name); + if (main.mode == "editor" && !core.hasFlag("__statistics__")) { + return data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.firstData.hero[name]; + } + return core.status.hero[name]; +}; ////// 从status中获得属性,如果不存在则从勇士属性中获取 ////// control.prototype.getStatusOrDefault = function (status, name) { - if (status && name in status) - return Math.floor(status[name]); - return Math.floor(this.getStatus(name)); -} + if (status && name in status) return Math.floor(status[name]); + return Math.floor(this.getStatus(name)); +}; ////// 获得勇士实际属性(增幅后的) ////// control.prototype.getRealStatus = function (name) { - return this.getRealStatusOrDefault(null, name); -} + return this.getRealStatusOrDefault(null, name); +}; ////// 从status中获得实际属性(增幅后的),如果不存在则从勇士属性中获取 ////// control.prototype.getRealStatusOrDefault = function (status, name) { - return Math.floor(this.getStatusOrDefault(status, name) * this.getBuff(name)); -} + return Math.floor(this.getStatusOrDefault(status, name) * this.getBuff(name)); +}; ////// 获得勇士原始属性(无装备和衰弱影响) ////// control.prototype.getNakedStatus = function (name) { - var value = this.getStatus(name); - if (value == null) return value; - // 装备增幅 - core.status.hero.equipment.forEach(function (v) { - if (!v || !(core.material.items[v] || {}).equip) return; - value -= core.material.items[v].equip.value[name] || 0; - }); - // 衰弱扣除 - if (core.hasFlag('weak') && core.values.weakValue >= 1 && (name == 'atk' || name == 'def')) { - value += core.values.weakValue; - } - return value; -} + var value = this.getStatus(name); + if (value == null) return value; + // 装备增幅 + core.status.hero.equipment.forEach(function (v) { + if (!v || !(core.material.items[v] || {}).equip) return; + value -= core.material.items[v].equip.value[name] || 0; + }); + // 衰弱扣除 + if ( + core.hasFlag("weak") && + core.values.weakValue >= 1 && + (name == "atk" || name == "def") + ) { + value += core.values.weakValue; + } + return value; +}; ////// 获得某个属性的名字 ////// control.prototype.getStatusLabel = function (name) { - if (this.controldata.getStatusLabel) { - return this.controldata.getStatusLabel(name) || name; - } - return { - name: "名称", lv: "等级", hpmax: "生命上限", hp: "生命", manamax: "魔力上限", mana: "魔力", - atk: "攻击", def: "防御", mdef: "护盾", money: "金币", exp: "经验", point: "加点", steps: "步数" - }[name] || name; -} + if (this.controldata.getStatusLabel) { + return this.controldata.getStatusLabel(name) || name; + } + return ( + { + name: "名称", + lv: "等级", + hpmax: "生命上限", + hp: "生命", + manamax: "魔力上限", + mana: "魔力", + atk: "攻击", + def: "防御", + mdef: "护盾", + money: "金币", + exp: "经验", + point: "加点", + steps: "步数", + }[name] || name + ); +}; ////// 设置某个属性的增幅值 ////// control.prototype.setBuff = function (name, value) { - // 仅保留三位有效buff值 - value = parseFloat(value.toFixed(3)); - this.setFlag('__' + name + '_buff__', value); -} + // 仅保留三位有效buff值 + value = parseFloat(value.toFixed(3)); + this.setFlag("__" + name + "_buff__", value); +}; ////// 加减某个属性的增幅值 ////// control.prototype.addBuff = function (name, value) { - var buff = this.getBuff(name) + value; - // 仅保留三位有效buff值 - buff = parseFloat(buff.toFixed(3)); - this.setFlag('__' + name + '_buff__', buff); -} + var buff = this.getBuff(name) + value; + // 仅保留三位有效buff值 + buff = parseFloat(buff.toFixed(3)); + this.setFlag("__" + name + "_buff__", buff); +}; ////// 获得某个属性的增幅值 ////// control.prototype.getBuff = function (name) { - return core.getFlag('__' + name + '_buff__', 1); -} + return core.getFlag("__" + name + "_buff__", 1); +}; ////// 获得或移除毒衰咒效果 ////// control.prototype.triggerDebuff = function (action, type) { - return this.controldata.triggerDebuff(action, type); -} + return this.controldata.triggerDebuff(action, type); +}; ////// 设置勇士的位置 ////// control.prototype.setHeroLoc = function (name, value, noGather) { - if (!core.status.hero) return; - core.status.hero.loc[name] = value; - if ((name == 'x' || name == 'y') && !noGather) { - this.gatherFollowers(); - } - core.ui.drawStatusBar(); -} + if (!core.status.hero) return; + core.status.hero.loc[name] = value; + if ((name == "x" || name == "y") && !noGather) { + this.gatherFollowers(); + } + core.ui.drawStatusBar(); +}; ////// 获得勇士的位置 ////// control.prototype.getHeroLoc = function (name) { - if (!core.status.hero) return; - if (main.mode == 'editor') { - if (name == null) return data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.firstData.hero.loc; - return data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.firstData.hero.loc[name]; - } - if (name == null) return core.status.hero.loc; - return core.status.hero.loc[name]; -} + if (!core.status.hero) return; + if (main.mode == "editor") { + if (name == null) + return data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.firstData.hero.loc; + return data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.firstData.hero.loc[name]; + } + if (name == null) return core.status.hero.loc; + return core.status.hero.loc[name]; +}; ////// 获得某个等级的名称 ////// control.prototype.getLvName = function (lv) { - if (!core.status.hero) return null; - if (lv == null) lv = core.status.hero.lv; - return ((core.firstData.levelUp || [])[lv - 1] || {}).title || lv; -} + if (!core.status.hero) return null; + if (lv == null) lv = core.status.hero.lv; + return ((core.firstData.levelUp || [])[lv - 1] || {}).title || lv; +}; ////// 获得下个等级所需经验;如果不存在下个等级,返回null。 ////// control.prototype.getNextLvUpNeed = function () { - if (!core.status.hero) return null; - if (core.status.hero.lv >= core.firstData.levelUp.length) return null; - var need = core.calValue(core.firstData.levelUp[core.status.hero.lv].need); - if (core.flags.statusBarItems.indexOf('levelUpLeftMode') >= 0) - return Math.max(need - core.getStatus('exp'), 0); - else return need; -} + if (!core.status.hero) return null; + if (core.status.hero.lv >= core.firstData.levelUp.length) return null; + var need = core.calValue(core.firstData.levelUp[core.status.hero.lv].need); + if (core.flags.statusBarItems.indexOf("levelUpLeftMode") >= 0) + return Math.max(need - core.getStatus("exp"), 0); + else return need; +}; ////// 设置某个自定义变量或flag ////// control.prototype.setFlag = function (name, value) { - if (value == null) return this.removeFlag(name); - if (!core.status.hero) return; - core.status.hero.flags[name] = value; -} + if (value == null) return this.removeFlag(name); + if (!core.status.hero) return; + core.status.hero.flags[name] = value; +}; ////// 增加某个flag数值 ////// control.prototype.addFlag = function (name, value) { - if (!core.status.hero) return; - core.setFlag(name, core.getFlag(name, 0) + value); -} + if (!core.status.hero) return; + core.setFlag(name, core.getFlag(name, 0) + value); +}; ////// 获得某个自定义变量或flag ////// control.prototype.getFlag = function (name, defaultValue) { - if (!core.status.hero) return defaultValue; - var value = core.status.hero.flags[name]; - return value != null ? value : defaultValue; -} + if (!core.status.hero) return defaultValue; + var value = core.status.hero.flags[name]; + return value != null ? value : defaultValue; +}; ////// 是否存在某个自定义变量或flag,且值为true ////// control.prototype.hasFlag = function (name) { - return !!core.getFlag(name); -} + return !!core.getFlag(name); +}; ////// 删除某个自定义变量或flag ////// control.prototype.removeFlag = function (name) { - if (!core.status.hero) return; - delete core.status.hero.flags[name]; -} + if (!core.status.hero) return; + delete core.status.hero.flags[name]; +}; ////// 获得某个点的独立开关 ////// control.prototype.getSwitch = function (x, y, floorId, name, defaultValue) { - var prefix = [floorId || core.status.floorId || ":f", x != null ? x : "x", y != null ? y : "y"].join("@"); - return this.getFlag(prefix + "@" + name, defaultValue); -} + var prefix = [ + floorId || core.status.floorId || ":f", + x != null ? x : "x", + y != null ? y : "y", + ].join("@"); + return this.getFlag(prefix + "@" + name, defaultValue); +}; ////// 设置某个点的独立开关 ////// control.prototype.setSwitch = function (x, y, floorId, name, value) { - var prefix = [floorId || core.status.floorId || ":f", x != null ? x : "x", y != null ? y : "y"].join("@"); - return this.setFlag(prefix + "@" + name, value); -} + var prefix = [ + floorId || core.status.floorId || ":f", + x != null ? x : "x", + y != null ? y : "y", + ].join("@"); + return this.setFlag(prefix + "@" + name, value); +}; ////// 增加某个点的独立开关 ////// control.prototype.addSwitch = function (x, y, floorId, name, value) { - var prefix = [floorId || core.status.floorId || ":f", x != null ? x : "x", y != null ? y : "y"].join("@"); - return this.addFlag(prefix + "@" + name, value); -} + var prefix = [ + floorId || core.status.floorId || ":f", + x != null ? x : "x", + y != null ? y : "y", + ].join("@"); + return this.addFlag(prefix + "@" + name, value); +}; ////// 判定某个点的独立开关 ////// control.prototype.hasSwitch = function (x, y, floorId, name) { - var prefix = [floorId || core.status.floorId || ":f", x != null ? x : "x", y != null ? y : "y"].join("@"); - return this.hasFlag(prefix + "@" + name); -} + var prefix = [ + floorId || core.status.floorId || ":f", + x != null ? x : "x", + y != null ? y : "y", + ].join("@"); + return this.hasFlag(prefix + "@" + name); +}; ////// 删除某个点的独立开关 ////// control.prototype.removeSwitch = function (x, y, floorId, name) { - var prefix = [floorId || core.status.floorId || ":f", x != null ? x : "x", y != null ? y : "y"].join("@"); - return this.removeFlag(prefix + "@" + name); -} + var prefix = [ + floorId || core.status.floorId || ":f", + x != null ? x : "x", + y != null ? y : "y", + ].join("@"); + return this.removeFlag(prefix + "@" + name); +}; ////// 锁定状态栏,常常用于事件处理 ////// control.prototype.lockControl = function () { - core.status.lockControl = true; -} + core.status.lockControl = true; +}; ////// 解锁状态栏 ////// control.prototype.unlockControl = function () { - core.status.lockControl = false; -} + core.status.lockControl = false; +}; ////// 开启debug模式 ////// control.prototype.debug = function () { - core.setFlag('debug', true); - core.drawText("\t[调试模式开启]此模式下按住Ctrl键(或Ctrl+Shift键)可以穿墙并忽略一切事件。\n此模式下将无法上传成绩。"); -} + core.setFlag("debug", true); + core.drawText( + "\t[调试模式开启]此模式下按住Ctrl键(或Ctrl+Shift键)可以穿墙并忽略一切事件。\n此模式下将无法上传成绩。" + ); +}; control.prototype._bindRoutePush = function () { - core.status.route.push = function (element) { - // 忽视移动、转向、瞬移 - if (["up", "down", "left", "right", "turn"].indexOf(element) < 0 && !element.startsWith("move:")) { - core.clearRouteFolding(); - } - Array.prototype.push.call(core.status.route, element); + core.status.route.push = function (element) { + // 忽视移动、转向、瞬移 + if ( + ["up", "down", "left", "right", "turn"].indexOf(element) < 0 && + !element.startsWith("move:") + ) { + core.clearRouteFolding(); } -} + Array.prototype.push.call(core.status.route, element); + }; +}; ////// 清除录像折叠信息 ////// control.prototype.clearRouteFolding = function () { - core.status.routeFolding = {}; -} + core.status.routeFolding = {}; +}; ////// 检查录像折叠 ////// control.prototype.checkRouteFolding = function () { - // 未开启、未开始游戏、录像播放中、正在事件中:不执行 - if (!core.flags.enableRouteFolding || !core.isPlaying() || core.isReplaying() || core.status.event.id) { - return this.clearRouteFolding(); + // 未开启、未开始游戏、录像播放中、正在事件中:不执行 + if ( + !core.flags.enableRouteFolding || + !core.isPlaying() || + core.isReplaying() || + core.status.event.id + ) { + return this.clearRouteFolding(); + } + var hero = core.clone(core.status.hero, function (name, value) { + return name != "steps" && typeof value == "number"; + }); + var index = [ + core.getHeroLoc("x"), + core.getHeroLoc("y"), + core.getHeroLoc("direction").charAt(0), + ].join(","); + core.status.routeFolding = core.status.routeFolding || {}; + if (core.status.routeFolding[index]) { + var one = core.status.routeFolding[index]; + if (core.same(one.hero, hero) && one.length < core.status.route.length) { + Object.keys(core.status.routeFolding).forEach(function (v) { + if (core.status.routeFolding[v].length >= one.length) + delete core.status.routeFolding[v]; + }); + core.status.route = core.status.route.slice(0, one.length); + this._bindRoutePush(); } - var hero = core.clone(core.status.hero, function (name, value) { - return name != 'steps' && typeof value == 'number'; - }); - var index = [core.getHeroLoc('x'), core.getHeroLoc('y'), core.getHeroLoc('direction').charAt(0)].join(','); - core.status.routeFolding = core.status.routeFolding || {}; - if (core.status.routeFolding[index]) { - var one = core.status.routeFolding[index]; - if (core.same(one.hero, hero) && one.length < core.status.route.length) { - Object.keys(core.status.routeFolding).forEach(function (v) { - if (core.status.routeFolding[v].length >= one.length) delete core.status.routeFolding[v]; - }); - core.status.route = core.status.route.slice(0, one.length); - this._bindRoutePush(); - } - } - core.status.routeFolding[index] = { hero: hero, length: core.status.route.length }; -} + } + core.status.routeFolding[index] = { + hero: hero, + length: core.status.route.length, + }; +}; // ------ 天气,色调,BGM ------ // control.prototype.getMappedName = function (name) { - return core.getFlag('__nameMap__', {})[name] || (main.nameMap || {})[name] || name; -} + return ( + core.getFlag("__nameMap__", {})[name] || (main.nameMap || {})[name] || name + ); +}; ////// 更改天气效果 ////// control.prototype.setWeather = function (type, level) { - // 非雨雪 - if (type == null || !this.weathers[type]) { - core.deleteCanvas('weather') - core.animateFrame.weather.type = null; - core.animateFrame.weather.nodes = []; - return; - } - if (level == null) level = core.animateFrame.weather.level; - level = core.clamp(parseInt(level) || 5, 1, 10); - // 当前天气:则忽略 - if (type == core.animateFrame.weather.type && level == core.animateFrame.weather.level) return; - - // 计算当前的宽高 - core.createCanvas('weather', 0, 0, core._PX_, core._PY_, 80); - core.setOpacity('weather', 1.0); - core.animateFrame.weather.type = type; - core.animateFrame.weather.level = level; + // 非雨雪 + if (type == null || !this.weathers[type]) { + core.deleteCanvas("weather"); + core.animateFrame.weather.type = null; core.animateFrame.weather.nodes = []; - try { - core.doFunc(this.weathers[type].initFunc, this, level); - } catch (e) { - console.error(e); - console.error("ERROR in weather[" + type + "]:已自动注销该项。"); - core.unregisterWeather(type); - } -} + return; + } + if (level == null) level = core.animateFrame.weather.level; + level = core.clamp(parseInt(level) || 5, 1, 10); + // 当前天气:则忽略 + if ( + type == core.animateFrame.weather.type && + level == core.animateFrame.weather.level + ) + return; + + // 计算当前的宽高 + core.createCanvas("weather", 0, 0, core._PX_, core._PY_, 80); + core.setOpacity("weather", 1.0); + core.animateFrame.weather.type = type; + core.animateFrame.weather.level = level; + core.animateFrame.weather.nodes = []; + try { + core.doFunc(this.weathers[type].initFunc, this, level); + } catch (e) { + console.error(e); + console.error("ERROR in weather[" + type + "]:已自动注销该项。"); + core.unregisterWeather(type); + } +}; ////// 注册一个天气 ////// // name为天气类型,如 sun, rain, snow 等 // initFunc 为设置为此天气时的初始化,接受level参数 // frameFunc 为该天气下每帧的效果,接受和timestamp参数(从页面加载完毕到当前经过的时间) control.prototype.registerWeather = function (name, initFunc, frameFunc) { - this.unregisterWeather(name); - this.weathers[name] = { initFunc: initFunc, frameFunc: frameFunc }; -} + this.unregisterWeather(name); + this.weathers[name] = { initFunc: initFunc, frameFunc: frameFunc }; +}; ////// 取消注册一个天气 ////// control.prototype.unregisterWeather = function (name) { - delete this.weathers[name]; - if (core.animateFrame.weather.type == name) { - this.setWeather(null); - } -} + delete this.weathers[name]; + if (core.animateFrame.weather.type == name) { + this.setWeather(null); + } +}; control.prototype._weather_rain = function (level) { - var number = level * parseInt(20 * core.bigmap.width * core.bigmap.height / (core._WIDTH_ * core._HEIGHT_)); - for (var a = 0; a < number; a++) { - core.animateFrame.weather.nodes.push({ - 'x': Math.random() * core.bigmap.width * 32, - 'y': Math.random() * core.bigmap.height * 32, - 'l': Math.random() * 2.5, - 'xs': -4 + Math.random() * 4 + 2, - 'ys': Math.random() * 10 + 10 - }) - } -} + var number = + level * + parseInt( + (20 * core.bigmap.width * core.bigmap.height) / + (core._WIDTH_ * core._HEIGHT_) + ); + for (var a = 0; a < number; a++) { + core.animateFrame.weather.nodes.push({ + x: Math.random() * core.bigmap.width * 32, + y: Math.random() * core.bigmap.height * 32, + l: Math.random() * 2.5, + xs: -4 + Math.random() * 4 + 2, + ys: Math.random() * 10 + 10, + }); + } +}; control.prototype._weather_snow = function (level) { - var number = level * parseInt(20 * core.bigmap.width * core.bigmap.height / (core._WIDTH_ * core._HEIGHT_)); - for (var a = 0; a < number; a++) { - core.animateFrame.weather.nodes.push({ - 'x': Math.random() * core.bigmap.width * 32, - 'y': Math.random() * core.bigmap.height * 32, - 'r': Math.random() * 5 + 1, - 'd': Math.random() * Math.min(level, 200), - }) - } -} + var number = + level * + parseInt( + (20 * core.bigmap.width * core.bigmap.height) / + (core._WIDTH_ * core._HEIGHT_) + ); + for (var a = 0; a < number; a++) { + core.animateFrame.weather.nodes.push({ + x: Math.random() * core.bigmap.width * 32, + y: Math.random() * core.bigmap.height * 32, + r: Math.random() * 5 + 1, + d: Math.random() * Math.min(level, 200), + }); + } +}; control.prototype._weather_fog = function (level) { - if (!core.animateFrame.weather.fog) return; - core.animateFrame.weather.nodes = [{ - 'image': core.animateFrame.weather.fog, - 'level': 40 * level, - 'x': 0, - 'y': -core._PY_ / 2, - 'dx': -Math.random() * 1.5, - 'dy': Math.random(), - 'delta': 0.001, - }]; -} + if (!core.animateFrame.weather.fog) return; + core.animateFrame.weather.nodes = [ + { + image: core.animateFrame.weather.fog, + level: 40 * level, + x: 0, + y: -core._PY_ / 2, + dx: -Math.random() * 1.5, + dy: Math.random(), + delta: 0.001, + }, + ]; +}; control.prototype._weather_cloud = function (level) { - if (!core.animateFrame.weather.cloud) return; - core.animateFrame.weather.nodes = [{ - 'image': core.animateFrame.weather.cloud, - 'level': 40 * level, - 'x': 0, - 'y': -core._PY_ / 2, - 'dx': -Math.random() * 1.5, - 'dy': Math.random(), - 'delta': 0.001, - }]; -} + if (!core.animateFrame.weather.cloud) return; + core.animateFrame.weather.nodes = [ + { + image: core.animateFrame.weather.cloud, + level: 40 * level, + x: 0, + y: -core._PY_ / 2, + dx: -Math.random() * 1.5, + dy: Math.random(), + delta: 0.001, + }, + ]; +}; control.prototype._weather_sun = function (level) { - if (!core.animateFrame.weather.sun) return; - // 直接绘制 - core.clearMap('weather'); - core.drawImage( - 'weather', core.animateFrame.weather.sun, 0, 0, core.animateFrame.weather.sun.width, core.animateFrame.weather.sun.height, 0, 0, core._PX_, core._PY_ - ); - core.setOpacity('weather', level / 10); - core.animateFrame.weather.nodes = [{ opacity: level / 10, delta: 0.01 }]; -} + if (!core.animateFrame.weather.sun) return; + // 直接绘制 + core.clearMap("weather"); + core.drawImage( + "weather", + core.animateFrame.weather.sun, + 0, + 0, + core.animateFrame.weather.sun.width, + core.animateFrame.weather.sun.height, + 0, + 0, + core._PX_, + core._PY_ + ); + core.setOpacity("weather", level / 10); + core.animateFrame.weather.nodes = [{ opacity: level / 10, delta: 0.01 }]; +}; ////// 更改画面色调 ////// control.prototype.setCurtain = function (color, time, moveMode, callback) { - if (time == null) time = 750; - if (time <= 0) time = 0; - if (!core.status.curtainColor) - core.status.curtainColor = [0, 0, 0, 0]; - if (!color) color = [0, 0, 0, 0]; - if (color[3] == null) color[3] = 1; - color[3] = core.clamp(color[3], 0, 1); + if (time == null) time = 750; + if (time <= 0) time = 0; + if (!core.status.curtainColor) core.status.curtainColor = [0, 0, 0, 0]; + if (!color) color = [0, 0, 0, 0]; + if (color[3] == null) color[3] = 1; + color[3] = core.clamp(color[3], 0, 1); - if (time == 0) { - // 直接变色 - core.clearMap('curtain'); - core.fillRect('curtain', 0, 0, core._PX_, core._PY_, core.arrayToRGBA(color)); - core.status.curtainColor = color; - if (callback) callback(); - return; + if (time == 0) { + // 直接变色 + core.clearMap("curtain"); + core.fillRect( + "curtain", + 0, + 0, + core._PX_, + core._PY_, + core.arrayToRGBA(color) + ); + core.status.curtainColor = color; + if (callback) callback(); + return; + } + + this._setCurtain_animate( + core.status.curtainColor, + color, + time, + moveMode, + callback + ); +}; + +control.prototype._setCurtain_animate = function ( + nowColor, + color, + time, + moveMode, + callback +) { + time /= Math.max(core.status.replay.speed, 1); + var per_time = 10, + step = 0, + steps = parseInt(time / per_time); + if (steps <= 0) steps = 1; + var curr = nowColor; + var moveFunc = core.applyEasing(moveMode); + + var cb = function () { + core.status.curtainColor = curr; + if (callback) callback(); + }; + var animate = setInterval(function () { + step++; + curr = [ + nowColor[0] + (color[0] - nowColor[0]) * moveFunc(step / steps), + nowColor[1] + (color[1] - nowColor[1]) * moveFunc(step / steps), + nowColor[2] + (color[2] - nowColor[2]) * moveFunc(step / steps), + nowColor[3] + (color[3] - nowColor[3]) * moveFunc(step / steps), + ]; + core.clearMap("curtain"); + core.fillRect( + "curtain", + 0, + 0, + core._PX_, + core._PY_, + core.arrayToRGBA(curr) + ); + if (step == steps) { + delete core.animateFrame.asyncId[animate]; + clearInterval(animate); + cb(); } + }, per_time); - this._setCurtain_animate(core.status.curtainColor, color, time, moveMode, callback); -} - -control.prototype._setCurtain_animate = function (nowColor, color, time, moveMode, callback) { - time /= Math.max(core.status.replay.speed, 1) - var per_time = 10, step = 0, steps = parseInt(time / per_time); - if (steps <= 0) steps = 1; - var curr = nowColor; - var moveFunc = core.applyEasing(moveMode); - - var cb = function () { - core.status.curtainColor = curr; - if (callback) callback(); - } - var animate = setInterval(function () { - step++; - curr = [ - nowColor[0] + (color[0] - nowColor[0]) * moveFunc(step / steps), - nowColor[1] + (color[1] - nowColor[1]) * moveFunc(step / steps), - nowColor[2] + (color[2] - nowColor[2]) * moveFunc(step / steps), - nowColor[3] + (color[3] - nowColor[3]) * moveFunc(step / steps), - ] - core.clearMap('curtain'); - core.fillRect('curtain', 0, 0, core._PX_, core._PY_, core.arrayToRGBA(curr)); - if (step == steps) { - delete core.animateFrame.asyncId[animate]; - clearInterval(animate); - cb(); - } - }, per_time); - - core.animateFrame.lastAsyncId = animate; - core.animateFrame.asyncId[animate] = cb; -} + core.animateFrame.lastAsyncId = animate; + core.animateFrame.asyncId[animate] = cb; +}; ////// 画面闪烁 ////// -control.prototype.screenFlash = function (color, time, times, moveMode, callback) { - times = times || 1; - time = time / 3; - var nowColor = core.clone(core.status.curtainColor); - core.setCurtain(color, time, moveMode, function () { - core.setCurtain(nowColor, time * 2, moveMode, function () { - if (times > 1) - core.screenFlash(color, time * 3, times - 1, moveMode, callback); - else { - if (callback) callback(); - } - }); +control.prototype.screenFlash = function ( + color, + time, + times, + moveMode, + callback +) { + times = times || 1; + time = time / 3; + var nowColor = core.clone(core.status.curtainColor); + core.setCurtain(color, time, moveMode, function () { + core.setCurtain(nowColor, time * 2, moveMode, function () { + if (times > 1) + core.screenFlash(color, time * 3, times - 1, moveMode, callback); + else { + if (callback) callback(); + } }); -} + }); +}; ////// 播放背景音乐 ////// control.prototype.playBgm = function (bgm, startTime) { - bgm = core.getMappedName(bgm); - if (main.mode != 'play' || !core.material.bgms[bgm]) return; - // 如果不允许播放 - if (!core.musicStatus.bgmStatus) { - try { - core.musicStatus.playingBgm = bgm; - core.musicStatus.lastBgm = bgm; - core.material.bgms[bgm].pause(); - } - catch (e) { - console.error(e); - } - return; - } - this.setMusicBtn(); - + bgm = core.getMappedName(bgm); + if (main.mode != "play" || !core.material.bgms[bgm]) return; + // 如果不允许播放 + if (!core.musicStatus.bgmStatus) { try { - this._playBgm_play(bgm, startTime); + core.musicStatus.playingBgm = bgm; + core.musicStatus.lastBgm = bgm; + core.material.bgms[bgm].pause(); + } catch (e) { + console.error(e); } - catch (e) { - console.log("无法播放BGM " + bgm); - console.error(e); - core.musicStatus.playingBgm = null; - } -} + return; + } + this.setMusicBtn(); + + try { + this._playBgm_play(bgm, startTime); + } catch (e) { + console.log("无法播放BGM " + bgm); + console.error(e); + core.musicStatus.playingBgm = null; + } +}; control.prototype._playBgm_play = function (bgm, startTime) { - // 如果当前正在播放,且和本BGM相同,直接忽略 - if (core.musicStatus.playingBgm == bgm && !core.material.bgms[core.musicStatus.playingBgm].paused) { - return; - } - // 如果正在播放中,暂停 - if (core.musicStatus.playingBgm) { - core.material.bgms[core.musicStatus.playingBgm].pause(); - } - // 缓存BGM - core.loader.loadBgm(bgm); - // 播放当前BGM - core.material.bgms[bgm].volume = core.musicStatus.userVolume * core.musicStatus.designVolume; - core.material.bgms[bgm].currentTime = startTime || 0; - core.material.bgms[bgm].play(); - core.musicStatus.playingBgm = bgm; - core.musicStatus.lastBgm = bgm; - core.setBgmSpeed(100); -} + // 如果当前正在播放,且和本BGM相同,直接忽略 + if ( + core.musicStatus.playingBgm == bgm && + !core.material.bgms[core.musicStatus.playingBgm].paused + ) { + return; + } + // 如果正在播放中,暂停 + if (core.musicStatus.playingBgm) { + core.material.bgms[core.musicStatus.playingBgm].pause(); + } + // 缓存BGM + core.loader.loadBgm(bgm); + // 播放当前BGM + core.material.bgms[bgm].volume = + core.musicStatus.userVolume * core.musicStatus.designVolume; + core.material.bgms[bgm].currentTime = startTime || 0; + core.material.bgms[bgm].play(); + core.musicStatus.playingBgm = bgm; + core.musicStatus.lastBgm = bgm; + core.setBgmSpeed(100); +}; ///// 设置当前背景音乐的播放速度 ////// control.prototype.setBgmSpeed = function (speed, usePitch) { - var bgm = core.musicStatus.playingBgm; - if (main.mode != 'play' || !core.material.bgms[bgm]) return; - bgm = core.material.bgms[bgm]; - if (speed < 30 || speed > 300) return; - bgm.playbackRate = speed / 100; - core.musicStatus.bgmSpeed = speed; + var bgm = core.musicStatus.playingBgm; + if (main.mode != "play" || !core.material.bgms[bgm]) return; + bgm = core.material.bgms[bgm]; + if (speed < 30 || speed > 300) return; + bgm.playbackRate = speed / 100; + core.musicStatus.bgmSpeed = speed; - if (bgm.preservesPitch != null) { - if (bgm.__preservesPitch == null) bgm.__preservesPitch = bgm.preservesPitch; - if (usePitch == null) bgm.preservesPitch = bgm.__preservesPitch; - else if (usePitch) bgm.preservesPitch = false; - else bgm.preservesPitch = true; - core.musicStatus.bgmUsePitch = usePitch; - } -} + if (bgm.preservesPitch != null) { + if (bgm.__preservesPitch == null) bgm.__preservesPitch = bgm.preservesPitch; + if (usePitch == null) bgm.preservesPitch = bgm.__preservesPitch; + else if (usePitch) bgm.preservesPitch = false; + else bgm.preservesPitch = true; + core.musicStatus.bgmUsePitch = usePitch; + } +}; ////// 暂停背景音乐的播放 ////// control.prototype.pauseBgm = function () { - if (main.mode != 'play') return; - try { - if (core.musicStatus.playingBgm) { - core.musicStatus.pauseTime = core.material.bgms[core.musicStatus.playingBgm].currentTime; - core.material.bgms[core.musicStatus.playingBgm].pause(); - core.musicStatus.playingBgm = null; - } + if (main.mode != "play") return; + try { + if (core.musicStatus.playingBgm) { + core.musicStatus.pauseTime = + core.material.bgms[core.musicStatus.playingBgm].currentTime; + core.material.bgms[core.musicStatus.playingBgm].pause(); + core.musicStatus.playingBgm = null; } - catch (e) { - console.log("无法暂停BGM"); - console.error(e); - } - this.setMusicBtn(); -} + } catch (e) { + console.log("无法暂停BGM"); + console.error(e); + } + this.setMusicBtn(); +}; ////// 恢复背景音乐的播放 ////// control.prototype.resumeBgm = function (resumeTime) { - if (main.mode != 'play') return; - try { - var speed = core.musicStatus.bgmSpeed; - var usePitch = core.musicStatus.bgmUsePitch; - core.playBgm(core.musicStatus.playingBgm || core.musicStatus.lastBgm || main.startBgm, - resumeTime ? core.musicStatus.pauseTime : 0); - if (resumeTime) { - core.setBgmSpeed(speed, usePitch); - } + if (main.mode != "play") return; + try { + var speed = core.musicStatus.bgmSpeed; + var usePitch = core.musicStatus.bgmUsePitch; + core.playBgm( + core.musicStatus.playingBgm || core.musicStatus.lastBgm || main.startBgm, + resumeTime ? core.musicStatus.pauseTime : 0 + ); + if (resumeTime) { + core.setBgmSpeed(speed, usePitch); } - catch (e) { - console.log("无法恢复BGM"); - console.error(e); - } - this.setMusicBtn(); -} + } catch (e) { + console.log("无法恢复BGM"); + console.error(e); + } + this.setMusicBtn(); +}; control.prototype.setMusicBtn = function () { - if (core.musicStatus.bgmStatus) - core.dom.musicBtn.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAMAAADzN3VRAAABWVBMVEX///9iYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmL///8AAAC5ubn+/v6xsbEtLS0MDAxmZmZoaGhvb2/c3Nzd3d38/Pz9/f0oKCgpKSl0dHR1dXW6urrb29v7+/v09PTv7+/39/cgICACAgImJibh4eGFhYWGhoaHh4eOjo5paWm7u7vDw8PMzMwyMjI7OztAQEDe3t5FRUVMTEzj4+Pl5eXm5ubp6enr6+tcXFzi4uL19fVeXl74+PgjIyNkZGQGBgaSkpKYmJiampqenp4DAwMwMDBnZ2cICAivr68eHh63t7cLCwsSEhLw8PBhYWEUFBQVFRXNzc3Pz8/Z2dna2toaGhqkpKSlpaWpqamrq6tFOUNAAAAAc3RSTlMAAwQFBhUWGxwkJSYyO0dISVBRUmpvj5CSk5SVoaOlpqiysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKyA0IuUgAAAVdJREFUeF5NkVVbw0AQRTcQrLR4IIEGcidJoaUuQHF3d3d3+P/CkuxCzss8nG++mbnDBJXhNt2CpbeFK1kQpSEKidlc8S9qdATRa6UIdQMoxEpDA0Ov3wUAPfW+qLWACydNv9zMrzkJwPK6FB3oHyOfXfuNxvoBQ+GmBYinhHB77TmiVBxoYUw1AYcEq332AS8OYKosAuTT0nza9uU2USYPRJgGxEiSOFywJ3mNARozgBJJzkfLvfu8JgGDWcC9FEsjWzR+y80gYDEAA8QZ3N6kmP1Fs3fEASB7pob7Hh+Wz5L0ci17Or05J7bH6B6dZv05XWK3rG+myV05Ert592Qo55sPuoIr7hEZHHtieIPWy0RU9DLwc3Mnck/vi8/E8XNrDWQtEVnL/ySKMrv0jPwPp870fprcyYifmiEmqGpHkI5q9ofSFIUk2qiwIGpEMyxYhhZRRcMPz89RJ2s9W8wAAAAASUVORK5CYII="; - else - core.dom.musicBtn.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAMAAADzN3VRAAABYlBMVEX///9iYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmL////8/PwAAABmZmZoaGihoaGioqKxsbG5ubnb29vc3Nzd3d3h4eHi4uL9/f3+/v4tLS1nZ2d0dHSUlJSenp66uroMDAz7+/spKSkoKCgUFBRpaWkVFRVvb291dXU7OzuVlZWYmJhkZGQgICAjIyOkpKQCAgK3t7cGBgbv7++pqamrq6seHh4mJiZhYWGamprp6enr6+saGhpeXl7j4+Pl5eXm5uZKSkrw8PD09PT19fW7u7vDw8PMzMwICAgwMDAyMjILCwtAQECGhoaHh4eBgYGFhYUSEhJXV1dZWVlcXFyOjo6SkpLNzc339/fPz8/Z2dna2tqTk5OlpaWxOPeTAAAAdnRSTlMAAwQFBhUWGxwkJSYyO0dISVBRUmpvj5CSk5SVoaOlpqiysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKyNuo+uwAAAWJJREFUeF5NkmV34zAQReUm7WbTuJBNunY3bvXGDjNTkZkZlpn5/9eR5FPfbzr3jGb0RkwRiMQMDm7EIgHmRxtLwMOaHHoQjwz4MUKeCM8AWMrmd7u7f/aXAMyOShHiQD1n04DtN5e5FMBFlSauIsm585dKi4CpuSYKJIv1tBDVmvOSqJgEoowFLSBHaQh10XHWiCgHWEGmAw2blPrvOK/KRJUGoLM4kCVSKrWz7HwgoiwQZyaQJ0+9PvxV23BNATAZB25IqX9b3+jTW9fcApwB6NLgUD5NY3mPXnwmFwBezff1ztzRFzTp94FXMy36HDuCa2RafdnnmZqtL818Gl9/qNnEeyrUk2aTPiKj3qMyWBVi/YSuWq5qiwxkbtX3vYWzdz/l8M0k8ERlvViiB1Ygslb7SbVtJezncj+Cx5bYaeGuonZqhZlieAp+no74/s5EAh6JcY35Cepxk4ObcT3IJPe/1lKsDpFCFQAAAABJRU5ErkJggg=="; -} + if (core.musicStatus.bgmStatus) + core.dom.musicBtn.src = + "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAMAAADzN3VRAAABWVBMVEX///9iYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmL///8AAAC5ubn+/v6xsbEtLS0MDAxmZmZoaGhvb2/c3Nzd3d38/Pz9/f0oKCgpKSl0dHR1dXW6urrb29v7+/v09PTv7+/39/cgICACAgImJibh4eGFhYWGhoaHh4eOjo5paWm7u7vDw8PMzMwyMjI7OztAQEDe3t5FRUVMTEzj4+Pl5eXm5ubp6enr6+tcXFzi4uL19fVeXl74+PgjIyNkZGQGBgaSkpKYmJiampqenp4DAwMwMDBnZ2cICAivr68eHh63t7cLCwsSEhLw8PBhYWEUFBQVFRXNzc3Pz8/Z2dna2toaGhqkpKSlpaWpqamrq6tFOUNAAAAAc3RSTlMAAwQFBhUWGxwkJSYyO0dISVBRUmpvj5CSk5SVoaOlpqiysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKyA0IuUgAAAVdJREFUeF5NkVVbw0AQRTcQrLR4IIEGcidJoaUuQHF3d3d3+P/CkuxCzss8nG++mbnDBJXhNt2CpbeFK1kQpSEKidlc8S9qdATRa6UIdQMoxEpDA0Ov3wUAPfW+qLWACydNv9zMrzkJwPK6FB3oHyOfXfuNxvoBQ+GmBYinhHB77TmiVBxoYUw1AYcEq332AS8OYKosAuTT0nza9uU2USYPRJgGxEiSOFywJ3mNARozgBJJzkfLvfu8JgGDWcC9FEsjWzR+y80gYDEAA8QZ3N6kmP1Fs3fEASB7pob7Hh+Wz5L0ci17Or05J7bH6B6dZv05XWK3rG+myV05Ert592Qo55sPuoIr7hEZHHtieIPWy0RU9DLwc3Mnck/vi8/E8XNrDWQtEVnL/ySKMrv0jPwPp870fprcyYifmiEmqGpHkI5q9ofSFIUk2qiwIGpEMyxYhhZRRcMPz89RJ2s9W8wAAAAASUVORK5CYII="; + else + core.dom.musicBtn.src = + "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAMAAADzN3VRAAABYlBMVEX///9iYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmL////8/PwAAABmZmZoaGihoaGioqKxsbG5ubnb29vc3Nzd3d3h4eHi4uL9/f3+/v4tLS1nZ2d0dHSUlJSenp66uroMDAz7+/spKSkoKCgUFBRpaWkVFRVvb291dXU7OzuVlZWYmJhkZGQgICAjIyOkpKQCAgK3t7cGBgbv7++pqamrq6seHh4mJiZhYWGamprp6enr6+saGhpeXl7j4+Pl5eXm5uZKSkrw8PD09PT19fW7u7vDw8PMzMwICAgwMDAyMjILCwtAQECGhoaHh4eBgYGFhYUSEhJXV1dZWVlcXFyOjo6SkpLNzc339/fPz8/Z2dna2tqTk5OlpaWxOPeTAAAAdnRSTlMAAwQFBhUWGxwkJSYyO0dISVBRUmpvj5CSk5SVoaOlpqiysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKyNuo+uwAAAWJJREFUeF5NkmV34zAQReUm7WbTuJBNunY3bvXGDjNTkZkZlpn5/9eR5FPfbzr3jGb0RkwRiMQMDm7EIgHmRxtLwMOaHHoQjwz4MUKeCM8AWMrmd7u7f/aXAMyOShHiQD1n04DtN5e5FMBFlSauIsm585dKi4CpuSYKJIv1tBDVmvOSqJgEoowFLSBHaQh10XHWiCgHWEGmAw2blPrvOK/KRJUGoLM4kCVSKrWz7HwgoiwQZyaQJ0+9PvxV23BNATAZB25IqX9b3+jTW9fcApwB6NLgUD5NY3mPXnwmFwBezff1ztzRFzTp94FXMy36HDuCa2RafdnnmZqtL818Gl9/qNnEeyrUk2aTPiKj3qMyWBVi/YSuWq5qiwxkbtX3vYWzdz/l8M0k8ERlvViiB1Ygslb7SbVtJezncj+Cx5bYaeGuonZqhZlieAp+no74/s5EAh6JcY35Cepxk4ObcT3IJPe/1lKsDpFCFQAAAABJRU5ErkJggg=="; +}; ////// 更改背景音乐的播放 ////// control.prototype.triggerBgm = function () { - if (main.mode != 'play') return; + if (main.mode != "play") return; - core.musicStatus.bgmStatus = !core.musicStatus.bgmStatus; - if (core.musicStatus.bgmStatus) - this.resumeBgm(); - else - this.pauseBgm(); - core.setLocalStorage('bgmStatus', core.musicStatus.bgmStatus); -} + core.musicStatus.bgmStatus = !core.musicStatus.bgmStatus; + if (core.musicStatus.bgmStatus) this.resumeBgm(); + else this.pauseBgm(); + core.setLocalStorage("bgmStatus", core.musicStatus.bgmStatus); +}; ////// 播放音频 ////// control.prototype.playSound = function (sound, pitch, callback) { - sound = core.getMappedName(sound); - if (main.mode != 'play' || !core.musicStatus.soundStatus || !core.material.sounds[sound]) return; - try { - if (core.musicStatus.audioContext != null) { - var source = core.musicStatus.audioContext.createBufferSource(); - source.__name = sound; - source.buffer = core.material.sounds[sound]; - source.connect(core.musicStatus.gainNode); - var id = setTimeout(null); - if (pitch && pitch >= 30 && pitch <= 300) { - source.playbackRate.setValueAtTime(pitch / 100, 0); - } - source.onended = function () { - delete core.musicStatus.playingSounds[id]; - if (callback) callback(); - } - core.musicStatus.playingSounds[id] = source; - if (source.start) source.start(0); - else if (source.noteOn) source.noteOn(0); - return id; - } - else { - core.material.sounds[sound].volume = core.musicStatus.userVolume; - core.material.sounds[sound].play(); - if (callback) callback(); - } + sound = core.getMappedName(sound); + if ( + main.mode != "play" || + !core.musicStatus.soundStatus || + !core.material.sounds[sound] + ) + return; + try { + if (core.musicStatus.audioContext != null) { + var source = core.musicStatus.audioContext.createBufferSource(); + source.__name = sound; + source.buffer = core.material.sounds[sound]; + source.connect(core.musicStatus.gainNode); + var id = setTimeout(null); + if (pitch && pitch >= 30 && pitch <= 300) { + source.playbackRate.setValueAtTime(pitch / 100, 0); + } + source.onended = function () { + delete core.musicStatus.playingSounds[id]; + if (callback) callback(); + }; + core.musicStatus.playingSounds[id] = source; + if (source.start) source.start(0); + else if (source.noteOn) source.noteOn(0); + return id; + } else { + core.material.sounds[sound].volume = core.musicStatus.userVolume; + core.material.sounds[sound].play(); + if (callback) callback(); } - catch (e) { - console.log("无法播放SE " + sound); - console.error(e); - } -} + } catch (e) { + console.log("无法播放SE " + sound); + console.error(e); + } +}; ////// 停止所有音频 ////// control.prototype.stopSound = function (id) { - if (id == null) { - Object.keys(core.musicStatus.playingSounds).forEach(function (id) { - core.control.stopSound(id); - }); - return; - } - var source = core.musicStatus.playingSounds[id]; - if (!source) return; - try { - if (source.stop) source.stop(); - else if (source.noteOff) source.noteOff(); - } - catch (e) { - console.error(e); - } - delete core.musicStatus.playingSounds[id]; -} + if (id == null) { + Object.keys(core.musicStatus.playingSounds).forEach(function (id) { + core.control.stopSound(id); + }); + return; + } + var source = core.musicStatus.playingSounds[id]; + if (!source) return; + try { + if (source.stop) source.stop(); + else if (source.noteOff) source.noteOff(); + } catch (e) { + console.error(e); + } + delete core.musicStatus.playingSounds[id]; +}; ////// 获得当前正在播放的所有(指定)音效的id列表 ////// control.prototype.getPlayingSounds = function (name) { - name = core.getMappedName(name); - return Object.keys(core.musicStatus.playingSounds).filter(function (one) { - return name == null || core.musicStatus.playingSounds[one].__name == name - }); -} + name = core.getMappedName(name); + return Object.keys(core.musicStatus.playingSounds).filter(function (one) { + return name == null || core.musicStatus.playingSounds[one].__name == name; + }); +}; ////// 检查bgm状态 ////// control.prototype.checkBgm = function () { - core.playBgm(core.musicStatus.playingBgm || main.startBgm); -} + core.playBgm(core.musicStatus.playingBgm || main.startBgm); +}; ///// 设置屏幕放缩 ////// control.prototype.setDisplayScale = function (delta) { - var index = core.domStyle.availableScale.indexOf(core.domStyle.scale); - if (index < 0) return; - index = (index + delta + core.domStyle.availableScale.length) % core.domStyle.availableScale.length; - core.domStyle.scale = core.domStyle.availableScale[index]; - core.setLocalStorage('scale', core.domStyle.scale); - core.resize(); -} + var index = core.domStyle.availableScale.indexOf(core.domStyle.scale); + if (index < 0) return; + index = + (index + delta + core.domStyle.availableScale.length) % + core.domStyle.availableScale.length; + core.domStyle.scale = core.domStyle.availableScale[index]; + core.setLocalStorage("scale", core.domStyle.scale); + core.resize(); +}; // ------ 状态栏,工具栏等相关 ------ // ////// 清空状态栏 ////// control.prototype.clearStatusBar = function () { - Object.keys(core.statusBar).forEach(function (e) { - if (core.statusBar[e].innerHTML != null) { - core.statusBar[e].innerHTML = " "; - core.statusBar[e].removeAttribute('_style'); - core.statusBar[e].removeAttribute('_value'); - } - }) - core.statusBar.image.book.style.opacity = 0.3; - if (!core.flags.equipboxButton) - core.statusBar.image.fly.style.opacity = 0.3; -} + Object.keys(core.statusBar).forEach(function (e) { + if (core.statusBar[e].innerHTML != null) { + core.statusBar[e].innerHTML = " "; + core.statusBar[e].removeAttribute("_style"); + core.statusBar[e].removeAttribute("_value"); + } + }); + core.statusBar.image.book.style.opacity = 0.3; + if (!core.flags.equipboxButton) core.statusBar.image.fly.style.opacity = 0.3; +}; ////// 更新状态栏 ////// control.prototype.updateStatusBar = function (doNotCheckAutoEvents, immediate) { - if (!core.isPlaying()) return; - if (immediate) { - return this.updateStatusBar_update(); - } - if (!doNotCheckAutoEvents) this.noAutoEvents = false; - if (core.isReplaying()) return this.updateStatusBar_update(); - if (!core.control.updateNextFrame) { - core.control.updateNextFrame = true; - requestAnimationFrame(this.updateStatusBar_update); - } + if (!core.isPlaying()) return; + if (immediate) { + return this.updateStatusBar_update(); + } + if (!doNotCheckAutoEvents) this.noAutoEvents = false; + if (core.isReplaying()) return this.updateStatusBar_update(); + if (!core.control.updateNextFrame) { + core.control.updateNextFrame = true; + requestAnimationFrame(this.updateStatusBar_update); + } }; control.prototype.updateStatusBar_update = function () { - core.control.updateNextFrame = false; - if (!core.isPlaying() || core.hasFlag('__statistics__')) return; - core.control.controldata.updateStatusBar(); - if (!core.control.noAutoEvents) core.checkAutoEvents(); - core.control._updateStatusBar_setToolboxIcon(); - core.clearRouteFolding(); - core.control.noAutoEvents = true; + core.control.updateNextFrame = false; + if (!core.isPlaying() || core.hasFlag("__statistics__")) return; + core.control.controldata.updateStatusBar(); + if (!core.control.noAutoEvents) core.checkAutoEvents(); + core.control._updateStatusBar_setToolboxIcon(); + core.clearRouteFolding(); + core.control.noAutoEvents = true; }; control.prototype._updateStatusBar_setToolboxIcon = function () { - if (core.isReplaying()) { - core.statusBar.image.book.src = core.status.replay.pausing ? core.statusBar.icons.play.src : core.statusBar.icons.pause.src; - core.statusBar.image.book.style.opacity = 1; - core.statusBar.image.fly.src = core.statusBar.icons.stop.src; - core.statusBar.image.fly.style.opacity = 1; - core.statusBar.image.toolbox.src = core.statusBar.icons.rewind.src; - core.statusBar.image.keyboard.src = core.statusBar.icons.book.src; - core.statusBar.image.shop.src = core.statusBar.icons.floor.src; - core.statusBar.image.save.src = core.statusBar.icons.speedDown.src; - core.statusBar.image.save.style.opacity = 1; - core.statusBar.image.load.src = core.statusBar.icons.speedUp.src; - core.statusBar.image.settings.src = core.statusBar.icons.save.src; + if (core.isReplaying()) { + core.statusBar.image.book.src = core.status.replay.pausing + ? core.statusBar.icons.play.src + : core.statusBar.icons.pause.src; + core.statusBar.image.book.style.opacity = 1; + core.statusBar.image.fly.src = core.statusBar.icons.stop.src; + core.statusBar.image.fly.style.opacity = 1; + core.statusBar.image.toolbox.src = core.statusBar.icons.rewind.src; + core.statusBar.image.keyboard.src = core.statusBar.icons.book.src; + core.statusBar.image.shop.src = core.statusBar.icons.floor.src; + core.statusBar.image.save.src = core.statusBar.icons.speedDown.src; + core.statusBar.image.save.style.opacity = 1; + core.statusBar.image.load.src = core.statusBar.icons.speedUp.src; + core.statusBar.image.settings.src = core.statusBar.icons.save.src; + } else { + core.statusBar.image.book.src = core.statusBar.icons.book.src; + core.statusBar.image.book.style.opacity = core.hasItem("book") ? 1 : 0.3; + if (!core.flags.equipboxButton) { + core.statusBar.image.fly.src = core.statusBar.icons.fly.src; + core.statusBar.image.fly.style.opacity = core.hasItem("fly") ? 1 : 0.3; + } else { + core.statusBar.image.fly.src = core.statusBar.icons.equipbox.src; + core.statusBar.image.fly.style.opacity = 1; } - else { - core.statusBar.image.book.src = core.statusBar.icons.book.src; - core.statusBar.image.book.style.opacity = core.hasItem('book') ? 1 : 0.3; - if (!core.flags.equipboxButton) { - core.statusBar.image.fly.src = core.statusBar.icons.fly.src; - core.statusBar.image.fly.style.opacity = core.hasItem('fly') ? 1 : 0.3; - } - else { - core.statusBar.image.fly.src = core.statusBar.icons.equipbox.src; - core.statusBar.image.fly.style.opacity = 1; - } - core.statusBar.image.toolbox.src = core.statusBar.icons.toolbox.src; - core.statusBar.image.keyboard.src = core.statusBar.icons.keyboard.src; - core.statusBar.image.shop.src = core.statusBar.icons.shop.src; - core.statusBar.image.save.src = core.statusBar.icons.save.src; - core.statusBar.image.save.style.opacity = core.hasFlag('__forbidSave__') ? 0.3 : 1; - core.statusBar.image.load.src = core.statusBar.icons.load.src; - core.statusBar.image.settings.src = core.statusBar.icons.settings.src; - } -} + core.statusBar.image.toolbox.src = core.statusBar.icons.toolbox.src; + core.statusBar.image.keyboard.src = core.statusBar.icons.keyboard.src; + core.statusBar.image.shop.src = core.statusBar.icons.shop.src; + core.statusBar.image.save.src = core.statusBar.icons.save.src; + core.statusBar.image.save.style.opacity = core.hasFlag("__forbidSave__") + ? 0.3 + : 1; + core.statusBar.image.load.src = core.statusBar.icons.load.src; + core.statusBar.image.settings.src = core.statusBar.icons.settings.src; + } +}; control.prototype.showStatusBar = function () { - if (main.mode == 'editor') return; - if (core.domStyle.showStatusBar) return; - var statusItems = core.dom.status; - core.domStyle.showStatusBar = true; - core.removeFlag('hideStatusBar'); - // 显示 - for (var i = 0; i < statusItems.length; ++i) - statusItems[i].style.opacity = 1; - this.setToolbarButton(false); - core.dom.tools.hard.style.display = 'block'; - core.dom.toolBar.style.display = 'block'; -} + if (main.mode == "editor") return; + if (core.domStyle.showStatusBar) return; + var statusItems = core.dom.status; + core.domStyle.showStatusBar = true; + core.removeFlag("hideStatusBar"); + // 显示 + for (var i = 0; i < statusItems.length; ++i) statusItems[i].style.opacity = 1; + this.setToolbarButton(false); + core.dom.tools.hard.style.display = "block"; + core.dom.toolBar.style.display = "block"; +}; control.prototype.hideStatusBar = function (showToolbox) { - if (main.mode == 'editor') return; + if (main.mode == "editor") return; - // 如果原本就是隐藏的,则先显示 - if (!core.domStyle.showStatusBar) - this.showStatusBar(); - if (core.isReplaying()) showToolbox = true; + // 如果原本就是隐藏的,则先显示 + if (!core.domStyle.showStatusBar) this.showStatusBar(); + if (core.isReplaying()) showToolbox = true; - var statusItems = core.dom.status, toolItems = core.dom.tools; - core.domStyle.showStatusBar = false; - core.setFlag('hideStatusBar', true); - core.setFlag('showToolbox', showToolbox || null); - // 隐藏 - for (var i = 0; i < statusItems.length; ++i) - statusItems[i].style.opacity = 0; - if ((!core.domStyle.isVertical && !core.flags.extendToolbar) || !showToolbox) { - for (var i = 0; i < toolItems.length; ++i) - toolItems[i].style.display = 'none'; - } - if (!core.domStyle.isVertical && !core.flags.extendToolbar) { - core.dom.toolBar.style.display = 'none'; - } -} + var statusItems = core.dom.status, + toolItems = core.dom.tools; + core.domStyle.showStatusBar = false; + core.setFlag("hideStatusBar", true); + core.setFlag("showToolbox", showToolbox || null); + // 隐藏 + for (var i = 0; i < statusItems.length; ++i) statusItems[i].style.opacity = 0; + if ( + (!core.domStyle.isVertical && !core.flags.extendToolbar) || + !showToolbox + ) { + for (var i = 0; i < toolItems.length; ++i) + toolItems[i].style.display = "none"; + } + if (!core.domStyle.isVertical && !core.flags.extendToolbar) { + core.dom.toolBar.style.display = "none"; + } +}; ////// 更新状态栏的勇士图标 ////// control.prototype.updateHeroIcon = function (name) { - name = name || "hero.png"; - if (core.statusBar.icons.name == name) return; - core.statusBar.icons.name = name; + name = name || "hero.png"; + if (core.statusBar.icons.name == name) return; + core.statusBar.icons.name = name; - var image = core.material.images.hero; - // 全身图 - var w = core.material.icons.hero.width || 32; - var h = core.material.icons.hero.height || 48; - var ratio = Math.min(w / h, 1), width = 32 * ratio, left = 16 - width / 2; + var image = core.material.images.hero; + // 全身图 + var w = core.material.icons.hero.width || 32; + var h = core.material.icons.hero.height || 48; + var ratio = Math.min(w / h, 1), + width = 32 * ratio, + left = 16 - width / 2; - var canvas = document.createElement("canvas"); - var ctx = canvas.getContext("2d"); - canvas.width = 32; - canvas.height = 32; - core.drawImage(ctx, image, 0, 0, w, h, left, 0, width, 32); + var canvas = document.createElement("canvas"); + var ctx = canvas.getContext("2d"); + canvas.width = 32; + canvas.height = 32; + core.drawImage(ctx, image, 0, 0, w, h, left, 0, width, 32); - core.statusBar.image.name.src = canvas.toDataURL("image/png"); -} + core.statusBar.image.name.src = canvas.toDataURL("image/png"); +}; ////// 改变工具栏为按钮1-8 ////// control.prototype.setToolbarButton = function (useButton) { - if (!core.domStyle.showStatusBar) { - // 隐藏状态栏时检查竖屏 - if (!core.domStyle.isVertical && !core.flags.extendToolbar) { - for (var i = 0; i < core.dom.tools.length; ++i) - core.dom.tools[i].style.display = 'none'; - return; - } - if (!core.hasFlag('showToolbox')) return; - else core.dom.tools.hard.style.display = 'block'; + if (!core.domStyle.showStatusBar) { + // 隐藏状态栏时检查竖屏 + if (!core.domStyle.isVertical && !core.flags.extendToolbar) { + for (var i = 0; i < core.dom.tools.length; ++i) + core.dom.tools[i].style.display = "none"; + return; } + if (!core.hasFlag("showToolbox")) return; + else core.dom.tools.hard.style.display = "block"; + } - if (useButton == null) useButton = core.domStyle.toolbarBtn; - if ((!core.domStyle.isVertical && !core.flags.extendToolbar)) useButton = false; - core.domStyle.toolbarBtn = useButton; + if (useButton == null) useButton = core.domStyle.toolbarBtn; + if (!core.domStyle.isVertical && !core.flags.extendToolbar) useButton = false; + core.domStyle.toolbarBtn = useButton; - if (useButton) { - ["book", "fly", "toolbox", "keyboard", "shop", "save", "load", "settings"].forEach(function (t) { - core.statusBar.image[t].style.display = 'none'; - }); - ["btn1", "btn2", "btn3", "btn4", "btn5", "btn6", "btn7", "btn8"].forEach(function (t) { - core.statusBar.image[t].style.display = 'block'; - }) - main.statusBar.image.btn8.style.filter = core.getLocalStorage('altKey') ? 'sepia(1) contrast(1.5)' : ''; - } - else { - ["btn1", "btn2", "btn3", "btn4", "btn5", "btn6", "btn7", "btn8"].forEach(function (t) { - core.statusBar.image[t].style.display = 'none'; - }); - ["book", "fly", "toolbox", "save", "load", "settings"].forEach(function (t) { - core.statusBar.image[t].style.display = 'block'; - }); - core.statusBar.image.keyboard.style.display - = core.statusBar.image.shop.style.display - = core.domStyle.isVertical || core.flags.extendToolbar ? "block" : "none"; - } -} + if (useButton) { + [ + "book", + "fly", + "toolbox", + "keyboard", + "shop", + "save", + "load", + "settings", + ].forEach(function (t) { + core.statusBar.image[t].style.display = "none"; + }); + ["btn1", "btn2", "btn3", "btn4", "btn5", "btn6", "btn7", "btn8"].forEach( + function (t) { + core.statusBar.image[t].style.display = "block"; + } + ); + main.statusBar.image.btn8.style.filter = core.getLocalStorage("altKey") + ? "sepia(1) contrast(1.5)" + : ""; + } else { + ["btn1", "btn2", "btn3", "btn4", "btn5", "btn6", "btn7", "btn8"].forEach( + function (t) { + core.statusBar.image[t].style.display = "none"; + } + ); + ["book", "fly", "toolbox", "save", "load", "settings"].forEach(function ( + t + ) { + core.statusBar.image[t].style.display = "block"; + }); + core.statusBar.image.keyboard.style.display = + core.statusBar.image.shop.style.display = + core.domStyle.isVertical || core.flags.extendToolbar ? "block" : "none"; + } +}; ////// ------ resize处理 ------ // control.prototype._shouldDisplayStatus = function (id) { - if (id == null) { - var toDraw = [], status = core.dom.status; - for (var i = 0; i < status.length; ++i) { - var dom = core.dom.status[i], idCol = dom.id; - if (idCol.indexOf("Col") != idCol.length - 3) continue; - var id = idCol.substring(0, idCol.length - 3); - if (!this._shouldDisplayStatus(id)) continue; - toDraw.push(id); - } - return toDraw; + if (id == null) { + var toDraw = [], + status = core.dom.status; + for (var i = 0; i < status.length; ++i) { + var dom = core.dom.status[i], + idCol = dom.id; + if (idCol.indexOf("Col") != idCol.length - 3) continue; + var id = idCol.substring(0, idCol.length - 3); + if (!this._shouldDisplayStatus(id)) continue; + toDraw.push(id); } - var obj = {}; - core.flags.statusBarItems.forEach(function (v) { obj[v] = true; }) - switch (id) { - case 'floor': return obj.enableFloor; - case 'name': return obj.enableName; - case 'lv': return obj.enableLv; - case 'hp': return obj.enableHP; - case 'hpmax': return obj.enableHPMax; - case 'mana': return obj.enableMana; - case 'atk': return obj.enableAtk; - case 'def': return obj.enableDef; - case 'mdef': return obj.enableMDef; - case 'money': return obj.enableMoney; - case 'exp': return obj.enableExp && !obj.levelUpLeftMode; - case 'up': return obj.enableLevelUp; - case 'skill': return obj.enableSkill; - case 'key': return obj.enableKeys; - case 'pzf': return obj.enablePZF; - case 'debuff': return obj.enableDebuff; - default: return true; - } -} + return toDraw; + } + var obj = {}; + core.flags.statusBarItems.forEach(function (v) { + obj[v] = true; + }); + switch (id) { + case "floor": + return obj.enableFloor; + case "name": + return obj.enableName; + case "lv": + return obj.enableLv; + case "hp": + return obj.enableHP; + case "hpmax": + return obj.enableHPMax; + case "mana": + return obj.enableMana; + case "atk": + return obj.enableAtk; + case "def": + return obj.enableDef; + case "mdef": + return obj.enableMDef; + case "money": + return obj.enableMoney; + case "exp": + return obj.enableExp && !obj.levelUpLeftMode; + case "up": + return obj.enableLevelUp; + case "skill": + return obj.enableSkill; + case "key": + return obj.enableKeys; + case "pzf": + return obj.enablePZF; + case "debuff": + return obj.enableDebuff; + default: + return true; + } +}; ////// 注册一个resize函数 ////// // name为名称,可供注销使用 // func可以是一个函数,或者是插件中的函数名;可以接受obj参数,详见resize函数。 control.prototype.registerResize = function (name, func) { - this.unregisterResize(name); - this.resizes.push({ name: name, func: func }); -} + this.unregisterResize(name); + this.resizes.push({ name: name, func: func }); +}; ////// 注销一个resize函数 ////// control.prototype.unregisterResize = function (name) { - this.resizes = this.resizes.filter(function (b) { return b.name != name; }); -} + this.resizes = this.resizes.filter(function (b) { + return b.name != name; + }); +}; control.prototype._doResize = function (obj) { - for (var i in this.resizes) { - try { - if (core.doFunc(this.resizes[i].func, this, obj)) return true; - } catch (e) { - console.error(e); - console.error("ERROR in resizes[" + this.resizes[i].name + "]:已自动注销该项。"); - this.unregisterResize(this.resizes[i].name); - } + for (var i in this.resizes) { + try { + if (core.doFunc(this.resizes[i].func, this, obj)) return true; + } catch (e) { + console.error(e); + console.error( + "ERROR in resizes[" + this.resizes[i].name + "]:已自动注销该项。" + ); + this.unregisterResize(this.resizes[i].name); } - return false; -} + } + return false; +}; ////// 屏幕分辨率改变后重新自适应 ////// control.prototype.resize = function () { - if (main.mode == 'editor') return; - var clientWidth = main.dom.body.clientWidth, clientHeight = main.dom.body.clientHeight; - var BORDER = 3; - var extendToolbar = core.flags.extendToolbar; - let hideLeftStatusBar = core.flags.hideLeftStatusBar; - var BAR_WIDTH = hideLeftStatusBar ? 0 : Math.round(core._PY_ * 0.31); + if (main.mode == "editor") return; + var clientWidth = main.dom.body.clientWidth, + clientHeight = main.dom.body.clientHeight; + var BORDER = 3; + var extendToolbar = core.flags.extendToolbar; + let hideLeftStatusBar = core.flags.hideLeftStatusBar; + var BAR_WIDTH = hideLeftStatusBar ? 0 : Math.round(core._PY_ * 0.31); - var horizontalMaxRatio = (clientHeight - 2 * BORDER - (hideLeftStatusBar ? BORDER : 0)) / (core._PY_ + (hideLeftStatusBar ? 38 : 0)); + var horizontalMaxRatio = + (clientHeight - 2 * BORDER - (hideLeftStatusBar ? BORDER : 0)) / + (core._PY_ + (hideLeftStatusBar ? 38 : 0)); - if (clientWidth - 3 * BORDER >= core._PX_ + BAR_WIDTH || (clientWidth > clientHeight && horizontalMaxRatio < 1)) { - // 横屏 - core.domStyle.isVertical = false; + if ( + clientWidth - 3 * BORDER >= core._PX_ + BAR_WIDTH || + (clientWidth > clientHeight && horizontalMaxRatio < 1) + ) { + // 横屏 + core.domStyle.isVertical = false; - core.domStyle.availableScale = []; - [1, 1.25, 1.5, 1.75, 2, 2.25, 2.5].forEach(function (v) { - if (clientWidth - 3 * BORDER >= v * (core._PX_ + BAR_WIDTH) && horizontalMaxRatio >= v) { - core.domStyle.availableScale.push(v); - } - }); - if (core.domStyle.availableScale.indexOf(core.domStyle.scale) < 0) { - core.domStyle.scale = Math.min(1, horizontalMaxRatio); - } - } - else { - // 竖屏 - core.domStyle.isVertical = true; - core.domStyle.scale = Math.min((clientWidth - 2 * BORDER) / core._PX_); - core.domStyle.availableScale = []; - extendToolbar = false; - hideLeftStatusBar = false; - BAR_WIDTH = Math.round(core._PX_ * 0.3); + core.domStyle.availableScale = []; + [1, 1.25, 1.5, 1.75, 2, 2.25, 2.5].forEach(function (v) { + if ( + clientWidth - 3 * BORDER >= v * (core._PX_ + BAR_WIDTH) && + horizontalMaxRatio >= v + ) { + core.domStyle.availableScale.push(v); + } + }); + if (core.domStyle.availableScale.indexOf(core.domStyle.scale) < 0) { + core.domStyle.scale = Math.min(1, horizontalMaxRatio); } + } else { + // 竖屏 + core.domStyle.isVertical = true; + core.domStyle.scale = Math.min((clientWidth - 2 * BORDER) / core._PX_); + core.domStyle.availableScale = []; + extendToolbar = false; + hideLeftStatusBar = false; + BAR_WIDTH = Math.round(core._PX_ * 0.3); + } - var statusDisplayArr = this._shouldDisplayStatus(), count = statusDisplayArr.length; - var statusCanvas = core.flags.statusCanvas, statusCanvasRows = core.values.statusCanvasRowsOnMobile || 3; - var col = statusCanvas ? statusCanvasRows : Math.ceil(count / 3); - if (col > 5) { - if (statusCanvas) alert("自绘状态栏的在竖屏下的行数应不超过5!"); - else alert("当前状态栏数目(" + count + ")大于15,请调整到不超过15以避免手机端出现显示问题。"); - } - var globalAttribute = core.status.globalAttribute || core.initStatus.globalAttribute; + var statusDisplayArr = this._shouldDisplayStatus(), + count = statusDisplayArr.length; + var statusCanvas = core.flags.statusCanvas, + statusCanvasRows = core.values.statusCanvasRowsOnMobile || 3; + var col = statusCanvas ? statusCanvasRows : Math.ceil(count / 3); + if (col > 5) { + if (statusCanvas) alert("自绘状态栏的在竖屏下的行数应不超过5!"); + else + alert( + "当前状态栏数目(" + + count + + ")大于15,请调整到不超过15以避免手机端出现显示问题。" + ); + } + var globalAttribute = + core.status.globalAttribute || core.initStatus.globalAttribute; - var obj = { - clientWidth: clientWidth, - clientHeight: clientHeight, - BORDER: BORDER, - BAR_WIDTH: BAR_WIDTH, - TOOLBAR_HEIGHT: 38, - outerWidth: core._PX_ * core.domStyle.scale + 2 * BORDER, - outerHeight: core._PY_ * core.domStyle.scale + 2 * BORDER, - globalAttribute: globalAttribute, - border: '3px ' + core.arrayToRGBA(globalAttribute.borderColor) + ' solid', - statusDisplayArr: statusDisplayArr, - count: count, - col: col, - statusBarHeightInVertical: core.domStyle.isVertical ? (32 * col + 6) * core.domStyle.scale + 2 * BORDER : 0, - toolbarHeightInVertical: core.domStyle.isVertical ? 38 * core.domStyle.scale + 2 * BORDER : 0, - extendToolbar: extendToolbar, - is15x15: false, - hideLeftStatusBar - }; + var obj = { + clientWidth: clientWidth, + clientHeight: clientHeight, + BORDER: BORDER, + BAR_WIDTH: BAR_WIDTH, + TOOLBAR_HEIGHT: 38, + outerWidth: core._PX_ * core.domStyle.scale + 2 * BORDER, + outerHeight: core._PY_ * core.domStyle.scale + 2 * BORDER, + globalAttribute: globalAttribute, + border: "3px " + core.arrayToRGBA(globalAttribute.borderColor) + " solid", + statusDisplayArr: statusDisplayArr, + count: count, + col: col, + statusBarHeightInVertical: core.domStyle.isVertical + ? (32 * col + 6) * core.domStyle.scale + 2 * BORDER + : 0, + toolbarHeightInVertical: core.domStyle.isVertical + ? 38 * core.domStyle.scale + 2 * BORDER + : 0, + extendToolbar: extendToolbar, + is15x15: false, + hideLeftStatusBar, + }; - this._doResize(obj); - this.setToolbarButton(); - core.updateStatusBar(); -} + this._doResize(obj); + this.setToolbarButton(); + core.updateStatusBar(); +}; control.prototype._resize_gameGroup = function (obj) { - var startBackground = core.domStyle.isVertical ? (main.styles.startVerticalBackground || main.styles.startBackground) : main.styles.startBackground; - if (main.dom.startBackground.getAttribute('__src__') != startBackground) { - main.dom.startBackground.setAttribute('__src__', startBackground); - main.dom.startBackground.src = startBackground; - } + var startBackground = core.domStyle.isVertical + ? main.styles.startVerticalBackground || main.styles.startBackground + : main.styles.startBackground; + if (main.dom.startBackground.getAttribute("__src__") != startBackground) { + main.dom.startBackground.setAttribute("__src__", startBackground); + main.dom.startBackground.src = startBackground; + } - var gameGroup = core.dom.gameGroup; - var totalWidth, totalHeight; - if (core.domStyle.isVertical) { - totalWidth = obj.outerWidth; - totalHeight = obj.outerHeight + obj.statusBarHeightInVertical + obj.toolbarHeightInVertical - } - else { - totalWidth = obj.outerWidth + obj.BAR_WIDTH * core.domStyle.scale + (obj.hideLeftStatusBar ? 0 : obj.BORDER); - totalHeight = obj.outerHeight + (obj.extendToolbar ? obj.TOOLBAR_HEIGHT * core.domStyle.scale + obj.BORDER : 0); - } - gameGroup.style.width = totalWidth + "px"; - gameGroup.style.height = totalHeight + "px"; - gameGroup.style.left = (obj.clientWidth - totalWidth) / 2 + "px"; - gameGroup.style.top = (obj.clientHeight - totalHeight) / 2 + "px"; - // floorMsgGroup - var floorMsgGroup = core.dom.floorMsgGroup; - floorMsgGroup.style = obj.globalAttribute.floorChangingStyle; - floorMsgGroup.style.width = obj.outerWidth - 2 * obj.BORDER + "px"; - floorMsgGroup.style.height = totalHeight - 2 * obj.BORDER + "px"; - floorMsgGroup.style.fontSize = 16 * core.domStyle.scale + "px"; - // startPanel - core.dom.startPanel.style.fontSize = 16 * core.domStyle.scale + "px"; - // musicBtn - if (core.domStyle.isVertical || core.domStyle.scale < 1) { - core.dom.musicBtn.style.right = core.dom.musicBtn.style.bottom = "3px"; - } - else { - core.dom.musicBtn.style.right = (obj.clientWidth - totalWidth) / 2 + "px"; - core.dom.musicBtn.style.bottom = (obj.clientHeight - totalHeight) / 2 - 27 + "px"; - } -} + var gameGroup = core.dom.gameGroup; + var totalWidth, totalHeight; + if (core.domStyle.isVertical) { + totalWidth = obj.outerWidth; + totalHeight = + obj.outerHeight + + obj.statusBarHeightInVertical + + obj.toolbarHeightInVertical; + } else { + totalWidth = + obj.outerWidth + + obj.BAR_WIDTH * core.domStyle.scale + + (obj.hideLeftStatusBar ? 0 : obj.BORDER); + totalHeight = + obj.outerHeight + + (obj.extendToolbar + ? obj.TOOLBAR_HEIGHT * core.domStyle.scale + obj.BORDER + : 0); + } + gameGroup.style.width = totalWidth + "px"; + gameGroup.style.height = totalHeight + "px"; + gameGroup.style.left = (obj.clientWidth - totalWidth) / 2 + "px"; + gameGroup.style.top = (obj.clientHeight - totalHeight) / 2 + "px"; + // floorMsgGroup + var floorMsgGroup = core.dom.floorMsgGroup; + floorMsgGroup.style = obj.globalAttribute.floorChangingStyle; + floorMsgGroup.style.width = obj.outerWidth - 2 * obj.BORDER + "px"; + floorMsgGroup.style.height = totalHeight - 2 * obj.BORDER + "px"; + floorMsgGroup.style.fontSize = 16 * core.domStyle.scale + "px"; + // startPanel + core.dom.startPanel.style.fontSize = 16 * core.domStyle.scale + "px"; + // musicBtn + if (core.domStyle.isVertical || core.domStyle.scale < 1) { + core.dom.musicBtn.style.right = core.dom.musicBtn.style.bottom = "3px"; + } else { + core.dom.musicBtn.style.right = (obj.clientWidth - totalWidth) / 2 + "px"; + core.dom.musicBtn.style.bottom = + (obj.clientHeight - totalHeight) / 2 - 27 + "px"; + } +}; control.prototype._resize_canvas = function (obj) { - var innerWidth = (core._PX_ * core.domStyle.scale) + "px", innerHeight = (core._PY_ * core.domStyle.scale) + "px"; - if (!core.isPlaying()) { - for (var i = 0; i < core.dom.gameCanvas.length; ++i) { - var ctx = core.dom.gameCanvas[i].getContext('2d'); - core.resizeCanvas(ctx, core._PX_, core._PY_); - core.dom.gameCanvas[i].style.width = innerWidth; - core.dom.gameCanvas[i].style.height = innerHeight; - } - } else { - requestAnimationFrame(function () { - for (var i = 0; i < core.dom.gameCanvas.length; ++i) { - core.dom.gameCanvas[i].style.width = innerWidth; - core.dom.gameCanvas[i].style.height = innerHeight; - } - }); + var innerWidth = core._PX_ * core.domStyle.scale + "px", + innerHeight = core._PY_ * core.domStyle.scale + "px"; + if (!core.isPlaying()) { + for (var i = 0; i < core.dom.gameCanvas.length; ++i) { + var ctx = core.dom.gameCanvas[i].getContext("2d"); + core.resizeCanvas(ctx, core._PX_, core._PY_); + core.dom.gameCanvas[i].style.width = innerWidth; + core.dom.gameCanvas[i].style.height = innerHeight; } - core.dom.gif.style.width = innerWidth; - core.dom.gif.style.height = innerHeight; - core.dom.gif2.style.width = innerWidth; - core.dom.gif2.style.height = innerHeight; - core.dom.gameDraw.style.width = innerWidth; - core.dom.gameDraw.style.height = innerHeight; - core.dom.gameDraw.style.top = obj.statusBarHeightInVertical + "px"; - core.dom.gameDraw.style.right = 0; - core.dom.gameDraw.style.border = obj.border; - // resize bigmap - core.bigmap.canvas.forEach(function (cn) { - var ratio = core.canvas[cn].canvas.hasAttribute('isHD') ? core.domStyle.ratio : 1; - core.canvas[cn].canvas.style.width = core.canvas[cn].canvas.width / ratio * core.domStyle.scale + "px"; - core.canvas[cn].canvas.style.height = core.canvas[cn].canvas.height / ratio * core.domStyle.scale + "px"; + } else { + requestAnimationFrame(function () { + for (var i = 0; i < core.dom.gameCanvas.length; ++i) { + core.dom.gameCanvas[i].style.width = innerWidth; + core.dom.gameCanvas[i].style.height = innerHeight; + } }); - // resize dynamic canvas - if (!core.isPlaying()) { - for (var name in core.dymCanvas) { - var ctx = core.dymCanvas[name], canvas = ctx.canvas; - // core.maps._setHDCanvasSize(ctx, parseFloat(canvas.getAttribute('_width')), parseFloat(canvas.getAttribute('_height'))); - canvas.style.left = parseFloat(canvas.getAttribute("_left")) * core.domStyle.scale + "px"; - canvas.style.top = parseFloat(canvas.getAttribute("_top")) * core.domStyle.scale + "px"; - var scale = canvas.getAttribute('_scale') || 1; - core.resizeCanvas(canvas, canvas.width * scale / core.domStyle.scale, canvas.height * scale / core.domStyle.scale); - } - } else { - for (var name in core.dymCanvas) { - var ctx = core.dymCanvas[name], canvas = ctx.canvas; - core.resizeCanvas(ctx, parseFloat(canvas.getAttribute("_width")), parseFloat(canvas.getAttribute("_height"))) - canvas.style.left = parseFloat(canvas.getAttribute("_left")) * core.domStyle.scale + "px"; - canvas.style.top = parseFloat(canvas.getAttribute("_top")) * core.domStyle.scale + "px"; - } + } + core.dom.gif.style.width = innerWidth; + core.dom.gif.style.height = innerHeight; + core.dom.gif2.style.width = innerWidth; + core.dom.gif2.style.height = innerHeight; + core.dom.gameDraw.style.width = innerWidth; + core.dom.gameDraw.style.height = innerHeight; + core.dom.gameDraw.style.top = obj.statusBarHeightInVertical + "px"; + core.dom.gameDraw.style.right = 0; + core.dom.gameDraw.style.border = obj.border; + // resize bigmap + core.bigmap.canvas.forEach(function (cn) { + var ratio = core.canvas[cn].canvas.hasAttribute("isHD") + ? core.domStyle.ratio + : 1; + core.canvas[cn].canvas.style.width = + (core.canvas[cn].canvas.width / ratio) * core.domStyle.scale + "px"; + core.canvas[cn].canvas.style.height = + (core.canvas[cn].canvas.height / ratio) * core.domStyle.scale + "px"; + }); + // resize dynamic canvas + if (!core.isPlaying()) { + for (var name in core.dymCanvas) { + var ctx = core.dymCanvas[name], + canvas = ctx.canvas; + // core.maps._setHDCanvasSize(ctx, parseFloat(canvas.getAttribute('_width')), parseFloat(canvas.getAttribute('_height'))); + canvas.style.left = + parseFloat(canvas.getAttribute("_left")) * core.domStyle.scale + "px"; + canvas.style.top = + parseFloat(canvas.getAttribute("_top")) * core.domStyle.scale + "px"; + var scale = canvas.getAttribute("_scale") || 1; + core.resizeCanvas( + canvas, + (canvas.width * scale) / core.domStyle.scale, + (canvas.height * scale) / core.domStyle.scale + ); } - // resize next - main.dom.next.style.width = main.dom.next.style.height = 5 * core.domStyle.scale + "px"; - main.dom.next.style.borderBottomWidth = main.dom.next.style.borderRightWidth = 4 * core.domStyle.scale + "px"; -} + } else { + for (var name in core.dymCanvas) { + var ctx = core.dymCanvas[name], + canvas = ctx.canvas; + core.resizeCanvas( + ctx, + parseFloat(canvas.getAttribute("_width")), + parseFloat(canvas.getAttribute("_height")) + ); + canvas.style.left = + parseFloat(canvas.getAttribute("_left")) * core.domStyle.scale + "px"; + canvas.style.top = + parseFloat(canvas.getAttribute("_top")) * core.domStyle.scale + "px"; + } + } + // resize next + main.dom.next.style.width = main.dom.next.style.height = + 5 * core.domStyle.scale + "px"; + main.dom.next.style.borderBottomWidth = main.dom.next.style.borderRightWidth = + 4 * core.domStyle.scale + "px"; +}; control.prototype._resize_statusBar = function (obj) { - // statusBar - var statusBar = core.dom.statusBar; - if (core.domStyle.isVertical) { - statusBar.style.width = obj.outerWidth + "px"; - statusBar.style.height = obj.statusBarHeightInVertical + "px"; - statusBar.style.background = obj.globalAttribute.statusTopBackground; - statusBar.style.fontSize = 16 * core.domStyle.scale + "px"; + // statusBar + var statusBar = core.dom.statusBar; + if (core.domStyle.isVertical) { + statusBar.style.width = obj.outerWidth + "px"; + statusBar.style.height = obj.statusBarHeightInVertical + "px"; + statusBar.style.background = obj.globalAttribute.statusTopBackground; + statusBar.style.fontSize = 16 * core.domStyle.scale + "px"; + } else { + statusBar.style.width = + obj.BAR_WIDTH * core.domStyle.scale + obj.BORDER + "px"; + statusBar.style.height = + obj.outerHeight + + (obj.extendToolbar + ? obj.TOOLBAR_HEIGHT * core.domStyle.scale + obj.BORDER + : 0) + + "px"; + statusBar.style.background = obj.globalAttribute.statusLeftBackground; + // --- 计算文字大小 + if (obj.hideLeftStatusBar) { + statusBar.style.fontSize = 16 * core.domStyle.scale + "px"; + } else { + statusBar.style.fontSize = + 16 * + Math.min(1, (core._HEIGHT_ - 4) / obj.count) * + core.domStyle.scale + + "px"; } - else { - statusBar.style.width = (obj.BAR_WIDTH * core.domStyle.scale + obj.BORDER) + "px"; - statusBar.style.height = obj.outerHeight + (obj.extendToolbar ? obj.TOOLBAR_HEIGHT * core.domStyle.scale + obj.BORDER : 0) + "px"; - statusBar.style.background = obj.globalAttribute.statusLeftBackground; - // --- 计算文字大小 - if (obj.hideLeftStatusBar) { - statusBar.style.fontSize = 16 * core.domStyle.scale + "px"; - } else { - statusBar.style.fontSize = 16 * Math.min(1, (core._HEIGHT_ - 4) / obj.count) * core.domStyle.scale + "px"; - } - } - statusBar.style.display = obj.hideLeftStatusBar ? 'none' : 'block'; - statusBar.style.borderTop = statusBar.style.borderLeft = obj.border; - statusBar.style.borderRight = core.domStyle.isVertical ? obj.border : ''; - statusBar.style.borderBottom = core.domStyle.isVertical ? '' : obj.border; - // 自绘状态栏 - if (core.domStyle.isVertical) { - core.dom.statusCanvas.style.width = core._PX_ * core.domStyle.scale + "px"; - core.dom.statusCanvas.style.height = obj.statusBarHeightInVertical - 3 + "px"; - core.maps._setHDCanvasSize(core.dom.statusCanvasCtx, core._PX_, obj.col * 32 + 9); - } - else { - core.dom.statusCanvas.style.width = obj.BAR_WIDTH * core.domStyle.scale + "px"; - core.dom.statusCanvas.style.height = obj.outerHeight - 2 * obj.BORDER + (obj.extendToolbar ? obj.TOOLBAR_HEIGHT * core.domStyle.scale + obj.BORDER : 0) + "px"; - core.maps._setHDCanvasSize(core.dom.statusCanvasCtx, obj.BAR_WIDTH, core._PY_ + (obj.extendToolbar ? obj.TOOLBAR_HEIGHT + obj.BORDER : 0)); - } - core.dom.statusCanvas.style.display = core.flags.statusCanvas && !obj.hideLeftStatusBar ? "block" : "none"; -} + } + statusBar.style.display = obj.hideLeftStatusBar ? "none" : "block"; + statusBar.style.borderTop = statusBar.style.borderLeft = obj.border; + statusBar.style.borderRight = core.domStyle.isVertical ? obj.border : ""; + statusBar.style.borderBottom = core.domStyle.isVertical ? "" : obj.border; + // 自绘状态栏 + if (core.domStyle.isVertical) { + core.dom.statusCanvas.style.width = core._PX_ * core.domStyle.scale + "px"; + core.dom.statusCanvas.style.height = + obj.statusBarHeightInVertical - 3 + "px"; + core.maps._setHDCanvasSize( + core.dom.statusCanvasCtx, + core._PX_, + obj.col * 32 + 9 + ); + } else { + core.dom.statusCanvas.style.width = + obj.BAR_WIDTH * core.domStyle.scale + "px"; + core.dom.statusCanvas.style.height = + obj.outerHeight - + 2 * obj.BORDER + + (obj.extendToolbar + ? obj.TOOLBAR_HEIGHT * core.domStyle.scale + obj.BORDER + : 0) + + "px"; + core.maps._setHDCanvasSize( + core.dom.statusCanvasCtx, + obj.BAR_WIDTH, + core._PY_ + (obj.extendToolbar ? obj.TOOLBAR_HEIGHT + obj.BORDER : 0) + ); + } + core.dom.statusCanvas.style.display = + core.flags.statusCanvas && !obj.hideLeftStatusBar ? "block" : "none"; +}; control.prototype._resize_status = function (obj) { - var statusHeight; - if (core.domStyle.isVertical) { - statusHeight = 32 * core.domStyle.scale * 0.8; - } else { - statusHeight = (obj.hideLeftStatusBar ? core._HEIGHT_ : core._HEIGHT_ - 4) / obj.count * 32 * core.domStyle.scale * 0.8; - } - // status - for (var i = 0; i < core.dom.status.length; ++i) { - var id = core.dom.status[i].id, style = core.dom.status[i].style; - if (id.endsWith("Col")) id = id.substring(0, id.length - 3); - style.display = core.flags.statusCanvas || obj.statusDisplayArr.indexOf(id) < 0 ? 'none' : 'block'; - style.margin = 3 * core.domStyle.scale + "px"; - style.height = statusHeight + "px"; - style.maxWidth = obj.BAR_WIDTH * core.domStyle.scale * (core.domStyle.isVertical ? 0.95 : 1) + obj.BORDER + "px"; - if (obj.is15x15 && !core.domStyle.isVertical) - style.marginLeft = 11 * core.domStyle.scale + "px"; - } - // statusLabels, statusTexts - for (var i = 0; i < core.dom.statusLabels.length; ++i) { - core.dom.statusLabels[i].style.lineHeight = statusHeight + "px"; - core.dom.statusLabels[i].style.marginLeft = 6 * core.domStyle.scale + "px"; - } - for (var i = 0; i < core.dom.statusTexts.length; ++i) { - core.dom.statusTexts[i].style.color = core.arrayToRGBA(obj.globalAttribute.statusBarColor); - } - // keys - if (core.flags.statusBarItems.indexOf('enableGreenKey') >= 0) { - core.dom.keyCol.style.fontSize = '0.75em'; - core.statusBar.greenKey.style.display = ''; - } else { - core.dom.keyCol.style.fontSize = ''; - core.statusBar.greenKey.style.display = 'none'; - } -} + var statusHeight; + if (core.domStyle.isVertical) { + statusHeight = 32 * core.domStyle.scale * 0.8; + } else { + statusHeight = + ((obj.hideLeftStatusBar ? core._HEIGHT_ : core._HEIGHT_ - 4) / + obj.count) * + 32 * + core.domStyle.scale * + 0.8; + } + // status + for (var i = 0; i < core.dom.status.length; ++i) { + var id = core.dom.status[i].id, + style = core.dom.status[i].style; + if (id.endsWith("Col")) id = id.substring(0, id.length - 3); + style.display = + core.flags.statusCanvas || obj.statusDisplayArr.indexOf(id) < 0 + ? "none" + : "block"; + style.margin = 3 * core.domStyle.scale + "px"; + style.height = statusHeight + "px"; + style.maxWidth = + obj.BAR_WIDTH * + core.domStyle.scale * + (core.domStyle.isVertical ? 0.95 : 1) + + obj.BORDER + + "px"; + if (obj.is15x15 && !core.domStyle.isVertical) + style.marginLeft = 11 * core.domStyle.scale + "px"; + } + // statusLabels, statusTexts + for (var i = 0; i < core.dom.statusLabels.length; ++i) { + core.dom.statusLabels[i].style.lineHeight = statusHeight + "px"; + core.dom.statusLabels[i].style.marginLeft = 6 * core.domStyle.scale + "px"; + } + for (var i = 0; i < core.dom.statusTexts.length; ++i) { + core.dom.statusTexts[i].style.color = core.arrayToRGBA( + obj.globalAttribute.statusBarColor + ); + } + // keys + if (core.flags.statusBarItems.indexOf("enableGreenKey") >= 0) { + core.dom.keyCol.style.fontSize = "0.75em"; + core.statusBar.greenKey.style.display = ""; + } else { + core.dom.keyCol.style.fontSize = ""; + core.statusBar.greenKey.style.display = "none"; + } +}; control.prototype._resize_toolBar = function (obj) { - // toolBar - var toolBar = core.dom.toolBar; - if (core.domStyle.isVertical) { - toolBar.style.left = 0; - toolBar.style.right = ""; - toolBar.style.width = obj.outerWidth + "px"; - toolBar.style.top = obj.statusBarHeightInVertical + obj.outerHeight + "px"; - toolBar.style.height = obj.toolbarHeightInVertical + "px"; - toolBar.style.background = obj.globalAttribute.toolsBackground; - } - else { - if (obj.extendToolbar || obj.hideLeftStatusBar) { - toolBar.style.left = ""; - toolBar.style.right = 0; - toolBar.style.width = obj.outerWidth + "px"; - toolBar.style.top = obj.outerHeight + "px"; - toolBar.style.height = obj.TOOLBAR_HEIGHT * core.domStyle.scale + obj.BORDER + "px"; - toolBar.style.background = obj.globalAttribute.toolsBackground; - } else { - toolBar.style.left = 0; - toolBar.style.right = ""; - toolBar.style.width = obj.BAR_WIDTH * core.domStyle.scale + obj.BORDER + "px"; - toolBar.style.top = 0.75 * obj.outerHeight + "px"; - toolBar.style.height = 0.25 * obj.outerHeight + "px"; - toolBar.style.background = 'transparent'; - } - } - toolBar.style.borderLeft = obj.border; - toolBar.style.borderRight = toolBar.style.borderBottom = core.domStyle.isVertical || obj.extendToolbar ? obj.border : ''; - toolBar.style.fontSize = 16 * core.domStyle.scale + "px"; - - if (!core.domStyle.showStatusBar && !core.domStyle.isVertical && !obj.extendToolbar) { - toolBar.style.display = 'none'; + // toolBar + var toolBar = core.dom.toolBar; + if (core.domStyle.isVertical) { + toolBar.style.left = 0; + toolBar.style.right = ""; + toolBar.style.width = obj.outerWidth + "px"; + toolBar.style.top = obj.statusBarHeightInVertical + obj.outerHeight + "px"; + toolBar.style.height = obj.toolbarHeightInVertical + "px"; + toolBar.style.background = obj.globalAttribute.toolsBackground; + } else { + if (obj.extendToolbar || obj.hideLeftStatusBar) { + toolBar.style.left = ""; + toolBar.style.right = 0; + toolBar.style.width = obj.outerWidth + "px"; + toolBar.style.top = obj.outerHeight + "px"; + toolBar.style.height = + obj.TOOLBAR_HEIGHT * core.domStyle.scale + obj.BORDER + "px"; + toolBar.style.background = obj.globalAttribute.toolsBackground; } else { - toolBar.style.display = 'block'; + toolBar.style.left = 0; + toolBar.style.right = ""; + toolBar.style.width = + obj.BAR_WIDTH * core.domStyle.scale + obj.BORDER + "px"; + toolBar.style.top = 0.75 * obj.outerHeight + "px"; + toolBar.style.height = 0.25 * obj.outerHeight + "px"; + toolBar.style.background = "transparent"; } -} + } + toolBar.style.borderLeft = obj.border; + toolBar.style.borderRight = toolBar.style.borderBottom = + core.domStyle.isVertical || obj.extendToolbar ? obj.border : ""; + toolBar.style.fontSize = 16 * core.domStyle.scale + "px"; + + if ( + !core.domStyle.showStatusBar && + !core.domStyle.isVertical && + !obj.extendToolbar + ) { + toolBar.style.display = "none"; + } else { + toolBar.style.display = "block"; + } +}; control.prototype._resize_tools = function (obj) { - var toolsHeight = 32 * core.domStyle.scale * ((core.domStyle.isVertical || obj.extendToolbar) && !obj.is15x15 ? 0.95 : 1); - var toolsMarginLeft; - if (core.domStyle.isVertical || obj.extendToolbar) - toolsMarginLeft = (core._HALF_WIDTH_ - 3) * 3 * core.domStyle.scale; - else - toolsMarginLeft = (obj.BAR_WIDTH * core.domStyle.scale - 9 - toolsHeight * 3) / 4; - for (var i = 0; i < core.dom.tools.length; ++i) { - var style = core.dom.tools[i].style; - style.height = toolsHeight + "px"; - style.marginLeft = toolsMarginLeft + "px"; - style.marginTop = 3 * core.domStyle.scale + "px" - } - core.dom.hard.style.lineHeight = toolsHeight + "px"; - if (core.domStyle.isVertical || obj.extendToolbar) { - core.dom.hard.style.width = obj.outerWidth - 9 * toolsMarginLeft - 8.5 * toolsHeight - 12 + "px"; - } - else { - core.dom.hard.style.width = obj.BAR_WIDTH * core.domStyle.scale - 9 - 2 * toolsMarginLeft + "px"; - if (!obj.is15x15) core.dom.hard.style.marginTop = 0; - } -} + var toolsHeight = + 32 * + core.domStyle.scale * + ((core.domStyle.isVertical || obj.extendToolbar) && !obj.is15x15 + ? 0.95 + : 1); + var toolsMarginLeft; + if (core.domStyle.isVertical || obj.extendToolbar) + toolsMarginLeft = (core._HALF_WIDTH_ - 3) * 3 * core.domStyle.scale; + else + toolsMarginLeft = + (obj.BAR_WIDTH * core.domStyle.scale - 9 - toolsHeight * 3) / 4; + for (var i = 0; i < core.dom.tools.length; ++i) { + var style = core.dom.tools[i].style; + style.height = toolsHeight + "px"; + style.marginLeft = toolsMarginLeft + "px"; + style.marginTop = 3 * core.domStyle.scale + "px"; + } + core.dom.hard.style.lineHeight = toolsHeight + "px"; + if (core.domStyle.isVertical || obj.extendToolbar) { + core.dom.hard.style.width = + obj.outerWidth - 9 * toolsMarginLeft - 8.5 * toolsHeight - 12 + "px"; + } else { + core.dom.hard.style.width = + obj.BAR_WIDTH * core.domStyle.scale - 9 - 2 * toolsMarginLeft + "px"; + if (!obj.is15x15) core.dom.hard.style.marginTop = 0; + } +}; diff --git a/libs/events.js b/libs/events.js index 66d9954..030abdf 100644 --- a/libs/events.js +++ b/libs/events.js @@ -1,429 +1,485 @@ - "use strict"; -function events () { - this._init(); +function events() { + this._init(); } ////// 初始化 ////// events.prototype._init = function () { - this.eventdata = functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a.events; - this.commonEvent = events_c12a15a8_c380_4b28_8144_256cba95f760.commonEvent; - this.systemEvents = {}; - this.actions = {}; -} + this.eventdata = functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a.events; + 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); -} + 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 || ""; + main.dom.levelChooseButtons.style.display = "none"; + main.dom.startButtonGroup.style.display = "none"; + hard = hard || ""; - if (main.mode != 'play') return; + if (main.mode != "play") return; - // 无动画的开始游戏 - if (core.flags.startUsingCanvas || route != null) { - core.dom.startPanel.style.display = 'none'; - this._startGame_start(hard, seed, route, callback); - } - else { - core.hideStartAnimate(function () { - core.events._startGame_start(hard, seed, route, callback); - }); - } -} + // 无动画的开始游戏 + if (core.flags.startUsingCanvas || route != null) { + core.dom.startPanel.style.display = "none"; + this._startGame_start(hard, seed, route, callback); + } 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.setHeroLoc('x', -1); - core.setHeroLoc('y', -1); + 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(); - core.clearStatusBar(); + if (seed != null && seed > 0) { + core.setFlag("__seed__", seed); + core.setFlag("__rand__", seed); + } else core.utils.__init_seed(); + core.clearStatusBar(); - var todo = []; - if (core.flags.startUsingCanvas) { - core.hideStatusBar(); - 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, core.firstData.startText); - this.insertAction(todo, null, null, function () { - core.events._startGame_afterStart(callback); - }); + var todo = []; + if (core.flags.startUsingCanvas) { + core.hideStatusBar(); + 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, core.firstData.startText); + this.insertAction(todo, null, null, function () { + core.events._startGame_afterStart(callback); + }); - if (route != null) core.startReplay(route); -} + if (route != null) core.startReplay(route); +}; events.prototype._startGame_setHard = function () { - // 根据难度设置flag:hard - // 这一段应当在startCanvas之后,startText之前做 - var hardValue = 0; - var hardColor = 'red'; - main.levelChoose.forEach(function (one) { - if (one.name == core.status.hard) { - hardValue = one.hard; - hardColor = core.arrayToRGBA(one.color || [255, 0, 0, 1]); - core.insertAction(one.action); - } - }); - core.setFlag('hard', hardValue || 0); - core.setFlag('__hardColor__', hardColor); -} + // 根据难度设置flag:hard + // 这一段应当在startCanvas之后,startText之前做 + var hardValue = 0; + var hardColor = "red"; + main.levelChoose.forEach(function (one) { + if (one.name == core.status.hard) { + hardValue = one.hard; + hardColor = core.arrayToRGBA(one.color || [255, 0, 0, 1]); + core.insertAction(one.action); + } + }); + 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(); - }); - this._startGame_upload(); -} + core.ui.closePanel(); + 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 - var formData = new FormData(); - formData.append('type', 'people'); - formData.append('name', core.firstData.name); - formData.append('version', core.firstData.version); - formData.append('platform', core.platform.string); - formData.append('hard', core.encodeBase64(core.status.hard)); - formData.append('hardCode', core.getFlag('hard', 0)); - formData.append('base64', 1); + // Upload + var formData = new FormData(); + formData.append("type", "people"); + formData.append("name", core.firstData.name); + formData.append("version", core.firstData.version); + formData.append("platform", core.platform.string); + formData.append("hard", core.encodeBase64(core.status.hard)); + 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); -} + 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); }); - core.status.gameOver = true; - return this.eventdata.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.setWeather(); - } - core.ui.closePanel(); + if (!core.status.extraEvent) { + core.clearMap("all"); + core.deleteAllCanvas(); + core.dom.gif2.innerHTML = ""; + core.setWeather(); + } + core.ui.closePanel(); - if (main.isCompetition && ending != null) { - if (ending == "") ending = "恭喜通关"; - ending += "[比赛]"; - } + if (main.isCompetition && ending != null) { + if (ending == "") ending = "恭喜通关"; + ending += "[比赛]"; + } - var reason = null; - if (fromReplay) reason = "录像回放完毕!"; - else if (core.hasFlag("debug")) reason = "\t[系统提示]调试模式下无法上传成绩"; + var reason = null; + 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(); + core.ui.closePanel(); - if (ending == null) { - this._gameOver_confirmDownload(ending); - return; + if (ending == null) { + this._gameOver_confirmDownload(ending); + return; + } + 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); } - 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); - }) -} + ); +}; events.prototype._gameOver_doUpload = function (username, ending, norank) { - var hp = core.status.hero.hp; - if (username == null) hp = 1; - core.ui.closePanel(); - // upload - var formData = new FormData(); - formData.append('type', 'score'); - formData.append('name', core.firstData.name); - 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('ending', core.encodeBase64(ending)); - formData.append('lv', core.status.hero.lv); - formData.append('hp', Math.min(hp, Math.pow(2, 63))); - formData.append('atk', core.status.hero.atk); - formData.append('def', core.status.hero.def); - formData.append('mdef', core.status.hero.mdef); - formData.append('money', core.status.hero.money); - formData.append('experience', core.status.hero.exp); - 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('route', core.encodeRoute(core.status.route)); - formData.append('base64', 1); + var hp = core.status.hero.hp; + if (username == null) hp = 1; + core.ui.closePanel(); + // upload + var formData = new FormData(); + formData.append("type", "score"); + formData.append("name", core.firstData.name); + 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("ending", core.encodeBase64(ending)); + formData.append("lv", core.status.hero.lv); + formData.append("hp", Math.min(hp, Math.pow(2, 63))); + formData.append("atk", core.status.hero.atk); + formData.append("def", core.status.hero.def); + formData.append("mdef", core.status.hero.mdef); + formData.append("money", core.status.hero.money); + formData.append("experience", core.status.hero.exp); + 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("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); + if (main.isCompetition) + core.http("POST", "/games/competition/upload.php", formData); + else core.http("POST", "/games/upload.php", formData); - core.events._gameOver_confirmDownload(ending); -} + 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.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.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.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(); + core.ui.closePanel(); - // 继续接下来的事件 - if (core.status.extraEvent) { - core.status.event = core.status.extraEvent; - delete core.status.extraEvent; - core.lockControl(); - core.doAction(); - return; + // 继续接下来的事件 + if (core.status.extraEvent) { + core.status.event = core.status.extraEvent; + delete core.status.extraEvent; + core.lockControl(); + core.doAction(); + return; + } + + if (ending == null) { + if (!core.hasSave(0)) { + core.ui.closePanel(); + core.restart(); + return; } - if (ending == null) { - if (!core.hasSave(0)) { - core.ui.closePanel(); - core.restart(); - return; - } - - core.status.event.selection = 0; - 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.restart(); - } - else { - window.location.href = "/tower/?name=" + core.firstData.name; - } - }, function () { + core.status.event.selection = 0; + 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.restart(); + } else { + window.location.href = "/tower/?name=" + core.firstData.name; + } + }, + function () { + core.restart(); + } + ); +}; ////// 重新开始游戏;此函数将回到标题页面 ////// events.prototype.restart = function () { - core.showStartAnimate(); - core.playBgm(main.startBgm); -} + 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.playSound("打开界面"); + core.status.event.selection = 1; + core.ui.drawConfirmBox( + "你确定要返回标题页面吗?", + function () { + core.playSound("确定"); + core.ui.closePanel(); + core.restart(); + }, + function () { + core.playSound("取消"); + core.ui.closePanel(); + } + ); +}; // ------ 系统事件的处理 ------ // ////// 注册一个系统事件 ////// // type为事件名,func为事件的处理函数,可接受(data, callback)参数 events.prototype.registerSystemEvent = function (type, func) { - this.systemEvents[type] = func; -} + this.systemEvents[type] = func; +}; ////// 注销一个系统事件 ////// events.prototype.unregisterSystemEvent = function (type) { - delete this.systemEvents[type]; -} + delete this.systemEvents[type]; +}; ////// 执行一个系统事件 ////// events.prototype.doSystemEvent = function (type, data, callback) { - core.clearRouteFolding(); - if (this.systemEvents[type]) { - try { - return core.doFunc(this.systemEvents[type], this, data, callback); - } - catch (e) { - console.error(e); - console.error("ERROR in systemEvents[" + type + "]"); - } + core.clearRouteFolding(); + if (this.systemEvents[type]) { + try { + return core.doFunc(this.systemEvents[type], this, data, callback); + } catch (e) { + console.error(e); + console.error("ERROR in systemEvents[" + type + "]"); } - if (this["_sys_" + type]) return this["_sys_" + type](data, callback); - console.error("未知的系统事件: " + type + "!"); - if (callback) callback(); -} + } + 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) { - var _executeCallback = function () { - // 因为trigger之后还有可能触发其他同步脚本(比如阻激夹域检测) - // 所以这里强制callback被异步触发 - if (callback) { - setTimeout(callback, 1); // +1是为了录像检测系统 - } - return; - } - if (core.status.gameOver) return _executeCallback(); - if (core.status.event.id == 'action') { - core.insertAction({ "type": "function", "function": "function () { core.events._trigger_inAction(" + x + "," + y + "); }", "async": true }, - null, null, null, true); - return _executeCallback(); - } - if (core.status.event.id) return _executeCallback(); - - var block = core.getBlock(x, y); - if (block == null) return _executeCallback(); - - // 执行该点的脚本 - if (block.event.script) { - core.clearRouteFolding(); - try { - eval(block.event.script); - } catch (ee) { console.error(ee) } - } - - // 碰触事件 - if (block.event.event) { - core.clearRouteFolding(); - core.insertAction(block.event.event, block.x, block.y); - // 不再执行该点的系统事件 - return _executeCallback(); - } - - if (block.event.trigger && block.event.trigger != 'null') { - var noPass = block.event.noPass, trigger = block.event.trigger; - if (noPass) core.clearAutomaticRouteNode(x, y); - - // 转换楼层能否穿透 - if (trigger == 'changeFloor' && !noPass && this._trigger_ignoreChangeFloor(block)) - return _executeCallback(); - core.status.automaticRoute.moveDirectly = false; - this.doSystemEvent(trigger, block); + var _executeCallback = function () { + // 因为trigger之后还有可能触发其他同步脚本(比如阻激夹域检测) + // 所以这里强制callback被异步触发 + if (callback) { + setTimeout(callback, 1); // +1是为了录像检测系统 } + return; + }; + if (core.status.gameOver) return _executeCallback(); + if (core.status.event.id == "action") { + core.insertAction( + { + type: "function", + function: + "function () { core.events._trigger_inAction(" + x + "," + y + "); }", + async: true, + }, + null, + null, + null, + true + ); return _executeCallback(); -} + } + if (core.status.event.id) return _executeCallback(); + + var block = core.getBlock(x, y); + if (block == null) return _executeCallback(); + + // 执行该点的脚本 + if (block.event.script) { + core.clearRouteFolding(); + try { + eval(block.event.script); + } catch (ee) { + console.error(ee); + } + } + + // 碰触事件 + if (block.event.event) { + core.clearRouteFolding(); + core.insertAction(block.event.event, block.x, block.y); + // 不再执行该点的系统事件 + return _executeCallback(); + } + + if (block.event.trigger && block.event.trigger != "null") { + var noPass = block.event.noPass, + trigger = block.event.trigger; + if (noPass) core.clearAutomaticRouteNode(x, y); + + // 转换楼层能否穿透 + if ( + trigger == "changeFloor" && + !noPass && + this._trigger_ignoreChangeFloor(block) + ) + 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; + if (core.status.gameOver || core.status.event.id != "action") return; - var block = core.getBlock(x, y); - if (block == null) return core.doAction(); + var block = core.getBlock(x, y); + if (block == null) return core.doAction(); - // 执行该点的脚本 - try { - eval(block.event.script); - } catch (ee) { console.error(ee) } + // 执行该点的脚本 + try { + eval(block.event.script); + } catch (ee) { + console.error(ee); + } - // 碰触事件 - if (block.event.event) { - core.clearRouteFolding(); - core.insertAction(block.event.event, block.x, block.y); - // 不再执行该点的系统事件 - return core.doAction(); - } - - if (block.event.trigger && block.event.trigger != 'null') { - this.setEvents(null, x, y); - if (block.event.trigger == 'action') { - this.insertAction(block.event.data); - } - else { - this.doSystemEvent(block.event.trigger, block, core.doAction); - return; - } - } + // 碰触事件 + if (block.event.event) { + core.clearRouteFolding(); + core.insertAction(block.event.event, block.x, block.y); + // 不再执行该点的系统事件 return core.doAction(); -} + } + + if (block.event.trigger && block.event.trigger != "null") { + this.setEvents(null, x, y); + if (block.event.trigger == "action") { + this.insertAction(block.event.data); + } else { + this.doSystemEvent(block.event.trigger, block, core.doAction); + return; + } + } + return core.doAction(); +}; events.prototype._trigger_ignoreChangeFloor = function (block) { - var able = core.flags.ignoreChangeFloor; - if (block.event.data && block.event.data.ignoreChangeFloor != null) - able = block.event.data.ignoreChangeFloor; - if (able) { - if (core.isReplaying()) { - if (core.status.replay.toReplay[0] == 'no') { - core.status.replay.toReplay.shift(); - 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"); - return true; - } + var able = core.flags.ignoreChangeFloor; + if (block.event.data && block.event.data.ignoreChangeFloor != null) + able = block.event.data.ignoreChangeFloor; + if (able) { + if (core.isReplaying()) { + if (core.status.replay.toReplay[0] == "no") { + core.status.replay.toReplay.shift(); + 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"); + return true; } - return false; -} + } + return false; +}; events.prototype._sys_battle = function (data, callback) { - // 检查是否需要改变朝向 - /* if (data.x == core.nextX() && data.y == core.nextY()) { + // 检查是否需要改变朝向 + /* if (data.x == core.nextX() && data.y == core.nextY()) { var dir = core.turnDirection(":back"); var id = data.event.id, toId = (data.event.faceIds || {})[dir]; if (toId && id != toId) { @@ -433,499 +489,554 @@ 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); - if (beforeBattle.length > 0) { - core.push(beforeBattle, [{ "type": "battle", "x": data.x, "y": data.y }]); - core.clearContinueAutomaticRoute(); + // 检查战前事件 + 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 + ); + if (beforeBattle.length > 0) { + core.push(beforeBattle, [{ type: "battle", x: data.x, y: data.y }]); + core.clearContinueAutomaticRoute(); - // 自动存档 - var inAction = core.status.event.id == 'action'; - if (inAction) { - core.insertAction(beforeBattle, data.x, data.y); - core.doAction(); - } else { - core.autosave(true); - core.insertAction(beforeBattle, data.x, data.y, callback); - } + // 自动存档 + var inAction = core.status.event.id == "action"; + if (inAction) { + core.insertAction(beforeBattle, data.x, data.y); + core.doAction(); } else { - this.battle(data.event.id, data.x, data.y, false, callback); + core.autosave(true); + core.insertAction(beforeBattle, data.x, data.y, callback); } -} + } else { + this.battle(data.event.id, data.x, data.y, false, callback); + } +}; ////// 战斗 ////// events.prototype.battle = function (id, x, y, force, callback) { - core.saveAndStopAutomaticRoute(); - id = id || core.getBlockId(x, y); - if (!id) return core.clearContinueAutomaticRoute(callback); - // 非强制战斗 - if (!core.enemys.canBattle(id, x, y) && !force && !core.status.event.id) { - core.stopSound(); - core.playSound('操作失败'); - core.drawTip("你打不过此怪物!", id); - return core.clearContinueAutomaticRoute(callback); - } - // 自动存档 - if (!core.status.event.id) core.autosave(true); - // 战前事件 - if (!this.beforeBattle(id, x, y)) - return core.clearContinueAutomaticRoute(callback); - // 战后事件 - this.afterBattle(id, x, y); - if (callback) callback(); -} + core.saveAndStopAutomaticRoute(); + id = id || core.getBlockId(x, y); + if (!id) return core.clearContinueAutomaticRoute(callback); + // 非强制战斗 + if (!core.enemys.canBattle(id, x, y) && !force && !core.status.event.id) { + core.stopSound(); + core.playSound("操作失败"); + core.drawTip("你打不过此怪物!", id); + return core.clearContinueAutomaticRoute(callback); + } + // 自动存档 + if (!core.status.event.id) core.autosave(true); + // 战前事件 + if (!this.beforeBattle(id, x, y)) + return core.clearContinueAutomaticRoute(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); -} + 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(); - }); -} + this.openDoor(data.x, data.y, true, function () { + core.replay(); + if (callback) callback(); + }); +}; ////// 开门 ////// events.prototype.openDoor = function (x, y, needKey, callback) { - var block = core.getBlock(x, y); - core.saveAndStopAutomaticRoute(); - if (!this._openDoor_check(block, x, y, needKey)) { - var locked = core.status.lockControl; - core.waitHeroToStop(function () { - if (!locked) core.unlockControl(); - if (callback) callback(); - }); - return; - } - if (core.status.replay.speed == 24) { - core.status.replay.animate = true; - core.removeBlock(x, y); - setTimeout(function () { - core.status.replay.animate = false; - core.events.afterOpenDoor(block.event.id, x, y); - if (callback) callback(); - }, 1); // +1是为了录像检测系统 - } 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) { - return clearAndReturn(); - } - - if (id == 'steelDoor' && core.flags.steelDoorWithoutKey) - needKey = false; - var doorInfo = block.event.doorInfo; - if (doorInfo == null) return clearAndReturn(); - // Check all keys - var keyInfo = doorInfo.keys || {}; - if (needKey) { - for (var keyName in keyInfo) { - var keyValue = keyInfo[keyName]; - if (keyName.endsWith(':o')) keyName = keyName.substring(0, keyName.length - 2); - - // --- 如果是一个不存在的道具,则直接认为无法开启 - if (!core.material.items[keyName]) { - core.stopSound(); - core.playSound('操作失败'); - core.drawTip("无法开启此门"); - return clearAndReturn(); - } - if (core.itemCount(keyName) < keyValue) { - core.stopSound(); - core.playSound('操作失败'); - 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]); - } - } - core.playSound(doorInfo.openSound); - return true; -} - -events.prototype._openDoor_animate = function (block, x, y, callback) { - var blockInfo = core.getBlockInfo(block); - blockInfo.opacity = block.opacity; - blockInfo.filter = block.filter; - - var speed = (block.event.doorInfo.time || 160) / 4; - + var block = core.getBlock(x, y); + core.saveAndStopAutomaticRoute(); + if (!this._openDoor_check(block, x, y, needKey)) { var locked = core.status.lockControl; - core.lockControl(); + core.waitHeroToStop(function () { + if (!locked) core.unlockControl(); + if (callback) callback(); + }); + return; + } + if (core.status.replay.speed == 24) { core.status.replay.animate = true; core.removeBlock(x, y); + setTimeout(function () { + core.status.replay.animate = false; + core.events.afterOpenDoor(block.event.id, x, y); + if (callback) callback(); + }, 1); // +1是为了录像检测系统 + } else { + this._openDoor_animate(block, x, y, callback); + } +}; - blockInfo.posX = 0; - core.maps._drawBlockInfo(blockInfo, x, y); +events.prototype._openDoor_check = function (block, x, y, needKey) { + var clearAndReturn = function () { + core.clearContinueAutomaticRoute(); + return false; + }; - var cb = function () { - core.maps._removeBlockFromMap(core.status.floorId, block); - if (!locked) core.unlockControl(); - core.status.replay.animate = false; - core.events.afterOpenDoor(block.event.id, x, y); - if (callback) callback(); + 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 + ) { + return clearAndReturn(); + } + + if (id == "steelDoor" && core.flags.steelDoorWithoutKey) needKey = false; + var doorInfo = block.event.doorInfo; + if (doorInfo == null) return clearAndReturn(); + // Check all keys + var keyInfo = doorInfo.keys || {}; + if (needKey) { + for (var keyName in keyInfo) { + var keyValue = keyInfo[keyName]; + if (keyName.endsWith(":o")) + keyName = keyName.substring(0, keyName.length - 2); + + // --- 如果是一个不存在的道具,则直接认为无法开启 + if (!core.material.items[keyName]) { + core.stopSound(); + core.playSound("操作失败"); + core.drawTip("无法开启此门"); + return clearAndReturn(); + } + if (core.itemCount(keyName) < keyValue) { + core.stopSound(); + core.playSound("操作失败"); + 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]); + } + } + core.playSound(doorInfo.openSound); + return true; +}; - 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)); +events.prototype._openDoor_animate = function (block, x, y, callback) { + var blockInfo = core.getBlockInfo(block); + blockInfo.opacity = block.opacity; + blockInfo.filter = block.filter; - core.animateFrame.lastAsyncId = animate; - core.animateFrame.asyncId[animate] = cb; -} + var speed = (block.event.doorInfo.time || 160) / 4; + + var locked = core.status.lockControl; + core.lockControl(); + core.status.replay.animate = true; + core.removeBlock(x, y); + + blockInfo.posX = 0; + core.maps._drawBlockInfo(blockInfo, x, y); + + var cb = function () { + core.maps._removeBlockFromMap(core.status.floorId, block); + if (!locked) core.unlockControl(); + 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) + ); + + core.animateFrame.lastAsyncId = animate; + core.animateFrame.asyncId[animate] = cb; +}; ////// 开一个门后触发的事件 ////// events.prototype.afterOpenDoor = function (doorId, x, y) { - return this.eventdata.afterOpenDoor(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); -} + this.getItem(data.event.id, 1, data.x, data.y, false, callback); +}; ////// 获得某个物品 ////// events.prototype.getItem = function (id, num, x, y, isGentleClick, callback) { - if (num == null) num = 1; - var itemCls = core.material.items[id].cls; - 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); - core.drawTip(text, id); + if (num == null) num = 1; + var itemCls = core.material.items[id].cls; + 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); + 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 || "该道具暂无描述"; - try { - hint = core.replaceText(hint); - } 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在装备栏进行装备)" : "")); - } - itemHint.push(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 || "该道具暂无描述"; + try { + hint = core.replaceText(hint); + } 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在装备栏进行装备)" + : "") + ); } + itemHint.push(id); + } - this.afterGetItem(id, x, y, isGentleClick); - if (callback) callback(); -} + this.afterGetItem(id, x, y, isGentleClick); + if (callback) callback(); +}; events.prototype.afterGetItem = function (id, x, y, isGentleClick) { - this.eventdata.afterGetItem(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); + 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) { - return core.events._canGetNextItem(dir); - }); - return directions.length > 0 ? this._getNextItem(directions[0], noRoute) : false; -} + var directions = ["up", "down", "left", "right"].filter(function (dir) { + return core.events._canGetNextItem(dir); + }); + return directions.length > 0 + ? this._getNextItem(directions[0], noRoute) + : false; +}; events.prototype._canGetNextItem = function (direction) { - direction = direction || core.getHeroLoc('direction'); - if (!core.canMoveHero(null, null, direction)) return; - 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'; -} + direction = direction || core.getHeroLoc("direction"); + if (!core.canMoveHero(null, null, direction)) return; + 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" + ); +}; 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"); - this.getItem(core.getBlockId(nx, ny), 1, nx, ny, true); - return true; -} + 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"); + 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.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(); - }); -} + data = data.event.data; + var heroLoc = {}; + 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) { - var info = this._changeFloor_getInfo(floorId, stair, heroLoc, time); - if (info == null) { - if (callback) callback(); - return; - } - floorId = info.floorId; - info.locked = core.status.lockControl; +events.prototype.changeFloor = function ( + floorId, + stair, + heroLoc, + time, + callback +) { + var info = this._changeFloor_getInfo(floorId, stair, heroLoc, time); + if (info == null) { + if (callback) callback(); + return; + } + floorId = info.floorId; + info.locked = core.status.lockControl; - core.dom.floorNameLabel.innerText = core.status.maps[floorId].title; - core.lockControl(); - core.stopAutomaticRoute(); - core.clearContinueAutomaticRoute(); - core.status.replay.animate = true; - clearInterval(core.interval.onDownInterval); - core.interval.onDownInterval = 'tmp'; + core.dom.floorNameLabel.innerText = core.status.maps[floorId].title; + core.lockControl(); + core.stopAutomaticRoute(); + core.clearContinueAutomaticRoute(); + core.status.replay.animate = true; + clearInterval(core.interval.onDownInterval); + core.interval.onDownInterval = "tmp"; - this._changeFloor_beforeChange(info, callback); -} + this._changeFloor_beforeChange(info, callback); +}; -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') { - var index = core.floorIds.indexOf(core.status.floorId); - 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); - return null; - } +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") { + var index = core.floorIds.indexOf(core.status.floorId); + 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); + return null; + } - if (main.mode != 'play' || core.isReplaying()) time = 0; - if (time == null) time = core.values.floorChangeTime; - time /= 20; + if (main.mode != "play" || core.isReplaying()) time = 0; + if (time == null) time = core.values.floorChangeTime; + time /= 20; - return { - floorId: floorId, - time: time, - heroLoc: core.clone(this._changeFloor_getHeroLoc(floorId, stair, heroLoc)) - }; -} + return { + floorId: floorId, + time: time, + 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 (stair) { - // --- 对称 - 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') - heroLoc.x = core.bigmap.width - 1 - core.getHeroLoc('x'); - else if (stair == ':symmetry_y') - heroLoc.y = core.bigmap.height - 1 - core.getHeroLoc('y'); - // 检查该层地图的 upFloor & downFloor & flyPoint - else if (core.status.maps[floorId][stair]) { - heroLoc.x = core.status.maps[floorId][stair][0]; - heroLoc.y = core.status.maps[floorId][stair][1]; - } - else { - core.extractBlocks(floorId); - var blocks = core.status.maps[floorId].blocks; - for (var i in blocks) { - if (!blocks[i].disable && blocks[i].event.id === stair) { - heroLoc.x = blocks[i].x; - heroLoc.y = blocks[i].y; - break; - } - } + if (!heroLoc) heroLoc = core.clone(core.status.hero.loc); + if (stair) { + // --- 对称 + 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") + heroLoc.x = core.bigmap.width - 1 - core.getHeroLoc("x"); + else if (stair == ":symmetry_y") + heroLoc.y = core.bigmap.height - 1 - core.getHeroLoc("y"); + // 检查该层地图的 upFloor & downFloor & flyPoint + else if (core.status.maps[floorId][stair]) { + heroLoc.x = core.status.maps[floorId][stair][0]; + heroLoc.y = core.status.maps[floorId][stair][1]; + } else { + core.extractBlocks(floorId); + var blocks = core.status.maps[floorId].blocks; + for (var i in blocks) { + if (!blocks[i].disable && blocks[i].event.id === stair) { + heroLoc.x = blocks[i].x; + heroLoc.y = blocks[i].y; + break; } + } } - ['x', 'y', 'direction'].forEach(function (name) { - if (heroLoc[name] == null) - heroLoc[name] = core.getHeroLoc(name); - }); - return heroLoc; -} + } + ["x", "y", "direction"].forEach(function (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); - else - core.showWithAnimate(core.dom.floorMsgGroup, info.time / 2, function () { - core.events._changeFloor_changing(info, callback); - }); - }, 25) -} + this._changeFloor_playSound(); + // 需要 setTimeout 执行,不然会出错 + window.setTimeout(function () { + 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); +}; events.prototype._changeFloor_playSound = function () { - // 播放换层音效 - if (core.hasFlag('__fromLoad__')) // 是否是读档造成的切换 - core.playSound('读档'); - else if (core.hasFlag('__isFlying__')) // 是否是楼传造成的切换 - core.playSound('飞行器'); - else - core.playSound('上下楼'); -} + // 播放换层音效 + if (core.hasFlag("__fromLoad__")) + // 是否是读档造成的切换 + core.playSound("读档"); + else if (core.hasFlag("__isFlying__")) + // 是否是楼传造成的切换 + core.playSound("飞行器"); + else core.playSound("上下楼"); +}; events.prototype._changeFloor_changing = function (info, callback) { - this.changingFloor(info.floorId, info.heroLoc); - // 回归视角 - var __lockViewport__ = flags.__lockViewport__; - core.setFlag('__lockViewport__', null); - core.drawHero(); - core.setFlag('__lockViewport__', __lockViewport__); + this.changingFloor(info.floorId, info.heroLoc); + // 回归视角 + var __lockViewport__ = flags.__lockViewport__; + core.setFlag("__lockViewport__", null); + core.drawHero(); + core.setFlag("__lockViewport__", __lockViewport__); - 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); - }); -} + 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); + }); +}; events.prototype._changeFloor_afterChange = function (info, callback) { - if (!info.locked) core.unlockControl(); - core.status.replay.animate = false; - core.events.afterChangeFloor(info.floorId); + if (!info.locked) core.unlockControl(); + core.status.replay.animate = false; + core.events.afterChangeFloor(info.floorId); - if (callback) callback(); -} + if (callback) callback(); +}; events.prototype.changingFloor = function (floorId, heroLoc) { - this.eventdata.changingFloor(floorId, heroLoc); -} + this.eventdata.changingFloor(floorId, heroLoc); +}; ////// 转换楼层结束的事件 ////// events.prototype.afterChangeFloor = function (floorId) { - if (main.mode != 'play') return; - return this.eventdata.afterChangeFloor(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(); -} + this.pushBox(data); + if (callback) callback(); +}; ////// 推箱子 ////// events.prototype.pushBox = function (data) { - if (data.event.id != 'box' && data.event.id != 'boxed') return; + if (data.event.id != "box" && data.event.id != "boxed") return; - // 判断还能否前进,看看是否存在事件 - var direction = core.getHeroLoc('direction'), - nx = data.x + core.utils.scan[direction].x, ny = data.y + core.utils.scan[direction].y; + // 判断还能否前进,看看是否存在事件 + var direction = core.getHeroLoc("direction"), + nx = data.x + core.utils.scan[direction].x, + ny = data.y + core.utils.scan[direction].y; - // 检测能否推上去 - if (!core.canMoveHero()) return; - var canGoDeadZone = core.flags.canGoDeadZone; - core.flags.canGoDeadZone = true; - if (!core.canMoveHero(data.x, data.y, direction)) { - core.flags.canGoDeadZone = canGoDeadZone; - return; - } + // 检测能否推上去 + if (!core.canMoveHero()) return; + var canGoDeadZone = core.flags.canGoDeadZone; + core.flags.canGoDeadZone = true; + if (!core.canMoveHero(data.x, data.y, direction)) { core.flags.canGoDeadZone = canGoDeadZone; + return; + } + core.flags.canGoDeadZone = canGoDeadZone; - var nextId = core.getBlockId(nx, ny); - if (nextId != null && nextId != 'flower') return; + var nextId = core.getBlockId(nx, ny); + if (nextId != null && nextId != "flower") return; - core.setBlock(nextId == null ? 'box' : 'boxed', nx, ny); + 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); - // 勇士前进一格,然后触发推箱子后事件 - core.insertAction([ - { "type": "moveAction" }, - { "type": "function", "function": "function() { core.afterPushBox(); }" } - ]); -} + 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(); }" }, + ]); +}; ////// 推箱子后的事件 ////// events.prototype.afterPushBox = function () { - return this.eventdata.afterPushBox(); -} + return this.eventdata.afterPushBox(); +}; events.prototype._sys_ski = function (data, callback) { - core.insertAction(["V2.6后,请将滑冰放在背景层!"], data.x, data.y); - if (callback) callback(); -} + 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'; -} + 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; - // 检查是否需要改变朝向 - if (ex == core.nextX() && ey == core.nextY()) { - 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); - } + 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]; + if (toId && id != toId) { + var number = core.getNumberById(toId); + if (number > 0) core.setBlock(number, ex, ey); } - this.insertAction(ev, ex, ey, callback); -} + } + 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 + ); +}; // ------ 自定义事件的处理 ------ // @@ -933,2856 +1044,3552 @@ events.prototype._sys_custom = function (data, callback) { // type为事件名,func为事件的处理函数,可接受(data, x, y, prefix)参数 // data为事件内容,x和y为当前点坐标(可为null),prefix为当前点前缀 events.prototype.registerEvent = function (type, func) { - this.actions[type] = func; -} + this.actions[type] = func; +}; ////// 注销一个自定义事件 events.prototype.unregisterEvent = function (type) { - delete this.actions[type]; -} + delete this.actions[type]; +}; ////// 执行一个自定义事件 events.prototype.doEvent = function (data, x, y, prefix) { - var type = data.type; - if (this.actions[type]) { - try { - return core.doFunc(this.actions[type], this, data, x, y, prefix); - } - catch (e) { - console.error(e); - console.error("ERROR in actions[" + type + "]"); - } + var type = data.type; + if (this.actions[type]) { + try { + return core.doFunc(this.actions[type], this, data, x, y, prefix); + } catch (e) { + console.error(e); + console.error("ERROR in actions[" + type + "]"); } - if (this["_action_" + type]) return this["_action_" + type](data, x, y, prefix); - core.insertAction("未知的自定义事件: " + type + "!"); - core.doAction(); -} + } + 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" }]; - // 结束所有正在执行的自动事件 - if (list.length == 0) { - core.status.autoEvents.forEach(function (autoEvent) { - core.autoEventExecuting(autoEvent.symbol, false); - }); - } + 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" }]; + // 结束所有正在执行的自动事件 + if (list.length == 0) { + core.status.autoEvents.forEach(function (autoEvent) { + core.autoEventExecuting(autoEvent.symbol, false); + }); } - if (x != null) data.x = x; - if (y != null) data.y = y; - if (callback) data.callback = callback; - if (!data.appendingEvents) data.appendingEvents = []; - if (!data.locStack) data.locStack = []; - core.status.event.id = 'action'; - core.status.event.data = data; -} + } + if (x != null) data.x = x; + if (y != null) data.y = y; + if (callback) data.callback = callback; + if (!data.appendingEvents) data.appendingEvents = []; + if (!data.locStack) data.locStack = []; + core.status.event.id = "action"; + core.status.event.data = data; +}; ////// 开始执行一系列自定义事件 ////// events.prototype.startEvents = function (list, x, y, callback) { - if (!list) return; - if (!(list instanceof Array)) { - list = [list]; - } - this.setEvents(list, x, y, callback); - // 停止勇士 - core.waitHeroToStop(function () { - core.lockControl(); - core.doAction(); - }); -} + if (!list) return; + if (!(list instanceof Array)) { + list = [list]; + } + this.setEvents(list, x, y, callback); + // 停止勇士 + core.waitHeroToStop(function () { + core.lockControl(); + core.doAction(); + }); +}; ////// 执行当前自定义事件列表中的下一个事件 ////// events.prototype.doAction = function () { - // 清空boxAnimate和UI层 - clearInterval(core.status.event.interval); - clearTimeout(core.status.event.interval); - clearInterval(core.status.event.animateUI); - core.status.event.interval = null; - delete core.status.event.aniamteUI; - if (core.status.gameOver || core.status.replay.failed) return; - // 判定是否执行完毕 - if (this._doAction_finishEvents()) return; - 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 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 (data._disabled) return core.doAction(); - data.floorId = data.floorId || floorId; - core.status.event.data.type = data.type; - this.doEvent(data, x, y, prefix); - return; -} + // 清空boxAnimate和UI层 + clearInterval(core.status.event.interval); + clearTimeout(core.status.event.interval); + clearInterval(core.status.event.animateUI); + core.status.event.interval = null; + delete core.status.event.aniamteUI; + if (core.status.gameOver || core.status.replay.failed) return; + // 判定是否执行完毕 + if (this._doAction_finishEvents()) return; + 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 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 (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; - // 事件处理完毕 - if (core.status.event.data.list.length == 0) { - // 检测并执行延迟自动事件 - if (core.status.event.data.appendingEvents.length > 0) { - this.setEvents(core.status.event.data.appendingEvents.shift()); - return false; - } - var callback = core.status.event.data.callback; - core.ui.closePanel(); - if (callback) callback(); - core.replay(); - return true; + if (core.status.event.id != "action") return true; + // 事件处理完毕 + if (core.status.event.data.list.length == 0) { + // 检测并执行延迟自动事件 + if (core.status.event.data.appendingEvents.length > 0) { + this.setEvents(core.status.event.data.appendingEvents.shift()); + return false; } - return false; -} + var callback = core.status.event.data.callback; + core.ui.closePanel(); + if (callback) callback(); + core.replay(); + 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 - current.todo = core.clone(current.total); - } - else { - core.status.event.data.list.shift(); // remove stack - } - core.doAction(); - return true; + if (current.todo.length == 0) { + // current list is empty + if (core.calValue(current.condition, prefix)) { + // check condition + current.todo = core.clone(current.total); + } else { + core.status.event.data.list.shift(); // remove stack } - return false; -} + core.doAction(); + return true; + } + return false; +}; ////// 往当前事件列表之前或之后添加一个或多个事件 ////// events.prototype.insertAction = function (action, x, y, callback, addToLast) { - if (core.hasFlag("__statistics__")) return; - if (core.status.gameOver) return; - if (!action) return; - core.clearRouteFolding(); + if (core.hasFlag("__statistics__")) return; + if (core.status.gameOver) return; + if (!action) return; + core.clearRouteFolding(); - action = this.precompile(action); + action = this.precompile(action); - if (core.status.event.id != 'action') { - this.startEvents(action, x, y, callback); - } - else { - if (addToLast) { - var list = core.status.event.data.list[0].todo; - var index = 0; - for (var index = 0; index < list.length; index++) { - if (list[index].type == '_label') { - list.splice(index, 0, action); - break; - } - } + if (core.status.event.id != "action") { + this.startEvents(action, x, y, callback); + } else { + if (addToLast) { + var list = core.status.event.data.list[0].todo; + var index = 0; + for (var index = 0; index < list.length; index++) { + if (list[index].type == "_label") { + list.splice(index, 0, action); + break; } - else core.unshift(core.status.event.data.list[0].todo, action); - this.setEvents(null, x, y, callback); - } -} + } + } 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) { - var commonEvent = this.getCommonEvent(name); - if (!commonEvent) { - if (callback) callback(); - return; - } +events.prototype.insertCommonEvent = function ( + name, + args, + x, + y, + callback, + addToLast +) { + var commonEvent = this.getCommonEvent(name); + if (!commonEvent) { + if (callback) callback(); + return; + } - // 设置参数 - core.setFlag('arg0', name); - 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) } - } + // 设置参数 + core.setFlag("arg0", name); + 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); + } } + } - 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; -} + if (!name || typeof name !== "string") return null; + return this.commonEvent[name] || null; +}; ////// 恢复一个事件 ////// events.prototype.recoverEvents = function (data) { - if (data) { - core.ui.closePanel(); - core.lockControl(); - core.status.event.id = 'action'; - core.status.event.data = data; - setTimeout(function () { - core.doAction(); - }, 30); - return true; - } - return false; -} + if (data) { + core.ui.closePanel(); + core.lockControl(); + core.status.event.id = "action"; + core.status.event.data = data; + setTimeout(function () { + core.doAction(); + }, 30); + return true; + } + return false; +}; ////// 检测自动事件 ////// events.prototype.checkAutoEvents = function () { - // 只有在无操作或事件流中才能执行自动事件! - if (!core.isPlaying() || (core.status.lockControl && core.status.event.id != 'action')) return; - if (core.hasFlag('__doNotCheckAutoEvents__')) return; - var todo = [], delay = []; - core.status.autoEvents.forEach(function (autoEvent) { - 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; - try { - if (!core.calValue(autoEvent.condition, prefix)) return; - } catch (e) { - return; - } - - core.autoEventExecuting(symbol, true); - core.autoEventExecuted(symbol, true); - - var event; - if (x == null && y == null) { - event = [ - // 用do-while(0)包一层防止break影响事件流 - { "type": "dowhile", "condition": "false", "data": autoEvent.data }, - { - "type": "function", "function": - "function() { core.autoEventExecuting('" + symbol + "', false); }" - } - ]; - } else { - event = [ - { - "type": "function", "function": - "function() { core.pushEventLoc(" + x + ", " + y + ", '" + floorId + "' ); }" - }, - // 用do-while(0)包一层防止break影响事件流 - { "type": "dowhile", "condition": "false", "data": autoEvent.data }, - { - "type": "function", "function": - "function() { core.popEventLoc(); core.autoEventExecuting('" + symbol + "', false); }" - } - ]; - } - - if (autoEvent.delayExecute) - delay.push(event); - else - core.push(todo, event); - }); - - if (todo.length == 0 && delay.length == 0) return; - - if (core.status.event.id == 'action' || todo.length > 0) { - core.insertAction(todo); - core.push(core.status.event.data.appendingEvents, delay); - } else { - core.insertAction(delay[0]); - if (delay.length > 0) { - core.insertAction(delay.slice(1)); - } + // 只有在无操作或事件流中才能执行自动事件! + if ( + !core.isPlaying() || + (core.status.lockControl && core.status.event.id != "action") + ) + return; + if (core.hasFlag("__doNotCheckAutoEvents__")) return; + var todo = [], + delay = []; + core.status.autoEvents.forEach(function (autoEvent) { + 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; + try { + if (!core.calValue(autoEvent.condition, prefix)) return; + } catch (e) { + return; } -} + core.autoEventExecuting(symbol, true); + core.autoEventExecuted(symbol, true); + + var event; + if (x == null && y == null) { + event = [ + // 用do-while(0)包一层防止break影响事件流 + { type: "dowhile", condition: "false", data: autoEvent.data }, + { + type: "function", + function: + "function() { core.autoEventExecuting('" + symbol + "', false); }", + }, + ]; + } else { + event = [ + { + type: "function", + function: + "function() { core.pushEventLoc(" + + x + + ", " + + y + + ", '" + + floorId + + "' ); }", + }, + // 用do-while(0)包一层防止break影响事件流 + { type: "dowhile", condition: "false", data: autoEvent.data }, + { + type: "function", + function: + "function() { core.popEventLoc(); core.autoEventExecuting('" + + symbol + + "', false); }", + }, + ]; + } + + if (autoEvent.delayExecute) delay.push(event); + else core.push(todo, event); + }); + + if (todo.length == 0 && delay.length == 0) return; + + if (core.status.event.id == "action" || todo.length > 0) { + core.insertAction(todo); + core.push(core.status.event.data.appendingEvents, delay); + } else { + core.insertAction(delay[0]); + if (delay.length > 0) { + 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; }); - if (value) aei.push(symbol); - core.setFlag('__aei__', aei); - } -} + var aei = core.getFlag("__aei__", []); + if (value == null) return aei.indexOf(symbol) >= 0; + else { + 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; }); - if (value) aed.push(symbol); - core.setFlag('__aed__', aed); - } -} + var aed = core.getFlag("__aed__", []); + if (value == null) return aed.indexOf(symbol) >= 0; + else { + 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; - core.status.event.data.locStack.push({ - x: core.status.event.data.x, - y: core.status.event.data.y, - floorId: core.status.event.data.floorId - }); - core.status.event.data.x = x; - core.status.event.data.y = y; - core.status.event.data.floorId = floorId; -} + if (core.status.event.id != "action") return; + core.status.event.data.locStack.push({ + x: core.status.event.data.x, + y: core.status.event.data.y, + floorId: core.status.event.data.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; - var loc = core.status.event.data.locStack.shift(); - if (loc) { - core.status.event.data.x = loc.x; - core.status.event.data.y = loc.y; - core.status.event.data.floorId = loc.floorId; - } -} + if (core.status.event.id != "action") return; + var loc = core.status.event.data.locStack.shift(); + if (loc) { + core.status.event.data.x = loc.x; + core.status.event.data.y = loc.y; + core.status.event.data.floorId = loc.floorId; + } +}; events.prototype.precompile = function (data) { - var array = this.__precompile_getArray(); - if (typeof data == 'string') { - return this.__precompile_text(data); - } - if (data instanceof Array) { - for (var i = 0; i < data.length; ++i) { - data[i] = this.precompile(data[i]); - } - return data; - } - if (data && data.type) { - 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); - } - if (array.locs.indexOf(data.type) >= 0) { - data.loc = this.__precompile_array(data.loc); - } - if (array.values.indexOf(data.type) >= 0) { - data.value = core.replaceValue(data.value); - } - if (array.uievents.indexOf(data.type) >= 0) { - data.x = core.replaceValue(data.x); - data.y = core.replaceValue(data.y); - data.width = core.replaceValue(data.width); - data.height = core.replaceValue(data.height); - } - if (data.type in array.others) { - array.others[data.type].forEach(function (field) { - data[field] = core.replaceValue(data[field]); - }) - } + var array = this.__precompile_getArray(); + if (typeof data == "string") { + return this.__precompile_text(data); + } + if (data instanceof Array) { + for (var i = 0; i < data.length; ++i) { + data[i] = this.precompile(data[i]); } return data; -} + } + if (data && data.type) { + 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); + } + if (array.locs.indexOf(data.type) >= 0) { + data.loc = this.__precompile_array(data.loc); + } + if (array.values.indexOf(data.type) >= 0) { + data.value = core.replaceValue(data.value); + } + if (array.uievents.indexOf(data.type) >= 0) { + data.x = core.replaceValue(data.x); + data.y = core.replaceValue(data.y); + data.width = core.replaceValue(data.width); + data.height = core.replaceValue(data.height); + } + 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" - ]; - 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" - ]; - var values = [ - "setValue", "setEnemy", "setEnemyOnPoint", "setEquip", "setFloor", "setGlobalValue", - ]; - var uievents = [ - "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"], - }; - return { - texts: texts, - locs: locs, - values: values, - uievents: uievents, - others: others - }; -} + var texts = [ + "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", + ]; + var values = [ + "setValue", + "setEnemy", + "setEnemyOnPoint", + "setEquip", + "setFloor", + "setGlobalValue", + ]; + var uievents = [ + "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"], + }; + return { + texts: texts, + locs: locs, + values: values, + 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) + "}"; - }); -} + if (typeof text != "string") return text; + return text.replace(/\${(.*?)}/g, function (word, value) { + return "${" + core.replaceValue(value) + "}"; + }); +}; events.prototype.__precompile_array = function (value) { - if (typeof value == 'string') { - value = core.replaceValue(value); - return value; - } - if (value instanceof Array) { - for (var i = 0; i < value.length; ++i) { - value[i] = this.__precompile_array(value[i]); - } - } + if (typeof value == "string") { + value = core.replaceValue(value); return value; -} + } + if (value instanceof Array) { + for (var i = 0; i < value.length; ++i) { + value[i] = this.__precompile_array(value[i]); + } + } + return value; +}; // ------ 样板提供的的自定义事件 ------ // events.prototype.__action_checkReplaying = function () { - if (core.isReplaying()) { - core.doAction(); - return true; - } - return false; -} + if (core.isReplaying()) { + core.doAction(); + return true; + } + return false; +}; events.prototype.__action_getLoc = function (loc, x, y, prefix) { - if (loc) { - x = core.calValue(loc[0], prefix); - y = core.calValue(loc[1], prefix); - } - return [x, y]; -} + if (loc) { + x = core.calValue(loc[0], 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; -} + 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 { - func.apply(this, parameters.concat(core.doAction)); - } -} + var parameters = Array.prototype.slice.call(arguments, 2); + if (isAsync) { + func.apply(this, parameters); + core.doAction(); + } 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;; - data.ctx = ctx; - if (core.getContextByName(ctx) && !data.showAll) { - core.ui._animateUI('hide', ctx, function () { - core.ui.drawTextBox(data.text, data); - core.ui._animateUI('show', ctx, function () { - if (data.async) core.doAction(); - }); - }); - return; - } - core.ui.drawTextBox(data.text, data); - if (!data.showAll) { - core.ui._animateUI('show', ctx, function () { - if (data.async) core.doAction(); - }); - } -} + if (this.__action_checkReplaying()) return; + data.text = core.replaceText(data.text, prefix); + var ctx = data.code ? "__text__" + data.code : null; + data.ctx = ctx; + if (core.getContextByName(ctx) && !data.showAll) { + core.ui._animateUI("hide", ctx, function () { + core.ui.drawTextBox(data.text, data); + core.ui._animateUI("show", ctx, function () { + if (data.async) core.doAction(); + }); + }); + return; + } + core.ui.drawTextBox(data.text, data); + if (!data.showAll) { + core.ui._animateUI("show", ctx, function () { + 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); -} + 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 + ); +}; events.prototype._action_clearTextBox = function (data, x, y, prefix) { - if (this.__action_checkReplaying()) return; - core.clearTextBox(data.code, core.doAction); -} + 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); -} + 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); -} + 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 + ); +}; events.prototype._action_comment = function (data, x, y, prefix) { - core.doAction(); -} + core.doAction(); +}; events.prototype._action__label = function (data, x, y, prefix) { - core.doAction(); -} + core.doAction(); +}; events.prototype._action_setText = function (data, x, y, prefix) { - this.setTextAttribute(data); - core.doAction(); -} + 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(); -} + 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 { - data.loc.forEach(function (t) { - core.showBlock(t[0], t[1], data.floorId); - }); - core.doAction(); - } -} + 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 { + 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 { - 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(); - } -} + 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 { + 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); - } else { - data.loc.forEach(function (loc) { - core.setBlock(data.number, loc[0], loc[1], data.floorId); - }); - core.doAction(); - } -} + 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 + ); + } 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 { - data.loc.forEach(function (t) { - core.setBlockOpacity(data.opacity, t[0], t[1], data.floorId); - }); - core.doAction(); - } -} + 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 { + 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); - data.loc.forEach(function (t) { - core.setBlockFilter(data, t[0], t[1], data.floorId); - }); - core.doAction(); -} + data.loc = this.__action_getLoc2D(data.loc, x, y, prefix); + data.loc.forEach(function (t) { + 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); - data.loc.forEach(function (t) { - core.turnBlock(data.direction, t[0], t[1], data.floorId); - }); - core.doAction(); -} + data.loc = this.__action_getLoc2D(data.loc, x, y, prefix); + data.loc.forEach(function (t) { + 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); - data.loc.forEach(function (t) { - core.setBgFgBlock(data.name, data.number, t[0], t[1], data.floorId); - }); - core.doAction(); -} + data.loc = this.__action_getLoc2D(data.loc, x, y, prefix); + data.loc.forEach(function (t) { + 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(); -} + this.follow(data.name); + core.doAction(); +}; events.prototype._action_unfollow = function (data, x, y, prefix) { - this.unfollow(data.name); - core.doAction(); -} + 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); - } -} + 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 + ); + } +}; events.prototype._action_stopAnimate = function (data, x, y, prefix) { - core.stopAnimate(null, data.doCallback); - core.doAction(); -} + 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)]; - } else if (data.loc == null) { - 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); -} + 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), + ]; + } else if (data.loc == null) { + 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 + ); +}; events.prototype._action_lockViewport = function (data, x, y, prefix) { - core.setFlag('__lockViewport__', data.lock || null); - core.doAction(); -} + 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); -} + 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 + ); +}; events.prototype._action_moveAction = function (data, x, y, prefix) { - // 检查下一个点是否可通行 - if (core.canMoveHero()) { - var nx = core.nextX(), ny = core.nextY(); - // 检查noPass决定是撞击还是移动 - if (core.noPass(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" }, - ]); - } + // 检查下一个点是否可通行 + if (core.canMoveHero()) { + var nx = core.nextX(), + ny = core.nextY(); + // 检查noPass决定是撞击还是移动 + if (core.noPass(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" }, + ]); } - core.doAction(); -} + } + 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; - if (data.dxy) { - 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); -} + 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), + ]; + } 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 + ); +}; 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; -} + 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)]; - } else { - loc = this.__action_getHeroLoc(data.loc, prefix); - } - this.__action_doAsyncFunc(data.async, core.jumpHero, loc[0], loc[1], data.time); -} + 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), + ]; + } else { + loc = this.__action_getHeroLoc(data.loc, prefix); + } + 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); -} + 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); +}; events.prototype._action_changePos = function (data, x, y, prefix) { - core.clearMap('hero'); - if (!data.loc && data.direction) { - core.setHeroLoc('direction', core.turnDirection(data.direction), true); - core.drawHero(); - return core.doAction(); - } - - 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)); + core.clearMap("hero"); + if (!data.loc && data.direction) { + core.setHeroLoc("direction", core.turnDirection(data.direction), true); core.drawHero(); - core.doAction(); -} + return core.doAction(); + } + + 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)); + 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); -} + 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 + ); +}; events.prototype._precompile_showImage = function (data) { - data.sloc = this.__precompile_array(data.sloc); - data.loc = this.__precompile_array(data.loc); - return 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"; - 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); - delete core.material.images.images[__tmpName]; -} + 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"; + 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 + ); + 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); -} + if (core.isReplaying()) data.time = 0; + 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(); -} + 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); -} + if (this.__action_checkReplaying()) return; + 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; -} + 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); -} + if (this.__action_checkReplaying()) return; + 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; -} + 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); -} + if (this.__action_checkReplaying()) return; + 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; -} + 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); + 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.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) - core.setFlag('__weather__', [data.name, data.level]); - else core.removeFlag('__weather__'); - core.doAction(); -} + core.setWeather(data.name, data.level); + 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 { - core.removeBlock(loc[0], loc[1], floorId); - core.doAction(); - } -} + 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 { + 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); -} + var loc = this.__action_getLoc(data.loc, x, y, prefix); + 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 { - core.playSound('操作失败'); - 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 { - if (data.floorId != core.status.floorId) { - core.doAction(); - return; - } - 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) { // 公共事件 - core.insertCommonEvent(data.name, data.args); - } - 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) } - } - } - 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]]; - 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.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(); - if (data.sync) { - core.playSound(data.name, data.pitch, core.doAction); - } else { - 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); -} - -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); - if (!data.norefresh) { - if (core.status.hero.hp <= 0) { - core.status.hero.hp = 0; - core.updateStatusBar(); - core.events.lose(); - } else { - core.updateStatusBar(); - } - } - 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); - 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.doAction(); -} - -events.prototype._action_resetEnemyOnPoint = function (data, x, y, prefix) { - var loc = this.__action_getLoc2D(data.loc, x, y, prefix); - loc.forEach(function (one) { - 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; - if (data.dxy) { - 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); - 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.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(); - }); -} - -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(); - }); -} - -events.prototype.__action_getInput = function (hint, isText, callback) { - 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); - 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) { - core.control._replay_error(action); - return; - } - } - 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.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"]); - return data; -} - -events.prototype._action_switch = function (data, x, y, 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) { - core.push(list, data.caseList[i].action); - 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].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; } - }) - 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)) { - var index = action.substring(8); - if (!this.__action_choices_replaying(data, index)) { - core.control._replay_error(action); - return; - } - } else { - // 容错录像 - if (main.replayChecking) { - // 录像验证系统中选最后一项 - 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; - } - 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.setFlag('timeout', 0); - core.doAction(); - }, data.timeout); - } - core.status.event.timeout = new Date().getTime() + (data.timeout || 0); - } - 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 = core.replaceText(data.choices[i].text, prefix); - } - core.ui.drawChoices(core.replaceText(data.text, prefix), data.choices, data.width); -} - -events.prototype.__action_choices_replaying = function (data, index) { - var selection = index; - if (index != 'none') { - selection = parseInt(index); - if (isNaN(selection)) return false; - if (selection < 0) selection += data.choices.length; - if (selection < 0) return false; - if (selection % 100 > 50) selection += data.choices.length; - if (selection % 100 > data.choices.length) return false; - var timeout = Math.floor(selection / 100) || 0; - core.setFlag('timeout', timeout); - 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); - } - } - 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].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 }; - if (core.isReplaying()) { - var action = core.status.replay.toReplay.shift(); - 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) { - this.__action_confirm_replaying(data, index); - } else { - core.control._replay_error(action); - return; - } - } else { - // 录像中未记录选了哪个,则选默认值,而不是直接报错 - 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; - if (data.timeout) { - core.status.event.interval = setTimeout(function () { - core.status.route.push("choices:none"); - core.setFlag('timeout', 0); - core.doAction(); - }, data.timeout); - } - 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') { - var timeout = Math.floor(index / 100) || 0; - core.setFlag('timeout', timeout); - 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)); -} - -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 - if (!/^temp:[A-Z]$/.test(data.name)) { - core.insertAction('循环遍历事件只支持临时变量!'); - return core.doAction(); - } - 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('循环遍历事件要求【起始点】【终止点】【每步】仅能是数字!'); - return core.doAction(); - } - // 首次判定 - if ((step > 0 && from > to) || (step < 0 && from < to)) { - core.doAction(); - return; - } - - var letter = data.name.substring(5); - core.setFlag('@temp@' + letter, from); - var toName = '@temp@for-to@' + letter; - 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 + "'));" + - "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); -} - -events.prototype._precompile_for = function (data) { - data.from = core.replaceValue(data.from); - data.to = core.replaceValue(data.to); - 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 - if (!/^temp:[A-Z]$/.test(data.name)) { - core.insertAction(['循环遍历事件只支持临时变量!']); - return core.doAction(); - } - 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); -} - -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 } - ); - } - 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 } + // 考虑到可能覆盖楼传事件的问题,这里不对fly进行检查。 + if (data.id != "book" && core.canUseItem(data.id)) { + core.useItem(data.id, true, core.doAction); + } else { + core.playSound("操作失败"); + core.drawTip( + "当前无法使用" + ((core.material.items[data.id] || {}).name || "未知道具") ); 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_loadEquip = function (data, x, y, prefix) { + core.loadEquip(data.id); + core.doAction(); +}; -events.prototype._action_break = function (data, x, y, prefix) { - var n = data.n || 1; - while (n--) { - if (core.status.event.data.list.length > 1) - core.status.event.data.list.shift(); +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 { + if (data.floorId != core.status.floorId) { + core.doAction(); + return; } - core.doAction(); -} + var loc = this.__action_getLoc(data.loc, x, y, prefix); + this.battle(null, loc[0], loc[1], true, core.doAction); + } +}; -events.prototype._action_continue = function (data, x, y, prefix) { - var n = data.n || 1; - while (n-- > 1) { - if (core.status.event.data.list.length > 1) - core.status.event.data.list.shift(); - } - 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.shift(); +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) { + // 公共事件 + core.insertCommonEvent(data.name, data.args); + } 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); } + } } + 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]]; + 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.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(); + if (data.sync) { + core.playSound(data.name, data.pitch, core.doAction); + } else { + core.playSound(data.name, data.pitch); 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_stopSound = function (data, x, y, prefix) { + core.stopSound(); + core.doAction(); +}; -events.prototype._action_lose = function (data, x, y, prefix) { - this.lose(core.replaceText(data.reason, prefix)); -} +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 + ); +}; -events.prototype._action_restart = function (data, x, y, prefix) { - core.restart(); -} +events.prototype._action_setBgmSpeed = function (data, x, y, prefix) { + core.setBgmSpeed(data.value, data.pitch || false); + core.doAction(); +}; -events.prototype._action_function = function (data, x, y, prefix) { - var func = data["function"]; - try { - if (typeof func == "string" && func.indexOf("function") == 0) { - eval('(' + func + ')()'); - } - } catch (e) { - console.error(e); - } - 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); +events.prototype._action_setValue = function (data, x, y, prefix) { + this.setValue(data.name, data.operator, data.value, prefix); + if (!data.norefresh) { + if (core.status.hero.hp <= 0) { + core.status.hero.hp = 0; + core.updateStatusBar(); + core.events.lose(); } else { - core.setFlag('__heroOpacity__', data.opacity); - core.drawHero(); - core.doAction(); + core.updateStatusBar(); } -} + } + 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); -} +events.prototype._action_addValue = function (data, x, y, prefix) { + data.operator = "+="; + this._action_setValue(data, x, y, prefix); +}; -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); -} +events.prototype._action_setEnemy = function (data, x, y, prefix) { + this.setEnemy( + data.id, + data.name, + data.value, + data.operator, + prefix, + data.norefresh + ); + core.doAction(); +}; -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); - this.__action_wait_afterGet(data); - return core.doAction(); - } else { - var value = parseInt(code.substring(6)); - core.status.route.push("input:" + value); - this.__action_wait_getValue(value); - if (this.__action_wait_afterGet(data) || !data.forceChild) return core.doAction(); - } - } - core.control._replay_error(code); +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.doAction(); +}; + +events.prototype._action_resetEnemyOnPoint = function (data, x, y, prefix) { + var loc = this.__action_getLoc2D(data.loc, x, y, prefix); + loc.forEach(function (one) { + 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; + if (data.dxy) { + 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 + ); + 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.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(); + } + ); +}; + +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(); + } + ); +}; + +events.prototype.__action_getInput = function (hint, isText, callback) { + 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); + 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) { + core.control._replay_error(action); + return; + } + } 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.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"]); + return data; +}; + +events.prototype._action_switch = function (data, x, y, 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) { + core.push(list, data.caseList[i].action); + 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].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; + } + }); + 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) + ) { + var index = action.substring(8); + if (!this.__action_choices_replaying(data, index)) { + core.control._replay_error(action); 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.events.__action_wait_afterGet(data); - core.doAction(); - }, data.timeout); + } + } else { + // 容错录像 + if (main.replayChecking) { + // 录像验证系统中选最后一项 + 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; + } + 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.setFlag("timeout", 0); + core.doAction(); + }, data.timeout); } core.status.event.timeout = new Date().getTime() + (data.timeout || 0); -} + } + 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 = core.replaceText(data.choices[i].text, prefix); + } + core.ui.drawChoices( + core.replaceText(data.text, prefix), + data.choices, + data.width + ); +}; + +events.prototype.__action_choices_replaying = function (data, index) { + var selection = index; + if (index != "none") { + selection = parseInt(index); + if (isNaN(selection)) return false; + if (selection < 0) selection += data.choices.length; + if (selection < 0) return false; + if (selection % 100 > 50) selection += data.choices.length; + if (selection % 100 > data.choices.length) return false; + var timeout = Math.floor(selection / 100) || 0; + core.setFlag("timeout", timeout); + 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); + } + } + 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].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 }; + if (core.isReplaying()) { + var action = core.status.replay.toReplay.shift(); + 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) + ) { + this.__action_confirm_replaying(data, index); + } else { + core.control._replay_error(action); + return; + } + } else { + // 录像中未记录选了哪个,则选默认值,而不是直接报错 + 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; + if (data.timeout) { + core.status.event.interval = setTimeout(function () { + core.status.route.push("choices:none"); + core.setFlag("timeout", 0); + core.doAction(); + }, data.timeout); + } + 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") { + var timeout = Math.floor(index / 100) || 0; + core.setFlag("timeout", timeout); + 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) + ); +}; + +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 + if (!/^temp:[A-Z]$/.test(data.name)) { + core.insertAction("循环遍历事件只支持临时变量!"); + return core.doAction(); + } + 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( + "循环遍历事件要求【起始点】【终止点】【每步】仅能是数字!" + ); + return core.doAction(); + } + // 首次判定 + if ((step > 0 && from > to) || (step < 0 && from < to)) { + core.doAction(); + return; + } + + var letter = data.name.substring(5); + core.setFlag("@temp@" + letter, from); + var toName = "@temp@for-to@" + letter; + 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 + + "'));" + + "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 + ); +}; + +events.prototype._precompile_for = function (data) { + data.from = core.replaceValue(data.from); + data.to = core.replaceValue(data.to); + 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 + if (!/^temp:[A-Z]$/.test(data.name)) { + core.insertAction(["循环遍历事件只支持临时变量!"]); + return core.doAction(); + } + 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 + ); +}; + +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, + }); + } + 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, + }); + 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; + while (n--) { + if (core.status.event.data.list.length > 1) + core.status.event.data.list.shift(); + } + core.doAction(); +}; + +events.prototype._action_continue = function (data, x, y, prefix) { + var n = data.n || 1; + while (n-- > 1) { + if (core.status.event.data.list.length > 1) + core.status.event.data.list.shift(); + } + 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.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"]; + try { + if (typeof func == "string" && func.indexOf("function") == 0) { + eval("(" + func + ")()"); + } + } catch (e) { + console.error(e); + } + 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 + ); + } 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 + ); +}; + +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 + ); +}; + +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); + this.__action_wait_afterGet(data); + return core.doAction(); + } else { + var value = parseInt(code.substring(6)); + core.status.route.push("input:" + value); + this.__action_wait_getValue(value); + 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.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); - value %= 1e8; - if (value >= 1000000) { - core.setFlag('type', 1); - 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) { - core.setFlag('type', 1); - 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) { - core.setFlag('type', 0); - core.setFlag('keycode', value); - } -} + 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; + core.setFlag("px", px); + core.setFlag("py", py); + core.setFlag("x", parseInt(px / 32)); + core.setFlag("y", parseInt(py / 32)); + } else if (value >= 10000) { + core.setFlag("type", 1); + 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) { + core.setFlag("type", 0); + core.setFlag("keycode", value); + } +}; events.prototype.__action_wait_afterGet = function (data) { - if (!data.data) return false; - var todo = []; - var stop = false; - 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) { - found = true; - core.push(todo, one.action); - if (one["break"]) stop = true; - } - }); + if (!data.data) return false; + var todo = []; + var stop = false; + 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) { + found = true; + core.push(todo, one.action); + if (one["break"]) stop = true; } - 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); - if (px >= pxmin && px <= pxmax && py >= pymin && py <= pymax) { - found = true; - core.push(todo, one.action); - if (one["break"]) stop = true; - } - } - if (one["case"] == "condition") { - var condition = false; - try { condition = core.calValue(one.condition); } catch (e) { } - if (condition) { - found = true; - core.push(todo, one.action); - if (one["break"]) stop = true; - } - } - if (one["case"] == "timeout" && core.getFlag("type") == -1) { - found = true; - core.push(todo, one.action); - if (one["break"]) stop = true; - } - }) - if (found) { - core.insertAction(todo); - return true; + }); } - return false; -} + 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); + if (px >= pxmin && px <= pxmax && py >= pymin && py <= pymax) { + found = true; + core.push(todo, one.action); + if (one["break"]) stop = true; + } + } + if (one["case"] == "condition") { + var condition = false; + try { + condition = core.calValue(one.condition); + } catch (e) {} + if (condition) { + found = true; + core.push(todo, one.action); + if (one["break"]) stop = true; + } + } + if (one["case"] == "timeout" && core.getFlag("type") == -1) { + found = true; + core.push(todo, one.action); + 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); - v.action = this.precompile(v.action); - }, this); - } - return 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); + 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)) { - clearInterval(test); - core.doAction(); - } - }, 50 / core.status.replay.speed); -} + var test = window.setInterval(function () { + 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(); -} + core.stopAsync(); + core.doAction(); +}; events.prototype._action_callBook = function (data, x, y, prefix) { - if (core.isReplaying() || !core.hasItem('book')) { - core.doAction(); - } - 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__"); - core.doAction(); - } - else { - var e = core.clone(core.status.event.data); - core.ui.closePanel(); - var forbidSave = core.hasFlag('__forbidSave__'); - core.removeFlag('__forbidSave__'); - core.save(); - 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__'); - core.removeFlag('__forbidSave__'); - core.autosave(data.removeLast); - if (forbidSave) core.setFlag('__forbidSave__', true); + if (core.isReplaying() || !core.hasItem("book")) { 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; + } else { var e = core.clone(core.status.event.data); core.ui.closePanel(); - core.load(); + 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__"); + core.doAction(); + } else { + var e = core.clone(core.status.event.data); + core.ui.closePanel(); + var forbidSave = core.hasFlag("__forbidSave__"); + core.removeFlag("__forbidSave__"); + core.save(); + 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__"); + core.removeFlag("__forbidSave__"); + 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; + var e = core.clone(core.status.event.data); + core.ui.closePanel(); + core.load(); + core.status.event.interval = e; +}; events.prototype._action_exit = function (data, x, y, prefix) { - this.setEvents([]); - core.doAction(); -} + this.setEvents([]); + core.doAction(); +}; events.prototype._action_previewUI = function (data, x, y, prefix) { - this.insertAction(data.action); - core.doAction(); -} + this.insertAction(data.action); + core.doAction(); +}; events.prototype._precompile_previewUI = function (data) { - data.action = this.precompile(data.action); - return data; -} + data.action = this.precompile(data.action); + return data; +}; events.prototype.__action_doUIEvent = function (data) { - this.__action_doUIEvent_doOne(data); - var current = core.status.event.data.list[0]; - while (current.todo.length > 0) { - data = current.todo[0]; - if (this.__action_doUIEvent_doOne(current.todo[0])) - current.todo.shift(); - else break; - } - core.doAction(); -} + this.__action_doUIEvent_doOne(data); + var current = core.status.event.data.list[0]; + while (current.todo.length > 0) { + data = current.todo[0]; + if (this.__action_doUIEvent_doOne(current.todo[0])) current.todo.shift(); + else break; + } + core.doAction(); +}; events.prototype.__action_doUIEvent_doOne = function (data) { - if (core.ui['_uievent_' + data.type]) { - core.ui['_uievent_' + data.type](data); - return true; - } - return false; -} + if (core.ui["_uievent_" + data.type]) { + core.ui["_uievent_" + data.type](data); + return true; + } + return false; +}; events.prototype._action_clearMap = function (data, x, y, prefix) { - this.__action_doUIEvent(data); -} + this.__action_doUIEvent(data); +}; events.prototype._action_fillText = function (data, x, y, prefix) { - data.text = core.replaceText(data.text, prefix); - this.__action_doUIEvent(data); -} + 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); -} + data.text = core.replaceText(data.text, prefix); + this.__action_doUIEvent(data); +}; events.prototype._action_fillRect = function (data, x, y, prefix) { - this.__action_doUIEvent(data); -} + this.__action_doUIEvent(data); +}; events.prototype._action_fillPolygon = function (data, x, y, prefix) { - this.__action_doUIEvent(data); -} + this.__action_doUIEvent(data); +}; events.prototype._precompile_fillPolygon = function (data) { - data.nodes = this.__precompile_array(data.nodes); - return data; -} + data.nodes = this.__precompile_array(data.nodes); + return data; +}; events.prototype._action_strokeRect = function (data, x, y, prefix) { - this.__action_doUIEvent(data); -} + this.__action_doUIEvent(data); +}; events.prototype._action_strokePolygon = function (data, x, y, prefix) { - this.__action_doUIEvent(data); -} + this.__action_doUIEvent(data); +}; events.prototype._precompile_strokePolygon = function (data) { - data.nodes = this.__precompile_array(data.nodes); - return data; -} + data.nodes = this.__precompile_array(data.nodes); + return data; +}; events.prototype._action_fillEllipse = function (data, x, y, prefix) { - this.__action_doUIEvent(data); -} + this.__action_doUIEvent(data); +}; events.prototype._action_strokeEllipse = function (data, x, y, prefix) { - this.__action_doUIEvent(data); -} + this.__action_doUIEvent(data); +}; events.prototype._action_fillArc = function (data, x, y, prefix) { - this.__action_doUIEvent(data); -} + this.__action_doUIEvent(data); +}; events.prototype._action_strokeArc = function (data, x, y, prefix) { - this.__action_doUIEvent(data); -} + this.__action_doUIEvent(data); +}; events.prototype._action_drawLine = function (data, x, y, prefix) { - this.__action_doUIEvent(data); -} + this.__action_doUIEvent(data); +}; events.prototype._action_drawArrow = function (data, x, y, prefix) { - this.__action_doUIEvent(data); -} + this.__action_doUIEvent(data); +}; events.prototype._action_setAttribute = function (data, x, y, prefix) { - this.__action_doUIEvent(data); -} + this.__action_doUIEvent(data); +}; events.prototype._action_setFilter = function (data, x, y, prefix) { - this.__action_doUIEvent(data); -} + this.__action_doUIEvent(data); +}; events.prototype._action_drawImage = function (data, x, y, prefix) { - this.__action_doUIEvent(data); -} + this.__action_doUIEvent(data); +}; events.prototype._action_drawIcon = function (data, x, y, prefix) { - this.__action_doUIEvent(data); -} + this.__action_doUIEvent(data); +}; events.prototype._action_drawSelector = function (data, x, y, prefix) { - this.__action_doUIEvent(data); -} + this.__action_doUIEvent(data); +}; events.prototype._action_drawBackground = function (data, x, y, prefix) { - this.__action_doUIEvent(data); -} + this.__action_doUIEvent(data); +}; events.prototype._action_drawTextContent = function (data, x, y, prefix) { - data.text = core.replaceText(data.text, prefix); - this.__action_doUIEvent(data); -} + data.text = core.replaceText(data.text, prefix); + this.__action_doUIEvent(data); +}; // ------ 点击状态栏图标所进行的一些操作 ------ // ////// 判断当前能否进入某个事件 ////// events.prototype._checkStatus = function (name, fromUserAction, checkItem) { - if (fromUserAction && core.status.event.id == name) { - core.ui.closePanel(); - return false; - } - if (fromUserAction && core.status.lockControl) return false; - if (checkItem && !core.hasItem(name)) { - core.playSound('操作失败'); - core.drawTip("你没有" + core.material.items[name].name, name); - return false; - } - if (core.isMoving()) { - core.playSound('操作失败'); - core.drawTip("请先停止勇士行动"); - return false; - } - core.lockControl(); - core.status.event.id = name; - return true; -} + if (fromUserAction && core.status.event.id == name) { + core.ui.closePanel(); + return false; + } + if (fromUserAction && core.status.lockControl) return false; + if (checkItem && !core.hasItem(name)) { + core.playSound("操作失败"); + core.drawTip("你没有" + core.material.items[name].name, name); + return false; + } + if (core.isMoving()) { + core.playSound("操作失败"); + 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)) - return; - // 当前是book,且从“浏览地图”打开 - if (core.status.event.id == 'book' && core.status.event.ui) { - core.status.boxAnimateObjs = []; - core.ui._drawViewMaps(core.status.event.ui); - return; - } - // 从“浏览地图”页面打开 - if (core.status.event.id == 'viewMaps') { - fromUserAction = false; - core.status.event.ui = core.status.event.data; - } - if (!this._checkStatus('book', fromUserAction, true)) return; - core.playSound('打开界面'); - core.useItem('book', true); -} + if (core.isReplaying()) return; + // 如果能恢复事件(从callBook事件触发) + 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) { + core.status.boxAnimateObjs = []; + core.ui._drawViewMaps(core.status.event.ui); + return; + } + // 从“浏览地图”页面打开 + if (core.status.event.id == "viewMaps") { + fromUserAction = false; + core.status.event.ui = core.status.event.data; + } + if (!this._checkStatus("book", fromUserAction, true)) return; + core.playSound("打开界面"); + core.useItem("book", true); +}; ////// 点击楼层传送器时的打开操作 ////// events.prototype.useFly = function (fromUserAction) { - if (core.isReplaying()) return; - // 从“浏览地图”页面:尝试直接传送到该层 - if (core.status.event.id == 'viewMaps') { - if (!core.hasItem('fly')) { - core.playSound('操作失败'); - core.drawTip('你没有' + core.material.items['fly'].name, 'fly'); - } else if (!core.canUseItem('fly') || (core.flags.flyNearStair && !core.nearStair())) { - core.playSound('操作失败'); - core.drawTip('无法传送到当前层', 'fly'); - } else { - core.flyTo(core.status.event.data.floorId); - } - return; + if (core.isReplaying()) return; + // 从“浏览地图”页面:尝试直接传送到该层 + if (core.status.event.id == "viewMaps") { + if (!core.hasItem("fly")) { + core.playSound("操作失败"); + core.drawTip("你没有" + core.material.items["fly"].name, "fly"); + } else if ( + !core.canUseItem("fly") || + (core.flags.flyNearStair && !core.nearStair()) + ) { + core.playSound("操作失败"); + core.drawTip("无法传送到当前层", "fly"); + } else { + core.flyTo(core.status.event.data.floorId); } - - if (!this._checkStatus('fly', fromUserAction, true)) return; - if (core.flags.flyNearStair && !core.nearStair()) { - core.playSound('操作失败'); - core.drawTip("只有在楼梯边才能使用" + core.material.items['fly'].name, 'fly'); - core.unlockControl(); - core.status.event.data = null; - core.status.event.id = null; - return; - } - if (!core.canUseItem('fly')) { - core.playSound('操作失败'); - core.drawTip(core.material.items['fly'].name + "好像失效了", 'fly'); - core.unlockControl(); - core.status.event.data = null; - core.status.event.id = null; - return; - } - core.playSound('打开界面'); - core.useItem('fly', true); return; -} + } + + if (!this._checkStatus("fly", fromUserAction, true)) return; + if (core.flags.flyNearStair && !core.nearStair()) { + core.playSound("操作失败"); + core.drawTip( + "只有在楼梯边才能使用" + core.material.items["fly"].name, + "fly" + ); + core.unlockControl(); + core.status.event.data = null; + core.status.event.id = null; + return; + } + if (!core.canUseItem("fly")) { + core.playSound("操作失败"); + core.drawTip(core.material.items["fly"].name + "好像失效了", "fly"); + core.unlockControl(); + core.status.event.data = null; + core.status.event.id = null; + return; + } + core.playSound("打开界面"); + core.useItem("fly", true); + return; +}; events.prototype.flyTo = function (toId, callback) { - return this.eventdata.flyTo(toId, callback); -} + return this.eventdata.flyTo(toId, callback); +}; ////// 点击装备栏时的打开操作 ////// events.prototype.openEquipbox = function (fromUserAction) { - if (core.isReplaying()) return; - if (!this._checkStatus('equipbox', fromUserAction)) return; - core.playSound('打开界面'); - core.ui._drawEquipbox(); -} + if (core.isReplaying()) return; + if (!this._checkStatus("equipbox", fromUserAction)) return; + core.playSound("打开界面"); + core.ui._drawEquipbox(); +}; ////// 点击工具栏时的打开操作 ////// events.prototype.openToolbox = function (fromUserAction) { - if (core.isReplaying()) return; - if (!this._checkStatus('toolbox', fromUserAction)) return; - core.playSound('打开界面'); - core.ui._drawToolbox(); -} + if (core.isReplaying()) return; + if (!this._checkStatus("toolbox", fromUserAction)) return; + core.playSound("打开界面"); + core.ui._drawToolbox(); +}; ////// 点击快捷商店按钮时的打开操作 ////// events.prototype.openQuickShop = function (fromUserAction) { - if (core.isReplaying()) return; + if (core.isReplaying()) return; - if (Object.keys(core.status.shops).length == 0) { - core.playSound('操作失败'); - core.drawTip("本游戏没有快捷商店!"); - return; + if (Object.keys(core.status.shops).length == 0) { + core.playSound("操作失败"); + core.drawTip("本游戏没有快捷商店!"); + return; + } + + // --- 如果只有一个商店,则直接打开之 + if (Object.keys(core.status.shops).length == 1) { + var shopId = Object.keys(core.status.shops)[0]; + if (core.status.event.id != null) return; + if (!core.canOpenShop(shopId)) { + core.playSound("操作失败"); + core.drawTip("当前无法打开快捷商店!"); + return; } - - // --- 如果只有一个商店,则直接打开之 - if (Object.keys(core.status.shops).length == 1) { - var shopId = Object.keys(core.status.shops)[0]; - if (core.status.event.id != null) return; - if (!core.canOpenShop(shopId)) { - core.playSound('操作失败'); - core.drawTip("当前无法打开快捷商店!"); - return; - } - var message = core.canUseQuickShop(shopId); - if (message != null) { - core.playSound('操作失败'); - core.drawTip(message); - return; - } - core.openShop(shopId, false); - return; + var message = core.canUseQuickShop(shopId); + if (message != null) { + core.playSound("操作失败"); + core.drawTip(message); + return; } + core.openShop(shopId, false); + return; + } - if (!this._checkStatus('selectShop', fromUserAction)) return; - core.ui._drawQuickShop(); -} + 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(); -} + if (core.isReplaying()) return; + if (!this._checkStatus("keyBoard", fromUserAction)) return; + core.ui._drawKeyBoard(); +}; ////// 点击保存按钮时的打开操作 ////// events.prototype.save = function (fromUserAction) { - if (core.isReplaying()) return; - if (core.hasFlag('__forbidSave__')) { - core.playSound('操作失败'); - core.drawTip('当前禁止存档'); - return; - } - 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; - core.playSound('打开界面'); - core.ui._drawSLPanel(10 * page + offset); -} + if (core.isReplaying()) return; + if (core.hasFlag("__forbidSave__")) { + core.playSound("操作失败"); + core.drawTip("当前禁止存档"); + return; + } + 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; + 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; - // 游戏开始前读档 - if (!core.isPlaying()) { - core.dom.startPanel.style.display = 'none'; - core.clearStatus(); - core.clearMap('all'); - 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)) - return; - if (!this._checkStatus('load', fromUserAction)) return; - core.playSound('打开界面'); + if (core.isReplaying()) return; + var saveIndex = core.saves.saveIndex; + 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.lockControl = true; + core.playSound("打开界面"); core.ui._drawSLPanel(10 * page + offset); -} + return; + } + 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; - core.playSound('打开界面'); - core.ui._drawSettings(); -} + if (core.isReplaying()) return; + if (!this._checkStatus("settings", fromUserAction)) return; + core.playSound("打开界面"); + core.ui._drawSettings(); +}; // ------ 一些事件的具体执行过程 ------ // events.prototype.hasAsync = function () { - return Object.keys(core.animateFrame.asyncId).length > 0; -} + return Object.keys(core.animateFrame.asyncId).length > 0; +}; ////// 立刻停止所有异步事件 ////// events.prototype.stopAsync = function () { - var callbacks = []; - for (var id in core.animateFrame.asyncId) { - clearInterval(id); - callbacks.push(core.animateFrame.asyncId[id]); - } - core.animateFrame.asyncId = {}; - callbacks.forEach(function (cb) { - if (cb && cb instanceof Function) cb(); - }); -} + var callbacks = []; + for (var id in core.animateFrame.asyncId) { + clearInterval(id); + callbacks.push(core.animateFrame.asyncId[id]); + } + core.animateFrame.asyncId = {}; + callbacks.forEach(function (cb) { + if (cb && cb instanceof Function) cb(); + }); +}; events.prototype.hasAsyncAnimate = function () { - return (core.status.animateObjs || []).length > 0; -} + 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.gatherFollowers(); - core.clearMap('hero'); - core.drawHero(); - } - core.clearRouteFolding(); -} + name = core.getMappedName(name); + if (core.material.images.images[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 = []; + if (!name) { + core.status.hero.followers = []; + } else { + name = core.getMappedName(name); + for (var i = 0; i < core.status.hero.followers.length; i++) { + if (core.status.hero.followers[i].name == name) { + core.status.hero.followers.splice(i, 1); + break; + } } - else { - name = core.getMappedName(name); - for (var i = 0; i < core.status.hero.followers.length; i++) { - if (core.status.hero.followers[i].name == name) { - core.status.hero.followers.splice(i, 1); - break; - } - } - } - core.gatherFollowers(); - core.clearMap('hero'); - core.drawHero(); - core.clearRouteFolding(); -} + } + core.gatherFollowers(); + core.clearMap("hero"); + core.drawHero(); + core.clearRouteFolding(); +}; -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; - } - return value; -} +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; + } + return value; +}; ////// 数值操作 ////// events.prototype.setValue = function (name, operator, value, prefix) { - 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); - this._setValue_setFlag(name, value); - this._setValue_setSwitch(name, value, prefix); - this._setValue_setTemp(name, value, prefix); - this._setValue_setGlobal(name, value); -} + 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); + this._setValue_setFlag(name, value); + 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; - core.setStatus(name.substring(7), value); -} + 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); -} + 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 (value > count) core.getItem(itemId, value - count); - else core.setItem(itemId, value); -} + 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; - core.setFlag(name.substring(5), value); -} + 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; - core.setGlobal(name.substring(7), value); -} + if (name.indexOf("global:") !== 0) return; + core.setGlobal(name.substring(7), value); +}; ////// 设置一个怪物属性 ////// -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); - enemyInfo[id][name] = value; - (core.material.enemys[id] || {})[name] = core.clone(value); - if (!norefresh) core.updateStatusBar(); -} +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 + ); + 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) { - 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); - 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; - if (!norefresh) core.updateStatusBar(); -} +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 + ); + 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; + if (!norefresh) core.updateStatusBar(); +}; ////// 重置某个点上的怪物属性 ////// events.prototype.resetEnemyOnPoint = function (x, y, floorId, norefresh) { - delete ((flags.enemyOnPoint || {})[floorId || core.status.floorId] || {})[x + "," + y]; - if (!norefresh) core.updateStatusBar(); -} + delete ((flags.enemyOnPoint || {})[floorId || core.status.floorId] || {})[ + x + "," + y + ]; + if (!norefresh) core.updateStatusBar(); +}; ////// 将某个点上已经设置的怪物属性移动到其他点 ////// -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 (!norefresh) core.updateStatusBar(); - } -} +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 (!norefresh) core.updateStatusBar(); + } +}; ////// 设置楼层属性 ////// events.prototype.setFloorInfo = function (name, value, floorId, prefix) { - floorId = floorId || core.status.floorId; - core.status.maps[floorId][name] = value; - core.updateStatusBar(); -} + 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) == "'")) - value = value.substring(1, value.length - 1); - // --- 检查 [] - if (value.charAt(0) == '[' && value.charAt(value.length - 1) == ']') - value = eval(value); - // --- 检查颜色 - if (/^[0-9 ]+,[0-9 ]+,[0-9 ]+(,[0-9. ]+)?$/.test(value)) { - value = 'rgba(' + value + ')'; - } + if (typeof value == "string") { + 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) == "]") + value = eval(value); + // --- 检查颜色 + if (/^[0-9 ]+,[0-9 ]+,[0-9 ]+(,[0-9. ]+)?$/.test(value)) { + value = "rgba(" + value + ")"; } - core.status.globalAttribute[name] = value; - core.setFlag('globalAttribute', core.status.globalAttribute); - core.resize(); -} + } + core.status.globalAttribute[name] = value; + core.setFlag("globalAttribute", core.status.globalAttribute); + core.resize(); +}; ////// 设置全局开关 ////// events.prototype.setGlobalFlag = function (name, value) { - var flags = core.getFlag("globalFlags", {}); - if (name.startsWith('s:')) { - name = name.substring(2); - 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.resize(); - if (name == 'blurFg') - core.redrawMap(); -} + var flags = core.getFlag("globalFlags", {}); + if (name.startsWith("s:")) { + name = name.substring(2); + 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.resize(); + if (name == "blurFg") core.redrawMap(); +}; ////// 设置文件别名 ////// events.prototype.setNameMap = function (name, value) { - if (!core.hasFlag('__nameMap__')) core.setFlag('__nameMap__', {}); - flags.__nameMap__[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) { - 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) { - if (data[t].length == 3) data[t].push(1); - core.status.textAttribute[t] = data[t]; - } - if (t == 'background') { - var name = core.getMappedName(data[t]); - var img = core.material.images.images[name]; - if (img && img.width == 192 && img.height == 128) { - core.status.textAttribute[t] = name; - } - } - }); - if (main.mode == 'play') core.setFlag('textAttribute', core.status.textAttribute); -} - -events.prototype.moveTextBox = function (code, loc, relative, moveMode, time, callback) { - var ctx = core.getContextByName('__text__' + code); - if (!ctx) { - if (callback) callback(); - return; + if (!core.isPlaying()) return; + [ + "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) { + if (data[t].length == 3) data[t].push(1); + core.status.textAttribute[t] = data[t]; } - 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 ox = parseInt(ctx.canvas.getAttribute('_left')) || 0; - var oy = parseInt(ctx.canvas.getAttribute('_top')) || 0; - - if (!time) { - core.relocateCanvas(ctx, ox + dx, oy + dy); - ctx.canvas.setAttribute('_text_left', loc[0]); - ctx.canvas.setAttribute('_text_top', loc[1]); - if (callback) callback(); - return; + if (t == "background") { + var name = core.getMappedName(data[t]); + var img = core.material.images.images[name]; + if (img && img.width == 192 && img.height == 128) { + core.status.textAttribute[t] = name; + } } + }); + if (main.mode == "play") + core.setFlag("textAttribute", core.status.textAttribute); +}; - 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) - }; - this._moveTextBox_moving(ctx, moveInfo, callback); -} +events.prototype.moveTextBox = function ( + code, + loc, + relative, + moveMode, + time, + callback +) { + var ctx = core.getContextByName("__text__" + code); + if (!ctx) { + if (callback) callback(); + return; + } + 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 ox = parseInt(ctx.canvas.getAttribute("_left")) || 0; + var oy = parseInt(ctx.canvas.getAttribute("_top")) || 0; + + if (!time) { + core.relocateCanvas(ctx, ox + dx, oy + dy); + ctx.canvas.setAttribute("_text_left", loc[0]); + ctx.canvas.setAttribute("_text_top", loc[1]); + if (callback) callback(); + return; + } + + 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), + }; + this._moveTextBox_moving(ctx, moveInfo, callback); +}; events.prototype._moveTextBox_moving = function (ctx, moveInfo, callback) { - 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)); - ctx.canvas.setAttribute('_text_left', moveInfo.sx + dx); - ctx.canvas.setAttribute('_text_top', moveInfo.sy + dy); - if (step == steps) { - delete core.animateFrame.asyncId[animate]; - clearInterval(animate); - if (callback) callback(); - } - }, 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) + ); + ctx.canvas.setAttribute("_text_left", moveInfo.sx + dx); + ctx.canvas.setAttribute("_text_top", moveInfo.sy + dy); + if (step == steps) { + delete core.animateFrame.asyncId[animate]; + clearInterval(animate); + if (callback) callback(); + } + }, 10); - core.animateFrame.lastAsyncId = animate; - core.animateFrame.asyncId[animate] = 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); }) - } + if (code == null) { + 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]; - var index = 0; - var _work = function () { - if (index == code.length) { - if (callback) callback(); - return; - } - var ctx = '__text__' + code[index++]; - if (!core.getContextByName(ctx)) return _work(); - core.ui._animateUI('hide', ctx, function () { - core.deleteCanvas(ctx); - _work(); - }); - }; - _work(); -} + if (!(code instanceof Array)) code = [code]; + var index = 0; + var _work = function () { + if (index == code.length) { + if (callback) callback(); + return; + } + var ctx = "__text__" + code[index++]; + if (!core.getContextByName(ctx)) return _work(); + core.ui._animateUI("hide", ctx, function () { + core.deleteCanvas(ctx); + _work(); + }); + }; + _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) { - if (callback) callback(); + id = id || ""; + if ( + (core.material.icons.animates[id] == null && + core.material.icons.npc48[id] == null) || + core.getBlock(x, y) != null + ) { + if (callback) callback(); + return; + } + var block = core.getBlockById(id); + var doorInfo = (block.event || {}).doorInfo; + if (!doorInfo) { + if (callback) callback(); + return; + } + + core.playSound(doorInfo.closeSound); + var blockInfo = core.getBlockInfo(block); + var speed = (doorInfo.time || 160) / 4; + blockInfo.posX = 3; + core.maps._drawBlockInfo(blockInfo, x, y); + + var cb = function () { + 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; - } - var block = core.getBlockById(id); - var doorInfo = (block.event || {}).doorInfo; - if (!doorInfo) { - if (callback) callback(); - return; - } + } + core.maps._drawBlockInfo(blockInfo, x, y); + }, + core.status.replay.speed == 24 + ? 1 + : speed / Math.max(core.status.replay.speed, 1) + ); - core.playSound(doorInfo.closeSound); - var blockInfo = core.getBlockInfo(block); - var speed = (doorInfo.time || 160) / 4; - blockInfo.posX = 3; - core.maps._drawBlockInfo(blockInfo, x, y); - - var cb = function () { - 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)); - - core.animateFrame.lastAsyncId = animate; - core.animateFrame.asyncId[animate] = cb; -} + core.animateFrame.lastAsyncId = animate; + core.animateFrame.asyncId[animate] = cb; +}; ////// 显示图片 ////// -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')) { - image = image.substring(0, image.length - 2); - } - image = core.getMappedName(image); - image = core.material.images.images[image]; +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")) { + image = image.substring(0, image.length - 2); } - if (!image) { - if (callback) callback(); - 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]); - 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]); - if (w == null) w = sw; - if (h == null) h = sh; - var zIndex = code + 100; - time = time || 0; - 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); - if (time == 0) { - core.setOpacity(name, opacityVal); - if (callback) callback(); - return; - } - core.setOpacity(name, 0); - this.moveImage(code, null, opacityVal, null, time, callback); -} + image = core.getMappedName(image); + image = core.material.images.images[image]; + } + if (!image) { + if (callback) callback(); + 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]); + 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]); + if (w == null) w = sw; + if (h == null) h = sh; + var zIndex = code + 100; + time = time || 0; + 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 + ); + if (time == 0) { + core.setOpacity(name, opacityVal); + if (callback) callback(); + return; + } + 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); - if (time == 0 || !core.dymCanvas[name]) { - core.deleteCanvas(name); - if (callback) callback(); - return; - } - this.moveImage(code, null, 0, null, time, function () { - core.deleteCanvas(name); - if (callback) callback(); - }); -} + time = time || 0; + var name = "image" + (code + 100); + if (time == 0 || !core.dymCanvas[name]) { + core.deleteCanvas(name); + if (callback) callback(); + return; + } + this.moveImage(code, null, 0, null, time, function () { + core.deleteCanvas(name); + if (callback) callback(); + }); +}; ////// 移动图片 ////// -events.prototype.moveImage = function (code, to, opacityVal, moveMode, time, callback) { - to = to || []; - var name = "image" + (code + 100); - if (!core.dymCanvas[name]) { - if (callback) callback(); - return; - } - 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); +events.prototype.moveImage = function ( + code, + to, + opacityVal, + moveMode, + time, + callback +) { + to = to || []; + var name = "image" + (code + 100); + if (!core.dymCanvas[name]) { + if (callback) callback(); + return; + } + 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 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); - core.setOpacity(toOpacity); - if (callback) callback(); - return; - } + if (!time) { + core.relocateCanvas(name, toX, toY); + core.setOpacity(toOpacity); + if (callback) callback(); + 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); - 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 moveFunc = core.applyEasing(moveInfo.moveMode); - var animate = setInterval(function () { - step++; - currOpacity = opacity + (toOpacity - opacity) * moveFunc(step / steps); - currX = parseInt(fromX + (toX - fromX) * moveFunc(step / steps)); - currY = parseInt(fromY + (toY - fromY) * moveFunc(step / steps)); - core.setOpacity(name, currOpacity); - core.relocateCanvas(name, currX, currY); - if (step == steps) { - delete core.animateFrame.asyncId[animate]; - clearInterval(animate); - if (callback) callback(); - } - }, 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 moveFunc = core.applyEasing(moveInfo.moveMode); + var animate = setInterval(function () { + step++; + currOpacity = opacity + (toOpacity - opacity) * moveFunc(step / steps); + currX = parseInt(fromX + (toX - fromX) * moveFunc(step / steps)); + currY = parseInt(fromY + (toY - fromY) * moveFunc(step / steps)); + core.setOpacity(name, currOpacity); + core.relocateCanvas(name, currX, currY); + if (step == steps) { + delete core.animateFrame.asyncId[animate]; + clearInterval(animate); + if (callback) callback(); + } + }, per_time); - core.animateFrame.lastAsyncId = animate; - core.animateFrame.asyncId[animate] = callback; -} + core.animateFrame.lastAsyncId = animate; + core.animateFrame.asyncId[animate] = callback; +}; ////// 旋转图片 ////// -events.prototype.rotateImage = function (code, center, angle, moveMode, time, callback) { - center = center || []; - 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]); +events.prototype.rotateImage = function ( + code, + center, + angle, + moveMode, + time, + callback +) { + center = center || []; + 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 fromAngle = parseFloat(canvas.getAttribute('_angle')) || 0; + var fromAngle = parseFloat(canvas.getAttribute("_angle")) || 0; - if (!time) { - core.rotateCanvas(name, fromAngle + angle, centerX, centerY); - if (callback) callback(); - return; - } + if (!time) { + core.rotateCanvas(name, fromAngle + angle, centerX, centerY); + if (callback) callback(); + return; + } - var rotateInfo = { - 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); -} + var rotateInfo = { + 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); - 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); - if (step == steps) { - delete core.animateFrame.asyncId[animate]; - clearInterval(animate); - if (callback) callback(); - } - }, 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); + if (step == steps) { + delete core.animateFrame.asyncId[animate]; + clearInterval(animate); + if (callback) callback(); + } + }, per_time); - core.animateFrame.lastAsyncId = animate; - core.animateFrame.asyncId[animate] = callback; -} + core.animateFrame.lastAsyncId = animate; + core.animateFrame.asyncId[animate] = callback; +}; ////// 放缩一张图片 ////// -events.prototype.scaleImage = function (code, center, scale, moveMode, time, callback) { - center = center || []; - var name = "image" + (code + 100); - if (!core.dymCanvas[name]) { - if (callback) callback(); - return; - } - var ctx = core.dymCanvas[name]; - var currScale = 1.0; - if (ctx.canvas.hasAttribute('_scale')) { - 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]); - if (centerX == null || centerY == null) { - 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 - } - this._scaleImage_scale(ctx, scaleInfo, callback); -} +events.prototype.scaleImage = function ( + code, + center, + scale, + moveMode, + time, + callback +) { + center = center || []; + var name = "image" + (code + 100); + if (!core.dymCanvas[name]) { + if (callback) callback(); + return; + } + var ctx = core.dymCanvas[name]; + var currScale = 1.0; + if (ctx.canvas.hasAttribute("_scale")) { + 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]); + if (centerX == null || centerY == null) { + 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, + }; + 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); - ctx.canvas.setAttribute('_scale', 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) { - this._scaleInfo_scale(ctx, scaleInfo, scaleInfo.scale); - if (callback) callback(); - return; + if (!scaleInfo.time) { + this._scaleInfo_scale(ctx, scaleInfo, scaleInfo.scale); + if (callback) callback(); + return; + } + + 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); + core.events._scaleInfo_scale(ctx, scaleInfo, scale); + if (step == steps) { + delete core.animateFrame.asyncId[animate]; + clearInterval(animate); + if (callback) callback(); } + }, 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); - core.events._scaleInfo_scale(ctx, scaleInfo, scale); - if (step == steps) { - delete core.animateFrame.asyncId[animate]; - clearInterval(animate); - if (callback) callback(); - } - }, per_time); - - core.animateFrame.lastAsyncId = animate; - core.animateFrame.asyncId[animate] = callback; -} + core.animateFrame.lastAsyncId = animate; + core.animateFrame.asyncId[animate] = callback; +}; ////// 绘制或取消一张gif图片 ////// events.prototype.showGif = function (name, x, y) { - name = core.getMappedName(name); - var image = core.material.images.images[name]; - if (image) { - 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"; - core.dom.gif2.appendChild(gif); - } - else { - core.dom.gif2.innerHTML = ""; - } -} + name = core.getMappedName(name); + var image = core.material.images.images[name]; + if (image) { + 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"; + core.dom.gif2.appendChild(gif); + } 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; + 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; + }; + if (!time || time < 100) { + set(value); + if (callback) callback(); + return; + } + var currVolume = core.musicStatus.designVolume; + time /= Math.max(core.status.replay.speed, 1); + var per_time = 10, + step = 0, + steps = parseInt(time / per_time); + if (steps <= 0) steps = 1; + var animate = setInterval(function () { + step++; + set(currVolume + ((value - currVolume) * step) / steps); + if (step >= steps) { + delete core.animateFrame.asyncId[animate]; + clearInterval(animate); + if (callback) callback(); } - if (!time || time < 100) { - set(value); - if (callback) callback(); - return; - } - var currVolume = core.musicStatus.designVolume; - time /= Math.max(core.status.replay.speed, 1); - var per_time = 10, step = 0, steps = parseInt(time / per_time); - if (steps <= 0) steps = 1; - var animate = setInterval(function () { - step++; - set(currVolume + (value - currVolume) * step / steps); - if (step >= steps) { - delete core.animateFrame.asyncId[animate]; - clearInterval(animate); - if (callback) callback(); - } - }, per_time); + }, per_time); - core.animateFrame.lastAsyncId = animate; - core.animateFrame.asyncId[animate] = callback; -} + core.animateFrame.lastAsyncId = animate; + core.animateFrame.asyncId[animate] = callback; +}; ////// 画面震动 ////// events.prototype.vibrate = function (direction, time, speed, power, callback) { - if (core.isReplaying()) { - if (callback) callback(); - return; + if (core.isReplaying()) { + if (callback) callback(); + return; + } + if (!time) time = 1000; + speed = speed || 10; + power = power || 10; + 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) + ]; + } + 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); } - if (!time) time = 1000; - speed = speed || 10; - power = power || 10; - 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)]; + if (shakeInfo.duration === 0 && shakeInfo.shake == 0) { + delete core.animateFrame.asyncId[animate]; + clearInterval(animate); + cb(); } - 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); - } - if (shakeInfo.duration === 0 && shakeInfo.shake == 0) { - delete core.animateFrame.asyncId[animate]; - clearInterval(animate); - cb(); - } - }, 10); + }, 10); - core.animateFrame.lastAsyncId = animate; - core.animateFrame.asyncId[animate] = cb; -} + 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) { - shakeInfo.shake = 0; - } else { - shakeInfo.shake += delta; - } - if (shakeInfo.shake > shakeInfo.power) { - shakeInfo.direction = -1; - } - if (shakeInfo.shake < -shakeInfo.power) { - shakeInfo.direction = 1; - } - if (shakeInfo.duration >= 1) { - shakeInfo.duration -= 1 - } + if (shakeInfo.duration >= 1 || shakeInfo.shake != 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; } -} + if (shakeInfo.shake > shakeInfo.power) { + shakeInfo.direction = -1; + } + if (shakeInfo.shake < -shakeInfo.power) { + shakeInfo.direction = 1; + } + if (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); - }); - 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); - delete core.animateFrame.asyncId[animate]; - _run(); - } - else if (core.events._eventMoveHero_moving(++step, moveSteps)) - step = 0; - } - }, 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 o = direction == 'backward' ? -1 : 1; - if (direction == 'forward' || direction == 'backward') direction = core.getHeroLoc('direction'); - var faceDirection = direction; - if (direction == 'leftup' || direction == 'leftdown') faceDirection = 'left'; - if (direction == 'rightup' || direction == 'rightdown') faceDirection = 'right'; - core.setHeroLoc('direction', direction); - if (curr[1] <= 0) { - core.setHeroLoc('direction', faceDirection); - moveSteps.shift(); - return true; - } - if (step <= 4) { - core.drawHero('leftFoot', 4 * o * step); - } - else if (step <= 8) { - core.drawHero('rightFoot', 4 * o * step); - } - if (step == 8) { - core.setHeroLoc('x', x + o * core.utils.scan2[direction].x, true); - core.setHeroLoc('y', y + o * core.utils.scan2[direction].y, true); - core.updateFollowers(); - curr[1]--; - if (curr[1] <= 0) moveSteps.shift(); - core.setHeroLoc('direction', faceDirection); - return true; - } - return false; -} - -////// 勇士跳跃事件 ////// -events.prototype.jumpHero = function (ex, ey, time, callback) { - 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; - if (!core.isset(ex)) ex = sx; - if (!core.isset(ey)) ey = sy; - var jumpInfo = core.maps.__generateJumpInfo(sx, sy, ex, ey, time || 500); - jumpInfo.icon = core.material.icons.hero[core.getHeroLoc('direction')]; - jumpInfo.width = core.material.icons.hero.width || 32; - jumpInfo.height = core.material.icons.hero.height; - - this._jumpHero_doJump(jumpInfo, callback); -} - -events.prototype._jumpHero_doJump = function (jumpInfo, 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) + ); + }); + core.status.heroMoving = -1; + var _run = function () { var cb = function () { - core.setHeroLoc('x', jumpInfo.ex); - core.setHeroLoc('y', jumpInfo.ey); - core.status.heroMoving = 0; - core.drawHero(); - if (callback) 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) - else { - delete core.animateFrame.asyncId[animate]; + 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); - cb(); + delete core.animateFrame.asyncId[animate]; + _run(); + } else if (core.events._eventMoveHero_moving(++step, moveSteps)) + step = 0; } - }, jumpInfo.per_time); + }, + 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 o = direction == "backward" ? -1 : 1; + if (direction == "forward" || direction == "backward") + direction = core.getHeroLoc("direction"); + var faceDirection = direction; + if (direction == "leftup" || direction == "leftdown") faceDirection = "left"; + if (direction == "rightup" || direction == "rightdown") + faceDirection = "right"; + core.setHeroLoc("direction", direction); + if (curr[1] <= 0) { + core.setHeroLoc("direction", faceDirection); + moveSteps.shift(); + return true; + } + if (step <= 4) { + core.drawHero("leftFoot", 4 * o * step); + } else if (step <= 8) { + core.drawHero("rightFoot", 4 * o * step); + } + if (step == 8) { + core.setHeroLoc("x", x + o * core.utils.scan2[direction].x, true); + core.setHeroLoc("y", y + o * core.utils.scan2[direction].y, true); + core.updateFollowers(); + curr[1]--; + if (curr[1] <= 0) moveSteps.shift(); + core.setHeroLoc("direction", faceDirection); + return true; + } + return false; +}; + +////// 勇士跳跃事件 ////// +events.prototype.jumpHero = function (ex, ey, time, callback) { + 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; + if (!core.isset(ex)) ex = sx; + if (!core.isset(ey)) ey = sy; + var jumpInfo = core.maps.__generateJumpInfo(sx, sy, ex, ey, time || 500); + jumpInfo.icon = core.material.icons.hero[core.getHeroLoc("direction")]; + jumpInfo.width = core.material.icons.hero.width || 32; + jumpInfo.height = core.material.icons.hero.height; + + this._jumpHero_doJump(jumpInfo, callback); +}; + +events.prototype._jumpHero_doJump = function (jumpInfo, callback) { + var cb = function () { + core.setHeroLoc("x", jumpInfo.ex); + core.setHeroLoc("y", jumpInfo.ey); + 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); + else { + delete core.animateFrame.asyncId[animate]; + clearInterval(animate); + cb(); + } + }, jumpInfo.per_time); + + 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; - core.drawHero('stop', { x: nowx - 32 * x, y: nowy - 32 * y }); -} + 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; + 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); - return; - } - if (core.material.images.hero == img) return; - core.status.hero.image = name; - core.material.images.hero = img; - core.material.icons.hero.width = img.width / 4; - core.material.icons.hero.height = img.height / 4; - core.control.updateHeroIcon(name); - if (!noDraw) core.drawHero(); -} + name = core.getMappedName(name); + var img = core.material.images.images[name]; + if (!img) { + console.error("找不到图片: " + img); + return; + } + if (core.material.images.hero == img) return; + core.status.hero.image = name; + core.material.images.hero = img; + core.material.icons.hero.width = img.width / 4; + core.material.icons.hero.height = img.height / 4; + core.control.updateHeroIcon(name); + if (!noDraw) core.drawHero(); +}; ////// 检查升级事件 ////// events.prototype.checkLvUp = function () { - var actions = []; - while (true) { - var next = this._checkLvUp_check(); - if (next == null) break; - actions = actions.concat(next); - } - if (actions.length > 0) core.insertAction(actions); -} + var actions = []; + while (true) { + var next = this._checkLvUp_check(); + if (next == null) break; + 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; - // 计算下一个所需要的数值 - 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) { - // 升级 - core.status.hero.lv++; - if (next.clear) core.status.hero.exp -= need; - return next.action || []; - } + 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 need = core.calValue(next.need); + if (need == null) return null; + if (core.status.hero.exp >= need) { + // 升级 + core.status.hero.lv++; + if (next.clear) core.status.hero.exp -= need; + return next.action || []; + } + return null; +}; ////// 尝试使用道具 ////// events.prototype.tryUseItem = function (itemId) { - if (itemId == 'book') { - core.ui.closePanel(); - return core.openBook(false); - } - if (itemId == 'fly') { - core.ui.closePanel(); - return core.useFly(false); - } - if (itemId == 'centerFly') { - core.ui.closePanel(); - return core.ui._drawCenterFly(); - } - if (core.canUseItem(itemId)) { - core.ui.closePanel(); - core.useItem(itemId); - } else { - core.playSound('操作失败'); - core.drawTip("当前无法使用" + core.material.items[itemId].name, itemId); - } -} + if (itemId == "book") { + core.ui.closePanel(); + return core.openBook(false); + } + if (itemId == "fly") { + core.ui.closePanel(); + return core.useFly(false); + } + if (itemId == "centerFly") { + core.ui.closePanel(); + return core.ui._drawCenterFly(); + } + if (core.canUseItem(itemId)) { + core.ui.closePanel(); + core.useItem(itemId); + } else { + core.playSound("操作失败"); + core.drawTip("当前无法使用" + core.material.items[itemId].name, itemId); + } +}; diff --git a/libs/loader.js b/libs/loader.js index e00620d..27a5ec4 100644 --- a/libs/loader.js +++ b/libs/loader.js @@ -1,606 +1,818 @@ - /* loader.js:负责对资源的加载 */ "use strict"; -function loader () { - this._init(); +function loader() { + this._init(); } -loader.prototype._init = function () { - -} +loader.prototype._init = function () {}; ////// 设置加载进度条进度 ////// loader.prototype._setStartProgressVal = function (val) { - core.dom.startTopProgress.style.width = val + '%'; -} + core.dom.startTopProgress.style.width = val + "%"; +}; ////// 设置加载进度条提示文字 ////// loader.prototype._setStartLoadTipText = function (text) { - core.dom.startTopLoadTips.innerText = text; -} + core.dom.startTopLoadTips.innerText = text; +}; loader.prototype._load = function (callback) { - this._loadMusics(); - if (main.useCompress) { - this._load_async(callback); - } else { - this._load_sync(callback); - } -} + this._loadMusics(); + if (main.useCompress) { + this._load_async(callback); + } else { + this._load_sync(callback); + } +}; loader.prototype._load_sync = function (callback) { - this._loadAnimates_sync(); - this._loadSounds_sync(); - core.loader._loadMaterials_sync(function () { - core.loader._loadExtraImages_sync(function () { - core.loader._loadAutotiles_sync(function () { - core.loader._loadTilesets_sync(callback); - }) - }) + this._loadAnimates_sync(); + this._loadSounds_sync(); + core.loader._loadMaterials_sync(function () { + core.loader._loadExtraImages_sync(function () { + core.loader._loadAutotiles_sync(function () { + core.loader._loadTilesets_sync(callback); + }); }); -} + }); +}; loader.prototype._load_async = function (callback) { - core.loader._setStartLoadTipText('正在加载资源文件...'); - const all = {}; + core.loader._setStartLoadTipText("正在加载资源文件..."); + const all = {}; - const _makeOnProgress = function (name) { - if (!all[name]) all[name] = { loaded: 0, total: 0, finished: false }; - return (loaded, total) => { - all[name].loaded = loaded; - all[name].total = total; - let allLoaded = 0, allTotal = 0; - for (const one of Object.values(all)) { - allLoaded += one.loaded; - allTotal += one.total; - } - console.log(allLoaded. allTotal); - if (allTotal > 0) { - if (allLoaded == allTotal) { - core.loader._setStartLoadTipText("正在处理资源文件... 请稍候..."); - } else { - core.loader._setStartLoadTipText('正在加载资源文件... ' + - core.formatSize(allLoaded) + " / " + core.formatSize(allTotal) + - " (" + (allLoaded / allTotal * 100).toFixed(2) + "%)"); - } - core.loader._setStartProgressVal(allLoaded / allTotal * 100); - } - }; - } - const _makeOnFinished = function (name) { - return () => { - setTimeout(() => { - all[name].finished = true; - for (var one in all) { - if (!all[one].finished) return; - } - callback(); - }); + const _makeOnProgress = function (name) { + if (!all[name]) all[name] = { loaded: 0, total: 0, finished: false }; + return (loaded, total) => { + all[name].loaded = loaded; + all[name].total = total; + let allLoaded = 0, + allTotal = 0; + for (const one of Object.values(all)) { + allLoaded += one.loaded; + allTotal += one.total; + } + console.log(allLoaded.allTotal); + if (allTotal > 0) { + if (allLoaded == allTotal) { + core.loader._setStartLoadTipText("正在处理资源文件... 请稍候..."); + } else { + core.loader._setStartLoadTipText( + "正在加载资源文件... " + + core.formatSize(allLoaded) + + " / " + + core.formatSize(allTotal) + + " (" + + ((allLoaded / allTotal) * 100).toFixed(2) + + "%)" + ); } - } + core.loader._setStartProgressVal((allLoaded / allTotal) * 100); + } + }; + }; + const _makeOnFinished = function (name) { + return () => { + setTimeout(() => { + all[name].finished = true; + for (var one in all) { + if (!all[one].finished) return; + } + callback(); + }); + }; + }; - if (main.splitChunkMap) { - this._loadAnimates_chunked(main.splitChunkMap.animates, _makeOnProgress, _makeOnFinished); - this._loadSounds_chunked(main.splitChunkMap.sounds, _makeOnProgress, _makeOnFinished); - this._loadMaterials_chunked(main.splitChunkMap.materials, _makeOnProgress, _makeOnFinished); - this._loadExtraImages_chunked(main.splitChunkMap.images, _makeOnProgress, _makeOnFinished); - this._loadAutotiles_chunked(main.splitChunkMap.autotiles, _makeOnProgress, _makeOnFinished); - this._loadTilesets_chunked(main.splitChunkMap.tilesets, _makeOnProgress, _makeOnFinished); - } else { - this._loadAnimates_async(_makeOnProgress('animates'), _makeOnFinished('animates')); - this._loadSounds_async(_makeOnProgress('sounds'), _makeOnFinished('sounds')); - this._loadMaterials_async(_makeOnProgress('materials'), _makeOnFinished('materials')); - this._loadExtraImages_async(_makeOnProgress('images'), _makeOnFinished('images')); - this._loadAutotiles_async(_makeOnProgress('autotiles'), _makeOnFinished('autotiles')); - this._loadTilesets_async(_makeOnProgress('tilesets'), _makeOnFinished('tilesets')); - } -} + if (main.splitChunkMap) { + this._loadAnimates_chunked( + main.splitChunkMap.animates, + _makeOnProgress, + _makeOnFinished + ); + this._loadSounds_chunked( + main.splitChunkMap.sounds, + _makeOnProgress, + _makeOnFinished + ); + this._loadMaterials_chunked( + main.splitChunkMap.materials, + _makeOnProgress, + _makeOnFinished + ); + this._loadExtraImages_chunked( + main.splitChunkMap.images, + _makeOnProgress, + _makeOnFinished + ); + this._loadAutotiles_chunked( + main.splitChunkMap.autotiles, + _makeOnProgress, + _makeOnFinished + ); + this._loadTilesets_chunked( + main.splitChunkMap.tilesets, + _makeOnProgress, + _makeOnFinished + ); + } else { + this._loadAnimates_async( + _makeOnProgress("animates"), + _makeOnFinished("animates") + ); + this._loadSounds_async( + _makeOnProgress("sounds"), + _makeOnFinished("sounds") + ); + this._loadMaterials_async( + _makeOnProgress("materials"), + _makeOnFinished("materials") + ); + this._loadExtraImages_async( + _makeOnProgress("images"), + _makeOnFinished("images") + ); + this._loadAutotiles_async( + _makeOnProgress("autotiles"), + _makeOnFinished("autotiles") + ); + this._loadTilesets_async( + _makeOnProgress("tilesets"), + _makeOnFinished("tilesets") + ); + } +}; // ----- 加载资源文件 ------ // loader.prototype._loadMaterials_sync = function (callback) { - this._setStartLoadTipText("正在加载资源文件..."); - this.loadImages("materials", core.materials, core.material.images, function () { - core.loader._loadMaterials_afterLoad(); - callback(); - }); -} + this._setStartLoadTipText("正在加载资源文件..."); + this.loadImages( + "materials", + core.materials, + core.material.images, + function () { + core.loader._loadMaterials_afterLoad(); + callback(); + } + ); +}; loader.prototype._loadMaterials_async = function (onprogress, onfinished) { - this.loadImagesFromZip('project/materials/materials.h5data', core.materials, core.material.images, onprogress, function () { - core.loader._loadMaterials_afterLoad(); - onfinished(); - }); -} + this.loadImagesFromZip( + "project/materials/materials.h5data", + core.materials, + core.material.images, + onprogress, + function () { + core.loader._loadMaterials_afterLoad(); + onfinished(); + } + ); +}; -loader.prototype._loadMaterials_chunked = async function (chunks, makeOnProgress, makeOnFinished) { - await this._loadImagesFromChunks(chunks, core.materials, core.material.images, makeOnProgress, makeOnFinished); - core.loader._loadMaterials_afterLoad(); -} +loader.prototype._loadMaterials_chunked = async function ( + chunks, + makeOnProgress, + makeOnFinished +) { + await this._loadImagesFromChunks( + chunks, + core.materials, + core.material.images, + makeOnProgress, + makeOnFinished + ); + core.loader._loadMaterials_afterLoad(); +}; loader.prototype._loadMaterials_afterLoad = function () { - const images = core.splitImage(core.material.images['icons']); - for (let key in core.statusBar.icons) { - if (typeof core.statusBar.icons[key] == 'number') { - core.statusBar.icons[key] = images[core.statusBar.icons[key]]; - if (core.statusBar.image[key] != null) - core.statusBar.image[key].src = core.statusBar.icons[key].src; - } + const images = core.splitImage(core.material.images["icons"]); + for (let key in core.statusBar.icons) { + if (typeof core.statusBar.icons[key] == "number") { + core.statusBar.icons[key] = images[core.statusBar.icons[key]]; + if (core.statusBar.image[key] != null) + core.statusBar.image[key].src = core.statusBar.icons[key].src; } -} + } +}; // ------ 加载使用的图片 ------ // loader.prototype._loadExtraImages_sync = function (callback) { - core.material.images.images = {}; - this._setStartLoadTipText("正在加载图片文件..."); - core.loadImages("images", core.images, core.material.images.images, callback); -} + core.material.images.images = {}; + this._setStartLoadTipText("正在加载图片文件..."); + core.loadImages("images", core.images, core.material.images.images, callback); +}; loader.prototype._loadExtraImages_async = function (onprogress, onfinished) { - core.material.images.images = {}; - - // Check .gif - const gifs = images.filter(function (name) { - return name.toLowerCase().endsWith('.gif'); - }); - // gif没有被压缩在zip中,延迟加载... - this._loadExtraImages_loadLazy(gifs); + core.material.images.images = {}; - images = images.filter((name) => !name.toLowerCase().endsWith('.gif')); + // Check .gif + const gifs = images.filter(function (name) { + return name.toLowerCase().endsWith(".gif"); + }); + // gif没有被压缩在zip中,延迟加载... + this._loadExtraImages_loadLazy(gifs); - this.loadImagesFromZip('project/images/images.h5data', images, core.material.images.images, onprogress, onfinished); -} + images = images.filter((name) => !name.toLowerCase().endsWith(".gif")); -loader.prototype._loadExtraImages_chunked = function (chunks, makeOnProgress, makeOnFinished) { - core.material.images.images = {}; - let images = core.images; + this.loadImagesFromZip( + "project/images/images.h5data", + images, + core.material.images.images, + onprogress, + onfinished + ); +}; - // Check .gif - const gifs = images.filter(function (name) { - return name.toLowerCase().endsWith('.gif'); - }); - // gif没有被压缩在zip中,延迟加载... - this._loadExtraImages_loadLazy(gifs); +loader.prototype._loadExtraImages_chunked = function ( + chunks, + makeOnProgress, + makeOnFinished +) { + core.material.images.images = {}; + let images = core.images; - images = images.filter((name) => !name.toLowerCase().endsWith('.gif')); + // Check .gif + const gifs = images.filter(function (name) { + return name.toLowerCase().endsWith(".gif"); + }); + // gif没有被压缩在zip中,延迟加载... + this._loadExtraImages_loadLazy(gifs); - this._loadImagesFromChunks(chunks, images, core.material.images.images, makeOnProgress, makeOnFinished); -} + images = images.filter((name) => !name.toLowerCase().endsWith(".gif")); + + this._loadImagesFromChunks( + chunks, + images, + core.material.images.images, + makeOnProgress, + makeOnFinished + ); +}; loader.prototype._loadExtraImages_loadLazy = function (list) { - list.forEach(function (gif) { - this.loadImage("images", gif, (id, image) => { - if (image != null) { - core.material.images.images[gif] = image; - } - }); - }, this); -} + list.forEach(function (gif) { + this.loadImage("images", gif, (id, image) => { + if (image != null) { + core.material.images.images[gif] = image; + } + }); + }, this); +}; // ------ 加载自动元件 ------ // loader.prototype._loadAutotiles_sync = function (callback) { - core.material.images.autotile = {}; - var keys = Object.keys(core.material.icons.autotile); - var autotiles = {}; + core.material.images.autotile = {}; + var keys = Object.keys(core.material.icons.autotile); + var autotiles = {}; - this._setStartLoadTipText("正在加载自动元件..."); - this.loadImages("autotiles", keys, autotiles, function () { - core.loader._loadAutotiles_afterLoad(keys, autotiles); - callback(); - }); -} + this._setStartLoadTipText("正在加载自动元件..."); + this.loadImages("autotiles", keys, autotiles, function () { + core.loader._loadAutotiles_afterLoad(keys, autotiles); + callback(); + }); +}; loader.prototype._loadAutotiles_async = function (onprogress, onfinished) { - core.material.images.autotile = {}; - var keys = Object.keys(core.material.icons.autotile); - var autotiles = {}; + core.material.images.autotile = {}; + var keys = Object.keys(core.material.icons.autotile); + var autotiles = {}; - this.loadImagesFromZip('project/autotiles/autotiles.h5data', keys, autotiles, onprogress, function () { - core.loader._loadAutotiles_afterLoad(keys, autotiles); - onfinished(); - }); -} + this.loadImagesFromZip( + "project/autotiles/autotiles.h5data", + keys, + autotiles, + onprogress, + function () { + core.loader._loadAutotiles_afterLoad(keys, autotiles); + onfinished(); + } + ); +}; -loader.prototype._loadAutotiles_chunked = async function (chunks, makeOnProgress, makeOnFinished) { - core.material.images.autotile = {}; - const keys = Object.keys(core.material.icons.autotile); - const autotiles = {}; +loader.prototype._loadAutotiles_chunked = async function ( + chunks, + makeOnProgress, + makeOnFinished +) { + core.material.images.autotile = {}; + const keys = Object.keys(core.material.icons.autotile); + const autotiles = {}; - await this._loadImagesFromChunks(chunks, keys, autotiles, makeOnProgress, makeOnFinished); - core.loader._loadAutotiles_afterLoad(keys, autotiles); -} + await this._loadImagesFromChunks( + chunks, + keys, + autotiles, + makeOnProgress, + makeOnFinished + ); + core.loader._loadAutotiles_afterLoad(keys, autotiles); +}; loader.prototype._loadAutotiles_afterLoad = function (keys, autotiles) { - // autotile需要保证顺序 - keys.forEach(function (v) { - core.material.images.autotile[v] = autotiles[v]; - }); + // autotile需要保证顺序 + keys.forEach(function (v) { + core.material.images.autotile[v] = autotiles[v]; + }); - setTimeout(function () { - core.maps._makeAutotileEdges(); - }); - -} + setTimeout(function () { + core.maps._makeAutotileEdges(); + }); +}; // ------ 加载额外素材 ------ // loader.prototype._loadTilesets_sync = function (callback) { - core.material.images.tilesets = {}; - this._setStartLoadTipText("正在加载额外素材..."); - this.loadImages("tilesets", core.tilesets, core.material.images.tilesets, function () { - core.loader._loadTilesets_afterLoad(); - callback(); - }); -} + core.material.images.tilesets = {}; + this._setStartLoadTipText("正在加载额外素材..."); + this.loadImages( + "tilesets", + core.tilesets, + core.material.images.tilesets, + function () { + core.loader._loadTilesets_afterLoad(); + callback(); + } + ); +}; loader.prototype._loadTilesets_async = function (onprogress, onfinished) { - core.material.images.tilesets = {}; - this.loadImagesFromZip('project/tilesets/tilesets.h5data', core.tilesets, core.material.images.tilesets, onprogress, function () { - core.loader._loadTilesets_afterLoad(); - onfinished(); - }); -} + core.material.images.tilesets = {}; + this.loadImagesFromZip( + "project/tilesets/tilesets.h5data", + core.tilesets, + core.material.images.tilesets, + onprogress, + function () { + core.loader._loadTilesets_afterLoad(); + onfinished(); + } + ); +}; -loader.prototype._loadTilesets_chunked = async function (chunks, makeOnProgress, makeOnFinished) { - core.material.images.tilesets = {}; - await this._loadImagesFromChunks(chunks, core.tilesets, core.material.images.tilesets, makeOnProgress, makeOnFinished); - core.loader._loadTilesets_afterLoad(); -} +loader.prototype._loadTilesets_chunked = async function ( + chunks, + makeOnProgress, + makeOnFinished +) { + core.material.images.tilesets = {}; + await this._loadImagesFromChunks( + chunks, + core.tilesets, + core.material.images.tilesets, + makeOnProgress, + makeOnFinished + ); + core.loader._loadTilesets_afterLoad(); +}; loader.prototype._loadTilesets_afterLoad = function () { - // 检查宽高是32倍数,如果出错在控制台报错 - for (var imgName in core.material.images.tilesets) { - var img = core.material.images.tilesets[imgName]; - if (img.width % 32 != 0 || img.height % 32 != 0) { - console.warn("警告!" + imgName + "的宽或高不是32的倍数!"); - } - if (img.width * img.height > 32 * 32 * 3000) { - console.warn("警告!" + imgName + "上的图块素材个数大于3000!"); - } + // 检查宽高是32倍数,如果出错在控制台报错 + for (var imgName in core.material.images.tilesets) { + var img = core.material.images.tilesets[imgName]; + if (img.width % 32 != 0 || img.height % 32 != 0) { + console.warn("警告!" + imgName + "的宽或高不是32的倍数!"); } -} + if (img.width * img.height > 32 * 32 * 3000) { + console.warn("警告!" + imgName + "上的图块素材个数大于3000!"); + } + } +}; // ------ 实际加载一系列图片 ------ // loader.prototype.loadImages = function (dir, names, toSave, callback) { - if (!names || names.length == 0) { - if (callback) callback(); + if (!names || names.length == 0) { + if (callback) callback(); + return; + } + var items = 0; + for (var i = 0; i < names.length; i++) { + this.loadImage(dir, names[i], function (id, image) { + core.loader._setStartLoadTipText("正在加载图片 " + id + "..."); + if (toSave[id] !== undefined) { + if (image != null) toSave[id] = image; return; - } - var items = 0; - for (var i = 0; i < names.length; i++) { - this.loadImage(dir, names[i], function (id, image) { - core.loader._setStartLoadTipText('正在加载图片 ' + id + "..."); - if (toSave[id] !== undefined) { - if (image != null) - toSave[id] = image; - return; - } - toSave[id] = image; - items++; - core.loader._setStartProgressVal(items * (100 / names.length)); - if (items == names.length) { - if (callback) callback(); - } - }) - } -} + } + toSave[id] = image; + items++; + core.loader._setStartProgressVal(items * (100 / names.length)); + if (items == names.length) { + if (callback) callback(); + } + }); + } +}; loader.prototype.loadImage = function (dir, imgName, callback) { - try { - var name = imgName; - if (name.indexOf(".") < 0) - name = name + ".png"; - var image = new Image(); - image.onload = function () { - image.setAttribute('_width', image.width); - image.setAttribute('_height', image.height); - callback(imgName, image); - } - image.onerror = function () { - callback(imgName, null); - } - image.src = 'project/' + dir + '/' + name + "?v=" + main.version; - if (name.endsWith('.gif')) - callback(imgName, null); - } - catch (e) { - console.error(e); - } -} + try { + var name = imgName; + if (name.indexOf(".") < 0) name = name + ".png"; + var image = new Image(); + image.onload = function () { + image.setAttribute("_width", image.width); + image.setAttribute("_height", image.height); + callback(imgName, image); + }; + image.onerror = function () { + callback(imgName, null); + }; + image.src = "project/" + dir + "/" + name + "?v=" + main.version; + if (name.endsWith(".gif")) callback(imgName, null); + } catch (e) { + console.error(e); + } +}; // ------ 从zip中加载一系列图片 ------ // -loader.prototype.loadImagesFromZip = function (url, names, toSave, onprogress, onfinished) { - if (!names || names.length == 0) { - if (onfinished) onfinished(); - return; - } +loader.prototype.loadImagesFromZip = function ( + url, + names, + toSave, + onprogress, + onfinished +) { + if (!names || names.length == 0) { + if (onfinished) onfinished(); + return; + } - core.unzip(url + "?v=" + main.version, function (data) { - var cnt = 1; - names.forEach(function (name) { - var imgName = name; - if (imgName.indexOf('.') < 0) imgName += '.png'; - if (imgName in data) { - var img = new Image(); - var url = URL.createObjectURL(data[imgName]); - cnt++; - img.onload = function () { - cnt--; - URL.revokeObjectURL(url); - img.setAttribute('_width', img.width); - img.setAttribute('_height', img.height); - if (cnt == 0 && onfinished) onfinished(); - } - img.src = url; - toSave[name] = img; - } - }); - cnt--; - if (cnt == 0 && onfinished) onfinished(); - }, null, false, onprogress); -} + core.unzip( + url + "?v=" + main.version, + function (data) { + var cnt = 1; + names.forEach(function (name) { + var imgName = name; + if (imgName.indexOf(".") < 0) imgName += ".png"; + if (imgName in data) { + var img = new Image(); + var url = URL.createObjectURL(data[imgName]); + cnt++; + img.onload = function () { + cnt--; + URL.revokeObjectURL(url); + img.setAttribute("_width", img.width); + img.setAttribute("_height", img.height); + if (cnt == 0 && onfinished) onfinished(); + }; + img.src = url; + toSave[name] = img; + } + }); + cnt--; + if (cnt == 0 && onfinished) onfinished(); + }, + null, + false, + onprogress + ); +}; -loader.prototype._loadImagesFromChunks = async function (chunks, names, toSave, makeOnProgress, makeOnFinished) { - await Promise.all(chunks.map((chunk) => { - const onfinished = makeOnFinished(chunk); - const onprogress = makeOnProgress(chunk); - return new Promise((resolve) => { - this.loadImagesFromZip(chunk, names, toSave, onprogress, () => { - onfinished(); - resolve(); - }); +loader.prototype._loadImagesFromChunks = async function ( + chunks, + names, + toSave, + makeOnProgress, + makeOnFinished +) { + await Promise.all( + chunks.map((chunk) => { + const onfinished = makeOnFinished(chunk); + const onprogress = makeOnProgress(chunk); + return new Promise((resolve) => { + this.loadImagesFromZip(chunk, names, toSave, onprogress, () => { + onfinished(); + resolve(); }); - })); -} + }); + }) + ); +}; // ------ 加载动画文件 ------ // loader.prototype._loadAnimates_sync = function () { - this._setStartLoadTipText("正在加载动画文件..."); + this._setStartLoadTipText("正在加载动画文件..."); - if (main.supportBunch) { - if (core.animates.length > 0) { - core.http('GET', '__all_animates__?v=' + main.version + '&id=' + core.animates.join(','), null, function (content) { - var u = content.split('@@@~~~###~~~@@@'); - for (var i = 0; i < core.animates.length; ++i) { - if (u[i] != '') { - core.material.animates[core.animates[i]] = core.loader._loadAnimate(u[i]); - } else { - console.error('无法找到动画文件' + core.animates[i] + '!'); - } - } - }, "text/plain; charset=x-user-defined"); - } - return; + if (main.supportBunch) { + if (core.animates.length > 0) { + core.http( + "GET", + "__all_animates__?v=" + main.version + "&id=" + core.animates.join(","), + null, + function (content) { + var u = content.split("@@@~~~###~~~@@@"); + for (var i = 0; i < core.animates.length; ++i) { + if (u[i] != "") { + core.material.animates[core.animates[i]] = + core.loader._loadAnimate(u[i]); + } else { + console.error("无法找到动画文件" + core.animates[i] + "!"); + } + } + }, + "text/plain; charset=x-user-defined" + ); } + return; + } - core.animates.forEach(function (t) { - core.http('GET', 'project/animates/' + t + ".animate?v=" + main.version, null, function (content) { - core.material.animates[t] = core.loader._loadAnimate(content); - }, function (e) { - console.error(e); - core.material.animates[t] = null; - }, "text/plain; charset=x-user-defined") - }); -} + core.animates.forEach(function (t) { + core.http( + "GET", + "project/animates/" + t + ".animate?v=" + main.version, + null, + function (content) { + core.material.animates[t] = core.loader._loadAnimate(content); + }, + function (e) { + console.error(e); + core.material.animates[t] = null; + }, + "text/plain; charset=x-user-defined" + ); + }); +}; loader.prototype._loadAnimates_async = function (onprogress, onfinished) { - this._loadFileFromZip('project/animates/animates.h5data', this._saveAnimate, true, onprogress, onfinished); -} + this._loadFileFromZip( + "project/animates/animates.h5data", + this._saveAnimate, + true, + onprogress, + onfinished + ); +}; -loader.prototype._loadAnimates_chunked = function (chunks, makeOnProgress, makeOnFinished) { - this._loadFileFromChunks(chunks, this._saveAnimate, true, makeOnProgress, makeOnFinished); -} +loader.prototype._loadAnimates_chunked = function ( + chunks, + makeOnProgress, + makeOnFinished +) { + this._loadFileFromChunks( + chunks, + this._saveAnimate, + true, + makeOnProgress, + makeOnFinished + ); +}; loader.prototype._saveAnimate = function (animates, onfinished) { - for (var name in animates) { - if (name.endsWith(".animate")) { - var t = name.substring(0, name.length - 8); - if (core.animates.indexOf(t) >= 0) - core.material.animates[t] = core.loader._loadAnimate(animates[name]); - } + for (var name in animates) { + if (name.endsWith(".animate")) { + var t = name.substring(0, name.length - 8); + if (core.animates.indexOf(t) >= 0) + core.material.animates[t] = core.loader._loadAnimate(animates[name]); } - onfinished(); -} + } + onfinished(); +}; loader.prototype._loadAnimate = function (content) { - try { - content = JSON.parse(content); - var data = {}; - data.ratio = content.ratio; - data.se = content.se; - data.pitch = content.pitch; - data.images = []; - content.bitmaps.forEach(function (t2) { - if (!t2) { - data.images.push(null); - } - else { - try { - var image = new Image(); - image.src = t2; - data.images.push(image); - } catch (e) { - console.error(e); - data.images.push(null); - } - } - }) - data.frame = content.frame_max; - data.frames = []; - content.frames.forEach(function (t2) { - var info = []; - t2.forEach(function (t3) { - info.push({ - 'index': t3[0], - 'x': t3[1], - 'y': t3[2], - 'zoom': t3[3], - 'opacity': t3[4], - 'mirror': t3[5] || 0, - 'angle': t3[6] || 0, - }) - }) - data.frames.push(info); + try { + content = JSON.parse(content); + var data = {}; + data.ratio = content.ratio; + data.se = content.se; + data.pitch = content.pitch; + data.images = []; + content.bitmaps.forEach(function (t2) { + if (!t2) { + data.images.push(null); + } else { + try { + var image = new Image(); + image.src = t2; + data.images.push(image); + } catch (e) { + console.error(e); + data.images.push(null); + } + } + }); + data.frame = content.frame_max; + data.frames = []; + content.frames.forEach(function (t2) { + var info = []; + t2.forEach(function (t3) { + info.push({ + index: t3[0], + x: t3[1], + y: t3[2], + zoom: t3[3], + opacity: t3[4], + mirror: t3[5] || 0, + angle: t3[6] || 0, }); - return data; - } - catch (e) { - console.error(e); - return null; - } -} + }); + data.frames.push(info); + }); + return data; + } catch (e) { + console.error(e); + return null; + } +}; // ------ 加载音乐和音效 ------ // loader.prototype._loadMusics = function () { - core.bgms.forEach(function (t) { - core.loader.loadOneMusic(t); - }); - // 直接开始播放 - core.playBgm(main.startBgm); -} + core.bgms.forEach(function (t) { + core.loader.loadOneMusic(t); + }); + // 直接开始播放 + core.playBgm(main.startBgm); +}; loader.prototype._loadSounds_sync = function () { - this._setStartLoadTipText("正在加载音效文件..."); - core.sounds.forEach(function (t) { - core.loader.loadOneSound(t); - }); -} + this._setStartLoadTipText("正在加载音效文件..."); + core.sounds.forEach(function (t) { + core.loader.loadOneSound(t); + }); +}; loader.prototype._loadSounds_async = function (onprogress, onfinished) { - this._loadFileFromZip('project/sounds/sounds.h5data', this._saveSounds, false, onprogress, onfinished); -} + this._loadFileFromZip( + "project/sounds/sounds.h5data", + this._saveSounds, + false, + onprogress, + onfinished + ); +}; -loader.prototype._loadSounds_chunked = function (chunks, makeOnProgress, makeOnFinished) { - this._loadFileFromChunks(chunks, this._saveSounds, false, makeOnProgress, makeOnFinished); -} +loader.prototype._loadSounds_chunked = function ( + chunks, + makeOnProgress, + makeOnFinished +) { + this._loadFileFromChunks( + chunks, + this._saveSounds, + false, + makeOnProgress, + makeOnFinished + ); +}; loader.prototype._saveSounds = function (data, onfinished) { - // 延迟解析 - setTimeout(function () { - for (var name in data) { - if (core.sounds.indexOf(name) >= 0) { - core.loader._loadOneSound_decodeData(name, data[name]); - } - } - onfinished(); - }); -} + // 延迟解析 + setTimeout(function () { + for (var name in data) { + if (core.sounds.indexOf(name) >= 0) { + core.loader._loadOneSound_decodeData(name, data[name]); + } + } + onfinished(); + }); +}; loader.prototype.loadOneMusic = function (name) { - var music = new Audio(); - music.preload = 'none'; - if (main.bgmRemote) music.src = main.bgmRemoteRoot + core.firstData.name + '/' + name; - else music.src = 'project/bgms/' + name; - music.loop = 'loop'; - core.material.bgms[name] = music; -} + var music = new Audio(); + music.preload = "none"; + if (main.bgmRemote) + music.src = main.bgmRemoteRoot + core.firstData.name + "/" + name; + else music.src = "project/bgms/" + name; + music.loop = "loop"; + core.material.bgms[name] = music; +}; loader.prototype.loadOneSound = function (name) { - core.http('GET', 'project/sounds/' + name + "?v=" + main.version, null, function (data) { - core.loader._loadOneSound_decodeData(name, data); - }, function (e) { - console.error(e); - core.material.sounds[name] = null; - }, null, 'arraybuffer'); -} + core.http( + "GET", + "project/sounds/" + name + "?v=" + main.version, + null, + function (data) { + core.loader._loadOneSound_decodeData(name, data); + }, + function (e) { + console.error(e); + core.material.sounds[name] = null; + }, + null, + "arraybuffer" + ); +}; loader.prototype._loadOneSound_decodeData = function (name, data) { - if (data instanceof Blob) { - var blobReader = new zip.BlobReader(data); - blobReader.init(function () { - blobReader.readUint8Array(0, blobReader.size, function (uint8) { - core.loader._loadOneSound_decodeData(name, uint8.buffer); - }) - }); - return; - } - try { - core.musicStatus.audioContext.decodeAudioData(data, function (buffer) { - core.material.sounds[name] = buffer; - }, function (e) { - console.error(e); - core.material.sounds[name] = null; - }) - } - catch (e) { + if (data instanceof Blob) { + var blobReader = new zip.BlobReader(data); + blobReader.init(function () { + blobReader.readUint8Array(0, blobReader.size, function (uint8) { + core.loader._loadOneSound_decodeData(name, uint8.buffer); + }); + }); + return; + } + try { + core.musicStatus.audioContext.decodeAudioData( + data, + function (buffer) { + core.material.sounds[name] = buffer; + }, + function (e) { console.error(e); core.material.sounds[name] = null; - } -} + } + ); + } catch (e) { + console.error(e); + core.material.sounds[name] = null; + } +}; loader.prototype.loadBgm = function (name) { - name = core.getMappedName(name); - if (!core.material.bgms[name]) return; - // 如果没开启音乐,则不预加载 - if (!core.musicStatus.bgmStatus) return; - // 是否已经预加载过 - var index = core.musicStatus.cachedBgms.indexOf(name); - if (index >= 0) { - core.musicStatus.cachedBgms.splice(index, 1); + name = core.getMappedName(name); + if (!core.material.bgms[name]) return; + // 如果没开启音乐,则不预加载 + if (!core.musicStatus.bgmStatus) return; + // 是否已经预加载过 + var index = core.musicStatus.cachedBgms.indexOf(name); + if (index >= 0) { + core.musicStatus.cachedBgms.splice(index, 1); + } else { + // 预加载BGM + this._preloadBgm(core.material.bgms[name]); + // core.material.bgms[name].load(); + // 清理尾巴 + if (core.musicStatus.cachedBgms.length == core.musicStatus.cachedBgmCount) { + this.freeBgm(core.musicStatus.cachedBgms.pop()); } - else { - // 预加载BGM - this._preloadBgm(core.material.bgms[name]); - // core.material.bgms[name].load(); - // 清理尾巴 - if (core.musicStatus.cachedBgms.length == core.musicStatus.cachedBgmCount) { - this.freeBgm(core.musicStatus.cachedBgms.pop()); - } - } - // 移动到缓存最前方 - core.musicStatus.cachedBgms.unshift(name); -} + } + // 移动到缓存最前方 + core.musicStatus.cachedBgms.unshift(name); +}; loader.prototype._preloadBgm = function (bgm) { - bgm.volume = 0; - bgm.play(); -} + bgm.volume = 0; + bgm.play(); +}; loader.prototype.freeBgm = function (name) { - name = core.getMappedName(name); - if (!core.material.bgms[name]) return; - // 从cachedBgms中删除 - core.musicStatus.cachedBgms = core.musicStatus.cachedBgms.filter(function (t) { - return t != name; - }); - // 清掉缓存 - core.material.bgms[name].removeAttribute("src"); - core.material.bgms[name].load(); - core.material.bgms[name] = null; - if (name == core.musicStatus.playingBgm) { - core.musicStatus.playingBgm = null; - } - // 三秒后重新加载 - setTimeout(function () { - core.loader.loadOneMusic(name); - }, 3000); -} + name = core.getMappedName(name); + if (!core.material.bgms[name]) return; + // 从cachedBgms中删除 + core.musicStatus.cachedBgms = core.musicStatus.cachedBgms.filter(function ( + t + ) { + return t != name; + }); + // 清掉缓存 + core.material.bgms[name].removeAttribute("src"); + core.material.bgms[name].load(); + core.material.bgms[name] = null; + if (name == core.musicStatus.playingBgm) { + core.musicStatus.playingBgm = null; + } + // 三秒后重新加载 + setTimeout(function () { + core.loader.loadOneMusic(name); + }, 3000); +}; -loader.prototype._loadFileFromZip = function (url, save, convertToText, onprogress, onfinished) { - core.unzip(url + '?v=' + main.version, function (data) { - save(data, onfinished); - }, null, convertToText, onprogress); -} +loader.prototype._loadFileFromZip = function ( + url, + save, + convertToText, + onprogress, + onfinished +) { + core.unzip( + url + "?v=" + main.version, + function (data) { + save(data, onfinished); + }, + null, + convertToText, + onprogress + ); +}; -loader.prototype._loadFileFromChunks = async function (chunks, save, convertToText, makeOnProgress, makeOnFinished) { - await Promise.all(chunks.map((chunk) => { - const onfinished = makeOnFinished(chunk); - const onprogress = makeOnProgress(chunk); - return new Promise((resolve) => { - this._loadFileFromZip(chunk, save, convertToText, onprogress, () => { - onfinished(); - resolve(); - }); +loader.prototype._loadFileFromChunks = async function ( + chunks, + save, + convertToText, + makeOnProgress, + makeOnFinished +) { + await Promise.all( + chunks.map((chunk) => { + const onfinished = makeOnFinished(chunk); + const onprogress = makeOnProgress(chunk); + return new Promise((resolve) => { + this._loadFileFromZip(chunk, save, convertToText, onprogress, () => { + onfinished(); + resolve(); }); - })); -} + }); + }) + ); +}; diff --git a/main.js b/main.js index b8b19c0..05f0435 100644 --- a/main.js +++ b/main.js @@ -909,7 +909,7 @@ main.prototype.listen = function () { ////// 点击“开始游戏”时 ////// main.dom.playGame.onclick = function () { main.dom.startButtons.style.display = "none"; - main.core.control.checkBgm(); + main.core.checkBgm(); if (main.levelChoose.length == 0) { core.events.startGame(""); @@ -922,13 +922,13 @@ main.prototype.listen = function () { ////// 点击“载入游戏”时 ////// main.dom.loadGame.onclick = function () { - main.core.control.checkBgm(); + main.core.checkBgm(); main.core.load(); }; ////// 点击“录像回放”时 ////// main.dom.replayGame.onclick = function () { - main.core.control.checkBgm(); + main.core.checkBgm(); main.core.chooseReplayFile(); }; diff --git a/project/bgms/theme.mp3 b/project/bgms/theme.mp3 deleted file mode 100644 index 9310d7d..0000000 Binary files a/project/bgms/theme.mp3 and /dev/null differ diff --git a/project/bgms/theme.opus b/project/bgms/theme.opus new file mode 100644 index 0000000..00b2488 Binary files /dev/null and b/project/bgms/theme.opus differ diff --git a/project/data.js b/project/data.js index cd7fc5f..b277d60 100644 --- a/project/data.js +++ b/project/data.js @@ -905,7 +905,7 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = "Halbmond.opus", "ed.opus", "op.opus", - "theme.mp3" + "theme.opus" ], "sounds": [ "aiy010000010.opus", @@ -998,7 +998,6 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = "aiy820000010.opus", "aiy820000020.opus", "attack.opus", - "attack.opus", "bomb.opus", "cancel.opus", "centerFly.opus", @@ -1062,7 +1061,7 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = "饰品", "饰品" ], - "startBgm": "theme.mp3", + "startBgm": "theme.opus", "styles": { "startBackground": "project/images/background.webp", "startVerticalBackground": "project/images/backgroundvertical.webp", @@ -1446,7 +1445,7 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = }, { "type": "function", - "function": "function(){\ncore.control.checkBgm()\n}" + "function": "function(){\ncore.checkBgm()\n}" }, { "type": "if", diff --git a/project/events.js b/project/events.js index 632325c..5c6c1a0 100644 --- a/project/events.js +++ b/project/events.js @@ -440,6 +440,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "Blood_Stain.opus", "keep": true }, + { + "type": "cgtextList", + "textList": "chapter0" + }, { "type": "cgtext", "bg": "other_0001.webp", @@ -449,11 +453,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "0", "time": 30, "wait": 1000, "sound": "", - "text": "这些天,街道不曾下雨。", "bodyList": [ { "name": "", @@ -471,11 +474,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "1", "time": 30, "wait": 1000, "sound": "", - "text": "所以,那浸湿地面的,定是那些女孩们流落的鲜血无疑。", "bodyList": [ { "name": "", @@ -493,11 +495,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "2", "time": 30, "wait": 1000, "sound": "", - "text": "我蹲在充斥着铁锈味般恶臭的小巷中,悠闲地如是想着。", "bodyList": [ { "name": "", @@ -524,11 +525,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "3", "time": 30, "wait": 1000, "sound": "", - "text": "扑哧。", "bodyList": [ { "name": "", @@ -546,11 +546,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "4", "time": 30, "wait": 1000, "sound": "", - "text": "耳旁再次响起象征着某个女孩子死去的声音。", "bodyList": [ { "name": "", @@ -568,11 +567,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "5", "time": 30, "wait": 1000, "sound": "", - "text": "再一次——", "bodyList": [ { "name": "", @@ -590,11 +588,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "6", "time": 30, "wait": 1000, "sound": "", - "text": "再一次。", "bodyList": [ { "name": "", @@ -612,11 +609,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "7", "time": 30, "wait": 1000, "sound": "", - "text": "女子们被肢解成单纯的肉块。", "bodyList": [ { "name": "", @@ -634,11 +630,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "8", "time": 30, "wait": 1000, "sound": "", - "text": "我任由流下的血浸满全身,屏住自己的呼吸。", "bodyList": [ { "name": "", @@ -656,11 +651,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "9", "time": 30, "wait": 1000, "sound": "", - "text": "祈求自己能拥有从猎人手中逃脱的幸运。", "bodyList": [ { "name": "", @@ -678,11 +672,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "10", "time": 30, "wait": 1000, "sound": "", - "text": "扑哧。", "bodyList": [ { "name": "", @@ -709,11 +702,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "11", "time": 30, "wait": 1000, "sound": "", - "text": "直到刚才,我们还坐在去往娼馆的马车的路上。", "bodyList": [ { "name": "", @@ -731,11 +723,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "12", "time": 30, "wait": 1000, "sound": "", - "text": "而在这之中的某些人,已经不在这个世上了。", "bodyList": [ { "name": "", @@ -753,11 +744,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "13", "time": 30, "wait": 1000, "sound": "", - "text": "不,应该把“某些”换成“几乎所有”才更为恰当吧。", "bodyList": [ { "name": "", @@ -775,11 +765,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "14", "time": 30, "wait": 1000, "sound": "", - "text": "恐怕,不久之后我也会变成小巷中血腥的装饰品。", "bodyList": [ { "name": "", @@ -797,11 +786,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "15", "time": 30, "wait": 1000, "sound": "", - "text": "我是为了得到这种死法,才辛苦苟活至今的吗?", "bodyList": [ { "name": "", @@ -819,11 +807,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "16", "time": 30, "wait": 1000, "sound": "", - "text": "来个人告诉我啊——", "bodyList": [ { "name": "", @@ -841,11 +828,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "17", "time": 30, "wait": 1000, "sound": "", - "text": "谁都好。", "bodyList": [ { "name": "", @@ -863,11 +849,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "18", "time": 30, "wait": 1000, "sound": "", - "text": "来人啊!!", "bodyList": [ { "name": "", @@ -894,11 +879,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "少女", + "index": "19", "time": 30, "wait": 1000, "sound": "aiy010000010.opus", - "text": "「呃······!?」", "bodyList": [ { "name": "", @@ -925,11 +909,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "20", "time": 30, "wait": 1000, "sound": "", - "text": "漆黑的物体充斥了我的整个视野", "bodyList": [ { "name": "", @@ -947,11 +930,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "21", "time": 30, "wait": 1000, "sound": "", - "text": "我很快意识到,那是只很大的脚。", "bodyList": [ { "name": "", @@ -978,11 +960,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "22", "time": 30, "wait": 1000, "sound": "", - "text": "必须要出声求救。", "bodyList": [ { "name": "", @@ -1009,11 +990,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "23", "time": 30, "wait": 1000, "sound": "", - "text": "可是,耳中却只能听到自己的牙关不停交战的声音。", "bodyList": [ { "name": "", @@ -1031,11 +1011,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "24", "time": 50, "wait": 1000, "sound": "", - "text": "我是如此的无助。", "bodyList": [ { "name": "", @@ -1062,11 +1041,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "25", "time": 30, "wait": 1000, "sound": "", - "text": "逃跑也好,道歉也罢。", "bodyList": [ { "name": "", @@ -1084,11 +1062,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "26", "time": 30, "wait": 1000, "sound": "", - "text": "就连抬头看一眼将要杀掉我的人的面孔都做不到。", "bodyList": [ { "name": "", @@ -1106,11 +1083,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "少女", + "index": "27", "time": 30, "wait": 2000, "sound": "aiy010000020.opus", - "text": "「······被杀」", "bodyList": [ { "name": "", @@ -1128,11 +1104,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "28", "time": 30, "wait": 1000, "sound": "", - "text": "会被杀。", "bodyList": [ { "name": "", @@ -1150,11 +1125,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "29", "time": 30, "wait": 1000, "sound": "", - "text": "会被杀!!", "bodyList": [ { "name": "", @@ -1172,11 +1146,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "30", "time": 30, "wait": 1000, "sound": "", - "text": "来自内心深处的冰冷预感,渐渐地在体内蔓延开来。", "bodyList": [ { "name": "", @@ -1194,11 +1167,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "少女", + "index": "31", "time": 30, "wait": 1000, "sound": "aiy010000030.opus", - "text": "「不,不要······」", "bodyList": [ { "name": "", @@ -1230,11 +1202,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "32", "time": 30, "wait": 1000, "sound": "", - "text": "浮游都市,《诺瓦斯·艾蒂尔》。", "bodyList": [ { "name": "", @@ -1252,11 +1223,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "33", "time": 30, "wait": 1000, "sound": "", - "text": "《特别受灾地区》——", "bodyList": [ { "name": "", @@ -1274,11 +1244,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "34", "time": 30, "wait": 1000, "sound": "", - "text": "通称,《牢狱》", "bodyList": [ { "name": "", @@ -1296,11 +1265,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "35", "time": 30, "wait": 1000, "sound": "", - "text": "是被险峻的峭壁环绕,与世隔绝的,都市的最底部。", "bodyList": [ { "name": "", @@ -1318,11 +1286,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "年轻人", + "index": "36", "time": 30, "wait": 1000, "sound": "aiy710000010.opus", - "text": "「放开我!」", "bodyList": [ { "name": "", @@ -1340,11 +1307,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "年轻人", + "index": "37", "time": 30, "wait": 1000, "sound": "aiy710000020.opus", - "text": "「我只是在帮那个女人而已!」", "bodyList": [ { "name": "", @@ -1371,11 +1337,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "年轻人", + "index": "38", "time": 30, "wait": 1000, "sound": "aiy710000030.opus", - "text": "「你们没听到吗!?」", "bodyList": [ { "name": "", @@ -1393,11 +1358,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "年轻人", + "index": "39", "time": 30, "wait": 1000, "sound": "aiy710000040.opus", - "text": "「她是被受骗才会被卖到娼馆来的」", "bodyList": [ { "name": "", @@ -1415,11 +1379,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "年轻人", + "index": "40", "time": 30, "wait": 1000, "sound": "aiy710000050.opus", - "text": "「用肮脏的手段把钱借给她父母的,就是你们这些家伙吧!?」", "bodyList": [ { "name": "", @@ -1446,11 +1409,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "年轻人", + "index": "41", "time": 30, "wait": 1000, "sound": "aiy710000060.opus", - "text": "「给我说些什么啊」", "bodyList": [ { "name": "", @@ -1468,11 +1430,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "42", "time": 30, "wait": 1000, "sound": "aiy310000010.opus", - "text": "「这些话等到了娼馆再说吧」", "bodyList": [ { "name": "", @@ -1490,11 +1451,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "43", "time": 30, "wait": 1000, "sound": "aiy310000020.opus", - "text": "「我来抓你,只是受雇于人而已」", "bodyList": [ { "name": "", @@ -1521,11 +1481,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "44", "time": 30, "wait": 1000, "sound": "", - "text": "我走进娼馆《莉莉乌姆》的接待室。", "bodyList": [ { "name": "", @@ -1543,11 +1502,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "45", "time": 30, "wait": 1000, "sound": "", - "text": "正在桌旁整理账簿的奥兹停下手头的工作,抬起头向我看来。", "bodyList": [ { "name": "", @@ -1565,11 +1523,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "奥兹", + "index": "46", "time": 30, "wait": 1000, "sound": "aiy350000010.opus", - "text": "「这不是凯伊姆先生吗,辛苦了」", "bodyList": [ { "name": "", @@ -1587,11 +1544,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "奥兹", + "index": "47", "time": 30, "wait": 1000, "sound": "aiy350000020.opus", - "text": "「委托已经完成了吗?」", "bodyList": [ { "name": "", @@ -1609,11 +1565,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "48", "time": 30, "wait": 1000, "sound": "aiy310000030.opus", - "text": "「啊啊,是这家伙没错吧」", "bodyList": [ { "name": "", @@ -1631,11 +1586,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "49", "time": 30, "wait": 1000, "sound": "", - "text": "奥兹用只要接触到就能杀人般的眼神在男人脸上搜过。", "bodyList": [ { "name": "", @@ -1653,11 +1607,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "奥兹", + "index": "50", "time": 30, "wait": 1000, "sound": "aiy350000030.opus", - "text": "「没错,就是这个人」", "bodyList": [ { "name": "", @@ -1675,11 +1628,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "51", "time": 30, "wait": 1000, "sound": "aiy310000040.opus", - "text": "「是么」", "bodyList": [ { "name": "", @@ -1697,11 +1649,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "年轻人", + "index": "52", "time": 30, "wait": 1000, "sound": "aiy710000070.opus", - "text": "「你,你们要对我做什么」", "bodyList": [ { "name": "", @@ -1719,11 +1670,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "奥兹", + "index": "53", "time": 30, "wait": 1000, "sound": "aiy350000040.opus", - "text": "「······」", "bodyList": [ { "name": "", @@ -1741,11 +1691,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "54", "time": 30, "wait": 1000, "sound": "", - "text": "奥兹用一个眼神,就让男人闭上了嘴。", "bodyList": [ { "name": "", @@ -1763,11 +1712,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "55", "time": 30, "wait": 1000, "sound": "", - "text": "然后,向我这边转过身来。", "bodyList": [ { "name": "", @@ -1785,11 +1733,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "奥兹", + "index": "56", "time": 30, "wait": 1000, "sound": "aiy350000050.opus", - "text": "「抱歉啊,总是麻烦你去做这些无聊的事」", "bodyList": [ { "name": "", @@ -1807,11 +1754,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "奥兹", + "index": "57", "time": 30, "wait": 1000, "sound": "aiy350000060.opus", - "text": "「都怪我们这边的年轻人太没用」", "bodyList": [ { "name": "", @@ -1829,11 +1775,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "58", "time": 30, "wait": 1000, "sound": "aiy310000050.opus", - "text": "「客套话就免了」", "bodyList": [ { "name": "", @@ -1851,11 +1796,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "奥兹", + "index": "59", "time": 30, "wait": 1000, "sound": "aiy350000070.opus", - "text": "「这还真是失礼了」", "bodyList": [ { "name": "", @@ -1873,11 +1817,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "奥兹", + "index": "60", "time": 30, "wait": 1000, "sound": "aiy350000080.opus", - "text": "「喂,来个人」", "bodyList": [ { "name": "", @@ -1895,11 +1838,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "光头男人", + "index": "61", "time": 30, "wait": 1000, "sound": "aiy820000010.opus", - "text": "「是」", "bodyList": [ { "name": "", @@ -1917,11 +1859,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "奥兹", + "index": "62", "time": 30, "wait": 1000, "sound": "aiy350000090.opus", - "text": "「凯伊姆先生做完工作回来了」", "bodyList": [ { "name": "", @@ -1939,11 +1880,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "光头男人", + "index": "63", "time": 30, "wait": 1000, "sound": "aiy820000020.opus", - "text": "「是,是,那个······」", "bodyList": [ { "name": "", @@ -1961,11 +1901,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "奥兹", + "index": "64", "time": 30, "wait": 1000, "sound": "aiy350000100.opus", - "text": "「我是要你拿些酒来,这个蠢材!」", "bodyList": [ { "name": "", @@ -1983,11 +1922,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "65", "time": 30, "wait": 1000, "sound": "", - "text": "喀!", "bodyList": [ { "name": "", @@ -2005,11 +1943,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "66", "time": 30, "wait": 1000, "sound": "", - "text": "奥兹扔出的烟灰缸砸中了手下的额头。", "bodyList": [ { "name": "", @@ -2027,11 +1964,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "67", "time": 30, "wait": 1000, "sound": "", - "text": "鲜血四溅。", "bodyList": [ { "name": "", @@ -2049,11 +1985,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "68", "time": 30, "wait": 1000, "sound": "aiy310000060.opus", - "text": "「不用这么麻烦」", "bodyList": [ { "name": "", @@ -2071,11 +2006,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "69", "time": 30, "wait": 1000, "sound": "aiy310000070.opus", - "text": "「我接下来要去《菲诺列塔》」", "bodyList": [ { "name": "", @@ -2093,11 +2027,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "奥兹", + "index": "70", "time": 30, "wait": 1000, "sound": "aiy350000110.opus", - "text": "「喔唷」", "bodyList": [ { "name": "", @@ -2115,11 +2048,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "奥兹", + "index": "71", "time": 30, "wait": 1000, "sound": "aiy350000120.opus", - "text": "「既然如此,我就不留您在这里喝难饮的劣质酒了」", "bodyList": [ { "name": "", @@ -2137,11 +2069,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "72", "time": 30, "wait": 1000, "sound": "", - "text": "奥兹斜眼看着正捂住额头呻吟的手下,轻描淡写地说道。", "bodyList": [ { "name": "", @@ -2159,11 +2090,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "73", "time": 30, "wait": 1000, "sound": "aiy310000080.opus", - "text": "「用这些钱去买药」", "bodyList": [ { "name": "", @@ -2181,11 +2111,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "74", "time": 30, "wait": 1000, "sound": "", - "text": "我将几枚铜钱仍在那个手下的身前。", "bodyList": [ { "name": "", @@ -2203,11 +2132,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "奥兹", + "index": "75", "time": 30, "wait": 1000, "sound": "aiy350000130.opus", - "text": "「凯伊姆先生,不用对他们这么好」", "bodyList": [ { "name": "", @@ -2225,11 +2153,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "76", "time": 30, "wait": 1000, "sound": "aiy310000090.opus", - "text": "「无妨」", "bodyList": [ { "name": "", @@ -2247,11 +2174,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "77", "time": 30, "wait": 1000, "sound": "aiy310000100.opus", - "text": "「话说回来,那个要落跑的女人呢?」", "bodyList": [ { "name": "", @@ -2269,11 +2195,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "奥兹", + "index": "78", "time": 30, "wait": 1000, "sound": "aiy350000140.opus", - "text": "「我把她交给那些年轻人了,现在应该正在体会人生的严苛吧」", "bodyList": [ { "name": "", @@ -2291,11 +2216,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "奥兹", + "index": "79", "time": 30, "wait": 1000, "sound": "aiy350000150.opus", - "text": "「正好,趁此机会凯伊姆先生也来享受一番如何?」", "bodyList": [ { "name": "", @@ -2313,11 +2237,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "年轻人", + "index": "80", "time": 30, "wait": 1000, "sound": "aiy710000080.opus", - "text": "「你,你们这些家伙,要对她做什么!?」", "bodyList": [ { "name": "", @@ -2335,11 +2258,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "81", "time": 30, "wait": 1000, "sound": "", - "text": "咣!", "bodyList": [ { "name": "", @@ -2357,11 +2279,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "82", "time": 30, "wait": 1000, "sound": "", - "text": "奥兹给了他一拳。", "bodyList": [ { "name": "", @@ -2379,11 +2300,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "83", "time": 30, "wait": 1000, "sound": "", - "text": "一击即倒。", "bodyList": [ { "name": "", @@ -2401,11 +2321,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "84", "time": 30, "wait": 1000, "sound": "", - "text": "喀,咚,咯!", "bodyList": [ { "name": "", @@ -2423,11 +2342,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "85", "time": 30, "wait": 1000, "sound": "", - "text": "奥兹毫不留情地向男人的脸上踩去。", "bodyList": [ { "name": "", @@ -2445,11 +2363,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "年轻人", + "index": "86", "time": 30, "wait": 1000, "sound": "aiy710000090.opus", - "text": "「咕······呃咳······」", "bodyList": [ { "name": "", @@ -2467,11 +2384,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "87", "time": 30, "wait": 1000, "sound": "", - "text": "折断的牙齿伴着血泡被吐出。", "bodyList": [ { "name": "", @@ -2489,11 +2405,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "88", "time": 30, "wait": 1000, "sound": "", - "text": "这份白色在鲜红色的液体中格外显眼。", "bodyList": [ { "name": "", @@ -2511,11 +2426,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "年轻人", + "index": "89", "time": 30, "wait": 1000, "sound": "aiy710000100.opus", - "text": "「你们以为做出这种事······卫兵会坐视不理吗······」", "bodyList": [ { "name": "", @@ -2533,11 +2447,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "奥兹", + "index": "90", "time": 30, "wait": 1000, "sound": "aiy350000160.opus", - "text": "「啊啊,不会坐视不理的」", "bodyList": [ { "name": "", @@ -2555,11 +2468,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "奥兹", + "index": "91", "time": 30, "wait": 1000, "sound": "aiy350000170.opus", - "text": "「应该会拿出你的钱包,和我们商量如何瓜分吧」", "bodyList": [ { "name": "", @@ -2577,11 +2489,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "年轻人", + "index": "92", "time": 30, "wait": 1000, "sound": "aiy710000110.opus", - "text": "「那,那种事······」", "bodyList": [ { "name": "", @@ -2599,11 +2510,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "93", "time": 30, "wait": 1000, "sound": "", - "text": "这在牢狱是理所当然的事。", "bodyList": [ { "name": "", @@ -2621,11 +2531,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "奥兹", + "index": "94", "time": 30, "wait": 2000, "sound": "aiy350000180.opus", - "text": "「怎么,头一回来牢狱么?」", "bodyList": [ { "name": "", @@ -2643,11 +2552,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "95", "time": 30, "wait": 1000, "sound": "", - "text": "男人点了点头。", "bodyList": [ { "name": "", @@ -2665,11 +2573,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "奥兹", + "index": "96", "time": 30, "wait": 1000, "sound": "aiy350000190.opus", - "text": "「为了被骗的女人而来到牢狱,真是个规矩人啊」", "bodyList": [ { "name": "", @@ -2687,11 +2594,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "奥兹", + "index": "97", "time": 30, "wait": 1000, "sound": "aiy350000200.opus", - "text": "「······前提是,被骗的人不是你」", "bodyList": [ { "name": "", @@ -2709,11 +2615,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "年轻人", + "index": "98", "time": 30, "wait": 1000, "sound": "aiy710000120.opus", - "text": "「你说······我被骗了?」", "bodyList": [ { "name": "", @@ -2731,11 +2636,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "年轻人", + "index": "99", "time": 30, "wait": 1000, "sound": "aiy710000130.opus", - "text": "「那,那是怎么回事!?」", "bodyList": [ { "name": "", @@ -2753,11 +2657,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "奥兹", + "index": "100", "time": 30, "wait": 1000, "sound": "aiy350000210.opus", - "text": "「不用急,今天晚上会好好告诉你的」", "bodyList": [ { "name": "", @@ -2775,11 +2678,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "101", "time": 30, "wait": 1000, "sound": "", - "text": "奥兹抓起男人的脸。", "bodyList": [ { "name": "", @@ -2797,11 +2699,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "102", "time": 30, "wait": 1000, "sound": "", - "text": "为引诱客人的怜悯之心而装纯,是娼妇的惯用手段。", "bodyList": [ { "name": "", @@ -2819,11 +2720,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "103", "time": 30, "wait": 1000, "sound": "", - "text": "双亲被骗而借钱,结果作为抵押而将自己卖到这里,这是典型的说法。", "bodyList": [ { "name": "", @@ -2841,11 +2741,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "104", "time": 30, "wait": 1000, "sound": "", - "text": "如果只是头脑发热而成为常客也就罢了,这次的男人热血过头,居然想出了要带女人私奔的计划。", "bodyList": [ { "name": "", @@ -2863,11 +2762,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "105", "time": 30, "wait": 1000, "sound": "", - "text": "虽然女人半开玩笑地予以拒绝,但不知天高地厚的这家伙还是拉着她逃跑了。", "bodyList": [ { "name": "", @@ -2885,11 +2783,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "106", "time": 30, "wait": 1000, "sound": "", - "text": "不过,想要逃脱追击本来就是不可能的任务。", "bodyList": [ { "name": "", @@ -2907,11 +2804,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "107", "time": 30, "wait": 1000, "sound": "", - "text": "但即便如此,这种事情还是会一再的出现。", "bodyList": [ { "name": "", @@ -2929,11 +2825,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "108", "time": 30, "wait": 1000, "sound": "", - "text": "说谎的女人和被骗的男人。", "bodyList": [ { "name": "", @@ -2951,11 +2846,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "109", "time": 30, "wait": 1000, "sound": "", - "text": "在娼馆街,这是令人看到生厌的日常的风景。", "bodyList": [ { "name": "", @@ -2973,11 +2867,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "110", "time": 30, "wait": 1000, "sound": "aiy310000110.opus", - "text": "「我要走了」", "bodyList": [ { "name": "", @@ -2995,11 +2888,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "奥兹", + "index": "111", "time": 30, "wait": 1000, "sound": "aiy350000220.opus", - "text": "「好的,下次再麻烦您」", "bodyList": [ { "name": "", @@ -3017,11 +2909,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "奥兹", + "index": "112", "time": 30, "wait": 1000, "sound": "aiy350000230.opus", - "text": "「之后吉克先生会将谢礼交给您的」", "bodyList": [ { "name": "", @@ -3039,11 +2930,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "113", "time": 30, "wait": 1000, "sound": "aiy310000120.opus", - "text": "「啊啊」", "bodyList": [ { "name": "", @@ -3061,11 +2951,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "114", "time": 30, "wait": 1000, "sound": "", - "text": "我背向奥兹走出娼馆。", "bodyList": [ { "name": "", @@ -3083,11 +2972,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "115", "time": 30, "wait": 1000, "sound": "aiy310000130.opus", - "text": "「······?」", "bodyList": [ { "name": "", @@ -3114,11 +3002,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "116", "time": 30, "wait": 1000, "sound": "", - "text": "从远方传来微弱的歌声。", "bodyList": [ { "name": "", @@ -3136,11 +3023,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "117", "time": 30, "wait": 1000, "sound": "", - "text": "是关卡广场的方向。", "bodyList": [ { "name": "", @@ -3158,11 +3044,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "118", "time": 30, "wait": 1000, "sound": "", - "text": "对了。", "bodyList": [ { "name": "", @@ -3180,11 +3065,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "119", "time": 30, "wait": 1000, "sound": "", - "text": "今天有觐见圣女的仪式。", "bodyList": [ { "name": "", @@ -3202,11 +3086,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "120", "time": 30, "wait": 1000, "sound": "", - "text": "当代的圣女伊莲——", "bodyList": [ { "name": "", @@ -3224,11 +3107,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "121", "time": 30, "wait": 1000, "sound": "", - "text": "俗称《盲眼之圣女》,据说即使在历代的圣女中,人气也是数一数二的。", "bodyList": [ { "name": "", @@ -3246,11 +3128,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "122", "time": 30, "wait": 1000, "sound": "", - "text": "广场上的人估计相当多吧。", "bodyList": [ { "name": "", @@ -3268,11 +3149,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "123", "time": 30, "wait": 1000, "sound": "", - "text": "虽然我也想去看看她长什么样,不过要在人潮中挤来挤去就免了。", "bodyList": [ { "name": "", @@ -3290,11 +3170,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "124", "time": 30, "wait": 1000, "sound": "", - "text": "还是老老实实去菲诺列塔喝烧酒吧。", "bodyList": [ { "name": "", @@ -3312,11 +3191,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "125", "time": 30, "wait": 1000, "sound": "", - "text": "正当我这样想着的时候,一个身影自小巷的那头走来。", "bodyList": [ { "name": "", @@ -3343,11 +3221,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "126", "time": 30, "wait": 1000, "sound": "aiy310000140.opus", - "text": "「艾莉斯」", "bodyList": [ { "name": "", @@ -3380,6 +3257,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "time": 30, "style": "引入" }, + { + "type": "cgtextList", + "textList": "chapter01" + }, { "type": "cgtext", "bg": "bg_3601.webp", @@ -3389,11 +3270,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_020106.webp", "px": -300 }, - "name": "艾莉斯", + "index": "0", "time": 30, "wait": 1000, "sound": "aiy020000005.opus", - "text": "「啊,凯伊姆」", "bodyList": [ { "name": "", @@ -3404,8 +3284,7 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = }, { "type": "playBgm", - "name": "Halbmond.opus", - "keep": true + "name": "Halbmond.opus" }, { "type": "cgtext", @@ -3416,11 +3295,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_020141.webp", "px": -300 }, - "name": "艾莉斯", + "index": "1", "time": 30, "wait": 1000, "sound": "aiy020000010.opus", - "text": "「正好,我还想要去找你呢」", "bodyList": [ { "name": "tati_020141.webp", @@ -3438,11 +3316,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_020157.webp", "px": -300 }, - "name": "艾莉斯", + "index": "2", "time": 30, "wait": 1000, "sound": "aiy020000020.opus", - "text": "「没想到凯伊姆会主动出现······这是命运吗?」", "bodyList": [ { "name": "tati_020157.webp", @@ -3460,11 +3337,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "3", "time": 30, "wait": 1000, "sound": "aiy310000150.opus", - "text": "「显然不是吧」", "bodyList": [ { "name": "tati_020157.webp", @@ -3482,11 +3358,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_020107.webp", "px": -300 }, - "name": "艾莉斯", + "index": "4", "time": 30, "wait": 1000, "sound": "aiy020000030.opus", - "text": "「啊,是么」", "bodyList": [ { "name": "tati_020107.webp", @@ -3504,11 +3379,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "5", "time": 30, "wait": 1000, "sound": "", - "text": "艾莉斯挑了挑整齐的双眉,微微地哼了一声。", "bodyList": [ { "name": "tati_020107.webp", @@ -3526,11 +3400,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "6", "time": 30, "wait": 1000, "sound": "", - "text": "虽然是个相当引人注目的美人,但她这个将亲切儿子丢入无底深渊的性格,为自己扣了不少的分", "bodyList": [ { "name": "tati_020107.webp", @@ -3548,11 +3421,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "7", "time": 30, "wait": 1000, "sound": "", - "text": "给人印象最深的,就是那潭水般的双瞳。", "bodyList": [ { "name": "tati_020107.webp", @@ -3570,11 +3442,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "8", "time": 30, "wait": 1000, "sound": "", - "text": "在漆黑的瞳孔中,完全看不出感情的波动。", "bodyList": [ { "name": "tati_020107.webp", @@ -3592,11 +3463,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_020157.webp", "px": -300 }, - "name": "艾莉斯", + "index": "9", "time": 30, "wait": 1000, "sound": "aiy020000040.opus", - "text": "「喜欢我的眼睛吗?」", "bodyList": [ { "name": "tati_020157.webp", @@ -3614,11 +3484,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_020157.webp", "px": -300 }, - "name": "艾莉斯", + "index": "10", "time": 30, "wait": 1000, "sound": "aiy020000050.opus", - "text": "「如果想要的话就给你吧?」", "bodyList": [ { "name": "tati_020157.webp", @@ -3636,11 +3505,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "11", "time": 30, "wait": 1000, "sound": "aiy310000160.opus", - "text": "「用不着」", "bodyList": [ { "name": "tati_020157.webp", @@ -3658,11 +3526,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_020111.webp", "px": -300 }, - "name": "艾莉斯", + "index": "12", "time": 30, "wait": 1000, "sound": "aiy020000060.opus", - "text": "「阿拉,可惜」", "bodyList": [ { "name": "tati_020111.webp", @@ -3680,11 +3547,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "13", "time": 30, "wait": 1000, "sound": "aiy310000170.opus", - "text": "「那么,找我有什么事」", "bodyList": [ { "name": "tati_020111.webp", @@ -3702,11 +3568,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_020101.webp", "px": -300 }, - "name": "艾莉斯", + "index": "14", "time": 30, "wait": 1000, "sound": "aiy020000070.opus", - "text": "「梅尔特的钱好像被偷了」", "bodyList": [ { "name": "tati_020101.webp", @@ -3724,11 +3589,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "15", "time": 30, "wait": 1000, "sound": "aiy310000180.opus", - "text": "「钱被偷了?都几岁了还这么没用」", "bodyList": [ { "name": "tati_020101.webp", @@ -3746,11 +3610,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_020107.webp", "px": -300 }, - "name": "艾莉斯", + "index": "16", "time": 30, "wait": 1000, "sound": "aiy020000080.opus", - "text": "「不要对我说啊」", "bodyList": [ { "name": "tati_020107.webp", @@ -3768,11 +3631,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "17", "time": 30, "wait": 1000, "sound": "aiy310000190.opus", - "text": "「那家伙,该不会说要让我去抓那个小偷吧?」", "bodyList": [ { "name": "tati_020107.webp", @@ -3790,11 +3652,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_020157.webp", "px": -300 }, - "name": "艾莉斯", + "index": "18", "time": 30, "wait": 1000, "sound": "aiy020000090.opus", - "text": "「就是这样」", "bodyList": [ { "name": "tati_020157.webp", @@ -3812,11 +3673,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "19", "time": 30, "wait": 1000, "sound": "aiy310000200.opus", - "text": "「笨蛋吗」", "bodyList": [ { "name": "tati_020157.webp", @@ -3834,11 +3694,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "20", "time": 30, "wait": 1000, "sound": "aiy310000210.opus", - "text": "「如果是小钱的话,就当做是买个教训吧」", "bodyList": [ { "name": "tati_020157.webp", @@ -3856,11 +3715,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_020125.webp", "px": -300 }, - "name": "艾莉斯", + "index": "21", "time": 30, "wait": 1000, "sound": "aiy020000100.opus", - "text": "「说起来,被盗的是这个月的上纳金」", "bodyList": [ { "name": "tati_020125.webp", @@ -3878,11 +3736,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "22", "time": 30, "wait": 1000, "sound": "aiy310000220.opus", - "text": "「你说什么?」", "bodyList": [ { "name": "tati_020125.webp", @@ -3900,11 +3757,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_020121.webp", "px": -300 }, - "name": "艾莉斯", + "index": "23", "time": 30, "wait": 1000, "sound": "aiy020000110.opus", - "text": "「用这些钱买教训,也太过奢侈了呢」", "bodyList": [ { "name": "tati_020121.webp", @@ -3922,11 +3778,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "24", "time": 30, "wait": 1000, "sound": "aiy310000230.opus", - "text": "「知道了,我去找」", "bodyList": [ { "name": "tati_020121.webp", @@ -3944,11 +3799,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "25", "time": 30, "wait": 1000, "sound": "aiy310000240.opus", - "text": "「小偷的特征呢」", "bodyList": [ { "name": "tati_020121.webp", @@ -3966,11 +3820,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_020105.webp", "px": -300 }, - "name": "艾莉斯", + "index": "26", "time": 30, "wait": 1000, "sound": "aiy020000120.opus", - "text": "「男孩子」", "bodyList": [ { "name": "tati_020105.webp", @@ -3988,11 +3841,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_020103.webp", "px": -300 }, - "name": "艾莉斯", + "index": "27", "time": 30, "wait": 1000, "sound": "aiy020000130.opus", - "text": "「······而且,背后有翅膀」", "bodyList": [ { "name": "tati_020103.webp", @@ -4010,11 +3862,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_020141.webp", "px": -300 }, - "name": "艾莉斯", + "index": "28", "time": 30, "wait": 1000, "sound": "aiy020000140.opus", - "text": "「虽然姑且是藏在身后,但是仔细观察的话是很明显的」", "bodyList": [ { "name": "tati_020141.webp", @@ -4032,11 +3883,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "29", "time": 30, "wait": 1000, "sound": "aiy310000250.opus", - "text": "「羽化病吗」", "bodyList": [ { "name": "tati_020141.webp", @@ -4054,11 +3904,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_020105.webp", "px": -300 }, - "name": "艾莉斯", + "index": "30", "time": 30, "wait": 1000, "sound": "aiy020000150.opus", - "text": "「那些人可是毫不留情的,所以即使是为了那个孩子,也要赶快抓到他」", "bodyList": [ { "name": "tati_020105.webp", @@ -4076,11 +3925,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "31", "time": 30, "wait": 1000, "sound": "aiy310000260.opus", - "text": "「注意到他逃窜的方向了吗?」", "bodyList": [ { "name": "tati_020105.webp", @@ -4098,11 +3946,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_020105.webp", "px": -300 }, - "name": "艾莉斯", + "index": "32", "time": 30, "wait": 1000, "sound": "aiy020000160.opus", - "text": "「广场那边」", "bodyList": [ { "name": "tati_020105.webp", @@ -4120,11 +3967,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_020107.webp", "px": -300 }, - "name": "艾莉斯", + "index": "33", "time": 30, "wait": 1000, "sound": "aiy020000170.opus", - "text": "「虽然刚才《不蚀金锁》的人去追了,不过多半是······」", "bodyList": [ { "name": "tati_020107.webp", @@ -4142,11 +3988,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "34", "time": 30, "wait": 1000, "sound": "aiy310000280.opus", - "text": "「偏偏还是广场吗」", "bodyList": [ { "name": "tati_020107.webp", @@ -4164,11 +4009,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_020141.webp", "px": -300 }, - "name": "艾莉斯", + "index": "35", "time": 30, "wait": 1000, "sound": "aiy020000180.opus", - "text": "「今天是觐见圣女大人的日子」", "bodyList": [ { "name": "tati_020145.webp", @@ -4186,11 +4030,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "36", "time": 30, "wait": 1000, "sound": "aiy310000290.opus", - "text": "「我知道」", "bodyList": [ { "name": "tati_020145.webp", @@ -4208,11 +4051,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "37", "time": 30, "wait": 1000, "sound": "aiy310000300.opus", - "text": "「尽量找找看就好」", "bodyList": [ { "name": "tati_020145.webp", @@ -4241,6 +4083,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "time": 30, "style": "引入" }, + { + "type": "cgtextList", + "textList": "chapter02" + }, { "type": "cgtext", "bg": "bg_3561.webp", @@ -4250,11 +4096,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "不蚀金锁成员", + "index": "0", "time": 30, "wait": 1000, "sound": "", - "text": "「凯伊姆先生,凯伊姆先生」", "bodyList": [ { "name": "", @@ -4272,11 +4117,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "不蚀金锁成员", + "index": "1", "time": 30, "wait": 1000, "sound": "", - "text": "「您已经和艾莉斯大夫见过面了吗?」", "bodyList": [ { "name": "", @@ -4294,11 +4138,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "2", "time": 30, "wait": 1000, "sound": "", - "text": "「啊啊,所以才会追过来的」", "bodyList": [ { "name": "", @@ -4316,11 +4159,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "3", "time": 30, "wait": 1000, "sound": "", - "text": "「看到小偷了吗?」", "bodyList": [ { "name": "", @@ -4338,11 +4180,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "不蚀金锁成员", + "index": "4", "time": 30, "wait": 1000, "sound": "", - "text": "「没有,他向广场那边逃了过去,今天这么拥挤,我们也只能放弃了」", "bodyList": [ { "name": "", @@ -4360,11 +4201,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "不蚀金锁成员", + "index": "5", "time": 30, "wait": 1000, "sound": "", - "text": "「不过,我也只是刚好在店里所以才追了过去,并不是受人所托」", "bodyList": [ { "name": "", @@ -4382,11 +4222,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "不蚀金锁成员", + "index": "6", "time": 30, "wait": 1000, "sound": "", - "text": "「我已经准备撤退了」", "bodyList": [ { "name": "", @@ -4404,11 +4243,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "不蚀金锁成员", + "index": "7", "time": 30, "wait": 1000, "sound": "", - "text": "「凯伊姆先生还要继续追吗?」", "bodyList": [ { "name": "", @@ -4426,11 +4264,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "8", "time": 30, "wait": 1000, "sound": "", - "text": "「啊啊」", "bodyList": [ { "name": "", @@ -4448,11 +4285,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "9", "time": 30, "wait": 1000, "sound": "", - "text": "做完情报交换之后,我跟男人道别。", "bodyList": [ { "name": "", @@ -4479,11 +4315,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "10", "time": 30, "wait": 1000, "sound": "", - "text": "「和我想的一样啊······」", "bodyList": [ { "name": "", @@ -4501,11 +4336,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "11", "time": 30, "wait": 1000, "sound": "", - "text": "在牢狱中最大的广场上,聚集着看不到尽头的人群。", "bodyList": [ { "name": "", @@ -4523,11 +4357,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "12", "time": 30, "wait": 1000, "sound": "", - "text": "就算是来参见圣女祈祷,这人数也太多了点吧。", "bodyList": [ { "name": "", @@ -4545,11 +4378,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "13", "time": 30, "wait": 1000, "sound": "", - "text": "自然,我也找不到逃跑的孩子。", "bodyList": [ { "name": "", @@ -4567,11 +4399,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "14", "time": 30, "wait": 1000, "sound": "", - "text": "是混杂到人群中了吧。", "bodyList": [ { "name": "", @@ -4589,11 +4420,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "15", "time": 30, "wait": 1000, "sound": "", - "text": "如果已经从广场上脱身了的话,就更难发现了。", "bodyList": [ { "name": "", @@ -4611,11 +4441,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "16", "time": 30, "wait": 1000, "sound": "", - "text": "只好赌他还在这里了。", "bodyList": [ { "name": "", @@ -4642,11 +4471,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "17", "time": 30, "wait": 1000, "sound": "", - "text": "我先移动到了一个视野良好的地方。", "bodyList": [ { "name": "", @@ -4664,11 +4492,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "18", "time": 30, "wait": 1000, "sound": "", - "text": "从这里,一眼就可以看到人群的变化。", "bodyList": [ { "name": "", @@ -4686,11 +4513,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "19", "time": 30, "wait": 1000, "sound": "", - "text": "广场还是沸腾起来。", "bodyList": [ { "name": "", @@ -4721,11 +4547,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "20", "time": 30, "wait": 1000, "sound": "", - "text": "抬头望去,原来是在天台之上出现了一个人影", "bodyList": [ { "name": "tati_440101.webp", @@ -4743,11 +4568,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "21", "time": 30, "wait": 1000, "sound": "", - "text": "但是,与周围的期待不同,现身的是一名中年的神官。", "bodyList": [ { "name": "tati_440101.webp", @@ -4765,11 +4589,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "22", "time": 30, "wait": 1000, "sound": "", - "text": "骂声四溢。", "bodyList": [ { "name": "tati_440101.webp", @@ -4787,11 +4610,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "23", "time": 30, "wait": 1000, "sound": "", - "text": "神官则是笑着摆正衣领", "bodyList": [ { "name": "", @@ -4809,11 +4631,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_440101.webp", "px": -300 }, - "name": "神官", + "index": "24", "time": 30, "wait": 1000, "sound": "", - "text": "「从现在开始,举行谒见的仪式」", "bodyList": [ { "name": "", @@ -4831,11 +4652,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_440105.webp", "px": -300 }, - "name": "神官", + "index": "25", "time": 30, "wait": 1000, "sound": "", - "text": "「在参见那位大人之前,我希望牢狱的诸位再次思考这个《诺瓦斯·艾蒂尔》存在的意义······」", "bodyList": [ { "name": "", @@ -4853,11 +4673,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_440101.webp", "px": -300 }, - "name": "神官", + "index": "26", "time": 30, "wait": 1000, "sound": "", - "text": "「初代圣女伊莲大人,便是也难怪这崇高的祈祷之力,令《诺瓦斯·艾蒂尔》浮在空中,拯救了我们的祖先」", "bodyList": [ { "name": "", @@ -4875,11 +4694,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_440110.webp", "px": -300 }, - "name": "神官", + "index": "27", "time": 30, "wait": 1000, "sound": "", - "text": "「这之后的几百年来,传承了初代大人力量的历代圣女伊莲大人,让这里留在了空中」", "bodyList": [ { "name": "", @@ -4897,11 +4715,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_440101.webp", "px": -300 }, - "name": "神官", + "index": "28", "time": 30, "wait": 1000, "sound": "", - "text": "「这座都市是被圣女大人守护的人类最后的圣域,而我们则是被选召的虔诚的信徒」", "bodyList": [ { "name": "", @@ -4919,11 +4736,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_440102.webp", "px": -300 }, - "name": "神官", + "index": "29", "time": 30, "wait": 1000, "sound": "", - "text": "「怀着对圣女的感激祈祷吧,感谢圣女伊莲吧!并献上祈祷!」", "bodyList": [ { "name": "", @@ -4967,11 +4783,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_030102.webp", "px": -300 }, - "name": "圣女", + "index": "30", "time": 30, "wait": 1000, "sound": "", - "text": "「不忘感谢与祈祷,神才会拯救我们」", "bodyList": [ { "name": "", @@ -4989,11 +4804,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_030101.webp", "px": -300 }, - "name": "圣女", + "index": "31", "time": 30, "wait": 1000, "sound": "", - "text": "「与我一起,向审虔诚地祈祷吧」", "bodyList": [ { "name": "", @@ -5015,11 +4829,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "32", "time": 30, "wait": 1000, "sound": "", - "text": "广场上欢声雷动。", "bodyList": [ { "name": "", @@ -5037,11 +4850,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "33", "time": 30, "wait": 1000, "sound": "", - "text": "圣女没有回应喧嚣的人声,而是静静地合上双眼面向广场。", "bodyList": [ { "name": "", @@ -5059,11 +4871,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "34", "time": 30, "wait": 1000, "sound": "", - "text": "虽然感觉有些冷淡,但总比像个傻瓜似的笑着向这群人挥手要强。", "bodyList": [ { "name": "", @@ -5081,11 +4892,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "35", "time": 30, "wait": 1000, "sound": "", - "text": "她掌握着这条街道,还有在这条街上生活的人的命运。", "bodyList": [ { "name": "", @@ -5103,11 +4913,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "36", "time": 30, "wait": 1000, "sound": "", - "text": "比起揽得人气,她更想要为了街道的继续存在而献出全力。", "bodyList": [ { "name": "", @@ -5125,11 +4934,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "37", "time": 30, "wait": 1000, "sound": "", - "text": "也是为了不让《大崩落》的惨剧再度发生。", "bodyList": [ { "name": "", @@ -5147,11 +4955,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "38", "time": 30, "wait": 1000, "sound": "", - "text": "十几年前的那场悲剧。", "bodyList": [ { "name": "", @@ -5169,11 +4976,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "39", "time": 30, "wait": 1000, "sound": "", - "text": "虽然在我脑海中的记忆已经相当模糊,但哪怕只是稍有触及,不快的感觉都会在胸口蔓延开。", "bodyList": [ { "name": "", @@ -5191,11 +4997,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "40", "time": 30, "wait": 1000, "sound": "", - "text": "「······」", "bodyList": [ { "name": "", @@ -5213,11 +5018,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "41", "time": 30, "wait": 1000, "sound": "", - "text": "这时我才想起,现在不是我在这里看圣女的时候。", "bodyList": [ { "name": "", @@ -5239,11 +5043,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "女声", + "index": "42", "time": 30, "wait": 1000, "sound": "", - "text": "「——っ!?」", "bodyList": [ { "name": "", @@ -5270,11 +5073,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "围观的女人", + "index": "43", "time": 30, "wait": 1000, "sound": "", - "text": "「羽,羽化病人!?」", "bodyList": [ { "name": "", @@ -5292,11 +5094,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "围观的中年人", + "index": "44", "time": 30, "wait": 1000, "sound": "", - "text": "「喂,谁去叫下羽狩」", "bodyList": [ { "name": "", @@ -5314,11 +5115,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "惊慌的观众", + "index": "45", "time": 30, "wait": 1000, "sound": "", - "text": "「你这家伙不要靠近我,要是传染了可怎么办」", "bodyList": [ { "name": "", @@ -5336,11 +5136,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "粗鲁的观众", + "index": "46", "time": 30, "wait": 1000, "sound": "", - "text": "「你这小鬼赶快滚开」", "bodyList": [ { "name": "", @@ -5358,11 +5157,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "47", "time": 30, "wait": 1000, "sound": "", - "text": "「接下来」", "bodyList": [ { "name": "", @@ -5389,11 +5187,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_030107.webp", "px": -300 }, - "name": "圣女", + "index": "48", "time": 30, "wait": 1000, "sound": "", - "text": "「发生什么事了?看上去似乎很嘈杂」", "bodyList": [ { "name": "", @@ -5411,11 +5208,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_130104.webp", "px": -300 }, - "name": "随从", + "index": "49", "time": 30, "wait": 1000, "sound": "", - "text": "「似乎是某个人逃跑了······具体的我也不是很清楚」", "bodyList": [ { "name": "", @@ -5433,11 +5229,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_440103.webp", "px": -300 }, - "name": "神官", + "index": "50", "time": 30, "wait": 1000, "sound": "", - "text": "「圣女大人,继续待在天台上可能会出事,请您先回到室内吧」", "bodyList": [ { "name": "", @@ -5455,11 +5250,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_030145.webp", "px": -300 }, - "name": "圣女", + "index": "51", "time": 30, "wait": 1000, "sound": "", - "text": "「不用在意我,比起那个,我更关心究竟发生了什么事」", "bodyList": [ { "name": "", @@ -5477,11 +5271,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_440107.webp", "px": -300 }, - "name": "神官", + "index": "52", "time": 30, "wait": 1000, "sound": "", - "text": "「对不起,我真的不知道」", "bodyList": [ { "name": "", @@ -5499,11 +5292,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_030145.webp", "px": -300 }, - "name": "圣女", + "index": "53", "time": 30, "wait": 1000, "sound": "", - "text": "「······是吗」", "bodyList": [ { "name": "", @@ -5521,11 +5313,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_320101.webp", "px": -300 }, - "name": "男", + "index": "54", "time": 30, "wait": 1000, "sound": "", - "text": "「恕我僭越,请准许我说明情况」", "bodyList": [ { "name": "", @@ -5543,11 +5334,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_320105.webp", "px": -300 }, - "name": "男", + "index": "55", "time": 30, "wait": 1000, "sound": "", - "text": "「在来觐见的人群中出现了《羽化病》的患者」", "bodyList": [ { "name": "", @@ -5565,11 +5355,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_320101.webp", "px": -300 }, - "name": "男", + "index": "56", "time": 30, "wait": 1000, "sound": "", - "text": "「围观的人群因而产生了骚动」", "bodyList": [ { "name": "", @@ -5587,11 +5376,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_320102.webp", "px": -300 }, - "name": "男", + "index": "57", "time": 30, "wait": 1000, "sound": "", - "text": "「现在,《防疫局》已经派遣了部队。我想不久之后,他们就会安静下来了」", "bodyList": [ { "name": "", @@ -5609,11 +5397,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_030124.webp", "px": -300 }, - "name": "圣女", + "index": "58", "time": 30, "wait": 1000, "sound": "", - "text": "「羽化病······」", "bodyList": [ { "name": "", @@ -5631,11 +5418,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_320107.webp", "px": -300 }, - "name": "男", + "index": "59", "time": 30, "wait": 1000, "sound": "", - "text": "「怎么了?」", "bodyList": [ { "name": "", @@ -5653,11 +5439,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_030125.webp", "px": -300 }, - "name": "圣女", + "index": "60", "time": 30, "wait": 1000, "sound": "", - "text": "「没什么」", "bodyList": [ { "name": "", @@ -5675,11 +5460,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_030141.webp", "px": -300 }, - "name": "圣女", + "index": "61", "time": 30, "wait": 1000, "sound": "", - "text": "「辛苦了,你的名字是?」", "bodyList": [ { "name": "", @@ -5697,11 +5481,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_320102.webp", "px": -300 }, - "name": "男", + "index": "62", "time": 30, "wait": 1000, "sound": "", - "text": "「属下是在防疫局任职的,鲁基乌斯· 迪斯·米利尤」", "bodyList": [ { "name": "", @@ -5719,11 +5502,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_440102.webp", "px": -300 }, - "name": "神官", + "index": "63", "time": 30, "wait": 1000, "sound": "", - "text": "「噢噢,阁下就是鲁基乌斯卿吗,我听说过你的传闻」", "bodyList": [ { "name": "", @@ -5741,11 +5523,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_440109.webp", "px": -300 }, - "name": "神官", + "index": "64", "time": 30, "wait": 1000, "sound": "", - "text": "「阁下是在工作上相当出色的人呢」", "bodyList": [ { "name": "", @@ -5763,11 +5544,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_320101.webp", "px": -300 }, - "name": "鲁基乌斯", + "index": "65", "time": 30, "wait": 1000, "sound": "", - "text": "「不敢当」", "bodyList": [ { "name": "", @@ -5785,11 +5565,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_320108.webp", "px": -300 }, - "name": "鲁基乌斯", + "index": "66", "time": 30, "wait": 1000, "sound": "", - "text": "「话说回来,这次是属下警备工作的失职。让圣女大人见到这不成体统的一面,请您见谅」", "bodyList": [ { "name": "", @@ -5807,11 +5586,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_030145.webp", "px": -300 }, - "name": "圣女", + "index": "67", "time": 30, "wait": 1000, "sound": "", - "text": "「即使是目不见物的我,也能感受到聚集于此的民众数量之多。警备工作难以展开也在情理之中」", "bodyList": [ { "name": "", @@ -5829,11 +5607,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_320101.webp", "px": -300 }, - "name": "鲁基乌斯", + "index": "68", "time": 30, "wait": 1000, "sound": "", - "text": "「属下不胜惶恐」", "bodyList": [ { "name": "", @@ -5851,11 +5628,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_320102.webp", "px": -300 }, - "name": "鲁基乌斯", + "index": "69", "time": 30, "wait": 1000, "sound": "", - "text": "「接下来属下还要回到工作岗位上,在这里就先告退了」", "bodyList": [ { "name": "", @@ -5873,11 +5649,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_030101.webp", "px": -300 }, - "name": "圣女", + "index": "70", "time": 30, "wait": 1000, "sound": "", - "text": "「鲁基乌斯先生」", "bodyList": [ { "name": "", @@ -5895,11 +5670,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_320101.webp", "px": -300 }, - "name": "鲁基乌斯", + "index": "71", "time": 30, "wait": 1000, "sound": "", - "text": "「属下在」", "bodyList": [ { "name": "", @@ -5917,11 +5691,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_030105.webp", "px": -300 }, - "name": "圣女", + "index": "72", "time": 30, "wait": 1000, "sound": "", - "text": "「你是怎样看待羽狩的工作的呢?」", "bodyList": [ { "name": "", @@ -5939,11 +5712,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_440106.webp", "px": -300 }, - "name": "神官", + "index": "73", "time": 30, "wait": 1000, "sound": "", - "text": "「圣,圣女大人」", "bodyList": [ { "name": "", @@ -5961,11 +5733,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_320101.webp", "px": -300 }, - "name": "鲁基乌斯", + "index": "74", "time": 30, "wait": 1000, "sound": "", - "text": "「防疫局的工作是国王陛下赐予的重要职务。属下非常荣幸能够为这个都市的繁荣尽一份微薄之力」", "bodyList": [ { "name": "", @@ -5983,11 +5754,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_440102.webp", "px": -300 }, - "name": "神官", + "index": "75", "time": 30, "wait": 1000, "sound": "", - "text": "「不,不亏是鲁基乌斯卿,相当优秀的想法」", "bodyList": [ { "name": "", @@ -6005,11 +5775,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_030125.webp", "px": -300 }, - "name": "圣女", + "index": "76", "time": 30, "wait": 1000, "sound": "", - "text": "「是吗。辛苦你了」", "bodyList": [ { "name": "", @@ -6027,11 +5796,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_130124.webp", "px": -300 }, - "name": "随从", + "index": "77", "time": 30, "wait": 1000, "sound": "", - "text": "「圣女大人······」", "bodyList": [ { "name": "", @@ -6049,11 +5817,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_320102.webp", "px": -300 }, - "name": "鲁基乌斯", + "index": "78", "time": 30, "wait": 1000, "sound": "", - "text": "「······」", "bodyList": [ { "name": "", @@ -6071,11 +5838,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_320101.webp", "px": -300 }, - "name": "鲁基乌斯", + "index": "79", "time": 30, "wait": 1000, "sound": "", - "text": "「那么,属下就回岗位去了」", "bodyList": [ { "name": "", @@ -6108,6 +5874,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "time": 30, "style": "引入" }, + { + "type": "cgtextList", + "textList": "chapter03" + }, { "type": "cgtext", "bg": "bg_3801.webp", @@ -6117,11 +5887,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "0", "time": 30, "wait": 1000, "sound": "", - "text": "从羽化病的少年纷乱的足音中,可以听得出相当的疲劳。", "bodyList": [ { "name": "", @@ -6139,11 +5908,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "1", "time": 30, "wait": 1000, "sound": "", - "text": "显然,他并没有想到我会捷足先登吧。", "bodyList": [ { "name": "", @@ -6161,11 +5929,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "2", "time": 30, "wait": 1000, "sound": "", - "text": "少年惶恐地回头看了一眼后,微微露出安心的表情,双手拄在膝盖上。", "bodyList": [ { "name": "", @@ -6183,11 +5950,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "3", "time": 30, "wait": 1000, "sound": "", - "text": "「辛苦你了」", "bodyList": [ { "name": "", @@ -6205,11 +5971,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "羽化病患少年", + "index": "4", "time": 30, "wait": 1000, "sound": "", - "text": "「稀!?」", "bodyList": [ { "name": "", @@ -6227,11 +5992,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "5", "time": 30, "wait": 1000, "sound": "", - "text": "「逃到贫民区是个不错的想法」", "bodyList": [ { "name": "", @@ -6249,11 +6013,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "羽化病患少年", + "index": "6", "time": 30, "wait": 1000, "sound": "", - "text": "「你,你是,羽狩吗?」", "bodyList": [ { "name": "", @@ -6271,11 +6034,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "7", "time": 30, "wait": 1000, "sound": "", - "text": "「不是」", "bodyList": [ { "name": "", @@ -6293,11 +6055,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "羽化病患少年", + "index": "8", "time": 30, "wait": 1000, "sound": "", - "text": "「什,什么啊······混蛋,不要吓我啊」", "bodyList": [ { "name": "", @@ -6315,11 +6076,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "9", "time": 30, "wait": 1000, "sound": "", - "text": "「我对令你受惊这件事致以歉意」", "bodyList": [ { "name": "", @@ -6337,11 +6097,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "10", "time": 30, "wait": 1000, "sound": "", - "text": "「作为回报,麻烦你把从店里偷的钱交出来吧」", "bodyList": [ { "name": "", @@ -6359,11 +6118,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "羽化病患少年", + "index": "11", "time": 30, "wait": 1000, "sound": "", - "text": "「钱?你在说什么」", "bodyList": [ { "name": "", @@ -6381,11 +6139,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "12", "time": 30, "wait": 1000, "sound": "", - "text": "「你要找的腰上的东西,掉在你身后了」", "bodyList": [ { "name": "", @@ -6403,11 +6160,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "羽化病患少年", + "index": "13", "time": 30, "wait": 1000, "sound": "", - "text": "「哎?」", "bodyList": [ { "name": "", @@ -6429,11 +6185,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "羽化病患少年", + "index": "14", "time": 30, "wait": 1000, "sound": "", - "text": "「呃呀」", "bodyList": [ { "name": "", @@ -6451,11 +6206,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "羽化病患少年", + "index": "15", "time": 30, "wait": 1000, "sound": "", - "text": "「你······你这混蛋」", "bodyList": [ { "name": "", @@ -6473,11 +6227,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "16", "time": 30, "wait": 1000, "sound": "", - "text": "「······」", "bodyList": [ { "name": "", @@ -6495,11 +6248,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "17", "time": 30, "wait": 1000, "sound": "", - "text": "「把偷的钱交出来」", "bodyList": [ { "name": "", @@ -6517,11 +6269,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "羽化病患少年", + "index": "18", "time": 30, "wait": 1000, "sound": "", - "text": "「我不知道你在······咕」", "bodyList": [ { "name": "", @@ -6547,11 +6298,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "羽化病患少年", + "index": "19", "time": 30, "wait": 1000, "sound": "", - "text": "「你,你说是我偷的······有什么证据吗」", "bodyList": [ { "name": "", @@ -6569,11 +6319,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "20", "time": 30, "wait": 1000, "sound": "", - "text": "「你还挺倔的啊」", "bodyList": [ { "name": "", @@ -6591,11 +6340,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "21", "time": 30, "wait": 1000, "sound": "", - "text": "「不过,给我听好了」", "bodyList": [ { "name": "", @@ -6613,11 +6361,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "22", "time": 30, "wait": 1000, "sound": "", - "text": "「你偷的那些钱,是要上缴给《不蚀金锁》的上纳金」", "bodyList": [ { "name": "", @@ -6635,11 +6382,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "23", "time": 30, "wait": 1000, "sound": "", - "text": "「而且,钱的主人是从前和吉克颇有渊源的女人」", "bodyList": [ { "name": "", @@ -6657,11 +6403,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "羽化病患少年", + "index": "24", "time": 30, "wait": 1000, "sound": "", - "text": "「吉克?」", "bodyList": [ { "name": "", @@ -6679,11 +6424,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "25", "time": 30, "wait": 1000, "sound": "", - "text": "「他是《不蚀金锁》的主人,这么说你就明白了吧」", "bodyList": [ { "name": "", @@ -6701,11 +6445,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "羽化病患少年", + "index": "26", "time": 30, "wait": 1000, "sound": "", - "text": "「哎?哎?怎么会······」", "bodyList": [ { "name": "", @@ -6723,11 +6466,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "羽化病患少年", + "index": "27", "time": 30, "wait": 1000, "sound": "", - "text": "「再问你一遍,钱在哪里?」", "bodyList": [ { "name": "", @@ -6745,11 +6487,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "羽化病患少年", + "index": "28", "time": 30, "wait": 1000, "sound": "", - "text": "「是,是,是,在我的怀里」", "bodyList": [ { "name": "", @@ -6767,11 +6508,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "29", "time": 30, "wait": 1000, "sound": "", - "text": "「你没有擅自拿掉一部分吧」", "bodyList": [ { "name": "", @@ -6789,11 +6529,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "羽化病患少年", + "index": "30", "time": 30, "wait": 1000, "sound": "", - "text": "「是,是的」", "bodyList": [ { "name": "", @@ -6811,11 +6550,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "羽化病患少年", + "index": "31", "time": 30, "wait": 1000, "sound": "", - "text": "「那,那个,您是《不蚀金锁》的人吗?」", "bodyList": [ { "name": "", @@ -6833,11 +6571,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "32", "time": 30, "wait": 1000, "sound": "", - "text": "「算是吧」", "bodyList": [ { "name": "", @@ -6855,11 +6592,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "羽化病患少年", + "index": "33", "time": 30, "wait": 1000, "sound": "", - "text": "「我什么都可以做,请您一定要帮帮我」", "bodyList": [ { "name": "", @@ -6877,11 +6613,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "34", "time": 30, "wait": 1000, "sound": "", - "text": "「抱歉,我并没有兴趣去帮助他人」", "bodyList": [ { "name": "", @@ -6899,11 +6634,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "羽化病患少年", + "index": "35", "time": 30, "wait": 1000, "sound": "", - "text": "「我什么······什么,都会做的······」", "bodyList": [ { "name": "", @@ -6921,11 +6655,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "羽化病患少年", + "index": "36", "time": 30, "wait": 1000, "sound": "", - "text": "「我一直都是生活在下层的」", "bodyList": [ { "name": "", @@ -6943,11 +6676,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "羽化病患少年", + "index": "37", "time": 30, "wait": 1000, "sound": "", - "text": "「可是,不知何时染上了羽化病······背后长出了翅膀······」", "bodyList": [ { "name": "", @@ -6965,11 +6697,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "羽化病患少年", + "index": "38", "time": 30, "wait": 1000, "sound": "", - "text": "「被寄宿工作的店赶了出来,只得流落到牢狱这里」", "bodyList": [ { "name": "", @@ -6987,11 +6718,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "羽化病患少年", + "index": "39", "time": 30, "wait": 1000, "sound": "", - "text": "「因为独自实在是饿的不行了,所以才会偷这些钱的」", "bodyList": [ { "name": "", @@ -7009,11 +6739,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "羽化病患少年", + "index": "40", "time": 30, "wait": 1000, "sound": "", - "text": "「我明明没有做任何坏事······为什么······会遇到这种事······」", "bodyList": [ { "name": "", @@ -7031,11 +6760,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "41", "time": 30, "wait": 1000, "sound": "", - "text": "「谁知道」", "bodyList": [ { "name": "", @@ -7053,11 +6781,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "羽化病患少年", + "index": "42", "time": 30, "wait": 1000, "sound": "", - "text": "「呜······呜呜······接下来,要对我做什么?」", "bodyList": [ { "name": "", @@ -7075,11 +6802,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "43", "time": 30, "wait": 1000, "sound": "", - "text": "「我要把你带到组织那里」", "bodyList": [ { "name": "", @@ -7097,11 +6823,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "羽化病患少年", + "index": "44", "time": 30, "wait": 1000, "sound": "", - "text": "「怎,怎么这样」", "bodyList": [ { "name": "", @@ -7119,11 +6844,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "45", "time": 30, "wait": 1000, "sound": "", - "text": "「不过,那样做的前提是你不是羽化病人」", "bodyList": [ { "name": "", @@ -7141,11 +6865,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "46", "time": 30, "wait": 1000, "sound": "", - "text": "「组织也没有笨到把羽化病人招待到家里的程度」", "bodyList": [ { "name": "", @@ -7163,11 +6886,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "羽化病患少年", + "index": "47", "time": 30, "wait": 1000, "sound": "", - "text": "「那么,是要放我逃走吗?」", "bodyList": [ { "name": "", @@ -7185,11 +6907,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "48", "time": 30, "wait": 1000, "sound": "", - "text": "「我要让你学到教训」", "bodyList": [ { "name": "", @@ -7211,11 +6932,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "49", "time": 30, "wait": 1000, "sound": "", - "text": "「如果换做是组织的制裁,至少要有断条胳膊的觉悟」", "bodyList": [ { "name": "", @@ -7233,11 +6953,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "50", "time": 30, "wait": 1000, "sound": "", - "text": "「你的运气不错」", "bodyList": [ { "name": "", @@ -7255,11 +6974,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "羽化病患少年", + "index": "51", "time": 30, "wait": 1000, "sound": "", - "text": "「唔······啊,是的······」", "bodyList": [ { "name": "", @@ -7277,11 +6995,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "52", "time": 30, "wait": 1000, "sound": "", - "text": "「滚」", "bodyList": [ { "name": "", @@ -7299,11 +7016,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "羽化病患少年", + "index": "53", "time": 30, "wait": 1000, "sound": "", - "text": "「非常感谢」", "bodyList": [ { "name": "", @@ -7321,11 +7037,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "羽化病患少年", + "index": "54", "time": 30, "wait": 1000, "sound": "", - "text": "「唔啊!?」", "bodyList": [ { "name": "", @@ -7347,11 +7062,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_430103.webp", "px": -300 }, - "name": "男", + "index": "55", "time": 30, "wait": 1000, "sound": "", - "text": "「到这里就结束了,羽化病人」", "bodyList": [ { "name": "tati_430103.webp", @@ -7369,11 +7083,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_430105.webp", "px": -300 }, - "name": "男", + "index": "56", "time": 30, "wait": 1000, "sound": "", - "text": "「确认他的翅膀」", "bodyList": [ { "name": "tati_430105.webp", @@ -7391,11 +7104,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "57", "time": 30, "wait": 1000, "sound": "", - "text": "趁还没有被卷入麻烦的事情之前,赶快离开这里吧", "bodyList": [ { "name": "tati_430105.webp", @@ -7431,11 +7143,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_430106.webp", "px": -300 }, - "name": "羽狩的队长", + "index": "58", "time": 30, "wait": 1000, "sound": "", - "text": "「那边的那个人」", "bodyList": [ { "name": "", @@ -7453,11 +7164,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "59", "time": 30, "wait": 1000, "sound": "", - "text": "「······有什么事?」", "bodyList": [ { "name": "tati_430101.webp", @@ -7475,11 +7185,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_430101.webp", "px": -300 }, - "name": "羽狩的队长", + "index": "60", "time": 30, "wait": 1000, "sound": "", - "text": "「可以稍微让我问几句话吗」", "bodyList": [ { "name": "tati_430101.webp", @@ -7497,11 +7206,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "61", "time": 30, "wait": 1000, "sound": "", - "text": "「······」", "bodyList": [ { "name": "tati_430101.webp", @@ -7519,11 +7227,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "62", "time": 30, "wait": 1000, "sound": "", - "text": "「啊啊,无妨」", "bodyList": [ { "name": "tati_430101.webp", @@ -7541,11 +7248,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_430102.webp", "px": -300 }, - "name": "羽狩的队长", + "index": "63", "time": 30, "wait": 1000, "sound": "", - "text": "「感谢您的合作」", "bodyList": [ { "name": "tati_430102.webp", @@ -7563,11 +7269,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_430102.webp", "px": -300 }, - "name": "", + "index": "64", "time": 0, "wait": 2000, "sound": "", - "text": "队长殷勤地致以谢礼。", "bodyList": [ { "name": "tati_430102.webp", @@ -7585,11 +7290,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_430102.webp", "px": -300 }, - "name": "", + "index": "65", "time": 0, "wait": 2000, "sound": "", - "text": "而在他的眼前,少年的衣服已经被他的补下们扯破。", "bodyList": [ { "name": "tati_430102.webp", @@ -7607,11 +7311,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_430102.webp", "px": -300 }, - "name": "", + "index": "66", "time": 0, "wait": 2000, "sound": "", - "text": "在瘦骨嶙峋的裸露后背上,长有纯白的羽翼。", "bodyList": [ { "name": "tati_430102.webp", @@ -7629,11 +7332,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_430102.webp", "px": -300 }, - "name": "红发的羽狩", + "index": "67", "time": 30, "wait": 1000, "sound": "", - "text": "「副队长,确认翅膀的持有了」", "bodyList": [ { "name": "", @@ -7651,11 +7353,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_430105.webp", "px": -300 }, - "name": "羽狩的副队长", + "index": "68", "time": 30, "wait": 1000, "sound": "", - "text": "「保护他」", "bodyList": [ { "name": "tati_430105.webp", @@ -7673,11 +7374,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "羽化病患少年", + "index": "69", "time": 30, "wait": 1000, "sound": "", - "text": "「不要······请原谅,我······」", "bodyList": [ { "name": "tati_430105.webp", @@ -7695,11 +7395,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_430102.webp", "px": -300 }, - "name": "羽狩的副队长", + "index": "70", "time": 30, "wait": 1000, "sound": "", - "text": "「我们只是要带你去治愈院治疗羽化病,不是什么应该感到害怕的事情」", "bodyList": [ { "name": "tati_430102.webp", @@ -7717,11 +7416,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "羽化病患少年", + "index": "71", "time": 30, "wait": 1000, "sound": "", - "text": "「可是,可是」", "bodyList": [ { "name": "tati_430102.webp", @@ -7739,11 +7437,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_430102.webp", "px": -300 }, - "name": "羽狩的副队长", + "index": "72", "time": 30, "wait": 1000, "sound": "", - "text": "「没关系的」", "bodyList": [ { "name": "tati_430102.webp", @@ -7761,11 +7458,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "羽化病患少年", + "index": "73", "time": 30, "wait": 1000, "sound": "", - "text": "「······哥,哥哥」", "bodyList": [ { "name": "tati_430102.webp", @@ -7783,11 +7479,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_430105.webp", "px": -300 }, - "name": "羽狩的副队长", + "index": "74", "time": 30, "wait": 1000, "sound": "", - "text": "「你是羽化病人的亲属吗?」", "bodyList": [ { "name": "tati_430105.webp", @@ -7805,11 +7500,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "75", "time": 30, "wait": 1000, "sound": "", - "text": "「只是路人而已」", "bodyList": [ { "name": "tati_430105.webp", @@ -7827,11 +7521,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "76", "time": 30, "wait": 1000, "sound": "", - "text": "「顺带一提,我也没有打算找你们的麻烦」", "bodyList": [ { "name": "tati_430105.webp", @@ -7849,11 +7542,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_430101.webp", "px": -300 }, - "name": "羽狩的副队长", + "index": "77", "time": 30, "wait": 1000, "sound": "", - "text": "「前几天,有个和你说了同样的话的人,在我们背向他的瞬间对我们发动了袭击」", "bodyList": [ { "name": "tati_430101.webp", @@ -7871,11 +7563,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_430108.webp", "px": -300 }, - "name": "羽狩的副队长", + "index": "78", "time": 30, "wait": 1000, "sound": "", - "text": "「我的一个部下就此永久失去了半截胳膊」", "bodyList": [ { "name": "tati_430108.webp", @@ -7893,11 +7584,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "79", "time": 30, "wait": 1000, "sound": "", - "text": "「我表示同情」", "bodyList": [ { "name": "tati_430108.webp", @@ -7915,11 +7605,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "80", "time": 30, "wait": 1000, "sound": "", - "text": "「我马上就会消失的,这样就没问题了吧?」", "bodyList": [ { "name": "tati_430108.webp", @@ -7937,11 +7626,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_430102.webp", "px": -300 }, - "name": "羽狩的副队长", + "index": "81", "time": 30, "wait": 1000, "sound": "", - "text": "「嘛,不要这么慌张」", "bodyList": [ { "name": "tati_430102.webp", @@ -7959,11 +7647,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "82", "time": 30, "wait": 1000, "sound": "", - "text": "副队长看着羽化的少年。", "bodyList": [ { "name": "tati_430102.webp", @@ -7981,11 +7668,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_430105.webp", "px": -300 }, - "name": "羽狩的副队长", + "index": "83", "time": 30, "wait": 1000, "sound": "", - "text": "「你与这个人是什么关系?没有被他殴打吗?」", "bodyList": [ { "name": "tati_430105.webp", @@ -8003,11 +7689,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "羽化病患少年", + "index": "84", "time": 30, "wait": 1000, "sound": "", - "text": "「没,没有」", "bodyList": [ { "name": "tati_430105.webp", @@ -8025,11 +7710,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_430102.webp", "px": -300 }, - "name": "羽狩的副队长", + "index": "85", "time": 30, "wait": 1000, "sound": "", - "text": "「如何对我们保持合作,你就可以在治愈院得到优先的治疗」", "bodyList": [ { "name": "tati_430102.webp", @@ -8047,11 +7731,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "羽化病患少年", + "index": "86", "time": 30, "wait": 1000, "sound": "", - "text": "「······」", "bodyList": [ { "name": "tati_430102.webp", @@ -8069,11 +7752,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "羽化病患少年", + "index": "87", "time": 30, "wait": 1000, "sound": "", - "text": "「那个人,是《不蚀金锁》的组织成员······」", "bodyList": [ { "name": "tati_430102.webp", @@ -8091,11 +7773,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "羽化病患少年", + "index": "88", "time": 30, "wait": 1000, "sound": "", - "text": "「突然说让我拿出钱来,我刚一拒绝他就打我」", "bodyList": [ { "name": "tati_430102.webp", @@ -8113,11 +7794,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_430105.webp", "px": -300 }, - "name": "羽狩的副队长", + "index": "89", "time": 30, "wait": 1000, "sound": "", - "text": "「原来如此······」", "bodyList": [ { "name": "tati_430105.webp", @@ -8135,11 +7815,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_430107.webp", "px": -300 }, - "name": "羽狩的副队长", + "index": "90", "time": 30, "wait": 1000, "sound": "", - "text": "「那位少年说你是《不蚀金锁》的一员,不知此事是否属实?」", "bodyList": [ { "name": "tati_430107.webp", @@ -8157,11 +7836,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "91", "time": 30, "wait": 1000, "sound": "", - "text": "「当然不是」", "bodyList": [ { "name": "tati_430107.webp", @@ -8179,11 +7857,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "92", "time": 30, "wait": 1000, "sound": "", - "text": "「我只是从那里接受工作而已,并不是他们的成员」", "bodyList": [ { "name": "tati_430107.webp", @@ -8201,11 +7878,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_430105.webp", "px": -300 }, - "name": "羽狩的副队长", + "index": "93", "time": 30, "wait": 1000, "sound": "", - "text": "「你的意思是说,少年在说谎吗?」", "bodyList": [ { "name": "tati_430105.webp", @@ -8223,11 +7899,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "94", "time": 30, "wait": 1000, "sound": "", - "text": "「啊啊」", "bodyList": [ { "name": "tati_430105.webp", @@ -8245,11 +7920,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "95", "time": 30, "wait": 1000, "sound": "", - "text": "「如果你们和组织有关系的话,只要问问我是不是那里的成员就能明白事实了吧」", "bodyList": [ { "name": "tati_430105.webp", @@ -8267,11 +7941,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_430107.webp", "px": -300 }, - "name": "羽狩的副队长", + "index": "96", "time": 30, "wait": 1000, "sound": "", - "text": "「就算我去询问,也无法从他们那里得到事实」", "bodyList": [ { "name": "tati_430107.webp", @@ -8289,11 +7962,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_430108.webp", "px": -300 }, - "name": "羽狩的副队长", + "index": "97", "time": 30, "wait": 1000, "sound": "", - "text": "「《不蚀金锁》的那些人一向都不对我们合作,我对此深感困扰」", "bodyList": [ { "name": "tati_430108.webp", @@ -8311,11 +7983,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "98", "time": 30, "wait": 1000, "sound": "", - "text": "「真是辛苦啊」", "bodyList": [ { "name": "tati_430108.webp", @@ -8333,11 +8004,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_430102.webp", "px": -300 }, - "name": "羽狩的副队长", + "index": "99", "time": 30, "wait": 1000, "sound": "", - "text": "「说的是啊」", "bodyList": [ { "name": "tati_430102.webp", @@ -8355,11 +8025,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_430105.webp", "px": -300 }, - "name": "羽狩的副队长", + "index": "100", "time": 30, "wait": 1000, "sound": "", - "text": "「其实,砍下我部下胳膊的似乎也是组织的成员呢」", "bodyList": [ { "name": "tati_430105.webp", @@ -8377,11 +8046,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_430102.webp", "px": -300 }, - "name": "羽狩的副队长", + "index": "101", "time": 30, "wait": 1000, "sound": "", - "text": "「无需如此警戒,我只是想在看守所向你咨询一些事情而已」", "bodyList": [ { "name": "tati_430102.webp", @@ -8399,11 +8067,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_430105.webp", "px": -300 }, - "name": "羽狩的副队长", + "index": "102", "time": 30, "wait": 1000, "sound": "", - "text": "「如果能够知晓牢狱与组织的事情,我们也可以尽可能地对更多的羽化病人进行保护」", "bodyList": [ { "name": "tati_430105.webp", @@ -8421,11 +8088,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_430102.webp", "px": -300 }, - "name": "羽狩的副队长", + "index": "103", "time": 30, "wait": 1000, "sound": "", - "text": "「那和整条街道的和平也是紧密相关的吧?」", "bodyList": [ { "name": "tati_430102.webp", @@ -8443,11 +8109,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "104", "time": 30, "wait": 1000, "sound": "", - "text": "「我知道,你们有逮捕干扰狩猎羽化病人的权力」", "bodyList": [ { "name": "tati_430102.webp", @@ -8465,11 +8130,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "105", "time": 30, "wait": 1000, "sound": "", - "text": "「但是,我没有对你们做出任何干扰,为什么要对我如此纠缠不休呢」", "bodyList": [ { "name": "tati_430102.webp", @@ -8487,11 +8151,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_430105.webp", "px": -300 }, - "name": "羽狩的副队长", + "index": "106", "time": 30, "wait": 1000, "sound": "", - "text": "「那些话,我们会在看守所对你详细说明的」", "bodyList": [ { "name": "tati_430105.webp", @@ -8509,11 +8172,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "107", "time": 30, "wait": 1000, "sound": "", - "text": "「······」", "bodyList": [ { "name": "tati_430105.webp", @@ -8531,11 +8193,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "108", "time": 30, "wait": 1000, "sound": "", - "text": "在这里起争执的话,就会被羽狩加害。", "bodyList": [ { "name": "tati_430105.webp", @@ -8553,11 +8214,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "109", "time": 30, "wait": 1000, "sound": "", - "text": "就算能从这里脱身,今后只要碰面就会产生纠纷也是摆明的事情。", "bodyList": [ { "name": "tati_430105.webp", @@ -8575,11 +8235,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "110", "time": 30, "wait": 1000, "sound": "", - "text": "就算逃跑,也没有好的结果。", "bodyList": [ { "name": "tati_430105.webp", @@ -8597,11 +8256,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "111", "time": 30, "wait": 1000, "sound": "", - "text": "正当我想要打圆场的时候,刚才的气氛一瞬间产生了转变。", "bodyList": [ { "name": "tati_430105.webp", @@ -8619,11 +8277,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "112", "time": 30, "wait": 1000, "sound": "", - "text": "发生了什么事······", "bodyList": [ { "name": "tati_430105.webp", @@ -8641,11 +8298,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_050101.webp", "px": -300 }, - "name": "??", + "index": "113", "time": 30, "wait": 1000, "sound": "", - "text": "「我认为,那位先生是正确的」", "bodyList": [ { "name": "tati_430105.webp", @@ -8663,11 +8319,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "114", "time": 30, "wait": 1000, "sound": "", - "text": "耳边突然响起了一个能够将这阴暗的气息一扫而空的声音", "bodyList": [ { "name": "tati_430105.webp", @@ -8685,11 +8340,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "115", "time": 30, "wait": 1000, "sound": "", - "text": "羽狩们一起回头。", "bodyList": [ { "name": "", @@ -8707,11 +8361,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "116", "time": 30, "wait": 1000, "sound": "", - "text": "而在他们视线的焦点处,", "bodyList": [ { "name": "", @@ -8729,11 +8382,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "117", "time": 30, "wait": 1000, "sound": "", - "text": "伫立着一位女性。", "bodyList": [ { "name": "tati_050101.webp", @@ -8751,11 +8403,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "118", "time": 30, "wait": 1000, "sound": "", - "text": "在端正的容颜下,代表着强烈意志的双眉十分显眼。", "bodyList": [ { "name": "tati_050101.webp", @@ -8773,11 +8424,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "119", "time": 30, "wait": 1000, "sound": "", - "text": "身体的柔软与紧紧包裹在其身上的御兽支付,两者显得十分的不搭配。", "bodyList": [ { "name": "tati_050101.webp", @@ -8795,11 +8445,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "120", "time": 30, "wait": 1000, "sound": "", - "text": "我还是第一次看到女性的羽狩。", "bodyList": [ { "name": "tati_050101.webp", @@ -8817,11 +8466,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_430105.webp", "px": -300 }, - "name": "羽狩的副队长", + "index": "121", "time": 30, "wait": 1000, "sound": "", - "text": "「队长,这是获得《不蚀金锁》情报的好机会」", "bodyList": [ { "name": "tati_050101.webp", @@ -8844,11 +8492,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_430141.webp", "px": -300 }, - "name": "羽狩的队长", + "index": "122", "time": 30, "wait": 1000, "sound": "", - "text": "「兰格副队长,就算是为了获得情报,也不能做出恫吓的发言啊」", "bodyList": [ { "name": "tati_050141.webp", @@ -8871,11 +8518,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_430106.webp", "px": -300 }, - "name": "兰格副队长", + "index": "123", "time": 30, "wait": 1000, "sound": "", - "text": "「我并没有打算去恫吓他······」", "bodyList": [ { "name": "tati_050141.webp", @@ -8898,11 +8544,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_050221.webp", "px": -300 }, - "name": "羽狩的队长", + "index": "124", "time": 30, "wait": 1000, "sound": "", - "text": "「告诉我那个被砍掉胳膊的队员的名字」", "bodyList": [ { "name": "tati_050221.webp", @@ -8925,11 +8570,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_050223.webp", "px": -300 }, - "name": "羽狩的队长", + "index": "125", "time": 30, "wait": 1000, "sound": "", - "text": "「我会去探望他的」", "bodyList": [ { "name": "tati_050223.webp", @@ -8952,11 +8596,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_430104.webp", "px": -300 }, - "name": "兰格副队长", + "index": "126", "time": 30, "wait": 1000, "sound": "", - "text": "「那个是······」", "bodyList": [ { "name": "tati_050223.webp", @@ -8979,11 +8622,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_050101.webp", "px": -300 }, - "name": "羽狩的队长", + "index": "127", "time": 30, "wait": 1000, "sound": "", - "text": "「我知道,你一直在为有所收获而努力工作」", "bodyList": [ { "name": "tati_050101.webp", @@ -9006,11 +8648,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_050105.webp", "px": -300 }, - "name": "羽狩的队长", + "index": "128", "time": 30, "wait": 1000, "sound": "", - "text": "「但是,正因为我们的工作是为民众提供帮助」", "bodyList": [ { "name": "tati_050105.webp", @@ -9033,11 +8674,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_050103.webp", "px": -300 }, - "name": "羽狩的队长", + "index": "129", "time": 30, "wait": 1000, "sound": "", - "text": "「所以就更不能损害人与人之间的信赖」", "bodyList": [ { "name": "tati_050103.webp", @@ -9060,11 +8700,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_430105.webp", "px": -300 }, - "name": "兰格副队长", + "index": "130", "time": 30, "wait": 1000, "sound": "", - "text": "「我会铭记在心」", "bodyList": [ { "name": "tati_050103.webp", @@ -9087,11 +8726,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_050101.webp", "px": -300 }, - "name": "羽狩的队长", + "index": "131", "time": 30, "wait": 1000, "sound": "", - "text": "「这位先生,我的部下失礼了」", "bodyList": [ { "name": "tati_050101.webp", @@ -9109,11 +8747,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "132", "time": 30, "wait": 1000, "sound": "", - "text": "「只要不对我再来一次就好」", "bodyList": [ { "name": "tati_050101.webp", @@ -9131,11 +8768,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_050126.webp", "px": -300 }, - "name": "羽狩的队长", + "index": "133", "time": 30, "wait": 1000, "sound": "", - "text": "「请稍等」", "bodyList": [ { "name": "tati_050126.webp", @@ -9153,11 +8789,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "134", "time": 30, "wait": 1000, "sound": "", - "text": "「有什么事?」", "bodyList": [ { "name": "tati_050126.webp", @@ -9175,11 +8810,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_050101.webp", "px": -300 }, - "name": "羽狩的队长", + "index": "135", "time": 30, "wait": 1000, "sound": "", - "text": "「我想确认一件事」", "bodyList": [ { "name": "tati_050101.webp", @@ -9197,11 +8831,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_050105.webp", "px": -300 }, - "name": "羽狩的队长", + "index": "136", "time": 30, "wait": 1000, "sound": "", - "text": "「你真的不是《不蚀金锁》的成员吗?」", "bodyList": [ { "name": "tati_050105.webp", @@ -9219,11 +8852,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "137", "time": 30, "wait": 1000, "sound": "", - "text": "「真的」", "bodyList": [ { "name": "tati_050105.webp", @@ -9241,11 +8873,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "138", "time": 30, "wait": 1000, "sound": "", - "text": "「如果我说是的话,你有什么打算?」", "bodyList": [ { "name": "tati_050105.webp", @@ -9263,11 +8894,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_050143.webp", "px": -300 }, - "name": "羽狩的队长", + "index": "139", "time": 30, "wait": 1000, "sound": "", - "text": "「我听过传闻,说他们是用依靠暴力而得的钱在生活」", "bodyList": [ { "name": "tati_050143.webp", @@ -9285,11 +8915,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "140", "time": 30, "wait": 1000, "sound": "", - "text": "「······这样啊」", "bodyList": [ { "name": "tati_050143.webp", @@ -9307,11 +8936,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "141", "time": 30, "wait": 1000, "sound": "", - "text": "「如果能有收获就好了啊」", "bodyList": [ { "name": "tati_050143.webp", @@ -9367,6 +8995,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "time": 30, "style": "场景切换" }, + { + "type": "cgtextList", + "textList": "chapter04" + }, { "type": "cgtext", "bg": "bg_3551.webp", @@ -9376,11 +9008,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_120122.webp", "px": -300 }, - "name": "梅尔特", + "index": "0", "time": 0, "wait": 2000, "sound": "", - "text": "「欢迎光临」", "bodyList": [ { "name": "", @@ -9398,11 +9029,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_120101.webp", "px": -300 }, - "name": "梅尔特", + "index": "1", "time": 0, "wait": 2000, "sound": "", - "text": "「辛苦了」", "bodyList": [ { "name": "tati_120101.webp", @@ -9420,11 +9050,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_120107.webp", "px": -300 }, - "name": "梅尔特", + "index": "2", "time": 0, "wait": 2000, "sound": "", - "text": "「抱歉,又拜托给你了个这么麻烦的工作」", "bodyList": [ { "name": "tati_120107.webp", @@ -9442,11 +9071,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "3", "time": 0, "wait": 2000, "sound": "", - "text": "「没什么,比想象中完成的更容易」", "bodyList": [ { "name": "tati_120107.webp", @@ -9464,11 +9092,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_120112.webp", "px": -300 }, - "name": "梅尔特", + "index": "4", "time": 0, "wait": 2000, "sound": "", - "text": "「那就好」", "bodyList": [ { "name": "tati_120112.webp", @@ -9486,11 +9113,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_120102.webp", "px": -300 }, - "name": "梅尔特", + "index": "5", "time": 0, "wait": 2000, "sound": "", - "text": "「这是我的一点谢意」", "bodyList": [ { "name": "tati_120102.webp", @@ -9508,11 +9134,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "6", "time": 0, "wait": 2000, "sound": "", - "text": "「味道有些变化啊」", "bodyList": [ { "name": "tati_120102.webp", @@ -9530,11 +9155,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_120107.webp", "px": -300 }, - "name": "梅尔特", + "index": "7", "time": 0, "wait": 2000, "sound": "", - "text": "「啊,被发现了?」", "bodyList": [ { "name": "tati_120107.webp", @@ -9552,11 +9176,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_120111.webp", "px": -300 }, - "name": "梅尔特", + "index": "8", "time": 0, "wait": 2000, "sound": "", - "text": "「最近,没能到手什么好的原料呢」", "bodyList": [ { "name": "tati_120111.webp", @@ -9574,11 +9197,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "9", "time": 0, "wait": 2000, "sound": "", - "text": "「去拜托吉克如何?」", "bodyList": [ { "name": "tati_120111.webp", @@ -9596,11 +9218,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_120127.webp", "px": -300 }, - "name": "梅尔特", + "index": "10", "time": 0, "wait": 2000, "sound": "", - "text": "「话是这么说,但是总不能用店里采购的这种小事去麻烦他吧······」", "bodyList": [ { "name": "tati_120127.webp", @@ -9618,11 +9239,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "11", "time": 0, "wait": 2000, "sound": "", - "text": "「那希望你也不要来麻烦我」", "bodyList": [ { "name": "tati_120127.webp", @@ -9640,11 +9260,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_120112.webp", "px": -300 }, - "name": "梅尔特", + "index": "12", "time": 0, "wait": 2000, "sound": "", - "text": "「那 是 两 码 事」", "bodyList": [ { "name": "tati_120112.webp", @@ -9662,11 +9281,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_120113.webp", "px": -300 }, - "name": "梅尔特", + "index": "13", "time": 0, "wait": 2000, "sound": "", - "text": "「再说,凯伊姆是靠着工作来生活的吧」", "bodyList": [ { "name": "tati_120113.webp", @@ -9684,11 +9302,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_120113.webp", "px": -300 }, - "name": "梅尔特", + "index": "14", "time": 0, "wait": 2000, "sound": "", - "text": "「而且,自己的钱被偷了这么害羞的事,向凯伊姆意外的其他人都说不出口」", "bodyList": [ { "name": "tati_120113.webp", @@ -9706,11 +9323,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "15", "time": 0, "wait": 2000, "sound": "", - "text": "「反正,也已经传到吉克的耳朵里了」", "bodyList": [ { "name": "tati_120113.webp", @@ -9728,11 +9344,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_120112.webp", "px": -300 }, - "name": "梅尔特", + "index": "16", "time": 0, "wait": 2000, "sound": "", - "text": "「这是面子问题啊,面子问题」", "bodyList": [ { "name": "tati_120112.webp", @@ -9750,11 +9365,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "17", "time": 0, "wait": 2000, "sound": "", - "text": "「嘛,算了」", "bodyList": [ { "name": "tati_120101.webp", @@ -9772,11 +9386,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "18", "time": 0, "wait": 2000, "sound": "", - "text": "「这样就好了吧?」", "bodyList": [ { "name": "tati_120101.webp", @@ -9794,11 +9407,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_120121.webp", "px": -300 }, - "name": "梅尔特", + "index": "19", "time": 0, "wait": 2000, "sound": "", - "text": "「这是钱包呢」", "bodyList": [ { "name": "tati_120121.webp", @@ -9816,11 +9428,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_120102.webp", "px": -300 }, - "name": "梅尔特", + "index": "20", "time": 0, "wait": 2000, "sound": "", - "text": "「嗯,东西没少」", "bodyList": [ { "name": "tati_120102.webp", @@ -9838,11 +9449,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_120111.webp", "px": -300 }, - "name": "梅尔特", + "index": "21", "time": 0, "wait": 2000, "sound": "", - "text": "「太好啦—这个月的上纳金,我可全部都放在里面了呢」", "bodyList": [ { "name": "tati_120111.webp", @@ -9860,11 +9470,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_120113.webp", "px": -300 }, - "name": "梅尔特", + "index": "22", "time": 0, "wait": 2000, "sound": "", - "text": "「如果没有找到的话,说不定就又会被送到娼馆里了呢」", "bodyList": [ { "name": "tati_120113.webp", @@ -9882,11 +9491,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "23", "time": 0, "wait": 2000, "sound": "", - "text": "「在那边不是来钱更快吗?」", "bodyList": [ { "name": "tati_120113.webp", @@ -9904,11 +9512,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_120106.webp", "px": -300 }, - "name": "梅尔特", + "index": "24", "time": 0, "wait": 2000, "sound": "", - "text": "「阿拉,你是在说我还能有魅力吗?」", "bodyList": [ { "name": "tati_120106.webp", @@ -9926,11 +9533,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "25", "time": 0, "wait": 2000, "sound": "", - "text": "「这是客套话而已」", "bodyList": [ { "name": "tati_120106.webp", @@ -9948,11 +9554,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_120113.webp", "px": -300 }, - "name": "梅尔特", + "index": "26", "time": 0, "wait": 2000, "sound": "", - "text": "「欺负人」", "bodyList": [ { "name": "tati_120113.webp", @@ -9974,11 +9579,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_120122.webp", "px": -300 }, - "name": "梅尔特", + "index": "27", "time": 0, "wait": 2000, "sound": "", - "text": "「总而言之,今天帮大忙了」", "bodyList": [ { "name": "tati_120122.webp", @@ -9996,11 +9600,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_120107.webp", "px": -300 }, - "name": "梅尔特", + "index": "28", "time": 0, "wait": 2000, "sound": "", - "text": "「谢礼嘛······」", "bodyList": [ { "name": "tati_120107.webp", @@ -10018,11 +9621,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "29", "time": 0, "wait": 2000, "sound": "", - "text": "「就记在账单上吧」", "bodyList": [ { "name": "tati_120107.webp", @@ -10040,11 +9642,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_120112.webp", "px": -300 }, - "name": "梅尔特", + "index": "30", "time": 0, "wait": 2000, "sound": "", - "text": "「了解—盛谢惠顾了哦?」", "bodyList": [ { "name": "tati_120112.webp", @@ -10062,11 +9663,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "31", "time": 0, "wait": 2000, "sound": "", - "text": "喀啷喀啷", "bodyList": [ { "name": "", @@ -10084,11 +9684,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "32", "time": 0, "wait": 2000, "sound": "", - "text": "门铃响起", "bodyList": [ { "name": "", @@ -10106,11 +9705,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "33", "time": 0, "wait": 2000, "sound": "", - "text": "喧哗瞬间安静下来。", "bodyList": [ { "name": "", @@ -10128,11 +9726,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "34", "time": 0, "wait": 2000, "sound": "", - "text": "进来的人是吉克。", "bodyList": [ { "name": "tati_340101.webp", @@ -10150,11 +9747,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "35", "time": 0, "wait": 2000, "sound": "", - "text": "是掌控着牢狱的组织之一,《不蚀金锁》的头目。", "bodyList": [ { "name": "tati_340101.webp", @@ -10172,11 +9768,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "36", "time": 0, "wait": 2000, "sound": "", - "text": "不仅组织的成员,就连店内一般的客人也对他以注目礼表示敬意。", "bodyList": [ { "name": "tati_340101.webp", @@ -10194,11 +9789,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_340102.webp", "px": -300 }, - "name": "吉克", + "index": "37", "time": 0, "wait": 2000, "sound": "", - "text": "「各位继续吧」", "bodyList": [ { "name": "tati_340102.webp", @@ -10216,11 +9810,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "38", "time": 0, "wait": 2000, "sound": "", - "text": "仿佛停滞的时钟重新转动了一般,店内恢复了热闹的气氛。", "bodyList": [ { "name": "tati_340102.webp", @@ -10238,11 +9831,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_340101.webp", "px": -300 }, - "name": "吉克", + "index": "39", "time": 0, "wait": 2000, "sound": "", - "text": "「抱歉,今天拜托你去做了无聊的工作」", "bodyList": [ { "name": "tati_340101.webp", @@ -10260,11 +9852,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "40", "time": 0, "wait": 2000, "sound": "", - "text": "「不用介意」", "bodyList": [ { "name": "tati_340101.webp", @@ -10282,11 +9873,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "41", "time": 0, "wait": 2000, "sound": "", - "text": "吉克轻轻点了点头,在我右边坐了下来", "bodyList": [ { "name": "tati_z340101.webp", @@ -10304,11 +9894,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "42", "time": 0, "wait": 2000, "sound": "", - "text": "「逃跑的男人怎么样了?」", "bodyList": [ { "name": "tati_z340101.webp", @@ -10326,11 +9915,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_340104.webp", "px": -300 }, - "name": "吉克", + "index": "43", "time": 0, "wait": 2000, "sound": "", - "text": "「嗯?已经不在这个世上了」", "bodyList": [ { "name": "tati_z340104.webp", @@ -10348,11 +9936,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_340107.webp", "px": -300 }, - "name": "吉克", + "index": "44", "time": 0, "wait": 2000, "sound": "", - "text": "「有什么想要知道的事吗?」", "bodyList": [ { "name": "tati_z340107.webp", @@ -10370,11 +9957,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "45", "time": 0, "wait": 2000, "sound": "", - "text": "「不,没什么」", "bodyList": [ { "name": "tati_z340107.webp", @@ -10392,11 +9978,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_340108.webp", "px": -300 }, - "name": "吉克", + "index": "46", "time": 0, "wait": 2000, "sound": "", - "text": "「那个无聊的家伙,完全没有趣味呢」", "bodyList": [ { "name": "tati_z340108.webp", @@ -10414,11 +9999,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_340114.webp", "px": -300 }, - "name": "吉克", + "index": "47", "time": 0, "wait": 2000, "sound": "", - "text": "「真希望他也替我负责清扫的部下也考虑考虑」", "bodyList": [ { "name": "tati_z340114.webp", @@ -10436,11 +10020,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "48", "time": 0, "wait": 2000, "sound": "", - "text": "「真是灾难啊」", "bodyList": [ { "name": "tati_z340114.webp", @@ -10458,11 +10041,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_340102.webp", "px": -300 }, - "name": "吉克", + "index": "49", "time": 0, "wait": 2000, "sound": "", - "text": "「比起那个,我听说了哦。你去追羽化病人了啊」", "bodyList": [ { "name": "tati_z340102.webp", @@ -10480,11 +10062,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "50", "time": 0, "wait": 2000, "sound": "", - "text": "「消息真灵通」", "bodyList": [ { "name": "tati_z340102.webp", @@ -10502,11 +10083,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_340104.webp", "px": -300 }, - "name": "吉克", + "index": "51", "time": 0, "wait": 2000, "sound": "", - "text": "「梅尔特也注意点」", "bodyList": [ { "name": "tati_z340104.webp", @@ -10524,11 +10104,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_340107.webp", "px": -300 }, - "name": "吉克", + "index": "52", "time": 0, "wait": 2000, "sound": "", - "text": "「你丢钱已经不是一回两回了」", "bodyList": [ { "name": "tati_z340107.webp", @@ -10546,11 +10125,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_120132.webp", "px": -300 }, - "name": "梅尔特", + "index": "53", "time": 0, "wait": 2000, "sound": "", - "text": "「好的—我会注意的。」", "bodyList": [ { "name": "tati_z340104.webp", @@ -10573,11 +10151,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_120101.webp", "px": -300 }, - "name": "梅尔特", + "index": "54", "time": 0, "wait": 2000, "sound": "", - "text": "「吉克还是平常的点单吧」", "bodyList": [ { "name": "tati_z340102.webp", @@ -10600,11 +10177,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_120121.webp", "px": -300 }, - "name": "梅尔特", + "index": "55", "time": 0, "wait": 2000, "sound": "", - "text": "「凯伊姆要再来一杯吗?」", "bodyList": [ { "name": "tati_z340102.webp", @@ -10627,11 +10203,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "56", "time": 0, "wait": 2000, "sound": "", - "text": "我们用眼神点头示意后,梅尔特开始准备起酒来。", "bodyList": [ { "name": "tati_z340102.webp", @@ -10649,11 +10224,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "", + "index": "57", "time": 0, "wait": 2000, "sound": "", - "text": "悠然地吐出眼圈后,吉克取出一个纸包放在柜台上。", "bodyList": [ { "name": "tati_z340102.webp", @@ -10671,11 +10245,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_340101.webp", "px": -300 }, - "name": "吉克", + "index": "58", "time": 0, "wait": 2000, "sound": "", - "text": "「这是抓捕逃跑男人的报酬」", "bodyList": [ { "name": "tati_z340101.webp", @@ -10693,11 +10266,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "59", "time": 0, "wait": 2000, "sound": "", - "text": "「下次有什么事再告诉我」", "bodyList": [ { "name": "tati_z340101.webp", @@ -10715,11 +10287,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_120102.webp", "px": -300 }, - "name": "梅尔特", + "index": "60", "time": 0, "wait": 2000, "sound": "", - "text": "「来,久等了」", "bodyList": [ { "name": "tati_z340101.webp", @@ -10742,11 +10313,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "61", "time": 0, "wait": 2000, "sound": "", - "text": "「话说回来梅尔特,为什么会被那种孩子偷到钱?」", "bodyList": [ { "name": "tati_z340101.webp", @@ -10769,11 +10339,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_340102.webp", "px": -300 }, - "name": "吉克", + "index": "62", "time": 0, "wait": 2000, "sound": "", - "text": "「让我猜猜看」", "bodyList": [ { "name": "tati_z340102.webp", @@ -10796,11 +10365,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_340110.webp", "px": -300 }, - "name": "吉克", + "index": "63", "time": 0, "wait": 2000, "sound": "", - "text": "「是那个吧,看某个特立独行的男人入迷了,所以就有了空隙?」", "bodyList": [ { "name": "tati_z340110.webp", @@ -10823,11 +10391,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_120113.webp", "px": -300 }, - "name": "梅尔特", + "index": "64", "time": 0, "wait": 2000, "sound": "", - "text": "「可惜—」", "bodyList": [ { "name": "tati_z340110.webp", @@ -10850,11 +10417,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_120101.webp", "px": -300 }, - "name": "梅尔特", + "index": "65", "time": 0, "wait": 2000, "sound": "", - "text": "「事实恰恰相反,是那家伙一直在纠缠我」", "bodyList": [ { "name": "tati_z340101.webp", @@ -10877,11 +10443,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "66", "time": 0, "wait": 2000, "sound": "", - "text": "「完全把你当成新进的女佣了么」", "bodyList": [ { "name": "tati_z340101.webp", @@ -10904,11 +10469,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_120121.webp", "px": -300 }, - "name": "梅尔特", + "index": "67", "time": 0, "wait": 2000, "sound": "", - "text": "「我从前可是很有名的,不会被当成这种下人吧」", "bodyList": [ { "name": "tati_z340101.webp", @@ -10931,11 +10495,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_120132.webp", "px": -300 }, - "name": "梅尔特", + "index": "68", "time": 0, "wait": 2000, "sound": "", - "text": "「······而且,我没法对对我这么钟情的人发火啊」", "bodyList": [ { "name": "tati_z340101.webp", @@ -10958,11 +10521,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_340106.webp", "px": -300 }, - "name": "凯伊姆&吉克", + "index": "69", "time": 0, "wait": 2000, "sound": "", - "text": "「你傻啊」", "bodyList": [ { "name": "tati_z340106.webp", @@ -10985,11 +10547,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_340112.webp", "px": -300 }, - "name": "梅尔特", + "index": "70", "time": 0, "wait": 2000, "sound": "", - "text": "「异口同声呢,不亏是兄弟」", "bodyList": [ { "name": "tati_z340106.webp", @@ -11012,11 +10573,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "71", "time": 0, "wait": 2000, "sound": "", - "text": "「别用这种称呼,怪恶心的」", "bodyList": [ { "name": "tati_z340106.webp", @@ -11039,11 +10599,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_340108.webp", "px": -300 }, - "name": "吉克", + "index": "72", "time": 0, "wait": 2000, "sound": "", - "text": "「说得没错」", "bodyList": [ { "name": "tati_z340108.webp", @@ -11066,11 +10625,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_340105.webp", "px": -300 }, - "name": "吉克", + "index": "73", "time": 0, "wait": 2000, "sound": "", - "text": "「······说起来······」", "bodyList": [ { "name": "tati_z340105.webp", @@ -11093,11 +10651,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_120107.webp", "px": -300 }, - "name": "梅尔特", + "index": "74", "time": 0, "wait": 2000, "sound": "", - "text": "「怎么了?」", "bodyList": [ { "name": "tati_z340105.webp", @@ -11120,11 +10677,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_340107.webp", "px": -300 }, - "name": "吉克", + "index": "75", "time": 0, "wait": 2000, "sound": "", - "text": "「有件事我一直很在意,我和凯伊姆,哪个是哥哥啊?」", "bodyList": [ { "name": "tati_z340107.webp", @@ -11147,11 +10703,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "", "px": -300 }, - "name": "凯伊姆", + "index": "76", "time": 0, "wait": 2000, "sound": "", - "text": "「你也说这么无聊的话题」", "bodyList": [ { "name": "tati_z340107.webp", @@ -11174,11 +10729,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_340103.webp", "px": -300 }, - "name": "吉克", + "index": "77", "time": 0, "wait": 2000, "sound": "", - "text": "「不,这是很重要的事情」", "bodyList": [ { "name": "tati_z340103.webp", @@ -11201,11 +10755,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_340101.webp", "px": -300 }, - "name": "吉克", + "index": "78", "time": 0, "wait": 2000, "sound": "", - "text": "「梅尔特,事实是怎么样的?」", "bodyList": [ { "name": "tati_z340101.webp", @@ -11228,11 +10781,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_120113.webp", "px": -300 }, - "name": "梅尔特", + "index": "79", "time": 0, "wait": 2000, "sound": "", - "text": "「啊~是怎么样的呢~」", "bodyList": [ { "name": "tati_z340105.webp", @@ -11255,11 +10807,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_120112.webp", "px": -300 }, - "name": "梅尔特", + "index": "80", "time": 0, "wait": 2000, "sound": "", - "text": "「我忘记了」", "bodyList": [ { "name": "tati_z340105.webp", @@ -11282,11 +10833,10 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = "name": "face_340107.webp", "px": -300 }, - "name": "吉克", + "index": "81", "time": 0, "wait": 2000, "sound": "", - "text": "「骗人」", "bodyList": [ { "name": "tati_z340107.webp", diff --git a/project/functions.js b/project/functions.js index e6ab598..92736e7 100644 --- a/project/functions.js +++ b/project/functions.js @@ -888,7 +888,9 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = core.openBook(true); break; case 71: // G:使用楼传器 - core.ui._drawViewMaps(core.floorIds.indexOf(core.status.floorId)); + flags.canMoveFloor = core.canMoveFloor() + if (core.isPlaying()) core.ui._drawViewMaps(core.floorIds.indexOf(core.status.floorId)); + core.status.route.push("key:71"); break; case 65: // A:读取自动存档(回退) core.doSL("autoSave", "load"); diff --git a/project/items.js b/project/items.js index fddc8ac..edc41cf 100644 --- a/project/items.js +++ b/project/items.js @@ -332,7 +332,7 @@ var items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a = "text": "可以自由往来去过的楼层", "hideInReplay": true, "hideInToolbox": true, - "useItemEffect": "//core.ui.drawFly(core.floorIds.indexOf(core.status.floorId));\ncore.ui._drawViewMaps(core.floorIds.indexOf(core.status.floorId));", + "useItemEffect": "//core.ui.drawFly(core.floorIds.indexOf(core.status.floorId));\nflags.canMoveFloor = core.canMoveFloor()\nif (core.isPlaying()) core.ui._drawViewMaps(core.floorIds.indexOf(core.status.floorId));", "canUseItemEffect": "(function () {\n\tif (core.flags.flyNearStair && !core.nearStair() && !core.canMoveFloor())\n\t\treturn false;\n\treturn core.status.maps[core.status.floorId].canFlyFrom;\n})();" }, "coin": { diff --git a/project/plugins.js b/project/plugins.js index cab1c09..c39164e 100644 --- a/project/plugins.js +++ b/project/plugins.js @@ -1,270 +1,263 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = { "init": function () { - this._afterLoadResources = function () { - // 本函数将在所有资源加载完毕后,游戏开启前被执行 - core.ui.statusBar.init(); - core.dom.playGame.style.fontFamily = "pala"; - core.dom.loadGame.style.fontFamily = "pala"; - core.dom.CGMode.style.fontFamily = "pala"; - core.dom.musicMode.style.fontFamily = "pala"; - core.dom.replayGame.style.fontFamily = "pala"; - core.registerEvent("changeMouse", function (data) { - if (!main.replayChecking && !core.isReplaying()) - core.changeMouse( - data.icon, - data.div, - data.translate[0], - data.translate[1], - data.scale[0], - data.scale[1], - data.angel, - data.px, - data.py - ); - core.doAction(); - }); - core.registerEvent("removeMouse", function (data) { - if (!main.replayChecking && !core.isReplaying()) - core.removeMouse(data.div); - core.doAction(); - }); - core.registerEvent("addPop", function (data) { - if (!main.replayChecking && !core.isReplaying()) { - data.value = core.replaceText(data.value); - core.addPop( - data.value, - data.px, - data.py, - data.color, - data.boldColor, - data.left, - data.jump, - data.time, - data.show, - data.font, - data.speed - ); - } - core.doAction(); - }); - core.registerEvent("drawWarning", function (data) { - if (!main.replayChecking && !core.isReplaying()) { - data.text = core.replaceText(data.text); - data.text2 = core.replaceText(data.text2); - core.drawWarning( - data.x, - data.y, - data.size, - data?.text, - data?.text2, - data?.warning - ); - setTimeout(() => core.doAction(), 3100); - } else { - core.doAction(); - } - }); - core.registerEvent("playStereo", function (data) { - if (!main.replayChecking && !core.isReplaying()) - core.playStereo(data.name, data.left, data.right, data.split); - core.doAction(); - }); - core.registerEvent("moveStereo", function (data) { - if (!main.replayChecking && !core.isReplaying()) { - const id = core.playStereo( - data.name, - data.left, - data.right, - data.split - ); - core.moveStereo(id, data.leftTo, data.rightTo, data.time); - } - core.doAction(); - }); - core.registerEvent("over", function (data) { - let image = data.image ?? ""; - let time = data.time ?? 3000; - let sound = data.sound ?? ""; - let textColor = data.textColor ?? "#FFFFFF"; - let boldColor = data.boldColor ?? "#000000"; - let font = data.font ?? "bold 48px Verdana"; - let text = data.text ?? ""; - let hidetime = data.hidetime ?? 100; - if (!main.replayChecking && !core.isReplaying()) { - core.over( - image, - data.memory, - time, - hidetime, - sound, - textColor, - boldColor, - font, - text - ); - } else { - core.doAction(); - } - }); - core.registerEvent("changebg", function (data) { - if (!main.replayChecking && !core.isReplaying()) { - core.changebg( - data.img1, - data.memory1, - data.img2, - data.memory2, - data.time, - data.style - ); - } else { - core.doAction(); - } - }); - core.registerEvent("overlist", function (data) { - if (!main.replayChecking && !core.isReplaying()) { - core.overlist( - data.image, - data.memory, - data.hidetime || 30, - data.list || [ - { - text: "", - sound: "", - time: 50, - textColor: "#FFFFFF", - boldColor: "#000000", - font: "bold 48px Verdana", - frame: 0, - }, - ] - ); - } else { - core.doAction(); - } - }); - core.registerEvent("op", function (data) { - if (!main.replayChecking && !core.isReplaying()) { - core.openvideo(); - } else { - core.doAction(); - } - }); - core.registerEvent("animationDrawable", function (data) { - if (!main.replayChecking && !core.isReplaying()) { - core.animationDrawable( - data.allFarme, - data.color, - data.globalAlpha, - data.imageList, - data.soundList - ); - } else { - core.doAction(); - } - }); - core.registerEvent("setanimate", function (data) { - data.px = data.px ?? 0; - data.py = data.py ?? 0; - core.setanimate( - data.name, - data.px, - data.py, - data.width, - data.height, - data.allFarme, - data.imageList, - data.soundList - ); - core.doAction(); - }); - core.registerEvent("clearanimate", function (data) { - core.plugin.playing.clear(); + this._afterLoadResources = function () { + // 本函数将在所有资源加载完毕后,游戏开启前被执行 + core.ui.statusBar.init(); + core.dom.playGame.style.fontFamily = "pala"; + core.dom.loadGame.style.fontFamily = "pala"; + core.dom.CGMode.style.fontFamily = "pala"; + core.dom.musicMode.style.fontFamily = "pala"; + core.dom.replayGame.style.fontFamily = "pala"; + core.registerEvent("changeMouse", function (data) { + if (!main.replayChecking && !core.isReplaying()) + core.changeMouse( + data.icon, + data.div, + data.translate[0], + data.translate[1], + data.scale[0], + data.scale[1], + data.angel, + data.px, + data.py + ); + core.doAction(); + }); + core.registerEvent("removeMouse", function (data) { + if (!main.replayChecking && !core.isReplaying()) + core.removeMouse(data.div); + core.doAction(); + }); + core.registerEvent("addPop", function (data) { + if (!main.replayChecking && !core.isReplaying()) { + data.value = core.replaceText(data.value); + core.addPop( + data.value, + data.px, + data.py, + data.color, + data.boldColor, + data.left, + data.jump, + data.time, + data.show, + data.font, + data.speed + ); + } + core.doAction(); + }); + core.registerEvent("drawWarning", function (data) { + if (!main.replayChecking && !core.isReplaying()) { + data.text = core.replaceText(data.text); + data.text2 = core.replaceText(data.text2); + core.drawWarning( + data.x, + data.y, + data.size, + data?.text, + data?.text2, + data?.warning + ); + setTimeout(() => core.doAction(), 3100); + } else { + core.doAction(); + } + }); - core.doAction(); - }); - core.registerEvent("deleteanimate", function (data) { - core.deleteanimate(data.name); - core.doAction(); - }); - core.registerEvent("playanimate", function (data) { - if (!main.replayChecking && !core.isReplaying()) { - data.x = data.x ?? 0; - data.y = data.y ?? 0; - data.scalex = data.scalex ?? 1; - data.scaley = data.scaley ?? 1; - core.playanimate( - data.name, - data.x, - data.y, - data.hero, - data.scalex, - data.scaley - ); - core.doAction(); - } else { - core.doAction(); - } - }); - core.registerEvent("cgtext", function (data) { - if (!main.replayChecking && !core.isReplaying()) { - core.ui.cgText.image = data.bg; - core.ui.cgText.memory = data.memory; - core.ui.cgText.head = core.clone(data.head); - core.ui.cgText.name = data.name; - core.ui.cgText.text = data.text; - core.ui.cgText.time = data.time; - core.ui.cgText.wait = data.wait; - core.ui.cgText.WindowSkin = data.WindowSkin; - core.ui.cgText.sound = data.sound || ""; - core.ui.cgText.bodyList = core.clone(data.bodyList); - main.dom.cgText.style.display = "block"; - core.ui.cgText.update(); - } else { - core.doAction(); - } - }); - core.registerEvent("introAndLoop", function (data) { - if (!main.replayChecking && !core.isReplaying()) { - core.plugin.introAndLoop(data.intro, data.time, data.loop); - core.doAction(); - } else { - core.doAction(); - } - }); - core.registerEvent("setq", function (data) { - core.setFlag("任务地点", data.id); + core.registerEvent("over", function (data) { + let image = data.image ?? ""; + let time = data.time ?? 3000; + let sound = data.sound ?? ""; + let textColor = data.textColor ?? "#FFFFFF"; + let boldColor = data.boldColor ?? "#000000"; + let font = data.font ?? "bold 48px Verdana"; + let text = data.text ?? ""; + let hidetime = data.hidetime ?? 100; + if (!main.replayChecking && !core.isReplaying()) { + core.over( + image, + data.memory, + time, + hidetime, + sound, + textColor, + boldColor, + font, + text + ); + } else { + core.doAction(); + } + }); + core.registerEvent("changebg", function (data) { + if (!main.replayChecking && !core.isReplaying()) { + core.changebg( + data.img1, + data.memory1, + data.img2, + data.memory2, + data.time, + data.style + ); + } else { + core.doAction(); + } + }); + core.registerEvent("overlist", function (data) { + if (!main.replayChecking && !core.isReplaying()) { + core.overlist( + data.image, + data.memory, + data.hidetime || 30, + data.list || [{ + text: "", + sound: "", + time: 50, + textColor: "#FFFFFF", + boldColor: "#000000", + font: "bold 48px Verdana", + frame: 0, + }, ] + ); + } else { + core.doAction(); + } + }); + core.registerEvent("op", function (data) { + if (!main.replayChecking && !core.isReplaying()) { + core.openvideo(); + } else { + core.doAction(); + } + }); + core.registerEvent("animationDrawable", function (data) { + if (!main.replayChecking && !core.isReplaying()) { + core.animationDrawable( + data.allFarme, + data.color, + data.globalAlpha, + data.imageList, + data.soundList + ); + } else { + core.doAction(); + } + }); + core.registerEvent("setanimate", function (data) { + data.px = data.px ?? 0; + data.py = data.py ?? 0; + core.setanimate( + data.name, + data.px, + data.py, + data.width, + data.height, + data.allFarme, + data.imageList, + data.soundList + ); + core.doAction(); + }); + core.registerEvent("clearanimate", function (data) { + core.plugin.playing.clear(); - core.doAction(); - }); - core.registerEvent("setmusics", function (data) { - if ( - (core.getLocalStorage("musics") && - core.getLocalStorage("musics").length === 0) || - !core.getLocalStorage("musics") - ) - core.setLocalStorage("musics", ["theme.mp3"]); - let a = core.getLocalStorage("musics"); - if (!data.bgm) { - core.setLocalStorage("musics", ["theme.mp3"]); - } else { - if (!a.includes(data.bgm)) a.push(data.bgm); - core.setLocalStorage("musics", a); - } - core.doAction(); - }); - core.registerEvent("setcgs", function (data) { - if (!data.img) { - core.setLocalStorage("cgs", []); - } else { - let a = core.getLocalStorage("cgs") ?? []; - if (!a.includes(data.img)) a.push(data.img); - core.setLocalStorage("cgs", a); - } - core.doAction(); - }); - }; - }, + core.doAction(); + }); + core.registerEvent("deleteanimate", function (data) { + core.deleteanimate(data.name); + core.doAction(); + }); + core.registerEvent("playanimate", function (data) { + if (!main.replayChecking && !core.isReplaying()) { + data.x = data.x ?? 0; + data.y = data.y ?? 0; + data.scalex = data.scalex ?? 1; + data.scaley = data.scaley ?? 1; + core.playanimate( + data.name, + data.x, + data.y, + data.hero, + data.scalex, + data.scaley + ); + core.doAction(); + } else { + core.doAction(); + } + }); + core.registerEvent('cgtextList', function (data) { + core.ui.cgText.textList = core.plugin[data.textList] + core.doAction(); + }) + core.registerEvent("cgtext", function (data) { + if (!main.replayChecking && !core.isReplaying()) { + core.ui.cgText.image = data.bg; + core.ui.cgText.memory = data.memory; + core.ui.cgText.head = core.clone(data.head); + core.ui.cgText.index = data.index + core.ui.cgText.name = core.ui.cgText.textList[data.index][0]; + core.ui.cgText.text = data.text ? data.text : core.ui.cgText.textList[data.index][1]; + core.ui.cgText.time = data.time; + core.ui.cgText.wait = data.wait; + core.ui.cgText.WindowSkin = data.WindowSkin; + core.ui.cgText.sound = data.sound || ""; + core.ui.cgText.bodyList = core.clone(data.bodyList); + main.dom.cgText.style.display = "block"; + core.ui.cgText.update(); + } else { + core.doAction(); + } + }); + core.registerEvent("introAndLoop", function (data) { + if (!main.replayChecking && !core.isReplaying()) { + core.plugin.introAndLoop(data.intro, data.time, data.loop); + core.doAction(); + } else { + core.doAction(); + } + }); + core.registerEvent("setq", function (data) { + core.setFlag("任务地点", data.id); + + core.doAction(); + }); + core.registerEvent("playBgm", core.events._action_playBgm); + core.registerEvent("pauseBgm", core.events._action_pauseBgm); + core.registerEvent("resumeBgm", core.events._action_resumeBgm); + core.registerEvent("loadBgm", core.events._action_loadBgm); + core.registerEvent("playSound", core.events._action_playSound); + core.registerEvent("stopSound", core.events._action_stopSound); + core.registerEvent("setmusics", function (data) { + if ( + (core.getLocalStorage("musics") && + core.getLocalStorage("musics").length === 0) || + !core.getLocalStorage("musics") + ) + core.setLocalStorage("musics", ["theme.mp3"]); + let a = core.getLocalStorage("musics"); + if (!data.bgm) { + core.setLocalStorage("musics", ["theme.mp3"]); + } else { + if (!a.includes(data.bgm)) a.push(data.bgm); + core.setLocalStorage("musics", a); + } + core.doAction(); + }); + core.registerEvent("setcgs", function (data) { + if (!data.img) { + core.setLocalStorage("cgs", []); + } else { + let a = core.getLocalStorage("cgs") ?? []; + if (!a.includes(data.img)) a.push(data.img); + core.setLocalStorage("cgs", a); + } + core.doAction(); + }); + }; +}, "drawLight": function () { // 绘制灯光/漆黑层效果。调用方式 core.plugin.drawLight(...) // 【参数说明】 @@ -2528,1596 +2521,1779 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = })(); }, "statusBar": function () { - main.dom.floorMsgGroup.style.display = "none"; - main.dom.statusBar.style.display = "none"; - main.dom.toolBar.style.display = "none"; - //所有数据*3是为了实现高清画布 - const GAMEVIEW_WIDTH = 676 * 3; //横屏画面宽度 - const GAMEVIEW_HEIGHT = 416 * 3; //横屏画面高度 + main.dom.floorMsgGroup.style.display = "none"; + main.dom.statusBar.style.display = "none"; + main.dom.toolBar.style.display = "none"; + //所有数据*3是为了实现高清画布 + const GAMEVIEW_WIDTH = 676 * 3; //横屏画面宽度 + const GAMEVIEW_HEIGHT = 416 * 3; //横屏画面高度 - const GAMEVIEW_WIDTH_VERTICAL = 416 * 3; //竖屏画面宽度 - const GAMEVIEW_HEIGHT_VERTICAL = 676 * 3; //竖屏画面高度 + const GAMEVIEW_WIDTH_VERTICAL = 416 * 3; //竖屏画面宽度 + const GAMEVIEW_HEIGHT_VERTICAL = 676 * 3; //竖屏画面高度 - const BAR_WIDTH = 130 * 3; //横屏左侧额外距离(即边栏宽度) - const BAR_HEIGHT_VERTICAL = 130 * 3; //竖屏上侧额外距离(即边栏高度) - const BORDER_WIDTH = 0; //游戏画面左侧偏移距离 - const BORDER_HEIGHT = 0; //游戏画面上侧偏移距离 + const BAR_WIDTH = 130 * 3; //横屏左侧额外距离(即边栏宽度) + const BAR_HEIGHT_VERTICAL = 130 * 3; //竖屏上侧额外距离(即边栏高度) + const BORDER_WIDTH = 0; //游戏画面左侧偏移距离 + const BORDER_HEIGHT = 0; //游戏画面上侧偏移距离 - const ITEM_BOX_LEFT = 549 * 3; //横屏道具栏左侧距离(右侧边栏需增加BAR_WIDTH+GAMEVIEW_HEIGHT) - const ITEM_BOX_TOP = 155 * 3; //横屏道具栏上侧距离 - const ITEM_BOX_LEFT_VERTICAL = 160 * 3; //竖屏道具栏左侧距离 - const ITEM_BOX_TOP_VERTICAL = 549 * 3; //竖屏道具栏上侧距离(下侧边栏需增加BAR_HEIGHT_VERTICAL+GAMEVIEW_WIDTH_VERTICAL) + const ITEM_BOX_LEFT = 549 * 3; //横屏道具栏左侧距离(右侧边栏需增加BAR_WIDTH+GAMEVIEW_HEIGHT) + const ITEM_BOX_TOP = 155 * 3; //横屏道具栏上侧距离 + const ITEM_BOX_LEFT_VERTICAL = 160 * 3; //竖屏道具栏左侧距离 + const ITEM_BOX_TOP_VERTICAL = 549 * 3; //竖屏道具栏上侧距离(下侧边栏需增加BAR_HEIGHT_VERTICAL+GAMEVIEW_WIDTH_VERTICAL) - const EQUIP_BLOCK_LEFT = 549 * 3; //横屏装备栏左侧距离(右侧边栏需增加BAR_WIDTH+GAMEVIEW_HEIGHT) - const EQUIP_BLOCK_TOP = 10 * 3; //横屏装备栏上侧距离 - const EQUIP_BLOCK_LEFT_VERTICAL = 10 * 3; //竖屏装备栏左侧距离 - const EQUIP_BLOCK_TOP_VERTICAL = 549 * 3; //竖屏装备栏上侧距离(下侧边栏需增加BAR_HEIGHT_VERTICAL+GAMEVIEW_WIDTH_VERTICAL) + const EQUIP_BLOCK_LEFT = 549 * 3; //横屏装备栏左侧距离(右侧边栏需增加BAR_WIDTH+GAMEVIEW_HEIGHT) + const EQUIP_BLOCK_TOP = 10 * 3; //横屏装备栏上侧距离 + const EQUIP_BLOCK_LEFT_VERTICAL = 10 * 3; //竖屏装备栏左侧距离 + const EQUIP_BLOCK_TOP_VERTICAL = 549 * 3; //竖屏装备栏上侧距离(下侧边栏需增加BAR_HEIGHT_VERTICAL+GAMEVIEW_WIDTH_VERTICAL) - const MAP_BLOCK_LEFT = 551 * 3; //横屏小地图左侧距离(右侧边栏需增加BAR_WIDTH+GAMEVIEW_HEIGHT) - const MAP_BLOCK_TOP = 0; //横屏小地图上侧距离 - const MAP_BLOCK_LEFT_VERTICAL = 0; //竖屏小地图左侧距离 - const MAP_BLOCK_TOP_VERTICAL = 551 * 3; //竖屏小地图上侧距离(下侧边栏需增加BAR_HEIGHT_VERTICAL+GAMEVIEW_WIDTH_VERTICAL) + const MAP_BLOCK_LEFT = 551 * 3; //横屏小地图左侧距离(右侧边栏需增加BAR_WIDTH+GAMEVIEW_HEIGHT) + const MAP_BLOCK_TOP = 0; //横屏小地图上侧距离 + const MAP_BLOCK_LEFT_VERTICAL = 0; //竖屏小地图左侧距离 + const MAP_BLOCK_TOP_VERTICAL = 551 * 3; //竖屏小地图上侧距离(下侧边栏需增加BAR_HEIGHT_VERTICAL+GAMEVIEW_WIDTH_VERTICAL) - const KEY_BLOCK_LEFT = EQUIP_BLOCK_LEFT; //横屏钥匙栏左侧距离(右侧边栏需增加BAR_WIDTH+GAMEVIEW_HEIGHT) - const KEY_BLOCK_TOP = 110 * 3; //横屏钥匙栏上侧距离 - const KEY_BLOCK_LEFT_VERTICAL = 110 * 3; //竖屏钥匙栏左侧距离 - const KEY_BLOCK_TOP_VERTICAL = EQUIP_BLOCK_TOP_VERTICAL; //竖屏钥匙栏上侧距离(下侧边栏需增加BAR_HEIGHT_VERTICAL+GAMEVIEW_WIDTH_VERTICAL) + const KEY_BLOCK_LEFT = EQUIP_BLOCK_LEFT; //横屏钥匙栏左侧距离(右侧边栏需增加BAR_WIDTH+GAMEVIEW_HEIGHT) + const KEY_BLOCK_TOP = 110 * 3; //横屏钥匙栏上侧距离 + const KEY_BLOCK_LEFT_VERTICAL = 110 * 3; //竖屏钥匙栏左侧距离 + const KEY_BLOCK_TOP_VERTICAL = EQUIP_BLOCK_TOP_VERTICAL; //竖屏钥匙栏上侧距离(下侧边栏需增加BAR_HEIGHT_VERTICAL+GAMEVIEW_WIDTH_VERTICAL) - const INFO_BLOCK_LEFT = 10 * 3; //横屏道具说明左侧距离(右侧边栏需增加BAR_WIDTH+GAMEVIEW_HEIGHT) - const INFO_BLOCK_TOP = 180 * 3; //横屏道具说明上侧距离 - const INFO_BLOCK_LEFT_VERTICAL = 113 * 3; //竖屏道具说明左侧距离 - const INFO_BLOCK_TOP_VERTICAL = 8 * 3; //竖屏道具说明上侧距离(下侧边栏需增加BAR_HEIGHT_VERTICAL+GAMEVIEW_WIDTH_VERTICAL) + const INFO_BLOCK_LEFT = 10 * 3; //横屏道具说明左侧距离(右侧边栏需增加BAR_WIDTH+GAMEVIEW_HEIGHT) + const INFO_BLOCK_TOP = 180 * 3; //横屏道具说明上侧距离 + const INFO_BLOCK_LEFT_VERTICAL = 113 * 3; //竖屏道具说明左侧距离 + const INFO_BLOCK_TOP_VERTICAL = 8 * 3; //竖屏道具说明上侧距离(下侧边栏需增加BAR_HEIGHT_VERTICAL+GAMEVIEW_WIDTH_VERTICAL) - const TOOL_BOX_LEFT = EQUIP_BLOCK_LEFT; //横屏工具栏左侧距离(右侧边栏需增加BAR_WIDTH+GAMEVIEW_HEIGHT) - const TOOL_BOX_TOP = 348 * 3; //横屏工具栏上侧距离 - const TOOL_BOX_LEFT_VERTICAL = 348 * 3; //竖屏工具栏左侧距离 - const TOOL_BOX_TOP_VERTICAL = 549 * 3; //竖屏工具栏上侧距离(下侧边栏需增加BAR_HEIGHT_VERTICAL+GAMEVIEW_WIDTH_VERTICAL) + const TOOL_BOX_LEFT = EQUIP_BLOCK_LEFT; //横屏工具栏左侧距离(右侧边栏需增加BAR_WIDTH+GAMEVIEW_HEIGHT) + const TOOL_BOX_TOP = 348 * 3; //横屏工具栏上侧距离 + const TOOL_BOX_LEFT_VERTICAL = 348 * 3; //竖屏工具栏左侧距离 + const TOOL_BOX_TOP_VERTICAL = 549 * 3; //竖屏工具栏上侧距离(下侧边栏需增加BAR_HEIGHT_VERTICAL+GAMEVIEW_WIDTH_VERTICAL) - const TOOL_ICON_OUTER_SIZE = 34 * 3; + const TOOL_ICON_OUTER_SIZE = 34 * 3; - const TEXT_COLOR = "#FFFFFF"; //默认文字颜色 - const globalAlpha = 0.7; //默认底框透明度 - const FORCE_COUNTABLE_ITEMS = ["centerFly"]; //常态显示数量的非永久道具,如果道具不在此数组中,则只有道具多余1时显示数量 + const TEXT_COLOR = "#FFFFFF"; //默认文字颜色 + const globalAlpha = 0.7; //默认底框透明度 + const FORCE_COUNTABLE_ITEMS = ["centerFly"]; //常态显示数量的非永久道具,如果道具不在此数组中,则只有道具多余1时显示数量 - const outerBackground = document.createElement("canvas"); //背景画布设置 - let globalAlphafloor = 0, - globalAlphafloorStatus = 4; - outerBackground.style.position = "absolute"; - outerBackground.style.zIndex = 5; - outerBackground.id = "outerBackground"; - main.dom.outerBackground = outerBackground; - main.dom.startPanel.insertAdjacentElement("afterend", outerBackground); + const outerBackground = document.createElement("canvas"); //背景画布设置 + let globalAlphafloor = 0, + globalAlphafloorStatus = 4; + outerBackground.style.position = "absolute"; + outerBackground.style.zIndex = 5; + outerBackground.id = "outerBackground"; + main.dom.outerBackground = outerBackground; + main.dom.startPanel.insertAdjacentElement("afterend", outerBackground); - const outerUI = document.createElement("canvas"); //额外ui画布设置(状态栏所有绘制、点击都在额外ui上) - outerUI.style.position = "absolute"; - outerUI.style.zIndex = 165; - outerUI.id = "outerUI"; + const outerUI = document.createElement("canvas"); //额外ui画布设置(状态栏所有绘制、点击都在额外ui上) + outerUI.style.position = "absolute"; + outerUI.style.zIndex = 165; + outerUI.id = "outerUI"; - main.dom.outerUI = outerUI; - outerBackground.insertAdjacentElement("afterend", outerUI); - setTimeout(function () { - // Should be executed immediately after init() - main.canvas.outerUI = outerUI.getContext("2d"); - }); - outerUI.onclick = function (e) { - try { - e.preventDefault(); - if (!core.isPlaying()) return false; - const left = core.dom.gameGroup.offsetLeft; - const top = core.dom.gameGroup.offsetTop; - const px = Math.floor((e.clientX - left) / core.domStyle.scale), - py = Math.floor((e.clientY - top) / core.domStyle.scale); - core.ui.statusBar.onclick(px * 3, py * 3); - } catch (ee) { - main.log(ee); - } - }; + main.dom.outerUI = outerUI; + outerBackground.insertAdjacentElement("afterend", outerUI); + setTimeout(function () { + // Should be executed immediately after init() + main.canvas.outerUI = outerUI.getContext("2d"); + }); + outerUI.onclick = function (e) { + try { + e.preventDefault(); + if (!core.isPlaying()) return false; + const left = core.dom.gameGroup.offsetLeft; + const top = core.dom.gameGroup.offsetTop; + const px = Math.floor((e.clientX - left) / core.domStyle.scale), + py = Math.floor((e.clientY - top) / core.domStyle.scale); + core.ui.statusBar.onclick(px * 3, py * 3); + } catch (ee) { + main.log(ee); + } + }; - const _resize_gameGroup = function (obj) { - //游戏画面自适应调节 - const gameGroup = core.dom.gameGroup; - gameGroup.style.width = obj.totalWidth + "px"; - gameGroup.style.height = obj.totalHeight + "px"; - gameGroup.style.left = (obj.clientWidth - obj.totalWidth) / 2 + "px"; - gameGroup.style.top = (obj.clientHeight - obj.totalHeight) / 2 + "px"; - //floorMsgGroup为切换楼层中生效,显示时间可通过‘全塔属性’——‘切换楼层时间’或游戏内设置调整 - //显示内容为游戏名/版本号/楼层名 - // floorMsgGroup - var floorMsgGroup = core.dom.floorMsgGroup; - var globalAttribute = - core.status.globalAttribute || core.initStatus.globalAttribute; - floorMsgGroup.style = globalAttribute.floorChangingStyle; - floorMsgGroup.style.height = floorMsgGroup.style.width = - (GAMEVIEW_HEIGHT / 3) * core.domStyle.scale + "px"; - floorMsgGroup.style.fontSize = 16 * core.domStyle.scale + "px"; + const _resize_gameGroup = function (obj) { + //游戏画面自适应调节 + const gameGroup = core.dom.gameGroup; + gameGroup.style.width = obj.totalWidth + "px"; + gameGroup.style.height = obj.totalHeight + "px"; + gameGroup.style.left = (obj.clientWidth - obj.totalWidth) / 2 + "px"; + gameGroup.style.top = (obj.clientHeight - obj.totalHeight) / 2 + "px"; + //floorMsgGroup为切换楼层中生效,显示时间可通过‘全塔属性’——‘切换楼层时间’或游戏内设置调整 + //显示内容为游戏名/版本号/楼层名 + // floorMsgGroup + var floorMsgGroup = core.dom.floorMsgGroup; + var globalAttribute = + core.status.globalAttribute || core.initStatus.globalAttribute; + floorMsgGroup.style = globalAttribute.floorChangingStyle; + floorMsgGroup.style.height = floorMsgGroup.style.width = + (GAMEVIEW_HEIGHT / 3) * core.domStyle.scale + "px"; + floorMsgGroup.style.fontSize = 16 * core.domStyle.scale + "px"; - if (core.domStyle.isVertical) { - floorMsgGroup.style.left = "0px"; - floorMsgGroup.style.top = - ((GAMEVIEW_HEIGHT_VERTICAL / 3 - GAMEVIEW_WIDTH_VERTICAL / 3) * - core.domStyle.scale) / - 2 + - "px"; - } else { - floorMsgGroup.style.left = - ((GAMEVIEW_WIDTH / 3 - GAMEVIEW_HEIGHT / 3) * core.domStyle.scale) / - 2 + - "px"; - floorMsgGroup.style.top = "0px"; - } - core.dom.musicBtn.style.right = - (obj.clientWidth - obj.totalWidth) / 2 + "px"; - core.dom.musicBtn.style.bottom = - (obj.clientHeight - obj.totalHeight) / 2 - 27 + "px"; - let startBackground = core.domStyle.isVertical - ? main.styles.startVerticalBackground || main.styles.startBackground - : main.styles.startBackground; - if (main.dom.startBackground.getAttribute("__src__") != startBackground) { - main.dom.startBackground.setAttribute("__src__", startBackground); - main.dom.startBackground.src = startBackground; - } - const span = document - .getElementById("startButtons") - .getElementsByTagName("span"); - let font = (GAMEVIEW_WIDTH / 100) * core.domStyle.scale; - if (core.domStyle.isVertical) - font = ((GAMEVIEW_WIDTH_VERTICAL * 2) / 100) * core.domStyle.scale; + if (core.domStyle.isVertical) { + floorMsgGroup.style.left = "0px"; + floorMsgGroup.style.top = + ((GAMEVIEW_HEIGHT_VERTICAL / 3 - GAMEVIEW_WIDTH_VERTICAL / 3) * + core.domStyle.scale) / + 2 + + "px"; + } else { + floorMsgGroup.style.left = + ((GAMEVIEW_WIDTH / 3 - GAMEVIEW_HEIGHT / 3) * core.domStyle.scale) / + 2 + + "px"; + floorMsgGroup.style.top = "0px"; + } + core.dom.musicBtn.style.right = + (obj.clientWidth - obj.totalWidth) / 2 + "px"; + core.dom.musicBtn.style.bottom = + (obj.clientHeight - obj.totalHeight) / 2 - 27 + "px"; + let startBackground = core.domStyle.isVertical ? + main.styles.startVerticalBackground || main.styles.startBackground : + main.styles.startBackground; + if (main.dom.startBackground.getAttribute("__src__") != startBackground) { + main.dom.startBackground.setAttribute("__src__", startBackground); + main.dom.startBackground.src = startBackground; + } + const span = document + .getElementById("startButtons") + .getElementsByTagName("span"); + let font = (GAMEVIEW_WIDTH / 100) * core.domStyle.scale; + if (core.domStyle.isVertical) + font = ((GAMEVIEW_WIDTH_VERTICAL * 2) / 100) * core.domStyle.scale; - core.dom.playGame.style.fontSize = font + "px"; - core.dom.loadGame.style.fontSize = font + "px"; - core.dom.CGMode.style.fontSize = font + "px"; - core.dom.musicMode.style.fontSize = font + "px"; - core.dom.replayGame.style.fontSize = font + "px"; - core.dom.startButtonGroup.style.padding = font * 0.3 + "px 25px"; - }; - const _resize_canvas = function (obj) { - //自适应画布 - main.dom.outerBackground.style.width = obj.totalWidth + "px"; - main.dom.outerBackground.style.height = obj.totalHeight + "px"; - main.dom.outerUI.style.width = obj.totalWidth + "px"; - main.dom.outerUI.style.height = obj.totalHeight + "px"; - if (main.dom.CGUI) { - main.dom.CGUI.style.width = obj.totalWidth + 3 + "px"; - main.dom.CGUI.style.height = obj.totalHeight + 3 + "px"; - } - if (main.dom.music) { - main.dom.music.style.width = obj.totalWidth + 3 + "px"; - main.dom.music.style.height = obj.totalHeight + 3 + "px"; - } - if (main.dom.cgText) { - main.dom.cgText.style.width = obj.totalWidth + 3 + "px"; - main.dom.cgText.style.height = obj.totalHeight + 3 + "px"; - } - if (main.dom.over) { - main.dom.over.style.width = obj.totalWidth + 3 + "px"; - main.dom.over.style.height = obj.totalHeight + 3 + "px"; - } - if (main.dom.video) { - main.dom.video.style.width = obj.totalWidth + 3 + "px"; - main.dom.video.style.height = obj.totalHeight + 3 + "px"; - if (core.domStyle.isVertical) - main.dom.video.style.width = obj.totalHeight + 3 + "px"; - if (core.domStyle.isVertical) - main.dom.video.style.height = obj.totalWidth + 3 + "px"; - main.dom.video.style.top = "50%"; - main.dom.video.style.left = "50%"; + core.dom.playGame.style.fontSize = font + "px"; + core.dom.loadGame.style.fontSize = font + "px"; + core.dom.CGMode.style.fontSize = font + "px"; + core.dom.musicMode.style.fontSize = font + "px"; + core.dom.replayGame.style.fontSize = font + "px"; + core.dom.startButtonGroup.style.padding = font * 0.3 + "px 25px"; + }; + const _resize_canvas = function (obj) { + //自适应画布 + main.dom.outerBackground.style.width = obj.totalWidth + "px"; + main.dom.outerBackground.style.height = obj.totalHeight + "px"; + main.dom.outerUI.style.width = obj.totalWidth + "px"; + main.dom.outerUI.style.height = obj.totalHeight + "px"; + if (main.dom.CGUI) { + main.dom.CGUI.style.width = obj.totalWidth + 3 + "px"; + main.dom.CGUI.style.height = obj.totalHeight + 3 + "px"; + } + if (main.dom.music) { + main.dom.music.style.width = obj.totalWidth + 3 + "px"; + main.dom.music.style.height = obj.totalHeight + 3 + "px"; + } + if (main.dom.cgText) { + main.dom.cgText.style.width = obj.totalWidth + 3 + "px"; + main.dom.cgText.style.height = obj.totalHeight + 3 + "px"; + } + if (main.dom.logcanvas) { - main.dom.video.style.transform = "translate(-50%,-50%)"; + main.dom.logcanvas.style.width = obj.totalWidth + 3 + "px"; + main.dom.logcanvas.style.height = obj.totalHeight + 3 + "px"; + } + if (main.dom.over) { + main.dom.over.style.width = obj.totalWidth + 3 + "px"; + main.dom.over.style.height = obj.totalHeight + 3 + "px"; + } + if (main.dom.video) { + main.dom.video.style.width = obj.totalWidth + 3 + "px"; + main.dom.video.style.height = obj.totalHeight + 3 + "px"; + if (core.domStyle.isVertical) + main.dom.video.style.width = obj.totalHeight + 3 + "px"; + if (core.domStyle.isVertical) + main.dom.video.style.height = obj.totalWidth + 3 + "px"; + main.dom.video.style.top = "50%"; + main.dom.video.style.left = "50%"; - if (core.domStyle.isVertical) - main.dom.video.style.transform = "translate(-50%,-50%) rotate(90deg)"; - } - if (main.dom.video1) { - main.dom.video1.style.width = obj.totalWidth + 3 + "px"; - main.dom.video1.style.height = obj.totalHeight + 3 + "px"; - } + main.dom.video.style.transform = "translate(-50%,-50%)"; - const innerSize = obj.canvasWidth * core.domStyle.scale + "px"; - for (let i = 0; i < core.dom.gameCanvas.length; ++i) - core.dom.gameCanvas[i].style.width = core.dom.gameCanvas[ - i - ].style.height = innerSize; - core.dom.gif.style.width = core.dom.gif.style.height = innerSize; - core.dom.gif2.style.width = core.dom.gif2.style.height = innerSize; + if (core.domStyle.isVertical) + main.dom.video.style.transform = "translate(-50%,-50%) rotate(90deg)"; + } + if (main.dom.video1) { + main.dom.video1.style.width = obj.totalWidth + 3 + "px"; + main.dom.video1.style.height = obj.totalHeight + 3 + "px"; + } - core.dom.gameDraw.style.width = core.dom.gameDraw.style.height = - innerSize; - core.dom.gameDraw.style.top = - obj.gameDrawBox.top * core.domStyle.scale + "px"; - core.dom.gameDraw.style.left = - obj.gameDrawBox.left * core.domStyle.scale + "px"; - // resize bigmap - core.bigmap.canvas.forEach(function (cn) { - const ratio = core.canvas[cn].canvas.hasAttribute("isHD") - ? core.domStyle.ratio - : 1; - core.canvas[cn].canvas.style.width = - (innerSize / ratio) * core.domStyle.scale + "px"; - core.canvas[cn].canvas.style.height = - (innerSize / ratio) * core.domStyle.scale + "px"; - }); - // resize dynamic canvas - for (const name in core.dymCanvas) { - const ctx = core.dymCanvas[name], - canvas = ctx.canvas; - const ratio = canvas.hasAttribute("isHD") ? core.domStyle.ratio : 1; - canvas.style.width = (innerSize / ratio) * core.domStyle.scale + "px"; - canvas.style.height = (innerSize / ratio) * core.domStyle.scale + "px"; - canvas.style.left = - parseFloat(canvas.getAttribute("_left")) * core.domStyle.scale + "px"; - canvas.style.top = - parseFloat(canvas.getAttribute("_top")) * core.domStyle.scale + "px"; - } - // resize next - main.dom.next.style.width = main.dom.next.style.height = - 5 * core.domStyle.scale + "px"; - main.dom.next.style.borderBottomWidth = - main.dom.next.style.borderRightWidth = 4 * core.domStyle.scale + "px"; - }; - const bgctx = main.dom.outerBackground.getContext("2d"); - const uictx = main.dom.outerUI.getContext("2d"); - let now = 0; - core.registerAnimationFrame("lightFloor", true, function (timestamp) { - if (timestamp - now > 1000 / 60) { - now = timestamp; - globalAlphafloor += globalAlphafloorStatus; - if (globalAlphafloor === 100) globalAlphafloorStatus = -2; - if (globalAlphafloor === 0) globalAlphafloorStatus = 2; + const innerSize = obj.canvasWidth * core.domStyle.scale + "px"; + for (let i = 0; i < core.dom.gameCanvas.length; ++i) + core.dom.gameCanvas[i].style.width = core.dom.gameCanvas[ + i + ].style.height = innerSize; + core.dom.gif.style.width = core.dom.gif.style.height = innerSize; + core.dom.gif2.style.width = core.dom.gif2.style.height = innerSize; - if (core.domStyle.isVertical) { - core.clearMap( - uictx, - MAP_BLOCK_LEFT_VERTICAL, - MAP_BLOCK_TOP_VERTICAL, - 340, - 360 - ); - if (core.status.event.id === "viewMaps") { - core.ui.statusBar._update_map(core.status.event.data.floorId); - } else { - core.ui.statusBar._update_map(); - } + core.dom.gameDraw.style.width = core.dom.gameDraw.style.height = + innerSize; + core.dom.gameDraw.style.top = + obj.gameDrawBox.top * core.domStyle.scale + "px"; + core.dom.gameDraw.style.left = + obj.gameDrawBox.left * core.domStyle.scale + "px"; + // resize bigmap + core.bigmap.canvas.forEach(function (cn) { + const ratio = core.canvas[cn].canvas.hasAttribute("isHD") ? + core.domStyle.ratio : + 1; + core.canvas[cn].canvas.style.width = + (innerSize / ratio) * core.domStyle.scale + "px"; + core.canvas[cn].canvas.style.height = + (innerSize / ratio) * core.domStyle.scale + "px"; + }); + // resize dynamic canvas + for (const name in core.dymCanvas) { + const ctx = core.dymCanvas[name], + canvas = ctx.canvas; + const ratio = canvas.hasAttribute("isHD") ? core.domStyle.ratio : 1; + canvas.style.width = (innerSize / ratio) * core.domStyle.scale + "px"; + canvas.style.height = (innerSize / ratio) * core.domStyle.scale + "px"; + canvas.style.left = + parseFloat(canvas.getAttribute("_left")) * core.domStyle.scale + "px"; + canvas.style.top = + parseFloat(canvas.getAttribute("_top")) * core.domStyle.scale + "px"; + } + // resize next + main.dom.next.style.width = main.dom.next.style.height = + 5 * core.domStyle.scale + "px"; + main.dom.next.style.borderBottomWidth = + main.dom.next.style.borderRightWidth = 4 * core.domStyle.scale + "px"; + }; + const bgctx = main.dom.outerBackground.getContext("2d"); + const uictx = main.dom.outerUI.getContext("2d"); + let now = 0; + core.registerAnimationFrame("lightFloor", true, function (timestamp) { + if (timestamp - now > 1000 / 60) { + now = timestamp; + globalAlphafloor += globalAlphafloorStatus; + if (globalAlphafloor === 100) globalAlphafloorStatus = -2; + if (globalAlphafloor === 0) globalAlphafloorStatus = 2; - uictx.globalAlpha = globalAlphafloor / 100; - core.drawImage( - uictx, - "green.webp", - MAP_BLOCK_LEFT_VERTICAL + 135, - MAP_BLOCK_TOP_VERTICAL + 170 - ); - uictx.globalAlpha = 1; - } else { - core.clearMap(uictx, MAP_BLOCK_LEFT, MAP_BLOCK_TOP, 340, 360); - if (core.status.event.id === "viewMaps") { - core.ui.statusBar._update_map(core.status.event.data.floorId); - } else { - core.ui.statusBar._update_map(); - } - uictx.globalAlpha = globalAlphafloor / 100; - core.drawImage( - uictx, - "green.webp", - MAP_BLOCK_LEFT + 150, - MAP_BLOCK_TOP + 180 - ); - uictx.globalAlpha = 1; - } - } - }); + if (core.domStyle.isVertical) { + core.clearMap( + uictx, + MAP_BLOCK_LEFT_VERTICAL, + MAP_BLOCK_TOP_VERTICAL, + 340, + 360 + ); + if (core.status.event.id === "viewMaps") { + core.ui.statusBar._update_map(core.status.event.data.floorId); + } else { + core.ui.statusBar._update_map(); + } - core.control.resize = function () { - //自适应,可实现横竖屏切换 - if (main.mode == "editor") return; + uictx.globalAlpha = globalAlphafloor / 100; + core.drawImage( + uictx, + "green.webp", + MAP_BLOCK_LEFT_VERTICAL + 135, + MAP_BLOCK_TOP_VERTICAL + 170 + ); + uictx.globalAlpha = 1; + } else { + core.clearMap(uictx, MAP_BLOCK_LEFT, MAP_BLOCK_TOP, 340, 360); + if (core.status.event.id === "viewMaps") { + core.ui.statusBar._update_map(core.status.event.data.floorId); + } else { + core.ui.statusBar._update_map(); + } + uictx.globalAlpha = globalAlphafloor / 100; + core.drawImage( + uictx, + "green.webp", + MAP_BLOCK_LEFT + 150, + MAP_BLOCK_TOP + 180 + ); + uictx.globalAlpha = 1; + } + } + }); - const clientWidth = main.dom.body.clientWidth, - clientHeight = main.dom.body.clientHeight; - const canvasWidth = core.__PIXELS__; + core.control.resize = function () { + //自适应,可实现横竖屏切换 + if (main.mode == "editor") return; - const isVertical = clientHeight > clientWidth; - core.domStyle.isVertical = isVertical; + const clientWidth = main.dom.body.clientWidth, + clientHeight = main.dom.body.clientHeight; + const canvasWidth = core.__PIXELS__; - const totalWidth = isVertical - ? GAMEVIEW_WIDTH_VERTICAL / 3 - : GAMEVIEW_WIDTH / 3, - totalHeight = isVertical - ? GAMEVIEW_HEIGHT_VERTICAL / 3 - : GAMEVIEW_HEIGHT / 3; + const isVertical = clientHeight > clientWidth; + core.domStyle.isVertical = isVertical; - const maxRatio = Math.min( - clientWidth / totalWidth, - clientHeight / totalHeight - ); + const totalWidth = isVertical ? + GAMEVIEW_WIDTH_VERTICAL / 3 : + GAMEVIEW_WIDTH / 3, + totalHeight = isVertical ? + GAMEVIEW_HEIGHT_VERTICAL / 3 : + GAMEVIEW_HEIGHT / 3; - core.domStyle.availableScale = []; - [1, 1.25, 1.5, 1.75, 2].forEach(function (v) { - if (maxRatio >= v) { - core.domStyle.availableScale.push(v); - } - }); + const maxRatio = Math.min( + clientWidth / totalWidth, + clientHeight / totalHeight + ); - if (core.domStyle.availableScale.indexOf(core.domStyle.scale) < 0) { - core.domStyle.scale = Math.min(1, maxRatio); - } else if ( - core.getLocalStorage("scale") == null && - core.domStyle.availableScale.length >= 2 - ) { - core.domStyle.scale = - core.domStyle.availableScale[core.domStyle.availableScale.length - 2]; - core.setLocalStorage("scale", core.domStyle.scale); - } + core.domStyle.availableScale = []; + [1, 1.25, 1.5, 1.75, 2].forEach(function (v) { + if (maxRatio >= v) { + core.domStyle.availableScale.push(v); + } + }); - const totalWidthScaled = totalWidth * core.domStyle.scale, - totalHeightScaled = totalHeight * core.domStyle.scale; + if (core.domStyle.availableScale.indexOf(core.domStyle.scale) < 0) { + core.domStyle.scale = Math.min(1, maxRatio); + } else if ( + core.getLocalStorage("scale") == null && + core.domStyle.availableScale.length >= 2 + ) { + core.domStyle.scale = + core.domStyle.availableScale[core.domStyle.availableScale.length - 2]; + core.setLocalStorage("scale", core.domStyle.scale); + } - const gameDrawBox = isVertical - ? { - left: BORDER_WIDTH / 3, - top: BAR_HEIGHT_VERTICAL / 3 + BORDER_HEIGHT / 3, - } - : { left: BAR_WIDTH / 3 + BORDER_WIDTH / 3, top: BORDER_HEIGHT / 3 }; + const totalWidthScaled = totalWidth * core.domStyle.scale, + totalHeightScaled = totalHeight * core.domStyle.scale; - const obj = { - clientWidth: clientWidth, - clientHeight: clientHeight, - canvasWidth: canvasWidth, - totalWidth: totalWidthScaled, - totalHeight: totalHeightScaled, - gameDrawBox: gameDrawBox, - globalAttribute: - core.status.globalAttribute || core.initStatus.globalAttribute, - }; + const gameDrawBox = isVertical ? { + left: BORDER_WIDTH / 3, + top: BAR_HEIGHT_VERTICAL / 3 + BORDER_HEIGHT / 3, + } : { left: BAR_WIDTH / 3 + BORDER_WIDTH / 3, top: BORDER_HEIGHT / 3 }; - _resize_gameGroup(obj); - _resize_canvas(obj); + const obj = { + clientWidth: clientWidth, + clientHeight: clientHeight, + canvasWidth: canvasWidth, + totalWidth: totalWidthScaled, + totalHeight: totalHeightScaled, + gameDrawBox: gameDrawBox, + globalAttribute: core.status.globalAttribute || core.initStatus.globalAttribute, + }; - if (core.status.automaticRoute == null) core.status.automaticRoute = {}; - core.updateStatusBar(); - if (main.dom.CGUI && main.dom.CGUI.style.display === "block") - core.ui.CG.update(); - if (main.dom.music && main.dom.music.style.display === "block") - core.ui.music.update(); - if (main.dom.cgText && main.dom.cgText.style.display === "block") - core.ui.cgText.update(); - }; + _resize_gameGroup(obj); + _resize_canvas(obj); - class StatusBar { - constructor() { - //道具栏列表 - this.itemMx = [ - //空位用‘none’填充,当前ui至多4列6行 - ["book", "wand", "none", "fly"], - ["cross", "superPotion", "pickaxe"], - ["bomb", "centerFly", "upFly"], - ["none", "none", "none"], - ["downFly", "knife", "snow"], - ["bigKey", "earthquake", "coin"], - ]; - } - //初始化内容(工具栏/录像操作执行函数) - init() { - this.toolbarAction = [ - [ - main.core.openKeyBoard, - main.core.openQuickShop, - core.openToolbox, - core.doSL, - ], - [main.core.openSettings, main.core.save, main.core.load, core.doSL], - ]; - this.replayAction = [ - [core.triggerReplay, core.stopReplay, core.rewindReplay], - [core.speedDownReplay, core.speedUpReplay, core.saveReplay], - ]; - } - //更新 - update() { - this._update_background(); //更新背景 - this._update_props(); //更新属性 - //this._update_items(); //更新道具 - //this._update_equips(); //更新装备 - //this._update_keys(); //更新钥匙 - //this._update_infoWindow(); //更新道具说明 - this._update_toolBox(); //更新工具栏 - this._redrawMap(); - } - _redrawMap() { - if (core.domStyle.isVertical) { - core.clearMap( - uictx, - MAP_BLOCK_LEFT_VERTICAL, - MAP_BLOCK_TOP_VERTICAL, - 340, - 360 - ); - this._update_map(); - uictx.globalAlpha = globalAlphafloor / 100; - core.drawImage( - uictx, - "green.webp", - MAP_BLOCK_LEFT_VERTICAL + 125, - MAP_BLOCK_TOP_VERTICAL + 170 - ); - uictx.globalAlpha = 1; - } else { - core.clearMap(uictx, MAP_BLOCK_LEFT, MAP_BLOCK_TOP, 340, 360); - this._update_map(); - uictx.globalAlpha = globalAlphafloor / 100; - core.drawImage( - uictx, - "green.webp", - MAP_BLOCK_LEFT + 150, - MAP_BLOCK_TOP + 170 - ); - uictx.globalAlpha = 1; - } - } - //更新背景 - _update_background() { - if (core.domStyle.isVertical) { - bgctx.canvas.width = GAMEVIEW_WIDTH_VERTICAL; - bgctx.canvas.height = GAMEVIEW_HEIGHT_VERTICAL; - uictx.canvas.width = GAMEVIEW_WIDTH_VERTICAL; - uictx.canvas.height = GAMEVIEW_HEIGHT_VERTICAL; + if (core.status.automaticRoute == null) core.status.automaticRoute = {}; + core.updateStatusBar(); + if (main.dom.CGUI && main.dom.CGUI.style.display === "block") + core.ui.CG.update(); + if (main.dom.music && main.dom.music.style.display === "block") + core.ui.music.update(); + if (main.dom.cgText && main.dom.cgText.style.display === "block") + core.ui.cgText.update(); + if (main.dom.logcanvas && main.dom.logcanvas.style.display === "block") + core.ui.cgText.update(); + }; - const bg = core.material.images.images["status.webp"]; //竖屏背景(上) - bgctx.drawImage( - bg, - 0, - 0, - GAMEVIEW_WIDTH_VERTICAL, - BAR_HEIGHT_VERTICAL - ); - const bg2 = core.material.images.images["status.webp"]; //竖屏背景(下) - bgctx.drawImage( - bg2, - 0, - BAR_HEIGHT_VERTICAL + GAMEVIEW_WIDTH_VERTICAL, - GAMEVIEW_WIDTH_VERTICAL, - BAR_HEIGHT_VERTICAL - ); - bgctx.globalAlpha = globalAlpha; - bgctx.globalAlpha = 1; - core.setTextAlign("outerUI", "center"); - } else { - bgctx.canvas.width = GAMEVIEW_WIDTH; - bgctx.canvas.height = GAMEVIEW_HEIGHT; - uictx.canvas.width = GAMEVIEW_WIDTH; - uictx.canvas.height = GAMEVIEW_HEIGHT; + class StatusBar { + constructor() { + //道具栏列表 + this.itemMx = [ + //空位用‘none’填充,当前ui至多4列6行 + ["book", "wand", "none", "fly"], + ["cross", "superPotion", "pickaxe"], + ["bomb", "centerFly", "upFly"], + ["none", "none", "none"], + ["downFly", "knife", "snow"], + ["bigKey", "earthquake", "coin"], + ]; + } + //初始化内容(工具栏/录像操作执行函数) + init() { + this.toolbarAction = [ + [ + main.core.openKeyBoard, + main.core.openQuickShop, + core.openToolbox, + core.doSL, + ], + [main.core.openSettings, main.core.save, main.core.load, core.doSL], + ]; + this.replayAction = [ + [core.triggerReplay, core.stopReplay, core.rewindReplay], + [core.speedDownReplay, core.speedUpReplay, core.saveReplay], + ]; + } + //更新 + update() { + this._update_background(); //更新背景 + this._update_props(); //更新属性 + //this._update_items(); //更新道具 + //this._update_equips(); //更新装备 + //this._update_keys(); //更新钥匙 + //this._update_infoWindow(); //更新道具说明 + this._update_toolBox(); //更新工具栏 + this._redrawMap(); + } + _redrawMap() { + if (core.domStyle.isVertical) { + core.clearMap( + uictx, + MAP_BLOCK_LEFT_VERTICAL, + MAP_BLOCK_TOP_VERTICAL, + 340, + 360 + ); + this._update_map(); + uictx.globalAlpha = globalAlphafloor / 100; + core.drawImage( + uictx, + "green.webp", + MAP_BLOCK_LEFT_VERTICAL + 125, + MAP_BLOCK_TOP_VERTICAL + 170 + ); + uictx.globalAlpha = 1; + } else { + core.clearMap(uictx, MAP_BLOCK_LEFT, MAP_BLOCK_TOP, 340, 360); + this._update_map(); + uictx.globalAlpha = globalAlphafloor / 100; + core.drawImage( + uictx, + "green.webp", + MAP_BLOCK_LEFT + 150, + MAP_BLOCK_TOP + 170 + ); + uictx.globalAlpha = 1; + } + } + //更新背景 + _update_background() { + if (core.domStyle.isVertical) { + bgctx.canvas.width = GAMEVIEW_WIDTH_VERTICAL; + bgctx.canvas.height = GAMEVIEW_HEIGHT_VERTICAL; + uictx.canvas.width = GAMEVIEW_WIDTH_VERTICAL; + uictx.canvas.height = GAMEVIEW_HEIGHT_VERTICAL; - const bg = core.material.images.images["status.webp"]; //横屏背景(左) - bgctx.drawImage(bg, 0, 0, BAR_WIDTH, GAMEVIEW_HEIGHT); - const bg2 = core.material.images.images["status.webp"]; //横屏背景(右) - bgctx.drawImage( - bg2, - BAR_WIDTH + GAMEVIEW_HEIGHT, - 0, - BAR_WIDTH, - GAMEVIEW_HEIGHT - ); - bgctx.globalAlpha = globalAlpha; + const bg = core.material.images.images["status.webp"]; //竖屏背景(上) + bgctx.drawImage( + bg, + 0, + 0, + GAMEVIEW_WIDTH_VERTICAL, + BAR_HEIGHT_VERTICAL + ); + const bg2 = core.material.images.images["status.webp"]; //竖屏背景(下) + bgctx.drawImage( + bg2, + 0, + BAR_HEIGHT_VERTICAL + GAMEVIEW_WIDTH_VERTICAL, + GAMEVIEW_WIDTH_VERTICAL, + BAR_HEIGHT_VERTICAL + ); + bgctx.globalAlpha = globalAlpha; + bgctx.globalAlpha = 1; + core.setTextAlign("outerUI", "center"); + } else { + bgctx.canvas.width = GAMEVIEW_WIDTH; + bgctx.canvas.height = GAMEVIEW_HEIGHT; + uictx.canvas.width = GAMEVIEW_WIDTH; + uictx.canvas.height = GAMEVIEW_HEIGHT; - bgctx.globalAlpha = 1; - core.setTextAlign("outerUI", "center"); - } - } - // 更新属性 - _update_props(updatedFloorTitle) { - if (!updatedFloorTitle && core.status.floorId) { - updatedFloorTitle = core.status.maps[core.status.floorId].title; - } - const statusList = ["hp", "atk", "def", "money"]; //属性列表,图标在函数复写core.statusBar.icons中声明,数字为project\materials\icons.png中的图标序号(可使用便捷ps追加,第一个序号为0) - const drawStatusList = (baseX, baseY) => { - let curh = baseY; - core.setTextAlign("outerUI", "right"); - statusList.forEach((item) => { - // 绘制图标 - core.drawIcon( - "outerUI", - item, - baseX - 95 * 3, - curh - 18 * 3, - 22 * 3, - 22 * 3 - ); + const bg = core.material.images.images["status.webp"]; //横屏背景(左) + bgctx.drawImage(bg, 0, 0, BAR_WIDTH, GAMEVIEW_HEIGHT); + const bg2 = core.material.images.images["status.webp"]; //横屏背景(右) + bgctx.drawImage( + bg2, + BAR_WIDTH + GAMEVIEW_HEIGHT, + 0, + BAR_WIDTH, + GAMEVIEW_HEIGHT + ); + bgctx.globalAlpha = globalAlpha; - // 四舍五入 - core.status.hero[item] = Math.round(core.status.hero[item]); - // 大数据格式化 - core.fillBoldText1( - "outerUI", - core.getRealStatus(item), - baseX, - curh, - TEXT_COLOR, - "#000000", - 6 - ); - curh += 24 * 3; - if (curh > 130 * 3 && core.domStyle.isVertical) { - curh = 24 * 3; - baseX += 105 * 3; - } - }); - core.setTextAlign("outerUI", "center"); - }; - if (core.domStyle.isVertical) { - core.clearMap("outerUI", 10 * 3, 0, 210 * 3, 120 * 3); - core.setFont("outerUI", "bold 42px Verdana"); - if (updatedFloorTitle) { - core.fillBoldText1( - "outerUI", - updatedFloorTitle, - 60 * 3, - 22 * 3, - TEXT_COLOR, - "#000000", - 6 - ); - } - //drawStatusList(96 * 3, 46 * 3); - //core.drawImage("outerUI", "lane1.png", 0, 0) - core.drawImage("outerUI", "cao.webp", 0, 0); - } else { - core.clearMap("outerUI", 10 * 3, 40 * 3, 105 * 3, 250 * 3); - core.setFont("outerUI", "bold 48px Verdana"); - if (updatedFloorTitle) { - core.fillBoldText1( - "outerUI", - updatedFloorTitle, - 62 * 3, - 41 * 3, - TEXT_COLOR, - "#000000", - 6 - ); - } - //drawStatusList(110 * 3, 93 * 3); - //core.drawImage("outerUI", "lane1.png", 0, 30) - core.drawImage( - "outerUI", - "cao.webp", - 0, - 0, - 400, - 350, - 0, - 30, - 360, - 315 - ); - } - } - _update_items() { - //更新道具栏 - const drawItemMx = (drawFn) => { - for (let i = 0; i < this.itemMx.length; i++) { - for (let j = 0; j < this.itemMx[i].length; j++) { - var item = this.itemMx[i][j]; - drawFn(i, j, item); - } - } - }; - const drawItem = (item, posx, posy) => { - const icon = core.material.icons.items[item], - image = core.material.images.items; - core.drawImage( - "outerUI", - image, - 0, - 32 * icon, - 32, - 32, - posx, - posy, - 30 * 3, - 30 * 3 - ); - const cnt = core.itemCount(item); - if ( - (core.items.items[item].cls === "tools" && cnt > 1) || - FORCE_COUNTABLE_ITEMS.includes(item) - ) { - core.fillText( - "outerUI", - cnt, - posx + 25 * 3, - posy + 28 * 3, - "#FFFFFF", - "bold 36px Verdana" - ); - } - }; - if (core.domStyle.isVertical) { - core.clearMap( - "outerUI", - ITEM_BOX_LEFT_VERTICAL, - ITEM_BOX_TOP_VERTICAL, - 185 * 3, - 125 * 3 - ); + bgctx.globalAlpha = 1; + core.setTextAlign("outerUI", "center"); + } + } + // 更新属性 + _update_props(updatedFloorTitle) { + if (!updatedFloorTitle && core.status.floorId) { + updatedFloorTitle = core.status.maps[core.status.floorId].title; + } + const statusList = ["hp", "atk", "def", "money"]; //属性列表,图标在函数复写core.statusBar.icons中声明,数字为project\materials\icons.png中的图标序号(可使用便捷ps追加,第一个序号为0) + const drawStatusList = (baseX, baseY) => { + let curh = baseY; + core.setTextAlign("outerUI", "right"); + statusList.forEach((item) => { + // 绘制图标 + core.drawIcon( + "outerUI", + item, + baseX - 95 * 3, + curh - 18 * 3, + 22 * 3, + 22 * 3 + ); - drawItemMx((i, j, item) => { - if (core.hasItem(item)) { - const posx = ITEM_BOX_LEFT_VERTICAL + i * 30 * 3, - posy = ITEM_BOX_TOP_VERTICAL + j * 31 * 3; - drawItem(item, posx, posy); - } - }); - } else { - core.clearMap( - "outerUI", - ITEM_BOX_LEFT, - ITEM_BOX_TOP, - 125 * 3, - 185 * 3 - ); + // 四舍五入 + core.status.hero[item] = Math.round(core.status.hero[item]); + // 大数据格式化 + core.fillBoldText1( + "outerUI", + core.getRealStatus(item), + baseX, + curh, + TEXT_COLOR, + "#000000", + 6 + ); + curh += 24 * 3; + if (curh > 130 * 3 && core.domStyle.isVertical) { + curh = 24 * 3; + baseX += 105 * 3; + } + }); + core.setTextAlign("outerUI", "center"); + }; + if (core.domStyle.isVertical) { + core.clearMap("outerUI", 10 * 3, 0, 210 * 3, 120 * 3); + core.setFont("outerUI", "bold 42px Verdana"); + if (updatedFloorTitle) { + core.fillBoldText1( + "outerUI", + updatedFloorTitle, + 60 * 3, + 22 * 3, + TEXT_COLOR, + "#000000", + 6 + ); + } + //drawStatusList(96 * 3, 46 * 3); + //core.drawImage("outerUI", "lane1.png", 0, 0) + core.drawImage("outerUI", "cao.webp", 0, 0); + } else { + core.clearMap("outerUI", 10 * 3, 40 * 3, 105 * 3, 250 * 3); + core.setFont("outerUI", "bold 48px Verdana"); + if (updatedFloorTitle) { + core.fillBoldText1( + "outerUI", + updatedFloorTitle, + 62 * 3, + 41 * 3, + TEXT_COLOR, + "#000000", + 6 + ); + } + //drawStatusList(110 * 3, 93 * 3); + //core.drawImage("outerUI", "lane1.png", 0, 30) + core.drawImage( + "outerUI", + "cao.webp", + 0, + 0, + 400, + 350, + 0, + 30, + 360, + 315 + ); + } + } + _update_items() { + //更新道具栏 + const drawItemMx = (drawFn) => { + for (let i = 0; i < this.itemMx.length; i++) { + for (let j = 0; j < this.itemMx[i].length; j++) { + var item = this.itemMx[i][j]; + drawFn(i, j, item); + } + } + }; + const drawItem = (item, posx, posy) => { + const icon = core.material.icons.items[item], + image = core.material.images.items; + core.drawImage( + "outerUI", + image, + 0, + 32 * icon, + 32, + 32, + posx, + posy, + 30 * 3, + 30 * 3 + ); + const cnt = core.itemCount(item); + if ( + (core.items.items[item].cls === "tools" && cnt > 1) || + FORCE_COUNTABLE_ITEMS.includes(item) + ) { + core.fillText( + "outerUI", + cnt, + posx + 25 * 3, + posy + 28 * 3, + "#FFFFFF", + "bold 36px Verdana" + ); + } + }; + if (core.domStyle.isVertical) { + core.clearMap( + "outerUI", + ITEM_BOX_LEFT_VERTICAL, + ITEM_BOX_TOP_VERTICAL, + 185 * 3, + 125 * 3 + ); - drawItemMx((i, j, item) => { - if (core.hasItem(item)) { - const posx = ITEM_BOX_LEFT + j * 30 * 3, - posy = ITEM_BOX_TOP + i * 31 * 3; - drawItem(item, posx, posy); - } - }); - } - } + drawItemMx((i, j, item) => { + if (core.hasItem(item)) { + const posx = ITEM_BOX_LEFT_VERTICAL + i * 30 * 3, + posy = ITEM_BOX_TOP_VERTICAL + j * 31 * 3; + drawItem(item, posx, posy); + } + }); + } else { + core.clearMap( + "outerUI", + ITEM_BOX_LEFT, + ITEM_BOX_TOP, + 125 * 3, + 185 * 3 + ); - _update_map(floorId = core.status.floorId) { - const x = core.domStyle.isVertical - ? MAP_BLOCK_LEFT_VERTICAL - : MAP_BLOCK_LEFT; - const y = core.domStyle.isVertical - ? MAP_BLOCK_TOP_VERTICAL - : MAP_BLOCK_TOP; + drawItemMx((i, j, item) => { + if (core.hasItem(item)) { + const posx = ITEM_BOX_LEFT + j * 30 * 3, + posy = ITEM_BOX_TOP + i * 31 * 3; + drawItem(item, posx, posy); + } + }); + } + } - if (!floorId) return; - const info = core.plugin.getMapDrawInfo(floorId, Infinity, true); - core.setTextAlign("outerUI", "center"); + _update_map(floorId = core.status.floorId) { + const x = core.domStyle.isVertical ? + MAP_BLOCK_LEFT_VERTICAL : + MAP_BLOCK_LEFT; + const y = core.domStyle.isVertical ? + MAP_BLOCK_TOP_VERTICAL : + MAP_BLOCK_TOP; - core.plugin.drawSmallMap(uictx, info, floorId, x, y, 300, 300); - } + if (!floorId) return; + const info = core.plugin.getMapDrawInfo(floorId, Infinity, true); + core.setTextAlign("outerUI", "center"); - _update_equips() { - return; - core.setFont("outerUI", "bold 48px Verdana"); - const drawEquip = (baseX, baseY, id, color, back) => { - if (!id) - core.fillText( - "outerUI", - back, - baseX + 20 * 3, - baseY + 22 * 3, - color - ); - else { - var icon = core.material.icons.items[id]; - core.drawImage( - "outerUI", - core.material.images.items, - 0, - 32 * icon, - 32, - 32, - baseX + 5 * 3, - baseY, - 32 * 3, - 32 * 3 - ); - } - }; - if (core.domStyle.isVertical) { - core.clearMap( - "outerUI", - EQUIP_BLOCK_LEFT_VERTICAL, - EQUIP_BLOCK_TOP_VERTICAL, - 90 * 3, - 130 * 3 - ); - drawEquip( - EQUIP_BLOCK_LEFT_VERTICAL, - EQUIP_BLOCK_TOP_VERTICAL, - core.getEquip(0), - "#D1CEFF", - "无" - ); - drawEquip( - EQUIP_BLOCK_LEFT_VERTICAL + 45 * 3, - EQUIP_BLOCK_TOP_VERTICAL, - core.getEquip(1), - "#D1CEFF", - "无" - ); - drawEquip( - EQUIP_BLOCK_LEFT_VERTICAL, - EQUIP_BLOCK_TOP_VERTICAL + 45 * 3, - core.getEquip(2), - "#D1CEFF", - "无" - ); - drawEquip( - EQUIP_BLOCK_LEFT_VERTICAL + 45 * 3, - EQUIP_BLOCK_TOP_VERTICAL + 45 * 3, - core.getEquip(3), - "#D1CEFF", - "无" - ); - drawEquip( - EQUIP_BLOCK_LEFT_VERTICAL, - EQUIP_BLOCK_TOP_VERTICAL + 90 * 3, - core.getEquip(4), - "#D1CEFF", - "无" - ); - drawEquip( - EQUIP_BLOCK_LEFT_VERTICAL + 45 * 3, - EQUIP_BLOCK_TOP_VERTICAL + 90 * 3, - core.getEquip(5), - "#D1CEFF", - "无" - ); - } else { - core.clearMap( - "outerUI", - EQUIP_BLOCK_LEFT, - EQUIP_BLOCK_TOP, - 130 * 3, - 95 * 3 - ); - drawEquip( - EQUIP_BLOCK_LEFT, - EQUIP_BLOCK_TOP, - core.getEquip(0), - "#D1CEFF", - "无" - ); - drawEquip( - EQUIP_BLOCK_LEFT + 42 * 3, - EQUIP_BLOCK_TOP, - core.getEquip(1), - "#D1CEFF", - "无" - ); - drawEquip( - EQUIP_BLOCK_LEFT + 85 * 3, - EQUIP_BLOCK_TOP, - core.getEquip(2), - "#D1CEFF", - "无" - ); - drawEquip( - EQUIP_BLOCK_LEFT, - EQUIP_BLOCK_TOP + 45 * 3, - core.getEquip(3), - "#D1CEFF", - "无" - ); - drawEquip( - EQUIP_BLOCK_LEFT + 42 * 3, - EQUIP_BLOCK_TOP + 45 * 3, - core.getEquip(4), - "#D1CEFF", - "无" - ); - drawEquip( - EQUIP_BLOCK_LEFT + 85 * 3, - EQUIP_BLOCK_TOP + 45 * 3, - core.getEquip(5), - "#D1CEFF", - "无" - ); - } - } - _update_keys() { - const drawKeyList = (baseX, baseY) => { - const todraw = [], - keyList = ["yellowKey", "blueKey", "redKey", "greenKey"]; - let total = 0; - keyList.forEach(function (key, i) { - todraw[i] = core.itemCount(key); - total += todraw[i]; - }); + core.plugin.drawSmallMap(uictx, info, floorId, x, y, 300, 300); + } - let dn = 3; - for (let i = 0; i <= dn; i++) { - let delta = i * 32 * 3; + _update_equips() { + return; + core.setFont("outerUI", "bold 48px Verdana"); + const drawEquip = (baseX, baseY, id, color, back) => { + if (!id) + core.fillText( + "outerUI", + back, + baseX + 20 * 3, + baseY + 22 * 3, + color + ); + else { + var icon = core.material.icons.items[id]; + core.drawImage( + "outerUI", + core.material.images.items, + 0, + 32 * icon, + 32, + 32, + baseX + 5 * 3, + baseY, + 32 * 3, + 32 * 3 + ); + } + }; + if (core.domStyle.isVertical) { + core.clearMap( + "outerUI", + EQUIP_BLOCK_LEFT_VERTICAL, + EQUIP_BLOCK_TOP_VERTICAL, + 90 * 3, + 130 * 3 + ); + drawEquip( + EQUIP_BLOCK_LEFT_VERTICAL, + EQUIP_BLOCK_TOP_VERTICAL, + core.getEquip(0), + "#D1CEFF", + "无" + ); + drawEquip( + EQUIP_BLOCK_LEFT_VERTICAL + 45 * 3, + EQUIP_BLOCK_TOP_VERTICAL, + core.getEquip(1), + "#D1CEFF", + "无" + ); + drawEquip( + EQUIP_BLOCK_LEFT_VERTICAL, + EQUIP_BLOCK_TOP_VERTICAL + 45 * 3, + core.getEquip(2), + "#D1CEFF", + "无" + ); + drawEquip( + EQUIP_BLOCK_LEFT_VERTICAL + 45 * 3, + EQUIP_BLOCK_TOP_VERTICAL + 45 * 3, + core.getEquip(3), + "#D1CEFF", + "无" + ); + drawEquip( + EQUIP_BLOCK_LEFT_VERTICAL, + EQUIP_BLOCK_TOP_VERTICAL + 90 * 3, + core.getEquip(4), + "#D1CEFF", + "无" + ); + drawEquip( + EQUIP_BLOCK_LEFT_VERTICAL + 45 * 3, + EQUIP_BLOCK_TOP_VERTICAL + 90 * 3, + core.getEquip(5), + "#D1CEFF", + "无" + ); + } else { + core.clearMap( + "outerUI", + EQUIP_BLOCK_LEFT, + EQUIP_BLOCK_TOP, + 130 * 3, + 95 * 3 + ); + drawEquip( + EQUIP_BLOCK_LEFT, + EQUIP_BLOCK_TOP, + core.getEquip(0), + "#D1CEFF", + "无" + ); + drawEquip( + EQUIP_BLOCK_LEFT + 42 * 3, + EQUIP_BLOCK_TOP, + core.getEquip(1), + "#D1CEFF", + "无" + ); + drawEquip( + EQUIP_BLOCK_LEFT + 85 * 3, + EQUIP_BLOCK_TOP, + core.getEquip(2), + "#D1CEFF", + "无" + ); + drawEquip( + EQUIP_BLOCK_LEFT, + EQUIP_BLOCK_TOP + 45 * 3, + core.getEquip(3), + "#D1CEFF", + "无" + ); + drawEquip( + EQUIP_BLOCK_LEFT + 42 * 3, + EQUIP_BLOCK_TOP + 45 * 3, + core.getEquip(4), + "#D1CEFF", + "无" + ); + drawEquip( + EQUIP_BLOCK_LEFT + 85 * 3, + EQUIP_BLOCK_TOP + 45 * 3, + core.getEquip(5), + "#D1CEFF", + "无" + ); + } + } + _update_keys() { + const drawKeyList = (baseX, baseY) => { + const todraw = [], + keyList = ["yellowKey", "blueKey", "redKey", "greenKey"]; + let total = 0; + keyList.forEach(function (key, i) { + todraw[i] = core.itemCount(key); + total += todraw[i]; + }); - if (core.domStyle.isVertical) { - this.drawKey(keyList[i], baseX, baseY + delta); - } else { - this.drawKey(keyList[i], baseX + delta, baseY); - } + let dn = 3; + for (let i = 0; i <= dn; i++) { + let delta = i * 32 * 3; - core.setFont("outerUI", "bold 48px Verdana"); - core.setTextAlign("outerUI", "left"); - if (core.domStyle.isVertical) { - core.fillText( - "outerUI", - todraw[i], - baseX + 20 * 3, - baseY + 14 * 3 + delta, - TEXT_COLOR - ); - } else { - core.fillText( - "outerUI", - todraw[i], - baseX + delta, - baseY + 32 * 3, - TEXT_COLOR - ); - } - } - }; - if (core.domStyle.isVertical) { - core.clearMap( - "outerUI", - KEY_BLOCK_LEFT_VERTICAL, - KEY_BLOCK_TOP_VERTICAL, - 45 * 3, - 130 * 3 - ); - drawKeyList( - KEY_BLOCK_LEFT_VERTICAL + 3 * 3, - KEY_BLOCK_TOP_VERTICAL + 5 * 3 - ); - } else { - core.clearMap( - "outerUI", - KEY_BLOCK_LEFT, - KEY_BLOCK_TOP, - 130 * 3, - 45 * 3 - ); - drawKeyList(KEY_BLOCK_LEFT + 10 * 3, KEY_BLOCK_TOP); - } - } - drawKey(key, x, y) { - let sx = 0, - sy = 0; + if (core.domStyle.isVertical) { + this.drawKey(keyList[i], baseX, baseY + delta); + } else { + this.drawKey(keyList[i], baseX + delta, baseY); + } - if (key == "yellowKey") sx += 13; - else if (key == "blueKey") sx += 26; - else if (key == "greenKey") sx += 39; + core.setFont("outerUI", "bold 48px Verdana"); + core.setTextAlign("outerUI", "left"); + if (core.domStyle.isVertical) { + core.fillText( + "outerUI", + todraw[i], + baseX + 20 * 3, + baseY + 14 * 3 + delta, + TEXT_COLOR + ); + } else { + core.fillText( + "outerUI", + todraw[i], + baseX + delta, + baseY + 32 * 3, + TEXT_COLOR + ); + } + } + }; + if (core.domStyle.isVertical) { + core.clearMap( + "outerUI", + KEY_BLOCK_LEFT_VERTICAL, + KEY_BLOCK_TOP_VERTICAL, + 45 * 3, + 130 * 3 + ); + drawKeyList( + KEY_BLOCK_LEFT_VERTICAL + 3 * 3, + KEY_BLOCK_TOP_VERTICAL + 5 * 3 + ); + } else { + core.clearMap( + "outerUI", + KEY_BLOCK_LEFT, + KEY_BLOCK_TOP, + 130 * 3, + 45 * 3 + ); + drawKeyList(KEY_BLOCK_LEFT + 10 * 3, KEY_BLOCK_TOP); + } + } + drawKey(key, x, y) { + let sx = 0, + sy = 0; - core.drawImage( - "outerUI", - "maba.webp", - sx, - sy, - 13, - 26, - x, - y, - 13 * 3, - 26 * 3 - ); - } - _update_infoWindow() { - const itemId = this.selectedItem; - let text = ""; - if (this.selectedItem) { - text = core.replaceText(core.material.items[itemId]?.text); - if (text[0] == "," || text[0] == ",") text = text.substring(1); - } - if (core.domStyle.isVertical) { - core.clearMap( - "outerUI", - INFO_BLOCK_LEFT_VERTICAL, - INFO_BLOCK_TOP_VERTICAL, - 300 * 3, - 120 * 3 - ); + if (key == "yellowKey") sx += 13; + else if (key == "blueKey") sx += 26; + else if (key == "greenKey") sx += 39; - if (this.selectedItem) { - const icon = core.material.icons.items[itemId]; - core.setTextAlign("outerUI", "left"); - core.fillText( - "outerUI", - core.material.items[itemId].name, - INFO_BLOCK_LEFT_VERTICAL + 50 * 3, - INFO_BLOCK_TOP_VERTICAL + 27 * 3, - "#D1CEFF" - ); - core.drawImage( - "outerUI", - core.material.images.items, - 0, - 32 * icon, - 32, - 32, - INFO_BLOCK_LEFT_VERTICAL + 10 * 3, - INFO_BLOCK_TOP_VERTICAL + 8 * 3, - 32 * 3, - 32 * 3 - ); - core.ui.drawTextContent("outerUI", text, { - left: INFO_BLOCK_LEFT_VERTICAL + 10 * 3, - top: INFO_BLOCK_TOP_VERTICAL + 40 * 3, - maxWidth: 275 * 3, - color: "#D1CEFF", - fontSize: 36, - }); - } - } else { - core.clearMap( - "outerUI", - INFO_BLOCK_LEFT, - INFO_BLOCK_TOP, - 115 * 3, - 230 * 3 - ); + core.drawImage( + "outerUI", + "maba.webp", + sx, + sy, + 13, + 26, + x, + y, + 13 * 3, + 26 * 3 + ); + } + _update_infoWindow() { + const itemId = this.selectedItem; + let text = ""; + if (this.selectedItem) { + text = core.replaceText(core.material.items[itemId]?.text); + if (text[0] == "," || text[0] == ",") text = text.substring(1); + } + if (core.domStyle.isVertical) { + core.clearMap( + "outerUI", + INFO_BLOCK_LEFT_VERTICAL, + INFO_BLOCK_TOP_VERTICAL, + 300 * 3, + 120 * 3 + ); - if (this.selectedItem) { - const icon = core.material.icons.items[itemId]; - core.setTextAlign("outerUI", "center"); - core.fillText( - "outerUI", - core.material.items[itemId].name, - INFO_BLOCK_LEFT + 60 * 3, - INFO_BLOCK_TOP + 25 * 3, - "#D1CEFF" - ); - core.drawImage( - "outerUI", - core.material.images.items, - 0, - 32 * icon, - 32, - 32, - INFO_BLOCK_LEFT + 45 * 3, - INFO_BLOCK_TOP + 30 * 3, - 32 * 3, - 32 * 3 - ); - core.ui.drawTextContent("outerUI", text, { - left: INFO_BLOCK_LEFT + 10 * 3, - top: INFO_BLOCK_TOP + 60 * 3, - maxWidth: 105 * 3, - color: "#D1CEFF", - fontSize: 36, - }); - } - } - } - showItemInfo(itemId) { - //展示道具说明 - this.selectedItem = itemId; - this._update_infoWindow(); - } - clearItemInfo() { - //清除道具说明 - this.selectedItem = null; - this._update_infoWindow(); - } - _update_toolBox() { - const tools = core.isReplaying() - ? [ - [core.status.replay.pausing ? "play" : "pause", "stop", "rewind"], - ["speedDown", "speedUp", "save"], - ] - : [ - ["keyboard", "shop", "pack", "T332"], - ["settings", "save", "load", "T331"], - ]; - if (core.domStyle.isVertical) { - core.clearMap( - "outerUI", - TOOL_BOX_LEFT_VERTICAL, - TOOL_BOX_TOP_VERTICAL, - 115, - 130 - ); + if (this.selectedItem) { + const icon = core.material.icons.items[itemId]; + core.setTextAlign("outerUI", "left"); + core.fillText( + "outerUI", + core.material.items[itemId].name, + INFO_BLOCK_LEFT_VERTICAL + 50 * 3, + INFO_BLOCK_TOP_VERTICAL + 27 * 3, + "#D1CEFF" + ); + core.drawImage( + "outerUI", + core.material.images.items, + 0, + 32 * icon, + 32, + 32, + INFO_BLOCK_LEFT_VERTICAL + 10 * 3, + INFO_BLOCK_TOP_VERTICAL + 8 * 3, + 32 * 3, + 32 * 3 + ); + core.ui.drawTextContent("outerUI", text, { + left: INFO_BLOCK_LEFT_VERTICAL + 10 * 3, + top: INFO_BLOCK_TOP_VERTICAL + 40 * 3, + maxWidth: 275 * 3, + color: "#D1CEFF", + fontSize: 36, + }); + } + } else { + core.clearMap( + "outerUI", + INFO_BLOCK_LEFT, + INFO_BLOCK_TOP, + 115 * 3, + 230 * 3 + ); - for (let i = 0; i < tools.length; i++) { - for (let j = 0; j < tools[i].length; j++) { - core.drawIcon( - "outerUI", - tools[i][j], - TOOL_BOX_LEFT_VERTICAL + i * 31 * 3, - TOOL_BOX_TOP_VERTICAL + j * 31 * 3, - 30 * 3, - 30 * 3 - ); - } - } - } else { - core.clearMap( - "outerUI", - TOOL_BOX_LEFT, - TOOL_BOX_TOP, - 130 * 3, - 80 * 3 - ); + if (this.selectedItem) { + const icon = core.material.icons.items[itemId]; + core.setTextAlign("outerUI", "center"); + core.fillText( + "outerUI", + core.material.items[itemId].name, + INFO_BLOCK_LEFT + 60 * 3, + INFO_BLOCK_TOP + 25 * 3, + "#D1CEFF" + ); + core.drawImage( + "outerUI", + core.material.images.items, + 0, + 32 * icon, + 32, + 32, + INFO_BLOCK_LEFT + 45 * 3, + INFO_BLOCK_TOP + 30 * 3, + 32 * 3, + 32 * 3 + ); + core.ui.drawTextContent("outerUI", text, { + left: INFO_BLOCK_LEFT + 10 * 3, + top: INFO_BLOCK_TOP + 60 * 3, + maxWidth: 105 * 3, + color: "#D1CEFF", + fontSize: 36, + }); + } + } + } + showItemInfo(itemId) { + //展示道具说明 + this.selectedItem = itemId; + this._update_infoWindow(); + } + clearItemInfo() { + //清除道具说明 + this.selectedItem = null; + this._update_infoWindow(); + } + _update_toolBox() { + const tools = core.isReplaying() ? [ + [core.status.replay.pausing ? "play" : "pause", "stop", "rewind"], + ["speedDown", "speedUp", "save"], + ] : [ + ["keyboard", "shop", "pack", "T332"], + ["settings", "save", "load", "T331"], + ]; + if (core.domStyle.isVertical) { + core.clearMap( + "outerUI", + TOOL_BOX_LEFT_VERTICAL, + TOOL_BOX_TOP_VERTICAL, + 115, + 130 + ); - for (let i = 0; i < tools.length; i++) { - for (let j = 0; j < tools[i].length; j++) { - core.drawIcon( - "outerUI", - tools[i][j], - TOOL_BOX_LEFT + j * 31 * 3, - TOOL_BOX_TOP + i * 31 * 3, - 30 * 3, - 30 * 3 - ); - } - } - } - } - onclick(x, y) { - const makeBox = ([x, y], [w, h]) => { - return [ - [x, y], - [x + w, y + h], - ]; - }; - const gridify = ([x, y], [gw, gh]) => { - return [Math.floor(x / gw), Math.floor(y / gh)]; - }; - const useItem = (itemId) => { - if (!core.hasItem(itemId)) return; + for (let i = 0; i < tools.length; i++) { + for (let j = 0; j < tools[i].length; j++) { + core.drawIcon( + "outerUI", + tools[i][j], + TOOL_BOX_LEFT_VERTICAL + i * 31 * 3, + TOOL_BOX_TOP_VERTICAL + j * 31 * 3, + 30 * 3, + 30 * 3 + ); + } + } + } else { + core.clearMap( + "outerUI", + TOOL_BOX_LEFT, + TOOL_BOX_TOP, + 130 * 3, + 80 * 3 + ); - if (itemId != this.selectedItem) { - this.showItemInfo(itemId); - } else { - switch (itemId) { - case "centerFly": - core.ui._drawCenterFly(); - break; - case "book": - core.openBook(true); - break; - case "wand": - core.insertAction({ - type: "useItem", - id: itemId, - }); - break; - case "fly": - core.useItem(itemId, true); - break; - default: - core.useItem(itemId); - } - } - }; - const inRect = ([x, y], [[sx, sy], [dx, dy]]) => { - return sx <= x && x <= dx && sy <= y && y <= dy; - }; - const relativeTo = ([x, y], [ax, ay]) => { - return [x - ax, y - ay]; - }; - const pos = [x, y]; - if (core.domStyle.isVertical) { - const itemBox = makeBox( - [ITEM_BOX_LEFT_VERTICAL, ITEM_BOX_TOP_VERTICAL], - [30 * 6 * 3, 31 * 4 * 3] - ); - if (inRect(pos, itemBox)) { - const [gx, gy] = gridify(relativeTo(pos, itemBox[0]), [ - 30 * 3, - 31 * 3, - ]); - const itemId = this.itemMx[gx][gy]; - if ( - (core.status.event.id == "viewMaps" || - core.status.event.id == "fly") && - itemId === "book" - ) - core.openBook(true); - if ( - core.isReplaying() || - core.status.lockControl || - core.isMoving() - ) - return; - useItem(itemId); - return; - } - const toolBox = makeBox( - [TOOL_BOX_LEFT_VERTICAL, TOOL_BOX_TOP_VERTICAL], - [31 * 2 * 3, 31 * 4 * 3] - ); - if (inRect(pos, toolBox)) { - const [col, row] = gridify(relativeTo(pos, toolBox[0]), [ - 31 * 3, - 31 * 3, - ]); - if (core.isReplaying()) { - this.replayAction[col][row].call(core); - } else if (core.isPlaying()) { - if (col === 0 && row === 3) { - core.doSL("autoSave", "load"); - } else if (col === 1 && row === 3) { - core.doSL("autoSave", "reload"); - } else { - this.toolbarAction[col][row].call(core, true); - } - } - return; - } - const mapBox = makeBox( - [MAP_BLOCK_LEFT_VERTICAL, MAP_BLOCK_TOP_VERTICAL], - [350, 350] - ); - if (inRect(pos, mapBox)) { - if ( - core.isReplaying() || - core.status.lockControl || - core.isMoving() - ) - return; - core.ui._drawViewMaps(core.floorIds.indexOf(core.status.floorId)); - return; - } - /*const equipBox = makeBox([EQUIP_BLOCK_LEFT_VERTICAL, EQUIP_BLOCK_TOP_VERTICAL], [90 * 3, 130 * 3]) + for (let i = 0; i < tools.length; i++) { + for (let j = 0; j < tools[i].length; j++) { + core.drawIcon( + "outerUI", + tools[i][j], + TOOL_BOX_LEFT + j * 31 * 3, + TOOL_BOX_TOP + i * 31 * 3, + 30 * 3, + 30 * 3 + ); + } + } + } + } + onclick(x, y) { + const makeBox = ([x, y], [w, h]) => { + return [ + [x, y], + [x + w, y + h], + ]; + }; + const gridify = ([x, y], [gw, gh]) => { + return [Math.floor(x / gw), Math.floor(y / gh)]; + }; + const useItem = (itemId) => { + if (!core.hasItem(itemId)) return; + + if (itemId != this.selectedItem) { + this.showItemInfo(itemId); + } else { + switch (itemId) { + case "centerFly": + core.ui._drawCenterFly(); + break; + case "book": + core.openBook(true); + break; + case "wand": + core.insertAction({ + type: "useItem", + id: itemId, + }); + break; + case "fly": + core.useItem(itemId); + break; + default: + core.useItem(itemId); + } + } + }; + const inRect = ([x, y], [ + [sx, sy], + [dx, dy] + ]) => { + return sx <= x && x <= dx && sy <= y && y <= dy; + }; + const relativeTo = ([x, y], [ax, ay]) => { + return [x - ax, y - ay]; + }; + const pos = [x, y]; + if (core.domStyle.isVertical) { + const itemBox = makeBox( + [ITEM_BOX_LEFT_VERTICAL, ITEM_BOX_TOP_VERTICAL], + [30 * 6 * 3, 31 * 4 * 3] + ); + if (inRect(pos, itemBox)) { + const [gx, gy] = gridify(relativeTo(pos, itemBox[0]), [ + 30 * 3, + 31 * 3, + ]); + const itemId = this.itemMx[gx][gy]; + if ( + (core.status.event.id == "viewMaps" || + core.status.event.id == "fly") && + itemId === "book" + ) + core.openBook(true); + if ( + core.isReplaying() || + core.status.lockControl || + core.isMoving() + ) + return; + useItem(itemId); + return; + } + const toolBox = makeBox( + [TOOL_BOX_LEFT_VERTICAL, TOOL_BOX_TOP_VERTICAL], + [31 * 2 * 3, 31 * 4 * 3] + ); + if (inRect(pos, toolBox)) { + const [col, row] = gridify(relativeTo(pos, toolBox[0]), [ + 31 * 3, + 31 * 3, + ]); + if (core.isReplaying()) { + this.replayAction[col][row].call(core); + } else if (core.isPlaying()) { + if (col === 0 && row === 3) { + core.doSL("autoSave", "load"); + } else if (col === 1 && row === 3) { + core.doSL("autoSave", "reload"); + } else { + this.toolbarAction[col][row].call(core, true); + } + } + return; + } + const mapBox = makeBox( + [MAP_BLOCK_LEFT_VERTICAL, MAP_BLOCK_TOP_VERTICAL], + [350, 350] + ); + if (inRect(pos, mapBox)) { + if ( + core.isReplaying() || + core.status.lockControl || + core.isMoving() + ) + return; + core.ui._drawViewMaps(core.floorIds.indexOf(core.status.floorId)); + return; + } + /*const equipBox = makeBox([EQUIP_BLOCK_LEFT_VERTICAL, EQUIP_BLOCK_TOP_VERTICAL], [90 * 3, 130 * 3]) if (inRect(pos, equipBox)) { if (core.isReplaying() || core.status.lockControl || core.isMoving()) return; core.openEquipbox(true) return; }*/ - } else { - const mapBox = makeBox([MAP_BLOCK_LEFT, MAP_BLOCK_TOP], [350, 350]); - if (inRect(pos, mapBox)) { - if ( - core.isReplaying() || - core.status.lockControl || - core.isMoving() - ) - return; - core.ui._drawViewMaps(core.floorIds.indexOf(core.status.floorId)); - return; - } - /* + } else { + const mapBox = makeBox([MAP_BLOCK_LEFT, MAP_BLOCK_TOP], [350, 350]); + if (inRect(pos, mapBox)) { + if ( + core.isReplaying() || + core.status.lockControl || + core.isMoving() + ) + return; + core.ui._drawViewMaps(core.floorIds.indexOf(core.status.floorId)); + return; + } + /* const equipBox = makeBox([EQUIP_BLOCK_LEFT, EQUIP_BLOCK_TOP], [130, 95]) if (inRect(pos, equipBox)) { if (core.isReplaying() || core.status.lockControl || core.isMoving()) return; core.openEquipbox(true) return; }*/ - const itemBox = makeBox( - [ITEM_BOX_LEFT, ITEM_BOX_TOP], - [31 * 4 * 3, 30 * 6 * 3] - ); - if (inRect(pos, itemBox)) { - const [gx, gy] = gridify(relativeTo(pos, itemBox[0]), [ - 31 * 3, - 30 * 3, - ]); - const itemId = this.itemMx[gy][gx]; - if ( - (core.status.event.id == "viewMaps" || - core.status.event.id == "fly") && - itemId === "book" - ) - core.openBook(true); - if ( - core.isReplaying() || - core.status.lockControl || - core.isMoving() - ) - return; - useItem(itemId); - return; - } - const toolBox = makeBox( - [TOOL_BOX_LEFT, TOOL_BOX_TOP], - [31 * 4 * 3, 31 * 2 * 3] - ); - if (inRect(pos, toolBox)) { - const [row, col] = gridify(relativeTo(pos, toolBox[0]), [ - 31 * 3, - 31 * 3, - ]); - if (core.isReplaying()) { - this.replayAction[col][row].call(core); - } else if (core.isPlaying()) { - if (col === 0 && row === 3) { - core.doSL("autoSave", "load"); - } else if (col === 1 && row === 3) { - core.doSL("autoSave", "reload"); - } else { - this.toolbarAction[col][row].call(core, true); - } - } - return; - } - } - } - } - - core.ui.statusBar = new StatusBar(); - - core.control.clearStatusBar = function () { - core.clearMap("outerUI"); - }; - // init() called in `afterLoadResources`. - }, - "override": function () { - core.statusBar.icons = { - floor: 0, - name: null, - lv: 1, - hpmax: 2, - hp: 3, - atk: 4, - def: 5, - mdef: 6, - money: 7, - exp: 8, - up: 9, - book: 10, - fly: 11, - toolbox: 12, - keyboard: 13, - shop: 14, - save: 15, - load: 16, - settings: 17, - play: 18, - pause: 19, - stop: 20, - speedDown: 21, - speedUp: 22, - rewind: 23, - equipbox: 24, - mana: 25, - skill: 26, - exit: 27, - btn1: 28, - btn2: 29, - btn3: 30, - btn4: 31, - btn5: 32, - btn6: 33, - btn7: 34, - alt: 35, - keys: 36, - help: 37, - battle: 38, - }; - core.actions._getClickLoc = function (x, y) { - var size = 32 * core.domStyle.scale; - var left = main.dom.gameDraw.offsetLeft + main.dom.gameGroup.offsetLeft; - var top = main.dom.gameDraw.offsetTop + main.dom.gameGroup.offsetTop; - var loc = { - x: Math.max(x - left, 0), - y: Math.max(y - top, 0), - size: size, - }; - return loc; - }; - core.ui._drawWindowSelector = function (background, x, y, w, h) { - w = Math.round(w) + 48; - h = Math.round(h); - var ctx = core.ui.createCanvas("_selector", x - 24, y, w, h, 165); - ctx.canvas.id = ""; - this._drawSelector(ctx, background, w, h); - }; - - core.ui._drawSelector = function (ctx, background, w, h, left, top) { - left = left || 0; - top = top || 0; - ctx = this.getContextByName(ctx); - if (!ctx) return; - if (typeof background == "string") - background = core.material.images.images[background]; - if (!(background instanceof Image)) return; - // badge - ctx.drawImage(background, 132, 68, 24, 24, left + 4, top + 4, 24, 24); - ctx.drawImage( - background, - 132, - 68, - 24, - 24, - w - left - 28, - top + 4, - 24, - 24 - ); - }; - - enemys.prototype._nextCriticals_useBinarySearch = function ( - enemy, - info, - number, - x, - y, - floorId - ) { - var mon_hp = info.mon_hp, - hero_atk = core.status.hero.atk, - mon_def = info.mon_def, - pre = info.damage; - var list = []; - var start_atk = hero_atk; - if (info.__over__) { - start_atk += info.__overAtk__; - list.push([info.__overAtk__, -info.damage]); - } - var calNext = function (currAtk, maxAtk) { - var start = Math.floor(currAtk), - end = Math.floor(maxAtk); - if (start > end) return null; - - while (start < end) { - var mid = Math.floor((start + end) / 2); - if (mid - start > end - mid) mid--; - var nextInfo = core.enemys.getDamageInfo( - enemy, { atk: mid }, - x, - y, - floorId + const itemBox = makeBox( + [ITEM_BOX_LEFT, ITEM_BOX_TOP], + [31 * 4 * 3, 30 * 6 * 3] ); - if (nextInfo == null || typeof nextInfo == "number") return null; - if (pre > nextInfo.damage) end = mid; - else start = mid + 1; - } - var nextInfo = core.enemys.getDamageInfo( - enemy, { atk: start }, - x, - y, - floorId - ); - return nextInfo == null || - typeof nextInfo == "number" || - nextInfo.damage >= pre ? - null : [start, nextInfo.damage]; - }; - var currAtk = start_atk; - while (true) { - var next = calNext(currAtk + 1, Number.MAX_SAFE_INTEGER, pre); - if (next == null) break; - currAtk = next[0]; - pre = next[1]; - list.push([currAtk - hero_atk, info.damage - pre]); - if (pre <= 0 && !core.flags.enableNegativeDamage) break; - if (list.length >= number) break; - } - if (list.length == 0) list.push([0, 0]); - return list; - }; - core.ui.clearMap = function (name, x, y, width, height) { - if (name == "all") { - for (var m in core.canvas) { - core.canvas[m].clearRect( - -32, - -32, - core.canvas[m].canvas.width + 32, - core.canvas[m].canvas.height + 32 - ); - } - core.clearMap("outerUI"); - core.dom.gif.innerHTML = ""; - core.removeGlobalAnimate(); - core.deleteCanvas(function (one) { - return one.startsWith("_bigImage_"); - }); - core.setWeather(null); - } else { - var ctx = this.getContextByName(name); - if (ctx) - ctx.clearRect( - x || 0, - y || 0, - width || ctx.canvas.width, - height || ctx.canvas.height - ); - } - }; - events.prototype.openBook = function (fromUserAction) { - if (core.isReplaying()) return; - // 如果能恢复事件(从callBook事件触发) - 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) { - core.status.boxAnimateObjs = []; - core.ui._drawViewMaps(core.status.event.ui); - return; - } - // 从“浏览地图”页面打开 - if (core.status.event.id == "viewMaps" || core.status.event.id == "fly") { - fromUserAction = false; - core.status.event.ui = core.status.event.data; - } - if (!this._checkStatus("book", fromUserAction, true)) return; - core.playSound("打开界面"); - core.useItem("book", true); - }; - ////// 怪物手册界面时,放开某个键的操作 ////// - core.actions._keyUpBook = function (keycode) { - if (keycode == 27 || keycode == 88) { - core.playSound("取消"); - if (core.events.recoverEvents(core.status.event.interval)) { - return; - } else if (core.status.event.ui != null) { - core.status.boxAnimateObjs = []; - if (typeof core.status.event.ui === "number") { - core.status.event.id = "fly"; - core.ui.drawFly(core.status.event.ui); - } else { - core.ui._drawViewMaps(core.status.event.ui); + if (inRect(pos, itemBox)) { + const [gx, gy] = gridify(relativeTo(pos, itemBox[0]), [ + 31 * 3, + 30 * 3, + ]); + const itemId = this.itemMx[gy][gx]; + if ( + (core.status.event.id == "viewMaps" || + core.status.event.id == "fly") && + itemId === "book" + ) + core.openBook(true); + if ( + core.isReplaying() || + core.status.lockControl || + core.isMoving() + ) + return; + useItem(itemId); + return; } - } else core.ui.closePanel(); - return; - } - if (keycode == 13 || keycode == 32 || keycode == 67) { - var data = core.status.event.data; - if (data != null) { - core.ui._drawBookDetail(data); - } - return; - } - }; - ////// 怪物手册界面的点击操作 ////// - actions.prototype._clickBook = function (x, y) { - var pageinfo = core.ui._drawBook_pageinfo(); - // 上一页 - if ( - (x == this._HX_ - 2 || x == this._HX_ - 3) && - y === core._HEIGHT_ - 1 - ) { - core.playSound("光标移动"); - core.ui.drawBook(core.status.event.data - pageinfo.per_page); - return; - } - // 下一页 - if ( - (x == this._HX_ + 2 || x == this._HX_ + 3) && - y === core._HEIGHT_ - 1 - ) { - core.playSound("光标移动"); - core.ui.drawBook(core.status.event.data + pageinfo.per_page); - return; - } - // 返回 - if (x >= this.LAST - 2 && y === core._HEIGHT_ - 1) { - core.playSound("取消"); - if (core.events.recoverEvents(core.status.event.interval)) { - return; - } else if (core.status.event.ui != null) { - core.status.boxAnimateObjs = []; - if (typeof core.status.event.ui === "number") { - core.status.event.id = "fly"; - core.ui.drawFly(core.status.event.ui); - } else { - core.ui._drawViewMaps(core.status.event.ui); - } - } else core.ui.closePanel(); - return; - } - // 怪物信息 - var data = core.status.event.data; - if (data != null && y < core._HEIGHT_ - 1) { - var per_page = pageinfo.per_page, - page = parseInt(data / per_page); - var u = (core._HEIGHT_ - 1) / per_page; - for (var i = 0; i < per_page; ++i) { - if (y >= u * i && y < u * (i + 1)) { - var index = per_page * page + i; - core.ui.drawBook(index); - core.ui._drawBookDetail(index); - break; + const toolBox = makeBox( + [TOOL_BOX_LEFT, TOOL_BOX_TOP], + [31 * 4 * 3, 31 * 2 * 3] + ); + if (inRect(pos, toolBox)) { + const [row, col] = gridify(relativeTo(pos, toolBox[0]), [ + 31 * 3, + 31 * 3, + ]); + if (core.isReplaying()) { + this.replayAction[col][row].call(core); + } else if (core.isPlaying()) { + if (col === 0 && row === 3) { + core.doSL("autoSave", "load"); + } else if (col === 1 && row === 3) { + core.doSL("autoSave", "reload"); + } else { + this.toolbarAction[col][row].call(core, true); + } + } + return; } } - return; } - return; - }; - - ////// 执行当前自定义事件列表中的下一个事件 ////// - events.prototype.doAction = function () { - // 清空boxAnimate和UI层 - clearInterval(core.status.event.interval); - clearTimeout(core.status.event.interval); - clearInterval(core.status.event.animateUI); - core.status.event.interval = null; - delete core.status.event.aniamteUI; - if (core.status.gameOver || core.status.replay.failed) return; - // 判定是否执行完毕 - if (this._doAction_finishEvents()) return; - 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 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 (data._disabled) return core.doAction(); - if (data.type !== "cgtext") { - core.unregisterAnimationFrame("skip"); - core.setFlag("skip", false); - } - data.floorId = data.floorId || floorId; - core.status.event.data.type = data.type; - this.doEvent(data, x, y, prefix); - return; - }; - - ////// 在某个canvas上绘制粗体 ////// - core.fillBoldText1 = function ( - name, - text, - x, - y, - style, - strokeStyle, - lineWidth, - font, - maxWidth - ) { - var ctx = this.getContextByName(name); - if (!ctx) return; - if (font) ctx.font = font; - if (!style) style = ctx.fillStyle; - style = core.arrayToRGBA(style); - if (!strokeStyle) strokeStyle = "#000000"; - strokeStyle = core.arrayToRGBA(strokeStyle); - if (maxWidth != null) { - this.setFontForMaxWidth(ctx, text, maxWidth); - } - ctx.strokeStyle = strokeStyle; - - if (!lineWidth) lineWidth = 2; - ctx.lineWidth = lineWidth; - ctx.strokeText(text, x, y); - ctx.fillStyle = style; - ctx.fillText(text, x, y); - }; - ////// 绘制 WindowSkin - ui.prototype.drawWindowSkin = function (background, ctx, x, y, w, h, direction, px, py, size = 1) { - background = background || core.status.textAttribute.background; - - // 仿RM窗口皮肤 ↓ - // 绘制背景 - core.drawImage(ctx, background, 0, 0, 128, 128, x + 2 * size, y + 2 * size, w - 4 * size, h - 4 * size); - // 绘制边框 - // 上方 - core.drawImage(ctx, background, 128, 0, 16, 16, x, y, 16 * size, 16 * size); - for (var dx = 0; dx < w - 64 * size; dx += 32 * size) { - core.drawImage(ctx, background, 144, 0, 32, 16, x + dx + 16 * size, y, 32 * size, 16 * size); - core.drawImage(ctx, background, 144, 48, 32, 16, x + dx + 16 * size, y + h - 16 * size, 32 * size, 16 * size); - } - core.drawImage(ctx, background, 144, 0, (w - dx - 32 * size) / size, 16, x + dx + 16 * size, y, w - dx - 32 * size, 16 * size); - core.drawImage(ctx, background, 144, 48, (w - dx - 32 * size) / size, 16, x + dx + 16 * size, y + h - 16 * size, w - dx - 32 * size, 16 * size); - core.drawImage(ctx, background, 176, 0, 16, 16, x + w - 16 * size, y, 16 * size, 16 * size); - // 左右 - for (var dy = 0; dy < h - 64 * size; dy += 32 * size) { - core.drawImage(ctx, background, 128, 16, 16, 32, x, y + dy + 16 * size, 16 * size, 32 * size); - core.drawImage(ctx, background, 176, 16, 16, 32, x + w - 16 * size, y + dy + 16 * size, 16 * size, 32 * size); - } - core.drawImage(ctx, background, 128, 16, 16, (h - dy - 32 * size) / size, x, y + dy + 16 * size, 16 * size, h - dy - 32 * size); - core.drawImage(ctx, background, 176, 16, 16, (h - dy - 32 * size) / size, x + w - 16 * size, y + dy + 16 * size, 16 * size, h - dy - 32 * size); - //下方 - core.drawImage(ctx, background, 128, 48, 16, 16, x, y + h - 16 * size, 16 * size, 16 * size); - core.drawImage(ctx, background, 176, 48, 16, 16, x + w - 16 * size, y + h - 16 * size, 16 * size, 16 * size); - - // arrow - if (px != null && py != null) { - if (direction == 'up') { - core.drawImage(ctx, background, 128, 96, 32, 32, px, y + h - 3 * size, 32 * size, 32 * size); - } else if (direction == 'down') { - core.drawImage(ctx, background, 160, 96, 32, 32, px, y - 29 * size, 32 * size, 32 * size); - } - } - // 仿RM窗口皮肤 ↑ } + core.ui.statusBar = new StatusBar(); + + core.control.clearStatusBar = function () { + core.clearMap("outerUI"); + }; + // init() called in `afterLoadResources`. }, + "override": function () { + core.statusBar.icons = { + floor: 0, + name: null, + lv: 1, + hpmax: 2, + hp: 3, + atk: 4, + def: 5, + mdef: 6, + money: 7, + exp: 8, + up: 9, + book: 10, + fly: 11, + toolbox: 12, + keyboard: 13, + shop: 14, + save: 15, + load: 16, + settings: 17, + play: 18, + pause: 19, + stop: 20, + speedDown: 21, + speedUp: 22, + rewind: 23, + equipbox: 24, + mana: 25, + skill: 26, + exit: 27, + btn1: 28, + btn2: 29, + btn3: 30, + btn4: 31, + btn5: 32, + btn6: 33, + btn7: 34, + alt: 35, + keys: 36, + help: 37, + battle: 38, + }; + core.actions._getClickLoc = function (x, y) { + var size = 32 * core.domStyle.scale; + var left = main.dom.gameDraw.offsetLeft + main.dom.gameGroup.offsetLeft; + var top = main.dom.gameDraw.offsetTop + main.dom.gameGroup.offsetTop; + var loc = { + x: Math.max(x - left, 0), + y: Math.max(y - top, 0), + size: size, + }; + return loc; + }; + core.ui._drawWindowSelector = function (background, x, y, w, h) { + w = Math.round(w) + 48; + h = Math.round(h); + var ctx = core.ui.createCanvas("_selector", x - 24, y, w, h, 165); + ctx.canvas.id = ""; + this._drawSelector(ctx, background, w, h); + }; + + core.ui._drawSelector = function (ctx, background, w, h, left, top) { + left = left || 0; + top = top || 0; + ctx = this.getContextByName(ctx); + if (!ctx) return; + if (typeof background == "string") + background = core.material.images.images[background]; + if (!(background instanceof Image)) return; + // badge + ctx.drawImage(background, 132, 68, 24, 24, left + 4, top + 4, 24, 24); + ctx.drawImage( + background, + 132, + 68, + 24, + 24, + w - left - 28, + top + 4, + 24, + 24 + ); + }; + + enemys.prototype._nextCriticals_useBinarySearch = function ( + enemy, + info, + number, + x, + y, + floorId + ) { + var mon_hp = info.mon_hp, + hero_atk = core.status.hero.atk, + mon_def = info.mon_def, + pre = info.damage; + var list = []; + var start_atk = hero_atk; + if (info.__over__) { + start_atk += info.__overAtk__; + list.push([info.__overAtk__, -info.damage]); + } + var calNext = function (currAtk, maxAtk) { + var start = Math.floor(currAtk), + end = Math.floor(maxAtk); + if (start > end) return null; + + while (start < end) { + var mid = Math.floor((start + end) / 2); + if (mid - start > end - mid) mid--; + var nextInfo = core.enemys.getDamageInfo( + enemy, + { atk: mid }, + x, + y, + floorId + ); + if (nextInfo == null || typeof nextInfo == "number") return null; + if (pre > nextInfo.damage) end = mid; + else start = mid + 1; + } + var nextInfo = core.enemys.getDamageInfo( + enemy, + { atk: start }, + x, + y, + floorId + ); + return nextInfo == null || + typeof nextInfo == "number" || + nextInfo.damage >= pre + ? null + : [start, nextInfo.damage]; + }; + var currAtk = start_atk; + while (true) { + var next = calNext(currAtk + 1, Number.MAX_SAFE_INTEGER, pre); + if (next == null) break; + currAtk = next[0]; + pre = next[1]; + list.push([currAtk - hero_atk, info.damage - pre]); + if (pre <= 0 && !core.flags.enableNegativeDamage) break; + if (list.length >= number) break; + } + if (list.length == 0) list.push([0, 0]); + return list; + }; + core.ui.clearMap = function (name, x, y, width, height) { + if (name == "all") { + for (var m in core.canvas) { + core.canvas[m].clearRect( + -32, + -32, + core.canvas[m].canvas.width + 32, + core.canvas[m].canvas.height + 32 + ); + } + core.clearMap("outerUI"); + core.dom.gif.innerHTML = ""; + core.removeGlobalAnimate(); + core.deleteCanvas(function (one) { + return one.startsWith("_bigImage_"); + }); + core.setWeather(null); + } else { + var ctx = this.getContextByName(name); + if (ctx) + ctx.clearRect( + x || 0, + y || 0, + width || ctx.canvas.width, + height || ctx.canvas.height + ); + } + }; + events.prototype.openBook = function (fromUserAction) { + if (core.isReplaying()) return; + // 如果能恢复事件(从callBook事件触发) + 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) { + core.status.boxAnimateObjs = []; + core.ui._drawViewMaps(core.status.event.ui); + return; + } + // 从“浏览地图”页面打开 + if (core.status.event.id == "viewMaps" || core.status.event.id == "fly") { + fromUserAction = false; + core.status.event.ui = core.status.event.data; + } + if (!this._checkStatus("book", fromUserAction, true)) return; + core.playSound("打开界面"); + core.useItem("book", true); + }; + ////// 怪物手册界面时,放开某个键的操作 ////// + core.actions._keyUpBook = function (keycode) { + if (keycode == 27 || keycode == 88) { + core.playSound("取消"); + if (core.events.recoverEvents(core.status.event.interval)) { + return; + } else if (core.status.event.ui != null) { + core.status.boxAnimateObjs = []; + if (typeof core.status.event.ui === "number") { + core.status.event.id = "fly"; + core.ui.drawFly(core.status.event.ui); + } else { + core.ui._drawViewMaps(core.status.event.ui); + } + } else core.ui.closePanel(); + return; + } + if (keycode == 13 || keycode == 32 || keycode == 67) { + var data = core.status.event.data; + if (data != null) { + core.ui._drawBookDetail(data); + } + return; + } + }; + ////// 怪物手册界面的点击操作 ////// + actions.prototype._clickBook = function (x, y) { + var pageinfo = core.ui._drawBook_pageinfo(); + // 上一页 + if ( + (x == this._HX_ - 2 || x == this._HX_ - 3) && + y === core._HEIGHT_ - 1 + ) { + core.playSound("光标移动"); + core.ui.drawBook(core.status.event.data - pageinfo.per_page); + return; + } + // 下一页 + if ( + (x == this._HX_ + 2 || x == this._HX_ + 3) && + y === core._HEIGHT_ - 1 + ) { + core.playSound("光标移动"); + core.ui.drawBook(core.status.event.data + pageinfo.per_page); + return; + } + // 返回 + if (x >= this.LAST - 2 && y === core._HEIGHT_ - 1) { + core.playSound("取消"); + if (core.events.recoverEvents(core.status.event.interval)) { + return; + } else if (core.status.event.ui != null) { + core.status.boxAnimateObjs = []; + if (typeof core.status.event.ui === "number") { + core.status.event.id = "fly"; + core.ui.drawFly(core.status.event.ui); + } else { + core.ui._drawViewMaps(core.status.event.ui); + } + } else core.ui.closePanel(); + return; + } + // 怪物信息 + var data = core.status.event.data; + if (data != null && y < core._HEIGHT_ - 1) { + var per_page = pageinfo.per_page, + page = parseInt(data / per_page); + var u = (core._HEIGHT_ - 1) / per_page; + for (var i = 0; i < per_page; ++i) { + if (y >= u * i && y < u * (i + 1)) { + var index = per_page * page + i; + core.ui.drawBook(index); + core.ui._drawBookDetail(index); + break; + } + } + return; + } + return; + }; + + ////// 执行当前自定义事件列表中的下一个事件 ////// + events.prototype.doAction = function () { + // 清空boxAnimate和UI层 + clearInterval(core.status.event.interval); + clearTimeout(core.status.event.interval); + clearInterval(core.status.event.animateUI); + core.status.event.interval = null; + delete core.status.event.aniamteUI; + if (core.status.gameOver || core.status.replay.failed) return; + // 判定是否执行完毕 + if (this._doAction_finishEvents()) return; + 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 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 (data._disabled) return core.doAction(); + if (data.type !== "cgtext") { + core.unregisterAnimationFrame("skip"); + core.setFlag("skip", false); + } + data.floorId = data.floorId || floorId; + core.status.event.data.type = data.type; + this.doEvent(data, x, y, prefix); + return; + }; + + ////// 在某个canvas上绘制粗体 ////// + core.fillBoldText1 = function ( + name, + text, + x, + y, + style, + strokeStyle, + lineWidth, + font, + maxWidth + ) { + var ctx = this.getContextByName(name); + if (!ctx) return; + if (font) ctx.font = font; + if (!style) style = ctx.fillStyle; + style = core.arrayToRGBA(style); + if (!strokeStyle) strokeStyle = "#000000"; + strokeStyle = core.arrayToRGBA(strokeStyle); + if (maxWidth != null) { + this.setFontForMaxWidth(ctx, text, maxWidth); + } + ctx.strokeStyle = strokeStyle; + + if (!lineWidth) lineWidth = 2; + ctx.lineWidth = lineWidth; + ctx.strokeText(text, x, y); + ctx.fillStyle = style; + ctx.fillText(text, x, y); + }; + ////// 绘制 WindowSkin + ui.prototype.drawWindowSkin = function ( + background, + ctx, + x, + y, + w, + h, + direction, + px, + py, + size = 1 + ) { + background = background || core.status.textAttribute.background; + + // 仿RM窗口皮肤 ↓ + // 绘制背景 + core.drawImage( + ctx, + background, + 0, + 0, + 128, + 128, + x + 2 * size, + y + 2 * size, + w - 4 * size, + h - 4 * size + ); + // 绘制边框 + // 上方 + core.drawImage( + ctx, + background, + 128, + 0, + 16, + 16, + x, + y, + 16 * size, + 16 * size + ); + for (var dx = 0; dx < w - 64 * size; dx += 32 * size) { + core.drawImage( + ctx, + background, + 144, + 0, + 32, + 16, + x + dx + 16 * size, + y, + 32 * size, + 16 * size + ); + core.drawImage( + ctx, + background, + 144, + 48, + 32, + 16, + x + dx + 16 * size, + y + h - 16 * size, + 32 * size, + 16 * size + ); + } + core.drawImage( + ctx, + background, + 144, + 0, + (w - dx - 32 * size) / size, + 16, + x + dx + 16 * size, + y, + w - dx - 32 * size, + 16 * size + ); + core.drawImage( + ctx, + background, + 144, + 48, + (w - dx - 32 * size) / size, + 16, + x + dx + 16 * size, + y + h - 16 * size, + w - dx - 32 * size, + 16 * size + ); + core.drawImage( + ctx, + background, + 176, + 0, + 16, + 16, + x + w - 16 * size, + y, + 16 * size, + 16 * size + ); + // 左右 + for (var dy = 0; dy < h - 64 * size; dy += 32 * size) { + core.drawImage( + ctx, + background, + 128, + 16, + 16, + 32, + x, + y + dy + 16 * size, + 16 * size, + 32 * size + ); + core.drawImage( + ctx, + background, + 176, + 16, + 16, + 32, + x + w - 16 * size, + y + dy + 16 * size, + 16 * size, + 32 * size + ); + } + core.drawImage( + ctx, + background, + 128, + 16, + 16, + (h - dy - 32 * size) / size, + x, + y + dy + 16 * size, + 16 * size, + h - dy - 32 * size + ); + core.drawImage( + ctx, + background, + 176, + 16, + 16, + (h - dy - 32 * size) / size, + x + w - 16 * size, + y + dy + 16 * size, + 16 * size, + h - dy - 32 * size + ); + //下方 + core.drawImage( + ctx, + background, + 128, + 48, + 16, + 16, + x, + y + h - 16 * size, + 16 * size, + 16 * size + ); + core.drawImage( + ctx, + background, + 176, + 48, + 16, + 16, + x + w - 16 * size, + y + h - 16 * size, + 16 * size, + 16 * size + ); + + // arrow + if (px != null && py != null) { + if (direction == "up") { + core.drawImage( + ctx, + background, + 128, + 96, + 32, + 32, + px, + y + h - 3 * size, + 32 * size, + 32 * size + ); + } else if (direction == "down") { + core.drawImage( + ctx, + background, + 160, + 96, + 32, + 32, + px, + y - 29 * size, + 32 * size, + 32 * size + ); + } + } + // 仿RM窗口皮肤 ↑ + }; + }, "额外信息": function () { /* 宝石血瓶左下角显示数值 * 注意!!!不要在道具属性中直接操作flags,使用core.status.hero.flags或core.setFlag系列函数代替! @@ -8529,8 +8705,8 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = }; }, "音频系统": function () { - // 在此增加新插件 - /*首先,在造塔群下载所需的库文件,然后放置在塔目录下的 libs/thirdparty 或其他目录下,之后在 index.html 的最后加上下面这几行: + // 在此增加新插件 + /*首先,在造塔群下载所需的库文件,然后放置在塔目录下的 libs/thirdparty 或其他目录下,之后在 index.html 的最后加上下面这几行: @@ -8538,2107 +8714,2134 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = */ - // 将__enable置为false将关闭插件 - let __enable = true; - if (!__enable || main.mode === "editor") return; - const { OggOpusDecoderWebWorker } = window["ogg-opus-decoder"]; - const { OggVorbisDecoderWebWorker } = window["ogg-vorbis-decoder"]; - const { CodecParser } = window.CodecParser; - const { Transition, linear } = core.plugin.animate; - - const audio = new Audio(); - const AudioStatus = { - Playing: 0, - Pausing: 1, - Paused: 2, - Stoping: 3, - Stoped: 4, - }; - const supportMap = new Map(); - const AudioType = { - Mp3: "audio/mpeg", - Wav: 'audio/wav; codecs="1"', - Flac: "audio/flac", - Opus: 'audio/ogg; codecs="opus"', - Ogg: 'audio/ogg; codecs="vorbis"', - Aac: "audio/aac", - }; - /** - * 检查一种音频类型是否能被播放 - * @param type 音频类型 AudioType - */ - function isAudioSupport(type) { - if (supportMap.has(type)) return supportMap.get(type); - else { - const support = audio.canPlayType(type); - const canPlay = support === "maybe" || support === "probably"; - supportMap.set(type, canPlay); - return canPlay; - } - } - - const typeMap = new Map([ - ["ogg", AudioType.Ogg], - ["mp3", AudioType.Mp3], - ["wav", AudioType.Wav], - ["flac", AudioType.Flac], - ["opus", AudioType.Opus], - ["aac", AudioType.Aac], - ]); - - /** - * 根据文件名拓展猜测其类型 - * @param file 文件名 string - */ - function guessTypeByExt(file) { - const ext = /\.[a-zA-Z\d]+$/.exec(file); - if (!ext?.[0]) return ""; - const type = ext[0].slice(1); - return typeMap.get(type.toLocaleLowerCase()) ?? ""; - } - - isAudioSupport(AudioType.Ogg); - isAudioSupport(AudioType.Mp3); - isAudioSupport(AudioType.Wav); - isAudioSupport(AudioType.Flac); - isAudioSupport(AudioType.Opus); - isAudioSupport(AudioType.Aac); - - function isNil(value) { - return value === void 0 || value === null; - } - - function sleep(time) { - return new Promise((res) => setTimeout(res, time)); - } - class AudioEffect { - constructor(ac) {} - /** - * 连接至其他效果器 - * @param target 目标输入 IAudioInput - * @param output 当前效果器输出通道 Number - * @param input 目标效果器的输入通道 Number - */ - connect(target, output, input) { - this.output.connect(target.input, output, input); - } - - /** - * 与其他效果器取消连接 - * @param target 目标输入 IAudioInput - * @param output 当前效果器输出通道 Number - * @param input 目标效果器的输入通道 Number - */ - disconnect(target, output, input) { - if (!target) { - if (!isNil(output)) { - this.output.disconnect(output); - } else { - this.output.disconnect(); - } - } else { - if (!isNil(output)) { - if (!isNil(input)) { - this.output.disconnect(target.input, output, input); - } else { - this.output.disconnect(target.input, output); - } - } else { - this.output.disconnect(target.input); - } - } - } - } - - class StereoEffect extends AudioEffect { - constructor(ac) { - super(ac); - const panner = ac.createPanner(); - this.input = panner; - this.output = panner; - } - - /** - * 设置音频朝向,x正方形水平向右,y正方形垂直于地面向上,z正方向垂直屏幕远离用户 - * @param x 朝向x坐标 Number - * @param y 朝向y坐标 Number - * @param z 朝向z坐标 Number - */ - setOrientation(x, y, z) { - this.output.orientationX.value = x; - this.output.orientationY.value = y; - this.output.orientationZ.value = z; - } - /** - * 设置音频位置,x正方形水平向右,y正方形垂直于地面向上,z正方向垂直屏幕远离用户 - * @param x 位置x坐标 Number - * @param y 位置y坐标 Number - * @param z 位置z坐标 Number - */ - setPosition(x, y, z) { - this.output.positionX.value = x; - this.output.positionY.value = y; - this.output.positionZ.value = z; - } - end() {} - - start() {} - } - class VolumeEffect extends AudioEffect { - constructor(ac) { - super(ac); - const gain = ac.createGain(); - this.input = gain; - this.output = gain; - } - - /** - * 设置音量大小 - * @param volume 音量大小 Number - */ - setVolume(volume) { - this.output.gain.value = volume; - } - - /** - * 获取音量大小 Number - */ - getVolume() { - return this.output.gain.value; - } - - end() {} - - start() {} - } - class ChannelVolumeEffect extends AudioEffect { - /** 所有的音量控制节点 */ - - constructor(ac) { - super(ac); - /** 所有的音量控制节点 */ - this.gain = []; - const splitter = ac.createChannelSplitter(); - const merger = ac.createChannelMerger(); - this.output = merger; - this.input = splitter; - for (let i = 0; i < 6; i++) { - const gain = ac.createGain(); - splitter.connect(gain, i); - gain.connect(merger, 0, i); - this.gain.push(gain); - } - } - - /** - * 设置某个声道的音量大小 - * @param channel 要设置的声道,可填0-5 Number - * @param volume 这个声道的音量大小 Number - */ - setVolume(channel, volume) { - if (!this.gain[channel]) return; - this.gain[channel].gain.value = volume; - } - - /** - * 获取某个声道的音量大小,可填0-5 - * @param channel 要获取的声道 Number - */ - getVolume(channel) { - if (!this.gain[channel]) return 0; - return this.gain[channel].gain.value; - } - - end() {} - - start() {} - } - class DelayEffect extends AudioEffect { - constructor(ac) { - super(ac); - - const delay = ac.createDelay(); - this.input = delay; - this.output = delay; - } - - /** - * 设置延迟时长 - * @param delay 延迟时长,单位秒 Number - */ - setDelay(delay) { - this.output.delayTime.value = delay; - } - - /** - * 获取延迟时长 - */ - getDelay() { - return this.output.delayTime.value; - } - - end() {} - - start() {} - } - class EchoEffect extends AudioEffect { - constructor(ac) { - super(ac); - /** 当前增益 */ - this.gain = 0.5; - /** 是否正在播放 */ - this.playing = false; - const delay = ac.createDelay(); - const gain = ac.createGain(); - gain.gain.value = 0.5; - delay.delayTime.value = 0.05; - delay.connect(gain); - gain.connect(delay); - /** 延迟节点 */ - this.delay = delay; - /** 反馈增益节点 */ - this.gainNode = gain; - - this.input = gain; - this.output = gain; - } - - /** - * 设置回声反馈增益大小 - * @param gain 增益大小,范围 0-1,大于等于1的视为0.5,小于0的视为0 Number - */ - setFeedbackGain(gain) { - const resolved = gain >= 1 ? 0.5 : gain < 0 ? 0 : gain; - this.gain = resolved; - if (this.playing) this.gainNode.gain.value = resolved; - } - - /** - * 设置回声间隔时长 - * @param delay 回声时长,范围 0.01-Infinity,小于0.01的视为0.01 Number - */ - setEchoDelay(delay) { - const resolved = delay < 0.01 ? 0.01 : delay; - this.delay.delayTime.value = resolved; - } - - /** - * 获取反馈节点增益 - */ - getFeedbackGain() { - return this.gain; - } - - /** - * 获取回声间隔时长 - */ - getEchoDelay() { - return this.delay.delayTime.value; - } - - end() { - this.playing = false; - const echoTime = Math.ceil(Math.log(0.001) / Math.log(this.gain)) + 10; - sleep(this.delay.delayTime.value * echoTime).then(() => { - if (!this.playing) this.gainNode.gain.value = 0; - }); - } - - start() { - this.playing = true; - this.gainNode.gain.value = this.gain; - } - } - - class StreamLoader { - constructor(url) { - /** 传输目标 Set*/ - this.target = new Set(); - this.loading = false; - } - - /** - * 将加载流传递给字节流读取对象 - * @param reader 字节流读取对象 IStreamReader - */ - pipe(reader) { - if (this.loading) { - console.warn( - "Cannot pipe new StreamReader object when stream is loading." - ); - return; - } - this.target.add(reader); - reader.piped(this); - return this; - } - - async start() { - if (this.loading) return; - this.loading = true; - const response = await window.fetch(this.url); - const stream = response.body; - if (!stream) { - console.error("Cannot get reader when fetching '" + this.url + "'."); - return; - } - // 获取读取器 - /** 读取流对象 */ - this.stream = stream; - const reader = response.body?.getReader(); - const targets = [...this.target]; - - await Promise.all(targets.map((v) => v.start(stream, this, response))); - if (reader && reader.read) { - // 开始流传输 - while (true) { - const { value, done } = await reader.read(); - await Promise.all( - targets.map((v) => v.pump(value, done, response)) - ); - if (done) break; - } - } else { - // 如果不支持流传输 - const buffer = await response.arrayBuffer(); - const data = new Uint8Array(buffer); - await Promise.all(targets.map((v) => v.pump(data, true, response))); - } - // 开始流传输 - while (true) { - const { value, done } = await reader.read(); - await Promise.all(targets.map((v) => v.pump(value, done, response))); - if (done) break; - } - - this.loading = false; - targets.forEach((v) => v.end(true)); - - // - } - - cancel(reason) { - if (!this.stream) return; - this.stream.cancel(reason); - this.loading = false; - this.target.forEach((v) => v.end(false, reason)); - } - } - const fileSignatures = [ - [AudioType.Mp3, [0x49, 0x44, 0x33]], - [AudioType.Ogg, [0x4f, 0x67, 0x67, 0x53]], - [AudioType.Wav, [0x52, 0x49, 0x46, 0x46]], - [AudioType.Flac, [0x66, 0x4c, 0x61, 0x43]], - [AudioType.Aac, [0xff, 0xf1]], - [AudioType.Aac, [0xff, 0xf9]], - ]; - const oggHeaders = [ - [AudioType.Opus, [0x4f, 0x70, 0x75, 0x73, 0x48, 0x65, 0x61, 0x64]], - ]; - - function checkAudioType(data) { - let audioType = ""; - // 检查头文件获取音频类型,仅检查前256个字节 - const toCheck = data.slice(0, 256); - for (const [type, value] of fileSignatures) { - if (value.every((v, i) => toCheck[i] === v)) { - audioType = type; - break; - } - } - if (audioType === AudioType.Ogg) { - // 如果是ogg的话,进一步判断是不是opus - for (const [key, value] of oggHeaders) { - const has = toCheck.some((_, i) => { - return value.every((v, ii) => toCheck[i + ii] === v); - }); - if (has) { - audioType = key; - break; - } - } - } - - return audioType; - } - class AudioDecoder { - /** - * 注册一个解码器 - * @param type 要注册的解码器允许解码的类型 - * @param decoder 解码器对象 - */ - static registerDecoder(type, decoder) { - if (!this.decoderMap) this.decoderMap = new Map(); - if (this.decoderMap.has(type)) { - console.warn( - "Audio stream decoder for audio type '" + - type + - "' has already existed." - ); - return; - } - - this.decoderMap.set(type, decoder); - } - - /** - * 解码音频数据 - * @param data 音频文件数据 - * @param player AudioPlayer实例 - */ - static async decodeAudioData(data, player) { - // 检查头文件获取音频类型,仅检查前256个字节 - const toCheck = data.slice(0, 256); - const type = checkAudioType(data); - if (type === "") { - console.error( - "Unknown audio type. Header: '" + - [...toCheck] - .map((v) => v.toString().padStart(2, "0")) - .join(" ") - .toUpperCase() + - "'" - ); - return null; - } - if (isAudioSupport(type)) { - if (data.buffer instanceof ArrayBuffer) { - return player.ac.decodeAudioData(data.buffer); - } else { - return null; - } - } else { - const Decoder = this.decoderMap.get(type); - if (!Decoder) { - return null; - } else { - const decoder = new Decoder(); - await decoder.create(); - const decodedData = await decoder.decode(data); - if (!decodedData) return null; - const buffer = player.ac.createBuffer( - decodedData.channelData.length, - decodedData.channelData[0].length, - decodedData.sampleRate - ); - decodedData.channelData.forEach((v, i) => { - buffer.copyToChannel(v, i); - }); - decoder.destroy(); - return buffer; - } - } - } - } - - class VorbisDecoder { - /** - * 创建音频解码器 - */ - async create() { - this.decoder = new OggVorbisDecoderWebWorker(); - await this.decoder.ready; - } - /** - * 摧毁这个解码器 - */ - destroy() { - this.decoder?.free(); - } - /** - * 解码流数据 - * @param data 流数据 - */ - - async decode(data) { - return this.decoder?.decode(data); - } - /** - * 解码整个文件 - * @param data 文件数据 - */ - async decodeAll(data) { - return this.decoder?.decodeFile(data); - } - /** - * 当音频解码完成后,会调用此函数,需要返回之前还未解析或未返回的音频数据。调用后,该解码器将不会被再次使用 - */ - async flush() { - return this.decoder?.flush(); - } - } - - class OpusDecoder { - /** - * 创建音频解码器 - */ - async create() { - this.decoder = new OggOpusDecoderWebWorker(); - await this.decoder.ready; - } - /** - * 摧毁这个解码器 - */ - destroy() { - this.decoder?.free(); - } - /** - * 解码流数据 - * @param data 流数据 - */ - async decode(data) { - return this.decoder?.decode(data); - } - /** - * 解码整个文件 - * @param data 文件数据 - */ - async decodeAll(data) { - return this.decoder?.decodeFile(data); - } - /** - * 当音频解码完成后,会调用此函数,需要返回之前还未解析或未返回的音频数据。调用后,该解码器将不会被再次使用 - */ - async flush() { - return await this.decoder?.flush(); - } - } - const mimeTypeMap = { - [AudioType.Aac]: "audio/aac", - [AudioType.Flac]: "audio/flac", - [AudioType.Mp3]: "audio/mpeg", - [AudioType.Ogg]: "application/ogg", - [AudioType.Opus]: "application/ogg", - [AudioType.Wav]: "application/ogg", - }; - - function isOggPage(data) { - return !isNil(data.isFirstPage); - } - class AudioStreamSource { - constructor(context) { - this.output = context.createBufferSource(); - /** 是否已经完全加载完毕 */ - this.loaded = false; - /** 是否正在播放 */ - this.playing = false; - /** 已经缓冲了多长时间,如果缓冲完那么跟歌曲时长一致 */ - this.buffered = 0; - /** 已经缓冲的采样点数量 */ - this.bufferedSamples = 0; - /** 歌曲时长,加载完毕之前保持为 0 */ - this.duration = 0; - /** 在流传输阶段,至少缓冲多长时间的音频之后才开始播放,单位秒 */ - this.bufferPlayDuration = 1; - /** 音频的采样率,未成功解析出之前保持为 0 */ - this.sampleRate = 0; - //是否循环播放 - this.loop = false; - /** 上一次播放是从何时开始的 */ - this.lastStartWhen = 0; - /** 开始播放时刻 */ - this.lastStartTime = 0; - /** 上一次播放的缓存长度 */ - this.lastBufferSamples = 0; - - /** 是否已经获取到头文件 */ - this.headerRecieved = false; - /** 音频类型 */ - this.audioType = ""; - /** 每多长时间组成一个缓存 Float32Array */ - this.bufferChunkSize = 10; - /** 缓存音频数据,每 bufferChunkSize 秒钟组成一个 Float32Array,用于流式解码 */ - this.audioData = []; - - this.errored = false; - this.ac = context; - } - /** 当前已经播放了多长时间 */ - get currentTime() { - return this.ac.currentTime - this.lastStartTime + this.lastStartWhen; - } - /** - * 设置每个缓存数据的大小,默认为10秒钟一个缓存数据 - * @param size 每个缓存数据的时长,单位秒 - */ - setChunkSize(size) { - if (this.controller?.loading || this.loaded) return; - this.bufferChunkSize = size; - } - on(event, fn, context) {} - piped(controller) { - this.controller = controller; - } - - async pump(data, done) { - if (!data || this.errored) return; - if (!this.headerRecieved) { - // 检查头文件获取音频类型,仅检查前256个字节 - const toCheck = data.slice(0, 256); - this.audioType = checkAudioType(data); - if (!this.audioType) { - console.error( - "Unknown audio type. Header: '" + - [...toCheck] - .map((v) => v.toString(16).padStart(2, "0")) - .join(" ") - .toUpperCase() + - "'" - ); - return; - } - // 创建解码器 - const Decoder = AudioDecoder.decoderMap.get(this.audioType); - if (!Decoder) { - this.errored = true; - console.error( - "Cannot decode stream source type of '" + - this.audioType + - "', since there is no registered decoder for that type." - ); - return Promise.reject( - `Cannot decode stream source type of '${this.audioType}', since there is no registered decoder for that type.` - ); - } - this.decoder = new Decoder(); - // 创建数据解析器 - const mime = mimeTypeMap[this.audioType]; - const parser = new CodecParser(mime); - this.parser = parser; - await this.decoder.create(); - this.headerRecieved = true; - } - - const decoder = this.decoder; - const parser = this.parser; - if (!decoder || !parser) { - this.errored = true; - return Promise.reject( - "No parser or decoder attached in this AudioStreamSource" - ); - } - - await this.decodeData(data, decoder, parser); - if (done) await this.decodeFlushData(decoder, parser); - this.checkBufferedPlay(); - } - - /** - * 检查采样率,如果还未解析出采样率,那么将设置采样率,如果当前采样率与之前不同,那么发出警告 - */ - checkSampleRate(info) { - for (const one of info) { - const frame = isOggPage(one) ? one.codecFrames[0] : one; - if (frame) { - const rate = frame.header.sampleRate; - if (this.sampleRate === 0) { - this.sampleRate = rate; - break; - } else { - if (rate !== this.sampleRate) { - console.warn("Sample rate in stream audio must be constant."); - } - } - } - } - } - - /** - * 解析音频数据 - */ - async decodeData(data, decoder, parser) { - // 解析音频数据 - const audioData = await decoder.decode(data); - if (!audioData) return; - // @ts-expect-error 库类型声明错误 - const audioInfo = [...parser.parseChunk(data)]; - - // 检查采样率 - this.checkSampleRate(audioInfo); - // 追加音频数据 - this.appendDecodedData(audioData, audioInfo); - } - - /** - * 解码剩余数据 - */ - async decodeFlushData(decoder, parser) { - const audioData = await decoder.flush(); - if (!audioData) return; - // @ts-expect-error 库类型声明错误 - const audioInfo = [...parser.flush()]; - - this.checkSampleRate(audioInfo); - this.appendDecodedData(audioData, audioInfo); - } - - /** - * 追加音频数据 - */ - appendDecodedData(data, info) { - const channels = data.channelData.length; - if (channels === 0) return; - if (this.audioData.length !== channels) { - this.audioData = []; - for (let i = 0; i < channels; i++) { - this.audioData.push([]); - } - } - // 计算出应该放在哪 - const chunk = this.sampleRate * this.bufferChunkSize; - const sampled = this.bufferedSamples; - const pushIndex = Math.floor(sampled / chunk); - const bufferIndex = sampled % chunk; - const dataLength = data.channelData[0].length; - let buffered = 0; - let nowIndex = pushIndex; - let toBuffer = bufferIndex; - while (buffered < dataLength) { - const rest = toBuffer !== 0 ? chunk - bufferIndex : chunk; - - for (let i = 0; i < channels; i++) { - const audioData = this.audioData[i]; - if (!audioData[nowIndex]) { - audioData.push(new Float32Array(chunk)); - } - const toPush = data.channelData[i].slice(buffered, buffered + rest); - - audioData[nowIndex].set(toPush, toBuffer); - } - buffered += rest; - nowIndex++; - toBuffer = 0; - } - - this.buffered += - info.reduce((prev, curr) => prev + curr.duration, 0) / 1000; - this.bufferedSamples += info.reduce( - (prev, curr) => prev + curr.samples, - 0 - ); - } - - /** - * 检查已缓冲内容,并在未开始播放时播放 - */ - checkBufferedPlay() { - if (this.playing || this.sampleRate === 0) return; - const played = this.lastBufferSamples / this.sampleRate; - const dt = this.buffered - played; - if (this.loaded) { - this.playAudio(played); - return; - } - if (dt < this.bufferPlayDuration) return; - - this.lastBufferSamples = this.bufferedSamples; - // 需要播放 - this.mergeBuffers(); - if (!this.buffer) return; - if (this.playing) this.output.stop(); - this.createSourceNode(this.buffer); - this.output.loop = false; - this.output.start(0, played); - this.lastStartTime = this.ac.currentTime; - this.playing = true; - this.output.addEventListener("ended", () => { - this.playing = false; - this.checkBufferedPlay(); - }); - } - - mergeBuffers() { - const buffer = this.ac.createBuffer( - this.audioData.length, - this.bufferedSamples, - this.sampleRate - ); - const chunk = this.sampleRate * this.bufferChunkSize; - const bufferedChunks = Math.floor(this.bufferedSamples / chunk); - const restLength = this.bufferedSamples % chunk; - for (let i = 0; i < this.audioData.length; i++) { - const audio = this.audioData[i]; - const data = new Float32Array(this.bufferedSamples); - for (let j = 0; j < bufferedChunks; j++) { - data.set(audio[j], chunk * j); - } - if (restLength !== 0) { - data.set( - audio[bufferedChunks].slice(0, restLength), - chunk * bufferedChunks - ); - } - - buffer.copyToChannel(data, i, 0); - } - this.buffer = buffer; - } - - async start() { - delete this.buffer; - this.headerRecieved = false; - this.audioType = ""; - this.errored = false; - this.buffered = 0; - this.sampleRate = 0; - this.bufferedSamples = 0; - this.duration = 0; - this.loaded = false; - if (this.playing) this.output.stop(); - this.playing = false; - this.lastStartTime = this.ac.currentTime; - } - - end(done, reason) { - if (done && this.buffer) { - this.loaded = true; - delete this.controller; - this.mergeBuffers(); - - this.duration = this.buffered; - this.audioData = []; - this.decoder?.destroy(); - delete this.decoder; - delete this.parser; - } else { - console.warn( - "Unexpected end when loading stream audio, reason: '" + - (reason ?? "") + - "'" - ); - } - } - - playAudio(when) { - if (!this.buffer) return; - this.lastStartTime = this.ac.currentTime; - if (this.playing) this.output.stop(); - if (this.player.status !== AudioStatus.Playing) { - this.player.status = AudioStatus.Playing; - } - this.createSourceNode(this.buffer); - this.output.start(0, when); - this.playing = true; - - this.output.addEventListener("ended", () => { - this.playing = false; - if (this.player.status === AudioStatus.Playing) { - this.player.status = AudioStatus.Stoped; - } - if (this.loop && !this.output.loop) this.play(0); - }); - } - /** - * 开始播放这个音频源 - */ - play(when) { - if (this.playing || this.errored) return; - if (this.loaded && this.buffer) { - this.playing = true; - this.playAudio(when); - } else { - this.controller?.start(); - } - } - - createSourceNode(buffer) { - if (!this.target) return; - const node = this.ac.createBufferSource(); - node.buffer = buffer; - if (this.playing) this.output.stop(); - this.playing = false; - this.output = node; - node.connect(this.target.input); - node.loop = this.loop; - } - /** - * 停止播放这个音频源 - * @returns 音频暂停的时刻 number - */ - stop() { - if (this.playing) this.output.stop(); - this.playing = false; - return this.ac.currentTime - this.lastStartTime; - } - /** - * 连接到音频路由图上,每次调用播放的时候都会执行一次 - * @param target 连接至的目标 IAudioInput - */ - connect(target) { - this.target = target; - } - /** - * 设置是否循环播放 - * @param loop 是否循环 boolean) - */ - setLoop(loop) { - this.loop = loop; - } - } - class AudioElementSource { - constructor(context) { - const audio = new Audio(); - audio.preload = "none"; - this.output = context.createMediaElementSource(audio); - this.audio = audio; - this.ac = context; - audio.addEventListener("play", () => { - this.playing = true; - if (this.player.status !== AudioStatus.Playing) { - this.player.status = AudioStatus.Playing; - } - }); - audio.addEventListener("ended", () => { - this.playing = false; - if (this.player.status === AudioStatus.Playing) { - this.player.status = AudioStatus.Stoped; - } - }); - } - get duration() { - return this.audio.duration; - } - get currentTime() { - return this.audio.currentTime; - } - /** - * 设置音频源的路径 - * @param url 音频路径 - */ - setSource(url) { - this.audio.src = url; - } - - play(when = 0) { - if (this.playing) return; - this.audio.currentTime = when; - this.audio.play(); - } - - stop() { - this.audio.pause(); - this.playing = false; - if (this.player.status === AudioStatus.Playing) { - this.player.status = AudioStatus.Stoped; - } - return this.audio.currentTime; - } - - connect(target) { - this.output.connect(target.input); - } - - setLoop(loop) { - this.audio.loop = loop; - } - } - class AudioBufferSource { - constructor(context) { - this.output = context.createBufferSource(); - /** 是否循环 */ - this.loop = false; - /** 上一次播放是从何时开始的 */ - this.lastStartWhen = 0; - /** 播放开始时刻 */ - this.lastStartTime = 0; - this.duration = 0; - this.ac = context; - } - get currentTime() { - return this.ac.currentTime - this.lastStartTime + this.lastStartWhen; - } - - /** - * 设置音频源数据 - * @param buffer 音频源,可以是未解析的 ArrayBuffer,也可以是已解析的 AudioBuffer - */ - async setBuffer(buffer) { - if (buffer instanceof ArrayBuffer) { - this.buffer = await this.ac.decodeAudioData(buffer); - } else { - this.buffer = buffer; - } - this.duration = this.buffer.duration; - } - - play(when) { - if (this.playing || !this.buffer) return; - this.playing = true; - this.lastStartTime = this.ac.currentTime; - if (this.player.status !== AudioStatus.Playing) { - this.player.status = AudioStatus.Playing; - } - this.createSourceNode(this.buffer); - this.output.start(0, when); - this.output.addEventListener("ended", () => { - this.playing = false; - if (this.player.status === AudioStatus.Playing) { - this.player.status = AudioStatus.Stoped; - } - if (this.loop && !this.output.loop) this.play(0); - }); - } - - createSourceNode(buffer) { - if (!this.target) return; - const node = this.ac.createBufferSource(); - node.buffer = buffer; - this.output = node; - node.connect(this.target.input); - node.loop = this.loop; - } - - stop() { - this.output.stop(); - return this.ac.currentTime - this.lastStartTime; - } - - connect(target) { - this.target = target; - } - - setLoop(loop) { - this.loop = loop; - } - } - class AudioPlayer { - constructor() { - /** 音频播放上下文 */ - this.ac = new AudioContext(); - /** 音量节点 */ - this.gain = this.ac.createGain(); - this.gain.connect(this.ac.destination); - this.audioRoutes = new Map(); - const func = () => { - this.ac.resume(); - document.body.removeEventListener("mousedown", func); - document.body.removeEventListener("touchstart", func); - document.body.removeEventListener("keydown", func); - }; - document.body.addEventListener("mousedown", func, { capture: true }); - document.body.addEventListener("touchstart", func, { capture: true }); - document.body.addEventListener("keydown", func, { capture: true }); - } - /** - * 解码音频数据 - * @param data 音频数据 - */ - decodeAudioData(data) { - return AudioDecoder.decodeAudioData(data, this); - } - /** - * 设置音量 - * @param volume 音量 - */ - setVolume(volume) { - this.gain.gain.value = volume; - } - - /** - * 获取音量 - */ - getVolume() { - return this.gain.gain.value; - } - - /** - * 创建一个音频源 - * @param Source 音频源类 - */ - createSource(Source) { - return new Source(this.ac); - } - - /** - * 创建一个兼容流式音频源,可以与流式加载相结合,主要用于处理 opus ogg 不兼容的情况 - */ - createStreamSource() { - return new AudioStreamSource(this.ac); - } - - /** - * 创建一个通过 audio 元素播放的音频源 - */ - createElementSource() { - return new AudioElementSource(this.ac); - } - - /** - * 创建一个通过 AudioBuffer 播放的音频源 - */ - createBufferSource() { - return new AudioBufferSource(this.ac); - } - - /** - * 获取音频目的地 - */ - getDestination() { - return this.gain; - } - - /** - * 创建一个音频效果器 - * @param Effect 效果器类 - */ - createEffect(Effect) { - return new Effect(this.ac); - } - - /** - * 创建一个修改音量的效果器 - * ```txt - * |----------| - * Input ----> | GainNode | ----> Output - * |----------| - * ``` - */ - createVolumeEffect() { - return new VolumeEffect(this.ac); - } - - /** - * 创建一个立体声效果器 - * ```txt - * |------------| - * Input ----> | PannerNode | ----> Output - * |------------| - * ``` - */ - createStereoEffect() { - return new StereoEffect(this.ac); - } - - /** - * 创建一个修改单个声道音量的效果器 - * ```txt - * |----------| - * -> | GainNode | \ - * |--------------| / |----------| -> |------------| - * Input ----> | SplitterNode | ...... | MergerNode | ----> Output - * |--------------| \ |----------| -> |------------| - * -> | GainNode | / - * |----------| - * ``` - */ - createChannelVolumeEffect() { - return new ChannelVolumeEffect(this.ac); - } - - /** - * 创建一个延迟效果器 - * |-----------| - * Input ----> | DelayNode | ----> Output - * |-----------| - */ - createDelay() { - return new DelayEffect(this.ac); - } - - /** - * 创建一个回声效果器 - * ```txt - * |----------| - * Input ----> | GainNode | ----> Output - * ^ |----------| | - * | | - * | |------------| ↓ - * |-- | Delay Node | <-- - * |------------| - * ``` - */ - createEchoEffect() { - return new EchoEffect(this.ac); - } - - /** - * 创建一个音频播放路由 - * @param source 音频源 - */ - createRoute(source) { - return new AudioRoute(source, this); - } - - /** - * 添加一个音频播放路由,可以直接被播放 - * @param id 这个音频播放路由的名称 - * @param route 音频播放路由对象 - */ - addRoute(id, route) { - if (!this.audioRoutes) this.audioRoutes = new Map(); - if (this.audioRoutes.has(id)) { - console.warn( - "Audio route with id of '" + - id + - "' has already existed. New route will override old route." - ); - } - this.audioRoutes.set(id, route); - } - - /** - * 根据名称获取音频播放路由对象 - * @param id 音频播放路由的名称 - */ - getRoute(id) { - return this.audioRoutes.get(id); - } - /** - * 移除一个音频播放路由 - * @param id 要移除的播放路由的名称 - */ - removeRoute(id) { - this.audioRoutes.delete(id); - } - /** - * 播放音频 - * @param id 音频名称 - * @param when 从音频的哪个位置开始播放,单位秒 - */ - play(id, when) { - const route = this.getRoute(id); - if (!route) { - console.warn( - "Cannot play audio route '" + - id + - "', since there is not added route named it." - ); - return; - } - - route.play(when); - } - - /** - * 暂停音频播放 - * @param id 音频名称 - * @returns 当音乐真正停止时兑现 - */ - pause(id) { - const route = this.getRoute(id); - if (!route) { - console.warn( - "Cannot pause audio route '" + - id + - "', since there is not added route named it." - ); - return; - } - return route.pause(); - } - - /** - * 停止音频播放 - * @param id 音频名称 - * @returns 当音乐真正停止时兑现 - */ - stop(id) { - const route = this.getRoute(id); - if (!route) { - console.warn( - "Cannot stop audio route '" + - id + - "', since there is not added route named it." - ); - return; - } - return route.stop(); - } - - /** - * 继续音频播放 - * @param id 音频名称 - */ - resume(id) { - const route = this.getRoute(id); - if (!route) { - console.warn( - "Cannot pause audio route '" + - id + - "', since there is not added route named it." - ); - return; - } - route.resume(); - } - - /** - * 设置听者位置,x正方向水平向右,y正方向垂直于地面向上,z正方向垂直屏幕远离用户 - * @param x 位置x坐标 - * @param y 位置y坐标 - * @param z 位置z坐标 - */ - setListenerPosition(x, y, z) { - const listener = this.ac.listener; - listener.positionX.value = x; - listener.positionY.value = y; - listener.positionZ.value = z; - } - - /** - * 设置听者朝向,x正方向水平向右,y正方向垂直于地面向上,z正方向垂直屏幕远离用户 - * @param x 朝向x坐标 - * @param y 朝向y坐标 - * @param z 朝向z坐标 - */ - setListenerOrientation(x, y, z) { - const listener = this.ac.listener; - listener.forwardX.value = x; - listener.forwardY.value = y; - listener.forwardZ.value = z; - } - - /** - * 设置听者头顶朝向,x正方向水平向右,y正方向垂直于地面向上,z正方向垂直屏幕远离用户 - * @param x 头顶朝向x坐标 - * @param y 头顶朝向y坐标 - * @param z 头顶朝向z坐标 - */ - setListenerUp(x, y, z) { - const listener = this.ac.listener; - listener.upX.value = x; - listener.upY.value = y; - listener.upZ.value = z; - } - } - class AudioRoute { - constructor(source, player) { - this.output = source.output; - - /** 效果器路由图 */ - this.effectRoute = []; - - /** 结束时长,当音频暂停或停止时,会经过这么长时间之后才真正终止播放,期间可以做音频淡入淡出等效果 */ - this.endTime = 0; - /** 暂停时播放了多长时间 */ - this.pauseCurrentTime = 0; - /** 当前播放状态 */ - this.player = player; - this.player.status = AudioStatus.Stoped; - this.shouldStop = false; - /** - * 每次暂停或停止时自增,用于判断当前正在处理的情况。 - * 假如暂停后很快播放,然后很快暂停,那么需要根据这个来判断实际是否应该执行暂停后操作 - */ - this.stopIdentifier = 0; - /** 暂停时刻 */ - this.pauseTime = 0; - this.source = source; - this.source.player = player; - } - /** 音频时长,单位秒 */ - get duration() { - return this.source.duration; - } - /** 当前播放了多长时间,单位秒 */ - get currentTime() { - if (this.player.status === AudioStatus.Paused) { - return this.pauseCurrentTime; - } else { - return this.source.currentTime; - } - } - set currentTime(time) { - this.source.stop(); - this.source.play(time); - } - /** - * 设置结束时间,暂停或停止时,会经过这么长时间才终止音频的播放,这期间可以做一下音频淡出的效果。 - * @param time 暂停或停止时,经过多长时间之后才会结束音频的播放 - */ - setEndTime(time) { - this.endTime = time; - } - - /** - * 当音频播放时执行的函数,可以用于音频淡入效果 - * @param fn 音频开始播放时执行的函数 - */ - onStart(fn) { - this.audioStartHook = fn; - } - - /** - * 当音频暂停或停止时执行的函数,可以用于音频淡出效果 - * @param fn 音频在暂停或停止时执行的函数,不填时表示取消这个钩子。 - * 包含两个参数,第一个参数是结束时长,第二个参数是当前音频播放路由对象 - */ - onEnd(fn) { - this.audioEndHook = fn; - } - - /** - * 开始播放这个音频 - * @param when 从音频的什么时候开始播放,单位秒 - */ - play(when = 0) { - if (this.player.status === AudioStatus.Playing) return; - this.link(); - if (this.effectRoute.length > 0) { - const first = this.effectRoute[0]; - this.source.connect(first); - const last = this.effectRoute.at(-1); - last.connect({ input: this.player.getDestination() }); - } else { - this.source.connect({ input: this.player.getDestination() }); - } - this.source.play(when); - this.player.status = AudioStatus.Playing; - this.pauseTime = 0; - this.audioStartHook?.(this); - this.startAllEffect(); - if (this.source.player.status !== AudioStatus.Playing) { - this.source.player.status = AudioStatus.Playing; - } - } - - /** - * 暂停音频播放 - */ - async pause() { - if (this.player.status !== AudioStatus.Playing) return; - this.player.status = AudioStatus.Pausing; - this.stopIdentifier++; - const identifier = this.stopIdentifier; - if (this.audioEndHook) { - this.audioEndHook(this.endTime, this); - await sleep(this.endTime); - } - if ( - this.player.status !== AudioStatus.Pausing || - this.stopIdentifier !== identifier - ) { - return; - } - this.pauseCurrentTime = this.source.currentTime; - const time = this.source.stop(); - this.pauseTime = time; - if (this.shouldStop) { - this.player.status = AudioStatus.Stoped; - this.endAllEffect(); - - this.shouldStop = false; - } else { - this.player.status = AudioStatus.Paused; - this.endAllEffect(); - } - this.endAllEffect(); - } - - /** - * 继续音频播放 - */ - resume() { - if (this.player.status === AudioStatus.Playing) return; - if ( - this.player.status === AudioStatus.Pausing || - this.player.status === AudioStatus.Stoping - ) { - this.audioStartHook?.(this); - - return; - } - if (this.player.status === AudioStatus.Paused) { - this.play(this.pauseTime); - } else { - this.play(0); - } - this.player.status = AudioStatus.Playing; - this.pauseTime = 0; - this.audioStartHook?.(this); - this.startAllEffect(); - } - - /** - * 停止音频播放 - */ - async stop() { - if (this.status !== AudioStatus.Playing) { - if (this.status === AudioStatus.Pausing) { - this.shouldStop = true; - } - return; - } - this.status = AudioStatus.Stoping; - this.stopIdentifier++; - const identifier = this.stopIdentifier; - if (this.audioEndHook) { - this.audioEndHook(this.endTime, this); - await sleep(this.endTime); - } - if ( - this.status !== AudioStatus.Stoping || - this.stopIdentifier !== identifier - ) { - return; - } - this.source.stop(); - this.status = AudioStatus.Stoped; - this.pauseTime = 0; - this.endAllEffect(); - } - - /** - * 添加效果器 - * @param effect 要添加的效果,可以是数组,表示一次添加多个 - * @param index 从哪个位置开始添加,如果大于数组长度,那么加到末尾,如果小于0,那么将会从后面往前数。默认添加到末尾 - */ - addEffect(effect, index) { - if (isNil(index)) { - if (effect instanceof Array) { - this.effectRoute.push(...effect); - } else { - this.effectRoute.push(effect); - } - } else { - if (effect instanceof Array) { - this.effectRoute.splice(index, 0, ...effect); - } else { - this.effectRoute.splice(index, 0, effect); - } - } - this.setOutput(); - if (this.source.playing) this.link(); - } - - /** - * 移除一个效果器 - * @param effect 要移除的效果 - */ - removeEffect(effect) { - const index = this.effectRoute.indexOf(effect); - if (index === -1) return; - this.effectRoute.splice(index, 1); - effect.disconnect(); - this.setOutput(); - if (this.source.playing) this.link(); - } - - setOutput() { - const effect = this.effectRoute.at(-1); - if (!effect) this.output = this.source.output; - else this.output = effect.output; - } - - /** - * 连接音频路由图 - */ - link() { - this.effectRoute.forEach((v) => v.disconnect()); - this.effectRoute.forEach((v, i) => { - const next = this.effectRoute[i + 1]; - if (next) { - v.connect(next); - } - }); - } - - startAllEffect() { - this.effectRoute.forEach((v) => v.start()); - } - - endAllEffect() { - this.effectRoute.forEach((v) => v.end()); - } - } - - const audioPlayer = new AudioPlayer(); - - class BgmController { - constructor(player) { - this.mainGain = player.createVolumeEffect(); - this.player = player; - /** bgm音频名称的前缀 */ - this.prefix = "bgms."; - /** 每个 bgm 的音量控制器 */ - this.gain = new Map(); - - /** 正在播放的 bgm */ - this.playingBgm = ""; - /** 是否正在播放 */ - this.playing = false; - - /** 是否已经启用 */ - this.enabled = true; - /** 是否屏蔽所有的音乐切换 */ - this.blocking = false; - /** 渐变时长 */ - this.transitionTime = 2000; - } - - /** - * 设置音频渐变时长 - * @param time 渐变时长 - */ - setTransitionTime(time) { - this.transitionTime = time; - for (const [, value] of this.gain) { - value.transition.time(time); - } - } - - /** - * 屏蔽音乐切换 - */ - blockChange() { - this.blocking = true; - } - - /** - * 取消屏蔽音乐切换 - */ - unblockChange() { - this.blocking = false; - } - - /** - * 设置总音量大小 - * @param volume 音量大小 - */ - setVolume(volume) { - this.mainGain.setVolume(volume); - this._volume = volume; - } - /** - * 获取总音量大小 - */ - getVolume() { - return this.mainGain.getVolume(); - } - /** - * 设置是否启用 - * @param enabled 是否启用 - */ - setEnabled(enabled) { - if (enabled) this.resume(); - else this.stop(); - this.enabled = enabled; - } - - /** - * 设置 bgm 音频名称的前缀 - */ - setPrefix(prefix) { - this.prefix = prefix; - } - - getId(name) { - return `${this.prefix}${name}`; - } - - /** - * 根据 bgm 名称获取其 AudioRoute 实例 - * @param id 音频名称 - */ - get(id) { - return this.player.getRoute(this.getId(id)); - } - - /** - * 添加一个 bgm - * @param id 要添加的 bgm 的名称 - * @param url 指定 bgm 的加载地址 - */ - addBgm(id, url = `project/bgms/${id}`) { - const type = guessTypeByExt(id); - if (!type) { - console.warn( - "Unknown audio extension name: '" + - id.split(".").slice(0, -1).join(".") + - "'" - ); - return; - } - const gain = this.player.createVolumeEffect(); - if (isAudioSupport(type)) { - const source = audioPlayer.createElementSource(); - source.setSource(url); - source.setLoop(true); - const route = new AudioRoute(source, audioPlayer); - route.addEffect([gain, this.mainGain]); - audioPlayer.addRoute(this.getId(id), route); - this.setTransition(id, route, gain); - } else { - const source = audioPlayer.createStreamSource(); - const stream = new StreamLoader(url); - stream.pipe(source); - source.setLoop(true); - const route = new AudioRoute(source, audioPlayer); - route.addEffect([gain, this.mainGain]); - audioPlayer.addRoute(this.getId(id), route); - this.setTransition(id, route, gain); - } - } - - /** - * 移除一个 bgm - * @param id 要移除的 bgm 的名称 - */ - removeBgm(id) { - this.player.removeRoute(this.getId(id)); - const gain = this.gain.get(id); - gain?.transition.ticker.destroy(); - this.gain.delete(id); - } - - setTransition(id, route, gain) { - const transition = new Transition(); - transition - .time(this.transitionTime) - .mode(linear()) - .transition("volume", 0); - - const tick = () => { - gain.setVolume(transition.value.volume); - }; - - /** - * @param expect 在结束时应该是正在播放还是停止 - */ - const setTick = async (expect) => { - transition.ticker.remove(tick); - transition.ticker.add(tick); - const identifier = route.stopIdentifier; - await sleep(this.transitionTime + 500); - if (route.status === expect && identifier === route.stopIdentifier) { - transition.ticker.remove(tick); - if (route.status === AudioStatus.Playing) { - gain.setVolume(1); - } else { - gain.setVolume(0); - } - } - }; - - route.onStart(async () => { - transition.transition("volume", 1); - setTick(AudioStatus.Playing); - }); - route.onEnd(() => { - transition.transition("volume", 0); - setTick(AudioStatus.Paused); - }); - route.setEndTime(this.transitionTime); - - this.gain.set(id, { effect: gain, transition }); - } - - /** - * 播放一个 bgm - * @param id 要播放的 bgm 名称 - */ - play(id, when) { - if (this.blocking) return; - if (id !== this.playingBgm && this.playingBgm) { - this.player.pause(this.getId(this.playingBgm)); - } - this.playingBgm = id; - if (!this.enabled) return; - this.player.play(this.getId(id), when); - this.playing = true; - if (this.player.status !== AudioStatus.Playing) { - this.player.status = AudioStatus.Playing; - } - } - - /** - * 继续当前的 bgm - */ - resume() { - if (this.blocking || !this.enabled || this.playing) return; - if (this.playingBgm) { - this.player.resume(this.getId(this.playingBgm)); - } - this.playing = true; - } - - /** - * 暂停当前的 bgm - */ - pause() { - if (this.blocking || !this.enabled) return; - if (this.playingBgm) { - this.player.pause(this.getId(this.playingBgm)); - } - this.playing = false; - } - - /** - * 停止当前的 bgm - */ - stop() { - if (this.blocking || !this.enabled) return; - if (this.playingBgm) { - this.player.stop(this.getId(this.playingBgm)); - } - this.playing = false; - } - } - const bgmController = new BgmController(audioPlayer); - - class SoundPlayer { - constructor(player) { - /** 每个音效的唯一标识符 */ - this.num = 0; - this.enabled = true; - this.gain = player.createVolumeEffect(); - /** 每个音效的数据 */ - this.buffer = new Map(); - /** 所有正在播放的音乐 */ - this.playing = new Set(); - this.player = player; - } - /** - * 设置是否启用音效 - * @param enabled 是否启用音效 - */ - setEnabled(enabled) { - if (!enabled) this.stopAllSounds(); - this.enabled = enabled; - } - - /** - * 设置音量大小 - * @param volume 音量大小 - */ - setVolume(volume) { - this.gain.setVolume(volume); - } - /** - * 获取音量大小 - */ - getVolume() { - return this.gain.getVolume(); - } - /** - * 添加一个音效 - * @param id 音效名称 - * @param data 音效的Uint8Array数据 - */ - async add(id, data) { - const buffer = await this.player.decodeAudioData(data); - if (!buffer) { - console.warn( - "Cannot decode sound '" + - id + - "', since audio file may not supported by 2.b." - ); - return; - } - this.buffer.set(id, buffer); - } - - /** - * 播放一个音效 - * @param id 音效名称 - * @param position 音频位置,[0, 0, 0]表示正中心,x轴指向水平向右,y轴指向水平向上,z轴指向竖直向上 - * @param orientation 音频朝向,[0, 1, 0]表示朝向前方 - */ - play(id, position = [0, 0, 0], orientation = [1, 0, 0]) { - if (!this.enabled) return -1; - const buffer = this.buffer.get(id); - if (!buffer) { - console.warn( - "Cannot play sound '" + - id + - "', since there is no added data named it." - ); - return -1; - } - const soundNum = this.num++; - - const source = this.player.createBufferSource(); - source.setBuffer(buffer); - const route = this.player.createRoute(source); - const stereo = this.player.createStereoEffect(); - stereo.setPosition(position[0], position[1], position[2]); - stereo.setOrientation(orientation[0], orientation[1], orientation[2]); - route.addEffect([stereo, this.gain]); - this.player.addRoute(`sounds.${soundNum}`, route); - route.play(); - source.output.addEventListener("ended", () => { - this.playing.delete(soundNum); - }); - this.playing.add(soundNum); - return soundNum; - } - - /** - * 停止一个音效 - * @param num 音效的唯一 id - */ - stop(num) { - const id = `sounds.${num}`; - const route = this.player.getRoute(id); - if (route) { - route.stop(); - this.player.removeRoute(id); - this.playing.delete(num); - } - } - - /** - * 停止播放所有音效 - */ - stopAllSounds() { - this.playing.forEach((v) => { - const id = `sounds.${v}`; - const route = this.player.getRoute(id); - if (route) { - route.stop(); - this.player.removeRoute(id); - } - }); - this.playing.clear(); - } - } - const soundPlayer = new SoundPlayer(audioPlayer); - - function loadAllBgm() { - const data = data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d; - for (const bgm of data.main.bgms) { - bgmController.addBgm(bgm); - } - } - loadAllBgm(); - AudioDecoder.registerDecoder(AudioType.Ogg, VorbisDecoder); - AudioDecoder.registerDecoder(AudioType.Opus, OpusDecoder); - - core.plugin.audioSystem = { - AudioType, - AudioDecoder, - AudioStatus, - checkAudioType, - isAudioSupport, - audioPlayer, - soundPlayer, - bgmController, - guessTypeByExt, - BgmController, - SoundPlayer, - EchoEffect, - DelayEffect, - ChannelVolumeEffect, - VolumeEffect, - StereoEffect, - AudioEffect, - AudioPlayer, - AudioRoute, - AudioStreamSource, - AudioElementSource, - AudioBufferSource, - loadAllBgm, - StreamLoader, - }; - //bgm相关复写 - control.prototype.playBgm = (bgm, when) => { - bgmController.play(bgm, when); - core.setMusicBtn(); - }; - control.prototype.pauseBgm = () => { - bgmController.pause(); - core.setMusicBtn(); - }; - - control.prototype.resumeBgm = function () { - bgmController.resume(); - core.setMusicBtn(); - }; - control.prototype.checkBgm = function () { - if (bgmController.playing) return; - if (core.musicStatus.bgmStatus) { - if (bgmController.playingBgm) { - bgmController.play(bgmController.playingBgm); - } else { - play(main.startBgm, 0); - } - } else { - pause(); - } - }; - control.prototype.triggerBgm = function () { - core.musicStatus.bgmStatus = !core.musicStatus.bgmStatus; - if (bgmController.playing) bgmController.pause(); - else bgmController.resume(); - core.setMusicBtn(); - core.setLocalStorage("bgmStatus", core.musicStatus.bgmStatus); - }; - //sound相关复写 - control.prototype.playSound = function ( - sound, - _pitch, - callback, - position, - orientation - ) { - if (main.mode != "play" || !core.musicStatus.soundStatus) return; - const name = core.getMappedName(sound); - const num = soundPlayer.play(name, position, orientation); - const route = audioPlayer.getRoute(`sounds.${num}`); - if (!route) { - callback?.(); - return -1; - } else { - sleep(route.duration).then(() => callback?.()); - return num; - } - }; - control.prototype.stopSound = function (id) { - if (isNil(id)) { - soundPlayer.stopAllSounds(); - } else { - soundPlayer.stop(id); - } - }; - control.prototype.getPlayingSounds = function () { - return [...soundPlayer.playing]; - }; - //sound加载复写 - loader.prototype._loadOneSound_decodeData = function (name, data) { - if (data instanceof Blob) { - var blobReader = new zip.BlobReader(data); - blobReader.init(function () { - blobReader.readUint8Array(0, blobReader.size, function (uint8) { - //core.loader._loadOneSound_decodeData(name, uint8.buffer); - soundPlayer.add(name, uint8); - }); - }); - return; - } - if (data instanceof ArrayBuffer) { - const uint8 = new Uint8Array(data); - soundPlayer.add(name, uint8); - } - }; - //音量控制复写 - soundPlayer.setVolume( - core.musicStatus.userVolume * core.musicStatus.designVolume - ); - bgmController.setVolume( - core.musicStatus.userVolume * core.musicStatus.designVolume - ); - actions.prototype._clickSwitchs_sounds_userVolume = function (delta) { - var value = Math.round(Math.sqrt(100 * core.musicStatus.userVolume)); - if (value == 0 && delta < 0) return; - core.musicStatus.userVolume = core.clamp( - Math.pow(value + delta, 2) / 100, - 0, - 1 - ); - //audioContext 音效 不受designVolume 影响 - if (core.musicStatus.gainNode != null) - core.musicStatus.gainNode.gain.value = core.musicStatus.userVolume; - soundPlayer.setVolume( - core.musicStatus.userVolume * core.musicStatus.designVolume - ); - bgmController.setVolume( - core.musicStatus.userVolume * core.musicStatus.designVolume - ); - core.setLocalStorage("userVolume", core.musicStatus.userVolume); - core.playSound("确定"); - core.ui._drawSwitchs_sounds(); - }; - }, + // 将__enable置为false将关闭插件 + let __enable = true; + if (!__enable || main.mode === "editor") return; + const { OggOpusDecoderWebWorker } = window["ogg-opus-decoder"]; + const { OggVorbisDecoderWebWorker } = window["ogg-vorbis-decoder"]; + const { CodecParser } = window.CodecParser; + const { Transition, linear } = core.plugin.animate; + + const audio = new Audio(); + const AudioStatus = { + Playing: 0, + Pausing: 1, + Paused: 2, + Stoping: 3, + Stoped: 4, + }; + const supportMap = new Map(); + const AudioType = { + Mp3: "audio/mpeg", + Wav: 'audio/wav; codecs="1"', + Flac: "audio/flac", + Opus: 'audio/ogg; codecs="opus"', + Ogg: 'audio/ogg; codecs="vorbis"', + Aac: "audio/aac", + }; + /** + * 检查一种音频类型是否能被播放 + * @param type 音频类型 AudioType + */ + function isAudioSupport(type) { + if (supportMap.has(type)) return supportMap.get(type); + else { + const support = audio.canPlayType(type); + const canPlay = support === "maybe" || support === "probably"; + supportMap.set(type, canPlay); + return canPlay; + } + } + + const typeMap = new Map([ + ["ogg", AudioType.Ogg], + ["mp3", AudioType.Mp3], + ["wav", AudioType.Wav], + ["flac", AudioType.Flac], + ["opus", AudioType.Opus], + ["aac", AudioType.Aac], + ]); + + /** + * 根据文件名拓展猜测其类型 + * @param file 文件名 string + */ + function guessTypeByExt(file) { + const ext = /\.[a-zA-Z\d]+$/.exec(file); + if (!ext?.[0]) return ""; + const type = ext[0].slice(1); + return typeMap.get(type.toLocaleLowerCase()) ?? ""; + } + + isAudioSupport(AudioType.Ogg); + isAudioSupport(AudioType.Mp3); + isAudioSupport(AudioType.Wav); + isAudioSupport(AudioType.Flac); + isAudioSupport(AudioType.Opus); + isAudioSupport(AudioType.Aac); + + function isNil(value) { + return value === void 0 || value === null; + } + + function sleep(time) { + return new Promise((res) => setTimeout(res, time)); + } + class AudioEffect { + constructor(ac) {} + /** + * 连接至其他效果器 + * @param target 目标输入 IAudioInput + * @param output 当前效果器输出通道 Number + * @param input 目标效果器的输入通道 Number + */ + connect(target, output, input) { + this.output.connect(target.input, output, input); + } + + /** + * 与其他效果器取消连接 + * @param target 目标输入 IAudioInput + * @param output 当前效果器输出通道 Number + * @param input 目标效果器的输入通道 Number + */ + disconnect(target, output, input) { + if (!target) { + if (!isNil(output)) { + this.output.disconnect(output); + } else { + this.output.disconnect(); + } + } else { + if (!isNil(output)) { + if (!isNil(input)) { + this.output.disconnect(target.input, output, input); + } else { + this.output.disconnect(target.input, output); + } + } else { + this.output.disconnect(target.input); + } + } + } + } + + class StereoEffect extends AudioEffect { + constructor(ac) { + super(ac); + const panner = ac.createPanner(); + this.input = panner; + this.output = panner; + } + + /** + * 设置音频朝向,x正方形水平向右,y正方形垂直于地面向上,z正方向垂直屏幕远离用户 + * @param x 朝向x坐标 Number + * @param y 朝向y坐标 Number + * @param z 朝向z坐标 Number + */ + setOrientation(x, y, z) { + this.output.orientationX.value = x; + this.output.orientationY.value = y; + this.output.orientationZ.value = z; + } + /** + * 设置音频位置,x正方形水平向右,y正方形垂直于地面向上,z正方向垂直屏幕远离用户 + * @param x 位置x坐标 Number + * @param y 位置y坐标 Number + * @param z 位置z坐标 Number + */ + setPosition(x, y, z) { + this.output.positionX.value = x; + this.output.positionY.value = y; + this.output.positionZ.value = z; + } + end() {} + + start() {} + } + class VolumeEffect extends AudioEffect { + constructor(ac) { + super(ac); + const gain = ac.createGain(); + this.input = gain; + this.output = gain; + } + + /** + * 设置音量大小 + * @param volume 音量大小 Number + */ + setVolume(volume) { + this.output.gain.value = volume; + } + + /** + * 获取音量大小 Number + */ + getVolume() { + return this.output.gain.value; + } + + end() {} + + start() {} + } + class ChannelVolumeEffect extends AudioEffect { + /** 所有的音量控制节点 */ + + constructor(ac) { + super(ac); + /** 所有的音量控制节点 */ + this.gain = []; + const splitter = ac.createChannelSplitter(); + const merger = ac.createChannelMerger(); + this.output = merger; + this.input = splitter; + for (let i = 0; i < 6; i++) { + const gain = ac.createGain(); + splitter.connect(gain, i); + gain.connect(merger, 0, i); + this.gain.push(gain); + } + } + + /** + * 设置某个声道的音量大小 + * @param channel 要设置的声道,可填0-5 Number + * @param volume 这个声道的音量大小 Number + */ + setVolume(channel, volume) { + if (!this.gain[channel]) return; + this.gain[channel].gain.value = volume; + } + + /** + * 获取某个声道的音量大小,可填0-5 + * @param channel 要获取的声道 Number + */ + getVolume(channel) { + if (!this.gain[channel]) return 0; + return this.gain[channel].gain.value; + } + + end() {} + + start() {} + } + class DelayEffect extends AudioEffect { + constructor(ac) { + super(ac); + + const delay = ac.createDelay(); + this.input = delay; + this.output = delay; + } + + /** + * 设置延迟时长 + * @param delay 延迟时长,单位秒 Number + */ + setDelay(delay) { + this.output.delayTime.value = delay; + } + + /** + * 获取延迟时长 + */ + getDelay() { + return this.output.delayTime.value; + } + + end() {} + + start() {} + } + class EchoEffect extends AudioEffect { + constructor(ac) { + super(ac); + /** 当前增益 */ + this.gain = 0.5; + /** 是否正在播放 */ + this.playing = false; + const delay = ac.createDelay(); + const gain = ac.createGain(); + gain.gain.value = 0.5; + delay.delayTime.value = 0.05; + delay.connect(gain); + gain.connect(delay); + /** 延迟节点 */ + this.delay = delay; + /** 反馈增益节点 */ + this.gainNode = gain; + + this.input = gain; + this.output = gain; + } + + /** + * 设置回声反馈增益大小 + * @param gain 增益大小,范围 0-1,大于等于1的视为0.5,小于0的视为0 Number + */ + setFeedbackGain(gain) { + const resolved = gain >= 1 ? 0.5 : gain < 0 ? 0 : gain; + this.gain = resolved; + if (this.playing) this.gainNode.gain.value = resolved; + } + + /** + * 设置回声间隔时长 + * @param delay 回声时长,范围 0.01-Infinity,小于0.01的视为0.01 Number + */ + setEchoDelay(delay) { + const resolved = delay < 0.01 ? 0.01 : delay; + this.delay.delayTime.value = resolved; + } + + /** + * 获取反馈节点增益 + */ + getFeedbackGain() { + return this.gain; + } + + /** + * 获取回声间隔时长 + */ + getEchoDelay() { + return this.delay.delayTime.value; + } + + end() { + this.playing = false; + const echoTime = Math.ceil(Math.log(0.001) / Math.log(this.gain)) + 10; + sleep(this.delay.delayTime.value * echoTime).then(() => { + if (!this.playing) this.gainNode.gain.value = 0; + }); + } + + start() { + this.playing = true; + this.gainNode.gain.value = this.gain; + } + } + + class StreamLoader { + constructor(url) { + /** 传输目标 Set*/ + this.target = new Set(); + this.loading = false; + } + + /** + * 将加载流传递给字节流读取对象 + * @param reader 字节流读取对象 IStreamReader + */ + pipe(reader) { + if (this.loading) { + console.warn( + "Cannot pipe new StreamReader object when stream is loading." + ); + return; + } + this.target.add(reader); + reader.piped(this); + return this; + } + + async start() { + if (this.loading) return; + this.loading = true; + const response = await window.fetch(this.url); + const stream = response.body; + if (!stream) { + console.error("Cannot get reader when fetching '" + this.url + "'."); + return; + } + // 获取读取器 + /** 读取流对象 */ + this.stream = stream; + const reader = response.body?.getReader(); + const targets = [...this.target]; + + await Promise.all(targets.map((v) => v.start(stream, this, response))); + if (reader && reader.read) { + // 开始流传输 + while (true) { + const { value, done } = await reader.read(); + await Promise.all( + targets.map((v) => v.pump(value, done, response)) + ); + if (done) break; + } + } else { + // 如果不支持流传输 + const buffer = await response.arrayBuffer(); + const data = new Uint8Array(buffer); + await Promise.all(targets.map((v) => v.pump(data, true, response))); + } + // 开始流传输 + while (true) { + const { value, done } = await reader.read(); + await Promise.all(targets.map((v) => v.pump(value, done, response))); + if (done) break; + } + + this.loading = false; + targets.forEach((v) => v.end(true)); + + // + } + + cancel(reason) { + if (!this.stream) return; + this.stream.cancel(reason); + this.loading = false; + this.target.forEach((v) => v.end(false, reason)); + } + } + const fileSignatures = [ + [AudioType.Mp3, [0x49, 0x44, 0x33]], + [AudioType.Ogg, [0x4f, 0x67, 0x67, 0x53]], + [AudioType.Wav, [0x52, 0x49, 0x46, 0x46]], + [AudioType.Flac, [0x66, 0x4c, 0x61, 0x43]], + [AudioType.Aac, [0xff, 0xf1]], + [AudioType.Aac, [0xff, 0xf9]], + ]; + const oggHeaders = [ + [AudioType.Opus, [0x4f, 0x70, 0x75, 0x73, 0x48, 0x65, 0x61, 0x64]], + ]; + + function checkAudioType(data) { + let audioType = ""; + // 检查头文件获取音频类型,仅检查前256个字节 + const toCheck = data.slice(0, 256); + for (const [type, value] of fileSignatures) { + if (value.every((v, i) => toCheck[i] === v)) { + audioType = type; + break; + } + } + if (audioType === AudioType.Ogg) { + // 如果是ogg的话,进一步判断是不是opus + for (const [key, value] of oggHeaders) { + const has = toCheck.some((_, i) => { + return value.every((v, ii) => toCheck[i + ii] === v); + }); + if (has) { + audioType = key; + break; + } + } + } + + return audioType; + } + class AudioDecoder { + /** + * 注册一个解码器 + * @param type 要注册的解码器允许解码的类型 + * @param decoder 解码器对象 + */ + static registerDecoder(type, decoder) { + if (!this.decoderMap) this.decoderMap = new Map(); + if (this.decoderMap.has(type)) { + console.warn( + "Audio stream decoder for audio type '" + + type + + "' has already existed." + ); + return; + } + + this.decoderMap.set(type, decoder); + } + + /** + * 解码音频数据 + * @param data 音频文件数据 + * @param player AudioPlayer实例 + */ + static async decodeAudioData(data, player) { + // 检查头文件获取音频类型,仅检查前256个字节 + const toCheck = data.slice(0, 256); + const type = checkAudioType(data); + if (type === "") { + console.error( + "Unknown audio type. Header: '" + [...toCheck] + .map((v) => v.toString().padStart(2, "0")) + .join(" ") + .toUpperCase() + + "'" + ); + return null; + } + if (isAudioSupport(type)) { + if (data.buffer instanceof ArrayBuffer) { + return player.ac.decodeAudioData(data.buffer); + } else { + return null; + } + } else { + const Decoder = this.decoderMap.get(type); + if (!Decoder) { + return null; + } else { + const decoder = new Decoder(); + await decoder.create(); + const decodedData = await decoder.decode(data); + if (!decodedData) return null; + const buffer = player.ac.createBuffer( + decodedData.channelData.length, + decodedData.channelData[0].length, + decodedData.sampleRate + ); + decodedData.channelData.forEach((v, i) => { + buffer.copyToChannel(v, i); + }); + decoder.destroy(); + return buffer; + } + } + } + } + + class VorbisDecoder { + /** + * 创建音频解码器 + */ + async create() { + this.decoder = new OggVorbisDecoderWebWorker(); + await this.decoder.ready; + } + /** + * 摧毁这个解码器 + */ + destroy() { + this.decoder?.free(); + } + /** + * 解码流数据 + * @param data 流数据 + */ + + async decode(data) { + return this.decoder?.decode(data); + } + /** + * 解码整个文件 + * @param data 文件数据 + */ + async decodeAll(data) { + return this.decoder?.decodeFile(data); + } + /** + * 当音频解码完成后,会调用此函数,需要返回之前还未解析或未返回的音频数据。调用后,该解码器将不会被再次使用 + */ + async flush() { + return this.decoder?.flush(); + } + } + + class OpusDecoder { + /** + * 创建音频解码器 + */ + async create() { + this.decoder = new OggOpusDecoderWebWorker(); + await this.decoder.ready; + } + /** + * 摧毁这个解码器 + */ + destroy() { + this.decoder?.free(); + } + /** + * 解码流数据 + * @param data 流数据 + */ + async decode(data) { + return this.decoder?.decode(data); + } + /** + * 解码整个文件 + * @param data 文件数据 + */ + async decodeAll(data) { + return this.decoder?.decodeFile(data); + } + /** + * 当音频解码完成后,会调用此函数,需要返回之前还未解析或未返回的音频数据。调用后,该解码器将不会被再次使用 + */ + async flush() { + return await this.decoder?.flush(); + } + } + const mimeTypeMap = { + [AudioType.Aac]: "audio/aac", + [AudioType.Flac]: "audio/flac", + [AudioType.Mp3]: "audio/mpeg", + [AudioType.Ogg]: "application/ogg", + [AudioType.Opus]: "application/ogg", + [AudioType.Wav]: "application/ogg", + }; + + function isOggPage(data) { + return !isNil(data.isFirstPage); + } + class AudioStreamSource { + constructor(context) { + this.output = context.createBufferSource(); + /** 是否已经完全加载完毕 */ + this.loaded = false; + /** 是否正在播放 */ + this.playing = false; + /** 已经缓冲了多长时间,如果缓冲完那么跟歌曲时长一致 */ + this.buffered = 0; + /** 已经缓冲的采样点数量 */ + this.bufferedSamples = 0; + /** 歌曲时长,加载完毕之前保持为 0 */ + this.duration = 0; + /** 在流传输阶段,至少缓冲多长时间的音频之后才开始播放,单位秒 */ + this.bufferPlayDuration = 1; + /** 音频的采样率,未成功解析出之前保持为 0 */ + this.sampleRate = 0; + //是否循环播放 + this.loop = false; + /** 上一次播放是从何时开始的 */ + this.lastStartWhen = 0; + /** 开始播放时刻 */ + this.lastStartTime = 0; + /** 上一次播放的缓存长度 */ + this.lastBufferSamples = 0; + + /** 是否已经获取到头文件 */ + this.headerRecieved = false; + /** 音频类型 */ + this.audioType = ""; + /** 每多长时间组成一个缓存 Float32Array */ + this.bufferChunkSize = 10; + /** 缓存音频数据,每 bufferChunkSize 秒钟组成一个 Float32Array,用于流式解码 */ + this.audioData = []; + + this.errored = false; + this.ac = context; + } + /** 当前已经播放了多长时间 */ + get currentTime() { + return this.ac.currentTime - this.lastStartTime + this.lastStartWhen; + } + /** + * 设置每个缓存数据的大小,默认为10秒钟一个缓存数据 + * @param size 每个缓存数据的时长,单位秒 + */ + setChunkSize(size) { + if (this.controller?.loading || this.loaded) return; + this.bufferChunkSize = size; + } + on(event, fn, context) {} + piped(controller) { + this.controller = controller; + } + + async pump(data, done) { + if (!data || this.errored) return; + if (!this.headerRecieved) { + // 检查头文件获取音频类型,仅检查前256个字节 + const toCheck = data.slice(0, 256); + this.audioType = checkAudioType(data); + if (!this.audioType) { + console.error( + "Unknown audio type. Header: '" + [...toCheck] + .map((v) => v.toString(16).padStart(2, "0")) + .join(" ") + .toUpperCase() + + "'" + ); + return; + } + // 创建解码器 + const Decoder = AudioDecoder.decoderMap.get(this.audioType); + if (!Decoder) { + this.errored = true; + console.error( + "Cannot decode stream source type of '" + + this.audioType + + "', since there is no registered decoder for that type." + ); + return Promise.reject( + `Cannot decode stream source type of '${this.audioType}', since there is no registered decoder for that type.` + ); + } + this.decoder = new Decoder(); + // 创建数据解析器 + const mime = mimeTypeMap[this.audioType]; + const parser = new CodecParser(mime); + this.parser = parser; + await this.decoder.create(); + this.headerRecieved = true; + } + + const decoder = this.decoder; + const parser = this.parser; + if (!decoder || !parser) { + this.errored = true; + return Promise.reject( + "No parser or decoder attached in this AudioStreamSource" + ); + } + + await this.decodeData(data, decoder, parser); + if (done) await this.decodeFlushData(decoder, parser); + this.checkBufferedPlay(); + } + + /** + * 检查采样率,如果还未解析出采样率,那么将设置采样率,如果当前采样率与之前不同,那么发出警告 + */ + checkSampleRate(info) { + for (const one of info) { + const frame = isOggPage(one) ? one.codecFrames[0] : one; + if (frame) { + const rate = frame.header.sampleRate; + if (this.sampleRate === 0) { + this.sampleRate = rate; + break; + } else { + if (rate !== this.sampleRate) { + console.warn("Sample rate in stream audio must be constant."); + } + } + } + } + } + + /** + * 解析音频数据 + */ + async decodeData(data, decoder, parser) { + // 解析音频数据 + const audioData = await decoder.decode(data); + if (!audioData) return; + // @ts-expect-error 库类型声明错误 + const audioInfo = [...parser.parseChunk(data)]; + + // 检查采样率 + this.checkSampleRate(audioInfo); + // 追加音频数据 + this.appendDecodedData(audioData, audioInfo); + } + + /** + * 解码剩余数据 + */ + async decodeFlushData(decoder, parser) { + const audioData = await decoder.flush(); + if (!audioData) return; + // @ts-expect-error 库类型声明错误 + const audioInfo = [...parser.flush()]; + + this.checkSampleRate(audioInfo); + this.appendDecodedData(audioData, audioInfo); + } + + /** + * 追加音频数据 + */ + appendDecodedData(data, info) { + const channels = data.channelData.length; + if (channels === 0) return; + if (this.audioData.length !== channels) { + this.audioData = []; + for (let i = 0; i < channels; i++) { + this.audioData.push([]); + } + } + // 计算出应该放在哪 + const chunk = this.sampleRate * this.bufferChunkSize; + const sampled = this.bufferedSamples; + const pushIndex = Math.floor(sampled / chunk); + const bufferIndex = sampled % chunk; + const dataLength = data.channelData[0].length; + let buffered = 0; + let nowIndex = pushIndex; + let toBuffer = bufferIndex; + while (buffered < dataLength) { + const rest = toBuffer !== 0 ? chunk - bufferIndex : chunk; + + for (let i = 0; i < channels; i++) { + const audioData = this.audioData[i]; + if (!audioData[nowIndex]) { + audioData.push(new Float32Array(chunk)); + } + const toPush = data.channelData[i].slice(buffered, buffered + rest); + + audioData[nowIndex].set(toPush, toBuffer); + } + buffered += rest; + nowIndex++; + toBuffer = 0; + } + + this.buffered += + info.reduce((prev, curr) => prev + curr.duration, 0) / 1000; + this.bufferedSamples += info.reduce( + (prev, curr) => prev + curr.samples, + 0 + ); + } + + /** + * 检查已缓冲内容,并在未开始播放时播放 + */ + checkBufferedPlay() { + if (this.playing || this.sampleRate === 0) return; + const played = this.lastBufferSamples / this.sampleRate; + const dt = this.buffered - played; + if (this.loaded) { + this.playAudio(played); + return; + } + if (dt < this.bufferPlayDuration) return; + + this.lastBufferSamples = this.bufferedSamples; + // 需要播放 + this.mergeBuffers(); + if (!this.buffer) return; + if (this.playing) this.output.stop(); + this.createSourceNode(this.buffer); + this.output.loop = false; + this.output.start(0, played); + this.lastStartTime = this.ac.currentTime; + this.playing = true; + this.output.addEventListener("ended", () => { + this.playing = false; + this.checkBufferedPlay(); + }); + } + + mergeBuffers() { + const buffer = this.ac.createBuffer( + this.audioData.length, + this.bufferedSamples, + this.sampleRate + ); + const chunk = this.sampleRate * this.bufferChunkSize; + const bufferedChunks = Math.floor(this.bufferedSamples / chunk); + const restLength = this.bufferedSamples % chunk; + for (let i = 0; i < this.audioData.length; i++) { + const audio = this.audioData[i]; + const data = new Float32Array(this.bufferedSamples); + for (let j = 0; j < bufferedChunks; j++) { + data.set(audio[j], chunk * j); + } + if (restLength !== 0) { + data.set( + audio[bufferedChunks].slice(0, restLength), + chunk * bufferedChunks + ); + } + + buffer.copyToChannel(data, i, 0); + } + this.buffer = buffer; + } + + async start() { + delete this.buffer; + this.headerRecieved = false; + this.audioType = ""; + this.errored = false; + this.buffered = 0; + this.sampleRate = 0; + this.bufferedSamples = 0; + this.duration = 0; + this.loaded = false; + if (this.playing) this.output.stop(); + this.playing = false; + this.lastStartTime = this.ac.currentTime; + } + + end(done, reason) { + if (done && this.buffer) { + this.loaded = true; + delete this.controller; + this.mergeBuffers(); + + this.duration = this.buffered; + this.audioData = []; + this.decoder?.destroy(); + delete this.decoder; + delete this.parser; + } else { + console.warn( + "Unexpected end when loading stream audio, reason: '" + + (reason ?? "") + + "'" + ); + } + } + + playAudio(when) { + if (!this.buffer) return; + this.lastStartTime = this.ac.currentTime; + if (this.playing) this.output.stop(); + if (this.player.status !== AudioStatus.Playing) { + this.player.status = AudioStatus.Playing; + } + this.createSourceNode(this.buffer); + this.output.start(0, when); + this.playing = true; + + this.output.addEventListener("ended", () => { + this.playing = false; + if (this.player.status === AudioStatus.Playing) { + this.player.status = AudioStatus.Stoped; + } + if (this.loop && !this.output.loop) this.play(0); + }); + } + /** + * 开始播放这个音频源 + */ + play(when) { + if (this.playing || this.errored) return; + if (this.loaded && this.buffer) { + this.playing = true; + this.playAudio(when); + } else { + this.controller?.start(); + } + } + + createSourceNode(buffer) { + if (!this.target) return; + const node = this.ac.createBufferSource(); + node.buffer = buffer; + if (this.playing) this.output.stop(); + this.playing = false; + this.output = node; + node.connect(this.target.input); + node.loop = this.loop; + } + /** + * 停止播放这个音频源 + * @returns 音频暂停的时刻 number + */ + stop() { + if (this.playing) this.output.stop(); + this.playing = false; + return this.ac.currentTime - this.lastStartTime; + } + /** + * 连接到音频路由图上,每次调用播放的时候都会执行一次 + * @param target 连接至的目标 IAudioInput + */ + connect(target) { + this.target = target; + } + /** + * 设置是否循环播放 + * @param loop 是否循环 boolean) + */ + setLoop(loop) { + this.loop = loop; + } + } + class AudioElementSource { + constructor(context) { + const audio = new Audio(); + audio.preload = "none"; + this.output = context.createMediaElementSource(audio); + this.audio = audio; + this.ac = context; + audio.addEventListener("play", () => { + this.playing = true; + if (this.player.status !== AudioStatus.Playing) { + this.player.status = AudioStatus.Playing; + } + }); + audio.addEventListener("ended", () => { + this.playing = false; + if (this.player.status === AudioStatus.Playing) { + this.player.status = AudioStatus.Stoped; + } + }); + } + get duration() { + return this.audio.duration; + } + get currentTime() { + return this.audio.currentTime; + } + /** + * 设置音频源的路径 + * @param url 音频路径 + */ + setSource(url) { + this.audio.src = url; + } + + play(when = 0) { + if (this.playing) return; + this.audio.currentTime = when; + this.audio.play(); + } + + stop() { + this.audio.pause(); + this.playing = false; + if (this.player.status === AudioStatus.Playing) { + this.player.status = AudioStatus.Stoped; + } + return this.audio.currentTime; + } + + connect(target) { + this.output.connect(target.input); + } + + setLoop(loop) { + this.audio.loop = loop; + } + } + class AudioBufferSource { + constructor(context) { + this.output = context.createBufferSource(); + /** 是否循环 */ + this.loop = false; + /** 上一次播放是从何时开始的 */ + this.lastStartWhen = 0; + /** 播放开始时刻 */ + this.lastStartTime = 0; + this.duration = 0; + this.ac = context; + } + get currentTime() { + return this.ac.currentTime - this.lastStartTime + this.lastStartWhen; + } + + /** + * 设置音频源数据 + * @param buffer 音频源,可以是未解析的 ArrayBuffer,也可以是已解析的 AudioBuffer + */ + async setBuffer(buffer) { + if (buffer instanceof ArrayBuffer) { + this.buffer = await this.ac.decodeAudioData(buffer); + } else { + this.buffer = buffer; + } + this.duration = this.buffer.duration; + } + + play(when) { + if (this.playing || !this.buffer) return; + this.playing = true; + this.lastStartTime = this.ac.currentTime; + if (this.player.status !== AudioStatus.Playing) { + this.player.status = AudioStatus.Playing; + } + this.createSourceNode(this.buffer); + this.output.start(0, when); + this.output.addEventListener("ended", () => { + this.playing = false; + if (this.player.status === AudioStatus.Playing) { + this.player.status = AudioStatus.Stoped; + } + if (this.loop && !this.output.loop) this.play(0); + }); + } + + createSourceNode(buffer) { + if (!this.target) return; + const node = this.ac.createBufferSource(); + node.buffer = buffer; + this.output = node; + node.connect(this.target.input); + node.loop = this.loop; + } + + stop() { + this.output.stop(); + return this.ac.currentTime - this.lastStartTime; + } + + connect(target) { + this.target = target; + } + + setLoop(loop) { + this.loop = loop; + } + } + class AudioPlayer { + constructor() { + /** 音频播放上下文 */ + this.ac = new AudioContext(); + /** 音量节点 */ + this.gain = this.ac.createGain(); + this.gain.connect(this.ac.destination); + this.audioRoutes = new Map(); + const func = () => { + this.ac.resume(); + document.body.removeEventListener("mousedown", func); + document.body.removeEventListener("touchstart", func); + document.body.removeEventListener("keydown", func); + }; + document.body.addEventListener("mousedown", func, { capture: true }); + document.body.addEventListener("touchstart", func, { capture: true }); + document.body.addEventListener("keydown", func, { capture: true }); + } + /** + * 解码音频数据 + * @param data 音频数据 + */ + decodeAudioData(data) { + return AudioDecoder.decodeAudioData(data, this); + } + /** + * 设置音量 + * @param volume 音量 + */ + setVolume(volume) { + this.gain.gain.value = volume; + } + + /** + * 获取音量 + */ + getVolume() { + return this.gain.gain.value; + } + + /** + * 创建一个音频源 + * @param Source 音频源类 + */ + createSource(Source) { + return new Source(this.ac); + } + + /** + * 创建一个兼容流式音频源,可以与流式加载相结合,主要用于处理 opus ogg 不兼容的情况 + */ + createStreamSource() { + return new AudioStreamSource(this.ac); + } + + /** + * 创建一个通过 audio 元素播放的音频源 + */ + createElementSource() { + return new AudioElementSource(this.ac); + } + + /** + * 创建一个通过 AudioBuffer 播放的音频源 + */ + createBufferSource() { + return new AudioBufferSource(this.ac); + } + + /** + * 获取音频目的地 + */ + getDestination() { + return this.gain; + } + + /** + * 创建一个音频效果器 + * @param Effect 效果器类 + */ + createEffect(Effect) { + return new Effect(this.ac); + } + + /** + * 创建一个修改音量的效果器 + * ```txt + * |----------| + * Input ----> | GainNode | ----> Output + * |----------| + * ``` + */ + createVolumeEffect() { + return new VolumeEffect(this.ac); + } + + /** + * 创建一个立体声效果器 + * ```txt + * |------------| + * Input ----> | PannerNode | ----> Output + * |------------| + * ``` + */ + createStereoEffect() { + return new StereoEffect(this.ac); + } + + /** + * 创建一个修改单个声道音量的效果器 + * ```txt + * |----------| + * -> | GainNode | \ + * |--------------| / |----------| -> |------------| + * Input ----> | SplitterNode | ...... | MergerNode | ----> Output + * |--------------| \ |----------| -> |------------| + * -> | GainNode | / + * |----------| + * ``` + */ + createChannelVolumeEffect() { + return new ChannelVolumeEffect(this.ac); + } + + /** + * 创建一个延迟效果器 + * |-----------| + * Input ----> | DelayNode | ----> Output + * |-----------| + */ + createDelay() { + return new DelayEffect(this.ac); + } + + /** + * 创建一个回声效果器 + * ```txt + * |----------| + * Input ----> | GainNode | ----> Output + * ^ |----------| | + * | | + * | |------------| ↓ + * |-- | Delay Node | <-- + * |------------| + * ``` + */ + createEchoEffect() { + return new EchoEffect(this.ac); + } + + /** + * 创建一个音频播放路由 + * @param source 音频源 + */ + createRoute(source) { + return new AudioRoute(source, this); + } + + /** + * 添加一个音频播放路由,可以直接被播放 + * @param id 这个音频播放路由的名称 + * @param route 音频播放路由对象 + */ + addRoute(id, route) { + if (!this.audioRoutes) this.audioRoutes = new Map(); + if (this.audioRoutes.has(id)) { + console.warn( + "Audio route with id of '" + + id + + "' has already existed. New route will override old route." + ); + } + this.audioRoutes.set(id, route); + } + + /** + * 根据名称获取音频播放路由对象 + * @param id 音频播放路由的名称 + */ + getRoute(id) { + return this.audioRoutes.get(id); + } + /** + * 移除一个音频播放路由 + * @param id 要移除的播放路由的名称 + */ + removeRoute(id) { + this.audioRoutes.delete(id); + } + /** + * 播放音频 + * @param id 音频名称 + * @param when 从音频的哪个位置开始播放,单位秒 + */ + play(id, when) { + const route = this.getRoute(id); + if (!route) { + console.warn( + "Cannot play audio route '" + + id + + "', since there is not added route named it." + ); + return; + } + + route.play(when); + } + + /** + * 暂停音频播放 + * @param id 音频名称 + * @returns 当音乐真正停止时兑现 + */ + pause(id) { + const route = this.getRoute(id); + if (!route) { + console.warn( + "Cannot pause audio route '" + + id + + "', since there is not added route named it." + ); + return; + } + return route.pause(); + } + + /** + * 停止音频播放 + * @param id 音频名称 + * @returns 当音乐真正停止时兑现 + */ + stop(id) { + const route = this.getRoute(id); + if (!route) { + console.warn( + "Cannot stop audio route '" + + id + + "', since there is not added route named it." + ); + return; + } + return route.stop(); + } + + /** + * 继续音频播放 + * @param id 音频名称 + */ + resume(id) { + const route = this.getRoute(id); + if (!route) { + console.warn( + "Cannot pause audio route '" + + id + + "', since there is not added route named it." + ); + return; + } + route.resume(); + } + + /** + * 设置听者位置,x正方向水平向右,y正方向垂直于地面向上,z正方向垂直屏幕远离用户 + * @param x 位置x坐标 + * @param y 位置y坐标 + * @param z 位置z坐标 + */ + setListenerPosition(x, y, z) { + const listener = this.ac.listener; + listener.positionX.value = x; + listener.positionY.value = y; + listener.positionZ.value = z; + } + + /** + * 设置听者朝向,x正方向水平向右,y正方向垂直于地面向上,z正方向垂直屏幕远离用户 + * @param x 朝向x坐标 + * @param y 朝向y坐标 + * @param z 朝向z坐标 + */ + setListenerOrientation(x, y, z) { + const listener = this.ac.listener; + listener.forwardX.value = x; + listener.forwardY.value = y; + listener.forwardZ.value = z; + } + + /** + * 设置听者头顶朝向,x正方向水平向右,y正方向垂直于地面向上,z正方向垂直屏幕远离用户 + * @param x 头顶朝向x坐标 + * @param y 头顶朝向y坐标 + * @param z 头顶朝向z坐标 + */ + setListenerUp(x, y, z) { + const listener = this.ac.listener; + listener.upX.value = x; + listener.upY.value = y; + listener.upZ.value = z; + } + } + class AudioRoute { + constructor(source, player) { + this.output = source.output; + + /** 效果器路由图 */ + this.effectRoute = []; + + /** 结束时长,当音频暂停或停止时,会经过这么长时间之后才真正终止播放,期间可以做音频淡入淡出等效果 */ + this.endTime = 0; + /** 暂停时播放了多长时间 */ + this.pauseCurrentTime = 0; + /** 当前播放状态 */ + this.player = player; + this.player.status = AudioStatus.Stoped; + this.shouldStop = false; + /** + * 每次暂停或停止时自增,用于判断当前正在处理的情况。 + * 假如暂停后很快播放,然后很快暂停,那么需要根据这个来判断实际是否应该执行暂停后操作 + */ + this.stopIdentifier = 0; + /** 暂停时刻 */ + this.pauseTime = 0; + this.source = source; + this.source.player = player; + } + /** 音频时长,单位秒 */ + get duration() { + return this.source.duration; + } + /** 当前播放了多长时间,单位秒 */ + get currentTime() { + if (this.player.status === AudioStatus.Paused) { + return this.pauseCurrentTime; + } else { + return this.source.currentTime; + } + } + set currentTime(time) { + this.source.stop(); + this.source.play(time); + } + /** + * 设置结束时间,暂停或停止时,会经过这么长时间才终止音频的播放,这期间可以做一下音频淡出的效果。 + * @param time 暂停或停止时,经过多长时间之后才会结束音频的播放 + */ + setEndTime(time) { + this.endTime = time; + } + + /** + * 当音频播放时执行的函数,可以用于音频淡入效果 + * @param fn 音频开始播放时执行的函数 + */ + onStart(fn) { + this.audioStartHook = fn; + } + + /** + * 当音频暂停或停止时执行的函数,可以用于音频淡出效果 + * @param fn 音频在暂停或停止时执行的函数,不填时表示取消这个钩子。 + * 包含两个参数,第一个参数是结束时长,第二个参数是当前音频播放路由对象 + */ + onEnd(fn) { + this.audioEndHook = fn; + } + + /** + * 开始播放这个音频 + * @param when 从音频的什么时候开始播放,单位秒 + */ + play(when = 0) { + if (this.player.status === AudioStatus.Playing) return; + this.link(); + if (this.effectRoute.length > 0) { + const first = this.effectRoute[0]; + this.source.connect(first); + const last = this.effectRoute.at(-1); + last.connect({ input: this.player.getDestination() }); + } else { + this.source.connect({ input: this.player.getDestination() }); + } + this.source.play(when); + this.player.status = AudioStatus.Playing; + this.pauseTime = 0; + this.audioStartHook?.(this); + this.startAllEffect(); + if (this.source.player.status !== AudioStatus.Playing) { + this.source.player.status = AudioStatus.Playing; + } + } + + /** + * 暂停音频播放 + */ + async pause() { + if (this.player.status !== AudioStatus.Playing) return; + this.player.status = AudioStatus.Pausing; + this.stopIdentifier++; + const identifier = this.stopIdentifier; + if (this.audioEndHook) { + this.audioEndHook(this.endTime, this); + await sleep(this.endTime); + } + if ( + this.player.status !== AudioStatus.Pausing || + this.stopIdentifier !== identifier + ) { + return; + } + this.pauseCurrentTime = this.source.currentTime; + const time = this.source.stop(); + this.pauseTime = time; + if (this.shouldStop) { + this.player.status = AudioStatus.Stoped; + this.endAllEffect(); + + this.shouldStop = false; + } else { + this.player.status = AudioStatus.Paused; + this.endAllEffect(); + } + this.endAllEffect(); + } + + /** + * 继续音频播放 + */ + resume() { + if (this.player.status === AudioStatus.Playing) return; + if ( + this.player.status === AudioStatus.Pausing || + this.player.status === AudioStatus.Stoping + ) { + this.audioStartHook?.(this); + + return; + } + if (this.player.status === AudioStatus.Paused) { + this.play(this.pauseTime); + } else { + this.play(0); + } + this.player.status = AudioStatus.Playing; + this.pauseTime = 0; + this.audioStartHook?.(this); + this.startAllEffect(); + } + + /** + * 停止音频播放 + */ + async stop() { + if (this.status !== AudioStatus.Playing) { + if (this.status === AudioStatus.Pausing) { + this.shouldStop = true; + } + return; + } + this.status = AudioStatus.Stoping; + this.stopIdentifier++; + const identifier = this.stopIdentifier; + if (this.audioEndHook) { + this.audioEndHook(this.endTime, this); + await sleep(this.endTime); + } + if ( + this.status !== AudioStatus.Stoping || + this.stopIdentifier !== identifier + ) { + return; + } + this.source.stop(); + this.status = AudioStatus.Stoped; + this.pauseTime = 0; + this.endAllEffect(); + } + + /** + * 添加效果器 + * @param effect 要添加的效果,可以是数组,表示一次添加多个 + * @param index 从哪个位置开始添加,如果大于数组长度,那么加到末尾,如果小于0,那么将会从后面往前数。默认添加到末尾 + */ + addEffect(effect, index) { + if (isNil(index)) { + if (effect instanceof Array) { + this.effectRoute.push(...effect); + } else { + this.effectRoute.push(effect); + } + } else { + if (effect instanceof Array) { + this.effectRoute.splice(index, 0, ...effect); + } else { + this.effectRoute.splice(index, 0, effect); + } + } + this.setOutput(); + if (this.source.playing) this.link(); + } + + /** + * 移除一个效果器 + * @param effect 要移除的效果 + */ + removeEffect(effect) { + const index = this.effectRoute.indexOf(effect); + if (index === -1) return; + this.effectRoute.splice(index, 1); + effect.disconnect(); + this.setOutput(); + if (this.source.playing) this.link(); + } + + setOutput() { + const effect = this.effectRoute.at(-1); + if (!effect) this.output = this.source.output; + else this.output = effect.output; + } + + /** + * 连接音频路由图 + */ + link() { + this.effectRoute.forEach((v) => v.disconnect()); + this.effectRoute.forEach((v, i) => { + const next = this.effectRoute[i + 1]; + if (next) { + v.connect(next); + } + }); + } + + startAllEffect() { + this.effectRoute.forEach((v) => v.start()); + } + + endAllEffect() { + this.effectRoute.forEach((v) => v.end()); + } + } + + const audioPlayer = new AudioPlayer(); + + class BgmController { + constructor(player) { + this.mainGain = player.createVolumeEffect(); + this.player = player; + /** bgm音频名称的前缀 */ + this.prefix = "bgms."; + /** 每个 bgm 的音量控制器 */ + this.gain = new Map(); + + /** 正在播放的 bgm */ + this.playingBgm = ""; + /** 是否正在播放 */ + this.playing = false; + + /** 是否已经启用 */ + this.enabled = true; + /** 是否屏蔽所有的音乐切换 */ + this.blocking = false; + /** 渐变时长 */ + this.transitionTime = 2000; + } + + /** + * 设置音频渐变时长 + * @param time 渐变时长 + */ + setTransitionTime(time) { + this.transitionTime = time; + for (const [, value] of this.gain) { + value.transition.time(time); + } + } + + /** + * 屏蔽音乐切换 + */ + blockChange() { + this.blocking = true; + } + + /** + * 取消屏蔽音乐切换 + */ + unblockChange() { + this.blocking = false; + } + + /** + * 设置总音量大小 + * @param volume 音量大小 + */ + setVolume(volume) { + this.mainGain.setVolume(volume); + this._volume = volume; + } + /** + * 获取总音量大小 + */ + getVolume() { + return this.mainGain.getVolume(); + } + /** + * 设置是否启用 + * @param enabled 是否启用 + */ + setEnabled(enabled) { + if (enabled) this.resume(); + else this.stop(); + this.enabled = enabled; + } + + /** + * 设置 bgm 音频名称的前缀 + */ + setPrefix(prefix) { + this.prefix = prefix; + } + + getId(name) { + return `${this.prefix}${name}`; + } + + /** + * 根据 bgm 名称获取其 AudioRoute 实例 + * @param id 音频名称 + */ + get(id) { + return this.player.getRoute(this.getId(id)); + } + + /** + * 添加一个 bgm + * @param id 要添加的 bgm 的名称 + * @param url 指定 bgm 的加载地址 + */ + addBgm(id, url = `project/bgms/${id}`) { + const type = guessTypeByExt(id); + if (!type) { + console.warn( + "Unknown audio extension name: '" + + id.split(".").slice(0, -1).join(".") + + "'" + ); + return; + } + const gain = this.player.createVolumeEffect(); + if (isAudioSupport(type)) { + const source = audioPlayer.createElementSource(); + source.setSource(url); + source.setLoop(true); + const route = new AudioRoute(source, audioPlayer); + route.addEffect([gain, this.mainGain]); + audioPlayer.addRoute(this.getId(id), route); + this.setTransition(id, route, gain); + } else { + const source = audioPlayer.createStreamSource(); + const stream = new StreamLoader(url); + stream.pipe(source); + source.setLoop(true); + const route = new AudioRoute(source, audioPlayer); + route.addEffect([gain, this.mainGain]); + audioPlayer.addRoute(this.getId(id), route); + this.setTransition(id, route, gain); + } + } + + /** + * 移除一个 bgm + * @param id 要移除的 bgm 的名称 + */ + removeBgm(id) { + this.player.removeRoute(this.getId(id)); + const gain = this.gain.get(id); + gain?.transition.ticker.destroy(); + this.gain.delete(id); + } + + setTransition(id, route, gain) { + const transition = new Transition(); + transition + .time(this.transitionTime) + .mode(linear()) + .transition("volume", 0); + + const tick = () => { + gain.setVolume(transition.value.volume); + }; + + /** + * @param expect 在结束时应该是正在播放还是停止 + */ + const setTick = async (expect) => { + transition.ticker.remove(tick); + transition.ticker.add(tick); + const identifier = route.stopIdentifier; + await sleep(this.transitionTime + 500); + if (route.status === expect && identifier === route.stopIdentifier) { + transition.ticker.remove(tick); + if (route.status === AudioStatus.Playing) { + gain.setVolume(1); + } else { + gain.setVolume(0); + } + } + }; + + route.onStart(async () => { + transition.transition("volume", 1); + setTick(AudioStatus.Playing); + }); + route.onEnd(() => { + transition.transition("volume", 0); + setTick(AudioStatus.Paused); + }); + route.setEndTime(this.transitionTime); + + this.gain.set(id, { effect: gain, transition }); + } + + /** + * 播放一个 bgm + * @param id 要播放的 bgm 名称 + */ + play(id, when) { + if (this.blocking) return; + if (id !== this.playingBgm && this.playingBgm) { + this.player.pause(this.getId(this.playingBgm)); + } + this.playingBgm = id; + if (!this.enabled) return; + this.player.play(this.getId(id), when); + this.playing = true; + if (this.player.status !== AudioStatus.Playing) { + this.player.status = AudioStatus.Playing; + } + } + + /** + * 继续当前的 bgm + */ + resume() { + if (this.blocking || !this.enabled || this.playing) return; + if (this.playingBgm) { + this.player.resume(this.getId(this.playingBgm)); + } + this.playing = true; + } + + /** + * 暂停当前的 bgm + */ + pause() { + if (this.blocking || !this.enabled) return; + if (this.playingBgm) { + this.player.pause(this.getId(this.playingBgm)); + } + this.playing = false; + } + + /** + * 停止当前的 bgm + */ + stop() { + if (this.blocking || !this.enabled) return; + if (this.playingBgm) { + this.player.stop(this.getId(this.playingBgm)); + } + this.playing = false; + } + } + const bgmController = new BgmController(audioPlayer); + + class SoundPlayer { + constructor(player) { + /** 每个音效的唯一标识符 */ + this.num = 0; + this.enabled = true; + this.gain = player.createVolumeEffect(); + /** 每个音效的数据 */ + this.buffer = new Map(); + /** 所有正在播放的音乐 */ + this.playing = new Set(); + this.player = player; + } + /** + * 设置是否启用音效 + * @param enabled 是否启用音效 + */ + setEnabled(enabled) { + if (!enabled) this.stopAllSounds(); + this.enabled = enabled; + } + + /** + * 设置音量大小 + * @param volume 音量大小 + */ + setVolume(volume) { + this.gain.setVolume(volume); + } + /** + * 获取音量大小 + */ + getVolume() { + return this.gain.getVolume(); + } + /** + * 添加一个音效 + * @param id 音效名称 + * @param data 音效的Uint8Array数据 + */ + async add(id, data) { + const buffer = await this.player.decodeAudioData(data); + if (!buffer) { + console.warn( + "Cannot decode sound '" + + id + + "', since audio file may not supported by 2.b." + ); + return; + } + this.buffer.set(id, buffer); + } + + /** + * 播放一个音效 + * @param id 音效名称 + * @param position 音频位置,[0, 0, 0]表示正中心,x轴指向水平向右,y轴指向水平向上,z轴指向竖直向上 + * @param orientation 音频朝向,[0, 1, 0]表示朝向前方 + */ + play(id, position = [0, 0, 0], orientation = [1, 0, 0]) { + if (!this.enabled) return -1; + const buffer = this.buffer.get(id); + if (!buffer) { + console.warn( + "Cannot play sound '" + + id + + "', since there is no added data named it." + ); + return -1; + } + const soundNum = this.num++; + + const source = this.player.createBufferSource(); + source.setBuffer(buffer); + const route = this.player.createRoute(source); + const stereo = this.player.createStereoEffect(); + stereo.setPosition(position[0], position[1], position[2]); + stereo.setOrientation(orientation[0], orientation[1], orientation[2]); + route.addEffect([stereo, this.gain]); + this.player.addRoute(`sounds.${soundNum}`, route); + route.play(); + source.output.addEventListener("ended", () => { + this.playing.delete(soundNum); + }); + this.playing.add(soundNum); + return soundNum; + } + + /** + * 停止一个音效 + * @param num 音效的唯一 id + */ + stop(num) { + const id = `sounds.${num}`; + const route = this.player.getRoute(id); + if (route) { + route.stop(); + this.player.removeRoute(id); + this.playing.delete(num); + } + } + + /** + * 停止播放所有音效 + */ + stopAllSounds() { + this.playing.forEach((v) => { + const id = `sounds.${v}`; + const route = this.player.getRoute(id); + if (route) { + route.stop(); + this.player.removeRoute(id); + } + }); + this.playing.clear(); + } + } + const soundPlayer = new SoundPlayer(audioPlayer); + + function loadAllBgm() { + const data = data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d; + for (const bgm of data.main.bgms) { + bgmController.addBgm(bgm); + } + } + loadAllBgm(); + AudioDecoder.registerDecoder(AudioType.Ogg, VorbisDecoder); + AudioDecoder.registerDecoder(AudioType.Opus, OpusDecoder); + + core.plugin.audioSystem = { + AudioType, + AudioDecoder, + AudioStatus, + checkAudioType, + isAudioSupport, + audioPlayer, + soundPlayer, + bgmController, + guessTypeByExt, + BgmController, + SoundPlayer, + EchoEffect, + DelayEffect, + ChannelVolumeEffect, + VolumeEffect, + StereoEffect, + AudioEffect, + AudioPlayer, + AudioRoute, + AudioStreamSource, + AudioElementSource, + AudioBufferSource, + loadAllBgm, + StreamLoader, + }; + //bgm相关复写 + control.prototype.playBgm = (bgm, when) => { + bgmController.play(bgm, when); + core.setMusicBtn(); + }; + control.prototype.pauseBgm = () => { + bgmController.pause(); + core.setMusicBtn(); + }; + + control.prototype.resumeBgm = function () { + bgmController.resume(); + core.setMusicBtn(); + }; + control.prototype.checkBgm = function () { + core.playBgm(bgmController.playingBgm || main.startBgm); + }; + control.prototype.triggerBgm = function () { + core.musicStatus.bgmStatus = !core.musicStatus.bgmStatus; + if (bgmController.playing) bgmController.pause(); + else bgmController.resume(); + core.setMusicBtn(); + core.setLocalStorage("bgmStatus", core.musicStatus.bgmStatus); + }; + //sound相关复写 + control.prototype.playSound = function ( + sound, + _pitch, + callback, + position, + orientation + ) { + if (main.mode != "play" || !core.musicStatus.soundStatus) return; + const name = core.getMappedName(sound); + const num = soundPlayer.play(name, position, orientation); + const route = audioPlayer.getRoute(`sounds.${num}`); + if (!route) { + callback?.(); + return -1; + } else { + sleep(route.duration * 1000).then(() => callback?.()); + return num; + } + }; + control.prototype.stopSound = function (id) { + if (isNil(id)) { + soundPlayer.stopAllSounds(); + } else { + soundPlayer.stop(id); + } + }; + control.prototype.getPlayingSounds = function () { + return [...soundPlayer.playing]; + }; + //sound加载复写 + loader.prototype._loadOneSound_decodeData = function (name, data) { + if (data instanceof Blob) { + var blobReader = new zip.BlobReader(data); + blobReader.init(function () { + blobReader.readUint8Array(0, blobReader.size, function (uint8) { + //core.loader._loadOneSound_decodeData(name, uint8.buffer); + soundPlayer.add(name, uint8); + }); + }); + return; + } + if (data instanceof ArrayBuffer) { + const uint8 = new Uint8Array(data); + soundPlayer.add(name, uint8); + } + }; + //音量控制复写 + soundPlayer.setVolume( + core.musicStatus.userVolume * core.musicStatus.designVolume + ); + bgmController.setVolume( + core.musicStatus.userVolume * core.musicStatus.designVolume + ); + actions.prototype._clickSwitchs_sounds_userVolume = function (delta) { + var value = Math.round(Math.sqrt(100 * core.musicStatus.userVolume)); + if (value == 0 && delta < 0) return; + core.musicStatus.userVolume = core.clamp( + Math.pow(value + delta, 2) / 100, + 0, + 1 + ); + //audioContext 音效 不受designVolume 影响 + if (core.musicStatus.gainNode != null) + core.musicStatus.gainNode.gain.value = core.musicStatus.userVolume; + soundPlayer.setVolume( + core.musicStatus.userVolume * core.musicStatus.designVolume + ); + bgmController.setVolume( + core.musicStatus.userVolume * core.musicStatus.designVolume + ); + core.setLocalStorage("userVolume", core.musicStatus.userVolume); + core.playSound("确定"); + core.ui._drawSwitchs_sounds(); + }; + //系统事件复写 + 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.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_playSound = function (data, x, y, prefix) { + if (data.stop) core.stopSound(); + if (data.sync) { + core.playSound(data.name, data.pitch, core.doAction); + } else { + core.playSound(data.name, data.pitch); + core.doAction(); + } + }; + + events.prototype._action_stopSound = function (data, x, y, prefix) { + core.stopSound(); + core.doAction(); + }; + +}, "怪物碎裂特效": function () { // 在此增加新插件 // -------------------- 安装说明 -------------------- // @@ -10885,21 +11088,21 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = }; }, "自定义常用事件": function () { - // editorBlocklyconfigPlus.js - // 自訂常見事件模板插件 - // 本插件引用了通用函數插件(Utility.js) - // 適用樣板:2.10.3 - // 請注意: - // 此插件對事件編輯器(editor_blocklyconfig)進行複寫,若還有其它針對事件編輯器做複寫的插件,請謹慎使用! - // 此插件對表格操作行為(editor_mode.doActionList)進行複寫,若還有其它對表格操作行為做複寫的插件,請謹慎使用! - // 使用方法: - // 現在在主頁下拉選單多了個常用事件模版,在那邊可以自由設定常用事件模板。 - // 設定完後按F5刷新,再到事件編輯器看就有你設定好的常用事件模板了。 + // editorBlocklyconfigPlus.js + // 自訂常見事件模板插件 + // 本插件引用了通用函數插件(Utility.js) + // 適用樣板:2.10.3 + // 請注意: + // 此插件對事件編輯器(editor_blocklyconfig)進行複寫,若還有其它針對事件編輯器做複寫的插件,請謹慎使用! + // 此插件對表格操作行為(editor_mode.doActionList)進行複寫,若還有其它對表格操作行為做複寫的插件,請謹慎使用! + // 使用方法: + // 現在在主頁下拉選單多了個常用事件模版,在那邊可以自由設定常用事件模板。 + // 設定完後按F5刷新,再到事件編輯器看就有你設定好的常用事件模板了。 - if (main.mode == "editor") { - //#region 配置表格初始化 - let TableFileName = "project/table/CommonEventTemplate_comment.js"; - let TableRow = ` + if (main.mode == "editor") { + //#region 配置表格初始化 + let TableFileName = "project/table/CommonEventTemplate_comment.js"; + let TableRow = ` var CommonEventTemplate_comment = {"_type": "object", "_data": { "CommonEventTemplate": { @@ -10942,241 +11145,221 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = } }} `; - if (!events_c12a15a8_c380_4b28_8144_256cba95f760.CommonEventTemplate) { - /** - * @type {{[EvnetName:actionParserJson]}} - */ - events_c12a15a8_c380_4b28_8144_256cba95f760.CommonEventTemplate = { - 检测音乐如果没有开启则系统提示开启: [ - { - type: "if", - condition: "!core.musicStatus.bgmStatus", - true: [ - "\t[系统提示]你当前音乐处于关闭状态,本塔开音乐游戏效果更佳", - ], - false: [], - }, - ], - 仿新新魔塔一次性商人: [ - { - type: "if", - condition: "switch:A", - true: [ - "\t[行商,trader]\b[this]这是购买我的道具后我给玩家的提示。", - { - type: "comment", - text: "下一条指令可视情况使用或不使用", - }, - { - type: "hide", - remove: true, - time: 250, - }, - ], - false: [ - { - type: "confirm", - text: "我有3把黄钥匙,\n你出50金币就卖给你。", - yes: [ - { - type: "if", - condition: "status:money>=50", - true: [ - { - type: "setValue", - name: "status:money", - operator: "-=", - value: "50", - }, - { - type: "setValue", - name: "item:yellowKey", - operator: "+=", - value: "3", - }, - { - type: "playSound", - name: "确定", - stop: true, - }, - { - type: "setValue", - name: "switch:A", - value: "true", - }, - ], - false: [ - { - type: "playSound", - name: "操作失败", - }, - "\t[行商,trader]\b[this]你的金币不足!", - ], - }, - ], - no: [], - }, - ], - }, - ], - 全地图选中一个点: [ - { - type: "comment", - text: "全地图选中一个点,需要用鼠标或触屏操作", - }, - { - type: "setValue", - name: "temp:X", - value: "status:x", - }, - { - type: "setValue", - name: "temp:Y", - value: "status:y", - }, - { - type: "tip", - text: "再次点击闪烁位置确认", - }, - { - type: "while", - condition: "true", - data: [ - { - type: "drawSelector", - image: "winskin.webp", - code: 1, - x: "32*temp:X", - y: "32*temp:Y", - width: 32, - height: 32, - }, - { - type: "wait", - }, - { - type: "if", - condition: "(flag:type === 1)", - true: [ - { - type: "if", - condition: "((temp:X===flag:x)&&(temp:Y===flag:y))", - true: [ - { - type: "break", - n: 1, - }, - ], - }, - { - type: "setValue", - name: "temp:X", - value: "flag:x", - }, - { - type: "setValue", - name: "temp:Y", - value: "flag:y", - }, - ], - }, - ], - }, - { - type: "drawSelector", - code: 1, - }, - { - type: "comment", - text: "流程进行到这里可以对[X,Y]点进行处理,比如", - }, - { - type: "closeDoor", - id: "yellowDoor", - loc: ["temp:X", "temp:Y"], - }, - ], - 多阶段Boss战斗: [ - { - type: "comment", - text: "多阶段boss,请直接作为战后事件使用", - }, - { - type: "setValue", - name: "switch:A", - operator: "+=", - value: "1", - }, - { - type: "switch", - condition: "switch:A", - caseList: [ - { - case: "1", - action: [ - { - type: "setBlock", - number: "redSlime", - }, - "\t[2阶段boss,redSlime]\b[this]你以为你已经打败我了吗?没听说过史莱姆有九条命吗?", - ], - }, - { - case: "2", - action: [ - { - type: "setBlock", - number: "blackSlime", - }, - "\t[3阶段boss,blackSlime]\b[this]不能消灭我的,只会让我更强大!", - ], - }, - { - case: "3", - action: [ - { - type: "setBlock", - number: "slimelord", - }, - "\t[4阶段boss,slimelord]\b[this]我还能打!", - ], - }, - { - case: "4", - action: ["\t[4阶段boss,slimelord]我一定会回来的!"], - }, - ], - }, - ], - }; - } - //#endregion + if (!events_c12a15a8_c380_4b28_8144_256cba95f760.CommonEventTemplate) { + /** + * @type {{[EvnetName:actionParserJson]}} + */ + events_c12a15a8_c380_4b28_8144_256cba95f760.CommonEventTemplate = { + 检测音乐如果没有开启则系统提示开启: [{ + type: "if", + condition: "!core.musicStatus.bgmStatus", + true: [ + "\t[系统提示]你当前音乐处于关闭状态,本塔开音乐游戏效果更佳", + ], + false: [], + }, ], + 仿新新魔塔一次性商人: [{ + type: "if", + condition: "switch:A", + true: [ + "\t[行商,trader]\b[this]这是购买我的道具后我给玩家的提示。", + { + type: "comment", + text: "下一条指令可视情况使用或不使用", + }, + { + type: "hide", + remove: true, + time: 250, + }, + ], + false: [{ + type: "confirm", + text: "我有3把黄钥匙,\n你出50金币就卖给你。", + yes: [{ + type: "if", + condition: "status:money>=50", + true: [{ + type: "setValue", + name: "status:money", + operator: "-=", + value: "50", + }, + { + type: "setValue", + name: "item:yellowKey", + operator: "+=", + value: "3", + }, + { + type: "playSound", + name: "确定", + stop: true, + }, + { + type: "setValue", + name: "switch:A", + value: "true", + }, + ], + false: [{ + type: "playSound", + name: "操作失败", + }, + "\t[行商,trader]\b[this]你的金币不足!", + ], + }, ], + no: [], + }, ], + }, ], + 全地图选中一个点: [{ + type: "comment", + text: "全地图选中一个点,需要用鼠标或触屏操作", + }, + { + type: "setValue", + name: "temp:X", + value: "status:x", + }, + { + type: "setValue", + name: "temp:Y", + value: "status:y", + }, + { + type: "tip", + text: "再次点击闪烁位置确认", + }, + { + type: "while", + condition: "true", + data: [{ + type: "drawSelector", + image: "winskin.webp", + code: 1, + x: "32*temp:X", + y: "32*temp:Y", + width: 32, + height: 32, + }, + { + type: "wait", + }, + { + type: "if", + condition: "(flag:type === 1)", + true: [{ + type: "if", + condition: "((temp:X===flag:x)&&(temp:Y===flag:y))", + true: [{ + type: "break", + n: 1, + }, ], + }, + { + type: "setValue", + name: "temp:X", + value: "flag:x", + }, + { + type: "setValue", + name: "temp:Y", + value: "flag:y", + }, + ], + }, + ], + }, + { + type: "drawSelector", + code: 1, + }, + { + type: "comment", + text: "流程进行到这里可以对[X,Y]点进行处理,比如", + }, + { + type: "closeDoor", + id: "yellowDoor", + loc: ["temp:X", "temp:Y"], + }, + ], + 多阶段Boss战斗: [{ + type: "comment", + text: "多阶段boss,请直接作为战后事件使用", + }, + { + type: "setValue", + name: "switch:A", + operator: "+=", + value: "1", + }, + { + type: "switch", + condition: "switch:A", + caseList: [{ + case: "1", + action: [{ + type: "setBlock", + number: "redSlime", + }, + "\t[2阶段boss,redSlime]\b[this]你以为你已经打败我了吗?没听说过史莱姆有九条命吗?", + ], + }, + { + case: "2", + action: [{ + type: "setBlock", + number: "blackSlime", + }, + "\t[3阶段boss,blackSlime]\b[this]不能消灭我的,只会让我更强大!", + ], + }, + { + case: "3", + action: [{ + type: "setBlock", + number: "slimelord", + }, + "\t[4阶段boss,slimelord]\b[this]我还能打!", + ], + }, + { + case: "4", + action: ["\t[4阶段boss,slimelord]我一定会回来的!"], + }, + ], + }, + ], + }; + } + //#endregion - // 新增模板選項 - let editModeSelect = document.getElementById("editModeSelect"); - let newEditModeOption = document.createElement("option"); - newEditModeOption.value = "CommonEventTemplate"; - newEditModeOption.text = "常見事件模板"; - editModeSelect.add(newEditModeOption); + // 新增模板選項 + let editModeSelect = document.getElementById("editModeSelect"); + let newEditModeOption = document.createElement("option"); + newEditModeOption.value = "CommonEventTemplate"; + newEditModeOption.text = "常見事件模板"; + editModeSelect.add(newEditModeOption); - //檢查可用的編輯模板ID - let leftIDNumber = 11 - 1; - let ExistLeftElement = document.querySelector(".main"); - while (ExistLeftElement) { - leftIDNumber++; - ExistLeftElement = document.getElementById(`left${leftIDNumber}`); - } + //檢查可用的編輯模板ID + let leftIDNumber = 11 - 1; + let ExistLeftElement = document.querySelector(".main"); + while (ExistLeftElement) { + leftIDNumber++; + ExistLeftElement = document.getElementById(`left${leftIDNumber}`); + } - //新增編輯模板 - let MainDiv = document.querySelector(".main"); + //新增編輯模板 + let MainDiv = document.querySelector(".main"); - let CommonEventTemplateMainDiv = document.createElement("div"); - CommonEventTemplateMainDiv.id = `left${leftIDNumber}`; - CommonEventTemplateMainDiv.className = "leftTab"; - CommonEventTemplateMainDiv.style.zIndex = "-1"; - CommonEventTemplateMainDiv.style.opacity = "0"; + let CommonEventTemplateMainDiv = document.createElement("div"); + CommonEventTemplateMainDiv.id = `left${leftIDNumber}`; + CommonEventTemplateMainDiv.className = "leftTab"; + CommonEventTemplateMainDiv.style.zIndex = "-1"; + CommonEventTemplateMainDiv.style.opacity = "0"; - CommonEventTemplateMainDiv.innerHTML = ` + CommonEventTemplateMainDiv.innerHTML = `

常見事件模板   @@ -11199,980 +11382,958 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = `; - MainDiv.appendChild(CommonEventTemplateMainDiv); + MainDiv.appendChild(CommonEventTemplateMainDiv); - (async function () { - //等待編輯器初始化 - while (!editor_mode.ids) { - await Sleep(100); - } - //新增編輯模板ID - editor_mode.ids["CommonEventTemplate"] = `left${leftIDNumber}`; - editor_mode.init_dom_ids(); - //切換至常見事件模板 - editor_mode.CommonEventTemplate = function (callback) { - var objs = []; - editor.file.editCommonEventTemplate([], function (objs_) { - objs = objs_; - //console.log(objs_) - }); - //只查询不修改时,内部实现不是异步的,所以可以这么写 - var tableinfo = editor.table.objToTable(objs[0], objs[1]); - document.getElementById( - "table_298572d8-93dd-4c6e-a278-6a7d49831e3a" - ).innerHTML = tableinfo.HTML; - tableinfo.listen(tableinfo.guids); - if (Boolean(callback)) callback(); - }; + (async function () { + //等待編輯器初始化 + while (!editor_mode.ids) { + await Sleep(100); + } + //新增編輯模板ID + editor_mode.ids["CommonEventTemplate"] = `left${leftIDNumber}`; + editor_mode.init_dom_ids(); + //切換至常見事件模板 + editor_mode.CommonEventTemplate = function (callback) { + var objs = []; + editor.file.editCommonEventTemplate([], function (objs_) { + objs = objs_; + //console.log(objs_) + }); + //只查询不修改时,内部实现不是异步的,所以可以这么写 + var tableinfo = editor.table.objToTable(objs[0], objs[1]); + document.getElementById( + "table_298572d8-93dd-4c6e-a278-6a7d49831e3a" + ).innerHTML = tableinfo.HTML; + tableinfo.listen(tableinfo.guids); + if (Boolean(callback)) callback(); + }; - //檢查配置表格存在 - let TableRowExist = null; - fs.readFile(TableFileName, "base64", function (err, data) { - if (err) { - console.log(`察覺常見事件模板配置表格不存在,原因:${err}`); - console.log("新建一個常見事件模板配置表格。"); - TableRowExist = false; - } else { - TableRowExist = true; - } - }); - //等待配置表格載入完畢(最多0.3秒,超過則視為失敗) - for (let i = 0; i < 3; i++) { - if (TableRowExist == null) { - await Sleep(100); - } - } - //配置表格初始化 - if (TableRowExist != true) { - fs.mkdir("project/table", function (err, data) { - if (err) throw `常見事件模板配置表格目錄初始化失敗,原因:${err}`; - }); - fs.writeFile( - TableFileName, - editor.util.encode64(TableRow || ""), - "base64", - function (err, data) { - if (err) throw `常見事件模板配置表格文件初始化失敗,原因:${err}`; - } - ); - } - //載入配置表格 - //editor.file.loadCommentjs(callback); - (function () { - var key = "CommonEventTemplate_comment"; - var script = document.createElement("script"); - script.src = "project/table/" + key + ".js"; - document.body.appendChild(script); - script.onload = function () { - editor.file[key] = eval(key.replace(".", "_")); - var loaded = Boolean(editor.file[key]); - }; - })(); - //按下配置表格 - editor_multi.CommonEventTemplateEditCommentJs = function (mod) { - editor_multi.lintAutocomplete = true; - editor_multi.setLint(); - editor_multi.importFile(TableFileName); - }; + //檢查配置表格存在 + let TableRowExist = null; + fs.readFile(TableFileName, "base64", function (err, data) { + if (err) { + console.log(`察覺常見事件模板配置表格不存在,原因:${err}`); + console.log("新建一個常見事件模板配置表格。"); + TableRowExist = false; + } else { + TableRowExist = true; + } + }); + //等待配置表格載入完畢(最多0.3秒,超過則視為失敗) + for (let i = 0; i < 3; i++) { + if (TableRowExist == null) { + await Sleep(100); + } + } + //配置表格初始化 + if (TableRowExist != true) { + fs.mkdir("project/table", function (err, data) { + if (err) throw `常見事件模板配置表格目錄初始化失敗,原因:${err}`; + }); + fs.writeFile( + TableFileName, + editor.util.encode64(TableRow || ""), + "base64", + function (err, data) { + if (err) throw `常見事件模板配置表格文件初始化失敗,原因:${err}`; + } + ); + } + //載入配置表格 + //editor.file.loadCommentjs(callback); + (function () { + var key = "CommonEventTemplate_comment"; + var script = document.createElement("script"); + script.src = "project/table/" + key + ".js"; + document.body.appendChild(script); + script.onload = function () { + editor.file[key] = eval(key.replace(".", "_")); + var loaded = Boolean(editor.file[key]); + }; + })(); + //按下配置表格 + editor_multi.CommonEventTemplateEditCommentJs = function (mod) { + editor_multi.lintAutocomplete = true; + editor_multi.setLint(); + editor_multi.importFile(TableFileName); + }; - //定義表格操作行為 - editor_mode.OriginDoActionList = editor_mode.doActionList; - editor_mode.doActionList = function (mode, actionList, callback) { - if (editor_mode.mode == "CommonEventTemplate") { - if (actionList.length == 0) return; - printf("修改中..."); - var cb = function (objs_) { - if (objs_.slice(-1)[0] != null) { - printe(objs_.slice(-1)[0]); - throw objs_.slice(-1)[0]; - } - var str = "修改成功!"; - if ( - data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.firstData.name == - "template" - ) - str += "
请注意:全塔属性的name尚未修改,请及时予以设置。"; - printf(str); - if (callback) callback(); - }; - editor.file.editCommonEventTemplate(actionList, cb); - } else { - editor_mode.OriginDoActionList(mode, actionList, callback); - } - }; - //添加表格列 - editor.table.CommonEventTemplateAddFunc = function () { - let obj = events_c12a15a8_c380_4b28_8144_256cba95f760; + //定義表格操作行為 + editor_mode.OriginDoActionList = editor_mode.doActionList; + editor_mode.doActionList = function (mode, actionList, callback) { + if (editor_mode.mode == "CommonEventTemplate") { + if (actionList.length == 0) return; + printf("修改中..."); + var cb = function (objs_) { + if (objs_.slice(-1)[0] != null) { + printe(objs_.slice(-1)[0]); + throw objs_.slice(-1)[0]; + } + var str = "修改成功!"; + if ( + data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.firstData.name == + "template" + ) + str += "
请注意:全塔属性的name尚未修改,请及时予以设置。"; + printf(str); + if (callback) callback(); + }; + editor.file.editCommonEventTemplate(actionList, cb); + } else { + editor_mode.OriginDoActionList(mode, actionList, callback); + } + }; + //添加表格列 + editor.table.CommonEventTemplateAddFunc = function () { + let obj = events_c12a15a8_c380_4b28_8144_256cba95f760; - // 1.输入id - let newid = prompt("请输入新项的ID(支持中文)"); - if (newid == null || newid.length == 0) { - return; - } + // 1.输入id + let newid = prompt("请输入新项的ID(支持中文)"); + if (newid == null || newid.length == 0) { + return; + } - // 2.检查id是否符合规范或与已有id重复 - var conflict = true; - var basefield = "".replace(/\[[^\[]*\]$/, ""); + // 2.检查id是否符合规范或与已有id重复 + var conflict = true; + var basefield = "".replace(/\[[^\[]*\]$/, ""); - try { - var baseobj = eval("obj" + basefield); - conflict = newid in baseobj; - } catch (ee) { - // 理论上这里不会发生错误 - printe(ee); - throw ee; - } + try { + var baseobj = eval("obj" + basefield); + conflict = newid in baseobj; + } catch (ee) { + // 理论上这里不会发生错误 + printe(ee); + throw ee; + } - if (conflict) { - printe("id已存在, 请直接修改该项的值"); - return; - } + if (conflict) { + printe("id已存在, 请直接修改该项的值"); + return; + } - // 3.添加 - editor_mode.addAction(["add", basefield + "['" + newid + "']", null]); - editor_mode.onmode("save", function () { - printf("添加成功,刷新后生效;也可以继续新增其他项目。"); - }); //自动保存 删掉此行的话点保存按钮才会保存 - }; - //對表格的存讀 - editor.file.editCommonEventTemplate = function (actionList, callback) { - /*actionList:[ + // 3.添加 + editor_mode.addAction(["add", basefield + "['" + newid + "']", null]); + editor_mode.onmode("save", function () { + printf("添加成功,刷新后生效;也可以继续新增其他项目。"); + }); //自动保存 删掉此行的话点保存按钮才会保存 + }; + //對表格的存讀 + editor.file.editCommonEventTemplate = function (actionList, callback) { + /*actionList:[ ["change","['test']",['123']], ] 为[]时只查询不修改 */ - var data_obj = - events_c12a15a8_c380_4b28_8144_256cba95f760.CommonEventTemplate; - checkCallback(callback); - if (isset(actionList) && actionList.length > 0) { - actionList.forEach(function (value) { - value[1] = "['CommonEventTemplate']" + value[1]; - }); - editor.file.saveSetting("events", actionList, function (err) { - callback([err]); - }); - } else { - callback([ - Object.assign({}, data_obj), - editor.file.CommonEventTemplate_comment._data.CommonEventTemplate, - null, - ]); - } - }; - })(); + var data_obj = + events_c12a15a8_c380_4b28_8144_256cba95f760.CommonEventTemplate; + checkCallback(callback); + if (isset(actionList) && actionList.length > 0) { + actionList.forEach(function (value) { + value[1] = "['CommonEventTemplate']" + value[1]; + }); + editor.file.saveSetting("events", actionList, function (err) { + callback([err]); + }); + } else { + callback([ + Object.assign({}, data_obj), + editor.file.CommonEventTemplate_comment._data.CommonEventTemplate, + null, + ]); + } + }; + })(); - //複寫事件編輯器(editor_blocklyconfig) - editor_blocklyconfig = function () { - // start mark sfergsvae + //複寫事件編輯器(editor_blocklyconfig) + editor_blocklyconfig = function () { + // start mark sfergsvae - (function () { - var getCategory = function (name, custom) { - for (var node of document.getElementById("toolbox").children) { - if (node.getAttribute("name") == name) return node; - } - var node = document.createElement("category"); - node.setAttribute("name", name); - if (custom) node.setAttribute("custom", custom); - document.getElementById("toolbox").appendChild(node); - return node; - }; + (function () { + var getCategory = function (name, custom) { + for (var node of document.getElementById("toolbox").children) { + if (node.getAttribute("name") == name) return node; + } + var node = document.createElement("category"); + node.setAttribute("name", name); + if (custom) node.setAttribute("custom", custom); + document.getElementById("toolbox").appendChild(node); + return node; + }; - var toolboxObj = { - 入口方块: [ - '', - MotaActionFunctions.actionParser.parse( - [ - "欢迎使用事件编辑器", - "本事件触发一次后会消失", - { type: "hide", time: 500 }, - ], - "event" - ), - MotaActionFunctions.actionParser.parse( - { - condition: "flag:__door__===2", - currentFloor: true, - priority: 0, - delayExecute: false, - multiExecute: false, - data: [{ type: "openDoor", loc: [10, 5] }], - }, - "autoEvent" - ), - MotaActionBlocks["changeFloor_m"].xmlText(), - MotaActionFunctions.actionParser.parse( - [ - { - id: "shop1", - text: "\t[贪婪之神,moneyShop]勇敢的武士啊, 给我${20+2*flag:shop1}金币就可以:", - textInList: "1F金币商店", - choices: [ - { - text: "生命+800", - need: "status:money>=20+2*flag:shop1", - action: [ - { - type: "comment", - text: "新版商店中需要手动扣减金币和增加访问次数", - }, - { - type: "setValue", - name: "status:money", - operator: "-=", - value: "20+2*flag:shop1", - }, - { - type: "setValue", - name: "flag:shop1", - operator: "+=", - value: "1", - }, - { - type: "setValue", - name: "status:hp", - operator: "+=", - value: "800", - }, - ], - }, - ], - }, - { - id: "itemShop", - item: true, - textInList: "道具商店", - choices: [{ id: "yellowKey", number: 10, money: 10 }], - }, - { - id: "keyShop1", - textInList: "回收钥匙商店", - commonEvent: "回收钥匙商店", - args: "", - }, - ], - "shop" - ), - MotaActionBlocks["common_m"].xmlText(), - MotaActionBlocks["beforeBattle_m"].xmlText(), - MotaActionBlocks["afterBattle_m"].xmlText(), - MotaActionBlocks["afterGetItem_m"].xmlText(), - MotaActionBlocks["afterOpenDoor_m"].xmlText(), - MotaActionBlocks["firstArrive_m"].xmlText(), - MotaActionBlocks["eachArrive_m"].xmlText(), - MotaActionBlocks["level_m"].xmlText(), - MotaActionFunctions.actionParser.parse( - [["MTx", ""]], - "floorPartition" - ), - MotaActionBlocks["commonEvent_m"].xmlText(), - MotaActionBlocks["item_m"].xmlText(), - MotaActionFunctions.actionParser.parse( - [ - { - title: "简单", - name: "Easy", - hard: 1, - action: [ - { type: "comment", text: "在这里写该难度需执行的事件" }, - ], - }, - ], - "levelChoose" - ), - MotaActionFunctions.actionParser.parse( - { - type: 0, - value: { atk: 10 }, - percentage: { speed: 10 }, - }, - "equip" - ), - MotaActionFunctions.actionParser.parse( - [ - { - name: "bg.webp", - x: 0, - y: 0, - canvas: "bg", - }, - ], - "floorImage" - ), - MotaActionFunctions.actionParser.parse( - { - time: 160, - openSound: "door.opus", - closeSound: "door.opus", - keys: { yellowKey: 1, orangeKey: 1 }, - }, - "doorInfo" - ), - MotaActionBlocks["faceIds_m"].xmlText(), - MotaActionBlocks["mainStyle_m"].xmlText(), - MotaActionFunctions.actionParser.parse( - { - 背景音乐: "bgm.opus", - 确定: "confirm.opus", - 攻击: "attack.opus", - 背景图: "bg.webp", - 领域: "zone", - 文件名: "file.jpg", - }, - "nameMap" - ), - MotaActionFunctions.actionParser.parse( - [{ name: "hero.webp", width: 32, height: 32, prefix: "hero_" }], - "splitImages" - ), - ], - 显示文字: [ - MotaActionBlocks["text_0_s"].xmlText(), - MotaActionBlocks["text_1_s"].xmlText(), - MotaActionFunctions.actionParser.parseList( - "\t[小妖精,fairy]\f[fairy.webp,0,0]欢迎使用事件编辑器(双击方块可直接预览)" - ), - MotaActionBlocks["over_s"].xmlText(), - MotaActionFunctions.actionParser.parseList([ - { - type: "overlist", - image: "bg_5043.webp", - memory: false, - hidetime: 30, - list: [ - { - text: "", - sound: "", - time: 50, - textColor: "255,255,255,1", - boldColor: "0,0,0,1", - font: "bold 48px Verdana", - frame: 0, - }, - ], - }, - ]), - MotaActionFunctions.actionParser.parseList([ - { - type: "cgtext", - bg: "bg_5043.webp", - memory: false, - WindowSkin: false, - head: { name: "face_050445.webp", px: -300 }, - name: "菲奥奈", - time: 0, - wait: 2000, - sound: "", - text: "这句话显示在对话框内", - bodyList: [ - { name: "tati_050145a.webp", px: 100, filter: false }, - ], - }, - ]), - MotaActionBlocks["moveTextBox_s"].xmlText(), - MotaActionBlocks["clearTextBox_s"].xmlText(), - MotaActionBlocks["comment_s"].xmlText(), - MotaActionBlocks["autoText_s"].xmlText(), - MotaActionBlocks["scrollText_s"].xmlText(), - MotaActionBlocks["setText_s"].xmlText(), - MotaActionBlocks["tip_s"].xmlText(), - MotaActionBlocks["addPop_s"].xmlText(), - MotaActionBlocks["confirm_s"].xmlText(), - MotaActionBlocks["choices_s"].xmlText([ - "选择剑或者盾", - "流浪者", - "man", - 0, - "", - MotaActionBlocks["choicesContext"].xmlText([ - "剑", - "", - "", - null, - "", - "", - MotaActionFunctions.actionParser.parseList([ - { type: "openDoor", loc: [3, 3] }, - ]), - ]), - ]), - MotaActionBlocks["win_s"].xmlText(), - MotaActionBlocks["lose_s"].xmlText(), - MotaActionBlocks["restart_s"].xmlText(), - ], - 数据相关: [ - MotaActionBlocks["setValue_s"].xmlText([ - MotaActionBlocks["idIdList_e"].xmlText(["status", "生命"]), - "=", - "", - false, - ]), - MotaActionBlocks["setEnemy_s"].xmlText(), - MotaActionBlocks["setEnemyOnPoint_s"].xmlText(), - MotaActionBlocks["resetEnemyOnPoint_s"].xmlText(), - MotaActionBlocks["moveEnemyOnPoint_s"].xmlText(), - MotaActionBlocks["moveEnemyOnPoint_1_s"].xmlText(), - MotaActionBlocks["setEquip_s"].xmlText(), - MotaActionBlocks["setFloor_s"].xmlText(), - MotaActionBlocks["setGlobalAttribute_s"].xmlText(), - MotaActionBlocks["setGlobalValue_s"].xmlText(), - MotaActionBlocks["setGlobalFlag_s"].xmlText(), - MotaActionBlocks["setNameMap_s"].xmlText(), - MotaActionBlocks["input_s"].xmlText(), - MotaActionBlocks["input2_s"].xmlText(), - MotaActionBlocks["update_s"].xmlText(), - MotaActionBlocks["moveAction_s"].xmlText(), - MotaActionBlocks["changeFloor_s"].xmlText(), - MotaActionBlocks["changePos_s"].xmlText(), - MotaActionBlocks["battle_s"].xmlText(), - MotaActionBlocks["useItem_s"].xmlText(), - MotaActionBlocks["loadEquip_s"].xmlText(), - MotaActionBlocks["unloadEquip_s"].xmlText(), - MotaActionBlocks["openShop_s"].xmlText(), - MotaActionBlocks["disableShop_s"].xmlText(), - MotaActionBlocks["setHeroIcon_s"].xmlText(), - MotaActionBlocks["follow_s"].xmlText(), - MotaActionBlocks["unfollow_s"].xmlText(), - ], - 地图处理: [ - MotaActionBlocks["battle_1_s"].xmlText(), - MotaActionBlocks["openDoor_s"].xmlText(), - MotaActionBlocks["closeDoor_s"].xmlText(), - MotaActionBlocks["show_s"].xmlText(), - MotaActionBlocks["hide_s"].xmlText(), - MotaActionBlocks["setBlock_s"].xmlText(), - MotaActionBlocks["setBlockOpacity_s"].xmlText(), - MotaActionBlocks["setBlockFilter_s"].xmlText(), - MotaActionBlocks["turnBlock_s"].xmlText(), - MotaActionBlocks["moveHero_s"].xmlText(), - MotaActionBlocks["move_s"].xmlText(), - MotaActionBlocks["jumpHero_s"].xmlText(), - MotaActionBlocks["jumpHero_1_s"].xmlText(), - MotaActionBlocks["jump_s"].xmlText(), - MotaActionBlocks["jump_1_s"].xmlText(), - MotaActionBlocks["showBgFgMap_s"].xmlText(), - MotaActionBlocks["hideBgFgMap_s"].xmlText(), - MotaActionBlocks["setBgFgBlock_s"].xmlText(), - MotaActionBlocks["showFloorImg_s"].xmlText(), - MotaActionBlocks["hideFloorImg_s"].xmlText(), - ], - 事件控制: [ - MotaActionBlocks["if_1_s"].xmlText(), - MotaActionBlocks["if_s"].xmlText(), - MotaActionFunctions.actionParser.parseList({ - type: "switch", - condition: "判别值", - caseList: [ - { - action: [ - { type: "comment", text: "当判别值是值的场合执行此事件" }, - ], - }, - { - case: "default", - action: [ - { - type: "comment", - text: "当没有符合的值的场合执行default事件", - }, - ], - }, - ], - }), - MotaActionFunctions.actionParser.parseList({ - type: "for", - name: "temp:A", - from: "0", - to: "12", - step: "1", - data: [], - }), - MotaActionFunctions.actionParser.parseList({ - type: "forEach", - name: "temp:A", - list: ["status:atk", "status:def"], - data: [], - }), - MotaActionBlocks["while_s"].xmlText(), - MotaActionBlocks["dowhile_s"].xmlText(), - MotaActionBlocks["break_s"].xmlText(), - MotaActionBlocks["continue_s"].xmlText(), - MotaActionBlocks["exit_s"].xmlText(), - MotaActionBlocks["trigger_s"].xmlText(), - MotaActionBlocks["insert_1_s"].xmlText(), - MotaActionBlocks["insert_2_s"].xmlText(), - ], - 特效表现: [ - MotaActionBlocks["sleep_s"].xmlText(), - MotaActionBlocks["setq_s"].xmlText(), - MotaActionBlocks["setcgs_s"].xmlText(), - MotaActionBlocks["setmusics_s"].xmlText(), - MotaActionBlocks["changebg_s"].xmlText(), - MotaActionFunctions.actionParser.parseList({ - type: "wait", - timeout: 0, - data: [ - { - case: "keyboard", - keycode: "13,32", - action: [ - { - type: "comment", - text: "当按下回车(keycode=13)或空格(keycode=32)时执行此事件\n超时剩余时间会写入flag:timeout", - }, - ], - }, - { - case: "mouse", - px: [0, 32], - py: [0, 32], - action: [ - { - type: "comment", - text: "当点击地图左上角时执行此事件\n超时剩余时间会写入flag:timeout", - }, - ], - }, - { - case: "condition", - condition: "flag:type==0\n&&flag:keycode==13", - action: [ - { - type: "comment", - text: "当满足自定义条件时会执行此事件\n超时剩余时间会写入flag:timeout", - }, - ], - }, - { - case: "timeout", - action: [ - { type: "comment", text: "当超时未操作时执行此事件" }, - ], - }, - ], - }), - MotaActionBlocks["waitAsync_s"].xmlText(), - MotaActionBlocks["stopAsync_s"].xmlText(), - MotaActionBlocks["op_s"].xmlText(), - MotaActionBlocks["drawWarning_s"].xmlText(), - MotaActionBlocks["changeMouse_s"].xmlText(), - MotaActionBlocks["removeMouse_s"].xmlText(), - MotaActionBlocks["vibrate_s"].xmlText(), - MotaActionBlocks["animate_s"].xmlText(), - MotaActionBlocks["animate_1_s"].xmlText(), - MotaActionBlocks["stopAnimate_s"].xmlText(), - MotaActionBlocks["setViewport_s"].xmlText(), - MotaActionBlocks["setViewport_1_s"].xmlText(), - MotaActionBlocks["lockViewport_s"].xmlText(), - MotaActionBlocks["showStatusBar_s"].xmlText(), - MotaActionBlocks["hideStatusBar_s"].xmlText(), - MotaActionBlocks["setHeroOpacity_s"].xmlText(), - MotaActionBlocks["setCurtain_0_s"].xmlText(), - MotaActionBlocks["setCurtain_1_s"].xmlText(), - MotaActionBlocks["screenFlash_s"].xmlText(), - MotaActionBlocks["setWeather_s"].xmlText(), - MotaActionBlocks["callBook_s"].xmlText(), - MotaActionBlocks["callSave_s"].xmlText(), - MotaActionBlocks["autoSave_s"].xmlText(), - MotaActionBlocks["forbidSave_s"].xmlText(), - MotaActionBlocks["callLoad_s"].xmlText(), - ], - 音像处理: [ - MotaActionBlocks["animationDrawable_s"].xmlText(), - MotaActionBlocks["introAndLoop_s"].xmlText(), - MotaActionBlocks["setanimate_s"].xmlText(), - MotaActionBlocks["deleteanimate_s"].xmlText(), - MotaActionBlocks["playanimate_s"].xmlText(), - MotaActionBlocks["clearanimate_s"].xmlText(), - MotaActionBlocks["showImage_s"].xmlText(), - MotaActionBlocks["showImage_1_s"].xmlText(), - MotaActionBlocks["hideImage_s"].xmlText(), - MotaActionBlocks["showTextImage_s"].xmlText(), - MotaActionBlocks["moveImage_s"].xmlText(), - MotaActionBlocks["rotateImage_s"].xmlText(), - MotaActionBlocks["scaleImage_s"].xmlText(), - MotaActionBlocks["showGif_s"].xmlText(), - MotaActionBlocks["playBgm_s"].xmlText(), - MotaActionBlocks["playStereo_s"].xmlText(), - MotaActionBlocks["moveStereo_s"].xmlText(), - MotaActionBlocks["pauseBgm_s"].xmlText(), - MotaActionBlocks["resumeBgm_s"].xmlText(), - MotaActionBlocks["loadBgm_s"].xmlText(), - MotaActionBlocks["freeBgm_s"].xmlText(), - MotaActionBlocks["playSound_s"].xmlText(), - MotaActionBlocks["playSound_1_s"].xmlText(), - MotaActionBlocks["stopSound_s"].xmlText(), - MotaActionBlocks["setVolume_s"].xmlText(), - MotaActionBlocks["setBgmSpeed_s"].xmlText(), - ], - UI绘制: [ - MotaActionBlocks["previewUI_s"].xmlText(), - MotaActionBlocks["clearMap_s"].xmlText(), - MotaActionBlocks["setAttribute_s"].xmlText(), - MotaActionBlocks["setFilter_s"].xmlText(), - MotaActionBlocks["fillText_s"].xmlText(), - MotaActionBlocks["fillBoldText_s"].xmlText(), - MotaActionBlocks["drawTextContent_s"].xmlText(), - MotaActionBlocks["fillRect_s"].xmlText(), - MotaActionBlocks["strokeRect_s"].xmlText(), - MotaActionBlocks["drawLine_s"].xmlText(), - MotaActionBlocks["drawArrow_s"].xmlText(), - MotaActionBlocks["fillPolygon_s"].xmlText(), - MotaActionBlocks["strokePolygon_s"].xmlText(), - MotaActionBlocks["fillEllipse_s"].xmlText(), - MotaActionBlocks["strokeEllipse_s"].xmlText(), - MotaActionBlocks["fillArc_s"].xmlText(), - MotaActionBlocks["strokeArc_s"].xmlText(), - MotaActionBlocks["drawImage_s"].xmlText(), - MotaActionBlocks["drawImage_1_s"].xmlText(), - MotaActionBlocks["drawIcon_s"].xmlText(), - MotaActionBlocks["drawBackground_s"].xmlText(), - MotaActionBlocks["drawSelector_s"].xmlText(), - MotaActionBlocks["drawSelector_1_s"].xmlText(), - ], - 原生脚本: [ - MotaActionBlocks["function_s"].xmlText(), - MotaActionBlocks["unknown_s"].xmlText(), - ], - 值块: [ - MotaActionBlocks["setValue_s"].xmlText([ - MotaActionBlocks["idIdList_e"].xmlText(["status", "生命"]), - "=", - "", - false, - ]), - MotaActionBlocks["expression_arithmetic_0"].xmlText(), - MotaActionBlocks["idFlag_e"].xmlText(), - MotaActionBlocks["idTemp_e"].xmlText(), - MotaActionBlocks["negate_e"].xmlText(), - MotaActionBlocks["unaryOperation_e"].xmlText(), - MotaActionBlocks["bool_e"].xmlText(), - MotaActionBlocks["idString_e"].xmlText(), - MotaActionBlocks["idIdList_e"].xmlText(), - MotaActionBlocks["idFixedList_e"].xmlText(), - MotaActionBlocks["enemyattr_e"].xmlText(), - MotaActionBlocks["blockId_e"].xmlText(), - MotaActionBlocks["blockNumber_e"].xmlText(), - MotaActionBlocks["blockCls_e"].xmlText(), - MotaActionBlocks["hasEquip_e"].xmlText(), - MotaActionBlocks["equip_e"].xmlText(), - MotaActionBlocks["nextXY_e"].xmlText(), - MotaActionBlocks["isReplaying_e"].xmlText(), - MotaActionBlocks["hasVisitedFloor_e"].xmlText(), - MotaActionBlocks["isShopVisited_e"].xmlText(), - MotaActionBlocks["canBattle_e"].xmlText(), - MotaActionBlocks["damage_e"].xmlText(), - MotaActionBlocks["damage_1_e"].xmlText(), - MotaActionBlocks["rand_e"].xmlText(), - MotaActionBlocks["evalString_e"].xmlText(), - ], - 常见事件模板: [ - '', - ], - 最近使用事件: [ - '', - ], - }; - var toolboxgap = ''; - //xml_text = MotaActionFunctions.actionParser.parse(obj,type||'event') - //MotaActionBlocks['idString_e'].xmlText() + var toolboxObj = { + 入口方块: [ + '', + MotaActionFunctions.actionParser.parse( + [ + "欢迎使用事件编辑器", + "本事件触发一次后会消失", + { type: "hide", time: 500 }, + ], + "event" + ), + MotaActionFunctions.actionParser.parse({ + condition: "flag:__door__===2", + currentFloor: true, + priority: 0, + delayExecute: false, + multiExecute: false, + data: [{ type: "openDoor", loc: [10, 5] }], + }, + "autoEvent" + ), + MotaActionBlocks["changeFloor_m"].xmlText(), + MotaActionFunctions.actionParser.parse( + [{ + id: "shop1", + text: "\t[贪婪之神,moneyShop]勇敢的武士啊, 给我${20+2*flag:shop1}金币就可以:", + textInList: "1F金币商店", + choices: [{ + text: "生命+800", + need: "status:money>=20+2*flag:shop1", + action: [{ + type: "comment", + text: "新版商店中需要手动扣减金币和增加访问次数", + }, + { + type: "setValue", + name: "status:money", + operator: "-=", + value: "20+2*flag:shop1", + }, + { + type: "setValue", + name: "flag:shop1", + operator: "+=", + value: "1", + }, + { + type: "setValue", + name: "status:hp", + operator: "+=", + value: "800", + }, + ], + }, ], + }, + { + id: "itemShop", + item: true, + textInList: "道具商店", + choices: [{ id: "yellowKey", number: 10, money: 10 }], + }, + { + id: "keyShop1", + textInList: "回收钥匙商店", + commonEvent: "回收钥匙商店", + args: "", + }, + ], + "shop" + ), + MotaActionBlocks["common_m"].xmlText(), + MotaActionBlocks["beforeBattle_m"].xmlText(), + MotaActionBlocks["afterBattle_m"].xmlText(), + MotaActionBlocks["afterGetItem_m"].xmlText(), + MotaActionBlocks["afterOpenDoor_m"].xmlText(), + MotaActionBlocks["firstArrive_m"].xmlText(), + MotaActionBlocks["eachArrive_m"].xmlText(), + MotaActionBlocks["level_m"].xmlText(), + MotaActionFunctions.actionParser.parse( + [ + ["MTx", ""] + ], + "floorPartition" + ), + MotaActionBlocks["commonEvent_m"].xmlText(), + MotaActionBlocks["item_m"].xmlText(), + MotaActionFunctions.actionParser.parse( + [{ + title: "简单", + name: "Easy", + hard: 1, + action: [ + { type: "comment", text: "在这里写该难度需执行的事件" }, + ], + }, ], + "levelChoose" + ), + MotaActionFunctions.actionParser.parse({ + type: 0, + value: { atk: 10 }, + percentage: { speed: 10 }, + }, + "equip" + ), + MotaActionFunctions.actionParser.parse( + [{ + name: "bg.webp", + x: 0, + y: 0, + canvas: "bg", + }, ], + "floorImage" + ), + MotaActionFunctions.actionParser.parse({ + time: 160, + openSound: "door.opus", + closeSound: "door.opus", + keys: { yellowKey: 1, orangeKey: 1 }, + }, + "doorInfo" + ), + MotaActionBlocks["faceIds_m"].xmlText(), + MotaActionBlocks["mainStyle_m"].xmlText(), + MotaActionFunctions.actionParser.parse({ + 背景音乐: "bgm.opus", + 确定: "confirm.opus", + 攻击: "attack.opus", + 背景图: "bg.webp", + 领域: "zone", + 文件名: "file.jpg", + }, + "nameMap" + ), + MotaActionFunctions.actionParser.parse( + [{ name: "hero.webp", width: 32, height: 32, prefix: "hero_" }], + "splitImages" + ), + ], + 显示文字: [ + MotaActionBlocks["text_0_s"].xmlText(), + MotaActionBlocks["text_1_s"].xmlText(), + MotaActionFunctions.actionParser.parseList( + "\t[小妖精,fairy]\f[fairy.webp,0,0]欢迎使用事件编辑器(双击方块可直接预览)" + ), + MotaActionBlocks["over_s"].xmlText(), + MotaActionFunctions.actionParser.parseList([{ + type: "overlist", + image: "bg_5043.webp", + memory: false, + hidetime: 30, + list: [{ + text: "", + sound: "", + time: 50, + textColor: "255,255,255,1", + boldColor: "0,0,0,1", + font: "bold 48px Verdana", + frame: 0, + }, ], + }, ]), + MotaActionBlocks["cgtextList_s"].xmlText(), + MotaActionFunctions.actionParser.parseList([{ + type: "cgtext", + bg: "bg_5043.webp", + memory: false, + WindowSkin: false, + index: 0, + head: { name: "face_050445.webp", px: -300 }, - //#region 動態常見事件模板 - let CommonEventTemplateHTML = []; + time: 0, + wait: 2000, + sound: "", - for (let commonEventName in events_c12a15a8_c380_4b28_8144_256cba95f760.CommonEventTemplate) { - if ( - events_c12a15a8_c380_4b28_8144_256cba95f760.CommonEventTemplate.hasOwnProperty( - commonEventName - ) - ) { - let actionParserJson = Array.from( - events_c12a15a8_c380_4b28_8144_256cba95f760.CommonEventTemplate[ - commonEventName - ] ?? [] - ); + bodyList: [ + { name: "tati_050145a.webp", px: 100, filter: false }, + ], + }, ]), + MotaActionBlocks["moveTextBox_s"].xmlText(), + MotaActionBlocks["clearTextBox_s"].xmlText(), + MotaActionBlocks["comment_s"].xmlText(), + MotaActionBlocks["autoText_s"].xmlText(), + MotaActionBlocks["scrollText_s"].xmlText(), + MotaActionBlocks["setText_s"].xmlText(), + MotaActionBlocks["tip_s"].xmlText(), + MotaActionBlocks["addPop_s"].xmlText(), + MotaActionBlocks["confirm_s"].xmlText(), + MotaActionBlocks["choices_s"].xmlText([ + "选择剑或者盾", + "流浪者", + "man", + 0, + "", + MotaActionBlocks["choicesContext"].xmlText([ + "剑", + "", + "", + null, + "", + "", + MotaActionFunctions.actionParser.parseList([ + { type: "openDoor", loc: [3, 3] }, + ]), + ]), + ]), + MotaActionBlocks["win_s"].xmlText(), + MotaActionBlocks["lose_s"].xmlText(), + MotaActionBlocks["restart_s"].xmlText(), + ], + 数据相关: [ + MotaActionBlocks["setValue_s"].xmlText([ + MotaActionBlocks["idIdList_e"].xmlText(["status", "生命"]), + "=", + "", + false, + ]), + MotaActionBlocks["setEnemy_s"].xmlText(), + MotaActionBlocks["setEnemyOnPoint_s"].xmlText(), + MotaActionBlocks["resetEnemyOnPoint_s"].xmlText(), + MotaActionBlocks["moveEnemyOnPoint_s"].xmlText(), + MotaActionBlocks["moveEnemyOnPoint_1_s"].xmlText(), + MotaActionBlocks["setEquip_s"].xmlText(), + MotaActionBlocks["setFloor_s"].xmlText(), + MotaActionBlocks["setGlobalAttribute_s"].xmlText(), + MotaActionBlocks["setGlobalValue_s"].xmlText(), + MotaActionBlocks["setGlobalFlag_s"].xmlText(), + MotaActionBlocks["setNameMap_s"].xmlText(), + MotaActionBlocks["input_s"].xmlText(), + MotaActionBlocks["input2_s"].xmlText(), + MotaActionBlocks["update_s"].xmlText(), + MotaActionBlocks["moveAction_s"].xmlText(), + MotaActionBlocks["changeFloor_s"].xmlText(), + MotaActionBlocks["changePos_s"].xmlText(), + MotaActionBlocks["battle_s"].xmlText(), + MotaActionBlocks["useItem_s"].xmlText(), + MotaActionBlocks["loadEquip_s"].xmlText(), + MotaActionBlocks["unloadEquip_s"].xmlText(), + MotaActionBlocks["openShop_s"].xmlText(), + MotaActionBlocks["disableShop_s"].xmlText(), + MotaActionBlocks["setHeroIcon_s"].xmlText(), + MotaActionBlocks["follow_s"].xmlText(), + MotaActionBlocks["unfollow_s"].xmlText(), + ], + 地图处理: [ + MotaActionBlocks["battle_1_s"].xmlText(), + MotaActionBlocks["openDoor_s"].xmlText(), + MotaActionBlocks["closeDoor_s"].xmlText(), + MotaActionBlocks["show_s"].xmlText(), + MotaActionBlocks["hide_s"].xmlText(), + MotaActionBlocks["setBlock_s"].xmlText(), + MotaActionBlocks["setBlockOpacity_s"].xmlText(), + MotaActionBlocks["setBlockFilter_s"].xmlText(), + MotaActionBlocks["turnBlock_s"].xmlText(), + MotaActionBlocks["moveHero_s"].xmlText(), + MotaActionBlocks["move_s"].xmlText(), + MotaActionBlocks["jumpHero_s"].xmlText(), + MotaActionBlocks["jumpHero_1_s"].xmlText(), + MotaActionBlocks["jump_s"].xmlText(), + MotaActionBlocks["jump_1_s"].xmlText(), + MotaActionBlocks["showBgFgMap_s"].xmlText(), + MotaActionBlocks["hideBgFgMap_s"].xmlText(), + MotaActionBlocks["setBgFgBlock_s"].xmlText(), + MotaActionBlocks["showFloorImg_s"].xmlText(), + MotaActionBlocks["hideFloorImg_s"].xmlText(), + ], + 事件控制: [ + MotaActionBlocks["if_1_s"].xmlText(), + MotaActionBlocks["if_s"].xmlText(), + MotaActionFunctions.actionParser.parseList({ + type: "switch", + condition: "判别值", + caseList: [{ + action: [ + { type: "comment", text: "当判别值是值的场合执行此事件" }, + ], + }, + { + case: "default", + action: [{ + type: "comment", + text: "当没有符合的值的场合执行default事件", + }, ], + }, + ], + }), + MotaActionFunctions.actionParser.parseList({ + type: "for", + name: "temp:A", + from: "0", + to: "12", + step: "1", + data: [], + }), + MotaActionFunctions.actionParser.parseList({ + type: "forEach", + name: "temp:A", + list: ["status:atk", "status:def"], + data: [], + }), + MotaActionBlocks["while_s"].xmlText(), + MotaActionBlocks["dowhile_s"].xmlText(), + MotaActionBlocks["break_s"].xmlText(), + MotaActionBlocks["continue_s"].xmlText(), + MotaActionBlocks["exit_s"].xmlText(), + MotaActionBlocks["trigger_s"].xmlText(), + MotaActionBlocks["insert_1_s"].xmlText(), + MotaActionBlocks["insert_2_s"].xmlText(), + ], + 特效表现: [ + MotaActionBlocks["sleep_s"].xmlText(), + MotaActionBlocks["setq_s"].xmlText(), + MotaActionBlocks["setcgs_s"].xmlText(), + MotaActionBlocks["setmusics_s"].xmlText(), + MotaActionBlocks["changebg_s"].xmlText(), + MotaActionFunctions.actionParser.parseList({ + type: "wait", + timeout: 0, + data: [{ + case: "keyboard", + keycode: "13,32", + action: [{ + type: "comment", + text: "当按下回车(keycode=13)或空格(keycode=32)时执行此事件\n超时剩余时间会写入flag:timeout", + }, ], + }, + { + case: "mouse", + px: [0, 32], + py: [0, 32], + action: [{ + type: "comment", + text: "当点击地图左上角时执行此事件\n超时剩余时间会写入flag:timeout", + }, ], + }, + { + case: "condition", + condition: "flag:type==0\n&&flag:keycode==13", + action: [{ + type: "comment", + text: "当满足自定义条件时会执行此事件\n超时剩余时间会写入flag:timeout", + }, ], + }, + { + case: "timeout", + action: [ + { type: "comment", text: "当超时未操作时执行此事件" }, + ], + }, + ], + }), + MotaActionBlocks["waitAsync_s"].xmlText(), + MotaActionBlocks["stopAsync_s"].xmlText(), + MotaActionBlocks["op_s"].xmlText(), + MotaActionBlocks["drawWarning_s"].xmlText(), + MotaActionBlocks["changeMouse_s"].xmlText(), + MotaActionBlocks["removeMouse_s"].xmlText(), + MotaActionBlocks["vibrate_s"].xmlText(), + MotaActionBlocks["animate_s"].xmlText(), + MotaActionBlocks["animate_1_s"].xmlText(), + MotaActionBlocks["stopAnimate_s"].xmlText(), + MotaActionBlocks["setViewport_s"].xmlText(), + MotaActionBlocks["setViewport_1_s"].xmlText(), + MotaActionBlocks["lockViewport_s"].xmlText(), + MotaActionBlocks["showStatusBar_s"].xmlText(), + MotaActionBlocks["hideStatusBar_s"].xmlText(), + MotaActionBlocks["setHeroOpacity_s"].xmlText(), + MotaActionBlocks["setCurtain_0_s"].xmlText(), + MotaActionBlocks["setCurtain_1_s"].xmlText(), + MotaActionBlocks["screenFlash_s"].xmlText(), + MotaActionBlocks["setWeather_s"].xmlText(), + MotaActionBlocks["callBook_s"].xmlText(), + MotaActionBlocks["callSave_s"].xmlText(), + MotaActionBlocks["autoSave_s"].xmlText(), + MotaActionBlocks["forbidSave_s"].xmlText(), + MotaActionBlocks["callLoad_s"].xmlText(), + ], + 音像处理: [ + MotaActionBlocks["animationDrawable_s"].xmlText(), + MotaActionBlocks["introAndLoop_s"].xmlText(), + MotaActionBlocks["setanimate_s"].xmlText(), + MotaActionBlocks["deleteanimate_s"].xmlText(), + MotaActionBlocks["playanimate_s"].xmlText(), + MotaActionBlocks["clearanimate_s"].xmlText(), + MotaActionBlocks["showImage_s"].xmlText(), + MotaActionBlocks["showImage_1_s"].xmlText(), + MotaActionBlocks["hideImage_s"].xmlText(), + MotaActionBlocks["showTextImage_s"].xmlText(), + MotaActionBlocks["moveImage_s"].xmlText(), + MotaActionBlocks["rotateImage_s"].xmlText(), + MotaActionBlocks["scaleImage_s"].xmlText(), + MotaActionBlocks["showGif_s"].xmlText(), + MotaActionBlocks["playBgm_s"].xmlText(), + MotaActionBlocks["pauseBgm_s"].xmlText(), + MotaActionBlocks["resumeBgm_s"].xmlText(), + MotaActionBlocks["loadBgm_s"].xmlText(), + MotaActionBlocks["freeBgm_s"].xmlText(), + MotaActionBlocks["playSound_s"].xmlText(), + MotaActionBlocks["playSound_1_s"].xmlText(), + MotaActionBlocks["stopSound_s"].xmlText(), + MotaActionBlocks["setVolume_s"].xmlText(), + MotaActionBlocks["setBgmSpeed_s"].xmlText(), + ], + UI绘制: [ + MotaActionBlocks["previewUI_s"].xmlText(), + MotaActionBlocks["clearMap_s"].xmlText(), + MotaActionBlocks["setAttribute_s"].xmlText(), + MotaActionBlocks["setFilter_s"].xmlText(), + MotaActionBlocks["fillText_s"].xmlText(), + MotaActionBlocks["fillBoldText_s"].xmlText(), + MotaActionBlocks["drawTextContent_s"].xmlText(), + MotaActionBlocks["fillRect_s"].xmlText(), + MotaActionBlocks["strokeRect_s"].xmlText(), + MotaActionBlocks["drawLine_s"].xmlText(), + MotaActionBlocks["drawArrow_s"].xmlText(), + MotaActionBlocks["fillPolygon_s"].xmlText(), + MotaActionBlocks["strokePolygon_s"].xmlText(), + MotaActionBlocks["fillEllipse_s"].xmlText(), + MotaActionBlocks["strokeEllipse_s"].xmlText(), + MotaActionBlocks["fillArc_s"].xmlText(), + MotaActionBlocks["strokeArc_s"].xmlText(), + MotaActionBlocks["drawImage_s"].xmlText(), + MotaActionBlocks["drawImage_1_s"].xmlText(), + MotaActionBlocks["drawIcon_s"].xmlText(), + MotaActionBlocks["drawBackground_s"].xmlText(), + MotaActionBlocks["drawSelector_s"].xmlText(), + MotaActionBlocks["drawSelector_1_s"].xmlText(), + ], + 原生脚本: [ + MotaActionBlocks["function_s"].xmlText(), + MotaActionBlocks["unknown_s"].xmlText(), + ], + 值块: [ + MotaActionBlocks["setValue_s"].xmlText([ + MotaActionBlocks["idIdList_e"].xmlText(["status", "生命"]), + "=", + "", + false, + ]), + MotaActionBlocks["expression_arithmetic_0"].xmlText(), + MotaActionBlocks["idFlag_e"].xmlText(), + MotaActionBlocks["idTemp_e"].xmlText(), + MotaActionBlocks["negate_e"].xmlText(), + MotaActionBlocks["unaryOperation_e"].xmlText(), + MotaActionBlocks["bool_e"].xmlText(), + MotaActionBlocks["idString_e"].xmlText(), + MotaActionBlocks["idIdList_e"].xmlText(), + MotaActionBlocks["idFixedList_e"].xmlText(), + MotaActionBlocks["enemyattr_e"].xmlText(), + MotaActionBlocks["blockId_e"].xmlText(), + MotaActionBlocks["blockNumber_e"].xmlText(), + MotaActionBlocks["blockCls_e"].xmlText(), + MotaActionBlocks["hasEquip_e"].xmlText(), + MotaActionBlocks["equip_e"].xmlText(), + MotaActionBlocks["nextXY_e"].xmlText(), + MotaActionBlocks["isReplaying_e"].xmlText(), + MotaActionBlocks["hasVisitedFloor_e"].xmlText(), + MotaActionBlocks["isShopVisited_e"].xmlText(), + MotaActionBlocks["canBattle_e"].xmlText(), + MotaActionBlocks["damage_e"].xmlText(), + MotaActionBlocks["damage_1_e"].xmlText(), + MotaActionBlocks["rand_e"].xmlText(), + MotaActionBlocks["evalString_e"].xmlText(), + ], + 常见事件模板: [ + '', + ], + 最近使用事件: [ + '', + ], + }; + var toolboxgap = ''; + //xml_text = MotaActionFunctions.actionParser.parse(obj,type||'event') + //MotaActionBlocks['idString_e'].xmlText() - let labelHTML = ""; - let blockHTML = ""; + //#region 動態常見事件模板 + let CommonEventTemplateHTML = []; - labelHTML = ``; + for (let commonEventName in events_c12a15a8_c380_4b28_8144_256cba95f760.CommonEventTemplate) { + if ( + events_c12a15a8_c380_4b28_8144_256cba95f760.CommonEventTemplate.hasOwnProperty( + commonEventName + ) + ) { + let actionParserJson = Array.from( + events_c12a15a8_c380_4b28_8144_256cba95f760.CommonEventTemplate[ + commonEventName + ] ?? [] + ); - if (actionParserJson.length > 1) { - actionParserJson = { - type: "if", - condition: "true", - true: actionParserJson, - }; - } else if (actionParserJson.length < 1) { - actionParserJson = [ - "空的常用事件模板。\n請在主頁下拉菜單中,選擇常用事件模板,進行編輯。\n編輯後需按F5刷新事件編輯器。", - ]; - } - blockHTML = - MotaActionFunctions.actionParser.parseList(actionParserJson); + let labelHTML = ""; + let blockHTML = ""; - CommonEventTemplateHTML.push(labelHTML); - CommonEventTemplateHTML.push(blockHTML); - } - } + labelHTML = ``; - toolboxObj["常见事件模板"] = CommonEventTemplateHTML; - //#endregion + if (actionParserJson.length > 1) { + actionParserJson = { + type: "if", + condition: "true", + true: actionParserJson, + }; + } else if (actionParserJson.length < 1) { + actionParserJson = [ + "空的常用事件模板。\n請在主頁下拉菜單中,選擇常用事件模板,進行編輯。\n編輯後需按F5刷新事件編輯器。", + ]; + } + blockHTML = + MotaActionFunctions.actionParser.parseList(actionParserJson); - for (var name in toolboxObj) { - var custom = null; - if (name == "最近使用事件") custom = "searchBlockCategory"; - if (name == "入口方块") custom = "entranceCategory"; - getCategory(name, custom).innerHTML = - toolboxObj[name].join(toolboxgap); - } + CommonEventTemplateHTML.push(labelHTML); + CommonEventTemplateHTML.push(blockHTML); + } + } - var blocklyArea = document.getElementById("blocklyArea"); - var blocklyDiv = document.getElementById("blocklyDiv"); - var workspace = Blockly.inject(blocklyDiv, { - media: "_server/blockly/media/", - toolbox: document.getElementById("toolbox"), - zoom: { - controls: true, - wheel: false, //滚轮改为上下(shift:左右)翻滚 - startScale: 1.0, - maxScale: 3, - minScale: 0.3, - scaleSpeed: 1.08, - }, - trashcan: false, - }); + toolboxObj["常见事件模板"] = CommonEventTemplateHTML; + //#endregion - editor_blockly.isCommonEntry = function () { - var commonEntries = [ - "beforeBattle", - "afterBattle", - "afterOpenDoor", - "firstArrive", - "eachArrive", - "commonEvent", - "item", - ]; - return commonEntries.indexOf(editor_blockly.entryType) >= 0; - }; + for (var name in toolboxObj) { + var custom = null; + if (name == "最近使用事件") custom = "searchBlockCategory"; + if (name == "入口方块") custom = "entranceCategory"; + getCategory(name, custom).innerHTML = + toolboxObj[name].join(toolboxgap); + } - editor_blockly.entranceCategoryCallback = function (workspace) { - var list = toolboxObj["入口方块"]; - var xmlList = []; - var eventType = - (editor_blockly.isCommonEntry() - ? "common" - : editor_blockly.entryType) + "_m"; - for (var ii = 0, blockText; (blockText = list[ii]); ii++) { - if ( - new RegExp('').exec(blockText) - ) { - var block = Blockly.Xml.textToDom( - "" + blockText + "" - ).firstChild; - block.setAttribute("gap", 5); - xmlList.push(block); - } - } - return xmlList; - }; + var blocklyArea = document.getElementById("blocklyArea"); + var blocklyDiv = document.getElementById("blocklyDiv"); + var workspace = Blockly.inject(blocklyDiv, { + media: "_server/blockly/media/", + toolbox: document.getElementById("toolbox"), + zoom: { + controls: true, + wheel: false, //滚轮改为上下(shift:左右)翻滚 + startScale: 1.0, + maxScale: 3, + minScale: 0.3, + scaleSpeed: 1.08, + }, + trashcan: false, + }); - workspace.registerToolboxCategoryCallback( - "entranceCategory", - editor_blockly.entranceCategoryCallback - ); + editor_blockly.isCommonEntry = function () { + var commonEntries = [ + "beforeBattle", + "afterBattle", + "afterOpenDoor", + "firstArrive", + "eachArrive", + "commonEvent", + "item", + ]; + return commonEntries.indexOf(editor_blockly.entryType) >= 0; + }; - editor_blockly.searchBlockCategoryCallback = function (workspace) { - var xmlList = []; - var labels = editor_blockly.searchBlock(); - for (var i = 0; i < labels.length; i++) { - var blockText = - "" + MotaActionBlocks[labels[i]].xmlText() + ""; - var block = Blockly.Xml.textToDom(blockText).firstChild; - block.setAttribute("gap", 5); - xmlList.push(block); - } - return xmlList; - }; + editor_blockly.entranceCategoryCallback = function (workspace) { + var list = toolboxObj["入口方块"]; + var xmlList = []; + var eventType = + (editor_blockly.isCommonEntry() ? + "common" : + editor_blockly.entryType) + "_m"; + for (var ii = 0, blockText; + (blockText = list[ii]); ii++) { + if ( + new RegExp('').exec(blockText) + ) { + var block = Blockly.Xml.textToDom( + "" + blockText + "" + ).firstChild; + block.setAttribute("gap", 5); + xmlList.push(block); + } + } + return xmlList; + }; - workspace.registerToolboxCategoryCallback( - "searchBlockCategory", - editor_blockly.searchBlockCategoryCallback - ); + workspace.registerToolboxCategoryCallback( + "entranceCategory", + editor_blockly.entranceCategoryCallback + ); - var onresize = function (e) { - blocklyDiv.style.width = blocklyArea.offsetWidth + "px"; - blocklyDiv.style.height = blocklyArea.offsetHeight + "px"; - Blockly.svgResize(workspace); - }; - if (typeof editor !== "undefined" && !editor.isMobile) - window.addEventListener("resize", onresize, false); - onresize(); - //Blockly.svgResize(workspace); + editor_blockly.searchBlockCategoryCallback = function (workspace) { + var xmlList = []; + var labels = editor_blockly.searchBlock(); + for (var i = 0; i < labels.length; i++) { + var blockText = + "" + MotaActionBlocks[labels[i]].xmlText() + ""; + var block = Blockly.Xml.textToDom(blockText).firstChild; + block.setAttribute("gap", 5); + xmlList.push(block); + } + return xmlList; + }; - //Blockly.bindEventWithChecks_(workspace.svgGroup_,"wheel",workspace,function(e){}); - document.getElementById("blocklyDiv").onmousewheel = function (e) { - //console.log(e); - e.preventDefault(); - var hvScroll = e.shiftKey ? "hScroll" : "vScroll"; - var mousewheelOffsetValue = - (20 / 380) * workspace.scrollbar[hvScroll].handleLength_ * 3; - workspace.scrollbar[hvScroll].handlePosition_ += - (e.deltaY || 0) + (e.detail || 0) > 0 - ? mousewheelOffsetValue - : -mousewheelOffsetValue; - workspace.scrollbar[hvScroll].onScroll_(); - // workspace.setScale(workspace.scale); - }; + workspace.registerToolboxCategoryCallback( + "searchBlockCategory", + editor_blockly.searchBlockCategoryCallback + ); - var doubleClickCheck = [[0, "abc"]]; + var onresize = function (e) { + blocklyDiv.style.width = blocklyArea.offsetWidth + "px"; + blocklyDiv.style.height = blocklyArea.offsetHeight + "px"; + Blockly.svgResize(workspace); + }; + if (typeof editor !== "undefined" && !editor.isMobile) + window.addEventListener("resize", onresize, false); + onresize(); + //Blockly.svgResize(workspace); - function omitedcheckUpdateFunction(event) { - if (event.type === "create") { - editor_blockly.addIntoLastUsedType(event.blockId); - } - if (event.type === "ui" && event.element == "click") { - var newClick = [new Date().getTime(), event.blockId]; - var lastClick = doubleClickCheck.shift(); - doubleClickCheck.push(newClick); - if (newClick[0] - lastClick[0] < 500) { - if (newClick[1] === lastClick[1]) { - editor_blockly.doubleClickBlock(newClick[1]); - } - } - } - // Only handle these events - if (["create", "move", "change", "delete"].indexOf(event.type) < 0) - return; - if (editor_blockly.workspace.topBlocks_.length >= 2) { - editor_blockly.setValue("入口方块只能有一个"); - return; - } - var eventType = editor_blockly.entryType; - if (editor_blockly.workspace.topBlocks_.length == 1) { - var blockType = editor_blockly.workspace.topBlocks_[0].type; - if ( - blockType !== eventType + "_m" && - !(editor_blockly.isCommonEntry() && blockType == "common_m") - ) { - editor_blockly.setValue("入口方块类型错误"); - return; - } - } - try { - var code = Blockly.JavaScript.workspaceToCode(workspace).replace( - /\\(i|c|d|e|g|z)/g, - "\\\\$1" - ); - editor_blockly.setValue(code); - } catch (error) { - editor_blockly.setValue(String(error)); - if (error instanceof OmitedError) { - var blockName = error.blockName; - var varName = error.varName; - var block = error.block; - } - // console.log(error); - } - } + //Blockly.bindEventWithChecks_(workspace.svgGroup_,"wheel",workspace,function(e){}); + document.getElementById("blocklyDiv").onmousewheel = function (e) { + //console.log(e); + e.preventDefault(); + var hvScroll = e.shiftKey ? "hScroll" : "vScroll"; + var mousewheelOffsetValue = + (20 / 380) * workspace.scrollbar[hvScroll].handleLength_ * 3; + workspace.scrollbar[hvScroll].handlePosition_ += + (e.deltaY || 0) + (e.detail || 0) > 0 ? + mousewheelOffsetValue : + -mousewheelOffsetValue; + workspace.scrollbar[hvScroll].onScroll_(); + // workspace.setScale(workspace.scale); + }; - workspace.addChangeListener(omitedcheckUpdateFunction); + var doubleClickCheck = [ + [0, "abc"] + ]; - workspace.addChangeListener(Blockly.Events.disableOrphans); + function omitedcheckUpdateFunction(event) { + if (event.type === "create") { + editor_blockly.addIntoLastUsedType(event.blockId); + } + if (event.type === "ui" && event.element == "click") { + var newClick = [new Date().getTime(), event.blockId]; + var lastClick = doubleClickCheck.shift(); + doubleClickCheck.push(newClick); + if (newClick[0] - lastClick[0] < 500) { + if (newClick[1] === lastClick[1]) { + editor_blockly.doubleClickBlock(newClick[1]); + } + } + } + // Only handle these events + if (["create", "move", "change", "delete"].indexOf(event.type) < 0) + return; + if (editor_blockly.workspace.topBlocks_.length >= 2) { + editor_blockly.setValue("入口方块只能有一个"); + return; + } + var eventType = editor_blockly.entryType; + if (editor_blockly.workspace.topBlocks_.length == 1) { + var blockType = editor_blockly.workspace.topBlocks_[0].type; + if ( + blockType !== eventType + "_m" && + !(editor_blockly.isCommonEntry() && blockType == "common_m") + ) { + editor_blockly.setValue("入口方块类型错误"); + return; + } + } + try { + var code = Blockly.JavaScript.workspaceToCode(workspace).replace( + /\\(i|c|d|e|g|z)/g, + "\\\\$1" + ); + editor_blockly.setValue(code); + } catch (error) { + editor_blockly.setValue(String(error)); + if (error instanceof OmitedError) { + var blockName = error.blockName; + var varName = error.varName; + var block = error.block; + } + // console.log(error); + } + } - editor_blockly.workspace = workspace; + workspace.addChangeListener(omitedcheckUpdateFunction); - MotaActionFunctions.workspace = function () { - return editor_blockly.workspace; - }; + workspace.addChangeListener(Blockly.Events.disableOrphans); - // 因为在editor_blockly.parse里已经HTML转义过一次了,所以这里要覆盖掉以避免在注释中出现<等 - MotaActionFunctions.xmlText = function ( - ruleName, - inputs, - isShadow, - comment, - collapsed, - disabled - ) { - var rule = MotaActionBlocks[ruleName]; - var blocktext = isShadow ? "shadow" : "block"; - var xmlText = []; - xmlText.push( - "<" + - blocktext + - ' type="' + - ruleName + - '"' + - (collapsed ? ' collapsed="true"' : "") + - (disabled ? ' disabled="true"' : "") + - ">" - ); - if (!inputs) inputs = []; - for (var ii = 0, inputType; (inputType = rule.argsType[ii]); ii++) { - var input = inputs[ii]; - var _input = ""; - var noinput = input === null || input === undefined; - if ( - noinput && - inputType === "field" && - MotaActionBlocks[rule.argsGrammarName[ii]].type !== - "field_dropdown" - ) - continue; - if (noinput && inputType === "field") { - noinput = false; - input = rule.fieldDefault(rule.args[ii]); - } - if (noinput) input = ""; - if ( - inputType === "field" && - MotaActionBlocks[rule.argsGrammarName[ii]].type === - "field_checkbox" - ) - input = input ? "TRUE" : "FALSE"; - if (inputType !== "field") { - var subList = false; - var subrulename = rule.argsGrammarName[ii]; - var subrule = MotaActionBlocks[subrulename]; - if (subrule instanceof Array) { - subrulename = subrule[subrule.length - 1]; - subrule = MotaActionBlocks[subrulename]; - subList = true; - } - _input = subrule.xmlText([], true); - if (noinput && !subList && !isShadow) { - //无输入的默认行为是: 如果语句块的备选方块只有一个,直接代入方块 - input = subrule.xmlText(); - } - } - xmlText.push("<" + inputType + ' name="' + rule.args[ii] + '">'); - xmlText.push(_input + input); - xmlText.push(""); - } - if (comment) { - xmlText.push(""); - xmlText.push(comment); - xmlText.push(""); - } - var next = inputs[rule.args.length]; - if (next) { - //next - xmlText.push(""); - xmlText.push(next); - xmlText.push(""); - } - xmlText.push(""); - return xmlText.join(""); - }; - })(); + editor_blockly.workspace = workspace; - // end mark sfergsvae - } - .toString() - .split("// start mark sfergsvae")[1] - .split("// end mark sfergsvae")[0]; - } - }, + MotaActionFunctions.workspace = function () { + return editor_blockly.workspace; + }; + + // 因为在editor_blockly.parse里已经HTML转义过一次了,所以这里要覆盖掉以避免在注释中出现<等 + MotaActionFunctions.xmlText = function ( + ruleName, + inputs, + isShadow, + comment, + collapsed, + disabled + ) { + var rule = MotaActionBlocks[ruleName]; + var blocktext = isShadow ? "shadow" : "block"; + var xmlText = []; + xmlText.push( + "<" + + blocktext + + ' type="' + + ruleName + + '"' + + (collapsed ? ' collapsed="true"' : "") + + (disabled ? ' disabled="true"' : "") + + ">" + ); + if (!inputs) inputs = []; + for (var ii = 0, inputType; + (inputType = rule.argsType[ii]); ii++) { + var input = inputs[ii]; + var _input = ""; + var noinput = input === null || input === undefined; + if ( + noinput && + inputType === "field" && + MotaActionBlocks[rule.argsGrammarName[ii]].type !== + "field_dropdown" + ) + continue; + if (noinput && inputType === "field") { + noinput = false; + input = rule.fieldDefault(rule.args[ii]); + } + if (noinput) input = ""; + if ( + inputType === "field" && + MotaActionBlocks[rule.argsGrammarName[ii]].type === + "field_checkbox" + ) + input = input ? "TRUE" : "FALSE"; + if (inputType !== "field") { + var subList = false; + var subrulename = rule.argsGrammarName[ii]; + var subrule = MotaActionBlocks[subrulename]; + if (subrule instanceof Array) { + subrulename = subrule[subrule.length - 1]; + subrule = MotaActionBlocks[subrulename]; + subList = true; + } + _input = subrule.xmlText([], true); + if (noinput && !subList && !isShadow) { + //无输入的默认行为是: 如果语句块的备选方块只有一个,直接代入方块 + input = subrule.xmlText(); + } + } + xmlText.push("<" + inputType + ' name="' + rule.args[ii] + '">'); + xmlText.push(_input + input); + xmlText.push(""); + } + if (comment) { + xmlText.push(""); + xmlText.push(comment); + xmlText.push(""); + } + var next = inputs[rule.args.length]; + if (next) { + //next + xmlText.push(""); + xmlText.push(next); + xmlText.push(""); + } + xmlText.push(""); + return xmlText.join(""); + }; + })(); + + // end mark sfergsvae + } + .toString() + .split("// start mark sfergsvae")[1] + .split("// end mark sfergsvae")[0]; + } +}, "夹击激光动画": function () { function createCanvas(name, zIndex) { if (!name) return; @@ -12971,1619 +13132,1624 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = }; }, "楼传": function () { - // 在此增加新插件 + // 在此增加新插件 - core.canMoveFloor = function () { - let canmove = false; - core.status.thisMap.blocks.forEach((block) => { - if ( - !block.disable && - (block.event.id == "upFloor" || block.event.id == "downFloor") - ) { - let automaticRoute = core.automaticRoute(block.x, block.y); - if (!core.flags.flyNearStair || automaticRoute.length > 0) { - let loc = automaticRoute.pop(); - loc = automaticRoute.pop(); - if (core.canMoveDirectly(loc?.x, loc?.y) >= 0 || !loc) { - canmove = true; + core.canMoveFloor = function () { + let canmove = false; + core.status.thisMap.blocks.forEach((block) => { + if ( + !block.disable && + (block.event.id == "upFloor" || block.event.id == "downFloor") + ) { + let automaticRoute = core.automaticRoute(block.x, block.y); + if (!core.flags.flyNearStair || automaticRoute.length > 0) { + let loc = automaticRoute.pop(); + loc = automaticRoute.pop(); + if (core.canMoveDirectly(loc?.x, loc?.y) >= 0 || !loc) { + canmove = true; + } + } + } + }); + return canmove; + }; + ui.prototype._drawViewMaps_drawHint = function () { + core.playSound("打开界面"); + }; + + ////// 绘制浏览地图界面 ////// + ui.prototype._drawViewMaps = function (index, x, y) { + core.lockControl(); + + core.clearMap("data"); + core.status.event.id = "viewMaps"; + this.clearUI(); + //console.log(index) + if (index == null) index = core.floorIds.indexOf(core.status.floorId); + core.animateFrame.tip = null; + core.status.checkBlock.cache = {}; + let data = this._drawViewMaps_buildData(index, x, y); + core.drawWindowSkin("winskin1.webp", "ui", 0, 0, 416, 416); + let page = core.status.event.data.index; + let floorId = core.status.event.data.floorId; + core.ui.statusBar._update_map(floorId); + const bfs = core.plugin.bfsSearch(floorId, 1, true); + const mapdir = bfs.mapdir[floorId]; + core.setTextAlign("ui", "center"); + let size = (core.__PIXELS__ * 3) / 4; //312 + const areas = core.getFlag("areas"); + + let i = areas.findIndex((v) => v.maps.includes(floorId)); + core.fillRoundRect("ui", 15 - 2, 15 - 2, 35 + 4, 35 + 4, 4, "#444444"); + core.strokeRoundRect( + "ui", + 15 - 4, + 15 - 4, + 35 + 8, + 35 + 8, + 4, + "#444444", + 1 + ); + core.fillBoldText1( + "ui", + "当前", + 13 + 20, + 17 + 20, + "#FFFFFF", + "#000000", + 2, + this._buildFont(18, true) + ); + + core.fillRoundRect( + "ui", + 15 - 2, + 15 - 2 + 35 + 8 + size + 8 - 54, + 35 + 4, + 35 + 4, + 4, + "#444444" + ); + core.strokeRoundRect( + "ui", + 15 - 4, + 15 - 4 + 35 + 8 + size + 8 - 54, + 35 + 8, + 35 + 8, + 4, + "#444444", + 1 + ); + if ( + !core.status.maps[core.floorIds[page]].canFlyTo || + !core.hasVisitedFloor(core.floorIds[page]) + ) { + core.fillBoldText1( + "ui", + "预览", + 13 + 20, + 17 + 20 + 35 + 8 + size + 8 - 54, + "#909090", + "#000000", + 2, + this._buildFont(18, true) + ); + } else { + core.fillBoldText1( + "ui", + "传送", + 13 + 20, + 17 + 20 + 35 + 8 + size + 8 - 54, + "#909090", + "#000000", + 2, + this._buildFont(18, true) + ); + } + core.fillRoundRect( + "ui", + 15 - 4 + size - 2 + 45, + 15 - 2 + size - 4 + 45, + 35 + 4, + 35 + 4, + 4, + "#444444" + ); + core.strokeRoundRect( + "ui", + 15 - 4 + size - 4 + 45, + 15 - 4 + size - 4 + 45, + 35 + 8, + 35 + 8, + 4, + "#444444", + 1 + ); + core.fillBoldText1( + "ui", + "离开", + 15 - 4 + size - 4 + 45 + 22, + 15 - 4 + size - 4 + 45 + 26, + "#FFFFFF", + "#000000", + 2, + this._buildFont(18, true) + ); + + core.fillRoundRect( + "ui", + 15 + 44 - 2, + 15 - 2, + size + 4 - 58, + 35 + 4, + 4, + "#444444" + ); + core.strokeRoundRect( + "ui", + 15 + 44 - 4, + 15 - 4, + size + 8 - 58, + 35 + 8, + 4, + "#444444", + 1 + ); + if (mapdir.includes("up")) { + core.fillBoldText1( + "ui", + "北▲", + 30 + 145 + 10, + 17 + 20, + "#FFFFFF", + "#000000", + 2, + this._buildFont(18, true) + ); + } else { + core.fillBoldText1( + "ui", + "北▲", + 30 + 145 + 10, + 17 + 20, + "#909090", + "#000000", + 2, + this._buildFont(18, true) + ); + } + + core.fillRoundRect( + "ui", + 15 - 2, + 59 - 2, + 35 + 4, + size + 4 - 58, + 4, + "#444444" + ); + core.strokeRoundRect( + "ui", + 15 - 4, + 59 - 4, + 35 + 8, + size + 8 - 58, + 4, + "#444444", + 1 + ); + if (mapdir.includes("left")) { + core.fillBoldText1( + "ui", + "西", + 15 + 17, + 25 + 150, + "#FFFFFF", + "#000000", + 2, + this._buildFont(18, true) + ); + core.fillBoldText1( + "ui", + "◀", + 15 + 17, + 45 + 150, + "#FFFFFF", + "#000000", + 2, + this._buildFont(18, true) + ); + } else { + core.fillBoldText1( + "ui", + "西", + 15 + 17, + 25 + 150, + "#909090", + "#000000", + 2, + this._buildFont(18, true) + ); + core.fillBoldText1( + "ui", + "◀", + 15 + 17, + 45 + 150, + "#909090", + "#000000", + 2, + this._buildFont(18, true) + ); + } + core.fillRoundRect( + "ui", + 15 + 44 - 2, + 15 - 2 + size - 4, + size + 4 - 58, + 35 + 4, + 4, + "#444444" + ); + core.strokeRoundRect( + "ui", + 15 + 44 - 4, + 15 - 4 + size - 4, + size + 8 - 58, + 35 + 8, + 4, + "#444444", + 1 + ); + if (mapdir.includes("down")) { + core.fillBoldText1( + "ui", + "南▼", + 30 + 145 + 10, + 17 + 20 + size - 4, + "#FFFFFF", + "#000000", + 2, + this._buildFont(18, true) + ); + } else { + core.fillBoldText1( + "ui", + "南▼", + 30 + 145 + 10, + 17 + 20 + size - 4, + "#909090", + "#000000", + 2, + this._buildFont(18, true) + ); + } + + core.fillRoundRect( + "ui", + 15 - 2 + size - 4, + 59 - 2, + 35 + 4, + size + 4 - 58, + 4, + "#444444" + ); + core.strokeRoundRect( + "ui", + 15 - 4 + size - 4, + 59 - 4, + 35 + 8, + size + 8 - 58, + 4, + "#444444", + 1 + ); + if (mapdir.includes("right")) { + core.fillBoldText1( + "ui", + "东", + 15 + 17 + size - 4, + 25 + 150, + "#FFFFFF", + "#000000", + 2, + this._buildFont(18, true) + ); + core.fillBoldText1( + "ui", + "▶", + 15 + 17 + size - 4, + 45 + 150, + "#FFFFFF", + "#000000", + 2, + this._buildFont(18, true) + ); + } else { + core.fillBoldText1( + "ui", + "东", + 15 + 17 + size - 4, + 25 + 150, + "#909090", + "#000000", + 2, + this._buildFont(18, true) + ); + core.fillBoldText1( + "ui", + "▶", + 15 + 17 + size - 4, + 45 + 150, + "#909090", + "#000000", + 2, + this._buildFont(18, true) + ); + } + core.fillRoundRect( + "ui", + 60 - 2, + 60 - 2, + size - 58 + 4, + size - 58 + 4, + 4, + "#444444" + ); + core.strokeRoundRect( + "ui", + 60 - 4, + 60 - 4, + size - 58 + 8, + size - 58 + 8, + 4, + "#444444", + 1 + ); + core.drawThumbnail(floorId, null, { + damage: data.damage, + ctx: "ui", + x: 58, + y: 58, + size: 0.62, + all: data.all, + }); + if ( + !core.status.maps[core.floorIds[page]].canFlyTo || + !core.hasVisitedFloor(core.floorIds[page]) + ) + core.drawImage( + "ui", + "lock.webp", + 0, + 0, + size, + size, + 58, + 58, + size - 8, + size - 8 + ); + + core.fillRoundRect( + "ui", + 15 + 44 - 2, + 60 - 2 + size - 4, + size + 4 - 58, + 35 + 4, + 4, + "#444444" + ); + core.strokeRoundRect( + "ui", + 15 + 44 - 4, + 60 - 4 + size - 4, + size + 8 - 58, + 35 + 8, + 4, + "#444444", + 1 + ); + core.fillBoldText1( + "ui", + core.status.maps[floorId].areas, + 30 + 145 + 10, + 17 + 65 + size - 4, + "#FFFFFF", + "#000000", + 2, + this._buildFont(18, true) + ); + core.fillRoundRect( + "ui", + 15 - 2, + 60 - 2 + size - 4, + 35 + 4, + 35 + 4, + 4, + "#444444" + ); + core.strokeRoundRect( + "ui", + 15 - 4, + 60 - 4 + size - 4, + 35 + 8, + 35 + 8, + 4, + "#444444", + 1 + ); + if (i === 0) { + core.fillBoldText1( + "ui", + "◀", + 30, + 17 + 65 + size - 4, + "#909090", + "#000000", + 2, + this._buildFont(18, true) + ); + } else { + core.fillBoldText1( + "ui", + "◀", + 30, + 17 + 65 + size - 4, + "#FFFFFF", + "#000000", + 2, + this._buildFont(18, true) + ); + } + core.fillRoundRect( + "ui", + 15 - 2 + size - 4, + 60 - 2 + size - 4, + 35 + 4, + 35 + 4, + 4, + "#444444" + ); + core.strokeRoundRect( + "ui", + 15 - 4 + size - 4, + 60 - 4 + size - 4, + 35 + 8, + 35 + 8, + 4, + "#444444", + 1 + ); + if (i === areas.length - 1) { + core.fillBoldText1( + "ui", + "▶", + 30 + 300 + 10, + 17 + 65 + size - 4, + "#909090", + "#000000", + 2, + this._buildFont(18, true) + ); + } else { + core.fillBoldText1( + "ui", + "▶", + 30 + 300 + 10, + 17 + 65 + size - 4, + "#FFFFFF", + "#000000", + 2, + this._buildFont(18, true) + ); + } + + core.fillRoundRect( + "ui", + 15 - 2 + size - 4, + 15 - 2, + 80 + 4, + 35 + 4, + 4, + "#444444" + ); + core.strokeRoundRect( + "ui", + 15 - 4 + size - 4, + 15 - 4, + 80 + 8, + 35 + 8, + 4, + "#444444", + 1 + ); + if (mapdir.includes("upFloor")) { + core.fillBoldText1( + "ui", + "上楼", + 30 + 320 + 10, + 17 + 20, + "#FFFFFF", + "#000000", + 2, + this._buildFont(18, true) + ); + } else { + core.fillBoldText1( + "ui", + "上楼", + 30 + 320 + 10, + 17 + 20, + "#909090", + "#000000", + 2, + this._buildFont(18, true) + ); + } + core.fillRoundRect( + "ui", + 15 - 2 + size - 4, + 15 - 2 + size - 4, + 80 + 4, + 35 + 4, + 4, + "#444444" + ); + core.strokeRoundRect( + "ui", + 15 - 4 + size - 4, + 15 - 4 + size - 4, + 80 + 8, + 35 + 8, + 4, + "#444444", + 1 + ); + if (mapdir.includes("downFloor")) { + core.fillBoldText1( + "ui", + "下楼", + 30 + 320 + 10, + 17 + 20 + size - 4, + "#FFFFFF", + "#000000", + 2, + this._buildFont(18, true) + ); + } else { + core.fillBoldText1( + "ui", + "下楼", + 30 + 320 + 10, + 17 + 20 + size - 4, + "#909090", + "#000000", + 2, + this._buildFont(18, true) + ); + } + + core.fillRoundRect( + "ui", + 15 - 2 + size - 4 + 35 + 8, + 59 - 2, + 37 + 4, + (size - 58) / 2 + 4, + 4, + "#444444" + ); + core.strokeRoundRect( + "ui", + 15 - 4 + size - 4 + 35 + 8, + 59 - 4, + 37 + 8, + (size - 58) / 2 + 8, + 4, + "#444444", + 1 + ); + const title = core.status.maps[floorId].title; + //const length = title.length + fillTextVertical( + "ui", + title, + 15 - 4 + size - 4 + 45, + 85, + "#FFFFFF", + "#000000", + 18 + ); + //const uictx = main.dom.gameCanvas.ui.getContext('2d') + core.fillRoundRect( + "ui", + 15 - 2 + size - 4 + 35 + 8, + 59 - 2 + (size - 58) / 2 + 8, + 37 + 4, + 119 + 4, + 4, + "#444444" + ); + core.strokeRoundRect( + "ui", + 15 - 4 + size - 4 + 35 + 8, + 59 - 4 + (size - 58) / 2 + 8, + 37 + 8, + 119 + 8, + 4, + "#444444", + 1 + ); + if (core.getFlag("showEnemy")) { + fillTextVertical( + "ui", + "关闭漏怪检测", + 15 - 4 + size - 4 + 45, + 220, + "#FFFFFF", + "#000000", + 18 + ); + } else { + fillTextVertical( + "ui", + "开启漏怪检测", + 15 - 4 + size - 4 + 45, + 220, + "#FFFFFF", + "#000000", + 18 + ); + } + + //uictx.fillTextVertical(title, 15 - 4 + size - 4 + 35 + 29, 25 + 150) + //fillTextVertical('ui', title, 15 - 4 + size - 4 + 35 + 29, 25 + 150, '#FFFFFF', this._buildFont(18, true)) + }; + + function fillTextVertical(name, text, x, y, style, boldstyle, fontsize) { + //竖向文字绘制 + + const ctx = core.ui.getContextByName(name); + if (!ctx) return; + const canvas = document.createElement("canvas"); + const context = canvas.getContext("2d"); + fontsize *= 3; + const length = text.length; + canvas.width = fontsize * 2; + canvas.height = fontsize * length * 2; + if (style) context.fillStyle = core.arrayToRGBA(style); + if (boldstyle) context.strokeStyle = core.arrayToRGBA(boldstyle); + context.lineWidth = 2; + if (fontsize) context.font = core.ui._buildFont(fontsize, true); + let arrText = text.split(""); + + let arrWidth = arrText.map(function (letter) { + return context.measureText(letter).width; + }); + + let align = context.textAlign; + + let baseline = context.textBaseline; + let sx = fontsize, + sy = fontsize * length; + if (align == "left") { + sx = sx + Math.max.apply(null, arrWidth) / 2; + } else if (align == "right") { + sx = sx - Math.max.apply(null, arrWidth) / 2; + } + + if ( + baseline == "bottom" || + baseline == "alphabetic" || + baseline == "ideographic" + ) { + sy = sy - arrWidth[0] / 2; + } else if (baseline == "top" || baseline == "hanging") { + sy = sy + arrWidth[0] / 2; + } + + context.textAlign = "center"; + + context.textBaseline = "middle"; + context.lineWidth = 6; + + // 开始逐字绘制 + + arrText.forEach(function (letter, index) { + // 确定下一个字符的纵坐标位置 + + context.strokeText(letter, sx, sy); + context.fillText(letter, sx, sy); + // 旋转坐标系还原成初始态 + + context.setTransform(1, 0, 0, 1, 0, 0); + + // 确定下一个字符的纵坐标位置 + + var letterWidth = 54; + + sy = sy + letterWidth; + }); + + // 水平垂直对齐方式还原 + + context.textAlign = align; + + context.textBaseline = baseline; + + //绘制到目标位置 + ctx.drawImage( + canvas, + x, + y - (fontsize / 3) * length, + canvas.width / 3, + canvas.height / 3 + ); + } + + ////// 点击楼层传送器时的打开操作 ////// + events.prototype.useFly = function (fromUserAction) { + if (!core.isplaying()) return; + if (!core.status.maps[core.status.floorId].canFlyFrom) { + core.drawTip(core.material.items["fly"].name + "好像失效了", "fly"); + return; + } + // 从“浏览地图”页面:尝试直接传送到该层 + if (core.status.event.id == "viewMaps") { + if (!core.hasItem("fly")) { + core.playSound("操作失败"); + core.drawTip("你没有" + core.material.items["fly"].name, "fly"); + } else if ( + core.flags.flyNearStair && + !core.nearStair() && + !flags.canMoveFloor + ) { + core.playSound("操作失败"); + core.drawTip( + "无法到达楼梯边使用" + core.material.items["fly"].name, + "fly" + ); + } else { + core.flyTo(core.status.event.data.floorId); + core.updateStatusBar(); + } + return; + } + + if (!this._checkStatus("fly", fromUserAction, true)) return; + //if (core.flags.flyNearStair && !core.nearStair()) + + if ( + (core.flags.flyNearStair && !core.nearStair()) || + !flags.canMoveFloor + ) { + core.playSound("操作失败"); + core.drawTip( + "无法到达楼梯边使用" + core.material.items["fly"].name, + "fly" + ); + core.unlockControl(); + core.status.event.data = null; + core.status.event.id = null; + return; + } + if (!core.canUseItem("fly")) { + core.playSound("操作失败"); + core.drawTip(core.material.items["fly"].name + "好像失效了", "fly"); + core.unlockControl(); + core.status.event.data = null; + core.status.event.id = null; + return; + } + core.playSound("打开界面"); + core.useItem("fly", true); + core.updateStatusBar(); + return; + }; + ////// 系统菜单栏界面时的点击操作 ////// + actions.prototype._clickSettings = function (x, y) { + if (this._out(x)) return; + var choices = core.status.event.ui.choices; + var topIndex = this._getChoicesTopIndex(choices.length); + if (y >= topIndex && y < topIndex + choices.length) { + var selection = y - topIndex; + core.status.event.selection = selection; + switch (selection) { + case 0: + core.status.event.selection = 0; + core.playSound("确定"); + core.ui._drawSwitchs(); + break; + case 1: + // core.playSound('确定'); + core.ui._drawKeyBoard(); + break; + case 2: + // core.playSound('确定'); + core.clearUI(); + core.useItem("fly"); + break; + case 3: + core.status.event.selection = 0; + core.playSound("确定"); + core.ui._drawNotes(); + break; + case 4: + core.status.event.selection = 0; + core.playSound("确定"); + core.ui._drawSyncSave(); + break; + case 5: + core.status.event.selection = 0; + core.playSound("确定"); + core.ui._drawGameInfo(); + break; + case 6: + return core.confirmRestart(); + case 7: + core.playSound("取消"); + core.ui.closePanel(); + break; + } + } + return; + }; + ////// 查看地图界面时的点击操作 ////// + actions.prototype._clickViewMaps = function (x, y, px, py) { + if (core.status.event.data == null) { + core.ui._drawViewMaps(core.floorIds.indexOf(core.status.floorId)); + return; + } + let now = core.floorIds.indexOf(core.status.floorId); + let index = core.status.event.data.index; + let cx = core.status.event.data.x, + cy = core.status.event.data.y; + let floorId = core.floorIds[index], + mw = core.floors[floorId].width, + mh = core.floors[floorId].height; + let perpx = core.__PIXELS__ / 5, + cornerpx = (perpx * 3) / 4; + const bfs = core.plugin.bfsSearch(floorId, 1, true); + const mapdir = bfs.mapdir[floorId]; + const res = bfs.res; + const formto = {}; + for (let from in res) { + const to = res[from]; + const [fromfloorId, fromsx, fromsy, dir] = from.split("_"); + const [tofloorId, tosx, tosy] = to.split("_"); + if (!formto[fromfloorId]) formto[fromfloorId] = {}; + if (!formto[fromfloorId][dir]) formto[fromfloorId][dir] = tofloorId; + } + const areas = core.getFlag("areas"); + let i = areas.findIndex((v) => v.maps.includes(floorId)); + + if (px >= 11 && px <= 54 && py >= 11 && py <= 54) { + core.ui._drawViewMaps(core.floorIds.indexOf(core.status.floorId)); + } else if (px >= 362 && px <= 407 && py >= 191 && py <= 318) { + flags.showEnemy = !flags.showEnemy; + core.ui._drawViewMaps(index); + } else if (px >= 364 && px <= 407 && py >= 364 && py <= 407) { + core.clearMap("data"); + core.playSound("取消"); + core.ui.closePanel(); + core.getItemDetail(); + core.redrawMap(); + core.updateStatusBar(); + core.ui.statusBar._update_map(); + return; + } else if (px >= 55 && px <= 317 && py >= 11 && py <= 54) { + if (mapdir.includes("up")) + core.ui._drawViewMaps(core.floorIds.indexOf(formto[floorId].up)); + } else if (px >= 55 && px <= 317 && py >= 319 && py <= 362) { + if (mapdir.includes("down")) + core.ui._drawViewMaps(core.floorIds.indexOf(formto[floorId].down)); + } else if (px >= 11 && px <= 54 && py >= 55 && py <= 317) { + if (mapdir.includes("left")) + core.ui._drawViewMaps(core.floorIds.indexOf(formto[floorId].left)); + } else if (px >= 319 && px <= 362 && py >= 55 && py <= 317) { + if (mapdir.includes("right")) + core.ui._drawViewMaps(core.floorIds.indexOf(formto[floorId].right)); + } else if (px >= 319 && px <= 407 && py >= 11 && py <= 54) { + if (mapdir.includes("upFloor")) + core.ui._drawViewMaps(core.floorIds.indexOf(formto[floorId].upFloor)); + } else if (px >= 319 && px <= 407 && py >= 319 && py <= 362) { + if (mapdir.includes("downFloor")) + core.ui._drawViewMaps( + core.floorIds.indexOf(formto[floorId].downFloor) + ); + } else if ( + px >= 55 && + px <= 317 && + py >= 55 && + py <= 317 && + core.isplaying() + ) { + core.useFly(false); + return; + } else if (px >= 11 && px <= 54 && py >= 364 && py <= 407) { + if (i > 0) { + i -= 1; + core.ui._drawViewMaps(core.floorIds.indexOf(areas[i].maps[0])); + } + } else if (px >= 319 && px <= 362 && py >= 364 && py <= 407) { + if (i < areas.length - 1) { + i += 1; + core.ui._drawViewMaps(core.floorIds.indexOf(areas[i].maps[0])); + } + } + }; + const replayAction_fly = function (action) { + //楼层传送的录像操作 + if (action.indexOf("fly:") != 0) return false; + var floorId = action.substring(4); + var toIndex = core.floorIds.indexOf(floorId); + if ( + !core.canUseItem("fly") || + (core.flags.flyNearStair && !core.nearStair() && !flags.canMoveFloor) + ) + return false; + core.ui._drawViewMaps(toIndex); + if (core.status.replay.speed == 24) { + if (!core.flyTo(floorId, core.replay)) + core.control._replay_error(action); + return true; + } + setTimeout(function () { + if (!core.flyTo(floorId, core.replay)) + core.control._replay_error(action); + }, core.control.__replay_getTimeout()); + return true; + }; + core.registerReplayAction("fly", replayAction_fly); + ////// 查看地图界面时,放开某个键的操作 ////// + actions.prototype._keyUpViewMaps = function (keycode) { + if (core.status.event.data == null) { + core.ui._drawViewMaps(core.floorIds.indexOf(core.status.floorId)); + return; + } + var floorId = core.floorIds[core.status.event.data.index]; + + if (keycode == 27 || keycode == 71) { + core.clearMap("data"); + core.playSound("取消"); + core.ui.closePanel(); + core.getItemDetail(); + core.redrawMap(); + core.ui.statusBar._update_map(); + core.updateStatusBar(); + return; + } + if (keycode == 88) { + core.openBook(true); + return; + } + if (keycode == 86) { + core.status.event.data.damage = !core.status.event.data.damage; + core.playSound("光标移动"); + core.ui._drawViewMaps(core.status.event.data); + return; + } + if (keycode == 66) { + core.openBook(false); + return; + } + if ( + (keycode == 13 || keycode == 32 || keycode == 67) && + !core.isReplaying() + ) { + core.useFly(false); + return; + } + return; + }; + actions.prototype._keyDownViewMaps = function (keycode) { + if (core.status.event.data == null) return; + + var floorId = core.floorIds[core.status.event.data.index], + mh = core.floors[floorId].height; + + if (keycode == 39) this._clickViewMaps(9, 1, 330, 250); + if (keycode == 37) this._clickViewMaps(9, 8, 25, 200); + if (keycode == 40) this._clickViewMaps(9, 6, 250, 330); + if (keycode == 38) this._clickViewMaps(9, 3, 200, 25); + if (keycode == 34) this._clickViewMaps(9, 3, 350, 330); + if (keycode == 33) this._clickViewMaps(9, 3, 350, 25); + return; + }; + + actions.prototype._sys_onmousewheel = function (direct) { + // 向下滚动是 -1 ,向上是 1 + + if (this._checkReplaying()) { + // 滚轮控制速度 + if (direct == 1) core.speedUpReplay(); + if (direct == -1) core.speedDownReplay(); + return; + } + + // 楼层飞行器 + if (core.status.lockControl && core.status.event.id == "fly") { + if (direct == 1) core.ui.drawFly(this._getNextFlyFloor(1)); + if (direct == -1) core.ui.drawFly(this._getNextFlyFloor(-1)); + return; + } + + // 怪物手册 + if (core.status.lockControl && core.status.event.id == "book") { + var pageinfo = core.ui._drawBook_pageinfo(); + if (direct == 1) + core.ui.drawBook(core.status.event.data - pageinfo.per_page); + if (direct == -1) + core.ui.drawBook(core.status.event.data + pageinfo.per_page); + return; + } + + // 存读档 + if ( + core.status.lockControl && + (core.status.event.id == "save" || core.status.event.id == "load") + ) { + var index = + core.status.event.data.page * 10 + core.status.event.data.offset; + if (direct == 1) core.ui._drawSLPanel(index - 10); + if (direct == -1) core.ui._drawSLPanel(index + 10); + return; + } + + // 浏览地图 + if (core.status.lockControl && core.status.event.id == "viewMaps") { + let floorId = core.floorIds[core.status.event.data.index]; + if (!flags.__visited__[floorId]) floorId = core.status.floorId; + const visit = Object.keys(flags.__visited__); + let index = visit.indexOf(floorId); + if (direct == 1) { + if (index > 0) + core.ui._drawViewMaps(core.floorIds.indexOf(visit[index - 1])); + } + if (direct == -1) { + if (index < visit.length - 1) + core.ui._drawViewMaps(core.floorIds.indexOf(visit[index + 1])); + } + return; + } + + // wait事件 + if ( + core.status.lockControl && + core.status.event.id == "action" && + core.status.event.data.type == "wait" + ) { + var timeout = + Math.max(0, core.status.event.timeout - new Date().getTime()) || 0; + core.setFlag("type", 0); + var keycode = direct == 1 ? 33 : 34; + core.setFlag("keycode", keycode); + core.setFlag("timeout", timeout); + var executed = core.events.__action_wait_afterGet( + core.status.event.data.current + ); + if (executed || !core.status.event.data.current.forceChild) { + core.status.route.push("input:" + (1e8 * timeout + keycode)); + clearTimeout(core.status.event.interval); + delete core.status.event.timeout; + core.doAction(); + } + return; + } + }; + core.registerAction( + "onmousewheel", + "_sys_onmousewheel", + actions.prototype._sys_onmousewheel, + 0 + ); + }, + "CG回廊": function () { + // 在此增加新插件 + const CGUI = document.createElement("canvas"); //CGui画布设置 + CGUI.style.position = "absolute"; + CGUI.style.zIndex = 300; + CGUI.style.display = "none"; + CGUI.id = "CGUI"; + main.dom.gameGroup.insertAdjacentElement("afterend", CGUI); + CGUI.style.top = "50%"; + CGUI.style.left = "50%"; + CGUI.style.transform = "translate(-50%,-50%)"; + const ctx = CGUI.getContext("2d"); + main.dom.CGUI = CGUI; + let page = 0; //初始页面 + let show = false; //展示状态 + CGUI.onclick = function (e) { + try { + e.preventDefault(); + if (core.isPlaying()) return false; + const left = core.dom.gameGroup.offsetLeft; + const top = core.dom.gameGroup.offsetTop; + const px = Math.floor((e.clientX - left) / core.domStyle.scale), + py = Math.floor((e.clientY - top) / core.domStyle.scale); + core.ui.CG.onclick(px * 3, py * 3); + } catch (ee) { + main.log(ee); + } + }; + + class CG { + constructor() { + this.cgs; + //cg列表 + this.UIMx = [ + //空位用‘none’填充,当前ui至多4列6行 + [ + ["eve_010102.webp", "eve_010203.webp", "eve_010304.webp"], + ["eve_010501.webp", "eve_010601.webp", "eve_010701.webp"], + ], + [ + ["eve_010801.webp", "eve_010902.webp", "eve_011001.webp"], + ["eve_011101.webp", "eve_011202.webp", "eve_011302.webp"], + ], + [ + ["eve_011402.webp", "eve_020102.webp", "eve_020201.webp"], + ["eve_020301.webp", "eve_020401.webp", "eve_020501.webp"], + ], + [ + ["eve_020605.webp", "eve_020701.webp", "eve_020801.webp"], + ["eve_030101.webp", "eve_030206.webp", "eve_030302.webp"], + ], + [ + ["eve_030508.webp", "eve_030601.webp", "eve_030801.webp"], + ["eve_030901.webp", "eve_031002.webp", "eve_031101.webp"], + ], + [ + ["eve_040201.webp", "eve_040401.webp", "eve_040501.webp"], + ["eve_040601.webp", "eve_040702.webp", "eve_040801.webp"], + ], + [ + ["eve_050101.webp", "eve_050201.webp", "eve_050401.webp"], + ["eve_050501.webp", "eve_050601.webp", "eve_050704.webp"], + ], + [ + ["eve_050801.webp", "eve_070101.webp", "bg_1511.webp"], + ["bg_1521.webp", "bg_2011.webp", "bg_2521.webp"], + ], + [ + ["bg_3042.webp", "bg_3551.webp", "bg_3571.webp"], + ["bg_3721.webp", "bg_5033.webp", "bg_5044.webp"], + ], + ]; + } + + //更新 + update() { + this.background(); + this.drawUI(); + } + background() { + //画布大小设置 + if (core.domStyle.isVertical) { + CGUI.width = 1248; + CGUI.height = 2028; + } else { + CGUI.width = 2028; + CGUI.height = 1248; + } + core.setTextAlign(ctx, "center"); + } + onclick(px, py) { + //点击 + + if (show) { + show = !show; + core.clearMap(ctx); + this.update(); + return; + } + const makeBox = ([x, y], [w, h]) => { + return [ + [x, y], + [x + w, y + h], + ]; + }; + const inRect = ([x, y], [ + [sx, sy], + [dx, dy] + ]) => { + return sx <= x && x <= dx && sy <= y && y <= dy; + }; + const pos = [px, py]; + const backbox = makeBox([15, 35], [210, 90]); + if (inRect(pos, backbox)) { + //离开按钮是一致的,其余的记区分横竖屏 + CGUI.style.display = "none"; + core.clearMap(ctx); + core.restart(); + return; + } + if (core.domStyle.isVertical) { + //竖屏 + const pageupbox = makeBox([200, 1830], [200, 100]); + const pagedownbox = makeBox([900, 1830], [200, 100]); + + const imagebox0 = makeBox([50, 200], [560, 420]); + const imagebox1 = makeBox([50, 750], [560, 420]); + const imagebox2 = makeBox([50, 1300], [560, 420]); + + const imagebox3 = makeBox([650, 200], [560, 420]); + const imagebox4 = makeBox([650, 750], [560, 420]); + const imagebox5 = makeBox([650, 1300], [560, 420]); + if (inRect(pos, pagedownbox)) { + //2代表当前最大页数-1 + if (page < this.UIMx.length - 1) { + page++; + core.clearMap(ctx); + this.update(); + } + } else if (inRect(pos, pageupbox)) { + if (page > 0) { + page--; + core.clearMap(ctx); + this.update(); + } + } else if (inRect(pos, imagebox0)) { + if (this.cgs.includes(this.UIMx[page][0][0])) { + const img = core.material.images.images[this.UIMx[page][0][0]]; + if (img) { + ctx.save(); //保存设置 + ctx.translate(1248, 0); //重新定位右上角为基准 + ctx.rotate(Math.PI / 2); //旋转90度 + ctx.drawImage(img, 0, 0, 2028, 1248); + ctx.restore(); //重置画布设置 + show = !show; + } + } + } else if (inRect(pos, imagebox1)) { + if (this.cgs.includes(this.UIMx[page][0][1])) { + const img = core.material.images.images[this.UIMx[page][0][1]]; + if (img) { + ctx.save(); //保存设置 + ctx.translate(1248, 0); //重新定位右上角为基准 + ctx.rotate(Math.PI / 2); //旋转90度 + ctx.drawImage(img, 0, 0, 2028, 1248); + ctx.restore(); //重置画布设置 + show = !show; + } + } + } else if (inRect(pos, imagebox2)) { + if (this.cgs.includes(this.UIMx[page][0][2])) { + const img = core.material.images.images[this.UIMx[page][0][2]]; + if (img) { + ctx.save(); //保存设置 + ctx.translate(1248, 0); //重新定位右上角为基准 + ctx.rotate(Math.PI / 2); //旋转90度 + ctx.drawImage(img, 0, 0, 2028, 1248); + ctx.restore(); //重置画布设置 + show = !show; + } + } + } else if (inRect(pos, imagebox3)) { + if (this.cgs.includes(this.UIMx[page][1][0])) { + const img = core.material.images.images[this.UIMx[page][1][0]]; + if (img) { + ctx.save(); //保存设置 + ctx.translate(1248, 0); //重新定位右上角为基准 + ctx.rotate(Math.PI / 2); //旋转90度 + ctx.drawImage(img, 0, 0, 2028, 1248); + ctx.restore(); //重置画布设置 + show = !show; + } + } + } else if (inRect(pos, imagebox4)) { + if (this.cgs.includes(this.UIMx[page][1][1])) { + const img = core.material.images.images[this.UIMx[page][1][1]]; + if (img) { + ctx.save(); //保存设置 + ctx.translate(1248, 0); //重新定位右上角为基准 + ctx.rotate(Math.PI / 2); //旋转90度 + ctx.drawImage(img, 0, 0, 2028, 1248); + ctx.restore(); //重置画布设置 + show = !show; + } + } + } else if (inRect(pos, imagebox5)) { + if (this.cgs.includes(this.UIMx[page][1][2])) { + const img = core.material.images.images[this.UIMx[page][1][2]]; + if (img) { + ctx.save(); //保存设置 + ctx.translate(1248, 0); //重新定位右上角为基准 + ctx.rotate(Math.PI / 2); //旋转90度 + ctx.drawImage(img, 0, 0, 2028, 1248); + ctx.restore(); //重置画布设置 + show = !show; + } + } + } + } else { + const pageupbox = makeBox([200, 1110], [200, 100]); + const pagedownbox = makeBox([1600, 1110], [200, 100]); + const imagebox0 = makeBox([75, 150], [600, 450]); + const imagebox1 = makeBox([725, 150], [600, 450]); + const imagebox2 = makeBox([1300, 150], [600, 450]); + const imagebox3 = makeBox([75, 650], [600, 450]); + const imagebox4 = makeBox([725, 650], [600, 450]); + const imagebox5 = makeBox([1375, 650], [600, 450]); + if (inRect(pos, pagedownbox)) { + if (page < this.UIMx.length - 1) { + page++; + core.clearMap(ctx); + this.update(); + } + } else if (inRect(pos, pageupbox)) { + if (page > 0) { + page--; + core.clearMap(ctx); + this.update(); + } + } else if (inRect(pos, imagebox0)) { + if (this.cgs.includes(this.UIMx[page][0][0])) { + const img = core.material.images.images[this.UIMx[page][0][0]]; + if (img) { + ctx.drawImage(img, 0, 0, 2028, 1248); + show = !show; + } + } + } else if (inRect(pos, imagebox1)) { + if (this.cgs.includes(this.UIMx[page][0][1])) { + const img = core.material.images.images[this.UIMx[page][0][1]]; + if (img) { + ctx.drawImage(img, 0, 0, 2028, 1248); + show = !show; + } + } + } else if (inRect(pos, imagebox2)) { + if (this.cgs.includes(this.UIMx[page][0][2])) { + const img = core.material.images.images[this.UIMx[page][0][2]]; + if (img) { + ctx.drawImage(img, 0, 0, 2028, 1248); + show = !show; + } + } + } else if (inRect(pos, imagebox3)) { + if (this.cgs.includes(this.UIMx[page][1][0])) { + const img = core.material.images.images[this.UIMx[page][1][0]]; + if (img) { + ctx.drawImage(img, 0, 0, 2028, 1248); + show = !show; + } + } + } else if (inRect(pos, imagebox4)) { + if (this.cgs.includes(this.UIMx[page][1][1])) { + const img = core.material.images.images[this.UIMx[page][1][1]]; + if (img) { + ctx.drawImage(img, 0, 0, 2028, 1248); + show = !show; + } + } + } else if (inRect(pos, imagebox5)) { + if (this.cgs.includes(this.UIMx[page][1][2])) { + const img = core.material.images.images[this.UIMx[page][1][2]]; + if (img) { + ctx.drawImage(img, 0, 0, 2028, 1248); + show = !show; + } } } } - }); - return canmove; - }; - ui.prototype._drawViewMaps_drawHint = function () { - core.playSound("打开界面"); - }; - let canMoveFloor - ////// 绘制浏览地图界面 ////// - ui.prototype._drawViewMaps = function (index, x, y) { - core.lockControl(); - canMoveFloor = core.canMoveFloor() - core.clearMap("data"); - core.status.event.id = "viewMaps"; - this.clearUI(); - //console.log(index) - if (index == null) index = core.floorIds.indexOf(core.status.floorId); - core.animateFrame.tip = null; - core.status.checkBlock.cache = {}; - let data = this._drawViewMaps_buildData(index, x, y); - core.drawWindowSkin("winskin1.webp", "ui", 0, 0, 416, 416); - let page = core.status.event.data.index; - let floorId = core.status.event.data.floorId; - core.ui.statusBar._update_map(floorId); - const bfs = core.plugin.bfsSearch(floorId, 1, true); - const mapdir = bfs.mapdir[floorId]; - core.setTextAlign("ui", "center"); - let size = (core.__PIXELS__ * 3) / 4; //312 - const areas = core.getFlag("areas"); - - let i = areas.findIndex((v) => v.maps.includes(floorId)); - core.fillRoundRect("ui", 15 - 2, 15 - 2, 35 + 4, 35 + 4, 4, "#444444"); - core.strokeRoundRect( - "ui", - 15 - 4, - 15 - 4, - 35 + 8, - 35 + 8, - 4, - "#444444", - 1 - ); - core.fillBoldText1( - "ui", - "当前", - 13 + 20, - 17 + 20, - "#FFFFFF", - "#000000", - 2, - this._buildFont(18, true) - ); - - core.fillRoundRect( - "ui", - 15 - 2, - 15 - 2 + 35 + 8 + size + 8 - 54, - 35 + 4, - 35 + 4, - 4, - "#444444" - ); - core.strokeRoundRect( - "ui", - 15 - 4, - 15 - 4 + 35 + 8 + size + 8 - 54, - 35 + 8, - 35 + 8, - 4, - "#444444", - 1 - ); - if ( - !core.status.maps[core.floorIds[page]].canFlyTo || - !core.hasVisitedFloor(core.floorIds[page]) - ) { - core.fillBoldText1( - "ui", - "预览", - 13 + 20, - 17 + 20 + 35 + 8 + size + 8 - 54, - "#909090", - "#000000", - 2, - this._buildFont(18, true) - ); - } else { - core.fillBoldText1( - "ui", - "传送", - 13 + 20, - 17 + 20 + 35 + 8 + size + 8 - 54, - "#909090", - "#000000", - 2, - this._buildFont(18, true) - ); } - core.fillRoundRect( - "ui", - 15 - 4 + size - 2 + 45, - 15 - 2 + size - 4 + 45, - 35 + 4, - 35 + 4, - 4, - "#444444" - ); - core.strokeRoundRect( - "ui", - 15 - 4 + size - 4 + 45, - 15 - 4 + size - 4 + 45, - 35 + 8, - 35 + 8, - 4, - "#444444", - 1 - ); - core.fillBoldText1( - "ui", - "离开", - 15 - 4 + size - 4 + 45 + 22, - 15 - 4 + size - 4 + 45 + 26, - "#FFFFFF", - "#000000", - 2, - this._buildFont(18, true) - ); + drawUI() { + //绘制页面 + core.clearMap(CGUI); + const bgVertical = core.material.images.images["bg_2010.webp"]; //竖屏背景 + const bg = core.material.images.images["bg_5043.webp"]; //横屏背景 - core.fillRoundRect( - "ui", - 15 + 44 - 2, - 15 - 2, - size + 4 - 58, - 35 + 4, - 4, - "#444444" - ); - core.strokeRoundRect( - "ui", - 15 + 44 - 4, - 15 - 4, - size + 8 - 58, - 35 + 8, - 4, - "#444444", - 1 - ); - if (mapdir.includes("up")) { - core.fillBoldText1( - "ui", - "北▲", - 30 + 145 + 10, - 17 + 20, - "#FFFFFF", - "#000000", - 2, - this._buildFont(18, true) - ); - } else { - core.fillBoldText1( - "ui", - "北▲", - 30 + 145 + 10, - 17 + 20, - "#909090", - "#000000", - 2, - this._buildFont(18, true) - ); - } + if (core.domStyle.isVertical) { + //竖屏 - core.fillRoundRect( - "ui", - 15 - 2, - 59 - 2, - 35 + 4, - size + 4 - 58, - 4, - "#444444" - ); - core.strokeRoundRect( - "ui", - 15 - 4, - 59 - 4, - 35 + 8, - size + 8 - 58, - 4, - "#444444", - 1 - ); - if (mapdir.includes("left")) { - core.fillBoldText1( - "ui", - "西", - 15 + 17, - 25 + 150, - "#FFFFFF", - "#000000", - 2, - this._buildFont(18, true) - ); - core.fillBoldText1( - "ui", - "◀", - 15 + 17, - 45 + 150, - "#FFFFFF", - "#000000", - 2, - this._buildFont(18, true) - ); - } else { - core.fillBoldText1( - "ui", - "西", - 15 + 17, - 25 + 150, - "#909090", - "#000000", - 2, - this._buildFont(18, true) - ); - core.fillBoldText1( - "ui", - "◀", - 15 + 17, - 45 + 150, - "#909090", - "#000000", - 2, - this._buildFont(18, true) - ); - } - core.fillRoundRect( - "ui", - 15 + 44 - 2, - 15 - 2 + size - 4, - size + 4 - 58, - 35 + 4, - 4, - "#444444" - ); - core.strokeRoundRect( - "ui", - 15 + 44 - 4, - 15 - 4 + size - 4, - size + 8 - 58, - 35 + 8, - 4, - "#444444", - 1 - ); - if (mapdir.includes("down")) { - core.fillBoldText1( - "ui", - "南▼", - 30 + 145 + 10, - 17 + 20 + size - 4, - "#FFFFFF", - "#000000", - 2, - this._buildFont(18, true) - ); - } else { - core.fillBoldText1( - "ui", - "南▼", - 30 + 145 + 10, - 17 + 20 + size - 4, - "#909090", - "#000000", - 2, - this._buildFont(18, true) - ); - } + core.fillRect(ctx, 0, 0, 1248, 2028, "#000000"); //黑色背景 + ctx.globalAlpha = 0.5; //透明度 + if (bgVertical) + ctx.drawImage(bgVertical, 0, 0, 1280, 1500, 0, 0, 1248, 2028); //绘制半透明背景图片 + ctx.globalAlpha = 1; //恢复为不透明 - core.fillRoundRect( - "ui", - 15 - 2 + size - 4, - 59 - 2, - 35 + 4, - size + 4 - 58, - 4, - "#444444" - ); - core.strokeRoundRect( - "ui", - 15 - 4 + size - 4, - 59 - 4, - 35 + 8, - size + 8 - 58, - 4, - "#444444", - 1 - ); - if (mapdir.includes("right")) { - core.fillBoldText1( - "ui", - "东", - 15 + 17 + size - 4, - 25 + 150, - "#FFFFFF", - "#000000", - 2, - this._buildFont(18, true) - ); - core.fillBoldText1( - "ui", - "▶", - 15 + 17 + size - 4, - 45 + 150, - "#FFFFFF", - "#000000", - 2, - this._buildFont(18, true) - ); - } else { - core.fillBoldText1( - "ui", - "东", - 15 + 17 + size - 4, - 25 + 150, - "#909090", - "#000000", - 2, - this._buildFont(18, true) - ); - core.fillBoldText1( - "ui", - "▶", - 15 + 17 + size - 4, - 45 + 150, - "#909090", - "#000000", - 2, - this._buildFont(18, true) - ); - } - core.fillRoundRect( - "ui", - 60 - 2, - 60 - 2, - size - 58 + 4, - size - 58 + 4, - 4, - "#444444" - ); - core.strokeRoundRect( - "ui", - 60 - 4, - 60 - 4, - size - 58 + 8, - size - 58 + 8, - 4, - "#444444", - 1 - ); - core.drawThumbnail(floorId, null, { - damage: data.damage, - ctx: "ui", - x: 58, - y: 58, - size: 0.62, - all: data.all, - }); - if ( - !core.status.maps[core.floorIds[page]].canFlyTo || - !core.hasVisitedFloor(core.floorIds[page]) - ) - core.drawImage( - "ui", - "lock.webp", - 0, - 0, - size, - size, - 58, - 58, - size - 8, - size - 8 - ); - - core.fillRoundRect( - "ui", - 15 + 44 - 2, - 60 - 2 + size - 4, - size + 4 - 58, - 35 + 4, - 4, - "#444444" - ); - core.strokeRoundRect( - "ui", - 15 + 44 - 4, - 60 - 4 + size - 4, - size + 8 - 58, - 35 + 8, - 4, - "#444444", - 1 - ); - core.fillBoldText1( - "ui", - core.status.maps[floorId].areas, - 30 + 145 + 10, - 17 + 65 + size - 4, - "#FFFFFF", - "#000000", - 2, - this._buildFont(18, true) - ); - core.fillRoundRect( - "ui", - 15 - 2, - 60 - 2 + size - 4, - 35 + 4, - 35 + 4, - 4, - "#444444" - ); - core.strokeRoundRect( - "ui", - 15 - 4, - 60 - 4 + size - 4, - 35 + 8, - 35 + 8, - 4, - "#444444", - 1 - ); - if (i === 0) { - core.fillBoldText1( - "ui", - "◀", - 30, - 17 + 65 + size - 4, - "#909090", - "#000000", - 2, - this._buildFont(18, true) - ); - } else { - core.fillBoldText1( - "ui", - "◀", - 30, - 17 + 65 + size - 4, - "#FFFFFF", - "#000000", - 2, - this._buildFont(18, true) - ); - } - core.fillRoundRect( - "ui", - 15 - 2 + size - 4, - 60 - 2 + size - 4, - 35 + 4, - 35 + 4, - 4, - "#444444" - ); - core.strokeRoundRect( - "ui", - 15 - 4 + size - 4, - 60 - 4 + size - 4, - 35 + 8, - 35 + 8, - 4, - "#444444", - 1 - ); - if (i === areas.length - 1) { - core.fillBoldText1( - "ui", - "▶", - 30 + 300 + 10, - 17 + 65 + size - 4, - "#909090", - "#000000", - 2, - this._buildFont(18, true) - ); - } else { - core.fillBoldText1( - "ui", - "▶", - 30 + 300 + 10, - 17 + 65 + size - 4, - "#FFFFFF", - "#000000", - 2, - this._buildFont(18, true) - ); - } - - core.fillRoundRect( - "ui", - 15 - 2 + size - 4, - 15 - 2, - 80 + 4, - 35 + 4, - 4, - "#444444" - ); - core.strokeRoundRect( - "ui", - 15 - 4 + size - 4, - 15 - 4, - 80 + 8, - 35 + 8, - 4, - "#444444", - 1 - ); - if (mapdir.includes("upFloor")) { - core.fillBoldText1( - "ui", - "上楼", - 30 + 320 + 10, - 17 + 20, - "#FFFFFF", - "#000000", - 2, - this._buildFont(18, true) - ); - } else { - core.fillBoldText1( - "ui", - "上楼", - 30 + 320 + 10, - 17 + 20, - "#909090", - "#000000", - 2, - this._buildFont(18, true) - ); - } - core.fillRoundRect( - "ui", - 15 - 2 + size - 4, - 15 - 2 + size - 4, - 80 + 4, - 35 + 4, - 4, - "#444444" - ); - core.strokeRoundRect( - "ui", - 15 - 4 + size - 4, - 15 - 4 + size - 4, - 80 + 8, - 35 + 8, - 4, - "#444444", - 1 - ); - if (mapdir.includes("downFloor")) { - core.fillBoldText1( - "ui", - "下楼", - 30 + 320 + 10, - 17 + 20 + size - 4, - "#FFFFFF", - "#000000", - 2, - this._buildFont(18, true) - ); - } else { - core.fillBoldText1( - "ui", - "下楼", - 30 + 320 + 10, - 17 + 20 + size - 4, - "#909090", - "#000000", - 2, - this._buildFont(18, true) - ); - } - - core.fillRoundRect( - "ui", - 15 - 2 + size - 4 + 35 + 8, - 59 - 2, - 37 + 4, - (size - 58) / 2 + 4, - 4, - "#444444" - ); - core.strokeRoundRect( - "ui", - 15 - 4 + size - 4 + 35 + 8, - 59 - 4, - 37 + 8, - (size - 58) / 2 + 8, - 4, - "#444444", - 1 - ); - const title = core.status.maps[floorId].title; - //const length = title.length - fillTextVertical( - "ui", - title, - 15 - 4 + size - 4 + 45, - 85, - "#FFFFFF", - "#000000", - 18 - ); - //const uictx = main.dom.gameCanvas.ui.getContext('2d') - core.fillRoundRect( - "ui", - 15 - 2 + size - 4 + 35 + 8, - 59 - 2 + (size - 58) / 2 + 8, - 37 + 4, - 119 + 4, - 4, - "#444444" - ); - core.strokeRoundRect( - "ui", - 15 - 4 + size - 4 + 35 + 8, - 59 - 4 + (size - 58) / 2 + 8, - 37 + 8, - 119 + 8, - 4, - "#444444", - 1 - ); - if (core.getFlag("showEnemy")) { - fillTextVertical( - "ui", - "关闭漏怪检测", - 15 - 4 + size - 4 + 45, - 220, - "#FFFFFF", - "#000000", - 18 - ); - } else { - fillTextVertical( - "ui", - "开启漏怪检测", - 15 - 4 + size - 4 + 45, - 220, - "#FFFFFF", - "#000000", - 18 - ); - } - - //uictx.fillTextVertical(title, 15 - 4 + size - 4 + 35 + 29, 25 + 150) - //fillTextVertical('ui', title, 15 - 4 + size - 4 + 35 + 29, 25 + 150, '#FFFFFF', this._buildFont(18, true)) - }; - - function fillTextVertical(name, text, x, y, style, boldstyle, fontsize) { - //竖向文字绘制 - - const ctx = core.ui.getContextByName(name); - if (!ctx) return; - const canvas = document.createElement("canvas"); - const context = canvas.getContext("2d"); - fontsize *= 3; - const length = text.length; - canvas.width = fontsize * 2; - canvas.height = fontsize * length * 2; - if (style) context.fillStyle = core.arrayToRGBA(style); - if (boldstyle) context.strokeStyle = core.arrayToRGBA(boldstyle); - context.lineWidth = 2; - if (fontsize) context.font = core.ui._buildFont(fontsize, true); - let arrText = text.split(""); - - let arrWidth = arrText.map(function (letter) { - return context.measureText(letter).width; - }); - - let align = context.textAlign; - - let baseline = context.textBaseline; - let sx = fontsize, - sy = fontsize * length; - if (align == "left") { - sx = sx + Math.max.apply(null, arrWidth) / 2; - } else if (align == "right") { - sx = sx - Math.max.apply(null, arrWidth) / 2; - } - - if ( - baseline == "bottom" || - baseline == "alphabetic" || - baseline == "ideographic" - ) { - sy = sy - arrWidth[0] / 2; - } else if (baseline == "top" || baseline == "hanging") { - sy = sy + arrWidth[0] / 2; - } - - context.textAlign = "center"; - - context.textBaseline = "middle"; - context.lineWidth = 6; - - // 开始逐字绘制 - - arrText.forEach(function (letter, index) { - // 确定下一个字符的纵坐标位置 - - context.strokeText(letter, sx, sy); - context.fillText(letter, sx, sy); - // 旋转坐标系还原成初始态 - - context.setTransform(1, 0, 0, 1, 0, 0); - - // 确定下一个字符的纵坐标位置 - - var letterWidth = 54; - - sy = sy + letterWidth; - }); - - // 水平垂直对齐方式还原 - - context.textAlign = align; - - context.textBaseline = baseline; - - //绘制到目标位置 - ctx.drawImage( - canvas, - x, - y - (fontsize / 3) * length, - canvas.width / 3, - canvas.height / 3 - ); - } - - ////// 点击楼层传送器时的打开操作 ////// - events.prototype.useFly = function (fromUserAction) { - if (core.isReplaying()) return; - if (!core.status.maps[core.status.floorId].canFlyFrom) { - core.drawTip(core.material.items["fly"].name + "好像失效了", "fly"); - return; - } - // 从“浏览地图”页面:尝试直接传送到该层 - if (core.status.event.id == "viewMaps") { - if (!core.hasItem("fly")) { - core.playSound("操作失败"); - core.drawTip("你没有" + core.material.items["fly"].name, "fly"); - } else if ( - core.flags.flyNearStair && - !core.nearStair() && - canMoveFloor - ) { - core.playSound("操作失败"); - core.drawTip( - "无法到达楼梯边使用" + core.material.items["fly"].name, - "fly" + core.setTextAlign(ctx, "center"); + core.fillBoldText1( + ctx, + "◀离开", + 100, + 110, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(66, true) ); + + core.fillBoldText1( + ctx, + "上一页", + 300, + 1900, + page === 0 ? "#444444" : "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(66, true) + ); + + core.fillBoldText1( + ctx, + page + 1 + "/" + this.UIMx.length, + 650, + 1900, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(66, true) + ); + core.fillBoldText1( + ctx, + "下一页", + 1000, + 1900, + page === this.UIMx.length - 1 ? "#444444" : "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(66, true) + ); + // 添加向上翻页和向下翻页的按钮 + + // 添加3*2个4:3的画框,及图片 + for (let i = 0; i < 3; i++) { + for (let j = 0; j < 2; j++) { + const img = core.material.images.images[this.UIMx[page][j][i]]; + core.strokeRect( + ctx, + 50 + j * 600, + 200 + i * 550, + 560, + 420, + "#444444", + 5 + ); + if (this.cgs.includes(this.UIMx[page][j][i])) { + if (img) + ctx.drawImage( + img, + 50 + j * 600 + 15, + 200 + i * 550 + 15, + 560 - 30, + 420 - 30 + ); + } else { + ctx.fillStyle = "#000000"; + ctx.fillRect( + 50 + j * 600 + 15, + 200 + i * 550 + 15, + 560 - 30, + 420 - 30 + ); + const img = core.material.images.images["LOGO.webp"]; + if (img) + ctx.drawImage( + img, + 50 + j * 600 + 15, + 200 + i * 550 + 15, + 560 - 30, + 420 - 30 + ); + } + } + } } else { - core.flyTo(core.status.event.data.floorId); - core.updateStatusBar() - } - return; - } + //横屏 + core.fillRect(ctx, 0, 0, 2028, 1248, "#000000"); //黑色背景 + ctx.globalAlpha = 0.5; //透明度 + if (bg) ctx.drawImage(bg, 0, 0, 1280, 720, 0, 0, 2028, 1248); //绘制半透明背景图片 + ctx.globalAlpha = 1; //恢复为不透明 - if (!this._checkStatus("fly", fromUserAction, true)) return; - //if (core.flags.flyNearStair && !core.nearStair()) - - if ( - (core.flags.flyNearStair && !core.nearStair()) || - canMoveFloor - ) { - core.playSound("操作失败"); - core.drawTip( - "无法到达楼梯边使用" + core.material.items["fly"].name, - "fly" - ); - core.unlockControl(); - core.status.event.data = null; - core.status.event.id = null; - return; - } - if (!core.canUseItem("fly")) { - core.playSound("操作失败"); - core.drawTip(core.material.items["fly"].name + "好像失效了", "fly"); - core.unlockControl(); - core.status.event.data = null; - core.status.event.id = null; - return; - } - core.playSound("打开界面"); - core.useItem("fly", true); - return; - }; - ////// 系统菜单栏界面时的点击操作 ////// - actions.prototype._clickSettings = function (x, y) { - if (this._out(x)) return; - var choices = core.status.event.ui.choices; - var topIndex = this._getChoicesTopIndex(choices.length); - if (y >= topIndex && y < topIndex + choices.length) { - var selection = y - topIndex; - core.status.event.selection = selection; - switch (selection) { - case 0: - core.status.event.selection = 0; - core.playSound("确定"); - core.ui._drawSwitchs(); - break; - case 1: - // core.playSound('确定'); - core.ui._drawKeyBoard(); - break; - case 2: - // core.playSound('确定'); - core.clearUI(); - core.ui._drawViewMaps(core.floorIds.indexOf(core.status.floorId)); - break; - case 3: - core.status.event.selection = 0; - core.playSound("确定"); - core.ui._drawNotes(); - break; - case 4: - core.status.event.selection = 0; - core.playSound("确定"); - core.ui._drawSyncSave(); - break; - case 5: - core.status.event.selection = 0; - core.playSound("确定"); - core.ui._drawGameInfo(); - break; - case 6: - return core.confirmRestart(); - case 7: - core.playSound("取消"); - core.ui.closePanel(); - break; - } - } - return; - }; - ////// 查看地图界面时的点击操作 ////// - actions.prototype._clickViewMaps = function (x, y, px, py) { - if (core.status.event.data == null) { - core.ui._drawViewMaps(core.floorIds.indexOf(core.status.floorId)); - return; - } - let now = core.floorIds.indexOf(core.status.floorId); - let index = core.status.event.data.index; - let cx = core.status.event.data.x, - cy = core.status.event.data.y; - let floorId = core.floorIds[index], - mw = core.floors[floorId].width, - mh = core.floors[floorId].height; - let perpx = core.__PIXELS__ / 5, - cornerpx = (perpx * 3) / 4; - const bfs = core.plugin.bfsSearch(floorId, 1, true); - const mapdir = bfs.mapdir[floorId]; - const res = bfs.res; - const formto = {}; - for (let from in res) { - const to = res[from]; - const [fromfloorId, fromsx, fromsy, dir] = from.split("_"); - const [tofloorId, tosx, tosy] = to.split("_"); - if (!formto[fromfloorId]) formto[fromfloorId] = {}; - if (!formto[fromfloorId][dir]) formto[fromfloorId][dir] = tofloorId; - } - const areas = core.getFlag("areas"); - let i = areas.findIndex((v) => v.maps.includes(floorId)); - - if (px >= 11 && px <= 54 && py >= 11 && py <= 54) { - core.ui._drawViewMaps(core.floorIds.indexOf(core.status.floorId)); - } else if (px >= 362 && px <= 407 && py >= 191 && py <= 318) { - flags.showEnemy = !flags.showEnemy; - core.ui._drawViewMaps(index); - } else if (px >= 364 && px <= 407 && py >= 364 && py <= 407) { - core.clearMap("data"); - core.playSound("取消"); - core.ui.closePanel(); - core.getItemDetail(); - core.redrawMap(); - core.updateStatusBar() - core.ui.statusBar._update_map(); - return; - } else if (px >= 55 && px <= 317 && py >= 11 && py <= 54) { - if (mapdir.includes("up")) - core.ui._drawViewMaps(core.floorIds.indexOf(formto[floorId].up)); - } else if (px >= 55 && px <= 317 && py >= 319 && py <= 362) { - if (mapdir.includes("down")) - core.ui._drawViewMaps(core.floorIds.indexOf(formto[floorId].down)); - } else if (px >= 11 && px <= 54 && py >= 55 && py <= 317) { - if (mapdir.includes("left")) - core.ui._drawViewMaps(core.floorIds.indexOf(formto[floorId].left)); - } else if (px >= 319 && px <= 362 && py >= 55 && py <= 317) { - if (mapdir.includes("right")) - core.ui._drawViewMaps(core.floorIds.indexOf(formto[floorId].right)); - } else if (px >= 319 && px <= 407 && py >= 11 && py <= 54) { - if (mapdir.includes("upFloor")) - core.ui._drawViewMaps(core.floorIds.indexOf(formto[floorId].upFloor)); - } else if (px >= 319 && px <= 407 && py >= 319 && py <= 362) { - if (mapdir.includes("downFloor")) - core.ui._drawViewMaps( - core.floorIds.indexOf(formto[floorId].downFloor) + core.setTextAlign(ctx, "center"); + core.fillBoldText1( + ctx, + "◀离开", + 110, + 100, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(66, true) ); - } else if ( - px >= 55 && - px <= 317 && - py >= 55 && - py <= 317 && - !core.isReplaying() - ) { - core.useFly(false); - return; - } else if (px >= 11 && px <= 54 && py >= 364 && py <= 407) { - if (i > 0) { - i -= 1; - core.ui._drawViewMaps(core.floorIds.indexOf(areas[i].maps[0])); - } - } else if (px >= 319 && px <= 362 && py >= 364 && py <= 407) { - if (i < areas.length - 1) { - i += 1; - core.ui._drawViewMaps(core.floorIds.indexOf(areas[i].maps[0])); + + // 添加向上翻页和向下翻页的按钮 + core.fillBoldText1( + ctx, + "上一页", + 300, + 1180, + page === 0 ? "#444444" : "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(66, true) + ); + + core.fillBoldText1( + ctx, + page + 1 + "/" + this.UIMx.length, + 1000, + 1180, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(66, true) + ); + core.fillBoldText1( + ctx, + "下一页", + 1700, + 1180, + page === this.UIMx.length - 1 ? "#444444" : "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(66, true) + ); + + // 添加3*2个4:3的画框 + for (let i = 0; i < 2; i++) { + for (let j = 0; j < 3; j++) { + core.strokeRect( + ctx, + 75 + j * 650, + 150 + i * 500, + 600, + 450, + "#444444", + 2 + ); + if (this.cgs.includes(this.UIMx[page][i][j])) { + const img = core.material.images.images[this.UIMx[page][i][j]]; + if (img) + ctx.drawImage( + img, + 75 + j * 650 + 15, + 150 + i * 500 + 15, + 600 - 30, + 450 - 30 + ); + } else { + ctx.fillStyle = "#000000"; + ctx.fillRect( + 75 + j * 650 + 15, + 150 + i * 500 + 15, + 600 - 30, + 450 - 30 + ); + const img = core.material.images.images["LOGO.webp"]; + if (img) + ctx.drawImage( + img, + 75 + j * 650 + 15, + 150 + i * 500 + 15, + 600 - 30, + 450 - 30 + ); + } + } + } } } + } + this.setcgs = function (img) { + const a = core.getLocalStorage("cgs", []); + if (img) { + if (!a.includes(img)) a.push(img); + core.setLocalStorage("cgs", a); + } else core.setLocalStorage("cgs"); }; - const replayAction_fly = function (action) { - //楼层传送的录像操作 - if (action.indexOf("fly:") != 0) return false; - var floorId = action.substring(4); - var toIndex = core.floorIds.indexOf(floorId); - if ( - !core.canUseItem("fly") || - (core.flags.flyNearStair && !core.nearStair()) - ) - return false; - core.ui._drawViewMaps(toIndex); - if (core.status.replay.speed == 24) { - if (!core.flyTo(floorId, core.replay)) - core.control._replay_error(action); - return true; - } - setTimeout(function () { - if (!core.flyTo(floorId, core.replay)) - core.control._replay_error(action); - }, core.control.__replay_getTimeout()); - return true; + core.ui.CG = new CG(); + main.dom.CGMode.onclick = function () { + //点击开始页面的CG MODE进入cg回廊 + main.core.control.checkBgm(); + page = 0; + main.core.ui.CG.cgs = core.getLocalStorage("cgs", []); + CGUI.style.display = "block"; + main.core.ui.CG.update(); }; - core.registerReplayAction("fly", replayAction_fly); - ////// 查看地图界面时,放开某个键的操作 ////// - actions.prototype._keyUpViewMaps = function (keycode) { - if (core.status.event.data == null) { - core.ui._drawViewMaps(core.floorIds.indexOf(core.status.floorId)); - return; - } - var floorId = core.floorIds[core.status.event.data.index]; - - if (keycode == 27 || keycode == 71) { - core.clearMap("data"); - core.playSound("取消"); - core.ui.closePanel(); - core.getItemDetail(); - core.redrawMap(); - core.ui.statusBar._update_map(); - return; - } - if (keycode == 88) { - core.openBook(true); - return; - } - if (keycode == 86) { - core.status.event.data.damage = !core.status.event.data.damage; - core.playSound("光标移动"); - core.ui._drawViewMaps(core.status.event.data); - return; - } - if (keycode == 66) { - core.openBook(false); - return; - } - if ( - (keycode == 13 || keycode == 32 || keycode == 67) && - !core.isReplaying() - ) { - core.useFly(false); - return; - } - return; - }; - actions.prototype._keyDownViewMaps = function (keycode) { - if (core.status.event.data == null) return; - - var floorId = core.floorIds[core.status.event.data.index], - mh = core.floors[floorId].height; - - if (keycode == 39) this._clickViewMaps(9, 1, 330, 250); - if (keycode == 37) this._clickViewMaps(9, 8, 25, 200); - if (keycode == 40) this._clickViewMaps(9, 6, 250, 330); - if (keycode == 38) this._clickViewMaps(9, 3, 200, 25); - if (keycode == 34) this._clickViewMaps(9, 3, 350, 330); - if (keycode == 33) this._clickViewMaps(9, 3, 350, 25); - return; - }; - - actions.prototype._sys_onmousewheel = function (direct) { - // 向下滚动是 -1 ,向上是 1 - - if (this._checkReplaying()) { - // 滚轮控制速度 - if (direct == 1) core.speedUpReplay(); - if (direct == -1) core.speedDownReplay(); - return; - } - - // 楼层飞行器 - if (core.status.lockControl && core.status.event.id == "fly") { - if (direct == 1) core.ui.drawFly(this._getNextFlyFloor(1)); - if (direct == -1) core.ui.drawFly(this._getNextFlyFloor(-1)); - return; - } - - // 怪物手册 - if (core.status.lockControl && core.status.event.id == "book") { - var pageinfo = core.ui._drawBook_pageinfo(); - if (direct == 1) - core.ui.drawBook(core.status.event.data - pageinfo.per_page); - if (direct == -1) - core.ui.drawBook(core.status.event.data + pageinfo.per_page); - return; - } - - // 存读档 - if ( - core.status.lockControl && - (core.status.event.id == "save" || core.status.event.id == "load") - ) { - var index = - core.status.event.data.page * 10 + core.status.event.data.offset; - if (direct == 1) core.ui._drawSLPanel(index - 10); - if (direct == -1) core.ui._drawSLPanel(index + 10); - return; - } - - // 浏览地图 - if (core.status.lockControl && core.status.event.id == "viewMaps") { - let floorId = core.floorIds[core.status.event.data.index]; - if (!flags.__visited__[floorId]) floorId = core.status.floorId; - const visit = Object.keys(flags.__visited__); - let index = visit.indexOf(floorId); - if (direct == 1) { - if (index > 0) - core.ui._drawViewMaps(core.floorIds.indexOf(visit[index - 1])); - } - if (direct == -1) { - if (index < visit.length - 1) - core.ui._drawViewMaps(core.floorIds.indexOf(visit[index + 1])); - } - return; - } - - // wait事件 - if ( - core.status.lockControl && - core.status.event.id == "action" && - core.status.event.data.type == "wait" - ) { - var timeout = - Math.max(0, core.status.event.timeout - new Date().getTime()) || 0; - core.setFlag("type", 0); - var keycode = direct == 1 ? 33 : 34; - core.setFlag("keycode", keycode); - core.setFlag("timeout", timeout); - var executed = core.events.__action_wait_afterGet( - core.status.event.data.current - ); - if (executed || !core.status.event.data.current.forceChild) { - core.status.route.push("input:" + (1e8 * timeout + keycode)); - clearTimeout(core.status.event.interval); - delete core.status.event.timeout; - core.doAction(); - } - return; - } - }; - core.registerAction( - "onmousewheel", - "_sys_onmousewheel", - actions.prototype._sys_onmousewheel, - 0 - ); }, - "CG回廊": function () { - // 在此增加新插件 - const CGUI = document.createElement("canvas"); //CGui画布设置 - CGUI.style.position = "absolute"; - CGUI.style.zIndex = 300; - CGUI.style.display = "none"; - CGUI.id = "CGUI"; - main.dom.gameGroup.insertAdjacentElement("afterend", CGUI); - CGUI.style.top = "50%"; - CGUI.style.left = "50%"; - CGUI.style.transform = "translate(-50%,-50%)"; - const ctx = CGUI.getContext("2d"); - main.dom.CGUI = CGUI; - let page = 0; //初始页面 - let show = false; //展示状态 - CGUI.onclick = function (e) { - try { - e.preventDefault(); - if (core.isPlaying()) return false; - const left = core.dom.gameGroup.offsetLeft; - const top = core.dom.gameGroup.offsetTop; - const px = Math.floor((e.clientX - left) / core.domStyle.scale), - py = Math.floor((e.clientY - top) / core.domStyle.scale); - core.ui.CG.onclick(px * 3, py * 3); - } catch (ee) { - main.log(ee); - } - }; - - class CG { - constructor() { - this.cgs; - //cg列表 - this.UIMx = [ - //空位用‘none’填充,当前ui至多4列6行 - [ - ["eve_010102.webp", "eve_010203.webp", "eve_010304.webp"], - ["eve_010501.webp", "eve_010601.webp", "eve_010701.webp"], - ], - [ - ["eve_010801.webp", "eve_010902.webp", "eve_011001.webp"], - ["eve_011101.webp", "eve_011202.webp", "eve_011302.webp"], - ], - [ - ["eve_011402.webp", "eve_020102.webp", "eve_020201.webp"], - ["eve_020301.webp", "eve_020401.webp", "eve_020501.webp"], - ], - [ - ["eve_020605.webp", "eve_020701.webp", "eve_020801.webp"], - ["eve_030101.webp", "eve_030206.webp", "eve_030302.webp"], - ], - [ - ["eve_030508.webp", "eve_030601.webp", "eve_030801.webp"], - ["eve_030901.webp", "eve_031002.webp", "eve_031101.webp"], - ], - [ - ["eve_040201.webp", "eve_040401.webp", "eve_040501.webp"], - ["eve_040601.webp", "eve_040702.webp", "eve_040801.webp"], - ], - [ - ["eve_050101.webp", "eve_050201.webp", "eve_050401.webp"], - ["eve_050501.webp", "eve_050601.webp", "eve_050704.webp"], - ], - [ - ["eve_050801.webp", "eve_070101.webp", "bg_1511.webp"], - ["bg_1521.webp", "bg_2011.webp", "bg_2521.webp"], - ], - [ - ["bg_3042.webp", "bg_3551.webp", "bg_3571.webp"], - ["bg_3721.webp", "bg_5033.webp", "bg_5044.webp"], - ], - ]; - } - - //更新 - update() { - this.background(); - this.drawUI(); - } - background() { - //画布大小设置 - if (core.domStyle.isVertical) { - CGUI.width = 1248; - CGUI.height = 2028; - } else { - CGUI.width = 2028; - CGUI.height = 1248; - } - core.setTextAlign(ctx, "center"); - } - onclick(px, py) { - //点击 - - if (show) { - show = !show; - core.clearMap(ctx); - this.update(); - return; - } - const makeBox = ([x, y], [w, h]) => { - return [ - [x, y], - [x + w, y + h], - ]; - }; - const inRect = ([x, y], [[sx, sy], [dx, dy]]) => { - return sx <= x && x <= dx && sy <= y && y <= dy; - }; - const pos = [px, py]; - const backbox = makeBox([15, 35], [210, 90]); - if (inRect(pos, backbox)) { - //离开按钮是一致的,其余的记区分横竖屏 - CGUI.style.display = "none"; - core.clearMap(ctx); - core.restart(); - return; - } - if (core.domStyle.isVertical) { - //竖屏 - const pageupbox = makeBox([200, 1830], [200, 100]); - const pagedownbox = makeBox([900, 1830], [200, 100]); - - const imagebox0 = makeBox([50, 200], [560, 420]); - const imagebox1 = makeBox([50, 750], [560, 420]); - const imagebox2 = makeBox([50, 1300], [560, 420]); - - const imagebox3 = makeBox([650, 200], [560, 420]); - const imagebox4 = makeBox([650, 750], [560, 420]); - const imagebox5 = makeBox([650, 1300], [560, 420]); - if (inRect(pos, pagedownbox)) { - //2代表当前最大页数-1 - if (page < this.UIMx.length - 1) { - page++; - core.clearMap(ctx); - this.update(); - } - } else if (inRect(pos, pageupbox)) { - if (page > 0) { - page--; - core.clearMap(ctx); - this.update(); - } - } else if (inRect(pos, imagebox0)) { - if (this.cgs.includes(this.UIMx[page][0][0])) { - const img = core.material.images.images[this.UIMx[page][0][0]]; - if (img) { - ctx.save(); //保存设置 - ctx.translate(1248, 0); //重新定位右上角为基准 - ctx.rotate(Math.PI / 2); //旋转90度 - ctx.drawImage(img, 0, 0, 2028, 1248); - ctx.restore(); //重置画布设置 - show = !show; - } - } - } else if (inRect(pos, imagebox1)) { - if (this.cgs.includes(this.UIMx[page][0][1])) { - const img = core.material.images.images[this.UIMx[page][0][1]]; - if (img) { - ctx.save(); //保存设置 - ctx.translate(1248, 0); //重新定位右上角为基准 - ctx.rotate(Math.PI / 2); //旋转90度 - ctx.drawImage(img, 0, 0, 2028, 1248); - ctx.restore(); //重置画布设置 - show = !show; - } - } - } else if (inRect(pos, imagebox2)) { - if (this.cgs.includes(this.UIMx[page][0][2])) { - const img = core.material.images.images[this.UIMx[page][0][2]]; - if (img) { - ctx.save(); //保存设置 - ctx.translate(1248, 0); //重新定位右上角为基准 - ctx.rotate(Math.PI / 2); //旋转90度 - ctx.drawImage(img, 0, 0, 2028, 1248); - ctx.restore(); //重置画布设置 - show = !show; - } - } - } else if (inRect(pos, imagebox3)) { - if (this.cgs.includes(this.UIMx[page][1][0])) { - const img = core.material.images.images[this.UIMx[page][1][0]]; - if (img) { - ctx.save(); //保存设置 - ctx.translate(1248, 0); //重新定位右上角为基准 - ctx.rotate(Math.PI / 2); //旋转90度 - ctx.drawImage(img, 0, 0, 2028, 1248); - ctx.restore(); //重置画布设置 - show = !show; - } - } - } else if (inRect(pos, imagebox4)) { - if (this.cgs.includes(this.UIMx[page][1][1])) { - const img = core.material.images.images[this.UIMx[page][1][1]]; - if (img) { - ctx.save(); //保存设置 - ctx.translate(1248, 0); //重新定位右上角为基准 - ctx.rotate(Math.PI / 2); //旋转90度 - ctx.drawImage(img, 0, 0, 2028, 1248); - ctx.restore(); //重置画布设置 - show = !show; - } - } - } else if (inRect(pos, imagebox5)) { - if (this.cgs.includes(this.UIMx[page][1][2])) { - const img = core.material.images.images[this.UIMx[page][1][2]]; - if (img) { - ctx.save(); //保存设置 - ctx.translate(1248, 0); //重新定位右上角为基准 - ctx.rotate(Math.PI / 2); //旋转90度 - ctx.drawImage(img, 0, 0, 2028, 1248); - ctx.restore(); //重置画布设置 - show = !show; - } - } - } - } else { - const pageupbox = makeBox([200, 1110], [200, 100]); - const pagedownbox = makeBox([1600, 1110], [200, 100]); - const imagebox0 = makeBox([75, 150], [600, 450]); - const imagebox1 = makeBox([725, 150], [600, 450]); - const imagebox2 = makeBox([1300, 150], [600, 450]); - const imagebox3 = makeBox([75, 650], [600, 450]); - const imagebox4 = makeBox([725, 650], [600, 450]); - const imagebox5 = makeBox([1375, 650], [600, 450]); - if (inRect(pos, pagedownbox)) { - if (page < this.UIMx.length - 1) { - page++; - core.clearMap(ctx); - this.update(); - } - } else if (inRect(pos, pageupbox)) { - if (page > 0) { - page--; - core.clearMap(ctx); - this.update(); - } - } else if (inRect(pos, imagebox0)) { - if (this.cgs.includes(this.UIMx[page][0][0])) { - const img = core.material.images.images[this.UIMx[page][0][0]]; - if (img) { - ctx.drawImage(img, 0, 0, 2028, 1248); - show = !show; - } - } - } else if (inRect(pos, imagebox1)) { - if (this.cgs.includes(this.UIMx[page][0][1])) { - const img = core.material.images.images[this.UIMx[page][0][1]]; - if (img) { - ctx.drawImage(img, 0, 0, 2028, 1248); - show = !show; - } - } - } else if (inRect(pos, imagebox2)) { - if (this.cgs.includes(this.UIMx[page][0][2])) { - const img = core.material.images.images[this.UIMx[page][0][2]]; - if (img) { - ctx.drawImage(img, 0, 0, 2028, 1248); - show = !show; - } - } - } else if (inRect(pos, imagebox3)) { - if (this.cgs.includes(this.UIMx[page][1][0])) { - const img = core.material.images.images[this.UIMx[page][1][0]]; - if (img) { - ctx.drawImage(img, 0, 0, 2028, 1248); - show = !show; - } - } - } else if (inRect(pos, imagebox4)) { - if (this.cgs.includes(this.UIMx[page][1][1])) { - const img = core.material.images.images[this.UIMx[page][1][1]]; - if (img) { - ctx.drawImage(img, 0, 0, 2028, 1248); - show = !show; - } - } - } else if (inRect(pos, imagebox5)) { - if (this.cgs.includes(this.UIMx[page][1][2])) { - const img = core.material.images.images[this.UIMx[page][1][2]]; - if (img) { - ctx.drawImage(img, 0, 0, 2028, 1248); - show = !show; - } - } - } - } - } - drawUI() { - //绘制页面 - core.clearMap(CGUI); - const bgVertical = core.material.images.images["bg_2010.webp"]; //竖屏背景 - const bg = core.material.images.images["bg_5043.webp"]; //横屏背景 - - if (core.domStyle.isVertical) { - //竖屏 - - core.fillRect(ctx, 0, 0, 1248, 2028, "#000000"); //黑色背景 - ctx.globalAlpha = 0.5; //透明度 - if (bgVertical) - ctx.drawImage(bgVertical, 0, 0, 1280, 1500, 0, 0, 1248, 2028); //绘制半透明背景图片 - ctx.globalAlpha = 1; //恢复为不透明 - - core.setTextAlign(ctx, "center"); - core.fillBoldText1( - ctx, - "◀离开", - 100, - 110, - "#FFFFFF", - "#000000", - 6, - core.ui._buildFont(66, true) - ); - - core.fillBoldText1( - ctx, - "上一页", - 300, - 1900, - page === 0 ? "#444444" : "#FFFFFF", - "#000000", - 6, - core.ui._buildFont(66, true) - ); - - core.fillBoldText1( - ctx, - page + 1 + "/" + this.UIMx.length, - 650, - 1900, - "#FFFFFF", - "#000000", - 6, - core.ui._buildFont(66, true) - ); - core.fillBoldText1( - ctx, - "下一页", - 1000, - 1900, - page === this.UIMx.length - 1 ? "#444444" : "#FFFFFF", - "#000000", - 6, - core.ui._buildFont(66, true) - ); - // 添加向上翻页和向下翻页的按钮 - - // 添加3*2个4:3的画框,及图片 - for (let i = 0; i < 3; i++) { - for (let j = 0; j < 2; j++) { - const img = core.material.images.images[this.UIMx[page][j][i]]; - core.strokeRect( - ctx, - 50 + j * 600, - 200 + i * 550, - 560, - 420, - "#444444", - 5 - ); - if (this.cgs.includes(this.UIMx[page][j][i])) { - if (img) - ctx.drawImage( - img, - 50 + j * 600 + 15, - 200 + i * 550 + 15, - 560 - 30, - 420 - 30 - ); - } else { - ctx.fillStyle = "#000000"; - ctx.fillRect( - 50 + j * 600 + 15, - 200 + i * 550 + 15, - 560 - 30, - 420 - 30 - ); - const img = core.material.images.images["LOGO.webp"]; - if (img) - ctx.drawImage( - img, - 50 + j * 600 + 15, - 200 + i * 550 + 15, - 560 - 30, - 420 - 30 - ); - } - } - } - } else { - //横屏 - core.fillRect(ctx, 0, 0, 2028, 1248, "#000000"); //黑色背景 - ctx.globalAlpha = 0.5; //透明度 - if (bg) ctx.drawImage(bg, 0, 0, 1280, 720, 0, 0, 2028, 1248); //绘制半透明背景图片 - ctx.globalAlpha = 1; //恢复为不透明 - - core.setTextAlign(ctx, "center"); - core.fillBoldText1( - ctx, - "◀离开", - 110, - 100, - "#FFFFFF", - "#000000", - 6, - core.ui._buildFont(66, true) - ); - - // 添加向上翻页和向下翻页的按钮 - core.fillBoldText1( - ctx, - "上一页", - 300, - 1180, - page === 0 ? "#444444" : "#FFFFFF", - "#000000", - 6, - core.ui._buildFont(66, true) - ); - - core.fillBoldText1( - ctx, - page + 1 + "/" + this.UIMx.length, - 1000, - 1180, - "#FFFFFF", - "#000000", - 6, - core.ui._buildFont(66, true) - ); - core.fillBoldText1( - ctx, - "下一页", - 1700, - 1180, - page === this.UIMx.length - 1 ? "#444444" : "#FFFFFF", - "#000000", - 6, - core.ui._buildFont(66, true) - ); - - // 添加3*2个4:3的画框 - for (let i = 0; i < 2; i++) { - for (let j = 0; j < 3; j++) { - core.strokeRect( - ctx, - 75 + j * 650, - 150 + i * 500, - 600, - 450, - "#444444", - 2 - ); - if (this.cgs.includes(this.UIMx[page][i][j])) { - const img = core.material.images.images[this.UIMx[page][i][j]]; - if (img) - ctx.drawImage( - img, - 75 + j * 650 + 15, - 150 + i * 500 + 15, - 600 - 30, - 450 - 30 - ); - } else { - ctx.fillStyle = "#000000"; - ctx.fillRect( - 75 + j * 650 + 15, - 150 + i * 500 + 15, - 600 - 30, - 450 - 30 - ); - const img = core.material.images.images["LOGO.webp"]; - if (img) - ctx.drawImage( - img, - 75 + j * 650 + 15, - 150 + i * 500 + 15, - 600 - 30, - 450 - 30 - ); - } - } - } - } - } - } - this.setcgs = function (img) { - const a = core.getLocalStorage("cgs", []); - if (img) { - if (!a.includes(img)) a.push(img); - core.setLocalStorage("cgs", a); - } else core.setLocalStorage("cgs"); - }; - core.ui.CG = new CG(); - main.dom.CGMode.onclick = function () { - //点击开始页面的CG MODE进入cg回廊 - main.core.control.checkBgm(); - page = 0; - main.core.ui.CG.cgs = core.getLocalStorage("cgs", []); - CGUI.style.display = "block"; - main.core.ui.CG.update(); - }; - }, "光标设置": function () { // 在此增加新插件 this.changeMouse = function ( @@ -14729,172 +14895,68 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = }; }, "warning": function () { - // 在此增加新插件 - // 默认音效名 - var defaultSound = "jingbao.opus"; - // 默认字体名 - var defaultFont = "Verdana"; + // 在此增加新插件 + // 默认音效名 + var defaultSound = "jingbao.opus"; + // 默认字体名 + var defaultFont = "Verdana"; - var timeout; - /** warning提示 - * @param {number} x 横坐标 - * @param {number} y 纵坐标 - * @param {string} text 显示的文字 - */ - this.drawWarning = function (x, y, size, text, text2, warning) { - if (timeout) return; - x = x ?? 6; - y = y ?? 6; - text = text || "boss"; - text += "
"; - for (var i = 0; i < 10; i++) text += " "; - text += text2; - // 生成文字 - var elements = document.querySelectorAll(".gameCanvas"); - var t = document.createElement("p"); - t.innerHTML = text; - t.style.position = "absolute"; - t.style.fontSize = size * core.domStyle.scale + "px"; - t.style.left = -(300 * core.domStyle.scale) + "px"; - t.style.top = parseInt(elements[0].style.height) / 2 - 100 + "px"; - t.style.zIndex = "300"; - t.style.color = "#f11"; - t.style.fontFamily = defaultFont; - t.style.overflow = "none"; - t.style.width = "100%"; - t.classList.add("warning"); - core.dom.gameDraw.appendChild(t); - setTimeout(function () { - t.style.left = 416 * core.domStyle.scale + "px"; - }, 50); - // 计算偏移量 - var px = ((6 - x) / 12) * 50; - var py = ((6 - y) / 12) * 50; - // 修改画布的scale和transform - elements.forEach(function (v) { - if (v instanceof HTMLCanvasElement) { - v.style.transform = "scale(2)translate(" + px + "%, " + py + "%)"; - } - }); - if (!warning) core.playSound(defaultSound); - // 拉回镜头 - timeout = setTimeout(function () { - timeout = setTimeout(function () { - timeout = void 0; - core.dom.gameDraw.removeChild(t); - }, 1500); - elements.forEach(function (v) { - if (v instanceof HTMLCanvasElement) { - v.style.transform = "none"; - } - }); - }, 1600); - }; - }, - "立体声音效": function () { - // 在此增加新插件 - // 音效双声道播放 - var can = true; - if (!AudioContext) { - console.warn("该浏览器不支持AudioContext,无法播放立体声"); - can = false; - } - if (can) var ac = new AudioContext(); - var datas = {}; - - /** 播放立体声 参考:https://developer.mozilla.org/zh-CN/docs/Web/API/BaseAudioContext/createChannelSplitter - * @param {number} name 音效名 - * @param {number} left 左声道音量,默认为1 - * @param {number} right 右声道音量,默认为1 - * @param {boolean} split 音效为双声道,请填true,为单声道,请填false或不填 - * @returns 该音效的唯一id - */ - this.playStereo = function (name, left, right, split) { - if (!can) return core.playSound(name); - var sound = core.getMappedName(name); - if ( - main.mode != "play" || - !core.musicStatus.soundStatus || - !core.material.sounds[sound] - ) - return; - if (!core.status.stereo) core.status.stereo = {}; - var buffer = core.material.sounds[sound]; - var source = ac.createBufferSource(); - source.buffer = buffer; - var splitter = ac.createChannelSplitter(2); - source.connect(splitter); - var merger = ac.createChannelMerger(2); - - /* 大致流程 - gain(L) - / \ - source ---- splitter merger ---- destination - \ / - gain(R) - */ - - var L = ac.createGain(); - var R = ac.createGain(); - L.gain.value = left * core.musicStatus.userVolume; - R.gain.value = right * core.musicStatus.userVolume; - splitter.connect(L, 0, 0); - if (!split) splitter.connect(R, 0, 0); - else splitter.connect(R, 1, 0); - - var id = setTimeout(null); - core.status.stereo[id] = { source: source, L: L, R: R }; - - L.connect(merger, 0, 0); - R.connect(merger, 0, 1); - - var dest = ac.destination; - - source.onended = function () { - delete datas[id]; - source = void 0; - }; - - merger.connect(dest); - source.start(0); - return id; - }; - - /** 移动声源(渐变调整左右声道音量) - * @param {number} id 为playStereo返回的id - * @param {number} left 要渐变到的左声道音量 - * @param {number} right 要渐变到的右声道音量 - * @param {number} time 渐变时间 - */ - this.moveStereo = function (id, left, right, time) { - if (!can) return; - if (main.mode != "play" || !core.musicStatus.soundStatus) return; - var stereo = core.status.stereo[id]; - datas[id] = { - time: time, - curr: 0, - dL: - ((left - stereo.L.gain.value) / time) * - 10 * - core.musicStatus.userVolume, - dR: - ((right - stereo.R.gain.value) / time) * - 10 * - core.musicStatus.userVolume, - }; - var interval = setInterval(function () { - var data = datas[id]; - if (!data) return clearInterval(interval); - data.curr += 10; - if (data.curr >= data.time) { - clearInterval(interval); - datas[id] = void 0; - } - stereo.L.gain.value += data.dL; - stereo.R.gain.value += data.dR; - }, 10); - }; - }, + var timeout; + /** warning提示 + * @param {number} x 横坐标 + * @param {number} y 纵坐标 + * @param {string} text 显示的文字 + */ + this.drawWarning = function (x, y, size, text, text2, warning) { + if (timeout) return; + x = x ?? 6; + y = y ?? 6; + text = text || "boss"; + text += "
"; + for (var i = 0; i < 10; i++) text += " "; + text += text2; + // 生成文字 + var elements = document.querySelectorAll(".gameCanvas"); + var t = document.createElement("p"); + t.innerHTML = text; + t.style.position = "absolute"; + t.style.fontSize = size * core.domStyle.scale + "px"; + t.style.left = -(300 * core.domStyle.scale) + "px"; + t.style.top = parseInt(elements[0].style.height) / 2 - 100 + "px"; + t.style.zIndex = "300"; + t.style.color = "#f11"; + t.style.fontFamily = defaultFont; + t.style.overflow = "none"; + t.style.width = "100%"; + t.classList.add("warning"); + core.dom.gameDraw.appendChild(t); + setTimeout(function () { + t.style.left = 416 * core.domStyle.scale + "px"; + }, 50); + // 计算偏移量 + var px = ((6 - x) / 12) * 50; + var py = ((6 - y) / 12) * 50; + // 修改画布的scale和transform + elements.forEach(function (v) { + if (v instanceof HTMLCanvasElement) { + v.style.transform = "scale(2)translate(" + px + "%, " + py + "%)"; + } + }); + if (!warning) core.playSound(defaultSound); + // 拉回镜头 + timeout = setTimeout(function () { + timeout = setTimeout(function () { + timeout = void 0; + core.dom.gameDraw.removeChild(t); + }, 1500); + elements.forEach(function (v) { + if (v instanceof HTMLCanvasElement) { + v.style.transform = "none"; + } + }); + }, 1600); + }; +}, "滑动转场": function () { // 在此增加新插件 const defaultChange = { @@ -15098,12 +15160,94 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = cg.style.transform = "translate(-50%,-50%)"; const ctx = cg.getContext("2d"); main.dom.cgText = cg; + const logcanvas = document.createElement("canvas"); //cg画布设置 + logcanvas.style.position = "absolute"; + logcanvas.style.zIndex = 301; + logcanvas.style.display = "none"; + logcanvas.id = "cgText"; + main.dom.gameGroup.insertAdjacentElement("afterend", logcanvas); + logcanvas.style.top = "50%"; + logcanvas.style.left = "50%"; + logcanvas.style.transform = "translate(-50%,-50%)"; + const logctx = logcanvas.getContext("2d"); + main.dom.logcanvas = logcanvas; + logcanvas.onmouseup = function (e) { + //鼠标抬起 + try { + + if (!core.isPlaying()) return false; + core.unregisterAnimationFrame("skip"); + let a = core.getFlag("skip", false); + core.setFlag("skip", false); + if (a) { + const data = core.clone(core.status.event.data.current); + + core.insertAction(data); + core.doAction(); + } + } catch (ee) { + console.error(ee); + } + }; + logcanvas.onmousedown = function (e) { + //鼠标按下 + try { + + if (!core.isPlaying()) return false; + const left = core.dom.gameGroup.offsetLeft; + const top = core.dom.gameGroup.offsetTop; + const px = Math.floor((e.clientX - left) / core.domStyle.scale), + py = Math.floor((e.clientY - top) / core.domStyle.scale); + core.ui.cgText.click(px * 3, py * 3); + + } catch (ee) { + main.log(ee); + } + }; + logcanvas.ontouchend = function (e) { + //触摸抬起 + + try { + + if (!core.isPlaying()) return false; + core.unregisterAnimationFrame("skip"); + core.setFlag("skip", false); + let a = core.getFlag("skip", false); + core.setFlag("skip", false); + if (a) { + const data = core.clone(core.status.event.data.current); + + core.insertAction(data); + core.doAction(); + } + } catch (ee) { + + } + }; + logcanvas.ontouchstart = function (e) { + //触摸按下 + try { + + if (!core.isPlaying()) return false; + const left = core.dom.gameGroup.offsetLeft; + const top = core.dom.gameGroup.offsetTop; + const px = Math.floor( + (e.targetTouches[0].clientX - left) / core.domStyle.scale + ), + py = Math.floor( + (e.targetTouches[0].clientY - top) / core.domStyle.scale + ); + core.ui.cgText.click(px * 3, py * 3); + } catch (ee) { + main.log(ee); + } + }; cg.onmouseup = function (e) { //鼠标抬起 try { - e.stopPropagation(); + if (!core.isPlaying()) return false; core.unregisterAnimationFrame("skip"); let a = core.getFlag("skip", false); @@ -15121,13 +15265,14 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = cg.onmousedown = function (e) { //鼠标按下 try { - e.stopPropagation(); + if (!core.isPlaying()) return false; const left = core.dom.gameGroup.offsetLeft; const top = core.dom.gameGroup.offsetTop; const px = Math.floor((e.clientX - left) / core.domStyle.scale), py = Math.floor((e.clientY - top) / core.domStyle.scale); core.ui.cgText.click(px * 3, py * 3); + } catch (ee) { main.log(ee); } @@ -15136,7 +15281,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = //触摸抬起 try { - e.preventDefault(); + if (!core.isPlaying()) return false; core.unregisterAnimationFrame("skip"); core.setFlag("skip", false); @@ -15155,7 +15300,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = cg.ontouchstart = function (e) { //触摸按下 try { - e.preventDefault(); + if (!core.isPlaying()) return false; const left = core.dom.gameGroup.offsetLeft; const top = core.dom.gameGroup.offsetTop; @@ -15171,6 +15316,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = } }; let auto = false; + class cgText { constructor() { //绘制需要的变量 @@ -15186,8 +15332,13 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = this.WindowSkin = false; this.sound = ""; this.beforeSound = 0; - this.wait = 200; + this.wait = 1000; this.memory = false; + this.textList = [] + this.page = 1 + this.overpage = 1 + this.log = false + this.index = 0 } click(px, py) { //点击效果 @@ -15207,101 +15358,156 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = const pos = [px, py]; const savebox = makeBox([1700, 1100], [192, 96]); const saveboxVertical = makeBox([52, 1700], [96, 192]); - const skipbox = makeBox([1400, 1100], [192, 96]); - const skipboxVertical = makeBox([52, 1400], [96, 192]); + const skipbox = makeBox([1700, 1000], [192, 96]); + const skipboxVertical = makeBox([152, 1700], [96, 192]); const autobox = makeBox([1700, 900], [192, 96]); - const autoboxVertical = makeBox([256, 1700], [96, 192]); - if ( - (core.domStyle.isVertical && - inRect(pos, skipboxVertical) && - !this.WindowSkin) || - (!core.domStyle.isVertical && - !this.WindowSkin && - inRect(pos, skipbox)) - ) { - auto = false; - let time = 0; - core.stopSound(this.beforeSound); - core.registerAnimationFrame("skip", true, (timestamp) => { - if (timestamp > time + 50) { - time = timestamp; - if ( - core.status.event.id == "action" && - core.status.event.data.type == "cgtext" - ) { - core.setFlag("skip", true); - main.dom.cgText.style.display = "none"; - core.doAction(); - } - } - }); - } else if ( - (core.domStyle.isVertical && - inRect(pos, autoboxVertical) && - !this.WindowSkin) || - (!core.domStyle.isVertical && - !this.WindowSkin && - inRect(pos, autobox)) - ) { - auto = !auto; - - const data = core.clone(core.status.event.data.current); - data.showAll = true; - data.time = 0; - data.text = data.text.replace(/(\\(z))(\[.*?])?/g, ""); //去除打字机暂停效果 - data.sound = ""; - core.insertAction(data); - core.doAction(); - } else if ( - (core.domStyle.isVertical && - inRect(pos, saveboxVertical) && - !this.WindowSkin) || - (!core.domStyle.isVertical && - !this.WindowSkin && - inRect(pos, savebox)) - ) { - //存档 - auto = false; - if (core.status.event.animateUI) return; - if (core.status.event.interval != null) return; - const current = core.clone(core.status.event.data.current); - current.showAll = true; - current.time = 0; - current.sound = ""; - current.text = current.text.replace(/(\\(z))(\[.*?])?/g, ""); //去除当前事件所有打字机效果 - cg.style.display = "none"; - const data = [{ type: "callSave" }, current]; //插入存档事件 - core.insertAction(data); - - core.doAction(); - } else if (!core.status.event.data) { - cg.style.display = "none"; - core.ui._animateUI("hide", null, () => { - core.doAction(); - }); + const autoboxVertical = makeBox([252, 1700], [96, 192]); + const textbox = makeBox([1700, 800], [192, 96]); + const textboxVertical = makeBox([352, 1700], [96, 192]); + const backbox = makeBox([15, 35], [210, 90]); + const backboxVertical = makeBox([1123, 15], [90, 210]); + const pageupbox = makeBox([300, 1130], [200, 100]); + const pageupboxVertical = makeBox([18, 300], [100, 200]); + const pagedownbox = makeBox([1500, 1130], [200, 100]); + const pagedownboxVertical = makeBox([18, 1500], [100, 200]); + if (this.log) { + if ( + (core.domStyle.isVertical && inRect(pos, backboxVertical)) || + (!core.domStyle.isVertical && + inRect(pos, backbox)) + ) { + core.clearMap(logctx) + main.dom.logcanvas.style.display = "none" + this.log = false + } else if ((core.domStyle.isVertical && inRect(pos, pageupboxVertical)) || + (!core.domStyle.isVertical && + inRect(pos, pageupbox)) + ) { + core.clearMap(logctx) + if (this.page > 1) this.page-- + this.logdraw(this.page) + } else if ((core.domStyle.isVertical && inRect(pos, pagedownboxVertical)) || + (!core.domStyle.isVertical && + inRect(pos, pagedownbox)) + ) { + core.clearMap(logctx) + if (this.page < this.overpage) this.page++ + this.logdraw(this.page) + } } else { - // 正在淡入淡出的话不执行 - if (core.status.event.animateUI) return; - auto = false; - - // 打字机效果显示全部文字 - if (core.status.event.interval != null) { - const data = core.clone(core.status.event.data?.current); + if ( + (core.domStyle.isVertical && + inRect(pos, skipboxVertical) && + !this.WindowSkin) || + (!core.domStyle.isVertical && + !this.WindowSkin && + inRect(pos, skipbox)) + ) { + auto = false; + let time = 0; + core.stopSound(this.beforeSound); + core.registerAnimationFrame("skip", true, (timestamp) => { + if (timestamp > time + 50) { + time = timestamp; + if ( + core.status.event.id == "action" && + core.status.event.data.type == "cgtext" + ) { + core.setFlag("skip", true); + main.dom.cgText.style.display = "none"; + core.doAction(); + } + } + }) + } else if ( + (core.domStyle.isVertical && + inRect(pos, textboxVertical) && + !this.WindowSkin) || + (!core.domStyle.isVertical && + !this.WindowSkin && + inRect(pos, textbox)) + ) { + auto = false + this.log = true + this.overpage = Math.floor(this.index / 6) + 1 + this.page = this.overpage + logcanvas.style.display = "block" + const data = core.clone(core.status.event.data.current); data.showAll = true; data.time = 0; - data.text = data.text.replace(/(\\(z))(\[.*?])?/g, ""); //去除打字机暂停效果 + data.text = this.text.replaceAll(/(\\(z))(\[.*?\])?/g, ""); //去除打字机暂停效果 data.sound = ""; core.insertAction(data); core.doAction(); - return; - } else { - core.stopSound(this.beforeSound); - } + this.logdraw(this.page) + } else if ( + (core.domStyle.isVertical && + inRect(pos, autoboxVertical) && + !this.WindowSkin) || + (!core.domStyle.isVertical && + !this.WindowSkin && + inRect(pos, autobox)) + ) { + auto = !auto; - cg.style.display = "none"; - core.ui._animateUI("hide", null, () => { + const data = core.clone(core.status.event.data.current); + data.showAll = true; + data.time = 0; + data.text = this.text.replaceAll(/(\\(z))(\[.*?\])?/g, ""); //去除打字机暂停效果 + data.sound = ""; + core.insertAction(data); core.doAction(); - }); + } else if ( + (core.domStyle.isVertical && + inRect(pos, saveboxVertical) && + !this.WindowSkin) || + (!core.domStyle.isVertical && + !this.WindowSkin && + inRect(pos, savebox)) + ) { + //存档 + auto = false; + if (core.status.event.animateUI) return; + if (core.status.event.interval != null) return; + const current = core.clone(core.status.event.data.current); + current.showAll = true; + current.time = 0; + current.sound = ""; + current.text = this.text.replaceAll(/(\\(z))(\[.*?\])?/g, ""); //去除当前事件所有打字机效果 + cg.style.display = "none"; + const data = [{ type: "callSave" }, current]; //插入存档事件 + core.insertAction(data); + + core.doAction(); + } else if (!core.status.event.data) { + cg.style.display = "none"; + core.ui._animateUI("hide", null, () => { + core.doAction(); + }); + } else { + // 正在淡入淡出的话不执行 + if (core.status.event.animateUI) return; + auto = false; + + // 打字机效果显示全部文字 + if (core.status.event.interval != null) { + const data = core.clone(core.status.event.data?.current); + data.showAll = true; + data.time = 0; + data.text = this.text.replaceAll(/(\\(z))(\[.*?\])?/g, ""); //去除打字机暂停效果 + data.sound = ""; + core.insertAction(data); + core.doAction(); + return; + } else { + core.stopSound(this.beforeSound); + } + + cg.style.display = "none"; + core.ui._animateUI("hide", null, () => { + core.doAction(); + }); + } } } @@ -15411,10 +15617,12 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = if (config.time == 0) { while (_drawNext()); + if ( - (auto && !this.WindowSkin && !core.ui.cgText.sound) || + (auto && !core.ui.cgText.WindowSkin && !core.ui.cgText.sound) || (core.ui.cgText.sound && !core.musicStatus.soundStatus) ) { + setTimeout(() => { if (auto) { cg.style.display = "none"; @@ -15430,8 +15638,9 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = if (!_drawNext()) { clearInterval(core.status.event.interval); core.status.event.interval = null; + if ( - (auto && !this.WindowSkin && !core.ui.cgText.sound) || + (auto && !core.ui.cgText.WindowSkin && !core.ui.cgText.sound) || (core.ui.cgText.sound && !core.musicStatus.soundStatus) ) setTimeout(() => { @@ -15451,6 +15660,161 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = update() { this.background(); + if (this.log) this.logdraw(this.page) + } + logdraw(page) { + if (core.domStyle.isVertical) { + logctx.canvas.width = 1248; + logctx.canvas.height = 2028; + logctx.save(); //保存设置 + logctx.translate(1248, 0); //重新定位右上角为基准 + logctx.rotate(Math.PI / 2); //旋转90度 + } else { + logctx.canvas.width = 2028; + logctx.canvas.height = 1248; + } + core.fillRect(logctx, 0, 0, 2028, 1248, "rgba(0,0,0,0.5)") + core.setTextAlign(logctx, "center") + core.fillBoldText1( + logctx, + "◀离开", + 110, + 100, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(66, true) + ); + logctx.strokeStyle = "#FFFFFF"; + logctx.lineWidth = 3; + logctx.beginPath(); + logctx.moveTo(100, 150); + logctx.lineTo(1928, 150); + + logctx.stroke(); + let posy = 150; + const indexList = this.textList; + core.setTextAlign(logctx, "left"); + for (let i = (page - 1) * 6; i <= Math.min(this.index, page * 6 - 1); i++) { + const text = this.textList[i][1].replaceAll(/(\\(d|e|f|g|i|n|r|b|c|t|z))(\[.*?\])?/g, ""); //取消打字机 + const name = this.textList[i][0] ? "【" + this.textList[i][0] + "】" : ""; + if (name) { + core.fillBoldText1( + logctx, + name, + 150, + posy + 50, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(42, true) + ); + } + if (text.length < 30) { + core.fillBoldText1( + logctx, + text, + 650, + posy + 50, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(42, true) + ); + } else { + let text1 = text.slice(0, 30) + core.fillBoldText1( + logctx, + text1, + 650, + posy + 50, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(42, true)) + if (text.length > 60) { + let text2 = text.slice(30, 60) + let text3 = text.slice(60) + core.fillBoldText1( + logctx, + text2, + 650, + posy + 100, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(42, true)) + core.fillBoldText1( + logctx, + text3, + 650, + posy + 150, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(42, true)) + } else { + let text2 = text.slice(30) + core.fillBoldText1( + logctx, + text2, + 650, + posy + 100, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(42, true)) + } + } + + + logctx.strokeStyle = "#FFFFFF"; + logctx.lineWidth = 3; + logctx.beginPath(); + logctx.moveTo(100, posy); + logctx.lineTo(1928, posy); + logctx.stroke(); + + posy += 160; + } + logctx.beginPath(); + logctx.moveTo(100, 1120); + logctx.lineTo(1928, 1120); + logctx.moveTo(100, 1110); + logctx.lineTo(1928, 1110); + logctx.stroke(); + core.fillBoldText1( + logctx, + "上一页", + 300, + 1200, + page === 1 ? "#444444" : "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(66, true) + ); + + core.fillBoldText1( + logctx, + page + "/" + this.overpage, + 1000, + 1200, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(66, true) + ); + core.fillBoldText1( + logctx, + "下一页", + 1500, + 1200, + page === this.overpage ? "#444444" : "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(66, true) + ); + } background() { const img = core.material.images.images?.[this.image]; @@ -15513,9 +15877,9 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = "winskin.webp", ctx, 30, - 802, + 780, 1968, - 416, + 436, null, null, null, @@ -15531,12 +15895,34 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = head.width, head.height, this.head.px, - 1248 - head.height * 2, - head.width * 2, - head.height * 2 + 1248 - head.height * 2.2, + head.width * 2.2, + head.height * 2.2 ); } if (core.isPlaying() && !this.WindowSkin) { + core.drawWindowSkin( + "winskin.webp", + ctx, + 1700, + 800, + 192, + 96, + null, + null, + null, + 3 + ); + core.fillBoldText1( + ctx, + "记 录", + 1736, + 866, + "#FFFFFF", + "#000000", + 6, + "bold 48px Verdana" + ); core.drawWindowSkin( "winskin.webp", ctx, @@ -15562,8 +15948,8 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = core.drawWindowSkin( "winskin.webp", ctx, - 1400, - 1100, + 1700, + 1000, 192, 96, null, @@ -15574,8 +15960,8 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = core.fillBoldText1( ctx, "▶▶", - 1456, - 1166, + 1756, + 1066, "#FFFFFF", "#000000", 6, @@ -15610,16 +15996,16 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = core.fillBoldText1( ctx, `【${this.name}】`, - 500, + 550, 880, "#FFFFFF", "#000000", 6, "bold 48px Verdana" ); //绘制名字 + if ( - this.sound && - core.material.sounds[this.sound] && + this.sound && core.sounds && !core.getFlag("skip", false) && core.musicStatus.soundStatus ) { @@ -15637,14 +16023,14 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = core.doAction(); }); } - }, core.ui.cgText.wait); + }, this.wait); } }); } if (this.text && !core.getFlag("skip", false)) { //绘制对话 this.drawTextContent(ctx, this.text, { - left: 500, + left: 550, top: 950, bold: true, color: "#FFFFFF", @@ -15725,9 +16111,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = if (frame > hidetime + time && frame <= hidetime * 2 + time) core.setAlpha(ctx, 1 - (frame - hidetime - time) / hidetime); const lisen = - sound && - core.material.sounds[sound] && - core.musicStatus.soundStatus; + sound && core.sounds[sound] && core.musicStatus.soundStatus; if (frame == hidetime && lisen) { sod = core.playSound(sound); } @@ -15897,9 +16281,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = core.stopSound(sod); } const lisenb = - b.sound && - core.material.sounds[b.sound] && - core.musicStatus.soundStatus; + b.sound && core.sounds[b.sound] && core.musicStatus.soundStatus; if (b.frame && lisenb) { sod = core.playSound(sound); } @@ -16200,189 +16582,189 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = core.ui.boss = new boss1(); }, "剧情视频引用": function () { - // 在此增加新插件 - let a; - let bgm; + // 在此增加新插件 + let a; + let bgm; - function gtouchstart() { - timeOutEvent = setTimeout(() => { - video.remove(); - video1.remove(); - core.doAction(); - clearTimeout(a); - core.playBgm(bgm); - core.resumeBgm(); - }, 2000); //这里设置定时器,定义长按500毫秒触发长按事件,时间可以自己改,个人感觉500毫秒非常合适 - return false; - } + function gtouchstart() { + timeOutEvent = setTimeout(() => { + video.remove(); + video1.remove(); + core.doAction(); + clearTimeout(a); + core.playBgm(bgm); + core.resumeBgm(); + }, 2000); //这里设置定时器,定义长按500毫秒触发长按事件,时间可以自己改,个人感觉500毫秒非常合适 + return false; + } - //手释放,如果在500毫秒内就释放,则取消长按事件,此时可以执行onclick应该执行的事件 - function gtouchend() { - if (timeOutEvent != 0) { - //这里写要执行的内容(尤如onclick事件) - console.log("你这是点击,不是长按"); - } - clearTimeout(timeOutEvent); //清除定时器 - return false; - } + //手释放,如果在500毫秒内就释放,则取消长按事件,此时可以执行onclick应该执行的事件 + function gtouchend() { + if (timeOutEvent != 0) { + //这里写要执行的内容(尤如onclick事件) + console.log("你这是点击,不是长按"); + } + clearTimeout(timeOutEvent); //清除定时器 + return false; + } - this.openvideo = function () { - if (!core.isPlaying()) return; - const video = document.createElement("iframe"); //iframe设置 - video.style.position = "absolute"; - video.style.zIndex = 320; - video.style.display = "block"; - video.id = "video"; - main.dom.gameGroup.insertAdjacentElement("afterend", video); - video.style.top = "50%"; - video.style.left = "50%"; - video.style.transform = "translate(-50%,-50%)"; - main.dom.video = video; - const video1 = document.createElement("canvas"); //video1画布设置 - video1.style.position = "absolute"; - video1.style.zIndex = 330; - video1.style.display = "block"; - video1.id = "video1"; - main.dom.gameGroup.insertAdjacentElement("afterend", video1); - video1.style.top = "50%"; - video1.style.left = "50%"; - video1.style.transform = "translate(-50%,-50%)"; - const ctx = video1.getContext("2d"); - main.dom.video1 = video1; - if (core.domStyle.isVertical) { - video.width = 416 * 3; - video.height = 676 * 3; - video.style.transform = "translate(-50%,-50%) rotate(90deg)"; //重新定位右上角为基准 - } else { - video.width = 676 * 3; - video.height = 416 * 3; - video.style.transform = "translate(-50%,-50%)"; - } - video1.ontouchstart = function (e) { - try { - e.preventDefault(); - if (!core.isPlaying()) return false; - gtouchstart(); - } catch (ee) { - main.log(ee); - } - }; - video1.ontouchend = function (e) { - try { - e.preventDefault(); - if (!core.isPlaying()) return false; - gtouchend(); - } catch (ee) { - main.log(ee); - } - }; + this.openvideo = function () { + if (!core.isPlaying()) return; + const video = document.createElement("iframe"); //iframe设置 + video.style.position = "absolute"; + video.style.zIndex = 320; + video.style.display = "block"; + video.id = "video"; + main.dom.gameGroup.insertAdjacentElement("afterend", video); + video.style.top = "50%"; + video.style.left = "50%"; + video.style.transform = "translate(-50%,-50%)"; + main.dom.video = video; + const video1 = document.createElement("canvas"); //video1画布设置 + video1.style.position = "absolute"; + video1.style.zIndex = 330; + video1.style.display = "block"; + video1.id = "video1"; + main.dom.gameGroup.insertAdjacentElement("afterend", video1); + video1.style.top = "50%"; + video1.style.left = "50%"; + video1.style.transform = "translate(-50%,-50%)"; + const ctx = video1.getContext("2d"); + main.dom.video1 = video1; + if (core.domStyle.isVertical) { + video.width = 416 * 3; + video.height = 676 * 3; + video.style.transform = "translate(-50%,-50%) rotate(90deg)"; //重新定位右上角为基准 + } else { + video.width = 676 * 3; + video.height = 416 * 3; + video.style.transform = "translate(-50%,-50%)"; + } + video1.ontouchstart = function (e) { + try { + e.preventDefault(); + if (!core.isPlaying()) return false; + gtouchstart(); + } catch (ee) { + main.log(ee); + } + }; + video1.ontouchend = function (e) { + try { + e.preventDefault(); + if (!core.isPlaying()) return false; + gtouchend(); + } catch (ee) { + main.log(ee); + } + }; - video1.onmouseup = function (e) { - //鼠标抬起 - try { - e.stopPropagation(); - if (!core.isPlaying()) return false; - gtouchend(); - } catch (ee) { - console.error(ee); - } - }; - video1.onmousedown = function (e) { - //鼠标按下 - try { - e.stopPropagation(); - if (!core.isPlaying()) return false; - gtouchstart(); - } catch (ee) { - main.log(ee); - } - }; - let globalAlpha = 0; - let frame = 1; - let al = 0; - core.registerAnimationFrame("beforeop", true, function () { - al++; - core.clearMap(ctx); - ctx.globalAlpha = al / 30; - core.fillRect(ctx, 0, 0, video1.width, video1.height, "#000000"); - ctx.globalAlpha = 1; - core.fillBoldText1( - ctx, - "Loading...", - 1014, - 624, - "#FFFFFF", - "#000000", - 6, - "bold 72px Verdana" - ); - }); - core.control.resize(); + video1.onmouseup = function (e) { + //鼠标抬起 + try { + e.stopPropagation(); + if (!core.isPlaying()) return false; + gtouchend(); + } catch (ee) { + console.error(ee); + } + }; + video1.onmousedown = function (e) { + //鼠标按下 + try { + e.stopPropagation(); + if (!core.isPlaying()) return false; + gtouchstart(); + } catch (ee) { + main.log(ee); + } + }; + let globalAlpha = 0; + let frame = 1; + let al = 0; + core.registerAnimationFrame("beforeop", true, function () { + al++; + core.clearMap(ctx); + ctx.globalAlpha = al / 30; + core.fillRect(ctx, 0, 0, video1.width, video1.height, "#000000"); + ctx.globalAlpha = 1; + core.fillBoldText1( + ctx, + "Loading...", + 1014, + 624, + "#FFFFFF", + "#000000", + 6, + "bold 72px Verdana" + ); + }); + core.control.resize(); - //player.bilibili.com/player.html - //www.bilibili.com/blackboard/html5mobileplayer.html - // - video.src = - "///www.bilibili.com/blackboard/html5mobileplayer.html?isOutside=true&aid=6484104&bvid=BV1cs411b7cH&cid=10546155&p=1&poster=0&autoplay=1&high_quality=1&muted=0&danmaku=0"; - video.scrolling = "no"; - video.border = "0"; - video.crossorigin = true; - video.frameborder = "no"; - video.framespacing = "0"; - video.allowfullscreen = false; + //player.bilibili.com/player.html + //www.bilibili.com/blackboard/html5mobileplayer.html + // + video.src = + "///www.bilibili.com/blackboard/html5mobileplayer.html?isOutside=true&aid=6484104&bvid=BV1cs411b7cH&cid=10546155&p=1&poster=0&autoplay=1&high_quality=1&muted=0&danmaku=0"; + video.scrolling = "no"; + video.border = "0"; + video.crossorigin = true; + video.frameborder = "no"; + video.framespacing = "0"; + video.allowfullscreen = false; - video.sandbox = - "allow-top-navigation allow-same-origin allow-forms allow-scripts"; - //gsl_play_mask + video.sandbox = + "allow-top-navigation allow-same-origin allow-forms allow-scripts"; + //gsl_play_mask - video.addEventListener("load", function () { - core.unregisterAnimationFrame("beforeop"); - core.registerAnimationFrame("op", true, function () { - core.clearMap(ctx); - if (core.domStyle.isVertical) { - ctx.canvas.width = 416 * 3; - ctx.canvas.height = 676 * 3; - ctx.save(); //保存设置 - ctx.translate(416 * 3, 0); //重新定位右上角为基准 - ctx.rotate(Math.PI / 2); //旋转90度 - } else { - ctx.canvas.width = 676 * 3; - ctx.canvas.height = 416 * 3; - } - ctx.globalAlpha = 1; - core.fillRect(ctx, 0, 0, video1.width, video1.height, "#000000"); + video.addEventListener("load", function () { + core.unregisterAnimationFrame("beforeop"); + core.registerAnimationFrame("op", true, function () { + core.clearMap(ctx); + if (core.domStyle.isVertical) { + ctx.canvas.width = 416 * 3; + ctx.canvas.height = 676 * 3; + ctx.save(); //保存设置 + ctx.translate(416 * 3, 0); //重新定位右上角为基准 + ctx.rotate(Math.PI / 2); //旋转90度 + } else { + ctx.canvas.width = 676 * 3; + ctx.canvas.height = 416 * 3; + } + ctx.globalAlpha = 1; + core.fillRect(ctx, 0, 0, video1.width, video1.height, "#000000"); - ctx.globalAlpha = globalAlpha / 30; - core.setTextAlign(ctx, "center"); - core.fillBoldText1( - ctx, - "长按2秒后跳过op", - 1014, - 624, - "#FFFFFF", - "#000000", - 6, - "bold 48px Verdana" - ); - globalAlpha += frame; - if (globalAlpha > 29) frame = -1; - ctx.restore(); - if (frame === -1 && globalAlpha < 0) { - core.clearMap(ctx); - core.unregisterAnimationFrame("op"); - } - }); - bgm = core.musicStatus.playingBgm; - core.playBgm("op.opus"); - a = setTimeout(() => { - video.remove(); - video1.remove(); - core.playBgm(bgm); - core.doAction(); - }, 127500); - }); - }; - }, + ctx.globalAlpha = globalAlpha / 30; + core.setTextAlign(ctx, "center"); + core.fillBoldText1( + ctx, + "长按2秒后跳过op", + 1014, + 624, + "#FFFFFF", + "#000000", + 6, + "bold 48px Verdana" + ); + globalAlpha += frame; + if (globalAlpha > 29) frame = -1; + ctx.restore(); + if (frame === -1 && globalAlpha < 0) { + core.clearMap(ctx); + core.unregisterAnimationFrame("op"); + } + }); + bgm = core.musicStatus.playingBgm; + core.playBgm("op.opus"); + a = setTimeout(() => { + video.remove(); + video1.remove(); + core.playBgm(bgm); + core.doAction(); + }, 127500); + }); + }; +}, "帧动画/图片叠拼": function () { // 在此增加新插件 this.animationDrawable = function ( @@ -16484,7 +16866,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = soundList.forEach(function (one) { const lisen = one.sound && - core.material.sounds[one.sound] && + core.sounds[one.sound] && core.musicStatus.soundStatus; if (farme == one.startfarme && lisen) { if (one.stopbefore) core.stopSound(); @@ -16506,1125 +16888,1128 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = }; }, "musicMode": function () { - // 在此增加新插件 - const music = document.createElement("canvas"); - music.style.position = "absolute"; - music.style.zIndex = 300; - music.style.display = "none"; - music.id = "music"; - main.dom.gameGroup.insertAdjacentElement("afterend", music); - music.style.top = "50%"; - music.style.left = "50%"; - music.style.transform = "translate(-50%,-50%)"; - const ctx = music.getContext("2d"); - main.dom.music = music; - - const audio = core.plugin.audioSystem.bgmController; - - let page = 0; //初始页面 - - let isvolume = false; - - function shuffle(arr) { - let n = arr.length, - random; - while (n) { - random = (Math.random() * n--) >>> 0; - [arr[n], arr[random]] = [arr[random], arr[n]]; - } - return arr; - } - music.addEventListener("mousedown", function (e) { - e.stopPropagation(); - const left = core.dom.gameGroup.offsetLeft; - const top = core.dom.gameGroup.offsetTop; - const px = Math.floor((e.clientX - left) / core.domStyle.scale), - py = Math.floor((e.clientY - top) / core.domStyle.scale); - core.ui.music.mousedown(px * 3, py * 3); - }); - music.addEventListener("mousemove", function (e) { - e.stopPropagation(); - const left = core.dom.gameGroup.offsetLeft; - const top = core.dom.gameGroup.offsetTop; - const px = Math.floor((e.clientX - left) / core.domStyle.scale), - py = Math.floor((e.clientY - top) / core.domStyle.scale); - core.ui.music.mousemove(px * 3, py * 3); - }); - music.addEventListener("mouseup", function (e) { - e.stopPropagation(); - - isvolume = false; - }); - music.addEventListener("mouseleave", function (e) { - e.stopPropagation(); - - isvolume = false; - }); - music.addEventListener("touchstart", function (e) { - e.preventDefault(); - const left = core.dom.gameGroup.offsetLeft; - const top = core.dom.gameGroup.offsetTop; - const px = Math.floor( - (e.touches[0].clientX - left) / core.domStyle.scale - ), - py = Math.floor((e.touches[0].clientY - top) / core.domStyle.scale); - core.ui.music.mousedown(px * 3, py * 3); - }); - music.addEventListener("touchmove", function (e) { - e.stopPropagation(); - const left = core.dom.gameGroup.offsetLeft; - const top = core.dom.gameGroup.offsetTop; - const px = Math.floor( - (e.touches[0].clientX - left) / core.domStyle.scale - ), - py = Math.floor((e.touches[0].clientY - top) / core.domStyle.scale); - core.ui.music.mousemove(px * 3, py * 3); - }); - music.addEventListener("touchend", function (e) { - e.stopPropagation(); - - isvolume = false; - }); - music.addEventListener("touchcancel", function (e) { - e.stopPropagation(); - - isvolume = false; - }); - - class musicclass { - constructor() { - this.musics = ["theme.mp3"]; - //music列表 - //需全塔属性注册并保存在bgms文件夹,每个数组为显示的一页内容 - this.musicMx = [ - [ - "Crawler.opus", - "Blood_Stain.opus", - "Blind_Alley.opus", - "Halbmond.opus", - ], - ["theme.mp3", "op.opus", "Asphodelus_Ceui.opus", "ed.opus"], - ]; - //音乐别名(将在播放器内显示的音乐名,music列表内的都要有对应歌名) - this.musicname = { - "Asphodelus_Ceui.opus": "Asphodelus (Full.ver)", - "Blind_Alley.opus": "Blind Alley", - "Crawler.opus": "Crawler", - "op.opus": "Asphodelus", - "theme.mp3": "One of Episodes", - "ed.opus": "親愛なる世界へ", - "Blood_Stain.opus": "Blood Stain", - "Halbmond.opus": "Halbmond", - }; - this.selection = [0, 0]; - this.stop = false; - this.type = "xunhuan"; - this.randomList = []; - this.random = 0; - } - - //更新 - update() { - this.background(); - this.drawUI(); - } - background() { - //画布大小设置 - if (core.domStyle.isVertical) { - music.width = 1248; - music.height = 2028; - } else { - music.width = 2028; - music.height = 1248; - } - } - mousedown(px, py) { - //鼠标按下时 - - const makeBox = ([x, y], [w, h]) => { - return [ - [x, y], - [x + w, y + h], - ]; - }; - const inRect = ([x, y], [[sx, sy], [dx, dy]]) => { - return sx <= x && x <= dx && sy <= y && y <= dy; - }; - const pos = [px, py]; - const backbox = makeBox([15, 35], [210, 90]); - if (inRect(pos, backbox)) { - //离开按钮是一致的,其余的记区分横竖屏 - music.style.display = "none"; - core.clearMap(ctx); - - core.unregisterAnimationFrame("music"); - core.restart(); - - return; - } - if (core.domStyle.isVertical) { - //竖屏 - - const pageupbox = makeBox([100, 1230], [200, 100]); - const pagedownbox = makeBox([950, 1230], [200, 100]); - const musicbox = makeBox( - [100, 200], - [1048, this.musicMx[page].length * 100] - ); - const beforebox = makeBox([120, 1620], [100, 100]); - const afterbox = makeBox([780, 1620], [100, 100]); - const playbox = makeBox([420, 1580], [200, 200]); - const typebox = makeBox([1040, 1600], [120, 120]); - - const volumebox = makeBox([250, 1940], [1050, 20]); - if (inRect(pos, pageupbox)) { - if (page !== 0) page -= 1; - return; - } - if (inRect(pos, pagedownbox)) { - if (page !== this.musicMx.length - 1) page += 1; - return; - } - if (inRect(pos, playbox)) { - if (this.stop) { - this.stop = !this.stop; - - core.resumeBgm(); - } else { - this.stop = !this.stop; - core.pauseBgm(); - } - return; - } - if (inRect(pos, beforebox)) { - this.stop = false; - switch (this.type) { - case "danqu": - core.playBgm( - main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ - main.core.ui.music.selection[1] - ] - ); - - page = this.selection[0]; - - break; - case "xunhuan": - for (;;) { - if (this.selection[1] === 0) { - if (this.selection[0] === 0) { - this.selection[0] = this.musicMx.length - 1; - this.selection[1] = - this.musicMx[this.selection[0]].length - 1; - } else { - this.selection[0] -= 1; - this.selection[1] = - this.musicMx[this.selection[0]].length - 1; - } - } else { - this.selection[1] -= 1; - } - this.random = this.randomList.indexOf( - this.musicMx[this.selection[0]][this.selection[1]] - ); - page = this.selection[0]; - if ( - this.musics.includes( - this.musicMx[this.selection[0]][this.selection[1]] - ) || - page !== this.musicMx.length - 1 - ) - break; - } - core.playBgm( - main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ - main.core.ui.music.selection[1] - ] - ); - - break; - case "suiji": - for (;;) { - if (this.random > 0) { - this.random -= 1; - } else { - this.random = this.randomList.length - 1; - } - this.selection[0] = this.musicMx.findIndex((v) => - v.includes(this.randomList[this.random]) - ); - this.selection[1] = this.musicMx[this.selection[0]].indexOf( - this.randomList[this.random] - ); - - page = this.selection[0]; - if ( - this.musics.includes( - this.musicMx[this.selection[0]][this.selection[1]] - ) || - page !== this.musicMx.length - 1 - ) - break; - } - core.playBgm( - main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ - main.core.ui.music.selection[1] - ] - ); - - break; - } - return; - } - if (inRect(pos, afterbox)) { - this.stop = false; - switch (this.type) { - case "danqu": - core.playBgm( - main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ - main.core.ui.music.selection[1] - ] - ); - - page = this.selection[0]; - break; - case "xunhuan": - for (;;) { - if ( - this.selection[1] === - this.musicMx[this.selection[0]].length - 1 - ) { - if (this.selection[0] === this.musicMx.length - 1) { - this.selection[0] = 0; - this.selection[1] = 0; - } else { - this.selection[0] += 1; - this.selection[1] = 0; - } - } else { - this.selection[1] += 1; - } - this.random = this.randomList.indexOf( - this.musicMx[this.selection[0]][this.selection[1]] - ); - page = this.selection[0]; - if ( - this.musics.includes( - this.musicMx[this.selection[0]][this.selection[1]] - ) || - page !== this.musicMx.length - 1 - ) - break; - } - core.playBgm( - main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ - main.core.ui.music.selection[1] - ] - ); - - break; - case "suiji": - for (;;) { - if (this.random < this.randomList.length - 1) { - this.random += 1; - } else { - this.random = 0; - } - this.selection[0] = this.musicMx.findIndex((v) => - v.includes(this.randomList[this.random]) - ); - this.selection[1] = this.musicMx[this.selection[0]].indexOf( - this.randomList[this.random] - ); - - page = this.selection[0]; - if ( - this.musics.includes( - this.musicMx[this.selection[0]][this.selection[1]] - ) || - page !== this.musicMx.length - 1 - ) - break; - } - core.playBgm( - main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ - main.core.ui.music.selection[1] - ] - ); - - break; - } - return; - } - if (inRect(pos, typebox)) { - switch (this.type) { - case "danqu": - this.type = "xunhuan"; - break; - case "xunhuan": - this.type = "suiji"; - break; - case "suiji": - this.type = "danqu"; - break; - } - return; - } - if (inRect(pos, musicbox)) { - const index = Math.floor((py - 200) / 100); - if (page !== this.selection[0] || index !== this.selection[1]) { - if ( - this.musics.includes(this.musicMx[page][index]) || - page !== this.musicMx.length - 1 - ) { - this.selection[0] = page; - - this.selection[1] = index; - this.randomList.indexOf( - this.musicMx[this.selection[0]][this.selection[1]] - ); - - core.playBgm( - main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ - main.core.ui.music.selection[1] - ] - ); - - this.stop = false; - } - } else { - if (this.stop) { - this.stop = !this.stop; - core.resumeBgm(); - } else { - this.stop = !this.stop; - core.pauseBgm(); - } - } - return; - } - - if (inRect(pos, volumebox)) { - const time = Math.min(Math.max((px - 250) / 800, 0), 1); - audio.setVolume(time); - core.plugin.audioSystem.soundPlayer.setVolume(time); - isvolume = true; - } - } else { - //横屏 - const pageupbox = makeBox([1050, 1100], [200, 100]); - const pagedownbox = makeBox([1550, 1100], [200, 100]); - const musicbox = makeBox( - [900, 100], - [1000, this.musicMx[page].length * 100] - ); - const beforebox = makeBox([60, 620], [100, 100]); - const afterbox = makeBox([450, 620], [100, 100]); - const playbox = makeBox([200, 570], [200, 200]); - const typebox = makeBox([620, 600], [120, 120]); - - const volumebox = makeBox([100, 990], [600, 20]); - if (inRect(pos, pageupbox)) { - if (page !== 0) page -= 1; - return; - } - if (inRect(pos, pagedownbox)) { - if (page !== this.musicMx.length - 1) page += 1; - return; - } - if (inRect(pos, playbox)) { - if (this.stop) { - this.stop = !this.stop; - core.resumeBgm(); - } else { - this.stop = !this.stop; - core.pauseBgm(); - } - return; - } - if (inRect(pos, beforebox)) { - this.stop = false; - switch (this.type) { - case "danqu": - core.playBgm( - main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ - main.core.ui.music.selection[1] - ] - ); - - page = this.selection[0]; - - break; - case "xunhuan": - for (;;) { - if (this.selection[1] === 0) { - if (this.selection[0] === 0) { - this.selection[0] = this.musicMx.length - 1; - this.selection[1] = - this.musicMx[this.selection[0]].length - 1; - } else { - this.selection[0] -= 1; - this.selection[1] = - this.musicMx[this.selection[0]].length - 1; - } - } else { - this.selection[1] -= 1; - } - this.random = this.randomList.indexOf( - this.musicMx[this.selection[0]][this.selection[1]] - ); - page = this.selection[0]; - - if ( - this.musics.includes( - this.musicMx[this.selection[0]][this.selection[1]] - ) || - page !== this.musicMx.length - 1 - ) - break; - } - core.playBgm( - main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ - main.core.ui.music.selection[1] - ] - ); - - break; - case "suiji": - for (;;) { - if (this.random > 0) { - this.random -= 1; - } else { - this.random = this.randomList.length - 1; - } - this.selection[0] = this.musicMx.findIndex((v) => - v.includes(this.randomList[this.random]) - ); - this.selection[1] = this.musicMx[this.selection[0]].indexOf( - this.randomList[this.random] - ); - - page = this.selection[0]; - - if ( - this.musics.includes( - this.musicMx[this.selection[0]][this.selection[1]] - ) || - page !== this.musicMx.length - 1 - ) - break; - } - core.playBgm( - main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ - main.core.ui.music.selection[1] - ] - ); - - break; - } - return; - } - if (inRect(pos, afterbox)) { - this.stop = false; - switch (this.type) { - case "danqu": - core.playBgm( - main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ - main.core.ui.music.selection[1] - ] - ); - - page = this.selection[0]; - break; - case "xunhuan": - for (;;) { - if ( - this.selection[1] === - this.musicMx[this.selection[0]].length - 1 - ) { - if (this.selection[0] === this.musicMx.length - 1) { - this.selection[0] = 0; - this.selection[1] = 0; - } else { - this.selection[0] += 1; - this.selection[1] = 0; - } - } else { - this.selection[1] += 1; - } - this.randomList.findIndex( - (v) => - v === this.musicMx[this.selection[0]][this.selection[1]] - ); - page = this.selection[0]; - - if ( - this.musics.includes( - this.musicMx[this.selection[0]][this.selection[1]] - ) || - page !== this.musicMx.length - 1 - ) - break; - } - core.playBgm( - main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ - main.core.ui.music.selection[1] - ] - ); - - break; - case "suiji": - for (;;) { - if (this.random < this.randomList.length - 1) { - this.random += 1; - } else { - this.random = 0; - } - this.selection[0] = this.musicMx.findIndex((v) => - v.includes(this.randomList[this.random]) - ); - this.selection[1] = this.musicMx[this.selection[0]].indexOf( - main.core.ui.music.randomList[main.core.ui.music.random] - ); - - page = this.selection[0]; - if ( - this.musics.includes( - this.musicMx[this.selection[0]][this.selection[1]] - ) || - page !== this.musicMx.length - 1 - ) - break; - } - core.playBgm( - main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ - main.core.ui.music.selection[1] - ] - ); - - break; - } - return; - } - if (inRect(pos, typebox)) { - switch (this.type) { - case "danqu": - this.type = "xunhuan"; - break; - case "xunhuan": - this.type = "suiji"; - break; - case "suiji": - this.type = "danqu"; - break; - } - return; - } - if (inRect(pos, musicbox)) { - const index = Math.floor((py - 100) / 100); - if (page !== this.selection[0] || index !== this.selection[1]) { - if ( - this.musics.includes(this.musicMx[page][index]) || - page !== this.musicMx.length - 1 - ) { - this.selection[0] = page; - this.selection[1] = index; - this.randomList.indexOf( - (v) => - v === this.musicMx[this.selection[0]][this.selection[1]] - ); - - core.playBgm( - main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ - main.core.ui.music.selection[1] - ] - ); - this.stop = false; - } - } else { - if (this.stop) { - this.stop = !this.stop; - core.resumeBgm(); - } else { - this.stop = !this.stop; - core.pauseBgm(); - } - } - return; - } - - if (inRect(pos, volumebox)) { - const time = Math.min(Math.max((px - 100) / 600, 0), 1); - audio.setVolume(time); - core.plugin.audioSystem.soundPlayer.setVolume(time); - isvolume = true; - } - } - } - mousemove(px, py) { - if (isvolume) { - if (core.domStyle.isVertical) { - const time = Math.min(Math.max((px - 250) / 800, 0), 1); - audio.setVolume(time); - core.plugin.audioSystem.soundPlayer.setVolume(time); - } else { - const time = Math.min(Math.max((px - 100) / 600, 0), 1); - audio.setVolume(time); - core.plugin.audioSystem.soundPlayer.setVolume(time); - } - } - } - - drawUI() { - //绘制页面 - core.clearMap(music); - const bgVertical = core.material.images.images["bg_2010.webp"]; //竖屏背景 - const bg = core.material.images.images["bg_5043.webp"]; //竖屏背景 - if (core.domStyle.isVertical) { - //竖屏 - - core.fillRect(ctx, 0, 0, 1248, 2028, "#000000"); //黑色背景 - ctx.globalAlpha = 0.3; //透明度 - if (bgVertical) - ctx.drawImage(bgVertical, 0, 0, 1280, 1500, 0, 0, 1248, 2028); //绘制半透明背景图片 - ctx.globalAlpha = 1; //恢复为不透明 - - core.setTextAlign(ctx, "center"); - core.fillBoldText1( - ctx, - "◀离开", - 110, - 100, - "#FFFFFF", - "#000000", - 6, - core.ui._buildFont(66, true) - ); - - ctx.strokeStyle = "#FFFFFF"; - ctx.lineWidth = 3; - ctx.beginPath(); - ctx.moveTo(100, 200); - ctx.lineTo(1148, 200); - - ctx.stroke(); - let posy = 300; - const indexList = this.musicMx[page]; - core.setTextAlign(ctx, "left"); - for (let i = 0; i < indexList.length; i++) { - const text = this.musicname[indexList[i]]; - if ( - this.musics.includes(this.musicMx[page][i]) || - page !== this.musicMx.length - 1 - ) { - core.fillBoldText1( - ctx, - text, - 150, - posy - 30, - page === this.selection[0] && i === this.selection[1] - ? "#FFFFFF" - : "#444444", - "#000000", - 6, - core.ui._buildFont(66, true) - ); - - ctx.strokeStyle = "#FFFFFF"; - ctx.lineWidth = 3; - ctx.beginPath(); - ctx.moveTo(100, posy); - ctx.lineTo(1148, posy); - ctx.stroke(); - } - posy += 100; - } - ctx.beginPath(); - ctx.moveTo(100, 1210); - ctx.lineTo(1148, 1210); - ctx.moveTo(100, 1200); - ctx.lineTo(1148, 1200); - ctx.stroke(); - - core.fillBoldText1( - ctx, - "上一页", - 100, - 1300, - page === 0 ? "#444444" : "#FFFFFF", - "#000000", - 6, - core.ui._buildFont(66, true) - ); - - core.fillBoldText1( - ctx, - page + 1 + "/" + this.musicMx.length, - 580, - 1300, - "#FFFFFF", - "#000000", - 6, - core.ui._buildFont(66, true) - ); - core.fillBoldText1( - ctx, - "下一页", - 950, - 1300, - page === this.musicMx.length - 1 ? "#444444" : "#FFFFFF", - "#000000", - 6, - core.ui._buildFont(66, true) - ); - - ctx.strokeStyle = "#ffffff"; - ctx.lineWidth = 3; - - core.fillBoldText( - ctx, - "|", - 100, - 1697, - "#FFFFFF", - 6, - core.ui._buildFont(96, true) - ); - core.fillBoldText( - ctx, - "◀", - 115, - 1700, - "#FFFFFF", - 6, - core.ui._buildFont(96, true) - ); - - ctx.beginPath(); - ctx.arc(505, 1670, 80, 0, 3 * Math.PI); - ctx.stroke(); - core.fillText( - ctx, - "|", - 835, - 1697, - "#FFFFFF", - core.ui._buildFont(96, true) - ); - core.fillText( - ctx, - "▶", - 785, - 1700, - "#FFFFFF", - core.ui._buildFont(96, true) - ); - - if (this.stop) { - core.fillText( - ctx, - "▶", - 473, - 1700, - "#FFFFFF", - core.ui._buildFont(96, true) - ); - } else { - core.fillText( - ctx, - "||", - 453, - 1700, - "#FFFFFF", - core.ui._buildFont(96, true) - ); - } - - const img = core.material.images.images[this.type + ".webp"]; - if (img) ctx.drawImage(img, 1000, 1555, 200, 200); - core.setTextAlign(ctx, "center"); - ctx.font = "bold 52px Verdana"; - ctx.fillText("当前歌曲", 625, 1397); - ctx.fillText( - this.musicname[this.musicMx[this.selection[0]][this.selection[1]]], - 625, - 1507 - ); - - ctx.fillStyle = "#ffffff"; - ctx.font = "bold 48px Verdana"; - ctx.fillText("音量", 150, 1970); - ctx.lineWidth = 3; - ctx.beginPath(); - ctx.moveTo(250, 1950); - ctx.lineTo(1050, 1950); - ctx.stroke(); - ctx.strokeStyle = "#ffffff"; - ctx.lineWidth = 9; - ctx.fillStyle = "rgba(255,255,255,0.5)"; - - ctx.beginPath(); - ctx.moveTo(250, 1950); - ctx.lineTo(800 * audio.getVolume() + 250, 1950); - ctx.stroke(); - ctx.beginPath(); - ctx.arc(800 * audio.getVolume() + 250, 1950, 10, 0, 2 * Math.PI); - ctx.fill(); - core.fillBoldText1( - ctx, - Math.floor(100 * audio.getVolume()), - 1120, - 1970, - "#FFFFFF", - "#000000", - 6, - core.ui._buildFont(56, true) - ); - } else { - //横屏 - - core.fillRect(ctx, 0, 0, 2028, 1248, "#000000"); //黑色背景 - ctx.globalAlpha = 0.5; //透明度 - if (bg) ctx.drawImage(bg, 0, 0, 1280, 720, 0, 0, 2028, 1248); //绘制半透明背景图片 - ctx.globalAlpha = 1; //恢复为不透明 - core.setTextAlign(ctx, "center"); - - core.fillBoldText1( - ctx, - "◀离开", - 110, - 100, - "#FFFFFF", - "#000000", - 6, - core.ui._buildFont(66, true) - ); - - ctx.strokeStyle = "#FFFFFF"; - ctx.lineWidth = 3; - ctx.beginPath(); - ctx.moveTo(800, 100); - ctx.lineTo(800, 1148); - ctx.moveTo(900, 100); - ctx.lineTo(1900, 100); - ctx.stroke(); - let posy = 200; - const indexList = this.musicMx[page]; - core.setTextAlign(ctx, "left"); - for (let i = 0; i < indexList.length; i++) { - const text = this.musicname[indexList[i]]; - if ( - this.musics.includes(this.musicMx[page][i]) || - page !== this.musicMx.length - 1 - ) { - core.fillBoldText1( - ctx, - text, - 950, - posy - 30, - page === this.selection[0] && i === this.selection[1] - ? "#FFFFFF" - : "#444444", - "#000000", - 6, - core.ui._buildFont(66, true) - ); - - ctx.strokeStyle = "#FFFFFF"; - ctx.lineWidth = 3; - ctx.beginPath(); - ctx.moveTo(900, posy); - ctx.lineTo(1900, posy); - ctx.stroke(); - } - posy += 100; - } - core.fillBoldText1( - ctx, - "上一页", - 1050, - 1200 - 30, - page === 0 ? "#444444" : "#FFFFFF", - "#000000", - 6, - core.ui._buildFont(66, true) - ); - - core.fillBoldText1( - ctx, - page + 1 + "/" + this.musicMx.length, - 1350, - 1200 - 30, - "#FFFFFF", - "#000000", - 6, - core.ui._buildFont(66, true) - ); - core.fillBoldText1( - ctx, - "下一页", - 1550, - 1200 - 30, - page === this.musicMx.length - 1 ? "#444444" : "#FFFFFF", - "#000000", - 6, - core.ui._buildFont(66, true) - ); - ctx.strokeStyle = "#ffffff"; - ctx.lineWidth = 3; - - core.fillText( - ctx, - "|", - 55, - 697, - "#FFFFFF", - core.ui._buildFont(96, true) - ); - core.fillText( - ctx, - "◀", - 70, - 700, - "#FFFFFF", - core.ui._buildFont(96, true) - ); - - ctx.beginPath(); - ctx.arc(295, 670, 80, 0, 2 * Math.PI); - ctx.stroke(); - if (this.stop) { - core.fillText( - ctx, - "▶", - 265, - 700, - "#FFFFFF", - core.ui._buildFont(96, true) - ); - } else { - core.fillText( - ctx, - "||", - 245, - 700, - "#FFFFFF", - core.ui._buildFont(96, true) - ); - } - core.fillText( - ctx, - "|", - 495, - 697, - "#FFFFFF", - core.ui._buildFont(96, true) - ); - core.fillText( - ctx, - "▶", - 450, - 700, - "#FFFFFF", - core.ui._buildFont(96, true) - ); - - ctx.font = "bold 48px Verdana"; - ctx.fillText("音量", 350, 900); - ctx.beginPath(); - ctx.moveTo(100, 1000); - ctx.lineTo(700, 1000); - ctx.stroke(); - ctx.strokeStyle = "#ffffff"; - ctx.lineWidth = 9; - ctx.fillStyle = "rgba(255,255,255,0.5)"; - - ctx.beginPath(); - ctx.moveTo(100, 1000); - ctx.lineTo(600 * audio.getVolume() + 100, 1000); - ctx.stroke(); - ctx.beginPath(); - ctx.arc(600 * audio.getVolume() + 100, 1000, 10, 0, 2 * Math.PI); - ctx.fill(); - core.fillBoldText1( - ctx, - Math.floor(100 * audio.getVolume()), - 720, - 1010, - "#FFFFFF", - "#000000", - 6, - core.ui._buildFont(56, true) - ); - const img = core.material.images.images[this.type + ".webp"]; - if (img) ctx.drawImage(img, 580, 560, 200, 200); - core.setTextAlign(ctx, "center"); - ctx.font = "bold 48px Verdana"; - ctx.fillText("当前歌曲", 400, 297); - ctx.fillText( - this.musicname[this.musicMx[this.selection[0]][this.selection[1]]], - 400, - 397 - ); - } - } - } - core.ui.music = new musicclass(); - main.dom.musicMode.onclick = function () { - //点击开始页面的CG MODE进入cg回廊 - if ( - (core.getLocalStorage("musics") && - core.getLocalStorage("musics").length === 0) || - !core.getLocalStorage("musics") - ) - core.setLocalStorage("musics", ["theme.mp3"]); - core.ui.music.musics = core.getLocalStorage("musics"); - core.playBgm( - main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ - main.core.ui.music.selection[1] - ] - ); - - const arr = main.core.ui.music.musicMx.flat(Infinity); - main.core.ui.music.randomList = shuffle(arr); - main.core.ui.music.random = main.core.ui.music.randomList.indexOf( - main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ - main.core.ui.music.selection[1] - ] - ); - page = 0; - music.style.display = "block"; - let time = 0; - core.registerAnimationFrame("music", null, (temptime) => { - if (temptime > time + 1000 / 60) { - time = temptime; - main.core.ui.music.update(); - const duration = - core.plugin.audioSystem.bgmController.player.getRoute( - "bgms." + - main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ - main.core.ui.music.selection[1] - ] - ).duration; - - const currentTime = - core.plugin.audioSystem.bgmController.player.getRoute( - "bgms." + - main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ - main.core.ui.music.selection[1] - ] - ).currentTime; - if (currentTime && duration && duration - currentTime < 0.05) { - if (core.domStyle.isVertical) { - core.ui.music.mousedown(830, 1770); - } else { - core.ui.music.mousedown(475, 765); - } - } - } - }); - }; - }, + // 在此增加新插件 + const music = document.createElement("canvas"); + music.style.position = "absolute"; + music.style.zIndex = 300; + music.style.display = "none"; + music.id = "music"; + main.dom.gameGroup.insertAdjacentElement("afterend", music); + music.style.top = "50%"; + music.style.left = "50%"; + music.style.transform = "translate(-50%,-50%)"; + const ctx = music.getContext("2d"); + main.dom.music = music; + + const audio = core.plugin.audioSystem.bgmController; + + let page = 0; //初始页面 + + let isvolume = false; + + function shuffle(arr) { + let n = arr.length, + random; + while (n) { + random = (Math.random() * n--) >>> 0; + [arr[n], arr[random]] = [arr[random], arr[n]]; + } + return arr; + } + music.addEventListener("mousedown", function (e) { + e.stopPropagation(); + const left = core.dom.gameGroup.offsetLeft; + const top = core.dom.gameGroup.offsetTop; + const px = Math.floor((e.clientX - left) / core.domStyle.scale), + py = Math.floor((e.clientY - top) / core.domStyle.scale); + core.ui.music.mousedown(px * 3, py * 3); + }); + music.addEventListener("mousemove", function (e) { + e.stopPropagation(); + const left = core.dom.gameGroup.offsetLeft; + const top = core.dom.gameGroup.offsetTop; + const px = Math.floor((e.clientX - left) / core.domStyle.scale), + py = Math.floor((e.clientY - top) / core.domStyle.scale); + core.ui.music.mousemove(px * 3, py * 3); + }); + music.addEventListener("mouseup", function (e) { + e.stopPropagation(); + + isvolume = false; + }); + music.addEventListener("mouseleave", function (e) { + e.stopPropagation(); + + isvolume = false; + }); + music.addEventListener("touchstart", function (e) { + e.preventDefault(); + const left = core.dom.gameGroup.offsetLeft; + const top = core.dom.gameGroup.offsetTop; + const px = Math.floor( + (e.touches[0].clientX - left) / core.domStyle.scale + ), + py = Math.floor((e.touches[0].clientY - top) / core.domStyle.scale); + core.ui.music.mousedown(px * 3, py * 3); + }); + music.addEventListener("touchmove", function (e) { + e.stopPropagation(); + const left = core.dom.gameGroup.offsetLeft; + const top = core.dom.gameGroup.offsetTop; + const px = Math.floor( + (e.touches[0].clientX - left) / core.domStyle.scale + ), + py = Math.floor((e.touches[0].clientY - top) / core.domStyle.scale); + core.ui.music.mousemove(px * 3, py * 3); + }); + music.addEventListener("touchend", function (e) { + e.stopPropagation(); + + isvolume = false; + }); + music.addEventListener("touchcancel", function (e) { + e.stopPropagation(); + + isvolume = false; + }); + + class musicclass { + constructor() { + this.musics = ["theme.mp3"]; + //music列表 + //需全塔属性注册并保存在bgms文件夹,每个数组为显示的一页内容 + this.musicMx = [ + [ + "Crawler.opus", + "Blood_Stain.opus", + "Blind_Alley.opus", + "Halbmond.opus", + ], + ["theme.mp3", "op.opus", "Asphodelus_Ceui.opus", "ed.opus"], + ]; + //音乐别名(将在播放器内显示的音乐名,music列表内的都要有对应歌名) + this.musicname = { + "Asphodelus_Ceui.opus": "Asphodelus (Full.ver)", + "Blind_Alley.opus": "Blind Alley", + "Crawler.opus": "Crawler", + "op.opus": "Asphodelus", + "theme.mp3": "One of Episodes", + "ed.opus": "親愛なる世界へ", + "Blood_Stain.opus": "Blood Stain", + "Halbmond.opus": "Halbmond", + }; + this.selection = [0, 0]; + this.stop = false; + this.type = "xunhuan"; + this.randomList = []; + this.random = 0; + } + + //更新 + update() { + this.background(); + this.drawUI(); + } + background() { + //画布大小设置 + if (core.domStyle.isVertical) { + music.width = 1248; + music.height = 2028; + } else { + music.width = 2028; + music.height = 1248; + } + } + mousedown(px, py) { + //鼠标按下时 + + const makeBox = ([x, y], [w, h]) => { + return [ + [x, y], + [x + w, y + h], + ]; + }; + const inRect = ([x, y], [ + [sx, sy], + [dx, dy] + ]) => { + return sx <= x && x <= dx && sy <= y && y <= dy; + }; + const pos = [px, py]; + const backbox = makeBox([15, 35], [210, 90]); + if (inRect(pos, backbox)) { + //离开按钮是一致的,其余的记区分横竖屏 + music.style.display = "none"; + core.clearMap(ctx); + + core.unregisterAnimationFrame("music"); + core.restart(); + + return; + } + if (core.domStyle.isVertical) { + //竖屏 + + const pageupbox = makeBox([100, 1230], [200, 100]); + const pagedownbox = makeBox([950, 1230], [200, 100]); + const musicbox = makeBox( + [100, 200], + [1048, this.musicMx[page].length * 100] + ); + const beforebox = makeBox([120, 1620], [100, 100]); + const afterbox = makeBox([780, 1620], [100, 100]); + const playbox = makeBox([420, 1580], [200, 200]); + const typebox = makeBox([1040, 1600], [120, 120]); + + const volumebox = makeBox([250, 1940], [1050, 20]); + if (inRect(pos, pageupbox)) { + if (page !== 0) page -= 1; + return; + } + if (inRect(pos, pagedownbox)) { + if (page !== this.musicMx.length - 1) page += 1; + return; + } + if (inRect(pos, playbox)) { + if (this.stop) { + this.stop = !this.stop; + + core.resumeBgm(); + } else { + this.stop = !this.stop; + core.pauseBgm(); + } + return; + } + if (inRect(pos, beforebox)) { + this.stop = false; + switch (this.type) { + case "danqu": + core.playBgm( + main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ + main.core.ui.music.selection[1] + ] + ); + + page = this.selection[0]; + + break; + case "xunhuan": + for (;;) { + if (this.selection[1] === 0) { + if (this.selection[0] === 0) { + this.selection[0] = this.musicMx.length - 1; + this.selection[1] = + this.musicMx[this.selection[0]].length - 1; + } else { + this.selection[0] -= 1; + this.selection[1] = + this.musicMx[this.selection[0]].length - 1; + } + } else { + this.selection[1] -= 1; + } + this.random = this.randomList.indexOf( + this.musicMx[this.selection[0]][this.selection[1]] + ); + page = this.selection[0]; + if ( + this.musics.includes( + this.musicMx[this.selection[0]][this.selection[1]] + ) || + page !== this.musicMx.length - 1 + ) + break; + } + core.playBgm( + main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ + main.core.ui.music.selection[1] + ] + ); + + break; + case "suiji": + for (;;) { + if (this.random > 0) { + this.random -= 1; + } else { + this.random = this.randomList.length - 1; + } + this.selection[0] = this.musicMx.findIndex((v) => + v.includes(this.randomList[this.random]) + ); + this.selection[1] = this.musicMx[this.selection[0]].indexOf( + this.randomList[this.random] + ); + + page = this.selection[0]; + if ( + this.musics.includes( + this.musicMx[this.selection[0]][this.selection[1]] + ) || + page !== this.musicMx.length - 1 + ) + break; + } + core.playBgm( + main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ + main.core.ui.music.selection[1] + ] + ); + + break; + } + return; + } + if (inRect(pos, afterbox)) { + this.stop = false; + switch (this.type) { + case "danqu": + core.playBgm( + main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ + main.core.ui.music.selection[1] + ] + ); + + page = this.selection[0]; + break; + case "xunhuan": + for (;;) { + if ( + this.selection[1] === + this.musicMx[this.selection[0]].length - 1 + ) { + if (this.selection[0] === this.musicMx.length - 1) { + this.selection[0] = 0; + this.selection[1] = 0; + } else { + this.selection[0] += 1; + this.selection[1] = 0; + } + } else { + this.selection[1] += 1; + } + this.random = this.randomList.indexOf( + this.musicMx[this.selection[0]][this.selection[1]] + ); + page = this.selection[0]; + if ( + this.musics.includes( + this.musicMx[this.selection[0]][this.selection[1]] + ) || + page !== this.musicMx.length - 1 + ) + break; + } + core.playBgm( + main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ + main.core.ui.music.selection[1] + ] + ); + + break; + case "suiji": + for (;;) { + if (this.random < this.randomList.length - 1) { + this.random += 1; + } else { + this.random = 0; + } + this.selection[0] = this.musicMx.findIndex((v) => + v.includes(this.randomList[this.random]) + ); + this.selection[1] = this.musicMx[this.selection[0]].indexOf( + this.randomList[this.random] + ); + + page = this.selection[0]; + if ( + this.musics.includes( + this.musicMx[this.selection[0]][this.selection[1]] + ) || + page !== this.musicMx.length - 1 + ) + break; + } + core.playBgm( + main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ + main.core.ui.music.selection[1] + ] + ); + + break; + } + return; + } + if (inRect(pos, typebox)) { + switch (this.type) { + case "danqu": + this.type = "xunhuan"; + break; + case "xunhuan": + this.type = "suiji"; + break; + case "suiji": + this.type = "danqu"; + break; + } + return; + } + if (inRect(pos, musicbox)) { + const index = Math.floor((py - 200) / 100); + if (page !== this.selection[0] || index !== this.selection[1]) { + if ( + this.musics.includes(this.musicMx[page][index]) || + page !== this.musicMx.length - 1 + ) { + this.selection[0] = page; + + this.selection[1] = index; + this.randomList.indexOf( + this.musicMx[this.selection[0]][this.selection[1]] + ); + + core.playBgm( + main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ + main.core.ui.music.selection[1] + ] + ); + + this.stop = false; + } + } else { + if (this.stop) { + this.stop = !this.stop; + core.resumeBgm(); + } else { + this.stop = !this.stop; + core.pauseBgm(); + } + } + return; + } + + if (inRect(pos, volumebox)) { + const time = Math.min(Math.max((px - 250) / 800, 0), 1); + audio.setVolume(time); + core.plugin.audioSystem.soundPlayer.setVolume(time); + isvolume = true; + } + } else { + //横屏 + const pageupbox = makeBox([1050, 1100], [200, 100]); + const pagedownbox = makeBox([1550, 1100], [200, 100]); + const musicbox = makeBox( + [900, 100], + [1000, this.musicMx[page].length * 100] + ); + const beforebox = makeBox([60, 620], [100, 100]); + const afterbox = makeBox([450, 620], [100, 100]); + const playbox = makeBox([200, 570], [200, 200]); + const typebox = makeBox([620, 600], [120, 120]); + + const volumebox = makeBox([100, 990], [600, 20]); + if (inRect(pos, pageupbox)) { + if (page !== 0) page -= 1; + return; + } + if (inRect(pos, pagedownbox)) { + if (page !== this.musicMx.length - 1) page += 1; + return; + } + if (inRect(pos, playbox)) { + if (this.stop) { + this.stop = !this.stop; + core.resumeBgm(); + } else { + this.stop = !this.stop; + core.pauseBgm(); + } + return; + } + if (inRect(pos, beforebox)) { + this.stop = false; + switch (this.type) { + case "danqu": + core.playBgm( + main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ + main.core.ui.music.selection[1] + ] + ); + + page = this.selection[0]; + + break; + case "xunhuan": + for (;;) { + if (this.selection[1] === 0) { + if (this.selection[0] === 0) { + this.selection[0] = this.musicMx.length - 1; + this.selection[1] = + this.musicMx[this.selection[0]].length - 1; + } else { + this.selection[0] -= 1; + this.selection[1] = + this.musicMx[this.selection[0]].length - 1; + } + } else { + this.selection[1] -= 1; + } + this.random = this.randomList.indexOf( + this.musicMx[this.selection[0]][this.selection[1]] + ); + page = this.selection[0]; + + if ( + this.musics.includes( + this.musicMx[this.selection[0]][this.selection[1]] + ) || + page !== this.musicMx.length - 1 + ) + break; + } + core.playBgm( + main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ + main.core.ui.music.selection[1] + ] + ); + + break; + case "suiji": + for (;;) { + if (this.random > 0) { + this.random -= 1; + } else { + this.random = this.randomList.length - 1; + } + this.selection[0] = this.musicMx.findIndex((v) => + v.includes(this.randomList[this.random]) + ); + this.selection[1] = this.musicMx[this.selection[0]].indexOf( + this.randomList[this.random] + ); + + page = this.selection[0]; + + if ( + this.musics.includes( + this.musicMx[this.selection[0]][this.selection[1]] + ) || + page !== this.musicMx.length - 1 + ) + break; + } + core.playBgm( + main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ + main.core.ui.music.selection[1] + ] + ); + + break; + } + return; + } + if (inRect(pos, afterbox)) { + this.stop = false; + switch (this.type) { + case "danqu": + core.playBgm( + main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ + main.core.ui.music.selection[1] + ] + ); + + page = this.selection[0]; + break; + case "xunhuan": + for (;;) { + if ( + this.selection[1] === + this.musicMx[this.selection[0]].length - 1 + ) { + if (this.selection[0] === this.musicMx.length - 1) { + this.selection[0] = 0; + this.selection[1] = 0; + } else { + this.selection[0] += 1; + this.selection[1] = 0; + } + } else { + this.selection[1] += 1; + } + this.randomList.findIndex( + (v) => + v === this.musicMx[this.selection[0]][this.selection[1]] + ); + page = this.selection[0]; + + if ( + this.musics.includes( + this.musicMx[this.selection[0]][this.selection[1]] + ) || + page !== this.musicMx.length - 1 + ) + break; + } + core.playBgm( + main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ + main.core.ui.music.selection[1] + ] + ); + + break; + case "suiji": + for (;;) { + if (this.random < this.randomList.length - 1) { + this.random += 1; + } else { + this.random = 0; + } + this.selection[0] = this.musicMx.findIndex((v) => + v.includes(this.randomList[this.random]) + ); + this.selection[1] = this.musicMx[this.selection[0]].indexOf( + main.core.ui.music.randomList[main.core.ui.music.random] + ); + + page = this.selection[0]; + if ( + this.musics.includes( + this.musicMx[this.selection[0]][this.selection[1]] + ) || + page !== this.musicMx.length - 1 + ) + break; + } + core.playBgm( + main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ + main.core.ui.music.selection[1] + ] + ); + + break; + } + return; + } + if (inRect(pos, typebox)) { + switch (this.type) { + case "danqu": + this.type = "xunhuan"; + break; + case "xunhuan": + this.type = "suiji"; + break; + case "suiji": + this.type = "danqu"; + break; + } + return; + } + if (inRect(pos, musicbox)) { + const index = Math.floor((py - 100) / 100); + if (page !== this.selection[0] || index !== this.selection[1]) { + if ( + this.musics.includes(this.musicMx[page][index]) || + page !== this.musicMx.length - 1 + ) { + this.selection[0] = page; + this.selection[1] = index; + this.randomList.indexOf( + (v) => + v === this.musicMx[this.selection[0]][this.selection[1]] + ); + + core.playBgm( + main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ + main.core.ui.music.selection[1] + ] + ); + this.stop = false; + } + } else { + if (this.stop) { + this.stop = !this.stop; + core.resumeBgm(); + } else { + this.stop = !this.stop; + core.pauseBgm(); + } + } + return; + } + + if (inRect(pos, volumebox)) { + const time = Math.min(Math.max((px - 100) / 600, 0), 1); + audio.setVolume(time); + core.plugin.audioSystem.soundPlayer.setVolume(time); + isvolume = true; + } + } + } + mousemove(px, py) { + if (isvolume) { + if (core.domStyle.isVertical) { + const time = Math.min(Math.max((px - 250) / 800, 0), 1); + audio.setVolume(time); + core.plugin.audioSystem.soundPlayer.setVolume(time); + } else { + const time = Math.min(Math.max((px - 100) / 600, 0), 1); + audio.setVolume(time); + core.plugin.audioSystem.soundPlayer.setVolume(time); + } + } + } + + drawUI() { + //绘制页面 + core.clearMap(music); + const bgVertical = core.material.images.images["bg_2010.webp"]; //竖屏背景 + const bg = core.material.images.images["bg_5043.webp"]; //竖屏背景 + if (core.domStyle.isVertical) { + //竖屏 + + core.fillRect(ctx, 0, 0, 1248, 2028, "#000000"); //黑色背景 + ctx.globalAlpha = 0.3; //透明度 + if (bgVertical) + ctx.drawImage(bgVertical, 0, 0, 1280, 1500, 0, 0, 1248, 2028); //绘制半透明背景图片 + ctx.globalAlpha = 1; //恢复为不透明 + + core.setTextAlign(ctx, "center"); + core.fillBoldText1( + ctx, + "◀离开", + 110, + 100, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(66, true) + ); + + ctx.strokeStyle = "#FFFFFF"; + ctx.lineWidth = 3; + ctx.beginPath(); + ctx.moveTo(100, 200); + ctx.lineTo(1148, 200); + + ctx.stroke(); + let posy = 300; + const indexList = this.musicMx[page]; + core.setTextAlign(ctx, "left"); + for (let i = 0; i < indexList.length; i++) { + const text = this.musicname[indexList[i]]; + if ( + this.musics.includes(this.musicMx[page][i]) || + page !== this.musicMx.length - 1 + ) { + core.fillBoldText1( + ctx, + text, + 150, + posy - 30, + page === this.selection[0] && i === this.selection[1] ? + "#FFFFFF" : + "#444444", + "#000000", + 6, + core.ui._buildFont(66, true) + ); + + ctx.strokeStyle = "#FFFFFF"; + ctx.lineWidth = 3; + ctx.beginPath(); + ctx.moveTo(100, posy); + ctx.lineTo(1148, posy); + ctx.stroke(); + } + posy += 100; + } + ctx.beginPath(); + ctx.moveTo(100, 1210); + ctx.lineTo(1148, 1210); + ctx.moveTo(100, 1200); + ctx.lineTo(1148, 1200); + ctx.stroke(); + + core.fillBoldText1( + ctx, + "上一页", + 100, + 1300, + page === 0 ? "#444444" : "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(66, true) + ); + + core.fillBoldText1( + ctx, + page + 1 + "/" + this.musicMx.length, + 580, + 1300, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(66, true) + ); + core.fillBoldText1( + ctx, + "下一页", + 950, + 1300, + page === this.musicMx.length - 1 ? "#444444" : "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(66, true) + ); + + ctx.strokeStyle = "#ffffff"; + ctx.lineWidth = 3; + + core.fillBoldText( + ctx, + "|", + 100, + 1697, + "#FFFFFF", + 6, + core.ui._buildFont(96, true) + ); + core.fillBoldText( + ctx, + "◀", + 115, + 1700, + "#FFFFFF", + 6, + core.ui._buildFont(96, true) + ); + + ctx.beginPath(); + ctx.arc(505, 1670, 80, 0, 3 * Math.PI); + ctx.stroke(); + core.fillText( + ctx, + "|", + 835, + 1697, + "#FFFFFF", + core.ui._buildFont(96, true) + ); + core.fillText( + ctx, + "▶", + 785, + 1700, + "#FFFFFF", + core.ui._buildFont(96, true) + ); + + if (this.stop) { + core.fillText( + ctx, + "▶", + 473, + 1700, + "#FFFFFF", + core.ui._buildFont(96, true) + ); + } else { + core.fillText( + ctx, + "||", + 453, + 1700, + "#FFFFFF", + core.ui._buildFont(96, true) + ); + } + + const img = core.material.images.images[this.type + ".webp"]; + if (img) ctx.drawImage(img, 1000, 1555, 200, 200); + core.setTextAlign(ctx, "center"); + ctx.font = "bold 52px Verdana"; + ctx.fillText("当前歌曲", 625, 1397); + ctx.fillText( + this.musicname[this.musicMx[this.selection[0]][this.selection[1]]], + 625, + 1507 + ); + + ctx.fillStyle = "#ffffff"; + ctx.font = "bold 48px Verdana"; + ctx.fillText("音量", 150, 1970); + ctx.lineWidth = 3; + ctx.beginPath(); + ctx.moveTo(250, 1950); + ctx.lineTo(1050, 1950); + ctx.stroke(); + ctx.strokeStyle = "#ffffff"; + ctx.lineWidth = 9; + ctx.fillStyle = "rgba(255,255,255,0.5)"; + + ctx.beginPath(); + ctx.moveTo(250, 1950); + ctx.lineTo(800 * audio.getVolume() + 250, 1950); + ctx.stroke(); + ctx.beginPath(); + ctx.arc(800 * audio.getVolume() + 250, 1950, 10, 0, 2 * Math.PI); + ctx.fill(); + core.fillBoldText1( + ctx, + Math.floor(100 * audio.getVolume()), + 1120, + 1970, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(56, true) + ); + } else { + //横屏 + + core.fillRect(ctx, 0, 0, 2028, 1248, "#000000"); //黑色背景 + ctx.globalAlpha = 0.5; //透明度 + if (bg) ctx.drawImage(bg, 0, 0, 1280, 720, 0, 0, 2028, 1248); //绘制半透明背景图片 + ctx.globalAlpha = 1; //恢复为不透明 + core.setTextAlign(ctx, "center"); + + core.fillBoldText1( + ctx, + "◀离开", + 110, + 100, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(66, true) + ); + + ctx.strokeStyle = "#FFFFFF"; + ctx.lineWidth = 3; + ctx.beginPath(); + ctx.moveTo(800, 100); + ctx.lineTo(800, 1148); + ctx.moveTo(900, 100); + ctx.lineTo(1900, 100); + ctx.stroke(); + let posy = 200; + const indexList = this.musicMx[page]; + core.setTextAlign(ctx, "left"); + for (let i = 0; i < indexList.length; i++) { + const text = this.musicname[indexList[i]]; + if ( + this.musics.includes(this.musicMx[page][i]) || + page !== this.musicMx.length - 1 + ) { + core.fillBoldText1( + ctx, + text, + 950, + posy - 30, + page === this.selection[0] && i === this.selection[1] ? + "#FFFFFF" : + "#444444", + "#000000", + 6, + core.ui._buildFont(66, true) + ); + + ctx.strokeStyle = "#FFFFFF"; + ctx.lineWidth = 3; + ctx.beginPath(); + ctx.moveTo(900, posy); + ctx.lineTo(1900, posy); + ctx.stroke(); + } + posy += 100; + } + core.fillBoldText1( + ctx, + "上一页", + 1050, + 1200 - 30, + page === 0 ? "#444444" : "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(66, true) + ); + + core.fillBoldText1( + ctx, + page + 1 + "/" + this.musicMx.length, + 1350, + 1200 - 30, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(66, true) + ); + core.fillBoldText1( + ctx, + "下一页", + 1550, + 1200 - 30, + page === this.musicMx.length - 1 ? "#444444" : "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(66, true) + ); + ctx.strokeStyle = "#ffffff"; + ctx.lineWidth = 3; + + core.fillText( + ctx, + "|", + 55, + 697, + "#FFFFFF", + core.ui._buildFont(96, true) + ); + core.fillText( + ctx, + "◀", + 70, + 700, + "#FFFFFF", + core.ui._buildFont(96, true) + ); + + ctx.beginPath(); + ctx.arc(295, 670, 80, 0, 2 * Math.PI); + ctx.stroke(); + if (this.stop) { + core.fillText( + ctx, + "▶", + 265, + 700, + "#FFFFFF", + core.ui._buildFont(96, true) + ); + } else { + core.fillText( + ctx, + "||", + 245, + 700, + "#FFFFFF", + core.ui._buildFont(96, true) + ); + } + core.fillText( + ctx, + "|", + 495, + 697, + "#FFFFFF", + core.ui._buildFont(96, true) + ); + core.fillText( + ctx, + "▶", + 450, + 700, + "#FFFFFF", + core.ui._buildFont(96, true) + ); + + ctx.font = "bold 48px Verdana"; + ctx.fillText("音量", 350, 900); + ctx.beginPath(); + ctx.moveTo(100, 1000); + ctx.lineTo(700, 1000); + ctx.stroke(); + ctx.strokeStyle = "#ffffff"; + ctx.lineWidth = 9; + ctx.fillStyle = "rgba(255,255,255,0.5)"; + + ctx.beginPath(); + ctx.moveTo(100, 1000); + ctx.lineTo(600 * audio.getVolume() + 100, 1000); + ctx.stroke(); + ctx.beginPath(); + ctx.arc(600 * audio.getVolume() + 100, 1000, 10, 0, 2 * Math.PI); + ctx.fill(); + core.fillBoldText1( + ctx, + Math.floor(100 * audio.getVolume()), + 720, + 1010, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(56, true) + ); + const img = core.material.images.images[this.type + ".webp"]; + if (img) ctx.drawImage(img, 580, 560, 200, 200); + core.setTextAlign(ctx, "center"); + ctx.font = "bold 48px Verdana"; + ctx.fillText("当前歌曲", 400, 297); + ctx.fillText( + this.musicname[this.musicMx[this.selection[0]][this.selection[1]]], + 400, + 397 + ); + } + } + } + core.ui.music = new musicclass(); + main.dom.musicMode.onclick = function () { + //点击开始页面的CG MODE进入cg回廊 + if ( + (core.getLocalStorage("musics") && + core.getLocalStorage("musics").length === 0) || + !core.getLocalStorage("musics") + ) + core.setLocalStorage("musics", ["theme.mp3"]); + core.ui.music.musics = core.getLocalStorage("musics"); + core.playBgm( + main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ + main.core.ui.music.selection[1] + ] + ); + + const arr = main.core.ui.music.musicMx.flat(Infinity); + main.core.ui.music.randomList = shuffle(arr); + main.core.ui.music.random = main.core.ui.music.randomList.indexOf( + main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ + main.core.ui.music.selection[1] + ] + ); + page = 0; + music.style.display = "block"; + let time = 0; + core.registerAnimationFrame("music", null, (temptime) => { + if (temptime > time + 1000 / 60) { + time = temptime; + main.core.ui.music.update(); + const duration = + core.plugin.audioSystem.bgmController.player.getRoute( + "bgms." + + main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ + main.core.ui.music.selection[1] + ] + ).duration; + + const currentTime = + core.plugin.audioSystem.bgmController.player.getRoute( + "bgms." + + main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ + main.core.ui.music.selection[1] + ] + ).currentTime; + if (currentTime && duration && duration - currentTime < 0.05) { + if (core.domStyle.isVertical) { + core.ui.music.mousedown(830, 1770); + } else { + core.ui.music.mousedown(475, 765); + } + } + } + }); + }; +}, "横屏切换": function () { // 在此增加新插件 this.triggerFullscreen = async function (full) { @@ -17876,7 +18261,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = data.soundList.forEach(function (sound) { const lisen = sound.sound && - core.material.sounds[sound.sound] && + core.sounds[sound.sound] && core.musicStatus.soundStatus; if (one.farme == sound.startfarme && lisen) { if (sound.stopbefore) core.stopSound(); @@ -18379,5 +18764,489 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = } }); }; - } + }, + "剧情内容": function () { + // 在此增加新插件 + // 每项为一个数组,第一项是名字,第二项是对话内容 + // 回放只会在同一个this下回放,进入剧情前请以事件块声明进入哪个剧情数组 + // 可以自由添加,但不能与已有插件及函数名相同,可以使用中文。 + this.chapter0 = [ + ['', '这些天,街道不曾下雨。'], + ['', '所以,那浸湿地面的,定是那些女孩们流落的鲜血无疑。'], + ['', '我蹲在充斥着铁锈味般恶臭的小巷中,悠闲地如是想着。'], + ['', '扑哧。'], + ['', '耳旁再次响起象征着某个女孩子死去的声音。'], + ['', '再一次——'], + ['', '再一次。'], + ['', '女子们被肢解成单纯的肉块。'], + ['', '我任由流下的血浸满全身,屏住自己的呼吸。'], + ['', '祈求自己能拥有从猎人手中逃脱的幸运。'], + ['', '扑哧。'], + ['', '直到刚才,我们还坐在去往娼馆的马车的路上。'], + ['', '而在这之中的某些人,已经不在这个世上了。'], + ['', '不,应该把“某些”换成“几乎所有”才更为恰当吧。'], + ['', '恐怕,不久之后我也会变成小巷中血腥的装饰品。'], + ['', '我是为了得到这种死法,才辛苦苟活至今的吗?'], + ['', '来个人告诉我啊——'], + ['', '谁都好。'], + ['', '来人啊!!'], + ['少女', '「呃······!?」'], + ['', '漆黑的物体充斥了我的整个视野'], + ['', '我很快意识到,那是只很大的脚。'], + ['', '必须要出声求救。'], + ['', '可是,耳中却只能听到自己的牙关不停交战的声音。'], + ['', '我是如此的无助。'], + ['', '逃跑也好,道歉也罢。'], + ['', '就连抬头看一眼将要杀掉我的人的面孔都做不到。'], + ['少女', '「······被杀」'], + ['', '会被杀。'], + ['', '会被杀!!'], + ['', '来自内心深处的冰冷预感,渐渐地在体内蔓延开来。'], + ['少女', '「不,不要······」'], + ['', '浮游都市,《诺瓦斯·艾蒂尔》。'], + ['', '《特别受灾地区》——'], + ['', '通称,《牢狱》'], + ['', '是被险峻的峭壁环绕,与世隔绝的,都市的最底部。'], + ['年轻人', '「放开我!」'], + ['年轻人', '「我只是在帮那个女人而已!」'], + ['年轻人', '「你们没听到吗!?」'], + ['年轻人', '「她是被受骗才会被卖到娼馆来的」'], + ['年轻人', '「用肮脏的手段把钱借给她父母的,就是你们这些家伙吧!?」'], + ['年轻人', '「给我说些什么啊」'], + ['凯伊姆', '「这些话等到了娼馆再说吧」'], + ['凯伊姆', '「我来抓你,只是受雇于人而已」'], + ['', '我走进娼馆《莉莉乌姆》的接待室。'], + ['', '正在桌旁整理账簿的奥兹停下手头的工作,抬起头向我看来。'], + ['奥兹', '「这不是凯伊姆先生吗,辛苦了」'], + ['奥兹', '「委托已经完成了吗?」'], + ['凯伊姆', '「啊啊,是这家伙没错吧」'], + ['', '奥兹用只要接触到就能杀人般的眼神在男人脸上搜过。'], + ['奥兹', '「没错,就是这个人」'], + ['凯伊姆', '「是么」'], + ['年轻人', '「你,你们要对我做什么」'], + ['奥兹', '「······」'], + ['', '奥兹用一个眼神,就让男人闭上了嘴。'], + ['', '然后,向我这边转过身来。'], + ['奥兹', '「抱歉啊,总是麻烦你去做这些无聊的事」'], + ['奥兹', '「都怪我们这边的年轻人太没用」'], + ['凯伊姆', '「客套话就免了」'], + ['奥兹', '「这还真是失礼了」'], + ['奥兹', '「喂,来个人」'], + ['光头男人', '「是」'], + ['奥兹', '「凯伊姆先生做完工作回来了」'], + ['光头男人', '「是,是,那个······」'], + ['奥兹', '「我是要你拿些酒来,这个蠢材!」'], + ['', '喀!'], + ['', '奥兹扔出的烟灰缸砸中了手下的额头。'], + ['', '鲜血四溅。'], + ['凯伊姆', '「不用这么麻烦」'], + ['凯伊姆', '「我接下来要去《菲诺列塔》」'], + ['奥兹', '「喔唷」'], + ['奥兹', '「既然如此,我就不留您在这里喝难饮的劣质酒了」'], + ['', '奥兹斜眼看着正捂住额头呻吟的手下,轻描淡写地说道。'], + ['凯伊姆', '「用这些钱去买药」'], + ['', '我将几枚铜钱仍在那个手下的身前。'], + ['奥兹', '「凯伊姆先生,不用对他们这么好」'], + ['凯伊姆', '「无妨」'], + ['凯伊姆', '「话说回来,那个要落跑的女人呢?」'], + ['奥兹', '「我把她交给那些年轻人了,现在应该正在体会人生的严苛吧」'], + ['奥兹', '「正好,趁此机会凯伊姆先生也来享受一番如何?」'], + ['年轻人', '「你,你们这些家伙,要对她做什么!?」'], + ['', '咣!'], + ['', '奥兹给了他一拳。'], + ['', '一击即倒。'], + ['', '喀,咚,咯!'], + ['', '奥兹毫不留情地向男人的脸上踩去。'], + ['年轻人', '「咕······呃咳······」'], + ['', '折断的牙齿伴着血泡被吐出。'], + ['', '这份白色在鲜红色的液体中格外显眼。'], + ['年轻人', '「你们以为做出这种事······卫兵会坐视不理吗······」'], + ['奥兹', '「啊啊,不会坐视不理的」'], + ['奥兹', '「应该会拿出你的钱包,和我们商量如何瓜分吧」'], + ['年轻人', '「那,那种事······」'], + ['', '这在牢狱是理所当然的事。'], + ['奥兹', '「怎么,头一回来牢狱么?」'], + ['', '男人点了点头。'], + ['奥兹', '「为了被骗的女人而来到牢狱,真是个规矩人啊」'], + ['奥兹', '「······前提是,被骗的人不是你」'], + ['年轻人', '「你说······我被骗了?」'], + ['年轻人', '「那,那是怎么回事!?」'], + ['奥兹', '「不用急,今天晚上会好好告诉你的」'], + ['', '奥兹抓起男人的脸。'], + ['', '为引诱客人的怜悯之心而装纯,是娼妇的惯用手段。'], + ['', '双亲被骗而借钱,结果作为抵押而将自己卖到这里,这是典型的说法。'], + ['', '如果只是头脑发热而成为常客也就罢了,这次的男人热血过头,居然想出了要带女人私奔的计划。'], + ['', '虽然女人半开玩笑地予以拒绝,但不知天高地厚的这家伙还是拉着她逃跑了。'], + ['', '不过,想要逃脱追击本来就是不可能的任务。'], + ['', '但即便如此,这种事情还是会一再的出现。'], + ['', '说谎的女人和被骗的男人。'], + ['', '在娼馆街,这是令人看到生厌的日常的风景。'], + ['凯伊姆', '「我要走了」'], + ['奥兹', '「好的,下次再麻烦您」'], + ['奥兹', '「之后吉克先生会将谢礼交给您的」'], + ['凯伊姆', '「啊啊」'], + ['', '我背向奥兹走出娼馆。'], + ['凯伊姆', '「······?」'], + ['', '从远方传来微弱的歌声。'], + ['', '是关卡广场的方向。'], + ['', '对了。'], + ['', '今天有觐见圣女的仪式。'], + ['', '当代的圣女伊莲——'], + ['', '俗称《盲眼之圣女》,据说即使在历代的圣女中,人气也是数一数二的。'], + ['', '广场上的人估计相当多吧。'], + ['', '虽然我也想去看看她长什么样,不过要在人潮中挤来挤去就免了。'], + ['', '还是老老实实去菲诺列塔喝烧酒吧。'], + ['', '正当我这样想着的时候,一个身影自小巷的那头走来。'], + ['凯伊姆', '「艾莉斯」'] + ] + this.chapter01 = [ + ['艾莉斯', '「啊,凯伊姆」'], + ['艾莉斯', '「正好,我还想要去找你呢」'], + ['艾莉斯', '「没想到凯伊姆会主动出现······这是命运吗?」'], + ['凯伊姆', '「显然不是吧」'], + ['艾莉斯', '「啊,是么」'], + ['', '艾莉斯挑了挑整齐的双眉,微微地哼了一声。'], + ['', '虽然是个相当引人注目的美人,但她这个将亲切儿子丢入无底深渊的性格,为自己扣了不少的分'], + ['', '给人印象最深的,就是那潭水般的双瞳。'], + ['', '在漆黑的瞳孔中,完全看不出感情的波动。'], + ['艾莉斯', '「喜欢我的眼睛吗?」'], + ['艾莉斯', '「如果想要的话就给你吧?」'], + ['凯伊姆', '「用不着」'], + ['艾莉斯', '「阿拉,可惜」'], + ['凯伊姆', '「那么,找我有什么事」'], + ['艾莉斯', '「梅尔特的钱好像被偷了」'], + ['凯伊姆', '「钱被偷了?都几岁了还这么没用」'], + ['艾莉斯', '「不要对我说啊」'], + ['凯伊姆', '「那家伙,该不会说要让我去抓那个小偷吧?」'], + ['艾莉斯', '「就是这样」'], + ['凯伊姆', '「笨蛋吗」'], + ['凯伊姆', '「如果是小钱的话,就当做是买个教训吧」'], + ['艾莉斯', '「说起来,被盗的是这个月的上纳金」'], + ['凯伊姆', '「你说什么?」'], + ['艾莉斯', '「用这些钱买教训,也太过奢侈了呢」'], + ['凯伊姆', '「知道了,我去找」'], + ['凯伊姆', '「小偷的特征呢」'], + ['艾莉斯', '「男孩子」'], + ['艾莉斯', '「······而且,背后有翅膀」'], + ['艾莉斯', '「虽然姑且是藏在身后,但是仔细观察的话是很明显的」'], + ['凯伊姆', '「羽化病吗」'], + ['艾莉斯', '「那些人可是毫不留情的,所以即使是为了那个孩子,也要赶快抓到他」'], + ['凯伊姆', '「注意到他逃窜的方向了吗?」'], + ['艾莉斯', '「广场那边」'], + ['艾莉斯', '「虽然刚才《不蚀金锁》的人去追了,不过多半是······」'], + ['凯伊姆', '「偏偏还是广场吗」'], + ['艾莉斯', '「今天是觐见圣女大人的日子」'], + ['凯伊姆', '「我知道」'], + ['凯伊姆', '「尽量找找看就好」'] + ] + this.chapter02 = [ + ['不蚀金锁成员', '「凯伊姆先生,凯伊姆先生」'], + ['不蚀金锁成员', '「您已经和艾莉斯大夫见过面了吗?」'], + ['凯伊姆', '「啊啊,所以才会追过来的」'], + ['凯伊姆', '「看到小偷了吗?」'], + ['不蚀金锁成员', '「没有,他向广场那边逃了过去,今天这么拥挤,我们也只能放弃了」'], + ['不蚀金锁成员', '「不过,我也只是刚好在店里所以才追了过去,并不是受人所托」'], + ['不蚀金锁成员', '「我已经准备撤退了」'], + ['不蚀金锁成员', '「凯伊姆先生还要继续追吗?」'], + ['凯伊姆', '「啊啊」'], + ['', '做完情报交换之后,我跟男人道别。'], + ['凯伊姆', '「和我想的一样啊······」'], + ['', '在牢狱中最大的广场上,聚集着看不到尽头的人群。'], + ['', '就算是来参见圣女祈祷,这人数也太多了点吧。'], + ['', '自然,我也找不到逃跑的孩子。'], + ['', '是混杂到人群中了吧。'], + ['', '如果已经从广场上脱身了的话,就更难发现了。'], + ['', '只好赌他还在这里了。'], + ['', '我先移动到了一个视野良好的地方。'], + ['', '从这里,一眼就可以看到人群的变化。'], + ['', '广场还是沸腾起来。'], + ['', '抬头望去,原来是在天台之上出现了一个人影'], + ['', '但是,与周围的期待不同,现身的是一名中年的神官。'], + ['', '骂声四溢。'], + ['', '神官则是笑着摆正衣领'], + ['神官', '「从现在开始,举行谒见的仪式」'], + ['神官', '「在参见那位大人之前,我希望牢狱的诸位再次思考这个《诺瓦斯·艾蒂尔》存在的意义······」'], + ['神官', '「初代圣女伊莲大人,便是也难怪这崇高的祈祷之力,令《诺瓦斯·艾蒂尔》浮在空中,拯救了我们的祖先」'], + ['神官', '「这之后的几百年来,传承了初代大人力量的历代圣女伊莲大人,让这里留在了空中」'], + ['神官', '「这座都市是被圣女大人守护的人类最后的圣域,而我们则是被选召的虔诚的信徒」'], + ['神官', '「怀着对圣女的感激祈祷吧,感谢圣女伊莲吧!并献上祈祷!」'], + ['圣女', '「不忘感谢与祈祷,神才会拯救我们」'], + ['圣女', '「与我一起,向神虔诚地祈祷吧」'], + ['', '广场上欢声雷动。'], + ['', '圣女没有回应喧嚣的人声,而是静静地合上双眼面向广场。'], + ['', '虽然感觉有些冷淡,但总比像个傻瓜似的笑着向这群人挥手要强。'], + ['', '她掌握着这条街道,还有在这条街上生活的人的命运。'], + ['', '比起揽得人气,她更想要为了街道的继续存在而献出全力。'], + ['', '也是为了不让《大崩落》的惨剧再度发生。'], + ['', '十几年前的那场悲剧。'], + ['', '虽然在我脑海中的记忆已经相当模糊,但哪怕只是稍有触及,不快的感觉都会在胸口蔓延开。'], + ['凯伊姆', '「······」'], + ['', '这时我才想起,现在不是我在这里看圣女的时候。'], + ['女声', '「——っ!?」'], + ['围观的女人', '「羽,羽化病人!?」'], + ['围观的中年人', '「喂,谁去叫下羽狩」'], + ['惊慌的观众', '「你这家伙不要靠近我,要是传染了可怎么办」'], + ['粗鲁的观众', '「你这小鬼赶快滚开」'], + ['凯伊姆', '「接下来」'], + ['圣女', '「发生什么事了?看上去似乎很嘈杂」'], + ['随从', '「似乎是某个人逃跑了······具体的我也不是很清楚」'], + ['神官', '「圣女大人,继续待在天台上可能会出事,请您先回到室内吧」'], + ['圣女', '「不用在意我,比起那个,我更关心究竟发生了什么事」'], + ['神官', '「对不起,我真的不知道」'], + ['圣女', '「······是吗」'], + ['男', '「恕我僭越,请准许我说明情况」'], + ['男', '「在来觐见的人群中出现了《羽化病》的患者」'], + ['男', '「围观的人群因而产生了骚动」'], + ['男', '「现在,《防疫局》已经派遣了部队。我想不久之后,他们就会安静下来了」'], + ['圣女', '「羽化病······」'], + ['男', '「怎么了?」'], + ['圣女', '「没什么」'], + ['圣女', '「辛苦了,你的名字是?」'], + ['男', '「属下是在防疫局任职的,鲁基乌斯· 迪斯·米利尤」'], + ['神官', '「噢噢,阁下就是鲁基乌斯卿吗,我听说过你的传闻」'], + ['神官', '「阁下是在工作上相当出色的人呢」'], + ['鲁基乌斯', '「不敢当」'], + ['鲁基乌斯', '「话说回来,这次是属下警备工作的失职。让圣女大人见到这不成体统的一面,请您见谅」'], + ['圣女', '「即使是目不见物的我,也能感受到聚集于此的民众数量之多。警备工作难以展开也在情理之中」'], + ['鲁基乌斯', '「属下不胜惶恐」'], + ['鲁基乌斯', '「接下来属下还要回到工作岗位上,在这里就先告退了」'], + ['圣女', '「鲁基乌斯先生」'], + ['鲁基乌斯', '「属下在」'], + ['圣女', '「你是怎样看待羽狩的工作的呢?」'], + ['神官', '「圣,圣女大人」'], + ['鲁基乌斯', '「防疫局的工作是国王陛下赐予的重要职务。属下非常荣幸能够为这个都市的繁荣尽一份微薄之力」'], + ['神官', '「不,不亏是鲁基乌斯卿,相当优秀的想法」'], + ['圣女', '「是吗。辛苦你了」'], + ['随从', '「圣女大人······」'], + ['鲁基乌斯', '「······」'], + ['鲁基乌斯', '「那么,属下就回岗位去了」'] + ] + this.chapter03 = [ + ['', '从羽化病的少年纷乱的足音中,可以听得出相当的疲劳。'], + ['', '显然,他并没有想到我会捷足先登吧。'], + ['', '少年惶恐地回头看了一眼后,微微露出安心的表情,双手拄在膝盖上。。'], + ['凯伊姆', '「辛苦你了」'], + ['羽化病患少年', '「稀!?」'], + ['凯伊姆', '「逃到贫民区是个不错的想法」'], + ['羽化病患少年', '「你,你是,羽狩吗?」'], + ['凯伊姆', '「不是」'], + ['羽化病患少年', '「什,什么啊······混蛋,不要吓我啊」'], + ['凯伊姆', '「我对令你受惊这件事致以歉意」'], + ['凯伊姆', '「作为回报,麻烦你把从店里偷的钱交出来吧」'], + ['羽化病患少年', '「钱?你在说什么」'], + ['凯伊姆', '「你要找的腰上的东西,掉在你身后了」'], + ['羽化病患少年', '「哎?」'], + ['羽化病患少年', '「呃呀」'], + ['羽化病患少年', '「你······你这混蛋」'], + ['凯伊姆', '「······」'], + ['凯伊姆', '「把偷的钱交出来」'], + ['羽化病患少年', '「我不知道你在······咕」'], + ['羽化病患少年', '「你,你说是我偷的······有什么证据吗」'], + ['凯伊姆', '「你还挺倔的啊」'], + ['凯伊姆', '「不过,给我听好了」'], + ['凯伊姆', '「你偷的那些钱,是要上缴给《不蚀金锁》的上纳金」'], + ['凯伊姆', '「而且,钱的主人是从前和吉克颇有渊源的女人」'], + ['羽化病患少年', '「吉克?」'], + ['凯伊姆', '「他是《不蚀金锁》的主人,这么说你就明白了吧」'], + ['羽化病患少年', '「哎?哎?怎么会······」'], + ['凯伊姆', '「再问你一遍,钱在哪里?」'], + ['羽化病患少年', '「是,是,是,在我的怀里」'], + ['凯伊姆', '「你没有擅自拿掉一部分吧」'], + ['羽化病患少年', '「是,是的」'], + ['羽化病患少年', '「那,那个,您是《不蚀金锁》的人吗?」'], + ['凯伊姆', '「算是吧」'], + ['羽化病患少年', '「我什么都可以做,请您一定要帮帮我」'], + ['凯伊姆', '「抱歉,我并没有兴趣去帮助他人」'], + ['羽化病患少年', '「我什么······什么,都会做的······」'], + ['羽化病患少年', '「我一直都是生活在下层的」'], + ['羽化病患少年', '「可是,不知何时染上了羽化病······背后长出了翅膀······」'], + ['羽化病患少年', '「被寄宿工作的店赶了出来,只得流落到牢狱这里」'], + ['羽化病患少年', '「因为独自实在是饿的不行了,所以才会偷这些钱的」'], + ['羽化病患少年', '「我明明没有做任何坏事······为什么······会遇到这种事······」'], + ['凯伊姆', '「谁知道」'], + ['羽化病患少年', '「呜······呜呜······接下来,要对我做什么?」'], + ['凯伊姆', '「我要把你带到组织那里」'], + ['羽化病患少年', '「怎,怎么这样」'], + ['凯伊姆', '「不过,那样做的前提是你不是羽化病人」'], + ['凯伊姆', '「组织也没有笨到把羽化病人招待到家里的程度」'], + ['羽化病患少年', '「那么,是要放我逃走吗?」'], + ['凯伊姆', '「我要让你学到教训」'], + ['凯伊姆', '「如果换做是组织的制裁,至少要有断条胳膊的觉悟」'], + ['凯伊姆', '「你的运气不错」'], + ['羽化病患少年', '「唔······啊,是的······」'], + ['凯伊姆', '「滚」'], + ['羽化病患少年', '「非常感谢」'], + ['羽化病患少年', '「唔啊!?」'], + ['男', '「到这里就结束了,羽化病人」'], + ['男', '「确认他的翅膀」'], + ['', '趁还没有被卷入麻烦的事情之前,赶快离开这里吧'], + ['羽狩的队长', '「那边的那个人」'], + ['凯伊姆', '「······有什么事?」'], + ['羽狩的队长', '「可以稍微让我问几句话吗」'], + ['凯伊姆', '「······」'], + ['凯伊姆', '「啊啊,无妨」'], + ['羽狩的队长', '「感谢您的合作」'], + ['', '队长殷勤地致以谢礼。'], + ['', '而在他的眼前,少年的衣服已经被他的补下们扯破。'], + ['', '在瘦骨嶙峋的裸露后背上,长有纯白的羽翼。'], + ['红发的羽狩', '「副队长,确认翅膀的持有了」'], + ['羽狩的副队长', '「保护他」'], + ['羽化病患少年', '「不要······请原谅,我······」'], + ['羽狩的副队长', '「我们只是要带你去治愈院治疗羽化病,不是什么应该感到害怕的事情」'], + ['羽化病患少年', '「可是,可是」'], + ['羽狩的副队长', '「没关系的」'], + ['羽化病患少年', '「······哥,哥哥」'], + ['羽狩的副队长', '「你是羽化病人的亲属吗?」'], + ['凯伊姆', '「只是路人而已」'], + ['凯伊姆', '「顺带一提,我也没有打算找你们的麻烦」'], + ['羽狩的副队长', '「前几天,有个和你说了同样的话的人,在我们背向他的瞬间对我们发动了袭击」'], + ['羽狩的副队长', '「我的一个部下就此永久失去了半截胳膊」'], + ['凯伊姆', '「我表示同情」'], + ['凯伊姆', '「我马上就会消失的,这样就没问题了吧?」'], + ['羽狩的副队长', '「嘛,不要这么慌张」'], + ['', '副队长看着羽化的少年。'], + ['羽狩的副队长', '「你与这个人是什么关系?没有被他殴打吗?」'], + ['羽化病患少年', '「没,没有」'], + ['羽狩的副队长', '「如何对我们保持合作,你就可以在治愈院得到优先的治疗」'], + ['羽化病患少年', '「······」'], + ['羽化病患少年', '「那个人,是《不蚀金锁》的组织成员······」'], + ['羽化病患少年', '「突然说让我拿出钱来,我刚一拒绝他就打我」'], + ['羽狩的副队长', '「原来如此······」'], + ['羽狩的副队长', '「那位少年说你是《不蚀金锁》的一员,不知此事是否属实?」'], + ['凯伊姆', '「当然不是」'], + ['凯伊姆', '「我只是从那里接受工作而已,并不是他们的成员」'], + ['羽狩的副队长', '「你的意思是说,少年在说谎吗?」'], + ['凯伊姆', '「啊啊」'], + ['凯伊姆', '「如果你们和组织有关系的话,只要问问我是不是那里的成员就能明白事实了吧」'], + ['羽狩的副队长', '「就算我去询问,也无法从他们那里得到事实」'], + ['羽狩的副队长', '「《不蚀金锁》的那些人一向都不对我们合作,我对此深感困扰」'], + ['凯伊姆', '「真是辛苦啊」'], + ['羽狩的副队长', '「说的是啊」'], + ['羽狩的副队长', '「其实,砍下我部下胳膊的似乎也是组织的成员呢」'], + ['羽狩的副队长', '「无需如此警戒,我只是想在看守所向你咨询一些事情而已」'], + ['羽狩的副队长', '「如果能够知晓牢狱与组织的事情,我们也可以尽可能地对更多的羽化病人进行保护」'], + ['羽狩的副队长', '「那和整条街道的和平也是紧密相关的吧?」'], + ['凯伊姆', '「我知道,你们有逮捕干扰狩猎羽化病人的权力」'], + ['凯伊姆', '「但是,我没有对你们做出任何干扰,为什么要对我如此纠缠不休呢」'], + ['羽狩的副队长', '「那些话,我们会在看守所对你详细说明的」'], + ['凯伊姆', '「······」'], + ['', '在这里起争执的话,就会被羽狩加害。'], + ['', '就算能从这里脱身,今后只要碰面就会产生纠纷也是摆明的事情。'], + ['', '就算逃跑,也没有好的结果。'], + ['', '正当我想要打圆场的时候,刚才的气氛一瞬间产生了转变。'], + ['', '发生了什么事······'], + ['???', '「我认为,那位先生是正确的」'], + ['', '羽狩们一起回头。'], + ['', '而在他们视线的焦点处,'], + ['', '伫立着一位女性。'], + ['', '在端正的容颜下,代表着强烈意志的双眉十分显眼。'], + ['', '身体的柔软与紧紧包裹在其身上的羽狩制服,两者显得十分的不搭配。'], + ['', '我还是第一次看到女性的羽狩。'], + ['羽狩的副队长', '「队长,这是获得《不蚀金锁》情报的好机会」'], + ['羽狩的队长', '「兰格副队长,就算是为了获得情报,也不能做出恫吓的发言啊」'], + ['兰格副队长', '「我并没有打算去恫吓他······」'], + ['羽狩的队长', '「告诉我那个被砍掉胳膊的队员的名字」'], + ['羽狩的队长', '「我会去探望他的」'], + ['兰格副队长', '「那个是······」'], + ['羽狩的队长', '「我知道,你一直在为有所收获而努力工作」'], + ['羽狩的队长', '「但是,正因为我们的工作是为民众提供帮助」'], + ['羽狩的队长', '「所以就更不能损害人与人之间的信赖」'], + ['兰格副队长', '「我会铭记在心」'], + ['羽狩的队长', '「这位先生,我的部下失礼了」'], + ['凯伊姆', '「只要不对我再来一次就好」'], + ['羽狩的队长', '「请稍等」'], + ['凯伊姆', '「有什么事?」'], + ['羽狩的队长', '「我想确认一件事」'], + ['羽狩的队长', '「你真的不是《不蚀金锁》的成员吗?」'], + ['凯伊姆', '「真的」'], + ['凯伊姆', '「如果我说是的话,你有什么打算?」'], + ['羽狩的队长', '「我听过传闻,说他们是用依靠暴力而得的钱在生活」'], + ['凯伊姆', '「······这样啊」'], + ['凯伊姆', '「如果能有收获就好了啊」'] + ] + this.chapter04 = [ + ['梅尔特', '「欢迎光临」'], + ['梅尔特', '「辛苦了」'], + ['梅尔特', '「抱歉,又拜托给你了个这么麻烦的工作」'], + ['凯伊姆', '「没什么,比想象中完成的更容易」'], + ['梅尔特', '「那就好」'], + ['梅尔特', '「这是我的一点谢意」'], + ['凯伊姆', '「味道有些变化啊」'], + ['梅尔特', '「啊,被发现了?」'], + ['梅尔特', '「最近,没能到手什么好的原料呢」'], + ['凯伊姆', '「去拜托吉克如何?」'], + ['梅尔特', '「话是这么说,但是总不能用店里采购的这种小事去麻烦他吧······」'], + ['凯伊姆', '「那希望你也不要来麻烦我」'], + ['梅尔特', '「那 是 两 码 事」'], + ['梅尔特', '「再说,凯伊姆是靠着工作来生活的吧」'], + ['梅尔特', '「而且,自己的钱被偷了这么害羞的事,向凯伊姆意外的其他人都说不出口」'], + ['凯伊姆', '「反正,也已经传到吉克的耳朵里了」'], + ['梅尔特', '「这是面子问题啊,面子问题」'], + ['凯伊姆', '「嘛,算了」'], + ['凯伊姆', '「这样就好了吧?」'], + ['梅尔特', '「这是钱包呢」'], + ['梅尔特', '「嗯,东西没少」'], + ['梅尔特', '「太好啦—这个月的上纳金,我可全部都放在里面了呢」'], + ['梅尔特', '「如果没有找到的话,说不定就又会被送到娼馆里了呢」'], + ['凯伊姆', '「在那边不是来钱更快吗?」'], + ['梅尔特', '「阿拉,你是在说我还能有魅力吗?」'], + ['凯伊姆', '「这是客套话而已」'], + ['梅尔特', '「欺负人」'], + ['梅尔特', '「总而言之,今天帮大忙了」'], + ['梅尔特', '「谢礼嘛······」'], + ['凯伊姆', '「就记在账单上吧」'], + ['梅尔特', '「了解—盛谢惠顾了哦?」'], + ['', '喀啷喀啷'], + ['', '门铃响起'], + ['', '喧哗瞬间安静下来。'], + ['', '进来的人是吉克。'], + ['', '是掌控着牢狱的组织之一,《不蚀金锁》的头目。'], + ['', '不仅组织的成员,就连店内一般的客人也对他以注目礼表示敬意。'], + ['吉克', '「各位继续吧」'], + ['', '仿佛停滞的时钟重新转动了一般,店内恢复了热闹的气氛。'], + ['吉克', '「抱歉,今天拜托你去做了无聊的工作」。'], + ['凯伊姆', '「不用介意」'], + ['', '吉克轻轻点了点头,在我右边坐了下来'], + ['凯伊姆', '「逃跑的男人怎么样了?」'], + ['吉克', '「嗯?已经不在这个世上了」。'], + ['吉克', '「有什么想要知道的事吗?」'], + ['凯伊姆', '「不,没什么」'], + ['吉克', '「那个无聊的家伙,完全没有趣味呢」'], + ['吉克', '「真希望他也替我负责清扫的部下也考虑考虑」'], + ['凯伊姆', '「真是灾难啊」'], + ['吉克', '「比起那个,我听说了哦。你去追羽化病人了啊」'], + ['凯伊姆', '「消息真灵通」'], + ['吉克', '「梅尔特也注意点」'], + ['吉克', '「你丢钱已经不是一回两回了」'], + ['梅尔特', '「好的—我会注意的。」'], + ['梅尔特', '「吉克还是平常的点单吧」'], + ['梅尔特', '「凯伊姆要再来一杯吗?」'], + ['', '我们用眼神点头示意后,梅尔特开始准备起酒来。'], + ['', '悠然地吐出眼圈后,吉克取出一个纸包放在柜台上。'], + ['吉克', '「这是抓捕逃跑男人的报酬」'], + ['凯伊姆', '「下次有什么事再告诉我」'], + ['梅尔特', '「来,久等了」'], + ['凯伊姆', '「话说回来梅尔特,为什么会被那种孩子偷到钱?」'], + ['吉克', '「让我猜猜看」'], + ['吉克', '「是那个吧,看某个特立独行的男人入迷了,所以就有了空隙?」'], + ['梅尔特', '「可惜—」'], + ['梅尔特', '「事实恰恰相反,是那家伙一直在纠缠我」'], + ['凯伊姆', '「完全把你当成新进的女佣了么」'], + ['梅尔特', '「我从前可是很有名的,不会被当成这种下人吧」'], + ['梅尔特', '「······而且,我没法对对我这么钟情的人发火啊」'], + ['凯伊姆&吉克', '「你傻啊」'], + ['梅尔特', '「异口同声呢,不亏是兄弟」'], + ['凯伊姆', '「别用这种称呼,怪恶心的」'], + ['吉克', '「说得没错」'], + ['吉克', '「······说起来······」'], + ['梅尔特', '「怎么了?」'], + ['吉克', '「有件事我一直很在意,我和凯伊姆,哪个是哥哥啊?」'], + ['凯伊姆', '「你也说这么无聊的话题」'], + ['吉克', '「不,这是很重要的事情」'], + ['吉克', '「梅尔特,事实是怎么样的?」'], + ['梅尔特', '「啊~是怎么样的呢~」'], + ['梅尔特', '「我忘记了」'], + ['吉克', '「骗人」'] + ] +} } \ No newline at end of file