mirror of
				https://github.com/unanmed/HumanBreak.git
				synced 2025-10-31 12:12:58 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			4551 lines
		
	
	
		
			136 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			4551 lines
		
	
	
		
			136 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| ///<reference path="../../src/types/declaration/core.d.ts" />
 | ||
| 
 | ||
| 'use strict';
 | ||
| 
 | ||
| function events() {
 | ||
|     this._init();
 | ||
| }
 | ||
| 
 | ||
| ////// 初始化 //////
 | ||
| events.prototype._init = function () {
 | ||
|     this.eventdata = functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a.events;
 | ||
|     this.commonEvent = events_c12a15a8_c380_4b28_8144_256cba95f760.commonEvent;
 | ||
|     this.systemEvents = {};
 | ||
|     this.actions = {};
 | ||
| };
 | ||
| 
 | ||
| // ------ 初始化,开始和结束 ------ //
 | ||
| 
 | ||
| /// 初始化游戏
 | ||
| events.prototype.resetGame = function (hero, hard, floorId, maps, values) {
 | ||
|     this.eventdata.resetGame(hero, hard, floorId, maps, values);
 | ||
| };
 | ||
| 
 | ||
| ////// 游戏开始事件 //////
 | ||
| events.prototype.startGame = function (hard, seed, route, callback) {
 | ||
|     hard = hard || '';
 | ||
| 
 | ||
|     if (main.mode != 'play') return;
 | ||
| 
 | ||
|     // 无动画的开始游戏
 | ||
|     if (core.flags.startUsingCanvas || route != null) {
 | ||
|         this._startGame_start(hard, seed, route, callback);
 | ||
|     } else {
 | ||
|         core.hideStartAnimate(function () {
 | ||
|             core.events._startGame_start(hard, seed, route, callback);
 | ||
|         });
 | ||
|     }
 | ||
| };
 | ||
| 
 | ||
| events.prototype._startGame_start = function (hard, seed, route, callback) {
 | ||
|     core.resetGame(
 | ||
|         core.firstData.hero,
 | ||
|         hard,
 | ||
|         null,
 | ||
|         core.clone(core.initStatus.maps)
 | ||
|     );
 | ||
|     core.setHeroLoc('x', -1);
 | ||
|     core.setHeroLoc('y', -1);
 | ||
| 
 | ||
|     if (seed != null && seed > 0) {
 | ||
|         core.setFlag('__seed__', seed);
 | ||
|         core.setFlag('__rand__', seed);
 | ||
|     } else core.utils.__init_seed();
 | ||
|     core.clearStatusBar();
 | ||
| 
 | ||
|     var todo = [];
 | ||
|     if (core.flags.startUsingCanvas) {
 | ||
|         core.hideStatusBar();
 | ||
|         core.push(todo, core.firstData.startCanvas);
 | ||
|     }
 | ||
|     core.push(todo, {
 | ||
|         type: 'function',
 | ||
|         function: 'function() { core.events._startGame_setHard(); }'
 | ||
|     });
 | ||
|     core.push(todo, core.firstData.startText);
 | ||
|     this.insertAction(todo, null, null, function () {
 | ||
|         core.events._startGame_afterStart(callback);
 | ||
|     });
 | ||
| 
 | ||
|     if (route != null) {
 | ||
|         core.startReplay(route);
 | ||
|     }
 | ||
| };
 | ||
| 
 | ||
| events.prototype._startGame_setHard = function () {
 | ||
|     // 根据难度设置flag:hard
 | ||
|     // 这一段应当在startCanvas之后,startText之前做
 | ||
|     var hardValue = 0;
 | ||
|     var hardColor = 'red';
 | ||
|     main.levelChoose.forEach(function (one) {
 | ||
|         if (one.name == core.status.hard) {
 | ||
|             hardValue = one.hard;
 | ||
|             hardColor = core.arrayToRGBA(one.color || [255, 0, 0, 1]);
 | ||
|             core.insertAction(one.action);
 | ||
|         }
 | ||
|     });
 | ||
|     core.setFlag('hard', hardValue || 0);
 | ||
|     core.setFlag('__hardColor__', hardColor);
 | ||
| };
 | ||
| 
 | ||
| events.prototype._startGame_afterStart = function (callback) {
 | ||
|     core.ui.closePanel();
 | ||
|     core.changeFloor(
 | ||
|         core.firstData.floorId,
 | ||
|         null,
 | ||
|         core.firstData.hero.loc,
 | ||
|         null,
 | ||
|         function () {
 | ||
|             // 插入一个空事件避免直接回放录像出错
 | ||
|             core.insertAction([]);
 | ||
|             if (callback) callback();
 | ||
|         }
 | ||
|     );
 | ||
|     this._startGame_upload();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._startGame_upload = function () {
 | ||
|     // Upload
 | ||
|     var formData = new FormData();
 | ||
|     formData.append('type', 'people');
 | ||
|     formData.append('name', core.firstData.name);
 | ||
|     formData.append('version', core.firstData.version);
 | ||
|     formData.append('platform', core.platform.string);
 | ||
|     formData.append('hard', core.encodeBase64(core.status.hard));
 | ||
|     formData.append('hardCode', core.getFlag('hard', 0));
 | ||
|     formData.append('base64', 1);
 | ||
| 
 | ||
|     core.utils.http('POST', '/games/upload.php', formData);
 | ||
| };
 | ||
| 
 | ||
| ////// 游戏获胜事件 //////
 | ||
| events.prototype.win = function (reason, norank, noexit) {
 | ||
|     return this.eventdata.win(reason, norank, noexit);
 | ||
| };
 | ||
| 
 | ||
| ////// 游戏失败事件 //////
 | ||
| events.prototype.lose = function (reason) {
 | ||
|     if (core.isReplaying())
 | ||
|         return core.control._replay_error(reason, function () {
 | ||
|             core.lose(reason);
 | ||
|         });
 | ||
|     return this.eventdata.lose(reason);
 | ||
| };
 | ||
| 
 | ||
| ////// 游戏结束 //////
 | ||
| events.prototype.gameOver = function (ending, fromReplay, norank) {
 | ||
|     if (!core.status.extraEvent) {
 | ||
|         core.clearMap('all');
 | ||
|         core.deleteAllCanvas();
 | ||
|         core.setWeather();
 | ||
|     }
 | ||
|     core.ui.closePanel();
 | ||
| 
 | ||
|     if (main.isCompetition && ending != null) {
 | ||
|         if (ending == '') ending = '恭喜通关';
 | ||
|         ending += '[比赛]';
 | ||
|     }
 | ||
| 
 | ||
|     var reason = null;
 | ||
|     if (fromReplay) reason = '录像回放完毕!';
 | ||
|     else if (core.hasFlag('debug'))
 | ||
|         reason = '\t[系统提示]调试模式下无法上传成绩';
 | ||
| 
 | ||
|     if (reason != null) core.drawText(reason, core.restart);
 | ||
|     else this._gameOver_confirmUpload(ending, norank);
 | ||
| };
 | ||
| 
 | ||
| events.prototype._gameOver_confirmUpload = function (ending, norank) {
 | ||
|     core.ui.closePanel();
 | ||
| 
 | ||
|     if (ending == null) {
 | ||
|         this._gameOver_confirmDownload(ending);
 | ||
|         return;
 | ||
|     }
 | ||
|     core.ui.drawConfirmBox(
 | ||
|         '你想记录你的ID和成绩吗?',
 | ||
|         function () {
 | ||
|             if (main.isCompetition) {
 | ||
|                 core.events._gameOver_doUpload('', ending, norank);
 | ||
|             } else {
 | ||
|                 var id = core.getCookie('id') || '';
 | ||
|                 var hint =
 | ||
|                     '请输入你的ID:\n(登录状态下输入数字用户编号可成为蓝名成绩并计入用户通关数)';
 | ||
|                 if (id)
 | ||
|                     hint =
 | ||
|                         '请输入你的ID:\n(输入数字用户编号' +
 | ||
|                         id +
 | ||
|                         '可成为蓝名成绩并计入用户通关数)';
 | ||
|                 core.myprompt(hint, id, function (username) {
 | ||
|                     core.events._gameOver_doUpload(username, ending, norank);
 | ||
|                 });
 | ||
|             }
 | ||
|         },
 | ||
|         function () {
 | ||
|             if (main.isCompetition)
 | ||
|                 core.events._gameOver_confirmDownload(ending);
 | ||
|             else core.events._gameOver_doUpload(null, ending, norank);
 | ||
|         },
 | ||
|         true
 | ||
|     );
 | ||
| };
 | ||
| 
 | ||
| events.prototype._gameOver_doUpload = function (username, ending, norank) {
 | ||
|     var hp = core.status.hero.hp;
 | ||
|     if (username == null) hp = 1;
 | ||
|     core.ui.closePanel();
 | ||
|     // upload
 | ||
|     var formData = new FormData();
 | ||
|     formData.append('type', 'score');
 | ||
|     formData.append('name', core.firstData.name);
 | ||
|     formData.append('version', core.firstData.version);
 | ||
|     formData.append('platform', core.platform.string);
 | ||
|     formData.append('hard', core.encodeBase64(core.status.hard));
 | ||
|     formData.append('username', core.encodeBase64(username || ''));
 | ||
|     formData.append('ending', core.encodeBase64(ending));
 | ||
|     formData.append('lv', core.status.hero.lv);
 | ||
|     formData.append('hp', Math.min(hp, Math.pow(2, 63)));
 | ||
|     formData.append('atk', core.status.hero.atk);
 | ||
|     formData.append('def', core.status.hero.def);
 | ||
|     formData.append('mdef', core.status.hero.mdef);
 | ||
|     formData.append('money', core.status.hero.money);
 | ||
|     formData.append('experience', core.status.hero.exp);
 | ||
|     formData.append('steps', core.status.hero.steps);
 | ||
|     formData.append('norank', norank ? 1 : 0);
 | ||
|     formData.append('seed', core.getFlag('__seed__'));
 | ||
|     formData.append(
 | ||
|         'totalTime',
 | ||
|         Math.floor(core.status.hero.statistics.totalTime / 1000)
 | ||
|     );
 | ||
|     formData.append('route', core.encodeRoute(core.status.route));
 | ||
|     formData.append('base64', 1);
 | ||
| 
 | ||
|     if (main.isCompetition)
 | ||
|         core.http('POST', '/games/competition/upload.php', formData);
 | ||
|     else core.http('POST', '/games/upload.php', formData);
 | ||
| 
 | ||
|     core.events._gameOver_confirmDownload(ending);
 | ||
| };
 | ||
| 
 | ||
| events.prototype._gameOver_confirmDownload = function (ending) {
 | ||
|     core.ui.closePanel();
 | ||
|     core.ui.drawConfirmBox(
 | ||
|         '你想下载录像吗?',
 | ||
|         function () {
 | ||
|             var obj = {
 | ||
|                 name: core.firstData.name,
 | ||
|                 version: core.firstData.version,
 | ||
|                 hard: core.status.hard,
 | ||
|                 seed: core.getFlag('__seed__'),
 | ||
|                 route: core.encodeRoute(core.status.route)
 | ||
|             };
 | ||
|             core.download(
 | ||
|                 core.firstData.name +
 | ||
|                     '_' +
 | ||
|                     core.formatDate2(new Date()) +
 | ||
|                     '.h5route',
 | ||
|                 LZString.compressToBase64(JSON.stringify(obj))
 | ||
|             );
 | ||
|             core.events._gameOver_askRate(ending);
 | ||
|         },
 | ||
|         function () {
 | ||
|             core.events._gameOver_askRate(ending);
 | ||
|         },
 | ||
|         true
 | ||
|     );
 | ||
| };
 | ||
| 
 | ||
| events.prototype._gameOver_askRate = function (ending) {
 | ||
|     core.ui.closePanel();
 | ||
| 
 | ||
|     // 继续接下来的事件
 | ||
|     if (core.status.extraEvent) {
 | ||
|         core.status.event = core.status.extraEvent;
 | ||
|         delete core.status.extraEvent;
 | ||
|         core.lockControl();
 | ||
|         core.doAction();
 | ||
|         return;
 | ||
|     }
 | ||
| 
 | ||
|     if (ending == null) {
 | ||
|         if (!core.hasSave(0)) {
 | ||
|             core.ui.closePanel();
 | ||
|             core.restart();
 | ||
|             return;
 | ||
|         }
 | ||
| 
 | ||
|         core.status.event.selection = 0;
 | ||
|         core.ui.drawConfirmBox(
 | ||
|             '你想读取自动存档么?',
 | ||
|             function () {
 | ||
|                 core.ui.closePanel();
 | ||
|                 core.doSL('autoSave', 'load');
 | ||
|             },
 | ||
|             function () {
 | ||
|                 core.ui.closePanel();
 | ||
|                 core.restart();
 | ||
|             },
 | ||
|             true
 | ||
|         );
 | ||
|         return;
 | ||
|     }
 | ||
| 
 | ||
|     core.ui.drawConfirmBox(
 | ||
|         '恭喜通关!你想查看榜单、评论,\n以及评分和标色投票吗?',
 | ||
|         function () {
 | ||
|             if (core.platform.isPC) {
 | ||
|                 window.open('/tower/?name=' + core.firstData.name, '_blank');
 | ||
|                 core.restart();
 | ||
|             } else {
 | ||
|                 window.location.href = '/tower/?name=' + core.firstData.name;
 | ||
|             }
 | ||
|         },
 | ||
|         function () {
 | ||
|             core.restart();
 | ||
|         },
 | ||
|         true
 | ||
|     );
 | ||
| };
 | ||
| 
 | ||
| ////// 重新开始游戏;此函数将回到标题页面 //////
 | ||
| events.prototype.restart = function () {
 | ||
|     core.hideStatusBar();
 | ||
|     core.showStartAnimate();
 | ||
|     core.playBgm(main.startBgm);
 | ||
|     Mota.require('@user/data-base').hook.emit('restart');
 | ||
| };
 | ||
| 
 | ||
| ////// 询问是否需要重新开始 //////
 | ||
| events.prototype.confirmRestart = function () {
 | ||
|     core.playSound('打开界面');
 | ||
|     core.status.event.selection = 1;
 | ||
|     core.ui.drawConfirmBox(
 | ||
|         '你确定要返回标题页面吗?',
 | ||
|         function () {
 | ||
|             core.playSound('确定');
 | ||
|             core.ui.closePanel();
 | ||
|             core.restart();
 | ||
|         },
 | ||
|         function () {
 | ||
|             core.playSound('取消');
 | ||
|             core.ui.closePanel();
 | ||
|         },
 | ||
|         true
 | ||
|     );
 | ||
| };
 | ||
| 
 | ||
| // ------ 系统事件的处理 ------ //
 | ||
| 
 | ||
| ////// 注册一个系统事件 //////
 | ||
| // type为事件名,func为事件的处理函数,可接受(data, callback)参数
 | ||
| events.prototype.registerSystemEvent = function (type, func) {
 | ||
|     this.systemEvents[type] = func;
 | ||
| };
 | ||
| 
 | ||
| ////// 注销一个系统事件 //////
 | ||
| events.prototype.unregisterSystemEvent = function (type) {
 | ||
|     delete this.systemEvents[type];
 | ||
| };
 | ||
| 
 | ||
| ////// 执行一个系统事件 //////
 | ||
| events.prototype.doSystemEvent = function (type, data, callback) {
 | ||
|     core.clearRouteFolding();
 | ||
|     if (this.systemEvents[type]) {
 | ||
|         try {
 | ||
|             return this.systemEvents[type].call(this, data, callback);
 | ||
|         } catch (e) {
 | ||
|             console.error(e);
 | ||
|             console.error('ERROR in systemEvents[' + type + ']');
 | ||
|         }
 | ||
|     }
 | ||
|     if (this['_sys_' + type]) return this['_sys_' + type](data, callback);
 | ||
|     console.error('未知的系统事件: ' + type + '!');
 | ||
|     if (callback) callback();
 | ||
| };
 | ||
| 
 | ||
| ////// 触发(x,y)点的事件 //////
 | ||
| events.prototype.trigger = function (x, y, callback) {
 | ||
|     var _executeCallback = function () {
 | ||
|         // 因为trigger之后还有可能触发其他同步脚本(比如阻激夹域检测)
 | ||
|         // 所以这里强制callback被异步触发
 | ||
|         if (callback) {
 | ||
|             setTimeout(callback, 1); // +1是为了录像检测系统
 | ||
|         }
 | ||
|         return;
 | ||
|     };
 | ||
|     if (core.status.gameOver) return _executeCallback();
 | ||
|     if (core.status.event.id == 'action') {
 | ||
|         core.insertAction(
 | ||
|             {
 | ||
|                 type: 'function',
 | ||
|                 function:
 | ||
|                     'function () { core.events._trigger_inAction(' +
 | ||
|                     x +
 | ||
|                     ',' +
 | ||
|                     y +
 | ||
|                     '); }',
 | ||
|                 async: true
 | ||
|             },
 | ||
|             void 0,
 | ||
|             void 0,
 | ||
|             void 0,
 | ||
|             true
 | ||
|         );
 | ||
|         return _executeCallback();
 | ||
|     }
 | ||
|     if (core.status.event.id) return _executeCallback();
 | ||
| 
 | ||
|     let block = core.getBlock(x, y);
 | ||
| 
 | ||
|     if (block == null) return _executeCallback();
 | ||
| 
 | ||
|     // 执行该点的脚本
 | ||
|     if (block.event.script) {
 | ||
|         core.clearRouteFolding();
 | ||
|         try {
 | ||
|             eval(block.event.script);
 | ||
|         } catch (ee) {
 | ||
|             console.error(ee);
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
|     // 碰触事件
 | ||
|     if (block.event.event) {
 | ||
|         core.clearRouteFolding();
 | ||
|         core.insertAction(block.event.event, block.x, block.y);
 | ||
|         // 不再执行该点的系统事件
 | ||
|         return _executeCallback();
 | ||
|     }
 | ||
| 
 | ||
|     if (block.event.trigger && block.event.trigger !== 'null') {
 | ||
|         core.clearRouteFolding();
 | ||
|         var noPass = block.event.noPass,
 | ||
|             trigger = block.event.trigger;
 | ||
|         if (noPass) core.clearAutomaticRouteNode(x, y);
 | ||
| 
 | ||
|         // 转换楼层能否穿透
 | ||
|         if (
 | ||
|             trigger == 'changeFloor' &&
 | ||
|             !noPass &&
 | ||
|             this._trigger_ignoreChangeFloor(block)
 | ||
|         )
 | ||
|             return _executeCallback();
 | ||
|         // @ts-ignore
 | ||
|         core.status.automaticRoute.moveDirectly = false;
 | ||
|         this.doSystemEvent(trigger, block);
 | ||
|     }
 | ||
|     return _executeCallback();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._trigger_inAction = function (x, y) {
 | ||
|     if (core.status.gameOver || core.status.event.id != 'action') return;
 | ||
| 
 | ||
|     var block = core.getBlock(x, y);
 | ||
|     if (block == null) return core.doAction();
 | ||
| 
 | ||
|     // 执行该点的脚本
 | ||
|     try {
 | ||
|         eval(block.event.script);
 | ||
|     } catch (ee) {
 | ||
|         console.error(ee);
 | ||
|     }
 | ||
| 
 | ||
|     // 碰触事件
 | ||
|     if (block.event.event) {
 | ||
|         core.clearRouteFolding();
 | ||
|         core.insertAction(block.event.event, block.x, block.y);
 | ||
|         // 不再执行该点的系统事件
 | ||
|         return core.doAction();
 | ||
|     }
 | ||
| 
 | ||
|     if (block.event.trigger && block.event.trigger != 'null') {
 | ||
|         this.setEvents(null, x, y);
 | ||
|         if (block.event.trigger == 'action') {
 | ||
|             this.insertAction(block.event.data);
 | ||
|         } else {
 | ||
|             this.doSystemEvent(block.event.trigger, block, core.doAction);
 | ||
|             return;
 | ||
|         }
 | ||
|     }
 | ||
|     return core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._trigger_ignoreChangeFloor = function (block) {
 | ||
|     var able = core.flags.ignoreChangeFloor;
 | ||
|     if (block.event.data && block.event.data.ignoreChangeFloor != null)
 | ||
|         able = block.event.data.ignoreChangeFloor;
 | ||
|     if (able) {
 | ||
|         if (core.isReplaying()) {
 | ||
|             if (core.status.replay.toReplay[0] == 'no') {
 | ||
|                 core.status.replay.toReplay.shift();
 | ||
|                 core.status.route.push('no');
 | ||
|                 return true;
 | ||
|             }
 | ||
|         } else if (
 | ||
|             core.status.automaticRoute.autoHeroMove ||
 | ||
|             core.status.automaticRoute.autoStep <
 | ||
|                 core.status.automaticRoute.autoStepRoutes.length
 | ||
|         ) {
 | ||
|             core.status.route.push('no');
 | ||
|             return true;
 | ||
|         }
 | ||
|     }
 | ||
|     return false;
 | ||
| };
 | ||
| 
 | ||
| events.prototype._sys_battle = function (data, callback) {
 | ||
|     // Deprecated. See /src/plugin/game/enemy/battle.ts
 | ||
| };
 | ||
| 
 | ||
| ////// 战斗 //////
 | ||
| events.prototype.battle = function (id, x, y, force, callback) {
 | ||
|     // Deprecated. See src/plugin/game/enemy/battle.ts
 | ||
| };
 | ||
| 
 | ||
| ////// 战斗前触发的事件 //////
 | ||
| events.prototype.beforeBattle = function (enemyId, x, y) {
 | ||
|     // Deprecated. See src/plugin/game/enemy/battle.ts
 | ||
| };
 | ||
| 
 | ||
| ////// 战斗结束后触发的事件 //////
 | ||
| events.prototype.afterBattle = function (enemyId, x, y) {
 | ||
|     // Deprecated. See src/plugin/game/enemy/battle.ts
 | ||
| };
 | ||
| 
 | ||
| events.prototype._sys_openDoor = function (data, callback) {
 | ||
|     this.openDoor(data.x, data.y, true, function () {
 | ||
|         core.replay();
 | ||
|         if (callback) callback();
 | ||
|     });
 | ||
| };
 | ||
| 
 | ||
| ////// 开门 //////
 | ||
| events.prototype.openDoor = function (x, y, needKey, callback) {
 | ||
|     var block = core.getBlock(x, y);
 | ||
|     core.saveAndStopAutomaticRoute();
 | ||
|     if (!this._openDoor_check(block, x, y, needKey)) {
 | ||
|         var locked = core.status.lockControl;
 | ||
|         core.waitHeroToStop(function () {
 | ||
|             if (!locked) core.unlockControl();
 | ||
|             if (callback) callback();
 | ||
|         });
 | ||
|         return;
 | ||
|     }
 | ||
|     if (core.status.replay.speed == 24) {
 | ||
|         core.status.replay.animate = true;
 | ||
|         core.removeBlock(x, y);
 | ||
|         setTimeout(function () {
 | ||
|             core.status.replay.animate = false;
 | ||
|             Mota.require('@user/data-base').hook.emit(
 | ||
|                 'afterOpenDoor',
 | ||
|                 block.event.id,
 | ||
|                 x,
 | ||
|                 y
 | ||
|             );
 | ||
|             if (callback) callback();
 | ||
|         }, 1); // +1是为了录像检测系统
 | ||
|     } else {
 | ||
|         this._openDoor_animate(block, x, y, callback);
 | ||
|     }
 | ||
| };
 | ||
| 
 | ||
| events.prototype._openDoor_check = function (block, x, y, needKey) {
 | ||
|     var clearAndReturn = function () {
 | ||
|         core.clearContinueAutomaticRoute();
 | ||
|         return false;
 | ||
|     };
 | ||
| 
 | ||
|     if (block == null || block.event == null) return clearAndReturn();
 | ||
|     var id = block.event.id;
 | ||
| 
 | ||
|     // 是否存在门或暗墙
 | ||
|     if (
 | ||
|         core.material.icons.animates[id] == null &&
 | ||
|         core.material.icons.npc48[id] == null
 | ||
|     ) {
 | ||
|         return clearAndReturn();
 | ||
|     }
 | ||
| 
 | ||
|     if (id == 'steelDoor' && core.flags.steelDoorWithoutKey) needKey = false;
 | ||
|     var doorInfo = block.event.doorInfo;
 | ||
|     if (doorInfo == null) return clearAndReturn();
 | ||
|     // Check all keys
 | ||
|     var keyInfo = doorInfo.keys || {};
 | ||
|     if (needKey) {
 | ||
|         for (var keyName in keyInfo) {
 | ||
|             var keyValue = keyInfo[keyName];
 | ||
|             if (keyName.endsWith(':o'))
 | ||
|                 keyName = keyName.substring(0, keyName.length - 2);
 | ||
| 
 | ||
|             // --- 如果是一个不存在的道具,则直接认为无法开启
 | ||
|             if (!core.material.items[keyName]) {
 | ||
|                 core.stopSound();
 | ||
|                 core.playSound('操作失败');
 | ||
|                 core.drawTip('无法开启此门');
 | ||
|                 return clearAndReturn();
 | ||
|             }
 | ||
|             if (core.itemCount(keyName) < keyValue) {
 | ||
|                 core.stopSound();
 | ||
|                 core.playSound('操作失败');
 | ||
|                 core.drawTip(
 | ||
|                     '你的' +
 | ||
|                         ((core.material.items[keyName] || {}).name || '钥匙') +
 | ||
|                         '不足!',
 | ||
|                     null,
 | ||
|                     true
 | ||
|                 );
 | ||
|                 return false;
 | ||
|             }
 | ||
|         }
 | ||
|         if (!core.status.event.id) core.autosave(true);
 | ||
|         for (var keyName in keyInfo) {
 | ||
|             if (!keyName.endsWith(':o'))
 | ||
|                 core.removeItem(keyName, keyInfo[keyName]);
 | ||
|         }
 | ||
|     }
 | ||
|     core.playSound(doorInfo.openSound);
 | ||
|     return true;
 | ||
| };
 | ||
| 
 | ||
| events.prototype._openDoor_animate = function (block, x, y, callback) {
 | ||
|     var blockInfo = core.getBlockInfo(block);
 | ||
|     blockInfo.opacity = block.opacity;
 | ||
|     blockInfo.filter = block.filter;
 | ||
| 
 | ||
|     var speed = (block.event.doorInfo.time || 160) / 4;
 | ||
| 
 | ||
|     var locked = core.status.lockControl;
 | ||
|     core.lockControl();
 | ||
|     core.status.replay.animate = true;
 | ||
|     core.removeBlock(x, y);
 | ||
| 
 | ||
|     blockInfo.posX = 0;
 | ||
|     core.maps._drawBlockInfo(blockInfo, x, y);
 | ||
| 
 | ||
|     var cb = function () {
 | ||
|         core.maps._removeBlockFromMap(core.status.floorId, block);
 | ||
|         if (!locked) core.unlockControl();
 | ||
|         core.status.replay.animate = false;
 | ||
|         Mota.require('@user/data-base').hook.emit(
 | ||
|             'afterOpenDoor',
 | ||
|             block.event.id,
 | ||
|             x,
 | ||
|             y
 | ||
|         );
 | ||
|         if (callback) callback();
 | ||
|     };
 | ||
| 
 | ||
|     var animate = window.setInterval(
 | ||
|         function () {
 | ||
|             blockInfo.posX++;
 | ||
|             if (blockInfo.posX == 4) {
 | ||
|                 clearInterval(animate);
 | ||
|                 delete core.animateFrame.asyncId[animate];
 | ||
|                 cb();
 | ||
|                 return;
 | ||
|             }
 | ||
|             core.maps._drawBlockInfo(blockInfo, x, y);
 | ||
|         },
 | ||
|         core.status.replay.speed == 24
 | ||
|             ? 1
 | ||
|             : speed / Math.max(core.status.replay.speed, 1)
 | ||
|     );
 | ||
| 
 | ||
|     core.animateFrame.lastAsyncId = animate;
 | ||
|     core.animateFrame.asyncId[animate] = cb;
 | ||
| };
 | ||
| 
 | ||
| ////// 开一个门后触发的事件 //////
 | ||
| events.prototype.afterOpenDoor = function (doorId, x, y) {
 | ||
|     // Deprecated. See hook#afterOpenDoor.
 | ||
| };
 | ||
| 
 | ||
| events.prototype._sys_getItem = function (data, callback) {
 | ||
|     this.getItem(data.event.id, 1, data.x, data.y, false, callback);
 | ||
| };
 | ||
| 
 | ||
| ////// 获得某个物品 //////
 | ||
| events.prototype.getItem = function (id, num, x, y, isGentleClick, callback) {
 | ||
|     if (num == null) num = 1;
 | ||
|     var itemCls = core.material.items[id].cls;
 | ||
|     core.removeBlock(x, y);
 | ||
|     core.items.getItemEffect(id, num);
 | ||
|     var text = '获得 ' + core.material.items[id].name;
 | ||
|     if (num > 1) text += 'x' + num;
 | ||
|     if (itemCls === 'items' && num == 1)
 | ||
|         text += core.items.getItemEffectTip(id);
 | ||
|     core.drawTip(text, id);
 | ||
| 
 | ||
|     // --- 首次获得道具的提示
 | ||
|     if (!core.hasFlag('__itemHint__')) core.setFlag('__itemHint__', []);
 | ||
|     var itemHint = core.getFlag('__itemHint__');
 | ||
|     if (
 | ||
|         core.flags.itemFirstText &&
 | ||
|         itemHint.indexOf(id) < 0 &&
 | ||
|         itemCls != 'items'
 | ||
|     ) {
 | ||
|         var hint = core.material.items[id].text || '该道具暂无描述';
 | ||
|         try {
 | ||
|             hint = core.replaceText(hint);
 | ||
|         } catch (e) {}
 | ||
|         if (!core.status.event.id || core.status.event.id == 'action') {
 | ||
|             core.insertAction(
 | ||
|                 '\t[' +
 | ||
|                     core.material.items[id].name +
 | ||
|                     ',' +
 | ||
|                     id +
 | ||
|                     ']' +
 | ||
|                     hint +
 | ||
|                     '\n' +
 | ||
|                     (id.endsWith('Key')
 | ||
|                         ? '(钥匙类道具,遇到对应的门时自动打开)'
 | ||
|                         : itemCls == 'tools'
 | ||
|                           ? '(消耗类道具,请按T在道具栏使用)'
 | ||
|                           : itemCls == 'constants'
 | ||
|                             ? '(永久类道具,请按T在道具栏使用)'
 | ||
|                             : itemCls == 'equips'
 | ||
|                               ? '(装备类道具,请按Q在装备栏进行装备)'
 | ||
|                               : '')
 | ||
|             );
 | ||
|         }
 | ||
|         itemHint.push(id);
 | ||
|     }
 | ||
| 
 | ||
|     Mota.require('@user/data-base').hook.emit(
 | ||
|         'afterGetItem',
 | ||
|         id,
 | ||
|         x,
 | ||
|         y,
 | ||
|         isGentleClick
 | ||
|     );
 | ||
|     if (callback) callback();
 | ||
| };
 | ||
| 
 | ||
| events.prototype.afterGetItem = function (id, x, y, isGentleClick) {
 | ||
|     // Deprecated. See hook#afterGetItem
 | ||
| };
 | ||
| 
 | ||
| ////// 获得面前的物品(轻按) //////
 | ||
| events.prototype.getNextItem = function (noRoute) {
 | ||
|     if (core.isMoving() || !core.flags.enableGentleClick) return false;
 | ||
|     if (this._canGetNextItem()) return this._getNextItem(null, noRoute);
 | ||
| 
 | ||
|     var directions = ['up', 'down', 'left', 'right'].filter(function (dir) {
 | ||
|         return core.events._canGetNextItem(dir);
 | ||
|     });
 | ||
|     return directions.length > 0
 | ||
|         ? this._getNextItem(directions[0], noRoute)
 | ||
|         : false;
 | ||
| };
 | ||
| 
 | ||
| events.prototype._canGetNextItem = function (direction) {
 | ||
|     direction = direction || core.getHeroLoc('direction');
 | ||
|     if (!core.canMoveHero(null, null, direction)) return;
 | ||
|     var nx = core.getHeroLoc('x') + core.utils.scan[direction].x;
 | ||
|     var ny = core.getHeroLoc('y') + core.utils.scan[direction].y;
 | ||
|     var block = core.getBlock(nx, ny);
 | ||
|     return (
 | ||
|         block != null &&
 | ||
|         !block.event.script &&
 | ||
|         !block.event.event &&
 | ||
|         block.event.trigger == 'getItem'
 | ||
|     );
 | ||
| };
 | ||
| 
 | ||
| events.prototype._getNextItem = function (direction, noRoute) {
 | ||
|     direction = direction || core.getHeroLoc('direction');
 | ||
|     var nx = core.getHeroLoc('x') + core.utils.scan[direction].x;
 | ||
|     var ny = core.getHeroLoc('y') + core.utils.scan[direction].y;
 | ||
|     if (!noRoute) core.status.route.push('getNext');
 | ||
|     this.getItem(core.getBlockId(nx, ny), 1, nx, ny, true);
 | ||
|     return true;
 | ||
| };
 | ||
| 
 | ||
| events.prototype._sys_changeFloor = function (data, callback) {
 | ||
|     data = data.event.data;
 | ||
|     let heroLoc = {};
 | ||
|     if (data.loc) heroLoc = { x: data.loc[0], y: data.loc[1] };
 | ||
|     if (data.direction) heroLoc.direction = data.direction;
 | ||
|     // @ts-ignore
 | ||
|     if (core.status.event.id != 'action') core.status.event.id = null;
 | ||
|     core.changeFloor(data.floorId, data.stair, heroLoc, data.time, function () {
 | ||
|         core.replay();
 | ||
|         if (callback) callback();
 | ||
|     });
 | ||
| };
 | ||
| 
 | ||
| ////// 楼层切换 //////
 | ||
| events.prototype.changeFloor = function (
 | ||
|     floorId,
 | ||
|     stair,
 | ||
|     heroLoc,
 | ||
|     time,
 | ||
|     callback
 | ||
| ) {
 | ||
|     var info = this._changeFloor_getInfo(floorId, stair, heroLoc, time);
 | ||
|     if (info == null) {
 | ||
|         if (callback) callback();
 | ||
|         return;
 | ||
|     }
 | ||
|     floorId = info.floorId;
 | ||
|     info.locked = core.status.lockControl;
 | ||
| 
 | ||
|     core.lockControl();
 | ||
|     core.stopAutomaticRoute();
 | ||
|     core.clearContinueAutomaticRoute();
 | ||
|     core.status.replay.animate = true;
 | ||
|     clearInterval(core.interval.onDownInterval);
 | ||
|     core.interval.onDownInterval = 'tmp';
 | ||
| 
 | ||
|     this._changeFloor_beforeChange(info, callback);
 | ||
| };
 | ||
| 
 | ||
| events.prototype._changeFloor_getInfo = function (
 | ||
|     floorId,
 | ||
|     stair,
 | ||
|     heroLoc,
 | ||
|     time
 | ||
| ) {
 | ||
|     floorId = floorId || core.status.floorId;
 | ||
|     if (floorId == ':before') {
 | ||
|         var index = core.floorIds.indexOf(core.status.floorId);
 | ||
|         if (index > 0) floorId = core.floorIds[index - 1];
 | ||
|         else floorId = core.status.floorId;
 | ||
|     } else if (floorId == ':next') {
 | ||
|         var index = core.floorIds.indexOf(core.status.floorId);
 | ||
|         if (index < core.floorIds.length - 1)
 | ||
|             floorId = core.floorIds[index + 1];
 | ||
|         else floorId = core.status.floorId;
 | ||
|     } else if (floorId == ':now') {
 | ||
|         floorId = core.status.floorId;
 | ||
|     }
 | ||
|     if (!core.status.maps[floorId]) {
 | ||
|         console.error('不存在的楼层:' + floorId);
 | ||
|         return null;
 | ||
|     }
 | ||
| 
 | ||
|     if (main.mode != 'play' || core.isReplaying()) time = 0;
 | ||
|     if (time == null) time = core.values.floorChangeTime;
 | ||
| 
 | ||
|     return {
 | ||
|         floorId: floorId,
 | ||
|         time: time,
 | ||
|         heroLoc: core.clone(
 | ||
|             this._changeFloor_getHeroLoc(floorId, stair, heroLoc)
 | ||
|         )
 | ||
|     };
 | ||
| };
 | ||
| 
 | ||
| events.prototype._changeFloor_getHeroLoc = function (floorId, stair, heroLoc) {
 | ||
|     if (!heroLoc) heroLoc = core.clone(core.status.hero.loc);
 | ||
|     if (stair) {
 | ||
|         // --- 对称
 | ||
|         if (stair == ':now') heroLoc = core.clone(core.status.hero.loc);
 | ||
|         else if (stair == ':symmetry') {
 | ||
|             heroLoc.x = core.bigmap.width - 1 - core.getHeroLoc('x');
 | ||
|             heroLoc.y = core.bigmap.height - 1 - core.getHeroLoc('y');
 | ||
|         } else if (stair == ':symmetry_x')
 | ||
|             heroLoc.x = core.bigmap.width - 1 - core.getHeroLoc('x');
 | ||
|         else if (stair == ':symmetry_y')
 | ||
|             heroLoc.y = core.bigmap.height - 1 - core.getHeroLoc('y');
 | ||
|         // 检查该层地图的 upFloor & downFloor & flyPoint
 | ||
|         else if (core.status.maps[floorId][stair]) {
 | ||
|             heroLoc.x = core.status.maps[floorId][stair][0];
 | ||
|             heroLoc.y = core.status.maps[floorId][stair][1];
 | ||
|         } else {
 | ||
|             core.extractBlocks(floorId);
 | ||
|             var blocks = core.status.maps[floorId].blocks;
 | ||
|             for (var i in blocks) {
 | ||
|                 if (!blocks[i].disable && blocks[i].event.id === stair) {
 | ||
|                     heroLoc.x = blocks[i].x;
 | ||
|                     heroLoc.y = blocks[i].y;
 | ||
|                     break;
 | ||
|                 }
 | ||
|             }
 | ||
|         }
 | ||
|     }
 | ||
|     ['x', 'y', 'direction'].forEach(function (name) {
 | ||
|         if (heroLoc[name] == null) heroLoc[name] = core.getHeroLoc(name);
 | ||
|     });
 | ||
|     return heroLoc;
 | ||
| };
 | ||
| 
 | ||
| events.prototype._changeFloor_beforeChange = function (info, callback) {
 | ||
|     this._changeFloor_playSound();
 | ||
|     // 需要 setTimeout 执行,不然会出错
 | ||
|     window.setTimeout(function () {
 | ||
|         if (info.time === 0 || main.replayChecking) {
 | ||
|             core.events._changeFloor_changing(info, callback);
 | ||
|         } else {
 | ||
|             const Render = Mota.require('@motajs/render').MotaRenderer;
 | ||
|             const main = Render.get('render-main');
 | ||
|             const change = main.getElementById('floor-change');
 | ||
|             change.setTitle(core.floors[info.floorId]?.title ?? '');
 | ||
|             change.showChange(info.time / 2).then(() => {
 | ||
|                 core.events._changeFloor_changing(info, callback);
 | ||
|             });
 | ||
|         }
 | ||
|     }, 25);
 | ||
| };
 | ||
| 
 | ||
| events.prototype._changeFloor_playSound = function () {
 | ||
|     // 播放换层音效
 | ||
|     if (core.hasFlag('__fromLoad__'))
 | ||
|         // 是否是读档造成的切换
 | ||
|         core.playSound('读档');
 | ||
|     else if (core.hasFlag('__isFlying__'))
 | ||
|         // 是否是楼传造成的切换
 | ||
|         core.playSound('飞行器');
 | ||
|     else core.playSound('上下楼');
 | ||
| };
 | ||
| 
 | ||
| events.prototype._changeFloor_changing = function (info, callback) {
 | ||
|     this.changingFloor(info.floorId, info.heroLoc);
 | ||
|     // 回归视角
 | ||
|     var __lockViewport__ = flags.__lockViewport__;
 | ||
|     core.setFlag('__lockViewport__', null);
 | ||
|     core.drawHero();
 | ||
|     core.setFlag('__lockViewport__', __lockViewport__);
 | ||
| 
 | ||
|     if (info.time === 0 || main.replayChecking) {
 | ||
|         this._changeFloor_afterChange(info, callback);
 | ||
|     } else {
 | ||
|         const Render = Mota.require('@motajs/render').MotaRenderer;
 | ||
|         const main = Render.get('render-main');
 | ||
|         const change = main.getElementById('floor-change');
 | ||
|         change.hideChange(info.time / 2).then(() => {
 | ||
|             core.events._changeFloor_afterChange(info, callback);
 | ||
|         });
 | ||
|     }
 | ||
| };
 | ||
| 
 | ||
| events.prototype._changeFloor_afterChange = function (info, callback) {
 | ||
|     if (!info.locked) core.unlockControl();
 | ||
|     core.status.replay.animate = false;
 | ||
|     core.events.afterChangeFloor(info.floorId);
 | ||
| 
 | ||
|     if (callback) callback();
 | ||
| };
 | ||
| 
 | ||
| events.prototype.changingFloor = function (floorId, heroLoc) {
 | ||
|     this.eventdata.changingFloor(floorId, heroLoc);
 | ||
|     Mota.require('@user/data-base').hook.emit(
 | ||
|         'changingFloor',
 | ||
|         floorId,
 | ||
|         heroLoc
 | ||
|     );
 | ||
| };
 | ||
| 
 | ||
| ////// 转换楼层结束的事件 //////
 | ||
| events.prototype.afterChangeFloor = function (floorId) {
 | ||
|     if (main.mode != 'play') return;
 | ||
|     return this.eventdata.afterChangeFloor(floorId);
 | ||
| };
 | ||
| 
 | ||
| ////// 是否到达过某个楼层 //////
 | ||
| events.prototype.hasVisitedFloor = function (floorId) {
 | ||
|     if (!core.hasFlag('__visited__')) core.setFlag('__visited__', {});
 | ||
|     return core.getFlag('__visited__')[floorId] || false;
 | ||
| };
 | ||
| 
 | ||
| ////// 到达某楼层 //////
 | ||
| events.prototype.visitFloor = function (floorId) {
 | ||
|     if (!core.hasFlag('__visited__')) core.setFlag('__visited__', {});
 | ||
|     core.getFlag('__visited__')[floorId] = true;
 | ||
| };
 | ||
| 
 | ||
| events.prototype._sys_pushBox = function (data, callback) {
 | ||
|     this.pushBox(data);
 | ||
|     if (callback) callback();
 | ||
| };
 | ||
| 
 | ||
| ////// 推箱子 //////
 | ||
| events.prototype.pushBox = function (data) {
 | ||
|     if (data.event.id != 'box' && data.event.id != 'boxed') return;
 | ||
| 
 | ||
|     // 判断还能否前进,看看是否存在事件
 | ||
|     var direction = core.getHeroLoc('direction'),
 | ||
|         nx = data.x + core.utils.scan[direction].x,
 | ||
|         ny = data.y + core.utils.scan[direction].y;
 | ||
| 
 | ||
|     // 检测能否推上去
 | ||
|     if (!core.canMoveHero()) return;
 | ||
|     var canGoDeadZone = core.flags.canGoDeadZone;
 | ||
|     core.flags.canGoDeadZone = true;
 | ||
|     if (!core.canMoveHero(data.x, data.y, direction)) {
 | ||
|         core.flags.canGoDeadZone = canGoDeadZone;
 | ||
|         return;
 | ||
|     }
 | ||
|     core.flags.canGoDeadZone = canGoDeadZone;
 | ||
| 
 | ||
|     var nextId = core.getBlockId(nx, ny);
 | ||
|     if (nextId != null && nextId != 'flower') return;
 | ||
| 
 | ||
|     core.setBlock(nextId == null ? 'box' : 'boxed', nx, ny);
 | ||
| 
 | ||
|     if (data.event.id == 'box') core.removeBlock(data.x, data.y);
 | ||
|     else core.setBlock('flower', data.x, data.y);
 | ||
|     // 勇士前进一格,然后触发推箱子后事件
 | ||
| };
 | ||
| 
 | ||
| events.prototype._sys_ski = function (data, callback) {
 | ||
|     core.insertAction(['V2.6后,请将滑冰放在背景层!'], data.x, data.y);
 | ||
|     if (callback) callback();
 | ||
| };
 | ||
| 
 | ||
| /// 当前是否在冰上
 | ||
| events.prototype.onSki = function (number) {
 | ||
|     if (number == null) number = core.getBgNumber();
 | ||
|     var block = core.getBlockByNumber(number);
 | ||
|     return block && block.event && block.event.trigger == 'ski';
 | ||
| };
 | ||
| 
 | ||
| events.prototype._sys_action = function (data, callback) {
 | ||
|     var ev = core.clone(data.event.data),
 | ||
|         ex = data.x,
 | ||
|         ey = data.y;
 | ||
|     // 检查是否需要改变朝向
 | ||
|     if (ex == core.nextX() && ey == core.nextY()) {
 | ||
|         var dir = core.turnDirection(':back');
 | ||
|         var id = data.event.id,
 | ||
|             toId = (data.event.faceIds || {})[dir];
 | ||
|         if (toId && id != toId) {
 | ||
|             var number = core.getNumberById(toId);
 | ||
|             if (number > 0) core.setBlock(number, ex, ey);
 | ||
|         }
 | ||
|     }
 | ||
|     this.insertAction(ev, ex, ey, callback);
 | ||
| };
 | ||
| 
 | ||
| events.prototype._sys_custom = function (data, callback) {
 | ||
|     core.insertAction(
 | ||
|         [
 | ||
|             "请使用\r[yellow]core.registerSystemEvent('custom', func)\r来处理自己添加的系统触发器!"
 | ||
|         ],
 | ||
|         data.x,
 | ||
|         data.y,
 | ||
|         callback
 | ||
|     );
 | ||
| };
 | ||
| 
 | ||
| // ------ 自定义事件的处理 ------ //
 | ||
| 
 | ||
| ////// 注册一个自定义事件 //////
 | ||
| // type为事件名,func为事件的处理函数,可接受(data, x, y, prefix)参数
 | ||
| // data为事件内容,x和y为当前点坐标(可为null),prefix为当前点前缀
 | ||
| events.prototype.registerEvent = function (type, func) {
 | ||
|     this.actions[type] = func;
 | ||
| };
 | ||
| 
 | ||
| ////// 注销一个自定义事件
 | ||
| events.prototype.unregisterEvent = function (type) {
 | ||
|     delete this.actions[type];
 | ||
| };
 | ||
| 
 | ||
| ////// 执行一个自定义事件
 | ||
| events.prototype.doEvent = function (data, x, y, prefix) {
 | ||
|     var type = data.type;
 | ||
|     if (this.actions[type]) {
 | ||
|         try {
 | ||
|             return this.actions[type].call(this, data, x, y, prefix);
 | ||
|         } catch (e) {
 | ||
|             console.error(e);
 | ||
|             console.error('ERROR in actions[' + type + ']');
 | ||
|         }
 | ||
|     }
 | ||
|     if (this['_action_' + type])
 | ||
|         return this['_action_' + type](data, x, y, prefix);
 | ||
|     core.insertAction('未知的自定义事件: ' + type + '!');
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype.setEvents = function (list, x, y, callback) {
 | ||
|     var data = core.status.event.data || {};
 | ||
|     if (list) {
 | ||
|         var l = core.clone(list);
 | ||
|         if (!(l instanceof Array)) l = [l];
 | ||
|         l.push({ type: '_label' });
 | ||
|         data.list = [{ todo: l, total: core.clone(l), condition: 'false' }];
 | ||
|         // 结束所有正在执行的自动事件
 | ||
|         if (list.length == 0) {
 | ||
|             core.status.autoEvents.forEach(function (autoEvent) {
 | ||
|                 core.autoEventExecuting(autoEvent.symbol, false);
 | ||
|             });
 | ||
|         }
 | ||
|     }
 | ||
|     if (x != null) data.x = x;
 | ||
|     if (y != null) data.y = y;
 | ||
|     if (callback) data.callback = callback;
 | ||
|     if (!data.appendingEvents) data.appendingEvents = [];
 | ||
|     if (!data.locStack) data.locStack = [];
 | ||
|     core.status.event.id = 'action';
 | ||
|     core.status.event.data = data;
 | ||
| };
 | ||
| 
 | ||
| ////// 开始执行一系列自定义事件 //////
 | ||
| events.prototype.startEvents = function (list, x, y, callback) {
 | ||
|     if (!list) return;
 | ||
|     if (!(list instanceof Array)) {
 | ||
|         list = [list];
 | ||
|     }
 | ||
|     this.setEvents(list, x, y, callback);
 | ||
|     // 停止勇士
 | ||
|     core.waitHeroToStop(function () {
 | ||
|         core.lockControl();
 | ||
|         core.doAction();
 | ||
|     });
 | ||
| };
 | ||
| 
 | ||
| ////// 执行当前自定义事件列表中的下一个事件 //////
 | ||
| events.prototype.doAction = function () {
 | ||
|     // 清空boxAnimate和UI层
 | ||
|     clearInterval(core.status.event.interval);
 | ||
|     clearTimeout(core.status.event.interval);
 | ||
|     clearInterval(core.status.event.animateUI);
 | ||
|     core.status.event.interval = null;
 | ||
|     delete core.status.event.aniamteUI;
 | ||
|     if (core.status.gameOver || core.status.replay.failed) return;
 | ||
|     // 判定是否执行完毕
 | ||
|     if (this._doAction_finishEvents()) return;
 | ||
|     core.clearUI();
 | ||
|     var floorId = core.status.event.data.floorId || core.status.floorId;
 | ||
|     // 当前点坐标和前缀
 | ||
|     var x = core.status.event.data.x,
 | ||
|         y = core.status.event.data.y;
 | ||
|     var prefix = [
 | ||
|         floorId || ':f',
 | ||
|         x != null ? x : 'x',
 | ||
|         y != null ? y : 'y'
 | ||
|     ].join('@');
 | ||
|     var current = core.status.event.data.list[0];
 | ||
|     if (this._popEvents(current, prefix)) return;
 | ||
|     // 当前要执行的事件
 | ||
|     var data = current.todo.shift();
 | ||
|     core.status.event.data.current = data;
 | ||
|     if (typeof data == 'string') data = { type: 'text', text: data };
 | ||
|     // 该事件块已经被禁用
 | ||
|     if (data._disabled) return core.doAction();
 | ||
|     data.floorId = data.floorId || floorId;
 | ||
|     core.status.event.data.type = data.type;
 | ||
|     this.doEvent(data, x, y, prefix);
 | ||
|     return;
 | ||
| };
 | ||
| 
 | ||
| events.prototype._doAction_finishEvents = function () {
 | ||
|     if (core.status.event.id != 'action') return true;
 | ||
|     // 事件处理完毕
 | ||
|     if (core.status.event.data.list.length == 0) {
 | ||
|         // 检测并执行延迟自动事件
 | ||
|         if (core.status.event.data.appendingEvents.length > 0) {
 | ||
|             this.setEvents(core.status.event.data.appendingEvents.shift());
 | ||
|             return false;
 | ||
|         }
 | ||
|         var callback = core.status.event.data.callback;
 | ||
|         core.ui.closePanel();
 | ||
|         if (callback) callback();
 | ||
|         core.replay();
 | ||
|         return true;
 | ||
|     }
 | ||
|     return false;
 | ||
| };
 | ||
| 
 | ||
| events.prototype._popEvents = function (current, prefix) {
 | ||
|     if (current.todo.length == 0) {
 | ||
|         // current list is empty
 | ||
|         if (core.calValue(current.condition, prefix)) {
 | ||
|             // check condition
 | ||
|             current.todo = core.clone(current.total);
 | ||
|         } else {
 | ||
|             core.status.event.data.list.shift(); // remove stack
 | ||
|         }
 | ||
|         core.doAction();
 | ||
|         return true;
 | ||
|     }
 | ||
|     return false;
 | ||
| };
 | ||
| 
 | ||
| ////// 往当前事件列表之前或之后添加一个或多个事件 //////
 | ||
| events.prototype.insertAction = function (action, x, y, callback, addToLast) {
 | ||
|     if (core.hasFlag('__statistics__')) return;
 | ||
|     if (core.status.gameOver) return;
 | ||
|     if (!action) return;
 | ||
|     core.clearRouteFolding();
 | ||
| 
 | ||
|     action = this.precompile(action);
 | ||
| 
 | ||
|     if (core.status.event.id != 'action') {
 | ||
|         this.startEvents(action, x, y, callback);
 | ||
|     } else {
 | ||
|         if (addToLast) {
 | ||
|             var list = core.status.event.data.list[0].todo;
 | ||
|             var index = 0;
 | ||
|             for (var index = 0; index < list.length; index++) {
 | ||
|                 if (list[index].type == '_label') {
 | ||
|                     list.splice(index, 0, action);
 | ||
|                     break;
 | ||
|                 }
 | ||
|             }
 | ||
|         } else core.unshift(core.status.event.data.list[0].todo, action);
 | ||
|         this.setEvents(null, x, y, callback);
 | ||
|     }
 | ||
| };
 | ||
| 
 | ||
| ////// 往当前事件列表之前或之后添加一个公共事件 //////
 | ||
| events.prototype.insertCommonEvent = function (
 | ||
|     name,
 | ||
|     args,
 | ||
|     x,
 | ||
|     y,
 | ||
|     callback,
 | ||
|     addToLast
 | ||
| ) {
 | ||
|     var commonEvent = this.getCommonEvent(name);
 | ||
|     if (!commonEvent) {
 | ||
|         if (callback) callback();
 | ||
|         return;
 | ||
|     }
 | ||
| 
 | ||
|     // 设置参数
 | ||
|     core.setFlag('arg0', name);
 | ||
|     if (args instanceof Array) {
 | ||
|         for (var i = 0; i < args.length; ++i) {
 | ||
|             try {
 | ||
|                 if (args[i] != null) core.setFlag('arg' + (i + 1), args[i]);
 | ||
|             } catch (ee) {
 | ||
|                 console.error(ee);
 | ||
|             }
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
|     this.insertAction(
 | ||
|         { type: 'dowhile', condition: 'false', data: commonEvent },
 | ||
|         x,
 | ||
|         y,
 | ||
|         callback,
 | ||
|         addToLast
 | ||
|     );
 | ||
| };
 | ||
| 
 | ||
| ////// 获得一个公共事件 //////
 | ||
| events.prototype.getCommonEvent = function (name) {
 | ||
|     if (!name || typeof name !== 'string') return null;
 | ||
|     return this.commonEvent[name] || null;
 | ||
| };
 | ||
| 
 | ||
| ////// 恢复一个事件 //////
 | ||
| events.prototype.recoverEvents = function (data) {
 | ||
|     if (data) {
 | ||
|         core.ui.closePanel();
 | ||
|         core.lockControl();
 | ||
|         core.status.event.id = 'action';
 | ||
|         core.status.event.data = data;
 | ||
|         setTimeout(function () {
 | ||
|             core.doAction();
 | ||
|         }, 30);
 | ||
|         return true;
 | ||
|     }
 | ||
|     return false;
 | ||
| };
 | ||
| 
 | ||
| ////// 检测自动事件 //////
 | ||
| events.prototype.checkAutoEvents = function () {
 | ||
|     // 只有在无操作或事件流中才能执行自动事件!
 | ||
|     if (
 | ||
|         !core.isPlaying() ||
 | ||
|         (core.status.lockControl && core.status.event.id != 'action')
 | ||
|     )
 | ||
|         return;
 | ||
|     if (core.hasFlag('__doNotCheckAutoEvents__')) return;
 | ||
|     var todo = [],
 | ||
|         delay = [];
 | ||
|     core.status.autoEvents.forEach(function (autoEvent) {
 | ||
|         var symbol = autoEvent.symbol,
 | ||
|             x = autoEvent.x,
 | ||
|             y = autoEvent.y,
 | ||
|             floorId = autoEvent.floorId;
 | ||
|         // 不在当前楼层 or 已经执行过 or 已被分区 or 正在执行中
 | ||
|         if (autoEvent.currentFloor && floorId != core.status.floorId) return;
 | ||
|         if (!autoEvent.multiExecute && core.autoEventExecuted(symbol)) return;
 | ||
|         if ((flags.__removed__ || []).indexOf(floorId) >= 0) return;
 | ||
|         if (core.autoEventExecuting(symbol)) return;
 | ||
|         var prefix = floorId + '@' + x + '@' + y;
 | ||
|         try {
 | ||
|             if (!core.calValue(autoEvent.condition, prefix)) return;
 | ||
|         } catch (e) {
 | ||
|             return;
 | ||
|         }
 | ||
| 
 | ||
|         core.autoEventExecuting(symbol, true);
 | ||
|         core.autoEventExecuted(symbol, true);
 | ||
| 
 | ||
|         var event;
 | ||
|         if (x == null && y == null) {
 | ||
|             event = [
 | ||
|                 // 用do-while(0)包一层防止break影响事件流
 | ||
|                 { type: 'dowhile', condition: 'false', data: autoEvent.data },
 | ||
|                 {
 | ||
|                     type: 'function',
 | ||
|                     function:
 | ||
|                         "function() { core.autoEventExecuting('" +
 | ||
|                         symbol +
 | ||
|                         "', false); }"
 | ||
|                 }
 | ||
|             ];
 | ||
|         } else {
 | ||
|             event = [
 | ||
|                 {
 | ||
|                     type: 'function',
 | ||
|                     function:
 | ||
|                         'function() { core.pushEventLoc(' +
 | ||
|                         x +
 | ||
|                         ', ' +
 | ||
|                         y +
 | ||
|                         ", '" +
 | ||
|                         floorId +
 | ||
|                         "' ); }"
 | ||
|                 },
 | ||
|                 // 用do-while(0)包一层防止break影响事件流
 | ||
|                 { type: 'dowhile', condition: 'false', data: autoEvent.data },
 | ||
|                 {
 | ||
|                     type: 'function',
 | ||
|                     function:
 | ||
|                         "function() { core.popEventLoc(); core.autoEventExecuting('" +
 | ||
|                         symbol +
 | ||
|                         "', false); }"
 | ||
|                 }
 | ||
|             ];
 | ||
|         }
 | ||
| 
 | ||
|         if (autoEvent.delayExecute) delay.push(event);
 | ||
|         else core.push(todo, event);
 | ||
|     });
 | ||
| 
 | ||
|     if (todo.length == 0 && delay.length == 0) return;
 | ||
| 
 | ||
|     if (core.status.event.id == 'action' || todo.length > 0) {
 | ||
|         core.insertAction(todo);
 | ||
|         core.push(core.status.event.data.appendingEvents, delay);
 | ||
|     } else {
 | ||
|         core.insertAction(delay[0]);
 | ||
|         if (delay.length > 0) {
 | ||
|             core.insertAction(delay.slice(1));
 | ||
|         }
 | ||
|     }
 | ||
| };
 | ||
| 
 | ||
| events.prototype.autoEventExecuting = function (symbol, value) {
 | ||
|     var aei = core.getFlag('__aei__', []);
 | ||
|     if (value == null) return aei.indexOf(symbol) >= 0;
 | ||
|     else {
 | ||
|         aei = aei.filter(function (one) {
 | ||
|             return one != symbol;
 | ||
|         });
 | ||
|         if (value) aei.push(symbol);
 | ||
|         core.setFlag('__aei__', aei);
 | ||
|     }
 | ||
| };
 | ||
| 
 | ||
| events.prototype.autoEventExecuted = function (symbol, value) {
 | ||
|     var aed = core.getFlag('__aed__', []);
 | ||
|     if (value == null) return aed.indexOf(symbol) >= 0;
 | ||
|     else {
 | ||
|         aed = aed.filter(function (one) {
 | ||
|             return one != symbol;
 | ||
|         });
 | ||
|         if (value) aed.push(symbol);
 | ||
|         core.setFlag('__aed__', aed);
 | ||
|     }
 | ||
| };
 | ||
| 
 | ||
| events.prototype.pushEventLoc = function (x, y, floorId) {
 | ||
|     if (core.status.event.id != 'action') return;
 | ||
|     core.status.event.data.locStack.push({
 | ||
|         x: core.status.event.data.x,
 | ||
|         y: core.status.event.data.y,
 | ||
|         floorId: core.status.event.data.floorId
 | ||
|     });
 | ||
|     core.status.event.data.x = x;
 | ||
|     core.status.event.data.y = y;
 | ||
|     core.status.event.data.floorId = floorId;
 | ||
| };
 | ||
| 
 | ||
| events.prototype.popEventLoc = function () {
 | ||
|     if (core.status.event.id != 'action') return;
 | ||
|     var loc = core.status.event.data.locStack.shift();
 | ||
|     if (loc) {
 | ||
|         core.status.event.data.x = loc.x;
 | ||
|         core.status.event.data.y = loc.y;
 | ||
|         core.status.event.data.floorId = loc.floorId;
 | ||
|     }
 | ||
| };
 | ||
| 
 | ||
| events.prototype.precompile = function (data) {
 | ||
|     var array = this.__precompile_getArray();
 | ||
|     if (typeof data == 'string') {
 | ||
|         return this.__precompile_text(data);
 | ||
|     }
 | ||
|     if (data instanceof Array) {
 | ||
|         for (var i = 0; i < data.length; ++i) {
 | ||
|             data[i] = this.precompile(data[i]);
 | ||
|         }
 | ||
|         return data;
 | ||
|     }
 | ||
|     if (data && data.type) {
 | ||
|         if (this['_precompile_' + data.type]) {
 | ||
|             data = this['_precompile_' + data.type](data);
 | ||
|         }
 | ||
|         if (array.texts.indexOf(data.type) >= 0) {
 | ||
|             data.text = this.__precompile_text(data.text);
 | ||
|         }
 | ||
|         if (array.locs.indexOf(data.type) >= 0) {
 | ||
|             data.loc = this.__precompile_array(data.loc);
 | ||
|         }
 | ||
|         if (array.values.indexOf(data.type) >= 0) {
 | ||
|             data.value = core.replaceValue(data.value);
 | ||
|         }
 | ||
|         if (array.uievents.indexOf(data.type) >= 0) {
 | ||
|             data.x = core.replaceValue(data.x);
 | ||
|             data.y = core.replaceValue(data.y);
 | ||
|             data.width = core.replaceValue(data.width);
 | ||
|             data.height = core.replaceValue(data.height);
 | ||
|         }
 | ||
|         if (data.type in array.others) {
 | ||
|             array.others[data.type].forEach(function (field) {
 | ||
|                 data[field] = core.replaceValue(data[field]);
 | ||
|             });
 | ||
|         }
 | ||
|     }
 | ||
|     return data;
 | ||
| };
 | ||
| 
 | ||
| events.prototype.__precompile_getArray = function () {
 | ||
|     var texts = [
 | ||
|         'text',
 | ||
|         'autoText',
 | ||
|         'scrollText',
 | ||
|         'tip',
 | ||
|         'textImage',
 | ||
|         'input',
 | ||
|         'input2',
 | ||
|         'choices',
 | ||
|         'confirm',
 | ||
|         'fillText',
 | ||
|         'fillBoldText',
 | ||
|         'drawTextContent'
 | ||
|     ];
 | ||
|     var locs = [
 | ||
|         'show',
 | ||
|         'hide',
 | ||
|         'setBlock',
 | ||
|         'setBlockOpacity',
 | ||
|         'showFloorImg',
 | ||
|         'hideFloorImg',
 | ||
|         'showBgFgMap',
 | ||
|         'hideBgFgMap',
 | ||
|         'setBgFgBlock',
 | ||
|         'animate',
 | ||
|         'setViewport',
 | ||
|         'move',
 | ||
|         'jumoHero',
 | ||
|         'changeFloor',
 | ||
|         'changePos',
 | ||
|         'showTextImage',
 | ||
|         'showGif',
 | ||
|         'openDoor',
 | ||
|         'closeDoor',
 | ||
|         'battle',
 | ||
|         'trigger',
 | ||
|         'insert',
 | ||
|         'setEnemyOnPoint',
 | ||
|         'resetEnemyOnPoint'
 | ||
|     ];
 | ||
|     var values = [
 | ||
|         'setValue',
 | ||
|         'setEnemy',
 | ||
|         'setEnemyOnPoint',
 | ||
|         'setEquip',
 | ||
|         'setFloor',
 | ||
|         'setGlobalValue'
 | ||
|     ];
 | ||
|     var uievents = [
 | ||
|         'clearMap',
 | ||
|         'fillText',
 | ||
|         'fillBoldText',
 | ||
|         'fillRect',
 | ||
|         'strokeRect',
 | ||
|         'fillEllipse',
 | ||
|         'strokeEllipse',
 | ||
|         'fillArc',
 | ||
|         'strokeArc',
 | ||
|         'drawIcon',
 | ||
|         'drawSelector',
 | ||
|         'drawBackground'
 | ||
|     ];
 | ||
|     var others = {
 | ||
|         fillEllipse: ['a', 'b', 'angle'],
 | ||
|         strokeEllipse: ['a', 'b', 'angle'],
 | ||
|         fillRect: ['radius', 'angle'],
 | ||
|         strokeRect: ['radius', 'angle'],
 | ||
|         fillArc: ['r', 'start', 'end'],
 | ||
|         strokeArc: ['r', 'start', 'end'],
 | ||
|         drawLine: ['x1', 'y1', 'x2', 'y2'],
 | ||
|         drawArrow: ['x1', 'y1', 'x2', 'y2'],
 | ||
|         drawImage: ['x', 'y', 'w', 'h', 'x1', 'y1', 'w1', 'h1', 'angle'],
 | ||
|         drawTextContent: ['left', 'top']
 | ||
|     };
 | ||
|     return {
 | ||
|         texts: texts,
 | ||
|         locs: locs,
 | ||
|         values: values,
 | ||
|         uievents: uievents,
 | ||
|         others: others
 | ||
|     };
 | ||
| };
 | ||
| 
 | ||
| events.prototype.__precompile_text = function (text) {
 | ||
|     if (typeof text != 'string') return text;
 | ||
|     return text.replace(/\${(.*?)}/g, function (word, value) {
 | ||
|         return '${' + core.replaceValue(value) + '}';
 | ||
|     });
 | ||
| };
 | ||
| 
 | ||
| events.prototype.__precompile_array = function (value) {
 | ||
|     if (typeof value == 'string') {
 | ||
|         value = core.replaceValue(value);
 | ||
|         return value;
 | ||
|     }
 | ||
|     if (value instanceof Array) {
 | ||
|         for (var i = 0; i < value.length; ++i) {
 | ||
|             value[i] = this.__precompile_array(value[i]);
 | ||
|         }
 | ||
|     }
 | ||
|     return value;
 | ||
| };
 | ||
| 
 | ||
| // ------ 样板提供的的自定义事件 ------ //
 | ||
| 
 | ||
| events.prototype.__action_checkReplaying = function () {
 | ||
|     if (core.isReplaying()) {
 | ||
|         core.doAction();
 | ||
|         return true;
 | ||
|     }
 | ||
|     return false;
 | ||
| };
 | ||
| 
 | ||
| events.prototype.__action_getLoc = function (loc, x, y, prefix) {
 | ||
|     if (loc) {
 | ||
|         x = core.calValue(loc[0], prefix);
 | ||
|         y = core.calValue(loc[1], prefix);
 | ||
|     }
 | ||
|     return [x, y];
 | ||
| };
 | ||
| 
 | ||
| events.prototype.__action_getHeroLoc = function (loc, prefix) {
 | ||
|     return this.__action_getLoc(
 | ||
|         loc,
 | ||
|         core.getHeroLoc('x'),
 | ||
|         core.getHeroLoc('y'),
 | ||
|         prefix
 | ||
|     );
 | ||
| };
 | ||
| 
 | ||
| events.prototype.__action_getLoc2D = function (loc, x, y, prefix) {
 | ||
|     if (!(loc && loc[0] instanceof Array))
 | ||
|         loc = [this.__action_getLoc(loc, x, y, prefix)];
 | ||
|     return loc;
 | ||
| };
 | ||
| 
 | ||
| events.prototype.__action_doAsyncFunc = function (isAsync, func) {
 | ||
|     var parameters = Array.prototype.slice.call(arguments, 2);
 | ||
|     if (isAsync) {
 | ||
|         func.apply(this, parameters);
 | ||
|         core.doAction();
 | ||
|     } else {
 | ||
|         func.apply(this, parameters.concat(core.doAction));
 | ||
|     }
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_text = function (data) {
 | ||
|     if (main.replayChecking) {
 | ||
|         core.doAction();
 | ||
|         return;
 | ||
|     }
 | ||
|     if (this.__action_checkReplaying()) return;
 | ||
|     const Store = Mota.require('@user/client-modules').TextboxStore;
 | ||
|     const { textbox = 'main-textbox', text, icon = 'none', title = '' } = data;
 | ||
|     const store = Store.get(textbox);
 | ||
|     if (!store) {
 | ||
|         core.doAction();
 | ||
|         return;
 | ||
|     }
 | ||
|     const loc = store.data.loc?.slice() ?? [];
 | ||
|     loc[0] ??= 0;
 | ||
|     loc[1] ??= 0;
 | ||
|     loc[2] ??= 200;
 | ||
|     loc[3] ??= 200;
 | ||
|     const { x = loc[0], y = loc[1], width = loc[2], height = loc[3] } = data;
 | ||
|     store.show();
 | ||
|     store.modify({
 | ||
|         title,
 | ||
|         icon,
 | ||
|         x,
 | ||
|         y,
 | ||
|         width,
 | ||
|         height,
 | ||
|         loc: [x, y, width, height]
 | ||
|     });
 | ||
|     store.setText(text);
 | ||
|     core.events.nowTextbox = textbox;
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_autoText = function (data) {
 | ||
|     if (main.replayChecking) {
 | ||
|         core.doAction();
 | ||
|         return;
 | ||
|     }
 | ||
|     if (this.__action_checkReplaying()) return;
 | ||
|     const Store = Mota.require('@user/client-modules').TextboxStore;
 | ||
|     const { textbox = 'main-textbox', text, icon = 'none', title = '' } = data;
 | ||
|     const store = Store.get(textbox);
 | ||
|     if (!store) {
 | ||
|         core.doAction();
 | ||
|         return;
 | ||
|     }
 | ||
|     const loc = store.data.loc?.slice() ?? [];
 | ||
|     loc[0] ??= 0;
 | ||
|     loc[1] ??= 0;
 | ||
|     loc[2] ??= 200;
 | ||
|     loc[3] ??= 200;
 | ||
|     const { x = loc[0], y = loc[1], width = loc[2], height = loc[3] } = data;
 | ||
|     store.show();
 | ||
|     store.modify({
 | ||
|         title,
 | ||
|         icon,
 | ||
|         x,
 | ||
|         y,
 | ||
|         width,
 | ||
|         height,
 | ||
|         loc: [x, y, width, height]
 | ||
|     });
 | ||
|     store.setText(text);
 | ||
| 
 | ||
|     setTimeout(() => {
 | ||
|         store.hide();
 | ||
|         core.doAction();
 | ||
|     }, data.time ?? 3000);
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_scrollText = function (data, x, y, prefix) {
 | ||
|     if (this.__action_checkReplaying()) return;
 | ||
|     // todo: 2.B.1
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_comment = function (data, x, y, prefix) {
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action__label = function (data, x, y, prefix) {
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_setText = function (data) {
 | ||
|     if (main.replayChecking) {
 | ||
|         core.doAction();
 | ||
|         return;
 | ||
|     }
 | ||
|     const isNil = value => value === null || value === void 0;
 | ||
|     const { textbox = 'main-textbox' } = data;
 | ||
|     const Store = Mota.require('@user/client-modules').TextboxStore;
 | ||
|     const { TextAlign, WordBreak } = Mota.require('@user/client-modules');
 | ||
|     const Font = Mota.require('@motajs/render-style').Font;
 | ||
|     const store = Store.get(textbox);
 | ||
|     if (!store) {
 | ||
|         core.doAction();
 | ||
|         return;
 | ||
|     }
 | ||
|     // loc
 | ||
|     const loc = store.data.loc?.slice() ?? [];
 | ||
|     loc[0] ??= 0;
 | ||
|     loc[1] ??= 0;
 | ||
|     loc[2] ??= 200;
 | ||
|     loc[3] ??= 200;
 | ||
|     const { x = loc[0], y = loc[1], width = loc[2], height = loc[3] } = data;
 | ||
|     const newLoc = [x, y, width, height];
 | ||
|     // font
 | ||
|     const { fontFamily, fontSize, fontWeight, fontItalic } = data;
 | ||
|     const font = store.data.font ?? new Font();
 | ||
|     const newFont = Font.clone(font, {
 | ||
|         family: fontFamily,
 | ||
|         size: fontSize,
 | ||
|         weight: fontWeight,
 | ||
|         italic: fontItalic
 | ||
|     });
 | ||
|     // config
 | ||
|     const config = {
 | ||
|         x,
 | ||
|         y,
 | ||
|         width,
 | ||
|         height,
 | ||
|         loc: newLoc,
 | ||
|         font: newFont,
 | ||
|         keepLast: data.keepLast,
 | ||
|         interval: data.interval,
 | ||
|         lineHeight: data.lineHeight,
 | ||
|         fillStyle: data.fillStyle,
 | ||
|         strokeStyle: data.strokeStyle,
 | ||
|         strokeWidth: data.strokeWidth,
 | ||
|         fill: isNil(data.fill),
 | ||
|         stroke: !!data.stroke,
 | ||
|         backColor: data.backColor,
 | ||
|         winskin: data.winskin,
 | ||
|         padding: data.padding,
 | ||
|         titleFill: isNil(data.titleFill) ? 'gold' : 'transparent',
 | ||
|         titleStroke: data.titleStroke ? 'black' : 'transparent',
 | ||
|         titlePadding: data.titlePadding,
 | ||
|         ignoreLineStart: data.ignoreLineStart,
 | ||
|         ignoreLineEnd: data.ignoreLineEnd,
 | ||
|         breakChars: data.breakChars
 | ||
|     };
 | ||
|     switch (data.textAlign) {
 | ||
|         case 'left':
 | ||
|             config.textAlign = TextAlign.Left;
 | ||
|             break;
 | ||
|         case 'center':
 | ||
|             config.textAlign = TextAlign.Center;
 | ||
|             break;
 | ||
|         case 'right':
 | ||
|             config.textAlign = TextAlign.Right;
 | ||
|             break;
 | ||
|     }
 | ||
|     switch (data.wordBreak) {
 | ||
|         case 'none':
 | ||
|             config.wordBreak = WordBreak.None;
 | ||
|             break;
 | ||
|         case 'space':
 | ||
|             config.wordBreak = WordBreak.Space;
 | ||
|             break;
 | ||
|         case 'all':
 | ||
|             config.wordBreak = WordBreak.All;
 | ||
|             break;
 | ||
|     }
 | ||
| 
 | ||
|     store.modify(config);
 | ||
| 
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_tip = function (data, x, y, prefix) {
 | ||
|     core.drawTip(core.replaceText(data.text, prefix), data.icon);
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_confirm = function (data, x, y, prefix) {
 | ||
|     data.text = core.replaceText(data.text, prefix);
 | ||
|     core.ui.drawConfirmBox(
 | ||
|         data.text,
 | ||
|         () => {
 | ||
|             core.insertAction(data.yes ?? []);
 | ||
|             core.doAction();
 | ||
|         },
 | ||
|         () => {
 | ||
|             core.insertAction(data.no ?? []);
 | ||
|             core.doAction();
 | ||
|         }
 | ||
|     );
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_choices = function (data, x, y, prefix) {
 | ||
|     core.ui.drawChoices2(
 | ||
|         core.replaceText(data.text, prefix),
 | ||
|         data.choices,
 | ||
|         data.width
 | ||
|     );
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_show = function (data, x, y, prefix) {
 | ||
|     data.loc = this.__action_getLoc2D(data.loc, x, y, prefix);
 | ||
|     if (data.time > 0 && data.floorId == core.status.floorId) {
 | ||
|         this.__action_doAsyncFunc(
 | ||
|             data.async,
 | ||
|             core.animateBlock,
 | ||
|             data.loc,
 | ||
|             'show',
 | ||
|             data.time
 | ||
|         );
 | ||
|     } else {
 | ||
|         data.loc.forEach(function (t) {
 | ||
|             core.showBlock(t[0], t[1], data.floorId);
 | ||
|         });
 | ||
|         core.doAction();
 | ||
|     }
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_hide = function (data, x, y, prefix) {
 | ||
|     data.loc = this.__action_getLoc2D(data.loc, x, y, prefix);
 | ||
|     if (data.time > 0 && data.floorId == core.status.floorId) {
 | ||
|         this.__action_doAsyncFunc(
 | ||
|             data.async,
 | ||
|             core.animateBlock,
 | ||
|             data.loc,
 | ||
|             data.remove ? 'remove' : 'hide',
 | ||
|             data.time
 | ||
|         );
 | ||
|     } else {
 | ||
|         data.loc.forEach(function (t) {
 | ||
|             if (data.remove) core.removeBlock(t[0], t[1], data.floorId);
 | ||
|             else core.hideBlock(t[0], t[1], data.floorId);
 | ||
|         });
 | ||
|         core.doAction();
 | ||
|     }
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_setBlock = function (data, x, y, prefix) {
 | ||
|     data.loc = this.__action_getLoc2D(data.loc, x, y, prefix);
 | ||
|     data.time = data.time || 0;
 | ||
|     data.floorId = data.floorId || core.status.floorId;
 | ||
|     if (data.time > 0 && data.floorId == core.status.floorId) {
 | ||
|         this.__action_doAsyncFunc(
 | ||
|             data.async,
 | ||
|             core.animateSetBlocks,
 | ||
|             data.number,
 | ||
|             data.loc,
 | ||
|             data.floorId,
 | ||
|             data.time
 | ||
|         );
 | ||
|     } else {
 | ||
|         data.loc.forEach(function (loc) {
 | ||
|             core.setBlock(data.number, loc[0], loc[1], data.floorId);
 | ||
|         });
 | ||
|         core.doAction();
 | ||
|     }
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_setBlockOpacity = function (data, x, y, prefix) {
 | ||
|     data.loc = this.__action_getLoc2D(data.loc, x, y, prefix);
 | ||
|     if (data.time > 0 && data.floorId == core.status.floorId) {
 | ||
|         this.__action_doAsyncFunc(
 | ||
|             data.async,
 | ||
|             core.animateBlock,
 | ||
|             data.loc,
 | ||
|             data.opacity,
 | ||
|             data.time
 | ||
|         );
 | ||
|     } else {
 | ||
|         data.loc.forEach(function (t) {
 | ||
|             core.setBlockOpacity(data.opacity, t[0], t[1], data.floorId);
 | ||
|         });
 | ||
|         core.doAction();
 | ||
|     }
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_setBlockFilter = function (data, x, y, prefix) {
 | ||
|     data.loc = this.__action_getLoc2D(data.loc, x, y, prefix);
 | ||
|     data.loc.forEach(function (t) {
 | ||
|         core.setBlockFilter(data, t[0], t[1], data.floorId);
 | ||
|     });
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_turnBlock = function (data, x, y, prefix) {
 | ||
|     data.loc = this.__action_getLoc2D(data.loc, x, y, prefix);
 | ||
|     data.loc.forEach(function (t) {
 | ||
|         core.turnBlock(data.direction, t[0], t[1], data.floorId);
 | ||
|     });
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_showFloorImg = function (data, x, y, prefix) {
 | ||
|     core.maps.showFloorImage(
 | ||
|         this.__action_getLoc2D(data.loc, x, y, prefix),
 | ||
|         data.floorId,
 | ||
|         core.doAction
 | ||
|     );
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_hideFloorImg = function (data, x, y, prefix) {
 | ||
|     core.maps.hideFloorImage(
 | ||
|         this.__action_getLoc2D(data.loc, x, y, prefix),
 | ||
|         data.floorId,
 | ||
|         core.doAction
 | ||
|     );
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_showBgFgMap = function (data, x, y, prefix) {
 | ||
|     core.maps.showBgFgMap(
 | ||
|         data.name,
 | ||
|         this.__action_getLoc2D(data.loc, x, y, prefix),
 | ||
|         data.floorId,
 | ||
|         core.doAction
 | ||
|     );
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_hideBgFgMap = function (data, x, y, prefix) {
 | ||
|     core.maps.hideBgFgMap(
 | ||
|         data.name,
 | ||
|         this.__action_getLoc2D(data.loc, x, y, prefix),
 | ||
|         data.floorId,
 | ||
|         core.doAction
 | ||
|     );
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_setBgFgBlock = function (data, x, y, prefix) {
 | ||
|     data.loc = this.__action_getLoc2D(data.loc, x, y, prefix);
 | ||
|     data.loc.forEach(function (t) {
 | ||
|         core.setBgFgBlock(data.name, data.number, t[0], t[1], data.floorId);
 | ||
|     });
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_follow = function (data, x, y, prefix) {
 | ||
|     this.follow(data.name);
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_unfollow = function (data, x, y, prefix) {
 | ||
|     this.unfollow(data.name);
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_animate = function (data, x, y, prefix) {
 | ||
|     if (data.loc == 'hero') {
 | ||
|         this.__action_doAsyncFunc(data.async, core.drawHeroAnimate, data.name);
 | ||
|     } else {
 | ||
|         data.loc = this.__action_getLoc(data.loc, x, y, prefix);
 | ||
|         this.__action_doAsyncFunc(
 | ||
|             data.async,
 | ||
|             core.drawAnimate,
 | ||
|             data.name,
 | ||
|             data.loc[0],
 | ||
|             data.loc[1],
 | ||
|             data.alignWindow
 | ||
|         );
 | ||
|     }
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_stopAnimate = function (data, x, y, prefix) {
 | ||
|     core.stopAnimate(null, data.doCallback);
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_setViewport = function (data, x, y, prefix) {
 | ||
|     if (data.dxy != null) {
 | ||
|         data.loc = [
 | ||
|             core.bigmap.offsetX / 32 +
 | ||
|                 (core.calValue(data.dxy[0], prefix) || 0),
 | ||
|             core.bigmap.offsetY / 32 + (core.calValue(data.dxy[1], prefix) || 0)
 | ||
|         ];
 | ||
|     } else if (data.loc == null) {
 | ||
|         data.loc = [
 | ||
|             core.getHeroLoc('x') - core._HALF_WIDTH_,
 | ||
|             core.getHeroLoc('y') - core._HALF_HEIGHT_
 | ||
|         ];
 | ||
|     } else {
 | ||
|         data.loc = this.__action_getLoc(data.loc, x, y, prefix);
 | ||
|     }
 | ||
|     this.__action_doAsyncFunc(
 | ||
|         data.async,
 | ||
|         core.moveViewport,
 | ||
|         data.loc[0],
 | ||
|         data.loc[1],
 | ||
|         data.moveMode,
 | ||
|         data.time
 | ||
|     );
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_lockViewport = function (data, x, y, prefix) {
 | ||
|     core.setFlag('__lockViewport__', data.lock || null);
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_move = function (data, x, y, prefix) {
 | ||
|     var loc = this.__action_getLoc(data.loc, x, y, prefix);
 | ||
|     this.__action_doAsyncFunc(
 | ||
|         data.async,
 | ||
|         core.moveBlock,
 | ||
|         loc[0],
 | ||
|         loc[1],
 | ||
|         data.steps,
 | ||
|         data.time,
 | ||
|         data.keep
 | ||
|     );
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_moveAction = function (data, x, y, prefix) {
 | ||
|     // 检查下一个点是否可通行
 | ||
|     if (core.canMoveHero()) {
 | ||
|         var nx = core.nextX(),
 | ||
|             ny = core.nextY();
 | ||
|         // 检查noPass决定是撞击还是移动
 | ||
|         if (core.noPass(nx, ny)) {
 | ||
|             core.insertAction([{ type: 'trigger', loc: [nx, ny] }]);
 | ||
|         } else {
 | ||
|             // 先移动一格,然后尝试触发事件
 | ||
|             core.insertAction([
 | ||
|                 { type: 'moveHero', steps: ['forward'] },
 | ||
|                 {
 | ||
|                     type: 'function',
 | ||
|                     function: 'function() { core.moveOneStep(core.doAction); }',
 | ||
|                     async: true
 | ||
|                 },
 | ||
|                 { type: '_label' }
 | ||
|             ]);
 | ||
|         }
 | ||
|     }
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_moveHero = function (data, x, y, prefix) {
 | ||
|     this.__action_doAsyncFunc(
 | ||
|         data.async,
 | ||
|         core.eventMoveHero,
 | ||
|         data.steps,
 | ||
|         data.time
 | ||
|     );
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_jump = function (data, x, y, prefix) {
 | ||
|     var from = this.__action_getLoc(data.from, x, y, prefix),
 | ||
|         to;
 | ||
|     if (data.dxy) {
 | ||
|         to = [
 | ||
|             from[0] + (core.calValue(data.dxy[0], prefix) || 0),
 | ||
|             from[1] + (core.calValue(data.dxy[1], prefix) || 0)
 | ||
|         ];
 | ||
|     } else {
 | ||
|         to = this.__action_getLoc(data.to, x, y, prefix);
 | ||
|     }
 | ||
|     this.__action_doAsyncFunc(
 | ||
|         data.async,
 | ||
|         core.jumpBlock,
 | ||
|         from[0],
 | ||
|         from[1],
 | ||
|         to[0],
 | ||
|         to[1],
 | ||
|         data.time,
 | ||
|         data.keep
 | ||
|     );
 | ||
| };
 | ||
| 
 | ||
| events.prototype._precompile_jump = function (data) {
 | ||
|     data.from = this.__precompile_array(data.from);
 | ||
|     data.to = this.__precompile_array(data.to);
 | ||
|     data.dxy = this.__precompile_array(data.dxy);
 | ||
|     return data;
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_jumpHero = function (data, x, y, prefix) {
 | ||
|     var loc;
 | ||
|     if (data.dxy) {
 | ||
|         loc = [
 | ||
|             core.getHeroLoc('x') + (core.calValue(data.dxy[0], prefix) || 0),
 | ||
|             core.getHeroLoc('y') + (core.calValue(data.dxy[1], prefix) || 0)
 | ||
|         ];
 | ||
|     } else {
 | ||
|         loc = this.__action_getHeroLoc(data.loc, prefix);
 | ||
|     }
 | ||
| 
 | ||
|     this.__action_doAsyncFunc(
 | ||
|         data.async,
 | ||
|         core.jumpHero,
 | ||
|         loc[0],
 | ||
|         loc[1],
 | ||
|         data.time
 | ||
|     );
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_changeFloor = function (data, x, y, prefix) {
 | ||
|     var loc = this.__action_getHeroLoc(data.loc, prefix);
 | ||
|     var heroLoc = { x: loc[0], y: loc[1], direction: data.direction };
 | ||
|     core.changeFloor(
 | ||
|         data.floorId,
 | ||
|         data.stair,
 | ||
|         heroLoc,
 | ||
|         data.time,
 | ||
|         core.doAction
 | ||
|     );
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_changePos = function (data, x, y, prefix) {
 | ||
|     core.clearMap('hero');
 | ||
|     if (!data.loc && data.direction) {
 | ||
|         core.setHeroLoc('direction', core.turnDirection(data.direction), true);
 | ||
|         // core.drawHero();
 | ||
|         return core.doAction();
 | ||
|     }
 | ||
| 
 | ||
|     var loc = this.__action_getHeroLoc(data.loc, prefix);
 | ||
|     core.setHeroLoc('x', loc[0]);
 | ||
|     core.setHeroLoc('y', loc[1]);
 | ||
|     if (data.direction)
 | ||
|         core.setHeroLoc('direction', core.turnDirection(data.direction));
 | ||
|     core.drawHero();
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_showImage = function (data, x, y, prefix) {
 | ||
|     if (core.isReplaying()) data.time = 0;
 | ||
|     this.__action_doAsyncFunc(
 | ||
|         data.async || data.time == 0,
 | ||
|         core.showImage,
 | ||
|         data.code,
 | ||
|         data.image + (data.reverse || ''),
 | ||
|         data.sloc,
 | ||
|         data.loc,
 | ||
|         data.opacity,
 | ||
|         data.time
 | ||
|     );
 | ||
| };
 | ||
| 
 | ||
| events.prototype._precompile_showImage = function (data) {
 | ||
|     data.sloc = this.__precompile_array(data.sloc);
 | ||
|     data.loc = this.__precompile_array(data.loc);
 | ||
|     return data;
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_showTextImage = function (data, x, y, prefix) {
 | ||
|     var loc = this.__action_getLoc(data.loc, 0, 0, prefix);
 | ||
|     if (core.isReplaying()) data.time = 0;
 | ||
|     data.text = core.replaceText(data.text, prefix);
 | ||
|     var __tmpName =
 | ||
|         (Math.random() + '_' + Math.random()).replace(/\./g, '') + '.png';
 | ||
|     core.material.images.images[__tmpName] = core.ui.textImage(data.text);
 | ||
|     this.__action_doAsyncFunc(
 | ||
|         data.async || data.time == 0,
 | ||
|         core.showImage,
 | ||
|         data.code,
 | ||
|         __tmpName + (data.reverse || ''),
 | ||
|         null,
 | ||
|         loc,
 | ||
|         data.opacity,
 | ||
|         data.time
 | ||
|     );
 | ||
|     delete core.material.images.images[__tmpName];
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_hideImage = function (data, x, y, prefix) {
 | ||
|     if (core.isReplaying()) data.time = 0;
 | ||
|     this.__action_doAsyncFunc(
 | ||
|         data.async || data.time == 0,
 | ||
|         core.hideImage,
 | ||
|         data.code,
 | ||
|         data.time
 | ||
|     );
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_showGif = function (data, x, y, prefix) {
 | ||
|     var loc = this.__action_getLoc(data.loc, 0, 0, prefix);
 | ||
|     this.showGif(data.name, loc[0], loc[1]);
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_moveImage = function (data, x, y, prefix) {
 | ||
|     if (this.__action_checkReplaying()) return;
 | ||
|     this.__action_doAsyncFunc(
 | ||
|         data.async,
 | ||
|         core.moveImage,
 | ||
|         data.code,
 | ||
|         data.to,
 | ||
|         data.opacity,
 | ||
|         data.moveMode,
 | ||
|         data.time
 | ||
|     );
 | ||
| };
 | ||
| 
 | ||
| events.prototype._precompile_moveImage = function (data) {
 | ||
|     data.to = this.__precompile_array(data.to);
 | ||
|     return data;
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_rotateImage = function (data, x, y, prefix) {
 | ||
|     if (this.__action_checkReplaying()) return;
 | ||
|     this.__action_doAsyncFunc(
 | ||
|         data.async,
 | ||
|         core.rotateImage,
 | ||
|         data.code,
 | ||
|         data.center,
 | ||
|         data.angle,
 | ||
|         data.moveMode,
 | ||
|         data.time
 | ||
|     );
 | ||
| };
 | ||
| 
 | ||
| events.prototype._precompile_rotateImage = function (data) {
 | ||
|     data.center = this.__precompile_array(data.center);
 | ||
|     return data;
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_scaleImage = function (data, x, y, prefix) {
 | ||
|     if (this.__action_checkReplaying()) return;
 | ||
|     this.__action_doAsyncFunc(
 | ||
|         data.async,
 | ||
|         core.scaleImage,
 | ||
|         data.code,
 | ||
|         data.center,
 | ||
|         data.scale,
 | ||
|         data.moveMode,
 | ||
|         data.time
 | ||
|     );
 | ||
| };
 | ||
| 
 | ||
| events.prototype._precompile_scaleImage = function (data) {
 | ||
|     data.center = this.__precompile_array(data.center);
 | ||
|     return data;
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_setCurtain = function (data, x, y, prefix) {
 | ||
|     if (data.async) {
 | ||
|         core.setCurtain(
 | ||
|             data.color || core.status.thisMap.color,
 | ||
|             data.time,
 | ||
|             data.moveMode
 | ||
|         );
 | ||
|         if (data.color == null || data.keep)
 | ||
|             core.setFlag('__color__', data.color || null);
 | ||
|         core.doAction();
 | ||
|     } else {
 | ||
|         core.setCurtain(
 | ||
|             data.color || core.status.thisMap.color,
 | ||
|             data.time,
 | ||
|             data.moveMode,
 | ||
|             function () {
 | ||
|                 if (data.color == null || data.keep)
 | ||
|                     core.setFlag('__color__', data.color || null);
 | ||
|                 core.doAction();
 | ||
|             }
 | ||
|         );
 | ||
|     }
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_screenFlash = function (data, x, y, prefix) {
 | ||
|     this.__action_doAsyncFunc(
 | ||
|         data.async,
 | ||
|         core.screenFlash,
 | ||
|         data.color,
 | ||
|         data.time,
 | ||
|         data.times,
 | ||
|         data.moveMode
 | ||
|     );
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_setWeather = function (data, x, y, prefix) {
 | ||
|     core.setWeather(data.name, data.level);
 | ||
|     if (
 | ||
|         data.keep &&
 | ||
|         ['rain', 'snow', 'sun', 'fog', 'cloud'].indexOf(data.name) >= 0
 | ||
|     )
 | ||
|         core.setFlag('__weather__', [data.name, data.level]);
 | ||
|     else core.removeFlag('__weather__');
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_openDoor = function (data, x, y, prefix) {
 | ||
|     var loc = this.__action_getLoc(data.loc, x, y, prefix);
 | ||
|     var floorId = data.floorId;
 | ||
|     if (floorId == core.status.floorId) {
 | ||
|         this.__action_doAsyncFunc(
 | ||
|             data.async,
 | ||
|             core.openDoor,
 | ||
|             loc[0],
 | ||
|             loc[1],
 | ||
|             data.needKey
 | ||
|         );
 | ||
|     } else {
 | ||
|         core.removeBlock(loc[0], loc[1], floorId);
 | ||
|         core.doAction();
 | ||
|     }
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_closeDoor = function (data, x, y, prefix) {
 | ||
|     var loc = this.__action_getLoc(data.loc, x, y, prefix);
 | ||
|     this.__action_doAsyncFunc(
 | ||
|         data.async,
 | ||
|         core.closeDoor,
 | ||
|         loc[0],
 | ||
|         loc[1],
 | ||
|         data.id
 | ||
|     );
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_useItem = function (data, x, y, prefix) {
 | ||
|     // 考虑到可能覆盖楼传事件的问题,这里不对fly进行检查。
 | ||
|     if (data.id != 'book' && core.canUseItem(data.id)) {
 | ||
|         core.useItem(data.id, true, core.doAction);
 | ||
|     } else {
 | ||
|         core.playSound('操作失败');
 | ||
|         core.drawTip(
 | ||
|             '当前无法使用' +
 | ||
|                 ((core.material.items[data.id] || {}).name || '未知道具')
 | ||
|         );
 | ||
|         core.doAction();
 | ||
|     }
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_loadEquip = function (data, x, y, prefix) {
 | ||
|     core.loadEquip(data.id);
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_unloadEquip = function (data, x, y, prefix) {
 | ||
|     core.unloadEquip(data.pos);
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_openShop = function (data, x, y, prefix) {
 | ||
|     Mota.require('@user/legacy-plugin-data').setShopVisited(data.id, true);
 | ||
|     if (data.open)
 | ||
|         Mota.require('@user/legacy-plugin-data').openShop(data.id, true);
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_disableShop = function (data, x, y, prefix) {
 | ||
|     Mota.require('@user/legacy-plugin-data').setShopVisited(data.id, false);
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_battle = function (data, x, y, prefix) {
 | ||
|     // Deprecated. See src/plugin/game/enemy/battle.ts
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_trigger = function (data, x, y, prefix) {
 | ||
|     var loc = this.__action_getLoc(data.loc, x, y, prefix);
 | ||
|     this._trigger_inAction(loc[0], loc[1]);
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_insert = function (data, x, y, prefix) {
 | ||
|     if (data.name) {
 | ||
|         // 公共事件
 | ||
|         core.insertCommonEvent(data.name, data.args);
 | ||
|     } else {
 | ||
|         // 设置参数
 | ||
|         if (data.args instanceof Array) {
 | ||
|             for (var i = 0; i < data.args.length; ++i) {
 | ||
|                 try {
 | ||
|                     if (data.args[i] != null)
 | ||
|                         core.setFlag('arg' + (i + 1), data.args[i]);
 | ||
|                 } catch (ee) {
 | ||
|                     console.error(ee);
 | ||
|                 }
 | ||
|             }
 | ||
|         }
 | ||
|         var loc = this.__action_getLoc(data.loc, x, y, prefix);
 | ||
|         core.setFlag('arg0', loc);
 | ||
|         var floorId = data.floorId;
 | ||
|         var which = data.which || 'events';
 | ||
|         var event = (core.floors[floorId][which] || [])[loc[0] + ',' + loc[1]];
 | ||
|         if (event) this.insertAction(event.data || event);
 | ||
|     }
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_playBgm = function (data, x, y, prefix) {
 | ||
|     core.playBgm(data.name, data.startTime || 0);
 | ||
|     core.setFlag('__bgm__', data.keep ? data.name : null);
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_pauseBgm = function (data, x, y, prefix) {
 | ||
|     core.pauseBgm();
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_resumeBgm = function (data, x, y, prefix) {
 | ||
|     core.resumeBgm(data.resume);
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_loadBgm = function (data, x, y, prefix) {
 | ||
|     core.loadBgm(data.name);
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_freeBgm = function (data, x, y, prefix) {
 | ||
|     core.freeBgm(data.name);
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_playSound = function (data, x, y, prefix) {
 | ||
|     if (data.stop) core.stopSound();
 | ||
|     if (data.sync) {
 | ||
|         core.playSound(data.name, data.pitch, core.doAction);
 | ||
|     } else {
 | ||
|         core.playSound(data.name, data.pitch);
 | ||
|         core.doAction();
 | ||
|     }
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_stopSound = function (data, x, y, prefix) {
 | ||
|     core.stopSound();
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_setVolume = function (data, x, y, prefix) {
 | ||
|     data.value = core.clamp(parseInt(data.value) / 100, 0, 1);
 | ||
|     core.setFlag('__volume__', data.value);
 | ||
|     this.__action_doAsyncFunc(
 | ||
|         data.async,
 | ||
|         core.setVolume,
 | ||
|         data.value,
 | ||
|         data.time || 0
 | ||
|     );
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_setValue = function (data, x, y, prefix) {
 | ||
|     this.setValue(data.name, data.operator, data.value, prefix);
 | ||
|     if (!data.norefresh) {
 | ||
|         if (core.status.hero.hp <= 0) {
 | ||
|             core.status.hero.hp = 0;
 | ||
|             core.updateStatusBar();
 | ||
|             core.events.lose();
 | ||
|         } else {
 | ||
|             core.updateStatusBar();
 | ||
|         }
 | ||
|     }
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_addValue = function (data, x, y, prefix) {
 | ||
|     data.operator = '+=';
 | ||
|     this._action_setValue(data, x, y, prefix);
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_setEnemy = function (data, x, y, prefix) {
 | ||
|     this.setEnemy(
 | ||
|         data.id,
 | ||
|         data.name,
 | ||
|         data.value,
 | ||
|         data.operator,
 | ||
|         prefix,
 | ||
|         data.norefresh
 | ||
|     );
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_setEnemyOnPoint = function (data, x, y, prefix) {
 | ||
|     // Deprecated.
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_resetEnemyOnPoint = function (data, x, y, prefix) {
 | ||
|     var loc = this.__action_getLoc2D(data.loc, x, y, prefix);
 | ||
|     loc.forEach(function (one) {
 | ||
|         core.resetEnemyOnPoint(one[0], one[1], data.floorId, data.norefresh);
 | ||
|     });
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._precompile_moveEnemyOnPoint = function (data) {
 | ||
|     data.from = this.__precompile_array(data.from);
 | ||
|     data.to = this.__precompile_array(data.to);
 | ||
|     data.dxy = this.__precompile_array(data.dxy);
 | ||
|     return data;
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_moveEnemyOnPoint = function (data, x, y, prefix) {
 | ||
|     var from = this.__action_getLoc(data.from, x, y, prefix),
 | ||
|         to;
 | ||
|     if (data.dxy) {
 | ||
|         to = [
 | ||
|             from[0] + (core.calValue(data.dxy[0], prefix) || 0),
 | ||
|             from[1] + (core.calValue(data.dxy[1], prefix) || 0)
 | ||
|         ];
 | ||
|     } else {
 | ||
|         to = this.__action_getLoc(data.to, x, y, prefix);
 | ||
|     }
 | ||
|     this.moveEnemyOnPoint(
 | ||
|         from[0],
 | ||
|         from[1],
 | ||
|         to[0],
 | ||
|         to[1],
 | ||
|         data.floorId,
 | ||
|         data.norefresh
 | ||
|     );
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_setEquip = function (data, x, y, prefix) {
 | ||
|     core.setEquip(
 | ||
|         data.id,
 | ||
|         data.valueType,
 | ||
|         data.name,
 | ||
|         data.value,
 | ||
|         data.operator,
 | ||
|         prefix
 | ||
|     );
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_setFloor = function (data, x, y, prefix) {
 | ||
|     this.setFloorInfo(data.name, data.value, data.floorId, prefix);
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_setGlobalAttribute = function (data, x, y, prefix) {
 | ||
|     this.setGlobalAttribute(data.name, data.value);
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_setGlobalValue = function (data, x, y, prefix) {
 | ||
|     core.values[data.name] = data.value;
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_setGlobalFlag = function (data, x, y, prefix) {
 | ||
|     this.setGlobalFlag(data.name, data.value);
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_setNameMap = function (data, x, y, floorId) {
 | ||
|     this.setNameMap(data.name, data.value);
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_setHeroIcon = function (data, x, y, prefix) {
 | ||
|     this.setHeroIcon(data.name, data.noDraw);
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_input = function (data, x, y, prefix) {
 | ||
|     this.__action_getInput(
 | ||
|         core.replaceText(data.text, prefix),
 | ||
|         false,
 | ||
|         function (value) {
 | ||
|             value = parseInt(value) || 0; // 允许负整数
 | ||
|             core.status.route.push('input:' + value);
 | ||
|             core.setFlag('input', value);
 | ||
|             core.doAction();
 | ||
|         }
 | ||
|     );
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_input2 = function (data, x, y, prefix) {
 | ||
|     this.__action_getInput(
 | ||
|         core.replaceText(data.text, prefix),
 | ||
|         true,
 | ||
|         function (value) {
 | ||
|             value = value || '';
 | ||
|             core.status.route.push('input2:' + core.encodeBase64(value));
 | ||
|             core.setFlag('input', value);
 | ||
|             core.doAction();
 | ||
|         }
 | ||
|     );
 | ||
| };
 | ||
| 
 | ||
| events.prototype.__action_getInput = function (hint, isText, callback) {
 | ||
|     var value,
 | ||
|         prefix = isText ? 'input2:' : 'input:';
 | ||
|     if (core.isReplaying()) {
 | ||
|         var action = core.status.replay.toReplay.shift();
 | ||
|         try {
 | ||
|             if (action.indexOf(prefix) != 0) {
 | ||
|                 console.warn(
 | ||
|                     '警告!当前需要一个 ' + prefix + ' 项,实际为 ' + action
 | ||
|                 );
 | ||
|                 core.status.replay.toReplay.unshift(action);
 | ||
|                 return callback(isText ? '' : 0);
 | ||
|             }
 | ||
|             if (isText) value = core.decodeBase64(action.substring(7));
 | ||
|             else value = parseInt(action.substring(6));
 | ||
|             callback(value);
 | ||
|         } catch (e) {
 | ||
|             core.control._replay_error(action);
 | ||
|             return;
 | ||
|         }
 | ||
|     } else {
 | ||
|         core.myprompt(core.replaceText(hint), null, callback);
 | ||
|     }
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_if = function (data, x, y, prefix) {
 | ||
|     if (core.calValue(data.condition, prefix))
 | ||
|         core.events.insertAction(data['true']);
 | ||
|     else core.events.insertAction(data['false']);
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._precompile_if = function (data) {
 | ||
|     data.condition = core.replaceValue(data.condition);
 | ||
|     data['true'] = this.precompile(data['true']);
 | ||
|     data['false'] = this.precompile(data['false']);
 | ||
|     return data;
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_switch = function (data, x, y, prefix) {
 | ||
|     var key = core.calValue(data.condition, prefix);
 | ||
|     var list = [];
 | ||
|     for (var i = 0; i < data.caseList.length; i++) {
 | ||
|         if (data.caseList[i]._disabled) continue;
 | ||
|         var condition = data.caseList[i]['case'];
 | ||
|         if (
 | ||
|             condition == 'default' ||
 | ||
|             core.calValue(condition, prefix) === key
 | ||
|         ) {
 | ||
|             core.push(list, data.caseList[i].action);
 | ||
|             if (!data.caseList[i].nobreak) break;
 | ||
|         }
 | ||
|     }
 | ||
|     core.insertAction(list);
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._precompile_switch = function (data) {
 | ||
|     data.condition = core.replaceValue(data.condition);
 | ||
|     for (var i = 0; i < data.caseList.length; i++) {
 | ||
|         data.caseList[i]['case'] = core.replaceValue(data.caseList[i]['case']);
 | ||
|         data.caseList[i].action = this.precompile(data.caseList[i].action);
 | ||
|     }
 | ||
|     return data;
 | ||
| };
 | ||
| 
 | ||
| events.prototype.__action_choices_replaying = function (data, index) {
 | ||
|     var selection = index;
 | ||
|     if (index != 'none') {
 | ||
|         selection = parseInt(index);
 | ||
|         if (isNaN(selection)) return false;
 | ||
|         if (selection < 0) selection += data.choices.length;
 | ||
|         if (selection < 0) return false;
 | ||
|         if (selection % 100 > 50) selection += data.choices.length;
 | ||
|         if (selection % 100 > data.choices.length) return false;
 | ||
|         var timeout = Math.floor(selection / 100) || 0;
 | ||
|         core.setFlag('timeout', timeout);
 | ||
|         selection %= 100;
 | ||
|     } else core.setFlag('timeout', 0);
 | ||
|     core.status.event.selection = selection;
 | ||
|     setTimeout(
 | ||
|         function () {
 | ||
|             core.status.route.push('choices:' + index);
 | ||
|             if (selection != 'none') {
 | ||
|                 // 检查
 | ||
|                 var choice = data.choices[selection];
 | ||
|                 if (
 | ||
|                     choice.need != null &&
 | ||
|                     choice.need != '' &&
 | ||
|                     !core.calValue(choice.need)
 | ||
|                 ) {
 | ||
|                     // 无法选择此项
 | ||
|                     core.control._replay_error('无法选择项:' + index);
 | ||
|                     return;
 | ||
|                 } else {
 | ||
|                     core.insertAction(choice.action);
 | ||
|                 }
 | ||
|             }
 | ||
|             core.doAction();
 | ||
|         },
 | ||
|         core.status.replay.speed == 24
 | ||
|             ? 1
 | ||
|             : 750 / Math.max(1, core.status.replay.speed)
 | ||
|     );
 | ||
|     return true;
 | ||
| };
 | ||
| 
 | ||
| events.prototype._precompile_choices = function (data) {
 | ||
|     if (!(data.choices instanceof Array)) return data;
 | ||
|     for (var i = 0; i < data.choices.length; ++i) {
 | ||
|         data.choices[i].condition = core.replaceValue(
 | ||
|             data.choices[i].condition
 | ||
|         );
 | ||
|         data.choices[i].text = this.__precompile_text(data.choices[i].text);
 | ||
|         data.choices[i].action = this.precompile(data.choices[i].action);
 | ||
|     }
 | ||
|     return data;
 | ||
| };
 | ||
| 
 | ||
| events.prototype.__action_confirm_replaying = function (data, index) {
 | ||
|     if (index != 'none') {
 | ||
|         var timeout = Math.floor(index / 100) || 0;
 | ||
|         core.setFlag('timeout', timeout);
 | ||
|         index %= 100;
 | ||
|     } else core.setFlag('timeout', 0);
 | ||
|     core.status.event.selection = index;
 | ||
|     setTimeout(
 | ||
|         function () {
 | ||
|             core.status.route.push('choices:' + index);
 | ||
|             if (index != 'none') {
 | ||
|                 if (index == 0) core.insertAction(data.yes);
 | ||
|                 else core.insertAction(data.no);
 | ||
|             }
 | ||
|             core.doAction();
 | ||
|         },
 | ||
|         core.status.replay.speed == 24
 | ||
|             ? 1
 | ||
|             : 750 / Math.max(1, core.status.replay.speed)
 | ||
|     );
 | ||
| };
 | ||
| 
 | ||
| events.prototype._precompile_confirm = function (data) {
 | ||
|     data.yes = this.precompile(data.yes);
 | ||
|     data.no = this.precompile(data.no);
 | ||
|     return data;
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_for = function (data, x, y, prefix) {
 | ||
|     // Only support temp:A
 | ||
|     if (!/^temp:[A-Z]$/.test(data.name)) {
 | ||
|         core.insertAction('循环遍历事件只支持临时变量!');
 | ||
|         return core.doAction();
 | ||
|     }
 | ||
|     var from = core.calValue(data.from);
 | ||
|     var to = core.calValue(data.to);
 | ||
|     var step = core.calValue(data.step);
 | ||
|     if (
 | ||
|         typeof from != 'number' ||
 | ||
|         typeof to != 'number' ||
 | ||
|         typeof step != 'number'
 | ||
|     ) {
 | ||
|         core.insertAction(
 | ||
|             '循环遍历事件要求【起始点】【终止点】【每步】仅能是数字!'
 | ||
|         );
 | ||
|         return core.doAction();
 | ||
|     }
 | ||
|     // 首次判定
 | ||
|     if ((step > 0 && from > to) || (step < 0 && from < to)) {
 | ||
|         core.doAction();
 | ||
|         return;
 | ||
|     }
 | ||
| 
 | ||
|     var letter = data.name.substring(5);
 | ||
|     core.setFlag('@temp@' + letter, from);
 | ||
|     var toName = '@temp@for-to@' + letter;
 | ||
|     var stepName = '@temp@for-step@' + letter;
 | ||
|     core.setFlag(toName, data.to);
 | ||
|     core.setFlag(stepName, data.step);
 | ||
|     var condition =
 | ||
|         '(function () {' +
 | ||
|         "var to = core.calValue(core.getFlag('" +
 | ||
|         toName +
 | ||
|         "'));" +
 | ||
|         "var step = core.calValue(core.getFlag('" +
 | ||
|         stepName +
 | ||
|         "'));" +
 | ||
|         "if (typeof step != 'number' || typeof to != 'number') return false;" +
 | ||
|         'if (step == 0) return true;' +
 | ||
|         "var currentValue = core.getFlag('@temp@" +
 | ||
|         letter +
 | ||
|         "');" +
 | ||
|         'currentValue += step;' +
 | ||
|         "core.setFlag('@temp@" +
 | ||
|         letter +
 | ||
|         "', currentValue);" +
 | ||
|         'if (step > 0) { return currentValue <= to; }' +
 | ||
|         'else { return currentValue >= to; }' +
 | ||
|         '})()';
 | ||
|     return this._action_dowhile(
 | ||
|         { condition: condition, data: data.data },
 | ||
|         x,
 | ||
|         y,
 | ||
|         prefix
 | ||
|     );
 | ||
| };
 | ||
| 
 | ||
| events.prototype._precompile_for = function (data) {
 | ||
|     data.from = core.replaceValue(data.from);
 | ||
|     data.to = core.replaceValue(data.to);
 | ||
|     data.step = core.replaceValue(data.step);
 | ||
|     data.data = this.precompile(data.data);
 | ||
|     return data;
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_forEach = function (data, x, y, prefix) {
 | ||
|     // Only support temp:A
 | ||
|     if (!/^temp:[A-Z]$/.test(data.name)) {
 | ||
|         core.insertAction(['循环遍历事件只支持临时变量!']);
 | ||
|         return core.doAction();
 | ||
|     }
 | ||
|     var listName = '@temp@forEach@' + data.name.substring(5);
 | ||
|     core.setFlag(listName, core.clone(data.list));
 | ||
|     var condition =
 | ||
|         '(function () {' +
 | ||
|         "var list = core.getFlag('" +
 | ||
|         listName +
 | ||
|         "', []);" +
 | ||
|         'if (list.length == 0) return false;' +
 | ||
|         "core.setFlag('@temp@'+'" +
 | ||
|         data.name.substring(5) +
 | ||
|         "', list.shift());" +
 | ||
|         'return true;' +
 | ||
|         '})()';
 | ||
|     return this._action_while(
 | ||
|         { condition: condition, data: data.data },
 | ||
|         x,
 | ||
|         y,
 | ||
|         prefix
 | ||
|     );
 | ||
| };
 | ||
| 
 | ||
| events.prototype._precompile_forEach = function (data) {
 | ||
|     data.data = this.precompile(data.data);
 | ||
|     return data;
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_while = function (data, x, y, prefix) {
 | ||
|     if (core.calValue(data.condition, prefix)) {
 | ||
|         var list = core.clone(data.data);
 | ||
|         if (!(list instanceof Array)) list = [list];
 | ||
|         list.push({ type: '_label' });
 | ||
|         core.unshift(core.status.event.data.list, {
 | ||
|             todo: list,
 | ||
|             total: core.clone(list),
 | ||
|             condition: data.condition
 | ||
|         });
 | ||
|     }
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._precompile_while = function (data) {
 | ||
|     data.condition = core.replaceValue(data.condition);
 | ||
|     data.data = this.precompile(data.data);
 | ||
|     return data;
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_dowhile = function (data, x, y, prefix) {
 | ||
|     var list = core.clone(data.data);
 | ||
|     if (!(list instanceof Array)) list = [list];
 | ||
|     list.push({ type: '_label' });
 | ||
|     core.unshift(core.status.event.data.list, {
 | ||
|         todo: list,
 | ||
|         total: core.clone(list),
 | ||
|         condition: data.condition
 | ||
|     });
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._precompile_dowhile = function (data) {
 | ||
|     data.condition = core.replaceValue(data.condition);
 | ||
|     data.data = this.precompile(data.data);
 | ||
|     return data;
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_break = function (data, x, y, prefix) {
 | ||
|     var n = data.n || 1;
 | ||
|     while (n--) {
 | ||
|         if (core.status.event.data.list.length > 1)
 | ||
|             core.status.event.data.list.shift();
 | ||
|     }
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_continue = function (data, x, y, prefix) {
 | ||
|     var n = data.n || 1;
 | ||
|     while (n-- > 1) {
 | ||
|         if (core.status.event.data.list.length > 1)
 | ||
|             core.status.event.data.list.shift();
 | ||
|     }
 | ||
|     if (core.status.event.data.list.length > 1) {
 | ||
|         if (core.calValue(core.status.event.data.list[0].condition, prefix)) {
 | ||
|             core.status.event.data.list[0].todo = core.clone(
 | ||
|                 core.status.event.data.list[0].total
 | ||
|             );
 | ||
|         } else {
 | ||
|             core.status.event.data.list.shift();
 | ||
|         }
 | ||
|     }
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_win = function (data, x, y, prefix) {
 | ||
|     this.win(core.replaceText(data.reason, prefix), data.norank, data.noexit);
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_lose = function (data, x, y, prefix) {
 | ||
|     this.lose(core.replaceText(data.reason, prefix));
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_restart = function (data, x, y, prefix) {
 | ||
|     core.restart();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_function = function (data, x, y, prefix) {
 | ||
|     var func = data['function'];
 | ||
|     try {
 | ||
|         if (typeof func == 'string' && func.indexOf('function') == 0) {
 | ||
|             eval('(' + func + ')()');
 | ||
|         }
 | ||
|     } catch (e) {
 | ||
|         console.error(e);
 | ||
|     }
 | ||
|     if (!data.async) core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_update = function (data, x, y, prefix) {
 | ||
|     core.updateStatusBar(data.doNotCheckAutoEvents, true);
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_showStatusBar = function (data, x, y, prefix) {
 | ||
|     core.showStatusBar();
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_hideStatusBar = function (data, x, y, prefix) {
 | ||
|     core.hideStatusBar(data.toolbox);
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_showHero = function (data, x, y, prefix) {
 | ||
|     data.opacity = 1;
 | ||
|     return this._action_setHeroOpacity(data, x, y, prefix);
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_hideHero = function (data, x, y, prefix) {
 | ||
|     data.opacity = 0;
 | ||
|     return this._action_setHeroOpacity(data, x, y, prefix);
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_setHeroOpacity = function (data, x, y, prefix) {
 | ||
|     data.time = data.time || 0;
 | ||
|     if (data.opacity == null) data.opacity = 1;
 | ||
|     if (data.time > 0) {
 | ||
|         this.__action_doAsyncFunc(
 | ||
|             data.async,
 | ||
|             core.setHeroOpacity,
 | ||
|             data.opacity,
 | ||
|             data.moveMode,
 | ||
|             data.time
 | ||
|         );
 | ||
|     } else {
 | ||
|         core.setFlag('__heroOpacity__', data.opacity);
 | ||
|         core.drawHero();
 | ||
|         core.doAction();
 | ||
|     }
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_vibrate = function (data, x, y, prefix) {
 | ||
|     this.__action_doAsyncFunc(
 | ||
|         data.async,
 | ||
|         core.vibrate,
 | ||
|         data.direction,
 | ||
|         data.time,
 | ||
|         data.speed,
 | ||
|         data.power
 | ||
|     );
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_sleep = function (data, x, y, prefix) {
 | ||
|     core.timeout.sleepTimeout = setTimeout(
 | ||
|         function () {
 | ||
|             core.timeout.sleepTimeout = null;
 | ||
|             core.doAction();
 | ||
|         },
 | ||
|         core.isReplaying() ? Math.min(data.time, 20) : data.time
 | ||
|     );
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_wait = function (data, x, y, prefix) {
 | ||
|     if (core.isReplaying()) {
 | ||
|         var code = core.status.replay.toReplay.shift();
 | ||
|         if (
 | ||
|             code.indexOf('input:') == 0 &&
 | ||
|             !(code == 'input:none' && !data.timeout)
 | ||
|         ) {
 | ||
|             if (code == 'input:none') {
 | ||
|                 core.status.route.push('input:none');
 | ||
|                 core.setFlag('type', -1);
 | ||
|                 core.setFlag('timeout', 0);
 | ||
|                 this.__action_wait_afterGet(data);
 | ||
|                 return core.doAction();
 | ||
|             } else {
 | ||
|                 var value = parseInt(code.substring(6));
 | ||
|                 core.status.route.push('input:' + value);
 | ||
|                 this.__action_wait_getValue(value);
 | ||
|                 if (this.__action_wait_afterGet(data) || !data.forceChild)
 | ||
|                     return core.doAction();
 | ||
|             }
 | ||
|         }
 | ||
|         core.control._replay_error(code);
 | ||
|         return;
 | ||
|     } else if (data.timeout) {
 | ||
|         core.status.event.interval = setTimeout(function () {
 | ||
|             core.status.route.push('input:none');
 | ||
|             core.setFlag('type', -1);
 | ||
|             core.setFlag('timeout', 0);
 | ||
|             core.events.__action_wait_afterGet(data);
 | ||
|             core.doAction();
 | ||
|         }, data.timeout);
 | ||
|     }
 | ||
|     core.status.event.timeout = new Date().getTime() + (data.timeout || 0);
 | ||
| };
 | ||
| 
 | ||
| events.prototype.__action_wait_getValue = function (value) {
 | ||
|     core.setFlag('timeout', Math.floor(value / 1e8) || 0);
 | ||
|     value %= 1e8;
 | ||
|     if (value >= 1000000) {
 | ||
|         core.setFlag('type', 1);
 | ||
|         var px = Math.floor((value - 1000000) / 1000),
 | ||
|             py = value % 1000;
 | ||
|         core.setFlag('px', px);
 | ||
|         core.setFlag('py', py);
 | ||
|         core.setFlag('x', Math.floor(px / 32));
 | ||
|         core.setFlag('y', Math.floor(py / 32));
 | ||
|     } else if (value >= 10000) {
 | ||
|         core.setFlag('type', 1);
 | ||
|         var x = Math.floor((value - 10000) / 100),
 | ||
|             y = value % 100;
 | ||
|         core.setFlag('px', 32 * x + 16);
 | ||
|         core.setFlag('py', 32 * y + 16);
 | ||
|         core.setFlag('x', x);
 | ||
|         core.setFlag('y', y);
 | ||
|     } else if (value > 0) {
 | ||
|         core.setFlag('type', 0);
 | ||
|         core.setFlag('keycode', value);
 | ||
|     }
 | ||
| };
 | ||
| 
 | ||
| events.prototype.__action_wait_afterGet = function (data) {
 | ||
|     if (!data.data) return false;
 | ||
|     var todo = [];
 | ||
|     var stop = false;
 | ||
|     var found = false;
 | ||
|     data.data.forEach(function (one) {
 | ||
|         if (one._disabled || stop) return;
 | ||
|         if (one['case'] == 'keyboard' && core.getFlag('type') == 0) {
 | ||
|             (one.keycode + '').split(',').forEach(function (keycode) {
 | ||
|                 if (core.getFlag('keycode', 0) == keycode) {
 | ||
|                     found = true;
 | ||
|                     core.push(todo, one.action);
 | ||
|                     if (one['break']) stop = true;
 | ||
|                 }
 | ||
|             });
 | ||
|         }
 | ||
|         if (
 | ||
|             one['case'] == 'mouse' &&
 | ||
|             one.px instanceof Array &&
 | ||
|             one.py instanceof Array &&
 | ||
|             core.getFlag('type') == 1
 | ||
|         ) {
 | ||
|             var pxmin = core.calValue(one.px[0]);
 | ||
|             var pxmax = core.calValue(one.px[1]);
 | ||
|             var pymin = core.calValue(one.py[0]);
 | ||
|             var pymax = core.calValue(one.py[1]);
 | ||
|             var px = core.getFlag('px', 0),
 | ||
|                 py = core.getFlag('py', 0);
 | ||
|             if (px >= pxmin && px <= pxmax && py >= pymin && py <= pymax) {
 | ||
|                 found = true;
 | ||
|                 core.push(todo, one.action);
 | ||
|                 if (one['break']) stop = true;
 | ||
|             }
 | ||
|         }
 | ||
|         if (one['case'] == 'condition') {
 | ||
|             var condition = false;
 | ||
|             try {
 | ||
|                 condition = core.calValue(one.condition);
 | ||
|             } catch (e) {}
 | ||
|             if (condition) {
 | ||
|                 found = true;
 | ||
|                 core.push(todo, one.action);
 | ||
|                 if (one['break']) stop = true;
 | ||
|             }
 | ||
|         }
 | ||
|         if (one['case'] == 'timeout' && core.getFlag('type') == -1) {
 | ||
|             found = true;
 | ||
|             core.push(todo, one.action);
 | ||
|             if (one['break']) stop = true;
 | ||
|         }
 | ||
|     });
 | ||
|     if (found) {
 | ||
|         core.insertAction(todo);
 | ||
|         return true;
 | ||
|     }
 | ||
|     return false;
 | ||
| };
 | ||
| 
 | ||
| events.prototype._precompile_wait = function (data) {
 | ||
|     if (data.data) {
 | ||
|         data.data.forEach(function (v) {
 | ||
|             if (v.px != null) v.px = this.__precompile_array(v.px);
 | ||
|             if (v.py != null) v.py = this.__precompile_array(v.py);
 | ||
|             if (v.condition != null)
 | ||
|                 v.condition = this.__precompile_array(v.condition);
 | ||
|             v.action = this.precompile(v.action);
 | ||
|         }, this);
 | ||
|     }
 | ||
|     return data;
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_waitAsync = function (data, x, y, prefix) {
 | ||
|     var test = window.setInterval(function () {
 | ||
|         if (
 | ||
|             !core.hasAsync() &&
 | ||
|             (data.excludeAnimates ||
 | ||
|                 core.isReplaying() ||
 | ||
|                 core.getPlayingAnimates().length == 0) &&
 | ||
|             (!data.includeSounds ||
 | ||
|                 core.isReplaying() ||
 | ||
|                 core.getPlayingSounds().length == 0)
 | ||
|         ) {
 | ||
|             clearInterval(test);
 | ||
|             core.doAction();
 | ||
|         }
 | ||
|     }, 50 / core.status.replay.speed);
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_stopAsync = function (data, x, y, prefix) {
 | ||
|     core.stopAsync();
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_callBook = function (data, x, y, prefix) {
 | ||
|     if (core.isReplaying() || !core.hasItem('book')) {
 | ||
|         core.doAction();
 | ||
|     } else {
 | ||
|         var e = core.clone(core.status.event.data);
 | ||
|         core.ui.closePanel();
 | ||
|         core.openBook();
 | ||
|         core.status.event.interval = e;
 | ||
|     }
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_callSave = function (data, x, y, prefix) {
 | ||
|     if (core.isReplaying() || core.hasFlag('__events__')) {
 | ||
|         core.removeFlag('__events__');
 | ||
|         core.doAction();
 | ||
|     } else {
 | ||
|         var e = core.clone(core.status.event.data);
 | ||
|         core.ui.closePanel();
 | ||
|         var forbidSave = core.hasFlag('__forbidSave__');
 | ||
|         core.removeFlag('__forbidSave__');
 | ||
|         core.save();
 | ||
|         if (forbidSave) core.setFlag('__forbidSave__', true);
 | ||
|         core.status.event.interval = e;
 | ||
|     }
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_autoSave = function (data, x, y, prefix) {
 | ||
|     var forbidSave = core.hasFlag('__forbidSave__');
 | ||
|     core.removeFlag('__forbidSave__');
 | ||
|     core.autosave(data.removeLast);
 | ||
|     if (forbidSave) core.setFlag('__forbidSave__', true);
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_forbidSave = function (data, x, y, prefix) {
 | ||
|     core.setFlag('__forbidSave__', data.forbid || null);
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_callLoad = function (data, x, y, prefix) {
 | ||
|     if (this.__action_checkReplaying()) return;
 | ||
|     var e = core.clone(core.status.event.data);
 | ||
|     core.ui.closePanel();
 | ||
|     core.load();
 | ||
|     core.status.event.interval = e;
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_exit = function (data, x, y, prefix) {
 | ||
|     this.setEvents([]);
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_previewUI = function (data, x, y, prefix) {
 | ||
|     this.insertAction(data.action);
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._precompile_previewUI = function (data) {
 | ||
|     data.action = this.precompile(data.action);
 | ||
|     return data;
 | ||
| };
 | ||
| 
 | ||
| events.prototype.__action_doUIEvent = function (data) {
 | ||
|     this.__action_doUIEvent_doOne(data);
 | ||
|     var current = core.status.event.data.list[0];
 | ||
|     while (current.todo.length > 0) {
 | ||
|         data = current.todo[0];
 | ||
|         if (this.__action_doUIEvent_doOne(current.todo[0]))
 | ||
|             current.todo.shift();
 | ||
|         else break;
 | ||
|     }
 | ||
|     core.doAction();
 | ||
| };
 | ||
| 
 | ||
| events.prototype.__action_doUIEvent_doOne = function (data) {
 | ||
|     if (core.ui['_uievent_' + data.type]) {
 | ||
|         core.ui['_uievent_' + data.type](data);
 | ||
|         return true;
 | ||
|     }
 | ||
|     return false;
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_clearMap = function (data, x, y, prefix) {
 | ||
|     this.__action_doUIEvent(data);
 | ||
| };
 | ||
| 
 | ||
| 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);
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_fillRect = function (data, x, y, prefix) {
 | ||
|     this.__action_doUIEvent(data);
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_fillPolygon = function (data, x, y, prefix) {
 | ||
|     this.__action_doUIEvent(data);
 | ||
| };
 | ||
| 
 | ||
| events.prototype._precompile_fillPolygon = function (data) {
 | ||
|     data.nodes = this.__precompile_array(data.nodes);
 | ||
|     return data;
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_strokeRect = function (data, x, y, prefix) {
 | ||
|     this.__action_doUIEvent(data);
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_strokePolygon = function (data, x, y, prefix) {
 | ||
|     this.__action_doUIEvent(data);
 | ||
| };
 | ||
| 
 | ||
| events.prototype._precompile_strokePolygon = function (data) {
 | ||
|     data.nodes = this.__precompile_array(data.nodes);
 | ||
|     return data;
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_fillEllipse = function (data, x, y, prefix) {
 | ||
|     this.__action_doUIEvent(data);
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_strokeEllipse = function (data, x, y, prefix) {
 | ||
|     this.__action_doUIEvent(data);
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_fillArc = function (data, x, y, prefix) {
 | ||
|     this.__action_doUIEvent(data);
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_strokeArc = function (data, x, y, prefix) {
 | ||
|     this.__action_doUIEvent(data);
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_drawLine = function (data, x, y, prefix) {
 | ||
|     this.__action_doUIEvent(data);
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_drawArrow = function (data, x, y, prefix) {
 | ||
|     this.__action_doUIEvent(data);
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_setAttribute = function (data, x, y, prefix) {
 | ||
|     this.__action_doUIEvent(data);
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_setFilter = function (data, x, y, prefix) {
 | ||
|     this.__action_doUIEvent(data);
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_drawImage = function (data, x, y, prefix) {
 | ||
|     this.__action_doUIEvent(data);
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_drawIcon = function (data, x, y, prefix) {
 | ||
|     this.__action_doUIEvent(data);
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_drawSelector = function (data, x, y, prefix) {
 | ||
|     this.__action_doUIEvent(data);
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_drawBackground = function (data, x, y, prefix) {
 | ||
|     this.__action_doUIEvent(data);
 | ||
| };
 | ||
| 
 | ||
| events.prototype._action_drawTextContent = function (data, x, y, prefix) {
 | ||
|     data.text = core.replaceText(data.text, prefix);
 | ||
|     this.__action_doUIEvent(data);
 | ||
| };
 | ||
| 
 | ||
| // ------ 点击状态栏图标所进行的一些操作 ------ //
 | ||
| 
 | ||
| ////// 判断当前能否进入某个事件 //////
 | ||
| events.prototype._checkStatus = function (name, fromUserAction, checkItem) {
 | ||
|     if (fromUserAction && core.status.event.id == name) {
 | ||
|         core.ui.closePanel();
 | ||
|         return false;
 | ||
|     }
 | ||
|     if (fromUserAction && core.status.lockControl) return false;
 | ||
|     if (checkItem && !core.hasItem(name)) {
 | ||
|         core.playSound('操作失败');
 | ||
|         core.drawTip('你没有' + core.material.items[name].name, name);
 | ||
|         return false;
 | ||
|     }
 | ||
|     if (core.isMoving()) {
 | ||
|         core.playSound('操作失败');
 | ||
|         core.drawTip('请先停止勇士行动');
 | ||
|         return false;
 | ||
|     }
 | ||
|     core.lockControl();
 | ||
|     core.status.event.id = name;
 | ||
|     return true;
 | ||
| };
 | ||
| 
 | ||
| ////// 点击怪物手册时的打开操作 //////
 | ||
| events.prototype.openBook = function (fromUserAction) {
 | ||
|     if (core.isReplaying()) return;
 | ||
|     // 如果能恢复事件(从callBook事件触发)
 | ||
|     if (
 | ||
|         core.status.event.id == 'book' &&
 | ||
|         core.events.recoverEvents(core.status.event.interval)
 | ||
|     )
 | ||
|         return;
 | ||
|     // 当前是book,且从“浏览地图”打开
 | ||
|     if (core.status.event.id == 'book' && core.status.event.ui) {
 | ||
|         core.status.boxAnimateObjs = [];
 | ||
|         core.ui._drawViewMaps(core.status.event.ui);
 | ||
|         return;
 | ||
|     }
 | ||
|     // 从“浏览地图”页面打开
 | ||
|     if (core.status.event.id == 'viewMaps') {
 | ||
|         fromUserAction = false;
 | ||
|         core.status.event.ui = core.status.event.data;
 | ||
|     }
 | ||
|     if (!this._checkStatus('book', fromUserAction, true)) return;
 | ||
|     core.playSound('打开界面');
 | ||
|     core.useItem('book', true);
 | ||
| };
 | ||
| 
 | ||
| ////// 点击楼层传送器时的打开操作 //////
 | ||
| events.prototype.useFly = function (fromUserAction) {
 | ||
|     if (core.isReplaying()) return;
 | ||
|     // 从“浏览地图”页面:尝试直接传送到该层
 | ||
|     if (core.status.event.id == 'viewMaps') {
 | ||
|         if (!core.hasItem('fly')) {
 | ||
|             core.playSound('操作失败');
 | ||
|             core.drawTip('你没有' + core.material.items['fly'].name, 'fly');
 | ||
|         } else if (
 | ||
|             !core.canUseItem('fly') ||
 | ||
|             (core.flags.flyNearStair && !core.nearStair())
 | ||
|         ) {
 | ||
|             core.playSound('操作失败');
 | ||
|             core.drawTip('无法传送到当前层', 'fly');
 | ||
|         } else {
 | ||
|             core.flyTo(core.status.event.data.floorId);
 | ||
|         }
 | ||
|         return;
 | ||
|     }
 | ||
| 
 | ||
|     if (!this._checkStatus('fly', fromUserAction, true)) return;
 | ||
|     if (core.flags.flyNearStair && !core.nearStair()) {
 | ||
|         core.playSound('操作失败');
 | ||
|         core.drawTip(
 | ||
|             '只有在楼梯边才能使用' + core.material.items['fly'].name,
 | ||
|             'fly'
 | ||
|         );
 | ||
|         core.unlockControl();
 | ||
|         core.status.event.data = null;
 | ||
|         core.status.event.id = null;
 | ||
|         return;
 | ||
|     }
 | ||
|     if (!core.canUseItem('fly')) {
 | ||
|         core.playSound('操作失败');
 | ||
|         core.drawTip(core.material.items['fly'].name + '好像失效了', 'fly');
 | ||
|         core.unlockControl();
 | ||
|         core.status.event.data = null;
 | ||
|         core.status.event.id = null;
 | ||
|         return;
 | ||
|     }
 | ||
|     core.playSound('打开界面');
 | ||
|     core.useItem('fly', true);
 | ||
|     return;
 | ||
| };
 | ||
| 
 | ||
| events.prototype.flyTo = function (toId, callback) {
 | ||
|     return this.eventdata.flyTo(toId, callback);
 | ||
| };
 | ||
| 
 | ||
| ////// 点击装备栏时的打开操作 //////
 | ||
| events.prototype.openEquipbox = function (fromUserAction) {
 | ||
|     if (core.isReplaying()) return;
 | ||
|     if (!this._checkStatus('equipbox', fromUserAction)) return;
 | ||
|     core.playSound('打开界面');
 | ||
|     core.ui._drawEquipbox();
 | ||
| };
 | ||
| 
 | ||
| ////// 点击工具栏时的打开操作 //////
 | ||
| events.prototype.openToolbox = function (fromUserAction) {
 | ||
|     if (core.isReplaying()) return;
 | ||
|     if (!this._checkStatus('toolbox', fromUserAction)) return;
 | ||
|     core.playSound('打开界面');
 | ||
|     core.ui._drawToolbox();
 | ||
| };
 | ||
| 
 | ||
| ////// 点击快捷商店按钮时的打开操作 //////
 | ||
| events.prototype.openQuickShop = function (fromUserAction) {
 | ||
|     if (core.isReplaying()) return;
 | ||
|     const shop = Mota.require('@user/legacy-plugin-data');
 | ||
| 
 | ||
|     if (Object.keys(core.status.shops).length == 0) {
 | ||
|         core.playSound('操作失败');
 | ||
|         core.drawTip('本游戏没有快捷商店!');
 | ||
|         return;
 | ||
|     }
 | ||
| 
 | ||
|     // --- 如果只有一个商店,则直接打开之
 | ||
|     if (Object.keys(core.status.shops).length == 1) {
 | ||
|         var shopId = Object.keys(core.status.shops)[0];
 | ||
|         if (core.status.event.id != null) return;
 | ||
|         if (!shop.canOpenShop(shopId)) {
 | ||
|             core.playSound('操作失败');
 | ||
|             core.drawTip('当前无法打开快捷商店!');
 | ||
|             return;
 | ||
|         }
 | ||
|         var message = shop.canUseQuickShop(shopId);
 | ||
|         if (message != null) {
 | ||
|             core.playSound('操作失败');
 | ||
|             core.drawTip(message);
 | ||
|             return;
 | ||
|         }
 | ||
|         shop.openShop(shopId, false);
 | ||
|         return;
 | ||
|     }
 | ||
| 
 | ||
|     if (!this._checkStatus('selectShop', fromUserAction)) return;
 | ||
|     core.ui._drawQuickShop();
 | ||
| };
 | ||
| 
 | ||
| events.prototype.openKeyBoard = function (fromUserAction) {
 | ||
|     if (core.isReplaying()) return;
 | ||
|     if (!this._checkStatus('keyBoard', fromUserAction)) return;
 | ||
|     core.ui._drawKeyBoard();
 | ||
| };
 | ||
| 
 | ||
| ////// 点击保存按钮时的打开操作 //////
 | ||
| events.prototype.save = function (fromUserAction) {
 | ||
|     if (core.isReplaying()) return;
 | ||
|     if (core.hasFlag('__forbidSave__')) {
 | ||
|         core.playSound('操作失败');
 | ||
|         core.drawTip('当前禁止存档');
 | ||
|         return;
 | ||
|     }
 | ||
|     if (
 | ||
|         core.status.event.id == 'save' &&
 | ||
|         core.events.recoverEvents(core.status.event.interval)
 | ||
|     )
 | ||
|         return;
 | ||
|     if (!this._checkStatus('save', fromUserAction)) return;
 | ||
|     var saveIndex = core.saves.saveIndex;
 | ||
|     var page = Math.floor((saveIndex - 1) / 5),
 | ||
|         offset = saveIndex - 5 * page;
 | ||
|     core.playSound('打开界面');
 | ||
|     core.ui._drawSLPanel(10 * page + offset);
 | ||
| };
 | ||
| 
 | ||
| ////// 点击读取按钮时的打开操作 //////
 | ||
| events.prototype.load = function (fromUserAction) {
 | ||
|     if (core.isReplaying()) return;
 | ||
|     var saveIndex = core.saves.saveIndex;
 | ||
|     var page = Math.floor((saveIndex - 1) / 5),
 | ||
|         offset = saveIndex - 5 * page;
 | ||
|     // 游戏开始前读档
 | ||
|     if (!core.isPlaying()) {
 | ||
|         core.clearStatus();
 | ||
|         core.clearMap('all');
 | ||
|         core.status.event = { id: 'load', data: null };
 | ||
|         core.status.lockControl = true;
 | ||
|         core.playSound('打开界面');
 | ||
|         core.ui._drawSLPanel(10 * page + offset);
 | ||
|         return;
 | ||
|     }
 | ||
|     if (
 | ||
|         core.status.event.id == 'load' &&
 | ||
|         core.events.recoverEvents(core.status.event.interval)
 | ||
|     )
 | ||
|         return;
 | ||
|     if (!this._checkStatus('load', fromUserAction)) return;
 | ||
|     core.playSound('打开界面');
 | ||
|     core.ui._drawSLPanel(10 * page + offset);
 | ||
| };
 | ||
| 
 | ||
| ////// 点击设置按钮时的操作 //////
 | ||
| events.prototype.openSettings = function (fromUserAction) {
 | ||
|     // deprecated.
 | ||
| };
 | ||
| 
 | ||
| // ------ 一些事件的具体执行过程 ------ //
 | ||
| 
 | ||
| events.prototype.hasAsync = function () {
 | ||
|     return Object.keys(core.animateFrame.asyncId).length > 0;
 | ||
| };
 | ||
| 
 | ||
| ////// 立刻停止所有异步事件 //////
 | ||
| events.prototype.stopAsync = function () {
 | ||
|     var callbacks = [];
 | ||
|     for (var id in core.animateFrame.asyncId) {
 | ||
|         clearInterval(id);
 | ||
|         callbacks.push(core.animateFrame.asyncId[id]);
 | ||
|     }
 | ||
|     core.animateFrame.asyncId = {};
 | ||
|     callbacks.forEach(function (cb) {
 | ||
|         if (cb && cb instanceof Function) cb();
 | ||
|     });
 | ||
| };
 | ||
| 
 | ||
| events.prototype.hasAsyncAnimate = function () {
 | ||
|     return (core.status.animateObjs || []).length > 0;
 | ||
| };
 | ||
| 
 | ||
| ////// 跟随 //////
 | ||
| events.prototype.follow = function (name) {
 | ||
|     name = core.getMappedName(name);
 | ||
|     if (core.material.images.images[name]) {
 | ||
|         core.status.hero.followers.push({ name: name });
 | ||
|         core.gatherFollowers();
 | ||
|         core.clearMap('hero');
 | ||
|         core.drawHero();
 | ||
|     }
 | ||
|     core.clearRouteFolding();
 | ||
| };
 | ||
| 
 | ||
| ////// 取消跟随 //////
 | ||
| events.prototype.unfollow = function (name) {
 | ||
|     if (!name) {
 | ||
|         core.status.hero.followers = [];
 | ||
|     } else {
 | ||
|         name = core.getMappedName(name);
 | ||
|         for (var i = 0; i < core.status.hero.followers.length; i++) {
 | ||
|             if (core.status.hero.followers[i].name == name) {
 | ||
|                 core.status.hero.followers.splice(i, 1);
 | ||
|                 break;
 | ||
|             }
 | ||
|         }
 | ||
|     }
 | ||
|     core.gatherFollowers();
 | ||
|     core.clearMap('hero');
 | ||
|     core.drawHero();
 | ||
|     core.clearRouteFolding();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._updateValueByOperator = function (
 | ||
|     value,
 | ||
|     originValue,
 | ||
|     operator
 | ||
| ) {
 | ||
|     switch (operator) {
 | ||
|         case '+=':
 | ||
|             value = originValue + value;
 | ||
|             break;
 | ||
|         case '-=':
 | ||
|             value = originValue - value;
 | ||
|             break;
 | ||
|         case '*=':
 | ||
|             value = originValue * value;
 | ||
|             break;
 | ||
|         case '/=':
 | ||
|             value = originValue / value;
 | ||
|             break;
 | ||
|         case '**=':
 | ||
|             value = Math.pow(originValue, value);
 | ||
|             break;
 | ||
|         case '//=':
 | ||
|             value = Math.trunc(originValue / value);
 | ||
|             break;
 | ||
|         case '%=':
 | ||
|             value = originValue % value;
 | ||
|             break;
 | ||
|         case 'min=':
 | ||
|             value = Math.min(originValue, value);
 | ||
|             break;
 | ||
|         case 'max=':
 | ||
|             value = Math.max(originValue, value);
 | ||
|             break;
 | ||
|         default:
 | ||
|             break;
 | ||
|     }
 | ||
|     return value;
 | ||
| };
 | ||
| 
 | ||
| ////// 数值操作 //////
 | ||
| events.prototype.setValue = function (name, operator, value, prefix) {
 | ||
|     value = this._updateValueByOperator(
 | ||
|         core.calValue(value, prefix),
 | ||
|         core.calValue(name, prefix),
 | ||
|         operator
 | ||
|     );
 | ||
|     this._setValue_setStatus(name, value);
 | ||
|     this._setValue_setBuff(name, value);
 | ||
|     this._setValue_setItem(name, value);
 | ||
|     this._setValue_setFlag(name, value);
 | ||
|     this._setValue_setSwitch(name, value, prefix);
 | ||
|     this._setValue_setTemp(name, value, prefix);
 | ||
|     this._setValue_setGlobal(name, value);
 | ||
| };
 | ||
| 
 | ||
| events.prototype._setValue_setStatus = function (name, value) {
 | ||
|     if (name.indexOf('status:') !== 0) return;
 | ||
|     core.setStatus(name.substring(7), value);
 | ||
| };
 | ||
| 
 | ||
| events.prototype._setValue_setBuff = function (name, value) {
 | ||
|     if (name.indexOf('buff:') !== 0) return;
 | ||
|     core.setBuff(name.substring(5), value);
 | ||
| };
 | ||
| 
 | ||
| events.prototype._setValue_setItem = function (name, value) {
 | ||
|     if (name.indexOf('item:') !== 0) return;
 | ||
|     var itemId = name.substring(5),
 | ||
|         count = core.itemCount(itemId);
 | ||
|     if (value > count) core.getItem(itemId, value - count);
 | ||
|     else core.setItem(itemId, value);
 | ||
| };
 | ||
| 
 | ||
| events.prototype._setValue_setFlag = function (name, value) {
 | ||
|     if (name.indexOf('flag:') !== 0) return;
 | ||
|     core.setFlag(name.substring(5), value);
 | ||
| };
 | ||
| 
 | ||
| events.prototype._setValue_setSwitch = function (name, value, prefix) {
 | ||
|     if (name.indexOf('switch:') !== 0) return;
 | ||
|     core.setFlag((prefix || ':f@x@y') + '@' + name.substring(7), value);
 | ||
| };
 | ||
| 
 | ||
| events.prototype._setValue_setTemp = function (name, value) {
 | ||
|     if (name.indexOf('temp:') !== 0) return;
 | ||
|     core.setFlag('@temp@' + name.substring(5), value);
 | ||
| };
 | ||
| 
 | ||
| events.prototype._setValue_setGlobal = function (name, value) {
 | ||
|     if (name.indexOf('global:') !== 0) return;
 | ||
|     core.setGlobal(name.substring(7), value);
 | ||
| };
 | ||
| 
 | ||
| ////// 设置一个怪物属性 //////
 | ||
| events.prototype.setEnemy = function (
 | ||
|     id,
 | ||
|     name,
 | ||
|     value,
 | ||
|     operator,
 | ||
|     prefix,
 | ||
|     norefresh
 | ||
| ) {
 | ||
|     if (!core.hasFlag('enemyInfo')) {
 | ||
|         core.setFlag('enemyInfo', {});
 | ||
|     }
 | ||
|     var enemyInfo = core.getFlag('enemyInfo');
 | ||
|     if (!enemyInfo[id]) enemyInfo[id] = {};
 | ||
|     if (typeof value === 'string' && name == 'name')
 | ||
|         value = value.replace(/\r/g, '\\r');
 | ||
|     value = this._updateValueByOperator(
 | ||
|         core.calValue(value, prefix),
 | ||
|         (core.material.enemys[id] || {})[name],
 | ||
|         operator
 | ||
|     );
 | ||
|     enemyInfo[id][name] = value;
 | ||
|     (core.material.enemys[id] || {})[name] = core.clone(value);
 | ||
|     if (!norefresh) core.updateStatusBar();
 | ||
| };
 | ||
| 
 | ||
| ////// 设置某个点上的怪物属性 //////
 | ||
| events.prototype.setEnemyOnPoint = function (x, y) {
 | ||
|     // Deprecated.
 | ||
| };
 | ||
| 
 | ||
| ////// 重置某个点上的怪物属性 //////
 | ||
| events.prototype.resetEnemyOnPoint = function (x, y, floorId, norefresh) {
 | ||
|     delete ((flags.enemyOnPoint || {})[floorId || core.status.floorId] || {})[
 | ||
|         x + ',' + y
 | ||
|     ];
 | ||
|     if (!norefresh) core.updateStatusBar();
 | ||
| };
 | ||
| 
 | ||
| ////// 将某个点上已经设置的怪物属性移动到其他点 //////
 | ||
| events.prototype.moveEnemyOnPoint = function (
 | ||
|     fromX,
 | ||
|     fromY,
 | ||
|     toX,
 | ||
|     toY,
 | ||
|     floorId,
 | ||
|     norefresh
 | ||
| ) {
 | ||
|     floorId = floorId || core.status.floorId;
 | ||
|     if (((flags.enemyOnPoint || {})[floorId] || {})[fromX + ',' + fromY]) {
 | ||
|         flags.enemyOnPoint[floorId][toX + ',' + toY] =
 | ||
|             flags.enemyOnPoint[floorId][fromX + ',' + fromY];
 | ||
|         delete flags.enemyOnPoint[floorId][fromX + ',' + fromY];
 | ||
|         if (!norefresh) core.updateStatusBar();
 | ||
|     }
 | ||
| };
 | ||
| 
 | ||
| ////// 设置楼层属性 //////
 | ||
| events.prototype.setFloorInfo = function (name, value, floorId, prefix) {
 | ||
|     floorId = floorId || core.status.floorId;
 | ||
|     core.status.maps[floorId][name] = value;
 | ||
|     core.updateStatusBar();
 | ||
| };
 | ||
| 
 | ||
| ////// 设置全塔属性 //////
 | ||
| events.prototype.setGlobalAttribute = function (name, value) {
 | ||
|     if (typeof value == 'string') {
 | ||
|         if (
 | ||
|             (value.charAt(0) == '"' && value.charAt(value.length - 1) == '"') ||
 | ||
|             (value.charAt(0) == "'" && value.charAt(value.length - 1) == "'")
 | ||
|         )
 | ||
|             value = value.substring(1, value.length - 1);
 | ||
|         // --- 检查 []
 | ||
|         if (value.charAt(0) == '[' && value.charAt(value.length - 1) == ']')
 | ||
|             value = eval(value);
 | ||
|         // --- 检查颜色
 | ||
|         if (/^[0-9 ]+,[0-9 ]+,[0-9 ]+(,[0-9. ]+)?$/.test(value)) {
 | ||
|             value = 'rgba(' + value + ')';
 | ||
|         }
 | ||
|     }
 | ||
|     core.status.globalAttribute[name] = value;
 | ||
|     core.setFlag('globalAttribute', core.status.globalAttribute);
 | ||
|     core.resize();
 | ||
| };
 | ||
| 
 | ||
| ////// 设置全局开关 //////
 | ||
| events.prototype.setGlobalFlag = function (name, value) {
 | ||
|     var flags = core.getFlag('globalFlags', {});
 | ||
|     if (name.startsWith('s:')) {
 | ||
|         name = name.substring(2);
 | ||
|         var statusBarItems = core.flags.statusBarItems.filter(function (v) {
 | ||
|             return v != name;
 | ||
|         });
 | ||
|         if (value) statusBarItems.push(name);
 | ||
|         core.flags.statusBarItems = statusBarItems;
 | ||
|         flags.statusBarItems = core.clone(statusBarItems);
 | ||
|     } else {
 | ||
|         flags[name] = core.flags[name] = value;
 | ||
|     }
 | ||
|     core.setFlag('globalFlags', flags);
 | ||
|     core.resize();
 | ||
|     if (name == 'blurFg') core.redrawMap();
 | ||
| };
 | ||
| 
 | ||
| ////// 设置文件别名 //////
 | ||
| events.prototype.setNameMap = function (name, value) {
 | ||
|     if (!core.hasFlag('__nameMap__')) core.setFlag('__nameMap__', {});
 | ||
|     flags.__nameMap__[name] = value;
 | ||
| };
 | ||
| 
 | ||
| ////// 设置剧情文本的属性 //////
 | ||
| events.prototype.setTextAttribute = function (data) {
 | ||
|     if (!core.isPlaying()) return;
 | ||
|     [
 | ||
|         'position',
 | ||
|         'offset',
 | ||
|         'align',
 | ||
|         'bold',
 | ||
|         'titlefont',
 | ||
|         'textfont',
 | ||
|         'lineHeight',
 | ||
|         'time',
 | ||
|         'letterSpacing',
 | ||
|         'animateTime'
 | ||
|     ].forEach(function (t) {
 | ||
|         if (data[t] != null) core.status.textAttribute[t] = data[t];
 | ||
|     });
 | ||
|     ['background', 'title', 'text'].forEach(function (t) {
 | ||
|         if (data[t] instanceof Array && data[t].length >= 3) {
 | ||
|             if (data[t].length == 3) data[t].push(1);
 | ||
|             core.status.textAttribute[t] = data[t];
 | ||
|         }
 | ||
|         if (t == 'background') {
 | ||
|             var name = core.getMappedName(data[t]);
 | ||
|             var img = core.material.images.images[name];
 | ||
|             if (img && img.width == 192 && img.height == 128) {
 | ||
|                 core.status.textAttribute[t] = name;
 | ||
|             }
 | ||
|         }
 | ||
|     });
 | ||
|     if (main.mode == 'play')
 | ||
|         core.setFlag('textAttribute', core.status.textAttribute);
 | ||
| };
 | ||
| 
 | ||
| events.prototype.moveTextBox = function (
 | ||
|     code,
 | ||
|     loc,
 | ||
|     relative,
 | ||
|     moveMode,
 | ||
|     time,
 | ||
|     callback
 | ||
| ) {
 | ||
|     var ctx = core.getContextByName('__text__' + code);
 | ||
|     if (!ctx) {
 | ||
|         if (callback) callback();
 | ||
|         return;
 | ||
|     }
 | ||
|     var sx = parseInt(ctx.canvas.getAttribute('_text_left')) || 0;
 | ||
|     var sy = parseInt(ctx.canvas.getAttribute('_text_top')) || 0;
 | ||
|     var dx = relative ? loc[0] : loc[0] - sx;
 | ||
|     var dy = relative ? loc[1] : loc[1] - sy;
 | ||
|     var ox = parseInt(ctx.canvas.getAttribute('_left')) || 0;
 | ||
|     var oy = parseInt(ctx.canvas.getAttribute('_top')) || 0;
 | ||
| 
 | ||
|     if (!time) {
 | ||
|         core.relocateCanvas(ctx, ox + dx, oy + dy);
 | ||
|         ctx.canvas.setAttribute('_text_left', loc[0]);
 | ||
|         ctx.canvas.setAttribute('_text_top', loc[1]);
 | ||
|         if (callback) callback();
 | ||
|         return;
 | ||
|     }
 | ||
| 
 | ||
|     var moveInfo = {
 | ||
|         sx: sx,
 | ||
|         sy: sy,
 | ||
|         dx: dx,
 | ||
|         dy: dy,
 | ||
|         ox: ox,
 | ||
|         oy: oy,
 | ||
|         moveMode: moveMode,
 | ||
|         time: time / Math.max(core.status.replay.speed, 1)
 | ||
|     };
 | ||
|     this._moveTextBox_moving(ctx, moveInfo, callback);
 | ||
| };
 | ||
| 
 | ||
| events.prototype._moveTextBox_moving = function (ctx, moveInfo, callback) {
 | ||
|     var step = 0,
 | ||
|         steps = moveInfo.time / 10;
 | ||
|     if (steps <= 0) steps = 1;
 | ||
|     var moveFunc = core.applyEasing(moveInfo.moveMode);
 | ||
|     var animate = setInterval(function () {
 | ||
|         step++;
 | ||
|         var dx = moveInfo.dx * moveFunc(step / steps);
 | ||
|         var dy = moveInfo.dy * moveFunc(step / steps);
 | ||
|         core.relocateCanvas(
 | ||
|             ctx,
 | ||
|             Math.floor(moveInfo.ox + dx),
 | ||
|             Math.floor(moveInfo.oy + dy)
 | ||
|         );
 | ||
|         ctx.canvas.setAttribute('_text_left', moveInfo.sx + dx);
 | ||
|         ctx.canvas.setAttribute('_text_top', moveInfo.sy + dy);
 | ||
|         if (step == steps) {
 | ||
|             delete core.animateFrame.asyncId[animate];
 | ||
|             clearInterval(animate);
 | ||
|             if (callback) callback();
 | ||
|         }
 | ||
|     }, 10);
 | ||
| 
 | ||
|     core.animateFrame.lastAsyncId = animate;
 | ||
|     core.animateFrame.asyncId[animate] = callback;
 | ||
| };
 | ||
| 
 | ||
| ////// 清除对话框 //////
 | ||
| events.prototype.clearTextBox = function (code, callback) {
 | ||
|     if (code == null) {
 | ||
|         code = Object.keys(core.dymCanvas)
 | ||
|             .filter(function (one) {
 | ||
|                 return one.startsWith('__text__');
 | ||
|             })
 | ||
|             .map(function (one) {
 | ||
|                 return one.substring('__text__'.length);
 | ||
|             });
 | ||
|     }
 | ||
| 
 | ||
|     if (!(code instanceof Array)) code = [code];
 | ||
|     var index = 0;
 | ||
|     var _work = function () {
 | ||
|         if (index == code.length) {
 | ||
|             if (callback) callback();
 | ||
|             return;
 | ||
|         }
 | ||
|         var ctx = '__text__' + code[index++];
 | ||
|         if (!core.getContextByName(ctx)) return _work();
 | ||
|         core.ui._animateUI('hide', ctx, function () {
 | ||
|             core.deleteCanvas(ctx);
 | ||
|             _work();
 | ||
|         });
 | ||
|     };
 | ||
|     _work();
 | ||
| };
 | ||
| 
 | ||
| ////// 关门 //////
 | ||
| events.prototype.closeDoor = function (x, y, id, callback) {
 | ||
|     id = id || '';
 | ||
|     if (
 | ||
|         (core.material.icons.animates[id] == null &&
 | ||
|             core.material.icons.npc48[id] == null) ||
 | ||
|         core.getBlock(x, y) != null
 | ||
|     ) {
 | ||
|         if (callback) callback();
 | ||
|         return;
 | ||
|     }
 | ||
|     var block = core.getBlockById(id);
 | ||
|     var doorInfo = (block.event || {}).doorInfo;
 | ||
|     if (!doorInfo) {
 | ||
|         if (callback) callback();
 | ||
|         return;
 | ||
|     }
 | ||
| 
 | ||
|     core.playSound(doorInfo.closeSound);
 | ||
|     var blockInfo = core.getBlockInfo(block);
 | ||
|     var speed = (doorInfo.time || 160) / 4;
 | ||
|     blockInfo.posX = 3;
 | ||
|     core.maps._drawBlockInfo(blockInfo, x, y);
 | ||
| 
 | ||
|     var cb = function () {
 | ||
|         core.setBlock(id, x, y);
 | ||
|         core.showBlock(x, y);
 | ||
|         if (callback) callback();
 | ||
|     };
 | ||
| 
 | ||
|     var animate = window.setInterval(
 | ||
|         function () {
 | ||
|             blockInfo.posX--;
 | ||
|             if (blockInfo.posX < 0) {
 | ||
|                 clearInterval(animate);
 | ||
|                 delete core.animateFrame.asyncId[animate];
 | ||
|                 cb();
 | ||
|                 return;
 | ||
|             }
 | ||
|             core.maps._drawBlockInfo(blockInfo, x, y);
 | ||
|         },
 | ||
|         core.status.replay.speed == 24
 | ||
|             ? 1
 | ||
|             : speed / Math.max(core.status.replay.speed, 1)
 | ||
|     );
 | ||
| 
 | ||
|     core.animateFrame.lastAsyncId = animate;
 | ||
|     core.animateFrame.asyncId[animate] = cb;
 | ||
| };
 | ||
| 
 | ||
| ////// 显示图片 //////
 | ||
| events.prototype.showImage = function (
 | ||
|     code,
 | ||
|     image,
 | ||
|     sloc,
 | ||
|     loc,
 | ||
|     opacityVal,
 | ||
|     time,
 | ||
|     callback
 | ||
| ) {
 | ||
|     var imageName = null;
 | ||
|     if (typeof image == 'string') {
 | ||
|         imageName = image;
 | ||
|         if (
 | ||
|             image.endsWith(':x') ||
 | ||
|             image.endsWith(':y') ||
 | ||
|             image.endsWith(':o')
 | ||
|         ) {
 | ||
|             image = image.substring(0, image.length - 2);
 | ||
|         }
 | ||
|         image = core.getMappedName(image);
 | ||
|         image = core.material.images.images[image];
 | ||
|     }
 | ||
|     if (!image) {
 | ||
|         if (callback) callback();
 | ||
|         return;
 | ||
|     }
 | ||
|     sloc = sloc || [];
 | ||
|     var sx = core.calValue(sloc[0]) || 0,
 | ||
|         sy = core.calValue(sloc[1]) || 0;
 | ||
|     var sw = core.calValue(sloc[2]),
 | ||
|         sh = core.calValue(sloc[3]);
 | ||
|     if (sw == null) sw = image.width;
 | ||
|     if (sh == null) sh = image.height;
 | ||
|     loc = loc || [];
 | ||
|     var x = core.calValue(loc[0]) || 0,
 | ||
|         y = core.calValue(loc[1]) || 0;
 | ||
|     var w = core.calValue(loc[2]),
 | ||
|         h = core.calValue(loc[3]);
 | ||
|     if (w == null) w = sw;
 | ||
|     if (h == null) h = sh;
 | ||
|     var zIndex = code + 100;
 | ||
|     time = time || 0;
 | ||
|     var name = 'image' + zIndex;
 | ||
|     var ctx = core.createCanvas(name, x, y, w, h, zIndex);
 | ||
|     core.drawImage(
 | ||
|         ctx,
 | ||
|         imageName == null ? image : imageName,
 | ||
|         sx,
 | ||
|         sy,
 | ||
|         sw,
 | ||
|         sh,
 | ||
|         0,
 | ||
|         0,
 | ||
|         w,
 | ||
|         h
 | ||
|     );
 | ||
|     if (time == 0) {
 | ||
|         core.setOpacity(name, opacityVal);
 | ||
|         if (callback) callback();
 | ||
|         return;
 | ||
|     }
 | ||
|     core.setOpacity(name, 0);
 | ||
|     this.moveImage(code, null, opacityVal, null, time, callback);
 | ||
| };
 | ||
| 
 | ||
| ////// 隐藏图片 //////
 | ||
| events.prototype.hideImage = function (code, time, callback) {
 | ||
|     time = time || 0;
 | ||
|     var name = 'image' + (code + 100);
 | ||
|     if (time == 0 || !core.dymCanvas[name]) {
 | ||
|         core.deleteCanvas(name);
 | ||
|         if (callback) callback();
 | ||
|         return;
 | ||
|     }
 | ||
|     this.moveImage(code, null, 0, null, time, function () {
 | ||
|         core.deleteCanvas(name);
 | ||
|         if (callback) callback();
 | ||
|     });
 | ||
| };
 | ||
| 
 | ||
| ////// 移动图片 //////
 | ||
| events.prototype.moveImage = function (
 | ||
|     code,
 | ||
|     to,
 | ||
|     opacityVal,
 | ||
|     moveMode,
 | ||
|     time,
 | ||
|     callback
 | ||
| ) {
 | ||
|     to = to || [];
 | ||
|     var name = 'image' + (code + 100);
 | ||
|     if (!core.dymCanvas[name]) {
 | ||
|         if (callback) callback();
 | ||
|         return;
 | ||
|     }
 | ||
|     var getOrDefault = function (a, b) {
 | ||
|         a = core.calValue(a);
 | ||
|         return a != null ? a : b;
 | ||
|     };
 | ||
|     var canvas = core.dymCanvas[name].canvas;
 | ||
|     var fromX = parseFloat(canvas.getAttribute('_left')),
 | ||
|         fromY = parseFloat(canvas.getAttribute('_top')),
 | ||
|         toX = getOrDefault(to[0], fromX),
 | ||
|         toY = getOrDefault(to[1], fromY);
 | ||
| 
 | ||
|     var opacity = parseFloat(canvas.style.opacity),
 | ||
|         toOpacity = getOrDefault(opacityVal, opacity);
 | ||
| 
 | ||
|     if (!time) {
 | ||
|         core.relocateCanvas(name, toX, toY);
 | ||
|         core.setOpacity(toOpacity);
 | ||
|         if (callback) callback();
 | ||
|         return;
 | ||
|     }
 | ||
| 
 | ||
|     this._moveImage_moving(
 | ||
|         name,
 | ||
|         {
 | ||
|             fromX: fromX,
 | ||
|             fromY: fromY,
 | ||
|             toX: toX,
 | ||
|             toY: toY,
 | ||
|             opacity: opacity,
 | ||
|             toOpacity: toOpacity,
 | ||
|             moveMode: moveMode,
 | ||
|             time: time / Math.max(core.status.replay.speed, 1)
 | ||
|         },
 | ||
|         callback
 | ||
|     );
 | ||
| };
 | ||
| 
 | ||
| events.prototype._moveImage_moving = function (name, moveInfo, callback) {
 | ||
|     var per_time = 10,
 | ||
|         step = 0,
 | ||
|         steps = Math.floor(moveInfo.time / per_time);
 | ||
|     if (steps <= 0) steps = 1;
 | ||
|     var fromX = moveInfo.fromX,
 | ||
|         fromY = moveInfo.fromY,
 | ||
|         toX = moveInfo.toX,
 | ||
|         toY = moveInfo.toY,
 | ||
|         opacity = moveInfo.opacity,
 | ||
|         toOpacity = moveInfo.toOpacity;
 | ||
|     var currX = fromX,
 | ||
|         currY = fromY,
 | ||
|         currOpacity = opacity;
 | ||
|     var moveFunc = core.applyEasing(moveInfo.moveMode);
 | ||
|     var animate = setInterval(function () {
 | ||
|         step++;
 | ||
|         currOpacity = opacity + (toOpacity - opacity) * moveFunc(step / steps);
 | ||
|         currX = Math.floor(fromX + (toX - fromX) * moveFunc(step / steps));
 | ||
|         currY = Math.floor(fromY + (toY - fromY) * moveFunc(step / steps));
 | ||
|         core.setOpacity(name, currOpacity);
 | ||
|         core.relocateCanvas(name, currX, currY);
 | ||
|         if (step == steps) {
 | ||
|             delete core.animateFrame.asyncId[animate];
 | ||
|             clearInterval(animate);
 | ||
|             if (callback) callback();
 | ||
|         }
 | ||
|     }, per_time);
 | ||
| 
 | ||
|     core.animateFrame.lastAsyncId = animate;
 | ||
|     core.animateFrame.asyncId[animate] = callback;
 | ||
| };
 | ||
| 
 | ||
| ////// 旋转图片 //////
 | ||
| events.prototype.rotateImage = function (
 | ||
|     code,
 | ||
|     center,
 | ||
|     angle,
 | ||
|     moveMode,
 | ||
|     time,
 | ||
|     callback
 | ||
| ) {
 | ||
|     center = center || [];
 | ||
|     var name = 'image' + (code + 100);
 | ||
|     if (!core.dymCanvas[name]) {
 | ||
|         if (callback) callback();
 | ||
|         return;
 | ||
|     }
 | ||
|     var canvas = core.dymCanvas[name].canvas;
 | ||
|     var centerX = core.calValue(center[0]),
 | ||
|         centerY = core.calValue(center[1]);
 | ||
| 
 | ||
|     var fromAngle = parseFloat(canvas.getAttribute('_angle')) || 0;
 | ||
| 
 | ||
|     if (!time) {
 | ||
|         core.rotateCanvas(name, fromAngle + angle, centerX, centerY);
 | ||
|         if (callback) callback();
 | ||
|         return;
 | ||
|     }
 | ||
| 
 | ||
|     var rotateInfo = {
 | ||
|         fromAngle: fromAngle,
 | ||
|         angle: angle,
 | ||
|         centerX: centerX,
 | ||
|         centerY: centerY,
 | ||
|         moveMode: moveMode,
 | ||
|         time: time / Math.max(core.status.replay.speed, 1)
 | ||
|     };
 | ||
|     this._rotateImage_rotating(name, rotateInfo, callback);
 | ||
| };
 | ||
| 
 | ||
| events.prototype._rotateImage_rotating = function (name, rotateInfo, callback) {
 | ||
|     var per_time = 10,
 | ||
|         step = 0,
 | ||
|         steps = Math.floor(rotateInfo.time / per_time);
 | ||
|     if (steps <= 0) steps = 1;
 | ||
|     var moveFunc = core.applyEasing(rotateInfo.moveMode);
 | ||
|     var animate = setInterval(function () {
 | ||
|         step++;
 | ||
|         var currAngle =
 | ||
|             rotateInfo.fromAngle + rotateInfo.angle * moveFunc(step / steps);
 | ||
|         core.rotateCanvas(
 | ||
|             name,
 | ||
|             currAngle,
 | ||
|             rotateInfo.centerX,
 | ||
|             rotateInfo.centerY
 | ||
|         );
 | ||
|         if (step == steps) {
 | ||
|             delete core.animateFrame.asyncId[animate];
 | ||
|             clearInterval(animate);
 | ||
|             if (callback) callback();
 | ||
|         }
 | ||
|     }, per_time);
 | ||
| 
 | ||
|     core.animateFrame.lastAsyncId = animate;
 | ||
|     core.animateFrame.asyncId[animate] = callback;
 | ||
| };
 | ||
| 
 | ||
| ////// 放缩一张图片 //////
 | ||
| events.prototype.scaleImage = function (
 | ||
|     code,
 | ||
|     center,
 | ||
|     scale,
 | ||
|     moveMode,
 | ||
|     time,
 | ||
|     callback
 | ||
| ) {
 | ||
|     center = center || [];
 | ||
|     var name = 'image' + (code + 100);
 | ||
|     if (!core.dymCanvas[name]) {
 | ||
|         if (callback) callback();
 | ||
|         return;
 | ||
|     }
 | ||
|     var ctx = core.dymCanvas[name];
 | ||
|     var currScale = 1.0;
 | ||
|     if (ctx.canvas.hasAttribute('_scale')) {
 | ||
|         currScale = parseFloat(ctx.canvas.getAttribute('_scale'));
 | ||
|     }
 | ||
|     var ratio = ctx.canvas.hasAttribute('isHD') ? core.domStyle.ratio : 1;
 | ||
|     var width = ctx.canvas.width / ratio,
 | ||
|         height = ctx.canvas.height / ratio;
 | ||
|     var currLeft = parseFloat(ctx.canvas.getAttribute('_left'));
 | ||
|     var currTop = parseFloat(ctx.canvas.getAttribute('_top'));
 | ||
|     var centerX = core.calValue(center[0]),
 | ||
|         centerY = core.calValue(center[1]);
 | ||
|     if (centerX == null || centerY == null) {
 | ||
|         centerX = currLeft + (width * currScale) / 2;
 | ||
|         centerY = currTop + (height * currScale) / 2;
 | ||
|     }
 | ||
|     var scaleInfo = {
 | ||
|         x: (currLeft - centerX) / currScale,
 | ||
|         y: (currTop - centerY) / currScale,
 | ||
|         centerX: centerX,
 | ||
|         centerY: centerY,
 | ||
|         width: width,
 | ||
|         height: height,
 | ||
|         currScale: currScale,
 | ||
|         scale: scale,
 | ||
|         moveMode: moveMode,
 | ||
|         time: time
 | ||
|     };
 | ||
|     this._scaleImage_scale(ctx, scaleInfo, callback);
 | ||
| };
 | ||
| 
 | ||
| events.prototype._scaleInfo_scale = function (ctx, scaleInfo, scale) {
 | ||
|     core.resizeCanvas(
 | ||
|         ctx,
 | ||
|         scaleInfo.width * scale,
 | ||
|         scaleInfo.height * scale,
 | ||
|         true
 | ||
|     );
 | ||
|     core.relocateCanvas(
 | ||
|         ctx,
 | ||
|         scaleInfo.centerX + scaleInfo.x * scale,
 | ||
|         scaleInfo.centerY + scaleInfo.y * scale
 | ||
|     );
 | ||
|     ctx.canvas.setAttribute('_scale', scale);
 | ||
| };
 | ||
| 
 | ||
| events.prototype._scaleImage_scale = function (ctx, scaleInfo, callback) {
 | ||
|     if (!scaleInfo.time) {
 | ||
|         this._scaleInfo_scale(ctx, scaleInfo, scaleInfo.scale);
 | ||
|         if (callback) callback();
 | ||
|         return;
 | ||
|     }
 | ||
| 
 | ||
|     var per_time = 10,
 | ||
|         step = 0,
 | ||
|         steps = Math.floor(scaleInfo.time / per_time);
 | ||
|     if (steps <= 0) steps = 1;
 | ||
|     var moveFunc = core.applyEasing(scaleInfo.moveMode);
 | ||
| 
 | ||
|     var animate = setInterval(function () {
 | ||
|         step++;
 | ||
|         var scale =
 | ||
|             scaleInfo.currScale +
 | ||
|             (scaleInfo.scale - scaleInfo.currScale) * moveFunc(step / steps);
 | ||
|         core.events._scaleInfo_scale(ctx, scaleInfo, scale);
 | ||
|         if (step == steps) {
 | ||
|             delete core.animateFrame.asyncId[animate];
 | ||
|             clearInterval(animate);
 | ||
|             if (callback) callback();
 | ||
|         }
 | ||
|     }, per_time);
 | ||
| 
 | ||
|     core.animateFrame.lastAsyncId = animate;
 | ||
|     core.animateFrame.asyncId[animate] = callback;
 | ||
| };
 | ||
| 
 | ||
| ////// 绘制或取消一张gif图片 //////
 | ||
| events.prototype.showGif = function (name, x, y) {
 | ||
|     // Deprecated.
 | ||
| };
 | ||
| 
 | ||
| ////// 淡入淡出音乐 //////
 | ||
| events.prototype.setVolume = function (value, time, callback) {
 | ||
|     var set = function (value) {
 | ||
|         core.musicStatus.designVolume = value;
 | ||
|         if (core.musicStatus.playingBgm)
 | ||
|             core.material.bgms[core.musicStatus.playingBgm].volume =
 | ||
|                 core.musicStatus.userVolume * core.musicStatus.designVolume;
 | ||
|     };
 | ||
|     if (!time || time < 100) {
 | ||
|         set(value);
 | ||
|         if (callback) callback();
 | ||
|         return;
 | ||
|     }
 | ||
|     var currVolume = core.musicStatus.designVolume;
 | ||
|     time /= Math.max(core.status.replay.speed, 1);
 | ||
|     var per_time = 10,
 | ||
|         step = 0,
 | ||
|         steps = Math.floor(time / per_time);
 | ||
|     if (steps <= 0) steps = 1;
 | ||
|     var animate = setInterval(function () {
 | ||
|         step++;
 | ||
|         set(currVolume + ((value - currVolume) * step) / steps);
 | ||
|         if (step >= steps) {
 | ||
|             delete core.animateFrame.asyncId[animate];
 | ||
|             clearInterval(animate);
 | ||
|             if (callback) callback();
 | ||
|         }
 | ||
|     }, per_time);
 | ||
| 
 | ||
|     core.animateFrame.lastAsyncId = animate;
 | ||
|     core.animateFrame.asyncId[animate] = callback;
 | ||
| };
 | ||
| 
 | ||
| ////// 画面震动 //////
 | ||
| events.prototype.vibrate = function (direction, time, speed, power, callback) {
 | ||
|     if (core.isReplaying()) {
 | ||
|         if (callback) callback();
 | ||
|         return;
 | ||
|     }
 | ||
|     if (!time) time = 1000;
 | ||
|     speed = speed || 10;
 | ||
|     power = power || 10;
 | ||
|     var shakeInfo = {
 | ||
|         duration: Math.floor(time / 10),
 | ||
|         speed: speed,
 | ||
|         power: power,
 | ||
|         direction: 1,
 | ||
|         shake: 0
 | ||
|     };
 | ||
|     if (direction == 'random') {
 | ||
|         direction = ['horizontal', 'vertical', 'diagonal1', 'diagonal2'][
 | ||
|             Math.floor(Math.random() * 4)
 | ||
|         ];
 | ||
|     }
 | ||
|     var cb = function () {
 | ||
|         core.addGameCanvasTranslate(0, 0);
 | ||
|         if (callback) callback();
 | ||
|     };
 | ||
|     var animate = setInterval(function () {
 | ||
|         core.events._vibrate_update(shakeInfo);
 | ||
|         switch (direction) {
 | ||
|             case 'vertical':
 | ||
|                 core.addGameCanvasTranslate(0, shakeInfo.shake);
 | ||
|                 break;
 | ||
|             case 'diagonal1':
 | ||
|                 core.addGameCanvasTranslate(shakeInfo.shake, shakeInfo.shake);
 | ||
|                 break;
 | ||
|             case 'diagonal2':
 | ||
|                 core.addGameCanvasTranslate(-shakeInfo.shake, shakeInfo.shake);
 | ||
|                 break;
 | ||
|             default:
 | ||
|                 core.addGameCanvasTranslate(shakeInfo.shake, 0);
 | ||
|         }
 | ||
|         if (shakeInfo.duration === 0 && shakeInfo.shake == 0) {
 | ||
|             delete core.animateFrame.asyncId[animate];
 | ||
|             clearInterval(animate);
 | ||
|             cb();
 | ||
|         }
 | ||
|     }, 10);
 | ||
| 
 | ||
|     core.animateFrame.lastAsyncId = animate;
 | ||
|     core.animateFrame.asyncId[animate] = cb;
 | ||
| };
 | ||
| 
 | ||
| events.prototype._vibrate_update = function (shakeInfo) {
 | ||
|     if (shakeInfo.duration >= 1 || shakeInfo.shake != 0) {
 | ||
|         var delta = (shakeInfo.speed * shakeInfo.direction) / 6;
 | ||
|         if (
 | ||
|             shakeInfo.duration <= 1 &&
 | ||
|             shakeInfo.shake * (shakeInfo.shake + delta) < 0
 | ||
|         ) {
 | ||
|             shakeInfo.shake = 0;
 | ||
|         } else {
 | ||
|             shakeInfo.shake += delta;
 | ||
|         }
 | ||
|         if (shakeInfo.shake > shakeInfo.power) {
 | ||
|             shakeInfo.direction = -1;
 | ||
|         }
 | ||
|         if (shakeInfo.shake < -shakeInfo.power) {
 | ||
|             shakeInfo.direction = 1;
 | ||
|         }
 | ||
|         if (shakeInfo.duration >= 1) {
 | ||
|             shakeInfo.duration -= 1;
 | ||
|         }
 | ||
|     }
 | ||
| };
 | ||
| 
 | ||
| /////// 使用事件让勇士移动。这个函数将不会触发任何事件 //////
 | ||
| events.prototype.eventMoveHero = function (steps, time, callback) {
 | ||
|     time = time || core.values.moveSpeed;
 | ||
|     // const render = Mota.require('module', 'Render').heroRender;
 | ||
|     var step = 0,
 | ||
|         moveSteps = (steps || [])
 | ||
|             .map(function (t) {
 | ||
|                 return [t.split(':')[0], parseInt(t.split(':')[1] || '1')];
 | ||
|             })
 | ||
|             .filter(function (t) {
 | ||
|                 return (
 | ||
|                     [
 | ||
|                         'up',
 | ||
|                         'down',
 | ||
|                         'left',
 | ||
|                         'right',
 | ||
|                         'forward',
 | ||
|                         'backward',
 | ||
|                         'leftup',
 | ||
|                         'leftdown',
 | ||
|                         'rightup',
 | ||
|                         'rightdown',
 | ||
|                         'speed'
 | ||
|                     ].indexOf(t[0]) >= 0 && !(t[0] == 'speed' && t[1] < 16)
 | ||
|                 );
 | ||
|             });
 | ||
|     core.status.heroMoving = -1;
 | ||
|     // render.move(false);
 | ||
|     var _run = function () {
 | ||
|         var cb = function () {
 | ||
|             core.status.heroMoving = 0;
 | ||
|             // render.move(false);
 | ||
|             core.drawHero();
 | ||
|             if (callback) callback();
 | ||
|         };
 | ||
| 
 | ||
|         var animate = window.setInterval(
 | ||
|             function () {
 | ||
|                 if (moveSteps.length == 0) {
 | ||
|                     delete core.animateFrame.asyncId[animate];
 | ||
|                     clearInterval(animate);
 | ||
|                     cb();
 | ||
|                 } else {
 | ||
|                     if (
 | ||
|                         step == 0 &&
 | ||
|                         moveSteps[0][0] == 'speed' &&
 | ||
|                         moveSteps[0][1] >= 16
 | ||
|                     ) {
 | ||
|                         time = moveSteps[0][1];
 | ||
|                         moveSteps.shift();
 | ||
|                         clearInterval(animate);
 | ||
|                         delete core.animateFrame.asyncId[animate];
 | ||
|                         _run();
 | ||
|                     } else if (
 | ||
|                         core.events._eventMoveHero_moving(++step, moveSteps)
 | ||
|                     )
 | ||
|                         step = 0;
 | ||
|                 }
 | ||
|             },
 | ||
|             core.status.replay.speed == 24
 | ||
|                 ? 1
 | ||
|                 : time / 8 / core.status.replay.speed
 | ||
|         );
 | ||
| 
 | ||
|         core.animateFrame.lastAsyncId = animate;
 | ||
|         core.animateFrame.asyncId[animate] = cb;
 | ||
|     };
 | ||
|     _run();
 | ||
| };
 | ||
| 
 | ||
| events.prototype._eventMoveHero_moving = function (step, moveSteps) {
 | ||
|     // see src/plugin/game/heroFourFrames.js
 | ||
| };
 | ||
| 
 | ||
| ////// 勇士跳跃事件 //////
 | ||
| events.prototype.jumpHero = function (ex, ey, time, callback) {
 | ||
|     var sx = core.getHeroLoc('x'),
 | ||
|         sy = core.getHeroLoc('y');
 | ||
|     if (ex == null) ex = sx;
 | ||
|     if (ey == null) ey = sy;
 | ||
|     var sx = core.status.hero.loc.x,
 | ||
|         sy = core.status.hero.loc.y;
 | ||
|     if (!core.isset(ex)) ex = sx;
 | ||
|     if (!core.isset(ey)) ey = sy;
 | ||
|     var jumpInfo = core.maps.__generateJumpInfo(sx, sy, ex, ey, time || 500);
 | ||
|     jumpInfo.icon = core.material.icons.hero[core.getHeroLoc('direction')];
 | ||
|     jumpInfo.width = core.material.icons.hero.width || 32;
 | ||
|     jumpInfo.height = core.material.icons.hero.height;
 | ||
| 
 | ||
|     this._jumpHero_doJump(jumpInfo, callback);
 | ||
| };
 | ||
| 
 | ||
| events.prototype._jumpHero_doJump = function (jumpInfo, callback) {
 | ||
|     // const render = Mota.require('module', 'Render').heroRender;
 | ||
|     var cb = function () {
 | ||
|         core.setHeroLoc('x', jumpInfo.ex);
 | ||
|         core.setHeroLoc('y', jumpInfo.ey);
 | ||
|         // render.move(false);
 | ||
|         core.status.heroMoving = 0;
 | ||
|         core.drawHero();
 | ||
|         if (callback) callback();
 | ||
|     };
 | ||
| 
 | ||
|     core.status.heroMoving = -1;
 | ||
|     // render.move(false);
 | ||
|     var animate = window.setInterval(function () {
 | ||
|         if (jumpInfo.jump_count > 0) core.events._jumpHero_jumping(jumpInfo);
 | ||
|         else {
 | ||
|             delete core.animateFrame.asyncId[animate];
 | ||
|             clearInterval(animate);
 | ||
|             cb();
 | ||
|         }
 | ||
|     }, jumpInfo.per_time);
 | ||
| 
 | ||
|     core.animateFrame.lastAsyncId = animate;
 | ||
|     core.animateFrame.asyncId[animate] = cb;
 | ||
| };
 | ||
| 
 | ||
| events.prototype._jumpHero_jumping = function (jumpInfo) {
 | ||
|     core.clearMap('hero');
 | ||
|     core.maps.__updateJumpInfo(jumpInfo);
 | ||
|     var x = core.getHeroLoc('x'),
 | ||
|         y = core.getHeroLoc('y');
 | ||
|     var nowx = jumpInfo.px,
 | ||
|         nowy = jumpInfo.py,
 | ||
|         width = jumpInfo.width || 32,
 | ||
|         height = jumpInfo.height;
 | ||
|     core.drawHero('stop', { x: nowx - 32 * x, y: nowy - 32 * y });
 | ||
| };
 | ||
| 
 | ||
| ////// 设置角色行走图 //////
 | ||
| events.prototype.setHeroIcon = function (name, noDraw) {
 | ||
|     name = core.getMappedName(name);
 | ||
|     var img = core.material.images.images[name];
 | ||
|     if (!img) {
 | ||
|         console.error('找不到图片: ' + img);
 | ||
|         return;
 | ||
|     }
 | ||
|     if (core.material.images.hero == img) return;
 | ||
|     core.status.hero.image = name;
 | ||
|     core.material.images.hero = img;
 | ||
|     core.material.icons.hero.width = img.width / 4;
 | ||
|     core.material.icons.hero.height = img.height / 4;
 | ||
|     // Mota.require('module', 'Render').heroRender.setHero();
 | ||
|     if (!noDraw) core.drawHero();
 | ||
| };
 | ||
| 
 | ||
| ////// 检查升级事件 //////
 | ||
| events.prototype.checkLvUp = function () {
 | ||
|     var actions = [];
 | ||
|     while (true) {
 | ||
|         var next = this._checkLvUp_check();
 | ||
|         if (next == null) break;
 | ||
|         actions = actions.concat(next);
 | ||
|     }
 | ||
|     if (actions.length > 0) core.insertAction(actions);
 | ||
| };
 | ||
| 
 | ||
| events.prototype._checkLvUp_check = function () {
 | ||
|     if (
 | ||
|         core.flags.statusBarItems.indexOf('enableLevelUp') < 0 ||
 | ||
|         !core.firstData.levelUp ||
 | ||
|         core.status.hero.lv >= core.firstData.levelUp.length
 | ||
|     )
 | ||
|         return null;
 | ||
|     // 计算下一个所需要的数值
 | ||
|     var next = core.firstData.levelUp[core.status.hero.lv] || {};
 | ||
|     var need = core.calValue(next.need);
 | ||
|     if (need == null) return null;
 | ||
|     if (core.status.hero.exp >= need) {
 | ||
|         // 升级
 | ||
|         core.status.hero.lv++;
 | ||
|         if (next.clear) core.status.hero.exp -= need;
 | ||
|         return next.action || [];
 | ||
|     }
 | ||
|     return null;
 | ||
| };
 | ||
| 
 | ||
| ////// 尝试使用道具 //////
 | ||
| events.prototype.tryUseItem = function (itemId, noRoute, callback) {
 | ||
|     if (itemId === 'book') {
 | ||
|         if (core.isReplaying()) {
 | ||
|             core.control._replay_book();
 | ||
|         } else {
 | ||
|             core.ui.closePanel();
 | ||
|             core.openBook(false);
 | ||
|             callback?.();
 | ||
|         }
 | ||
|         return;
 | ||
|     }
 | ||
|     if (core.isReplaying()) {
 | ||
|         callback?.();
 | ||
|         return;
 | ||
|     }
 | ||
|     if (itemId === 'fly') {
 | ||
|         core.ui.closePanel();
 | ||
|         core.useFly(false);
 | ||
|         callback?.();
 | ||
|         return;
 | ||
|     }
 | ||
|     if (itemId === 'centerFly') {
 | ||
|         core.ui.closePanel();
 | ||
|         core.ui._drawCenterFly();
 | ||
|         callback?.();
 | ||
|         return;
 | ||
|     }
 | ||
|     if (core.canUseItem(itemId)) {
 | ||
|         core.useItem(itemId, noRoute, callback);
 | ||
|     } else {
 | ||
|         core.playSound('操作失败');
 | ||
|         core.drawTip('当前无法使用' + core.material.items[itemId].name, itemId);
 | ||
|     }
 | ||
|     callback?.();
 | ||
| };
 |