事件系统入门 - Junye-666/RideBattleLib_NeoForge_1.21.1 GitHub Wiki
RideBattleLib 提供 NeoForge 事件监听,同时提供 ServerRiderDispatcher / ClientRiderDispatcher 分发系统。
1.3.3 推荐大型骑士使用分发系统,小型逻辑可直接监听 NeoForge 事件。
@EventBusSubscriber(modid = "yourmod")
public class YourEventHandler {
@SubscribeEvent
public static void onHenshinPre(HenshinEvent.Pre event) {
Player player = event.getPlayer();
ResourceLocation formId = event.getFormId();
player.level().playSound(
null,
player,
SoundEvents.LIGHTNING_BOLT_THUNDER,
SoundSource.PLAYERS,
1.0f,
1.0f
);
}
@SubscribeEvent
public static void onHenshinPost(HenshinEvent.Post event) {
event.getPlayer().displayClientMessage(
Component.literal("变身完成!").withStyle(ChatFormatting.GOLD),
true
);
}
}| 事件类 | Pre | Post | 说明 |
|---|---|---|---|
HenshinEvent |
可取消 | 有 | 变身前后 |
UnhenshinEvent |
可取消 | 有 | 解除变身前后 |
FormSwitchEvent |
可取消 | 有 | 形态切换前后 |
HenshinPauseEvent |
可取消 | 有 | 变身暂停前后 |
DriverActivationEvent |
可取消 | 无 | 驱动器激活 |
ItemInsertionEvent |
可取消,可改物品 | 有 | 插入物品前后 |
SlotExtractionEvent |
可取消,可改物品 | 有 | 取出物品前后 |
ReturnItemsEvent |
可取消 | 有 | 返还物品前后 |
ItemGrantEvent |
可取消,可改物品 | 有 | 授予物品前后 |
SkillEvent |
可取消 | 有 | 技能触发前后 |
RotateSkillEvent |
可取消 | 无 | 技能轮转 |
FormOverrideEvent |
可取消,可覆盖形态 | 无 | 形态匹配覆盖 |
FindRiderConfigEvent |
可取消 | 无 | 搜索 RiderConfig 时插入逻辑 |
PenaltyEvent |
子事件可取消 | 无 | 吃瘪各阶段 |
@SubscribeEvent
public static void onUnhenshin(UnhenshinEvent.Pre event) {
if (event.isPenalty()) {
event.getPlayer().displayClientMessage(
Component.literal("我的身体已经菠萝菠萝哒!").withStyle(ChatFormatting.RED),
true
);
}
}@SubscribeEvent
public static void onFormSwitchPre(FormSwitchEvent.Pre event) {
Player player = event.getPlayer();
ResourceLocation oldForm = event.getOldFormId();
ResourceLocation newForm = event.getNewFormId();
player.displayClientMessage(
Component.literal("形态切换: " + newForm.getPath()),
true
);
}@SubscribeEvent
public static void onSkillTrigger(SkillEvent.Post event) {
ResourceLocation skillId = event.getSkillId();
if (skillId.getPath().equals("rider_kick")) {
Player player = event.getPlayer();
Vec3 lookVec = player.getLookAngle();
player.setDeltaMovement(lookVec.x * 2.0, 0.5, lookVec.z * 2.0);
player.hurtMarked = true;
AABB area = player.getBoundingBox().inflate(3.0);
player.level().getEntities(player, area).forEach(entity -> {
if (entity instanceof LivingEntity target) {
target.hurt(player.damageSources().playerAttack(player), 10.0f);
}
});
player.level().explode(
player,
player.getX(), player.getY() + 1.0, player.getZ(),
2.0f,
false,
Level.ExplosionInteraction.NONE
);
}
}@SubscribeEvent
public static void onItemInsert(ItemInsertionEvent.Pre event) {
ItemStack original = event.getStack();
if (original.is(Items.DIAMOND)) {
event.setStack(new ItemStack(Items.NETHERITE_INGOT));
event.getPlayer().displayClientMessage(
Component.literal("钻石被转换为下界合金!"),
true
);
}
}@SubscribeEvent
public static void onItemGrant(ItemGrantEvent.Pre event) {
if (event.getStack().is(Items.IRON_SWORD)) {
event.setStack(new ItemStack(Items.DIAMOND_SWORD));
}
}@SubscribeEvent
public static void onFormOverride(FormOverrideEvent event) {
Player player = event.getPlayer();
boolean hasSpecialItem = false;
for (ItemStack stack : player.getInventory().items) {
if (!stack.isEmpty() && stack.is(Items.NETHERITE_INGOT)) {
hasSpecialItem = true;
break;
}
}
if (hasSpecialItem) {
event.overrideForm(
ResourceLocation.fromNamespaceAndPath("mymod", "super_form")
);
}
}注意:在 FormOverrideEvent 中调用 event.setCanceled(true) 会中止变身并返回 null。
@SubscribeEvent
public static void onFindConfig(FindRiderConfigEvent event) {
Player player = event.getPlayer();
Optional<ItemStack> found = CuriosApi.getCuriosHelper()
.findEquippedCurio(ModItems.DRIVER.get(), player)
.map(SlotResult::stack);
if (found.isPresent()) {
event.setConfig(MyRider.CONFIG);
}
}注意:在此处调用 event.setCanceled(true) 会使玩家变身失败。