From ef5aa25047e36cceab0216779a297098d7a96890 Mon Sep 17 00:00:00 2001 From: oc Date: Mon, 18 Mar 2019 00:01:18 +0800 Subject: [PATCH] automaticRoute & autoMove --- _docs/personalization.md | 2 +- _server/functions.comment.js | 11 +- libs/actions.js | 3 +- libs/control.js | 334 +++++++++++++---------------------- libs/items.js | 4 +- libs/maps.js | 69 ++++++++ libs/ui.js | 2 +- project/functions.js | 67 +++++-- 8 files changed, 251 insertions(+), 241 deletions(-) diff --git a/_docs/personalization.md b/_docs/personalization.md index c83c7eaa..f960eed9 100644 --- a/_docs/personalization.md +++ b/_docs/personalization.md @@ -972,7 +972,7 @@ this.getAchievements = function () { - **`flag:__color__`**, **`flag:__weather__`**, **`flag:__volume__`**: 当前的画面色调、天气和音量。 - **`flag:__events__`**: 当前保存的事件列表,读档时会恢复(适用于在事件中存档) - **`flag:textAttribute`**, **`flag:globalAttribute`**, **`flag:globalFlags`**: 当前的剧情文本属性,当前的全局属性,当前的全局开关。 -- **`flag:cannotMoveDirectly`**, **`flag:clickMove`**: 当前是否不允许瞬间移动,当前用户是否开启了单击瞬移。 +- **`flag:cannotMoveDirectly`**, **`flag:__noClickMove__`**: 当前是否不允许瞬间移动,当前用户是否开启了单击瞬移。 - **`flag:hideStatusBar`**, **`flag:showToolbox`**: 是否隐藏状态栏,是否显示工具栏。 - **`flag:debug`**, **`flag:__consoleOpened__`**: 当前是否开启了调试模式,是否开启了控制台。 - **`flag:__seed__`**, **`flag:__rand__`**: 伪随机数生成种子和当前的状态 diff --git a/_server/functions.comment.js b/_server/functions.comment.js index bf25ed95..af73b831 100644 --- a/_server/functions.comment.js +++ b/_server/functions.comment.js @@ -105,7 +105,6 @@ var functions_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = } }, "enemys": { - "_type": "object", "_data": { "getSpecials": { @@ -135,7 +134,6 @@ var functions_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = } }, "actions": { - "_type": "object", "_data": { "onKeyUp": { @@ -147,7 +145,6 @@ var functions_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = } }, "control": { - "_type": "object", "_data": { "flyTo": { @@ -173,11 +170,16 @@ var functions_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = "_type": "textarea", "_lint": true, "_data": "勇士每走一步的操作" + }, + "moveDirectly": { + "_leaf": true, + "_type": "textarea", + "_lint": true, + "_data": "瞬间移动" } } }, "ui": { - "_type": "object", "_data": { "drawStatusBar": { @@ -201,7 +203,6 @@ var functions_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = } }, "plugins": { - "_type": "object", "_data": { "parallelDo": { diff --git a/libs/actions.js b/libs/actions.js index 045cac89..c7e5fc70 100644 --- a/libs/actions.js +++ b/libs/actions.js @@ -1789,7 +1789,8 @@ actions.prototype._clickSwitchs = function (x, y) { core.ui.drawSwitchs(); break; case 6: - core.setFlag('clickMove', !core.getFlag('clickMove', true)); + if (core.hasFlag('__noClickMove__')) core.removeFlag('__noClickMove__'); + else core.setFlag('__noClickMove__', true); core.ui.drawSwitchs(); break; case 7: diff --git a/libs/control.js b/libs/control.js index 570f9946..ad816cdc 100644 --- a/libs/control.js +++ b/libs/control.js @@ -374,20 +374,16 @@ control.prototype._initStatistics = function (totalTime) { } } - -/////////////////////// 寻路算法 & 人物行走控制 /////////////////////// +// ------ 自动寻路,人物行走 ------ // ////// 清除自动寻路路线 ////// control.prototype.clearAutomaticRouteNode = function (x, y) { - if (core.status.event.id==null) - core.clearMap('route', x * 32 + 5 - core.status.automaticRoute.offsetX, y * 32 + 5 - core.status.automaticRoute.offsetY, 27, 27); + core.clearMap('route', x * 32 + 5 - core.status.automaticRoute.offsetX, y * 32 + 5 - core.status.automaticRoute.offsetY, 27, 27); } ////// 停止自动寻路操作 ////// control.prototype.stopAutomaticRoute = function () { - if (!core.status.played) { - return; - } + if (!core.status.played) return; core.status.automaticRoute.autoHeroMove = false; core.status.automaticRoute.autoStep = 0; core.status.automaticRoute.destStep = 0; @@ -401,6 +397,7 @@ control.prototype.stopAutomaticRoute = function () { core.deleteCanvas('route'); } +////// 保存剩下的寻路,并停止 ////// control.prototype.saveAndStopAutomaticRoute = function () { var automaticRoute = core.status.automaticRoute; if (automaticRoute.moveStepBeforeStop.length == 0) { @@ -431,52 +428,33 @@ control.prototype.clearContinueAutomaticRoute = function (callback) { if (callback) callback(); } -////// 瞬间移动 ////// -control.prototype.moveDirectly = function (destX, destY) { - var ignoreSteps = core.canMoveDirectly(destX, destY); - if (ignoreSteps>=0) { - core.clearMap('hero'); - var lastDirection = core.status.route[core.status.route.length-1]; - if (['left', 'right', 'up', 'down'].indexOf(lastDirection)>=0) - core.setHeroLoc('direction', lastDirection); - core.setHeroLoc('x', destX); - core.setHeroLoc('y', destY); - core.drawHero(); - core.status.route.push("move:"+destX+":"+destY); - core.status.hero.statistics.moveDirectly++; - core.status.hero.statistics.ignoreSteps+=ignoreSteps; - return true; - } - return false; -} - -////// 尝试瞬间移动 ////// -control.prototype.tryMoveDirectly = function (destX, destY) { - if (Math.abs(core.getHeroLoc('x')-destX)+Math.abs(core.getHeroLoc('y')-destY)<=1) - return false; - var canMoveArray = core.maps.generateMovableArray(); - var testMove = function (dx, dy, dir) { - if (dx<0 || dx>=core.bigmap.width|| dy<0 || dy>=core.bigmap.height) return false; - if (core.isset(dir) && !core.inArray(canMoveArray[dx][dy],dir)) return false; - if (core.control.moveDirectly(dx, dy)) { - if (core.isset(dir)) core.moveHero(dir, function() {}); - return true; - } - return false; - } - return testMove(destX,destY) || testMove(destX-1, destY, "right") || testMove(destX,destY-1,"down") - || testMove(destX,destY+1,"up") || testMove(destX+1,destY,"left"); +////// 显示离散的寻路点 ////// +control.prototype.fillPosWithPoint = function (pos) { + core.fillRect('ui', pos.x*32+12,pos.y*32+12,8,8, '#bfbfbf'); } ////// 设置自动寻路路线 ////// control.prototype.setAutomaticRoute = function (destX, destY, stepPostfix) { - if (!core.status.played || core.status.lockControl) { - return; - } - // 正在寻路中 + if (!core.status.played || core.status.lockControl) return; + if (this._setAutomaticRoute_isMoving(destX, destY)) return; + if (this._setAutomaticRoute_isTurning(destX, destY, stepPostfix)) return; + if (this._setAutomaticRoute_clickMoveDirectly(destX, destY, stepPostfix)) return; + // 找寻自动寻路路线 + var moveStep = core.automaticRoute(destX, destY).concat(stepPostfix); + if (moveStep.length == 0) return core.deleteCanvas('route'); + core.status.automaticRoute.destX=destX; + core.status.automaticRoute.destY=destY; + this._setAutomaticRoute_drawRoute(moveStep); + this._setAutomaticRoute_setAutoSteps(moveStep); + // 立刻移动 + core.setAutoHeroMove(); +} + +control.prototype._setAutomaticRoute_isMoving = function (destX, destY) { if (core.status.automaticRoute.autoHeroMove) { var lastX = core.status.automaticRoute.destX, lastY=core.status.automaticRoute.destY; core.stopAutomaticRoute(); + // 双击瞬移 if (lastX==destX && lastY==destY) { core.status.automaticRoute.moveDirectly = true; setTimeout(function () { @@ -486,8 +464,12 @@ control.prototype.setAutomaticRoute = function (destX, destY, stepPostfix) { core.status.automaticRoute.moveDirectly = false; }, core.values.moveSpeed || 100); } - return; + return true; } + return false; +} + +control.prototype._setAutomaticRoute_isTurning = function (destX, destY, stepPostfix) { if (destX == core.status.hero.loc.x && destY == core.status.hero.loc.y && stepPostfix.length==0) { if (core.timeout.turnHeroTimeout==null) { core.timeout.turnHeroTimeout = setTimeout(function() { @@ -501,27 +483,23 @@ control.prototype.setAutomaticRoute = function (destX, destY, stepPostfix) { core.timeout.turnHeroTimeout = null; core.getNextItem(); } - return; + return true; } + if (core.timeout.turnHeroTimeout!=null) return true; + return false; +} - if (core.timeout.turnHeroTimeout!=null) return; - +control.prototype._setAutomaticRoute_clickMoveDirectly = function (destX, destY, stepPostfix) { // 单击瞬间移动 if (core.status.heroStop && core.status.heroMoving==0) { - if (stepPostfix.length<=1 && core.getFlag('clickMove', true) && core.control.tryMoveDirectly(destX, destY)) - return; + if (stepPostfix.length<=1 && !core.hasFlag('__noClickMove__') && core.control.tryMoveDirectly(destX, destY)) + return true; } + return false; +} - var moveStep = core.automaticRoute(destX, destY).concat(stepPostfix); - if (moveStep.length == 0) { - core.deleteCanvas('route'); - return; - } - - core.status.automaticRoute.destX=destX; - core.status.automaticRoute.destY=destY; - - // 计算绘制区域的宽高 +control.prototype._setAutomaticRoute_drawRoute = function (moveStep) { + // 计算绘制区域的宽高,并尽可能小的创建route层 var sx = core.bigmap.width * 32, sy = core.bigmap.height * 32, dx = 0, dy = 0; moveStep.forEach(function (t) { sx = Math.min(sx, t.x * 32); dx = Math.max(dx, t.x * 32); @@ -547,7 +525,9 @@ control.prototype.setAutomaticRoute = function (destX, destY, stepPostfix) { ctx.stroke(); } } +} +control.prototype._setAutomaticRoute_setAutoSteps = function (moveStep) { // 路线转autoStepRoutes var step = 0, currStep = null; moveStep.forEach(function (t) { @@ -556,111 +536,17 @@ control.prototype.setAutomaticRoute = function (destX, destY, stepPostfix) { step++; else { core.status.automaticRoute.autoStepRoutes.push({'direction': currStep, 'step': step}); - step = 1; + step = 1; } currStep = dir; }); core.status.automaticRoute.autoStepRoutes.push({'direction': currStep, 'step': step}); - - // 立刻移动 - core.setAutoHeroMove(); -} - -////// 自动寻路算法,找寻最优路径 ////// -control.prototype.automaticRoute = function (destX, destY) { - var fw = core.bigmap.width, fh = core.bigmap.height; - var startX = core.getHeroLoc('x'); - var startY = core.getHeroLoc('y'); - if (destX == startX && destY == startY) return []; - - var route = []; - var queue = new PriorityQueue({comparator: function (a,b) { - return a.depth - b.depth; - }}); - var ans = []; - - var canMoveArray = core.maps.generateMovableArray(); - - route[startX + fw * startY] = ''; - queue.queue({depth: 0, x: startX, y: startY}); - while (queue.length!=0) { - var curr = queue.dequeue(); - var deep = curr.depth, nowX = curr.x, nowY = curr.y; - - for (var direction in core.utils.scan) { - if (!core.inArray(canMoveArray[nowX][nowY], direction)) - continue; - - var nx = nowX + core.utils.scan[direction].x; - var ny = nowY + core.utils.scan[direction].y; - if (nx<0 || nx>=fw || ny<0 || ny>=fh) continue; - - var nid = nx + fw * ny; - - if (core.isset(route[nid])) continue; - - var deepAdd=1; - var nextId, nextBlock = core.getBlock(nx,ny); - if (nextBlock!=null){ - nextId = nextBlock.block.event.id; - // 绕过亮灯(因为只有一次通行机会很宝贵) - if(nextId == "light") deepAdd=100; - // 绕过路障 - // if (nextId.substring(nextId.length-3)=="Net") deepAdd=core.values.lavaDamage*10; - // 绕过血瓶 - if (!core.flags.potionWhileRouting && nextId.substring(nextId.length-6)=="Potion") deepAdd+=20; - // 绕过传送点 - if (nextBlock.block.event.trigger == 'changeFloor') deepAdd+=10; - } - deepAdd+=core.status.checkBlock.damage[nid]*10; - // 绕过捕捉 - if ((core.status.checkBlock.ambush||[])[nid]) - deepAdd += 10000; - - if (nx == destX && ny == destY) { - route[nid] = direction; - break; - } - if (core.noPass(nx, ny)) - continue; - - route[nid] = direction; - queue.queue({depth: deep+deepAdd, x: nx, y: ny}); - } - if (core.isset(route[destX + fw * destY])) break; - } - if (!core.isset(route[destX + fw * destY])) { - return []; - } - - var nowX = destX, nowY = destY; - while (nowX != startX || nowY != startY) { - var dir = route[nowX + fw * nowY]; - ans.push({'direction': dir, 'x': nowX, 'y': nowY}); - nowX -= core.utils.scan[dir].x; - nowY -= core.utils.scan[dir].y; - } - - ans.reverse(); - return ans; -} - -////// 显示离散的寻路点 ////// -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; - if (steps.length == 0) { - return; - } + if (steps.length == 0) return; core.status.automaticRoute.autoStepRoutes=steps; core.status.automaticRoute.autoHeroMove = true; core.status.automaticRoute.autoStep = 1; @@ -670,35 +556,30 @@ control.prototype.setAutoHeroMove = function (steps) { ////// 设置行走的效果动画 ////// control.prototype.setHeroMoveInterval = function (direction, x, y, callback) { - if (core.status.heroMoving>0) { - return; - } + if (core.status.heroMoving > 0) return; core.status.heroMoving=1; var toAdd = 1; - if (core.status.replay.speed>3) - toAdd = 2; - if (core.status.replay.speed>6) - toAdd = 4; - if (core.status.replay.speed>12) - toAdd = 8; + if (core.status.replay.speed>3) toAdd = 2; + if (core.status.replay.speed>6) toAdd = 4; + if (core.status.replay.speed>12) toAdd = 8; core.interval.heroMoveInterval = window.setInterval(function () { core.status.heroMoving+=toAdd; if (core.status.heroMoving>=8) { - core.setHeroLoc('x', x+core.utils.scan[direction].x, true); - core.setHeroLoc('y', y+core.utils.scan[direction].y, true); - core.control.updateFollowers(); - core.moveOneStep(); - core.clearMap('hero'); - core.drawHero(direction); clearInterval(core.interval.heroMoveInterval); core.status.heroMoving = 0; - if (core.isset(callback)) callback(); + core.moveOneStep(x + core.utils.scan[direction].x, y + core.utils.scan[direction].y); + if (callback) callback(); } }, (core.values.moveSpeed||100) / 8 * toAdd / core.status.replay.speed); } +////// 每移动一格后执行的事件 ////// +control.prototype.moveOneStep = function(x, y) { + return this.controldata.moveOneStep(x, y); +} + ////// 实际每一步的行走过程 ////// control.prototype.moveAction = function (callback) { if (core.status.heroMoving>0) return; @@ -763,22 +644,6 @@ control.prototype.moveAction = function (callback) { } } -////// 转向 ////// -control.prototype.turnHero = function(direction) { - if (core.isset(direction)) { - core.setHeroLoc('direction', direction); - core.drawHero(); - core.status.route.push("turn:"+direction); - return; - } - if (core.status.hero.loc.direction == 'up') core.status.hero.loc.direction = 'right'; - else if (core.status.hero.loc.direction == 'right') core.status.hero.loc.direction = 'down'; - else if (core.status.hero.loc.direction == 'down') core.status.hero.loc.direction = 'left'; - else if (core.status.hero.loc.direction == 'left') core.status.hero.loc.direction = 'up'; - core.drawHero(); - core.status.route.push("turn"); -} - ////// 让勇士开始移动 ////// control.prototype.moveHero = function (direction, callback) { // 如果正在移动,直接return @@ -822,6 +687,51 @@ control.prototype.moveHero = function (direction, callback) { } } +////// 当前是否正在移动 ////// +control.prototype.isMoving = function () { + return !core.status.heroStop || core.status.heroMoving > 0; +} + +////// 停止勇士的一切行动,等待勇士行动结束后,再执行callback ////// +control.prototype.waitHeroToStop = function(callback) { + var lastDirection = core.status.automaticRoute.lastDirection; + core.stopAutomaticRoute(); + core.clearContinueAutomaticRoute(); + if (core.isset(callback)) { + core.status.replay.animate=true; + core.lockControl(); + core.status.automaticRoute.moveDirectly = false; + setTimeout(function(){ + core.status.replay.animate=false; + if (core.isset(lastDirection)) + core.setHeroLoc('direction', lastDirection); + core.drawHero(); + callback(); + }, 30); + } +} + +////// 停止勇士的移动状态 ////// +control.prototype.stopHero = function () { + core.status.heroStop = true; +} + +////// 转向 ////// +control.prototype.turnHero = function(direction) { + if (core.isset(direction)) { + core.setHeroLoc('direction', direction); + core.drawHero(); + core.status.route.push("turn:"+direction); + return; + } + if (core.status.hero.loc.direction == 'up') core.status.hero.loc.direction = 'right'; + else if (core.status.hero.loc.direction == 'right') core.status.hero.loc.direction = 'down'; + else if (core.status.hero.loc.direction == 'down') core.status.hero.loc.direction = 'left'; + else if (core.status.hero.loc.direction == 'left') core.status.hero.loc.direction = 'up'; + core.drawHero(); + core.status.route.push("turn"); +} + /////// 使用事件让勇士移动。这个函数将不会触发任何事件 ////// control.prototype.eventMoveHero = function(steps, time, callback) { time = time || core.values.moveSpeed || 100; @@ -949,33 +859,27 @@ control.prototype.jumpHero = function (ex, ey, time, callback) { core.animateFrame.asyncId[animate] = true; } -////// 每移动一格后执行的事件 ////// -control.prototype.moveOneStep = function() { - return this.controldata.moveOneStep(); +////// 瞬间移动 ////// +control.prototype.moveDirectly = function (destX, destY) { + return this.controldata.moveDirectly(destX, destY); } -////// 停止勇士的一切行动,等待勇士行动结束后,再执行callback ////// -control.prototype.waitHeroToStop = function(callback) { - var lastDirection = core.status.automaticRoute.lastDirection; - core.stopAutomaticRoute(); - core.clearContinueAutomaticRoute(); - if (core.isset(callback)) { - core.status.replay.animate=true; - core.lockControl(); - core.status.automaticRoute.moveDirectly = false; - setTimeout(function(){ - core.status.replay.animate=false; - if (core.isset(lastDirection)) - core.setHeroLoc('direction', lastDirection); - core.drawHero(); - callback(); - }, 30); +////// 尝试瞬间移动 ////// +control.prototype.tryMoveDirectly = function (destX, destY) { + if (Math.abs(core.getHeroLoc('x')-destX)+Math.abs(core.getHeroLoc('y')-destY)<=1) + return false; + var canMoveArray = core.maps.generateMovableArray(); + var testMove = function (dx, dy, dir) { + if (dx<0 || dx>=core.bigmap.width|| dy<0 || dy>=core.bigmap.height) return false; + if (core.isset(dir) && !core.inArray(canMoveArray[dx][dy],dir)) return false; + if (core.control.moveDirectly(dx, dy)) { + if (core.isset(dir)) core.moveHero(dir, function() {}); + return true; + } + return false; } -} - -////// 停止勇士的移动状态 ////// -control.prototype.stopHero = function () { - core.status.heroStop = true; + return testMove(destX,destY) || testMove(destX-1, destY, "right") || testMove(destX,destY-1,"down") + || testMove(destX,destY+1,"up") || testMove(destX+1,destY,"left"); } ////// 设置画布偏移 @@ -1038,7 +942,7 @@ control.prototype.drawHero = function (direction, x, y, status, offset) { core.clearAutomaticRouteNode(x+dx, y+dy); - core.clearMap('hero', x * 32 - core.bigmap.offsetX - 32, y * 32 - core.bigmap.offsetY - 32, 96, 96); + core.clearMap('hero', x * 32 - core.bigmap.offsetX - 32, y * 32 - core.bigmap.offsetY - 64, 96, 128); var heroIconArr = core.material.icons.hero; var drawObjs = []; diff --git a/libs/items.js b/libs/items.js index ace9bb3b..e61c23f9 100644 --- a/libs/items.js +++ b/libs/items.js @@ -156,7 +156,7 @@ items.prototype.canUseItem = function (itemId) { ////// 获得某个物品的个数 ////// items.prototype.itemCount = function (itemId) { - if (!core.material.items[itemId]) return 0; + if (!core.material.items[itemId] || !core.isPlaying()) return 0; var itemCls = core.material.items[itemId].cls; if (itemCls == "items") return 0; return core.status.hero.items[itemCls][itemId] || 0; @@ -169,7 +169,7 @@ items.prototype.hasItem = function (itemId) { ////// 是否装备某件装备 ////// items.prototype.hasEquip = function (itemId) { - if (!(core.material.items[itemId] || {}).equip) return null; + if (!(core.material.items[itemId] || {}).equip || !core.isPlaying()) return null; for (var i in core.status.hero.equipment) if (core.status.hero.equipment[i] == itemId) diff --git a/libs/maps.js b/libs/maps.js index de5b1d82..50fb037c 100644 --- a/libs/maps.js +++ b/libs/maps.js @@ -505,6 +505,75 @@ maps.prototype._canMoveDirectly_checkNextPoint = function (blocksObj, x, y) { return true; } +////// 自动寻路找寻最优路径 ////// +maps.prototype.automaticRoute = function (destX, destY) { + var startX = core.getHeroLoc('x'), startY = core.getHeroLoc('y'); + if (destX == startX && destY == startY) return []; + // BFS找寻最短路径 + var route = this._automaticRoute_bfs(startX, startY, destX, destY); + if (route[destX+","+destY] == null) return []; + // 路径数组转换 + var ans = [], nowX = destX, nowY = destY; + while (nowX != startX || nowY != startY) { + var dir = route[nowX + "," + nowY]; + ans.push({'direction': dir, 'x': nowX, 'y': nowY}); + nowX -= core.utils.scan[dir].x; + nowY -= core.utils.scan[dir].y; + } + ans.reverse(); + return ans; +} + +maps.prototype._automaticRoute_bfs = function (startX, startY, destX, destY) { + var route = {}, canMoveArray = this.generateMovableArray(); + // 使用优先队列 + var queue = new PriorityQueue({comparator: function (a,b) { return a.depth - b.depth; }}); + route[startX + "," + startY] = ''; + queue.queue({depth: 0, x: startX, y: startY}); + while (queue.length!=0) { + var curr = queue.dequeue(), deep = curr.depth, nowX = curr.x, nowY = curr.y; + for (var direction in core.utils.scan) { + if (!core.inArray(canMoveArray[nowX][nowY], direction)) continue; + var nx = nowX + core.utils.scan[direction].x; + var ny = nowY + core.utils.scan[direction].y; + if (nx<0 || nx>=core.bigmap.width || ny<0 || ny>=core.bigmap.height || route[nx+","+ny] != null) continue; + // 重点 + if (nx == destX && ny == destY) { + route[nx+","+ny] = direction; + break; + } + // 不可通行 + if (core.noPass(nx, ny)) continue; + route[nx+","+ny] = direction; + queue.queue({depth: deep + this._automaticRoute_deepAdd(nx, ny), x: nx, y: ny}); + } + if (route[destX+","+destY] != null) break; + } + return route; +} + +maps.prototype._automaticRoute_deepAdd = function (x, y) { + // 判定每个可通行点的损耗值,越高越应该绕路 + var deepAdd = 1; + var block = core.getBlock(x,y); + if (block != null){ + var id = block.block.event.id; + // 绕过亮灯 + if (id == "light") deepAdd += 100; + // 绕过路障 + if (id.endsWith("Net")) deepAdd += 100; + // 绕过血瓶 + if (!core.flags.potionWhileRouting && id.endsWith("Potion")) deepAdd += 100; + // 绕过传送点 + // if (nextBlock.block.event.trigger == 'changeFloor') deepAdd+=10; + } + // 绕过存在伤害的地方 + deepAdd += core.status.checkBlock.damage[x+","+y] * 100; + // 绕过捕捉 + if ((core.status.checkBlock.ambush||[])[x+","+y]) deepAdd += 1000; + return deepAdd; +} + // -------- 绘制地图,各层图块,楼层贴图,Autotile -------- // ////// 绘制一个图块 ////// diff --git a/libs/ui.js b/libs/ui.js index 6b381798..f7c437f8 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -1155,7 +1155,7 @@ ui.prototype.drawSwitchs = function() { "临界显伤: "+(core.flags.displayCritical ? "[ON]" : "[OFF]"), "领域显伤: "+(core.flags.displayExtraDamage ? "[ON]" : "[OFF]"), "新版存档: "+(core.platform.useLocalForage ? "[ON]":"[OFF]"), - "单击瞬移: "+(core.getFlag('clickMove', true) ? "[ON]":"[OFF]"), + "单击瞬移: "+(!core.hasFlag("__noClickMove__") ? "[ON]":"[OFF]"), "拓展键盘: "+(core.platform.extendKeyboard ? "[ON]":"[OFF]"), "返回主菜单" ]; diff --git a/project/functions.js b/project/functions.js index 514993d1..d95259e8 100644 --- a/project/functions.js +++ b/project/functions.js @@ -1156,26 +1156,61 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = } } }, - "moveOneStep": function () { - // 勇士每走一步后执行的操作 - core.status.hero.steps++; - // 中毒状态:扣血 - if (core.hasFlag('poison')) { - core.status.hero.statistics.poisonDamage += core.values.poisonDamage; - core.status.hero.hp -= core.values.poisonDamage; - if (core.status.hero.hp<=0) { - core.status.hero.hp=0; - core.updateStatusBar(); - core.events.lose(); - return; - } - core.updateStatusBar(); - } - // 备注:瞬间移动不会执行该函数。如果要控制能否瞬间移动有三种方法: + "moveOneStep": function (x, y) { + // 勇士每走一步后执行的操作,x,y为要移动到的坐标。 + // 这个函数执行在“刚走完”的时候,即还没有检查该点的事件和领域伤害等。 + // 请注意:瞬间移动不会执行该函数。如果要控制能否瞬间移动有三种方法: // 1. 将全塔属性中的cannotMoveDirectly这个开关勾上,即可在全塔中全程禁止使用瞬移。 // 2, 将楼层属性中的cannotMoveDirectly这个开关勾上,即禁止在该层楼使用瞬移。 // 3. 将flag:cannotMoveDirectly置为true,即可使用flag控制在某段剧情范围内禁止瞬移。 + // 设置当前坐标,增加步数 + core.setHeroLoc('x', x, true); + core.setHeroLoc('y', y, true); + core.status.hero.steps++; + // 更新跟随者状态,并绘制 + core.updateFollowers(); + core.drawHero(); + // 检查中毒状态的扣血和死亡 + if (core.hasFlag('poison')) { + core.status.hero.statistics.poisonDamage += core.values.poisonDamage; + core.status.hero.hp -= core.values.poisonDamage; + if (core.status.hero.hp <= 0) { + core.status.hero.hp = 0; + core.updateStatusBar(); + core.events.lose(); + return; + } + } + // 如需强行终止行走可以在这里条件判定: + // core.stopAutomaticRoute(); + + core.updateStatusBar(); +}, + "moveDirectly": function (x, y) { + // 瞬间移动;x,y为要瞬间移动的点 + // 返回true代表成功瞬移,false代表没有成功瞬移 + + // 判定能否瞬移到该点 + var ignoreSteps = core.canMoveDirectly(x, y); + if (ignoreSteps >= 0) { + core.clearMap('hero'); + // 获得勇士最后的朝向 + var lastDirection = core.status.route[core.status.route.length - 1]; + if (['left', 'right', 'up', 'down'].indexOf(lastDirection) >= 0) + core.setHeroLoc('direction', lastDirection); + // 设置坐标,并绘制 + core.setHeroLoc('x', x); + core.setHeroLoc('y', y); + core.drawHero(); + // 记录录像 + core.status.route.push("move:" + x + ":" + y); + // 统计信息 + core.status.hero.statistics.moveDirectly++; + core.status.hero.statistics.ignoreSteps += ignoreSteps; + return true; + } + return false; } }, "ui": {