Hihi,
I tried to make an arrow useable with the vanilla bow. It worked in older version( 1.8 maybe? one year ago) but I don't understand the code now.
I see a few possibilities:
- Add the tag ItemTags.ARROW to the custom item (but i don't know how to that)
-Maybe ArrowNockEvent?
-...
For now, the code compiles, but the arrow is not used in with the bow.
My code:
import net.minecraft.client.renderer.entity.TippedArrowRenderer;
import net.minecraft.entity.EntityType;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ActionResult;
import net.minecraft.util.ActionResultType;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.event.entity.player.ArrowNockEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.client.registry.RenderingRegistry;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import net.minecraftforge.fml.event.server.FMLServerStartingEvent;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@Mod(References.MODID)
@Mod.EventBusSubscriber(modid = References.MODID, bus = Mod.EventBusSubscriber.Bus.MOD)
public class ModClass
{
private static final Logger LOGGER = LogManager.getLogger();
private static TargetsMap targetsMap;
public ModClass()
{
MinecraftForge.EVENT_BUS.register(this);
}
@SubscribeEvent
public static void doRegisterItems(final RegistryEvent.Register<Item> event)
{
event.getRegistry().register(References.SEEKING_ITEM);
}
@SubscribeEvent
public static void doRegisterEntities(final RegistryEvent.Register<EntityType<?>> event)
{
event.getRegistry().register(References.SEEKING_ENTITY);
}
@SubscribeEvent
public static void doClientStuff(final FMLClientSetupEvent event)
{
Targeter targeter = new Targeter();
MinecraftForge.EVENT_BUS.addListener(targeter::onStartUsingBow);
MinecraftForge.EVENT_BUS.addListener(targeter::onStopUsingBow);
MinecraftForge.EVENT_BUS.addListener(targeter::onTickUsingBow);
RenderingRegistry.registerEntityRenderingHandler(SeekingEntity.class, TippedArrowRenderer::new);
}
@SubscribeEvent
public static void doServerStuff(final FMLServerStartingEvent event)
{
targetsMap = new TargetsMap();
}
@SubscribeEvent
public static void onArrowNock(final ArrowNockEvent event)
{
for(int i = 0; i < event.getPlayer().inventory.getSizeInventory(); ++i) {
ItemStack itemstack1 = event.getPlayer().inventory.getStackInSlot(i);
if (itemstack1.getItem() instanceof SeekingItem) {
event.setAction(new ActionResult<>(ActionResultType.SUCCESS, itemstack1));
}
}
}
public static TargetsMap getTargetMaps()
{
return targetsMap;
}
}
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.projectile.AbstractArrowEntity;
import net.minecraft.entity.projectile.ArrowEntity;
import net.minecraft.item.ArrowItem;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
/**
* Seeking arrow item.
* Arrow that will target the target of the player.
*/
public class SeekingItem extends ArrowItem
{
public SeekingItem(Properties builder)
{
super(builder);
}
@Override
public AbstractArrowEntity createArrow(World worldIn, ItemStack stack, LivingEntity shooter)
{
ArrowEntity arrowentity = null;
int targetID = ModClass.getTargetMaps().get(shooter);
if(targetID != -1)
{
Entity target = worldIn.getEntityByID(targetID);
if(target != null)
{
arrowentity = new SeekingEntity(worldIn, shooter, target);
}
}
if(arrowentity == null)
{
arrowentity = new ArrowEntity(worldIn, shooter);
}
arrowentity.setPotionEffect(stack);
return arrowentity;
}
}
import net.minecraft.entity.EntityClassification;
import net.minecraft.entity.EntityType;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
import net.minecraft.tags.ItemTags;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.network.NetworkRegistry;
import net.minecraftforge.fml.network.simple.SimpleChannel;
public enum References
{;
public static final String MODID = "seekingarrow";
public static final Item SEEKING_ITEM = new SeekingItem((new Item.Properties()).group(ItemGroup.COMBAT))
.setRegistryName(MODID, "seeking_item");
public static final EntityType<?> SEEKING_ENTITY =
EntityType.Builder.<SeekingEntity>create(SeekingEntity::new, EntityClassification.MISC)
.setTrackingRange(64).setUpdateInterval(20).setShouldReceiveVelocityUpdates(true)
.size(0.5F, 0.5F)
.build(MODID + ".seeking_entity").setRegistryName("seeking_entity");
private static final String PROTOCOL_VERSION = "1";
public static final SimpleChannel CHANNEL = NetworkRegistry.newSimpleChannel(
new ResourceLocation(MODID, "main"),
() -> PROTOCOL_VERSION,
PROTOCOL_VERSION::equals, // https://mcforge.readthedocs.io/en/latest/networking/simpleimpl/
PROTOCOL_VERSION::equals
);
static
{
CHANNEL.registerMessage(0,
TargetPacket.class,
TargetPacket::encode,
TargetPacket::new,
TargetPacket::handle);
ItemTags.ARROWS.getAllElements().add(SEEKING_ITEM);
}
}
Is there any problem in the code (is it clear) and am I missing something ?