From 00876fa43fc2cb7e504377e0415ed3cee49a5428 Mon Sep 17 00:00:00 2001 From: strawberry42271 <2806566736@qq.com> Date: Sun, 16 Mar 2025 19:07:11 +0800 Subject: [PATCH] =?UTF-8?q?=E6=95=99=E5=AD=A6demo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _server/table/plugins.comment.js | 6 + project/data.js | 4 +- project/floors/jiaocheng01.js | 4 +- project/floors/jiaocheng02.js | 4 +- project/functions.js | 4 +- project/icons.js | 3 +- project/items.js | 36 +- project/maps.js | 1 + project/materials/items.png | Bin 18696 -> 22527 bytes project/plugins.js | 3575 ++++++++++++++++-------------- 10 files changed, 1951 insertions(+), 1686 deletions(-) diff --git a/_server/table/plugins.comment.js b/_server/table/plugins.comment.js index 0ea6e33..a9cb7a1 100644 --- a/_server/table/plugins.comment.js +++ b/_server/table/plugins.comment.js @@ -128,6 +128,12 @@ var plugins_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = { "_type": "textarea", "_range": "typeof(thiseval)=='string' || thiseval==null", "_data": "背景音乐拼接" + }, + "scrollingText": { + "_leaf": true, + "_type": "textarea", + "_range": "typeof(thiseval)=='string' || thiseval==null", + "_data": "接收&发送在线留言" } } if (obj[key]) return obj[key]; diff --git a/project/data.js b/project/data.js index 9047933..c8c6aef 100644 --- a/project/data.js +++ b/project/data.js @@ -1520,7 +1520,7 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = }, "firstData": { "title": "秽翼的尤斯蒂娅", - "name": "Eustia", + "name": "Eustia_text", "version": "鸽子窝造塔小队", "floorId": "jiaocheng01", "hero": { @@ -1935,7 +1935,7 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = }, { "type": "function", - "function": "function(){\ncore.getItem('book', 1);\ncore.getItem('fly', 1);\n}" + "function": "function(){\ncore.getItem('book', 1);\ncore.getItem('fly', 1);\ncore.getItem('postman', 1);\ncore.getItem('I369', 1);\n}" }, { "type": "insert", diff --git a/project/floors/jiaocheng01.js b/project/floors/jiaocheng01.js index ee12147..1c5cd0f 100644 --- a/project/floors/jiaocheng01.js +++ b/project/floors/jiaocheng01.js @@ -1,7 +1,7 @@ main.floors.jiaocheng01= { "floorId": "jiaocheng01", - "title": "广场", + "title": "教程1", "name": "1", "width": 13, "height": 13, @@ -70,7 +70,7 @@ main.floors.jiaocheng01= [129, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,129], [ 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1] ], - "areas": "牢狱", + "areas": "教程", "bgmap": [ ], diff --git a/project/floors/jiaocheng02.js b/project/floors/jiaocheng02.js index 78b800f..e36624e 100644 --- a/project/floors/jiaocheng02.js +++ b/project/floors/jiaocheng02.js @@ -1,7 +1,7 @@ main.floors.jiaocheng02= { "floorId": "jiaocheng02", - "title": "广场", + "title": "教程2", "name": "1", "width": 13, "height": 13, @@ -82,7 +82,7 @@ main.floors.jiaocheng02= [ 28, 1, 30, 1, 27,129, 0,204, 0, 33, 0, 23, 0], [ 1, 1, 1, 1, 1, 1, 93, 1, 1, 1, 1, 1, 1] ], - "areas": "牢狱", + "areas": "教程", "bgmap": [ ], diff --git a/project/functions.js b/project/functions.js index 459927d..9727b82 100644 --- a/project/functions.js +++ b/project/functions.js @@ -192,6 +192,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = core.plugin.bfs(); } } + if (!core.isReplaying()) core.plugin.drawCommentSign() }, "flyTo": function (toId, callback) { // 楼层传送器的使用,从当前楼层飞往toId @@ -2022,6 +2023,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = nowy = core.getHeroLoc("y"); var block = core.getBlock(nowx, nowy); var hasTrigger = false; + core.showComment(nowx, nowy) if ( block != null && block.event.trigger == "getItem" && @@ -2061,7 +2063,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = core.status.hero.statistics.poisonDamage += damage; core.status.hero.hp -= damage; } - + core.showComment(nowx, nowy) core.clearMap("hero"); if ( core.bigmap.width * 32 === core.bigmap.height * 32 && diff --git a/project/icons.js b/project/icons.js index 73914d5..36641a7 100644 --- a/project/icons.js +++ b/project/icons.js @@ -326,7 +326,8 @@ var icons_4665ee12_3a1f_44a4_bea3_0fccba634dc1 = "I373": 36, "I374": 37, "I375": 38, - "I396": 39 + "I396": 39, + "postman": 62 }, "autotile": { "autotile": 0, diff --git a/project/items.js b/project/items.js index aa455cd..b437a50 100644 --- a/project/items.js +++ b/project/items.js @@ -529,9 +529,31 @@ var items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a = "canUseItemEffect": "true" }, "I369": { - "cls": "items", - "name": "新物品", - "canUseItemEffect": "true" + "cls": "constants", + "name": "动画开关", + "canUseItemEffect": "true", + "hideInToolbox": true, + "hideInReplay": true, + "useItemEvent": [ + { + "type": "confirm", + "text": "是否开启战斗动画", + "yes": [ + { + "type": "setValue", + "name": "flag:noAnimate", + "value": "false" + } + ], + "no": [ + { + "type": "setValue", + "name": "flag:noAnimate", + "value": "true" + } + ] + } + ] }, "I370": { "cls": "items", @@ -576,5 +598,13 @@ var items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a = "cls": "items", "name": "新物品", "canUseItemEffect": "true" + }, + "postman": { + "cls": "constants", + "name": "言灵", + "canUseItemEffect": "true", + "text": "可以发送和接收在线留言。", + "hideInToolbox": true, + "hideInReplay": true } } \ No newline at end of file diff --git a/project/maps.js b/project/maps.js index d1b42f0..dddf478 100644 --- a/project/maps.js +++ b/project/maps.js @@ -295,6 +295,7 @@ var maps_90f36752_8815_4be8_b32b_d7fad1d0542e = "394": {"cls":"terrains","id":"T394"}, "395": {"cls":"terrains","id":"T395"}, "396": {"cls":"items","id":"I396"}, + "397": {"cls":"items","id":"postman"}, "20034": {"cls":"tileset","id":"X20034","canPass":true}, "20154": {"cls":"tileset","id":"X20154","canPass":true}, "20216": {"cls":"tileset","id":"X20216","canPass":true}, diff --git a/project/materials/items.png b/project/materials/items.png index 04dc29b26ed379fd8d7537a1d290174c30fe2732..24458727bfae7062f21e09ffcae9325326841555 100644 GIT binary patch literal 22527 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 literal 18696 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 nowValue ? "#00FF00" : "#FF0000"; - nowValue = core.formatBigNumber(nowValue); - newValue = core.formatBigNumber(newValue); - - if (name === "mdef") { - nowValue += "%"; - newValue += "%"; - } - statusText += - core.getStatusLabel(name) + - " " + - nowValue + - "->\r[" + - color + - "]" + - newValue + - "\r\n"; - } - } - itemText = statusText + itemText; - if (item.equip) { - core.drawTextContent(ctx, itemText, { - left: itemText_x, - top: itemCls_middle, - bold: false, - color: "white", - align: "left", - fontSize: itemTextFontSize, - maxWidth: - rightbar_width - - (itemText_x - rightbar_x) * 2 + - itemTextFontSize / 2, - }); - } else { - core.drawTextContent(ctx, itemText, { - left: itemText_x, - top: itemText_y, - bold: false, - color: "white", - align: "left", - fontSize: itemTextFontSize, - maxWidth: - rightbar_width - - (itemText_x - rightbar_x) * 2 + - itemTextFontSize / 2, - }); - } - - ///// *** 退出按钮设置 - var btnRadius = 10; - var btnBorderWidth = 2; - var btnRight = toolboxRight - 2; - var btnBottom = toolboxBottom - 2; - var btnBorderStyle = "#fff"; - ///// *** - - // 获取圆心位置 - var btn_x = btnRight - btnRadius - btnBorderWidth / 2; - btn_y = btnBottom - btnRadius - btnBorderWidth / 2; - drawToolbox_setExitBtn( - ctx, - btn_x, - btn_y, - btnRadius, - btnBorderStyle, - btnBorderWidth - ); - - ///// *** 使用按钮设置 - var useBtnHeight = btnRadius * 2; - // 这里不设置useBtnWidth而是根据各项数据自动得出width - var useBtnRadius = useBtnHeight / 4; - var useBtn_x = rightbar_x + 4, - useBtn_y = btnBottom - useBtnHeight; - var useBtnBorderStyle = "#fff"; - var useBtnBorderWidth = btnBorderWidth; - const batchUseBtn_x = useBtn_x + 50; // 个人觉得,搞这么多参数还不如硬编码 - const hideBtn_y = useBtn_y - useBtnHeight - 8; - ///// *** - - drawToolbox_setUseBtn( - ctx, - useBtn_x, - useBtn_y, - useBtnRadius, - useBtnHeight, - useBtnBorderStyle, - useBtnBorderWidth - ); - if (core.status.event.id === "toolbox") { - drawToolbox_setBatchUseBtn( - ctx, - batchUseBtn_x, - useBtn_y, - useBtnRadius, - useBtnHeight, - useBtnBorderStyle, - useBtnBorderWidth - ); - } - drawToolbox_setHideBtn( - ctx, - useBtn_x, - hideBtn_y, - useBtnRadius, - useBtnHeight, - useBtnBorderStyle, - useBtnBorderWidth - ); - drawToolbox_setShowHideBtn( - ctx, - rightbar_x, - useBtn_y, - useBtnHeight, - useBtnBorderStyle - ); - } - - function drawEquipbox_drawOthers(ctx, obj) { - var info = core.status.thisUIEventInfo; - - ///// *** 装备格设置 - var equipList_lineWidth = 2; - var equipList_boxSize = 32; - var equipList_borderWidth = 2; - var equipList_borderStyle = "#fff"; - var equipList_nameColor = "#fff"; - ///// *** - - var equipList_x = obj.x + 4, - equipList_bottom = obj.obj.y - equipList_lineWidth, - equipList_y = equipList_bottom - obj.obj.oneItemHeight * reduceItem - 2, - equipList_height = equipList_bottom - equipList_y; - var equipList_right = obj.leftbar_right, - equipList_width = equipList_right - equipList_x; - core.drawLine( - ctx, - obj.x, - equipList_bottom + equipList_lineWidth / 2, - equipList_right, - equipList_bottom + equipList_lineWidth / 2, - equipList_borderStyle, - equipList_lineWidth - ); - var toDrawList = core.status.globalAttribute.equipName, - len = toDrawList.length; - - ///// *** 装备格设置 - var maxItem = 2; - var box_width = 32, - box_height = 32, - box_borderStyle = "#fff", - box_selectBorderStyle = "gold", // 选中的装备格的颜色 - box_borderWidth = 2; - var boxName_fontSize = 14, - boxName_space = 2, - boxName_color = "#fff"; // 装备格名称与上面的装备格框的距离 - var maxLine = Math.ceil(len / maxItem); - ///// *** - var l = Math.sqrt(len); - if (Math.pow(l) == len && len != 4) { - if (l <= maxItem) maxItem = l; - } - maxItem = Math.min(toDrawList.length, maxItem); - info.equips = maxItem; - - var boxName_font = core.ui._buildFont(boxName_fontSize); - // 总宽高减去所有装备格宽高得到空隙大小 - var oneBoxWidth = box_width + box_borderWidth * 2; - var oneBoxHeight = - box_height + boxName_fontSize + boxName_space + 2 * box_borderWidth; - var space_y = (equipList_height - maxLine * oneBoxHeight) / (1 + maxLine), - space_x = (equipList_width - maxItem * oneBoxWidth) / (1 + maxItem); - var box_x = equipList_x + space_x, - box_y = equipList_y + space_y + 12; - for (var i = 0; i < 2; i++) { - var id = core.getEquip(i), - name = toDrawList[i]; - if (i === 0) name = "主手"; - if (i === 1) name = "副手"; - var selectBorder = false; - if (core.status.thisUIEventInfo.select.type == i) selectBorder = true; - var borderStyle = selectBorder - ? box_selectBorderStyle - : box_borderStyle; - drawEquipbox_drawOne( - ctx, - name, - id, - box_x, - box_y, - box_width, - box_height, - boxName_space, - boxName_font, - boxName_color, - borderStyle, - box_borderWidth - ); - var todo = new Function( - "core.clickOneEquipbox('" + id + "'," + i + ")" - ); - addUIEventListener( - box_x - box_borderWidth / 2, - box_y - box_borderWidth / 2, - oneBoxWidth, - oneBoxHeight, - todo - ); - box_x += space_x + oneBoxWidth; - if ((i + 1) % maxItem == 0) { - box_x = equipList_x + space_x; - box_y += space_y + oneBoxHeight; - } - } - if (core.material.items[core.getEquip(0)]?.equipCls === "双手剑") { - core.drawLine( - ctx, - equipList_x + space_x + space_x + oneBoxWidth, - equipList_y + space_y + 12, - equipList_x + - space_x + - space_x + - oneBoxWidth + - box_width + - box_borderWidth, - equipList_y + space_y + box_height + 12 - ); - core.drawLine( - ctx, - equipList_x + space_x + space_x + oneBoxWidth, - equipList_y + space_y + box_height + 12, - equipList_x + - space_x + - space_x + - oneBoxWidth + - box_width + - box_borderWidth, - equipList_y + space_y + 12 - ); - } - ///// *** 装备格设置 - var maxItem = 3; - var box_width = 32, - box_height = 32, - box_borderStyle = "#fff", - box_selectBorderStyle = "gold", // 选中的装备格的颜色 - box_borderWidth = 2; - var boxName_fontSize = 14, - boxName_space = 2, - boxName_color = "#fff"; // 装备格名称与上面的装备格框的距离 - var maxLine = Math.ceil(len / maxItem); - ///// *** - var l = Math.sqrt(len); - if (Math.pow(l) == len && len != 4) { - if (l <= maxItem) maxItem = l; - } - maxItem = Math.min(toDrawList.length, maxItem); - info.equips = maxItem; - - var boxName_font = core.ui._buildFont(boxName_fontSize); - // 总宽高减去所有装备格宽高得到空隙大小 - var oneBoxWidth = box_width + box_borderWidth * 2; - var oneBoxHeight = - box_height + boxName_fontSize + boxName_space + 2 * box_borderWidth; - var space_y = (equipList_height - maxLine * oneBoxHeight) / (1 + maxLine), - space_x = (equipList_width - maxItem * oneBoxWidth) / (1 + maxItem); - var box_x = equipList_x + space_x, - box_y = equipList_y + space_y + space_y + oneBoxHeight; - for (var i = 2; i < len; i++) { - var id = core.getEquip(i), - name = toDrawList[i]; - var selectBorder = false; - if (core.status.thisUIEventInfo.select.type == i) selectBorder = true; - var borderStyle = selectBorder - ? box_selectBorderStyle - : box_borderStyle; - drawEquipbox_drawOne( - ctx, - name, - id, - box_x, - box_y, - box_width, - box_height, - boxName_space, - boxName_font, - boxName_color, - borderStyle, - box_borderWidth - ); - var todo = new Function( - "core.clickOneEquipbox('" + id + "'," + i + ")" - ); - addUIEventListener( - box_x - box_borderWidth / 2, - box_y - box_borderWidth / 2, - oneBoxWidth, - oneBoxHeight, - todo - ); - box_x += space_x + oneBoxWidth; - } - } - - this.drawToolbox = function (ctx) { - ctx = ctx || core.canvas.ui; - core.status.thisEventClickArea = []; - - var info = drawBoxBackground(ctx); - info.itemNum = itemNum; - drawItemListbox(ctx, info.obj); - drawToolboxRightbar(ctx, info); - core.setTextBaseline(ctx, "alphabetic"); - core.setTextAlign("left"); - }; - - var reduceItem = 4; - this.drawEquipbox = function (ctx) { - ctx = ctx || core.canvas.ui; - core.status.thisEventClickArea = []; - var info = drawBoxBackground(ctx); - info.itemNum = itemNum - reduceItem; - info.obj.y += info.obj.oneItemHeight * reduceItem; - info.obj.height -= info.obj.oneItemHeight * reduceItem; - drawItemListbox(ctx, info.obj); - drawEquipbox_drawOthers(ctx, info); - drawToolboxRightbar(ctx, info); - core.setTextBaseline(ctx, "alphabetic"); - core.setTextAlign("left"); - }; - - function drawEquipbox_drawOne( - ctx, - name, - id, - x, - y, - width, - height, - space, - font, - color, - style, - lineWidth - ) { - if (id) - core.drawIcon( - ctx, - id, - x + lineWidth / 2, - y + lineWidth / 2, - width, - height - ); - core.strokeRect( - ctx, - x, - y, - width + lineWidth, - height + lineWidth, - style, - lineWidth - ); - core.setTextAlign(ctx, "center"); - core.setTextBaseline(ctx, "top"); - var tx = (x + x + lineWidth / 2 + width) / 2, - ty = y + height + (lineWidth / 2) * 3 + space; - core.fillText(ctx, name, tx, ty, color, font); - - core.setAlpha(ctx, 1); - - core.setTextBaseline(ctx, "alphabetic"); - core.setTextAlign("left"); - } - - function drawItemListbox_drawItem( - ctx, - left, - right, - top, - height, - marginLeft, - marginHeight, - style, - id - ) { - var info = core.status.thisUIEventInfo; - var nowClick = info.index; - var item = core.material.items[id] || {}; - var name = item.name || "???"; - var num = core.itemCount(id) || 0; - var fontSize = Math.floor(height - marginHeight * 2); - core.setTextAlign(ctx, "right"); - var numText = "x" + num; - core.fillText( - ctx, - numText, - right - marginLeft, - top + height / 2, - style, - core.ui._buildFont(fontSize) - ); - - const hideInfo = core.getFlag("hideInfo", {}); - if ( - item && - (hideInfo.hasOwnProperty(id) ? hideInfo[id] : item.hideInToolbox) - ) - core.setAlpha(ctx, 0.5); - - if (name != "???") - core.drawIcon( - ctx, - id, - left + marginLeft, - top + marginHeight, - fontSize, - fontSize - ); - var text_x = left + marginLeft + fontSize + 2; - var maxWidth = right - core.calWidth(ctx, numText) - text_x; - core.setTextAlign(ctx, "left"); - core.fillText( - ctx, - name, - text_x, - top + height / 2, - style, - core.ui._buildFont(fontSize), - maxWidth - ); - core.setAlpha(ctx, 1); - - var todo = new Function("core.clickItemFunc('" + id + "');"); - addUIEventListener(left, top, right - left, height, todo); - } - - function setPageItems(page) { - var num = itemNum; - if (core.status.event.id == "equipbox") num -= reduceItem; - var info = core.status.thisUIEventInfo; - if (!info) return; - page = page || info.page; - var items = core.getToolboxItems( - core.status.event.id == "toolbox" ? "all" : "equips", - core.getFlag("showHideItem", false) - ); - info.allItems = items; - var maxPage = Math.ceil(items.length / num); - info.maxPage = maxPage; - var pageItems = items.slice((page - 1) * num, page * num); - info.pageItems = pageItems; - info.maxItem = pageItems.length; - if (items.length == 0 && pageItems.length == 0) info.index = null; - if (pageItems.length == 0 && info.page > 1) { - info.page = Math.max(1, info.page - 1); - return setPageItems(info.page); - } - return pageItems; - } - - function drawToolbox_setExitBtn(ctx, x, y, r, style, lineWidth) { - core.strokeCircle(ctx, x, y, r, style, lineWidth); - ctx.textAlign = "center"; - ctx.textBaseline = "middle"; - var textSize = Math.sqrt(2) * r; - core.fillText( - ctx, - "x", - x, - y, - style, - core.ui._buildFont(textSize), - textSize - ); - core.setTextAlign(ctx, "start"); - core.setTextBaseline(ctx, "top"); - - var todo = function () { - core.closePanel(); - }; - addUIEventListener(x - r, y - r, r * 2, r * 2, todo); - } - - function drawToolbox_setUseBtn(ctx, x, y, r, h, style, lineWidth) { - core.setTextAlign(ctx, "left"); - core.setTextBaseline(ctx, "top"); - var fontSize = h - 4; - var font = core.ui._buildFont(fontSize); - var text = core.status.event.id == "toolbox" ? "使用" : "装备"; - if (core.status.thisUIEventInfo.select.action == "unload") text = "卸下"; - var w = core.calWidth(ctx, text, font) + 2 * r + lineWidth / 2; - - core.strokeRoundRect(ctx, x, y, w, h, r, style, lineWidth); - core.fillText(ctx, text, x + r, y + lineWidth / 2 + 2, style, font); - - var todo = function () { - core.useSelectItemInBox(); - }; - addUIEventListener(x, y, w, h, todo); - } - - function getSelectedItem() { - var info = core.status.thisUIEventInfo; - if ( - !( - info && - info.select.id && - ["toolbox", "equipbox"].includes(core.status.event.id) - ) - ) { - core.drawFailTip("发生了未知错误!"); - return; - } - return info.select.id; - } - - function batchUse(item, count) { - try { - const itemCount = core.itemCount(item); - if (count > itemCount) count = itemCount; - core.closePanel(); - for (let i = 0; i < count; i++) { - if (core.canUseItem(item)) core.useItem(item); - else return; - } - } catch (e) { - console.error(e); - core.drawFailTip("批量使用时出现未知错误!"); - } - } - - function drawToolbox_setBatchUseBtn(ctx, x, y, r, h, style, lineWidth) { - try { - const selectedItem = getSelectedItem(); - let canBatchUse = eval(core.material.items[selectedItem]?.canBatchUse); - if (!canBatchUse) return; - } catch (error) { - console.error(error); - return; - } - core.setTextAlign(ctx, "left"); - core.setTextBaseline(ctx, "top"); - var fontSize = h - 4; - var font = core.ui._buildFont(fontSize); - var text = "批量使用"; - var w = core.calWidth(ctx, text, font) + 2 * r + lineWidth / 2; - - core.strokeRoundRect(ctx, x, y, w, h, r, style, lineWidth); - core.fillText(ctx, text, x + r, y + lineWidth / 2 + 2, style, font); - - var todo = function () { - core.utils.myprompt("输入要使用该物品的次数(0~99)。", null, (value) => { - value = parseInt(value); - const id = getSelectedItem(); - - if (Number.isNaN(value) || value < 0 || value > 99) { - core.drawFailTip("输入不合法!"); - return; - } - if (!core.canUseItem(id)) { - core.drawFailTip("当前无法使用该道具!"); - return; - } - core.closePanel(); - batchUse(id, value); - }); - }; - addUIEventListener(x, y, w, h, todo); - } - - function drawToolbox_setHideBtn(ctx, x, y, r, h, style, lineWidth) { - core.setTextAlign(ctx, "left"); - core.setTextBaseline(ctx, "top"); - var fontSize = h - 4; - var font = core.ui._buildFont(fontSize); - var text = "显示/隐藏"; - var w = core.calWidth(ctx, text, font) + 2 * r + lineWidth / 2; - - core.strokeRoundRect(ctx, x, y, w, h, r, style, lineWidth); - core.fillText(ctx, text, x + r, y + lineWidth / 2 + 2, style, font); - - var todo = function () { - //debugger; - var id = getSelectedItem(); - let hideInfo = core.getFlag("hideInfo", {}); - console.log(id); - if (hideInfo.hasOwnProperty(id)) { - hideInfo[id] = !hideInfo[id]; - core.setFlag("hideInfo", hideInfo); - } else { - hideInfo[id] = !core.material.items[id].hideInToolbox; - core.setFlag("hideInfo", hideInfo); - } - if (core.status.event.id === "toolbox") core.plugin.drawToolbox(); - else if (core.status.event.id === "equipbox") - core.plugin.drawEquipbox(); - }; - addUIEventListener(x, y, w, h, todo); - } - - ui.prototype.getToolboxItems = function (cls, showHide) { - let list = Object.keys(core.status.hero.items[cls] || {}); - if (cls === "all") { - for (let name in core.status.hero.items) { - if (name == "equips") continue; - list = list.concat(Object.keys(core.status.hero.items[name])); - } - if (!showHide) - list = list.filter(function (id2) { - const hideInfo = core.getFlag("hideInfo", {}); - if (hideInfo.hasOwnProperty(id2)) return !hideInfo[id2]; - else return !core.material.items[id2].hideInToolbox; - }); - list = list.sort(); - return list; - } - if (cls === "equips") { - if (!showHide) - list = list.filter(function (id2) { - const hideInfo = core.getFlag("hideInfo", {}); - if (hideInfo.hasOwnProperty(id2)) return !hideInfo[id2]; - else return !core.material.items[id2].hideInToolbox; - }); - - list = list.sort(); - return list; - } - if (this.uidata.getToolboxItems) { - return this.uidata.getToolboxItems(cls, showHide); - } - if (!showHide) - list = list.filter(function (id2) { - return !core.material.items[id2].hideInToolbox; - }); - list = list.sort(); - return list; - }; - - function drawToolbox_setShowHideBtn(ctx, x, y, h, style) { - core.setTextAlign(ctx, "left"); - core.setTextBaseline(ctx, "top"); - var fontSize = h - 6; - var font = core.ui._buildFont(fontSize); - var text = "显示隐藏"; - var w = core.calWidth(ctx, text, font); - h += 4; - const squareSize = h - 6; - - x -= w + squareSize + 26; - - const border = 2; - core.fillRect(ctx, x, y, squareSize, squareSize, " #F5F5F5"); - if (core.hasFlag("showHideItem")) { - core.fillRect( - ctx, - x + border, - y + border, - squareSize - 2 * border, - squareSize - 2 * border, - "lime" - ); - } - core.fillText(ctx, text, x + squareSize + 2, y + 4, style, font); - - var todo = function () { - core.setFlag("showHideItem", !core.getFlag("showHideItem", false)); - if (core.status.event.id === "toolbox") core.plugin.drawToolbox(); - else if (core.status.event.id === "equipbox") - core.plugin.drawEquipbox(); - }; - addUIEventListener(x, y, w, h, todo); - } - - function drawItemListbox_setPageBtn( - ctx, - left, - right, - bottom, - r, - style, - lineWidth - ) { - var offset = lineWidth / 2 + r; - - var x = left + offset; - var y = bottom - offset; - var pos = (Math.sqrt(2) / 2) * (r - lineWidth / 2); - core.fillPolygon( - ctx, - [ - [x - pos, y], - [x + pos - 2, y - pos], - [x + pos - 2, y + pos], - ], - style - ); - core.strokeCircle(ctx, x, y, r, style, lineWidth); - var todo = function () { - core.addItemListboxPage(-1); - }; - addUIEventListener(x - r - 2, y - r - 2, r * 2 + 4, r * 2 + 4, todo); - - x = right - offset; - core.fillPolygon( - ctx, - [ - [x + pos, y], - [x - pos + 2, y - pos], - [x - pos + 2, y + pos], - ], - style - ); - core.strokeCircle(ctx, x, y, r, style, lineWidth); - var todo = function () { - core.addItemListboxPage(1); - }; - addUIEventListener(x - r - 2, y - r - 2, r * 2 + 4, r * 2 + 4, todo); - } - - this.clickItemFunc = function (id) { - var info = core.status.thisUIEventInfo; - if (!info) return; - if (info.select.id == id) return core.useSelectItemInBox(); - info.select = {}; - info.select.id = id; - core.setIndexAndSelect("index"); - refreshBox(); - }; - - this.clickOneEquipbox = function (id, type) { - var info = core.status.thisUIEventInfo; - if (!info) return; - if (info.select.id == id && info.select.type == type) - core.useSelectItemInBox(); - else - core.status.thisUIEventInfo.select = { - id: id, - type: type, - action: "unload", - }; - return refreshBox(); - }; - - this.useSelectItemInBox = function () { - var info = core.status.thisUIEventInfo; - if (!info) return; - if (!info.select.id) return; - var id = info.select.id; - if (core.status.event.id == "toolbox") { - core.events.tryUseItem(id); - // core.closePanel(); - } else if (core.status.event.id == "equipbox") { - var action = info.select.action || "load"; - info.index = 1; - if (action == "load") { - var type = core.getEquipTypeById(id); - let equipClsid = core.material.items[id]?.equipCls; - let equipCls0 = core.material.items[core.getEquip(0)]?.equipCls; - let equipCls1 = core.material.items[core.getEquip(1)]?.equipCls; - if (equipClsid === "双手剑") { - core.unloadEquip(0, function () { - core.status.route.push("unEquip:" + 0); - }); - core.unloadEquip(1, function () { - core.status.route.push("unEquip:" + 1); - }); - } - if ( - equipCls0 === "双手剑" && - !(equipClsid === "饰品" || equipClsid === "护具") - ) { - core.unloadEquip(0, function () { - core.status.route.push("unEquip:" + 0); - }); - } - core.loadEquip(id, function () { - core.status.route.push("equip:" + id); - info.select.type = type; - core.setIndexAndSelect("select"); - core.drawEquipbox(); - }); - } else { - var type = info.select.type; - core.unloadEquip(type, function () { - core.status.route.push("unEquip:" + type); - info.select.type = type; - info.select.action = "load"; - core.setIndexAndSelect("select"); - core.drawEquipbox(); - }); - } - } - core.updateStatusBar(); - }; - - this.setIndexAndSelect = function (toChange) { - var info = core.status.thisUIEventInfo; - if (!info) return; - setPageItems(info.page); - var index = info.index || 1; - var items = info.pageItems; - - info.select.action = null; - info.select.type = null; - if (toChange == "index") info.index = items.indexOf(info.select.id) + 1; - info.select.id = items[info.index - 1]; - }; - - this.addItemListboxPage = function (num) { - var info = core.status.thisUIEventInfo; - if (!info) return; - var maxPage = info.maxPage || 1; - info.page = info.page || 1; - info.page += num; - if (info.page <= 0) info.page = maxPage; - if (info.page > maxPage) info.page = 1; - info.index = 1; - setPageItems(info.page); - core.setIndexAndSelect("select"); - refreshBox(); - }; - - this.addItemListboxIndex = function (num) { - var info = core.status.thisUIEventInfo; - if (!info) return; - var maxItem = info.maxItem || 0; - info.index = info.index || 0; - info.index += num; - if (info.index <= 0) info.index = 1; - if (info.index > maxItem) info.index = maxItem; - core.setIndexAndSelect("select"); - refreshBox(); - }; - - this.addEquipboxType = function (num) { - var info = core.status.thisUIEventInfo; - var type = info.select.type; - if (type == null && num > 0) info.select.type = 0; - else info.select.type = type + num; - var max = core.status.globalAttribute.equipName.length; - if (info.select.type >= max) { - info.select = {}; - core.setIndexAndSelect("select"); - return core.addItemListboxPage(0); - } else { - var m = Math.abs(info.select.type); - if (info.select.type < 0) info.select.type = max - m; - core.setIndexAndSelect("select"); - refreshBox(); - return; - } - }; - - core.actions._keyDownToolbox = function (keycode) { - if (!core.status.thisEventClickArea) return; - if (keycode == 37) { - // left - core.addItemListboxPage(-1); - return; - } - if (keycode == 38) { - // up - core.addItemListboxIndex(-1); - return; - } - if (keycode == 39) { - // right - core.addItemListboxPage(1); - return; - } - if (keycode == 40) { - // down - core.addItemListboxIndex(1); - return; - } - }; - - ////// 工具栏界面时,放开某个键的操作 ////// - core.actions._keyUpToolbox = function (keycode) { - if (keycode == 81) { - core.ui.closePanel(); - if (core.isReplaying()) core.control._replay_equipbox(); - else core.openEquipbox(); - return; - } - if (keycode == 84 || keycode == 27 || keycode == 88) { - core.closePanel(); - return; - } - if (keycode == 13 || keycode == 32 || keycode == 67) { - var info = core.status.thisUIEventInfo; - if (info.select) { - core.useSelectItemInBox(); - } - return; - } - }; - - core.actions._keyDownEquipbox = function (keycode) { - if (!core.status.thisEventClickArea) return; - if (keycode == 37) { - // left - var info = core.status.thisUIEventInfo; - if (info.index != null) return core.addItemListboxPage(-1); - return core.addEquipboxType(-1); - } - if (keycode == 38) { - // up - var info = core.status.thisUIEventInfo; - if (info.index == 1) { - info.select.type = core.status.globalAttribute.equipName.length - 1; - core.setIndexAndSelect(); - return refreshBox(); - } - if (info.index) return core.addItemListboxIndex(-1); - return core.addEquipboxType(-1 * info.equips); - } - if (keycode == 39) { - // right - var info = core.status.thisUIEventInfo; - if (info.index != null) return core.addItemListboxPage(1); - return core.addEquipboxType(1); - } - if (keycode == 40) { - // down - var info = core.status.thisUIEventInfo; - if (info.index) return core.addItemListboxIndex(1); - return core.addEquipboxType(info.equips); - } - }; - - core.actions._keyUpEquipbox = function (keycode, altKey) { - if (altKey && keycode >= 48 && keycode <= 57) { - core.items.quickSaveEquip(keycode - 48); - return; - } - if (keycode == 84) { - core.ui.closePanel(); - if (core.isReplaying()) core.control._replay_toolbox(); - else core.openToolbox(); - return; - } - if (keycode == 81 || keycode == 27 || keycode == 88) { - core.closePanel(); - return; - } - if (keycode == 13 || keycode == 32 || keycode == 67) { - var info = core.status.thisUIEventInfo; - if (info.select) core.useSelectItemInBox(); - return; - } - }; - - core.registerAction( - "ondown", - "inEventClickAction", - function (x, y, px, py) { - if (!core.status.thisEventClickArea) return false; - var info = core.status.thisEventClickArea; - for (var i = 0; i < info.length; i++) { - var obj = info[i]; - if ( - px >= obj.x && - px <= obj.x + obj.width && - py > obj.y && - py < obj.y + obj.height - ) { - if (obj.todo) obj.todo(); - break; - } - } - return true; - }, - 51 - ); - core.registerAction( - "onclick", - "stopClick", - function () { - if (core.status.thisEventClickArea) return true; - }, - 51 - ); - - function addUIEventListener(x, y, width, height, todo) { - if (!core.status.thisEventClickArea) return; - var obj = { - x: x, - y: y, - width: width, - height: height, - todo: todo, - }; - core.status.thisEventClickArea.push(obj); - } - - this.initThisEventInfo = function () { - core.status.thisUIEventInfo = { - page: 1, - select: {}, - }; - core.status.thisEventClickArea = []; - }; - - function refreshBox() { - if (!core.status.event.id) return; - if (core.status.event.id == "toolbox") core.drawToolbox(); - else core.drawEquipbox(); - } - - core.ui.closePanel = function () { - if (core.status.hero && core.status.hero.flags) { - // 清除全部临时变量 - Object.keys(core.status.hero.flags).forEach(function (name) { - if (name.startsWith("@temp@") || /^arg\d+$/.test(name)) { - delete core.status.hero.flags[name]; - } - }); - } - this.clearUI(); - core.maps.generateGroundPattern(); - core.updateStatusBar(true); - core.unlockControl(); - core.status.event.data = null; - core.status.event.id = null; - core.status.event.selection = null; - core.status.event.ui = null; - core.status.event.interval = null; - core.status.thisUIEventInfo = null; - core.status.thisEventClickArea = null; - }; - - this.getItemClsName = function (item) { - if (item == null) return itemClsName; - if (item.cls == "equips") { - if (typeof item.equip.type == "string") return item.equip.type; - var type = core.getEquipTypeById(item.id); - return core.status.globalAttribute.equipName[type]; - } else return itemClsName[item.cls] || item.cls; - }; - - core.events.openToolbox = function (fromUserAction) { - if (core.isReplaying()) return; - if (!this._checkStatus("toolbox", fromUserAction)) return; - core.initThisEventInfo(); - let info = core.status.thisUIEventInfo; - info.index = 1; - core.setIndexAndSelect("select"); - core.drawToolbox(); - }; - - core.events.openEquipbox = function (fromUserAction) { - if (core.isReplaying()) return; - if (!this._checkStatus("equipbox", fromUserAction)) return; - core.initThisEventInfo(); - let info = core.status.thisUIEventInfo; - info.select.type = 0; - core.setIndexAndSelect("select"); - core.drawEquipbox(); - }; - - core.control._replay_toolbox = function () { - if (!core.isPlaying() || !core.isReplaying()) return; - if (!core.status.replay.pausing) return core.drawTip("请先暂停录像"); - if (core.isMoving() || core.status.replay.animate || core.status.event.id) - return core.drawTip("请等待当前事件的处理结束"); - - core.lockControl(); - core.status.event.id = "toolbox"; - core.drawToolbox(); - }; - - core.control._replay_equipbox = function () { - if (!core.isPlaying() || !core.isReplaying()) return; - if (!core.status.replay.pausing) return core.drawTip("请先暂停录像"); - if (core.isMoving() || core.status.replay.animate || core.status.event.id) - return core.drawTip("请等待当前事件的处理结束"); - - core.lockControl(); - core.status.event.id = "equipbox"; - core.drawEquipbox(); - }; - - core.control._replayAction_item = function (action) { - if (action.indexOf("item:") != 0) return false; - var itemId = action.substring(5); - if (!core.canUseItem(itemId)) return false; - if ( - core.material.items[itemId].hideInReplay || - core.status.replay.speed == 24 - ) { - core.useItem(itemId, false, core.replay); - return true; - } - core.status.event.id = "toolbox"; - core.initThisEventInfo(); - var info = core.status.thisUIEventInfo; - var items = core.getToolboxItems( - "all", - core.getFlag("showHideItem", false) - ); - setPageItems(1); - var index = items.indexOf(itemId) + 1; - info.page = Math.ceil(index / info.maxItem); - info.index = index % info.maxItem || info.maxItem; - core.setIndexAndSelect("select"); - setPageItems(info.page); - core.drawToolbox(); - setTimeout(function () { - core.ui.closePanel(); - core.useItem(itemId, false, core.replay); - }, core.control.__replay_getTimeout()); - return true; - }; - - core.control._replayAction_equip = function (action) { - if (action.indexOf("equip:") != 0) return false; - var itemId = action.substring(6); - var items = core.getToolboxItems( - "equips", - core.getFlag("showHideItem", false) - ); - var index = items.indexOf(itemId) + 1; - if (index < 1) { - core.removeFlag("__doNotCheckAutoEvents__"); - return false; - } - - var cb = function () { - var next = core.status.replay.toReplay[0] || ""; - if (!next.startsWith("equip:") && !next.startsWith("unEquip:")) { - core.removeFlag("__doNotCheckAutoEvents__"); - core.checkAutoEvents(); - } - core.replay(); - }; - core.setFlag("__doNotCheckAutoEvents__", true); - - core.status.route.push(action); - if ( - core.material.items[itemId].hideInReplay || - core.status.replay.speed == 24 - ) { - core.loadEquip(itemId, cb); - return true; - } - core.status.event.id = "equipbox"; - core.initThisEventInfo(); - var info = core.status.thisUIEventInfo; - setPageItems(1); - info.page = Math.ceil(index / info.maxItem); - info.index = index % info.maxItem || info.maxItem; - core.setIndexAndSelect("select"); - setPageItems(info.page); - core.drawEquipbox(); - setTimeout(function () { - core.ui.closePanel(); - core.loadEquip(itemId, cb); - }, core.control.__replay_getTimeout()); - return true; - }; - - core.control._replayAction_unEquip = function (action) { - if (action.indexOf("unEquip:") != 0) return false; - var equipType = parseInt(action.substring(8)); - if (!core.isset(equipType)) { - core.removeFlag("__doNotCheckAutoEvents__"); - return false; - } - - var cb = function () { - var next = core.status.replay.toReplay[0] || ""; - if (!next.startsWith("equip:") && !next.startsWith("unEquip:")) { - core.removeFlag("__doNotCheckAutoEvents__"); - core.checkAutoEvents(); - } - core.replay(); - }; - core.setFlag("__doNotCheckAutoEvents__", true); - - core.status.route.push(action); - if (core.status.replay.speed == 24) { - core.unloadEquip(equipType, cb); - return true; - } - core.status.event.id = "equipbox"; - core.initThisEventInfo(); - var info = core.status.thisUIEventInfo; - setPageItems(1); - info.select.type = equipType; - core.setIndexAndSelect(); - core.drawEquipbox(); - setTimeout(function () { - core.ui.closePanel(); - core.unloadEquip(equipType, cb); - }, core.control.__replay_getTimeout()); - return true; - }; - core.registerReplayAction("item", core.control._replayAction_item); - core.registerReplayAction("equip", core.control._replayAction_equip); - core.registerReplayAction("unEquip", core.control._replayAction_unEquip); - }, + core.setAlpha(ctx, backgroundAlpha); + core.strokeRoundRect( + ctx, + x, + y, + w, + h, + borderRadius, + borderStyle, + borderWidth + ); + core.fillRoundRect( + ctx, + start_x, + start_y, + width, + height, + borderRadius, + backgroundColor + ); + core.setAlpha(ctx, 1); + + ///// *** 左栏配置 + var leftbar_height = height; + // 左边栏宽度(width*0.6) 本身仅为坐标使用 需要与底下的rightbar_width(width*0.4)同时更改 + var leftbar_width = width * 0.6; + ///// *** + + // xxx_right参数 代表最右侧坐标 + var leftbar_right = start_x + leftbar_width - borderWidth / 2; + var leftbar_bottom = start_y + leftbar_height; + var leftbar_x = start_x; + var leftbar_y = start_y; + + ///// *** 道具栏配置 + var boxName_color = "#fff"; + var boxName_fontSize = 15; + var boxName_font = core.ui._buildFont(boxName_fontSize, true); + var arrow_x = 10 + start_x; + var arrow_y = 10 + start_y; + var arrow_width = 20; + var arrow_style = "white"; + // 暂时只能是1 否则不太行 等待新样板(2.7.3)之后对drawArrow做优化 + var arrow_lineWidth = 2; + // 右箭头 + var rightArrow_right = leftbar_right - 10; + // 道具内栏顶部坐标 本质是通过该项 控制(道具栏顶部文字和箭头)与道具内栏顶部的间隔 + var itembar_top = arrow_y + 15; + ///// *** + + var itembar_right = rightArrow_right; + var boxName = + core.status.event.id == "toolbox" ? + "\r[yellow]道具栏\r | 装备栏" : + "道具栏 | \r[yellow]装备栏\r"; + core.drawArrow( + ctx, + arrow_x + arrow_width, + arrow_y, + arrow_x, + arrow_y, + arrow_style, + arrow_lineWidth + ); + core.drawArrow( + ctx, + rightArrow_right - arrow_width, + arrow_y, + rightArrow_right, + arrow_y, + arrow_style, + arrow_lineWidth + ); + core.setTextAlign(ctx, "center"); + core.setTextBaseline(ctx, "middle"); + var changeBox = function () { + var id = core.status.event.id; + core.closePanel(); + if (id == "toolbox") core.openEquipbox(); + else core.openToolbox(); + }; + core.fillText( + ctx, + boxName, + (leftbar_right + leftbar_x) / 2, + arrow_y + 2, + boxName_color, + boxName_font + ); + + ///// *** 底栏按钮 + var pageBtn_radius = 8; + // xxx_left 最左侧坐标 + var pageBtn_left = leftbar_x + 3; + var pageBtn_right = leftbar_right - 3; + // xxx_bottom 最底部坐标 + var pageBtn_bottom = leftbar_bottom - 2; + var pageBtn_borderStyle = "#fff"; + var pageBtn_borderWidth = 2; + var pageText_color = "#fff"; + // 底部按钮与上面的道具内栏的间隔大小 + var bottomSpace = 8; + ///// *** + + drawItemListbox_setPageBtn( + ctx, + pageBtn_left, + pageBtn_right, + pageBtn_bottom, + pageBtn_radius, + pageBtn_borderStyle, + pageBtn_borderWidth + ); + var page = info.page || 1; + var pageFontSize = pageBtn_radius * 2 - 4; + var pageFont = core.ui._buildFont(pageFontSize); + setPageItems(page); + var num = itemNum; + if (core.status.event.id == "equipbox") num -= 5; + var maxPage = info.maxPage; + var pageText = page + " / " + maxPage; + core.setTextAlign(ctx, "center"); + core.setTextBaseline(ctx, "bottom"); + core.fillText( + ctx, + pageText, + (leftbar_x + leftbar_right) / 2, + pageBtn_bottom, + pageText_color, + pageFont + ); + addUIEventListener( + start_x, + start_y, + leftbar_right - start_x, + arrow_y - start_y + 13, + changeBox + ); + var itembar_height = Math.ceil( + pageBtn_bottom - + pageBtn_radius * 2 - + pageBtn_borderWidth / 2 - + bottomSpace - + itembar_top + ); + var oneItemHeight = (itembar_height - 4) / itemNum; + return { + x: start_x, + y: start_y, + width: width, + height: height, + leftbar_right: leftbar_right, + obj: { + x: arrow_x, + y: itembar_top, + width: itembar_right - arrow_x, + height: itembar_height, + oneItemHeight: oneItemHeight, + }, + }; + } + + function drawItemListbox(ctx, obj) { + ctx = ctx || core.canvas.ui; + var itembar_x = obj.x, + itembar_y = obj.y, + itembar_width = obj.width, + itembar_height = obj.height, + itemNum = obj.itemNum, + oneItemHeight = obj.oneItemHeight; + var itembar_right = itembar_x + itembar_width; + var info = core.status.thisUIEventInfo || {}; + var obj = {}; + var page = info.page || 1, + index = info.index, + select = info.select || {}; + + ///// *** 道具栏内栏配置 + var itembar_style = "black"; + var itembar_alpha = 0.7; + // 一个竖屏下减少道具显示的例子: + // if (core.domStyle.isVertical) itemNum = 10; + // 每个道具项的上下空隙占总高度的比例 + var itembar_marginHeightRatio = 0.2; + // 左右间隔空隙 + var item_marginLeft = 2; + var item_x = itembar_x + 2, + item_y = itembar_y + 2, + item_right = itembar_right - 2, + itemName_color = "#fff"; + // 修改此项以更换闪烁光标 + var item_selector = "winskin.webp"; + ///// *** + + core.setAlpha(ctx, itembar_alpha); + core.fillRect( + ctx, + itembar_x, + itembar_y, + itembar_width, + itembar_height, + itembar_style + ); + core.setAlpha(ctx, 1); + var pageItems = setPageItems(page); + var marginHeight = itembar_marginHeightRatio * oneItemHeight; + core.setTextBaseline(ctx, "middle"); + var originColor = itemName_color; + for (var i = 0; i < pageItems.length; i++) { + itemName_color = originColor; + var item = pageItems[i]; + // 设置某个的字体颜色的一个例子 + // if (item.id == "xxx") itemName_color = "green"; + drawItemListbox_drawItem( + ctx, + item_x, + item_right, + item_y, + oneItemHeight, + item_marginLeft, + marginHeight, + itemName_color, + pageItems[i] + ); + if (index == i + 1) + core.ui._drawWindowSelector( + item_selector, + item_x + 1, + item_y - 1, + item_right - item_x - 2, + oneItemHeight - 2 + ); + item_y += oneItemHeight; + } + } + + function drawToolboxRightbar(ctx, obj) { + ctx = ctx || core.canvas.ui; + var info = core.status.thisUIEventInfo || {}; + var page = info.page || 1, + index = info.index || 1, + select = info.select || {}; + var start_x = obj.x, + start_y = obj.y, + width = obj.width, + height = obj.height; + var toolboxRight = start_x + width, + toolboxBottom = start_y + height; + + ///// *** 侧边栏(rightbar)背景设置(物品介绍) + var rightbar_width = width * 0.4; + var rightbar_height = height; + var rightbar_lineWidth = 2; + var rightbar_lineStyle = "#fff"; + ///// *** + + var rightbar_x = toolboxRight - rightbar_width - rightbar_lineWidth / 2; + var rightbar_y = start_y; + core.drawLine( + ctx, + rightbar_x, + rightbar_y, + rightbar_x, + rightbar_y + rightbar_height, + rightbar_lineStyle, + rightbar_lineWidth + ); + + // 获取道具id(有可能为null) + var itemId = select.id; + var item = core.material.items[itemId]; + + ///// *** 侧边栏物品Icon信息 + var iconRect_y = rightbar_y + 10; + // space:间距 + // 这里布局设定iconRect与侧边栏左边框 itemName与工具栏右边框 itemRect与itemName的间距均为space + var space = 15; + var iconRect_x = rightbar_x + space; + var iconRect_radius = 2, + iconRect_width = 32, + iconRect_height = 32, + iconRect_style = "#fff", + iconRect_lineWidth = 2; + ///// *** + + var iconRect_bottom = iconRect_y + iconRect_height, + iconRect_right = iconRect_x + iconRect_width; + + ///// *** 侧边栏各项信息 + var itemTextFontSize = 15, + itemText_x = iconRect_x - 4, + itemText_y = Math.floor(start_y + rightbar_height * 0.25), // 坐标取整防止模糊 + itemClsFontSize = 15, + itemClsFont = core.ui._buildFont(itemClsFontSize), + itemClsColor = "#fff", + itemCls_x = itemText_x - itemClsFontSize / 2, + itemCls_middle = (iconRect_bottom + itemText_y) / 2, //_middle代表文字的中心y坐标 + itemNameFontSize = 18, + itemNameColor = "#fff", + itemNameFont = core.ui._buildFont(itemNameFontSize, true); + var itemName_x = iconRect_right + space; + var itemName_middle = + iconRect_y + iconRect_height / 2 + iconRect_lineWidth; + // 修改这里可以编辑未选中道具时的默认值 + var defaultItem = { + cls: "constants", + name: "未知道具", + text: "没有道具最永久", + }; + var defaultEquip = { + cls: "equips", + name: "未知装备", + text: "一无所有,又何尝不是一种装备", + equip: { + type: "装备", + }, + }; + ///// *** + + var originItem = item; + if (core.status.event.id == "equipbox") item = item || defaultEquip; + item = item || defaultItem; + var itemCls = item.cls, + itemName = item.name, + itemText = item.text; + itemText = core.replaceText(itemText); + if (!itemText) itemText = "该道具无描述。"; + /* 一个根据道具id修改道具名字(右栏)的例子 + * if (item.id == "xxx") itemNameColor = "red"; + */ + var itemClsName = core.getItemClsName(item); + var itemNameMaxWidth = + rightbar_width - iconRect_width - iconRect_lineWidth * 2 - space * 2; + core.strokeRoundRect( + ctx, + iconRect_x, + iconRect_y, + iconRect_width, + iconRect_height, + iconRect_radius, + iconRect_style, + iconRect_lineWidth + ); + if (item.id) + core.drawIcon( + ctx, + item.id, + iconRect_x + iconRect_lineWidth / 2, + iconRect_y + iconRect_lineWidth / 2, + iconRect_width - iconRect_lineWidth, + iconRect_height - iconRect_lineWidth + ); + core.setTextAlign(ctx, "left"); + core.setTextBaseline(ctx, "middle"); + if (itemCls === "equips" && item.id) { + itemName = "【" + item.equipCls + "】" + itemName; + } + core.fillText( + ctx, + itemName, + itemName_x, + itemName_middle, + itemNameColor, + itemNameFont, + itemNameMaxWidth + ); + if (!item.equip) + core.fillText( + ctx, + "【" + itemClsName + "】", + itemCls_x, + itemCls_middle, + itemClsColor, + itemClsFont + ); + + var statusText = ""; + if (core.status.event.id == "equipbox") { + var type = item.equip.type; + if (typeof type == "string") type = core.getEquipTypeByName(type); + var compare = core.compareEquipment(item.id, core.getEquip(type)); + var compare2; + if (item.equipCls === "双手剑") + compare2 = core.compareEquipment(null, core.getEquip(1)); + if ( + item.equipCls === "盾牌" && + core.material.items[core.getEquip(0)]?.equipCls === "双手剑" + ) + compare2 = core.compareEquipment(null, core.getEquip(0)); + if (info.select.action == "unload") + compare = core.compareEquipment(null, item.id); + // --- 变化值... + for (var name in core.status.hero) { + if (typeof core.status.hero[name] != "number") continue; + var nowValue = core.getRealStatus(name); + // 查询新值 + var newValue = Math.floor( + ((core.getStatus(name) + + (compare.value[name] || 0) + + (compare2?.value[name] || 0)) * + (core.getBuff(name) * 100 + + (compare.percentage[name] || 0) + + (compare2?.percentage[name] || 0))) / + 100 + ); + if (name === "mdef") { + var nowValue = core.getRealStatus(name); + var newValue = Math.round( + (core.getStatus(name) - + (compare.value[name] || 0) - + (compare2?.value[name] || 0)) * + (1 - + (1 - core.getBuff(name)) * + (compare.percentage[name] || 1) * + (compare2?.percentage[name] || 1)) + ); + } + if (nowValue == newValue) continue; + var color = newValue > nowValue ? "#00FF00" : "#FF0000"; + nowValue = core.formatBigNumber(nowValue); + newValue = core.formatBigNumber(newValue); + + if (name === "mdef") { + nowValue += "%"; + newValue += "%"; + } + statusText += + core.getStatusLabel(name) + + " " + + nowValue + + "->\r[" + + color + + "]" + + newValue + + "\r\n"; + } + } + itemText = statusText + itemText; + if (item.equip) { + core.drawTextContent(ctx, itemText, { + left: itemText_x, + top: itemCls_middle, + bold: false, + color: "white", + align: "left", + fontSize: itemTextFontSize, + maxWidth: rightbar_width - + (itemText_x - rightbar_x) * 2 + + itemTextFontSize / 2, + }); + } else { + core.drawTextContent(ctx, itemText, { + left: itemText_x, + top: itemText_y, + bold: false, + color: "white", + align: "left", + fontSize: itemTextFontSize, + maxWidth: rightbar_width - + (itemText_x - rightbar_x) * 2 + + itemTextFontSize / 2, + }); + } + + ///// *** 退出按钮设置 + var btnRadius = 10; + var btnBorderWidth = 2; + var btnRight = toolboxRight - 2; + var btnBottom = toolboxBottom - 2; + var btnBorderStyle = "#fff"; + ///// *** + + // 获取圆心位置 + var btn_x = btnRight - btnRadius - btnBorderWidth / 2; + btn_y = btnBottom - btnRadius - btnBorderWidth / 2; + drawToolbox_setExitBtn( + ctx, + btn_x, + btn_y, + btnRadius, + btnBorderStyle, + btnBorderWidth + ); + + ///// *** 使用按钮设置 + var useBtnHeight = btnRadius * 2; + // 这里不设置useBtnWidth而是根据各项数据自动得出width + var useBtnRadius = useBtnHeight / 4; + var useBtn_x = rightbar_x + 4, + useBtn_y = btnBottom - useBtnHeight; + var useBtnBorderStyle = "#fff"; + var useBtnBorderWidth = btnBorderWidth; + const batchUseBtn_x = useBtn_x + 50; // 个人觉得,搞这么多参数还不如硬编码 + const hideBtn_y = useBtn_y - useBtnHeight - 8; + ///// *** + + drawToolbox_setUseBtn( + ctx, + useBtn_x, + useBtn_y, + useBtnRadius, + useBtnHeight, + useBtnBorderStyle, + useBtnBorderWidth + ); + if (core.status.event.id === "toolbox") { + drawToolbox_setBatchUseBtn( + ctx, + batchUseBtn_x, + useBtn_y, + useBtnRadius, + useBtnHeight, + useBtnBorderStyle, + useBtnBorderWidth + ); + } + drawToolbox_setHideBtn( + ctx, + useBtn_x, + hideBtn_y, + useBtnRadius, + useBtnHeight, + useBtnBorderStyle, + useBtnBorderWidth + ); + drawToolbox_setShowHideBtn( + ctx, + rightbar_x, + useBtn_y, + useBtnHeight, + useBtnBorderStyle + ); + } + + function drawEquipbox_drawOthers(ctx, obj) { + var info = core.status.thisUIEventInfo; + + ///// *** 装备格设置 + var equipList_lineWidth = 2; + var equipList_boxSize = 32; + var equipList_borderWidth = 2; + var equipList_borderStyle = "#fff"; + var equipList_nameColor = "#fff"; + ///// *** + + var equipList_x = obj.x + 4, + equipList_bottom = obj.obj.y - equipList_lineWidth, + equipList_y = equipList_bottom - obj.obj.oneItemHeight * reduceItem - 2, + equipList_height = equipList_bottom - equipList_y; + var equipList_right = obj.leftbar_right, + equipList_width = equipList_right - equipList_x; + core.drawLine( + ctx, + obj.x, + equipList_bottom + equipList_lineWidth / 2, + equipList_right, + equipList_bottom + equipList_lineWidth / 2, + equipList_borderStyle, + equipList_lineWidth + ); + var toDrawList = core.status.globalAttribute.equipName, + len = toDrawList.length; + + ///// *** 装备格设置 + var maxItem = 2; + var box_width = 32, + box_height = 32, + box_borderStyle = "#fff", + box_selectBorderStyle = "gold", // 选中的装备格的颜色 + box_borderWidth = 2; + var boxName_fontSize = 14, + boxName_space = 2, + boxName_color = "#fff"; // 装备格名称与上面的装备格框的距离 + var maxLine = Math.ceil(len / maxItem); + ///// *** + var l = Math.sqrt(len); + if (Math.pow(l) == len && len != 4) { + if (l <= maxItem) maxItem = l; + } + maxItem = Math.min(toDrawList.length, maxItem); + info.equips = maxItem; + + var boxName_font = core.ui._buildFont(boxName_fontSize); + // 总宽高减去所有装备格宽高得到空隙大小 + var oneBoxWidth = box_width + box_borderWidth * 2; + var oneBoxHeight = + box_height + boxName_fontSize + boxName_space + 2 * box_borderWidth; + var space_y = (equipList_height - maxLine * oneBoxHeight) / (1 + maxLine), + space_x = (equipList_width - maxItem * oneBoxWidth) / (1 + maxItem); + var box_x = equipList_x + space_x, + box_y = equipList_y + space_y + 12; + for (var i = 0; i < 2; i++) { + var id = core.getEquip(i), + name = toDrawList[i]; + if (i === 0) name = "主手"; + if (i === 1) name = "副手"; + var selectBorder = false; + if (core.status.thisUIEventInfo.select.type == i) selectBorder = true; + var borderStyle = selectBorder ? + box_selectBorderStyle : + box_borderStyle; + drawEquipbox_drawOne( + ctx, + name, + id, + box_x, + box_y, + box_width, + box_height, + boxName_space, + boxName_font, + boxName_color, + borderStyle, + box_borderWidth + ); + var todo = new Function( + "core.clickOneEquipbox('" + id + "'," + i + ")" + ); + addUIEventListener( + box_x - box_borderWidth / 2, + box_y - box_borderWidth / 2, + oneBoxWidth, + oneBoxHeight, + todo + ); + box_x += space_x + oneBoxWidth; + if ((i + 1) % maxItem == 0) { + box_x = equipList_x + space_x; + box_y += space_y + oneBoxHeight; + } + } + if (core.material.items[core.getEquip(0)]?.equipCls === "双手剑") { + core.drawLine( + ctx, + equipList_x + space_x + space_x + oneBoxWidth, + equipList_y + space_y + 12, + equipList_x + + space_x + + space_x + + oneBoxWidth + + box_width + + box_borderWidth, + equipList_y + space_y + box_height + 12 + ); + core.drawLine( + ctx, + equipList_x + space_x + space_x + oneBoxWidth, + equipList_y + space_y + box_height + 12, + equipList_x + + space_x + + space_x + + oneBoxWidth + + box_width + + box_borderWidth, + equipList_y + space_y + 12 + ); + } + ///// *** 装备格设置 + var maxItem = 3; + var box_width = 32, + box_height = 32, + box_borderStyle = "#fff", + box_selectBorderStyle = "gold", // 选中的装备格的颜色 + box_borderWidth = 2; + var boxName_fontSize = 14, + boxName_space = 2, + boxName_color = "#fff"; // 装备格名称与上面的装备格框的距离 + var maxLine = Math.ceil(len / maxItem); + ///// *** + var l = Math.sqrt(len); + if (Math.pow(l) == len && len != 4) { + if (l <= maxItem) maxItem = l; + } + maxItem = Math.min(toDrawList.length, maxItem); + info.equips = maxItem; + + var boxName_font = core.ui._buildFont(boxName_fontSize); + // 总宽高减去所有装备格宽高得到空隙大小 + var oneBoxWidth = box_width + box_borderWidth * 2; + var oneBoxHeight = + box_height + boxName_fontSize + boxName_space + 2 * box_borderWidth; + var space_y = (equipList_height - maxLine * oneBoxHeight) / (1 + maxLine), + space_x = (equipList_width - maxItem * oneBoxWidth) / (1 + maxItem); + var box_x = equipList_x + space_x, + box_y = equipList_y + space_y + space_y + oneBoxHeight; + for (var i = 2; i < len; i++) { + var id = core.getEquip(i), + name = toDrawList[i]; + var selectBorder = false; + if (core.status.thisUIEventInfo.select.type == i) selectBorder = true; + var borderStyle = selectBorder ? + box_selectBorderStyle : + box_borderStyle; + drawEquipbox_drawOne( + ctx, + name, + id, + box_x, + box_y, + box_width, + box_height, + boxName_space, + boxName_font, + boxName_color, + borderStyle, + box_borderWidth + ); + var todo = new Function( + "core.clickOneEquipbox('" + id + "'," + i + ")" + ); + addUIEventListener( + box_x - box_borderWidth / 2, + box_y - box_borderWidth / 2, + oneBoxWidth, + oneBoxHeight, + todo + ); + box_x += space_x + oneBoxWidth; + } + } + + this.drawToolbox = function (ctx) { + ctx = ctx || core.canvas.ui; + core.status.thisEventClickArea = []; + + var info = drawBoxBackground(ctx); + info.itemNum = itemNum; + drawItemListbox(ctx, info.obj); + drawToolboxRightbar(ctx, info); + core.setTextBaseline(ctx, "alphabetic"); + core.setTextAlign("left"); + }; + + var reduceItem = 4; + this.drawEquipbox = function (ctx) { + ctx = ctx || core.canvas.ui; + core.status.thisEventClickArea = []; + var info = drawBoxBackground(ctx); + info.itemNum = itemNum - reduceItem; + info.obj.y += info.obj.oneItemHeight * reduceItem; + info.obj.height -= info.obj.oneItemHeight * reduceItem; + drawItemListbox(ctx, info.obj); + drawEquipbox_drawOthers(ctx, info); + drawToolboxRightbar(ctx, info); + core.setTextBaseline(ctx, "alphabetic"); + core.setTextAlign("left"); + }; + + function drawEquipbox_drawOne( + ctx, + name, + id, + x, + y, + width, + height, + space, + font, + color, + style, + lineWidth + ) { + if (id) + core.drawIcon( + ctx, + id, + x + lineWidth / 2, + y + lineWidth / 2, + width, + height + ); + core.strokeRect( + ctx, + x, + y, + width + lineWidth, + height + lineWidth, + style, + lineWidth + ); + core.setTextAlign(ctx, "center"); + core.setTextBaseline(ctx, "top"); + var tx = (x + x + lineWidth / 2 + width) / 2, + ty = y + height + (lineWidth / 2) * 3 + space; + core.fillText(ctx, name, tx, ty, color, font); + + core.setAlpha(ctx, 1); + + core.setTextBaseline(ctx, "alphabetic"); + core.setTextAlign("left"); + } + + function drawItemListbox_drawItem( + ctx, + left, + right, + top, + height, + marginLeft, + marginHeight, + style, + id + ) { + var info = core.status.thisUIEventInfo; + var nowClick = info.index; + var item = core.material.items[id] || {}; + var name = item.name || "???"; + var num = core.itemCount(id) || 0; + var fontSize = Math.floor(height - marginHeight * 2); + core.setTextAlign(ctx, "right"); + var numText = "x" + num; + core.fillText( + ctx, + numText, + right - marginLeft, + top + height / 2, + style, + core.ui._buildFont(fontSize) + ); + + const hideInfo = core.getFlag("hideInfo", {}); + if ( + item && + (hideInfo.hasOwnProperty(id) ? hideInfo[id] : item.hideInToolbox) + ) + core.setAlpha(ctx, 0.5); + + if (name != "???") + core.drawIcon( + ctx, + id, + left + marginLeft, + top + marginHeight, + fontSize, + fontSize + ); + var text_x = left + marginLeft + fontSize + 2; + var maxWidth = right - core.calWidth(ctx, numText) - text_x; + core.setTextAlign(ctx, "left"); + core.fillText( + ctx, + name, + text_x, + top + height / 2, + style, + core.ui._buildFont(fontSize), + maxWidth + ); + core.setAlpha(ctx, 1); + + var todo = new Function("core.clickItemFunc('" + id + "');"); + addUIEventListener(left, top, right - left, height, todo); + } + + function setPageItems(page) { + var num = itemNum; + if (core.status.event.id == "equipbox") num -= reduceItem; + var info = core.status.thisUIEventInfo; + if (!info) return; + page = page || info.page; + var items = core.getToolboxItems( + core.status.event.id == "toolbox" ? "all" : "equips", + core.getFlag("showHideItem", false) + ); + info.allItems = items; + var maxPage = Math.ceil(items.length / num); + info.maxPage = maxPage; + var pageItems = items.slice((page - 1) * num, page * num); + info.pageItems = pageItems; + info.maxItem = pageItems.length; + if (items.length == 0 && pageItems.length == 0) info.index = null; + if (pageItems.length == 0 && info.page > 1) { + info.page = Math.max(1, info.page - 1); + return setPageItems(info.page); + } + return pageItems; + } + + function drawToolbox_setExitBtn(ctx, x, y, r, style, lineWidth) { + core.strokeCircle(ctx, x, y, r, style, lineWidth); + ctx.textAlign = "center"; + ctx.textBaseline = "middle"; + var textSize = Math.sqrt(2) * r; + core.fillText( + ctx, + "x", + x, + y, + style, + core.ui._buildFont(textSize), + textSize + ); + core.setTextAlign(ctx, "start"); + core.setTextBaseline(ctx, "top"); + + var todo = function () { + core.closePanel(); + }; + addUIEventListener(x - r, y - r, r * 2, r * 2, todo); + } + + function drawToolbox_setUseBtn(ctx, x, y, r, h, style, lineWidth) { + core.setTextAlign(ctx, "left"); + core.setTextBaseline(ctx, "top"); + var fontSize = h - 4; + var font = core.ui._buildFont(fontSize); + var text = core.status.event.id == "toolbox" ? "使用" : "装备"; + if (core.status.thisUIEventInfo.select.action == "unload") text = "卸下"; + var w = core.calWidth(ctx, text, font) + 2 * r + lineWidth / 2; + + core.strokeRoundRect(ctx, x, y, w, h, r, style, lineWidth); + core.fillText(ctx, text, x + r, y + lineWidth / 2 + 2, style, font); + + var todo = function () { + core.useSelectItemInBox(); + }; + addUIEventListener(x, y, w, h, todo); + } + + function getSelectedItem() { + var info = core.status.thisUIEventInfo; + if ( + !( + info && + info.select.id && ["toolbox", "equipbox"].includes(core.status.event.id) + ) + ) { + core.drawFailTip("发生了未知错误!"); + return; + } + return info.select.id; + } + + function batchUse(item, count) { + try { + const itemCount = core.itemCount(item); + if (count > itemCount) count = itemCount; + core.closePanel(); + for (let i = 0; i < count; i++) { + if (core.canUseItem(item)) core.useItem(item); + else return; + } + } catch (e) { + console.error(e); + core.drawFailTip("批量使用时出现未知错误!"); + } + } + + function drawToolbox_setBatchUseBtn(ctx, x, y, r, h, style, lineWidth) { + try { + const selectedItem = getSelectedItem(); + let canBatchUse = eval(core.material.items[selectedItem]?.canBatchUse); + if (!canBatchUse) return; + } catch (error) { + console.error(error); + return; + } + core.setTextAlign(ctx, "left"); + core.setTextBaseline(ctx, "top"); + var fontSize = h - 4; + var font = core.ui._buildFont(fontSize); + var text = "批量使用"; + var w = core.calWidth(ctx, text, font) + 2 * r + lineWidth / 2; + + core.strokeRoundRect(ctx, x, y, w, h, r, style, lineWidth); + core.fillText(ctx, text, x + r, y + lineWidth / 2 + 2, style, font); + + var todo = function () { + core.utils.myprompt("输入要使用该物品的次数(0~99)。", null, (value) => { + value = parseInt(value); + const id = getSelectedItem(); + + if (Number.isNaN(value) || value < 0 || value > 99) { + core.drawFailTip("输入不合法!"); + return; + } + if (!core.canUseItem(id)) { + core.drawFailTip("当前无法使用该道具!"); + return; + } + core.closePanel(); + batchUse(id, value); + }); + }; + addUIEventListener(x, y, w, h, todo); + } + + function drawToolbox_setHideBtn(ctx, x, y, r, h, style, lineWidth) { + core.setTextAlign(ctx, "left"); + core.setTextBaseline(ctx, "top"); + var fontSize = h - 4; + var font = core.ui._buildFont(fontSize); + var text = "显示/隐藏"; + var w = core.calWidth(ctx, text, font) + 2 * r + lineWidth / 2; + + core.strokeRoundRect(ctx, x, y, w, h, r, style, lineWidth); + core.fillText(ctx, text, x + r, y + lineWidth / 2 + 2, style, font); + + var todo = function () { + //debugger; + var id = getSelectedItem(); + let hideInfo = core.getFlag("hideInfo", {}); + console.log(id); + if (hideInfo.hasOwnProperty(id)) { + hideInfo[id] = !hideInfo[id]; + core.setFlag("hideInfo", hideInfo); + } else { + hideInfo[id] = !core.material.items[id].hideInToolbox; + core.setFlag("hideInfo", hideInfo); + } + if (core.status.event.id === "toolbox") core.plugin.drawToolbox(); + else if (core.status.event.id === "equipbox") + core.plugin.drawEquipbox(); + }; + addUIEventListener(x, y, w, h, todo); + } + + ui.prototype.getToolboxItems = function (cls, showHide) { + let list = Object.keys(core.status.hero.items[cls] || {}); + if (cls === "all") { + for (let name in core.status.hero.items) { + if (name == "equips") continue; + list = list.concat(Object.keys(core.status.hero.items[name])); + } + if (!showHide) + list = list.filter(function (id2) { + const hideInfo = core.getFlag("hideInfo", {}); + if (hideInfo.hasOwnProperty(id2)) return !hideInfo[id2]; + else return !core.material.items[id2].hideInToolbox; + }); + list = list.sort(); + return list; + } + if (cls === "equips") { + if (!showHide) + list = list.filter(function (id2) { + const hideInfo = core.getFlag("hideInfo", {}); + if (hideInfo.hasOwnProperty(id2)) return !hideInfo[id2]; + else return !core.material.items[id2].hideInToolbox; + }); + + list = list.sort(); + return list; + } + if (this.uidata.getToolboxItems) { + return this.uidata.getToolboxItems(cls, showHide); + } + if (!showHide) + list = list.filter(function (id2) { + return !core.material.items[id2].hideInToolbox; + }); + list = list.sort(); + return list; + }; + + function drawToolbox_setShowHideBtn(ctx, x, y, h, style) { + core.setTextAlign(ctx, "left"); + core.setTextBaseline(ctx, "top"); + var fontSize = h - 6; + var font = core.ui._buildFont(fontSize); + var text = "显示隐藏"; + var w = core.calWidth(ctx, text, font); + h += 4; + const squareSize = h - 6; + + x -= w + squareSize + 26; + + const border = 2; + core.fillRect(ctx, x, y, squareSize, squareSize, " #F5F5F5"); + if (core.hasFlag("showHideItem")) { + core.fillRect( + ctx, + x + border, + y + border, + squareSize - 2 * border, + squareSize - 2 * border, + "lime" + ); + } + core.fillText(ctx, text, x + squareSize + 2, y + 4, style, font); + + var todo = function () { + core.setFlag("showHideItem", !core.getFlag("showHideItem", false)); + if (core.status.event.id === "toolbox") core.plugin.drawToolbox(); + else if (core.status.event.id === "equipbox") + core.plugin.drawEquipbox(); + }; + addUIEventListener(x, y, w, h, todo); + } + + function drawItemListbox_setPageBtn( + ctx, + left, + right, + bottom, + r, + style, + lineWidth + ) { + var offset = lineWidth / 2 + r; + + var x = left + offset; + var y = bottom - offset; + var pos = (Math.sqrt(2) / 2) * (r - lineWidth / 2); + core.fillPolygon( + ctx, + [ + [x - pos, y], + [x + pos - 2, y - pos], + [x + pos - 2, y + pos], + ], + style + ); + core.strokeCircle(ctx, x, y, r, style, lineWidth); + var todo = function () { + core.addItemListboxPage(-1); + }; + addUIEventListener(x - r - 2, y - r - 2, r * 2 + 4, r * 2 + 4, todo); + + x = right - offset; + core.fillPolygon( + ctx, + [ + [x + pos, y], + [x - pos + 2, y - pos], + [x - pos + 2, y + pos], + ], + style + ); + core.strokeCircle(ctx, x, y, r, style, lineWidth); + var todo = function () { + core.addItemListboxPage(1); + }; + addUIEventListener(x - r - 2, y - r - 2, r * 2 + 4, r * 2 + 4, todo); + } + + this.clickItemFunc = function (id) { + var info = core.status.thisUIEventInfo; + if (!info) return; + if (info.select.id == id) return core.useSelectItemInBox(); + info.select = {}; + info.select.id = id; + core.setIndexAndSelect("index"); + refreshBox(); + }; + + this.clickOneEquipbox = function (id, type) { + var info = core.status.thisUIEventInfo; + if (!info) return; + if (info.select.id == id && info.select.type == type) + core.useSelectItemInBox(); + else + core.status.thisUIEventInfo.select = { + id: id, + type: type, + action: "unload", + }; + return refreshBox(); + }; + + this.useSelectItemInBox = function () { + var info = core.status.thisUIEventInfo; + if (!info) return; + if (!info.select.id) return; + var id = info.select.id; + if (core.status.event.id == "toolbox") { + core.events.tryUseItem(id); + // core.closePanel(); + } else if (core.status.event.id == "equipbox") { + var action = info.select.action || "load"; + info.index = 1; + if (action == "load") { + var type = core.getEquipTypeById(id); + let equipClsid = core.material.items[id]?.equipCls; + let equipCls0 = core.material.items[core.getEquip(0)]?.equipCls; + let equipCls1 = core.material.items[core.getEquip(1)]?.equipCls; + if (equipClsid === "双手剑") { + core.unloadEquip(0, function () { + core.status.route.push("unEquip:" + 0); + }); + core.unloadEquip(1, function () { + core.status.route.push("unEquip:" + 1); + }); + } + if ( + equipCls0 === "双手剑" && + !(equipClsid === "饰品" || equipClsid === "护具") + ) { + core.unloadEquip(0, function () { + core.status.route.push("unEquip:" + 0); + }); + } + core.loadEquip(id, function () { + core.status.route.push("equip:" + id); + info.select.type = type; + core.setIndexAndSelect("select"); + core.drawEquipbox(); + }); + } else { + var type = info.select.type; + core.unloadEquip(type, function () { + core.status.route.push("unEquip:" + type); + info.select.type = type; + info.select.action = "load"; + core.setIndexAndSelect("select"); + core.drawEquipbox(); + }); + } + } + core.updateStatusBar(); + }; + + this.setIndexAndSelect = function (toChange) { + var info = core.status.thisUIEventInfo; + if (!info) return; + setPageItems(info.page); + var index = info.index || 1; + var items = info.pageItems; + + info.select.action = null; + info.select.type = null; + if (toChange == "index") info.index = items.indexOf(info.select.id) + 1; + info.select.id = items[info.index - 1]; + }; + + this.addItemListboxPage = function (num) { + var info = core.status.thisUIEventInfo; + if (!info) return; + var maxPage = info.maxPage || 1; + info.page = info.page || 1; + info.page += num; + if (info.page <= 0) info.page = maxPage; + if (info.page > maxPage) info.page = 1; + info.index = 1; + setPageItems(info.page); + core.setIndexAndSelect("select"); + refreshBox(); + }; + + this.addItemListboxIndex = function (num) { + var info = core.status.thisUIEventInfo; + if (!info) return; + var maxItem = info.maxItem || 0; + info.index = info.index || 0; + info.index += num; + if (info.index <= 0) info.index = 1; + if (info.index > maxItem) info.index = maxItem; + core.setIndexAndSelect("select"); + refreshBox(); + }; + + this.addEquipboxType = function (num) { + var info = core.status.thisUIEventInfo; + var type = info.select.type; + if (type == null && num > 0) info.select.type = 0; + else info.select.type = type + num; + var max = core.status.globalAttribute.equipName.length; + if (info.select.type >= max) { + info.select = {}; + core.setIndexAndSelect("select"); + return core.addItemListboxPage(0); + } else { + var m = Math.abs(info.select.type); + if (info.select.type < 0) info.select.type = max - m; + core.setIndexAndSelect("select"); + refreshBox(); + return; + } + }; + + core.actions._keyDownToolbox = function (keycode) { + if (!core.status.thisEventClickArea) return; + if (keycode == 37) { + // left + core.addItemListboxPage(-1); + return; + } + if (keycode == 38) { + // up + core.addItemListboxIndex(-1); + return; + } + if (keycode == 39) { + // right + core.addItemListboxPage(1); + return; + } + if (keycode == 40) { + // down + core.addItemListboxIndex(1); + return; + } + }; + + ////// 工具栏界面时,放开某个键的操作 ////// + core.actions._keyUpToolbox = function (keycode) { + if (keycode == 81) { + core.ui.closePanel(); + if (core.isReplaying()) core.control._replay_equipbox(); + else core.openEquipbox(); + return; + } + if (keycode == 84 || keycode == 27 || keycode == 88) { + core.closePanel(); + return; + } + if (keycode == 13 || keycode == 32 || keycode == 67) { + var info = core.status.thisUIEventInfo; + if (info.select) { + core.useSelectItemInBox(); + } + return; + } + }; + + core.actions._keyDownEquipbox = function (keycode) { + if (!core.status.thisEventClickArea) return; + if (keycode == 37) { + // left + var info = core.status.thisUIEventInfo; + if (info.index != null) return core.addItemListboxPage(-1); + return core.addEquipboxType(-1); + } + if (keycode == 38) { + // up + var info = core.status.thisUIEventInfo; + if (info.index == 1) { + info.select.type = core.status.globalAttribute.equipName.length - 1; + core.setIndexAndSelect(); + return refreshBox(); + } + if (info.index) return core.addItemListboxIndex(-1); + return core.addEquipboxType(-1 * info.equips); + } + if (keycode == 39) { + // right + var info = core.status.thisUIEventInfo; + if (info.index != null) return core.addItemListboxPage(1); + return core.addEquipboxType(1); + } + if (keycode == 40) { + // down + var info = core.status.thisUIEventInfo; + if (info.index) return core.addItemListboxIndex(1); + return core.addEquipboxType(info.equips); + } + }; + + core.actions._keyUpEquipbox = function (keycode, altKey) { + if (altKey && keycode >= 48 && keycode <= 57) { + core.items.quickSaveEquip(keycode - 48); + return; + } + if (keycode == 84) { + core.ui.closePanel(); + if (core.isReplaying()) core.control._replay_toolbox(); + else core.openToolbox(); + return; + } + if (keycode == 81 || keycode == 27 || keycode == 88) { + core.closePanel(); + return; + } + if (keycode == 13 || keycode == 32 || keycode == 67) { + var info = core.status.thisUIEventInfo; + if (info.select) core.useSelectItemInBox(); + return; + } + }; + + core.registerAction( + "ondown", + "inEventClickAction", + function (x, y, px, py) { + if (!core.status.thisEventClickArea) return false; + var info = core.status.thisEventClickArea; + for (var i = 0; i < info.length; i++) { + var obj = info[i]; + if ( + px >= obj.x && + px <= obj.x + obj.width && + py > obj.y && + py < obj.y + obj.height + ) { + if (obj.todo) obj.todo(); + break; + } + } + return true; + }, + 51 + ); + core.registerAction( + "onclick", + "stopClick", + function () { + if (core.status.thisEventClickArea) return true; + }, + 51 + ); + + function addUIEventListener(x, y, width, height, todo) { + if (!core.status.thisEventClickArea) return; + var obj = { + x: x, + y: y, + width: width, + height: height, + todo: todo, + }; + core.status.thisEventClickArea.push(obj); + } + + this.initThisEventInfo = function () { + core.status.thisUIEventInfo = { + page: 1, + select: {}, + }; + core.status.thisEventClickArea = []; + }; + + function refreshBox() { + if (!core.status.event.id) return; + if (core.status.event.id == "toolbox") core.drawToolbox(); + else core.drawEquipbox(); + } + + core.ui.closePanel = function () { + if (core.status.hero && core.status.hero.flags) { + // 清除全部临时变量 + Object.keys(core.status.hero.flags).forEach(function (name) { + if (name.startsWith("@temp@") || /^arg\d+$/.test(name)) { + delete core.status.hero.flags[name]; + } + }); + } + this.clearUI(); + core.maps.generateGroundPattern(); + core.updateStatusBar(true); + core.unlockControl(); + core.status.event.data = null; + core.status.event.id = null; + core.status.event.selection = null; + core.status.event.ui = null; + core.status.event.interval = null; + core.status.thisUIEventInfo = null; + core.status.thisEventClickArea = null; + }; + + this.getItemClsName = function (item) { + if (item == null) return itemClsName; + if (item.cls == "equips") { + if (typeof item.equip.type == "string") return item.equip.type; + var type = core.getEquipTypeById(item.id); + return core.status.globalAttribute.equipName[type]; + } else return itemClsName[item.cls] || item.cls; + }; + + core.events.openToolbox = function (fromUserAction) { + if (core.isReplaying()) return; + if (!this._checkStatus("toolbox", fromUserAction)) return; + core.initThisEventInfo(); + let info = core.status.thisUIEventInfo; + info.index = 1; + core.setIndexAndSelect("select"); + core.drawToolbox(); + }; + + core.events.openEquipbox = function (fromUserAction) { + if (core.isReplaying()) return; + if (!this._checkStatus("equipbox", fromUserAction)) return; + core.initThisEventInfo(); + let info = core.status.thisUIEventInfo; + info.select.type = 0; + core.setIndexAndSelect("select"); + core.drawEquipbox(); + }; + + core.control._replay_toolbox = function () { + if (!core.isPlaying() || !core.isReplaying()) return; + if (!core.status.replay.pausing) return core.drawTip("请先暂停录像"); + if (core.isMoving() || core.status.replay.animate || core.status.event.id) + return core.drawTip("请等待当前事件的处理结束"); + + core.lockControl(); + core.status.event.id = "toolbox"; + core.drawToolbox(); + }; + + core.control._replay_equipbox = function () { + if (!core.isPlaying() || !core.isReplaying()) return; + if (!core.status.replay.pausing) return core.drawTip("请先暂停录像"); + if (core.isMoving() || core.status.replay.animate || core.status.event.id) + return core.drawTip("请等待当前事件的处理结束"); + + core.lockControl(); + core.status.event.id = "equipbox"; + core.drawEquipbox(); + }; + + core.control._replayAction_item = function (action) { + if (action.indexOf("item:") != 0) return false; + var itemId = action.substring(5); + if (!core.canUseItem(itemId)) return false; + if ( + core.material.items[itemId].hideInReplay || + core.status.replay.speed == 24 + ) { + core.useItem(itemId, false, core.replay); + return true; + } + core.status.event.id = "toolbox"; + core.initThisEventInfo(); + var info = core.status.thisUIEventInfo; + var items = core.getToolboxItems( + "all", + core.getFlag("showHideItem", false) + ); + setPageItems(1); + var index = items.indexOf(itemId) + 1; + info.page = Math.ceil(index / info.maxItem); + info.index = index % info.maxItem || info.maxItem; + core.setIndexAndSelect("select"); + setPageItems(info.page); + core.drawToolbox(); + setTimeout(function () { + core.ui.closePanel(); + core.useItem(itemId, false, core.replay); + }, core.control.__replay_getTimeout()); + return true; + }; + + core.control._replayAction_equip = function (action) { + if (action.indexOf("equip:") != 0) return false; + var itemId = action.substring(6); + var items = core.getToolboxItems( + "equips", + core.getFlag("showHideItem", false) + ); + var index = items.indexOf(itemId) + 1; + if (index < 1) { + core.removeFlag("__doNotCheckAutoEvents__"); + return false; + } + + var cb = function () { + var next = core.status.replay.toReplay[0] || ""; + if (!next.startsWith("equip:") && !next.startsWith("unEquip:")) { + core.removeFlag("__doNotCheckAutoEvents__"); + core.checkAutoEvents(); + } + core.replay(); + }; + core.setFlag("__doNotCheckAutoEvents__", true); + + core.status.route.push(action); + if ( + core.material.items[itemId].hideInReplay || + core.status.replay.speed == 24 + ) { + core.loadEquip(itemId, cb); + return true; + } + core.status.event.id = "equipbox"; + core.initThisEventInfo(); + var info = core.status.thisUIEventInfo; + setPageItems(1); + info.page = Math.ceil(index / info.maxItem); + info.index = index % info.maxItem || info.maxItem; + core.setIndexAndSelect("select"); + setPageItems(info.page); + core.drawEquipbox(); + setTimeout(function () { + core.ui.closePanel(); + core.loadEquip(itemId, cb); + }, core.control.__replay_getTimeout()); + return true; + }; + + core.control._replayAction_unEquip = function (action) { + if (action.indexOf("unEquip:") != 0) return false; + var equipType = parseInt(action.substring(8)); + if (!core.isset(equipType)) { + core.removeFlag("__doNotCheckAutoEvents__"); + return false; + } + + var cb = function () { + var next = core.status.replay.toReplay[0] || ""; + if (!next.startsWith("equip:") && !next.startsWith("unEquip:")) { + core.removeFlag("__doNotCheckAutoEvents__"); + core.checkAutoEvents(); + } + core.replay(); + }; + core.setFlag("__doNotCheckAutoEvents__", true); + + core.status.route.push(action); + if (core.status.replay.speed == 24) { + core.unloadEquip(equipType, cb); + return true; + } + core.status.event.id = "equipbox"; + core.initThisEventInfo(); + var info = core.status.thisUIEventInfo; + setPageItems(1); + info.select.type = equipType; + core.setIndexAndSelect(); + core.drawEquipbox(); + setTimeout(function () { + core.ui.closePanel(); + core.unloadEquip(equipType, cb); + }, core.control.__replay_getTimeout()); + return true; + }; + core.registerReplayAction("item", core.control._replayAction_item); + core.registerReplayAction("equip", core.control._replayAction_equip); + core.registerReplayAction("unEquip", core.control._replayAction_unEquip); +}, "技能树": function () { // 在此增加新插件 // @@ -23679,5 +23667,242 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = ctx.restore(); //恢复变换前的坐标,否则将连续转置 } +}, + "scrollingText": function () { + // 本插件用于绘制在线留言 + // 说明:https://h5mota.com/bbs/thread/?tid=1017 + // 目前使用core.http代替帖子中提到的axios + ////// 绘制提示同时播放成功音效 ////// + ui.prototype.drawSuccessTip = function (text, id, frame) { + this.drawTip(text, id, frame); + core.playSound('gem.mp3'); + } + core.plugin.aniMap = new Map() + ////// 绘制提示同时播放错误音效 ////// + ui.prototype.drawFailTip = function (text, id, frame) { + this.drawTip(text, id, frame); + core.playSound('error.mp3'); + } + /** 塔的英文名 */ + const towerName = core.firstData.name; + + let [W, H] = [core.__SIZE__, core.__SIZE__]; + let [WIDTH, HEIGHT] = [core.__PIXELS__, core.__PIXELS__]; + + //#region 弹幕的收发 + this.getComment = function () { + if (core.isReplaying()) return; + let form = new FormData(); + form.append('type', 1); + form.append('towername', towerName); + utils.prototype.http( + 'POST', + 'https://h5mota.com/backend/tower/barrage.php', + form, + function (res) { + try { + res = JSON.parse(res); + console.log(res); + core.drawTip('接收成功!') + core.playSound('item.mp3'); + let commentCollection = {}; + const commentList = res?.list; + const isEmpty = /^\s*$/; + for (let i = 0, l = commentList.length; i <= l - 1; i++) { + if (isEmpty.test(commentList[i]?.comment)) continue; + const commentTagsList = commentList[i].tags.split(','); + const [cFloorId, cX, cY] = commentTagsList; + if (0 <= cX && cX <= W - 1 && 0 <= cY && cY <= H - 1 && core.floorIds.includes(cFloorId)) { + if (!commentCollection.hasOwnProperty(cFloorId)) { commentCollection[cFloorId] = {}; } + const str = cX + ',' + cY; + if (!commentCollection[cFloorId].hasOwnProperty(str)) { commentCollection[cFloorId][str] = []; } + commentCollection[cFloorId][str].push(commentList[i]?.comment); + } + } + core.setFlag('commentCollection', commentCollection); + } catch (err) { + core.drawFailTip('接收失败!' + err.message); + } + }, + function (err) { + err = JSON.parse(err); + console.error(err); + core.drawFailTip('接收失败' + err?.message); + }, + null, null, null, 1000 + ); + } + + this.postComment = function (comment, tags) { + if (core.isReplaying()) return; + const isEmpty = /^\s*$/; + if (isEmpty.test(comment)) { + core.drawFailTip('您输入的消息为空,请重发!'); + return; + } + let form = new FormData(); + form.append('type', 2); + form.append('towername', towerName); + form.append('comment', comment); + form.append('tags', tags); + form.append('userid', 2324); + form.append('password', '77c8fd5ff49c370342e4472ebdda5903'); + utils.prototype.http( + 'POST', + 'https://h5mota.com/backend/tower/barrage.php', + form, + function (res) { + try { + res = JSON.parse(res); + console.log(res); + if (res?.code === 0) { + core.drawTip('提交成功!') + } else { + core.drawTip('提交失败!' + res?.message); + } + } catch (err) { + core.drawFailTip('提交失败!' + err.message); + } + }, + function (err) { + err = JSON.parse(err); + console.error(err); + core.drawFailTip('提交失败!' + err?.message); + }, + null, null, null, 1000 + ); + } + //#endregion + + /** 若变量comment为真,在每层切换时在地上有弹幕的地方显示相应图标。 */ + this.drawCommentSign = function () { + if (!core.hasFlag('comment') || core.isReplaying()) return; + let commentCollection = core.getFlag('commentCollection', {}), + floorId = core.status.floorId; + core.createCanvas('sign', 0, 0, WIDTH, HEIGHT, 61); + core.setOpacity('sign', 0.6); + if (commentCollection.hasOwnProperty(floorId)) { + for (let pos in commentCollection[floorId]) { + const l = commentCollection[floorId][pos].length; + for (let i = 0; i <= l - 1; i++) { + const [x, y] = pos.split(','); + core.drawIcon('sign', 'postman', 32 * x, 32 * y); + break; + } + } + } + } + + /** 立即清除楼层的弹幕图标。关闭弹幕相关设置时调用。 */ + this.clearCommentSign = function () { + core.deleteCanvas('sign'); + } + + /** 默认一次显示的弹幕数 */ + const showNum = 5; + + // 每走一步或瞬移,调用该函数,若目标点有弹幕,显示之 + this.showComment = function (x, y) { + if (!core.getFlag('comment') || core.isReplaying()) return; + const commentCollection = core.getFlag('commentCollection', {}); + const floorId = core.status.floorId, + str = x + ',' + y; + if (commentCollection.hasOwnProperty(floorId) && + commentCollection[floorId].hasOwnProperty(str)) { + let commentArr = commentCollection[floorId][str].concat(); + const commentArrPicked = pickComment(commentArr, showNum); + drawComment(commentArrPicked); + } + } + + /** 返回从commentArr中挑选showNum个comment组成的数组*/ + function pickComment(commentArr, showNum) { + let showList = []; + if (commentArr.length <= showNum) { + showList = commentArr; + } else { + for (let i = 0; i <= showNum - 1; i++) { + const l = commentArr.length, + n = core.plugin.dice(l - 1); + showList.push(commentArr[n]); + commentArr.splice(n, 1); + } + } + return showList; + } + + function drawComment(commentArr) { + const l = commentArr.length; + let yList = generateCommentYList(20, HEIGHT - 20, showNum); + if (l < showNum) yList = getRandomElements(yList, l); + for (let i = 0; i <= l - 1; i++) { + drawCommentStr(commentArr[i], WIDTH + 20 * Math.random(), + yList[i], Math.random() * 0.1 + 0.1); + } + } + + /** 生成count个随机数,范围从min到max,作为弹幕的y坐标*/ + function generateCommentYList(min, max, count) { + let yList = Array(count).fill(0); + const distance = (max - min) / (count + 1); + for (let i = 0; i < count; i++) { + yList[i] = min + distance * (i + 1) + (Math.random() - 0.5) * (distance / 2); + } + return yList; + } + + function getRandomElements(arr, count) { + let result = [...arr]; + let len = result.length; + count = Math.min(len, count); + + for (let i = len - 1; i > len - 1 - count; i--) { + let j = Math.floor(Math.random() * (i + 1)); + [result[i], result[j]] = [result[j], result[i]]; + } + + return result.slice(len - count); + } + + //#region 弹幕绘制部分 + const { Animation, linear, Ticker } = core.plugin.animate ?? {}; + const ctxName = 'scrollingText'; + + if (Ticker) { + const ticker = new Ticker(); + ticker.add(() => { + if (core.isReplaying()) return; + core.createCanvas(ctxName, 0, 0, core.__PIXELS__, core.__PIXELS__, 136); //每帧重绘该画布 + }); + } + + /** + * 绘制弹幕 + * @example + * drawCommentStr('OK', 450, 200, 0.1); + * @param {string} content 弹幕的内容 + * @param {number} x 弹幕的初始x坐标 + * @param {number} y 弹幕的初始y坐标 + * @param {number} vx 弹幕的横向滚动速度 + */ + function drawCommentStr(content, x, y, vx) { + if (core.isReplaying() || !Animation) return; + const ani = new Animation(); + core.plugin.aniMap.set(ani, (ani) => ani.ticker.destroy()); + ani.ticker.add(() => { + core.fillText(ctxName, content, x + ani.x, y, 'white', '16px Verdana'); + }) + // 弹幕的最大长度5600,再长属于异常数据 + const aim = 600 + Math.min(core.calWidth(ctxName, content, '16px Verdana'), 5000); + ani.mode(linear()) + .time(aim / vx) + .absolute() + .move(-aim, 0) + ani.all().then(() => { + ani.ticker.destroy(); + }); + } + //#endregion + } } \ No newline at end of file