底座判断1
This commit is contained in:
1 parent
5b2d0e9291
commit
be7e56d966
8 files changed
+105
-639
No files matched your search
@@ -16,8 +16,42 @@
|
||||
doneMsg: 完成后的提示消息
|
||||
dropIfDone: 熟了后拆掉掉落什么
|
||||
dropIfNot: 没熟拆掉掉落什么
|
||||
below: 下面必须放什么方块(列表),不写=自动推断,[]=不需要底座
|
||||
"""
|
||||
|
||||
# ===== 底座常量 =====
|
||||
# 灶台(灶台基础款 + 炉灶点燃态)
|
||||
BELOW_STOVE = ["rtdd:cookstoves", "rtdd:stove_2"]
|
||||
# 营火(架锅专用)
|
||||
BELOW_CAMPFIRE = ["minecraft:campfire"]
|
||||
|
||||
# ===== 方块前缀 → 底座 推断规则 =====
|
||||
# 如果配方里没写 below 字段,CookingService 会根据方块名自动推断需要什么底座
|
||||
# 匹配优先级:从上到下,先匹配到的生效
|
||||
# 默认:大多数烹饪方块都需要灶台底座
|
||||
_BASE_PREFIX_MAP = [
|
||||
# 架锅系列 → 营火
|
||||
(("rtdd:potsimmering",), BELOW_CAMPFIRE),
|
||||
# 手工工具/不需要底座
|
||||
(("rtdd:juicer", "rtdd:meatballmaker", "rtdd:wine_barrel",
|
||||
"rtdd:farineblock", "rtdd:beater", "rtdd:barbecuegrill",
|
||||
"rtdd:dough_", "rtdd:smalldough_", "rtdd:dought_",
|
||||
"rtdd:scallion_pancake_", "rtdd:dumplings_", "rtdd:roubao_",
|
||||
"rtdd:souffle_", "rtdd:cream_caramel",
|
||||
), []),
|
||||
]
|
||||
|
||||
|
||||
def inferBaseBlock(sourceName):
|
||||
"""根据方块名自动推断需要什么底座,返回底座列表,[]=不需要底座"""
|
||||
for prefixes, base in _BASE_PREFIX_MAP:
|
||||
for p in prefixes:
|
||||
if sourceName.startswith(p):
|
||||
return base
|
||||
# 默认:所有其他烹饪方块都需要灶台底座
|
||||
return BELOW_STOVE
|
||||
|
||||
|
||||
RECIPES = [
|
||||
|
||||
# =====================================================================
|
||||
|
||||
@@ -1,257 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
工具配置数据库(ToolData.py)
|
||||
============================
|
||||
独立于 RecipeData.py,专门管理烹饪工具的配置信息:
|
||||
- 每个工具的激活方式(用什么物品右键激活)
|
||||
- 底座要求(下面必须放什么方块才能工作)
|
||||
- 哪些工具本身可以作为底座(发热源)
|
||||
- 工具的状态切换链
|
||||
|
||||
与 RecipeData.py 的关系:
|
||||
RecipeData.py = 食材配方(什么食材+什么锅 = 什么菜)
|
||||
ToolData.py = 工具配置(锅怎么激活、需要什么底座)
|
||||
|
||||
CookingService 会同时加载这两个数据库,做菜时先检查工具配置,再查配方。
|
||||
"""
|
||||
|
||||
# ============================================================
|
||||
# 一、工具激活/底座配置
|
||||
# ============================================================
|
||||
# 格式:工具源方块 -> {激活物品, 底座列表, 激活后目标, 其他配置}
|
||||
# 当玩家用指定物品右键工具时,工具从"源方块"变成"目标方块"
|
||||
# 如果底座列表不为空,工具下面必须有一个底座方块才能激活
|
||||
|
||||
TOOL_CONFIG = {
|
||||
# ==================== 炒锅 ====================
|
||||
"rtdd:wok": {
|
||||
"name": "炒锅",
|
||||
"activate_item": "rtdd:spatula_oil", # 用带油锅铲激活
|
||||
"check_oil": True, # 需要检查物品含油标签
|
||||
"base_blocks": [ # 下面必须放这些方块之一
|
||||
"rtdd:cookstoves", # 灶台(基础款,有火)
|
||||
"rtdd:stove_2", # 灶台(高级款,有火)
|
||||
"minecraft:campfire", # 原版营火
|
||||
],
|
||||
"target": "rtdd:oilpan", # 激活后变成煎锅
|
||||
"need_fire": True, # 需要火源
|
||||
"is_heat_source": False, # 不是发热源
|
||||
},
|
||||
|
||||
# ==================== 煎锅 ====================
|
||||
"rtdd:oilpan": {
|
||||
"name": "煎锅",
|
||||
"activate_item": "rtdd:spatula_oil", # 用带油锅铲激活
|
||||
"check_oil": True,
|
||||
"base_blocks": [
|
||||
"rtdd:cookstoves",
|
||||
"rtdd:stove_2",
|
||||
"minecraft:campfire",
|
||||
],
|
||||
"target": "rtdd:oilpan", # 激活后不变(只是上油标记)
|
||||
"need_fire": True,
|
||||
"is_heat_source": False,
|
||||
},
|
||||
|
||||
# ==================== 油锅 ====================
|
||||
"rtdd:oilpot_0": {
|
||||
"name": "油锅",
|
||||
"activate_item": "rtdd:oilcan", # 用油罐直接激活
|
||||
"check_oil": False, # 不需要检查物品含油
|
||||
"base_blocks": [
|
||||
"rtdd:cookstoves",
|
||||
"rtdd:stove_2",
|
||||
"minecraft:campfire",
|
||||
],
|
||||
"target": "rtdd:oilpot_1", # 激活后变成倒了油的油锅
|
||||
"need_fire": True,
|
||||
"is_heat_source": False,
|
||||
},
|
||||
|
||||
# ==================== 架锅 ====================
|
||||
"rtdd:potsimmering_0": {
|
||||
"name": "架锅",
|
||||
"activate_item": "minecraft:water_bucket", # 用水桶加水
|
||||
"check_oil": False,
|
||||
"base_blocks": [
|
||||
"rtdd:cookstoves",
|
||||
"rtdd:stove_2",
|
||||
"minecraft:campfire",
|
||||
],
|
||||
"target": "rtdd:potsimmeringwater", # 激活后变成加了水的架锅
|
||||
"need_fire": True,
|
||||
"is_heat_source": False,
|
||||
},
|
||||
|
||||
# ==================== 蒸笼 ====================
|
||||
"rtdd:steamer": {
|
||||
"name": "蒸笼",
|
||||
"activate_item": "rtdd:steamercover", # 用蒸笼盖盖盖
|
||||
"check_oil": False,
|
||||
"base_blocks": [
|
||||
"rtdd:cookstoves",
|
||||
"rtdd:stove_2",
|
||||
"minecraft:campfire",
|
||||
],
|
||||
"target": "rtdd:steamer", # 盖盖后不变(只是标记已盖盖)
|
||||
"need_fire": True,
|
||||
"is_heat_source": False,
|
||||
},
|
||||
|
||||
# ==================== 烧烤架 ====================
|
||||
"rtdd:barbecuegrill_0": {
|
||||
"name": "烧烤架",
|
||||
"activate_item": "minecraft:flint_and_steel", # 打火石点火
|
||||
"check_oil": False,
|
||||
"base_blocks": [], # 不需要底座(自己就是发热源)
|
||||
"target": "rtdd:barbecuegrill_1", # 点火后变成烧烤架_1
|
||||
"need_fire": False,
|
||||
"is_heat_source": False, # 0状态还没点火,不是发热源
|
||||
},
|
||||
|
||||
# ==================== 搅拌器 ====================
|
||||
"rtdd:beater": {
|
||||
"name": "搅拌器",
|
||||
"activate_item": None, # 不需要激活,直接放食材
|
||||
"check_oil": False,
|
||||
"base_blocks": [], # 手工工具,不需要底座
|
||||
"target": None,
|
||||
"need_fire": False,
|
||||
"is_heat_source": False,
|
||||
},
|
||||
|
||||
# ==================== 榨汁机 ====================
|
||||
"rtdd:juicer_0": {
|
||||
"name": "榨汁机",
|
||||
"activate_item": None,
|
||||
"check_oil": False,
|
||||
"base_blocks": [],
|
||||
"target": None,
|
||||
"need_fire": False,
|
||||
"is_heat_source": False,
|
||||
},
|
||||
|
||||
# ==================== 丸子机 ====================
|
||||
"rtdd:meatballmaker_0": {
|
||||
"name": "丸子机",
|
||||
"activate_item": None,
|
||||
"check_oil": False,
|
||||
"base_blocks": [],
|
||||
"target": None,
|
||||
"need_fire": False,
|
||||
"is_heat_source": False,
|
||||
},
|
||||
|
||||
# ==================== 酒桶 ====================
|
||||
"rtdd:wine_barrel": {
|
||||
"name": "酒桶",
|
||||
"activate_item": None,
|
||||
"check_oil": False,
|
||||
"base_blocks": [],
|
||||
"target": None,
|
||||
"need_fire": False,
|
||||
"is_heat_source": False,
|
||||
},
|
||||
|
||||
# ==================== 面粉方块 ====================
|
||||
"rtdd:farineblock": {
|
||||
"name": "面粉方块",
|
||||
"activate_item": None,
|
||||
"check_oil": False,
|
||||
"base_blocks": [],
|
||||
"target": None,
|
||||
"need_fire": False,
|
||||
"is_heat_source": False,
|
||||
},
|
||||
}
|
||||
|
||||
# ============================================================
|
||||
# 二、发热源配置(哪些方块可以作为底座)
|
||||
# ============================================================
|
||||
# 这些方块放在锅下面,锅就能工作
|
||||
|
||||
HEAT_SOURCES = {
|
||||
# 模组自定义灶台
|
||||
"rtdd:cookstoves": {
|
||||
"name": "灶台(基础款)",
|
||||
"heat_level": 1,
|
||||
"supports": [
|
||||
"炒锅", "煎锅", "油锅", "架锅", "蒸笼"
|
||||
],
|
||||
},
|
||||
"rtdd:stove_2": {
|
||||
"name": "灶台(高级款·有火)",
|
||||
"heat_level": 1,
|
||||
"supports": [
|
||||
"炒锅", "煎锅", "油锅", "架锅", "蒸笼"
|
||||
],
|
||||
},
|
||||
|
||||
# 原版底座
|
||||
"minecraft:campfire": {
|
||||
"name": "营火",
|
||||
"heat_level": 1,
|
||||
"supports": [
|
||||
"炒锅", "煎锅", "油锅", "架锅", "蒸笼"
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
# ============================================================
|
||||
# 三、工具状态切换链(完整的状态流转)
|
||||
# ============================================================
|
||||
# 格式:工具名 -> 状态列表(从初始到结束)
|
||||
|
||||
TOOL_STATE_CHAINS = {
|
||||
"炒锅": {
|
||||
"chain": ["rtdd:wok", "rtdd:oilpan", "rtdd:wok"],
|
||||
"description": "空炒锅 -> 上油(煎锅) -> 做完菜 -> 空炒锅",
|
||||
},
|
||||
"油锅": {
|
||||
"chain": ["rtdd:oilpot_0", "rtdd:oilpot_1", "rtdd:oilpot_0"],
|
||||
"description": "空油锅 -> 倒油 -> 炸食材 -> 空油锅",
|
||||
},
|
||||
"架锅": {
|
||||
"chain": ["rtdd:potsimmering_0", "rtdd:potsimmeringwater", "rtdd:potsimmering_0"],
|
||||
"description": "空架锅 -> 加水 -> 炖食材 -> 空架锅",
|
||||
},
|
||||
"蒸笼": {
|
||||
"chain": ["rtdd:steamer", "rtdd:steamer", "rtdd:steamer"],
|
||||
"description": "蒸笼 -> 盖盖 -> 蒸食材 -> 蒸笼(状态不变,通过标记控制)",
|
||||
},
|
||||
"烧烤架": {
|
||||
"chain": ["rtdd:barbecuegrill_0", "rtdd:barbecuegrill_1", "rtdd:barbecuegrill_0"],
|
||||
"description": "烧烤架 -> 点火 -> 烤食材 -> 烧烤架",
|
||||
},
|
||||
"榨汁机": {
|
||||
"chain": ["rtdd:juicer_0", "rtdd:juicer_1", "rtdd:juicer_2",
|
||||
"rtdd:juicer_3", "rtdd:juicer_4", "rtdd:juicer_0"],
|
||||
"description": "空榨汁机 -> 放水果 -> 摇1 -> 摇2 -> 摇3 -> 取果汁 -> 空榨汁机",
|
||||
},
|
||||
"丸子机": {
|
||||
"chain": ["rtdd:meatballmaker_0", "rtdd:meatballmaker_1", "rtdd:meatballmaker_2",
|
||||
"rtdd:meatballmaker_3", "rtdd:meatballmaker_4", "rtdd:meatballmaker_5",
|
||||
"rtdd:meatballmaker_0"],
|
||||
"description": "空丸子机 -> 放碎肉 -> 摇1 -> 摇2 -> 摇3 -> 摇4 -> 取肉丸 -> 空丸子机",
|
||||
},
|
||||
"酒桶": {
|
||||
"chain": ["rtdd:wine_barrel", "b_81", "b_238", "rtdd:wine_barrel"],
|
||||
"description": "酒桶 -> 放原料 -> 发酵 -> 取酒 -> 酒桶",
|
||||
},
|
||||
}
|
||||
|
||||
# ============================================================
|
||||
# 四、工具分类(快速查询)
|
||||
# ============================================================
|
||||
|
||||
# 需要火源的厨具(必须放在发热底座上)
|
||||
NEED_FIRE_TOOLS = [k for k, v in TOOL_CONFIG.items() if v.get("need_fire")]
|
||||
|
||||
# 手工工具(不需要底座,放哪里都能用)
|
||||
MANUAL_TOOLS = [k for k, v in TOOL_CONFIG.items() if not v.get("need_fire") and not v.get("is_heat_source")]
|
||||
|
||||
# 发热源工具(激活后可以作为底座)
|
||||
HEAT_SOURCE_TOOLS = [k for k, v in TOOL_CONFIG.items() if v.get("is_heat_source")]
|
||||
|
||||
# 所有合法底座方块(原版+模组)
|
||||
ALL_BASE_BLOCKS = list(HEAT_SOURCES.keys())
|
||||
@@ -47,7 +47,7 @@ blockEntityDataComp = comp.CreateBlockEntityData(LevelId)
|
||||
|
||||
# ---- 导入所有配方 ----
|
||||
# RECIPES 是一个列表,每条配方是一个 dict,格式见 RecipeData.py 顶部注释
|
||||
from ..RecipeData import RECIPES
|
||||
from ..RecipeData import RECIPES, inferBaseBlock, BELOW_CAMPFIRE
|
||||
|
||||
# ---- 导入工具方块切换规则 ----
|
||||
# BLOCK_SWITCHES 是一个列表,每条规则是一个 dict,格式见 BlockSwitchData.py 顶部注释
|
||||
@@ -229,6 +229,10 @@ class CookingService(BlueFoxServerSystem):
|
||||
# 没找到匹配的配方 → 不是做菜操作,不拦截,让游戏正常处理
|
||||
return
|
||||
|
||||
# ---- 底座检查:锅下面必须有灶台/营火,否则不让操作 ----
|
||||
if not self.checkBaseBlock(recipe, playerId, pos, dim):
|
||||
return
|
||||
|
||||
# 找到配方后,取消默认行为(如喝药水、吃食物等),由本 Mod 全权接管
|
||||
args['cancel'] = True
|
||||
# 同时标记该玩家下一次物品使用事件也要取消,防止喝药水等默认行为
|
||||
@@ -578,6 +582,53 @@ class CookingService(BlueFoxServerSystem):
|
||||
self.replaceBlock(pos, dim, recipe["target"], playerId)
|
||||
self.clearStirData(key, playerId, pos, dim)
|
||||
|
||||
# ============================================================================
|
||||
# 底座检查(入口统一拦截)
|
||||
# ============================================================================
|
||||
|
||||
def checkBaseBlock(self, recipe, playerId, pos, dim):
|
||||
"""
|
||||
检查锅下面有没有合法的底座(灶台或营火)。
|
||||
|
||||
优先级:
|
||||
1. 配方里明确写了 "below" 字段 → 用配方的值
|
||||
- below=[] 表示不需要底座,直接通过
|
||||
- below=["xxx"] 表示必须是这些方块之一
|
||||
2. 配方没写 "below" → 调用 inferBaseBlock 自动推断
|
||||
- 大多数烹饪方块默认需要灶台(BELOW_STOVE)
|
||||
- 架锅系列需要营火(BELOW_CAMPFIRE)
|
||||
- 手工工具(榨汁机、搅拌器等)不需要底座
|
||||
|
||||
返回 True=底座合法/不需要底座,False=底座不合法
|
||||
"""
|
||||
# 配方显式指定了 below
|
||||
if "below" in recipe:
|
||||
required = recipe["below"]
|
||||
if not required: # 空列表 = 不需要底座
|
||||
return True
|
||||
else:
|
||||
# 自动推断
|
||||
required = inferBaseBlock(recipe["source"])
|
||||
if not required: # 推断结果为空 = 不需要底座
|
||||
return True
|
||||
|
||||
# 检查下面一格方块
|
||||
belowPos = (pos[0], pos[1] - 1, pos[2])
|
||||
try:
|
||||
belowBlock = comp.CreateBlockInfo(playerId).GetBlockNew(belowPos, dim)
|
||||
if belowBlock.get("name") in required:
|
||||
return True
|
||||
except:
|
||||
pass
|
||||
|
||||
# ---- 底座不通过,给玩家提示 ----
|
||||
if required == BELOW_CAMPFIRE:
|
||||
tip = "§c架锅下面需要放一个营火,才能做饭!"
|
||||
else:
|
||||
tip = "§c锅下面需要放一个灶台(点燃的炉灶),才能做饭!"
|
||||
comp.CreateMsg(playerId).NotifyOneMessage(playerId, tip)
|
||||
return False
|
||||
|
||||
# ============================================================================
|
||||
# 条件检查
|
||||
# ============================================================================
|
||||
@@ -586,27 +637,10 @@ class CookingService(BlueFoxServerSystem):
|
||||
"""
|
||||
检查配方的前置条件是否满足。
|
||||
|
||||
目前支持两种条件:
|
||||
1. below:锅下面一格必须是特定方块(比如灶台或营火)
|
||||
2. needOil:玩家手里的物品必须带有油标签
|
||||
|
||||
两个条件都满足才返回 True,有一个不满足就返回 False。
|
||||
目前只检查 needOil:玩家手里的物品必须带有油标签。
|
||||
底座检查已移到入口 checkBaseBlock 统一处理。
|
||||
"""
|
||||
# ---- 条件1:检查下面是否有指定方块(底座检查) ----
|
||||
if recipe.get("below"):
|
||||
# 下面一格坐标:(x, y-1, z)
|
||||
belowPos = (pos[0], pos[1] - 1, pos[2])
|
||||
blockComp = comp.CreateBlockInfo(playerId)
|
||||
try:
|
||||
belowBlock = blockComp.GetBlockNew(belowPos, dim)
|
||||
# 比较下面方块的名字是否和配方要求的底座一致
|
||||
if belowBlock.get("name") != recipe["below"]:
|
||||
return False
|
||||
except:
|
||||
# 读取失败(比如方块不存在)→ 条件不满足
|
||||
return False
|
||||
|
||||
# ---- 条件2:检查物品是否有油标签 ----
|
||||
# ---- 检查物品是否有油标签 ----
|
||||
if recipe.get("needOil") and itemDict:
|
||||
if not self.getItemOil(itemDict):
|
||||
return False
|
||||
@@ -643,18 +677,19 @@ class CookingService(BlueFoxServerSystem):
|
||||
"""
|
||||
消耗玩家主手物品的指定数量。
|
||||
|
||||
如果数量不够 → 清空主手(SetEntityItem 传 None)
|
||||
如果数量不够 → 清空主手
|
||||
如果数量够 → 减少对应数量
|
||||
|
||||
重要:SetInvItemNum 的参数是背包槽位索引(int),不是 ItemPosType 枚举。
|
||||
清空主手必须用 SetEntityItem(CARRIED, None),不能用 SetInvItemNum。
|
||||
"""
|
||||
if itemDict is None:
|
||||
return
|
||||
count = itemDict.get("count", 0)
|
||||
if count <= amount:
|
||||
# 数量不够或刚好用完 → 清空主手
|
||||
comp.CreateItem(playerId).SetEntityItem(
|
||||
serverApi.GetMinecraftEnum().ItemPosType.CARRIED,
|
||||
None)
|
||||
{"count": 0})
|
||||
else:
|
||||
# 数量够 → 减少 amount 个
|
||||
itemDict["count"] = count - amount
|
||||
|
||||
Reference in new issue
Block a user