enemys.js V2.6 & __atk_buff__
This commit is contained in:
parent
4b68df329d
commit
3fb6d09796
366
_docs/_api.md
366
_docs/_api.md
@ -1,366 +0,0 @@
|
||||
# 附录:API列表
|
||||
|
||||
?> 目前版本**v2.3.3**,上次更新时间:* {docsify-updated} *
|
||||
|
||||
所有系统支持的API都列在了这里。所有可能被用到的API都在前面用\*标记。
|
||||
|
||||
可以在chrome浏览器的控制台中(`ctrl+shift+I`,找到Console)中直接进行调用,以查看效果。
|
||||
|
||||
!> **`main.js`:游戏入口,所有其他JS文件都是被此文件加载。**
|
||||
|
||||
``` js
|
||||
main.init // 初始化
|
||||
main.loaderJs // 动态加载所有核心JS文件
|
||||
main,loaderFloors // 动态加载所有楼层(剧本)
|
||||
main.loadMod // 加载某一个JS文件
|
||||
main.loadFloor // 加载某一个楼层
|
||||
main.setMainTipsText // 加载过程提示
|
||||
window.onresize // 窗口大小变化时
|
||||
main.dom.body.onkeydown // 在界面上按下某按键时
|
||||
main.dom.body.onkeydown // 在界面上放开某按键时
|
||||
main.dom.body.onselectstart // 开始选择时
|
||||
main.dom.data.onmousedown // 鼠标按下时
|
||||
main.dom.data.onmousemove // 鼠标移动时
|
||||
main.dom.data.onmouseup // 鼠标放开时
|
||||
main.dom.data.onmousewheel // 鼠标滑轮滚动时
|
||||
main.dom.data.ontouchstart // 手指在触摸屏开始触摸时
|
||||
main.dom.data.ontouchmove // 手指在触摸屏上移动时
|
||||
main.dom.data.ontouchend // 手指离开触摸屏时
|
||||
main.statusBar.image.book.onclick // 点击状态栏中的怪物手册时
|
||||
main.statusBar.image.fly.onclick // 点击状态栏中的楼层传送器时
|
||||
main.statusBar.image.toolbox.onclick // 点击状态栏中的工具箱时
|
||||
main.statusBar.image.keyboard.onclick // 点击状态栏中的快捷商店时
|
||||
main.statusBar.image.save.onclick // 点击状态栏中的存档按钮时
|
||||
main.statusBar.image.load.onclick // 点击状态栏中的读档按钮时
|
||||
main.statusBar.image.settings.onclick // 点击状态栏中的系统菜单时
|
||||
main.dom.playGame.onclick // 点击“开始游戏”时
|
||||
main.dom.loadGame.onclick // 点击“载入游戏”时
|
||||
main.dom.replayGame.onclick // 点击“录像回放”时
|
||||
main.dom.easyLevel.onclick // 点击“简单难度”时
|
||||
main.dom.normalLevel.onclick // 点击“普通难度”时
|
||||
main.dom.hardLevel.onclick // 点击“困难难度”时
|
||||
```
|
||||
|
||||
!> **`core.js`:系统核心文件。所有核心逻辑处理都在此文件完成。**
|
||||
|
||||
``` js
|
||||
* core.status.floorId // 获得当前层floorId
|
||||
* core.status.thisMap // 获得当前层的地图信息
|
||||
* core.status.maps // 获得所有楼层的地图信息
|
||||
* core.floors // 获得所有楼层的剧本
|
||||
|
||||
// ------ 初始化部分 ------
|
||||
core.init // 初始化
|
||||
core.showStartAnimate // 显示游戏开始界面
|
||||
core.hideStartAnimate // 隐藏游戏开始界面
|
||||
core.setStartProgressVal // 设置加载进度条进度
|
||||
core.setStartLoadTipText // 设置加载进度条提示文字
|
||||
core.loader // 加载图片和音频
|
||||
core.loadAutotile // 加载Autotile
|
||||
core.loadImage // 加载图片
|
||||
core.loadMusic // 加载音频
|
||||
core.isPlaying // 游戏是否已经开始
|
||||
core.clearStatus // 清除游戏状态和数据
|
||||
core.resetStatus // 重置游戏状态和初始数据
|
||||
core.startGame // 开始游戏
|
||||
* core.restart // 重新开始游戏;此函数将回到标题页面
|
||||
|
||||
// ------ 键盘、鼠标事件 ------
|
||||
core.onKeyDown // 按下某个键时
|
||||
core.onKeyUp // 放开某个键时
|
||||
core.pressKey // 按住某个键时
|
||||
core.keyDown // 根据按下键的code来执行一系列操作
|
||||
core.keyUp // 根据放开键的code来执行一系列操作
|
||||
core.ondown // 点击(触摸)事件按下时
|
||||
core.onmove // 当在触摸屏上滑动时
|
||||
core.onup // 当点击(触摸)事件放开时
|
||||
core.getClickLoc // 获得点击事件相对左上角的坐标(0到12之间)
|
||||
core.onclick // 具体点击屏幕上(x,y)点时,执行的操作
|
||||
core.onmousewheel // 滑动鼠标滚轮时的操作
|
||||
|
||||
// ------ 自动寻路代码相关 ------
|
||||
core.clearAutomaticRouteNode // 清除自动寻路路线
|
||||
core.stopAutomaticRoute // 停止自动寻路操作
|
||||
core.continueAutomaticRoute // 继续剩下的自动寻路操作
|
||||
core.clearContinueAutomaticRoute // 清空剩下的自动寻路列表
|
||||
core.setAutomaticRoute // 设置自动寻路路线
|
||||
core.automaticRoute // 自动寻路算法,找寻最优路径
|
||||
core.fillPosWithPoint // 显示离散的寻路点
|
||||
core.clearStepPostfix // 清除已经寻路过的部分
|
||||
|
||||
// ------ 自动行走,行走控制 ------
|
||||
core.stopAutoHeroMove // 停止勇士的自动行走
|
||||
core.setAutoHeroMove // 设置勇士的自动行走路线
|
||||
core.autoHeroMove // 让勇士开始自动行走
|
||||
core.setHeroMoveInterval // 设置行走的效果动画
|
||||
core.setHeroMoveTriggerInterval // 设置勇士行走过程中对事件的触发检测
|
||||
core.moveAction // 实际每一步的行走过程
|
||||
* core.turnHero(direction) // 设置勇士的方向(转向)
|
||||
core.canMoveHero // 勇士能否前往某方向
|
||||
core.moveHero // 让勇士开始移动
|
||||
core.eventMoveHero // 使用事件让勇士移动。这个函数将不会触发任何事件。
|
||||
core.moveOneStep // 每移动一格后执行的事件。中毒时在这里进行扣血判断。
|
||||
core.waitHeroToStop(callback) // 停止勇士的一切行动,等待勇士行动结束后,再执行callback回调函数。
|
||||
core.stopHero // 停止勇士的移动状态。
|
||||
core.drawHero // 绘制勇士。
|
||||
* core.setHeroLoc(name, value) // 设置勇士的位置。name为”direction”,”x”,”y”
|
||||
* core.getHeroLoc(name) // 获得勇士的位置。
|
||||
* core.nextX // 获得勇士面对位置的x坐标
|
||||
* core.nextY // 获得勇士面对位置的y坐标
|
||||
|
||||
// ------ 地图和事件处理 ------
|
||||
* core.openDoor(id, x, y, needKey, callback) // 打开一扇位于 (x,y) 的门
|
||||
* core.battle(id, x, y, force, callback) // 进行战斗;force表示是否强制战斗
|
||||
core.afterBattle // 战斗完毕
|
||||
core.trigger(x,y) // 触发x,y点的事件
|
||||
* core.changeFloor(floorId, stair, heroLoc, time, callback) // 楼层切换。floorId为目标楼层Id,stair可指定为上/下楼梯,time动画时间
|
||||
core.mapChangeAnimate // 地图切换动画效果
|
||||
core.clearMap // 清除地图
|
||||
core.fillText // 在某个canvas上绘制一段文字
|
||||
core.fillRect // 在某个canvas上绘制一个矩形
|
||||
core.strokeRect // 在某个canvas上绘制一个矩形的边框
|
||||
core.drawLine // 在某个canvas上绘制一条线
|
||||
core.setFont // 设置某个canvas的文字字体
|
||||
core.setLineWidth // 设置某个canvas的线宽度
|
||||
core.saveCanvas // 保存某个canvas状态
|
||||
core.loadCanvas // 加载某个canvas状态
|
||||
core.setStrokeStyle // 设置某个canvas边框属性
|
||||
core.setAlpha // 设置某个canvas的alpha值
|
||||
core.setOpacity // 设置某个canvas的透明度
|
||||
core.setFillStyle // 设置某个canvas的绘制属性(如颜色等)
|
||||
* core.drawMap(mapId, callback) // 绘制某张地图。mapId为地图Id,绘制完毕将执行callback回调函数。
|
||||
core.drawAutotile // 绘制Autotile
|
||||
* core.noPassExists(x,y) // 某个点是否不可通行
|
||||
core.noPass // 某个点是否在区域内且不可通行
|
||||
* core.npcExists(x,y) // 某个点是否存在NPC
|
||||
* core.terrainExists(x,y) // 某个点是否存在(指定的)地形
|
||||
* core.stairExists(x,y) // 某个点是否存在楼梯
|
||||
* core.nearStair // 当前位置是否在楼梯边
|
||||
* core.enemyExists(x,y) // 某个点是否存在(指定的)怪物
|
||||
* core.getBlock(x, y, floorId, needEnable) // 获得某个点的block。floorId指定目标楼层,needEnable如果为false则即使该点的事件处于禁用状态也将被返回(否则只有事件启用的点才被返回)
|
||||
core.moveBlock // 显示移动某块的动画,达到{“type”:”move”}的效果
|
||||
core.animateBlock // 显示/隐藏某个块时的动画效果
|
||||
core.showBlock // 将某个块从禁用变成启用状态
|
||||
core.removeBlock // 将某个块从启用变成禁用状态
|
||||
core.removeBlockById // 根据block的索引删除该块
|
||||
core.removeBlockByIds // 一次性删除多个block
|
||||
core.addGlobalAnimate // 添加一个全局动画
|
||||
core.removeGlobalAnimate // 删除一个或所有全局动画
|
||||
core.setGlobalAnimate // 设置全局动画的显示效果
|
||||
core.syncGlobalAnimate // 同步所有的全局动画效果
|
||||
core.drawBoxAnimate // 绘制UI层的box动画
|
||||
core.updateCheckBlock // 更新领域、夹击、阻击的伤害地图
|
||||
core.checkBlock // 检查并执行领域、夹击、阻击事件
|
||||
core.snipe // 阻击事件(动画效果)
|
||||
core.setFg // 更改画面色调
|
||||
* core.updateFg // 更新全地图显伤
|
||||
* core.itemCount // 获得某个物品的个数
|
||||
* core.hasItem // 是否存在某个物品
|
||||
* core.setItem // 设置某个物品的个数
|
||||
* core.removeItem // 删除某个物品
|
||||
* core.useItem // 使用某个物品;直接调用items.js中的useItem函数。
|
||||
* core.canUseItem // 能否使用某个物品。直接调用items.js中的canUseItem函数。
|
||||
* core.addItem // 增加某个物品的个数
|
||||
core.getNextItem // 获得面前的物品(轻按)
|
||||
* core.getItem // 获得某个物品
|
||||
* core.drawTip // 左上角绘制一段提示
|
||||
* core.drawText // 地图中间绘制一段文字
|
||||
|
||||
// ------ 系统机制 ------
|
||||
core.replaceText // 将文字中的${和}(表达式)进行替换
|
||||
core.calValue // 计算表达式的值
|
||||
core.doEffect // 执行一个表达式的effect操作
|
||||
core.splitLines // 字符串自动换行的分割
|
||||
core.unshift // 向某个数组前插入另一个数组或元素
|
||||
core.setLocalStorage // 设置本地存储
|
||||
core.getLocalStorage // 获得本地存储
|
||||
core.removeLocalStorage // 移除本地存储
|
||||
core.clone // 深拷贝一个对象
|
||||
core.formatDate // 格式化时间为字符串
|
||||
core.formatDate2 // 格式化时间为最简字符串
|
||||
core.setTwoDigits // 两位数显示
|
||||
core.debug // 进入Debug模式,攻防血和钥匙都调成很高的数值
|
||||
core.replay // 开始回放
|
||||
core.checkStatus // 判断当前能否进入某个事件
|
||||
core.openBook // 点击怪物手册时的打开操作
|
||||
core.useFly // 点击楼层传送器时的打开操作
|
||||
core.openToolbox // 点击工具栏时的打开操作
|
||||
core.openQuickShop // 点击快捷商店时的打开操作
|
||||
core.save // 点击保存按钮时的打开操作
|
||||
core.load // 点击读取按钮时的打开操作
|
||||
core.openSettings // 点击设置按钮时的打开操作
|
||||
core.autosave // 自动存档
|
||||
core.doSL // 实际进行存读档事件
|
||||
core.syncSave // 存档同步操作
|
||||
core.saveData // 存档到本地
|
||||
core.loadData // 从本地读档
|
||||
core.encodeRoute // 将路线压缩
|
||||
core.decodeRoute // 将路线解压缩
|
||||
* core.setStatus // 设置勇士属性
|
||||
* core.getStatus // 获得勇士属性
|
||||
core.getLvName // 获得某个等级的名称
|
||||
* core.setFlag // 设置某个自定义变量或flag
|
||||
* core.getFlag // 获得某个自定义变量或flag
|
||||
* core.hasFlag // 是否存在某个自定义变量或flag,且值为true
|
||||
core.insertAction // 往当前事件列表之前插入一系列事件
|
||||
* core.lockControl // 锁定状态栏,常常用于事件处理
|
||||
* core.unlockControl // 解锁状态栏
|
||||
* core.isset // 判断某对象是否不为undefined也不会null
|
||||
core.readFile // 读取一个本地文件内容
|
||||
core.download // 下载文件到本地
|
||||
core.copy // 复制一段文字到剪切板
|
||||
* core.playBgm // 播放背景音乐
|
||||
* core.pauseBgm // 暂停背景音乐的播放
|
||||
* core.resumeBgm // 恢复背景音乐的播放
|
||||
* core.playSound // 播放音频
|
||||
core.show // 动画显示某对象
|
||||
core.hide // 动画使某对象消失
|
||||
core.clearStatusBar // 清空状态栏
|
||||
core.updateStatusBar // 更新状态栏
|
||||
core.resize // 屏幕分辨率改变后重新自适应
|
||||
core.domRenderer // 渲染DOM
|
||||
|
||||
// ------ core.js 结束 ------
|
||||
```
|
||||
|
||||
!> **`data.js` 定义了一些初始化的数据信息。**
|
||||
|
||||
!> **`enemys.js` 定义了怪物信息。**
|
||||
|
||||
``` js
|
||||
core.enemys.init // 初始化
|
||||
* core.enemys.getEnemys // 获得一个或所有怪物数据
|
||||
* core.enemys.hasSpecial // 判断是否含有某特殊属性
|
||||
* core.enemys.getSpecialText // 获得所有特殊属性的名称
|
||||
* core.enemys.getSpecialHint // 获得每个特殊属性的说明
|
||||
* core.enemys.getDamage // 获得某个怪物的伤害
|
||||
* core.enemys.getExtraDamage // 获得某个怪物的额外伤害
|
||||
* core.enemys.getCritical // 临界值计算
|
||||
* core.enemys.getCriticalDamage // 临界减伤计算
|
||||
* core.enemys.getDefDamage // 1防减伤计算
|
||||
* core.enemys.calDamage // 具体的伤害计算公式
|
||||
core.enemys.getCurrentEnemys // 获得当前楼层的怪物列表
|
||||
```
|
||||
|
||||
!> **`events.js` 定义了各个事件的处理流程。**
|
||||
|
||||
``` js
|
||||
core.events.init // 初始化
|
||||
core.events.getEvents // 获得一个或所有系统事件类型
|
||||
core.events.startGame // 游戏开始事件
|
||||
* core.events.setInitData // 不同难度分别设置初始属性
|
||||
* core.events.win // 游戏获胜事件
|
||||
* core.events.lose // 游戏失败事件
|
||||
core.evens.gameOver // 游戏结束
|
||||
core.events.afterChangeFloor // 转换楼层结束的事件
|
||||
core.events.doEvents // 开始执行一系列自定义事件
|
||||
core.events.doAction // 执行当前自定义事件列表中的下一个事件
|
||||
core.events.insertAction // 往当前事件列表之前添加一个或多个事件
|
||||
core.events.openShop // 打开一个全局商店
|
||||
core.events.disableQuickShop // 禁用一个全局商店
|
||||
* core.events.canUseQuickShop // 当前能否使用快捷商店
|
||||
* core.events.checkLvUp // 检查升级事件
|
||||
* core.events.useItem // 尝试使用道具
|
||||
core.events.addPoint // 加点事件
|
||||
core.events.afterBattle // 战斗结束后触发的事件
|
||||
core.events.afterOpenDoor // 开一个门后触发的事件
|
||||
core.events.passNet // 经过一个路障
|
||||
core.events.changeLight // 改变亮灯(感叹号)的事件
|
||||
* core.events.afterChangeLight // 改变亮灯之后,可以触发的事件
|
||||
* core.events.afterUseBomb // 使用炸弹/圣锤后的事件
|
||||
* core.events.beforeSaveData // 即将存档前可以执行的操作
|
||||
* core.events.afterLoadData // 读档事件后,载入事件前,可以执行的操作
|
||||
|
||||
// ------ 点击事件和键盘事件的处理 ------
|
||||
core.events.longClick // 长按
|
||||
core.events.keyDownCtrl // 按下Ctrl键时(快捷跳过对话)
|
||||
core.events.clickConfirmBox // 确认框界面时的点击操作
|
||||
core.events.keyUpConfirmBox // 确认框界面时,放开某个键的操作
|
||||
core.events.clickAction // 自定义事件时的点击操作
|
||||
core.events.keyDownAction // 自定义事件时,按下某个键的操作
|
||||
core.events.keyUpAction // 自定义事件时,放开某个键的操作
|
||||
core.events.clickBook // 怪物手册界面的点击操作
|
||||
core.events.keyDownBook // 怪物手册界面时,按下某个键的操作
|
||||
core.events.keyUpBook // 怪物手册界面时,放开某个键的操作
|
||||
core.events.clickBookDetail // 怪物手册属性显示界面时的点击操作
|
||||
core.events.clickFly // 楼层传送器界面时的点击操作
|
||||
core.events.keyDownFly // 楼层传送器界面时,按下某个键的操作
|
||||
core.events.keyUpFly // 楼层传送器界面时,放开某个键的操作
|
||||
core.events.clickViewMaps // 浏览地图界面时的点击操作
|
||||
core.events.keyDownViewMaps // 浏览地图界面时,按下某个键的操作
|
||||
core.events.keyUpViewMaps // 浏览地图界面时,放开某个键的操作
|
||||
core.events.clickShop // 商店界面时的点击操作
|
||||
core.events.keyDownShop // 商店界面时,按下某个键的操作
|
||||
core.events.keyUpShop // 商店界面时,放开某个键的操作
|
||||
core.events.clickQuickShop // 快捷商店界面时的点击操作
|
||||
core.events.keyDownQuickShop // 快捷商店界面时,按下某个键的操作
|
||||
core.events.keyUpQuickShop // 快捷商店界面时,放开某个键的操作
|
||||
core.events.clickToolbox // 工具栏界面时的点击操作
|
||||
core.events.clickToolboxIndex // 选择工具栏界面中某个Index后的操作
|
||||
core.events.keyDownToolbox // 工具栏界面时,按下某个键的操作
|
||||
core.events.keyUpToolbox // 工具栏界面时,放开某个键的操作
|
||||
core.events.clickSL // 存读档界面时的点击操作
|
||||
core.events.keyDownSL // 存读档界面时,按下某个键的操作
|
||||
core.events.keyUpSL // 存读档界面时,放开某个键的操作
|
||||
core.events.clickSwitchs // 系统设置界面时的点击操作
|
||||
core.events.keyDownSwitchs // 系统设置界面时,按下某个键的操作
|
||||
core.events.keyUpSwitchs // 系统设置界面时,放开某个键的操作
|
||||
core.events.clickSettings // 系统菜单栏界面时的点击事件
|
||||
core.events.keyDownSettings // 系统菜单栏界面时,按下某个键的操作
|
||||
core.events.keyUpSettings // 系统菜单栏界面时,放开某个键的操作
|
||||
core.events.clickSyncSave // 同步存档界面时的点击操作
|
||||
core.events.keyDownSyncSave // 同步存档界面时,按下某个键的操作
|
||||
core.events.keyUpSyncSave // 同步存档界面时,放开某个键的操作
|
||||
core.events.clickKeyBoard // 虚拟键盘界面时的点击操作
|
||||
core.events.clickAbout // “关于”界面时的点击操作
|
||||
```
|
||||
|
||||
!> `icons.js` 定义了素材ID和它在图片上的索引的对应关系。
|
||||
|
||||
!> `items.js` 定义了每个道具的名称,以及使用效果。
|
||||
|
||||
``` js
|
||||
core.items.init // 初始化
|
||||
core.items.getItems // 获得所有道具
|
||||
core.items.getItemEffect // “即捡即用类”道具的使用效果
|
||||
core.items.getItemEffectTip // “即捡即用类”道具的文字提示
|
||||
* core.items.useItem // 使用道具
|
||||
* core.items.cauUseItem // 当前能否使用道具
|
||||
```
|
||||
|
||||
!> `maps.js` 定义了数字-ID的对应关系。
|
||||
|
||||
``` js
|
||||
core.maps.loadFloor // 加载某个楼层(从剧本或存档中)
|
||||
core.maps.getBlock // 数字和ID的对应关系
|
||||
core.maps.addEvent // 向该楼层添加剧本的自定义事件
|
||||
core.maps.addChangeFloor // 向该楼层添加剧本的楼层转换事件
|
||||
core.maps.initMaps // 初始化所有地图
|
||||
core.maps.save // 将当前地图重新变成数字,以便于存档
|
||||
core.maps.load // 将存档中的地图信息重新读取出来
|
||||
core.maps.getMapArray // 将当前地图重新变成二维数组形式
|
||||
```
|
||||
|
||||
!> `ui.js` 定义了各种界面的绘制。
|
||||
|
||||
``` js
|
||||
core.ui.closePanel // 结束一切事件和绘制,关闭UI窗口,返回游戏进程
|
||||
core.ui.drawTextBox // 绘制一个对话框
|
||||
core.ui.drawChoices // 绘制一个选项界面
|
||||
core.ui.drawConfirmBox // 绘制一个确认/取消的警告页面
|
||||
core.ui.drawSwitchs // 绘制系统设置界面
|
||||
core.ui.drawSettings // 绘制系统菜单栏
|
||||
core.ui.drawQuickShop // 绘制快捷商店选择栏
|
||||
core.ui.drawWaiting // 绘制等待界面
|
||||
core.ui.drawSyncSave // 绘制存档同步界面
|
||||
core.ui.drawPagination // 绘制分页
|
||||
core.ui.drawEnemyBook // 绘制怪物手册
|
||||
core.ui.drawBookDetail // 绘制怪物属性的详细信息
|
||||
core.ui.drawFly // 绘制楼层传送器
|
||||
core.ui.drawMaps // 绘制浏览地图界面
|
||||
core.ui.drawToolbox // 绘制道具栏
|
||||
core.ui.drawSLPanel // 绘制存档/读档界面
|
||||
core.ui.drawThumbnail // 绘制一个缩略图
|
||||
core.ui.drawAbout // 绘制“关于”界面
|
||||
core.ui.drawHelp // 绘制帮助界面
|
||||
```
|
||||
222
_docs/_start.md
222
_docs/_start.md
@ -1,222 +0,0 @@
|
||||
# 快速上手
|
||||
|
||||
?> 目前版本**v2.3.3**,上次更新时间:* {docsify-updated} *
|
||||
|
||||
在这一节中,将详细介绍做一部塔的流程。现在,让我们来做一部单层塔!
|
||||
|
||||
## 前置需求
|
||||
|
||||
你需要有满足如下条件才能进行制作:
|
||||
|
||||
- Windows 8以上操作系统;Windows 7需要安装.Net Framework 4.0。(能打开同目录下的“启动服务.exe”即可)
|
||||
- Chrome浏览器。其他浏览器可能会导致本地服务器产生闪退等现象。
|
||||
- 一个很好的文本编辑器。推荐带有高亮染色、错误提示等效果。例如:WebStorm,VSCode,或者至少也要Sublime Text。
|
||||
- ([VSCode下载地址](https://code.visualstudio.com/),群里的群文件中也有,强烈推荐之。)
|
||||
- **2.0版本可以不需要,但是仍然强烈推荐有一个,从而能对H5造塔有更深的了解。**
|
||||
|
||||
只要满足了上述条件,你就可以开始做自己的塔啦!
|
||||
|
||||
## V2.0的使用
|
||||
|
||||
目前版本已经更新到V2.0,在2.0版本中,我们可以进行全GUI造塔。
|
||||
|
||||
下面的文档主要是讲如何通过代码编辑的方式来造,仍然强烈建议进行阅读从而有着一定的了解。
|
||||
|
||||
如果想直接知道如何在V2.0造塔,可以直接参见[V2.0版本介绍](V2.0)的说明,或者看[B站视频教程](http://www.bilibili.com/video/av17608025/)。
|
||||
|
||||
## 启动HTTP服务
|
||||
|
||||
在根目录下有一个“启动服务.exe”,运行之。
|
||||
|
||||

|
||||
|
||||
* “启动游戏”按钮将打开一个网页,你能在里面看到现在游戏的效果。
|
||||
* “地图编辑器”允许你以可视化的方式进行编辑地图。
|
||||
* “便捷PS工具”能让你很方便的对自定义素材进行添加。参见[自定义素材](personalization#自定义素材)。
|
||||
* “地图生成器”能让你从已有的截图(如RMXP项目)中立刻生成可被本样板识别的地图数据。
|
||||
* “RM动画导出器”能让你从RMXP中导出动画而被H5魔塔使用。
|
||||
* “JS代码压缩工具”能对JS代码进行压缩,从而减少IO请求数和文件大小。
|
||||
* “伤害和临界值计算器”是一个很便捷的小工具,能对怪物的伤害和临界值进行计算。
|
||||
|
||||
!> **警告:** 非Chrome浏览器(如Edge/IE等)下本地服务器可能表现不正常,会出现闪退等现象。请务必下载安装Chrome浏览器。
|
||||
|
||||
## 新建剧本
|
||||
|
||||
类似于RMXP,本塔每层楼都是一个“剧本”,剧本内主要定义了本层的地图和各种事件。主函数将读取每个剧本,并生成实际的地图供游戏使用。
|
||||
|
||||
我们打开 `project/floors/` 目录,这个目录是所有剧本的目录。我们需要指定一个楼层名,例如MT1;然后,我们可以将`MT0.js`(模板)复制重命名为为`MT1.js`,并使用文本编辑器打开。
|
||||
|
||||

|
||||
|
||||
然后将楼层名改为MT1,floorId改名为MT1;title可以改成任意内容,将在切换楼层时进行显示(比如可以改成“1层小塔”)。
|
||||
|
||||
具体样板文件的每个要素如下:
|
||||
- **`floorId`** 楼层唯一标识符;必须和文件名,以及 `main.floors.xxx` 完全一致
|
||||
- **`title`** 楼层中文名,将在切换楼层时进行显示
|
||||
- **`name`** 楼层再状态栏显示的名称
|
||||
- **`canFlyTo`** 当前楼层可否被楼传器飞到。如果该层不能飞到,则也在该层也不允许使用楼传器。
|
||||
- **`canUseQuickShop`** 当前楼层可否使用快捷商店。
|
||||
- **`defaultGround`** 该层的背景(地面)素材。
|
||||
- **`images`** 该层默认显示的前景/背景图片
|
||||
- **`color`** 该层的画面色调。
|
||||
- **`bgm`** 到达该层后默认播放的BGM。本项可忽略。
|
||||
- **`item_ratio`** 该层的宝石/血瓶倍率
|
||||
- **`map`** 本层地图,需要是13x13数组,建议使用地图生成器或者可视化地图编辑器制作。
|
||||
- **`firstArrive`** 第一次到该楼层触发的事件
|
||||
- **`events`** 该楼的所有可能事件列表
|
||||
- **`changeFloor`** 楼层转换事件;该事件不能和上面的events有冲突(同位置点),否则会被覆盖
|
||||
- **`afterBattle`** 战斗后可能触发的事件列表
|
||||
- **`afterGetItem`** 获得道具后可能触发的事件列表
|
||||
- **`afterOpenDoor`** 开完门后可能触发的事件列表
|
||||
- **`cannotMove`** 每个图块不可通行的方向,也就是悬崖效果
|
||||
|
||||
我们最终的任务其实是,将每个楼层的剧本(地图&事件)给写完即可。
|
||||
|
||||
换句话说,只需要简单的复制操作,我们就可以新建一个剧本了。
|
||||
|
||||
## 绘制地图
|
||||
|
||||
有两种绘制地图的方式:从头绘制地图;从RMXP中导入已有的地图。
|
||||
|
||||
### 从头绘制地图
|
||||
|
||||
我们直接打开“地图编辑器”,可以看到一个可视化的UI界面。
|
||||
|
||||

|
||||
|
||||
然后可以在上面任意进行绘制地图。
|
||||
|
||||
!> **如果地图的数字和ID未被定义,则会进行提示:数字和ID未被定义!此时要对素材的ID和数字进行定义,请参见[自定义素材](personalization#自定义素材)。**
|
||||
|
||||
绘制地图完毕后,点击"导出地图",即可在左边看到对应的JSON数组,并且已经复制到了剪切板。将其粘贴到剧本中的map位置即可。
|
||||
|
||||

|
||||
|
||||
!> V2.0版本可以直接将当前地图进行保存或另存为,不需要这样手动打开进行编辑。
|
||||
|
||||
### 从RMXP导入已有的地图
|
||||
|
||||
如果我们想复刻一个现有的,已经被RMXP所制作的塔,也有很便捷的方式,那就是用到我们的“地图生成器”。
|
||||
|
||||
首先,我们打开RMXP和对应的项目,可以看到它的地图。
|
||||
|
||||

|
||||
|
||||
我们打开Windows自带的“截图工具”,并将整个地图有效区域截图下来,并将其复制到剪切板。
|
||||
|
||||

|
||||
|
||||
截图时请注意:**只截取有效游戏空间内数据,并且有效空间内的范围必须是13x13。(如果地图小于13*13,请用星空或墙壁填充到13x13)。**
|
||||
|
||||
确认地图的图片文件已经复制到剪切板后,我们打开“地图生成器”,并点“加载图片”。大约1-2秒后,可以得到地图的数据。
|
||||
|
||||

|
||||
|
||||
然后点击“复制地图”,即可将地图数据复制到剪切板。
|
||||
|
||||
!> **如果有识别不一致的存在,即生成的地图和实际的地图不符,我们可以在地图编辑器中粘贴,再可视化进行编辑。**
|
||||
|
||||
!> **地图生成器默认只支持经典素材。如果有自定义素材需求(例如原版的1层小塔那种素材),请参见[自定义素材](personalization#自定义素材)。**
|
||||
|
||||
!> **请确保截图范围刚好为13x13,并且保证每个位置的像素都是32x32。**
|
||||
|
||||
|
||||
## 录入数据
|
||||
|
||||
有了地图后,我们下一步需要做的就是录入数据。数据主要包括如下几种:
|
||||
|
||||
- 勇士初始的属性
|
||||
- 全局变量(宝石效果、全局Flag等)
|
||||
- 怪物数据(每个怪物的攻防血金币经验等等)
|
||||
|
||||
下面依次进行说明。
|
||||
|
||||
我们打开`data.js`文件,这里面定义了各种全局属性和勇士初始值。
|
||||
|
||||
!> V2.0版本可以直接在地图编辑器的`全塔属性`中进行修改!
|
||||
|
||||
我们可以将本塔标题改名为“1层小塔”,
|
||||
|
||||
游戏的唯一标识符叫onefloor,然后可以直接修改勇士的各项初始数据.
|
||||
|
||||
!> **注:name作为游戏的唯一标识符必须进行修改,否则可能会导致存档等出现问题。**
|
||||
|
||||

|
||||
|
||||
!> **请注意,勇士的初始位置一栏,x为横坐标,y为纵坐标;即,x为从左到右第几列,y为从上到下第几行,均从0开始计算。**
|
||||
|
||||
修改完初始化信息后,接下来我们需要修改道具的信息(比如宝石加攻防的数值,血瓶加生命的数值等)。还是在这个`data.js`文件,往下拉,找到values一项,并进行相应的设置
|
||||
|
||||

|
||||
|
||||
然后,再设置一些系统Flag,以进行游戏。继续将`data.js`往下拉,我们注意到本塔是存在魔防的,不存在经验,因此我们可以简单地将enableMDef改为true,enableExperience改成false,enableDebuff改成false。
|
||||
|
||||
同理,本塔的破墙镐只能破面前的墙壁,因此`pickaxeFourDirections`需要改成`false`。
|
||||
|
||||

|
||||
|
||||
其他的几项暂时不会被涉及到,因此不用考虑。
|
||||
|
||||
全局变量修改完毕后,我们需要告诉主函数加载该楼层。打开`data.js`,找到`floorIds`项,将其值改为楼层ID即MT1。
|
||||
|
||||
最后一步就是录入怪物数据。打开`enemys.js`文件,依次输入你在本塔内使用到的所有怪物的攻防血的数据。其中怪物的特殊属性(special项)与该文件下面的getSpecialText对应。
|
||||
|
||||
!> V2.0版本可以直接在“图块属性”一栏进行修改怪物属性!
|
||||
|
||||

|
||||
|
||||
只需要修改自己用到的怪物属性即可,其他没有用到的怪物完全无所谓。
|
||||
|
||||
做完后保存所有文件,在本地服务器中“启动游戏”,就能立刻看到自己的塔并开始游戏啦!是不是很简单呢!
|
||||
|
||||

|
||||
|
||||
## 压缩与发布
|
||||
|
||||
当你将上述步骤完成后,你实际上已经做出来了一个魔塔,并且可以发布给大家进行游戏了。
|
||||
目前而言发布有如下几种方式:
|
||||
|
||||
- 离线版本:直接将游戏文件夹打包,放到百度网盘等地方供用户下载;用户下载到本地后直接使用浏览器打开`index.html`进行游戏。
|
||||
- 手机端的部分浏览器如chrome也支持本地网页,可以下载到手机然后直接打开进行游戏。
|
||||
- 在线版本:将游戏放到某个服务器上,大家在线联网游戏。
|
||||
|
||||
**离线版本的好处是:先全部下载后再游戏,无需考虑流量的问题,也可以支持高清音乐的播放。坏处是:没办法在多平台之间迁移,无法及时获得游戏更新(需要重新下载),而浏览器打开本地文件有丢失存档的风险。
|
||||
在线版本的好处是:随时随地可以玩,可以多平台接档,还可以在后台看到一些统计信息,可以随时对游戏进行更新;坏处是需要一个服务器,且还要考虑到用户流量的问题。**
|
||||
|
||||
在此我们只讨论在线版本。当你决定发布游戏时,强烈建议先将JS代码进行压缩以节省可能的IO请求以及网络流量。直接打开同目录下的“JS代码压缩工具”进行压缩即可。
|
||||
|
||||
压缩完毕后,你还需要将`main.js`中的useCompress从false改为true,这样方才只会加载压缩后的文件。
|
||||
|
||||
如果你需要发布到服务器上且你没有服务器,可以直接将本塔发给我(`艾之葵`),我会给负责你部署上去的。我的服务器至少能保证两年内有效。
|
||||
|
||||
然后就是发布帖子、链接二维码,能让任何人在任何时候任何平台上都能进行游戏啦!是不是很简单呢!
|
||||
|
||||
## 注意事项和常见FAQ
|
||||
|
||||
1. 截图请务必刚好截取13x13的图片,并需要保证每个位置必须为32x32像素。一般无放缩的RMXP符合条件。
|
||||
2. 游戏的唯一标识符name请务必修改。如果不修改可能会导致存档出现异常。
|
||||
3. 别忘了data.js中要修改floorIds指明所用到的所有楼层哦~
|
||||
|
||||
下面是几个常见的FAQ:
|
||||
|
||||
**Q: 为什么截图识别不出来?**
|
||||
|
||||
**A:** 请保证刚好为13x13,且每个位置必须32x32像素。如果不确定,可以保存你的截图,右键属性查看详细信息,看像素的宽高是不是在416左右。多少几十像素都是没关系的。
|
||||
|
||||

|
||||
|
||||
**Q: 打开游戏时卡死在了xxx.js加载完毕!无法进入游戏。**
|
||||
|
||||
**A:** 最大的可能是因为少了逗号,或者反括号等等。一般而言VSCode都会有错误提示,你哪里少了东西。
|
||||
|
||||
如果没有,可以采用如下方式debug:
|
||||
|
||||
Ctrl+Shift+I 打开Chrome的控制台,找到Console。
|
||||
|
||||
如果出现了语法错误,会有红色提示 **Unexpected xxx** ,找到后面文件名和行号,打开,使用VSCode检查该处是否存在问题,即可。
|
||||
|
||||

|
||||
|
||||
==========================================================================================
|
||||
|
||||
[继续阅读下一章:元件说明](element)
|
||||
@ -966,7 +966,7 @@ this.getAchievements = function () {
|
||||
- **`flag:heroIcon`**: 当前的勇士行走图名称。
|
||||
- **`flag:saveEquips`**: 快速换装时保存的套装。
|
||||
- **`flag:__visited__`**: 当前访问过的楼层。
|
||||
- **`flag:equip_atk_buff`**, **`flag:equip_def_buff`**, **`flag:equip_mdef_buff`**: 当前攻防魔防的实际计算比例加成。
|
||||
- **`flag:__atk_buff__`**, **`flag:__def_buff__`**, **`flag:__mdef_buff__`**: 当前攻防魔防的实际计算比例加成。
|
||||
- **`flag:__color__`**, **`flag:__weather__`**, **`flag:__volume__`**: 当前的画面色调、天气和音量。
|
||||
- **`flag:__events__`**: 当前保存的事件列表,读档时会恢复(适用于在事件中存档)
|
||||
- **`flag:textAttribute`**, **`flag:globalAttribute`**, **`flag:globalFlags`**: 当前的剧情文本属性,当前的全局属性,当前的全局开关。
|
||||
|
||||
@ -406,7 +406,7 @@ control.prototype.resetStatus = function(hero, hard, floorId, route, maps, value
|
||||
core.status.floorId = floorId;
|
||||
core.status.maps = core.clone(maps);
|
||||
// 初始化怪物
|
||||
core.material.enemys = core.clone(core.enemys.getEnemys());
|
||||
core.material.enemys = core.enemys.getEnemys();
|
||||
core.material.items = core.items.getItems();
|
||||
// 初始化人物属性
|
||||
core.status.hero = core.clone(hero);
|
||||
@ -2566,13 +2566,27 @@ control.prototype.setStatus = function (statusName, statusVal) {
|
||||
}
|
||||
|
||||
////// 获得勇士属性 //////
|
||||
control.prototype.getStatus = function (statusName) {
|
||||
control.prototype.getStatus = function (name) {
|
||||
if (!core.isset(core.status.hero)) return null;
|
||||
// support status:x
|
||||
if (core.isset(core.status.hero.loc[statusName]))
|
||||
return core.status.hero.loc[statusName];
|
||||
if (statusName == 'exp') statusName = 'experience';
|
||||
return core.status.hero[statusName];
|
||||
if (core.isset(core.status.hero.loc[name]))
|
||||
return core.status.hero.loc[name];
|
||||
if (name == 'exp') name = 'experience';
|
||||
return core.status.hero[name];
|
||||
}
|
||||
|
||||
control.prototype.getStatusOrDefault = function (status, name) {
|
||||
if (core.isset(status) && name in status)
|
||||
return status[name];
|
||||
return this.getStatus(name);
|
||||
}
|
||||
|
||||
control.prototype.getRealStatus = function (name) {
|
||||
return this.getRealStatusOrDefault(null, name);
|
||||
}
|
||||
|
||||
control.prototype.getRealStatusOrDefault = function (status, name) {
|
||||
return this.getStatusOrDefault(status, name) * core.getFlag('__'+name+'_buff__', 1);
|
||||
}
|
||||
|
||||
////// 获得某个等级的名称 //////
|
||||
@ -2608,6 +2622,12 @@ control.prototype.removeFlag = function(flag) {
|
||||
delete core.status.hero.flags[flag];
|
||||
}
|
||||
|
||||
////// 增加某个flag数值 //////
|
||||
control.prototype.addFlag = function(flag, delta) {
|
||||
if (!core.isset(core.status.hero)) return;
|
||||
core.setFlag(flag, core.getFlag(flag, 0) + delta);
|
||||
}
|
||||
|
||||
////// 锁定状态栏,常常用于事件处理 //////
|
||||
control.prototype.lockControl = function () {
|
||||
core.status.lockControl = true;
|
||||
|
||||
@ -237,7 +237,7 @@ core.prototype.init = function (coreData, callback) {
|
||||
document.title = core.firstData.title + " - HTML5魔塔";
|
||||
document.getElementById("startLogo").innerHTML = core.firstData.title;
|
||||
core.material.items = core.items.getItems();
|
||||
core.material.enemys = core.clone(core.enemys.getEnemys());
|
||||
core.material.enemys = core.enemys.getEnemys();
|
||||
core.material.icons = core.icons.getIcons();
|
||||
core.material.events = core.events.getEvents();
|
||||
|
||||
|
||||
333
libs/enemys.js
333
libs/enemys.js
@ -16,17 +16,12 @@ enemys.prototype._init = function () {
|
||||
}
|
||||
}
|
||||
|
||||
////// 获得一个或所有怪物数据 //////
|
||||
enemys.prototype.getEnemys = function (enemyId) {
|
||||
if (!core.isset(enemyId)) {
|
||||
return this.enemys;
|
||||
}
|
||||
return this.enemys[enemyId];
|
||||
enemys.prototype.getEnemys = function () {
|
||||
return core.clone(this.enemys);
|
||||
}
|
||||
|
||||
////// 判断是否含有某特殊属性 //////
|
||||
enemys.prototype.hasSpecial = function (special, test) {
|
||||
|
||||
if (!core.isset(special)) return false;
|
||||
|
||||
if (special instanceof Array) {
|
||||
@ -52,9 +47,9 @@ enemys.prototype.getSpecials = function () {
|
||||
return this.enemydata.getSpecials();
|
||||
}
|
||||
|
||||
enemys.prototype.calContent = function (enemy, content) {
|
||||
if (typeof enemy == 'string') enemy = core.material.enemys[enemy];
|
||||
enemys.prototype._calSpecialContent = function (enemy, content) {
|
||||
if (typeof content == 'string') return content;
|
||||
if (typeof enemy == 'string') enemy = core.material.enemys[enemy];
|
||||
if (content instanceof Function) {
|
||||
return content(enemy);
|
||||
}
|
||||
@ -63,8 +58,6 @@ enemys.prototype.calContent = function (enemy, content) {
|
||||
|
||||
////// 获得所有特殊属性的名称 //////
|
||||
enemys.prototype.getSpecialText = function (enemy) {
|
||||
// 移动到了脚本编辑 - getSpecials中
|
||||
|
||||
if (typeof enemy == 'string') enemy = core.material.enemys[enemy];
|
||||
if (!core.isset(enemy)) return [];
|
||||
var special = enemy.special;
|
||||
@ -74,7 +67,7 @@ enemys.prototype.getSpecialText = function (enemy) {
|
||||
if (core.isset(specials)) {
|
||||
for (var i=0;i<specials.length;i++) {
|
||||
if (this.hasSpecial(special, specials[i][0]))
|
||||
text.push(this.calContent(enemy, specials[i][1]));
|
||||
text.push(this._calSpecialContent(enemy, specials[i][1]));
|
||||
}
|
||||
}
|
||||
return text;
|
||||
@ -82,9 +75,6 @@ enemys.prototype.getSpecialText = function (enemy) {
|
||||
|
||||
////// 获得每个特殊属性的说明 //////
|
||||
enemys.prototype.getSpecialHint = function (enemy, special) {
|
||||
// 移动到了脚本编辑 - getSpecials中
|
||||
|
||||
if (typeof enemy == 'string') enemy = core.material.enemys[enemy];
|
||||
var specials=this.getSpecials();
|
||||
|
||||
if (!core.isset(special)) {
|
||||
@ -92,7 +82,7 @@ enemys.prototype.getSpecialHint = function (enemy, special) {
|
||||
var hints = [];
|
||||
for (var i=0;i<specials.length;i++) {
|
||||
if (this.hasSpecial(enemy, specials[i][0]))
|
||||
hints.push(this.calContent(enemy, specials[i][1])+":"+this.calContent(enemy, specials[i][2]));
|
||||
hints.push(this._calSpecialContent(enemy, specials[i][1])+":"+this._calSpecialContent(enemy, specials[i][2]));
|
||||
}
|
||||
return hints;
|
||||
}
|
||||
@ -100,21 +90,22 @@ enemys.prototype.getSpecialHint = function (enemy, special) {
|
||||
if (!core.isset(specials)) return "";
|
||||
for (var i=0;i<specials.length;i++) {
|
||||
if (special == specials[i][0])
|
||||
return this.calContent(enemy, specials[i][1])+":"+this.calContent(enemy, specials[i][2]);
|
||||
return this._calSpecialContent(enemy, specials[i][1])+":"+this._calSpecialContent(enemy, specials[i][2]);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
////// 能否获胜 //////
|
||||
enemys.prototype.canBattle = function (enemyId, x, y, floorId) {
|
||||
var damage = this.getDamage(enemyId, x, y, floorId);
|
||||
enemys.prototype.canBattle = function (enemy, x, y, floorId) {
|
||||
if (typeof enemy == 'string') enemy = core.material.enemys[enemy];
|
||||
var damage = this.getDamage(enemy, x, y, floorId);
|
||||
return damage != null && damage < core.status.hero.hp;
|
||||
}
|
||||
|
||||
////// 获得某个怪物的伤害 //////
|
||||
enemys.prototype.getDamage = function (enemy, x, y, floorId) {
|
||||
if (typeof enemy == 'string') enemy = core.material.enemys[enemy];
|
||||
var damage = this.calDamage(enemy, core.status.hero.hp, core.status.hero.atk, core.status.hero.def, core.status.hero.mdef, x, y, floorId);
|
||||
var damage = this.calDamage(enemy, null, x, y, floorId);
|
||||
if (damage == null) return null;
|
||||
return damage + this.getExtraDamage(enemy);
|
||||
}
|
||||
@ -134,7 +125,7 @@ enemys.prototype.getExtraDamage = function (enemy) {
|
||||
|
||||
enemys.prototype.getDamageString = function (enemy, x, y, floorId) {
|
||||
if (typeof enemy == 'string') enemy = core.material.enemys[enemy];
|
||||
var damage = core.enemys.getDamage(enemy, x, y, floorId);
|
||||
var damage = this.getDamage(enemy, x, y, floorId);
|
||||
|
||||
var color = '#000000';
|
||||
|
||||
@ -164,137 +155,137 @@ enemys.prototype.getDamageString = function (enemy, x, y, floorId) {
|
||||
};
|
||||
}
|
||||
|
||||
////// 接下来N个临界值和临界减伤计算 //////
|
||||
enemys.prototype.nextCriticals = function (enemy, number, x, y, floorId) {
|
||||
if (typeof enemy == 'string') enemy = core.material.enemys[enemy];
|
||||
|
||||
var useTurn = !core.flags.useLoop;
|
||||
|
||||
number = number||1;
|
||||
|
||||
if (this.hasSpecial(enemy.special, 3)) {
|
||||
if (core.status.hero.atk<=enemy.def) {
|
||||
return [[enemy.def+1-core.status.hero.atk,'?']];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
// 坚固、模仿怪物没有临界!
|
||||
if (this.hasSpecial(enemy.special, 10)) return [];
|
||||
var info = this.getDamageInfo(enemy, core.status.hero.hp, core.status.hero.atk, core.status.hero.def, core.status.hero.mdef, x, y, floorId);
|
||||
|
||||
if (info == null) {
|
||||
info = this.getEnemyInfo(enemy, core.status.hero.hp, core.status.hero.atk, core.status.hero.def, core.status.hero.mdef, x, y, floorId);
|
||||
if (core.status.hero.atk<=info.def) {
|
||||
return [[info.def+1-core.status.hero.atk,'?']];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
// getDamageInfo直接返回数字
|
||||
if (typeof info == 'number') {
|
||||
return [[0,0]];
|
||||
}
|
||||
|
||||
if (info.damage<=0 && !core.flags.enableNegativeDamage) {
|
||||
return [[0,0]];
|
||||
}
|
||||
|
||||
var list = [], pre = null;
|
||||
var mon_hp = info.mon_hp, hero_atk = core.status.hero.atk, mon_def = info.mon_def, turn = info.turn;
|
||||
|
||||
if (useTurn) { // 回合数计算法
|
||||
for (var t = turn-1;t>=1;t--) {
|
||||
var nextAtk = Math.ceil(mon_hp/t) + mon_def;
|
||||
// 装备提升比例的计算临界
|
||||
nextAtk = Math.ceil(nextAtk / core.getFlag('equip_atk_buff', 1));
|
||||
if (nextAtk<=hero_atk) break;
|
||||
if (nextAtk!=pre) {
|
||||
var nextInfo = this.getDamageInfo(enemy, core.status.hero.hp, nextAtk, core.status.hero.def, core.status.hero.mdef, x, y, floorId);
|
||||
if (nextInfo==null || (typeof nextInfo == 'number')) break;
|
||||
list.push([nextAtk-hero_atk,Math.floor(info.damage-nextInfo.damage)]);
|
||||
if (nextInfo.damage<=0 && !core.flags.enableNegativeDamage) break;
|
||||
pre = nextAtk;
|
||||
}
|
||||
if (list.length>=number)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else { // 暴力for循环法
|
||||
|
||||
// V2.5.3以后,大数据改为二分法进行计算
|
||||
var LOOP_MAX_VALUE = 1;
|
||||
pre = info.damage;
|
||||
if (hero_atk <= LOOP_MAX_VALUE) { // 循环法
|
||||
for (var atk=hero_atk+1;atk<=mon_hp+mon_def;atk++) {
|
||||
var nextInfo = this.getDamageInfo(enemy, core.status.hero.hp, atk, core.status.hero.def, core.status.hero.mdef, x, y, floorId);
|
||||
if (nextInfo==null || (typeof nextInfo == 'number')) break;
|
||||
if (pre>nextInfo.damage) {
|
||||
pre = nextInfo.damage;
|
||||
list.push([atk-hero_atk, info.damage-nextInfo.damage]);
|
||||
if (nextInfo.damage<=0 && !core.flags.enableNegativeDamage) break;
|
||||
if (list.length>=number) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else { // 二分法算临界
|
||||
var calNext = function (currAtk, maxAtk) {
|
||||
var start = Math.floor(currAtk), end = Math.floor(maxAtk);
|
||||
if (start>end) return null;
|
||||
|
||||
while (start<end) {
|
||||
var mid = Math.floor((start+end)/2);
|
||||
var nextInfo = core.enemys.getDamageInfo(enemy, core.status.hero.hp, mid, core.status.hero.def, core.status.hero.mdef, x, y, floorId);
|
||||
if (nextInfo == null || (typeof nextInfo == 'number')) return null;
|
||||
if (pre>nextInfo.damage) end = mid;
|
||||
else start = mid+1;
|
||||
}
|
||||
var nextInfo = core.enemys.getDamageInfo(enemy, core.status.hero.hp, start, core.status.hero.def, core.status.hero.mdef, x, y, floorId);
|
||||
return nextInfo==null||(typeof nextInfo == 'number')||nextInfo.damage>=pre?null:[start,nextInfo.damage];
|
||||
}
|
||||
var currAtk = hero_atk;
|
||||
while (true) {
|
||||
var next = calNext(currAtk+1, mon_hp+mon_def, pre);
|
||||
if (next == null) break;
|
||||
currAtk = next[0];
|
||||
pre = next[1];
|
||||
list.push([currAtk-hero_atk, info.damage-pre]);
|
||||
if (pre<=0 && !core.flags.enableNegativeDamage) break;
|
||||
if (list.length>=number) break;
|
||||
}
|
||||
enemys.prototype._nextCriticals_useLoop = function (enemy, info, number, x, y, floorId) {
|
||||
var mon_hp = info.mon_hp, hero_atk = core.status.hero.atk, mon_def = info.mon_def, pre = info.damage;
|
||||
var list = [];
|
||||
for (var atk=hero_atk+1;atk<=mon_hp+mon_def;atk++) {
|
||||
var nextInfo = this.getDamageInfo(enemy, {"atk": atk}, x, y, floorId);
|
||||
if (nextInfo==null || (typeof nextInfo == 'number')) break;
|
||||
if (pre>nextInfo.damage) {
|
||||
pre = nextInfo.damage;
|
||||
list.push([atk-hero_atk, info.damage-nextInfo.damage]);
|
||||
if (nextInfo.damage<=0 && !core.flags.enableNegativeDamage) break;
|
||||
if (list.length>=number) break;
|
||||
}
|
||||
}
|
||||
if (list.length==0) list.push([0,0]);
|
||||
return list;
|
||||
}
|
||||
|
||||
enemys.prototype._nextCriticals_useBinarySearch = function (enemy, info, number, x, y, floorId) {
|
||||
var mon_hp = info.mon_hp, hero_atk = core.status.hero.atk, mon_def = info.mon_def, pre = info.damage;
|
||||
var list = [];
|
||||
var calNext = function (currAtk, maxAtk) {
|
||||
var start = Math.floor(currAtk), end = Math.floor(maxAtk);
|
||||
if (start>end) return null;
|
||||
|
||||
while (start<end) {
|
||||
var mid = Math.floor((start+end)/2);
|
||||
var nextInfo = core.enemys.getDamageInfo(enemy, {"atk": mid}, x, y, floorId);
|
||||
if (nextInfo == null || (typeof nextInfo == 'number')) return null;
|
||||
if (pre>nextInfo.damage) end = mid;
|
||||
else start = mid+1;
|
||||
}
|
||||
var nextInfo = core.enemys.getDamageInfo(enemy, {"atk": start}, x, y, floorId);
|
||||
return nextInfo==null||(typeof nextInfo == 'number')||nextInfo.damage>=pre?null:[start,nextInfo.damage];
|
||||
}
|
||||
var currAtk = hero_atk;
|
||||
while (true) {
|
||||
var next = calNext(currAtk+1, mon_hp+mon_def, pre);
|
||||
if (next == null) break;
|
||||
currAtk = next[0];
|
||||
pre = next[1];
|
||||
list.push([currAtk-hero_atk, info.damage-pre]);
|
||||
if (pre<=0 && !core.flags.enableNegativeDamage) break;
|
||||
if (list.length>=number) break;
|
||||
}
|
||||
if (list.length==0) list.push([0,0]);
|
||||
return list;
|
||||
}
|
||||
|
||||
enemys.prototype._nextCriticals_useTurn = function (enemy, info, number, x, y, floorId) {
|
||||
var mon_hp = info.mon_hp, hero_atk = core.status.hero.atk, mon_def = info.mon_def, turn = info.turn;
|
||||
var list = [], pre = null;
|
||||
for (var t = turn-1;t>=1;t--) {
|
||||
var nextAtk = Math.ceil(mon_hp/t) + mon_def;
|
||||
// 装备提升比例的计算临界
|
||||
nextAtk = Math.ceil(nextAtk / core.getFlag('__atk_buff__', 1));
|
||||
if (nextAtk<=hero_atk) break;
|
||||
if (nextAtk!=pre) {
|
||||
var nextInfo = this.getDamageInfo(enemy, {"atk": nextAtk}, x, y, floorId);
|
||||
if (nextInfo==null || (typeof nextInfo == 'number')) break;
|
||||
list.push([nextAtk-hero_atk,Math.floor(info.damage-nextInfo.damage)]);
|
||||
if (nextInfo.damage<=0 && !core.flags.enableNegativeDamage) break;
|
||||
pre = nextAtk;
|
||||
}
|
||||
if (list.length>=number)
|
||||
break;
|
||||
}
|
||||
if (list.length==0) list.push([0,0]);
|
||||
return list;
|
||||
}
|
||||
|
||||
////// 接下来N个临界值和临界减伤计算 //////
|
||||
enemys.prototype.nextCriticals = function (enemy, number, x, y, floorId) {
|
||||
if (typeof enemy == 'string') enemy = core.material.enemys[enemy];
|
||||
number = number||1;
|
||||
|
||||
if (this.hasSpecial(enemy.special, 10)) return []; // 模仿怪物临界
|
||||
var info = this.getDamageInfo(enemy, null, x, y, floorId);
|
||||
if (info == null || this.hasSpecial(enemy.special, 3)) { // 未破防,或是坚固怪
|
||||
info = this.getEnemyInfo(enemy, null, x, y, floorId);
|
||||
if (core.status.hero.atk<=info.def) {
|
||||
return [[info.def+1-core.status.hero.atk,'?']];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
// getDamageInfo直接返回数字;0伤且无负伤
|
||||
if (typeof info == 'number' || (info.damage<=0 && !core.flags.enableNegativeDamage)) {
|
||||
return [[0,0]];
|
||||
}
|
||||
|
||||
if (core.flags.useLoop) {
|
||||
var LOOP_MAX_VALUE = 1;
|
||||
if (core.status.hero.atk <= LOOP_MAX_VALUE) {
|
||||
return this._nextCriticals_useLoop(enemy, info, number, x, y, floorId);
|
||||
}
|
||||
else {
|
||||
return this._nextCriticals_useBinarySearch(enemy, info, number, x, y, floorId);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return this._nextCriticals_useTurn(enemy, info, number, x, y, floorId);
|
||||
}
|
||||
}
|
||||
|
||||
////// N防减伤计算 //////
|
||||
enemys.prototype.getDefDamage = function (enemy, k, x, y, floorId) {
|
||||
if (typeof enemy == 'string') enemy = core.material.enemys[enemy];
|
||||
k = k || 1;
|
||||
var nowDamage = this.calDamage(enemy, core.status.hero.hp, core.status.hero.atk, core.status.hero.def, core.status.hero.mdef, x, y, floorId);
|
||||
var nextDamage = this.calDamage(enemy, core.status.hero.hp, core.status.hero.atk, core.status.hero.def + k, core.status.hero.mdef, x, y, floorId);
|
||||
var nowDamage = this.calDamage(enemy, null, x, y, floorId);
|
||||
var nextDamage = this.calDamage(enemy, {"def": core.status.hero.def + k}, x, y, floorId);
|
||||
if (nowDamage == null || nextDamage ==null) return "???";
|
||||
return nowDamage - nextDamage;
|
||||
}
|
||||
|
||||
enemys.prototype.getEnemyInfo = function (enemy, hero_hp, hero_atk, hero_def, hero_mdef, x, y, floorId) {
|
||||
enemys.prototype.getEnemyInfo = function (enemy, hero, x, y, floorId) {
|
||||
if (typeof enemy == 'string') enemy = core.material.enemys[enemy];
|
||||
return this.enemydata.getEnemyInfo(enemy, hero_hp, hero_atk, hero_def, hero_mdef, x, y, floorId)
|
||||
return this.enemydata.getEnemyInfo(enemy, hero, x, y, floorId)
|
||||
}
|
||||
|
||||
////// 获得战斗伤害信息(实际伤害计算函数) //////
|
||||
enemys.prototype.getDamageInfo = function(enemy, hero_hp, hero_atk, hero_def, hero_mdef, x, y, floorId) {
|
||||
enemys.prototype.getDamageInfo = function(enemy, hero, x, y, floorId) {
|
||||
// 移动到了脚本编辑 - getDamageInfo中
|
||||
if (typeof enemy == 'string') enemy = core.material.enemys[enemy];
|
||||
return this.enemydata.getDamageInfo(enemy, hero_hp, hero_atk, hero_def, hero_mdef, x, y, floorId);
|
||||
return this.enemydata.getDamageInfo(enemy, hero, x, y, floorId);
|
||||
}
|
||||
|
||||
////// 获得在某个勇士属性下怪物伤害 //////
|
||||
enemys.prototype.calDamage = function (enemy, hero_hp, hero_atk, hero_def, hero_mdef, x, y, floorId) {
|
||||
enemys.prototype.calDamage = function (enemy, hero, x, y, floorId) {
|
||||
if (typeof enemy == 'string') enemy = core.material.enemys[enemy];
|
||||
|
||||
var info = this.getDamageInfo(enemy, hero_hp, hero_atk, hero_def, hero_mdef, x, y, floorId);
|
||||
var info = this.getDamageInfo(enemy, hero, x, y, floorId);
|
||||
if (info == null) return null;
|
||||
if (typeof info == 'number') return info;
|
||||
return info.damage;
|
||||
@ -308,57 +299,56 @@ enemys.prototype.updateEnemys = function () {
|
||||
////// 获得当前楼层的怪物列表 //////
|
||||
enemys.prototype.getCurrentEnemys = function (floorId) {
|
||||
floorId=floorId||core.status.floorId;
|
||||
var enemys = [];
|
||||
var used = {};
|
||||
var enemys = [], used = {};
|
||||
var mapBlocks = core.status.maps[floorId].blocks;
|
||||
for (var b = 0; b < mapBlocks.length; b++) {
|
||||
if (core.isset(mapBlocks[b].event) && !mapBlocks[b].disable
|
||||
&& mapBlocks[b].event.cls.indexOf('enemy')==0) {
|
||||
var enemyId = mapBlocks[b].event.id;
|
||||
|
||||
var enemy = core.material.enemys[enemyId];
|
||||
if (!core.isset(enemy)) continue;
|
||||
|
||||
// 检查displayIdInBook
|
||||
var tmpId = enemy.displayIdInBook;
|
||||
if (core.isset(core.material.enemys[tmpId])) {
|
||||
enemyId = tmpId;
|
||||
enemy = core.material.enemys[tmpId];
|
||||
}
|
||||
if (core.isset(used[enemyId])) continue;
|
||||
|
||||
var mon_hp = enemy.hp, mon_atk = enemy.atk, mon_def = enemy.def;
|
||||
var hero_atk = core.status.hero.atk, hero_def = core.status.hero.def, hero_mdef = core.status.hero.mdef;
|
||||
|
||||
hero_atk = Math.floor(core.getFlag('equip_atk_buff',1)*hero_atk);
|
||||
hero_def = Math.floor(core.getFlag('equip_def_buff',1)*hero_def);
|
||||
hero_mdef = Math.floor(core.getFlag('equip_mdef_buff',1)*hero_mdef);
|
||||
|
||||
var enemyInfo = this.getEnemyInfo(enemy, core.status.hero.hp, hero_atk, hero_def, hero_mdef, null, null, floorId);
|
||||
|
||||
var specialText = core.enemys.getSpecialText(enemyId);
|
||||
if (specialText.length>=3) specialText = "多属性...";
|
||||
else specialText = specialText.join(" ");
|
||||
|
||||
var critical = this.nextCriticals(enemyId, 1, null, null, floorId);
|
||||
if (critical.length>0) critical=critical[0];
|
||||
|
||||
var e = core.clone(enemy);
|
||||
for (var x in enemyInfo) {
|
||||
e[x] = enemyInfo[x];
|
||||
}
|
||||
e.id = enemyId;
|
||||
e.specialText = specialText;
|
||||
e.damage = this.getDamage(enemyId, null, null, floorId);
|
||||
e.critical = critical[0];
|
||||
e.criticalDamage = critical[1];
|
||||
e.defDamage = this.getDefDamage(enemyId,1,null,null,floorId);
|
||||
enemys.push(e);
|
||||
used[enemyId] = true;
|
||||
this._getCurrentEnemys_addEnemy(mapBlocks[b].event.id, enemys, used, floorId);
|
||||
}
|
||||
}
|
||||
return this._getCurrentEnemys_sort(enemys);
|
||||
}
|
||||
|
||||
enemys.sort(function (a, b) {
|
||||
enemys.prototype._getCurrentEnemys_getEnemy = function (enemyId) {
|
||||
var enemy = core.material.enemys[enemyId];
|
||||
if (!core.isset(enemy)) return null;
|
||||
|
||||
// 检查displayIdInBook
|
||||
var tmpId = enemy.displayIdInBook;
|
||||
if (core.isset(core.material.enemys[tmpId])) {
|
||||
enemy = core.material.enemys[tmpId];
|
||||
}
|
||||
return enemy;
|
||||
}
|
||||
|
||||
enemys.prototype._getCurrentEnemys_addEnemy = function (enemyId, enemys, used, floorId) {
|
||||
var enemy = this._getCurrentEnemys_getEnemy(enemyId);
|
||||
if (enemy==null || used[enemy.id]) return;
|
||||
|
||||
var enemyInfo = this.getEnemyInfo(enemy, null, null, null, floorId);
|
||||
var specialText = core.enemys.getSpecialText(enemy);
|
||||
if (specialText.length>=3) specialText = "多属性...";
|
||||
else specialText = specialText.join(" ");
|
||||
|
||||
var critical = this.nextCriticals(enemy, 1, null, null, floorId);
|
||||
if (critical.length>0) critical=critical[0];
|
||||
|
||||
var e = core.clone(enemy);
|
||||
for (var x in enemyInfo) {
|
||||
e[x] = enemyInfo[x];
|
||||
}
|
||||
e.specialText = specialText;
|
||||
e.damage = this.getDamage(enemy, null, null, floorId);
|
||||
e.critical = critical[0];
|
||||
e.criticalDamage = critical[1];
|
||||
e.defDamage = this.getDefDamage(enemy,1,null,null,floorId);
|
||||
enemys.push(e);
|
||||
used[enemy.id] = true;
|
||||
}
|
||||
|
||||
enemys.prototype._getCurrentEnemys_sort = function (enemys) {
|
||||
return enemys.sort(function (a, b) {
|
||||
if (a.damage == b.damage) {
|
||||
return a.money - b.money;
|
||||
}
|
||||
@ -370,5 +360,4 @@ enemys.prototype.getCurrentEnemys = function (floorId) {
|
||||
}
|
||||
return a.damage - b.damage;
|
||||
});
|
||||
return enemys;
|
||||
}
|
||||
@ -13,7 +13,16 @@ icons.prototype._init = function () {
|
||||
}
|
||||
|
||||
icons.prototype.getIcons = function () {
|
||||
return this.icons;
|
||||
return core.clone(this.icons);
|
||||
}
|
||||
|
||||
////// 根据道具ID获得其cls //////
|
||||
icons.prototype.getClsFromId = function (id) {
|
||||
for (var cls in core.material.icons) {
|
||||
if (cls != 'hero' && id in core.material.icons[cls])
|
||||
return cls;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
////// 根据图块数字或ID获得所在的tileset和坐标信息 //////
|
||||
|
||||
@ -265,14 +265,12 @@ items.prototype._loadEquipEffect = function (equipId, unloadEquipId, isPercentag
|
||||
var result = core.compareEquipment(equipId, unloadEquipId);
|
||||
|
||||
if (isPercentage) {
|
||||
core.setFlag('equip_atk_buff', core.getFlag('equip_atk_buff',1)+result.atk/100);
|
||||
core.setFlag('equip_def_buff', core.getFlag('equip_def_buff',1)+result.def/100);
|
||||
core.setFlag('equip_mdef_buff', core.getFlag('equip_mdef_buff',1)+result.mdef/100);
|
||||
for (var v in result)
|
||||
core.addFlag('__'+v+'_buff__', result[v]/100);
|
||||
}
|
||||
else {
|
||||
core.status.hero.atk += result.atk;
|
||||
core.status.hero.def += result.def;
|
||||
core.status.hero.mdef += result.mdef;
|
||||
for (var v in result)
|
||||
core.status.hero[v] += result[v];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1985,7 +1985,7 @@ ui.prototype.drawEquipbox = function(index) {
|
||||
if (compare[name]<0) color = '#FF0000';
|
||||
var nowValue = core.getStatus(name), newValue = nowValue + compare[name];
|
||||
if (equip.equip.percentage) {
|
||||
var nowBuff = core.getFlag('equip_'+name+"_buff",1), newBuff = nowBuff+compare[name]/100;
|
||||
var nowBuff = core.getFlag('__'+name+"_buff__", 1), newBuff = nowBuff+compare[name]/100;
|
||||
nowValue = Math.floor(nowBuff*core.getStatus(name));
|
||||
newValue = Math.floor(newBuff*core.getStatus(name));
|
||||
}
|
||||
|
||||
@ -102,14 +102,14 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 =
|
||||
"text": ">=1:直接扣数值"
|
||||
},
|
||||
{
|
||||
"type": "setValue",
|
||||
"type": "setValue2",
|
||||
"name": "status:atk",
|
||||
"value": "status:atk-core.values.weakValue"
|
||||
"value": "-core.values.weakValue"
|
||||
},
|
||||
{
|
||||
"type": "setValue",
|
||||
"type": "setValue2",
|
||||
"name": "status:def",
|
||||
"value": "status:def-core.values.weakValue"
|
||||
"value": "-core.values.weakValue"
|
||||
}
|
||||
],
|
||||
"false": [
|
||||
@ -118,14 +118,14 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 =
|
||||
"text": "<1:扣比例"
|
||||
},
|
||||
{
|
||||
"type": "setValue",
|
||||
"name": "flag:equip_atk_buff",
|
||||
"value": "core.getFlag('equip_atk_buff',1)-core.values.weakValue"
|
||||
"type": "setValue2",
|
||||
"name": "flag:__atk_buff__",
|
||||
"value": "-core.values.weakValue"
|
||||
},
|
||||
{
|
||||
"type": "setValue",
|
||||
"name": "flag:equip_def_buff",
|
||||
"value": "core.getFlag('equip_def_buff',1)-core.values.weakValue"
|
||||
"type": "setValue2",
|
||||
"name": "flag:__def_buff__",
|
||||
"value": "-core.values.weakValue"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@ -34,22 +34,28 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
|
||||
},
|
||||
"setInitData": function (hard) {
|
||||
// 不同难度分别设置初始属性
|
||||
if (hard=='Easy') { // 简单难度
|
||||
if (hard == 'Easy') { // 简单难度
|
||||
core.setFlag('hard', 1); // 可以用flag:hard来获得当前难度
|
||||
// 可以在此设置一些初始福利,比如设置初始生命值可以调用:
|
||||
// core.setStatus("hp", 10000);
|
||||
// 赠送一把黄钥匙可以调用
|
||||
// core.setItem("yellowKey", 1);
|
||||
}
|
||||
if (hard=='Normal') { // 普通难度
|
||||
if (hard == 'Normal') { // 普通难度
|
||||
core.setFlag('hard', 2); // 可以用flag:hard来获得当前难度
|
||||
}
|
||||
if (hard=='Hard') { // 困难难度
|
||||
if (hard == 'Hard') { // 困难难度
|
||||
core.setFlag('hard', 3); // 可以用flag:hard来获得当前难度
|
||||
}
|
||||
if (hard=='Hell') { // 噩梦难度
|
||||
if (hard == 'Hell') { // 噩梦难度
|
||||
core.setFlag('hard', 4); // 可以用flag:hard来获得当前难度
|
||||
}
|
||||
|
||||
// 设置三围的初始增幅属性(均为1)
|
||||
["atk", "def", "mdef"].forEach(function (name) {
|
||||
core.setFlag("__" + name + "_buff__", 1);
|
||||
});
|
||||
|
||||
core.events.afterLoadData();
|
||||
},
|
||||
"win": function(reason, norank) {
|
||||
@ -461,7 +467,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
|
||||
[27, "捕捉", "当走到怪物周围十字时会强制进行战斗。"]
|
||||
];
|
||||
},
|
||||
"getEnemyInfo": function (enemy, hero_hp, hero_atk, hero_def, hero_mdef, x, y, floorId) {
|
||||
"getEnemyInfo": function (enemy, hero, x, y, floorId) {
|
||||
// 获得某个怪物变化后的数据;该函数将被伤害计算和怪物手册使用
|
||||
// 例如:坚固、模仿、仿攻等等
|
||||
//
|
||||
@ -472,6 +478,11 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
|
||||
// floorId:该怪物所在的楼层
|
||||
// 后面三个参数主要是可以在光环等效果上可以适用(也可以按需制作部分范围光环效果)
|
||||
floorId = floorId || core.status.floorId;
|
||||
var hero_hp = core.getRealStatusOrDefault(hero, 'hp'),
|
||||
hero_atk = core.getRealStatusOrDefault(hero, 'atk'),
|
||||
hero_def = core.getRealStatusOrDefault(hero, 'def'),
|
||||
hero_mdef = core.getRealStatusOrDefault(hero, 'mdef');
|
||||
|
||||
var mon_hp = enemy.hp,
|
||||
mon_atk = enemy.atk,
|
||||
mon_def = enemy.def,
|
||||
@ -566,18 +577,22 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
|
||||
"guards": guards, // 返回支援情况
|
||||
};
|
||||
},
|
||||
"getDamageInfo": function (enemy, hero_hp, hero_atk, hero_def, hero_mdef, x, y, floorId) {
|
||||
"getDamageInfo": function (enemy, hero, x, y, floorId) {
|
||||
// 获得战斗伤害信息(实际伤害计算函数)
|
||||
//
|
||||
// 参数说明:
|
||||
// enemy:该怪物信息
|
||||
// hero_hp,hero_atk,hero_def,hero_mdef:勇士的生命攻防魔防数据
|
||||
// hero:勇士的当前数据;如果对应项不存在则会从core.status.hero中取。
|
||||
// x,y:该怪物的坐标(查看手册和强制战斗时为undefined)
|
||||
// floorId:该怪物所在的楼层
|
||||
// 后面三个参数主要是可以在光环等效果上可以适用
|
||||
floorId = floorId || core.status.floorId;
|
||||
|
||||
var origin_hero_hp = hero_hp,
|
||||
var hero_hp = core.getRealStatusOrDefault(hero, 'hp'),
|
||||
hero_atk = core.getRealStatusOrDefault(hero, 'atk'),
|
||||
hero_def = core.getRealStatusOrDefault(hero, 'def'),
|
||||
hero_mdef = core.getRealStatusOrDefault(hero, 'mdef'),
|
||||
origin_hero_hp = hero_hp,
|
||||
origin_hero_atk = hero_atk,
|
||||
origin_hero_def = hero_def;
|
||||
|
||||
@ -587,14 +602,9 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
|
||||
hero_def = Math.max(0, hero_def);
|
||||
hero_mdef = Math.max(0, hero_mdef);
|
||||
|
||||
// 计算装备按比例增加属性后的数值
|
||||
hero_atk = Math.floor(core.getFlag('equip_atk_buff', 1) * hero_atk);
|
||||
hero_def = Math.floor(core.getFlag('equip_def_buff', 1) * hero_def);
|
||||
hero_mdef = Math.floor(core.getFlag('equip_mdef_buff', 1) * hero_mdef);
|
||||
|
||||
// 怪物的各项数据
|
||||
// 对坚固模仿等处理扔到了脚本编辑-getEnemyInfo之中
|
||||
var enemyInfo = core.enemys.getEnemyInfo(enemy, hero_hp, hero_atk, hero_def, hero_mdef, x, y, floorId);
|
||||
var enemyInfo = core.enemys.getEnemyInfo(enemy, hero, x, y, floorId);
|
||||
var mon_hp = enemyInfo.hp,
|
||||
mon_atk = enemyInfo.atk,
|
||||
mon_def = enemyInfo.def,
|
||||
@ -949,12 +959,10 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
|
||||
// 向下取整
|
||||
if (core.isset(core.status.hero[item]))
|
||||
core.status.hero[item] = Math.floor(core.status.hero[item]);
|
||||
// 装备按比例增加属性
|
||||
var value = Math.floor(core.getStatus(item)*core.getFlag('equip_'+item+'_buff',1));
|
||||
// 大数据格式化;
|
||||
core.statusBar[item].innerHTML = core.formatBigNumber(value);
|
||||
core.statusBar[item].innerHTML = core.formatBigNumber(core.getRealStatus(item));
|
||||
});
|
||||
|
||||
|
||||
// 设置魔力值
|
||||
if (core.flags.enableMana) {
|
||||
// 也可以使用flag:manaMax来表示最大魔力值;详见文档-个性化-技能塔的支持
|
||||
@ -973,14 +981,13 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
|
||||
// 如果是自定义添加的状态栏,也需要在这里进行设置显示的数值
|
||||
|
||||
// 进阶
|
||||
if (core.flags.enableLevelUp && core.status.hero.lv<core.firstData.levelUp.length) {
|
||||
if (core.flags.enableLevelUp && core.status.hero.lv < core.firstData.levelUp.length) {
|
||||
var need = core.calValue(core.firstData.levelUp[core.status.hero.lv].need);
|
||||
if (core.flags.levelUpLeftMode)
|
||||
core.statusBar.up.innerHTML = core.formatBigNumber(need - core.getStatus('experience')) || " ";
|
||||
else
|
||||
core.statusBar.up.innerHTML = core.formatBigNumber(need) || " ";
|
||||
}
|
||||
else core.statusBar.up.innerHTML = " ";
|
||||
} else core.statusBar.up.innerHTML = " ";
|
||||
|
||||
// 钥匙
|
||||
var keys = ['yellowKey', 'blueKey', 'redKey'];
|
||||
@ -988,16 +995,16 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
|
||||
core.statusBar[key].innerHTML = core.setTwoDigits(core.status.hero.items.keys[key]);
|
||||
});
|
||||
// 毒衰咒
|
||||
if(core.flags.enableDebuff){
|
||||
core.statusBar.poison.innerHTML = core.hasFlag('poison')?"毒":"";
|
||||
core.statusBar.weak.innerHTML = core.hasFlag('weak')?"衰":"";
|
||||
core.statusBar.curse.innerHTML = core.hasFlag('curse')?"咒":"";
|
||||
if (core.flags.enableDebuff) {
|
||||
core.statusBar.poison.innerHTML = core.hasFlag('poison') ? "毒" : "";
|
||||
core.statusBar.weak.innerHTML = core.hasFlag('weak') ? "衰" : "";
|
||||
core.statusBar.curse.innerHTML = core.hasFlag('curse') ? "咒" : "";
|
||||
}
|
||||
// 破炸飞
|
||||
if (core.flags.enablePZF) {
|
||||
core.statusBar.pickaxe.innerHTML = "破"+core.itemCount('pickaxe');
|
||||
core.statusBar.bomb.innerHTML = "炸"+core.itemCount('bomb');
|
||||
core.statusBar.fly.innerHTML = "飞"+core.itemCount('centerFly');
|
||||
core.statusBar.pickaxe.innerHTML = "破" + core.itemCount('pickaxe');
|
||||
core.statusBar.bomb.innerHTML = "炸" + core.itemCount('bomb');
|
||||
core.statusBar.fly.innerHTML = "飞" + core.itemCount('centerFly');
|
||||
}
|
||||
|
||||
// 难度
|
||||
|
||||
@ -372,9 +372,9 @@ var items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a =
|
||||
"upFly": "var loc = {'direction': core.status.hero.loc.direction, 'x': core.status.event.ui.x, 'y': core.status.event.ui.y};\nif (core.status.event.id == 'action') {\n\tcore.insertAction([\n\t\t{\"type\": \"changeFloor\", \"loc\": [loc.x, loc.y], \"direction\": loc.direction, \"floorId\": core.status.event.ui.id},\n\t\t{\"type\": \"tip\", \"text\": core.material.items[itemId].name + '使用成功'}\n\t]);\n}\nelse {\n\tcore.changeFloor(core.status.event.ui.id, null, loc, null, function (){\n\tcore.drawTip(core.material.items[itemId].name + '使用成功');\n\t\tcore.replay();\n\t});\n}",
|
||||
"downFly": "var loc = {'direction': core.status.hero.loc.direction, 'x': core.status.event.ui.x, 'y': core.status.event.ui.y};\nif (core.status.event.id == 'action') {\n\tcore.insertAction([\n\t\t{\"type\": \"changeFloor\", \"loc\": [loc.x, loc.y], \"direction\": loc.direction, \"floorId\": core.status.event.ui.id},\n\t\t{\"type\": \"tip\", \"text\": core.material.items[itemId].name + '使用成功'}\n\t]);\n}\nelse {\n\tcore.changeFloor(core.status.event.ui.id, null, loc, null, function (){\n\tcore.drawTip(core.material.items[itemId].name + '使用成功');\n\t\tcore.replay();\n\t});\n}\n",
|
||||
"poisonWine": "core.removeFlag('poison');",
|
||||
"weakWine": "core.removeFlag('weak');\nif (core.values.weakValue>=1) { // >=1:直接扣数值\n\tcore.status.hero.atk += core.values.weakValue;\n\tcore.status.hero.def += core.values.weakValue;\n}\nelse { // <1:扣比例\n\tcore.setFlag(\"equip_atk_buff\", core.getFlag(\"equip_atk_buff\", 1) + core.values.weakValue);\n\tcore.setFlag(\"equip_def_buff\", core.getFlag(\"equip_def_buff\", 1) + core.values.weakValue);\n}",
|
||||
"weakWine": "core.removeFlag('weak');\nif (core.values.weakValue>=1) { // >=1:直接扣数值\n\tcore.status.hero.atk += core.values.weakValue;\n\tcore.status.hero.def += core.values.weakValue;\n}\nelse { // <1:扣比例\n\tcore.addFlag(\"__atk_buff__\", core.values.weakValue);\n\tcore.addFlag(\"__def_buff__\", core.values.weakValue);\n}",
|
||||
"curseWine": "core.removeFlag('curse');",
|
||||
"superWine": "core.removeFlag('poison');\nif (core.hasFlag('weak')) {\n\tcore.removeFlag('weak');\n\tif (core.values.weakValue>=1) { // >=1:直接扣数值\n\t\tcore.status.hero.atk += core.values.weakValue;\n\t\tcore.status.hero.def += core.values.weakValue;\n\t}\n\telse { // <1:扣比例\n\t\tcore.setFlag(\"equip_atk_buff\", core.getFlag(\"equip_atk_buff\", 1) + core.values.weakValue);\n\t\tcore.setFlag(\"equip_def_buff\", core.getFlag(\"equip_def_buff\", 1) + core.values.weakValue);\n\t}\n}\ncore.removeFlag('curse');",
|
||||
"superWine": "core.removeFlag('poison');\nif (core.hasFlag('weak')) {\n\tcore.removeFlag('weak');\n\tif (core.values.weakValue>=1) { // >=1:直接扣数值\n\t\tcore.status.hero.atk += core.values.weakValue;\n\t\tcore.status.hero.def += core.values.weakValue;\n\t}\n\telse { // <1:扣比例\n\t\tcore.addFlag(\"__atk_buff__\", core.values.weakValue);\n\t\tcore.addFlag(\"__def_buff__\", core.values.weakValue);\n\t}\n}\ncore.removeFlag('curse');",
|
||||
"lifeWand": "core.insertAction([\n\t{\"type\": \"input\", \"text\": \"请输入生命魔杖使用次数:(0-${item:lifeWand})\"},\n\t{\"type\": \"if\", \"condition\": \"flag:input<=item:lifeWand\",\n\t\t\"true\": [\n\t\t\t{\"type\": \"setValue\", \"name\": \"item:lifeWand\", \"value\": \"item:lifeWand-flag:input\"},\n\t\t\t{\"type\": \"setValue\", \"name\": \"status:hp\", \"value\": \"status:hp+flag:input*100\"},\n\t\t\t\"成功使用${flag:input}次生命魔杖,恢复${flag:input*100}点生命。\"\n\t\t],\n\t\t\"false\": [\"输入不合法!\"]\n\t},\n]);\ncore.addItem('lifeWand', 1);",
|
||||
"jumpShoes": "core.insertAction({\"type\":\"jumpHero\",\"loc\":[core.nextX(2),core.nextY(2)]});",
|
||||
"redPotion": "core.status.hero.hp += core.values.redPotion",
|
||||
|
||||
Loading…
Reference in New Issue
Block a user