diff --git a/_docs/personalization.md b/_docs/personalization.md index 4831d9b5..c83c7eaa 100644 --- a/_docs/personalization.md +++ b/_docs/personalization.md @@ -427,7 +427,7 @@ function (enemy, hero_hp, hero_atk, hero_def, hero_mdef, x, y, floorId) { ``` js ////// 点击楼层传送器时的打开操作 ////// control.prototype.useFly = function (need) { - if (!core.status.heroStop || core.status.heroMoving > 0) { + if (core.isMoving()) { core.drawTip("请先停止勇士行动"); return; } diff --git a/_server/blockly/MotaAction.g4 b/_server/blockly/MotaAction.g4 index df4cf03e..bd5e3f4a 100644 --- a/_server/blockly/MotaAction.g4 +++ b/_server/blockly/MotaAction.g4 @@ -200,7 +200,7 @@ var loc = ', "loc": ['+Number_0+', '+Number_1+']'; if (Stair_List_0!=='loc')loc = ', "stair": "'+Stair_List_0+'"'; DirectionEx_List_0 = DirectionEx_List_0 && (', "direction": "'+DirectionEx_List_0+'"'); Int_0 = (Int_0!=='') ?(', "time": '+Int_0):''; -Bool_0 = Bool_0 ?'':(', "portalWithoutTrigger": false'); +Bool_0 = Bool_0 ?'':(', "ignoreChangeFloor": false'); var code = '{"floorId": "'+toFloorId+'"'+loc+DirectionEx_List_0+Int_0+Bool_0+' }\n'; return code; */; @@ -2006,7 +2006,7 @@ ActionParser.prototype.parse = function (obj,type) { if (!this.isset(obj.time)) obj.time=500; return MotaActionBlocks['changeFloor_m'].xmlText([ obj.floorType||'floorId',obj.floorId,obj.stair||'loc',obj.loc[0],obj.loc[1],obj.direction, - obj.time,!this.isset(obj.portalWithoutTrigger) + obj.time,!this.isset(obj.ignoreChangeFloor) ]); case 'level': diff --git a/_server/data.comment.js b/_server/data.comment.js index 4b6d6156..bad2978f 100644 --- a/_server/data.comment.js +++ b/_server/data.comment.js @@ -636,7 +636,7 @@ var data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = "_bool": "bool", "_data": "寻路算法是否经过血瓶;如果该项为false,则寻路算法会自动尽量绕过血瓶" }, - "portalWithoutTrigger": { + "ignoreChangeFloor": { "_leaf": true, "_type": "checkbox", "_bool": "bool", diff --git a/_server/functions.comment.js b/_server/functions.comment.js index 89181b22..8e961da5 100644 --- a/_server/functions.comment.js +++ b/_server/functions.comment.js @@ -43,11 +43,11 @@ var functions_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = "_lint": true, "_data": "转换楼层结束的事件\n此函数会在整个楼层切换完全结束后执行" }, - "addPoint": { + "beforeBattle": { "_leaf": true, "_type": "textarea", "_lint": true, - "_data": "加点事件" + "_data": "战斗前发生的事件" }, "afterBattle": { "_leaf": true, diff --git a/libs/control.js b/libs/control.js index 34e65e69..a3e706f5 100644 --- a/libs/control.js +++ b/libs/control.js @@ -486,6 +486,16 @@ control.prototype.stopAutomaticRoute = function () { core.deleteCanvas('route'); } +control.prototype.saveAndStopAutomaticRoute = function () { + var automaticRoute = core.status.automaticRoute; + if (automaticRoute.moveStepBeforeStop.length == 0) { + automaticRoute.moveStepBeforeStop = automaticRoute.autoStepRoutes.slice(automaticRoute.autoStep - 1); + if (automaticRoute.moveStepBeforeStop.length>=1) + automaticRoute.moveStepBeforeStop[0].step -= automaticRoute.movedStep; + } + this.stopAutomaticRoute(); +} + ////// 继续剩下的自动寻路操作 ////// control.prototype.continueAutomaticRoute = function () { // 此函数只应由events.afterOpenDoor和events.afterBattle调用 @@ -500,9 +510,10 @@ control.prototype.continueAutomaticRoute = function () { } ////// 清空剩下的自动寻路列表 ////// -control.prototype.clearContinueAutomaticRoute = function () { +control.prototype.clearContinueAutomaticRoute = function (callback) { core.deleteCanvas('route'); core.status.automaticRoute.moveStepBeforeStop=[]; + if (callback) callback(); } ////// 瞬间移动 ////// @@ -724,6 +735,11 @@ control.prototype.fillPosWithPoint = function (pos) { core.fillRect('ui', pos.x*32+12,pos.y*32+12,8,8, '#bfbfbf'); } +// 当前是否正在移动 +control.prototype.isMoving = function () { + return !core.status.heroStop || core.status.heroMoving > 0; +} + ////// 设置勇士的自动行走路线 ////// control.prototype.setAutoHeroMove = function (steps) { steps=steps||core.status.automaticRoute.autoStepRoutes; @@ -781,7 +797,7 @@ control.prototype.moveAction = function (callback) { core.status.automaticRoute.moveStepBeforeStop = []; core.status.automaticRoute.lastDirection = core.getHeroLoc('direction'); if (canMove) // 非箭头:触发 - core.trigger(x + core.utils.scan[direction].x, y + core.utils.scan[direction].y); + core.events._trigger(x + core.utils.scan[direction].x, y + core.utils.scan[direction].y); core.drawHero(direction, x, y); if (core.status.automaticRoute.moveStepBeforeStop.length==0) { @@ -822,11 +838,11 @@ control.prototype.moveAction = function (callback) { if (block!=null && block.block.event.trigger=='getItem' && !core.isset(core.floors[core.status.floorId].afterGetItem[nowx+","+nowy])) { hasTrigger = true; - core.trigger(nowx, nowy); + core.events._trigger(nowx, nowy); } core.checkBlock(); if (!hasTrigger && !core.status.gameOver) - core.trigger(nowx, nowy); + core.events._trigger(nowx, nowy); if (core.isset(callback)) callback(); }); } @@ -2023,7 +2039,7 @@ control.prototype.checkStatus = function (name, need, item) { core.drawTip("你没有" + core.material.items[name].name); return false; } - if (!core.status.heroStop) { + if (core.isMoving()) { core.drawTip("请先停止勇士行动"); return false; } diff --git a/libs/events.js b/libs/events.js index 33f1a0ad..7ef4ef98 100644 --- a/libs/events.js +++ b/libs/events.js @@ -50,6 +50,7 @@ events.prototype._startGame_start = function (hard, seed, route, callback) { core.setFlag('__rand__', seed); } else core.utils.__init_seed(); + this.setInitData(); core.clearMap('all'); core.deleteAllCanvas(); @@ -92,8 +93,8 @@ events.prototype._startGame_upload = function () { } ////// 不同难度分别设置初始属性 ////// -events.prototype.setInitData = function (hard) { - return this.eventdata.setInitData(hard); +events.prototype.setInitData = function () { + return this.eventdata.setInitData(); } ////// 游戏获胜事件 ////// @@ -248,47 +249,49 @@ events.prototype.doSystemEvent = function (type, data, callback) { } ////// 触发(x,y)点的事件 ////// -events.prototype.trigger = function (x, y) { - +events.prototype._trigger = function (x, y) { + // 如果正在自定义事件中,忽略 if (core.status.event.id == 'action') return; core.status.isSkiing = false; var block = core.getBlock(x, y); - if (block != null) { - block = block.block; - if (core.isset(block.event) && core.isset(block.event.trigger)) { - var noPass = block.event.noPass, trigger = block.event.trigger; - if (noPass) { - core.clearAutomaticRouteNode(x, y); - } - if (trigger == 'ski') core.status.isSkiing = true; + if (block == null) return; + block = block.block; + if (core.isset(block.event) && core.isset(block.event.trigger)) { + var noPass = block.event.noPass, trigger = block.event.trigger; + if (noPass) core.clearAutomaticRouteNode(x, y); + if (trigger == 'ski') core.status.isSkiing = true; - // 转换楼层能否穿透 - if (trigger=='changeFloor' && !noPass) { - var canCross = core.flags.portalWithoutTrigger; - if (core.isset(block.event.data) && core.isset(block.event.data.portalWithoutTrigger)) - canCross=block.event.data.portalWithoutTrigger; - if (canCross) { - if (core.isReplaying()) { - if (core.status.replay.toReplay[0]=='no') { - core.status.replay.toReplay.shift(); - core.status.route.push("no"); - return; - } - } - else if (core.status.automaticRoute.autoHeroMove || core.status.automaticRoute.autoStep=1)core.status.automaticRoute.moveStepBeforeStop[0].step-=core.status.automaticRoute.movedStep; - } - core.stopHero(); - core.stopAutomaticRoute(); - - if (!core.isset(id)) id = core.getBlockId(x, y); - if (!core.isset(id)) { - if (core.isset(callback)) callback(); - return; - } - + core.saveAndStopAutomaticRoute(); + id = id || core.getBlockId(x, y); + if (!core.isset(id)) return core.clearContinueAutomaticRoute(callback); // 非强制战斗 if (!core.enemys.canBattle(id, x, y) && !force && !core.isset(core.status.event.id)) { core.drawTip("你打不过此怪物!"); - core.clearContinueAutomaticRoute(); - if (core.isset(callback)) callback(); - return; + return core.clearContinueAutomaticRoute(callback); } + // 自动存档 + if (!core.isset(core.status.event.id)) core.autosave(true); + // 战前事件 + if (!this.beforeBattle(id, x, y)) + return core.clearContinueAutomaticRoute(callback); + // 战后事件 + this.afterBattle(id, x, y, callback); +} - if (!core.isset(core.status.event.id)) // 自动存档 - core.autosave(true); - - // ------ 支援技能 ------// - if (core.isset(x) && core.isset(y)) { - var index = x + "," + y, cache = (core.status.checkBlock.cache || {})[index] || {}, - guards = cache.guards || []; - if (guards.length>0) { - core.setFlag("__guards__"+x+"_"+y, guards); - var actions = []; - guards.forEach(function (g) { - core.push(actions, {"type": "jump", "from": [g[0],g[1]], "to": [x, y], - "time": 300, "keep": false, "async": true}); - }) - core.push(actions, [ - {"type": "waitAsync"}, - {"type": "trigger", "loc": [x,y]} - ]); - core.insertAction(actions); - return; - } - } - - core.events.afterBattle(id, x, y, callback); +////// 战斗前触发的事件 ////// +events.prototype.beforeBattle = function (enemyId, x, y) { + return this.eventdata.beforeBattle(enemyId, x, y) } ////// 战斗结束后触发的事件 ////// events.prototype.afterBattle = function (enemyId, x , y,callback) { - return this.eventdata.afterBattle(enemyId,x,y,callback); + return this.eventdata.afterBattle(enemyId, x, y, callback); +} + +events.prototype._sys_openDoor = function (data, callback) { + this.openDoor(data.event.id, data.x, data.y, true, callback); +} + +////// 开门 ////// +events.prototype.openDoor = function (id, x, y, needKey, callback) { + id = id || core.getBlockId(x, y); + core.saveAndStopAutomaticRoute(); + if (!this._openDoor_check(id, x, y, needKey)) return false; + core.playSound("door.mp3"); + this._openDoor_animate(id, x, y, callback); + return true; +} + +events.prototype._openDoor_check = function (id, x, y, needKey) { + // 是否存在门或暗墙 + if (!core.terrainExists(x, y, id) || !(id.endsWith("Door") || id.endsWith("Wall")) + || !core.isset(core.material.icons.animates[id])) { + core.clearContinueAutomaticRoute(); + return false; + } + + if (needKey && id.endsWith("Door")) { + var key = id.replace("Door", "Key"); + if (!core.hasItem(key)) { + if (key != "specialKey") + core.drawTip("你没有" + ((core.material.items[key]||{}).name||"钥匙")); + else core.drawTip("无法开启此门"); + core.clearContinueAutomaticRoute(); + return false; + } + core.autosave(true); + core.removeItem(key); + } + return true; +} + +events.prototype._openDoor_animate = function (id, x, y, callback) { + var door = core.material.icons.animates[id]; + var speed = id.endsWith("Door") ? 30 : 70; + + core.lockControl(); + core.status.replay.animate = true; + var state = 0; + var animate = window.setInterval(function () { + state++; + if (state == 4) { + clearInterval(animate); + core.removeBlock(x, y); + core.unLockControl(); + core.status.replay.animate = false; + core.events.afterOpenDoor(id, x, y, callback); + return; + } + core.clearMap('event', 32 * x, 32 * y, 32, 32); + core.drawImage('event', core.material.images.animates, 32 * state, 32 * door, 32, 32, 32 * x, 32 * y, 32, 32); + }, speed / core.status.replay.speed); +} + +////// 开一个门后触发的事件 ////// +events.prototype.afterOpenDoor = function (doorId, x, y, callback) { + return this.eventdata.afterOpenDoor(doorId,x,y,callback); } events.prototype._sys_getItem = function (data, callback) { @@ -355,7 +397,7 @@ events.prototype._sys_getItem = function (data, callback) { ////// 获得某个物品 ////// events.prototype.getItem = function (itemId, itemNum, itemX, itemY, callback) { - itemNum=itemNum||1; + itemNum = itemNum || 1; var itemCls = core.material.items[itemId].cls; core.items.getItemEffect(itemId, itemNum); core.removeBlock(itemX, itemY); @@ -370,106 +412,57 @@ events.prototype.getItem = function (itemId, itemNum, itemX, itemY, callback) { ////// 获得面前的物品(轻按) ////// events.prototype.getNextItem = function() { - if (!core.status.heroStop || !core.flags.enableGentleClick) return false; - - if (!core.canMoveHero()) return false; + if (core.isMoving() || !core.canMoveHero() || !core.flags.enableGentleClick) return false; var nextX = core.nextX(), nextY = core.nextY(); var block = core.getBlock(nextX, nextY); if (block==null) return false; if (block.block.event.trigger=='getItem') { - core.getItem(block.block.event.id, 1, nextX, nextY); core.status.route.push("getNext"); + this.getItem(block.block.event.id, 1, nextX, nextY); return true; } return false; } -events.prototype._sys_openDoor = function (data, callback) { - this.openDoor(data.event.id, data.x, data.y, true, callback); -} - -////// 开门 ////// -events.prototype.openDoor = function (id, x, y, needKey, callback) { - if (!core.isset(id)) id = core.getBlockId(x, y); - - // 是否存在门 - if (!core.terrainExists(x, y, id) || !(id.endsWith("Door") || id.endsWith("Wall")) - || !core.isset(core.material.icons.animates[id])) { - return false; - } - if (core.status.automaticRoute.moveStepBeforeStop.length==0) { - core.status.automaticRoute.moveStepBeforeStop=core.status.automaticRoute.autoStepRoutes.slice(core.status.automaticRoute.autoStep-1,core.status.automaticRoute.autoStepRoutes.length); - if (core.status.automaticRoute.moveStepBeforeStop.length>=1)core.status.automaticRoute.moveStepBeforeStop[0].step-=core.status.automaticRoute.movedStep; - } - - var speed = id.endsWith("Wall")?70:30; - - if (needKey && id.endsWith("Door")) { - var key = id.replace("Door", "Key"); - if (!core.hasItem(key)) { - if (key != "specialKey") - core.drawTip("你没有" + ((core.material.items[key]||{}).name||"钥匙")); - else core.drawTip("无法开启此门"); - core.clearContinueAutomaticRoute(); - return false; - } - core.autosave(true); - core.removeItem(key); - } - - // open - core.playSound("door.mp3"); - var state = 0; - var door = core.material.icons.animates[id]; - - core.lockControl(); - core.stopHero(); - core.stopAutomaticRoute(); - core.status.replay.animate=true; - core.removeGlobalAnimate(x,y); - var animate = window.setInterval(function () { - state++; - if (state == 4) { - clearInterval(animate); - core.removeBlock(x, y); - core.unLockControl(); - core.status.replay.animate=false; - core.events.afterOpenDoor(id,x,y,callback); - return; - } - core.clearMap('event', 32 * x, 32 * y, 32, 32); - core.drawImage('event', core.material.images.animates, 32 * state, 32 * door, 32, 32, 32 * x, 32 * y, 32, 32); - }, speed / core.status.replay.speed); - - return true; -} - -////// 开一个门后触发的事件 ////// -events.prototype.afterOpenDoor = function (doorId, x, y, callback) { - return this.eventdata.afterOpenDoor(doorId,x,y,callback); -} - events.prototype._sys_changeFloor = function (data, callback) { + data = data.event.data; var heroLoc = {}; - if (core.isset(data.event.data.loc)) - heroLoc = {'x': data.event.data.loc[0], 'y': data.event.data.loc[1]}; - if (core.isset(data.event.data.direction)) - heroLoc.direction = data.event.data.direction; + if (core.isset(data.loc)) + heroLoc = {'x': data.loc[0], 'y': data.loc[1]}; + if (core.isset(data.direction)) + heroLoc.direction = data.direction; if (core.status.event.id!='action') core.status.event.id=null; - core.changeFloor(data.event.data.floorId, data.event.data.stair, - heroLoc, data.event.data.time, callback); + core.changeFloor(data.floorId, data.stair, heroLoc, data.time, callback); } ////// 楼层切换 ////// events.prototype.changeFloor = function (floorId, stair, heroLoc, time, callback, fromLoad) { - - floorId = floorId || core.status.floorId; - if (!core.isset(floorId)) { - if (core.isset(callback)) callback(); + var info = this._changeFloor_getInfo(floorId, stair, heroLoc, time); + if (info == null) { + if (callback) callback(); return; } + info.fromLoad = fromLoad; + floorId = info.floorId; + core.dom.floorNameLabel.innerHTML = core.status.maps[floorId].title; + core.lockControl(); + core.stopAutomaticRoute(); + core.clearContinueAutomaticRoute(); + core.status.replay.animate=true; + + if (core.status.maps[floorId].canFlyTo && core.status.hero.flyRange.indexOf(floorId)<0) { + core.status.hero.flyRange.push(floorId); + core.status.hero.flyRange.sort(function (a, b) { + return core.floorIds.indexOf(a) - core.floorIds.indexOf(b); + }) + } + 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]; @@ -480,24 +473,29 @@ events.prototype.changeFloor = function (floorId, stair, heroLoc, time, callback if (index=100 && !core.isReplaying(); - + if (time<100) time = 0; time /= 20; - core.lockControl(); - core.stopHero(); - core.stopAutomaticRoute(); - core.clearContinueAutomaticRoute(); - core.status.replay.animate=true; - core.dom.floorNameLabel.innerHTML = core.status.maps[floorId].title; - if (!core.isset(stair) && !core.isset(heroLoc)) + + return { + floorId: floorId, + time: time, + heroLoc: core.clone(this._changeFloor_getHeroLoc(floorId, stair, heroLoc)) + }; +} + +events.prototype._changeFloor_getHeroLoc = function (floorId, stair, heroLoc) { + if (!core.isset(heroLoc)) heroLoc = core.clone(core.status.hero.loc); if (core.isset(stair)) { - if (!core.isset(heroLoc)) heroLoc={}; - + // 检查该层地图的 upFloor & downFloor if (core.isset(core.status.maps[floorId][stair])) { heroLoc.x = core.status.maps[floorId][stair][0]; heroLoc.y = core.status.maps[floorId][stair][1]; @@ -505,59 +503,55 @@ events.prototype.changeFloor = function (floorId, stair, heroLoc, time, callback else { var blocks = core.status.maps[floorId].blocks; for (var i in blocks) { - if (core.isset(blocks[i].event) && !blocks[i].disable && blocks[i].event.id === stair) { + if (!blocks[i].disable && blocks[i].event.id === stair) { heroLoc.x = blocks[i].x; heroLoc.y = blocks[i].y; break; } } } - if (!core.isset(heroLoc.x)) { - heroLoc.x=core.status.hero.loc.x; - heroLoc.y=core.status.hero.loc.y; - } - } - if (!core.isset(heroLoc.direction)) heroLoc.direction = core.status.hero.loc.direction; - - if (core.status.maps[floorId].canFlyTo && core.status.hero.flyRange.indexOf(floorId)<0) { - core.status.hero.flyRange.push(floorId); - core.status.hero.flyRange.sort(function (a, b) { - return core.floorIds.indexOf(a) - core.floorIds.indexOf(b); - }) } + ['x', 'y', 'direction'].forEach(function (name) { + if (!core.isset(heroLoc[name])) + heroLoc[name] = core.getHeroLoc(name); + }); + return heroLoc; +} +events.prototype._changeFloor_beforeChange = function (info, callback) { + core.playSound('floor.mp3'); + // 需要 setTimeout 执行,不然会出错 window.setTimeout(function () { - - var changing = function () { - - core.events.eventdata.changingFloor(floorId, heroLoc, fromLoad); - - var changed = function () { - core.unLockControl(); - core.status.replay.animate=false; - core.events.afterChangeFloor(floorId, fromLoad); - if (core.isset(callback)) callback(); - } - if (displayAnimate) { - core.hide(core.dom.floorMsgGroup, time/4, function () { - changed(); - }); - } - else { - changed(); - } - - } - core.playSound('floor.mp3'); - if (displayAnimate) { - core.show(core.dom.floorMsgGroup, time/2, function () { - changing(); + if (info.time == 0) + core.events._changeFloor_changing(info, callback); + else + core.show(core.dom.floorMsgGroup, info.time / 2, function () { + core.events._changeFloor_changing(info, callback); }); - } - else { - changing(); - } - }, 25); + }, 25) +} + +events.prototype._changeFloor_changing = function (info, callback) { + this.changingFloor(info.floorId, info.heroLoc, info.fromLoad); + + if (info.time == 0) + this._changeFloor_afterChange(info, callback); + else + core.hide(core.dom.floorMsgGroup, info.time / 4, function () { + core.events._changeFloor_afterChange(info, callback); + }); +} + +events.prototype._changeFloor_afterChange = function (info, callback) { + core.unLockControl(); + core.status.replay.animate=false; + core.events.afterChangeFloor(info.floorId, info.fromLoad); + + if (callback) callback(); +} + +events.prototype.changingFloor = function (floorId, heroLoc, fromLoad) { + this.eventdata.changingFloor(floorId, heroLoc, fromLoad); } ////// 转换楼层结束的事件 ////// @@ -566,6 +560,16 @@ events.prototype.afterChangeFloor = function (floorId, fromLoad) { return this.eventdata.afterChangeFloor(floorId, fromLoad); } +////// 是否到达过某个楼层 ////// +events.prototype.hasVisitedFloor = function (floorId) { + return core.getFlag("__visited__")[floorId] || false; +} + +////// 到达某楼层 ////// +events.prototype.visitFloor = function (floorId) { + core.getFlag("__visited__")[floorId] = true; +} + events.prototype._sys_passNet = function (data, callback) { this.passNet(data); if (callback) callback(); @@ -573,21 +577,8 @@ events.prototype._sys_passNet = function (data, callback) { ////// 经过一个路障 ////// events.prototype.passNet = function (data) { - // 有鞋子 if (core.hasItem('shoes')) return; - if (data.event.id=='lavaNet') { - // 血网 lavaNet 移动到 checkBlock 中处理 - /* - core.status.hero.hp -= core.values.lavaDamage; - if (core.status.hero.hp<=0) { - core.status.hero.hp=0; - core.updateStatusBar(); - core.events.lose(); - return; - } - core.drawTip('经过血网,生命-'+core.values.lavaDamage); - */ - } + // 血网 lavaNet 移动到 checkBlock 中处理 if (data.event.id=='poisonNet') { // 毒网 core.setFlag('debuff', 'poison'); core.insertAction('毒衰咒处理'); @@ -613,35 +604,26 @@ 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; + var direction = core.getHeroLoc('direction'), + nx = data.x + core.utils.scan[direction].x, ny = data.y + core.utils.scan[direction].y; - if (nx<0||nx>=core.bigmap.width||ny<0||ny>=core.bigmap.height) return; + // 检测能否推上去 + if (!core.canMoveHero() || !core.canMoveHero(data.x, data.y, direction)) return; + var nextId = core.getBlockId(nx, ny); + if (nextId != null && nextId != 'flower') return; - var block = core.getBlock(nx, ny, null, true); - if (block!=null && !(core.isset(block.block.event) && block.block.event.id=='flower')) - return; + core.setBlock(nextId==null?169:170, nx, ny); - if (block==null) { - core.status.thisMap.blocks.push(core.maps.initBlock(nx, ny, 169)); - block = core.getBlock(nx, ny); - } - else { - block.block.id=170; - block.block.event=core.maps.initBlock(null,null,170).event; - } - core.drawBlock(block.block); - - if (data.event.id=='box') { + if (data.event.id=='box') core.removeBlock(data.x, data.y); - } - else { - data.id=168; - data.event=core.maps.initBlock(null,null,168).event; - core.drawBlock(data); - } + else + core.setBlock(168, data.x, data.y); core.updateStatusBar(); + this._pushBox_moveHero(direction); +} +events.prototype._pushBox_moveHero = function (direction) { core.status.replay.animate = true; core.lockControl(); setTimeout(function () { @@ -655,8 +637,7 @@ events.prototype.pushBox = function (data) { core.replay(); } }); - }) - + }); } ////// 推箱子后的事件 ////// @@ -665,21 +646,14 @@ events.prototype.afterPushBox = function () { } events.prototype._sys_changeLight = function (data, callback) { - core.events.changeLight(data.x, data.y); + core.events.changeLight(data.event.id, data.x, data.y); if (callback) callback(); } ////// 改变亮灯(感叹号)的事件 ////// -events.prototype.changeLight = function(x, y) { - var block = core.getBlock(x, y); - if (block==null) return; - var index = block.index; - block = block.block; - if (block.event.id != 'light') return; - // 改变为dark - block.id = 166; - block.event = {'cls': 'terrains', 'id': 'darkLight', 'noPass': true}; - core.drawBlock(block); +events.prototype.changeLight = function(id, x, y) { + if (id != null && id != 'light') return; + core.setBlock(core.getNumberById('darkLight'), x, y); this.afterChangeLight(x,y); } diff --git a/libs/maps.js b/libs/maps.js index 82a40107..1d516e2b 100644 --- a/libs/maps.js +++ b/libs/maps.js @@ -1110,6 +1110,25 @@ maps.prototype.getBlockInfo = function (block) { return {number:number, id:id, cls:cls, image:image, posX:posX, posY:posY, height:height, faceIds:faceIds}; } +////// 搜索某个图块出现的所有位置 ////// +maps.prototype.searchBlock = function (id, floorId, showDisable) { + if (typeof id == 'number') id = this.initBlock(0, 0, id).event.id; + floorId = floorId || core.status.floorId; + var result = []; + if (floorId instanceof Array) { + floorId.forEach(function (floorId) { + result = result.concat(core.searchBlock(id, floorId, showDisable)); + }); + return result; + } + for (var i = 0; i < core.status.maps[floorId].blocks.length; ++i) { + var block = core.status.maps[floorId].blocks[i]; + if (block.event.id == id && (showDisable || !block.disable)) + result.push({floorId: floorId, index: i, block: block}); + } + return result; +} + // -------- 启用/禁用图块,楼层贴图 -------- // ////// 将某个块从禁用变成启用状态 ////// @@ -1215,6 +1234,26 @@ maps.prototype.removeBlockByIds = function (floorId, ids) { }); } +////// 将地图中所有某个图块替换成另一个图块 ////// +maps.prototype.replaceBlock = function (fromNumber, toNumber, floorId) { + floorId = floorId || core.status.floorId; + if (floorId instanceof Array) { + floorId.forEach(function (floorId) { + core.replaceBlock(fromNumber, toNumber, floorId); + }); + return; + } + var toBlock = this.initBlock(0, 0, toNumber, true); + core.status.maps[floorId].blocks.forEach(function (block) { + if (block.id == fromNumber) { + block.id = toNumber; + for (var one in toBlock.event) { + block.event[one] = core.clone(toBlock.event[one]); + } + } + }); +} + ////// 显示前景/背景地图 ////// maps.prototype.showBgFgMap = function (name, loc, floorId, callback) { this._triggerBgFgMap('show', name, loc, floorId, callback); diff --git a/libs/ui.js b/libs/ui.js index c00865ab..9a1d4b47 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -352,13 +352,11 @@ ui.prototype.getTitleAndIcon = function (content) { var number = core.maps.getNumberById(v); if (number>0) { var block = core.maps.initBlock(0,0,number,true); - if (core.isset(block.event)) { - var cls = block.event.cls; - image = core.material.images[cls]; - icon = core.material.icons[cls][v]; - iconHeight = block.event.height; - animate = block.event.animate; - } + var cls = block.event.cls; + image = core.material.images[cls]; + icon = core.material.icons[cls][v]; + iconHeight = block.event.height; + animate = block.event.animate; } }; diff --git a/libs/utils.js b/libs/utils.js index 22fa2a90..ee12e6f9 100644 --- a/libs/utils.js +++ b/libs/utils.js @@ -1003,7 +1003,7 @@ utils.prototype._export = function (floorIds) { // check monster x.forEach(function (t) { var block = core.maps.initBlock(null, null, t); - if (core.isset(block.event) && block.event.cls.indexOf("enemy")==0) { + if (block.event.cls.indexOf("enemy")==0) { monsterMap[t] = block.event.id; } }) diff --git a/project/data.js b/project/data.js index 5802ae43..cfecf74f 100644 --- a/project/data.js +++ b/project/data.js @@ -393,7 +393,7 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = "displayExtraDamage": true, "enableGentleClick": true, "potionWhileRouting": false, - "portalWithoutTrigger": true, + "ignoreChangeFloor": true, "canGoDeadZone": false, "enableMoveDirectly": true, "enableDisabledShop": true, diff --git a/project/functions.js b/project/functions.js index dead2159..4c8f9f6f 100644 --- a/project/functions.js +++ b/project/functions.js @@ -32,22 +32,22 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = core.material.items.shield5.cls = 'equips'; } }, - "setInitData": function (hard) { + "setInitData": function () { // 不同难度分别设置初始属性 - if (hard == 'Easy') { // 简单难度 + if (core.status.hard == 'Easy') { // 简单难度 core.setFlag('hard', 1); // 可以用flag:hard来获得当前难度 // 可以在此设置一些初始福利,比如设置初始生命值可以调用: // core.setStatus("hp", 10000); // 赠送一把黄钥匙可以调用 // core.setItem("yellowKey", 1); } - if (hard == 'Normal') { // 普通难度 + if (core.status.hard == 'Normal') { // 普通难度 core.setFlag('hard', 2); // 可以用flag:hard来获得当前难度 } - if (hard == 'Hard') { // 困难难度 + if (core.status.hard == 'Hard') { // 困难难度 core.setFlag('hard', 3); // 可以用flag:hard来获得当前难度 } - if (hard == 'Hell') { // 噩梦难度 + if (core.status.hard == 'Hell') { // 噩梦难度 core.setFlag('hard', 4); // 可以用flag:hard来获得当前难度 } @@ -55,6 +55,8 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = ["atk", "def", "mdef"].forEach(function (name) { core.setFlag("__" + name + "_buff__", 1); }); + // 设置已经到过的楼层 + core.setFlag("__visited__", {}); core.events.afterLoadData(); }, @@ -150,33 +152,50 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = // 转换楼层结束的事件;此函数会在整个楼层切换完全结束后再执行 // floorId是切换到的楼层;fromLoad若为true则代表是从读档行为造成的楼层切换 - // 如果是读档,则进行检查 + // 如果是读档,则进行检查(是否需要恢复事件) if (fromLoad) { core.events.recoverEvents(core.getFlag("__events__")); core.removeFlag("__events__"); - } - else { + } else { // 每次抵达楼层执行的事件 core.insertAction(core.floors[floorId].eachArrive); // 首次抵达楼层时执行的事件(后插入,先执行) - var visited = core.getFlag("__visited__", []); - if (visited.indexOf(floorId)===-1) { + if (!core.hasVisitedFloor(floorId)) { core.insertAction(core.floors[floorId].firstArrive); - visited.push(floorId); - core.setFlag("__visited__", visited); + core.visitFloor(floorId); } } }, - "addPoint": function (enemy) { - // 加点事件 - var point = enemy.point; - if (!core.flags.enableAddPoint || !core.isset(point) || point<=0) return []; + "beforeBattle": function (enemyId, x, y) { + // 战斗前触发的事件,可以加上一些战前特效(详见下面支援的例子) + // 此函数在“检测能否战斗和自动存档”【之后】执行。如果需要更早的战前事件,请在插件中覆重写 core.events.doSystemEvent 函数。 + // 返回true则将继续战斗,返回false将不再战斗。 - // 加点,返回一个choices事件 - // ----- 从V2.5.4开始,移动到“公共事件-加点事件”中 - core.setFlag('point', point); // 设置flag:point - return core.getCommonEvent('加点事件'); + // ------ 支援技能 ------ // + if (core.isset(x) && core.isset(y)) { + var index = x + "," + y, + cache = (core.status.checkBlock.cache || {})[index] || {}, + guards = cache.guards || []; + // 如果存在支援怪 + if (guards.length > 0) { + // 记录flag,当前要参与支援的怪物 + core.setFlag("__guards__" + x + "_" + y, guards); + var actions = []; + // 增加支援的特效动画(图块跳跃) + guards.forEach(function (g) { + core.push(actions, { "type": "jump", "from": [g[0], g[1]], "to": [x, y], "time": 300, "keep": false, "async": true }); + }); + core.push(actions, [ + { "type": "waitAsync" }, // 等待所有异步事件执行完毕 + { "type": "trigger", "loc": [x, y] } // 重要!重新触发本点事件(即重新触发战斗) + ]); + core.insertAction(actions); + return false; + } + } + + return true; }, "afterBattle": function (enemyId, x, y, callback) { // 战斗结束后触发的事件 @@ -192,7 +211,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = if (!core.isset((core.material.animates[equipAnimate] || {}).se)) core.playSound('attack.mp3'); // 强制战斗的战斗动画 - core.drawAnimate(equipAnimate, core.isset(x)?x:core.getHeroLoc('x'), core.isset(y)?y:core.getHeroLoc('y')); + core.drawAnimate(equipAnimate, core.isset(x) ? x : core.getHeroLoc('x'), core.isset(y) ? y : core.getHeroLoc('y')); var damage = core.enemys.getDamage(enemyId, x, y); if (damage == null) damage = core.status.hero.hp + 1; @@ -220,26 +239,24 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = } // 获得金币和经验 - var money = enemy.money; - guards.forEach(function (g) { - money += core.material.enemys[g[2]].money; - }); + var money = guards.reduce(function (curr, g) { + return curr + core.material.enemys[g[2]].money; + }, enemy.money); if (core.hasItem('coin')) money *= 2; if (core.hasFlag('curse')) money = 0; core.status.hero.money += money; core.status.hero.statistics.money += money; - var experience = enemy.experience; - guards.forEach(function (g) { - experience += core.material.enemys[g[2]].experience; - }) + + var experience = guards.reduce(function (curr, g) { + return curr + core.material.enemys[g[2]].experience; + }, enemy.experience); if (core.hasFlag('curse')) experience = 0; core.status.hero.experience += experience; core.status.hero.statistics.experience += experience; + var hint = "打败 " + enemy.name; - if (core.flags.enableMoney) - hint += ",金币+" + money; - if (core.flags.enableExperience) - hint += ",经验+" + experience; + if (core.flags.enableMoney) hint += ",金币+" + money; + if (core.flags.enableExperience) hint += ",经验+" + experience; core.drawTip(hint); // 事件的处理 @@ -263,7 +280,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = } // 仇恨属性:减半 if (core.flags.hatredDecrease && core.enemys.hasSpecial(special, 17)) { - core.setFlag('hatred', parseInt(core.getFlag('hatred', 0) / 2)); + core.setFlag('hatred', Math.floor(core.getFlag('hatred', 0) / 2)); } // 自爆 if (core.enemys.hasSpecial(special, 19)) { @@ -327,43 +344,42 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = if (core.isset(callback)) callback(); }, - "afterOpenDoor": function(doorId,x,y,callback) { + "afterOpenDoor": function (doorId, x, y, callback) { // 开一个门后触发的事件 - + var todo = []; if (core.isset(x) && core.isset(y)) { - var event = core.floors[core.status.floorId].afterOpenDoor[x+","+y]; + var event = core.floors[core.status.floorId].afterOpenDoor[x + "," + y]; if (core.isset(event)) { core.unshift(todo, event); } } - if (todo.length>0) { - core.events.insertAction(todo,x,y); + if (todo.length > 0) { + core.events.insertAction(todo, x, y); } if (core.status.event.id == null) { core.continueAutomaticRoute(); - } - else { + } else { core.clearContinueAutomaticRoute(); } if (core.isset(callback)) callback(); }, - "afterGetItem": function(itemId,x,y,callback) { + "afterGetItem": function (itemId, x, y, callback) { // 获得一个道具后触发的事件 core.playSound('item.mp3'); var todo = []; if (core.isset(x) && core.isset(y)) { - var event = core.floors[core.status.floorId].afterGetItem[x+","+y]; + var event = core.floors[core.status.floorId].afterGetItem[x + "," + y]; if (core.isset(event)) { core.unshift(todo, event); } } - if (todo.length>0) { - core.events.insertAction(todo,x,y); + if (todo.length > 0) { + core.events.insertAction(todo, x, y); } if (core.isset(callback)) callback(); @@ -374,17 +390,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = }, "afterPushBox": function () { // 推箱子后的事件 - - var noBoxLeft = function () { - // 地图上是否还存在未推到的箱子,如果不存在则返回true,存在则返回false - for (var i=0;i