Jump to content

Recommended Posts

Posted

Also sometimes is not tamed when spawned. So i want that my custom horse is by default tamed and with a saddle. I've this class but as you can see in the video below the horse spawns tamed but without a saddle (or sometimes even spawn not tamed)

package blaze.entities;

import java.util.Iterator;
import java.util.List;

import com.google.common.base.Predicate;

import blaze.core.BLItems;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityAgeable;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.EnumCreatureAttribute;
import net.minecraft.entity.IEntityLivingData;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.ai.EntityAIFollowParent;
import net.minecraft.entity.ai.EntityAILookIdle;
import net.minecraft.entity.ai.EntityAIMate;
import net.minecraft.entity.ai.EntityAINearestAttackableTarget;
import net.minecraft.entity.ai.EntityAIPanic;
import net.minecraft.entity.ai.EntityAIRunAroundLikeCrazy;
import net.minecraft.entity.ai.EntityAISwimming;
import net.minecraft.entity.ai.EntityAITempt;
import net.minecraft.entity.ai.EntityAIWander;
import net.minecraft.entity.ai.EntityAIWatchClosest;
import net.minecraft.entity.ai.attributes.IAttribute;
import net.minecraft.entity.ai.attributes.IAttributeInstance;
import net.minecraft.entity.ai.attributes.RangedAttribute;
import net.minecraft.entity.monster.EntitySkeleton;
import net.minecraft.entity.passive.EntityAnimal;
import net.minecraft.entity.passive.EntityHorse;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.inventory.AnimalChest;
import net.minecraft.inventory.IInvBasic;
import net.minecraft.inventory.InventoryBasic;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.pathfinding.PathNavigateGround;
import net.minecraft.potion.Potion;
import net.minecraft.server.management.PreYggdrasilConverter;
import net.minecraft.util.BlockPos;
import net.minecraft.util.DamageSource;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.util.MathHelper;
import net.minecraft.util.StatCollector;
import net.minecraft.world.DifficultyInstance;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;

public class EntityWitherHorse extends EntityHorse implements IInvBasic
{
private static final IAttribute horseJumpStrength = (new RangedAttribute((IAttribute)null, "horse.jumpStrength", 0.7D, 0.0D, 2.0D)).setDescription("Jump Strength").setShouldWatch(true);
private static final String[] horseTextures = new String[] {"blaze:textures/entity/mobs/horse_skeleton_wither"};
private int eatingHaystackCounter;
private int openMouthCounter;
private int jumpRearingCounter;
private float rearingAmount;
private float prevRearingAmount;
private float mouthOpenness;
private float prevMouthOpenness;
private AnimalChest horseChest;

public EntityWitherHorse(World worldIn)
{
	super(worldIn);
	this.isImmuneToFire = true;
	this.func_110226_cD();
}

private void func_110226_cD()
    {
        AnimalChest animalchest = this.horseChest;
        this.horseChest = new AnimalChest("HorseChest", this.func_110225_cC());
        this.horseChest.setCustomName(this.getName());

        if (animalchest != null)
        {
            animalchest.func_110132_b(this);
            int i = Math.min(animalchest.getSizeInventory(), this.horseChest.getSizeInventory());

            for (int j = 0; j < i; ++j)
            {
                ItemStack itemstack = animalchest.getStackInSlot(j);

                if (itemstack != null)
                {
                    this.horseChest.setInventorySlotContents(j, itemstack.copy());
                }
            }
        }

        this.horseChest.func_110134_a(this);
        this.func_110232_cE();
    }

private void func_110232_cE()
    {
        if (!this.worldObj.isRemote)
        {
            this.setHorseSaddled(this.horseChest.getStackInSlot(0) != null);

            if (this.canWearArmor())
            {
                this.setHorseArmorStack(this.horseChest.getStackInSlot(1));
            }
        }
    }

private int func_110225_cC()
    {
        int i = this.getHorseType();
        return this.isChested() && (i == 1 || i == 2) ? 17 : 2;
    }

protected void entityInit()
{
	super.entityInit();
}

/**
 * Gets the name of this command sender (usually username, but possibly "Rcon")
 */
public String getName()
{
	if (this.hasCustomName())
	{
		return this.getCustomNameTag();
	}
	else
	{
		return StatCollector.translateToLocal("entity.witherskeletonhorse.name");       
	}
}

private void setHorseWatchableBoolean(int par1, boolean par2)
{
	int j = this.dataWatcher.getWatchableObjectInt(16);

	if (par2)
	{
		this.dataWatcher.updateObject(16, Integer.valueOf(j | par1));
	}
	else
	{
		this.dataWatcher.updateObject(16, Integer.valueOf(j & ~par1));
	}
}

/**
 * Returns the sound this mob makes on death.
 */
protected String getDeathSound()
{
	this.openHorseMouth();
	return "mob.horse.skeleton.death";
}

protected Item getDropItem()
{
	boolean flag = this.rand.nextInt(4) == 0;
	return flag ? Items.coal : Items.bone;
}

/**
 * Returns the sound this mob makes when it is hurt.
 */
protected String getHurtSound()
{
	this.openHorseMouth();

	if (this.rand.nextInt(3) == 0)
	{
		this.makeHorseRear();
	}

	return "mob.horse.skeleton.hit";
}

/**
 * Returns the sound this mob makes while it's alive.
 */
protected String getLivingSound()
{
	this.openHorseMouth();

	if (this.rand.nextInt(10) == 0 && !this.isMovementBlocked())
	{
		this.makeHorseRear();
	}

	return "mob.horse.skeleton.idle";
}

/**
 * Dead and sleeping entities cannot move
 */
protected boolean isMovementBlocked()
{
	return false;
}

@Override
public boolean canWearArmor()
    {
        return false;
    }

/**
 * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons
 * use this to react to sunlight and start to burn.
 */
@Override
public void onLivingUpdate()
{
	super.onLivingUpdate();

	float f = (float)this.getEntityBoundingBox().minY;
	float f1 = (this.rand.nextFloat() * 2.0F - 1.0F) * this.width * 0.5F;
	float f2 = (this.rand.nextFloat() * 2.0F - 1.0F) * this.width * 0.5F;
	if(this.rand.nextInt(5) == 0)
	{    			
		this.worldObj.spawnParticle(EnumParticleTypes.SMOKE_NORMAL, this.posX + (double)f1, (double)(f + 0.8F), this.posZ + (double)f2, this.motionX, this.motionY, this.motionZ, new int[0]);
	}

	this.worldObj.spawnParticle(EnumParticleTypes.SPELL_MOB, this.posX + (double)f1, (double)(f + 0.8F), this.posZ + (double)f2, this.motionX, this.motionY, this.motionZ, new int[0]);
}

private void openHorseMouth()
{
	if (!this.worldObj.isRemote)
	{
		this.openMouthCounter = 1;
		this.setHorseWatchableBoolean(128, true);
	}
}

private void makeHorseRear()
{
	if (!this.worldObj.isRemote)
	{
		this.jumpRearingCounter = 1;
		this.setRearing(true);
	}
}

@Override
public boolean isEntityInvulnerable(DamageSource source)
{
	if(source.damageType.equals("lightningBolt"))
		return true;
	else
		return false;
}

public IEntityLivingData func_180482_a(DifficultyInstance difficulty, IEntityLivingData entity)
{
	Object object = super.func_180482_a(difficulty, entity);
	boolean flag = false;
	int i = 0;
	int l;

	this.setHorseSaddled(true);
	this.horseChest.setInventorySlotContents(0, new ItemStack(Items.saddle));
	this.setHorseTamed(true);

	EntityWitherSkeleton entityskeleton = new EntityWitherSkeleton(this.worldObj);
	entityskeleton.setLocationAndAngles(this.posX, this.posY, this.posZ, this.rotationYaw, 0.0F);
	entityskeleton.func_180482_a(difficulty, (IEntityLivingData)null);
	this.worldObj.spawnEntityInWorld(entityskeleton);
	entityskeleton.mountEntity(this);

	if (object instanceof EntityWitherHorse.GroupData)
	{
		l = ((EntityWitherHorse.GroupData)object).field_111107_a;
		i = ((EntityWitherHorse.GroupData)object).field_111106_b & 255 | this.rand.nextInt(5) << 8;
	}
	else
	{
		if (this.rand.nextInt(10) == 0)
		{
			l = 1;
		}
		else
		{
			int j = this.rand.nextInt(7);
			int k = this.rand.nextInt(5);
			l = 0;
			i = j | k << 8;
		}

		object = new EntityWitherHorse.GroupData(l, i);
	}

	this.setHorseType(l);
	this.setHorseVariant(i);

	if (this.rand.nextInt(5) == 0)
	{
		this.setGrowingAge(-24000);
	}

	if (l != 4 && l != 3)
	{
		this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue((double)this.func_110267_cL());

		if (l == 0)
		{
			this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(this.func_110203_cN());
		}
		else
		{
			this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.17499999701976776D);
		}
	}
	else
	{
		this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(15.0D);
		this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.20000000298023224D);
	}

	if (l != 2 && l != 1)
	{
		this.getEntityAttribute(horseJumpStrength).setBaseValue(this.func_110245_cM());
	}
	else
	{
		this.getEntityAttribute(horseJumpStrength).setBaseValue(0.5D);
	}

	this.setHealth(this.getMaxHealth());
	return (IEntityLivingData)object;
}

@SideOnly(Side.CLIENT)
public float getRearingAmount(float par1)
{
	return this.prevRearingAmount + (this.rearingAmount - this.prevRearingAmount) * par1;
}

@SideOnly(Side.CLIENT)
public float func_110201_q(float par1)
{
	return this.prevMouthOpenness + (this.mouthOpenness - this.prevMouthOpenness) * par1;
}


private float func_110267_cL()
{
	return 15.0F + (float)this.rand.nextInt( + (float)this.rand.nextInt(9);
}

private double func_110245_cM()
{
	return 0.4000000059604645D + this.rand.nextDouble() * 0.2D + this.rand.nextDouble() * 0.2D + this.rand.nextDouble() * 0.2D;
}

private double func_110203_cN()
{
	return (0.44999998807907104D + this.rand.nextDouble() * 0.3D + this.rand.nextDouble() * 0.3D + this.rand.nextDouble() * 0.3D) * 0.25D;
}

public static class GroupData implements IEntityLivingData
{
	public int field_111107_a;
	public int field_111106_b;

	public GroupData(int par1, int par2)
	{
		this.field_111107_a = par1;
		this.field_111106_b = par2;
	}
}
}

Video here:

https://www.youtube.com/watch?v=XDGvPwquDgg&feature=youtu.be

is ther something that i'm missing?

Don't blame me if i always ask for your help. I just want to learn to be better :)

Posted

EntityHorse already implements IInvBasic. Is it really necessary to restate that?

 

Modding horses is tricky. I read that horses started as somebody's mod some years ago, and then they were absorbed into vanilla. One consequence is that several things (e.g. horse armor) that should be coded elsewhere are wedged into entity horse. Private data and enums don't help, but reflection can sometimes.

 

I think there's already a skeletal horse coded into vanilla (at least there was), but it's not used. See getHorseType() and setHorseType(). You might be able to get a lot of mileage out of what's there so you wouldn't need to copy so much code into your own class.

The debugger is a powerful and necessary tool in any IDE, so learn how to use it. You'll be able to tell us more and get better help here if you investigate your runtime problems in the debugger before posting.

Posted

The skeleton horse code is in the EntityHorse class :) For the armor i've tried overriding the get/setHorseType function to return 0, but nothing changed. What i'm trying to figure out is why the horse sometimes spawned un-tamed and i can't tame it :/

Don't blame me if i always ask for your help. I just want to learn to be better :)

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.