# -*- 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