Files
xczjhk/behavior_pack_kcH4M5u0/Script_dn_sa/matchboxServer.py
T
2026-10-09 18:23:57 +08:00

89 lines
3.5 KiB
Python

# -*- coding: utf-8 -*-
#
# 火柴盒:点击方块消耗一点耐久并点燃地面,共20点耐久(对齐Java版sa_core火柴盒=打火石)
import mod.server.extraServerApi as serverApi
compFactory = serverApi.GetEngineCompFactory()
MATCHBOX_ID = "dn_sa:matchbox"
# 需要监听右键的原版方块(地面及常见方块),aux 用 * 匹配所有附加值
LISTEN_BLOCKS = [
"minecraft:grass_block:*",
"minecraft:dirt:*",
"minecraft:coarse_dirt:*",
"minecraft:podzol:*",
"minecraft:mycelium:*",
"minecraft:moss_block:*",
"minecraft:mud:*",
"minecraft:stone:*",
"minecraft:cobblestone:*",
"minecraft:mossy_cobblestone:*",
"minecraft:gravel:*",
"minecraft:sand:*",
"minecraft:sandstone:*",
"minecraft:clay:*",
"minecraft:snow_layer:*",
"minecraft:dirt_path:*",
"minecraft:netherrack:*",
"minecraft:end_stone:*",
"minecraft:obsidian:*",
"minecraft:log:*",
"minecraft:log2:*",
"minecraft:planks:*",
"minecraft:stone_bricks:*",
"minecraft:bricks:*",
"minecraft:terracotta:*",
]
# 点击方块面 -> 火焰放置位置偏移(Facing枚举:0下 1上 2北 3南 4西 5东)
FACE_OFFSETS = {
0: (0, -1, 0),
1: (0, 1, 0),
2: (0, 0, -1),
3: (0, 0, 1),
4: (-1, 0, 0),
5: (1, 0, 0),
}
class MatchboxServer(serverApi.GetServerSystemCls()):
def __init__(self, namespace, name):
super(MatchboxServer, self).__init__(namespace, name)
self.levelId = serverApi.GetLevelId()
self.ListenForEvent(serverApi.GetEngineNamespace(), serverApi.GetEngineSystemName(),
"ServerBlockUseEvent", self, self.OnBlockUse)
self.ListenForEvent(serverApi.GetEngineNamespace(), serverApi.GetEngineSystemName(),
"LoadServerAddonScriptsAfter", self, self.OnLoadAddon)
def OnLoadAddon(self, args):
# 注册原版方块对ServerBlockUseEvent的监听
whitelistComp = compFactory.CreateBlockUseEventWhiteList(self.levelId)
for blockName in LISTEN_BLOCKS:
whitelistComp.AddBlockItemListenForUseEvent(blockName)
def OnBlockUse(self, args):
playerId = args.get("playerId")
itemDict = args.get("itemDict") or {}
if itemDict.get("itemName") != MATCHBOX_ID:
return
# 检查主手火柴盒耐久,耐久为0时无法点燃
itemComp = compFactory.CreateItem(playerId)
carried = serverApi.GetMinecraftEnum().ItemPosType.CARRIED
durability = itemComp.GetItemDurability(carried, 0)
if durability <= 0:
return
# 计算点击面外的火焰放置位置
offset = FACE_OFFSETS.get(args.get("face", 1), (0, 1, 0))
firePos = (args["x"] + offset[0], args["y"] + offset[1], args["z"] + offset[2])
dimensionId = args.get("dimensionId")
# 获取目标位置方块(GetBlockNew 属于 CreateBlockInfo 组件)
blockInfoComp = compFactory.CreateBlockInfo(self.levelId)
curBlock = blockInfoComp.GetBlockNew(firePos, dimensionId)
if curBlock is not None and curBlock.get("name") == "minecraft:air":
# 目标位置为空气,放置火焰并消耗一点耐久,拦截该方块的交互逻辑(如同打火石)
# SetBlockNew 同属 CreateBlockInfo 组件
blockInfoComp.SetBlockNew(firePos, {"name": "minecraft:fire", "aux": 0}, 0, dimensionId)
itemComp.SetItemDurability(carried, 0, durability - 1)
args["cancel"] = True