mirror of
				https://github.com/unanmed/HumanBreak.git
				synced 2025-10-31 20:32:58 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			1214 lines
		
	
	
		
			52 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			1214 lines
		
	
	
		
			52 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| editor_blockly = function () {
 | ||
| 
 | ||
|     var editor_blockly = { entryType: 'event' };
 | ||
| 
 | ||
|     editor.uivalues.disableBlocklyReplace = editor.config.get("disableBlocklyReplace", false);
 | ||
|     var replaceCheckbox = document.getElementById('blocklyReplace');
 | ||
|     replaceCheckbox.checked = !editor.uivalues.disableBlocklyReplace;
 | ||
| 
 | ||
|     editor_blockly.triggerReplace = function () {
 | ||
|         editor.uivalues.disableBlocklyReplace = !replaceCheckbox.checked;
 | ||
|         editor.config.set("disableBlocklyReplace", !replaceCheckbox.checked);
 | ||
|         if (MotaActionFunctions) MotaActionFunctions.disableReplace = !replaceCheckbox.checked;
 | ||
|         alert("已" + (replaceCheckbox.checked ? "开启" : "关闭") + "中文变量名替换!\n关闭并重开事件编辑器以生效。");
 | ||
|     }
 | ||
| 
 | ||
|     editor.uivalues.disableBlocklyExpandCompare = editor.config.get("disableBlocklyExpandCompare", false);
 | ||
|     var expandCompareCheckbox = document.getElementById('blocklyExpandCompare');
 | ||
|     expandCompareCheckbox.checked = !editor.uivalues.disableBlocklyExpandCompare;
 | ||
| 
 | ||
|     editor_blockly.triggerExpandCompare = function () {
 | ||
|         editor.uivalues.disableBlocklyExpandCompare = !expandCompareCheckbox.checked;
 | ||
|         editor.config.set("disableBlocklyExpandCompare", !expandCompareCheckbox.checked);
 | ||
|         if (MotaActionFunctions) MotaActionFunctions.disableExpandCompare = !expandCompareCheckbox.checked;
 | ||
|     }
 | ||
| 
 | ||
|     var input_ = '';
 | ||
|     editor_blockly.runOne = function () {
 | ||
|         //var printf = console.log;
 | ||
|         //var printf = function(){};
 | ||
|         var grammerFile = input_;
 | ||
|         converter = new Converter().init();
 | ||
|         converter.generBlocks(grammerFile);
 | ||
|         //printf(converter.blocks);
 | ||
|         converter.renderGrammerName();
 | ||
|         //converter.generToolbox();
 | ||
|         converter.generMainFile();
 | ||
|         //printf(converter.mainFile.join(''));
 | ||
|         //console.log(converter);
 | ||
| 
 | ||
| 
 | ||
|         var script = document.createElement('script');
 | ||
|         script.innerHTML = converter.mainFile[5] + editor_blocklyconfig;
 | ||
|         document.body.appendChild(script);
 | ||
|     }
 | ||
|     var xhr = new XMLHttpRequest();
 | ||
|     xhr.onreadystatechange = function () {
 | ||
|         if (xhr.readyState != 4) return;
 | ||
|         if (xhr.status != 200) {
 | ||
|             alert("图块描述文件加载失败, 请在'启动服务.exe'中打开编辑器");
 | ||
|             return;
 | ||
|         }
 | ||
|         input_ = xhr.responseText;
 | ||
|         editor_blockly.runOne();
 | ||
|         MotaActionFunctions.disableReplace = editor.uivalues.disableBlocklyReplace;
 | ||
|         MotaActionFunctions.disableExpandCompare = editor.uivalues.disableBlocklyExpandCompare;
 | ||
|     }
 | ||
|     xhr.open('GET', '_server/MotaAction.g4', true);
 | ||
|     xhr.send(null);
 | ||
| 
 | ||
|     var codeAreaHL = CodeMirror.fromTextArea(document.getElementById("codeArea"), {
 | ||
|         lineNumbers: true,
 | ||
|         matchBrackets: true,
 | ||
|         lineWrapping: true,
 | ||
|         continueComments: "Enter",
 | ||
|         extraKeys: { "Ctrl-Q": "toggleComment" },
 | ||
|     });
 | ||
|     codeAreaHL.on('changes', function () {
 | ||
|         editor_blockly.highlightParse(!changeFromBlockly);
 | ||
|         changeFromBlockly = false;
 | ||
|     });
 | ||
|     var changeFromBlockly = false;
 | ||
|     var shouldNotifyParse = false;
 | ||
| 
 | ||
|     editor_blockly.showXML = function () {
 | ||
|         var xml = Blockly.Xml.workspaceToDom(editor_blockly.workspace);
 | ||
|         var xml_text = Blockly.Xml.domToPrettyText(xml);
 | ||
|         console.log(xml_text);
 | ||
|         var xml_text = Blockly.Xml.domToText(xml);
 | ||
|         console.log(xml_text);
 | ||
|         console.log(xml);
 | ||
|     }
 | ||
| 
 | ||
|     editor_blockly.runCode = function () {
 | ||
|         // Generate JavaScript code and run it.
 | ||
|         window.LoopTrap = 1000;
 | ||
|         Blockly.JavaScript.INFINITE_LOOP_TRAP =
 | ||
|             'if (--window.LoopTrap == 0) throw "Infinite loop.";\n';
 | ||
|         var code = Blockly.JavaScript.workspaceToCode(editor_blockly.workspace);
 | ||
|         Blockly.JavaScript.INFINITE_LOOP_TRAP = null;
 | ||
|         try {
 | ||
|             eval('obj=' + code);
 | ||
|             console.log(obj);
 | ||
|         } catch (e) {
 | ||
|             alert(e);
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
|     editor_blockly.setValue = function (value) {
 | ||
|         changeFromBlockly = true;
 | ||
|         codeAreaHL.setValue(value);
 | ||
|     }
 | ||
| 
 | ||
|     editor_blockly.parse = function () {
 | ||
|         MotaActionFunctions.parse(
 | ||
|             eval('obj=' + codeAreaHL.getValue().replace(/[<>&]/g, function (c) {
 | ||
|                 return { '<': '<', '>': '>', '&': '&' }[c];
 | ||
|             }).replace(/\\(r|f|i|c|d|e|g|z)/g, '\\\\$1')),
 | ||
|             editor_blockly.isCommonEntry() ? 'common' : editor_blockly.entryType
 | ||
|         );
 | ||
|     }
 | ||
| 
 | ||
|     editor_blockly.id = '';
 | ||
| 
 | ||
|     var _lastOpenPosition = {};
 | ||
| 
 | ||
|     editor_blockly.import = function (id_, args) {
 | ||
|         var thisTr = document.getElementById(id_);
 | ||
|         if (!thisTr) return false;
 | ||
|         var input = thisTr.children[2].children[0].children[0];
 | ||
|         var field = thisTr.children[0].getAttribute('title');
 | ||
|         var type = args.type;
 | ||
|         if (!type) return false;
 | ||
|         editor_blockly.id = id_;
 | ||
|         editor_blockly.setValue(input.value);
 | ||
|         editor_blockly.entryType = type;
 | ||
|         editor_blockly.parse();
 | ||
|         editor_blockly.show();
 | ||
|         var _offsetIndex = [editor_blockly.entryType, editor.pos.x, editor.pos.y, editor.currentFloorId].join(":");
 | ||
|         editor_blockly.workspace.scroll(0, _lastOpenPosition[_offsetIndex] || 0)
 | ||
|         return true;
 | ||
|     }
 | ||
| 
 | ||
|     var blocklyWidgetDiv = document.getElementsByClassName('blocklyWidgetDiv');
 | ||
|     editor_blockly.show = function () {
 | ||
|         if (typeof (selectBox) !== typeof (undefined)) selectBox.isSelected(false);
 | ||
|         document.getElementById('left6').style = '';
 | ||
|         for (var ii = 0, node; node = blocklyWidgetDiv[ii]; ii++) {
 | ||
|             node.style.zIndex = 201;
 | ||
|             node.style.opacity = '';
 | ||
|         }
 | ||
|     }
 | ||
|     editor_blockly.hide = function () {
 | ||
|         document.getElementById('left6').style = 'z-index:-1;opacity: 0;';
 | ||
|         for (var ii = 0, node; node = blocklyWidgetDiv[ii]; ii++) {
 | ||
|             node.style.zIndex = -1;
 | ||
|             node.style.opacity = 0;
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
|     var blocklyParseBtn = document.getElementById('blocklyParse');
 | ||
|     editor_blockly.highlightParse = function (shouldHighLight) {
 | ||
|         if (shouldNotifyParse == shouldHighLight) return;
 | ||
|         shouldNotifyParse = shouldHighLight;
 | ||
|         if (shouldHighLight) blocklyParseBtn.classList.add('highlight');
 | ||
|         else blocklyParseBtn.classList.remove('highlight');
 | ||
|     }
 | ||
| 
 | ||
|     editor_blockly.cancel = function () {
 | ||
|         var _offsetIndex = [editor_blockly.entryType, editor.pos.x, editor.pos.y, editor.currentFloorId].join(":");
 | ||
|         _lastOpenPosition[_offsetIndex] = editor_blockly.workspace.scrollY;
 | ||
| 
 | ||
|         editor_blockly.id = '';
 | ||
|         editor_blockly.hide();
 | ||
|     }
 | ||
| 
 | ||
|     editor_blockly.confirm = function (keep) {
 | ||
|         if (!editor_blockly.id) {
 | ||
|             editor_blockly.id = '';
 | ||
|             return;
 | ||
|         }
 | ||
|         if (shouldNotifyParse) {
 | ||
|             alert('你尚未解析修改后的内容,请进行解析或放弃操作');
 | ||
|             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;
 | ||
|             }
 | ||
|         }
 | ||
|         var setvalue = function (value) {
 | ||
|             var thisTr = document.getElementById(editor_blockly.id);
 | ||
|             var input = thisTr.children[2].children[0].children[0];
 | ||
|             input.value = value;
 | ||
|             if (!keep) {
 | ||
|                 editor_blockly.id = '';
 | ||
|                 editor_blockly.hide();
 | ||
|             }
 | ||
|             else alert('保存成功!');
 | ||
|             input.onchange();
 | ||
|         }
 | ||
|         if (codeAreaHL.getValue() === '') {
 | ||
|             eventType === 'shop' ? setvalue('[]') : setvalue('null');
 | ||
|             return;
 | ||
|         }
 | ||
|         var code = Blockly.JavaScript.workspaceToCode(editor_blockly.workspace);
 | ||
|         code = code.replace(/\\(i|c|d|e|g|z)/g, '\\\\$1');
 | ||
|         eval('var obj=' + code);
 | ||
|         if (this.checkAsync(obj) && confirm("警告!存在不等待执行完毕的事件但却没有用【等待所有异步事件处理完毕】来等待" +
 | ||
|             "它们执行完毕,这样可能会导致录像检测系统出问题。\n你要返回修改么?")) return;
 | ||
| 
 | ||
|         var _offsetIndex = [editor_blockly.entryType, editor.pos.x, editor.pos.y, editor.currentFloorId].join(":");
 | ||
|         _lastOpenPosition[_offsetIndex] = editor_blockly.workspace.scrollY;
 | ||
|         setvalue(JSON.stringify(obj));
 | ||
|     }
 | ||
| 
 | ||
|     // 检查"不等待处理完毕"
 | ||
|     editor_blockly.checkAsync = function (obj) {
 | ||
|         if (!(obj instanceof Array)) return false;
 | ||
|         var hasAsync = false;
 | ||
|         for (var i = 0; i < obj.length; ++i) {
 | ||
|             var one = obj[i];
 | ||
|             if (one.type == 'if' && (this.checkAsync(one['true']) || this.checkAsync(one['false'])))
 | ||
|                 return true;
 | ||
|             if ((one.type == 'while' || one.type == 'dowhile') && this.checkAsync(one.data))
 | ||
|                 return true;
 | ||
|             if (one.type == 'confirm' && (this.checkAsync(one.yes) || this.checkAsync(one.no)))
 | ||
|                 return true;
 | ||
|             if (one.type == 'choices') {
 | ||
|                 var list = one.choices;
 | ||
|                 if (list instanceof Array) {
 | ||
|                     for (var j = 0; j < list.length; j++) {
 | ||
|                         if (this.checkAsync(list[j].action)) return true;
 | ||
|                     }
 | ||
|                 }
 | ||
|             }
 | ||
|             if (one.type == 'switch') {
 | ||
|                 var list = one.caseList;
 | ||
|                 if (list instanceof Array) {
 | ||
|                     for (var j = 0; j < list.length; j++) {
 | ||
|                         if (this.checkAsync(list[j].action)) return true;
 | ||
|                     }
 | ||
|                 }
 | ||
|             }
 | ||
|             if (one.type == 'wait') {
 | ||
|                 var list = one.data;
 | ||
|                 if (list instanceof Array) {
 | ||
|                     for (var j = 0; j < list.length; j++) {
 | ||
|                         if (this.checkAsync(list[j].action)) return true;
 | ||
|                     }
 | ||
|                 }
 | ||
|             }
 | ||
|             if (one.type == 'previewUI' && this.checkAsync(one.action)) return true;
 | ||
|             if (one.async && one.type != 'animate' && one.type != 'function' && one.type != 'text') hasAsync = true;
 | ||
|             if (one.type == 'waitAsync' || one.type == 'stopAsync') hasAsync = false;
 | ||
|         }
 | ||
|         return hasAsync;
 | ||
|     }
 | ||
| 
 | ||
|     var _isTextAttributeSet = false;
 | ||
| 
 | ||
|     editor_blockly.previewBlock = function (b, args) {
 | ||
| 
 | ||
|         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 name = list[0];
 | ||
|                     var obj = { "type": "drawImage" };
 | ||
|                     if (name.endsWith(":o") || name.endsWith(":x") || name.endsWith(":y")) {
 | ||
|                         obj.reverse = name.substring(name.length - 2);
 | ||
|                         name = name.substring(0, name.length - 2);
 | ||
|                     }
 | ||
|                     obj.image = name;
 | ||
|                     obj.x = parseFloat(list[1]);
 | ||
|                     obj.y = parseFloat(list[2]);
 | ||
|                     if (list.length >= 5) {
 | ||
|                         obj.w = parseFloat(list[3]);
 | ||
|                         obj.h = parseFloat(list[4]);
 | ||
|                     }
 | ||
|                     if (list.length >= 9) {
 | ||
|                         obj.x1 = parseFloat(list[5]);
 | ||
|                         obj.y1 = parseFloat(list[6]);
 | ||
|                         obj.w1 = parseFloat(list[7]);
 | ||
|                         obj.h1 = parseFloat(list[8]);
 | ||
|                     }
 | ||
|                     if (list.length >= 10) {
 | ||
|                         arr.push({ "type": "setAttribute", "alpha": parseFloat(list[9]) });
 | ||
|                     }
 | ||
|                     if (list.length >= 11) {
 | ||
|                         obj.angle = parseFloat(list[10]);
 | ||
|                     }
 | ||
|                     arr.push(obj);
 | ||
|                 }
 | ||
|                 return "";
 | ||
|             });
 | ||
|             editor.uievent.previewUI(arr);
 | ||
|             return true;
 | ||
|         }
 | ||
| 
 | ||
|         try {
 | ||
|             // 特殊处理立绘
 | ||
|             if (b.type == 'textDrawing') {
 | ||
|                 previewTextDrawing(Blockly.JavaScript.blockToCode(b));
 | ||
|                 return true;
 | ||
|             }
 | ||
| 
 | ||
|             var code = "[" + Blockly.JavaScript.blockToCode(b).replace(/\\(i|c|d|e|g|z)/g, '\\\\$1') + "]";
 | ||
|             eval("var obj=" + code);
 | ||
|             if (obj.length == 0) return true;
 | ||
|             obj = obj[0];
 | ||
|             switch (b.type) {
 | ||
|                 case 'text_0_s':
 | ||
|                 case 'text_1_s':
 | ||
|                 case 'text_2_s':
 | ||
|                 case 'choices_s':
 | ||
|                 case 'confirm_s':
 | ||
|                     if (!_isTextAttributeSet) {
 | ||
|                         alert('警告!你尚未设置用于预览的剧情文本的属性,将采用默认属性进行预览。\n你可以双击“设置剧情文本的属性”事件来设置用于预览的属性。');
 | ||
|                         core.status.textAttribute = core.clone(core.initStatus.textAttribute);
 | ||
|                         _isTextAttributeSet = true;
 | ||
|                     }
 | ||
|                     editor.uievent.previewUI([obj]);
 | ||
|                     break;
 | ||
|                 case 'setText_s': // 设置剧情文本的属性
 | ||
|                     _isTextAttributeSet = true;
 | ||
|                     core.status.textAttribute = core.clone(core.initStatus.textAttribute);
 | ||
|                     core.setTextAttribute(obj);
 | ||
|                     alert('已成功设置此属性为显示文章的预览属性!')
 | ||
|                     break;
 | ||
|                 case 'waitContext_2': // 等待用户操作坐标预览
 | ||
|                     editor.uievent.previewUI([{
 | ||
|                         "type": "fillRect", "x": obj.px[0], "y": obj.py[0],
 | ||
|                         "width": "(" + obj.px[1] + ")-(" + obj.px[0] + ")", "height": "(" + obj.py[1] + ")-(" + obj.py[0] + ")",
 | ||
|                         "style": "rgba(255,0,0,0.5)"
 | ||
|                     }]);
 | ||
|                     break;
 | ||
|                 case 'showImage_s': // 显示图片
 | ||
|                 case 'showImage_1_s':
 | ||
|                     if (obj.sloc) {
 | ||
|                         editor.uievent.previewUI([
 | ||
|                             { type: "setAttribute", alpha: obj.opacity },
 | ||
|                             {
 | ||
|                                 type: "drawImage", image: obj.image, x: obj.sloc[0], y: obj.sloc[1], w: obj.sloc[2], h: obj.sloc[3],
 | ||
|                                 x1: obj.loc[0], y1: obj.loc[1], w1: obj.loc[2], h1: obj.loc[3], reverse: obj.reverse
 | ||
|                             }
 | ||
|                         ]);
 | ||
|                     } else {
 | ||
|                         editor.uievent.previewUI([
 | ||
|                             { type: "setAttribute", alpha: obj.opacity },
 | ||
|                             { type: "drawImage", image: obj.image, x: obj.loc[0], y: obj.loc[1], w: obj.loc[2], h: obj.loc[3], reverse: obj.reverse }
 | ||
|                         ]);
 | ||
|                     }
 | ||
|                     break;
 | ||
|                 case 'showGif_s': // 显示动图
 | ||
|                     if (obj.name && obj.loc) {
 | ||
|                         editor.uievent.previewUI([{ type: "drawImage", image: obj.name, x: obj.loc[0], y: obj.loc[1] }]);
 | ||
|                     }
 | ||
|                     break;
 | ||
|                 case 'setCurtain_0_s': // 更改色调
 | ||
|                     if (obj.color) {
 | ||
|                         editor.uievent.previewUI([{ type: "fillRect", x: 0, y: 0, width: core.__PIXELS__, height: core.__PIXELS__, style: obj.color }]);
 | ||
|                     }
 | ||
|                     break;
 | ||
|                 case 'floorOneImage': // 楼层贴图
 | ||
|                     obj.w = obj.w / (obj.frame || 1);
 | ||
|                     editor.uievent.previewUI([
 | ||
|                         {
 | ||
|                             type: "drawImage", image: obj.name, x: obj.sx || 0, y: obj.sy || 0, w: obj.w, h: obj.h,
 | ||
|                             x1: obj.x, y1: obj.y, w1: obj.w, h1: obj.h, reverse: obj.reverse
 | ||
|                         }
 | ||
|                     ]);
 | ||
|                     break;
 | ||
|                 case 'previewUI_s': // 预览
 | ||
|                     editor.uievent.previewUI(obj.action);
 | ||
|                     break;
 | ||
|                 default:
 | ||
|                     if (b.type.startsWith(obj.type)) {
 | ||
|                         editor.uievent.previewUI([obj]);
 | ||
|                     }
 | ||
|             }
 | ||
|         } catch (ee) { console.error(ee) }
 | ||
| 
 | ||
|     }
 | ||
| 
 | ||
|     editor_blockly.selectMaterial = function (b, material) {
 | ||
|         var value = b.getFieldValue(material[1]);
 | ||
|         value = main.nameMap[value] || value;
 | ||
|         editor.uievent.selectMaterial([value], '请选择素材', material[0], function (one) {
 | ||
|             if (b.type == 'animate_s' || b.type == 'animate_1_s' || b.type == 'nameMapAnimate') {
 | ||
|                 return /^[-A-Za-z0-9_.]+\.animate$/.test(one) ? one.substring(0, one.length - 8) : null;
 | ||
|             }
 | ||
|             return /^[-A-Za-z0-9_.]+$/.test(one) ? one : null;
 | ||
|         }, function (value) {
 | ||
|             if (value instanceof Array && value.length > 0) {
 | ||
|                 value = value[0];
 | ||
|                 // 检测是否别名替换
 | ||
|                 for (var name in main.nameMap) {
 | ||
|                     if (main.nameMap[name] == value) {
 | ||
|                         if (confirm("检测到该文件存在别名:" + name + "\n是否使用别名进行替换?")) {
 | ||
|                             b.setFieldValue(name, material[1]);
 | ||
|                             return;
 | ||
|                         } else {
 | ||
|                             break;
 | ||
|                         }
 | ||
|                     }
 | ||
|                 }
 | ||
|                 b.setFieldValue(value, material[1]);
 | ||
|             }
 | ||
|         });
 | ||
|     }
 | ||
| 
 | ||
|     editor_blockly.doubleclicktext = function (b, f) {
 | ||
|         var value = b.getFieldValue(f);
 | ||
|         //多行编辑
 | ||
|         editor_multi.multiLineEdit(value, b, f, { 'lint': f === 'RawEvalString_0' }, function (newvalue, b, f) {
 | ||
|             if (!f.startsWith('EvalString_Multi')) {
 | ||
|                 newvalue = newvalue.split('\n').join('\\n');
 | ||
|             }
 | ||
|             b.setFieldValue(newvalue, f);
 | ||
|         });
 | ||
|     }
 | ||
| 
 | ||
|     editor_blockly.doubleClickBlock = function (blockId) {
 | ||
|         var b = editor_blockly.workspace.getBlockById(blockId);
 | ||
| 
 | ||
|         if (b && MotaActionBlocks[b.type].previewBlock) {
 | ||
|             editor_blockly.previewBlock(b, MotaActionBlocks[b.type].previewBlock)
 | ||
|             return;
 | ||
|         }
 | ||
| 
 | ||
|         if (b && MotaActionBlocks[b.type].selectPoint) { // selectPoint
 | ||
|             editor_blockly.selectPoint(b, eval(MotaActionBlocks[b.type].selectPoint));
 | ||
|             return;
 | ||
|         }
 | ||
| 
 | ||
|         if (b && MotaActionBlocks[b.type].material) {
 | ||
|             editor_blockly.selectMaterial(b, JSON.parse(MotaActionBlocks[b.type].material));
 | ||
|             return;
 | ||
|         }
 | ||
| 
 | ||
|         if (b && MotaActionBlocks[b.type].doubleclicktext) { //多行编辑
 | ||
|             editor_blockly.doubleclicktext(b, MotaActionBlocks[b.type].doubleclicktext);
 | ||
|             return;
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
|     editor_blockly.selectPointFromButton = function () {
 | ||
|         var b = Blockly.selected;
 | ||
|         if (b && MotaActionBlocks[b.type].selectPoint) {
 | ||
|             editor_blockly.selectPoint(b, eval(MotaActionBlocks[b.type].selectPoint));
 | ||
|             return;
 | ||
|         } else {
 | ||
|             editor.uievent.selectPoint();
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
|     editor_blockly.showKeyCodes = function () {
 | ||
|         alert('键值查询表:\nA65 B66 C67 D68 E69 F70 G71 H72 I73 J74 K75 L76 M77\n'
 | ||
|             + 'N78 O79 P80 Q81 R82 S83 T84 U85 V86 W87 X88 Y89 Z90\n0:48 1:49 2:50 3:51 4:52 5:53 6:54 7:55 8:56 9:57\n'
 | ||
|             + '空格:13 回车:32 ESC:27 后退:8 Tab:9 Shift:16 Ctrl:17 Alt:18\nPgUp:33 PgDn:34 左:37 上:38 右:39 下:40\n更多键值请自行百度查表')
 | ||
|     }
 | ||
| 
 | ||
|     editor_blockly.lastUsedType = [
 | ||
|         'text_0_s',
 | ||
|         'comment_s',
 | ||
|         'show_s',
 | ||
|         'hide_s',
 | ||
|         'setValue_s',
 | ||
|         'if_s',
 | ||
|         'while_s',
 | ||
|         'battle_s',
 | ||
|         'openDoor_s',
 | ||
|         'choices_s',
 | ||
|         'setText_s',
 | ||
|         'exit_s',
 | ||
|         'sleep_s',
 | ||
|         'setBlock_s',
 | ||
|         'insert_1_s'
 | ||
|     ]; // 最常用的15个事件
 | ||
|     editor_blockly.lastUsedTypeNum = 15;
 | ||
| 
 | ||
|     editor_blockly.addIntoLastUsedType = function (blockId) {
 | ||
|         var b = editor_blockly.workspace.getBlockById(blockId);
 | ||
|         if (!b) return;
 | ||
|         var blockType = b.type;
 | ||
|         if (!blockType || blockType.indexOf("_s") !== blockType.length - 2 || blockType === 'pass_s') return;
 | ||
|         editor_blockly.lastUsedType = editor_blockly.lastUsedType.filter(function (v) { return v !== blockType; });
 | ||
|         if (editor_blockly.lastUsedType.length >= editor_blockly.lastUsedTypeNum)
 | ||
|             editor_blockly.lastUsedType.pop();
 | ||
|         editor_blockly.lastUsedType.unshift(blockType);
 | ||
| 
 | ||
|         document.getElementById("searchBlock").value = '';
 | ||
|     }
 | ||
| 
 | ||
|     // Index from 1 - 9
 | ||
|     editor_blockly.openToolbox = function (index) {
 | ||
|         if (index < 0) index += editor_blockly.workspace.toolbox_.tree_.children_.length;
 | ||
|         editor_blockly.workspace.toolbox_.tree_.setSelectedItem(editor_blockly.workspace.toolbox_.tree_.children_[index]);
 | ||
|     }
 | ||
|     editor_blockly.reopenToolbox = function (index) {
 | ||
|         if (index < 0) index += editor_blockly.workspace.toolbox_.tree_.children_.length;
 | ||
|         editor_blockly.workspace.toolbox_.tree_.setSelectedItem(editor_blockly.workspace.toolbox_.tree_.children_[index]);
 | ||
|         editor_blockly.workspace.getFlyout().show(editor_blockly.workspace.toolbox_.tree_.children_[index].blocks);
 | ||
|     }
 | ||
| 
 | ||
|     editor_blockly.closeToolbox = function () {
 | ||
|         editor_blockly.workspace.toolbox_.clearSelection();
 | ||
|     }
 | ||
| 
 | ||
|     var searchInput = document.getElementById("searchBlock");
 | ||
|     searchInput.onfocus = function () {
 | ||
|         editor_blockly.reopenToolbox(-1);
 | ||
|     }
 | ||
| 
 | ||
|     searchInput.oninput = function () {
 | ||
|         editor_blockly.reopenToolbox(-1);
 | ||
|     }
 | ||
| 
 | ||
|     editor_blockly.searchBlock = function (value) {
 | ||
|         if (value == null) value = searchInput.value;
 | ||
|         value = value.toLowerCase();
 | ||
|         if (value == '') return editor_blockly.lastUsedType;
 | ||
|         var results = [];
 | ||
|         for (var name in MotaActionBlocks) {
 | ||
|             if (typeof name !== 'string' || name.indexOf("_s") !== name.length - 2) continue;
 | ||
|             var block = MotaActionBlocks[name];
 | ||
|             if (block && block.json) {
 | ||
|                 if ((block.json.type || "").toLowerCase().indexOf(value) >= 0
 | ||
|                     || (block.json.message0 || "").toLowerCase().indexOf(value) >= 0
 | ||
|                     || (block.json.tooltip || "").toLowerCase().indexOf(value) >= 0) {
 | ||
|                     results.push(name);
 | ||
|                     if (results.length >= editor_blockly.lastUsedTypeNum)
 | ||
|                         break;
 | ||
|                 }
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         return results.length == 0 ? editor_blockly.lastUsedType : results;
 | ||
|     }
 | ||
| 
 | ||
|     // ------ select point ------
 | ||
| 
 | ||
|     editor_blockly.selectPoint = function (block, arr) {
 | ||
| 
 | ||
|         var floorId = editor.currentFloorId, pos = editor.pos, x = pos.x, y = pos.y;
 | ||
| 
 | ||
|         var xv = block.getFieldValue(arr[0]), yv = block.getFieldValue(arr[1]);
 | ||
|         if (xv != null) x = xv;
 | ||
|         if (yv != null) y = yv;
 | ||
|         if (arr[2] != null) floorId = block.getFieldValue(arr[2]) || floorId;
 | ||
| 
 | ||
|         editor.uievent.selectPoint(floorId, x, y, false, function (fv, xv, yv) {
 | ||
|             if (!arr) return;
 | ||
|             if (arr[2] != null) {
 | ||
|                 if (fv != editor.currentFloorId || editor_blockly.entryType == 'commonEvent') block.setFieldValue(fv, arr[2]);
 | ||
|                 else block.setFieldValue(arr[3] ? fv : "", arr[2]);
 | ||
|             }
 | ||
|             block.setFieldValue(xv + "", arr[0]);
 | ||
|             block.setFieldValue(yv + "", arr[1]);
 | ||
|             if (block.type == 'changeFloor_m' || block.type == 'changeFloor_s') {
 | ||
|                 block.setFieldValue("floorId", "Floor_List_0");
 | ||
|                 block.setFieldValue("loc", "Stair_List_0");
 | ||
|             }
 | ||
|         });
 | ||
|     }
 | ||
| 
 | ||
|     editor_blockly.getAutoCompletions = function (content, type, name, pb) {
 | ||
|         // --- content为当前框中输入内容;将返回一个列表,为后续所有可补全内容
 | ||
| 
 | ||
|         // console.log(type, name);
 | ||
| 
 | ||
|         // 检查 status:xxx,item:xxx和flag:xxx
 | ||
|         var index = Math.max(content.lastIndexOf(":"), content.lastIndexOf(":"));
 | ||
|         if (index >= 0) {
 | ||
|             var ch = content.charAt(index);
 | ||
|             var before = content.substring(0, index), token = content.substring(index + 1);
 | ||
|             if (/^[a-zA-Z0-9_\u4E00-\u9FCC\u3040-\u30FF\u2160-\u216B\u0391-\u03C9]*$/.test(token)) {
 | ||
|                 if (before.endsWith("状态") || (ch == ':' && before.endsWith("status"))) {
 | ||
|                     var list = Object.keys(core.status.hero);
 | ||
|                     if (before.endsWith("状态") && MotaActionFunctions) {
 | ||
|                         list = MotaActionFunctions.pattern.replaceStatusList.map(function (v) {
 | ||
|                             return v[1];
 | ||
|                         }).concat(list);
 | ||
|                     }
 | ||
|                     return list.filter(function (one) {
 | ||
|                         return one != token && one.startsWith(token);
 | ||
|                     }).sort();
 | ||
|                 }
 | ||
|                 else if (before.endsWith("物品") || (ch == ':' && before.endsWith("item"))) {
 | ||
|                     var list = Object.keys(core.material.items);
 | ||
|                     if (before.endsWith("物品") && MotaActionFunctions) {
 | ||
|                         list = MotaActionFunctions.pattern.replaceItemList.map(function (v) {
 | ||
|                             return v[1];
 | ||
|                         }).concat(list);
 | ||
|                     }
 | ||
|                     return list.filter(function (one) {
 | ||
|                         return one != token && one.startsWith(token);
 | ||
|                     }).sort();
 | ||
|                 }
 | ||
|                 else if (before.endsWith("变量") || (ch == ':' && before.endsWith("flag"))) {
 | ||
|                     return Object.keys(editor.used_flags || {}).filter(function (one) {
 | ||
|                         return one != token && one.startsWith(token);
 | ||
|                     }).sort();
 | ||
|                 } else if (before.endsWith("怪物") || (ch == ':' && before.endsWith("enemy"))) {
 | ||
|                     var list = Object.keys(core.material.enemys);
 | ||
|                     if (before.endsWith("怪物") && MotaActionFunctions) {
 | ||
|                         list = MotaActionFunctions.pattern.replaceEnemyList.map(function (v) {
 | ||
|                             return v[1];
 | ||
|                         }).concat(list);
 | ||
|                     }
 | ||
|                     return list.filter(function (one) {
 | ||
|                         return one != token && one.startsWith(token);
 | ||
|                     })
 | ||
|                 } else {
 | ||
|                     var index2 = Math.max(content.lastIndexOf(":", index - 1), content.lastIndexOf(":", index - 1));
 | ||
|                     var ch2 = content.charAt(index2);
 | ||
|                     if (index2 >= 0) {
 | ||
|                         before = content.substring(0, index2);
 | ||
|                         if (before.endsWith("怪物") || (ch == ':' && ch2 == ':' && before.endsWith("enemy"))) {
 | ||
|                             var list = MotaActionBlocks['EnemyId_List'].options.map(function (v) { return v[1] });
 | ||
|                             if (before.endsWith("怪物") && MotaActionFunctions) {
 | ||
|                                 list = MotaActionFunctions.pattern.replaceEnemyValueList.map(function (v) {
 | ||
|                                     return v[1];
 | ||
|                                 }).concat(list);
 | ||
|                             }
 | ||
|                             return list.filter(function (one) {
 | ||
|                                 return one != token && one.startsWith(token);
 | ||
|                             })
 | ||
|                         }
 | ||
|                     }
 | ||
| 
 | ||
|                 }
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         // 提供 core.xxx 的补全
 | ||
|         index = content.lastIndexOf("core.");
 | ||
|         if (index >= 0) {
 | ||
|             var s = content.substring(index + 5);
 | ||
|             if (/^[\w.]*$/.test(s)) {
 | ||
|                 var tokens = s.split(".");
 | ||
|                 var now = core, prefix = tokens[tokens.length - 1];
 | ||
|                 for (var i = 0; i < tokens.length - 1; ++i) {
 | ||
|                     now = now[tokens[i]];
 | ||
|                     if (now == null) break;
 | ||
|                 }
 | ||
|                 if (now != null) {
 | ||
|                     var candidates = [];
 | ||
|                     for (var i in now) {
 | ||
|                         candidates.push(i);
 | ||
|                     }
 | ||
|                     return candidates.filter(function (one) {
 | ||
|                         return one != prefix && one.startsWith(prefix);
 | ||
|                     }).sort();
 | ||
|                 }
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         // 提供 flags.xxx 补全
 | ||
|         index = content.lastIndexOf("flags.");
 | ||
|         if (index >= 0) {
 | ||
|             var token = content.substring(index + 6);
 | ||
|             return Object.keys(editor.used_flags || {}).filter(function (one) {
 | ||
|                 return one != token && one.startsWith(token)
 | ||
|                     && /^[a-zA-Z_]\w*$/.test(one);
 | ||
|             }).sort();
 | ||
|         }
 | ||
| 
 | ||
|         // 提供 hero.xxx 补全
 | ||
|         index = content.lastIndexOf("hero.");
 | ||
|         if (index >= 0) {
 | ||
|             var token = content.substring(index + 6);
 | ||
|             return Object.keys(core.status.hero).filter(function (one) {
 | ||
|                 return one != token && one.startsWith(token);
 | ||
|             }).sort();
 | ||
|         }
 | ||
| 
 | ||
|         // 提供 IdText_0 的补全
 | ||
|         if (type == 'idIdList_e' && name == 'IdText_0') {
 | ||
|             var list = [];
 | ||
|             switch (pb.getFieldValue('Id_List_0')) {
 | ||
|                 case 'status':
 | ||
|                     list = Object.keys(core.status.hero);
 | ||
|                     if (MotaActionFunctions && replaceCheckbox.checked) {
 | ||
|                         list = MotaActionFunctions.pattern.replaceStatusList.map(function (v) {
 | ||
|                             return v[1];
 | ||
|                         }).concat(list);
 | ||
|                     }
 | ||
|                     break;
 | ||
|                 case 'item':
 | ||
|                     list = Object.keys(core.material.items);
 | ||
|                     if (MotaActionFunctions && replaceCheckbox.checked) {
 | ||
|                         list = MotaActionFunctions.pattern.replaceItemList.map(function (v) {
 | ||
|                             return v[1];
 | ||
|                         }).concat(list);
 | ||
|                     }
 | ||
|                     break;
 | ||
|                 case 'flag':
 | ||
|                     list = Object.keys(editor.used_flags || {});
 | ||
|                     break;
 | ||
|             }
 | ||
|             return list.filter(function (one) {
 | ||
|                 return one != content && one.startsWith(content);
 | ||
|             }).sort();
 | ||
|         }
 | ||
| 
 | ||
|         var namesObj = {};
 | ||
| 
 | ||
|         namesObj.allIds = ["this"].concat(core.getAllIconIds());
 | ||
|         namesObj.allIconIds = namesObj.allIds.concat(Object.keys(core.statusBar.icons).filter(function (x) {
 | ||
|             return core.statusBar.icons[x] instanceof Image;
 | ||
|         }));
 | ||
|         namesObj.allImages = Object.keys(core.material.images.images)
 | ||
|             .concat(Object.keys(main.nameMap).filter(function (one) { return core.material.images.images[main.nameMap[one]]; }));
 | ||
|         namesObj.allEnemys = Object.keys(core.material.enemys);
 | ||
|         if (MotaActionFunctions && !MotaActionFunctions.disableReplace) {
 | ||
|             namesObj.allEnemys = namesObj.allEnemys.concat(MotaActionFunctions.pattern.replaceEnemyList.map(function (x) {
 | ||
|                 return x[1];
 | ||
|             }))
 | ||
|         }
 | ||
|         namesObj.allItems = Object.keys(core.material.items);
 | ||
|         namesObj.allEquips = namesObj.allItems.filter(function (one) { return core.material.items[one].cls == 'equips' });
 | ||
|         if (MotaActionFunctions && !MotaActionFunctions.disableReplace) {
 | ||
|             namesObj.allItems = namesObj.allItems.concat(MotaActionFunctions.pattern.replaceItemList.map(function (x) {
 | ||
|                 return x[1];
 | ||
|             }));
 | ||
|             namesObj.allEquips = namesObj.allEquips.concat(MotaActionFunctions.pattern.replaceItemList.filter(function (x) {
 | ||
|                 return namesObj.allEquips.includes(x[0]);
 | ||
|             }).map(function (x) { return x[1]; }));
 | ||
|         }
 | ||
|         namesObj.allAnimates = Object.keys(core.material.animates)
 | ||
|             .concat(Object.keys(main.nameMap).filter(function (one) { return core.material.animates[main.nameMap[one]]; }));
 | ||
|         namesObj.allBgms = Object.keys(core.material.bgms)
 | ||
|             .concat(Object.keys(main.nameMap).filter(function (one) { return core.material.bgms[main.nameMap[one]]; }));
 | ||
|         namesObj.allSounds = Object.keys(core.material.sounds)
 | ||
|             .concat(Object.keys(main.nameMap).filter(function (one) { return core.material.sounds[main.nameMap[one]]; }));;
 | ||
|         namesObj.allShops = Object.keys(core.status.shops);
 | ||
|         namesObj.allFloorIds = core.floorIds;
 | ||
|         namesObj.allColors = ["aqua(青色)", "black(黑色)", "blue(蓝色)", "fuchsia(品红色)", "gray(灰色)", "green(深绿色)", "lime(绿色)",
 | ||
|             "maroon(深红色)", "navy(深蓝色)", "gold(金色)", "olive(黄褐色)", "orange(橙色)", "purple(品红色)",
 | ||
|             "red(红色)", "silver(淡灰色)", "teal(深青色)", "white(白色)", "yellow(黄色)"];
 | ||
|         namesObj.allFonts = [main.styles.font].concat(main.fonts);
 | ||
|         namesObj.allDoors = ["this"].concat(Object.keys(maps_90f36752_8815_4be8_b32b_d7fad1d0542e)
 | ||
|             .map(function (key) { return maps_90f36752_8815_4be8_b32b_d7fad1d0542e[key]; })
 | ||
|             .filter(function (one) { return one.doorInfo != null; })
 | ||
|             .map(function (one) { return one.id; }));
 | ||
|         namesObj.allEvents = Object.keys(core.events.commonEvent);
 | ||
|         var filter = function (list, content) {
 | ||
|             return list.filter(function (one) {
 | ||
|                 return one != content && one.startsWith(content);
 | ||
|             }).sort();
 | ||
|         }
 | ||
| 
 | ||
|         // 对任意图块提供补全
 | ||
|         // 对怪物ID提供补全
 | ||
|         // 对道具ID进行补全
 | ||
|         // 对图片名进行补全
 | ||
|         // 对动画进行补全
 | ||
|         // 对音乐进行补全
 | ||
|         // 对音效进行补全
 | ||
|         // 对全局商店进行补全
 | ||
|         // 对楼层名进行补全
 | ||
|         for (var ii = 0, names; names = ['allIds', 'allEnemys', 'allItems', 'allEquips', 'allImages', 'allAnimates', 'allBgms', 'allSounds', 'allShops', 'allFloorIds', 'allDoors', 'allEvents'][ii]; ii++) {
 | ||
|             if (MotaActionBlocks[type][names] && eval(MotaActionBlocks[type][names]).indexOf(name) !== -1) {
 | ||
|                 return filter(namesObj[names], content);
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         // 对\f进行自动补全
 | ||
|         index = Math.max(content.lastIndexOf("\f["), content.lastIndexOf("\\f["));
 | ||
|         if (index >= 0) {
 | ||
|             if (content.charAt(index) == '\\') index++;
 | ||
|             var after = content.substring(index + 2);
 | ||
|             if (after.indexOf(",") < 0 && after.indexOf("]") < 0) {
 | ||
|                 return filter(namesObj.allImages, after);
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         // 对\\i进行补全
 | ||
|         index = content.lastIndexOf("\\i[");
 | ||
|         if (index >= 0) {
 | ||
|             var after = content.substring(index + 3);
 | ||
|             if (after.indexOf("]") < 0) {
 | ||
|                 return filter(namesObj.allIconIds, after);
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         // 对\r进行补全
 | ||
|         index = Math.max(content.lastIndexOf("\r["), content.lastIndexOf("\\r["));
 | ||
|         if (index >= 0) {
 | ||
|             if (content.charAt(index) == '\\') index++;
 | ||
|             var after = content.substring(index + 2);
 | ||
|             if (after.indexOf("]") < 0) {
 | ||
|                 return filter(namesObj.allColors, after);
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         // 对\g进行补全
 | ||
|         index = content.lastIndexOf("\\g[");
 | ||
|         if (index >= 0) {
 | ||
|             var after = content.substring(index + 3);
 | ||
|             if (after.indexOf("]") < 0) {
 | ||
|                 return filter(namesObj.allFonts, after);
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         // 对\进行补全!
 | ||
|         if (content.charAt(content.length - 1) == '\\') {
 | ||
|             return ["n(换行)", "f(立绘)", "r(变色)", "i(图标)", "z(暂停打字)", "t(标题图标)", "b(对话框)", "c(字体大小)", "d(粗体)", "e(斜体)", "g(字体)"];
 | ||
|         }
 | ||
| 
 | ||
|         return [];
 | ||
|     }
 | ||
| 
 | ||
|     editor_blockly.completeItems = [];
 | ||
| 
 | ||
|     editor_blockly.onTextFieldCreate = function (self, htmlInput) {
 | ||
|         var pb = self.sourceBlock_
 | ||
|         var args = MotaActionBlocks[pb.type].args
 | ||
|         var targetf = args[args.indexOf(self.name) + 1]
 | ||
| 
 | ||
|         // ------ colour
 | ||
| 
 | ||
|         if (targetf && targetf.slice(0, 7) === 'Colour_') {
 | ||
|             var inputDom = htmlInput;
 | ||
|             // var getValue=function(){ // 获得自己的字符串
 | ||
|             //     return pb.getFieldValue(self.name);
 | ||
|             // }
 | ||
|             var setValue = function (newValue) { // 设置右边颜色块的css颜色
 | ||
|                 pb.setFieldValue(newValue, targetf)
 | ||
|             }
 | ||
|             // 给inputDom绑事件
 | ||
|             inputDom.oninput = function () {
 | ||
|                 var value = inputDom.value
 | ||
|                 if (/^[0-9 ]+,[0-9 ]+,[0-9 ]+(,[0-9. ]+)?$/.test(value)) {
 | ||
|                     setValue('rgba(' + value + ')')
 | ||
|                 }
 | ||
|             }
 | ||
|         }
 | ||
|         else {
 | ||
| 
 | ||
|             htmlInput.onkeydown = function (e) {
 | ||
|                 if (e.keyCode == 13 && awesomplete.opened && awesomplete.selected) {
 | ||
|                     e.stopPropagation();
 | ||
|                     e.stopImmediatePropagation();
 | ||
|                     e.preventDefault();
 | ||
|                     awesomplete.select();
 | ||
|                     return false;
 | ||
|                 }
 | ||
|             }
 | ||
| 
 | ||
|             // --- awesomplete
 | ||
|             var awesomplete = new Awesomplete(htmlInput, {
 | ||
|                 minChars: 1,
 | ||
|                 maxItems: 12,
 | ||
|                 autoFirst: true,
 | ||
|                 replace: function (text) {
 | ||
|                     text = text.toString();
 | ||
|                     var index = text.indexOf("(");
 | ||
|                     if (index >= 0) text = text.substring(0, index);
 | ||
|                     var value = this.input.value, index = this.input.selectionEnd;
 | ||
|                     if (index == null) index = value.length;
 | ||
|                     if (index < awesomplete.prefix.length) index = awesomplete.prefix.length;
 | ||
|                     var str = value.substring(0, index - awesomplete.prefix.length) + text + value.substring(index);
 | ||
|                     this.input.value = str;
 | ||
|                     pb.setFieldValue(str, self.name);
 | ||
|                     self.forceRerender();
 | ||
|                     self.resizeEditor_();
 | ||
|                     index += text.length - awesomplete.prefix.length;
 | ||
|                     this.input.setSelectionRange(index, index);
 | ||
| 
 | ||
|                     editor_blockly.completeItems = editor_blockly.completeItems.filter(function (x) {
 | ||
|                         return x != text;
 | ||
|                     });
 | ||
|                     editor_blockly.completeItems.unshift(text);
 | ||
|                 },
 | ||
|                 filter: function () { return true; },
 | ||
|                 item: function (text, input) {
 | ||
|                     var id = text.label, info = core.getBlockInfo(id);
 | ||
|                     var li = document.createElement("li");
 | ||
|                     li.setAttribute("role", "option");
 | ||
|                     li.setAttribute("aria-selected", "false");
 | ||
|                     input = awesomplete.prefix.trim();
 | ||
|                     if (input != "") text = text.replace(new RegExp("^" + input, "i"), "<mark>$&</mark>");
 | ||
|                     li.innerHTML = text;
 | ||
|                     if (info) {
 | ||
|                         var height = (info.height || 32), width = 32;
 | ||
|                         var scale = 75;
 | ||
|                         height *= scale / 100;
 | ||
|                         width *= scale / 100;
 | ||
|                         var ctx = core.createCanvas('list_' + id, 0, 0, width, height),
 | ||
|                             canvas = ctx.canvas;
 | ||
|                         canvas.style.display = 'inline';
 | ||
|                         canvas.style.marginRight = '8px';
 | ||
|                         core.drawIcon(ctx, id, 0, 0, width, height);
 | ||
|                         canvas.style.position = '';
 | ||
|                         li.insertBefore(canvas, li.children[0]);
 | ||
|                     }
 | ||
|                     return li;
 | ||
|                 },
 | ||
|                 sort: function (a, b) {
 | ||
|                     a = a.toString(); b = b.toString();
 | ||
|                     var ia = editor_blockly.completeItems.indexOf(a), ib = editor_blockly.completeItems.indexOf(b);
 | ||
|                     if (ia < 0) ia = editor_blockly.completeItems.length;
 | ||
|                     if (ib < 0) ib = editor_blockly.completeItems.length;
 | ||
|                     if (ia != ib) return ia - ib;
 | ||
|                     if (a.length != b.length) return a.length - b.length;
 | ||
|                     return a < b ? -1 : 1;
 | ||
|                 }
 | ||
|             });
 | ||
| 
 | ||
|             htmlInput.oninput = function () {
 | ||
|                 var value = htmlInput.value, index = htmlInput.selectionEnd;
 | ||
|                 if (index == null) index = value.length;
 | ||
|                 value = value.substring(0, index);
 | ||
|                 // cal prefix
 | ||
|                 awesomplete.prefix = value;
 | ||
|                 for (var i = index - 1; i >= 0; i--) {
 | ||
|                     var c = value.charAt(i);
 | ||
|                     if (!/^[a-zA-Z0-9_\u4E00-\u9FCC\u3040-\u30FF\u2160-\u216B\u0391-\u03C9]$/.test(c)) {
 | ||
|                         awesomplete.prefix = value.substring(i + 1);
 | ||
|                         break;
 | ||
|                     }
 | ||
|                 }
 | ||
| 
 | ||
|                 var list = editor_blockly.getAutoCompletions(value, pb.type, self.name, pb);
 | ||
| 
 | ||
|                 awesomplete.list = list;
 | ||
|                 var caretPosition = getCaretCoordinates(htmlInput, htmlInput.selectionStart);
 | ||
|                 awesomplete.ul.style.marginLeft = caretPosition.left - htmlInput.scrollLeft - 20 + "px";
 | ||
|                 var totalHeight = parseFloat(Blockly.WidgetDiv.DIV.style.height.replace('px', ''));
 | ||
|                 awesomplete.ul.style.marginTop = caretPosition.top + caretPosition.height - totalHeight + 10 + 'px';
 | ||
|                 awesomplete.evaluate();
 | ||
|             }
 | ||
| 
 | ||
|             awesomplete.container.style.width = "100%";
 | ||
| 
 | ||
|             window.awesomplete = awesomplete;
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
|     editor_blockly.isBlockCollapsedSupported = function (block) {
 | ||
|         var supportedDisabledBlocks = [
 | ||
|             'text_0_s', 'text_1_s', 'text_2_s', 'if_s', 'if_1_s', 'confirm_s', 'switch_s', 'choices_s',
 | ||
|             'for_s', 'forEach_s', 'while_s', 'dowhile_s', 'wait_s', 'previewUI_s',
 | ||
|             'waitContext_1', 'waitContext_2', 'waitContext_3', 'switchCase', 'choicesContext'
 | ||
|         ];
 | ||
|         return supportedDisabledBlocks.indexOf(block.type || "") >= 0;
 | ||
|     }
 | ||
| 
 | ||
|     return editor_blockly;
 | ||
| }
 | ||
| 
 | ||
| // --- modify Blockly
 | ||
| 
 | ||
| Blockly.FieldColour.prototype.showEditor_ = function () {
 | ||
|     Blockly.WidgetDiv.hide();
 | ||
| 
 | ||
|     // console.log('here')
 | ||
|     var self = this;
 | ||
|     var pb = self.sourceBlock_
 | ||
|     var args = MotaActionBlocks[pb.type].args
 | ||
|     var targetf = args[args.indexOf(self.name) - 1]
 | ||
| 
 | ||
|     var getValue = function () {
 | ||
|         // return self.getValue() // css颜色
 | ||
|         var f = pb.getFieldValue(targetf);
 | ||
|         if (/^[0-9 ]+,[0-9 ]+,[0-9 ]+(,[0-9. ]+)?$/.test(f)) {
 | ||
|             return f;
 | ||
|         }
 | ||
|         return "";
 | ||
|         // 也可以用 pb.getFieldValue(targetf) 获得颜色块左边的域的内容
 | ||
|     }
 | ||
| 
 | ||
|     var setValue = function (newValue) { // css颜色
 | ||
|         self.setValue(newValue)
 | ||
|         pb.setFieldValue(newValue.replace("rgba(", "").replace(")", ""), targetf) // 放在颜色块左边的域中
 | ||
|     }
 | ||
| 
 | ||
|     setTimeout(function () {
 | ||
|         document.getElementById("colorPicker").value = getValue();
 | ||
|         // 设置位置
 | ||
|         var scaledBBox = self.getScaledBBox();
 | ||
|         openColorPicker(scaledBBox.left, scaledBBox.bottom, setValue);
 | ||
|     });
 | ||
| 
 | ||
|     return document.createElement('table');
 | ||
| };
 | ||
| 
 | ||
| Blockly.FieldColour.prototype.setValue = function (colour) {
 | ||
|     this.doValueUpdate_(colour);
 | ||
| }
 | ||
| 
 | ||
| Blockly.FieldColour.prototype.initView = function () {
 | ||
|     this.size_ = new Blockly.utils.Size(
 | ||
|         this.getConstants().FIELD_COLOUR_DEFAULT_WIDTH,
 | ||
|         this.getConstants().FIELD_COLOUR_DEFAULT_HEIGHT);
 | ||
|     if (!this.getConstants().FIELD_COLOUR_FULL_BLOCK) {
 | ||
|         this.createBorderRect_();
 | ||
|         this.borderRect_.style['fillOpacity'] = '1';
 | ||
|         this.borderRect_.classList.add('blocklyColourFieldRect');
 | ||
|     } else {
 | ||
|         this.clickTarget_ = this.sourceBlock_.getSvgRoot();
 | ||
|     }
 | ||
| };
 | ||
| 
 | ||
| Blockly.FieldTextInput.prototype.showInlineEditor_ = function (quietInput) {
 | ||
|     Blockly.WidgetDiv.show(
 | ||
|         this, this.sourceBlock_.RTL, this.widgetDispose_.bind(this));
 | ||
|     this.htmlInput_ = this.widgetCreate_();
 | ||
|     this.isBeingEdited_ = true;
 | ||
| 
 | ||
|     editor_blockly.onTextFieldCreate(this, this.htmlInput_);
 | ||
| 
 | ||
|     if (!quietInput) {
 | ||
|         this.htmlInput_.focus({ preventScroll: true });
 | ||
|         this.htmlInput_.select();
 | ||
|     }
 | ||
| };
 | ||
| 
 | ||
| Blockly.FieldTextInput.prototype.onHtmlInputKeyDown_ = function (e) {
 | ||
|     if (e.keyCode == Blockly.utils.KeyCodes.ENTER && !(window.awesomplete && window.awesomplete.opened)) {
 | ||
|         Blockly.WidgetDiv.hide();
 | ||
|         Blockly.DropDownDiv.hideWithoutAnimation();
 | ||
|     } else if (e.keyCode == Blockly.utils.KeyCodes.ESC) {
 | ||
|         this.htmlInput_.value = this.htmlInput_.defaultValue;
 | ||
|         Blockly.WidgetDiv.hide();
 | ||
|         Blockly.DropDownDiv.hideWithoutAnimation();
 | ||
|     } else if (e.keyCode == Blockly.utils.KeyCodes.TAB) {
 | ||
|         Blockly.WidgetDiv.hide();
 | ||
|         Blockly.DropDownDiv.hideWithoutAnimation();
 | ||
|         this.sourceBlock_.tab(this, !e.shiftKey);
 | ||
|         e.preventDefault();
 | ||
|     }
 | ||
| };
 | ||
| 
 | ||
| Blockly.FieldMultilineInput.prototype.showInlineEditor_ = function (quietInput) {
 | ||
|     Blockly.FieldMultilineInput.superClass_.showInlineEditor_.call(this, quietInput);
 | ||
|     // force to resize the input
 | ||
|     this.htmlInput_.style.height = Blockly.WidgetDiv.DIV.style.height;
 | ||
| };
 | ||
| 
 | ||
| Blockly.FieldMultilineInput.prototype.onHtmlInputChange_ = function (e) {
 | ||
|     Blockly.FieldMultilineInput.superClass_.onHtmlInputChange_.call(this, e);
 | ||
|     // force to resize the input
 | ||
|     this.htmlInput_.style.height = Blockly.WidgetDiv.DIV.style.height;
 | ||
| };
 | ||
| 
 | ||
| Blockly.copy_ = function (toCopy) {
 | ||
|     if (toCopy.isComment) {
 | ||
|         var xml = toCopy.toXmlWithXY();
 | ||
|     } else {
 | ||
|         var xml = Blockly.Xml.blockToDom(toCopy, true);
 | ||
|         // Copy only the selected block and internal blocks.
 | ||
|         Blockly.Xml.deleteNext(xml);
 | ||
|         // Encode start position in XML.
 | ||
|         var xy = toCopy.getRelativeToSurfaceXY();
 | ||
|         xml.setAttribute('x', toCopy.RTL ? -xy.x : xy.x);
 | ||
|         xml.setAttribute('oy', xy.y);
 | ||
|         xml.setAttribute('sy', toCopy.workspace.scrollY);
 | ||
|     }
 | ||
|     Blockly.clipboardXml_ = xml;
 | ||
|     Blockly.clipboardSource_ = toCopy.workspace;
 | ||
|     Blockly.clipboardTypeCounts_ = toCopy.isComment ? null :
 | ||
|         Blockly.utils.getBlockTypeCounts(toCopy, true);
 | ||
| };
 | ||
| 
 | ||
| /**
 | ||
|  * Paste the provided block onto the workspace.
 | ||
|  * @param {!Element} xmlBlock XML block element.
 | ||
|  */
 | ||
| Blockly.WorkspaceSvg.prototype.paste = function (xmlBlock) {
 | ||
|     if (!this.rendered || xmlBlock.getElementsByTagName('block').length >=
 | ||
|         this.remainingCapacity()) {
 | ||
|         return;
 | ||
|     }
 | ||
|     if (this.currentGesture_) {
 | ||
|         this.currentGesture_.cancel();  // Dragging while pasting?  No.
 | ||
|     }
 | ||
|     if (xmlBlock.tagName.toLowerCase() == 'comment') {
 | ||
|         this.pasteWorkspaceComment_(xmlBlock);
 | ||
|     } else {
 | ||
|         if (xmlBlock.hasAttribute('oy') && xmlBlock.hasAttribute('sy')) {
 | ||
|             xmlBlock.setAttribute('y', parseFloat(xmlBlock.getAttribute('oy')) + parseFloat(xmlBlock.getAttribute('sy')) - this.scrollY);
 | ||
|         }
 | ||
|         this.pasteBlock_(xmlBlock);
 | ||
|     }
 | ||
| };
 | ||
| 
 | ||
| // -- Support showing disabled blocks
 | ||
| 
 | ||
| Blockly.Generator.prototype.blockToCode = function (block, opt_thisOnly) {
 | ||
|     if (this.isInitialized === false) {
 | ||
|         console.warn(
 | ||
|             'Generator init was not called before blockToCode was called.');
 | ||
|     }
 | ||
|     if (!block) {
 | ||
|         return '';
 | ||
|     }
 | ||
|     if (!block.isEnabled() && !editor_blockly.isBlockCollapsedSupported(block)) {
 | ||
|         // Skip past this block if it is disabled.
 | ||
|         return opt_thisOnly ? '' : this.blockToCode(block.getNextBlock());
 | ||
|     }
 | ||
|     if (block.isInsertionMarker()) {
 | ||
|         // Skip past insertion markers.
 | ||
|         return opt_thisOnly ? '' : this.blockToCode(block.getChildren(false)[0]);
 | ||
|     }
 | ||
| 
 | ||
|     var func = this[block.type];
 | ||
|     if (typeof func != 'function') {
 | ||
|         throw Error('Language "' + this.name_ + '" does not know how to generate ' +
 | ||
|             'code for block type "' + block.type + '".');
 | ||
|     }
 | ||
|     // First argument to func.call is the value of 'this' in the generator.
 | ||
|     // Prior to 24 September 2013 'this' was the only way to access the block.
 | ||
|     // The current preferred method of accessing the block is through the second
 | ||
|     // argument to func.call, which becomes the first parameter to the generator.
 | ||
|     var code = func.call(block, block);
 | ||
|     if (Array.isArray(code)) {
 | ||
|         // Value blocks return tuples of code and operator order.
 | ||
|         if (!block.outputConnection) {
 | ||
|             throw TypeError('Expecting string from statement block: ' + block.type);
 | ||
|         }
 | ||
|         return [this.scrub_(block, code[0], opt_thisOnly), code[1]];
 | ||
|     } else if (typeof code == 'string') {
 | ||
|         if (this.STATEMENT_PREFIX && !block.suppressPrefixSuffix) {
 | ||
|             code = this.injectId(this.STATEMENT_PREFIX, block) + code;
 | ||
|         }
 | ||
|         if (this.STATEMENT_SUFFIX && !block.suppressPrefixSuffix) {
 | ||
|             code = code + this.injectId(this.STATEMENT_SUFFIX, block);
 | ||
|         }
 | ||
|         return this.scrub_(block, code, opt_thisOnly);
 | ||
|     } else if (code === null) {
 | ||
|         // Block has handled code generation itself.
 | ||
|         return '';
 | ||
|     }
 | ||
|     throw SyntaxError('Invalid code generated: ' + code);
 | ||
| };
 | ||
| 
 | ||
| Blockly.BlockSvg.prototype.generateContextMenu = function () {
 | ||
|     if (this.workspace.options.readOnly || !this.contextMenu) {
 | ||
|         return null;
 | ||
|     }
 | ||
|     // Save the current block in a variable for use in closures.
 | ||
|     var block = this;
 | ||
|     var menuOptions = [];
 | ||
| 
 | ||
|     if (!this.isInFlyout) {
 | ||
|         // 删除
 | ||
|         if (this.isDeletable() && this.isMovable()) {
 | ||
|             menuOptions.push(Blockly.ContextMenu.blockDuplicateOption(block));
 | ||
|         }
 | ||
| 
 | ||
|         if (editor_blockly.isBlockCollapsedSupported(this)) {
 | ||
|             menuOptions.push({
 | ||
|                 text: this.isCollapsed() ? Blockly.Msg['EXPAND_BLOCK'] : Blockly.Msg['COLLAPSE_BLOCK'],
 | ||
|                 enabled: true,
 | ||
|                 callback: function () { block.setCollapsed(!block.collapsed_); }
 | ||
|             });
 | ||
| 
 | ||
|             menuOptions.push({
 | ||
|                 text: this.isEnabled() ? Blockly.Msg['DISABLE_BLOCK'] : Blockly.Msg['ENABLE_BLOCK'],
 | ||
|                 enabled: !this.getInheritedDisabled(),
 | ||
|                 callback: function () {
 | ||
|                     var group = Blockly.Events.getGroup();
 | ||
|                     if (!group) {
 | ||
|                         Blockly.Events.setGroup(true);
 | ||
|                     }
 | ||
|                     block.setEnabled(!block.isEnabled());
 | ||
|                     if (!group) {
 | ||
|                         Blockly.Events.setGroup(false);
 | ||
|                     }
 | ||
|                 }
 | ||
|             });
 | ||
|         }
 | ||
|         if (this.isDeletable()) {
 | ||
|             menuOptions.push(Blockly.ContextMenu.blockDeleteOption(block));
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
|     menuOptions.push(Blockly.ContextMenu.blockHelpOption(block));
 | ||
|     if (this.customContextMenu) this.customContextMenu(menuOptions);
 | ||
|     return menuOptions;
 | ||
| };
 | ||
| 
 | ||
| Blockly.FieldDropdown.prototype.doClassValidation_ = function (opt_newValue) {
 | ||
|     return opt_newValue;
 | ||
| }
 | ||
| 
 | ||
| Blockly.FieldDropdown.prototype.doValueUpdate_ = function (newValue) {
 | ||
|     Blockly.FieldDropdown.superClass_.doValueUpdate_.call(this, newValue);
 | ||
|     var options = this.getOptions(true);
 | ||
|     for (var i = 0, option; (option = options[i]); i++) {
 | ||
|         if (option[1] == this.value_) {
 | ||
|             this.selectedOption_ = option;
 | ||
|         }
 | ||
|     }
 | ||
|     if (this.selectedOption_[1] != this.value_) {
 | ||
|         options.push([this.value_, this.value_]);
 | ||
|         this.selectedOption_ = options[options.length - 1];
 | ||
|     }
 | ||
| };
 | ||
| 
 | ||
| Blockly.FieldMultilineInput.prototype.getDisplayText_ = function () {
 | ||
|     var value = this.value_;
 | ||
|     if (!value) return Blockly.Field.NBSP;
 | ||
|     var curr = '', text = '';
 | ||
|     for (var i = 0; i < value.length; ++i) {
 | ||
|         if (value[i] == '\n' || curr.length == this.maxDisplayLength) {
 | ||
|             text += curr.replace(/\s/g, Blockly.Field.NBSP) + '\n';
 | ||
|             curr = value[i] == '\n' ? '' : value[i];
 | ||
|         } else curr += value[i];
 | ||
|     }
 | ||
|     return text + curr;
 | ||
| };
 |