冰棍盒机制改成同炒冰盒

This commit is contained in:
wenhe committed 2026-09-30 12:24:15 +08:00
1 parent 80ff9340f8
commit 61c7c71016
10 files changed
+23 -268

No files matched your search

@@ -12,7 +12,6 @@ from xiangyemod.shichangmaoyi.service.MarketService import MarketService
from xiangyemod.yuanbanfangzhi.service.YuanbanService import YuanbanService from xiangyemod.yuanbanfangzhi.service.YuanbanService import YuanbanService
from xiangyemod.jiaju.service.FurnitureService import FurnitureService from xiangyemod.jiaju.service.FurnitureService import FurnitureService
from xiangyemod.yinliao.service.YinliaoService import YinliaoService from xiangyemod.yinliao.service.YinliaoService import YinliaoService
from xiangyemod.yinliao.service.YinliaoTimerService import YinliaoTimerService
from xiangyemod.chuju.service.ChujuService import ChujuService from xiangyemod.chuju.service.ChujuService import ChujuService
from xiangyemod.chuju.service.ChujuTimerService import ChujuTimerService from xiangyemod.chuju.service.ChujuTimerService import ChujuTimerService
from xiangyemod.ziran.service.NaturalService import NaturalService from xiangyemod.ziran.service.NaturalService import NaturalService
@@ -195,11 +195,10 @@ class FeatureDispatcher(BlueFoxServerSystem):
def startTimerFor(cls, blockName, dim, pos, playerId=None): def startTimerFor(cls, blockName, dim, pos, playerId=None):
""" """
右键服务调用:把"计时源方块"的计时启动任务转发给对应的计时服务。 右键服务调用:把"计时源方块"的计时启动任务转发给对应的计时服务。
- 例如:烧烤右键"烤鸡(生)"开始烤制;动物装满饲料盆后自动开始变空计时; - 例如:烧烤右键"烤鸡(生)"开始烤制;动物装满饲料盆后自动开始变空计时
饮料冰棍盒手持冰块右键未定型启动定型计时
- 内部通过 timerOwner 路由表 O(1) 找到计时服务,调它的 startTimer, - 内部通过 timerOwner 路由表 O(1) 找到计时服务,调它的 startTimer,
并返回计时服务的实际返回值: 并返回计时服务的实际返回值:
True = 本次真正启动了计时(如饮料冰棍盒据此消耗冰块) True = 本次真正启动了计时
False = 没有计时服务 / 该方块已在计时中(不重复启动) False = 没有计时服务 / 该方块已在计时中(不重复启动)
""" """
service = cls.timerOwner.get(blockName) service = cls.timerOwner.get(blockName)
@@ -4,7 +4,7 @@
乡野饮料(xy_drink)转化规则数据 乡野饮料(xy_drink)转化规则数据
================================================================================ ================================================================================
所有"乡野饮料"(xy_drink) 分类下的转化规则常量都在这里。 所有"乡野饮料"(xy_drink) 分类下的转化规则常量都在这里。
只被 YinliaoService / YinliaoTimerService 读取,FeatureDispatcher 通过方块名/物品名 只被 YinliaoService 读取,FeatureDispatcher 通过方块名/物品名
集合路由到对应服务,不会去查其他功能的数据库。 集合路由到对应服务,不会去查其他功能的数据库。
【三大分组】 【三大分组】
@@ -12,7 +12,7 @@
果汁由第一步放入的水果决定并【持久化到方块实体数据】, 退出游戏重进后 果汁由第一步放入的水果决定并【持久化到方块实体数据】, 退出游戏重进后
榨汁完成仍取回正确果汁(详见 YinliaoService._readFruit / _writeFruit)。 榨汁完成仍取回正确果汁(详见 YinliaoService._readFruit / _writeFruit)。
2) 冰棍(冰棍盒 icelollybox_1/2 + 各水果盒 icelollyboxb~f) 2) 冰棍(冰棍盒 icelollybox_1/2 + 各水果盒 icelollyboxb~f)
未定型 → (手持冰块右键启动) 计时30秒 → 定型 → (手持水果x2) → 各水果盒 未定型 → (手持冰块右键) 立即定型 → (手持水果x2) → 各水果盒
→ (空手右键) 取出2根冰棍, 还原未定型。 → (空手右键) 取出2根冰棍, 还原未定型。
冰棍堆 popsiclepile_2/3: 组合式(苹果冰棍+堆 → 堆2, 空手取回 LIFO)。 冰棍堆 popsiclepile_2/3: 组合式(苹果冰棍+堆 → 堆2, 空手取回 LIFO)。
3) 冰棍盒·炒冰盒(frytheicebox / frytheicebox_1 + 各水果炒冰盒) 3) 冰棍盒·炒冰盒(frytheicebox / frytheicebox_1 + 各水果炒冰盒)
@@ -86,13 +86,11 @@ for _it in [GLASS_CUP] + list(JUICE_FRUITS.keys()):
# ============================================================================ # ============================================================================
# 三、冰棍盒(冰棍) # 三、冰棍盒(冰棍)
# ============================================================================ # ============================================================================
# 冰棍盒(未定型) icelollybox_1 → 冰棍盒(定型) icelollybox_2 的计时规则: # 冰棍盒(未定型) icelollybox_1 → 冰棍盒(定型) icelollybox_2 的直接转换规则:
# 手持冰块右键启动(消耗1个冰块), 约30秒定型; autoStart=False 不自动开始 # 手持冰块(广义的冰)右键未定型, 消耗1个冰块, 立即定型(不计时, 与炒冰盒放冰同机制)
ICE_LOLLY_TIMER = { ICE_LOLLY_FREEZE = {
"source": "rtdd:icelollybox_1", "source": "rtdd:icelollybox_1",
"target": "rtdd:icelollybox_2", "target": "rtdd:icelollybox_2",
"time": 30,
"autoStart": False,
} }
# 水果物品名 → (各水果冰棍盒, 冰棍方块, 口味名) # 水果物品名 → (各水果冰棍盒, 冰棍方块, 口味名)
@@ -2,9 +2,9 @@
""" """
乡野饮料客户端(预留) 乡野饮料客户端(预留)
===================== =====================
目前乡野饮料功能的服务端逻辑已由 YinliaoService + YinliaoTimerService 处理, 目前乡野饮料功能的服务端逻辑已由 YinliaoService 处理,
客户端暂不需要额外的 UI 工作。 客户端暂不需要额外的 UI 工作。
如果以后需要榨汁进度提示、冰棍定型倒计时等 UI,可以在这里扩展。 如果以后需要榨汁进度提示等 UI,可以在这里扩展。
""" """
import mod.client.extraClientApi as clientApi import mod.client.extraClientApi as clientApi
@@ -12,7 +12,7 @@
换态(SetBlockNew 会清空方块实体)都【先读旧→替换→写回新】, 因此玩家 换态(SetBlockNew 会清空方块实体)都【先读旧→替换→写回新】, 因此玩家
在 榨汁2→榨汁3 过程中退出游戏, 重进后取出的果汁仍是第一步放入的水果。 在 榨汁2→榨汁3 过程中退出游戏, 重进后取出的果汁仍是第一步放入的水果。
2) 冰棍盒(冰棍): 2) 冰棍盒(冰棍):
未定型(icelollybox_1) + 冰块 → 启动30秒定型计时(转发给计时服务, 消耗1冰) 未定型(icelollybox_1) + 冰块 → 立即定型(消耗1冰, 与炒冰盒放冰同机制)
定型(icelollybox_2) + 水果x2 → 各水果冰棍盒(icelollyboxb~f) 定型(icelollybox_2) + 水果x2 → 各水果冰棍盒(icelollyboxb~f)
各水果冰棍盒 空手右键 → 取出2根冰棍, 还原未定型 各水果冰棍盒 空手右键 → 取出2根冰棍, 还原未定型
3) 炒冰盒(冰棍盒·炒冰盒): 3) 炒冰盒(冰棍盒·炒冰盒):
@@ -26,11 +26,6 @@
空手右键: 冰棍堆2 取出 苹果冰棍 → 退回 冰棍堆; 空手右键: 冰棍堆2 取出 苹果冰棍 → 退回 冰棍堆;
冰棍堆 取出 西瓜冰棍 → 变回 单根橙子冰棍 冰棍堆 取出 西瓜冰棍 → 变回 单根橙子冰棍
【与计时转换解耦】
冰棍盒"未定型→定型"的 30 秒计时拆到独立类 YinliaoTimerService。
本类右键到计时源方块(icelollybox_1 + 冰块)时, 调 FeatureDispatcher.startTimerFor
转发给计时服务启动(冰块消耗由本类处理)。
【事件监听在哪?】 【事件监听在哪?】
本类【不】监听任何事件! 本类【不】监听任何事件!
所有事件由 FeatureDispatcher 统一监听, 按 blockOwner 路由到本类 handleBlockUse。 所有事件由 FeatureDispatcher 统一监听, 按 blockOwner 路由到本类 handleBlockUse。
@@ -39,7 +34,7 @@
handleBlockUse ← 入口:分发器转发右键方块事件 handleBlockUse ← 入口:分发器转发右键方块事件
├─ _handleJuicer ← 榨汁机: 放入水果/逐级榨汁/手持玻璃杯取出果汁 ├─ _handleJuicer ← 榨汁机: 放入水果/逐级榨汁/手持玻璃杯取出果汁
│ ├─ _readFruit / _writeFruit ← 水果类型 读/写(持久化) │ ├─ _readFruit / _writeFruit ← 水果类型 读/写(持久化)
├─ _handleLollyBox ← 冰棍盒: 加冰块(启动计时)/加水果/取冰棍 ├─ _handleLollyBox ← 冰棍盒: 加冰块(立即定型)/加水果/取冰棍
├─ _handleFryIceBox ← 炒冰盒: 加冰块/加水果/取冰沙 ├─ _handleFryIceBox ← 炒冰盒: 加冰块/加水果/取冰沙
└─ _handlePopsiclePile ← 冰棍堆: 单根+另一根叠堆/插苹果冰棍/空手取回 └─ _handlePopsiclePile ← 冰棍堆: 单根+另一根叠堆/插苹果冰棍/空手取回
(通用工具) getCarriedItem / consumeItem / replaceBlock / dropItems / checkCooldown (通用工具) getCarriedItem / consumeItem / replaceBlock / dropItems / checkCooldown
@@ -65,7 +60,7 @@ gameComp = comp.CreateGame(LevelId)
from ..YinliaoData import ( from ..YinliaoData import (
ICE_ITEMS, ICE_ITEMS,
JUICE_FRUITS, JUICER_CHAIN, JUICER_ADVANCE_TIPS, JUICE_FRUITS, JUICER_CHAIN, JUICER_ADVANCE_TIPS,
ICE_LOLLY_TIMER, POPSICLE_FRUITS, POPSICLE_BOX_INFO, ICE_LOLLY_FREEZE, POPSICLE_FRUITS, POPSICLE_BOX_INFO,
POPSICLE_SINGLE_ORANGE, POPSICLE_SINGLE_MELON, POPSICLE_SINGLE_ORANGE, POPSICLE_SINGLE_MELON,
POPSICLE_PILE_ADD, POPSICLE_PILE_2, POPSICLE_PILE_3, POPSICLE_PILE_ADD, POPSICLE_PILE_2, POPSICLE_PILE_3,
FRYICE_FRUITS, FRYICE_BOX_INFO, FRYICE_FRUITS, FRYICE_BOX_INFO,
@@ -211,21 +206,18 @@ class YinliaoService(BlueFoxServerSystem):
return False return False
# ============================================================================ # ============================================================================
# 三、冰棍盒(加冰块启动定型计时 / 加水果 / 取冰棍) # 三、冰棍盒(加冰块定型 / 加水果 / 取冰棍)
# ============================================================================ # ============================================================================
def _handleLollyBox(self, blockName, playerId, pos, dim, itemDict, itemName, key): def _handleLollyBox(self, blockName, playerId, pos, dim, itemDict, itemName, key):
# ---- 未定型 + 冰块 → 启动30秒定型计时(消耗1块冰) ---- # ---- 未定型 + 冰块 → 立即定型(消耗1块冰, 与炒冰盒放冰同机制) ----
if blockName == "rtdd:icelollybox_1": if blockName == ICE_LOLLY_FREEZE["source"]:
if itemName not in ICE_ITEMS: if itemName not in ICE_ITEMS:
return False return False
if not self.checkCooldown(key, 0.5): if not self.checkCooldown(key, 0.5):
return True return True
# 转发给计时服务: True=本次启动, False=已在定型中(不重复消耗冰块)
started = FeatureDispatcher.startTimerFor(blockName, dim, pos, playerId)
if not started:
return True # 已在定型中, 拦截但不消耗
self.consumeItem(playerId, itemDict, 1) self.consumeItem(playerId, itemDict, 1)
self.replaceBlock(pos, dim, ICE_LOLLY_FREEZE["target"], playerId)
return True return True
# ---- 定型 + 水果x2 → 各水果冰棍盒 ---- # ---- 定型 + 水果x2 → 各水果冰棍盒 ----
@@ -1,232 +0,0 @@
# -*- coding: utf-8 -*-
"""
================================================================================
乡野饮料·计时转换引擎(服务端)
================================================================================
只处理"乡野饮料"(xy_drink) 分类下的【计时自动转换】:
冰棍盒(未定型 icelollybox_1) → 冰棍盒(定型 icelollybox_2) 约30秒
【与右键转换解耦】
同分类的"右键切换"(榨汁/冰棍盒加水果/炒冰盒/冰棍堆)在 YinliaoService。
本类只负责计时,两者通过 FeatureDispatcher 协作:
- YinliaoService 手持冰块右键 未定型 → 调 FeatureDispatcher.startTimerFor
转发到本类的 startTimer 启动定型计时(冰块消耗由右键服务处理)
- 服务器 tick(ServerBlockEntityTickEvent)由 FeatureDispatcher 按 timerOwner
路由到本类的 handleBlockEntityTick,到点即转换为 定型
【计时怎么做到"退出游戏继续计时"】
不做倒计时,只记"开始时刻":
- 启动时把 开始时间戳(rtdd_tstart)+总时长(rtdd_tdur) 写进方块实体数据
- 每帧 tick 判断 当前时间-开始时刻 >= 总时长 → 到点转换
- 时间戳是绝对时间(time.time()),服务器重启/玩家离线,真实时间仍在流逝,
回来后 tick 直接算差值,剩余时间自然准确
【事件监听在哪?】
本类【不】监听任何事件!
ServerBlockEntityTickEvent 由 FeatureDispatcher 统一监听,再按 timerOwner
路由到本类的 handleBlockEntityTick。
【本类怎么做(自上而下的方法系列)】
handleBlockEntityTick ← 入口:分发器转发 tick 事件
└─ _tickProcess ← 判断是否到点 / autoStart=False 不自动补写
└─ _finishTimer ← 到点执行转换 + 完成提示
startTimer ← 入口:YinliaoService 转发过来启动定型
└─ _writeTimerData ← 写 开始时刻+时长+启动者 到方块实体
_clearTimerData ← 清理方块上的计时数据
================================================================================
"""
import time
import mod.server.extraServerApi as serverApi
# ---- 网易API基础对象 ----
ServerSystem = serverApi.GetServerSystemCls() # 服务端系统基类
comp = serverApi.GetEngineCompFactory() # 组件工厂
# ---- 继承 BlueFox 框架的系统基类 ----
from ....BlueFoxTools.SpecialFunciton.BlueFoxSystem import BlueFoxServerSystem
from ....BlueFoxTools.ToolsConfig import LevelId
# ---- 方块实体数据组件(计时持久化:把开始时间戳+时长写进方块,重启后继续计时) ----
blockEntityDataComp = comp.CreateBlockEntityData(LevelId)
# ---- 只导入乡野饮料自己的数据库 ----
from ..YinliaoData import ICE_LOLLY_TIMER
# ---- 统一分发器(本类把自己注册进计时路由表,让分发器把 tick 事件转发过来) ----
from ...service.FeatureDispatcher import FeatureDispatcher
class YinliaoTimerService(BlueFoxServerSystem):
"""
乡野饮料·计时转换引擎
【核心数据结构】
iceLollyTimers = {计时源方块名: 规则dict} # 目前只有 冰棍盒未定型
"""
def __init__(self, namespace, systemName):
super(YinliaoTimerService, self).__init__(namespace, systemName)
print "===== YinliaoTimerService init ====="
# ---- 收集计时型规则(source → 规则) ----
self.iceLollyTimers = {ICE_LOLLY_TIMER["source"]: ICE_LOLLY_TIMER}
# ---- 注册到分发器的计时路由表(tick 事件按方块名路由到这里) ----
FeatureDispatcher.registerTimer(self)
# ============================================================================
# 一、给 FeatureDispatcher 的接口
# ============================================================================
def getTimerBlocks(self):
"""返回本功能的所有"计时源方块"集合(tick 路由用)"""
return set(self.iceLollyTimers.keys())
def handleBlockEntityTick(self, args):
"""由 FeatureDispatcher 转发的计时方块 tick 入口"""
dim = args.get("dimension")
pos = (args.get("posX"), args.get("posY"), args.get("posZ"))
blockName = args.get("blockName", "")
self._tickProcess(dim, pos, blockName)
# ============================================================================
# 二、定型计时启动(YinliaoService 手持冰块右键未定型后转发调用)
# ============================================================================
def startTimer(self, dim, pos, blockName, playerId=None):
"""
启动定型计时:把 开始时间戳+时长 写入方块实体数据。
返回 True = 本次真正启动(右键服务据此消耗冰块)
返回 False = 已在定型中 / 无规则(不重复消耗)
"""
recipe = self.iceLollyTimers.get(blockName)
if not recipe:
return False
# 去重:如果该方块已经在本规则计时中,不重置(保持原剩余时间)
try:
data = blockEntityDataComp.GetBlockEntityData(dim, pos)
if data and data["rtdd_tid"] == blockName:
return False
except Exception:
pass
self._writeTimerData(dim, pos, recipe, playerId)
return True
# ============================================================================
# 三、tick 检查与到点转换
# ============================================================================
def _tickProcess(self, dim, pos, blockName):
"""
tick 主逻辑:
1) 按事件自带的当前方块名判断是否计时源
2) 是计时源但没有计时数据 → 只有 autoStart=True 才自动补写。
冰棍盒定型 autoStart=False:必须右键(放冰块)激活, 这里不补写
3) 有计时数据 → 到点执行转换(重启后时间戳照常生效)
注意:GetBlockEntityData 返回的对象不支持 .get(),统一用 [] 读取。
"""
try:
recipe = self.iceLollyTimers.get(blockName)
if not recipe:
return # 当前方块不是计时源
blockData = blockEntityDataComp.GetBlockEntityData(dim, pos)
if blockData is None:
return
try:
tid = blockData["rtdd_tid"]
except Exception:
tid = ""
if tid != blockName:
# 冰棍盒必须右键(放冰块)激活定型: autoStart=False 时不自动补写计时
if recipe.get("autoStart", True):
self._writeTimerData(dim, pos, recipe, None)
return
tstart = blockData["rtdd_tstart"]
tdur = blockData["rtdd_tdur"]
if time.time() - tstart >= tdur:
self._finishTimer(dim, pos, recipe, blockData)
except Exception:
pass
def _finishTimer(self, dim, pos, recipe, data):
"""计时到点:确认方块仍是计时源,才执行转换并清除计时数据"""
try:
cur = comp.CreateBlockInfo(LevelId).GetBlockNew(pos, dim)
if cur and cur.get("name") != recipe["source"]:
# 方块已被玩家改变 → 清掉过期计时
self._clearTimerData(dim, pos)
return
# 替换方块为定型
self.replaceBlock(pos, dim, recipe["target"], None)
self._clearTimerData(dim, pos)
except Exception:
pass
# ============================================================================
# 四、计时数据读写(存在方块实体数据里,重启不丢)
# ============================================================================
def _writeTimerData(self, dim, pos, recipe, playerId=None):
"""把 计时标识+开始时刻+时长+启动者 写进方块实体数据"""
try:
blockData = blockEntityDataComp.GetBlockEntityData(dim, pos)
if blockData is None:
return
now = time.time()
blockData["rtdd_tid"] = recipe["source"]
blockData["rtdd_tstart"] = now
blockData["rtdd_tdur"] = recipe.get("time", 60)
blockData["rtdd_tp"] = playerId if playerId else ""
except Exception:
pass
def _clearTimerData(self, dim, pos):
"""清除方块上的计时数据"""
try:
blockData = blockEntityDataComp.GetBlockEntityData(dim, pos)
if blockData is None:
return
blockData["rtdd_tid"] = ""
blockData["rtdd_tstart"] = 0
blockData["rtdd_tdur"] = 0
blockData["rtdd_tp"] = ""
except Exception:
pass
# ============================================================================
# 五、工具方法:完成提示
# ============================================================================
def _notifyIfOnline(self, playerId, tip):
"""若启动者在线,发送完成提示(离线则跳过)"""
if not tip or not playerId:
return
try:
ids = comp.CreateGame(LevelId).GetAllPlayerIds()
if playerId in ids:
comp.CreateMsg(playerId).NotifyOneMessage(playerId, tip)
except Exception:
pass
# ============================================================================
# 六、工具方法:替换方块
# ============================================================================
def replaceBlock(self, pos, dim, newBlockName, 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)
@@ -48,7 +48,7 @@
"netease:block_entity": { "netease:block_entity": {
"client_tick": false, "client_tick": false,
"movable": false, "movable": false,
"tick": true "tick": false
} }
} }
} }
+1 -1
View File
@@ -744,7 +744,7 @@ tile.rtdd:cookingscallions.name=炒锅_51(葱花锅底)
tile.rtdd:codsushi_6.name=鳕鱼寿司块(三个) tile.rtdd:codsushi_6.name=鳕鱼寿司块(三个)
tile.rtdd:codsushi_4.name=鳕鱼寿司(卷_3) tile.rtdd:codsushi_4.name=鳕鱼寿司(卷_3)
tile.rtdd:codsushi_5.name=鳕鱼寿司(卷_4) tile.rtdd:codsushi_5.name=鳕鱼寿司(卷_4)
tile.rtdd:barbecuegrill_1.name=烧烤架_2(烧烤架点燃) tile.rtdd:barbecuegrill_1.name=点燃的烧烤架
tile.rtdd:codsushi_2.name=鳕鱼寿司(卷_1) tile.rtdd:codsushi_2.name=鳕鱼寿司(卷_1)
tile.rtdd:codsushi_3.name=鳕鱼寿司(卷_2) tile.rtdd:codsushi_3.name=鳕鱼寿司(卷_2)
tile.rtdd:fishbucket_1.name=鳕鱼货桶 tile.rtdd:fishbucket_1.name=鳕鱼货桶
+2 -2
View File
@@ -49,9 +49,9 @@ todo 功能实现的时候需要考虑 玩家退出游戏后 我的步骤已经
======================================== ========================================
二、冰棍(冰棍盒系列) 二、冰棍(冰棍盒系列)
======================================== ========================================
7. 冰棍盒(冰棍未定型) -> 冰棍盒(冰棍定型) 7. 冰棍盒 -> 冰棍盒(冰棍定型)
转换条件:[手持 原版冰块[广义的冰] 右键 进行转换, 消耗1个] 转换条件:[手持 原版冰块[广义的冰] 右键 进行转换, 消耗1个]
机制: 手持冰块右键冰棍盒(未定型), 消耗1个, 计时约30秒定型 机制: 手持冰块右键冰棍盒, 消耗1个
8. 冰棍盒(冰棍定型) -> 冰棍盒(苹果/桃子/橙子/葡萄/西瓜冰棍) 8. 冰棍盒(冰棍定型) -> 冰棍盒(苹果/桃子/橙子/葡萄/西瓜冰棍)
转换条件:[手持 对应水果 右键 进行转换, 消耗2个] 转换条件:[手持 对应水果 右键 进行转换, 消耗2个]
+3 -4
View File
@@ -282,7 +282,7 @@ FurnitureData+FurnitureService 实现, 注册到 FeatureDispatcher)
######################################## ########################################
【乡野饮料】(xy_drink) 2026-09-04 【乡野饮料】(xy_drink) 2026-09-04
######################################## ########################################
实现于 xiangyemod/yinliao (YinliaoData + YinliaoService + YinliaoTimerService, 注册到 FeatureDispatcher) 实现于 xiangyemod/yinliao (YinliaoData + YinliaoService, 注册到 FeatureDispatcher)
一、榨汁机 (果汁·榨汁饮品, juicer 系列, 全流程右键) 一、榨汁机 (果汁·榨汁饮品, juicer 系列, 全流程右键)
- 空(juicer) + 水果(消耗1) → 放入水果(juicer_0), 并把水果类型写入方块实体数据(rtdd_jf) [已实现] - 空(juicer) + 水果(消耗1) → 放入水果(juicer_0), 并把水果类型写入方块实体数据(rtdd_jf) [已实现]
@@ -295,11 +295,10 @@ FurnitureData+FurnitureService 实现, 注册到 FeatureDispatcher)
- 黄豆(rtdd:soybean) 物品已从Java版迁入(物品/纹理/名称齐全) [已实现] - 黄豆(rtdd:soybean) 物品已从Java版迁入(物品/纹理/名称齐全) [已实现]
二、冰棍盒 (冰棍, icelollybox 系列) 二、冰棍盒 (冰棍, icelollybox 系列)
- 未定型(icelollybox_1) + 冰块(消耗1, 原版冰/冰砖/蓝冰/霜冰) → 启动30秒定型计时 - 未定型(icelollybox_1) + 冰块(消耗1, 原版冰/冰砖/蓝冰/霜冰) → 立即定型(不计时, 与炒冰盒放冰同机制)
(autoStart=False, 右键激活; 已在定型中不重复消耗) → 定型(icelollybox_2) [已实现] → 定型(icelollybox_2) [已实现]
- 定型 + 对应水果(消耗2) → 各口味冰棍盒(icelollyboxb 橙子/c 苹果/d 桃子/e 葡萄/f 西瓜) [已实现] - 定型 + 对应水果(消耗2) → 各口味冰棍盒(icelollyboxb 橙子/c 苹果/d 桃子/e 葡萄/f 西瓜) [已实现]
- 各口味冰棍盒 空手右键 → 掉落2根对应冰棍 + 还原未定型 [已实现] - 各口味冰棍盒 空手右键 → 掉落2根对应冰棍 + 还原未定型 [已实现]
- 定型计时用绝对时间戳写方块实体数据, 退出重进继续计时 [已实现]
三、冰棍堆 (组合, 顺序无关, 空手取回按方块状态固定, 不存数据) 三、冰棍堆 (组合, 顺序无关, 空手取回按方块状态固定, 不存数据)
- 单根 橙子冰棍/西瓜冰棍 放地上 + 手持另一根右键(消耗1) → 冰棍堆(橙子+西瓜 popsiclepile_2) - 单根 橙子冰棍/西瓜冰棍 放地上 + 手持另一根右键(消耗1) → 冰棍堆(橙子+西瓜 popsiclepile_2)