mirror of
https://github.com/architectury/architectury-api.git
synced 2026-03-28 03:56:59 -05:00
Add LightningEvent, FallingBlock land, move break/place to BlockEvent
This commit is contained in:
@@ -20,6 +20,9 @@
|
||||
package me.shedaniel.architectury.event;
|
||||
|
||||
import me.shedaniel.architectury.annotations.ExpectPlatform;
|
||||
import me.shedaniel.architectury.event.events.BlockEvent;
|
||||
import me.shedaniel.architectury.event.events.EntityEvent;
|
||||
import me.shedaniel.architectury.event.events.PlayerEvent;
|
||||
import me.shedaniel.architectury.platform.Platform;
|
||||
import me.shedaniel.architectury.utils.Env;
|
||||
import net.fabricmc.api.EnvType;
|
||||
@@ -38,6 +41,8 @@ public final class EventHandler {
|
||||
registerCommon();
|
||||
if (Platform.getEnvironment() == Env.SERVER)
|
||||
registerServer();
|
||||
|
||||
registerDelegates();
|
||||
}
|
||||
|
||||
@ExpectPlatform
|
||||
@@ -56,4 +61,10 @@ public final class EventHandler {
|
||||
private static void registerServer() {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private static void registerDelegates() {
|
||||
BlockEvent.PLACE.register((EntityEvent.PLACE_BLOCK.invoker()::placeBlock));
|
||||
BlockEvent.BREAK.register((PlayerEvent.BREAK_BLOCK.invoker()::breakBlock));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
package me.shedaniel.architectury.event.events;
|
||||
|
||||
import me.shedaniel.architectury.event.Event;
|
||||
import me.shedaniel.architectury.event.EventFactory;
|
||||
import me.shedaniel.architectury.utils.IntValue;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.item.FallingBlockEntity;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface BlockEvent {
|
||||
|
||||
// Block interaction events
|
||||
/**
|
||||
* Called when a player breaks a block.
|
||||
*/
|
||||
Event<Break> BREAK = EventFactory.createInteractionResult();
|
||||
/**
|
||||
* Called when a block is placed in the world by an entity.
|
||||
*/
|
||||
Event<Place> PLACE = EventFactory.createInteractionResult();
|
||||
|
||||
/**
|
||||
* Called when a falling block (sand, anvil, etc.) is about to land.
|
||||
* Use fallState#getBlock to get the type of block for more granular control.
|
||||
*/
|
||||
Event<FallingLand> FALLING_LAND = EventFactory.createLoop();
|
||||
|
||||
interface Break {
|
||||
InteractionResult breakBlock(Level world, BlockPos pos, BlockState state, ServerPlayer player, @Nullable IntValue xp);
|
||||
}
|
||||
|
||||
interface Place {
|
||||
InteractionResult placeBlock(Level world, BlockPos pos, BlockState state, @Nullable Entity placer);
|
||||
}
|
||||
|
||||
interface FallingLand {
|
||||
void onLand(Level level, BlockPos pos, BlockState fallState, BlockState landOn, FallingBlockEntity entity);
|
||||
}
|
||||
}
|
||||
@@ -28,6 +28,7 @@ import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface EntityEvent {
|
||||
@@ -43,6 +44,12 @@ public interface EntityEvent {
|
||||
* Invoked before entity is added to a world, equivalent to forge's {@code EntityJoinWorldEvent}.
|
||||
*/
|
||||
Event<Add> ADD = EventFactory.createInteractionResult();
|
||||
|
||||
/**
|
||||
* @deprecated use {@link BlockEvent#PLACE}
|
||||
*/
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.0")
|
||||
Event<PlaceBlock> PLACE_BLOCK = EventFactory.createInteractionResult();
|
||||
|
||||
interface LivingDeath {
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package me.shedaniel.architectury.event.events;
|
||||
|
||||
import me.shedaniel.architectury.event.Event;
|
||||
import me.shedaniel.architectury.event.EventFactory;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.LightningBolt;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface LightningEvent {
|
||||
|
||||
// TODO Pre - Called before a lightning bolt entity is added to the world. (cancellable)
|
||||
/**
|
||||
* Invoked after the lightning has gathered a list of entities to strike.
|
||||
* Remove entities from the list to stop them from being hit.
|
||||
*/
|
||||
Event<Strike> STRIKE = EventFactory.createLoop();
|
||||
// TODO Post - Called before a lightning bolt entity is removed from the world.
|
||||
|
||||
interface Strike {
|
||||
void onStrike(LightningBolt bolt, Level level, Vec3 pos, List<Entity> toStrike);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -34,6 +34,7 @@ import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface PlayerEvent {
|
||||
@@ -50,6 +51,12 @@ public interface PlayerEvent {
|
||||
Event<DropItem> DROP_ITEM = EventFactory.createLoop();
|
||||
Event<OpenMenu> OPEN_MENU = EventFactory.createLoop();
|
||||
Event<CloseMenu> CLOSE_MENU = EventFactory.createLoop();
|
||||
|
||||
/**
|
||||
* @deprecated use {@link BlockEvent#BREAK}
|
||||
*/
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.0")
|
||||
Event<BreakBlock> BREAK_BLOCK = EventFactory.createInteractionResult();
|
||||
|
||||
interface PlayerJoin {
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package me.shedaniel.architectury.mixin;
|
||||
|
||||
import me.shedaniel.architectury.event.events.BlockEvent;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.entity.item.FallingBlockEntity;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.FallingBlock;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||
|
||||
@Mixin(FallingBlock.class)
|
||||
public abstract class MixinFallingBlock extends Block {
|
||||
|
||||
public MixinFallingBlock(Properties properties) {
|
||||
super(properties);
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
@Inject(method = "onLand", at = @At("RETURN"), locals = LocalCapture.CAPTURE_FAILHARD)
|
||||
public void handleLand(Level level, BlockPos pos, BlockState fallState, BlockState landOn, FallingBlockEntity entity, CallbackInfo ci) {
|
||||
BlockEvent.FALLING_LAND.invoker().onLand(level, pos, fallState, landOn, entity);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package me.shedaniel.architectury.mixin;
|
||||
|
||||
import me.shedaniel.architectury.event.events.LightningEvent;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.LightningBolt;
|
||||
import net.minecraft.world.level.Level;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mixin(LightningBolt.class)
|
||||
public abstract class MixinLightningBolt extends Entity {
|
||||
|
||||
public MixinLightningBolt(EntityType<?> type, Level level) {
|
||||
super(type, level);
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
@Inject(method = "tick", at = @At(
|
||||
value = "INVOKE_ASSIGN",
|
||||
target = "Lnet/minecraft/world/level/Level;getEntities(Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/phys/AABB;Ljava/util/function/Predicate;)Ljava/util/List;",
|
||||
ordinal = 0,
|
||||
shift = At.Shift.BY,
|
||||
by = 1
|
||||
), locals = LocalCapture.CAPTURE_FAILHARD)
|
||||
public void handleLightning(CallbackInfo ci, double d0, List<Entity> list) {
|
||||
if (this.removed || this.level.isClientSide) {
|
||||
return;
|
||||
}
|
||||
|
||||
LightningEvent.STRIKE.invoker().onStrike((LightningBolt) (Object) this, this.level, this.position(), list);
|
||||
}
|
||||
|
||||
}
|
||||
16
common/src/main/resources/architectury-common.mixins.json
Normal file
16
common/src/main/resources/architectury-common.mixins.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"required": true,
|
||||
"package": "me.shedaniel.architectury.mixin",
|
||||
"compatibilityLevel": "JAVA_8",
|
||||
"minVersion": "0.7.11",
|
||||
"client": [
|
||||
],
|
||||
"mixins": [
|
||||
"MixinFallingBlock",
|
||||
"MixinLightningBolt"
|
||||
],
|
||||
"injectors": {
|
||||
"maxShiftBy": 5,
|
||||
"defaultRequire": 1
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
package me.shedaniel.architectury.mixin.fabric;
|
||||
|
||||
import me.shedaniel.architectury.event.events.EntityEvent;
|
||||
import me.shedaniel.architectury.event.events.BlockEvent;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.item.BlockItem;
|
||||
import net.minecraft.world.item.context.BlockPlaceContext;
|
||||
@@ -35,9 +35,9 @@ public abstract class MixinBlockItem {
|
||||
target = "Lnet/minecraft/world/item/context/BlockPlaceContext;getClickedPos()Lnet/minecraft/core/BlockPos;"),
|
||||
cancellable = true)
|
||||
private void place(BlockPlaceContext context, CallbackInfoReturnable<InteractionResult> cir) {
|
||||
InteractionResult result = EntityEvent.PLACE_BLOCK.invoker().placeBlock(context.getLevel(), context.getClickedPos(), context.getLevel().getBlockState(context.getClickedPos()), context.getPlayer());
|
||||
InteractionResult result = BlockEvent.PLACE.invoker().placeBlock(context.getLevel(), context.getClickedPos(), context.getLevel().getBlockState(context.getClickedPos()), context.getPlayer());
|
||||
if (result != InteractionResult.PASS) {
|
||||
cir.setReturnValue(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
package me.shedaniel.architectury.mixin.fabric;
|
||||
|
||||
import me.shedaniel.architectury.event.events.PlayerEvent;
|
||||
import me.shedaniel.architectury.event.events.BlockEvent;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
@@ -44,7 +44,7 @@ public class MixinServerPlayerGameMode {
|
||||
ordinal = 0),
|
||||
locals = LocalCapture.CAPTURE_FAILHARD, cancellable = true)
|
||||
private void onBreak(BlockPos blockPos, CallbackInfoReturnable<Boolean> cir, BlockState state) {
|
||||
if (PlayerEvent.BREAK_BLOCK.invoker().breakBlock(this.level, blockPos, state, this.player, null) == InteractionResult.FAIL) {
|
||||
if (BlockEvent.BREAK.invoker().breakBlock(this.level, blockPos, state, this.player, null) == InteractionResult.FAIL) {
|
||||
cir.setReturnValue(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
"license": "LGPL-3",
|
||||
"environment": "*",
|
||||
"mixins": [
|
||||
"architectury-common.mixins.json",
|
||||
"architectury.mixins.json"
|
||||
],
|
||||
"entrypoints": {
|
||||
@@ -30,4 +31,4 @@
|
||||
"custom": {
|
||||
"modmenu:api": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ plugins {
|
||||
}
|
||||
|
||||
loom {
|
||||
mixinConfig = "architectury.mixins.json"
|
||||
mixinConfigs = ["architectury.mixins.json", "architectury-common.mixins.json"]
|
||||
}
|
||||
|
||||
configurations {
|
||||
|
||||
@@ -44,7 +44,8 @@ import net.minecraftforge.event.entity.player.EntityItemPickupEvent;
|
||||
import net.minecraftforge.event.entity.player.PlayerContainerEvent;
|
||||
import net.minecraftforge.event.entity.player.PlayerEvent.*;
|
||||
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
|
||||
import net.minecraftforge.event.world.BlockEvent;
|
||||
import net.minecraftforge.event.world.BlockEvent.BreakEvent;
|
||||
import net.minecraftforge.event.world.BlockEvent.EntityPlaceEvent;
|
||||
import net.minecraftforge.event.world.ExplosionEvent.Detonate;
|
||||
import net.minecraftforge.event.world.ExplosionEvent.Start;
|
||||
import net.minecraftforge.event.world.WorldEvent;
|
||||
@@ -288,9 +289,9 @@ public class EventHandlerImplCommon {
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void event(BlockEvent.BreakEvent event) {
|
||||
public static void event(BreakEvent event) {
|
||||
if (event.getPlayer() instanceof ServerPlayer && event.getWorld() instanceof Level) {
|
||||
InteractionResult result = PlayerEvent.BREAK_BLOCK.invoker().breakBlock((Level) event.getWorld(), event.getPos(), event.getState(), (ServerPlayer) event.getPlayer(), new IntValue() {
|
||||
InteractionResult result = BlockEvent.BREAK.invoker().breakBlock((Level) event.getWorld(), event.getPos(), event.getState(), (ServerPlayer) event.getPlayer(), new IntValue() {
|
||||
@Override
|
||||
public int getAsInt() {
|
||||
return event.getExpToDrop();
|
||||
@@ -308,9 +309,9 @@ public class EventHandlerImplCommon {
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void event(BlockEvent.EntityPlaceEvent event) {
|
||||
public static void event(EntityPlaceEvent event) {
|
||||
if (event.getWorld() instanceof Level) {
|
||||
InteractionResult result = EntityEvent.PLACE_BLOCK.invoker().placeBlock((Level) event.getWorld(), event.getPos(), event.getState(), event.getEntity());
|
||||
InteractionResult result = BlockEvent.PLACE.invoker().placeBlock((Level) event.getWorld(), event.getPos(), event.getState(), event.getEntity());
|
||||
if (result != InteractionResult.PASS) {
|
||||
event.setCanceled(true);
|
||||
}
|
||||
|
||||
@@ -49,6 +49,14 @@ public class DebugEvents {
|
||||
}
|
||||
|
||||
public static void debugEvents() {
|
||||
BlockEvent.BREAK.register((world, pos, state, player, xp) -> {
|
||||
SINK.accept(player.getScoreboardName() + " breaks " + toShortString(pos) + logSide(player.level));
|
||||
return InteractionResult.PASS;
|
||||
});
|
||||
BlockEvent.PLACE.register((world, pos, state, placer) -> {
|
||||
SINK.accept(Optional.ofNullable(placer).map(Entity::getScoreboardName).orElse("null") + " places block at " + toShortString(pos) + logSide(world));
|
||||
return InteractionResult.PASS;
|
||||
});
|
||||
ChatEvent.SERVER.register((player, message, component) -> {
|
||||
SINK.accept("Server chat received: " + message);
|
||||
return InteractionResultHolder.pass(component);
|
||||
@@ -78,10 +86,6 @@ public class DebugEvents {
|
||||
}
|
||||
return InteractionResult.PASS;
|
||||
});
|
||||
EntityEvent.PLACE_BLOCK.register((world, pos, state, placer) -> {
|
||||
SINK.accept(Optional.ofNullable(placer).map(Entity::getScoreboardName).orElse("null") + " places block at " + toShortString(pos) + logSide(world));
|
||||
return InteractionResult.PASS;
|
||||
});
|
||||
ExplosionEvent.DETONATE.register((world, explosion, affectedEntities) -> {
|
||||
SINK.accept(world.dimension().location() + " explodes at " + toShortString(ExplosionHooks.getPosition(explosion)) + logSide(world));
|
||||
});
|
||||
@@ -155,10 +159,6 @@ public class DebugEvents {
|
||||
SINK.accept(player.getScoreboardName() + " drops " + new TranslatableComponent(entity.getItem().getDescriptionId()).getString() + logSide(player.level));
|
||||
return InteractionResult.PASS;
|
||||
});
|
||||
PlayerEvent.BREAK_BLOCK.register((world, pos, state, player, xp) -> {
|
||||
SINK.accept(player.getScoreboardName() + " breaks " + toShortString(pos) + logSide(player.level));
|
||||
return InteractionResult.PASS;
|
||||
});
|
||||
PlayerEvent.OPEN_MENU.register((player, menu) -> {
|
||||
SINK.accept(player.getScoreboardName() + " opens " + toSimpleName(menu) + logSide(player.level));
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user