Hello guys, I'm relative new to Minecraft Modding and Java coding in general. I've tried to make a clawshot out of The Legend of Zelda: Twilight Princess (and plan a double clawshot). On use it shoots an Clawshot_Head and "drags" the player to the place where it hits a block, or "drags" enemies it hits to the player. For this it has a maximum range for all this. The normal clawshot shoots max. 1 head so if you try to use it while you hang somewhere you fall down.
So that was the theory.
Here's what it actually does. The clawshot does nothing. And if I spawn with /summon the head it's simply a 1 block tall and 0.5 block wide box colored White. The code of the Head is mostly based on the Fishing hook. I know you all Always struggle with that, so I tell you what I think the problem is and hope somebody can confirm this or at least say me that I forgot something important:
So what I found out is that there's no registration of the fishinghook. As I use the same concept but don't know how to registrate this could cause the problem.
My Clawshot.class:
import com.cruelar.cruelars_triforcemod.Cruelars_Triforcemod_Core;
import com.cruelar.cruelars_triforcemod.entities.projectiles.Clawshot_Head;
import com.cruelar.cruelars_triforcemod.inventory.cruelars_triforcemod;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.IItemPropertyGetter;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ActionResult;
import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumHand;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import javax.annotation.Nullable;
import java.util.Objects;
public class Clawshot_TP extends Item {
public Clawshot_TP(){
this.setCreativeTab(cruelars_triforcemod.CRUELARS_TRIFORCEMOD);
this.setRegistryName("clawshot_tp");
this.setUnlocalizedName(Cruelars_Triforcemod_Core.MODID+".clawshot_tp");
this.addPropertyOverride(new ResourceLocation("cast"), new IItemPropertyGetter() {
@SideOnly(Side.CLIENT)
public float apply(ItemStack p_apply_1_, @Nullable World p_apply_2_, @Nullable EntityLivingBase p_apply_3_) {
if (p_apply_3_ == null) {
return 0.0F;
} else {
boolean lvt_4_1_ = p_apply_3_.getHeldItemMainhand() == p_apply_1_;
boolean lvt_5_1_ = p_apply_3_.getHeldItemOffhand() == p_apply_1_;
if (p_apply_3_.getHeldItemMainhand().getItem() instanceof Clawshot_TP) {
lvt_5_1_ = false;
}
return (lvt_4_1_ || lvt_5_1_) && p_apply_3_ instanceof EntityPlayer && ((EntityPlayer)p_apply_3_).fishEntity != null ? 1.0F : 0.0F;
}
}
});
}
@Override
public ActionResult<ItemStack> onItemRightClick(World world, EntityPlayer entityPlayer, EnumHand enumHand) {
ItemStack itemStack = entityPlayer.getHeldItem(EnumHand.MAIN_HAND);
Item item = entityPlayer.getHeldItemMainhand().getItem();
if (item == this) {
if (!world.isRemote) {
Clawshot_Head clawshot_head = new Clawshot_Head(world,entityPlayer);
world.spawnEntity(clawshot_head);
}
}
return new ActionResult(EnumActionResult.SUCCESS,itemStack);
}
@SideOnly(Side.CLIENT)
public void initModel(){
ModelLoader.setCustomModelResourceLocation(this, 0, new ModelResourceLocation(Objects.requireNonNull(getRegistryName()), "inventory"));
}
}
And his head (Clawshot_Head.class):
import net.minecraft.entity.Entity;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.projectile.EntityFishHook;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.datasync.DataParameter;
import net.minecraft.network.datasync.DataSerializers;
import net.minecraft.network.datasync.EntityDataManager;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import java.util.Iterator;
import java.util.List;
public class Clawshot_Head extends Entity{
private EntityPlayer entityPlayer;
public Entity caughtEntity;
public Clawshot_Head.State currentState;
private static final DataParameter<Integer> DATA_HOOKED_ENTITY;
private boolean inGround;
private int ticksInAir;
public static ResourceLocation RESOURCE_LOCATION=new ResourceLocation("cruelars_triforcemod:textures/entity/projectiles/clawshot_head.png");
public Clawshot_Head(World world){
super(world);
this.shoot((EntityPlayer)null);
}
public Clawshot_Head(World world, EntityPlayer entityPlayer){
super(world);
this.init(entityPlayer);
this.currentState = Clawshot_Head.State.FLYING;
this.setPosition((double)entityPlayer.posX,(double)entityPlayer.posY+entityPlayer.getEyeHeight(),(double)entityPlayer.posX);
this.shoot(entityPlayer);
}
@SideOnly(Side.CLIENT)
public Clawshot_Head(World world, EntityPlayer entityPlayer, double posX, double posY, double posZ) {
super(world);
this.init(entityPlayer);
this.setPosition(posX,posY,posZ);
this.prevPosX = this.posX;
this.prevPosY = this.posY;
this.prevPosZ = this.posZ;
}
public void notifyDataManagerChange(DataParameter<?> p_notifyDataManagerChange_1_) {
if (DATA_HOOKED_ENTITY.equals(p_notifyDataManagerChange_1_)) {
int i = (Integer)this.getDataManager().get(DATA_HOOKED_ENTITY);
this.caughtEntity = i > 0 ? this.world.getEntityByID(i - 1) : null;
}
super.notifyDataManagerChange(p_notifyDataManagerChange_1_);
}
public void shoot(Entity entity){
this.motionX=0.6D*entity.getLookVec().x;
this.motionY=0.6D*entity.getLookVec().y;
this.motionZ=0.6D*entity.getLookVec().z;
}
public void shoot(double p_shoot_1_, double p_shoot_3_, double p_shoot_5_, float p_shoot_7_, float p_shoot_8_){}
private void init(EntityPlayer p_init_1_) {
this.setSize(0.25F, 0.25F);
this.ignoreFrustumCheck = true;
this.entityPlayer = p_init_1_;
}
private void checkCollision() {
Vec3d vec3d = new Vec3d(this.posX, this.posY, this.posZ);
Vec3d vec3d1 = new Vec3d(this.posX + this.motionX, this.posY + this.motionY, this.posZ + this.motionZ);
RayTraceResult raytraceresult = this.world.rayTraceBlocks(vec3d, vec3d1, false, true, false);
vec3d = new Vec3d(this.posX, this.posY, this.posZ);
vec3d1 = new Vec3d(this.posX + this.motionX, this.posY + this.motionY, this.posZ + this.motionZ);
if (raytraceresult != null) {
vec3d1 = new Vec3d(raytraceresult.hitVec.x, raytraceresult.hitVec.y, raytraceresult.hitVec.z);
entityPlayer.posX=this.posX;
entityPlayer.posY=this.posY;
entityPlayer.posZ=this.posZ;
}
Entity entity = null;
List<Entity> list = this.world.getEntitiesWithinAABBExcludingEntity(this, this.getEntityBoundingBox().expand(this.motionX, this.motionY, this.motionZ).grow(1.0D));
double d0 = 0.0D;
Iterator var8 = list.iterator();
while(true) {
Entity entity1;
double d1;
do {
RayTraceResult raytraceresult1;
do {
do {
do {
if (!var8.hasNext()) {
if (entity != null) {
raytraceresult = new RayTraceResult(entity);
}
if (raytraceresult != null && raytraceresult.typeOfHit != RayTraceResult.Type.MISS) {
if (raytraceresult.typeOfHit == RayTraceResult.Type.ENTITY) {
this.caughtEntity = raytraceresult.entityHit;
this.setHookedEntity();
} else {
this.inGround = true;
}
}
return;
}
entity1 = (Entity)var8.next();
} while(!this.canBeHooked(entity1));
} while(entity1 == this.entityPlayer && this.ticksInAir < 5);
AxisAlignedBB axisalignedbb = entity1.getEntityBoundingBox().grow(0.30000001192092896D);
raytraceresult1 = axisalignedbb.calculateIntercept(vec3d, vec3d1);
} while(raytraceresult1 == null);
d1 = vec3d.squareDistanceTo(raytraceresult1.hitVec);
} while(d1 >= d0 && d0 != 0.0D);
entity = entity1;
d0 = d1;
}
}
private void setHookedEntity() {
this.getDataManager().set(DATA_HOOKED_ENTITY, this.caughtEntity.getEntityId() + 1);
}
protected boolean canBeHooked(Entity p_canBeHooked_1_) {
return p_canBeHooked_1_.canBeCollidedWith() || p_canBeHooked_1_ instanceof EntityItem;
}
protected void entityInit() {
this.getDataManager().register(DATA_HOOKED_ENTITY, 0);
}
@Override
protected void readEntityFromNBT(NBTTagCompound nbtTagCompound) {
}
@Override
protected void writeEntityToNBT(NBTTagCompound nbtTagCompound) {
}
static {
DATA_HOOKED_ENTITY = EntityDataManager.createKey(EntityFishHook.class, DataSerializers.VARINT);
}
static enum State {
FLYING,
HOOKED_IN_ENTITY;
private State() {
}
}
}
For Registration:
In ModItems:
import com.cruelar.cruelars_triforcemod.Cruelars_Triforcemod_Core;
import com.cruelar.cruelars_triforcemod.items.*;
import net.minecraft.client.renderer.ItemMeshDefinition;
import net.minecraft.client.renderer.ItemModelMesher;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.client.resources.IReloadableResourceManager;
import net.minecraft.client.resources.IResourceManagerReloadListener;
import net.minecraft.init.Items;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.Item;
import net.minecraft.item.ItemArmor;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumHand;
import net.minecraftforge.common.util.EnumHelper;
import net.minecraftforge.fml.common.Optional;
import net.minecraftforge.fml.common.registry.GameRegistry;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class ModItems {
...
@GameRegistry.ObjectHolder("cruelars_triforcemod:clawshot_tp")
public static Clawshot_TP clawshot_tp;
...
@SideOnly(Side.CLIENT)
public static void initModels(){
...
clawshot_tp.initModel();
...
}
}
In CommonProxy:
import com.cruelar.cruelars_triforcemod.*;
import com.cruelar.cruelars_triforcemod.init.ModArmor;
import com.cruelar.cruelars_triforcemod.init.ModBlocks;
import com.cruelar.cruelars_triforcemod.init.ModEntities;
import com.cruelar.cruelars_triforcemod.init.ModItems;
import com.cruelar.cruelars_triforcemod.blocks.*;
import com.cruelar.cruelars_triforcemod.items.*;
import com.cruelar.cruelars_triforcemod.tileentity.False_Block_TileEntity;
import com.cruelar.cruelars_triforcemod.tileentity.Hidden_Block_TileEntity;
import com.cruelar.cruelars_triforcemod.tileentity.Pedestal_Of_Time_TileEntity;
import net.minecraft.inventory.EntityEquipmentSlot;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.potion.PotionType;
import net.minecraft.world.storage.loot.LootTableList;
import net.minecraftforge.common.config.Configuration;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Optional;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.network.NetworkRegistry;
import net.minecraftforge.fml.common.registry.GameRegistry;
import java.io.File;
import java.util.Objects;
import static com.cruelar.cruelars_triforcemod.Cruelars_Triforcemod_Core.instance;
@Mod.EventBusSubscriber(modid = Cruelars_Triforcemod_Core.MODID)
public class CommonProxy {
public static Configuration config;
public void preInit(FMLPreInitializationEvent event) {
File directory = event.getModConfigurationDirectory();
config = new Configuration(new File(directory.getPath(),"cruelars_triforcemod.cfg"));
Config.readConfig();
ModEntities.init();
}
...
@SubscribeEvent
public static void registerItems(RegistryEvent.Register<Item> event){
...
event.getRegistry().register(new Clawshot_TP());
...
}
}
In Mod Entities:
import com.cruelar.cruelars_triforcemod.Cruelars_Triforcemod_Core;
import com.cruelar.cruelars_triforcemod.entities.EntityBombPrimed;
import com.cruelar.cruelars_triforcemod.entities.boss.*;
import com.cruelar.cruelars_triforcemod.entities.monster.*;
import com.cruelar.cruelars_triforcemod.entities.passive.Fairy;
import com.cruelar.cruelars_triforcemod.entities.projectiles.*;
import com.cruelar.cruelars_triforcemod.renderer.*;
import net.minecraft.entity.EnumCreatureType;
import net.minecraft.init.Biomes;
import net.minecraft.world.storage.loot.LootTableList;
import net.minecraftforge.fml.client.registry.RenderingRegistry;
import net.minecraftforge.fml.common.registry.EntityRegistry;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class ModEntities {
public static void init(){
int id = 1;
... // current id is 14
EntityRegistry.registerModEntity(Clawshot_Head.RESOURCE_LOCATION,Clawshot_Head.class,"cruelars_triforcemod:clawshot_head",id++,Cruelars_Triforcemod_Core.instance,64,3,true);
...
}
@SideOnly(Side.CLIENT)
public static void initModels(){
...
RenderingRegistry.registerEntityRenderingHandler(Clawshot_Head.class,RenderClawshot.FACTORY);
...
}
}
Rendering of the Head:
import com.cruelar.cruelars_triforcemod.entities.projectiles.Clawshot_Head;
import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.renderer.entity.RenderEntity;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.client.registry.IRenderFactory;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public class RenderClawshot extends RenderEntity {
public static final ResourceLocation RES_ARROW = new ResourceLocation("textures/entity/projectiles/arrow.png");
public static final ResourceLocation RES_Bomb_ARROW = new ResourceLocation("textures/entity/projectiles/clawshot_head.png");
public static final Factory FACTORY = new Factory();
public RenderClawshot(RenderManager p_i46547_1_) {
super(p_i46547_1_);
}
protected ResourceLocation getEntityTexture() {
return Clawshot_Head.RESOURCE_LOCATION;
}
public static class Factory implements IRenderFactory<Clawshot_Head> {
@Override
public Render<? super Clawshot_Head> createRenderFor(RenderManager manager){
return new RenderClawshot(manager);
}
}
}
Any advise on creating topics is also helpful, because I'm german and new to this.