目次
概要
Minecraft Forgeの機能を利用してバニラの動作に新しい処理を追加します。今回は爆発処理、地形破壊処理、チャット処理及びMOBのスポーン処理についてイベントを設定します。
動作確認
2023年12月13日
- Minecraft 1.19.4
- Forge 45.2.0
解説
ExampleTNTHooks.java
ExampleTNT/src/main/java/com/tntmodders/exampletnt/ExampleTNTHooks.java
package com.tntmodders.exampletnt;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.monster.EnderMan;
import net.minecraft.world.entity.monster.Phantom;
import net.minecraft.world.level.Level;
import net.minecraftforge.event.ServerChatEvent;
import net.minecraftforge.event.entity.EntityMobGriefingEvent;
import net.minecraftforge.event.entity.living.MobSpawnEvent;
import net.minecraftforge.event.level.ExplosionEvent;
import net.minecraftforge.eventbus.api.Event;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
@Mod.EventBusSubscriber(modid = ExampleTNT.MOD_ID, bus = Mod.EventBusSubscriber.Bus.FORGE)
public class ExampleTNTHooks {
@SubscribeEvent
public static void explosionEvent(ExplosionEvent.Detonate event) {
event.getAffectedEntities().forEach(entity -> {
if (entity instanceof ItemEntity item && !item.isRemoved() && item.getItem().getItem() == ExampleTNTItems.SMALL_TNT.get()) {
entity.discard();
entity.getLevel().explode(null, entity.getX(), entity.getY(), entity.getZ(), 6f, Level.ExplosionInteraction.TNT);
}
});
}
@SubscribeEvent
public static void entityMobGriefingEvent(EntityMobGriefingEvent event) {
if (event.getEntity() instanceof EnderMan) {
if (!event.getEntity().getLevel().isClientSide()) {
((EnderMan) event.getEntity()).addEffect(new MobEffectInstance(MobEffects.GLOWING));
}
event.setResult(Event.Result.DENY);
}
}
@SubscribeEvent
public static void serverChatEvent(ServerChatEvent event) {
if (event.getRawText().contains("tnt")) {
event.setCanceled(true);
}
}
@SubscribeEvent
public static void mobSpawnEvent(MobSpawnEvent.FinalizeSpawn event) {
if (event.getEntity() instanceof Phantom) {
event.setSpawnCancelled(true);
}
}
}
イベントを設定するクラスにはクラス定義の前にアノテーション@Mod.EventBusSubscriber
を付与します。第一引数にはMODID, 第二引数はFORGE
を設定する必要があります。
このクラス内部にはpublic static void
で定義したメソッドを記述することができます。このメソッドの引数にフックしたいイベントを設定することで、イベントが処理された際にこのメソッドが呼ばれることになります。
例として、このクラスでは最初にExplosionEvent.Detonate
を引数としたメソッドを用意しています。このメソッドは爆発で破壊されるブロックや効果を受けるエンティティが設定された直後に呼ばれます。イベントのメソッドで定義した内容が処理され、爆発に巻き込まれたItemEntityのうち内容物がSMALL_TNTであるもののみ誘爆する処理を追加しました。
イベント自体はnet.minecraftforge.event.*
のパッケージ内部にそれぞれクラスが存在します。自分の実装したい処理をクラス名から探し、イベントクラス上部にあるコメントからイベントが呼ばれるタイミング等を理解してから使うことをおすすめします。
イベントの中には処理を中断や禁止する事が可能なものもあります。2つ目のメソッドとしてEntityMobGriefingEvent
を利用します。エンティティの地形破壊が実施できるかを規定するイベントです。このイベントクラスはアノテーション@HasResult
が付与されており、このアノテーションがあるイベントではsetResult
メソッドを利用して結果を規定することができます。この利用例ではResult.DENY
を渡すことでエンダーマンの地形破壊を強制的に失敗にしています。
また、アノテーション@Cancelable
が付与されているイベントもあります。3つ目のメソッドではServerChatEvent
を利用します。サーバーにチャットが送信されたときに呼ばれるイベントです。このアノテーションがあるイベントではsetCanceled
メソッドを利用してキャンセルが可能です。この利用例ではチャットに"tnt"
を含むメッセージをキャンセルし、表示されないようにしています。
なお、4つ目のメソッドで利用しているMobSpawnEvent.FinalizeSpawn
はアノテーション@Cancelable
が付与されていますが、setCanceled
でキャンセルできるのはスポーン時の追加処理のみであり、setSpawnCancelled
を利用することで始めてスポーン自体をキャンセルできます。この利用例ではファントムをスポーンしないように変更しています。このようにイベントクラスごとに特殊な処理が存在しますので、自分が実装したい処理を考えて利用クラスを選ぶとともに、そのクラス上部のドキュメンテーションをよく読んで利用することが大事です。
関連クラス
net.minecraftforge.event.*
:各種イベントが設定されています。このパッケージ傘下のクラスは@SubscribeEvent
でフックしたメソッドを用いることでイベント処理を呼ぶために利用できます。
リンク
前:ブロックの追加
次:ビルド