package choonster.testmod3.capability.lastusetime;
import choonster.testmod3.TestMod3;
import choonster.testmod3.api.capability.lastusetime.ILastUseTime;
import choonster.testmod3.capability.CapabilityContainerListenerManager;
import choonster.testmod3.capability.CapabilityProviderSerializable;
import choonster.testmod3.item.IItemPropertyGetterFix;
import choonster.testmod3.util.CapabilityUtils;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.IItemPropertyGetter;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagLong;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.CapabilityInject;
import net.minecraftforge.common.capabilities.CapabilityManager;
import net.minecraftforge.common.capabilities.ICapabilityProvider;
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import javax.annotation.Nullable;
/**
* Capability for {@link ILastUseTime}.
*
* @author Choonster
*/
public final class CapabilityLastUseTime {
/**
* The {@link Capability} instance.
*/
@CapabilityInject(ILastUseTime.class)
public static final Capability<ILastUseTime> LAST_USE_TIME_CAPABILITY = null;
/**
* The default {@link EnumFacing} to use for this capability.
*/
public static final EnumFacing DEFAULT_FACING = null;
/**
* The ID of this capability.
*/
public static final ResourceLocation ID = new ResourceLocation(TestMod3.MODID, "LastUseTime");
public static void register() {
CapabilityManager.INSTANCE.register(ILastUseTime.class, new Capability.IStorage<ILastUseTime>() {
@Override
public NBTBase writeNBT(final Capability<ILastUseTime> capability, final ILastUseTime instance, final EnumFacing side) {
return new NBTTagLong(instance.get());
}
@Override
public void readNBT(final Capability<ILastUseTime> capability, final ILastUseTime instance, final EnumFacing side, final NBTBase nbt) {
instance.set(((NBTTagLong) nbt).getLong());
}
}, () -> new LastUseTime(true));
CapabilityContainerListenerManager.registerListenerFactory(ContainerListenerLastUseTime::new);
}
/**
* Get the {@link ILastUseTime} from the specified {@link ItemStack}'s capabilities, if any.
*
* @param itemStack The ItemStack
* @return The ILastUseTime, or null if there isn't one
*/
@Nullable
public static ILastUseTime getLastUseTime(final ItemStack itemStack) {
return CapabilityUtils.getCapability(itemStack, LAST_USE_TIME_CAPABILITY, DEFAULT_FACING);
}
/**
* Update the last use time of the player's held item.
*
* @param player The player
* @param itemStack The held ItemStack
*/
public static void updateLastUseTime(final EntityPlayer player, final ItemStack itemStack) {
final ILastUseTime lastUseTime = getLastUseTime(itemStack);
if (lastUseTime == null) return;
final World world = player.getEntityWorld();
lastUseTime.set(world.getTotalWorldTime());
}
/**
* Create a provider for the default {@link ILastUseTime} instance.
*
* @return The provider
*/
public static ICapabilityProvider createProvider() {
return new CapabilityProviderSerializable<>(LAST_USE_TIME_CAPABILITY, DEFAULT_FACING);
}
/**
* Create a provider for the specified {@link ILastUseTime} instance.
*
* @param lastUseTime The ILastUseTime
* @return The provider
*/
public static ICapabilityProvider createProvider(final ILastUseTime lastUseTime) {
return new CapabilityProviderSerializable<>(LAST_USE_TIME_CAPABILITY, DEFAULT_FACING, lastUseTime);
}
/**
* Event handler for the {@link ILastUseTime} capability.
*/
@Mod.EventBusSubscriber
public static class EventHandler {
/**
* Update the {@link ILastUseTime} of the player's held item when they right click.
*
* @param event The event
*/
@SubscribeEvent
public static void playerInteract(final PlayerInteractEvent.RightClickItem event) {
final ItemStack itemStack = event.getItemStack();
final ILastUseTime lastUseTime = getLastUseTime(itemStack);
if (lastUseTime != null && lastUseTime.automaticUpdates()) {
updateLastUseTime(event.getEntityPlayer(), itemStack);
}
}
}
/**
* {@link IItemPropertyGetter} to get the ticks since the last use of the item. Returns {@link Float#MAX_VALUE} if the required information isn't available.
*/
public static class TicksSinceLastUseGetter {
/**
* The ID of this getter.
*/
private static final ResourceLocation ID = new ResourceLocation(TestMod3.MODID, "ticksSinceLastUse");
/**
* The getter.
*/
private static final IItemPropertyGetter GETTER = IItemPropertyGetterFix.create((stack, worldIn, entityIn) -> {
final ILastUseTime lastUseTime = getLastUseTime(stack);
final World world = worldIn != null ? worldIn : entityIn != null ? entityIn.getEntityWorld() : null;
return lastUseTime != null && world != null ? world.getTotalWorldTime() - lastUseTime.get() : Float.MAX_VALUE;
});
/**
* Add this getter to an {@link Item}.
*
* @param item The item
*/
public static void addToItem(final Item item) {
item.addPropertyOverride(ID, GETTER);
}
}
}