fix: 商店问题

This commit is contained in:
unanmed 2025-10-14 14:00:25 +08:00
parent 7c9847aa40
commit 6ef75b99c2
6 changed files with 273 additions and 30 deletions

View File

@ -1,12 +1,26 @@
// @ts-nocheck
type Shop = CommonShopEvent | CommonEventShopEvent | ItemShopEvent;
export function openShop(shopId: string, noRoute: boolean) { 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: 检查能否打开此商店 // Step 1: 检查能否打开此商店
if (!canOpenShop(shopId)) { if (!canOpenShop(shopId)) {
core.drawTip('该商店尚未开启'); core.drawTip('该商店尚未开启');
return false; 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) { if (shop.item) {
Mota.r(() => { Mota.r(() => {
if (!core.isReplaying()) { if (!core.isReplaying()) {
@ -17,13 +31,16 @@ export function openShop(shopId: string, noRoute: boolean) {
}); });
return; return;
} }
// Step4 普通商店
core.insertAction(convertShop(shop));
return true; return true;
} }
/// 是否访问过某个快捷商店 /// 是否访问过某个快捷商店
export function isShopVisited(id: string) { export function isShopVisited(id: string) {
flags.__shops__ ??= {}; flags.__shops__ ??= {};
var shops = core.getFlag<any>('__shops__'); const shops = core.getFlag<any>('__shops__');
if (!shops[id]) shops[id] = {}; if (!shops[id]) shops[id] = {};
return shops[id].visited; return shops[id].visited;
} }
@ -31,7 +48,7 @@ export function isShopVisited(id: string) {
/// 当前应当显示的快捷商店列表 /// 当前应当显示的快捷商店列表
export function listShopIds() { export function listShopIds() {
return Object.keys(core.status.shops).filter(id => { return Object.keys(core.status.shops).filter(id => {
// @ts-ignore // @ts-expect-error 无法推导
return isShopVisited(id) || !core.status.shops[id].mustEnable; return isShopVisited(id) || !core.status.shops[id].mustEnable;
}); });
} }
@ -39,8 +56,8 @@ export function listShopIds() {
/// 是否能够打开某个商店 /// 是否能够打开某个商店
export function canOpenShop(id: string) { export function canOpenShop(id: string) {
if (isShopVisited(id)) return true; if (isShopVisited(id)) return true;
var shop = core.status.shops[id]; const shop = core.status.shops[id];
// @ts-ignore // @ts-expect-error 无法推导
if (shop.item || shop.commonEvent || shop.mustEnable) return false; if (shop.item || shop.commonEvent || shop.mustEnable) return false;
return true; return true;
} }
@ -48,7 +65,7 @@ export function canOpenShop(id: string) {
/// 启用或禁用某个快捷商店 /// 启用或禁用某个快捷商店
export function setShopVisited(id: string, visited: boolean) { export function setShopVisited(id: string, visited: boolean) {
if (!core.hasFlag('__shops__')) core.setFlag('__shops__', {}); if (!core.hasFlag('__shops__')) core.setFlag('__shops__', {});
var shops = core.getFlag<any>('__shops__'); const shops = core.getFlag<any>('__shops__');
if (!shops[id]) shops[id] = {}; if (!shops[id]) shops[id] = {};
if (visited) shops[id].visited = true; if (visited) shops[id].visited = true;
else delete shops[id].visited; else delete shops[id].visited;
@ -64,3 +81,117 @@ export function canUseQuickShop() {
return '当前楼层不能使用快捷商店。'; return '当前楼层不能使用快捷商店。';
return null; 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 });
}

View File

@ -317,7 +317,6 @@ function exit() {
onMounted(async () => { onMounted(async () => {
core.lockControl(); core.lockControl();
core.status.route.push(`openShop:${id}`);
}); });
onUnmounted(() => { onUnmounted(() => {

View File

@ -2276,13 +2276,14 @@ events.prototype._action_unloadEquip = function (data, x, y, prefix) {
}; };
events.prototype._action_openShop = function (data, x, y, prefix) { events.prototype._action_openShop = function (data, x, y, prefix) {
Mota.require('@user/data-state').setShopVisited(data.id, true); Mota.require('@user/legacy-plugin-data').setShopVisited(data.id, true);
if (data.open) Mota.require('@user/data-state').openShop(data.id, true); if (data.open)
Mota.require('@user/legacy-plugin-data').openShop(data.id, true);
core.doAction(); core.doAction();
}; };
events.prototype._action_disableShop = function (data, x, y, prefix) { 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(); core.doAction();
}; };

View File

@ -2254,7 +2254,7 @@ ui.prototype.drawChoices = async function (content, choices, width) {
choice, choice,
[HALF_WIDTH, HALF_HEIGHT, void 0, void 0, 0.5, 0.5], [HALF_WIDTH, HALF_HEIGHT, void 0, void 0, 0.5, 0.5],
width ?? POP_BOX_WIDTH, width ?? POP_BOX_WIDTH,
{ title: content ?? '' } { text: content ?? '' }
); );
core.insertAction(choices[selected].action); core.insertAction(choices[selected].action);
core.doAction(); core.doAction();

View File

@ -215,31 +215,123 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
], ],
"shops": [ "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": "等级+1100经验",
"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, "item": true,
"textInList": "道具商店", "textInList": "道具商店",
"use": "money", "use": "money",
"mustEnable": true, "mustEnable": false,
"choices": [ "choices": [
{ {
"id": "sword2", "id": "yellowKey",
"number": 1, "number": 10,
"money": "600", "money": "10",
"sell": "300" "sell": "5"
},
{
"id": "shield2",
"number": 1,
"money": "500",
"sell": "250"
},
{
"id": "I641",
"number": 1,
"money": "400",
"sell": "200"
} }
] ]
},
{
"id": "keyShop",
"textInList": "回收钥匙商店",
"mustEnable": false,
"commonEvent": "回收钥匙商店"
} }
], ],
"levelUp": [ "levelUp": [

View File

@ -865,6 +865,26 @@ main.floors.sample1=
"icon": "man", "icon": "man",
"text": "试着给我添加一个隐藏事件让我消失吧!" "text": "试着给我添加一个隐藏事件让我消失吧!"
} }
],
"5,9": [
{
"type": "choices",
"text": "选择剑或者盾 11111111111111111111 111111111111111",
"choices": [
{
"text": "剑",
"action": [
{
"type": "openDoor",
"loc": [
3,
3
]
}
]
}
]
}
] ]
}, },
"changeFloor": { "changeFloor": {