ForgePatch/src/test/java/net/minecraftforge/test/PlayerInteractEventTest.java

155 lines
6.7 KiB
Java

package net.minecraftforge.test;
import net.minecraft.entity.item.EntityArmorStand;
import net.minecraft.entity.monster.EntityCreeper;
import net.minecraft.entity.monster.EntitySkeleton;
import net.minecraft.entity.passive.EntityHorse;
import net.minecraft.init.Items;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityChest;
import net.minecraft.tileentity.TileEntityDropper;
import net.minecraft.util.EnumHand;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventHandler;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import net.minecraftforge.fml.common.eventhandler.Event;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import org.apache.logging.log4j.Logger;
@Mod(modid="PlayerInteractEventTest", name="PlayerInteractEventTest", version="0.0.0")
public class PlayerInteractEventTest
{
// NOTE: Test with both this ON and OFF - ensure none of the test behaviours show when this is off!
private static final boolean ENABLE = false;
private Logger logger;
@EventHandler
public void preinit(FMLPreInitializationEvent event)
{
logger = event.getModLog();
MinecraftForge.EVENT_BUS.register(this);
}
@SubscribeEvent(receiveCanceled = true) // this triggers after the subclasses below, and we'd like to log them all
public void global(PlayerInteractEvent evt)
{
if (!ENABLE) return;
logger.info("{} | {}", evt.getClass().getSimpleName(), evt.getSide().name());
logger.info("{} | stack: {}", evt.getHand(), evt.getItemStack());
logger.info("{} | face: {}", evt.getPos(), evt.getFace());
}
@SubscribeEvent
public void leftClickBlock(PlayerInteractEvent.LeftClickBlock evt)
{
if (!ENABLE) return;
logger.info("HIT VEC: {}", evt.getHitVec());
if (evt.getItemStack() != null)
{
if (evt.getItemStack().getItem() == Items.GOLDEN_PICKAXE)
evt.setCanceled(true); // Redstone should not activate and pick should not be able to dig anything
if (evt.getItemStack().getItem() == Items.DIAMOND_PICKAXE)
evt.setUseBlock(Event.Result.DENY); // Redstone should not activate, pick should still dig
if (evt.getItemStack().getItem() == Items.IRON_PICKAXE)
evt.setUseItem(Event.Result.DENY); // Pick should not dig, Redstone should still activate
}
// When item use denied, the event will keep firing as long as the left click button is held.
// This is due to how vanilla calls the left click handling methods to let people not lift their button when mining multiple blocks.
// Note that when item use is denied, the cool down for the item does not occur. This is good!
}
@SubscribeEvent
public void rightClickBlock(PlayerInteractEvent.RightClickBlock evt)
{
if (!ENABLE) return;
logger.info("HIT VEC: {}", evt.getHitVec());
// Shift right clicking dropper with an item in hand should still open the dropper contrary to normal mechanics
// The item in hand is used as well (not specifying anything would not use the item)
TileEntity te = evt.getWorld().getTileEntity(evt.getPos());
if (te instanceof TileEntityDropper)
{
evt.setUseBlock(Event.Result.ALLOW);
evt.setUseItem(Event.Result.ALLOW);
}
// Same as above, except the item should no longer be used
if (te instanceof TileEntityChest)
{
evt.setUseBlock(Event.Result.ALLOW);
evt.setUseItem(Event.Result.DENY); // could be left out as well
}
// Case: Flint and steel in main hand on top of a TE will light a fire, not open the TE.
// Note that if you do this on a chest, the f+s will fail, but then your off hand will open the chest
// If you dual wield flints and steels and right click a chest nothing should happen
if (evt.getItemStack() != null && evt.getItemStack().getItem() == Items.FLINT_AND_STEEL)
evt.setUseBlock(Event.Result.DENY);
// Case: Painting in main hand
// Opening a TE will also place a painting on the TE if possible
if (evt.getHand() == EnumHand.MAIN_HAND && evt.getItemStack() != null && evt.getItemStack().getItem() == Items.PAINTING) {
evt.setUseItem(Event.Result.ALLOW);
}
// Spawn egg in main hand, block in offhand -> block should be placed
// Sword in main hand, spawn egg in offhand -> nothing should happen
if (evt.getItemStack() != null && evt.getItemStack().getItem() == Items.SPAWN_EGG) {
evt.setCanceled(true);
}
}
@SubscribeEvent
public void rightClickItem(PlayerInteractEvent.RightClickItem evt)
{
if (!ENABLE) return;
// Use survival mode
// Case: Ender pearl in main hand, bow in offhand with arrows in inv -> Bow should trigger
// Case: Sword in main hand, ender pearl in offhand -> Nothing should happen
if (evt.getItemStack() != null && evt.getItemStack().getItem() == Items.ENDER_PEARL)
evt.setCanceled(true);
}
@SubscribeEvent
public void interactSpecific(PlayerInteractEvent.EntityInteractSpecific evt)
{
if (!ENABLE) return;
logger.info("LOCAL POS: {}", evt.getLocalPos());
if (evt.getItemStack() != null
&& evt.getTarget() instanceof EntityArmorStand
&& evt.getItemStack().getItem() == Items.IRON_HELMET)
evt.setCanceled(true); // Should not be able to place iron helmet onto armor stand (you will put it on instead)
if (evt.getWorld().isRemote
&& evt.getTarget() instanceof EntitySkeleton
&& evt.getLocalPos().yCoord > evt.getTarget().height / 2.0)
{
// If we right click the upper half of a skeleton it becomes wither skeleton. Otherwise nothing happens.
((EntitySkeleton) evt.getTarget()).setSkeletonType(1);
evt.setCanceled(true);
}
}
@SubscribeEvent
public void interactNormal(PlayerInteractEvent.EntityInteract evt)
{
if (!ENABLE) return;
if (evt.getItemStack() != null && (evt.getTarget() instanceof EntityHorse || evt.getTarget() instanceof EntityCreeper))
// Should not be able to feed wild horses with golden apple (you will start eating it in survival)
// Should not be able to ignite creeper with F+S
// Applies to both hands
evt.setCanceled(true);
}
}