CarryOn/src/main/java/tschipp/carryon/common/item/ItemCarryonEntity.java
2021-12-25 00:17:44 +01:00

285 lines
6.6 KiB
Java

package tschipp.carryon.common.item;
import java.lang.reflect.Method;
import java.util.Optional;
import javax.annotation.Nonnull;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TextComponent;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.fml.ModList;
import net.minecraftforge.fml.util.ObfuscationReflectionHelper;
import tschipp.carryon.CarryOn;
import tschipp.carryon.client.keybinds.CarryOnKeybinds;
import tschipp.carryon.common.config.Configs.Settings;
import tschipp.carryon.common.event.ItemEvents;
public class ItemCarryonEntity extends Item
{
private static final Method initGoals;
static
{
initGoals = ObfuscationReflectionHelper.findMethod(Mob.class, "m_8099_");
initGoals.setAccessible(true);
}
public static final String ENTITY_DATA_KEY = "entityData";
public ItemCarryonEntity()
{
super(new Item.Properties().stacksTo(1));
this.setRegistryName(CarryOn.MODID, "entity_item");
}
@Override
public Component getName(ItemStack stack)
{
if (hasEntityData(stack))
{
return new TranslatableComponent(getEntityType(stack).getDescriptionId());
}
return new TextComponent("");
}
public static boolean hasEntityData(ItemStack stack)
{
if (stack.hasTag())
{
CompoundTag tag = stack.getTag();
return tag.contains(ENTITY_DATA_KEY) && tag.contains("entity");
}
return false;
}
public static boolean storeEntityData(@Nonnull Entity entity, Level level, ItemStack stack)
{
if (entity == null || stack.isEmpty())
return false;
CompoundTag entityData = new CompoundTag();
entity.saveWithoutId(entityData);
String name = EntityType.getKey(entity.getType()).toString();
CompoundTag tag = stack.hasTag() ? stack.getTag() : new CompoundTag();
if (tag.contains(ENTITY_DATA_KEY))
return false;
tag.put(ENTITY_DATA_KEY, entityData);
tag.putString("entity", name);
stack.setTag(tag);
return true;
}
@Override
public InteractionResult useOn(UseOnContext context)
{
Player player = context.getPlayer();
Level level = context.getLevel();
BlockPos pos = context.getClickedPos();
Direction facing = context.getClickedFace();
ItemStack stack = context.getItemInHand();
BlockState state = level.getBlockState(pos);
if (ModList.get().isLoaded("betterplacement") && CarryOnKeybinds.isKeyPressed(player))
return InteractionResult.FAIL;
if (hasEntityData(stack))
{
BlockPos finalPos = pos;
if (!state.canBeReplaced(new BlockPlaceContext(context)))
{
finalPos = pos.relative(facing);
}
Entity entity = getEntity(stack, level);
if (entity != null)
{
if (!level.isClientSide)
{
entity.absMoveTo(finalPos.getX() + 0.5, finalPos.getY(), finalPos.getZ() + 0.5, 180 + player.yHeadRot, 0.0f);
level.addFreshEntity(entity);
if (entity instanceof Mob)
{
((Mob) entity).playAmbientSound();
}
clearEntityData(stack);
player.setItemInHand(InteractionHand.MAIN_HAND, ItemStack.EMPTY);
ItemEvents.sendPacket(player, 9, 0);
}
player.getPersistentData().remove("overrideKey");
return InteractionResult.SUCCESS;
}
}
return InteractionResult.FAIL;
}
@Override
public void inventoryTick(ItemStack stack, Level level, Entity entity, int itemSlot, boolean isSelected)
{
if (hasEntityData(stack))
{
if (getEntity(stack, level) == null)
stack = ItemStack.EMPTY;
if (entity instanceof LivingEntity)
{
if (entity instanceof Player && Settings.slownessInCreative.get() ? false : ((Player) entity).isCreative())
return;
((LivingEntity) entity).addEffect(new MobEffectInstance(MobEffects.MOVEMENT_SLOWDOWN, 1, this.potionLevel(stack, level), false, false));
}
}
else
{
stack = ItemStack.EMPTY;
}
}
public static void clearEntityData(ItemStack stack)
{
if (stack.hasTag())
{
CompoundTag tag = stack.getTag();
tag.remove(ENTITY_DATA_KEY);
tag.remove("entity");
}
}
public static CompoundTag getPersistentData(ItemStack stack)
{
if (stack.hasTag())
{
CompoundTag tag = stack.getTag();
return tag.getCompound(ENTITY_DATA_KEY);
}
return null;
}
public static Entity getEntity(ItemStack stack, Level level)
{
if (level == null)
return null;
String name = getEntityName(stack);
CompoundTag e = getPersistentData(stack);
Optional<EntityType<?>> type = EntityType.byString(name);
Entity entity = null;
if (type.isPresent())
{
entity = type.get().create(level);
}
if (entity != null)
{
try
{
if (entity instanceof Mob)
initGoals.invoke(entity);
entity.deserializeNBT(e);
}
catch (Exception e1)
{
try
{
entity.deserializeNBT(e);
}
catch (Exception e2)
{
}
}
}
return entity;
}
public static String getEntityName(ItemStack stack)
{
if (stack.hasTag())
{
CompoundTag tag = stack.getTag();
return tag.getString("entity");
}
return null;
}
public static String getCustomName(ItemStack stack)
{
if (stack.hasTag())
{
CompoundTag tag = stack.getTag();
if (tag.contains("CustomName") && !tag.getString("CustomName").isEmpty())
{
return tag.toString();
}
else
{
return tag.toString();
}
}
return null;
}
public static EntityType<?> getEntityType(ItemStack stack)
{
if (stack.hasTag())
{
CompoundTag tag = stack.getTag();
String name = tag.getString("entity");
Optional<EntityType<?>> type = EntityType.byString(name);
if (type.isPresent())
return type.get();
}
return null;
}
private int potionLevel(ItemStack stack, Level level)
{
Entity e = getEntity(stack, level);
if (e == null)
return 1;
int i = (int) (e.getBbHeight() * e.getBbWidth());
if (i > 4)
i = 4;
if (!Settings.heavyEntities.get())
i = 1;
double multiplier = Settings.entitySlownessMultiplier.get();
return (int) (multiplier * i);
}
}