Skip to content

Commit

Permalink
Merge pull request #14 from valoeghese/misaka_mikoto
Browse files Browse the repository at this point in the history
Block Place Event
  • Loading branch information
valoeghese authored Aug 23, 2020
2 parents 0c6d46b + ce6d431 commit 3b5b1ca
Show file tree
Hide file tree
Showing 7 changed files with 124 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ private InteractionsImpl() {
public static ItemStack eatFood(LivingEntity self, World world, ItemStack original) {
AtomicReference<ItemStack> eaten = new AtomicReference<>(original);
AtomicReference<ItemStack> moddedResultReference = new AtomicReference<>();
ActionResult eventResult = ItemEvents.EAT_FOOD.invoker().onPlayerEat(self, world, original, eaten, moddedResultReference);
ActionResult eventResult = ItemEvents.EAT_FOOD.invoker().onEatFood(self, world, original, eaten, moddedResultReference);

ItemStack defaultResult = eventResult == ActionResult.FAIL ? original : self.eatFood(world, eaten.get());
ItemStack moddedResult = moddedResultReference.get();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package io.github.fabriccommunity.events.mixin.item;

import java.util.concurrent.atomic.AtomicReference;

import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;

import io.github.fabriccommunity.events.play.ItemEvents;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.network.packet.s2c.play.ScreenHandlerSlotUpdateS2CPacket;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.ActionResult;

@Mixin(BlockItem.class)
public abstract class MixinBlockItem {
@Shadow
protected abstract BlockState getPlacementState(ItemPlacementContext context);

/**
* @reason getPlacementState is often overriden (has two vanilla overrides, could have more in modded). Therefore using a redirect rather than inject at return in {@code getPlacementState} is more compatible with other mods.
*/
@Redirect(at = @At(value = "INVOKE", target = "Lnet/minecraft/item/BlockItem;getPlacementState(Lnet/minecraft/item/ItemPlacementContext;)Lnet/minecraft/block/BlockState;"),
method = "place")
private BlockState onGetPlacementState(BlockItem self, ItemPlacementContext placementContext) {
BlockState original = this.getPlacementState(placementContext);
AtomicReference<BlockState> state = new AtomicReference<>(original);

ActionResult result = ItemEvents.PLACED.invoker().onBlockPlaced(placementContext, original, state);
BlockState modified = state.get();

if (result == ActionResult.FAIL) {
PlayerEntity entity = placementContext.getPlayer();

if (entity instanceof ServerPlayerEntity) {
int selectedSlot = entity.inventory.selectedSlot;
((ServerPlayerEntity) entity).networkHandler.sendPacket(new ScreenHandlerSlotUpdateS2CPacket(-2, selectedSlot, entity.inventory.getStack(selectedSlot)));
}

return null;
} else if (result == ActionResult.SUCCESS || (original != modified)) {
return modified;
} else {
return original;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

import net.fabricmc.fabric.api.event.Event;
import net.fabricmc.fabric.api.event.EventFactory;
import net.minecraft.block.BlockState;
import net.minecraft.entity.LivingEntity;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ActionResult;
import net.minecraft.world.World;
Expand All @@ -18,7 +20,22 @@ public final class ItemEvents {
*/
public static final Event<EatFood> EAT_FOOD = EventFactory.createArrayBacked(EatFood.class, listeners -> (entity, world, original, eaten, result) -> {
for (EatFood listener : listeners) {
ActionResult eventResult = listener.onPlayerEat(entity, world, original, eaten, result);
ActionResult eventResult = listener.onEatFood(entity, world, original, eaten, result);

if (eventResult != ActionResult.PASS) {
return eventResult;
}
}

return ActionResult.PASS;
});

/**
* Called when a block item is placed. Is configured to work server side.
*/
public static final Event<Placed> PLACED = EventFactory.createArrayBacked(Placed.class, listeners -> (context, original, state) -> {
for (Placed listener : listeners) {
ActionResult eventResult = listener.onBlockPlaced(context, original, state);

if (eventResult != ActionResult.PASS) {
return eventResult;
Expand Down Expand Up @@ -48,6 +65,27 @@ public interface EatFood {
* <li>{@code FAIL} to cancel further event processing and do not eat the food.
* </ul>
*/
ActionResult onPlayerEat(LivingEntity entity, World world, final ItemStack original, AtomicReference<ItemStack> eaten, AtomicReference<ItemStack> result);
ActionResult onEatFood(LivingEntity entity, World world, final ItemStack original, AtomicReference<ItemStack> eaten, AtomicReference<ItemStack> result);
}

/**
* Called when a block item is placed. Is configured to work server side.
* @author Valoeghese
*/
@FunctionalInterface
public interface Placed {
/**
* @param context the context of the block item placement.
* @param original the original blockstate to be placed.
* @param state the state to be placed. If the value stored herein differs from {@code original}, another mod has modified it.
* @return
* <ul>
* <li>{@code SUCCESS} to cancel further event processing place the block state in {@code state}<br/>
* <li>{@code CONSUME} to cancel further event processing and fall back to vanilla behaviour (not modifying the block).<br/>
* <li>{@code PASS} pass event handling on to further processing. If all listeners pass, it is treated as a {@code SUCCESS} if the block state has been modified from the original, and treated as a {@code CONSUME} if the block state has not been modified from the original.
* <li>{@code FAIL} to cancel further event processing and not place the block.
* </ul>
*/
ActionResult onBlockPlaced(ItemPlacementContext context, final BlockState original, AtomicReference<BlockState> state);
}
}
1 change: 1 addition & 0 deletions src/main/resources/toomanyevents.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"biomegen.MixinMultiNoiseBiomeSource",
"biomegen.MixinTheEndBiomeSource",
"biomegen.MixinVanillaLayeredBiomeSource",
"item.MixinBlockItem",
"item.MixinItem",
"player.MixinHungerManager",
"player.MixinPlayerEntity",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package io.github.fabriccommunity.events.test;

import io.github.fabriccommunity.events.play.ItemEvents;
import net.fabricmc.api.ModInitializer;
import net.minecraft.block.Blocks;
import net.minecraft.util.ActionResult;

/**
* @author Valoeghese
*/
public class BlockPlaceTest implements ModInitializer {
public static boolean ENABLED = true;

@Override
public void onInitialize() {
if (ENABLED) {
ItemEvents.PLACED.register((context, original, state) -> {
if (context.getBlockPos().getY() == 63) {
return ActionResult.FAIL;
} else if (context.getBlockPos().getY() == 64) {
state.set(Blocks.GOLD_BLOCK.getDefaultState());
return ActionResult.SUCCESS;
}

return ActionResult.PASS;
});
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* @author leocth
*/
public class ClientPlayerInteractionTest implements ClientModInitializer {
public static final boolean ENABLED = true;
public static final boolean ENABLED = false;

@Override
public void onInitializeClient() {
Expand Down
1 change: 1 addition & 0 deletions src/test/resources/fabric.mod.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"entrypoints": {
"main": [
"io.github.fabriccommunity.events.test.BiomePlacementTest",
"io.github.fabriccommunity.events.test.BlockPlaceTest",
"io.github.fabriccommunity.events.test.FoodTest",
"io.github.fabriccommunity.events.test.EntitySpawnTest",
"io.github.fabriccommunity.events.test.PlayerInteractionTest"
Expand Down

0 comments on commit 3b5b1ca

Please sign in to comment.