提供物品放置方块功能
This commit is contained in:
1 parent
e65cebaec1
commit
43c1859aad
8 files changed
+190
-6
No files matched your search
@@ -27,6 +27,7 @@ from xiangyemod.tangguo.service.TangguoTimerService import TangguoTimerService
|
|||||||
from xiangyemod.chaoguo.service.ChaoguoService import ChaoguoService
|
from xiangyemod.chaoguo.service.ChaoguoService import ChaoguoService
|
||||||
from xiangyemod.chaoguo.service.ChaoguoTimerService import ChaoguoTimerService
|
from xiangyemod.chaoguo.service.ChaoguoTimerService import ChaoguoTimerService
|
||||||
from xiangyemod.shiyongfood.service.ShiyongfoodService import ShiyongfoodService
|
from xiangyemod.shiyongfood.service.ShiyongfoodService import ShiyongfoodService
|
||||||
|
from xiangyemod.placeblock.service.PlaceBlockService import PlaceBlockService
|
||||||
|
|
||||||
if not serverApi.IsInServer():
|
if not serverApi.IsInServer():
|
||||||
# 客户端进程: 导入客户端拦截系统(继承 BlueFoxClientSystem, 框架自动注册),
|
# 客户端进程: 导入客户端拦截系统(继承 BlueFoxClientSystem, 框架自动注册),
|
||||||
|
|||||||
@@ -619,7 +619,7 @@ SWITCH_RULES = [
|
|||||||
|
|
||||||
# 盖饭转换清单(正向+反向共用): dish=成品菜, target=盖饭
|
# 盖饭转换清单(正向+反向共用): dish=成品菜, target=盖饭
|
||||||
GAI_FAN_ITEMS = [
|
GAI_FAN_ITEMS = [
|
||||||
{"dish": PLATE_47, "target": PLATE_48,
|
{"dish": PLATE_47, "target": PLATE_48, "giveItem": PLATE_48,
|
||||||
"name": "辣子鸡丁", "gaiName": "辣子鸡丁盖饭(全份)"},
|
"name": "辣子鸡丁", "gaiName": "辣子鸡丁盖饭(全份)"},
|
||||||
{"dish": PLATE_54, "target": PLATE_55,
|
{"dish": PLATE_54, "target": PLATE_55,
|
||||||
"name": "香菇滑鸡", "gaiName": "香菇滑鸡盖饭(全份)"},
|
"name": "香菇滑鸡", "gaiName": "香菇滑鸡盖饭(全份)"},
|
||||||
@@ -635,16 +635,17 @@ for _g in GAI_FAN_ITEMS:
|
|||||||
_target = _g["target"]
|
_target = _g["target"]
|
||||||
_name = _g["name"]
|
_name = _g["name"]
|
||||||
_gai = _g["gaiName"]
|
_gai = _g["gaiName"]
|
||||||
|
_give = _g.get("giveItem") # 给定则"被点方块消失 + 给玩家物品", 否则原位替换成 target 方块
|
||||||
# 正向: 手持成品菜 右键 米饭(三形态任一) -> 米饭变盖饭
|
# 正向: 手持成品菜 右键 米饭(三形态任一) -> 米饭变盖饭
|
||||||
for _rice in RICE_FORMS:
|
for _rice in RICE_FORMS:
|
||||||
ITEM_USE_ON_RULES.append({
|
ITEM_USE_ON_RULES.append({
|
||||||
"item": _dish, "surface": _rice, "target": _target, "consume": 1,
|
"item": _dish, "surface": _rice, "target": _target, "consume": 1,
|
||||||
"tip": None})
|
"giveItem": _give, "tip": None})
|
||||||
# 反向: 手持 米饭(三形态任一) 右键 成品菜 -> 菜品变盖饭
|
# 反向: 手持 米饭(三形态任一) 右键 成品菜 -> 菜品变盖饭
|
||||||
for _rice in RICE_FORMS:
|
for _rice in RICE_FORMS:
|
||||||
ITEM_USE_ON_RULES.append({
|
ITEM_USE_ON_RULES.append({
|
||||||
"item": _rice, "surface": _dish, "target": _target, "consume": 1,
|
"item": _rice, "surface": _dish, "target": _target, "consume": 1,
|
||||||
"tip": None})
|
"giveItem": _give, "tip": None})
|
||||||
# 蛋炒饭 加米饭(形态1/2/3都行) -> 炒锅_87(蛋炒饭_加米饭_熟)
|
# 蛋炒饭 加米饭(形态1/2/3都行) -> 炒锅_87(蛋炒饭_加米饭_熟)
|
||||||
for _rice in RICE_FORMS:
|
for _rice in RICE_FORMS:
|
||||||
ITEM_USE_ON_RULES.append({
|
ITEM_USE_ON_RULES.append({
|
||||||
|
|||||||
+7
-1
@@ -198,7 +198,13 @@ class ChaoguoService(BlueFoxServerSystem):
|
|||||||
self.consumeItem(playerId, itemDict, consume)
|
self.consumeItem(playerId, itemDict, consume)
|
||||||
|
|
||||||
# 替换被右键的表面方块(米饭变盖饭 / 菜品变盖饭 / 蛋炒饭变熟)
|
# 替换被右键的表面方块(米饭变盖饭 / 菜品变盖饭 / 蛋炒饭变熟)
|
||||||
self.replaceBlock(pos, dim, recipe["target"], playerId)
|
# giveItem: 新成品菜体系 —— 被点方块消失, 改为给玩家"成品菜物品"(可再放置出对应方块)
|
||||||
|
giveItem = recipe.get("giveItem")
|
||||||
|
if giveItem:
|
||||||
|
self.replaceBlock(pos, dim, "minecraft:air", playerId)
|
||||||
|
self.giveItemToPlayer(playerId, giveItem, 1, pos, dim)
|
||||||
|
else:
|
||||||
|
self.replaceBlock(pos, dim, recipe["target"], playerId)
|
||||||
self._clearWokData(dim, pos)
|
self._clearWokData(dim, pos)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
+165
@@ -0,0 +1,165 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
================================================================================
|
||||||
|
【物品放置方块】(placeblock) 服务 —— 创造栏显示 2D 物品图标, 放置出指定方块模型
|
||||||
|
================================================================================
|
||||||
|
背景: 网易 1.10 自定义物品不支持 minecraft:block_placer(实测"放不下去");
|
||||||
|
原版 1.21.60 物品虽能 block_placer, 但其 menu_category 只能进原版分页,
|
||||||
|
进不了网易自定义分页(如 xy_finished)。两者无法兼得。
|
||||||
|
方案A(脚本补位): 方块本体 register_to_creative_menu:false 不出现在创造栏;
|
||||||
|
另建带 2D 图标、category 指向自定义分页的网易 1.10 物品(分页正确);
|
||||||
|
手持该物品右键任意方块 -> 在被点面的相邻格放置对应方块, 消耗 1 个
|
||||||
|
(创造模式不消耗)。
|
||||||
|
|
||||||
|
路由: 走 FeatureDispatcher 的 itemUseOn(itemName -> 服务), 与其它转换服务同机制。
|
||||||
|
================================================================================
|
||||||
|
"""
|
||||||
|
import time
|
||||||
|
import mod.server.extraServerApi as serverApi
|
||||||
|
|
||||||
|
ServerSystem = serverApi.GetServerSystemCls() # 服务端系统基类
|
||||||
|
comp = serverApi.GetEngineCompFactory() # 组件工厂
|
||||||
|
|
||||||
|
from ....BlueFoxTools.SpecialFunciton.BlueFoxSystem import BlueFoxServerSystem
|
||||||
|
from ....BlueFoxTools.ToolsConfig import LevelId
|
||||||
|
from ...service.FeatureDispatcher import FeatureDispatcher, FACE_OFFSET
|
||||||
|
|
||||||
|
# ---- 物品 -> 放置出的方块(要新增的成品菜在这里登记) ----
|
||||||
|
PLACE_ITEMS = {
|
||||||
|
"rtdd:plate_48": "rtdd:plate_48_block",
|
||||||
|
}
|
||||||
|
|
||||||
|
# ---- 视为"可放置"的目标方块(空气/水) ----
|
||||||
|
AIR_LIKE = ("minecraft:air", "minecraft:water", "minecraft:flowing_water")
|
||||||
|
|
||||||
|
# ---- 同一玩家两次放置的最小间隔(秒, 防连点重复放置) ----
|
||||||
|
PLACE_COOLDOWN = 0.2
|
||||||
|
|
||||||
|
# ---- 朝向微调: 0=方块正面朝玩家视线方向; 2=方块正面朝玩家(视线反方向, 与正常摆放一致) ----
|
||||||
|
FACING_FLIP = 0
|
||||||
|
|
||||||
|
|
||||||
|
class PlaceBlockService(BlueFoxServerSystem):
|
||||||
|
"""物品放置方块服务(创造栏 2D 图标 -> 放置 3D 方块)"""
|
||||||
|
|
||||||
|
def __init__(self, namespace, systemName):
|
||||||
|
BlueFoxServerSystem.__init__(self, namespace, systemName)
|
||||||
|
self.itemBlocks = dict(PLACE_ITEMS)
|
||||||
|
self.cooldown = {}
|
||||||
|
FeatureDispatcher.register(self)
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
# 分发器路由表(FeatureDispatcher 调用)
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
def getFeatureBlocks(self):
|
||||||
|
"""本服务不接管任何"右键方块", 只处理 itemUseOn"""
|
||||||
|
return []
|
||||||
|
|
||||||
|
def getItemUseOnRules(self):
|
||||||
|
"""手持放置物品右键方块表面 -> 由本服务处理"""
|
||||||
|
return {item: True for item in self.itemBlocks}
|
||||||
|
|
||||||
|
def ownsItemUseOn(self, itemName, clickedName):
|
||||||
|
"""声明本服务明确处理这些物品的 itemUseOn(不受被点方块归属影响)"""
|
||||||
|
return itemName in self.itemBlocks
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
# 入口: 手持放置物品右键方块 -> 在相邻格放置方块 + 消耗1
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
def handleItemUseOn(self, args):
|
||||||
|
itemName = args.get("itemName")
|
||||||
|
blockName = self.itemBlocks.get(itemName)
|
||||||
|
if not blockName:
|
||||||
|
return False
|
||||||
|
playerId = args.get("playerId") or args.get("entityId")
|
||||||
|
if not playerId:
|
||||||
|
return False
|
||||||
|
# 冷却: 防连点重复放置
|
||||||
|
now = time.time()
|
||||||
|
if now - self.cooldown.get(playerId, 0) < PLACE_COOLDOWN:
|
||||||
|
return True
|
||||||
|
self.cooldown[playerId] = now
|
||||||
|
|
||||||
|
x, y, z = args.get("x"), args.get("y"), args.get("z")
|
||||||
|
face = args.get("face", 1)
|
||||||
|
if x is None or y is None or z is None:
|
||||||
|
return False
|
||||||
|
dim = args.get("dimensionId")
|
||||||
|
if dim is None:
|
||||||
|
try:
|
||||||
|
dim = comp.CreateDimension(playerId).GetEntityDimensionId()
|
||||||
|
except Exception:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 落点 = 被点方块相邻的那一格(0下 1上 2北 3南 4西 5东)
|
||||||
|
off = FACE_OFFSET.get(face, (0, 1, 0))
|
||||||
|
target = (x + off[0], y + off[1], z + off[2])
|
||||||
|
|
||||||
|
# 目标位置必须是空气/水, 否则不放置(交还原版)
|
||||||
|
try:
|
||||||
|
b = comp.CreateBlockInfo(LevelId).GetBlockNew(target, dim)
|
||||||
|
name = b.get("name") if b else None
|
||||||
|
if name not in AIR_LIKE:
|
||||||
|
return False
|
||||||
|
except Exception:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 放置方块(朝向按玩家水平朝向, 与正常摆放一致)
|
||||||
|
try:
|
||||||
|
aux = self._facingAux(playerId)
|
||||||
|
ok = comp.CreateBlockInfo(LevelId).SetBlockNew(
|
||||||
|
target, blockDict={"name": blockName, "aux": aux},
|
||||||
|
oldBlockHandling=0, dimensionId=dim)
|
||||||
|
except Exception:
|
||||||
|
ok = False
|
||||||
|
if not ok:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 消耗 1 个(创造模式不消耗)
|
||||||
|
if not self._isCreative(playerId):
|
||||||
|
self._consumeOne(playerId, itemName)
|
||||||
|
return True
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
# 工具
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
def _facingAux(self, playerId):
|
||||||
|
"""
|
||||||
|
netease:face_directional(type=direction) 的朝向值:
|
||||||
|
0=南(+Z) 1=西(-X) 2=北(-Z) 3=东(+X)
|
||||||
|
按玩家水平朝向(视线方向)取值; 若方向相反/偏移, 调 FACING_FLIP。
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
rot = comp.CreateRot(playerId).GetRot()
|
||||||
|
dx, _dy, dz = serverApi.GetDirFromRot(rot)
|
||||||
|
if abs(dx) >= abs(dz):
|
||||||
|
face = 3 if dx > 0 else 1 # +X 东 / -X 西
|
||||||
|
else:
|
||||||
|
face = 0 if dz > 0 else 2 # +Z 南 / -Z 北
|
||||||
|
except Exception:
|
||||||
|
face = 0
|
||||||
|
# 与正常摆放一致的微调: 方块"正面"朝向玩家(视线反方向)时改为 face+2
|
||||||
|
return (face + FACING_FLIP) % 4
|
||||||
|
|
||||||
|
def _isCreative(self, playerId):
|
||||||
|
try:
|
||||||
|
return comp.CreateGame(LevelId).GetPlayerGameType(playerId) == 1
|
||||||
|
except Exception:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def _consumeOne(self, playerId, itemName):
|
||||||
|
try:
|
||||||
|
itemComp = comp.CreateItem(playerId)
|
||||||
|
carried = itemComp.GetPlayerItem(
|
||||||
|
serverApi.GetMinecraftEnum().ItemPosType.CARRIED, 0, True)
|
||||||
|
if not carried or carried.get("newItemName") != itemName:
|
||||||
|
return
|
||||||
|
count = carried.get("count", 1)
|
||||||
|
itemComp.SetEntityItem(
|
||||||
|
serverApi.GetMinecraftEnum().ItemPosType.CARRIED,
|
||||||
|
{"itemName": itemName,
|
||||||
|
"count": max(count - 1, 0),
|
||||||
|
"auxValue": carried.get("newAuxValue", 0),
|
||||||
|
"userData": carried.get("userData", {})})
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
+10
-1
@@ -451,7 +451,16 @@ EAT_ITEMS = {
|
|||||||
"rtdd:beancurd", # 豆腐
|
"rtdd:beancurd", # 豆腐
|
||||||
}
|
}
|
||||||
|
|
||||||
ITEM_USE_ON_CANCEL_BY_ITEM = PLACE_ITEMS | EAT_ITEMS
|
# ---- 方案A: 物品放置方块 (placeblock) ----
|
||||||
|
# 手持该物品右键任意方块表面 -> 客户端 ret 掉默认行为并显式 ItemUseOnRequest,
|
||||||
|
# 服务端 PlaceBlockService.handleItemUseOn 负责在被点面相邻格放置对应方块。
|
||||||
|
# (原版 1.21 物品的 block_placer 可用但只能进原版分页; 网易 1.10 物品能进自定义
|
||||||
|
# 分页但不支持 block_placer, 故用脚本放置, 两者兼得。)
|
||||||
|
PLACE_BLOCK_ITEMS = {
|
||||||
|
"rtdd:plate_48",
|
||||||
|
}
|
||||||
|
|
||||||
|
ITEM_USE_ON_CANCEL_BY_ITEM = PLACE_ITEMS | EAT_ITEMS | PLACE_BLOCK_ITEMS
|
||||||
|
|
||||||
|
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
|
|||||||
+1
-1
@@ -206,7 +206,7 @@ EAT_RULES = [
|
|||||||
{"block": "rtdd:cookedpancake", "hunger": 9,
|
{"block": "rtdd:cookedpancake", "hunger": 9,
|
||||||
"effects": [("saturation", 30, 1), ("resistance", 30, 1)]},
|
"effects": [("saturation", 30, 1), ("resistance", 30, 1)]},
|
||||||
# 盖饭
|
# 盖饭
|
||||||
{"block": "rtdd:plate_48", "target": "rtdd:plate_48a", "hunger": 9,
|
{"block": "rtdd:plate_48_block", "target": "rtdd:plate_48a", "hunger": 9,
|
||||||
"effects": [("regeneration", 20, 2), ("health_boost", 60, 4)]},
|
"effects": [("regeneration", 20, 2), ("health_boost", 60, 4)]},
|
||||||
{"block": "rtdd:plate_48a", "hunger": 8, "drop": PLATE_DIRTY},
|
{"block": "rtdd:plate_48a", "hunger": 8, "drop": PLATE_DIRTY},
|
||||||
{"block": "rtdd:plate_55", "target": "rtdd:plate_55a", "hunger": 9,
|
{"block": "rtdd:plate_55", "target": "rtdd:plate_55a", "hunger": 9,
|
||||||
|
|||||||
Reference in new issue
Block a user