diff --git a/behavior_pack_v8jz0zSR/Script_NeteaseModousIY5aSF/xiangyemod/chuju/ChujuData.py b/behavior_pack_v8jz0zSR/Script_NeteaseModousIY5aSF/xiangyemod/chuju/ChujuData.py index c788f83..13e23cc 100644 --- a/behavior_pack_v8jz0zSR/Script_NeteaseModousIY5aSF/xiangyemod/chuju/ChujuData.py +++ b/behavior_pack_v8jz0zSR/Script_NeteaseModousIY5aSF/xiangyemod/chuju/ChujuData.py @@ -117,6 +117,15 @@ OIL_CAN_ITEM = "rtdd:oilcan" # 油罐(石磨产物) # 石磨材料标识(存方块实体 rtdd_stm): 'soybean'=黄豆, 'wheat'=小麦 STONEMILL_MATERIAL_KEY = "rtdd_stm" +# 石磨·客户端消闪拦截(BlockUse): 手持 玻璃罐/黄豆/小麦 右键石磨, 提前取消"放置预览", +# 再显式通知服务端(见 InterceptData.BLOCKUSE_CANCEL / ClientFeatureDispatcher)。 +# 实际行为仍由服务端 handleStonemill 决定(加料研磨 / 玻璃罐取油罐 / 空手取面粉)。 +STONEMILL_BLOCKUSE = [ + {"item": GLASS_TANK_ITEM, "block": "rtdd:stonemill"}, # 玻璃罐取油罐 + {"item": SOYBEAN_ITEM, "block": "rtdd:stonemill"}, # 加黄豆研磨 + {"item": WHEAT_ITEM, "block": "rtdd:stonemill"}, # 加小麦研磨 +] + # ============================================================================ # 四B、手持厨具物品(七、手持厨具物品): 锅铲 <-> 带油锅铲, 油罐蘸油/上油炒锅 # 19. 锅铲(spatula) 右键油罐(oilcan) -> 带油锅铲(spatula_oil, 附魔光效), 油罐次数-1 diff --git a/behavior_pack_v8jz0zSR/Script_NeteaseModousIY5aSF/xiangyemod/chuju/service/ChujuService.py b/behavior_pack_v8jz0zSR/Script_NeteaseModousIY5aSF/xiangyemod/chuju/service/ChujuService.py index 8325f09..9a43818 100644 --- a/behavior_pack_v8jz0zSR/Script_NeteaseModousIY5aSF/xiangyemod/chuju/service/ChujuService.py +++ b/behavior_pack_v8jz0zSR/Script_NeteaseModousIY5aSF/xiangyemod/chuju/service/ChujuService.py @@ -547,7 +547,8 @@ class ChujuService(BlueFoxServerSystem): if prog is None or prog < 0: return False mat = self._readMillMat((x, y, z), dim) or "soybean" - ret = FLOUR_ITEM if mat == "wheat" else SOYBEAN_ITEM + # 打碎返还【放入的原料】(不是成品): 小麦返小麦, 黄豆返黄豆 + ret = WHEAT_ITEM if mat == "wheat" else SOYBEAN_ITEM count = WHEAT_COUNT if mat == "wheat" else SOYBEAN_COUNT # 有材料:额外掉落对应原料(石磨本体由默认破坏掉落) try: @@ -559,11 +560,17 @@ class ChujuService(BlueFoxServerSystem): return False def _handleStonemill(self, playerId, pos, dim, itemDict, itemName, key): - prog = self._readMill(pos, dim) # None=空, 0~3=研磨中, 4=完成 + prog = self._readMill(pos, dim) # None/负=空(未放料, 或已取走成品), 0~3=研磨中, 4=完成 mat = self._readMillMat(pos, dim) or "soybean" # 默认黄豆; 'wheat'=小麦 + # 空磨: prog 为 None(从未放料) 或 <0(_clearMill 取走成品后写成 -1) + isEmpty = prog is None or prog < 0 + # 研磨已完成: prog 达到 STONEMILL_GRIND_COUNT(4) + isComplete = prog is not None and prog >= STONEMILL_GRIND_COUNT - # ---- 空石磨 + 黄豆(16) 或 小麦(6) -> 加入 ---- - if prog is None: + # ---- 加入研磨材料: 仅空磨(从未放料, 或已取走成品后)。 ---- + # 完成态(prog=4)必须先取走成品(空手取面粉/玻璃罐取油罐)变回空磨, + # 然后才能手持 黄豆(16)/小麦(6) 重新放入开工。 + if isEmpty: if itemName == WHEAT_ITEM: if (itemDict.get("count") or 0) < WHEAT_COUNT: comp.CreateMsg(playerId).NotifyOneMessage( @@ -590,10 +597,12 @@ class ChujuService(BlueFoxServerSystem): comp.CreateMsg(playerId).NotifyOneMessage( playerId, "§a加入黄豆,空手右键研磨") return True - return False + # 空磨 + 空手: 无操作(交还默认); 完成态 + 手持非材料(玻璃罐/空手取粉) 不在此拦住 + if isEmpty and (not itemName or itemName == "minecraft:air"): + return False # ---- 研磨中: 空手右键旋转一次 ---- - if 0 <= prog < STONEMILL_GRIND_COUNT: + if prog is not None and 0 <= prog < STONEMILL_GRIND_COUNT: if itemName and itemName != "minecraft:air": return False if not self.checkCooldown(key, 0.5): @@ -610,8 +619,8 @@ class ChujuService(BlueFoxServerSystem): playerId, "§a研磨中,(%d/%d)" % (newProg, STONEMILL_GRIND_COUNT)) return True - # ---- 完成 ---- - if prog >= STONEMILL_GRIND_COUNT: + # ---- 完成: 取成品 ---- + if isComplete: if mat == "wheat": # 小麦已磨成面粉: 空手右键 -> 掉落 1 面粉 + 还原空 if itemName and itemName != "minecraft:air": diff --git a/behavior_pack_v8jz0zSR/Script_NeteaseModousIY5aSF/xiangyemod/service/FeatureDispatcher.py b/behavior_pack_v8jz0zSR/Script_NeteaseModousIY5aSF/xiangyemod/service/FeatureDispatcher.py index 6ce95b7..acdb16f 100644 --- a/behavior_pack_v8jz0zSR/Script_NeteaseModousIY5aSF/xiangyemod/service/FeatureDispatcher.py +++ b/behavior_pack_v8jz0zSR/Script_NeteaseModousIY5aSF/xiangyemod/service/FeatureDispatcher.py @@ -49,6 +49,9 @@ from ...BlueFoxTools.ModConfig import MOD_NAME # 它是"普通逻辑类"(自己不监听), 由本分发器实例化并把 ServerEntityDieEvent 转给它。 from ..siwangshengwu.service.DeadmobGeneratorService import DeadmobGeneratorService +# ---- 钓鱼掉落: 螃蟹/龙虾(普通逻辑类, 由本分发器转发 PlayerFishingServerEvent) ---- +from ..yuanbanfangzhi.service.YuanbanFishing import YuanbanFishingService + # ---- 汤锅盛出自定义事件名(与客户端 ClientFeatureDispatcher TAKEOUT_EVENT 一致) ---- TAKEOUT_EVENT = "TakeoutRequest" @@ -206,6 +209,7 @@ class FeatureDispatcher(BlueFoxServerSystem): print "===== FeatureDispatcher init =====" self._cancelItemUse = {} # 将要取消下一次物品使用的玩家ID集合(防止喝药水等) self._deadmobGen = DeadmobGeneratorService() # 死亡生物·生成引擎(杀猪牛羊等->尸体方块) + self._fishing = YuanbanFishingService() # 钓鱼掉落(螃蟹/龙虾) self.ListenEvent() def Destroy(self): @@ -675,25 +679,12 @@ class FeatureDispatcher(BlueFoxServerSystem): def OnFishing(self, args): """ - 玩家收杆时、钓鱼掉落物生成前触发(PlayerFishingServerEvent)。 - 让 螃蟹(rtdd:crab)/龙虾(rtdd:lobster) 直接作为"钓上来的物品": - 有几率把本次钓上来的东西【替换】成 螃蟹 或 龙虾 —— 不再像 After 事件那样 - 额外多掉一只, 更贴近原版"钓上来什么就是什么"。 - args.关键字段: playerId / hookEntity / itemList(本次钓上的物品列表, 生成前可改)。 - 概率(草稿, 可调): 螃蟹 10% / 龙虾 6%。 + 玩家钓鱼收杆时触发(PlayerFishingServerEvent)。 + 转给 原版放置·钓鱼掉落(YuanbanFishingService): 取消默认钓物并在鱼钩位置 + 生成 螃蟹/龙虾。 """ try: - playerId = args.get("playerId") - itemList = args.get("itemList") - if not playerId or not isinstance(itemList, list) or not itemList: - return - # 【测试用】概率 100%: 每次收杆都替换成 螃蟹/龙虾(50/50), 方便验证两者都能钓到。 - # 测试完请调回(如 螃蟹0.10 / 龙虾0.06)。 - if random.random() < 0.5: - sea = "rtdd:crab" - else: - sea = "rtdd:lobster" - args["itemList"] = [{"itemName": sea, "count": 1, "auxValue": 0}] + self._fishing.OnFishing(args) except Exception as e: print "[FD-OnFishing-ERR]", e diff --git a/behavior_pack_v8jz0zSR/Script_NeteaseModousIY5aSF/xiangyemod/service/InterceptData.py b/behavior_pack_v8jz0zSR/Script_NeteaseModousIY5aSF/xiangyemod/service/InterceptData.py index b3ec028..176114f 100644 --- a/behavior_pack_v8jz0zSR/Script_NeteaseModousIY5aSF/xiangyemod/service/InterceptData.py +++ b/behavior_pack_v8jz0zSR/Script_NeteaseModousIY5aSF/xiangyemod/service/InterceptData.py @@ -129,11 +129,13 @@ except Exception: pass # 厨具(炉灶/丸子机/石磨: 木条+炉灶 等): ChujuData.STOVE_RULES / MEATBALLMAKER_RULES +# / STEAMER_RULES / STONEMILL_BLOCKUSE try: from ..chuju.ChujuData import (STOVE_RULES as CHUJU_STOVE, MEATBALLMAKER_RULES as CHUJU_MEAT, - STEAMER_RULES as CHUJU_STEAM) - _BLOCK_USE_TABLES.extend([CHUJU_STOVE, CHUJU_MEAT, CHUJU_STEAM]) + STEAMER_RULES as CHUJU_STEAM, + STONEMILL_BLOCKUSE as CHUJU_MILL) + _BLOCK_USE_TABLES.extend([CHUJU_STOVE, CHUJU_MEAT, CHUJU_STEAM, CHUJU_MILL]) except Exception: pass diff --git a/behavior_pack_v8jz0zSR/Script_NeteaseModousIY5aSF/xiangyemod/yuanbanfangzhi/service/YuanbanFishing.py b/behavior_pack_v8jz0zSR/Script_NeteaseModousIY5aSF/xiangyemod/yuanbanfangzhi/service/YuanbanFishing.py new file mode 100644 index 0000000..05574c5 --- /dev/null +++ b/behavior_pack_v8jz0zSR/Script_NeteaseModousIY5aSF/xiangyemod/yuanbanfangzhi/service/YuanbanFishing.py @@ -0,0 +1,74 @@ +# -*- coding: utf-8 -*- +""" +================================================================================ +原版放置·钓鱼掉落(螃蟹/龙虾) +================================================================================ +给"螃蟹(rtdd:crab)/龙虾(rtdd:lobster)"提供钓鱼获取渠道: + 玩家收杆时(PlayerFishingServerEvent, 掉落物生成前)触发本类: + - 尝试把本次钓鱼的默认掉落取消(cancel=True), 避免原版鱼再出现; + - 直接在鱼钩位置生成 1 只 螃蟹/龙虾, 让"钓上来的是什么就是什么"。 + +【为什么是普通逻辑类、不监听事件】 + 全模组只有 FeatureDispatcher 监听游戏事件。本类不监听, 由 FeatureDispatcher + 实例化并在 PlayerFishingServerEvent 时把事件转发给本类 OnFishing。 + (与 siwangshengwu/DeadmobGeneratorService 同架构。) + +【概率】 + 现为测试用 100%(50/50 螃蟹/龙虾); 测试通过后请改回正式概率。 +================================================================================ +""" +import random +import mod.server.extraServerApi as serverApi + +comp = serverApi.GetEngineCompFactory() + +# ---- 只有方块/游戏相关才用 LevelId(这里 CreateItem 用玩家 id, 不依赖 LevelId) ---- +from ....BlueFoxTools.ToolsConfig import LevelId + + +class YuanbanFishingService(object): + """ + 钓鱼掉落·螃蟹/龙虾(逻辑类, 由 FeatureDispatcher 实例化并转发事件) + """ + + def __init__(self): + print "===== YuanbanFishingService 钓鱼掉落(螃蟹/龙虾)已挂载 =====" + + def OnFishing(self, args): + """ + PlayerFishingServerEvent(收杆时、掉落物生成前): + 取消默认钓物 + 在鱼钩位置生成螃蟹/龙虾。 + args 关键字段: playerId(玩家) / hookEntity(鱼钩实体id)。 + """ + try: + playerId = args.get("playerId") + if not playerId: + return + # 正式概率: 螃蟹 10% / 龙虾 6% + roll = random.random() + if roll < 0.10: + sea = "rtdd:crab" + elif roll < 0.16: + sea = "rtdd:lobster" + else: + return # 未命中: 不取消默认, 保持原版钓鱼出原版物品 + # 命中才取消默认鱼/杂物掉落, 避免"原版鱼+螃蟹"两只 + args["cancel"] = True + pos = self._spawnPos(playerId, args.get("hookEntity")) + dim = comp.CreateDimension(playerId).GetEntityDimensionId() + comp.CreateItem(playerId).SpawnItemToLevel( + {"itemName": sea, "count": 1, "auxValue": 0}, dim, pos) + print "[YBFishing] 钓到 %s at %s" % (sea, pos) + except Exception as e: + print "[YBFishing-ERR]", e + + def _spawnPos(self, playerId, hookId): + """生成位置: 优先鱼钩位置, 取不到再用玩家脚下""" + if hookId: + try: + p = comp.CreatePos(hookId).GetFootPos() + return (p[0], p[1], p[2]) + except Exception: + pass + foot = comp.CreatePos(playerId).GetFootPos() + return (foot[0], foot[1] + 0.5, foot[2]) \ No newline at end of file diff --git a/behavior_pack_v8jz0zSR/netease_recipes/xy_bamboo_0.json b/behavior_pack_v8jz0zSR/netease_recipes/xy_bamboo_0.json new file mode 100644 index 0000000..aa96c0d --- /dev/null +++ b/behavior_pack_v8jz0zSR/netease_recipes/xy_bamboo_0.json @@ -0,0 +1,25 @@ +{ + "format_version": "1.12", + "minecraft:recipe_shaped": { + "key": { + "0": { + "item": "minecraft:bamboo", + "data": 0 + } + }, + "description": { + "identifier": "rtdd:xy_bamboo_0" + }, + "pattern": [ + "000" + ], + "result": { + "data": 0, + "item": "rtdd:bamboo_0", + "count": 1 + }, + "tags": [ + "crafting_table" + ] + } +} \ No newline at end of file diff --git a/behavior_pack_v8jz0zSR/netease_recipes/xy_meathook.json b/behavior_pack_v8jz0zSR/netease_recipes/xy_meathook.json new file mode 100644 index 0000000..eb6687e --- /dev/null +++ b/behavior_pack_v8jz0zSR/netease_recipes/xy_meathook.json @@ -0,0 +1,30 @@ +{ + "format_version": "1.12", + "minecraft:recipe_shaped": { + "key": { + "1": { + "item": "rtdd:support_rod", + "data": 0 + }, + "0": { + "item": "minecraft:iron_ingot", + "data": 0 + } + }, + "description": { + "identifier": "rtdd:xy_meathook" + }, + "pattern": [ + "1", + "0" + ], + "result": { + "data": 0, + "item": "rtdd:meathook", + "count": 1 + }, + "tags": [ + "crafting_table" + ] + } +} \ No newline at end of file diff --git a/behavior_pack_v8jz0zSR/netease_recipes/xy_firewood_plank.json b/behavior_pack_v8jz0zSR/netease_recipes/xy_woodstick_stonecut.json similarity index 67% rename from behavior_pack_v8jz0zSR/netease_recipes/xy_firewood_plank.json rename to behavior_pack_v8jz0zSR/netease_recipes/xy_woodstick_stonecut.json index 0ba2604..6a41012 100644 --- a/behavior_pack_v8jz0zSR/netease_recipes/xy_firewood_plank.json +++ b/behavior_pack_v8jz0zSR/netease_recipes/xy_woodstick_stonecut.json @@ -3,20 +3,20 @@ "minecraft:recipe_shapeless": { "ingredients": [ { - "item": "rtdd:firewood", + "tag": "minecraft:logs", "data": 0 } ], "description": { - "identifier": "rtdd:xy_firewood_plank" + "identifier": "rtdd:xy_woodstick_stonecut" }, "result": { "data": 0, "item": "rtdd:b_15", - "count": 9 + "count": 2 }, "tags": [ - "crafting_table" + "stonecutter" ] } } \ No newline at end of file diff --git a/resource_pack_Are13Lvd/entity/minecraft_villager_v2.json b/resource_pack_Are13Lvd/entity/minecraft_villager_v2.json new file mode 100644 index 0000000..cdaee33 --- /dev/null +++ b/resource_pack_Are13Lvd/entity/minecraft_villager_v2.json @@ -0,0 +1,89 @@ +{ + "format_version": "1.8.0", + "minecraft:client_entity": { + "description": { + "animation_controllers": [ + { + "general": "controller.animation.villager_v2.general" + }, + { + "move": "controller.animation.villager_v2.move" + }, + { + "raise_arms": "controller.animation.villager_v2.raise_arms" + }, + { + "baby": "controller.animation.villager_v2.baby" + } + ], + "animations": { + "baby_transform": "animation.villager.baby_transform", + "general": "animation.villager.general", + "get_in_bed": "animation.villager.get_in_bed", + "look_at_target": "animation.common.look_at_target", + "move": "animation.villager.move", + "raise_arms": "animation.villager.raise_arms" + }, + "geometry": { + "default": "geometry.villager_v2" + }, + "identifier": "minecraft:villager_v2", + "materials": { + "default": "villager_v2", + "masked": "villager_v2_masked" + }, + "render_controllers": [ + "controller.render.villager_v2_base", + "controller.render.villager_v2_masked", + "controller.render.villager_v2_level" + ], + "scripts": { + "pre_animation": [ + "variable.num_professions = 15;", + "variable.num_tiers = 3;", + "variable.profession_index = (query.variant < variable.num_professions ? query.variant : 0);", + "variable.level_index = query.trade_tier;" + ], + "scale": "0.9375" + }, + "spawn_egg": { + "texture": "spawn_egg_villager" + }, + "textures": { + "armorer": "textures/entity/villager2/professions/armorer", + "base": "textures/entity/villager2/villager", + "base2": "textures/entity/villager2/villager", + "base3": "textures/entity/villager2/villager", + "base4": "textures/entity/villager2/villager", + "base5": "textures/entity/villager2/villager", + "base6": "textures/entity/villager2/villager", + "butcher": "textures/entity/villager2/professions/butcher", + "cartographer": "textures/entity/villager2/professions/cartographer", + "cleric": "textures/entity/villager2/professions/cleric", + "desert": "textures/entity/villager2/biomes/biome_desert", + "farmer": "textures/entity/villager2/professions/farmer", + "fisherman": "textures/entity/villager2/professions/fisherman", + "fletcher": "textures/entity/villager2/professions/fletcher", + "jungle": "textures/entity/villager2/biomes/biome_jungle", + "leatherworker": "textures/entity/villager2/professions/leatherworker", + "level_diamond": "textures/entity/villager2/levels/level_diamond", + "level_emerald": "textures/entity/villager2/levels/level_emerald", + "level_gold": "textures/entity/villager2/levels/level_gold", + "level_iron": "textures/entity/villager2/levels/level_iron", + "level_stone": "textures/entity/villager2/levels/level_stone", + "librarian": "textures/entity/villager2/professions/librarian", + "nitwit": "textures/entity/villager2/professions/nitwit", + "plains": "textures/entity/villager2/biomes/biome_plains", + "savanna": "textures/entity/villager2/biomes/biome_savanna", + "shepherd": "textures/entity/villager2/professions/shepherd", + "snow": "textures/entity/villager2/biomes/biome_snow", + "stonemason": "textures/entity/villager2/professions/stonemason", + "swamp": "textures/entity/villager2/biomes/biome_swamp", + "taiga": "textures/entity/villager2/biomes/biome_taiga", + "tool_smith": "textures/entity/villager2/professions/toolsmith", + "unskilled": "textures/entity/villager2/professions/unskilled", + "weapon_smith": "textures/entity/villager2/professions/weaponsmith" + } + } + } +} \ No newline at end of file diff --git a/tuilun/ok/厨具转化关系.txt b/tuilun/ok/厨具转化关系.txt index 6dd84e0..f2f9148 100644 --- a/tuilun/ok/厨具转化关系.txt +++ b/tuilun/ok/厨具转化关系.txt @@ -100,7 +100,7 @@ (脏盘子可放水槽清洗, 见 家具家私转化关系.txt 水槽) ======================================== -六、石磨 (stonemill, 磨黄豆 -> 玻璃罐装 -> 油罐) +六、石磨 (stonemill, 磨黄豆->油罐 或 磨小麦->面粉) ======================================== 15. stonemill(空) + 黄豆 -> 加入黄豆 转换条件:[手持 黄豆(rtdd:soybean, 乡野食材) 右键 进行转换] @@ -114,6 +114,24 @@ 转换条件:[手持 玻璃罐(rtdd:medicinetank) 右键 进行转换] 机制: 研磨完成后, 手持玻璃罐右键取出, 消耗1个玻璃罐, 获得 油罐(oilcan), 石磨回空态 +17a. stonemill(空) + 小麦 -> 加入小麦 +转换条件:[手持 小麦(minecraft:wheat, 原版) 右键 进行转换] +机制: 手持小麦右键石磨, 消耗6个, 加入小麦 + +17b. 加入小麦 -> 研磨中(旋转) -> 研磨完成 +转换条件:[右键 进行转换(研磨)] +机制: 同黄豆: 右键研磨, 每次转90度, 四次完成 + +17c. 研磨完成(小麦) -> 石磨(空) + 面粉 +转换条件:[空手 右键 进行转换(取出)] +机制: 研磨完成后空手右键取出, 获得 1个 面粉(rtdd:farineblcok, 面食小麦·面团组起点), + 石磨回空态 + +17d. 磨小麦/磨黄豆 共用打碎返还 +转换条件:[左键打碎 石磨 释放转换] +机制: 研磨中或已完成未取时, 打碎石磨 返还【放入的原料】: 磨小麦返 6 小麦, + 磨黄豆返 16 黄豆(石磨本体照常掉落); 空石磨不返还。 + 18. oilcan(油罐) 取油耗尽 -> medicinetank(玻璃罐) 转换条件:[油罐 取油使用次数扣到0] 机制: 油罐的油被取光(被锅铲取油16次)后, 变回 玻璃罐(medicinetank) diff --git a/tuilun/全部功能做了什么.txt b/tuilun/全部功能做了什么.txt index 57ba918..abf7cab 100644 --- a/tuilun/全部功能做了什么.txt +++ b/tuilun/全部功能做了什么.txt @@ -438,7 +438,7 @@ FurnitureData+FurnitureService 实现, 注册到 FeatureDispatcher) - 稻谷(rice_seeds): 分类 xy_ingredients → xy_natural, 从 乡野食材/谷物·米面(ingr_08_grain) 移入 乡野自然/水稻·作物(nat_03_crop) [已调整] - 乡野自然转化关系.txt: 把新加的 todo 全部转正为正式规则并标【待实现】: - 果树"树苗成长"机制、葡萄藤取葡萄(4a)、柴火分解9木条(5b)、水稻成熟取16大米(7a) [已整理] + 果树"树苗成长"机制、葡萄藤取葡萄(4a)、柴火分解9木条(5b, 现已改切石机获得木条)、水稻成熟取16大米(7a) [已整理] - 乡野食材转化关系.txt: 移除 稻谷 条目(谷物·米面 只留 大米/生面) [已整理] - 上述待实现功能已记录到 全部功能没做什么.txt 乡野自然 节 @@ -457,10 +457,10 @@ FurnitureData+FurnitureService 实现, 注册到 FeatureDispatcher) - 生长: grapebushes_1 计时180秒 -> grapebushes_2 [已实现] - 取葡萄: grapebushes_2 空手右键 -> 掉落3个葡萄(grape) + 变回 grapebushes_1 [已实现] -三、柴火 (堆叠/取用 + 工作台分解) +三、柴火 (堆叠/取用) - 堆叠: firewood_2(柴火_2) + 手持柴火右键 -> firewood(柴火_1 堆放, 消耗1) [已实现] - 取用: firewood(堆放) 空手右键 -> firewood_2 + 返还1柴火 [已实现] -- 分解: firewood 工作台 -> 9个木条(b_15) (配方 xy_firewood_plank) [已实现] +- 木条(b_15) 改为 切石机获得: 任意原木(minecraft:logs) x1 -> 木条 x2 (配方 xy_woodstick_stonecut) [已调整] 四、水稻 (种植 + 生长 + 收获) - 种植: 手持稻谷(rice_seeds) 右键原版耕地(farmland) -> 耕地上方放置 水稻刚种下(riceseedlingsb) [已实现] @@ -1097,3 +1097,93 @@ FurnitureData+FurnitureService 实现, 注册到 FeatureDispatcher) 【待验证】网易事件参数名(entityId/attackedByEntId)、实体类型枚举名在不同版本可能不同, 需进游戏验证; 若类型判定不准, 改用实体类型字符串接口再调。 + +######################################## +【生存模式获取渠道补齐】2026-09-24 +######################################## +目的: 给"无任何获取渠道"的食材/工具补来源。此前盘点过 4 分类无渠道物品: + 食材(青菜/葱/大蒜/辣椒/螃蟹/龙虾/桃子/橙子)、面食(面粉/竹筒)、寿司(干海带)、 + 死亡生物(挂肉钩)。本轮完成: 村民交易/石磨磨面/竹筒·挂肉钩配方/钓鱼掉落。 + +一、村民交易(傻子职业卖乡野食材) —— 解决 青菜/葱/大蒜/辣椒/桃子/橙子/干海带 +- 新建 交易表 trading/xiangye_farmer_trades.json(网易自定义交易表正确目录为 trading/, + 非 trading/economy_trades/): + 7 笔交易, 单一品质全解锁, 玩家花 绿宝石 买, 价格: 干海带2 / 青菜1(量3) / + 葱1(量3) / 大蒜2(量2) / 辣椒2(量2) / 桃子2 / 橙子2 (max_uses 64)。 +- 在 entities/minecraft_villager_v2.json 的 傻子(nitwit) 职业组件组(约1510行) 加 + minecraft:economy_trade_table, table 指向 trading/xiangye_farmer_trades.json。 + 当初的坑: 交易表误放 trading/economy_trades/ 导致编辑器交易列表空 → 改回 trading/ 后正常。 +- 覆盖傻子职业因原版傻子本无交易(开不了交易界面), 故不挤掉任何原版有用交易。 + +二、石磨磨小麦→面粉 —— 解决 面粉(整棵面食树根源) +- 在厨具包内(未新建包): ChujuData.py 加 WHEAT_ITEM/小麦/面粉常量, + ChujuService.py 石磨(_handleStonemill)分材料处理: + 黄豆(16) → 研磨4次 → 玻璃罐取油罐(原逻辑不变) + 小麦(6) → 研磨4次 → 空手取出 1 面粉(rtdd:farineblcok) + 打碎按材料返还(返面粉原料=小麦6; 返黄豆16); 材料标识存方块实体 rtdd_stm。 + +三、竹筒 配方 —— 解决 竹筒(竹筒饭原料) +- 新增 netease_recipes/xy_bamboo_0.json: 3 原版竹子 → 1 竹筒(rtdd:bamboo_0)。 + +四、挂肉钩 配方 —— 解决 挂肉钩(切肉/挂鱼核心) +- 新增 netease_recipes/xy_meathook.json: 支撑杆(support_rod) + 铁锭 → 1 挂肉钩。 + +五、螃蟹/龙虾 钓鱼掉落 —— 解决 螃蟹/龙虾 +- 新建 yuanbanfangzhi/service/YuanbanFishing.py(普通逻辑类 YuanbanFishingService, + 照 deadmobGen 架构, 逻辑不在分发器内联)。 +- FeatureDispatcher 导入并实例化 self._fishing, 监听 PlayerFishingServerEvent(收杆、 + 掉落物生成前) 转发到 _fishing.OnFishing: + 先 args["cancel"]=True 取消默认钓物(避免原版鱼再出现), + 再在鱼钩位置 SpawnItemToLevel 生成 1 只 螃蟹/龙虾(测试用100%,50/50)。 +- 【待验证】PlayerFishingServerEvent 的 cancel 是否生效需进游戏实测; + 若 cancel 不生效(仍出原版鱼), 需改用"覆盖钓鱼掉落表 loot_tables/gameplay/fishing/" + 方案。正式概率待定(草稿: 螃蟹10% / 龙虾6%), 测试完调回。 + +######################################## +【死亡生物尸体生成修复 + 黄豆打草移位 + 榨汁机/石磨消闪 + 石磨复用】2026-09-24 +######################################## + +一、死亡生物·尸体方块生成(玩家杀 猪/牛/羊/鱿鱼/村民 → 死亡位置生成尸体方块) +- DeadmobGeneratorService.py 改为【普通逻辑类】(不再继承 BlueFoxServerSystem 自监听), + 由 FeatureDispatcher 在自身 __init__ 实例化 self._deadmobGen 并监听死亡事件转发。 + 起因: 新类按原架构(继承 BlueFoxServerSystem)无法被框架 GetLastSubclass 注册实例化, + 日志里连 init 都没有。 +- 死亡事件用 MobDieEvent(官方文档: 参数 id=死亡实体, attacker=击杀者, cause=伤害来源), + 不是 ServerEntityDieEvent(该 SDK 里不存在)。 +- 类型判断改 GetEngineTypeStr() 精确匹配: + minecraft:pig→dead_pig / cow→dead_cow / sheep→dead_sheep / squid→deadsquida / + villager(+villager_v2)→dead_villager。 +- 远程击杀: attacker 若是抛射物(箭等), 用 CreateBulletAttributes(attacker).GetSourceEntityId() + 取发射者, 发射者是玩家才计为玩家击杀。 +- 生成延迟: 死亡后 1.5 秒才放尸体方块(comp.CreateGame(LevelId).AddTimer), 不刚死瞬间出现。 +- 死亡 cause 过滤: 只有 cause∈{entity_attack(近战), projectile(远程)} 才生成; + 排除 /kill/指令(self_destruct) 及摔/溺/火等一切非玩家攻击的死亡。 + +二、黄豆打草掉黄豆 移回 乡野食材(Shicai) +- 从死亡生物包移走(职责不应在死亡生物): + 常量 SOYBEAN_ITEM / GRASS_DROP_CHANCE=0.15 / GRASS_BLOCKS → ShicaiData.py + 掉落方法 handleGrassDrop → ShicaiService.py, __init__ 里 FeatureDispatcher.registerGrassDrop(self) +- FeatureDispatcher.OnDestroy 顶部先试 grassDropOwners 的路由: 草/杂草 概率掉黄豆, + 不取消破坏本身(与打草掉小麦种子一致)。 + +三、榨汁机 玻璃杯/水果 右键 消闪 +- YinliaoData.py 新增 GLASS_CUP(=rtdd:fruitjuice_0 玻璃杯) + JUICER_BLOCKUSE + (玻璃杯 + 6 水果 × 榨汁机 6 状态 全组合)。 +- InterceptData.py 把 JUICER_BLOCKUSE 并入 _BLOCK_USE_TABLES → 自动派生进 BLOCKUSE_CANCEL, + 客户端提前 ret 放置预览 + Notify BlockUseRequest, 消闪。 +- 注意: 榨汁机取汁走 BlockUse(右击方块)通道, 不能标 action==take_out + (否则会被 BLOCKUSE_CANCEL 派生过滤掉; 且与汤锅/炒锅/油锅的盛出 ItemUseOn 通道不同)。 + +四、石磨(厨具) 两处修复 +- 玻璃罐/黄豆/小麦 右键石磨 消闪: + ChujuData.py 新增 STONEMILL_BLOCKUSE = [(玻璃罐 rtdd:medicinetank, 石磨), + (黄豆 rtdd:soybean, 石磨), (小麦 minecraft:wheat, 石磨)]; + InterceptData.py 把 STONEMILL_BLOCKUSE 并入厨具 _BLOCK_USE_TABLES → BLOCKUSE_CANCEL 消闪。 +- 研磨完成后可再次放料(先取成品再放): ChujuService._handleStonemill 空磨判定 + 由 prog is None 扩为 prog is None 或 prog<0 —— 取走成品后 _clearMill 把进度写成 + -1(非 None), 否则取完仍进不了"可加入材料"分支(已修)。 + 修正: 只有"空磨"(从未放料 或 已取走成品) 才能放料开工; + 完成态(prog=4)必须先取走成品(小麦空手取面粉 / 黄豆玻璃罐取油罐)变回空磨, + 之后才能手持 黄豆(16)/小麦(6) 重新放入再开一轮研磨。 +- 待实测: /kill 后 cause 是否为 self_destruct、村民实际类型串是否为 villager_v2。 + diff --git a/tuilun/配方整理汇总.txt b/tuilun/配方整理汇总.txt index 59adb13..fd5bc30 100644 --- a/tuilun/配方整理汇总.txt +++ b/tuilun/配方整理汇总.txt @@ -185,7 +185,7 @@ ● 箭桶(arrowbarrel_0)【有序 · 单格】 云杉活板门 【空】 【空】 -● 木条(b_15) x9【无序】:柴火堆_1 x1 -> 木条 x9 +● 木条(b_15) x2【切石机·无序】:任意原木(logs) x1 -> 木条 x2 ● 竹栏(bamboomeshfence)【有序】 竹子 竹子 竹子 竹子 竹子 竹子