From df642e417ec1e691c22af469529baabb126b68b3 Mon Sep 17 00:00:00 2001 From: ckcz123 Date: Sun, 18 Oct 2020 17:51:25 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B6=85=E6=97=B6flag;=E8=B7=B3=E5=87=BA?= =?UTF-8?q?=E5=B1=82=E6=95=B0;=E5=A4=9A=E8=A1=8C=E9=A2=84=E8=A7=88;?= =?UTF-8?q?=E4=B8=80=E5=85=83=E8=BF=90=E7=AE=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _server/MotaAction.g4 | 68 +++++++++++++++++++++++++-------- _server/MotaActionParser.js | 12 ++++-- _server/editor_blockly.js | 22 +++++++---- _server/editor_blocklyconfig.js | 6 ++- _server/editor_materialpanel.js | 8 +--- libs/actions.js | 36 +++++++++++++---- libs/events.js | 57 ++++++++++++++++++++++----- libs/maps.js | 2 + libs/utils.js | 14 +++++++ mota-js10月和273issue.txt | 32 +++++++++------- 10 files changed, 192 insertions(+), 65 deletions(-) diff --git a/_server/MotaAction.g4 b/_server/MotaAction.g4 index ef13fb1e..a76afb70 100644 --- a/_server/MotaAction.g4 +++ b/_server/MotaAction.g4 @@ -806,6 +806,7 @@ tooltip : text:显示一段文字(剧情),选项较多请右键点击帮 helpUrl : /_docs/#/instruction doubleclicktext : EvalString_Multi_0 allIds : ['EvalString_1'] +menu : [['预览所有立绘','editor_blockly.previewBlock(block)']] default : ["小妖精","fairy","","欢迎使用事件编辑器(回车直接多行编辑)",null] var title=''; if (EvalString_0==''){ @@ -2036,7 +2037,7 @@ move_s /* move_s tooltip : move: 让某个NPC/怪物移动,位置可不填代表当前事件 helpUrl : /_docs/#/instruction -default : ["","",500,false,false,"上右3下2后4左前2"] +default : ["","",500,true,false,"上右3下2后4左前2"] selectPoint : ["PosString_0", "PosString_1"] colour : this.mapColor var floorstr = ''; @@ -2525,24 +2526,28 @@ return code; */; break_s - : '跳出当前循环或公共事件' Newline + : '跳出循环或公共事件' '层数' Int Newline /* break_s tooltip : break:跳出循环或公共事件! helpUrl : /_docs/#/instruction colour : this.eventColor -var code = '{"type": "break"},\n'; +default : [1] +if (Int_0 <= 0) throw "层数至少为1!"; +var code = '{"type": "break", "n": '+Int_0+'},\n'; return code; */; continue_s - : '提前结束本轮循环或跳出公共事件' Newline + : '提前结束循环或跳出公共事件' '层数' Int Newline /* continue_s -tooltip : continue:继续执行当前循环的下一轮,或跳出公共事件! +tooltip : continue:提前结束循环或跳出公共事件,或跳出公共事件! helpUrl : /_docs/#/instruction colour : this.eventColor -var code = '{"type": "continue"},\n'; +default : [1] +if (Int_0 <= 0) throw "层数至少为1!"; +var code = '{"type": "continue", "n": '+Int_0+'},\n'; return code; */; @@ -2567,36 +2572,54 @@ return code; waitContext : waitContext_1 | waitContext_2 + | waitContext_3 | waitContext_empty; waitContext_1 - : '按键的场合' '键值' EvalString BGNL? Newline action+ BEND Newline + : '按键的场合' '键值' EvalString '不进行剩余判定' Bool BGNL? Newline action+ BEND Newline /* waitContext_1 tooltip : wait: 等待用户操作并获得按键或点击信息 helpUrl : /_docs/#/instruction colour : this.subColor +default : ["",false] if (!/^\d+(,\d+)*$/.test(EvalString_0)) { throw new Error('键值必须是正整数,可以以逗号分隔'); } +Bool_0 = Bool_0?', "break": true':''; var collapsed=block.isCollapsed()?', "_collapsed": true':''; -var code = '{"case": "keyboard", "keycode": "' + EvalString_0 + '"'+collapsed+', "action": [\n' + action_0 + ']},\n'; +var code = '{"case": "keyboard", "keycode": "' + EvalString_0 + '"'+Bool_0+collapsed+', "action": [\n' + action_0 + ']},\n'; return code; */; waitContext_2 - : '点击的场合' '像素x范围' PosString '~' PosString '; y范围' PosString '~' PosString BGNL? Newline action+ BEND Newline + : '点击的场合' '像素x范围' PosString '~' PosString '; y范围' PosString '~' PosString '不进行剩余判定' Bool BGNL? Newline action+ BEND Newline /* waitContext_2 tooltip : wait: 等待用户操作并获得按键或点击信息 helpUrl : /_docs/#/instruction -default : [0,32,0,32] +default : [0,32,0,32,false] previewBlock : true colour : this.subColor +Bool_0 = Bool_0?', "break": true':''; var collapsed=block.isCollapsed()?', "_collapsed": true':''; -var code = '{"case": "mouse", "px": [' + PosString_0 + ',' + PosString_1 + '], "py": [' + PosString_2 + ',' + PosString_3 + ']'+collapsed+', "action": [\n' + action_0 + ']},\n'; +var code = '{"case": "mouse", "px": [' + PosString_0 + ',' + PosString_1 + '], "py": [' + PosString_2 + ',' + PosString_3 + ']'+Bool_0+collapsed+', "action": [\n' + action_0 + ']},\n'; +return code; +*/; + +waitContext_3 + : '超时的场合' '不进行剩余判定' Bool BGNL? Newline action+ BEND Newline + +/* waitContext_3 +tooltip : wait: 等待用户操作并获得按键或点击信息 +helpUrl : /_docs/#/instruction +colour : this.subColor +default : [false] +Bool_0 = Bool_0?', "break": true':''; +var collapsed=block.isCollapsed()?', "_collapsed": true':''; +var code = '{"case": "timeout"'+Bool_0+collapsed+', "action": [\n' + action_0 + ']},\n'; return code; */; @@ -2786,6 +2809,7 @@ drawTextContent_s tooltip : drawTextContent:绘制多行文本 helpUrl : /_docs/#/instruction doubleclicktext : EvalString_Multi_0 +menu : [['预览多行文本','editor_blockly.previewBlock(block)']] colour : this.subColor default : ["绘制多行文本\\n可双击编辑","0","0","","",'rgba(255,255,255,1)',null,"","",false] TextAlign_List_0 = TextAlign_List_0==='null'?'': ', "align": "'+TextAlign_List_0+'"'; @@ -3125,6 +3149,7 @@ expression : expression Arithmetic_List expression | negate_e | unaryOperation_e + | utilOperation_e | bool_e | idFixedList_e | idFlag_e @@ -3187,7 +3212,16 @@ unaryOperation_e /* unaryOperation_e -var code = UnaryOperator_List_0 + expression_0; +var code = UnaryOperator_List_0 + '(' + expression_0 + ')'; +return [code, Blockly.JavaScript.ORDER_MEMBER]; +*/; + +utilOperation_e + : UtilOperator_List expression + + +/* utilOperation_e +var code = UtilOperator_List_0 + '(' + expression_0 + ')'; return [code, Blockly.JavaScript.ORDER_MEMBER]; */; @@ -3241,7 +3275,7 @@ enemyattr_e /* enemyattr_e -default : ['greenSlime',"攻击"] +default : ['greenSlime',"hp"] allEnemys : ['IdString_0'] var code = 'enemy:'+IdString_0+':'+EnemyId_List_0; return [code, Blockly.JavaScript.ORDER_ATOMIC]; @@ -3393,8 +3427,12 @@ AssignOperator_List /*AssignOperator_List ['=','+=','-=','*=','/=','**=','//=','%=','min=','max=']*/; UnaryOperator_List - : '向下取整'|'向上取整'|'四舍五入'|'整数截断'|'绝对值'|'开方' - /*UnaryOperator_List ['Math.floor', 'Math.ceil', 'Math.round', 'Math.trunc', 'Math.abs', 'Math.sqrt']*/; + : '向下取整'|'向上取整'|'四舍五入'|'整数截断'|'绝对值'|'开方'|'变量类型' + /*UnaryOperator_List ['Math.floor', 'Math.ceil', 'Math.round', 'Math.trunc', 'Math.abs', 'Math.sqrt', 'typeof']*/; + +UtilOperator_List + : '大数字格式化'|'哈希值'|'base64编码'|'base64解码'|'不可SL的随机'|'可以SL的随机'|'表达式求值'|'深拷贝'|'日期格式化'|'时间格式化'|'获得cookie'|'字符串字节数' + /*UtilOperator_List ['core.formatBigNumber', 'core.hashCode', 'core.encodeBase64', 'core.decodeBase64', 'core.rand', 'core.rand2', 'core.calValue', 'core.clone', 'core.formatDate', 'core.formatTime', 'core.getCookie', 'core.strlen']*/; Weather_List : '无'|'雨'|'雪'|'雾'|'云' diff --git a/_server/MotaActionParser.js b/_server/MotaActionParser.js index a49c1be8..d7927a3e 100644 --- a/_server/MotaActionParser.js +++ b/_server/MotaActionParser.js @@ -725,11 +725,11 @@ ActionParser.prototype.parseAction = function() { break; case "break": // 跳出循环 this.next = MotaActionBlocks['break_s'].xmlText([ - this.next]); + data.n || 1, this.next]); break; case "continue": // 继续执行当前循环 this.next = MotaActionBlocks['continue_s'].xmlText([ - this.next]); + data.n || 1, this.next]); break; case "win": this.next = MotaActionBlocks['win_s'].xmlText([ @@ -779,11 +779,15 @@ ActionParser.prototype.parseAction = function() { for(var ii=data.data.length-1,caseNow;caseNow=data.data[ii];ii--) { if (caseNow["case"] == "keyboard") { case_waitList = MotaActionFunctions.xmlText('waitContext_1',[ - caseNow.keycode || "0", this.insertActionList(caseNow.action), case_waitList + caseNow.keycode || "0", caseNow.nobreak || false, this.insertActionList(caseNow.action), case_waitList ], /* isShadow */false, /*comment*/ null, /*collapsed*/ caseNow._collapsed); } else if (caseNow["case"] == "mouse") { case_waitList = MotaActionFunctions.xmlText('waitContext_2',[ - caseNow.px[0], caseNow.px[1], caseNow.py[0], caseNow.py[1], this.insertActionList(caseNow.action), case_waitList + caseNow.px[0], caseNow.px[1], caseNow.py[0], caseNow.py[1], caseNow.nobreak || false, this.insertActionList(caseNow.action), case_waitList + ], /* isShadow */false, /*comment*/ null, /*collapsed*/ caseNow._collapsed); + } else if (caseNow["case"] == "timeout") { + case_waitList = MotaActionFunctions.xmlText('waitContext_3',[ + caseNow.nobreak || false, this.insertActionList(caseNow.action), case_waitList ], /* isShadow */false, /*comment*/ null, /*collapsed*/ caseNow._collapsed); } } diff --git a/_server/editor_blockly.js b/_server/editor_blockly.js index 76ac59c5..2b3bd34d 100644 --- a/_server/editor_blockly.js +++ b/_server/editor_blockly.js @@ -233,13 +233,11 @@ editor_blockly = function () { editor_blockly.previewBlock = function (b,args) { - try { - // 特殊处理立绘 - if (b.type == 'textDrawing') { - var str = Blockly.JavaScript.blockToCode(b); - var list = str.substring(str.indexOf('[')+1, str.lastIndexOf(']')).split(","); + var previewTextDrawing = function (content) { + var arr = []; + content.replace(/(\f|\\f)\[(.*?)]/g, function (text, sympol, str) { + var list = str.split(","); if (list.length == 3 || list.length == 5 || list.length >= 9) { - var arr = []; var name = list[0]; var obj = {"type": "drawImage"}; if (name.endsWith(":o") || name.endsWith(":x") || name.endsWith(":y")) { @@ -266,9 +264,17 @@ editor_blockly = function () { obj.angle = parseFloat(list[10]); } arr.push(obj); - console.log(arr); - editor.uievent.previewUI(arr); } + return ""; + }); + editor.uievent.previewUI(arr); + return true; + } + + try { + // 特殊处理立绘 + if (b.type == 'textDrawing' || b.type == 'text_2_s') { + previewTextDrawing(Blockly.JavaScript.blockToCode(b)); return true; } diff --git a/_server/editor_blocklyconfig.js b/_server/editor_blocklyconfig.js index c77ec8c9..5940e287 100644 --- a/_server/editor_blocklyconfig.js +++ b/_server/editor_blocklyconfig.js @@ -178,8 +178,9 @@ editor_blocklyconfig=(function(){ '特效/声音':[ MotaActionBlocks['sleep_s'].xmlText(), MotaActionFunctions.actionParser.parseList({"type": "wait", "timeout": 0, "data": [ - {"case": "keyboard", "keycode": "13,32", "action": [{"type": "comment", "text": "当按下回车(keycode=13)或空格(keycode=32)时执行此事件"}]}, - {"case": "mouse", "px": [0,32], "py": [0,32], "action": [{"type": "comment", "text": "当点击地图左上角时执行此事件"}]}, + {"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": "timeout", "action": [{"type": "comment", "text": "当超时未操作时执行此事件"}]}, ]}), MotaActionBlocks['waitAsync_s'].xmlText(), MotaActionBlocks['vibrate_s'].xmlText(), @@ -245,6 +246,7 @@ editor_blocklyconfig=(function(){ MotaActionBlocks['idTemp_e'].xmlText(), MotaActionBlocks['negate_e'].xmlText(), MotaActionBlocks['unaryOperation_e'].xmlText(), + MotaActionBlocks['utilOperation_e'].xmlText(), MotaActionBlocks['bool_e'].xmlText(), MotaActionBlocks['idString_e'].xmlText(), MotaActionBlocks['idIdList_e'].xmlText(), diff --git a/_server/editor_materialpanel.js b/_server/editor_materialpanel.js index f4df1bd3..c1e73f6a 100644 --- a/_server/editor_materialpanel.js +++ b/_server/editor_materialpanel.js @@ -190,10 +190,7 @@ editor_materialpanel_wrapper = function (editor) { } } - if (editor.info.isTile && e.button == 2) { //这段改一改之类的应该能给手机用,就不删了 - // 废弃好了 - alert('V2.7后右键已被废弃,请直接素材区拖框选中区域。'); - /* + if (editor.info.isTile && (editor.isMobile || e.button == 2)) { //这段改一改之类的应该能给手机用,就不删了 var v = prompt("请输入该额外素材区域绑定宽高,以逗号分隔", "1,1"); if (v != null && /^\d+,\d+$/.test(v)) { v = v.split(","); @@ -209,9 +206,8 @@ editor_materialpanel_wrapper = function (editor) { editor.dom.dataSelection.style.width = 32*x - 6 + 'px'; } } - */ } - if (editor.info.isTile && e.button != 2) { //左键拖拽框选 + if (editor.info.isTile && !editor.isMobile && e.button != 2) { //左键拖拽框选 var x = pos.x-pos0.x+1, y = pos.y-pos0.y+1; var widthX = editor.widthsX[editor.info.images]; diff --git a/libs/actions.js b/libs/actions.js index 6de7112d..5792a382 100644 --- a/libs/actions.js +++ b/libs/actions.js @@ -423,12 +423,15 @@ actions.prototype._sys_ondown_lockControl = function (x, y, px, py) { // --- wait事件也要提供px和py if (core.status.event.id == 'action' && core.status.event.data.type == 'wait') { clearTimeout(core.status.event.interval); + var timeout = Math.max(0, core.status.event.timeout - new Date().getTime()) || 0; + delete core.status.event.timeout; core.setFlag('type', 1); core.setFlag('x', x); core.setFlag('y', y); core.setFlag('px', px); core.setFlag('py', py); - core.status.route.push("input:" + (1000000 + 1000 * px + py)); + core.setFlag('timeout', timeout); + core.status.route.push("input:" + (1e8 * timeout + 1000000 + 1000 * px + py)); core.events.__action_wait_afterGet(core.status.event.data.current); core.doAction(); } @@ -727,10 +730,13 @@ actions.prototype._sys_onmousewheel = function (direct) { // wait事件 if (core.status.lockControl && core.status.event.id == 'action' && core.status.event.data.type == 'wait') { clearTimeout(core.status.event.interval); + var timeout = Math.max(0, core.status.event.timeout - new Date().getTime()) || 0; + delete core.status.event.timeout; core.setFlag('type', 0); var keycode = direct == 1 ? 33 : 34; core.setFlag('keycode', keycode); - core.status.route.push("input:" + keycode); + core.setFlag('timeout', timeout); + core.status.route.push("input:" + (1e8 * timeout + keycode)); core.events.__action_wait_afterGet(core.status.event.data.current); core.doAction(); return; @@ -980,8 +986,10 @@ actions.prototype._clickAction = function (x, y) { return; } clearTimeout(core.status.event.interval); - // 选择 - core.status.route.push("choices:" + (y - topIndex)); + var timeout = Math.max(0, core.status.event.timeout - new Date().getTime()) || 0; + delete core.status.event.timeout; + core.setFlag('timeout', timeout); + core.status.route.push("choices:" + (100 * timeout + y - topIndex)); core.insertAction(choice.action); core.doAction(); } @@ -992,13 +1000,19 @@ actions.prototype._clickAction = function (x, y) { if (core.status.event.data.type == 'confirm') { if ((x == this.HSIZE-2 || x == this.HSIZE-1) && y == this.HSIZE+1) { clearTimeout(core.status.event.interval); - core.status.route.push("choices:0"); + var timeout = Math.max(0, core.status.event.timeout - new Date().getTime()) || 0; + delete core.status.event.timeout; + core.setFlag('timeout', timeout); + core.status.route.push("choices:" + 100 * timeout); core.insertAction(core.status.event.ui.yes); core.doAction(); } else if ((x == this.HSIZE+2 || x == this.HSIZE+1) && y == this.HSIZE+1) { clearTimeout(core.status.event.interval); - core.status.route.push("choices:1"); + var timeout = Math.max(0, core.status.event.timeout - new Date().getTime()) || 0; + delete core.status.event.timeout; + core.setFlag('timeout', timeout); + core.status.route.push("choices:" + (100 * timeout + 1)); core.insertAction(core.status.event.ui.no); core.doAction(); } @@ -1031,9 +1045,12 @@ actions.prototype._keyUpAction = function (keycode) { } if (core.status.event.data.type == 'wait') { clearTimeout(core.status.event.interval); + var timeout = Math.max(0, core.status.event.timeout - new Date().getTime()) || 0; + delete core.status.event.timeout; core.setFlag('type', 0); core.setFlag('keycode', keycode); - core.status.route.push("input:" + keycode); + core.setFlag('timeout', timeout); + core.status.route.push("input:" + (1e8 * timeout + keycode)); core.events.__action_wait_afterGet(core.status.event.data.current); core.doAction(); return; @@ -1047,7 +1064,10 @@ actions.prototype._keyUpAction = function (keycode) { return; } if (core.status.event.data.type == 'confirm'&& (keycode == 13 || keycode == 32 || keycode == 67)) { - core.status.route.push("choices:" + core.status.event.selection); + var timeout = Math.max(0, core.status.event.timeout - new Date().getTime()) || 0; + delete core.status.event.timeout; + core.setFlag('timeout', timeout); + core.status.route.push("choices:" + (100 * timeout + core.status.event.selection)); if (core.status.event.selection == 0) core.insertAction(core.status.event.ui.yes); else core.insertAction(core.status.event.ui.no); diff --git a/libs/events.js b/libs/events.js index ba8cf454..5a8b8e65 100644 --- a/libs/events.js +++ b/libs/events.js @@ -1857,7 +1857,12 @@ events.prototype._action_choices = function (data, x, y, prefix) { if (action.indexOf('choices:') == 0) { var index = action.substring(8); if (index == "-1") index = data.choices.length - 1; - if (index == 'none' || ((index = parseInt(index)) >= 0) && index < data.choices.length) { + if (index == 'none' || ((index = parseInt(index)) >= 0) && index % 100 < data.choices.length) { + 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); @@ -1874,11 +1879,15 @@ events.prototype._action_choices = function (data, x, y, prefix) { }, core.status.replay.speed == 24 ? 1 : 750 / Math.max(1, core.status.replay.speed)); } } - } else if (data.timeout) { - core.status.event.interval = setTimeout(function () { - core.status.route.push("choices:none"); - core.doAction(); - }, data.timeout); + } 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); } core.ui.drawChoices(core.replaceText(data.text, prefix), data.choices); } @@ -1901,7 +1910,12 @@ events.prototype._action_confirm = function (data, x, y, prefix) { if (action == 'turn') action = core.status.replay.toReplay.shift(); if (action.indexOf('choices:') == 0) { var index = action.substring(8); - if (index == 'none' || ((index = parseInt(index)) >= 0) && index < 2) { + if (index == 'none' || ((index = parseInt(index)) >= 0) && index % 100 < 2) { + 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); @@ -1922,9 +1936,11 @@ events.prototype._action_confirm = function (data, x, y, prefix) { 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); } @@ -2039,12 +2055,20 @@ events.prototype._precompile_dowhile = function (data) { } events.prototype._action_break = function (data, x, y, prefix) { - if (core.status.event.data.list.length > 1) - core.status.event.data.list.shift(); + 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); @@ -2136,6 +2160,8 @@ events.prototype._action_wait = function (data, x, y, prefix) { if (code == "input:none") { core.status.route.push("input:none"); core.setFlag("type", -1); + core.setFlag("timeout", 0); + this.__action_wait_afterGet(data); } else { var value = parseInt(code.substring(6)); core.status.route.push("input:" + value); @@ -2154,12 +2180,17 @@ events.prototype._action_wait = function (data, x, y, prefix) { 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; @@ -2185,11 +2216,14 @@ events.prototype.__action_wait_getValue = function (value) { events.prototype.__action_wait_afterGet = function (data) { if (!data.data) return; var todo = []; + var stop = false; data.data.forEach(function (one) { + if (stop) return; if (one["case"] == "keyboard" && core.getFlag("type") == 0) { (one.keycode + "").split(",").forEach(function (keycode) { if (core.getFlag("keycode", 0) == keycode) { core.push(todo, one.action); + if (one["break"]) stop = true; } }); } @@ -2202,8 +2236,13 @@ events.prototype.__action_wait_afterGet = function (data) { var px = core.getFlag("px", 0), py = core.getFlag("py", 0); if (px >= pxmin && px <= pxmax && py >= pymin && py <= pymax) { core.push(todo, one.action); + if (one["break"]) stop = true; } } + if (one["case"] == "timeout" && core.getFlag("type") == -1) { + core.push(todo, one.action); + if (one["break"]) stop = true; + } }) if (todo.length > 0) core.insertAction(todo); diff --git a/libs/maps.js b/libs/maps.js index 3bd10f2f..c9a60018 100644 --- a/libs/maps.js +++ b/libs/maps.js @@ -2193,6 +2193,7 @@ maps.prototype._getAndRemoveBlock = function (x, y) { ////// 显示移动某块的动画,达到{“type”:”move”}的效果 ////// maps.prototype.moveBlock = function (x, y, steps, time, keep, callback) { if (core.status.replay.speed == 24) time = 1; + if (keep == null) keep = true; time = time || 500; var blockArr = this._getAndRemoveBlock(x, y); if (blockArr == null) { @@ -2282,6 +2283,7 @@ maps.prototype._moveBlock_moving = function (blockInfo, canvases, moveInfo) { ////// 显示跳跃某块的动画,达到{"type":"jump"}的效果 ////// maps.prototype.jumpBlock = function (sx, sy, ex, ey, time, keep, callback) { time = time || 500; + if (keep == null) keep = true; var blockArr = this._getAndRemoveBlock(sx, sy); if (blockArr == null) { if (callback) callback(); diff --git a/libs/utils.js b/libs/utils.js index 3c9f5450..c0163326 100644 --- a/libs/utils.js +++ b/libs/utils.js @@ -1097,6 +1097,20 @@ utils.prototype.getGuid = function () { return guid; } +utils.prototype.hashCode = function (obj) { + if (typeof obj == 'string') { + var hash = 0, i, chr; + if (obj.length === 0) return hash; + for (i = 0; i < obj.length; i++) { + chr = obj.charCodeAt(i); + hash = ((hash << 5) - hash) + chr; + hash |= 0; + } + return hash; + } + return this.hashCode(JSON.stringify(obj).split("").sort().join("")); +} + utils.prototype.same = function (a, b) { if (a == null && b == null) return true; if (a == null || b == null) return false; diff --git a/mota-js10月和273issue.txt b/mota-js10月和273issue.txt index d2c0a2f7..0f1118e1 100644 --- a/mota-js10月和273issue.txt +++ b/mota-js10月和273issue.txt @@ -69,19 +69,25 @@ N:可能影响接档等,下一个版本再考虑 (√)9.(完全信息)坚固怪和受光环影响的怪建议在详情框显示其原始能力,尤其是坚固和模仿,其实它们手册一级面板显示原值对玩家来说才是魔塔倡导的完全信息,变化后的值可以轻易口算。 (x)同理,楼传界面和浏览地图建议加一个按钮(可以是插件)来切换显示一些楼层属性,如上下楼点、楼传落点、本次楼传落点(这些点可以在地图或缩略图用不同颜色高亮显示)、ratio、ground的图标、几个勾选框、宽高、有无两个arrive事件、色调(尤其是是否为不透明的纯色)等。 (x)另外浏览地图界面的非缩略图建议像编辑器一样加上高亮刻度尺表示所在第几行第几列(此灵感来自秋橙的3D塔每走一步在状态栏实时显示xyz)。 -10. ui._drawCenterFly建议在大地图时也提供缩略图方式显示(可以做成可当时切换),以方便玩家。 -11.(显示文章)建议双击(或右击菜单中)同时预览所有立绘,现在一次预览一张图还是很不直观的。同理,其他一些被占用的功能也可以放进右击菜单,比如动画选坐标和跳跃选起点(已被z触完成)、UI多行文本绘制预览(现在必须塞进黄框) -12. “接受用户输入非负整数”建议改为魔塔样板4401的楼传那种界面(五个按钮,分别负责切换数位,在当前位加减1,和确定),并由作者指定位数,以优化观感和安全性且方便玩家。或者改成十个数字键和一个退格键也不错? -13. 建议新增大批一元和二元运算的Math和字符串等值块,一元如“typeof、formatBigNumber、en/decodeBase64(方便解谜元素防止玩家看答案)、getEquipTypeById、rand、rand2(对标rm)、length、strLen、calValue(用于循环遍历)、toLower/UpperCase、trim、isFinite/NaN/(Safe)Integer(建议配置表格里那一堆~~都改成这个规范的)”等,并把“非(!)”也放进下拉框。二元如“clone/subArray、matchWildcard、char(Code)At、(last)indexOf、replace(All)、starts/endsWith、includes、toFixed/Exponential/Precision(这个最好再进一步封装转换回数字,js这些函数返回是字符串)”等。g4文件结尾的FixedId_List建议增强到可以由作者更方便地在编辑器中追加(目前pc端只有开文件追加还算容易,但仅限对于高级用户),另外此List的量都是可读写的,但有些只读量也同样重要,如MAX_VALUE、MIN_VALUE、EPSILON、MIN_SAFE_INTEGER、MAX_SAFE_INTEGER等,建议提供为另一个下拉框。 -14.(后端)建议尽早适配服务器发塔前babel,如果一时做不到,建议在flag、global等冒号缩写量中检查是否使用了js保留字,以免压缩出问题。(1008)并采用闭包压缩方式(注意要处理window.flags等)以一定程度上防止控制台作弊。 -15.(循环增强)建议增强break和continue事件,使其能跳出指定的层数(js和java都可以带标号的)。 -16.(横屏)建议增加悬停和鼠标划过等action,意义很大,比如强化地图显伤和选择项提示。 -17.(事件栈帧)建议公共事件尽早加入调用栈迹和返回值系统,目前嵌套调用参数覆盖问题和递归调用返回值覆盖问题不是闹着玩的。 -18.(参照阻击)建议给推箱子增加推的动画,以优化观感且避免推到重生怪等隐藏但不删除的位置消失。 -19.(仿rmxp魔塔)夹击点(尤其是只有夹击的点,因为伤害可以由玩家口算)建议把显伤改为(或追加)rmxp魔塔的电光效果(此效果的变动频率比全局帧动画更为频繁,《盖伦排位记》也使用了此效果)。同理,大范围领域/激光的大量相同数字也不好看(272改版中已经一定程度上优化),改为美术效果更好。 -20.(毒衰咒处理)V2.6.x的公共事件法的缺点在于打断寻路,而V2.7改成脚本编辑后也许矫枉过正。事实上毒和咒起的是个开关的作用,实际效果要到走路和战后才有效,真正麻烦的只有衰。 -21.(QTE功能增强)希望加强QTE功能,在玩家操作时将剩余时间计入flag和录像,以便作者根据玩家的操作区间做不同处理(如音游),而且知道剩余时间还有一个最基本的用法是再等待这么久,以使得总的等待时间不变来和其他演出效果同步。 -22. 希望type:"wait"事件的场合块增加一个break勾选框 +(x)10. ui._drawCenterFly建议在大地图时也提供缩略图方式显示(可以做成可当时切换),以方便玩家。 +(√)11.(显示文章)建议双击(或右击菜单中)同时预览所有立绘,现在一次预览一张图还是很不直观的。 +(√)11.1 同理,其他一些被占用的功能也可以放进右击菜单,比如动画选坐标和跳跃选起点(已被z触完成)、 +(√)11.2 UI多行文本绘制预览(现在必须塞进黄框) +(x)12. “接受用户输入非负整数”建议改为魔塔样板4401的楼传那种界面(五个按钮,分别负责切换数位,在当前位加减1,和确定),并由作者指定位数,以优化观感和安全性且方便玩家。或者改成十个数字键和一个退格键也不错? +(√)13. 建议新增大批一元和二元运算的Math和字符串等值块,一元如“typeof、formatBigNumber、en/decodeBase64(方便解谜元素防止玩家看答案)、getEquipTypeById、rand、rand2(对标rm)、length、strLen、calValue(用于循环遍历)、toLower/UpperCase、trim、isFinite/NaN/(Safe)Integer(建议配置表格里那一堆~~都改成这个规范的)”等,并把“非(!)”也放进下拉框。 +(x)13.1 二元如“clone/subArray、matchWildcard、char(Code)At、(last)indexOf、replace(All)、starts/endsWith、includes、toFixed/Exponential/Precision(这个最好再进一步封装转换回数字,js这些函数返回是字符串)”等。g4文件结尾的FixedId_List建议增强到可以由作者更方便地在编辑器中追加(目前pc端只有开文件追加还算容易,但仅限对于高级用户),另外此List的量都是可读写的,但有些只读量也同样重要,如MAX_VALUE、MIN_VALUE、EPSILON、MIN_SAFE_INTEGER、MAX_SAFE_INTEGER等,建议提供为另一个下拉框。 +(x)14.(后端)建议尽早适配服务器发塔前babel,如果一时做不到,建议在flag、global等冒号缩写量中检查是否使用了js保留字,以免压缩出问题。 +(x)14.1. (1008)并采用闭包压缩方式(注意要处理window.flags等)以一定程度上防止控制台作弊。 +(√)15.(循环增强)建议增强break和continue事件,使其能跳出指定的层数(js和java都可以带标号的)。 +(x)16.(横屏)建议增加悬停和鼠标划过等action,意义很大,比如强化地图显伤和选择项提示。 +(N)17.(事件栈帧)建议公共事件尽早加入调用栈迹和返回值系统,目前嵌套调用参数覆盖问题和递归调用返回值覆盖问题不是闹着玩的。 +(x)18.(参照阻击)建议给推箱子增加推的动画,以优化观感且避免推到重生怪等隐藏但不删除的位置消失。 +(N)19.(仿rmxp魔塔)夹击点(尤其是只有夹击的点,因为伤害可以由玩家口算)建议把显伤改为(或追加)rmxp魔塔的电光效果(此效果的变动频率比全局帧动画更为频繁,《盖伦排位记》也使用了此效果)。 +(x)19.1. 同理,大范围领域/激光的大量相同数字也不好看(272改版中已经一定程度上优化),改为美术效果更好。 +(x)20.(毒衰咒处理)V2.6.x的公共事件法的缺点在于打断寻路,而V2.7改成脚本编辑后也许矫枉过正。事实上毒和咒起的是个开关的作用,实际效果要到走路和战后才有效,真正麻烦的只有衰。 +(√)21.(QTE功能增强)希望加强QTE功能,在玩家操作时将剩余时间计入flag和录像,以便作者根据玩家的操作区间做不同处理(如音游),而且知道剩余时间还有一个最基本的用法是再等待这么久,以使得总的等待时间不变来和其他演出效果同步。 +(√)22. 希望type:"wait"事件的场合块增加一个break勾选框 +(√)23. moveBlock和jumpBlock的keep参数建议默认为true(另外ad似乎实现了这两个函数的bgfg版本,只是有些许bug) 留到2.7.3才能做的issues: 0. sprite化!单图层!任意尺寸、帧数且能运行时动态修改色相和透明度的图块!动画内嵌全屏闪烁、多音效、图块闪烁,色调的其他叠加方式(普通、加法、乘法、屏幕)以适配rm导出的黑底动画,另外希望推出rm其他版本数据到mota-js的导出器。