# Minecraft Fabric Modding - Events ## Event 是甚麼? Event 中文直翻「事件」,即是遊戲中的所有事件,通常搭配 Mixin 做偵測,並做出一些反應。例如:拿剪刀剪羊毛掉出鑽石、把物品丟到水裡會爆炸...等 ## 實作 - 鑽石丟到水中會爆炸 ### Call Back Interface 此 interface 需要有 Event 的實作以及回應函數 ```java= 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 ```java= @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 ```java= 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 最後把函數放到主程式就完成囉! ```java= ModEvents.registerEvents(); ``` ## 參考資料 [Fabric Wiki - Custom Events](https://fabricmc.net/wiki/tutorial:events) --- ###### tags: `Minecraft Fabric Modding`