From 6ef75b99c2e1fda7c772316d54542c57cb0e2100 Mon Sep 17 00:00:00 2001 From: unanmed <1319491857@qq.com> Date: Tue, 14 Oct 2025 14:00:25 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=95=86=E5=BA=97=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages-user/legacy-plugin-data/src/shop.ts | 145 ++++++++++++++++++- packages/legacy-ui/src/ui/shop.vue | 1 - public/libs/events.js | 7 +- public/libs/ui.js | 2 +- public/project/data.js | 128 +++++++++++++--- public/project/floors/sample1.js | 20 +++ 6 files changed, 273 insertions(+), 30 deletions(-) diff --git a/packages-user/legacy-plugin-data/src/shop.ts b/packages-user/legacy-plugin-data/src/shop.ts index f82e00a..ab36b56 100644 --- a/packages-user/legacy-plugin-data/src/shop.ts +++ b/packages-user/legacy-plugin-data/src/shop.ts @@ -1,12 +1,26 @@ +// @ts-nocheck + +type Shop = CommonShopEvent | CommonEventShopEvent | ItemShopEvent; + export function openShop(shopId: string, noRoute: boolean) { - const shop = core.status.shops[shopId] as ItemShopEvent; + const shop = core.status.shops[shopId] as Shop; // Step 1: 检查能否打开此商店 if (!canOpenShop(shopId)) { core.drawTip('该商店尚未开启'); return false; } - // Step 3: 检查道具商店 or 公共事件 + if (!noRoute) { + core.status.route.push(`openShop:${shopId}`); + } + + // Step2: 检查公共事件商店 + if (shop.commonEvent) { + core.insertCommonEvent(shop.commonEvent, shop.args); + return; + } + + // Step 3: 检查道具商店 if (shop.item) { Mota.r(() => { if (!core.isReplaying()) { @@ -17,13 +31,16 @@ export function openShop(shopId: string, noRoute: boolean) { }); return; } + + // Step4 普通商店 + core.insertAction(convertShop(shop)); return true; } /// 是否访问过某个快捷商店 export function isShopVisited(id: string) { flags.__shops__ ??= {}; - var shops = core.getFlag('__shops__'); + const shops = core.getFlag('__shops__'); if (!shops[id]) shops[id] = {}; return shops[id].visited; } @@ -31,7 +48,7 @@ export function isShopVisited(id: string) { /// 当前应当显示的快捷商店列表 export function listShopIds() { return Object.keys(core.status.shops).filter(id => { - // @ts-ignore + // @ts-expect-error 无法推导 return isShopVisited(id) || !core.status.shops[id].mustEnable; }); } @@ -39,8 +56,8 @@ export function listShopIds() { /// 是否能够打开某个商店 export function canOpenShop(id: string) { if (isShopVisited(id)) return true; - var shop = core.status.shops[id]; - // @ts-ignore + const shop = core.status.shops[id]; + // @ts-expect-error 无法推导 if (shop.item || shop.commonEvent || shop.mustEnable) return false; return true; } @@ -48,7 +65,7 @@ export function canOpenShop(id: string) { /// 启用或禁用某个快捷商店 export function setShopVisited(id: string, visited: boolean) { if (!core.hasFlag('__shops__')) core.setFlag('__shops__', {}); - var shops = core.getFlag('__shops__'); + const shops = core.getFlag('__shops__'); if (!shops[id]) shops[id] = {}; if (visited) shops[id].visited = true; else delete shops[id].visited; @@ -64,3 +81,117 @@ export function canUseQuickShop() { return '当前楼层不能使用快捷商店。'; return null; } + +////// 将一个全局商店转变成可预览的公共事件 ////// +function convertShop(shop): MotaEvent { + return [ + { + type: 'function', + function: "function() {core.addFlag('@temp@shop', 1);}" + }, + { + type: 'while', + condition: 'true', + data: [ + // 检测能否访问该商店 + { + type: 'if', + condition: + "Mota.require('@user/legacy-plugin-data').isShopVisited('" + + shop.id + + "')", + true: [ + // 可以访问,直接插入执行效果 + { + type: 'function', + function: + "function() { Mota.require('@user/legacy-plugin-data').convertShop_replaceChoices('" + + shop.id + + "', false) }" + } + ], + false: [ + // 不能访问的情况下:检测能否预览 + { + type: 'if', + condition: shop.disablePreview, + true: [ + // 不可预览,提示并退出 + { type: 'playSound', name: '操作失败' }, + '当前无法访问该商店!', + { type: 'break' } + ], + false: [ + // 可以预览:将商店全部内容进行替换 + { + type: 'tip', + text: '当前处于预览模式,不可购买' + }, + { + type: 'function', + function: + "function() { Mota.require('@user/legacy-plugin-data').convertShop_replaceChoices('" + + shop.id + + "', true) }" + } + ] + } + ] + } + ] + }, + { + type: 'function', + function: "function() {core.addFlag('@temp@shop', -1);}" + } + ]; +} + +export function convertShop_replaceChoices(shopId, previewMode) { + const shop = core.status.shops[shopId]; + const choices = (shop.choices || []) + .filter(function (choice) { + if (choice.condition == null || choice.condition == '') return true; + try { + return core.calValue(choice.condition); + } catch (e) { + return true; + } + }) + .map(function (choice) { + const ableToBuy = core.calValue(choice.need); + return { + text: choice.text, + icon: choice.icon, + color: + ableToBuy && !previewMode + ? choice.color + : [153, 153, 153, 1], + action: + ableToBuy && !previewMode + ? [{ type: 'playSound', name: '商店' }].concat( + choice.action + ) + : [ + { type: 'playSound', name: '操作失败' }, + { + type: 'tip', + text: previewMode + ? '预览模式下不可购买' + : '购买条件不足' + } + ] + }; + }) + .concat({ + text: '离开', + action: [{ type: 'playSound', name: '取消' }, { type: 'break' }] + }); + + let text = shop.text.trim(); + if (text.startsWith('[')) { + const end = text.indexOf(']'); + text = text.slice(end + 1); + } + core.insertAction({ type: 'choices', text: text, choices: choices }); +} diff --git a/packages/legacy-ui/src/ui/shop.vue b/packages/legacy-ui/src/ui/shop.vue index 72c802b..92cec1b 100644 --- a/packages/legacy-ui/src/ui/shop.vue +++ b/packages/legacy-ui/src/ui/shop.vue @@ -317,7 +317,6 @@ function exit() { onMounted(async () => { core.lockControl(); - core.status.route.push(`openShop:${id}`); }); onUnmounted(() => { diff --git a/public/libs/events.js b/public/libs/events.js index a23a6f5..b5b57e7 100644 --- a/public/libs/events.js +++ b/public/libs/events.js @@ -2276,13 +2276,14 @@ events.prototype._action_unloadEquip = function (data, x, y, prefix) { }; events.prototype._action_openShop = function (data, x, y, prefix) { - Mota.require('@user/data-state').setShopVisited(data.id, true); - if (data.open) Mota.require('@user/data-state').openShop(data.id, true); + Mota.require('@user/legacy-plugin-data').setShopVisited(data.id, true); + if (data.open) + Mota.require('@user/legacy-plugin-data').openShop(data.id, true); core.doAction(); }; events.prototype._action_disableShop = function (data, x, y, prefix) { - Mota.require('@user/data-state').setShopVisited(data.id, false); + Mota.require('@user/legacy-plugin-data').setShopVisited(data.id, false); core.doAction(); }; diff --git a/public/libs/ui.js b/public/libs/ui.js index 91045fa..bce2c85 100644 --- a/public/libs/ui.js +++ b/public/libs/ui.js @@ -2254,7 +2254,7 @@ ui.prototype.drawChoices = async function (content, choices, width) { choice, [HALF_WIDTH, HALF_HEIGHT, void 0, void 0, 0.5, 0.5], width ?? POP_BOX_WIDTH, - { title: content ?? '' } + { text: content ?? '' } ); core.insertAction(choices[selected].action); core.doAction(); diff --git a/public/project/data.js b/public/project/data.js index 9e31025..fab6a73 100644 --- a/public/project/data.js +++ b/public/project/data.js @@ -215,31 +215,123 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = ], "shops": [ { - "id": "snowShop", + "id": "shop1", + "text": "\t[贪婪之神,moneyShop]勇敢的武士啊, 给我${20+2*flag:shop1}金币就可以:", + "textInList": "1F金币商店", + "mustEnable": false, + "disablePreview": false, + "choices": [ + { + "text": "生命+800", + "need": "status:money>=20+2*flag:shop1", + "action": [ + { + "type": "comment", + "text": "新版商店中需要手动扣减金币和增加访问次数" + }, + { + "type": "setValue", + "name": "status:money", + "operator": "-=", + "value": "20+2*flag:shop1" + }, + { + "type": "setValue", + "name": "flag:shop1", + "operator": "+=", + "value": "1" + }, + { + "type": "setValue", + "name": "status:hp", + "operator": "+=", + "value": "800" + } + ] + }, + { + "text": "攻击+4", + "need": "status:money>=20+2*flag:shop1", + "action": [ + { + "type": "comment", + "text": "新版商店中需要手动扣减金币和增加访问次数" + }, + { + "type": "setValue", + "name": "status:money", + "operator": "-=", + "value": "20+2*flag:shop1" + }, + { + "type": "setValue", + "name": "flag:shop1", + "operator": "+=", + "value": "1" + }, + { + "type": "setValue", + "name": "status:atk", + "operator": "+=", + "value": "4" + } + ] + } + ] + }, + { + "id": "shop2", + "text": "\t[贪婪之神,expShop]勇敢的武士啊, 给我一定经验就可以:", + "textInList": "1F经验商店", + "mustEnable": false, + "disablePreview": true, + "choices": [ + { + "text": "等级+1(100经验)", + "need": "status:exp>=100", + "action": [ + { + "type": "setValue", + "name": "status:exp", + "operator": "-=", + "value": "100" + }, + { + "type": "setValue", + "name": "status:lv", + "operator": "+=", + "value": "1" + }, + { + "type": "setValue", + "name": "status:hp", + "operator": "+=", + "value": "1000" + } + ] + } + ] + }, + { + "id": "itemShop", "item": true, "textInList": "道具商店", "use": "money", - "mustEnable": true, + "mustEnable": false, "choices": [ { - "id": "sword2", - "number": 1, - "money": "600", - "sell": "300" - }, - { - "id": "shield2", - "number": 1, - "money": "500", - "sell": "250" - }, - { - "id": "I641", - "number": 1, - "money": "400", - "sell": "200" + "id": "yellowKey", + "number": 10, + "money": "10", + "sell": "5" } ] + }, + { + "id": "keyShop", + "textInList": "回收钥匙商店", + "mustEnable": false, + "commonEvent": "回收钥匙商店" } ], "levelUp": [ diff --git a/public/project/floors/sample1.js b/public/project/floors/sample1.js index af2341a..d1142f2 100644 --- a/public/project/floors/sample1.js +++ b/public/project/floors/sample1.js @@ -865,6 +865,26 @@ main.floors.sample1= "icon": "man", "text": "试着给我添加一个隐藏事件让我消失吧!" } + ], + "5,9": [ + { + "type": "choices", + "text": "选择剑或者盾 11111111111111111111 111111111111111", + "choices": [ + { + "text": "剑", + "action": [ + { + "type": "openDoor", + "loc": [ + 3, + 3 + ] + } + ] + } + ] + } ] }, "changeFloor": {