Jump to content

Recommended Posts

Posted

Warning: I'm new to modding

 

Hi, as you probably guessed from the title, I want to try to make a block that, when activated with redstone, it will shear a sheep standing above it. I think I know how to do the activated with redstone part by just overriding onNeighborBlockChange(), however the shearing part kind of confuses me. I looked at the code for shears, but it uses  itemInteractionForEntity() which is used for when you right-click on an entity with an item so I don't think that I will be able to use that. I tried to alter the shears code to work with a block but I wasn't really able to get it to work correctly. Again, I am new to modding so this might be something really obvious.

Help is appreciated!

Thanks!

 

Posted

Shears appear to function by checking if the entity you have right clicked is shearable and, if so, performing the necessary functions. All you have to do is find a way to get what entity is standing on your block. Check out the onEntityWalking method. The final parameter is the entity, which you can then manipulate the same way shears do. Good luck!

Posted

Don't use onEntityWalking.  It's flaky and you'd have to figure out how to determine powered status (and sending the redstone signal wouldn't do anything!  You'd need the signal, then the walking!)

 

Look at pressure plates instead.  There's a world.getEntitiesInAABB function.  You'll want to copy that and add it to the onNeighborBlockChanged function (or wherever you're getting your redstone activation at) and do your shearing inside there.  Look at the sheers to see how they work.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted

Ok, so I got the block to be able to do things when a sheep walks on it just not shearing it. I looked in the IShearable class and found this:

public ArrayList<ItemStack> onSheared(ItemStack item, World world, int x, int y, int z, int fortune);

This should apparently preform all of the actions related to being sheared, but I'm not completely sure how to use this. I immediately see a problem with this in that there is a fortune variable which a block obviously won't have. This is my current code:

public void shearSheep(int x, int y, int z, Entity target)
{

}

@Override
public void onEntityWalking(World world, int x, int y, int z, Entity entity)
{
IShearable target = (IShearable)entity;
if(!world.isRemote && target.isShearable(null, entity.worldObj, (int)entity.posX, (int)entity.posY, (int)entity.posZ))
{
	shearSheep((int)entity.posX, (int)entity.posY, (int)entity.posZ, entity);
}
}

As you can see, the shearSheep() method is empty. I think the onSheared() method is supposed to be for items. Anyone have any ideas?

Posted

Hi

 

onSheared is applied to the sheep not the item

 

Have a look in

EntitySheep.onSheared

it's pretty simple and it doesn't even use any of the parameters you give it.

 

What you should do is just call EntitySheep.onSheared yourself, it will return an ArrayList containing one or more wool, see ItemShears.itemInteractionWithEntity to see what to do with it.  (Or just ignore if you don't care about the wool)

 

Alternatively you could call ItemShears.itemInteractionWithEntity, giving it the parameter it expects (eg a dummy shears and the sheep you want to shear).

 

-TGG

 

Posted

Sorry, but I'm not sure what you mean. I understand that I can call EntitySheep.onSheared() in my shearSheep method, but I don't understand the bit about not using parameters. I see that the actual EntitySheep.onSheared method does not use any of the parameters you give it, but I still have to put them in when I call it. Am I just able to put whatever I want(assuming it's the correct variable type)? I doubt I'm understanding what you mean. :)

Posted

Hmm, ok. If I understood you correctly, I believe this is what I should have:

public void shearSheep(World world, int x, int y, int z, Entity target)
{
EntitySheep.onSheared(null, world, (int)target.posX, (int)target.posY, (int)target.posZ, 3);
}

@Override
public void onEntityWalking(World world, int x, int y, int z, Entity entity)
{
IShearable target = (IShearable)entity;
if(!world.isRemote && target.isShearable(null, entity.worldObj, (int)entity.posX, (int)entity.posY, (int)entity.posZ))
{
	shearSheep(world, (int)entity.posX, (int)entity.posY, (int)entity.posZ, entity);
}
}

 

However, I get an error on the line where I call EntitySheep.onSheared(), saying that I can't make a static reference to a non-static field(which this method is not, so the error is correct). Have I done something incorrect?

Posted

Hi

 

Yeah there's a bit of a problem with your code-

 

EntitySheep.onSheared(...)

 

when you call mySheep.onSheared, you are saying

"shear mySheep".

 

But of course you need to tell it which sheep to shear.  Your current code attempts to say "shear the definition of a sheep" which is very different.

 

Luckily you have something that might be a sheep already (i.e. target)

 

if (target instanceof EntitySheep) {

  (EntitySheep)target.onSheared( ..etc.. )

}

 

-TGG

 

Posted

Ah, yes. Shearing a sheep is quite different from shearing the definition of a sheep :)

I tested it out and it works very well. All I need now is to get the items but I already know how to do that.

My only problem now is that if I(and possibly other mobs) step on the block, the game crashes. I think this is because of me casting the target to the type IShearable. I think I can fix this by just checking to make sure that the entity standing atop the block is a sheep.

Is there a method that would return the name of a specified entity?

Posted

Hi

 

If you're only interested in sheep -

first do

if (target instanceof EntitySheep)  {
  EntitySheep theSheep = (EntitySheep)target
   // rest of your code here, working on theSheep
}

Don't bother casting to IShearable.

 

-TGG

 

 

Posted

Thanks so much!

Mind if I ask one more thing? :)

I'm making a different block that I want to be activated with redstone but the only way I know how to do that is with onNeighborBlockChange which doesn't allow for an entity as a variable(which I need since this block will be interacting with entities)

Is there any way I can get around this?

Posted

Is there any way I can get around this?

 

Yes

 

Don't use onEntityWalking.  It's flaky and you'd have to figure out how to determine powered status (and sending the redstone signal wouldn't do anything!  You'd need the signal, then the walking!)

 

Look at pressure plates instead.  There's a world.getEntitiesInAABB function.  You'll want to copy that and add it to the onNeighborBlockChanged function (or wherever you're getting your redstone activation at) and do your shearing inside there.  Look at the sheers to see how they work.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted

Sorry, but I'm a bit confused with this. I looked in the BlockPressurePlate class but cannot seem to find any call of world.getEntitiesInAABB. I also can't find any method with this name in the world class. Am I not understanding correctly?

Posted

Sorry, but I'm a bit confused with this. I looked in the BlockPressurePlate class but cannot seem to find any call of world.getEntitiesInAABB. I also can't find any method with this name in the world class. Am I not understanding correctly?

 

Try the parent class, BlockBasePressurePlate.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted

I'm really sorry, I feel like I'm doing something wrong. I wasn't able to find it in the BlockBasePressurePlate either. However, I looked in the world class again and found getEntitiesWithinAABB. I feel like this might be what you're talking about. If it is, would you mind explaining how this works? I obviously put the class of the entity that I'm searching for within the AABB but I'm not too sure what AABB is(Axis Aligned Bounding Box?).

Posted

AABB is an AxisAlignedBoundingBox, yes.

 

Think of an AABB as a volume of blocks that must be cuboid in shape: it has width, height, and depth, as well as location.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted

Hi

 

Here is the basic idea of an AABB in two dimensions.

http://www.gamefromscratch.com/post/2012/11/26/GameDev-math-recipes-Collision-detection-using-an-axis-aligned-bounding-box.aspx

Minecraft AABB is in three dimensions of course.

 

You can create one of your own using

myAABB = AxisAlignedBB.getAABBPool().getAABB(minX, minY, minZ, maxX, maxY, maxZ);

 

It only lasts a short time (until the next tick) but for collision checking that's all you need.

 

Alternatively if you want the AABB for a particular block, you can use

myAABB = BLock.getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4)

 

and you can move it or make is bigger using eg

 

myAABB.offset(dx, dy, dz)

or

myAABB.expand(dx, dy, dz)

 

-TGG

 

 

 

 

Posted

Ok, I think I might understand how AABB works. So what I would have to do is create an AABB above the block and when the block gets powered, check if there is an entity in the AABB that can be sheared and if it can, then shear it? If that is the case, then I still have a problem(I think): world.getEntitiesWithinAABB() returns a list of the entities in the AABB. My shearSheep() method uses EntitySheep as the target and I'm pretty sure the game wouldn't like me trying to cast a list into an EntitySheep.

Posted

if(someEntity instanceof EntitySheep) {

  EntitySheep aSheep = (EntitySheep)someEntity;

}

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted

Ok, here is what I have now:

public void shearSheep(World world, int x, int y, int z, EntitySheep target)
{
	if(target instanceof EntitySheep)
	{
		ArrayList<ItemStack> stuff = target.onSheared(null, world, (int)target.posX, (int)target.posY, (int)target.posZ, 0);
	}
}


@Override
public void onNeighborBlockChange(World world, int x, int y, int z, int id)
{
	AxisAlignedBB myAABB = AxisAlignedBB.getAABBPool().getAABB(x, y+1, z, x, y+2, z);
	if(!world.isRemote && world.isBlockIndirectlyGettingPowered(x, y, z))
	{
		System.out.println("1");
		List entity= world.getEntitiesWithinAABB(EntitySheep.class, myAABB);

		if(entity instanceof EntitySheep)
		{
			System.out.println("2");
			EntitySheep aSheep = (EntitySheep)entity;
			shearSheep(world, x, y, z, aSheep);
		}
	}
}

I have it print "1" and "2" for testing. When I put a sheep above the block and power it, 1 is printed but 2 is not, so the sheep is not sheared. I think this is because world.getEntitiesWithinAABB() returns a list. I did try casting to an EntitySheep before checking but, as predicted, that did not work.

Posted

That's because your variable entity is a List and is not an instance of EntitySheep.  It does however, contain sheep.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted

Ah, yes. Sorry about that, it's quite late here and I'm forgetting things :). However, after doing some further testing, I'm not really sure what exactly it's putting in the list. I've tried testing using entity.contains() and so far nothing has come up true. Am I looking for the wrong thing?

Posted

~Loops~

 

List#get(int index)

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted

Well, testing with this:

List entities= world.getEntitiesWithinAABB(EntitySheep.class, myAABB);
		for(int i = 0; i < 10; i++)
		{
			System.out.println(entities.get(i));
		}

I was able to produce this: "EntitySheep['Sheep'/19, l='New World', x=29.07, y=4.00, z=-787.93]" Now I think I'm more confused than when I started :) I've either done something wrong to get this or I don't understand at all(probably both... :) ) This is not what I was expecting to get at all. I'm not really sure how I'm going to be able to check for something like this.

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.