添加for/forEach事件

This commit is contained in:
ckcz123 2020-05-08 15:13:47 +08:00
parent 21f9016b89
commit 78f4210eb7
7 changed files with 131 additions and 19 deletions

View File

@ -287,7 +287,7 @@ core.closePanel()
结束一切事件和绘制关闭UI窗口返回游戏进程。
core.replaceText(text)
core.replaceText(text, prefix, need, times)
将一段文字中的${}进行计算并替换。

View File

@ -1,3 +1,5 @@
// 编辑此文件用的vscode插件: https://marketplace.visualstudio.com/items?itemName=zhaouv.vscode-mota-js-extension
grammar MotaAction;
//===============parser===============
@ -400,6 +402,8 @@ action
| if_s
| if_1_s
| switch_s
| for_s
| forEach_s
| while_s
| dowhile_s
| break_s
@ -1936,6 +1940,35 @@ var code = ['{"type": "confirm"'+Int_0+Bool_0+', "text": "',EvalString_0,'",\n',
return code;
*/;
for_s
: '循环遍历' ': ' expression '从' EvalString '到' EvalString '步增' EvalString BGNL? Newline action+ BEND Newline
/* for_s
tooltip : for循环遍历
helpUrl : https://h5mota.com/games/template/_docs/#/event?id=while%ef%bc%9a%e5%89%8d%e7%bd%ae%e6%9d%a1%e4%bb%b6%e5%be%aa%e7%8e%af
colour : this.eventColor
if (!/^switch:[A-Z]$/.test(expression_0)) {
throw new Error('循环遍历仅允许使用独立开关!');
}
return '{"type": "for", "name": "'+expression_0+'", "from": "'+EvalString_0+'", "to": "'+EvalString_1+'", "step": "'+EvalString_2+'",\n"data": [\n'+action_0+']},\n';
*/;
forEach_s
: '循环遍历' ': ' expression '在列表' JsonEvalString '中' BGNL? Newline action+ BEND Newline
/* forEach_s
tooltip : forEach循环遍历列表
helpUrl : https://h5mota.com/games/template/_docs/#/event?id=while%ef%bc%9a%e5%89%8d%e7%bd%ae%e6%9d%a1%e4%bb%b6%e5%be%aa%e7%8e%af
colour : this.eventColor
if (!/^switch:[A-Z]$/.test(expression_0)) {
throw new Error('循环遍历仅允许使用独立开关!');
}
if (JsonEvalString_0 == '' || !(JSON.parse(JsonEvalString_0) instanceof Array)) {
throw new Error('参数列表必须是个有效的数组!');
}
return '{"type": "forEach", "name": "'+expression_0+'", "list": '+JsonEvalString_0 + ',\n"data": [\n'+action_0+']},\n';
*/;
while_s
: '前置条件循环' '' '当' expression '时' BGNL? Newline action+ BEND Newline
@ -3529,16 +3562,30 @@ ActionParser.prototype.parseAction = function() {
this.next = MotaActionBlocks['choices_s'].xmlText([
info[3],info[0],info[1],data.timeout||0,text_choices,this.next]);
break;
case "for": // 循环遍历
this.next = MotaActionBlocks['for_s'].xmlText([
this.tryToUseEvFlag_e('evalString_e', [data.name]),
data.from || 0, data.to || 0, data.step || 0,
this.insertActionList(data.data),
this.next]);
break;
case "forEach": // 循环遍历列表
this.next = MotaActionBlocks['forEach_s'].xmlText([
this.tryToUseEvFlag_e('evalString_e', [data.name]),
JSON.stringify(data.list),
this.insertActionList(data.data),
this.next]);
break;
case "while": // 前置条件循环处理
this.next = MotaActionBlocks['while_s'].xmlText([
// MotaActionBlocks['evalString_e'].xmlText([data.condition]),
this.tryToUseEvFlag_e('evalString_e', [data.condition]),
this.insertActionList(data["data"]),
this.insertActionList(data.data),
this.next]);
break;
case "dowhile": // 后置条件循环处理
this.next = MotaActionBlocks['dowhile_s'].xmlText([
this.insertActionList(data["data"]),
this.insertActionList(data.data),
// MotaActionBlocks['evalString_e'].xmlText([data.condition]),
this.tryToUseEvFlag_e('evalString_e', [data.condition]),
this.next]);

View File

@ -93,9 +93,6 @@ editor_blockly = function () {
MotaActionBlocks['choices_s'].xmlText([
'选择剑或者盾','流浪者','man',0,MotaActionBlocks['choicesContext'].xmlText([
'剑','','',null,'',MotaActionFunctions.actionParser.parseList([{"type": "openDoor", "loc": [3,3]}]),
MotaActionBlocks['choicesContext'].xmlText([
'盾','','',null,'',MotaActionFunctions.actionParser.parseList([{"type": "openDoor", "loc": [9,3]}]),
])
])
]),
],
@ -149,9 +146,10 @@ editor_blockly = function () {
MotaActionBlocks['if_s'].xmlText(),
MotaActionFunctions.actionParser.parseList({"type": "switch", "condition": "判别值", "caseList": [
{"action": [{"type": "comment", "text": "当判别值是值的场合执行此事件"}]},
{"action": [], "nobreak": true},
{"case": "default", "action": [{"type": "comment", "text": "当没有符合的值的场合执行default事件"}]},
]}),
MotaActionFunctions.actionParser.parseList({"type": "for", "name": "switch:A", "from": "0", "to": "12", "step": "1", "data": []}),
MotaActionFunctions.actionParser.parseList({"type": "forEach", "name": "switch:A", "list": ["status:atk","status:def"], "data": []}),
MotaActionBlocks['while_s'].xmlText(),
MotaActionBlocks['dowhile_s'].xmlText(),
MotaActionBlocks['break_s'].xmlText(),

View File

@ -1210,17 +1210,20 @@ events.prototype.__action_doAsyncFunc = function (isAsync, func) {
events.prototype._action_text = function (data, x, y, prefix) {
if (this.__action_checkReplaying()) return;
data.text = core.replaceText(data.text, prefix);
core.ui.drawTextBox(data.text, data.showAll);
}
events.prototype._action_autoText = function (data, x, y, prefix) {
if (this.__action_checkReplaying()) return;
data.text = core.replaceText(data.text, prefix);
core.ui.drawTextBox(data.text);
setTimeout(core.doAction, data.time || 3000);
}
events.prototype._action_scrollText = function (data, x, y, prefix) {
if (this.__action_checkReplaying()) return;
data.text = core.replaceText(data.text, prefix);
this.__action_doAsyncFunc(data.async, core.drawScrollText, data.text, data.time || 5000, data.lineHeight || 1.4);
}
@ -1250,7 +1253,7 @@ events.prototype._action_setText = function (data, x, y, prefix) {
}
events.prototype._action_tip = function (data, x, y, prefix) {
core.drawTip(core.replaceText(data.text), data.icon);
core.drawTip(core.replaceText(data.text, prefix), data.icon);
core.doAction();
}
@ -1412,6 +1415,7 @@ events.prototype._precompile_showImage = function (data) {
events.prototype._action_showTextImage = function (data, x, y, prefix) {
var loc = this.__action_getLoc(data.loc, 0, 0, prefix);
if (core.isReplaying()) data.time = 0;
data.text = core.replaceText(data.text, prefix);
this.__action_doAsyncFunc(data.async || data.time == 0, core.showImage,
data.code, core.ui.textImage(data.text), null, loc, data.opacity, data.time);
}
@ -1676,7 +1680,7 @@ events.prototype._action_setHeroIcon = function (data, x, y, prefix) {
}
events.prototype._action_input = function (data, x, y, prefix) {
this.__action_getInput(data.text, false, function (value) {
this.__action_getInput(core.replaceText(data.text, prefix), false, function (value) {
value = Math.abs(parseInt(value) || 0);
core.status.route.push("input:" + value);
core.setFlag("input", value);
@ -1685,7 +1689,7 @@ events.prototype._action_input = function (data, x, y, prefix) {
}
events.prototype._action_input2 = function (data, x, y, prefix) {
this.__action_getInput(data.text, true, function (value) {
this.__action_getInput(core.replaceText(data.text, prefix), true, function (value) {
value = value || "";
core.status.route.push("input2:" + core.encodeBase64(value));
core.setFlag("input", value);
@ -1782,7 +1786,7 @@ events.prototype._action_choices = function (data, x, y, prefix) {
core.doAction();
}, data.timeout);
}
core.ui.drawChoices(data.text, data.choices);
core.ui.drawChoices(core.replaceText(data.text, prefix), data.choices);
}
events.prototype._precompile_choices = function (data) {
@ -1796,7 +1800,7 @@ events.prototype._precompile_choices = function (data) {
}
events.prototype._action_confirm = function (data, x, y, prefix) {
core.status.event.ui = {"text": data.text, "yes": data.yes, "no": data.no};
core.status.event.ui = {"text": core.replaceText(data.text, prefix), "yes": data.yes, "no": data.no};
if (core.isReplaying()) {
var action = core.status.replay.toReplay.shift();
// --- 忽略可能的turn事件
@ -1837,6 +1841,66 @@ events.prototype._precompile_confirm = function (data) {
return data;
}
events.prototype._action_for = function (data, x, y, prefix) {
// Only support switch:A
if (!/^switch:[A-Z]$/.test(data.name)) {
core.insertAction(['循环遍历事件只支持独立开关!']);
return core.doAction();
}
var from = core.calValue(data.from);
if (typeof from != 'number') {
core.insertAction('循环遍历事件要求【起始点】仅能是数字!');
return core.doAction();
}
this._setValue_setSwitch(data.name, from, prefix);
var toName = '__for@to@' + prefix + '@' + data.name.substring(7) + '__';
var stepName = '__for@step@' + prefix + '@' + data.name.substring(7) + '__';
core.setFlag(toName, data.to);
core.setFlag(stepName, data.step);
var condition = "(function () {"+
"var to = core.calValue(core.getFlag('" + toName + "'));"+
"var step = core.calValue(core.getFlag('" + stepName + "'));"+
"if (typeof step != 'number' || typeof to != 'number') return false;"+
"if (step == 0) return true;"+
"var currentValue = core.calValue('switch:'+'" + data.name.substring(7) + "', '"+prefix+"');"+
"currentValue += step;"+
"core.events._setValue_setSwitch('switch:'+'" + data.name.substring(7) + "', currentValue, '"+prefix+"');"+
"if (step > 0) { return currentValue <= to; }"+
"else { return currentValue >= to; }"+
"})()";
return this._action_dowhile({"condition": condition, "data": data.data}, x, y, prefix);
}
events.prototype._precompile_for = function (data) {
data.from = core.replaceValue(data.from);
data.to = core.replaceValue(data.to);
data.step = core.replaceValue(data.step);
data.data = this.precompile(data.data);
return data;
}
events.prototype._action_forEach = function (data, x, y, prefix) {
// Only support switch:A
if (!/^switch:[A-Z]$/.test(data.name)) {
core.insertAction(['循环遍历事件只支持独立开关!']);
return core.doAction();
}
var listName = '__forEach@' + prefix + '@' + data.name.substring(7) + '__';
core.setFlag(listName, core.clone(data.list));
var condition = "(function () {" +
"var list = core.getFlag('"+listName+"', []);"+
"if (list.length == 0) { core.removeFlag('" + listName + "'); return false; }"+
"core.events._setValue_setSwitch('switch:'+'" + data.name.substring(7) + "', list.shift(), '"+prefix+"');"+
"return true;"+
"})()";
return this._action_while({"condition": condition, "data": data.data}, x, y, prefix);
}
events.prototype._precompile_forEach = function (data) {
data.data = this.precompile(data.data);
return data;
}
events.prototype._action_while = function (data, x, y, prefix) {
if (core.calValue(data.condition, prefix)) {
core.unshift(core.status.event.data.list,
@ -1881,11 +1945,11 @@ events.prototype._action_continue = function (data, x, y, prefix) {
}
events.prototype._action_win = function (data, x, y, prefix) {
this.win(core.replaceText(data.reason), data.norank, data.noexit);
this.win(core.replaceText(data.reason, prefix), data.norank, data.noexit);
}
events.prototype._action_lose = function (data, x, y, prefix) {
this.lose(core.replaceText(data.reason));
this.lose(core.replaceText(data.reason, prefix));
}
events.prototype._action_restart = function (data, x, y, prefix) {
@ -2129,10 +2193,12 @@ events.prototype._action_clearMap = function (data, x, y, prefix) {
}
events.prototype._action_fillText = function (data, x, y, prefix) {
data.text = core.replaceText(data.text, prefix);
this.__action_doUIEvent(data);
}
events.prototype._action_fillBoldText = function (data, x, y, prefix) {
data.text = core.replaceText(data.text, prefix);
this.__action_doUIEvent(data);
}
@ -2199,6 +2265,7 @@ events.prototype._action_drawBackground = function (data, x, y, prefix) {
}
events.prototype._action_drawTextContent = function (data, x, y, prefix) {
data.text = core.replaceText(data.text, prefix);
this.__action_doUIEvent(data);
}

View File

@ -2023,12 +2023,12 @@ ui.prototype.drawShop = function (shopId) {
core.status.event.selection = selection;
var times = shop.times, need=core.calValue(shop.need, null, null, times);
var content = "\t["+shop.name+","+shop.icon+"]" + core.replaceText(shop.text, need, times);
var content = "\t["+shop.name+","+shop.icon+"]" + core.replaceText(shop.text, null, need, times);
var use = shop.use=='experience'?'经验':'金币';
var choices = [];
for (var i=0;i<shop.choices.length;i++) {
var choice = shop.choices[i];
var text = core.replaceText(choice.text, need, times);
var text = core.replaceText(choice.text, null, need, times);
if (choice.need != null)
text += ""+core.calValue(choice.need, null, null, times)+use+"";
choices.push({"text": text, "color":shop.visited?null:"#999999"});

View File

@ -62,9 +62,9 @@ utils.prototype._init = function () {
}
////// 将文字中的${和}(表达式)进行替换 //////
utils.prototype.replaceText = function (text, need, times) {
utils.prototype.replaceText = function (text, prefix, need, times) {
return text.replace(/\${(.*?)}/g, function (word, value) {
return core.calValue(value, null, need, times);
return core.calValue(value, prefix, need, times);
});
}

2
runtime.d.ts vendored
View File

@ -1506,7 +1506,7 @@ declare class utils {
* @param times
* @returns
*/
replaceText(text: string, need?: number, times?: number): string
replaceText(text: string, prefix?: string, need?: number, times?: number): string
/**
* 如status:xxx等