diff --git a/_server/MotaAction.g4 b/_server/MotaAction.g4 index 1aa58715..1fa52eba 100644 --- a/_server/MotaAction.g4 +++ b/_server/MotaAction.g4 @@ -65,6 +65,7 @@ return code; shoplist : shopsub + | shopcommonevent | emptyshop ; @@ -77,6 +78,24 @@ var code = ' \n'; return code; */; +shopcommonevent + : '商店 id' IdString '快捷商店栏中名称' EvalString BGNL? '未开启状态则不显示在列表中' Bool BGNL? '执行的公共事件 id' EvalString '参数列表' EvalString? + +/* shopcommonevent +tooltip : 全局商店, 执行一个公共事件 +helpUrl : https://h5mota.com/games/template/docs/#/ +default : ["shop1","回收钥匙商店",false,"回收钥匙商店",""] +var code = { + 'id': IdString_0, + 'textInList': EvalString_0, + 'mustEnable': Bool_0, + 'commonEvent': EvalString_1, + 'args': EvalString_2 +} +code=JSON.stringify(code,null,2)+',\n'; +return code; +*/; + shopsub : '商店 id' IdString '标题' EvalString '图标' IdString BGNL? Newline '快捷商店栏中名称' EvalString '共用times' Bool BGNL? Newline '未开启状态则不显示在列表中' Bool BGNL? NewLine '使用' ShopUse_List '消耗' EvalString BGNL? Newline '显示文字' EvalString BGNL? Newline shopChoices+ BEND @@ -303,6 +322,7 @@ action | callBook_s | callSave_s | callLoad_s + | unknow_s | function_s | pass_s ; @@ -1726,6 +1746,19 @@ var code = '{"type": "callLoad"},\n'; return code; */; +unknow_s + : '自定义事件' BGNL? RawEvalString + +/* unknow_s +tooltip : 通过脚本自定义的事件类型, 以及编辑器不识别的事件类型 +helpUrl : https://h5mota.com/games/template/docs/#/ +default : ['{"type":"eventType1"}'] +colour : this.dataColor +var tempobj={}; +eval("tempobj='"+RawEvalString_0+"'"); +var code = tempobj +',\n'; +return code; +*/; function_s : '自定义JS脚本' '不自动执行下一个事件' Bool BGNL? Newline RawEvalString Newline BEND Newline @@ -2114,10 +2147,21 @@ ActionParser.prototype.parse = function (obj,type) { obj.id,obj.name,obj.icon,obj.textInList,obj.commonTimes,obj.mustEnable,obj.use,obj.need,parser.EvalString(obj.text),text_choices,next ]); } + var buildcommentevent = function(obj,parser,next){ + return MotaActionBlocks['shopcommonevent'].xmlText([ + obj.id,parser.EvalString(obj.textInList),obj.mustEnable,parser.EvalString(obj.commonEvent),parser.EvalString(obj.args),next + ]); + } var next=null; if(!obj)obj=[]; while(obj.length){ - next=buildsub(obj.pop(),this,next); + var shopobj=obj.pop() + if(shopobj.choices) + next=buildsub(shopobj,this,next); + else if(shopobj.commonEvent) + next=buildcommentevent(shopobj,this,next); + else + throw new Error("[警告]出错啦!\n"+shopobj.id+" 无效的商店"); } return MotaActionBlocks['shop_m'].xmlText([next]); @@ -2607,7 +2651,13 @@ ActionParser.prototype.parseAction = function() { case "animateImage": // 兼容 animateImage break; default: - throw new Error("[警告]出错啦!\n"+data.type+" 事件不被支持..."); + var rawdata = JSON.stringify(data,function(k,v){ + if(typeof(v)=='string')return v.split('\n').join('\\n'); + else return v; + },2); + rawdata=rawdata.split('\n').join('\\n'); + this.next = MotaActionBlocks['unknow_s'].xmlText([ + rawdata,this.next]); } this.parseAction(); return; diff --git a/_server/comment.js b/_server/comment.js index cdf576e4..d4c1ac53 100644 --- a/_server/comment.js +++ b/_server/comment.js @@ -227,8 +227,8 @@ var comment_c456ea59_6018_45ef_8bcc_211a24c627dc = "openDoor", "passNet", "changeLight", - "ski", - "pushBox" + "pushBox", + "custom" ] }, "_data": "该图块的默认触发器" diff --git a/_server/editor_blockly.js b/_server/editor_blockly.js index 9ebabaac..92ecfee2 100644 --- a/_server/editor_blockly.js +++ b/_server/editor_blockly.js @@ -37,6 +37,11 @@ editor_blockly = function () { {"text": "防御+4", "effect": "status:def+=4"}, {"text": "魔防+10", "effect": "status:mdef+=10"} ] + },{ + "id": "keyShop1", + "textInList": "回收钥匙商店", + "commonEvent": "回收钥匙商店", + "args": "" }],'shop'), MotaActionBlocks['afterBattle_m'].xmlText(), MotaActionBlocks['afterGetItem_m'].xmlText(), @@ -583,6 +588,7 @@ function omitedcheckUpdateFunction(event) { 'showTextImage_s': 'EvalString_0', 'function_s': 'RawEvalString_0', 'shopsub': 'EvalString_3', + 'unknow_s': 'RawEvalString_0', } var f = b ? textStringDict[b.type] : null; if (f) { diff --git a/libs/actions.js b/libs/actions.js index c8e9baeb..ad1c3c1d 100644 --- a/libs/actions.js +++ b/libs/actions.js @@ -686,8 +686,9 @@ actions.prototype._sys_onmousewheel = function (direct) { // 存读档 if (core.status.lockControl && (core.status.event.id == 'save' || core.status.event.id == 'load')) { - if (direct == 1) core.ui.drawSLPanel(core.status.event.data - 10); - if (direct == -1) core.ui.drawSLPanel(core.status.event.data + 10); + var index = core.status.event.data.page*10+core.status.event.data.offset; + if (direct == 1) core.ui.drawSLPanel(index - 10); + if (direct == -1) core.ui.drawSLPanel(index + 10); return; } @@ -1197,20 +1198,35 @@ actions.prototype._keyUpShop = function (keycode) { ////// 快捷商店界面时的点击操作 ////// actions.prototype._clickQuickShop = function (x, y) { - var shopList = core.status.shops, keys = Object.keys(shopList).filter(function (shopId) { - return shopList[shopId].visited || !shopList[shopId].mustEnable - }); + var keys = []; + if (core.flags.quickCommonEvents) { + keys = core.getFlag("__commonEventList__", []); + } + else { + keys = Object.keys(core.status.shops).filter(function (shopId) { + return core.status.shops[shopId].visited || !core.status.shops[shopId].mustEnable + }); + } + if (x >= this.CHOICES_LEFT && x <= this.CHOICES_RIGHT) { var topIndex = this.HSIZE - parseInt(keys.length / 2); if (y >= topIndex && y < topIndex + keys.length) { - var reason = core.events.canUseQuickShop(keys[y - topIndex]); - if (!core.flags.enableDisabledShop && reason) { - core.drawText(reason); - return; + if (core.flags.quickCommonEvents) { + var name = keys[y - topIndex]; + core.ui.closePanel(); + core.status.route.push("common:" + core.encodeBase64(name)); + core.insertAction(name); + } + else { + var reason = core.events.canUseQuickShop(keys[y - topIndex]); + if (!core.flags.enableDisabledShop && reason) { + core.drawText(reason); + return; + } + core.events.openShop(keys[y - topIndex], true); + if (core.status.event.id == 'shop') + core.status.event.data.fromList = true; } - core.events.openShop(keys[y - topIndex], true); - if (core.status.event.id == 'shop') - core.status.event.data.fromList = true; } // 离开 else if (y == topIndex + keys.length) @@ -1224,59 +1240,64 @@ actions.prototype._keyUpQuickShop = function (keycode) { core.ui.closePanel(); return; } - var shopList = core.status.shops, keys = Object.keys(shopList).filter(function (shopId) { - return shopList[shopId].visited || !shopList[shopId].mustEnable - }); - this._selectChoices(keys.length + 1, keycode, this._clickQuickShop); + var length = 0; + if (core.flags.quickCommonEvents) { + length = core.getFlag("__commonEventList__", []).length; + } + else { + var shopList = core.status.shops, keys = Object.keys(shopList).filter(function (shopId) { + return shopList[shopId].visited || !shopList[shopId].mustEnable + }); + length = keys.length; + } + this._selectChoices(length + 1, keycode, this._clickQuickShop); return; } ////// 工具栏界面时的点击操作 ////// actions.prototype._clickToolbox = function (x, y) { // 装备栏 - if (x >= 10 && x <= 12 && y == 0) { + if (x >= this.LAST - 2 && y == 0) { core.ui.closePanel(); core.openEquipbox(); return; } - // 返回 - if (x >= 10 && x <= 12 && y == 12) { + if (x >= this.LAST - 2 && y == this.LAST) { core.ui.closePanel(); return; } + var toolsPage = core.status.event.data.toolsPage; var constantsPage = core.status.event.data.constantsPage; // 上一页 - if (x == 3 || x == 4) { - if (y == 7 && toolsPage > 1) { + if (x == this.HSIZE-2 || x == this.HSIZE-3) { + if (y == this.LAST - 5 && toolsPage > 1) { core.status.event.data.toolsPage--; core.ui.drawToolbox(core.status.event.selection); } - if (y == 12 && constantsPage > 1) { + if (y == this.LAST && constantsPage > 1) { core.status.event.data.toolsPage--; core.ui.drawToolbox(core.status.event.selection); } } // 下一页 - if (x == 8 || x == 9) { - if (y == 7 && toolsPage < Math.ceil(Object.keys(core.status.hero.items.tools).length / 12)) { + if (x == this.HSIZE+2 || x == this.HSIZE+3) { + if (y == this.LAST - 5 && toolsPage < Math.ceil(Object.keys(core.status.hero.items.tools).length / this.LAST)) { core.status.event.data.toolsPage++; core.ui.drawToolbox(core.status.event.selection); } - if (y == 12 && constantsPage < Math.ceil(Object.keys(core.status.hero.items.constants).length / 12)) { + if (y == this.LAST && constantsPage < Math.ceil(Object.keys(core.status.hero.items.constants).length / this.LAST)) { core.status.event.data.constantsPage++; core.ui.drawToolbox(core.status.event.selection); } } var index = parseInt(x / 2); - ; - if (y == 4) index += 0; - else if (y == 6) index += 6; - else if (y == 9) index += 12; - else if (y == 11) index += 18; + if (y == this.LAST - 8) index += 0; + else if (y == this.LAST - 6) index += this.HSIZE; + else if (y == this.LAST - 3) index += this.LAST; + else if (y == this.LAST - 1) index += this.LAST + this.HSIZE; else index = -1; - if (index >= 0) this._clickToolboxIndex(index); } @@ -1285,12 +1306,12 @@ actions.prototype._clickToolbox = function (x, y) { actions.prototype._clickToolboxIndex = function (index) { var items = null; var select; - if (index < 12) { - select = index + 12 * (core.status.event.data.toolsPage - 1); + if (index < this.LAST) { + select = index + this.LAST * (core.status.event.data.toolsPage - 1); items = Object.keys(core.status.hero.items.tools).sort(); } else { - select = index % 12 + 12 * (core.status.event.data.constantsPage - 1); + select = index % this.LAST + this.LAST * (core.status.event.data.constantsPage - 1); items = Object.keys(core.status.hero.items.constants).sort(); } if (items == null) return; @@ -1308,33 +1329,35 @@ actions.prototype._clickToolboxIndex = function (index) { actions.prototype._keyDownToolbox = function (keycode) { if (core.status.event.data == null) return; + var last_index = this.LAST - 1; + var tools = Object.keys(core.status.hero.items.tools).sort(); var constants = Object.keys(core.status.hero.items.constants).sort(); var index = core.status.event.selection; var toolsPage = core.status.event.data.toolsPage; var constantsPage = core.status.event.data.constantsPage; - var toolsTotalPage = Math.ceil(tools.length / 12); - var constantsTotalPage = Math.ceil(constants.length / 12); - var toolsLastIndex = toolsPage < toolsTotalPage ? 11 : (tools.length + 11) % 12; - var constantsLastIndex = 12 + (constantsPage < constantsTotalPage ? 11 : (constants.length + 11) % 12); + var toolsTotalPage = Math.ceil(tools.length / this.LAST); + var constantsTotalPage = Math.ceil(constants.length / this.LAST); + var toolsLastIndex = toolsPage < toolsTotalPage ? last_index : (tools.length + last_index) % this.LAST; + var constantsLastIndex = this.LAST + (constantsPage < constantsTotalPage ? last_index : (constants.length + last_index) % this.LAST); if (keycode == 37) { // left if (index == 0) { // 处理向前翻页 if (toolsPage > 1) { core.status.event.data.toolsPage--; - index = 11; + index = last_index; } else return; // 第一页不向前翻 } - else if (index == 12) { + else if (index == this.LAST) { if (constantsPage == 1) { if (toolsTotalPage == 0) return; core.status.event.data.toolsPage = toolsTotalPage; - index = (tools.length + 11) % 12; + index = (tools.length + last_index) % this.LAST; } else { core.status.event.data.constantsPage--; - index = 23; + index = 2 * this.LAST - 1; } } else index -= 1; @@ -1342,29 +1365,29 @@ actions.prototype._keyDownToolbox = function (keycode) { return; } if (keycode == 38) { // up - if (index >= 12 && index <= 17) { // 进入tools + if (index >= this.LAST && index < this.LAST + this.HSIZE) { // 进入tools if (toolsTotalPage == 0) return; - if (toolsLastIndex >= 6) index = Math.min(toolsLastIndex, index - 6); - else index = Math.min(toolsLastIndex, index - 12); + if (toolsLastIndex >= this.HSIZE) index = Math.min(toolsLastIndex, index - this.HSIZE); + else index = Math.min(toolsLastIndex, index - this.LAST); } - else if (index < 6) return; // 第一行没有向上 - else index -= 6; + else if (index < this.HSIZE) return; // 第一行没有向上 + else index -= this.HSIZE; this._clickToolboxIndex(index); return; } if (keycode == 39) { // right - if (toolsPage < toolsTotalPage && index == 11) { + if (toolsPage < toolsTotalPage && index == last_index) { core.status.event.data.toolsPage++; index = 0; } - else if (constantsPage < constantsTotalPage && index == 23) { + else if (constantsPage < constantsTotalPage && index == 2 * this.LAST - 1) { core.status.event.data.constantsPage++; - index = 12; + index = this.LAST; } else if (index == toolsLastIndex) { if (constantsTotalPage == 0) return; core.status.event.data.constantsPage = 1; - index = 12; + index = this.LAST; } else if (index == constantsLastIndex) // 一个物品无操作 return; @@ -1374,16 +1397,17 @@ actions.prototype._keyDownToolbox = function (keycode) { } if (keycode == 40) { // down var nextIndex = null; - if (index <= 5) { - if (toolsLastIndex > 5) nextIndex = Math.min(toolsLastIndex, index + 6); - else index += 6; + if (index < this.HSIZE) { + if (toolsLastIndex >= this.HSIZE) nextIndex = Math.min(toolsLastIndex, index + this.HSIZE); + else index += this.HSIZE; } - if (nextIndex == null && index <= 11) { + if (nextIndex == null && index < this.LAST) { if (constantsTotalPage == 0) return; - nextIndex = Math.min(index + 6, constantsLastIndex); + nextIndex = Math.min(index + this.HSIZE, constantsLastIndex); } - if (nextIndex == null && index <= 17) { - if (constantsLastIndex > 17) nextIndex = Math.min(constantsLastIndex, index + 6); + if (nextIndex == null && index < this.LAST + this.HSIZE) { + if (constantsLastIndex >= this.LAST + this.HSIZE) + nextIndex = Math.min(constantsLastIndex, index + this.HSIZE); } if (nextIndex != null) { this._clickToolboxIndex(nextIndex); @@ -1414,64 +1438,65 @@ actions.prototype._keyUpToolbox = function (keycode) { ////// 装备栏界面时的点击操作 ////// actions.prototype._clickEquipbox = function (x, y) { // 道具栏 - if (x >= 10 && x <= 12 && y == 0) { + if (x >= this.LAST - 2 && y == 0) { core.ui.closePanel(); core.openToolbox(); return; } // 返回 - if (x >= 10 && x <= 12 && y == 12) { + if (x >= this.LAST - 2 && y == this.LAST) { core.ui.closePanel(); return; } - // 当前页面 - var page = core.status.event.data.page; - // 上一页 - if ((x == 3 || x == 4) && y == 12) { - if (page > 1) { + if ((x == this.HSIZE-2 || x == this.HSIZE-3) && y == this.LAST) { + if (core.status.event.data.page > 1) { core.status.event.data.page--; core.ui.drawEquipbox(core.status.event.selection); } return; } // 下一页 - if ((x == 8 || x == 9) && y == 12) { - var lastPage = Math.ceil(Object.keys(core.status.hero.items.equips).length / 12); - if (page < lastPage) { + if ((x == this.HSIZE+2 || x == this.HSIZE+3) && y == this.LAST) { + var lastPage = Math.ceil(Object.keys(core.status.hero.items.equips).length / this.LAST); + if (core.status.event.data.page < lastPage) { core.status.event.data.page++; core.ui.drawEquipbox(core.status.event.selection); } return; } - var index = parseInt(x / 2); - if (y == 4) index += 0; - else if (y == 6) index += 6; - else if (y == 9) index += 12; - else if (y == 11) index += 18; - else index = -1; - - if (index >= 0) { - if (index < 12) index = parseInt(index / 2); - this._clickEquipboxIndex(index); + var per_page = this.HSIZE - 3, v = this.SIZE / per_page; + if (y == this.LAST - 8) { + for (var i = 0; i < per_page; ++i) + if (x >= i * v && x <= (i + 1) * v) + return this._clickEquipboxIndex(i); } + else if (y == this.LAST - 6) { + for (var i = 0; i < per_page; ++i) + if (x >= i * v && x <= (i + 1) * v) + return this._clickEquipboxIndex(per_page + i); + } + else if (y == this.LAST - 3) + this._clickEquipboxIndex(this.LAST + parseInt(x / 2)) + else if (y == this.LAST - 1) + this._clickEquipboxIndex(this.LAST + this.HSIZE + parseInt(x / 2)); } ////// 选择装备栏界面中某个Index后的操作 ////// actions.prototype._clickEquipboxIndex = function (index) { - if (index < 6) { + if (index < this.LAST) { if (index >= core.status.globalAttribute.equipName.length) return; if (index == core.status.event.selection && core.status.hero.equipment[index]) { core.unloadEquip(index); core.status.route.push("unEquip:" + index); } } - else if (index >= 12) { + else { var equips = Object.keys(core.status.hero.items.equips || {}).sort(); if (index == core.status.event.selection) { - var equipId = equips[index - 12 + (core.status.event.data.page - 1) * 12]; + var equipId = equips[index - this.LAST + (core.status.event.data.page - 1) * this.LAST]; core.loadEquip(equipId); core.status.route.push("equip:" + equipId); } @@ -1481,21 +1506,23 @@ actions.prototype._clickEquipboxIndex = function (index) { ////// 装备栏界面时,按下某个键的操作 ////// actions.prototype._keyDownEquipbox = function (keycode) { - if (core.status.event.data != null) return; + if (core.status.event.data == null) return; + var last_index = this.LAST - 1; + var per_line = this.HSIZE - 3; var equipCapacity = core.status.globalAttribute.equipName.length; var ownEquipment = Object.keys(core.status.hero.items.equips).sort(); var index = core.status.event.selection; var page = core.status.event.data.page; - var totalPage = Math.ceil(ownEquipment.length / 12); - var totalLastIndex = 12 + (page < totalPage ? 11 : (ownEquipment.length + 11) % 12); + var totalPage = Math.ceil(ownEquipment.length / this.LAST); + var totalLastIndex = this.LAST + (page < totalPage ? last_index : (ownEquipment.length + last_index) % this.LAST); if (keycode == 37) { // left if (index == 0) return; - if (index == 12) { + if (index == this.LAST) { if (page > 1) { core.status.event.data.page--; - index = 23; + index = this.LAST + last_index; } else if (page == 1) index = equipCapacity - 1; @@ -1506,25 +1533,25 @@ actions.prototype._keyDownEquipbox = function (keycode) { return; } if (keycode == 38) { // up - if (index < 3) return; - else if (index < 6) index -= 3; - else if (index < 18) { - index = parseInt((index - 12) / 2); - if (equipCapacity > 3) index = Math.min(equipCapacity - 1, index + 3); + if (index < per_line) return; + else if (index < 2 * per_line) index -= per_line; + else if (index < this.LAST + this.HSIZE) { + index = parseInt((index - this.LAST) / 2); + if (equipCapacity > per_line) index = Math.min(equipCapacity - 1, index + per_line); else index = Math.min(equipCapacity - 1, index); } - else index -= 6; + else index -= this.HSIZE; this._clickEquipboxIndex(index); return; } if (keycode == 39) { // right - if (page < totalPage && index == 23) { + if (page < totalPage && index == this.LAST + last_index) { core.status.event.data.page++; - index = 12; + index = this.LAST; } else if (index == equipCapacity - 1) { if (totalPage == 0) return; - index = 12; + index = this.LAST; } else if (index == totalLastIndex) return; @@ -1533,19 +1560,19 @@ actions.prototype._keyDownEquipbox = function (keycode) { return; } if (keycode == 40) { // down - if (index < 3) { - if (equipCapacity > 3) index = Math.min(index + 3, equipCapacity - 1); + if (index < per_line) { + if (equipCapacity > per_line) index = Math.min(index + per_line, equipCapacity - 1); else { if (totalPage == 0) return; - index = Math.min(2 * index + 1 + 12, totalLastIndex); + index = Math.min(2 * index + 1 + this.LAST, totalLastIndex); } } - else if (index < 6) { + else if (index < 2 * per_line) { if (totalPage == 0) return; - index = Math.min(2 * (index - 3) + 1 + 12, totalLastIndex); + index = Math.min(2 * (index - per_line) + 1 + this.LAST, totalLastIndex); } - else if (index < 18) - index = Math.min(index + 6, totalLastIndex); + else if (index < this.LAST + this.HSIZE) + index = Math.min(index + this.HSIZE, totalLastIndex); else return; this._clickEquipboxIndex(index); return; @@ -1577,84 +1604,124 @@ actions.prototype._keyUpEquipbox = function (keycode, altKey) { ////// 存读档界面时的点击操作 ////// actions.prototype._clickSL = function (x, y) { - - var index = core.status.event.data; - var page = parseInt(index / 10), offset = index % 10; + var page = core.status.event.data.page, offset = core.status.event.data.offset; + var index = page * 10 + offset; // 上一页 - if ((x == 3 || x == 4) && y == 12) { + if ((x == this.HSIZE-2 || x == this.HSIZE-3) && y == this.LAST) { core.ui.drawSLPanel(10 * (page - 1) + offset); return; } // 下一页 - if ((x == 8 || x == 9) && y == 12) { + if ((x == this.HSIZE+2 || x == this.HSIZE+3) && y == this.LAST) { core.ui.drawSLPanel(10 * (page + 1) + offset); return; } // 返回 - if (x >= 10 && x <= 12 && y == 12) { - if (core.events.recoverEvents(core.status.event.interval)) { + if (x >= this.LAST-2 && y == this.LAST) { + if (core.events.recoverEvents(core.status.event.interval)) return; - } core.ui.closePanel(); - if (!core.isPlaying()) { + if (!core.isPlaying()) core.showStartAnimate(true); - } return; } // 删除 - if (x >= 0 && x <= 2 && y == 12) { - + if (x >= 0 && x <= 2 && y == this.LAST) { if (core.status.event.id == 'save') { core.status.event.selection = !core.status.event.selection; core.ui.drawSLPanel(index); } - else { - core.myprompt("请输入读档编号", null, function (index) { - index = parseInt(index) || 0; - if (index > 0) - core.doSL(index, core.status.event.id); - }); + else { // 显示收藏 + core.status.event.data.mode = core.status.event.data.mode == 'all'?'fav':'all'; + if (core.status.event.data.mode == 'fav') + core.ui.drawSLPanel(1, true); + else { + page = parseInt((core.saves.saveIndex-1)/5); + offset = core.saves.saveIndex-5*page; + core.ui.drawSLPanel(10*page + offset, true); + } } return; } + // 点存档名 + var xLeft = parseInt(this.SIZE/3), xRight = parseInt(this.SIZE*2/3); + var topY1 = 0, topY2 = this.HSIZE; + if(y >= topY1 && y <= topY1 + 1) { + if (x >= xLeft && x < xRight) return this._clickSL_favorite(page, 1); + if (x >= xRight) return this._clickSL_favorite(page, 2); + } + if(y >= topY2 && y <= topY2 + 1) { + if (x < xLeft) return this._clickSL_favorite(page, 3); + if (x >= xLeft && x < xRight) return this._clickSL_favorite(page, 4); + if (x >= xRight) return this._clickSL_favorite(page, 5); + } var id = null; - if (y >= 1 && y <= 4) { - if (x >= 1 && x <= 3) id = "autoSave"; - if (x >= 5 && x <= 7) id = 5 * page + 1; - if (x >= 9 && x <= 11) id = 5 * page + 2; + if (y >= topY1 + 2 && y < this.HSIZE - 1) { + if (x < xLeft) id = "autoSave"; + if (x >= xLeft && x < xRight) id = 5 * page + 1; + if (x >= xRight) id = 5 * page + 2; } - if (y >= 7 && y <= 10) { - if (x >= 1 && x <= 3) id = 5 * page + 3; - if (x >= 5 && x <= 7) id = 5 * page + 4; - if (x >= 9 && x <= 11) id = 5 * page + 5; + if (y >= topY2 + 2 && y < this.SIZE - 1) { + if (x < xLeft) id = 5 * page + 3; + if (x >= xLeft && x < xRight) id = 5 * page + 4; + if (x >= xRight) id = 5 * page + 5; } if (id != null) { if (core.status.event.selection) { - if (id == 'autoSave') { + if (id == 'autoSave') core.drawTip("无法删除自动存档!"); - } else { - // core.removeLocalStorage("save"+id); - core.removeLocalForage("save" + id, function () { + core.removeSave(id, function () { core.ui.drawSLPanel(index, true); - }, function () { - core.drawTip("无法删除存档!"); - }) + }); } } else { + if(core.status.event.data.mode == 'fav' && id != 'autoSave') + id = core.saves.favorite[id - 1]; core.doSL(id, core.status.event.id); } } } +actions.prototype._clickSL_favorite = function (page, offset) { + if (offset == 0) return; + var index = 5 * page + offset; + if (core.status.event.data.mode == 'fav') { // 收藏模式下点击的下标直接对应favorite + index = core.saves.favorite[index - 1]; + core.myprompt("请输入想要显示的存档名(长度不超过5字符)", null, function (value) { + if(value && value.length <= 5){ + core.saves.favoriteName[index] = value; + core.control._updateFavoriteSaves(); + core.drawSLPanel(10 * page + offset); + } else if (value) { + alert("无效的输入!"); + } + }); + } else { + var v = core.saves.favorite.indexOf(index); + if (v >= 0) { // 已经处于收藏状态:取消收藏 + core.saves.favorite.splice(v, 1); + delete core.saves.favoriteName[index]; + } + else if (core.hasSave(index)) { // 存在存档则进行收藏 + core.saves.favorite.push(index); + core.saves.favorite = core.saves.favorite.sort(function (a,b) {return a-b;}); // 保证有序 + core.drawTip("收藏成功!"); + } + core.control._updateFavoriteSaves(); + core.ui.drawSLPanel(10 * page + offset); + } +} + ////// 存读档界面时,按下某个键的操作 ////// actions.prototype._keyDownSL = function (keycode) { - var index = core.status.event.data; - var page = parseInt(index / 10), offset = index % 10; +// var index = core.status.event.data; + var page = core.status.event.data.page, offset = core.status.event.data.offset; + var index = page*10 + offset; if (keycode == 37) { // left if (offset == 0) { @@ -1704,35 +1771,26 @@ actions.prototype._keyDownSL = function (keycode) { ////// 存读档界面时,放开某个键的操作 ////// actions.prototype._keyUpSL = function (keycode) { + var page = core.status.event.data.page, offset = core.status.event.data.offset; + var index = page * 10 + offset; - var index = core.status.event.data; - var page = parseInt(index / 10), offset = index % 10; - - if (keycode == 27 || keycode == 88 || (core.status.event.id == 'save' && keycode == 83) || (core.status.event.id == 'load' && keycode == 68)) { - if (core.events.recoverEvents(core.status.event.interval)) { - return; - } - core.ui.closePanel(); - if (!core.isPlaying()) { - core.showStartAnimate(true); - } + if (keycode == 27 || keycode == 88 || (core.status.event.id == 'save' && keycode == 83) + || (core.status.event.id == 'load' && keycode == 68)) { + this._clickSL(this.LAST, this.LAST); return; } if (keycode == 13 || keycode == 32 || keycode == 67) { - if (offset == 0) { + if (offset == 0) core.doSL("autoSave", core.status.event.id); - } else { - core.doSL(5 * page + offset, core.status.event.id); + var id = 5 * page + offset; + if(core.status.event.data.mode == 'fav') id = core.saves.favorite[id - 1]; + core.doSL(id, core.status.event.id); } return; } - if (keycode == 69 && core.status.event.id != 'save') { // E - core.myprompt("请输入读档编号", null, function (index) { - index = parseInt(index) || 0; - if (index > 0) - core.doSL(index, core.status.event.id); - }); + if (keycode == 69 && core.status.event.id != 'save') { // E 收藏切换 + this._clickSL(0, this.LAST); return; } if (keycode == 46) { @@ -1740,17 +1798,19 @@ actions.prototype._keyUpSL = function (keycode) { core.drawTip("无法删除自动存档!"); } else { - // core.removeLocalStorage("save"+(5*page+offset)); - // core.ui.drawSLPanel(index); - core.removeLocalForage("save" + (5 * page + offset), function () { + var id = 5 * page + offset; + if(core.status.event.data.mode == 'fav') id = core.saves.favorite[id - 1]; + core.removeSave(id, function () { core.ui.drawSLPanel(index, true); - }, function () { - core.drawTip("无法删除存档!"); - }) + }); } } + if (keycode == 70 && core.status.event.data.mode == 'all') { // F + this._clickSL_favorite(page, offset); + } } + ////// 系统设置界面时的点击操作 ////// actions.prototype._clickSwitchs = function (x, y) { if (x < this.CHOICES_LEFT || x > this.CHOICES_RIGHT) return; @@ -2026,7 +2086,7 @@ actions.prototype._clickLocalSaveSelect = function (x, y) { var selection = y - topIndex; core.status.event.selection = selection; if (selection < 2) { - core.control.getSaves(selection == 0 ? null : core.saves.saveIndex, function (saves) { + core.getAllSaves(selection == 0 ? null : core.saves.saveIndex, function (saves) { if (saves) { var content = { "name": core.firstData.name, @@ -2079,12 +2139,16 @@ actions.prototype._clickStorageRemove = function (x, y) { actions.prototype._clickStorageRemove_all = function () { core.myconfirm("你确定要清除【全部塔】的所有本地存档?\n此行为不可逆!!!", function () { var done = function () { + core.saves.ids = {}; core.saves.autosave.data = null; core.saves.autosave.updated = false; core.ui.closePanel(); - core.drawText("\t[操作成功]你的所有存档已被清空。"); core.saves.saveIndex = 1; + core.saves.favorite = []; + core.saves.favoriteName = {}; + core.control._updateFavoriteSaves(); core.removeLocalStorage('saveIndex'); + core.drawText("\t[操作成功]你的所有存档已被清空。"); }; if (core.platform.useLocalForage) { core.ui.drawWaiting("正在清空,请稍后..."); @@ -2100,12 +2164,16 @@ actions.prototype._clickStorageRemove_all = function () { actions.prototype._clickStorageRemove_current = function () { core.myconfirm("你确定要清除本塔的所有本地存档?\n此行为不可逆!!!", function () { var done = function () { + core.saves.ids = {}; core.saves.autosave.data = null; core.saves.autosave.updated = false; core.ui.closePanel(); - core.drawText("\t[操作成功]当前塔的存档已被清空。"); core.saves.saveIndex = 1; + core.saves.favorite = []; + core.saves.favoriteName = {}; + core.control._updateFavoriteSaves(); core.removeLocalStorage('saveIndex'); + core.drawText("\t[操作成功]当前塔的存档已被清空。"); } if (core.platform.useLocalForage) { core.ui.drawWaiting("正在清空,请稍后..."); diff --git a/libs/control.js b/libs/control.js index e3946a74..fa0eaf5a 100644 --- a/libs/control.js +++ b/libs/control.js @@ -33,6 +33,7 @@ control.prototype._init = function () { this.registerReplayAction("fly", this._replayAction_fly); this.registerReplayAction("shop", this._replayAction_shop); this.registerReplayAction("turn", this._replayAction_turn); + this.registerReplayAction("common", this._replayAction_common); this.registerReplayAction("getNext", this._replayAction_getNext); this.registerReplayAction("moveDirectly", this._replayAction_moveDirectly); this.registerReplayAction("key", this._replayAction_key); @@ -795,7 +796,7 @@ control.prototype.tryMoveDirectly = function (destX, destY) { ////// 绘制勇士 ////// control.prototype.drawHero = function (status, offset) { - if (!core.isPlaying() || !core.status.floorId) return; + if (!core.isPlaying() || !core.status.floorId || core.status.gameOver) return; var x = core.getHeroLoc('x'), y = core.getHeroLoc('y'), direction = core.getHeroLoc('direction'); status = status || 'stop'; offset = offset || 0; @@ -1301,8 +1302,12 @@ control.prototype._replay_save = function () { control.prototype._replay_error = function (action) { core.status.replay.replaying = false; - main.log("录像文件出错,当前操作:" + action + - "\n接下来10个操作是:"+core.status.replay.toReplay.slice(0, 10).toString()); + var len = core.status.replay.toReplay.length; + var prevList = core.status.replay.totalList.slice(-len - 11, -len - 1); + var nextList = core.status.replay.toReplay.slice(0, 10); + main.log("录像文件出错,当前操作:" + action); + main.log("之前的10个操作是:\n" + prevList.toString()); + main.log("接下来10个操作是:\n" + nextList.toString()); core.ui.drawConfirmBox("录像文件出错,你想回到上个节点吗?", function () { core.ui.closePanel(); if (core.status.replay.save.length > 0) { @@ -1441,6 +1446,16 @@ control.prototype._replayAction_turn = function (action) { return true; } +control.prototype._replayAction_common = function (action) { + if (action.indexOf("common:") != 0) return false; + var name = core.decodeBase64(action.substring(7)); + if (core.getFlag("__commonEventList__").indexOf(name) == -1) return false; + core.status.route.push(action); + core.insertAction(name); + setTimeout(core.replay); + return true; +} + control.prototype._replayAction_getNext = function (action) { if (action != "getNext") return false; if (!core.getNextItem()) return false; @@ -1608,7 +1623,7 @@ control.prototype._doSL_replayLoad_afterGet = function (id, data) { ////// 同步存档到服务器 ////// control.prototype.syncSave = function (type) { core.ui.drawWaiting("正在同步,请稍后..."); - core.control.getSaves(type=='all'?null:core.saves.saveIndex, function (saves) { + core.getAllSaves(type=='all'?null:core.saves.saveIndex, function (saves) { if (!saves) return core.drawText("没有要同步的存档"); core.control._syncSave_http(type, saves); }) @@ -1702,32 +1717,54 @@ control.prototype.loadData = function (data, callback) { return this.controldata.loadData(data, callback); } -control.prototype.getSaves = function (index, callback) { - if (index != null) { - core.getLocalForage("save"+index, null, function(data) { - if (callback) callback(data); - }, function(err) { - main.log(err); - if (callback) callback(null); - }) +control.prototype.getSave = function (index, callback) { + if (index == 0) { + // --- 自动存档先从缓存中获取 + if (core.saves.autosave.data != null) + callback(core.clone(core.saves.autosave.data)); + else { + core.getLocalForage("autoSave", null, function(data) { + callback(data); + }, function(err) { + main.log(err); + callback(null); + }); + } return; } - var ids = Object.keys(core.saves.ids).filter(function(x){return x!=0;}) - .sort(function(a,b) {return a-b;}), number = ids.length, saves = []; - var load = function (index, callback) { - if (index > number) { - if (callback) callback(saves); - return; - } - core.getLocalForage("save"+ids[index], null, function (data) { - saves.push(data); - load(index+1, callback); - }, function(err) { - main.log(err); - load(index+1, callback); - }) + core.getLocalForage("save"+index, null, function(data) { + if (callback) callback(data); + }, function(err) { + main.log(err); + if (callback) callback(null); + }); +} + +control.prototype.getSaves = function (ids, callback) { + if (!(ids instanceof Array)) return this.getSave(ids, callback); + var count = ids.length, data = {}; + for (var i = 0; i < ids.length; ++i) { + (function (i) { + core.getSave(ids[i], function (result) { + data[i] = result; + if (Object.keys(data).length == count) + callback(data); + }) + })(i); } - load(0, callback); +} + +control.prototype.getAllSaves = function (id, callback) { + if (id != null) return this.getSave(id, callback); + var ids = Object.keys(core.saves.ids).filter(function(x){return x!=0;}) + .sort(function(a,b) {return a-b;}), saves = []; + this.getSaves(ids, function (data) { + for (var i = 0; i < ids.length; ++i) { + if (data[i] != null) + saves.push(data[i]); + } + callback(saves); + }); } ////// 获得所有存在存档的存档位 ////// @@ -1761,6 +1798,43 @@ control.prototype.hasSave = function (index) { return core.saves.ids[index] || false; } +////// 删除一个或多个存档 +control.prototype.removeSave = function (index, callback) { + if (index == 0 || index == "autoSave") { + index = "autoSave"; + core.removeLocalForage(index, function () { + core.saves.autosave.data = null; + core.saves.autosave.updated = false; + if (callback) callback(); + }); + return; + } + core.removeLocalForage("save" + index, function () { + core.saves.favorite = core.saves.favorite.filter(function (i) { return core.hasSave(i); }); + delete core.saves.favoriteName[index]; + core.control._updateFavoriteSaves(); + if (callback) callback(); + }, function () { + core.drawTip("无法删除存档!"); + if (callback) callback(); + }); +} + +////// 读取收藏信息 +control.prototype._loadFavoriteSaves = function () { + core.saves.favorite = core.getLocalStorage("favorite", []); + // --- 移除不存在的收藏 + core.saves.favorite = core.saves.favorite.filter(function (i) { return core.hasSave(i); }); + core.saves.favoriteName = core.getLocalStorage("favoriteName", {}); +} + +control.prototype._updateFavoriteSaves = function () { + core.setLocalStorage("favorite", core.saves.favorite); + core.setLocalStorage("favoriteName", core.saves.favoriteName); +} + +////// 加载某个存档 + // ------ 属性,状态,位置,buff,变量,锁定控制等 ------ // ////// 设置勇士属性 ////// @@ -1782,7 +1856,7 @@ control.prototype.addStatus = function (name, value) { control.prototype.getStatus = function (name) { if (!core.status.hero) return null; if (name == 'x' || name == 'y' || name == 'direction') - return this.getHeroLoc('x'); + return this.getHeroLoc(name); if (name == 'exp') name = 'experience'; return core.status.hero[name]; } @@ -1806,12 +1880,12 @@ control.prototype.getRealStatusOrDefault = function (status, name) { ////// 设置某个属性的增幅值 ////// control.prototype.setBuff = function (name, value) { - this.setFlag('flag:__'+name+'_buff__', value); + this.setFlag('__'+name+'_buff__', value); } ////// 加减某个属性的增幅值 ////// control.prototype.addBuff = function (name, value) { - this.setFlag('flag:__'+name+'_buff__', this.getBuff(name) + value); + this.setFlag('__'+name+'_buff__', this.getBuff(name) + value); } ////// 获得某个属性的增幅值 ////// diff --git a/libs/core.js b/libs/core.js index 4ef06a69..966aa4d0 100644 --- a/libs/core.js +++ b/libs/core.js @@ -67,6 +67,7 @@ function core() { 'isPC': true, // 是否是PC 'isAndroid': false, // 是否是Android 'isIOS': false, // 是否是iOS + 'string': 'PC', 'isWeChat': false, // 是否是微信 'isQQ': false, // 是否是QQ 'isChrome': false, // 是否是Chrome @@ -102,7 +103,9 @@ function core() { "data": null, "time": 0, "updated": false, - } + }, + "favorite": [], + "favoriteName": {} } this.initStatus = { 'played': false, @@ -272,6 +275,7 @@ core.prototype._init_platform = function () { core.platform.isPC = false; } }); + core.platform.string = core.platform.isPC ? "PC" : core.platform.isAndroid ? "Android" : core.platform.isIOS ? "iOS" : ""; core.platform.supportCopy = document.queryCommandSupported || document.queryCommandSupported("copy"); var chrome = /Chrome\/(\d+)\./i.exec(navigator.userAgent); if (chrome && parseInt(chrome[1]) >= 50) core.platform.isChrome = true; @@ -293,7 +297,7 @@ core.prototype._init_platform = function () { } core.prototype._init_checkLocalForage = function () { - core.platform.useLocalForage = core.getLocalStorage('useLocalForage', !core.platform.isIOS); + core.platform.useLocalForage = core.getLocalStorage('useLocalForage', true); var _error = function (e) { main.log(e); core.platform.useLocalForage = false; @@ -382,13 +386,16 @@ core.prototype._forwardFunc = function (name, funcname) { } if (core[funcname]) { - console.error("ERROR: Cannot forward function " + funcname + " from " + name + "!"); + console.error("ERROR: 无法转发 "+name+" 中的函数 "+funcname+" 到 core 中!同名函数已存在。"); return; } var parameterInfo = /^\s*function\s*[\w_$]*\(([\w_,$\s]*)\)\s*\{/.exec(core[name][funcname].toString()); var parameters = (parameterInfo == null ? "" : parameterInfo[1]).replace(/\s*/g, '').replace(/,/g, ', '); // core[funcname] = new Function(parameters, "return core."+name+"."+funcname+"("+parameters+");"); eval("core." + funcname + " = function (" + parameters + ") {\n\treturn core." + name + "." + funcname + "(" + parameters + ");\n}"); + if (name == 'plugin') { + main.log("插件函数转发:core."+funcname+" = core.plugin."+funcname); + } } core.prototype.doFunc = function (func, _this) { diff --git a/libs/events.js b/libs/events.js index fd81f219..4a1be196 100644 --- a/libs/events.js +++ b/libs/events.js @@ -89,7 +89,7 @@ events.prototype._startGame_upload = function () { formData.append('type', 'people'); formData.append('name', core.firstData.name); formData.append('version', core.firstData.version); - formData.append('platform', core.platform.isPC ? "PC" : core.platform.isAndroid ? "Android" : core.platform.isIOS ? "iOS" : ""); + formData.append('platform', core.platform.string); formData.append('hard', core.encodeBase64(core.status.hard)); formData.append('hardCode', core.getFlag('hard', 0)); formData.append('base64', 1); @@ -171,7 +171,7 @@ events.prototype._gameOver_doUpload = function (username, ending, norank) { formData.append('type', 'score'); formData.append('name', core.firstData.name); formData.append('version', core.firstData.version); - formData.append('platform', core.platform.isPC ? "PC" : core.platform.isAndroid ? "Android" : core.platform.isIOS ? "iOS" : ""); + formData.append('platform', core.platform.string); formData.append('hard', core.encodeBase64(core.status.hard)); formData.append('username', core.encodeBase64(username || "")); formData.append('ending', core.encodeBase64(ending)); @@ -251,7 +251,7 @@ events.prototype.unregisterSystemEvent = function (type) { events.prototype.doSystemEvent = function (type, data, callback) { if (this.systemEvents[type]) { try { - return core.doFunc(this.systemEvents[type], this, data, data, callback); + return core.doFunc(this.systemEvents[type], this, data, callback); } catch (e) { main.log(e); @@ -688,6 +688,11 @@ events.prototype._sys_action = function (data, callback) { this.insertAction(ev, ex, ey, callback); } +events.prototype._sys_custom = function (data, callback) { + core.insertAction(["请使用\r[yellow]core.registerSystemEvent('custom', func)\r来处理自己添加的系统触发器!"], + data.x, data.y, callback); +} + // ------ 自定义事件的处理 ------ // ////// 注册一个自定义事件 ////// @@ -801,7 +806,10 @@ events.prototype.insertAction = function (action, x, y, callback, addToLast) { // ------ 判定commonEvent var commonEvent = this.getCommonEvent(action); - if (commonEvent instanceof Array) action = commonEvent; + if (commonEvent instanceof Array) { + this._addCommentEventToList(action, commonEvent); + action = commonEvent; + } if (!action) return; if (core.status.event.id != 'action') { @@ -822,6 +830,22 @@ events.prototype.getCommonEvent = function (name) { return this.commonEvent[name] || null; } +events.prototype._addCommentEventToList = function (name, list) { + if (list == null) list = this.getCommonEvent(name); + if (!list || !core.flags.quickCommonEvents) return; + var addToList = false; + for (var x in list) { + if (list[x].type == 'addToList') { + addToList = true; + break; + } + } + if (!addToList) return; + var obj = core.getFlag("__commonEventList__", []); + if (obj.indexOf(name) == -1) obj.push(name); + core.setFlag("__commonEventList__", obj); +} + ////// 恢复一个事件 ////// events.prototype.recoverEvents = function (data) { if (data) { @@ -1163,13 +1187,14 @@ events.prototype._action_insert = function (data, x, y, prefix) { if (data.args instanceof Array) { for (var i = 0; i < data.args.length; ++i) { try { - core.setFlag('arg'+(i+1), core.calValue(data.args[i], prefix)); + if (data.args[i] != null) + core.setFlag('arg'+(i+1), data.args[i]); } catch (e) { main.log(e); } } } if (data.name) { // 公共事件 core.setFlag('arg0', data.name); - core.insertAction(this.getCommonEvent(data.name)); + core.insertAction(data.name); } else { var loc = this.__action_getLoc(data.loc, x, y, prefix); @@ -1182,6 +1207,10 @@ events.prototype._action_insert = function (data, x, y, prefix) { core.doAction(); } +events.prototype._action_addToList = function (data, x, y, prefix) { + core.doAction(); +} + events.prototype._action_playBgm = function (data, x, y, prefix) { core.playBgm(data.name); core.doAction(); @@ -2199,7 +2228,7 @@ events.prototype.uploadCurrent = function (username) { formData.append('type', 'score'); formData.append('name', core.firstData.name); formData.append('version', core.firstData.version); - formData.append('platform', core.platform.isPC ? "PC" : core.platform.isAndroid ? "Android" : core.platform.isIOS ? "iOS" : ""); + formData.append('platform', core.platform.string); formData.append('hard', core.encodeBase64(core.status.hard)); formData.append('username', core.encodeBase64(username || "current")); formData.append('lv', core.status.hero.lv); diff --git a/libs/items.js b/libs/items.js index 58faca5c..23056d8d 100644 --- a/libs/items.js +++ b/libs/items.js @@ -311,20 +311,17 @@ items.prototype.unloadEquip = function (equipType, callback) { } items.prototype.compareEquipment = function (compareEquipId, beComparedEquipId) { - var compareAtk = 0, compareDef = 0, compareMdef = 0; - if (compareEquipId) { - var compareEquip = core.material.items[compareEquipId]; - compareAtk += (compareEquip.equip || {}).atk || 0; - compareDef += (compareEquip.equip || {}).def || 0; - compareMdef += (compareEquip.equip || {}).mdef || 0; + var result = {}; + var first = core.material.items[compareEquipId], second = core.material.items[beComparedEquipId]; + for (var name in core.status.hero) { + if (typeof core.status.hero[name] == 'number') { + var ans = 0; + if (first) ans += (first.equip || {})[name] || 0; + if (second) ans -= (second.equip || {})[name] || 0; + if (ans != 0) result[name] = ans; + } } - if (beComparedEquipId) { - var beComparedEquip = core.material.items[beComparedEquipId]; - compareAtk -= (beComparedEquip.equip || {}).atk || 0; - compareDef -= (beComparedEquip.equip || {}).def || 0; - compareMdef -= (beComparedEquip.equip || {}).mdef || 0; - } - return {"atk": compareAtk, "def": compareDef, "mdef": compareMdef}; + return result; } ////// 实际换装的效果 ////// @@ -349,7 +346,7 @@ items.prototype._realLoadEquip = function (type, loadId, unloadId, callback) { var loadPercentage = loadEquip.equip.percentage, unloadPercentage = unloadEquip.equip.percentage; - if (loadPercentage != null && unloadPercentage != null && loadPercentage != unloadPercentage) { + if (loadId && unloadId && (loadPercentage || false) != (unloadPercentage || false)) { this.unloadEquip(type); this.loadEquip(loadId); if (callback) callback(); diff --git a/libs/maps.js b/libs/maps.js index cb7dbb7b..9d05a272 100644 --- a/libs/maps.js +++ b/libs/maps.js @@ -30,11 +30,14 @@ maps.prototype.loadFloor = function (floorId, map) { map = {"map": map}; } var content = {}; - ["floorId", "title", "name", "canFlyTo", "canUseQuickShop", "cannotViewMap", "cannotMoveDirectly", "color", "weather", - "defaultGround", "images", "item_ratio", "upFloor", "bgm", "downFloor", "underGround"].forEach(function (e) { - if (map[e] != null) content[e] = core.clone(map[e]); - else content[e] = core.clone(floor[e]); - }); + for (var name in floor) { + if (name != 'map' && name != 'bgmap' && name != 'fgmap' && floor[name] != null) + content[name] = core.clone(floor[name]); + } + for (var name in map) { + if (name != 'map' && name != 'bgmap' && name != 'fgmap' && map[name] != null) + content[name] = core.clone(map[name]); + } map = this.decompressMap(map.map, floorId); // 事件处理 content['blocks'] = this._mapIntoBlocks(map, floor, floorId); @@ -1696,6 +1699,7 @@ maps.prototype.animateBlock = function (loc, type, time, callback) { var isHide = type == 'hide'; if (typeof loc[0] == 'number' && typeof loc[1] == 'number') loc = [loc]; + // --- 检测所有是0的点 var list = this._animateBlock_getList(loc); if (list.length == 0) { if (callback) callback(); @@ -1714,7 +1718,8 @@ maps.prototype._animateBlock_doAnimate = function (loc, list, isHide, delta, cal delete core.animateFrame.asyncId[animate]; clearInterval(animate); list.forEach(function (t) { - core.maps._deleteDetachedBlock(t.canvases); + if (t.blockInfo) + core.maps._deleteDetachedBlock(t.canvases); }); loc.forEach(function (t) { if (isHide) core.removeBlock(t[0], t[1]); @@ -1735,7 +1740,10 @@ maps.prototype._animateBlock_getList = function (loc) { block = block.block; var blockInfo = core.maps.getBlockInfo(block); - if (blockInfo == null) return; + if (blockInfo == null) { + list.push({ 'x': t[0], 'y': t[1] }); + return; + } var canvases = core.maps._initDetachedBlock(blockInfo, t[0], t[1], block.event.displayDamage !== false); list.push({ @@ -1748,7 +1756,8 @@ maps.prototype._animateBlock_getList = function (loc) { maps.prototype._animateBlock_drawList = function (list, opacity) { list.forEach(function (t) { - core.maps._moveDetachedBlock(t.blockInfo, t.x * 32, t.y * 32, opacity, t.canvases); + if (t.blockInfo) + core.maps._moveDetachedBlock(t.blockInfo, t.x * 32, t.y * 32, opacity, t.canvases); }); } diff --git a/libs/ui.js b/libs/ui.js index 14007f9a..7529f589 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -455,6 +455,57 @@ ui.prototype.drawWindowSkin = function(background, ctx, x, y, w, h, direction, p // 仿RM窗口皮肤 ↑ } +////// 绘制一个背景图,可绘制 winskin 或纯色背景;支持小箭头绘制 +ui.prototype.drawBackground = function (left, top, right, bottom, posInfo) { + posInfo = posInfo || {}; + var px = posInfo.px == null ? null : posInfo.px * 32 - core.bigmap.offsetX; + var py = posInfo.py == null ? null : posInfo.py * 32 - core.bigmap.offsetY; + var xoffset = posInfo.xoffset || 0, yoffset = posInfo.yoffset || 0; + var background = core.status.textAttribute.background; + + if (typeof background == 'string' && core.material.images.images[background]) { + var image = core.material.images.images[background]; + if (image.width==192 && image.height==128) { + core.setAlpha('ui', 0.85); + this.drawWindowSkin(image, 'ui', left, top, right - left, bottom - top, posInfo.position, px, py); + core.setAlpha('ui', 1); + return true; + } + background = core.initStatus.textAttribute.background; + } + + var alpha = background[3]; + core.setAlpha('ui', alpha); + core.setStrokeStyle('ui', core.status.globalAttribute.borderColor); + core.setFillStyle('ui', core.arrayToRGB(background)); + core.setLineWidth('ui', 2); + + // 绘制 + var ctx = core.canvas.ui; + ctx.beginPath(); + ctx.moveTo(left, top); + // 上边缘三角 + if (posInfo.position == 'down' && px != null && py != null) { + ctx.lineTo(px + xoffset, top); + ctx.lineTo(px + 16, top - yoffset); + ctx.lineTo(px + 32 - xoffset, top); + } + ctx.lineTo(right, top); + ctx.lineTo(right, bottom); + // 下边缘三角 + if (posInfo.position == 'up' && px != null && py != null) { + ctx.lineTo(px + 32 - xoffset, bottom); + ctx.lineTo(px + 16, bottom + yoffset); + ctx.lineTo(px + xoffset, bottom); + } + ctx.lineTo(left, bottom); + ctx.closePath(); + ctx.fill(); + ctx.stroke(); + core.setAlpha('ui', 1); + return false; +} + ////// 计算有效文本框的宽度 ui.prototype.calTextBoxWidth = function (ctx, content, min_width, max_width, font) { // 无限长度自动换行 @@ -492,7 +543,8 @@ ui.prototype._getDrawableIconInfo = function (id) { } ui.prototype._buildFont = function (fontSize, bold) { - var textAttribute = core.status.textAttribute, globalAttribute = core.status.globalAttribute; + var textAttribute = core.status.textAttribute || core.initStatus.textAttribute, + globalAttribute = core.status.globalAttribute || core.initStatus.globalAttribute; if (bold == null) bold = textAttribute.bold; return (bold?"bold ":"") + (fontSize || textAttribute.textfont) + "px " + globalAttribute.font; } @@ -697,8 +749,10 @@ ui.prototype.drawTextBox = function(content, showAll) { var vPos = this._drawTextBox_getVerticalPosition(content, titleInfo, posInfo, hPos.validWidth); // Step 3: 绘制背景图 - var isWindowSkin = this._drawTextBox_drawBackground(titleInfo, posInfo, hPos, vPos); - var alpha = isWindowSkin ? 0.85 : (textAttribute.background[3] || core.initStatus.textAttribute.background[3]); + var pInfo = core.clone(posInfo); + pInfo.xoffset = hPos.xoffset; pInfo.yoffset = vPos.yoffset - 4; + var isWindowSkin = this.drawBackground(hPos.left, vPos.top, hPos.right, vPos.bottom, pInfo); + var alpha = isWindowSkin ? 0.85 : textAttribute.background[3]; // Step 4: 绘制标题、头像、 var content_top = this._drawTextBox_drawTitleAndIcon(titleInfo, hPos, vPos, alpha); @@ -780,56 +834,6 @@ ui.prototype._drawTextBox_getVerticalPosition = function (content, titleInfo, po return { top: top, height: height, bottom: top + height, yoffset: yoffset, lineHeight: lineHeight }; } -ui.prototype._drawTextBox_drawBackground = function (titleInfo, posInfo, hPos, vPos) { - var background = core.status.textAttribute.background; - var px = posInfo.px == null ? null : posInfo.px * 32 - core.bigmap.offsetX; - var py = posInfo.py == null ? null : posInfo.py * 32 - core.bigmap.offsetY; - var xoffset = hPos.xoffset, yoffset = vPos.yoffset - 4; - var left = hPos.left, right = hPos.right, top = vPos.top, bottom = vPos.bottom; - - if (typeof background == 'string' && core.material.images.images[background]) { - var image = core.material.images.images[background]; - if (image.width==192 && image.height==128) { - core.setAlpha('ui', 0.85); - this.drawWindowSkin(image, 'ui', left, top, right - left, bottom - top, posInfo.position, px, py); - core.setAlpha('ui', 1); - return true; - } - background = core.initStatus.textAttribute.background; - } - - var alpha = background[3]; - core.setAlpha('ui', alpha); - core.setStrokeStyle('ui', core.status.globalAttribute.borderColor); - core.setFillStyle('ui', core.arrayToRGB(background)); - core.setLineWidth('ui', 2); - - // 绘制 - var ctx = core.canvas.ui; - ctx.beginPath(); - ctx.moveTo(left, top); - // 上边缘三角 - if (posInfo.position == 'down' && px != null && py != null) { - ctx.lineTo(px + xoffset, top); - ctx.lineTo(px + 16, top - yoffset); - ctx.lineTo(px + 32 - xoffset, top); - } - ctx.lineTo(right, top); - ctx.lineTo(right, bottom); - // 下边缘三角 - if (posInfo.position == 'up' && px != null && py != null) { - ctx.lineTo(px + 32 - xoffset, bottom); - ctx.lineTo(px + 16, bottom + yoffset); - ctx.lineTo(px + xoffset, bottom); - } - ctx.lineTo(left, bottom); - ctx.closePath(); - ctx.fill(); - ctx.stroke(); - core.setAlpha('ui', 1); - return false; -} - ui.prototype._drawTextBox_drawTitleAndIcon = function (titleInfo, hPos, vPos, alpha) { core.setTextAlign('ui', 'left'); var textAttribute = core.status.textAttribute; @@ -841,7 +845,7 @@ ui.prototype._drawTextBox_drawTitleAndIcon = function (titleInfo, hPos, vPos, al core.setStrokeStyle('ui', core.arrayToRGB(textAttribute.title)); // --- title也要居中或者右对齐? - var title_width = core.calWidth('ui', titleInfo.title, 'bold '+titlefont+'px '+core.status.globalAttribute.font); + var title_width = core.calWidth('ui', titleInfo.title, this._buildFont(titlefont, true)); var title_left = hPos.content_left; if (textAttribute.align == 'center') title_left = hPos.left + (hPos.width - title_width) / 2; @@ -939,7 +943,7 @@ ui.prototype.drawChoices = function(content, choices) { var hPos = this._drawChoices_getHorizontalPosition(titleInfo, choices); var vPos = this._drawChoices_getVerticalPosition(titleInfo, choices, hPos); - var isWindowSkin = this._drawTextBox_drawBackground(titleInfo, {}, hPos, vPos); + var isWindowSkin = this.drawBackground(hPos.left, vPos.top, hPos.right, vPos.bottom); this._drawChoices_drawTitle(titleInfo, hPos, vPos); this._drawChoices_drawChoices(choices, isWindowSkin, hPos, vPos); } @@ -947,7 +951,7 @@ ui.prototype.drawChoices = function(content, choices) { ui.prototype._drawChoices_getHorizontalPosition = function (titleInfo, choices) { // 宽度计算:考虑选项的长度 var width = 246; - core.setFont('ui', "bold 17px "+core.status.globalAttribute.font); + core.setFont('ui', this._buildFont(17, true)); for (var i = 0; i < choices.length; i++) { if (typeof choices[i] === 'string') choices[i] = {"text": choices[i]}; @@ -999,7 +1003,7 @@ ui.prototype._drawChoices_drawTitle = function (titleInfo, hPos, vPos) { }; core.fillText('ui', titleInfo.title, title_offset, vPos.top + 27, - core.arrayToRGBA(core.status.textAttribute.title), 'bold 19px '+core.status.globalAttribute.font); + core.arrayToRGBA(core.status.textAttribute.title), this._buildFont(19, true)); } core.setTextAlign('ui', 'left'); @@ -1012,7 +1016,7 @@ ui.prototype._drawChoices_drawTitle = function (titleInfo, hPos, vPos) { ui.prototype._drawChoices_drawChoices = function (choices, isWindowSkin, hPos, vPos) { // 选项 core.setTextAlign('ui', 'center'); - core.setFont('ui', "bold 17px " + core.status.globalAttribute.font); + core.setFont('ui', this._buildFont(17, true)); for (var i = 0; i < choices.length; i++) { var color = choices[i].color || core.status.textAttribute.text; if (color instanceof Array) color = core.arrayToRGBA(color); @@ -1035,7 +1039,7 @@ ui.prototype._drawChoices_drawChoices = function (choices, isWindowSkin, hPos, v while (core.status.event.selection >= choices.length) core.status.event.selection -= choices.length; var len = choices[core.status.event.selection].width; if (isWindowSkin) - this.drawWindowSelector(core.material.images.images[core.status.textAttribute.background], + this.drawWindowSelector(core.status.textAttribute.background, this.HPIXEL - len/2 - 5, vPos.choice_top + 32 * core.status.event.selection - 20, len + 10, 28); else core.strokeRect('ui', this.HPIXEL - len/2 - 5, vPos.choice_top + 32 * core.status.event.selection - 20, @@ -1057,7 +1061,7 @@ ui.prototype.drawConfirmBox = function (text, yesCallback, noCallback) { core.setFont('ui', this._buildFont(19, true)); var contents = text.split("\n"); var rect = this._drawConfirmBox_getRect(contents); - var isWindowSkin = this._drawTextBox_drawBackground({}, {}, rect, rect); + var isWindowSkin = this.drawBackground(rect.left, rect.top, rect.right, rect.bottom); core.setTextAlign('ui', 'center'); core.setFillStyle('ui', core.arrayToRGBA(core.status.textAttribute.text)) @@ -1114,12 +1118,18 @@ ui.prototype.drawSettings = function () { ////// 绘制快捷商店选择栏 ////// ui.prototype.drawQuickShop = function () { core.status.event.id = 'selectShop'; - var shopList = core.status.shops, keys = Object.keys(shopList).filter(function (shopId) { - return shopList[shopId].visited || !shopList[shopId].mustEnable - }); - var choices = keys.map(function (shopId) { - return {"text": shopList[shopId].textInList, "color": shopList[shopId].visited?null:"#999999"}; - }); + var choices; + if (core.flags.quickCommonEvents) { + choices = core.clone(core.getFlag("__commonEventList__", [])); + } + else { + var shopList = core.status.shops, keys = Object.keys(shopList).filter(function (shopId) { + return shopList[shopId].visited || !shopList[shopId].mustEnable + }); + choices = keys.map(function (shopId) { + return {"text": shopList[shopId].textInList, "color": shopList[shopId].visited?null:"#999999"}; + }); + } choices.push("返回游戏"); this.drawChoices(null, choices); } @@ -1133,7 +1143,7 @@ ui.prototype.drawWaiting = function(text) { var text_length = core.calWidth('ui', text, this._buildFont(19, true)); var width = Math.max(text_length + 80, 220), left = this.HPIXEL - parseInt(width / 2), right = left + width; var top = this.HPIXEL - 48, height = 96, bottom = top + height; - this._drawTextBox_drawBackground({}, {}, {left: left, right: right}, {top: top, bottom: bottom}); + this.drawBackground(left, top, right, bottom); core.setTextAlign('ui', 'center'); core.fillText('ui', text, this.HPIXEL, top + 56, core.arrayToRGBA(core.status.textAttribute.text)); } @@ -1192,8 +1202,7 @@ ui.prototype.drawPagination = function (page, totalPage, top) { if (top == null) top = this.LAST; core.setFillStyle('ui', '#DDDDDD'); - var length = core.calWidth('ui', page + " / " + page, - "bold 15px " + (core.status.globalAttribute || core.initStatus.globalAttribute).font); + var length = core.calWidth('ui', page + " / " + page, this._buildFont(15, true)); core.setTextAlign('ui', 'left'); core.fillText('ui', page + " / " + totalPage, parseInt((this.PIXEL - length) / 2), top*32+19); @@ -1228,50 +1237,43 @@ ui.prototype.drawBook = function (index) { var enemys = core.enemys.getCurrentEnemys(floorId); core.clearUI(); core.clearMap('data'); + // 生成groundPattern + core.maps.generateGroundPattern(floorId); + this._drawBook_drawBackground(); + core.setAlpha('ui', 1); + + if (enemys.length == 0) { + core.setTextAlign('ui', 'center'); + core.fillText('ui', "本层无怪物", this.HPIXEL, this.HPIXEL + 14, '#999999', this._buildFont(50, true)); + core.fillText('ui', '返回游戏', this.PIXEL - 46, this.PIXEL - 13,'#DDDDDD', this._buildFont(15, true)); + return; + } - if (this._drawBook_drawBackground(floorId, enemys)) return; index = core.clamp(index, 0, enemys.length - 1); - var perpage = this.HSIZE, page = parseInt(index / perpage) + 1; - var totalPage = parseInt((enemys.length - 1) / perpage) + 1; core.status.event.data = index; - var start = (page - 1) * perpage, end = Math.min(page * perpage, enemys.length); - enemys = enemys.slice(start, end); + var perpage = this.HSIZE, page = parseInt(index / perpage) + 1, totalPage = Math.ceil(enemys.length / perpage); + var start = (page - 1) * perpage; + enemys = enemys.slice(start, page * perpage); - for (var i = 0; i < enemys.length; i++) { - this._drawBook_drawOne(floorId, i, enemys[i]); - } - - if (index - start >= 0 && index - start < enemys.length) { - core.strokeRect('ui', 10, 62 * (index - start) + 13, this.PIXEL - 10 * 2, 62, '#FFD700'); - } + for (var i = 0; i < enemys.length; i++) + this._drawBook_drawOne(floorId, i, enemys[i], index == start + i); core.drawBoxAnimate(); this.drawPagination(page, totalPage); core.fillText('ui', '返回游戏', this.PIXEL - 46, this.PIXEL - 13,'#DDDDDD', this._buildFont(15, true)); } -ui.prototype._drawBook_drawBackground = function (floorId, enemys) { - // 生成groundPattern - core.maps.generateGroundPattern(floorId); - +ui.prototype._drawBook_drawBackground = function () { + core.setAlpha('ui', 1); core.setFillStyle('ui', core.material.groundPattern); core.fillRect('ui', 0, 0, this.PIXEL, this.PIXEL); core.setAlpha('ui', 0.6); core.setFillStyle('ui', '#000000'); core.fillRect('ui', 0, 0, this.PIXEL, this.PIXEL); - - core.setAlpha('ui', 1); - if (enemys.length == 0) { - core.setTextAlign('ui', 'center'); - core.fillText('ui', "本层无怪物", this.HPIXEL, this.HPIXEL + 14, '#999999', this._buildFont(50, true)); - core.fillText('ui', '返回游戏', this.PIXEL - 46, this.PIXEL - 13,'#DDDDDD', this._buildFont(15, true)); - return true; - } - return false; } -ui.prototype._drawBook_drawOne = function (floorId, index, enemy) { +ui.prototype._drawBook_drawOne = function (floorId, index, enemy, selected) { // --- 区域规划:每个区域总高度为62,宽度为 PIXEL var top = 62 * index + 12; // 最上面margin是12px // 横向规划: @@ -1279,29 +1281,11 @@ ui.prototype._drawBook_drawOne = function (floorId, index, enemy) { this._drawBook_drawBox(index, enemy, top); // 剩余 PIXEL - 64 的宽度,按照 10 : 9 : 8 : 8 的比例划分 var left = 64, total_width = this.PIXEL - left; - var name_width = total_width * 10 / 35, - col1_width = total_width * 9 / 35, col1_offset = left + name_width, - col2_width = total_width * 8 / 35, col2_offset = col1_offset + col2_width, - col3_width = total_width * 8 / 35, col3_offset = col2_offset + col3_width; - this._drawBook_drawNameCol(index, enemy, top, left, name_width); - - // 第二行:金币、加点、经验 - var second_line = []; - if (core.flags.enableMoney) second_line.push(["金币", core.formatBigNumber(enemy.money || 0)]); - if (core.flags.enableAddPoint) second_line.push(["加点", core.formatBigNumber(enemy.point || 0)]); - if (core.flags.enableExperience && second_line.length < 2) - second_line.push(["经验", core.formatBigNumber(enemy.experience || 0)]); - var cnt = second_line.length; - - this._drawBook_drawCol1(index, enemy, top, col1_offset, col1_width, second_line); - this._drawBook_drawCol2(index, enemy, top, col2_offset, col2_width, second_line); - this._drawBook_drawCol3(index, enemy, top, col3_offset, col3_width); - - // get damage offset - var damageOffset = col1_offset + (col1_width + col2_width + col3_width) / 2 - 12; - if (cnt == 1) damageOffset = col2_offset + (col2_width + col3_width) / 2 - 12; - else if (cnt == 2) damageOffset = col3_offset + col3_width / 2 - 12; - this._drawBook_drawDamage(index, enemy, top, damageOffset); + var name_width = total_width * 10 / 35; + this._drawBook_drawName(index, enemy, top, left, name_width); + this._drawBook_drawContent(index, enemy, top, left + name_width); + if (selected) + core.strokeRect('ui', 10, top + 1, this.PIXEL - 10 * 2, 62, '#FFD700'); } ui.prototype._drawBook_drawBox = function (index, enemy, top) { @@ -1317,7 +1301,7 @@ ui.prototype._drawBook_drawBox = function (index, enemy, top) { }); } -ui.prototype._drawBook_drawNameCol = function (index, enemy, top, left, width) { +ui.prototype._drawBook_drawName = function (index, enemy, top, left, width) { // 绘制第零列(名称和特殊属性) // 如果需要添加自己的比如怪物的称号等,也可以在这里绘制 core.setTextAlign('ui', 'center'); @@ -1333,47 +1317,70 @@ ui.prototype._drawBook_drawNameCol = function (index, enemy, top, left, width) { } } -ui.prototype._drawBook_drawCol1 = function (index, enemy, top, left, width, second_line) { - // 绘制第一列 +ui.prototype._drawBook_drawContent = function (index, enemy, top, left) { + var width = this.PIXEL - left; // 9 : 8 : 8 划分三列 + this._drawBook_drawRow1(index, enemy, top, left, width, top + 20); + this._drawBook_drawRow2(index, enemy, top, left, width, top + 38); + this._drawBook_drawRow3(index, enemy, top, left, width, top + 56); +} + +ui.prototype._drawBook_drawRow1 = function (index, enemy, top, left, width, position) { + // 绘制第一行 core.setTextAlign('ui', 'left'); var b13 = this._buildFont(13, true), f13 = this._buildFont(13, false); - core.fillText('ui', '生命', left, top + 20, '#DDDDDD', f13); - core.fillText('ui', core.formatBigNumber(enemy.hp||0), left + 30, top + 20, null, b13); - if (second_line.length>0) { + var col1 = left, col2 = left + width * 9 / 25, col3 = left + width * 17 / 25; + core.fillText('ui', '生命', col1, position, '#DDDDDD', f13); + core.fillText('ui', core.formatBigNumber(enemy.hp||0), col1 + 30, position, null, b13); + core.fillText('ui', '攻击', col2, position, null, f13); + core.fillText('ui', core.formatBigNumber(enemy.atk||0), col2 + 30, position, null, b13); + core.fillText('ui', '防御', col3, position, null, f13); + core.fillText('ui', core.formatBigNumber(enemy.def||0), col3 + 30, position, null, b13); +} + +ui.prototype._drawBook_drawRow2 = function (index, enemy, top, left, width, position) { + // 绘制第二行 + core.setTextAlign('ui', 'left'); + var b13 = this._buildFont(13, true), f13 = this._buildFont(13, false); + var col1 = left, col2 = left + width * 9 / 25, col3 = left + width * 17 / 25; + // 获得第二行绘制的内容 + var second_line = []; + if (core.flags.enableMoney) second_line.push(["金币", core.formatBigNumber(enemy.money || 0)]); + if (core.flags.enableAddPoint) second_line.push(["加点", core.formatBigNumber(enemy.point || 0)]); + if (core.flags.enableExperience) second_line.push(["经验", core.formatBigNumber(enemy.experience || 0)]); + + var damage_offset = col1 + (this.PIXEL - col1) / 2 - 12; + // 第一列 + if (second_line.length > 0) { var one = second_line.shift(); - core.fillText('ui', one[0], left, top + 38, '#DDDDDD', f13); - core.fillText('ui', one[1], left + 30, top + 38, null, b13); + core.fillText('ui', one[0], col1, position, '#DDDDDD', f13); + core.fillText('ui', one[1], col1 + 30, position, null, b13); + damage_offset = col2 + (this.PIXEL - col2) / 2 - 12; } - core.fillText('ui', '临界', left, top + 56, '#DDDDDD', f13); - core.fillText('ui', core.formatBigNumber(enemy.critical||0), left + 30, top + 56, null, b13); -} - -ui.prototype._drawBook_drawCol2 = function (index, enemy, top, left, width, second_line) { - // 绘制第二列 - core.setTextAlign('ui', 'left'); - var b13 = this._buildFont(13, true), f13 = this._buildFont(13, false); - core.fillText('ui', '攻击', left, top + 20, '#DDDDDD', f13); - core.fillText('ui', core.formatBigNumber(enemy.atk||0), left + 30, top + 20, null, b13); - if (second_line.length>0) { + // 第二列 + if (second_line.length > 0) { var one = second_line.shift(); - core.fillText('ui', one[0], left, top + 38, '#DDDDDD', f13); - core.fillText('ui', one[1], left + 30, top + 38, null, b13); + core.fillText('ui', one[0], col2, position, '#DDDDDD', f13); + core.fillText('ui', one[1], col2 + 30, position, null, b13); + damage_offset = col3 + (this.PIXEL - col3) / 2 - 12; } - core.fillText('ui', '减伤', left, top + 56, '#DDDDDD', f13); - core.fillText('ui', core.formatBigNumber(enemy.criticalDamage||0), left + 30, top + 56, null, b13); + // 忽略第三列,直接绘制伤害 + this._drawBook_drawDamage(index, enemy, damage_offset, position); } -ui.prototype._drawBook_drawCol3 = function (index, enemy, top, left, width) { - // 绘制第三列 +ui.prototype._drawBook_drawRow3 = function (index, enemy, top, left, width, position) { + // 绘制第三行 core.setTextAlign('ui', 'left'); var b13 = this._buildFont(13, true), f13 = this._buildFont(13, false); - core.fillText('ui', '防御', left, top + 20, '#DDDDDD', f13); - core.fillText('ui', core.formatBigNumber(enemy.def||0), left + 30, top + 20, null, b13); - core.fillText('ui', '1防', left, top + 56, '#DDDDDD', f13); - core.fillText('ui', core.formatBigNumber(enemy.defDamage||0), left + 30, top + 56, null, b13); + var col1 = left, col2 = left + width * 9 / 25, col3 = left + width * 17 / 25; + core.fillText('ui', '临界', col1, position, '#DDDDDD', f13); + core.fillText('ui', core.formatBigNumber(enemy.critical||0), col1 + 30, position, null, b13); + core.fillText('ui', '减伤', col2, position, null, f13); + core.fillText('ui', core.formatBigNumber(enemy.criticalDamage||0), col2 + 30, position, null, b13); + core.fillText('ui', '1防', col3, position, null, f13); + core.fillText('ui', core.formatBigNumber(enemy.defDamage||0), col3 + 30, position, null, b13); } -ui.prototype._drawBook_drawDamage = function (index, enemy, top, damageOffset) { +ui.prototype._drawBook_drawDamage = function (index, enemy, offset, position) { core.setTextAlign('ui', 'center'); var damage = enemy.damage, color = '#FFFF00'; if (damage == null) { @@ -1389,12 +1396,13 @@ ui.prototype._drawBook_drawDamage = function (index, enemy, top, damageOffset) { if (core.enemys.hasSpecial(enemy, 11)) damage += "^"; } if (enemy.notBomb) damage += "[b]"; - core.fillText('ui', damage, damageOffset, top + 38, color, this._buildFont(13, true)); + core.fillText('ui', damage, offset, position, color, this._buildFont(13, true)); } ////// 绘制怪物属性的详细信息 ////// ui.prototype.drawBookDetail = function (index) { var info = this._drawBookDetail_getInfo(index), enemy = info[0]; + if (!enemy) return; var content = info[1].join("\n"); core.status.event.id = 'book-detail'; clearInterval(core.interval.tipAnimate); @@ -1417,7 +1425,7 @@ ui.prototype.drawBookDetail = function (index) { ui.prototype._drawBookDetail_getInfo = function (index) { var floorId = core.floorIds[(core.status.event.ui||{}).index] || core.status.floorId; var enemys = core.enemys.getCurrentEnemys(floorId); - if (enemys.length==0) return; + if (enemys.length==0) return []; index = core.clamp(index, 0, enemys.length - 1); var enemy = enemys[index], enemyId = enemy.id; var texts=core.enemys.getSpecialHint(enemyId); @@ -1557,7 +1565,7 @@ ui.prototype.drawFly = function(page) { var middle = this.HPIXEL + 39; if (core.actions._getNextFlyFloor(1) != page) { core.fillText('ui', '▲', this.PIXEL - 60, middle - 64, null, this._buildFont(17, false)); - core.fillText('ui', '▲', this.PIXEL - 60, middle - 96,); + core.fillText('ui', '▲', this.PIXEL - 60, middle - 96); core.fillText('ui', '▲', this.PIXEL - 60, middle - 96 - 7); } if (core.actions._getNextFlyFloor(-1) != page) { @@ -1708,466 +1716,418 @@ ui.prototype._drawMaps_buildData = function (index, x, y) { ////// 绘制道具栏 ////// ui.prototype.drawToolbox = function(index) { - // 设定eventdata - if (!core.isset(core.status.event.data) || !core.isset(core.status.event.data.toolsPage) || !core.isset(core.status.event.data.constantsPage)) - core.status.event.data = {"toolsPage":1, "constantsPage":1, "selectId":null} + var info = this._drawToolbox_getInfo(index); + this._drawToolbox_drawBackground(); + // 绘制线 + core.setAlpha('ui', 1); + core.setStrokeStyle('ui', '#DDDDDD'); + core.canvas.ui.lineWidth = 2; + core.canvas.ui.strokeWidth = 2; + core.setTextAlign('ui', 'right'); + var line1 = this.PIXEL - 306; + this._drawToolbox_drawLine(line1, "消耗道具"); + var line2 = this.PIXEL - 146; + this._drawToolbox_drawLine(line2, "永久道具"); + + this._drawToolbox_drawDescription(info, line1); + + this._drawToolbox_drawContent(info, line1, info.tools, info.toolsPage, true); + this.drawPagination(info.toolsPage, info.toolsTotalPage, this.LAST - 5); + this._drawToolbox_drawContent(info, line2, info.constants, info.constantsPage); + this.drawPagination(info.constantsPage, info.constantsTotalPage); + + core.setTextAlign('ui', 'center'); + core.fillText('ui', '[装备栏]', this.PIXEL - 46, 25, '#DDDDDD', this._buildFont(15, true)); + core.fillText('ui', '返回游戏', this.PIXEL - 46, this.PIXEL - 13); +} + +ui.prototype._drawToolbox_getInfo = function (index) { + // 设定eventdata + if (!core.status.event.data || core.status.event.data.toolsPage == null) + core.status.event.data = {"toolsPage":1, "constantsPage":1, "selectId":null} // 获取物品列表 var tools = Object.keys(core.status.hero.items.tools).sort(); var constants = Object.keys(core.status.hero.items.constants).sort(); - // 处理页数 var toolsPage = core.status.event.data.toolsPage; var constantsPage = core.status.event.data.constantsPage; - var toolsTotalPage = Math.ceil(tools.length/12); - var constantsTotalPage = Math.ceil(constants.length/12); - + var toolsTotalPage = Math.ceil(tools.length/this.LAST); + var constantsTotalPage = Math.ceil(constants.length/this.LAST); // 处理index - if (!core.isset(index)) { - if (tools.length>0) index=0; - else if (constants.length>0) index=12; - else index=0; - } + if (index == null) + index = tools.length == 0 && constants.length > 0 ? this.LAST : 0; core.status.event.selection=index; - // 确认选择对象 - var select; - var selectId; - if (index<12) { - select = index + (toolsPage-1)*12; + var select, selectId; + if (index=tools.length) select=Math.max(0, tools.length-1); selectId = tools[select]; } else { - select = index%12 + (constantsPage-1)*12; + select = index%this.LAST + (constantsPage-1)*this.LAST; if (select>=constants.length) select=Math.max(0, constants.length-1); selectId = constants[select]; } if (!core.hasItem(selectId)) selectId=null; core.status.event.data.selectId=selectId; + return { + index: index, tools: tools, constants: constants, toolsPage: toolsPage, constantsPage: constantsPage, + toolsTotalPage: toolsTotalPage, constantsTotalPage: constantsTotalPage, selectId: selectId + }; +} +ui.prototype._drawToolbox_drawBackground = function () { // 绘制 core.clearMap('ui'); core.setAlpha('ui', 0.85); - core.fillRect('ui', 0, 0, 416, 416, '#000000'); - core.setAlpha('ui', 1); + core.fillRect('ui', 0, 0, this.PIXEL, this.PIXEL, '#000000'); +} + +ui.prototype._drawToolbox_drawLine = function (yoffset, text) { core.setFillStyle('ui', '#DDDDDD'); - core.setStrokeStyle('ui', '#DDDDDD'); - core.canvas.ui.lineWidth = 2; - core.canvas.ui.strokeWidth = 2; - - var ydelta = 20; - - // 画线 core.canvas.ui.beginPath(); - core.canvas.ui.moveTo(0, 130-ydelta); - core.canvas.ui.lineTo(416, 130-ydelta); + core.canvas.ui.moveTo(0, yoffset); + core.canvas.ui.lineTo(this.PIXEL, yoffset); core.canvas.ui.stroke(); core.canvas.ui.beginPath(); - core.canvas.ui.moveTo(416,129-ydelta); - core.canvas.ui.lineTo(416,105-ydelta); - core.canvas.ui.lineTo(416-72,105-ydelta); - core.canvas.ui.lineTo(416-102,129-ydelta); + core.canvas.ui.moveTo(this.PIXEL, yoffset-1); + core.canvas.ui.lineTo(this.PIXEL, yoffset-25); + core.canvas.ui.lineTo(this.PIXEL-72, yoffset-25); + core.canvas.ui.lineTo(this.PIXEL-102, yoffset-1); core.canvas.ui.fill(); + core.fillText('ui', text, this.PIXEL - 5, yoffset-6, '#333333', this._buildFont(16, true)); +} - core.canvas.ui.beginPath(); - core.canvas.ui.moveTo(0, 290-ydelta); - core.canvas.ui.lineTo(416, 290-ydelta); - core.canvas.ui.stroke(); - core.canvas.ui.beginPath(); - core.canvas.ui.moveTo(416,289-ydelta); - core.canvas.ui.lineTo(416,265-ydelta); - core.canvas.ui.lineTo(416-72,265-ydelta); - core.canvas.ui.lineTo(416-102,289-ydelta); - core.canvas.ui.fill(); - - // 文字 - core.setTextAlign('ui', 'right'); - var globalFont = core.status.globalAttribute.font; - core.fillText('ui', "消耗道具", 411, 124-ydelta, '#333333', "bold 16px "+globalFont); - core.fillText('ui', "永久道具", 411, 284-ydelta); - +ui.prototype._drawToolbox_drawDescription = function (info, max_height) { core.setTextAlign('ui', 'left'); - // 描述 - if (core.isset(selectId)) { - var item=core.material.items[selectId]; - core.fillText('ui', item.name, 10, 32, '#FFD700', "bold 20px "+globalFont) - - var text = item.text||"该道具暂无描述。"; - try { - // 检查能否eval - text = core.replaceText(text); - } catch (e) {} - - var lines = core.splitLines('ui', text, 406, '17px '+globalFont); - - core.fillText('ui', lines[0], 10, 62, '#FFFFFF', '17px '+globalFont); - - if (lines.length==1) { - core.fillText('ui', '<继续点击该道具即可进行使用>', 10, 89, '#CCCCCC', '14px '+globalFont); - } - else { - var leftText = text.substring(lines[0].length); - core.fillText('ui', leftText, 10, 89, '#FFFFFF', '17px '+globalFont); - } + if (!info.selectId) return; + var item=core.material.items[info.selectId]; + core.fillText('ui', item.name, 10, 32, '#FFD700', this._buildFont(20, true)) + var text = item.text||"该道具暂无描述。"; + try { + // 检查能否eval + text = core.replaceText(text); + } catch (e) {} + var lines = core.splitLines('ui', text, this.PIXEL - 15, this._buildFont(17, false)); + // --- 开始逐行绘制 + var curr = 62, line_height = 25; + core.setFillStyle('ui', '#FFFFFF'); + for (var i=0;i=max_height) break; } + if (curr < max_height) { + core.fillText('ui', '<继续点击该道具即可进行使用>', 10, curr, '#CCCCCC', this._buildFont(14, false)); + } +} +ui.prototype._drawToolbox_drawContent = function (info, line, items, page, drawCount) { core.setTextAlign('ui', 'right'); - var images = core.material.images.items; - - // 消耗道具 - for (var i=0;i<12;i++) { - var tool=tools[12*(toolsPage-1)+i]; - if (!core.isset(tool)) break; - var yoffset = 144 + Math.floor(i/6)*54 + 5 - ydelta; - var icon=core.material.icons.items[tool]; - core.drawImage('ui', images, 0, icon*32, 32, 32, 16*(4*(i%6)+1)+5, yoffset, 32, 32) - // 个数 - core.fillText('ui', core.itemCount(tool), 16*(4*(i%6)+1)+40, yoffset+33, '#FFFFFF', "bold 14px "+globalFont); - if (selectId == tool) - core.strokeRect('ui', 16*(4*(i%6)+1)+1, yoffset-4, 40, 40, '#FFD700'); + for (var i = 0; i < this.LAST; i++) { + var item = items[this.LAST * (page - 1) + i]; + if (!item) continue; + var yoffset = line + 54 * Math.floor(i / this.HSIZE) + 19; + var icon = core.material.icons.items[item], image = core.material.images.items; + core.drawImage('ui', image, 0, 32 * icon, 32, 32, 64 * (i % this.HSIZE) + 21, yoffset, 32, 32); + if (drawCount) + core.fillText('ui', core.itemCount(item), 64 * (i % this.HSIZE) + 56, yoffset + 33, '#FFFFFF', this._buildFont(14, true)); + if (info.selectId == item) + core.strokeRect('ui', 64 * (i % this.HSIZE) + 17, yoffset - 4, 40, 40, '#FFD700'); } - - // 永久道具 - for (var i=0;i<12;i++) { - var constant=constants[12*(constantsPage-1)+i]; - if (!core.isset(constant)) break; - var yoffset = 304+Math.floor(i/6)*54+5-ydelta; - var icon=core.material.icons.items[constant]; - core.drawImage('ui', images, 0, icon*32, 32, 32, 16*(4*(i%6)+1)+5, yoffset, 32, 32) - if (selectId == constant) - core.strokeRect('ui', 16*(4*(i%6)+1)+1, yoffset-4, 40, 40, '#FFD700'); - } - - // 分页 - this.drawPagination(toolsPage, toolsTotalPage, 7); - this.drawPagination(constantsPage, constantsTotalPage, 12); - - core.setTextAlign('ui', 'center'); - - // 装备栏 - // if (core.flags.equipment) - core.fillText('ui', '[装备栏]', 370, 25,'#DDDDDD', 'bold 15px '+globalFont); - // core.fillText('ui', '删除道具', 370, 32,'#DDDDDD', 'bold 15px '+globalFont); - // 退出 - core.fillText('ui', '返回游戏', 370, 403,'#DDDDDD', 'bold 15px '+globalFont); } ////// 绘制装备界面 ////// ui.prototype.drawEquipbox = function(index) { - // 设定eventdata - if (!core.isset(core.status.event.data) || !core.isset(core.status.event.data.page)) - core.status.event.data = {"page":1, "selectId":null}; + var info = this._drawEquipbox_getInfo(index); + this._drawToolbox_drawBackground(); + core.setAlpha('ui', 1); + core.setStrokeStyle('ui', '#DDDDDD'); + core.canvas.ui.lineWidth = 2; + core.canvas.ui.strokeWidth = 2; + core.setTextAlign('ui', 'right'); + var line1 = this.PIXEL - 306; + this._drawToolbox_drawLine(line1, "当前装备"); + var line2 = this.PIXEL - 146; + this._drawToolbox_drawLine(line2, "拥有装备"); + + this._drawEquipbox_description(info, line1); + + this._drawEquipbox_drawEquiped(info, line1); + this._drawToolbox_drawContent(info, line2, info.ownEquipment, info.page, true); + this.drawPagination(info.page, info.totalPage); + + core.setTextAlign('ui', 'center'); + core.fillText('ui', '[道具栏]', this.PIXEL - 46, 25, '#DDDDDD', this._buildFont(15, true)); + core.fillText('ui', '返回游戏', this.PIXEL - 46, this.PIXEL - 13); +} + +ui.prototype._drawEquipbox_getInfo = function (index) { + if (!core.status.event.data || core.status.event.data.page == null) + core.status.event.data = {"page":1, "selectId":null}; var allEquips = core.status.globalAttribute.equipName; var equipLength = allEquips.length; - - if (!core.isset(core.status.hero.equipment)) core.status.hero.equipment = []; - + if (!core.status.hero.equipment) core.status.hero.equipment = []; var equipEquipment = core.status.hero.equipment; var ownEquipment = Object.keys(core.status.hero.items.equips).sort(); - var page = core.status.event.data.page; - var totalPage = Math.ceil(ownEquipment.length/12); - + var totalPage = Math.ceil(ownEquipment.length / this.LAST); // 处理index - if (!core.isset(index)) { - if (equipLength>0 && core.isset(equipEquipment[0])) index=0; - else if (ownEquipment.length>0) index=12; - else index=0; + if (index == null) { + if (equipLength > 0 && equipEquipment[0]) index = 0; + else if (ownEquipment.length > 0) index = this.LAST; + else index = 0; } - if (index>=12 && ownEquipment.length==0) index = 0; + if (index >= this.LAST && ownEquipment.length == 0) index = 0; var selectId=null; - if (index<12) { + if (index < this.LAST) { if (index >= equipLength) index=Math.max(0, equipLength - 1); - selectId = equipEquipment[index]||null; + selectId = equipEquipment[index] || null; } else { - if (page == totalPage) index = Math.min(index, (ownEquipment.length+11)%12+12); - selectId = ownEquipment[index-12 + (page-1)*12]; + if (page == totalPage) index = Math.min(index, (ownEquipment.length+this.LAST-1)%this.LAST+this.LAST); + selectId = ownEquipment[index - this.LAST + (page - 1) * this.LAST]; if (!core.hasItem(selectId)) selectId=null; } core.status.event.selection=index; core.status.event.data.selectId=selectId; + return { index: index, selectId: selectId, page: page, totalPage: totalPage, allEquips: allEquips, + equipLength: equipLength, equipEquipment: equipEquipment, ownEquipment: ownEquipment}; +} - core.clearMap('ui', 0, 0, 416, 416); - core.setAlpha('ui', 0.85); - core.fillRect('ui', 0, 0, 416, 416, '#000000'); - core.setAlpha('ui', 1); - core.setFillStyle('ui', '#DDDDDD'); - core.setStrokeStyle('ui', '#DDDDDD'); - core.canvas.ui.lineWidth = 2; - core.canvas.ui.strokeWidth = 2; - - var ydelta = 20; - - // 画线 - core.canvas.ui.beginPath(); - core.canvas.ui.moveTo(0, 130-ydelta); - core.canvas.ui.lineTo(416, 130-ydelta); - core.canvas.ui.stroke(); - core.canvas.ui.beginPath(); - core.canvas.ui.moveTo(416,129-ydelta); - core.canvas.ui.lineTo(416,105-ydelta); - core.canvas.ui.lineTo(416-72,105-ydelta); - core.canvas.ui.lineTo(416-102,129-ydelta); - core.canvas.ui.fill(); - - core.canvas.ui.beginPath(); - core.canvas.ui.moveTo(0, 290-ydelta); - core.canvas.ui.lineTo(416, 290-ydelta); - core.canvas.ui.stroke(); - core.canvas.ui.beginPath(); - core.canvas.ui.moveTo(416,289-ydelta); - core.canvas.ui.lineTo(416,265-ydelta); - core.canvas.ui.lineTo(416-72,265-ydelta); - core.canvas.ui.lineTo(416-102,289-ydelta); - core.canvas.ui.fill(); - - // 文字 - core.setTextAlign('ui', 'right'); - var globalFont = core.status.globalAttribute.font; - core.fillText('ui', "当前装备", 411, 124-ydelta, '#333333', "bold 16px "+globalFont); - core.fillText('ui', "拥有装备", 411, 284-ydelta); - +ui.prototype._drawEquipbox_description = function (info, max_height) { core.setTextAlign('ui', 'left'); + if (!info.selectId) return; + var equip=core.material.items[info.selectId]; + // --- 标题 + if (!equip.equip) equip.equip = {"type": 0}; + var equipType = equip.equip.type, equipString; + if (typeof equipType === 'string') { + equipString = equipType || "未知部位"; + equipType = core.items.getEquipTypeByName(equipType); + } + else equipString = info.allEquips[equipType] || "未知部位"; + core.fillText('ui', equip.name + "(" + equipString + ")", 10, 32, '#FFD700', this._buildFont(20, true)) + // --- 描述 + var text = equip.text || "该装备暂无描述。"; + try { + text = core.replaceText(text); + } catch (e) {} + var lines = core.splitLines('ui', text, this.PIXEL - 15, this._buildFont(17, false)); + var curr = 62, line_height = 25; + core.setFillStyle('ui', '#FFFFFF'); + for (var i = 0; i < lines.length; ++i) { + core.fillText('ui', lines[i], 10, curr); + curr += line_height; + if (curr >= max_height) break; + } + // --- 变化值 + if (curr >= max_height) return; + this._drawEquipbox_drawStatusChanged(info, curr, equip, equipType); +} - // 描述 - if (core.isset(selectId)) { - var equip=core.material.items[selectId]; - if (!core.isset(equip.equip)) equip.equip = {"type": 0}; - var equipType = equip.equip.type; - var equipString; - if (typeof equipType === 'string') { - equipString = equipType||"未知部位"; - equipType = core.items.getEquipTypeByName(equipType); - } - else equipString = allEquips[equipType]||"未知部位"; - - core.fillText('ui', equip.name + "(" + equipString + ")", 10, 32, '#FFD700', "bold 20px "+globalFont) - - var text = equip.text||"该装备暂无描述。"; - try { - text = core.replaceText(text); - } catch (e) {} - var lines = core.splitLines('ui', text, 406, '17px '+globalFont); - - core.fillText('ui', lines[0], 10, 62, '#FFFFFF', '17px '+globalFont); - - // 比较属性 - if (lines.length==1) { - var compare, differentMode = null; - if (index<12) compare = core.compareEquipment(null, selectId); - else { - if (equipType<0) { - differentMode = '<当前没有该装备的空位,请先卸下装备>'; - } - else { - var last = core.material.items[equipEquipment[equipType]]||{}; - // 检查是不是数值模式和比例模式之间的切换 - if (core.isset(last.equip) && (last.equip.percentage||false) != (equip.equip.percentage||false)) { - differentMode = '<数值和比例模式之间的切换不显示属性变化>'; - } - else { - compare = core.compareEquipment(selectId, equipEquipment[equipType]); - } - } - } - if (differentMode != null) { - core.fillText('ui', differentMode, 10, 89, '#CCCCCC', '14px '+globalFont); - } - else { - var drawOffset = 10; - [['攻击','atk'], ['防御','def'], ['魔防','mdef']].forEach(function (t) { - var title = t[0], name = t[1]; - if (!core.isset(compare[name]) || compare[name]==0) return; - var color = '#00FF00'; - if (compare[name]<0) color = '#FF0000'; - var nowValue = core.getStatus(name), newValue = nowValue + compare[name]; - if (equip.equip.percentage) { - var nowBuff = core.getBuff(name), newBuff = nowBuff+compare[name]/100; - nowValue = Math.floor(nowBuff*core.getStatus(name)); - newValue = Math.floor(newBuff*core.getStatus(name)); - } - var content = title + ' ' + nowValue + '->'; - core.fillText('ui', content, drawOffset, 89, '#CCCCCC', 'bold 14px '+globalFont); - drawOffset += core.calWidth('ui', content); - core.fillText('ui', newValue, drawOffset, 89, color); - drawOffset += core.calWidth('ui', newValue) + 15; - }) - } - } +ui.prototype._drawEquipbox_drawStatusChanged = function (info, y, equip, equipType) { + var compare, differentMode = null; + if (info.index < this.LAST) compare = core.compareEquipment(null, info.selectId); + else { + if (equipType<0) differentMode = '<当前没有该装备的空位,请先卸下装备>'; else { - var leftText = text.substring(lines[0].length); - core.fillText('ui', leftText, 10, 89, '#FFFFFF', '17px '+globalFont); + var last = core.material.items[info.equipEquipment[equipType]]||{}; + if (last.equip && (last.equip.percentage || false) != (equip.equip.percentage || false)) + differentMode = '<数值和比例模式之间的切换不显示属性变化>'; + else + compare = core.compareEquipment(info.selectId, info.equipEquipment[equipType]); } } + if (differentMode != null) { + core.fillText('ui', differentMode, 10, y, '#CCCCCC', this._buildFont(14, false)); + return; + } + var drawOffset = 10; + // --- 变化值... + core.setFont('ui', this._buildFont(14, true)); + for (var name in compare) { + var img = core.statusBar.icons[name]; + if (img) { // 绘制图标 + core.drawImage('ui', img, 0, 0, 32, 32, drawOffset, y - 13, 16, 16); + drawOffset += 20; + } + else { // 绘制文字 + core.fillText('ui', name + " ", drawOffset, y, '#CCCCCC'); + drawOffset += core.calWidth('ui', name + " "); + } + var nowValue = core.getStatus(name) * core.getBuff(name), newValue = (nowValue + compare[name]) * core.getBuff(name); + if (equip.equip.percentage) { + var nowBuff = core.getBuff(name), newBuff = nowBuff + compare[name] / 100; + nowValue = Math.floor(nowBuff * core.getStatus(name)); + newValue = Math.floor(newBuff * core.getStatus(name)); + } + nowValue = core.formatBigNumber(nowValue); + newValue = core.formatBigNumber(newValue); + core.fillText('ui', nowValue + "->", drawOffset, y, '#CCCCCC'); + drawOffset += core.calWidth('ui', nowValue + "->"); + core.fillText('ui', newValue, drawOffset, y, compare[name]>0?'#00FF00':'#FF0000'); + drawOffset += core.calWidth('ui', newValue) + 8; + } +} +ui.prototype._drawEquipbox_drawEquiped = function (info, line) { core.setTextAlign('ui', 'right'); - var images = core.material.images.items; - + var per_line = this.HSIZE - 3, width = Math.floor(this.PIXEL / (per_line + 0.25)); // 当前装备 - for (var i = 0 ; i < equipLength ; i++) { - var equipId = equipEquipment[i] || null; - if (core.isset(equipId)) { + for (var i = 0; i < info.equipLength ; i++) { + var equipId = info.equipEquipment[i] || null; + var offset_text = width * (i % per_line) + 56; + var offset_image = width * (i % per_line) + width * 2 / 3; + var y = line + 54 * Math.floor(i / per_line) + 19; + if (equipId) { var icon = core.material.icons.items[equipId]; - core.drawImage('ui', images, 0, icon*32, 32, 32, 16*(8*(i%3)+5)+5, 144+Math.floor(i/3)*54+5-ydelta, 32, 32); + core.drawImage('ui', core.material.images.items, 0, 32 * icon, 32, 32, offset_image, y, 32, 32); } - core.fillText('ui', allEquips[i]||"未知", 16*(8*(i%3)+1)+40, 144+Math.floor(i/3)*54+32-ydelta, '#FFFFFF', "bold 16px "+globalFont); - core.strokeRect('ui', 16*(8*(i%3)+5)+1, 144+Math.floor(i/3)*54+1-ydelta, 40, 40, index==i?'#FFD700':"#FFFFFF"); + core.fillText('ui', info.allEquips[i] || "未知", offset_text, y + 27, '#FFFFFF', this._buildFont(16, true)) + core.strokeRect('ui', offset_image - 4, y - 4, 40, 40, info.index==i?'#FFD700':"#FFFFFF"); } - - // 现有装备 - for (var i=0;i<12;i++) { - var ownEquip=ownEquipment[12*(page-1)+i]; - if (!core.isset(ownEquip)) continue; - var icon=core.material.icons.items[ownEquip]; - core.drawImage('ui', images, 0, icon*32, 32, 32, 16*(4*(i%6)+1)+5, 304+Math.floor(i/6)*54+5-ydelta, 32, 32) - // 个数 - if (core.itemCount(ownEquip)>1) - core.fillText('ui', core.itemCount(ownEquip), 16*(4*(i%6)+1)+40, 304+Math.floor(i/6)*54+38-ydelta, '#FFFFFF', "bold 14px "+globalFont); - if (index>=12 && selectId == ownEquip) - core.strokeRect('ui', 16*(4*(i%6)+1)+1, 304+Math.floor(i/6)*54+1-ydelta, 40, 40, '#FFD700'); - } - - this.drawPagination(page, totalPage, 12); - // 道具栏 - core.setTextAlign('ui', 'center'); - core.fillText('ui', '[道具栏]', 370, 25,'#DDDDDD', 'bold 15px '+globalFont); - // 退出按钮 - core.fillText('ui', '返回游戏', 370, 403,'#DDDDDD', 'bold 15px '+globalFont); } ////// 绘制存档/读档界面 ////// ui.prototype.drawSLPanel = function(index, refresh) { - if (!core.isset(index)) index=1; - if (index<0) index=0; + core.control._loadFavoriteSaves(); + if (index == null) index = 1; + if (index < 0) index = 0; var page = parseInt(index/10), offset=index%10; var max_page = main.savePages || 30; + if(core.status.event.data && core.status.event.data.mode=='fav') + max_page = Math.ceil((core.saves.favorite||[]).length/5); if (page>=max_page) page=max_page - 1; if (offset>5) offset=5; - index=10*page+offset; + if (core.status.event.data && core.status.event.data.mode=='fav' && page == max_page - 1) { + offset = Math.min(offset, (core.saves.favorite||[]).length - 5 * page); + } var last_page = -1; - if (core.isset(core.status.event.data)) { - last_page = parseInt(core.status.event.data/10); + var mode = 'all'; + if (core.status.event.data) { + last_page = core.status.event.data.page; + mode = core.status.event.data.mode; } - - core.status.event.data=index; - if (!core.isset(core.status.event.ui)) + core.status.event.data={ 'page':page, 'offset':offset, 'mode':mode }; + core.status.event.ui = core.status.event.ui || []; + if (refresh || page != last_page) { core.status.event.ui = []; + this._drawSLPanel_loadSave(page, function () { + core.ui._drawSLPanel_draw(page, max_page); + }); + } + else this._drawSLPanel_draw(page, max_page); +} - var u=416/6, size=118; +ui.prototype._drawSLPanel_draw = function (page, max_page) { + // --- 绘制背景 + this._drawSLPanel_drawBackground(); + // --- 绘制文字 + core.ui.drawPagination(page+1, max_page); + core.setTextAlign('ui', 'center'); + var bottom = this.PIXEL-13; + core.fillText('ui', '返回游戏', this.PIXEL-48, bottom, '#DDDDDD', this._buildFont(15, true)); + if (core.status.event.selection) + core.setFillStyle('ui', '#FF6A6A'); + if (core.status.event.id=='save') + core.fillText('ui', '删除模式', 48, bottom); + else{ + if(core.status.event.data.mode=='all'){ + core.fillText('ui', '[E]显示收藏', 52, bottom); + }else{ + core.fillText('ui', '[E]显示全部', 52, bottom); + } + } + // --- 绘制记录 + this._drawSLPanel_drawRecords(); +} + +ui.prototype._drawSLPanel_drawBackground = function() { + core.clearMap('ui'); + core.setAlpha('ui', 0.85); + core.fillRect('ui', 0, 0, this.PIXEL, this.PIXEL, '#000000');//可改成背景图图 + core.setAlpha('ui', 1); +} + +ui.prototype._drawSLPanel_loadSave = function(page, callback) { + var ids = [0]; + for (var i = 1; i <= 5; ++i) { + var id = 5 * page + i; + if(core.status.event.data.mode=='fav') + id = core.saves.favorite[id - 1]; // 因为favorite第一个不是自动存档 所以要偏移1 + ids.push(id); + } + core.getSaves(ids, function (data) { + for (var i = 0; i < ids.length; ++i) + core.status.event.ui[i] = data[i]; + core.saves.autosave.data = data[0]; + callback(); + }); +} + +// 在以x为中心轴 y为顶坐标 的位置绘制一条宽为size的记录 cho表示是否被选中 选中会加粗 highlight表示高亮标题 ✐ +ui.prototype._drawSLPanel_drawRecord = function(title, data, x, y, size, cho, highLight){ var strokeColor = '#FFD700'; if (core.status.event.selection) strokeColor = '#FF6A6A'; - var globalFont = (core.status.globalAttribute||core.initStatus.globalAttribute).font; + if (!data || !data.floorId) highLight = false; - var drawBg = function() { - core.clearMap('ui'); - core.setAlpha('ui', 0.85); - core.fillRect('ui', 0, 0, 416, 416, '#000000'); - core.setAlpha('ui', 1); - - core.ui.drawPagination(page+1, max_page, 12); - core.setTextAlign('ui', 'center'); - // 退出 - core.fillText('ui', '返回游戏', 370, 403,'#DDDDDD', 'bold 15px '+globalFont); - - if (core.status.event.selection) - core.setFillStyle('ui', '#FF6A6A'); - if (core.status.event.id=='save') - core.fillText('ui', '删除模式', 48, 403); - else - core.fillText('ui', '输入编号', 48, 403); + core.fillText('ui', title, x, y, highLight?'#FFD700':'#FFFFFF', this._buildFont(17, true)); + core.strokeRect('ui', x-size/2, y+15, size, size, cho?strokeColor:'#FFFFFF', cho?6:2); + if (data && data.floorId) { + core.drawThumbnail(data.floorId, core.maps.loadMap(data.maps, data.floorId).blocks, { + heroLoc: data.hero.loc, heroIcon: data.hero.flags.heroIcon, flags: data.hero.flags + }, { + ctx: 'ui', x: x-size/2, y: y+15, size: size, centerX: data.hero.loc.x, centerY: data.hero.loc.y + }); + var v = core.formatBigNumber(data.hero.hp,true)+"/"+core.formatBigNumber(data.hero.atk,true)+"/"+core.formatBigNumber(data.hero.def,true); + var v2 = "/"+core.formatBigNumber(data.hero.mdef,true); + if (core.calWidth('ui', v + v2, this._buildFont(10, false)) <= size) v += v2; + core.fillText('ui', v, x, y+30+size, '#FFD700'); + core.fillText('ui', core.formatDate(new Date(data.time)), x, y+43+size, data.hero.flags.__consoleOpened__?'#FF6A6A':'#FFFFFF'); } - - var draw = function (data, i) { - var name=core.status.event.id=='save'?"存档":core.status.event.id=='load'?"读档":core.status.event.id=='replayLoad'?"回放":""; - core.status.event.ui[i] = data; - var id=5*page+i; - if (i<3) { - core.fillText('ui', i==0?"自动存档":name+id, (2*i+1)*u, 30, '#FFFFFF', "bold 17px "+globalFont); - core.strokeRect('ui', (2*i+1)*u-size/2, 45, size, size, i==offset?strokeColor:'#FFFFFF', i==offset?6:2); - if (core.isset(data) && core.isset(data.floorId)) { - core.drawThumbnail(data.floorId, core.maps.loadMap(data.maps, data.floorId).blocks, { - heroLoc: data.hero.loc, heroIcon: data.hero.flags.heroIcon, flags: data.hero.flags - }, { - ctx: 'ui', x: (2*i+1)*u-size/2, y: 45, size: size, centerX: data.hero.loc.x, centerY: data.hero.loc.y - }); - var v = core.formatBigNumber(data.hero.hp,true)+"/"+core.formatBigNumber(data.hero.atk,true)+"/"+core.formatBigNumber(data.hero.def,true); - var v2 = "/"+core.formatBigNumber(data.hero.mdef,true); - if (v.length+v2.length<=21) v+=v2; - core.fillText('ui', v, (2*i+1)*u, 60+size, '#FFD700', '10px '+globalFont); - core.fillText('ui', core.formatDate(new Date(data.time)), (2*i+1)*u, 73+size, data.hero.flags.__consoleOpened__?'#FF6A6A':'#FFFFFF'); - } - else { - core.fillRect('ui', (2*i+1)*u-size/2, 45, size, size, '#333333', 2); - core.fillText('ui', '空', (2*i+1)*u, 112, '#FFFFFF', 'bold 30px '+globalFont); - } - } - else { - core.fillText('ui', name+id, (2*i-5)*u, 218, '#FFFFFF', "bold 17px "+globalFont); - core.strokeRect('ui', (2*i-5)*u-size/2, 233, size, size, i==offset?strokeColor:'#FFFFFF', i==offset?6:2); - if (core.isset(data) && core.isset(data.floorId)) { - core.drawThumbnail(data.floorId, core.maps.loadMap(data.maps, data.floorId).blocks, { - heroLoc: data.hero.loc, heroIcon: data.hero.flags.heroIcon, flags: data.hero.flags - }, { - ctx: 'ui', x: (2*i-5)*u-size/2, y: 233, size: size, centerX: data.hero.loc.x, centerY: data.hero.loc.y - }); - var v = core.formatBigNumber(data.hero.hp,true)+"/"+core.formatBigNumber(data.hero.atk,true)+"/"+core.formatBigNumber(data.hero.def,true); - var v2 = "/"+core.formatBigNumber(data.hero.mdef,true); - if (v.length+v2.length<=21) v+=v2; - core.fillText('ui', v, (2*i-5)*u, 248+size, '#FFD700', '10px '+globalFont); - core.fillText('ui', core.formatDate(new Date(data.time)), (2*i-5)*u, 261+size, data.hero.flags.__consoleOpened__?'#FF6A6A':'#FFFFFF', '10px '+globalFont); - } - else { - core.fillRect('ui', (2*i-5)*u-size/2, 233, size, size, '#333333', 2); - core.fillText('ui', '空', (2*i-5)*u, 297, '#FFFFFF', 'bold 30px '+globalFont); - } - } - }; - - function loadSave(i, callback) { - if (i==6) { - callback(); - return; - } - - if (i==0) { - if (core.saves.autosave.data!=null) { - core.status.event.ui[i] = core.saves.autosave.data; - loadSave(1, callback); - } - else { - core.getLocalForage("autoSave", null, function(data) { - core.saves.autosave.data = data; - core.status.event.ui[i]=data; - loadSave(i+1, callback); - }, function(err) {main.log(err);}); - } - } - else { - core.getLocalForage("save"+(5*page+i), null, function(data) { - core.status.event.ui[i]=data; - loadSave(i+1, callback); - }, function(err) {main.log(err);}); - } - } - - function drawAll() { - drawBg(); - for (var i=0;i<6;i++) - draw(core.status.event.ui[i], i); - } - if (refresh || page!=last_page) { - core.status.event.ui = []; - loadSave(0, drawAll); - } - else drawAll(); + else { + core.fillRect('ui', x-size/2, y+15, size, size, '#333333', 2); + core.fillText('ui', '空', x, parseInt(y+22+size/2), '#FFFFFF', this._buildFont(30,true)); + } } +ui.prototype._drawSLPanel_drawRecords = function (n) { + var page = core.status.event.data.page; + var offset = core.status.event.data.offset; + var u = Math.floor(this.PIXEL/6), size = Math.floor(this.PIXEL/3-20); + var name=core.status.event.id=='save'?"存档":core.status.event.id=='load'?"读档":core.status.event.id=='replayLoad'?"回放":""; + + for (var i = 0; i < (n||6); i++){ + var data = core.status.event.ui[i]; + var id = 5 * page + i; + var highLight = (i>0&&core.saves.favorite.indexOf(id)>=0) || core.status.event.data.mode=='fav'; + var title = (highLight?'★ ':'☆ ') + (core.saves.favoriteName[id] || (name + id)); + if (i != 0 && core.status.event.data.mode=='fav') { + if (!data) break; + var real_id = core.saves.favorite[id - 1]; + title = (core.saves.favoriteName[real_id] || (name + real_id)) + ' ✐'; + } + + var charSize = 32;// 字体占用像素范围 + var topSpan = parseInt((this.PIXEL-charSize-2*(charSize*2 + size))/3);// Margin + var yTop1 = topSpan+parseInt(charSize/2) + 8;//文字的中心 + var yTop2 = yTop1+charSize*2+size+topSpan; + if (i<3) { + this._drawSLPanel_drawRecord(i==0?"自动存档":title, data, (2*i+1)*u, yTop1, size, i==offset, highLight); + } + else { + this._drawSLPanel_drawRecord(title, data, (2*i-5)*u, yTop2, size, i==offset, highLight); + } + } +}; + ui.prototype.drawKeyBoard = function () { core.lockControl(); core.status.event.id = 'keyBoard'; @@ -2177,7 +2137,7 @@ ui.prototype.drawKeyBoard = function () { var left = (this.PIXEL - width) / 2, right = left + width; var top = (this.PIXEL - height) / 2, bottom = top + height; - var isWindowSkin = this._drawTextBox_drawBackground({}, {}, {left:left, right:right}, {top:top, bottom: bottom}); + var isWindowSkin = this.drawBackground(left, top, right, bottom); core.setTextAlign('ui', 'center'); core.setFillStyle('ui', core.arrayToRGBA(core.status.textAttribute.title)); core.fillText('ui', '虚拟键盘', this.HPIXEL, top + 35, null, this._buildFont(22, true)); @@ -2222,17 +2182,12 @@ ui.prototype.drawStatistics = function (floorIds) { (floorIds || core.floorIds).forEach(function (floorId) { core.ui._drawStatistics_floorId(floorId, obj); }); - var formatTime = function (time) { - return core.setTwoDigits(parseInt(time/3600000)) - +":"+core.setTwoDigits(parseInt(time/60000)%60) - +":"+core.setTwoDigits(parseInt(time/1000)%60); - } var statistics = core.status.hero.statistics; core.drawText([ this._drawStatistics_generateText(obj, "全塔", obj.total), this._drawStatistics_generateText(obj, "当前", obj.current), - "当前总步数:"+core.status.hero.steps+",当前游戏时长:"+formatTime(statistics.currTime) - +",总游戏时长"+formatTime(statistics.totalTime) + "当前总步数:"+core.status.hero.steps+",当前游戏时长:"+core.formatTime(statistics.currTime) + +",总游戏时长"+core.formatTime(statistics.totalTime) +"。\n瞬间移动次数:"+statistics.moveDirectly+",共计少走"+statistics.ignoreSteps+"步。" +"\n\n总计通过血瓶恢复生命值为"+core.formatBigNumber(statistics.hp)+"点。\n\n" +"总计打死了"+statistics.battle+"个怪物,得到了"+core.formatBigNumber(statistics.money)+"金币,"+core.formatBigNumber(statistics.experience)+"点经验。\n\n" diff --git a/libs/utils.js b/libs/utils.js index 1bca52b0..4dbd3e34 100644 --- a/libs/utils.js +++ b/libs/utils.js @@ -348,6 +348,12 @@ utils.prototype.formatDate2 = function (date) { + core.setTwoDigits(date.getHours()) + core.setTwoDigits(date.getMinutes()) + core.setTwoDigits(date.getSeconds()); } +utils.prototype.formatTime = function (time) { + return core.setTwoDigits(parseInt(time/3600000)) + +":"+core.setTwoDigits(parseInt(time/60000)%60) + +":"+core.setTwoDigits(parseInt(time/1000)%60); +} + ////// 两位数显示 ////// utils.prototype.setTwoDigits = function (x) { return parseInt(x) < 10 ? "0" + x : x; @@ -461,6 +467,8 @@ utils.prototype._encodeRoute_encodeOne = function (t) { return "P" + t.substring(6); else if (t.indexOf('input2:') == 0) return "Q" + t.substring(7) + ":"; + else if (t.indexOf('common:') == 0) + return "c" + t.substring(7) + ":"; else if (t == 'no') return 'N'; else if (t.indexOf('move:') == 0) @@ -519,7 +527,7 @@ utils.prototype._decodeRoute_number2id = function (number) { } utils.prototype._decodeRoute_decodeOne = function (decodeObj, c) { - var nxt = (c == 'I' || c == 'e' || c == 'F' || c == 'S' || c == 'Q' || c == 't') ? + var nxt = (c == 'I' || c == 'e' || c == 'F' || c == 'S' || c == 'Q' || c == 't' || c == 'c') ? this._decodeRoute_getString(decodeObj) : this._decodeRoute_getNumber(decodeObj); var mp = {"U": "up", "D": "down", "L": "left", "R": "right"}; @@ -564,6 +572,9 @@ utils.prototype._decodeRoute_decodeOne = function (decodeObj, c) { case "Q": decodeObj.ans.push("input2:" + nxt); break; + case "c": + decodeObj.ans.push("common:" + nxt); + break; case "N": decodeObj.ans.push("no"); break; diff --git a/main.js b/main.js index a6c60bba..9d26b266 100644 --- a/main.js +++ b/main.js @@ -675,7 +675,7 @@ window.onblur = function () { if (main.core && main.core.control) { try { main.core.control.checkAutosave(); - } catch (e) {main.log(e);} + } catch (e) {} } } diff --git a/project/data.js b/project/data.js index 878a6ca0..5b612081 100644 --- a/project/data.js +++ b/project/data.js @@ -249,6 +249,8 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = "name": "贪婪之神", "icon": "blueShop", "textInList": "1F金币商店", + "commonTimes": false, + "mustEnable": false, "use": "money", "need": "20+10*times*(times+1)", "text": "勇敢的武士啊,给我${need}金币就可以:", @@ -276,6 +278,8 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = "name": "经验之神", "icon": "pinkShop", "textInList": "1F经验商店", + "commonTimes": false, + "mustEnable": false, "use": "experience", "need": "-1", "text": "勇敢的武士啊,给我若干经验就可以:", @@ -296,6 +300,13 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = "effect": "status:def+=5" } ] + }, + { + "id": "keyShop1", + "textInList": "1F回收钥匙商店", + "mustEnable": false, + "commonEvent": "回收钥匙商店", + "args": "" } ], "levelUp": [ @@ -397,6 +408,7 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = "enableMoveDirectly": true, "enableDisabledShop": true, "disableShopOnDamage": false, + "quickCommonEvents": false, "checkConsole": false } } \ No newline at end of file diff --git a/project/events.js b/project/events.js index 85eb07ca..cfc58540 100644 --- a/project/events.js +++ b/project/events.js @@ -237,6 +237,100 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 = ], "false": [] } + ], + "回收钥匙商店": [ + { + "type": "comment", + "text": "此事件在全局商店中被引用了(全局商店keyShop1)" + }, + { + "type": "comment", + "text": "解除引用前勿删除此事件" + }, + { + "type": "comment", + "text": "玩家在快捷列表(V键)中可以使用本公共事件" + }, + { + "type": "while", + "condition": "1", + "data": [ + { + "type": "choices", + "text": "\t[商人,woman]你有多余的钥匙想要出售吗?", + "choices": [ + { + "text": "黄钥匙(10金币)", + "color": [ + 255, + 255, + 0, + 1 + ], + "action": [ + { + "type": "if", + "condition": "item:yellowKey >= 1", + "true": [ + { + "type": "addValue", + "name": "item:yellowKey", + "value": "-1" + }, + { + "type": "addValue", + "name": "status:money", + "value": "10" + } + ], + "false": [ + "\t[商人,woman]你没有黄钥匙!" + ] + } + ] + }, + { + "text": "蓝钥匙(50金币)", + "color": [ + 0, + 0, + 255, + 1 + ], + "action": [ + { + "type": "if", + "condition": "item:blueKey >= 1", + "true": [ + { + "type": "addValue", + "name": "item:blueKey", + "value": "-1" + }, + { + "type": "addValue", + "name": "status:money", + "value": "50" + } + ], + "false": [ + "\t[商人,woman]你没有蓝钥匙!" + ] + } + ] + }, + { + "text": "离开", + "action": [ + { + "type": "exit" + } + ] + } + ] + } + ] + } ] } } \ No newline at end of file diff --git a/project/functions.js b/project/functions.js index 64e05bf8..2044fe73 100644 --- a/project/functions.js +++ b/project/functions.js @@ -699,7 +699,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = gid = guards[i][2]; // 递归计算支援怪伤害信息,这里不传x,y保证不会重复调用 // 这里的mdef传0,因为护盾应该只会被计算一次 - var info = core.enemys.getDamageInfo(core.material.enemys[gid], origin_hero_hp, origin_hero_atk, origin_hero_def, 0); + var info = core.enemys.getDamageInfo(core.material.enemys[gid], { hp: origin_hero_hp, atk: origin_hero_atk, def: origin_hero_def, mdef: 0 }); if (info == null) { // 小队中任何一个怪物不可战斗,直接返回null return null; } diff --git a/project/icons.js b/project/icons.js index 71bce353..0fe339c2 100644 --- a/project/icons.js +++ b/project/icons.js @@ -259,7 +259,7 @@ var icons_4665ee12_3a1f_44a4_bea3_0fccba634dc1 = "hammer": 48, "jumpShoes": 49, "skill1": 30, - "I73": 10 + "wand": 10 }, "autotile": { "autotile": 0, diff --git a/project/items.js b/project/items.js index 83b236c7..efda5b71 100644 --- a/project/items.js +++ b/project/items.js @@ -303,7 +303,7 @@ var items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a = "text": "可以打开或关闭主动技能二倍斩", "hideInReplay": true }, - "I73": { + "wand": { "cls": "items", "name": "新物品" } diff --git a/project/maps.js b/project/maps.js index 78a610d0..d631d0ba 100644 --- a/project/maps.js +++ b/project/maps.js @@ -67,7 +67,7 @@ var maps_90f36752_8815_4be8_b32b_d7fad1d0542e = "70": {"cls":"items","id":"sword0"}, "71": {"cls":"items","id":"shield0"}, "72": {"cls":"items","id":"skill1"}, - "73": {"cls":"items","id":"I73"}, + "73": {"cls":"items","id":"wand"}, "81": {"cls":"terrains","id":"yellowDoor","trigger":"openDoor"}, "82": {"cls":"terrains","id":"blueDoor","trigger":"openDoor"}, "83": {"cls":"terrains","id":"redDoor","trigger":"openDoor"},