tianta/_server/editor_blockly.js

1231 lines
52 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 { '<': '&lt;', '>': '&gt;', '&': '&amp;' }[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 'showImage2_s': // 显示图片
case 'showImage2_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] - 160, 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] - 160, 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:xxxitem: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;
};