2016-01-12 00:04:22 +00:00
package net.minecraftforge.test ;
2016-02-15 22:30:24 +00:00
import net.minecraft.init.Blocks ;
2016-01-12 00:04:22 +00:00
import net.minecraft.init.Items ;
import net.minecraft.nbt.NBTBase ;
2016-12-21 19:11:25 +00:00
import net.minecraft.nbt.NBTTagCompound ;
2016-01-12 00:04:22 +00:00
import net.minecraft.tileentity.TileEntity ;
2016-03-01 12:58:03 +00:00
import net.minecraft.util.text.TextComponentString ;
import net.minecraft.util.text.TextFormatting ;
2016-01-12 00:04:22 +00:00
import net.minecraft.util.EnumFacing ;
import net.minecraft.util.ResourceLocation ;
import net.minecraftforge.common.MinecraftForge ;
import net.minecraftforge.common.capabilities.Capability ;
import net.minecraftforge.common.capabilities.Capability.IStorage ;
import net.minecraftforge.common.capabilities.CapabilityInject ;
import net.minecraftforge.common.capabilities.CapabilityManager ;
2016-12-21 19:11:25 +00:00
import net.minecraftforge.common.capabilities.ICapabilitySerializable ;
2016-01-12 00:04:22 +00:00
import net.minecraftforge.event.AttachCapabilitiesEvent ;
import net.minecraftforge.event.entity.player.PlayerInteractEvent ;
import net.minecraftforge.fml.common.Mod ;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent ;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent ;
2016-11-17 18:44:31 +00:00
import javax.annotation.Nonnull ;
import javax.annotation.Nullable ;
2016-11-22 20:12:13 +00:00
@Mod ( modid = " forge.testcapmod " , name = " Forge TestCapMod " , version = " 1.0 " , acceptableRemoteVersions = " * " )
2016-01-12 00:04:22 +00:00
public class TestCapabilityMod
{
// A Holder/Marker for if this capability is installed.
// MUST be Static final doesn't matter but is suggested to prevent
// you from overriding it elsewhere.
// As Annotations and generic's are erased/unload at runtime this
// does NOT create a hard dependency on the class.
@CapabilityInject ( IExampleCapability . class )
private static final Capability < IExampleCapability > TEST_CAP = null ;
@Mod.EventHandler
public void preinit ( FMLPreInitializationEvent evt )
{
// If you are a API, provide register your capability ASAP.
// You MUST supply a default save handler and a default implementation
// If you are a CONSUMER of the capability DO NOT register it. Only APIs should.
CapabilityManager . INSTANCE . register ( IExampleCapability . class , new Storage ( ) , DefaultImpl . class ) ;
MinecraftForge . EVENT_BUS . register ( this ) ;
}
@SubscribeEvent
2016-04-05 00:58:46 +00:00
public void onInteract ( PlayerInteractEvent . LeftClickBlock event )
2016-01-12 00:04:22 +00:00
{
2016-05-18 12:11:56 +00:00
if ( event . getItemStack ( ) . getItem ( ) ! = Items . STICK ) return ;
2016-01-12 00:04:22 +00:00
// This is just a example of how to interact with the TE, note the strong type binding that getCapability has
2016-03-24 08:44:52 +00:00
TileEntity te = event . getWorld ( ) . getTileEntity ( event . getPos ( ) ) ;
if ( te ! = null & & te . hasCapability ( TEST_CAP , event . getFace ( ) ) )
2016-01-12 00:04:22 +00:00
{
event . setCanceled ( true ) ;
2016-03-24 08:44:52 +00:00
IExampleCapability inv = te . getCapability ( TEST_CAP , event . getFace ( ) ) ;
2016-01-12 00:04:22 +00:00
System . out . println ( " Hi I'm a " + inv . getOwnerType ( ) ) ;
}
2016-12-21 19:11:25 +00:00
if ( event . getWorld ( ) . getBlockState ( event . getPos ( ) ) . getBlock ( ) = = Blocks . DIRT & & event . getItemStack ( ) . hasCapability ( TEST_CAP , null ) )
2016-02-15 22:30:24 +00:00
{
2016-12-21 19:11:25 +00:00
IExampleCapability cap = event . getItemStack ( ) . getCapability ( TEST_CAP , null ) ;
event . getEntityPlayer ( ) . addChatMessage ( new TextComponentString ( ( cap . getVal ( ) ? TextFormatting . GREEN : TextFormatting . RED ) + " " + TextFormatting . ITALIC + " TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST " ) ) ;
2016-02-15 22:30:24 +00:00
event . setCanceled ( true ) ;
}
2016-01-12 00:04:22 +00:00
}
2016-12-21 19:11:25 +00:00
@SubscribeEvent
public void onInteractItem ( PlayerInteractEvent . RightClickItem event )
{
if ( ! event . getEntityPlayer ( ) . isSneaking ( ) ) return ;
if ( event . getItemStack ( ) . getItem ( ) ! = Items . STICK ) return ;
if ( event . getItemStack ( ) . hasCapability ( TEST_CAP , null ) )
{
IExampleCapability cap = event . getItemStack ( ) . getCapability ( TEST_CAP , null ) ;
cap . toggleVal ( ) ;
System . out . println ( " Test value is now: " + ( cap . getVal ( ) ? " TRUE " : " FALSE " ) ) ;
}
}
2016-01-12 00:04:22 +00:00
// Example of having this annotation on a method, this will be called when the capability is present.
// You could do something like register event handlers to attach these capabilities to objects, or
// setup your factory, who knows. Just figured i'd give you the power.
@CapabilityInject ( IExampleCapability . class )
private static void capRegistered ( Capability < IExampleCapability > cap )
{
System . out . println ( " IExampleCapability was registered wheeeeee! " ) ;
}
2016-12-21 19:11:25 +00:00
// Having the Provider implement the cap is not recommended as this creates a hard dep on the cap interface.
// And does not allow for sidedness.
// But as this is a example and we do not care about that here we go.
class Provider < V > implements ICapabilitySerializable < NBTTagCompound > , IExampleCapability
{
private V obj ;
private boolean value ;
Provider ( V obj )
{
this . obj = obj ;
}
@Override
public boolean hasCapability ( @Nonnull Capability < ? > capability , @Nullable EnumFacing facing )
{
return TEST_CAP ! = null & & capability = = TEST_CAP ;
}
@Override
@Nullable
public < T > T getCapability ( @Nonnull Capability < T > capability , @Nullable EnumFacing facing )
{
if ( TEST_CAP ! = null & & capability = = TEST_CAP ) return TEST_CAP . cast ( this ) ;
return null ;
}
@Override
public NBTTagCompound serializeNBT ( ) {
NBTTagCompound tag = new NBTTagCompound ( ) ;
tag . setBoolean ( " CapTestVal " , this . value ) ;
return tag ;
}
@Override
public void deserializeNBT ( NBTTagCompound tag ) {
this . value = tag . getBoolean ( " CapTestVal " ) ;
}
@Override
public String getOwnerType ( ) {
return obj . getClass ( ) . getName ( ) ;
}
@Override
public boolean getVal ( ) {
return this . value ;
}
@Override
public void toggleVal ( ) {
this . value = ! this . value ;
}
}
2016-01-12 00:04:22 +00:00
// An example of how to attach a capability to an arbitrary Tile entity.
// Note: Doing this IS NOT recommended for normal implementations.
// If you control the TE it is HIGHLY recommend that you implement a fast
// version of the has/getCapability functions yourself. So you have control
// over everything yours being called first.
@SubscribeEvent
public void onTELoad ( AttachCapabilitiesEvent . TileEntity event )
{
2016-12-21 19:11:25 +00:00
//Attach it! The resource location MUST be unique it's recommended that you tag it with your modid and what the cap is.
2016-11-16 03:26:10 +00:00
event . addCapability ( new ResourceLocation ( " forge.testcapmod:dummy_cap " ) , new Provider ( event . getTileEntity ( ) ) ) ;
2016-01-12 00:04:22 +00:00
}
2016-12-21 19:11:25 +00:00
@SubscribeEvent
public void onItemLoad ( AttachCapabilitiesEvent . Item event )
{
if ( event . getItemStack ( ) . getItem ( ) = = Items . STICK )
event . addCapability ( new ResourceLocation ( " forge.testcapmod:dummy_cap " ) , new Provider ( event . getItemStack ( ) ) ) ;
}
2016-09-17 22:08:23 +00:00
@SuppressWarnings ( " rawtypes " )
@SubscribeEvent
public void attachEvent ( AttachCapabilitiesEvent event ) //Test Raw type gets everything still.
{
System . currentTimeMillis ( ) ;
}
@SubscribeEvent
public void attachTileEntity ( AttachCapabilitiesEvent < TileEntity > event )
{
if ( ! ( event . getObject ( ) instanceof TileEntity ) )
2016-12-21 19:11:25 +00:00
throw new IllegalArgumentException ( " Generic event handler failed! Expected Tile Entity got " + event . getObject ( ) ) ;
2016-09-17 22:08:23 +00:00
}
2016-01-12 00:04:22 +00:00
// Capabilities SHOULD be interfaces, NOT concrete classes, this allows for
// the most flexibility for the implementors.
public static interface IExampleCapability
{
String getOwnerType ( ) ;
2016-12-21 19:11:25 +00:00
boolean getVal ( ) ;
void toggleVal ( ) ;
2016-01-12 00:04:22 +00:00
}
// Storage implementations are required, tho there is some flexibility here.
// If you are the API provider you can also say that in order to use the default storage
// the consumer MUST use the default impl, to allow you to access innards.
// This is just a contract you will have to stipulate in the documentation of your cap.
public static class Storage implements IStorage < IExampleCapability >
{
@Override
public NBTBase writeNBT ( Capability < IExampleCapability > capability , IExampleCapability instance , EnumFacing side ) {
return null ;
}
@Override
public void readNBT ( Capability < IExampleCapability > capability , IExampleCapability instance , EnumFacing side , NBTBase nbt ) {
}
}
// You MUST also supply a default implementation.
// This is to make life easier on consumers.
public static class DefaultImpl implements IExampleCapability {
@Override
public String getOwnerType ( ) {
return " Default Implementation! " ;
}
2016-12-21 19:11:25 +00:00
public boolean getVal ( ) {
return false ;
}
@Override
public void toggleVal ( ) { }
2016-01-12 00:04:22 +00:00
}
2016-11-16 03:26:10 +00:00
}