Try   HackMD

Minecraft Fabric Modding - Events

Event 是甚麼?

Event 中文直翻「事件」,即是遊戲中的所有事件,通常搭配 Mixin 做偵測,並做出一些反應。例如:拿剪刀剪羊毛掉出鑽石、把物品丟到水裡會爆炸

實作 - 鑽石丟到水中會爆炸

Call Back Interface

此 interface 需要有 Event 的實作以及回應函數

public interface ItemEntityInWaterCallBack { Event<ItemEntityInWaterCallBack> EVENT = EventFactory.createArrayBacked(ItemEntityInWaterCallBack.class, listeners -> itemEntity -> { for (ItemEntityInWaterCallBack listener : listeners) { ActionResult result = listener.interact(itemEntity); if(result != ActionResult.PASS) return result; } return ActionResult.PASS; }); ActionResult interact(ItemEntity itemEntity); }
  • 這個 Event 需要被偵測的有一個 ItemEntity,因此在 interact() 函數中加入 ItemEntity 的參數

Mixin

@Mixin(ItemEntity.class) public abstract class ItemEntityTickMixin extends Entity { public ItemEntityTickMixin(EntityType<?> type, World world) { super(type, world); } @Shadow public abstract ItemEntity copy(); @Inject(method = "tick", at = @At(value = "HEAD"), cancellable = true) public void tick(CallbackInfo info) { ItemEntityInWaterCallBack.EVENT.invoker().interact(copy()); } }
  • 因為需要 @Shadow,請將 class 及函數加上 abstract 修飾

Register Event

public class ModEvents { public static void registerEvents() { ItemEntityInWaterCallBack.EVENT.register(itemEntity -> { World world = itemEntity.getWorld(); if (!world.isClient() && itemEntity.getStack().getItem() == Items.DIAMOND && world.getBlockState(new BlockPos(itemEntity.getPos())).getBlock() == Blocks.WATER) { float power = 1 + Math.floorDiv(itemEntity.getStack().getCount(), 8); world.createExplosion(itemEntity, DamageSource.explosion(new Explosion(world, itemEntity, itemEntity.getX(), itemEntity.getY(), itemEntity.getZ(), power)), new ExplosionBehavior(), itemEntity.getX(), itemEntity.getY(), itemEntity.getZ(), power, false, Explosion.DestructionType.BREAK); ((ServerWorld) world).spawnParticles(ParticleTypes.EXPLOSION, itemEntity.getX(), itemEntity.getY(), itemEntity.getZ(), (int) power, 2, 2, 2, 1); itemEntity.kill(); return ActionResult.SUCCESS; } else return ActionResult.FAIL; }); } }

Register at Initializer

最後把函數放到主程式就完成囉!

ModEvents.registerEvents();

參考資料

Fabric Wiki - Custom Events


tags: Minecraft Fabric Modding