市场贸易实现 bug修复
This commit is contained in:
1 parent
1f329f8b4c
commit
cae9bcb19e
25 files changed
+1300
-187
No files matched your search
+534
@@ -0,0 +1,534 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
================================================================================
|
||||
市场贸易分类转换规则数据
|
||||
================================================================================
|
||||
只处理"市场贸易"(xy_market) 分类下的右键转换:
|
||||
1) 条箱/货桶/售卖盒 放入: 手持对应物品右键 空容器 → 消耗物品 → 变为对应容器
|
||||
2) 条箱/货桶/售卖盒 取出: 空手右键 装满容器 → 变回空容器 + 以掉落物形式取回物品
|
||||
3) 悬赏纸循环: 空手右键逐级切换 bountypaper → _1 → _2 → bountypaper
|
||||
其余摊位设施(b_4/menus/vending_desk)为静态, 无转换。
|
||||
布料(clothbox_1/2)已按标注禁用, 不参与本分类转换。
|
||||
|
||||
【消耗数量】
|
||||
除 南瓜/西瓜 消耗1个原版方块(minecraft:pumpkin / minecraft:melon_block)外,
|
||||
其余均消耗32个对应物品; 取出时按放入数量取回(南瓜/西瓜取回1个方块)。
|
||||
|
||||
字段说明(与 AnimalData/DeadmobData 一致):
|
||||
source: 被右键的方块ID(必填)
|
||||
item: 玩家手里必须拿的物品, None=空手
|
||||
target: 替换成什么方块
|
||||
consume: 消耗物品数量, 0=不消耗
|
||||
dropItem: 转换时以掉落物形式生成的物品列表(取出用)
|
||||
tip: 转换成功提示
|
||||
================================================================================
|
||||
"""
|
||||
|
||||
MARKET_SWITCHES = [
|
||||
|
||||
# ============================================================
|
||||
# 一、条箱 (woodenbox_0空 → woodenbox_1~7 各装一种)
|
||||
# ============================================================
|
||||
# ---- 放入 (手持物品右键 空条箱) ----
|
||||
{
|
||||
"source": "rtdd:woodenbox_0",
|
||||
"item": "minecraft:apple",
|
||||
"target": "rtdd:woodenbox_1",
|
||||
"consume": 32,
|
||||
"type": "switch",
|
||||
"tip": "§a已放入32个苹果",
|
||||
"giveItem": None,
|
||||
},
|
||||
{
|
||||
"source": "rtdd:woodenbox_0",
|
||||
"item": "minecraft:carrot",
|
||||
"target": "rtdd:woodenbox_2",
|
||||
"consume": 32,
|
||||
"type": "switch",
|
||||
"tip": "§a已放入32个胡萝卜",
|
||||
"giveItem": None,
|
||||
},
|
||||
{
|
||||
"source": "rtdd:woodenbox_0",
|
||||
"item": "minecraft:potato",
|
||||
"target": "rtdd:woodenbox_3",
|
||||
"consume": 32,
|
||||
"type": "switch",
|
||||
"tip": "§a已放入32个土豆",
|
||||
"giveItem": None,
|
||||
},
|
||||
{
|
||||
"source": "rtdd:woodenbox_0",
|
||||
"item": "rtdd:peach",
|
||||
"target": "rtdd:woodenbox_4",
|
||||
"consume": 32,
|
||||
"type": "switch",
|
||||
"tip": "§a已放入32个桃子",
|
||||
"giveItem": None,
|
||||
},
|
||||
{
|
||||
"source": "rtdd:woodenbox_0",
|
||||
"item": "rtdd:orange",
|
||||
"target": "rtdd:woodenbox_5",
|
||||
"consume": 32,
|
||||
"type": "switch",
|
||||
"tip": "§a已放入32个橘子",
|
||||
"giveItem": None,
|
||||
},
|
||||
{
|
||||
"source": "rtdd:woodenbox_0",
|
||||
"item": "minecraft:cod",
|
||||
"target": "rtdd:woodenbox_6",
|
||||
"consume": 32,
|
||||
"type": "switch",
|
||||
"tip": "§a已放入32条鳕鱼",
|
||||
"giveItem": None,
|
||||
},
|
||||
{
|
||||
"source": "rtdd:woodenbox_0",
|
||||
"item": "minecraft:salmon",
|
||||
"target": "rtdd:woodenbox_7",
|
||||
"consume": 32,
|
||||
"type": "switch",
|
||||
"tip": "§a已放入32条鲑鱼",
|
||||
"giveItem": None,
|
||||
},
|
||||
# ---- 取出 (空手右键 装满的条箱) ----
|
||||
{
|
||||
"source": "rtdd:woodenbox_1",
|
||||
"item": None,
|
||||
"target": "rtdd:woodenbox_0",
|
||||
"consume": 0,
|
||||
"type": "switch",
|
||||
"dropItem": [{"name": "minecraft:apple", "count": 32}],
|
||||
"tip": "§a取出了32个苹果",
|
||||
"giveItem": None,
|
||||
},
|
||||
{
|
||||
"source": "rtdd:woodenbox_2",
|
||||
"item": None,
|
||||
"target": "rtdd:woodenbox_0",
|
||||
"consume": 0,
|
||||
"type": "switch",
|
||||
"dropItem": [{"name": "minecraft:carrot", "count": 32}],
|
||||
"tip": "§a取出了32个胡萝卜",
|
||||
"giveItem": None,
|
||||
},
|
||||
{
|
||||
"source": "rtdd:woodenbox_3",
|
||||
"item": None,
|
||||
"target": "rtdd:woodenbox_0",
|
||||
"consume": 0,
|
||||
"type": "switch",
|
||||
"dropItem": [{"name": "minecraft:potato", "count": 32}],
|
||||
"tip": "§a取出了32个土豆",
|
||||
"giveItem": None,
|
||||
},
|
||||
{
|
||||
"source": "rtdd:woodenbox_4",
|
||||
"item": None,
|
||||
"target": "rtdd:woodenbox_0",
|
||||
"consume": 0,
|
||||
"type": "switch",
|
||||
"dropItem": [{"name": "rtdd:peach", "count": 32}],
|
||||
"tip": "§a取出了32个桃子",
|
||||
"giveItem": None,
|
||||
},
|
||||
{
|
||||
"source": "rtdd:woodenbox_5",
|
||||
"item": None,
|
||||
"target": "rtdd:woodenbox_0",
|
||||
"consume": 0,
|
||||
"type": "switch",
|
||||
"dropItem": [{"name": "rtdd:orange", "count": 32}],
|
||||
"tip": "§a取出了32个橘子",
|
||||
"giveItem": None,
|
||||
},
|
||||
{
|
||||
"source": "rtdd:woodenbox_6",
|
||||
"item": None,
|
||||
"target": "rtdd:woodenbox_0",
|
||||
"consume": 0,
|
||||
"type": "switch",
|
||||
"dropItem": [{"name": "minecraft:cod", "count": 32}],
|
||||
"tip": "§a取出了32条鳕鱼",
|
||||
"giveItem": None,
|
||||
},
|
||||
{
|
||||
"source": "rtdd:woodenbox_7",
|
||||
"item": None,
|
||||
"target": "rtdd:woodenbox_0",
|
||||
"consume": 0,
|
||||
"type": "switch",
|
||||
"dropItem": [{"name": "minecraft:salmon", "count": 32}],
|
||||
"tip": "§a取出了32条鲑鱼",
|
||||
"giveItem": None,
|
||||
},
|
||||
|
||||
# ============================================================
|
||||
# 二、货桶 (fishbucket_0空 → 各装一种)
|
||||
# ============================================================
|
||||
# ---- 放入 ----
|
||||
{
|
||||
"source": "rtdd:fishbucket_0",
|
||||
"item": "minecraft:cod",
|
||||
"target": "rtdd:fishbucket_1",
|
||||
"consume": 32,
|
||||
"type": "switch",
|
||||
"tip": "§a已放入32条鳕鱼",
|
||||
"giveItem": None,
|
||||
},
|
||||
{
|
||||
"source": "rtdd:fishbucket_0",
|
||||
"item": "minecraft:salmon",
|
||||
"target": "rtdd:fishbucket_2",
|
||||
"consume": 32,
|
||||
"type": "switch",
|
||||
"tip": "§a已放入32条鲑鱼",
|
||||
"giveItem": None,
|
||||
},
|
||||
{
|
||||
"source": "rtdd:fishbucket_0",
|
||||
"item": "minecraft:carrot",
|
||||
"target": "rtdd:carrotbarrel",
|
||||
"consume": 32,
|
||||
"type": "switch",
|
||||
"tip": "§a已放入32个胡萝卜",
|
||||
"giveItem": None,
|
||||
},
|
||||
{
|
||||
"source": "rtdd:fishbucket_0",
|
||||
"item": "minecraft:potato",
|
||||
"target": "rtdd:potatobarrel",
|
||||
"consume": 32,
|
||||
"type": "switch",
|
||||
"tip": "§a已放入32个土豆",
|
||||
"giveItem": None,
|
||||
},
|
||||
{
|
||||
"source": "rtdd:fishbucket_0",
|
||||
"item": "rtdd:peach",
|
||||
"target": "rtdd:peachbarrel",
|
||||
"consume": 32,
|
||||
"type": "switch",
|
||||
"tip": "§a已放入32个桃子",
|
||||
"giveItem": None,
|
||||
},
|
||||
{
|
||||
"source": "rtdd:fishbucket_0",
|
||||
"item": "rtdd:orange",
|
||||
"target": "rtdd:orangebarrel",
|
||||
"consume": 32,
|
||||
"type": "switch",
|
||||
"tip": "§a已放入32个橘子",
|
||||
"giveItem": None,
|
||||
},
|
||||
{
|
||||
"source": "rtdd:fishbucket_0",
|
||||
"item": "minecraft:apple",
|
||||
"target": "rtdd:applebox",
|
||||
"consume": 32,
|
||||
"type": "switch",
|
||||
"tip": "§a已放入32个苹果",
|
||||
"giveItem": None,
|
||||
},
|
||||
# ---- 取出 ----
|
||||
{
|
||||
"source": "rtdd:fishbucket_1",
|
||||
"item": None,
|
||||
"target": "rtdd:fishbucket_0",
|
||||
"consume": 0,
|
||||
"type": "switch",
|
||||
"dropItem": [{"name": "minecraft:cod", "count": 32}],
|
||||
"tip": "§a取出了32条鳕鱼",
|
||||
"giveItem": None,
|
||||
},
|
||||
{
|
||||
"source": "rtdd:fishbucket_2",
|
||||
"item": None,
|
||||
"target": "rtdd:fishbucket_0",
|
||||
"consume": 0,
|
||||
"type": "switch",
|
||||
"dropItem": [{"name": "minecraft:salmon", "count": 32}],
|
||||
"tip": "§a取出了32条鲑鱼",
|
||||
"giveItem": None,
|
||||
},
|
||||
{
|
||||
"source": "rtdd:carrotbarrel",
|
||||
"item": None,
|
||||
"target": "rtdd:fishbucket_0",
|
||||
"consume": 0,
|
||||
"type": "switch",
|
||||
"dropItem": [{"name": "minecraft:carrot", "count": 32}],
|
||||
"tip": "§a取出了32个胡萝卜",
|
||||
"giveItem": None,
|
||||
},
|
||||
{
|
||||
"source": "rtdd:potatobarrel",
|
||||
"item": None,
|
||||
"target": "rtdd:fishbucket_0",
|
||||
"consume": 0,
|
||||
"type": "switch",
|
||||
"dropItem": [{"name": "minecraft:potato", "count": 32}],
|
||||
"tip": "§a取出了32个土豆",
|
||||
"giveItem": None,
|
||||
},
|
||||
{
|
||||
"source": "rtdd:peachbarrel",
|
||||
"item": None,
|
||||
"target": "rtdd:fishbucket_0",
|
||||
"consume": 0,
|
||||
"type": "switch",
|
||||
"dropItem": [{"name": "rtdd:peach", "count": 32}],
|
||||
"tip": "§a取出了32个桃子",
|
||||
"giveItem": None,
|
||||
},
|
||||
{
|
||||
"source": "rtdd:orangebarrel",
|
||||
"item": None,
|
||||
"target": "rtdd:fishbucket_0",
|
||||
"consume": 0,
|
||||
"type": "switch",
|
||||
"dropItem": [{"name": "rtdd:orange", "count": 32}],
|
||||
"tip": "§a取出了32个橘子",
|
||||
"giveItem": None,
|
||||
},
|
||||
{
|
||||
"source": "rtdd:applebox",
|
||||
"item": None,
|
||||
"target": "rtdd:fishbucket_0",
|
||||
"consume": 0,
|
||||
"type": "switch",
|
||||
"dropItem": [{"name": "minecraft:apple", "count": 32}],
|
||||
"tip": "§a取出了32个苹果",
|
||||
"giveItem": None,
|
||||
},
|
||||
|
||||
# ============================================================
|
||||
# 三、售卖盒 (sellingboxes空 → 各装一种)
|
||||
# 南瓜/西瓜消耗1个原版方块, 其余32个
|
||||
# ============================================================
|
||||
# ---- 放入 ----
|
||||
{
|
||||
"source": "rtdd:sellingboxes",
|
||||
"item": "rtdd:orange",
|
||||
"target": "rtdd:orangebox",
|
||||
"consume": 32,
|
||||
"type": "switch",
|
||||
"tip": "§a已放入32个橘子",
|
||||
"giveItem": None,
|
||||
},
|
||||
{
|
||||
"source": "rtdd:sellingboxes",
|
||||
"item": "rtdd:peach",
|
||||
"target": "rtdd:peachbox",
|
||||
"consume": 32,
|
||||
"type": "switch",
|
||||
"tip": "§a已放入32个桃子",
|
||||
"giveItem": None,
|
||||
},
|
||||
{
|
||||
"source": "rtdd:sellingboxes",
|
||||
"item": "minecraft:cod",
|
||||
"target": "rtdd:sales_box_cod",
|
||||
"consume": 32,
|
||||
"type": "switch",
|
||||
"tip": "§a已放入32条鳕鱼",
|
||||
"giveItem": None,
|
||||
},
|
||||
{
|
||||
"source": "rtdd:sellingboxes",
|
||||
"item": "minecraft:salmon",
|
||||
"target": "rtdd:b_30",
|
||||
"consume": 32,
|
||||
"type": "switch",
|
||||
"tip": "§a已放入32条鲑鱼",
|
||||
"giveItem": None,
|
||||
},
|
||||
{
|
||||
"source": "rtdd:sellingboxes",
|
||||
"item": "minecraft:carrot",
|
||||
"target": "rtdd:sales_box_carrot",
|
||||
"consume": 32,
|
||||
"type": "switch",
|
||||
"tip": "§a已放入32个胡萝卜",
|
||||
"giveItem": None,
|
||||
},
|
||||
{
|
||||
"source": "rtdd:sellingboxes",
|
||||
"item": "minecraft:bread",
|
||||
"target": "rtdd:sales_box_bread",
|
||||
"consume": 32,
|
||||
"type": "switch",
|
||||
"tip": "§a已放入32个面包",
|
||||
"giveItem": None,
|
||||
},
|
||||
{
|
||||
"source": "rtdd:sellingboxes",
|
||||
"item": "minecraft:apple",
|
||||
"target": "rtdd:sales_box_apple",
|
||||
"consume": 32,
|
||||
"type": "switch",
|
||||
"tip": "§a已放入32个苹果",
|
||||
"giveItem": None,
|
||||
},
|
||||
{
|
||||
"source": "rtdd:sellingboxes",
|
||||
"item": "minecraft:pumpkin",
|
||||
"target": "rtdd:sales_box_pumpkin",
|
||||
"consume": 1,
|
||||
"type": "switch",
|
||||
"tip": "§a已放入1个原版南瓜",
|
||||
"giveItem": None,
|
||||
},
|
||||
{
|
||||
"source": "rtdd:sellingboxes",
|
||||
"item": "minecraft:melon_block",
|
||||
"target": "rtdd:sales_box_watermelon",
|
||||
"consume": 1,
|
||||
"type": "switch",
|
||||
"tip": "§a已放入1个原版西瓜",
|
||||
"giveItem": None,
|
||||
},
|
||||
{
|
||||
"source": "rtdd:sellingboxes",
|
||||
"item": "minecraft:potato",
|
||||
"target": "rtdd:sales_box_potato",
|
||||
"consume": 32,
|
||||
"type": "switch",
|
||||
"tip": "§a已放入32个土豆",
|
||||
"giveItem": None,
|
||||
},
|
||||
# ---- 取出 ----
|
||||
{
|
||||
"source": "rtdd:orangebox",
|
||||
"item": None,
|
||||
"target": "rtdd:sellingboxes",
|
||||
"consume": 0,
|
||||
"type": "switch",
|
||||
"dropItem": [{"name": "rtdd:orange", "count": 32}],
|
||||
"tip": "§a取出了32个橘子",
|
||||
"giveItem": None,
|
||||
},
|
||||
{
|
||||
"source": "rtdd:peachbox",
|
||||
"item": None,
|
||||
"target": "rtdd:sellingboxes",
|
||||
"consume": 0,
|
||||
"type": "switch",
|
||||
"dropItem": [{"name": "rtdd:peach", "count": 32}],
|
||||
"tip": "§a取出了32个桃子",
|
||||
"giveItem": None,
|
||||
},
|
||||
{
|
||||
"source": "rtdd:sales_box_cod",
|
||||
"item": None,
|
||||
"target": "rtdd:sellingboxes",
|
||||
"consume": 0,
|
||||
"type": "switch",
|
||||
"dropItem": [{"name": "minecraft:cod", "count": 32}],
|
||||
"tip": "§a取出了32条鳕鱼",
|
||||
"giveItem": None,
|
||||
},
|
||||
{
|
||||
"source": "rtdd:b_30",
|
||||
"item": None,
|
||||
"target": "rtdd:sellingboxes",
|
||||
"consume": 0,
|
||||
"type": "switch",
|
||||
"dropItem": [{"name": "minecraft:salmon", "count": 32}],
|
||||
"tip": "§a取出了32条鲑鱼",
|
||||
"giveItem": None,
|
||||
},
|
||||
{
|
||||
"source": "rtdd:sales_box_carrot",
|
||||
"item": None,
|
||||
"target": "rtdd:sellingboxes",
|
||||
"consume": 0,
|
||||
"type": "switch",
|
||||
"dropItem": [{"name": "minecraft:carrot", "count": 32}],
|
||||
"tip": "§a取出了32个胡萝卜",
|
||||
"giveItem": None,
|
||||
},
|
||||
{
|
||||
"source": "rtdd:sales_box_bread",
|
||||
"item": None,
|
||||
"target": "rtdd:sellingboxes",
|
||||
"consume": 0,
|
||||
"type": "switch",
|
||||
"dropItem": [{"name": "minecraft:bread", "count": 32}],
|
||||
"tip": "§a取出了32个面包",
|
||||
"giveItem": None,
|
||||
},
|
||||
{
|
||||
"source": "rtdd:sales_box_apple",
|
||||
"item": None,
|
||||
"target": "rtdd:sellingboxes",
|
||||
"consume": 0,
|
||||
"type": "switch",
|
||||
"dropItem": [{"name": "minecraft:apple", "count": 32}],
|
||||
"tip": "§a取出了32个苹果",
|
||||
"giveItem": None,
|
||||
},
|
||||
{
|
||||
"source": "rtdd:sales_box_pumpkin",
|
||||
"item": None,
|
||||
"target": "rtdd:sellingboxes",
|
||||
"consume": 0,
|
||||
"type": "switch",
|
||||
"dropItem": [{"name": "minecraft:pumpkin", "count": 1}],
|
||||
"tip": "§a取出了1个原版南瓜",
|
||||
"giveItem": None,
|
||||
},
|
||||
{
|
||||
"source": "rtdd:sales_box_watermelon",
|
||||
"item": None,
|
||||
"target": "rtdd:sellingboxes",
|
||||
"consume": 0,
|
||||
"type": "switch",
|
||||
"dropItem": [{"name": "minecraft:melon_block", "count": 1}],
|
||||
"tip": "§a取出了1个原版西瓜",
|
||||
"giveItem": None,
|
||||
},
|
||||
{
|
||||
"source": "rtdd:sales_box_potato",
|
||||
"item": None,
|
||||
"target": "rtdd:sellingboxes",
|
||||
"consume": 0,
|
||||
"type": "switch",
|
||||
"dropItem": [{"name": "minecraft:potato", "count": 32}],
|
||||
"tip": "§a取出了32个土豆",
|
||||
"giveItem": None,
|
||||
},
|
||||
|
||||
# ============================================================
|
||||
# 四、悬赏纸循环 (空手右键逐级切换)
|
||||
# ============================================================
|
||||
{
|
||||
"source": "rtdd:bountypaper",
|
||||
"item": None,
|
||||
"target": "rtdd:bountypaper_1",
|
||||
"consume": 0,
|
||||
"type": "switch",
|
||||
"tip": "§a切换到悬赏纸_1",
|
||||
"giveItem": None,
|
||||
},
|
||||
{
|
||||
"source": "rtdd:bountypaper_1",
|
||||
"item": None,
|
||||
"target": "rtdd:bountypaper_2",
|
||||
"consume": 0,
|
||||
"type": "switch",
|
||||
"tip": "§a切换到悬赏纸_2",
|
||||
"giveItem": None,
|
||||
},
|
||||
{
|
||||
"source": "rtdd:bountypaper_2",
|
||||
"item": None,
|
||||
"target": "rtdd:bountypaper",
|
||||
"consume": 0,
|
||||
"type": "switch",
|
||||
"tip": "§a切回农贸清单",
|
||||
"giveItem": None,
|
||||
},
|
||||
]
|
||||
Whitespace-only changes.
+265
@@ -0,0 +1,265 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
================================================================================
|
||||
市场贸易·右键转换引擎(服务端)
|
||||
================================================================================
|
||||
只处理"市场贸易"(xy_market) 分类下的【右键切换型】转换:
|
||||
条箱/货桶/售卖盒 放入与取出、悬赏纸循环切换。
|
||||
全部为即时右键转换, 无计时, 因此只有一个服务类, 不需要拆分 TimerService。
|
||||
|
||||
【事件监听在哪?】
|
||||
本类【不】监听任何事件!
|
||||
所有事件由 FeatureDispatcher(xiangyemod/service/FeatureDispatcher.py)统一监听:
|
||||
- ServerBlockUseEvent → OnBlockUse → 按 blockOwner 路由到本类 handleBlockUse
|
||||
本类只实现被分发器调用的接口方法, 不关心事件来源。
|
||||
|
||||
【本类怎么做(自上而下的方法系列)】
|
||||
handleBlockUse ← 入口:分发器转发右键方块事件
|
||||
├─ findRecipe ← 匹配 (方块名, 物品名);空手规则需确认真正空手
|
||||
├─ checkCooldown← 连点冷却
|
||||
└─ handleSwitch ← 放入(消耗+替换) / 取出(掉落+替换) / 悬赏纸循环(替换)
|
||||
├─ checkCount ← 放入前检查物品数量足够(不足给红字提示)
|
||||
├─ consumeItem ← 消耗物品
|
||||
├─ replaceBlock ← 替换方块
|
||||
└─ dropItems ← 取出时以掉落物形式生成物品
|
||||
================================================================================
|
||||
"""
|
||||
import time
|
||||
import mod.server.extraServerApi as serverApi
|
||||
|
||||
# ---- 网易API基础对象 ----
|
||||
ServerSystem = serverApi.GetServerSystemCls() # 服务端系统基类
|
||||
comp = serverApi.GetEngineCompFactory() # 组件工厂
|
||||
|
||||
# ---- 继承 BlueFox 框架的系统基类(提供 CreateEngineItemEntity 等方法) ----
|
||||
from ....BlueFoxTools.SpecialFunciton.BlueFoxSystem import BlueFoxServerSystem
|
||||
from ....BlueFoxTools.ToolsConfig import LevelId
|
||||
|
||||
# ---- 只导入市场贸易自己的数据库 ----
|
||||
from ..MarketData import MARKET_SWITCHES
|
||||
|
||||
# ---- 统一分发器 ----
|
||||
from ...service.FeatureDispatcher import FeatureDispatcher
|
||||
|
||||
|
||||
class MarketService(BlueFoxServerSystem):
|
||||
"""
|
||||
市场贸易·右键转换引擎
|
||||
|
||||
【核心数据结构】
|
||||
marketRecipes = {(方块名, 物品名): 规则dict} # O(1) 查找
|
||||
marketBlockSet = {方块名, ...} # O(1) 注册用
|
||||
cooldown = {key: 时间戳} # 连点冷却表
|
||||
"""
|
||||
|
||||
def __init__(self, namespace, systemName):
|
||||
"""
|
||||
初始化:构建规则字典,并注册到统一分发器。
|
||||
"""
|
||||
super(MarketService, self).__init__(namespace, systemName)
|
||||
print "===== MarketService init ====="
|
||||
|
||||
# ---- 构建规则字典(O(1) 查找) ----
|
||||
self.marketRecipes = {}
|
||||
self.marketBlockSet = set()
|
||||
for sw in MARKET_SWITCHES:
|
||||
key = (sw["source"], sw.get("item"))
|
||||
self.marketRecipes[key] = sw
|
||||
self.marketBlockSet.add(sw["source"])
|
||||
|
||||
# ---- 右键冷却表 ----
|
||||
self.cooldown = {}
|
||||
|
||||
# ---- 注册到统一分发器 ----
|
||||
FeatureDispatcher.register(self)
|
||||
|
||||
# ============================================================================
|
||||
# 一、给 FeatureDispatcher 的接口
|
||||
# ============================================================================
|
||||
|
||||
def getFeatureBlocks(self):
|
||||
"""返回本功能管辖的所有方块名集合(右键路由用)"""
|
||||
return self.marketBlockSet
|
||||
|
||||
def getItemUseOnRules(self):
|
||||
"""返回"手持物品右键方块表面"的规则(市场贸易没有, 返回空)"""
|
||||
return {}
|
||||
|
||||
def handleBlockUse(self, args):
|
||||
"""
|
||||
由 FeatureDispatcher 转发的右键方块入口。
|
||||
只有 blockName 在本功能的方块集合里才会被调用。
|
||||
|
||||
返回 True = 本功能处理了这个右键(分发器取消默认行为)
|
||||
返回 False = 当前组合没有匹配规则(分发器不拦截)
|
||||
"""
|
||||
blockName = args.get("blockName")
|
||||
playerId = args.get("playerId")
|
||||
x, y, z = args.get("x"), args.get("y"), args.get("z")
|
||||
pos = (x, y, z)
|
||||
dim = comp.CreateDimension(playerId).GetEntityDimensionId()
|
||||
key = (dim, x, y, z)
|
||||
|
||||
itemDict = self.getCarriedItem(playerId)
|
||||
|
||||
recipe = self.findRecipe(blockName, itemDict)
|
||||
if not recipe:
|
||||
return False
|
||||
|
||||
# 连点冷却
|
||||
if not self.checkCooldown(key, recipe.get("switchCd", 0.5)):
|
||||
return True
|
||||
|
||||
# 放入前检查物品数量是否足够
|
||||
if recipe.get("item") is not None:
|
||||
need = recipe.get("consume", 1)
|
||||
if not self.checkCount(playerId, itemDict, need):
|
||||
return True
|
||||
|
||||
# 切换型规则:就地执行
|
||||
self.handleSwitch(recipe, playerId, pos, dim, itemDict)
|
||||
return True
|
||||
|
||||
# ============================================================================
|
||||
# 二、规则匹配(O(1) 字典查找)
|
||||
# ============================================================================
|
||||
|
||||
def findRecipe(self, blockName, itemDict):
|
||||
"""
|
||||
在市场中查找匹配规则:
|
||||
1. 先精确匹配 (方块名, 物品名) —— 放入(手持物品) / 悬赏纸循环
|
||||
2. 没找到再匹配 (方块名, None) —— 空手触发的规则(取出)
|
||||
注意:只有确认玩家真正空手时才 fallback 到空手规则, 避免手持物品误触发取出。
|
||||
"""
|
||||
itemName = itemDict.get("newItemName") if itemDict else None
|
||||
recipe = self.marketRecipes.get((blockName, itemName))
|
||||
if recipe:
|
||||
return recipe
|
||||
# 空手规则:只有确认空手(无物品或手持空气)才 fallback
|
||||
if not itemName or itemName == "minecraft:air":
|
||||
return self.marketRecipes.get((blockName, None))
|
||||
return None
|
||||
|
||||
# ============================================================================
|
||||
# 三、切换型规则处理
|
||||
# ============================================================================
|
||||
|
||||
def handleSwitch(self, recipe, playerId, pos, dim, itemDict):
|
||||
"""
|
||||
处理"右键直接转换"类规则。
|
||||
- 放入(item 不为 None): 消耗物品 + 替换方块 + 提示
|
||||
- 取出(item 为 None): 掉落物 + 替换方块 + 提示(悬赏纸循环只替换+提示)
|
||||
"""
|
||||
# ---- 放入:消耗物品 ----
|
||||
if recipe.get("item") is not None and recipe.get("consume", 1) > 0:
|
||||
self.consumeItem(playerId, itemDict, recipe.get("consume", 1))
|
||||
|
||||
# ---- 取出:掉落物 ----
|
||||
if recipe.get("dropItem"):
|
||||
self.dropItems(dim, pos, recipe["dropItem"])
|
||||
|
||||
# ---- 替换方块 ----
|
||||
if recipe.get("target"):
|
||||
self.replaceBlock(pos, dim, recipe["target"], playerId)
|
||||
|
||||
# ---- 转换成功提示 ----
|
||||
if recipe.get("tip"):
|
||||
comp.CreateMsg(playerId).NotifyOneMessage(playerId, recipe["tip"])
|
||||
|
||||
# ============================================================================
|
||||
# 四、工具方法:放入数量检查
|
||||
# ============================================================================
|
||||
|
||||
def checkCount(self, playerId, itemDict, need):
|
||||
"""放入前检查手中物品数量是否足够 need 个, 不足给红字提示并返回 False"""
|
||||
if itemDict is None:
|
||||
comp.CreateMsg(playerId).NotifyOneMessage(playerId, "§c需要至少%d个对应物品!" % need)
|
||||
return False
|
||||
count = itemDict.get("count", 0)
|
||||
if count < need:
|
||||
comp.CreateMsg(playerId).NotifyOneMessage(playerId, "§c数量不足,需要至少%d个对应物品!" % need)
|
||||
return False
|
||||
return True
|
||||
|
||||
# ============================================================================
|
||||
# 五、工具方法:获取玩家主手物品
|
||||
# ============================================================================
|
||||
|
||||
def getCarriedItem(self, playerId):
|
||||
itemComp = comp.CreateItem(playerId)
|
||||
return itemComp.GetPlayerItem(
|
||||
serverApi.GetMinecraftEnum().ItemPosType.CARRIED, 0)
|
||||
|
||||
# ============================================================================
|
||||
# 六、工具方法:消耗物品
|
||||
# ============================================================================
|
||||
|
||||
def consumeItem(self, playerId, itemDict, amount=1):
|
||||
if itemDict is None:
|
||||
return
|
||||
count = itemDict.get("count", 0)
|
||||
if count <= amount:
|
||||
comp.CreateItem(playerId).SetEntityItem(
|
||||
serverApi.GetMinecraftEnum().ItemPosType.CARRIED,
|
||||
{"itemName": "minecraft:air", "count": 0, "auxValue": 0})
|
||||
else:
|
||||
itemDict["count"] = count - amount
|
||||
comp.CreateItem(playerId).SetEntityItem(
|
||||
serverApi.GetMinecraftEnum().ItemPosType.CARRIED,
|
||||
{"itemName": itemDict["newItemName"],
|
||||
"count": itemDict["count"],
|
||||
"auxValue": itemDict.get("newAuxValue", 0)})
|
||||
|
||||
# ============================================================================
|
||||
# 七、工具方法:替换方块
|
||||
# ============================================================================
|
||||
|
||||
def replaceBlock(self, pos, dim, newBlockName, playerId=None):
|
||||
"""
|
||||
替换指定位置的方块。
|
||||
playerId 可为 None, 用 LevelId 创建组件。
|
||||
"""
|
||||
creator = playerId if playerId is not None else LevelId
|
||||
aux = 0
|
||||
try:
|
||||
oldBlock = comp.CreateBlockInfo(creator).GetBlockNew(pos, dim)
|
||||
aux = oldBlock.get("aux", 0)
|
||||
except Exception:
|
||||
aux = 0
|
||||
comp.CreateBlockInfo(creator).SetBlockNew(
|
||||
pos,
|
||||
blockDict={"name": newBlockName, "aux": aux},
|
||||
oldBlockHandling=0,
|
||||
dimensionId=dim)
|
||||
|
||||
# ============================================================================
|
||||
# 八、工具方法:以掉落物形式生成物品(取出)
|
||||
# ============================================================================
|
||||
|
||||
def dropItems(self, dim, pos, dropList):
|
||||
"""
|
||||
dropList 格式:[{"name": "xxx", "count": N}, ...]
|
||||
在方块上方生成掉落物实体, 让它自然掉到地上。
|
||||
"""
|
||||
for d in dropList:
|
||||
itemDict = {
|
||||
"itemName": d["name"],
|
||||
"count": d.get("count", 1),
|
||||
"auxValue": d.get("aux", 0),
|
||||
}
|
||||
self.CreateEngineItemEntity(itemDict, dim, (pos[0], pos[1] + 0.5, pos[2]))
|
||||
|
||||
# ============================================================================
|
||||
# 九、工具方法:冷却检查
|
||||
# ============================================================================
|
||||
|
||||
def checkCooldown(self, key, cd=0.5):
|
||||
"""
|
||||
右键冷却:同一方块 cd 秒内只响应一次, 防止连点刷物品/刷提示。
|
||||
"""
|
||||
now = time.time()
|
||||
last = self.cooldown.get(key, 0)
|
||||
if now - last < cd:
|
||||
return False
|
||||
self.cooldown[key] = now
|
||||
return True
|
||||
Whitespace-only changes.
Reference in new issue
Block a user