Jump to content

[1.7.2]Random Crafting?


drok0920

Recommended Posts

Hello MCF forums,

I was wondering if there was a way to make it so that when you craft an item you would have a 50%-50% of getting either a wood sword are a diamond sword for example.(I would like this to be expandable so that I can make it 33.3%-33.3%-33.3% chance or a 25%-25%-25%-25% chance, etc.)

Link to comment
Share on other sites

Setup a recipe to make X (call it the mystery item - I would image a large red question mark icon).

 

In the event handlers, look for X to be generated and as it is picked up change it based upon your odss.

Long time Bukkit & Forge Programmer

Happy to try and help

Link to comment
Share on other sites

Let me do blockdrops first - that is easier.

 

Here is some pseudocode for what you would want to do:

public class yourBlock extends Block
{
yourBlock()
{
	//constructor
}

/**
 * Returns the quantity of items to drop on block destruction.
 */
@Override
public int quantityDropped(Random p_149745_1_)
{
	return 1;
}

/**
 * Returns the Item dropped by the block when broken.
 */
@Override
public Item getItemDropped(int p_149650_1_, Random p_149650_2_, int p_149650_3_)
{
	Item[] drops;
	//populate with your possible drops
	int rand = (int) (Math.random()*drops.length);
	return drops[rand];
}
}

Link to comment
Share on other sites

For the crafting:

 

You will want to make the result of your recipe be a placeholder item as delpi suggested -- I will refer to it as mysteryItem.

 

To accomplish the turning of mysteryItem into one of your random crafting items, I will have the user rightclick whilst holding the mysteryItem.  (I can't find a forge event for crafting, just for anvils.)

 

In the mysteryItem class, add this code:

private static ItemStack[] craftables = {/*fill this with the appropriate ItemStacks*/};

/**
 * Called whenever this item is equipped and the right mouse button is
 * pressed. Args: itemStack, world, entityPlayer
 */
public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World,
	EntityPlayer par3EntityPlayer)
{
	if (!par3EntityPlayer.capabilities.isCreativeMode)
	{
		--par1ItemStack.stackSize;
	}

	int rand = (int) (Math.random()*craftables.length);
	par3EntityPlayer.inventory.addItemStackToInventory(craftables[rand]);

	return par1ItemStack;
}

Link to comment
Share on other sites

onItemRightClick goes into the mysteryItem class. (This is the item that crafting gives you.)

 

If you want to do a different randomizer, do something along the following:

 

 

 

public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World,
	EntityPlayer par3EntityPlayer)
{
	if (!par3EntityPlayer.capabilities.isCreativeMode)
	{
		--par1ItemStack.stackSize;
	}

	int rand = (int) (Math.random() *
		/* however many possibilities there are, in this example: */ 3);

	// references to possible drops
	ItemStack stack1 = null;
	ItemStack stack2 = null;
	ItemStack stack3 = null;
	// obviously not null in your code

	if (rand == 0)
	{
		par3EntityPlayer.inventory.addItemStackToInventory(stack1);
		par3EntityPlayer.inventory.addItemStackToInventory(stack2);
	}
	if (rand == 1)
	{
		par3EntityPlayer.inventory.addItemStackToInventory(stack2);
		par3EntityPlayer.inventory.addItemStackToInventory(stack3);
	}
	if (rand == 2)
	{
		par3EntityPlayer.inventory.addItemStackToInventory(stack3);
		par3EntityPlayer.inventory.addItemStackToInventory(stack1);
	}
	return par1ItemStack;
}

 

 

 

If you want to do something with percentages:

 

 

 

public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World,
	EntityPlayer par3EntityPlayer)
{
	if (!par3EntityPlayer.capabilities.isCreativeMode)
	{
		--par1ItemStack.stackSize;
	}

	int rand = (int) (Math.random());

	// references to possible drops
	ItemStack stack1 = null;
	ItemStack stack2 = null;
	ItemStack stack3 = null;
	// obviously not null in your code

	if (rand < .25d) // 25 % chance
		par3EntityPlayer.inventory.addItemStackToInventory(stack1);
	if (rand < .50d) // 50 % chance
		par3EntityPlayer.inventory.addItemStackToInventory(stack2);
	if (rand < .75d) // 75 % chance
		par3EntityPlayer.inventory.addItemStackToInventory(stack3);

	return par1ItemStack;
}

 

 

Link to comment
Share on other sites

Instead of null you reference whatever items you want as item stacks :) that's your random returned items.

 

I was going to suggest that you could use the onCreated method of the item... But then I'm not sure how well that works.

We all stuff up sometimes... But I seem to be at the bottom of that pot.

Link to comment
Share on other sites

I put the code like this but it gives me an error please help!

ItemStack stack1 = Blocks.beacon;
ItemStack stack2 = Blocks.anvil;
ItemStack stack3 = Blocks.coal_block;

 

That would be because you are trying to implicitly cast a Block to an ItemStack. These are not the same things. The code you want there (instead of Blocks.beacon) is this:

new ItemStack(Blocks.beacon, /*size of stack*/ 1, /*data, if applicable*/ 0)

 

Leave the data bit of the ItemStack constructor off if you don't need it.

 

And Kwibble, I'm going to go take a look at the Item.onCreated() method. I was looking for a hook for about a quarter hour before posting my clickable solution, so I got tired of looking and may have missed something obvious xD

 

EDIT:

 

Looking at the method, it looks like you could just replace the onRightClick from my previous explanation with onCreated and it should work.

 

so:

/**
* Called when item is crafted/smelted. Used only by maps so far.
*/
public void onCreated(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer)
{
if (!par3EntityPlayer.capabilities.isCreativeMode)
{
	--par1ItemStack.stackSize;
}

int rand = (int) (Math.random()*craftables.length);
par3EntityPlayer.inventory.addItemStackToInventory(craftables[rand]);
//or whatever randomizer you want

return par1ItemStack;
}

Link to comment
Share on other sites

No.. You want the blocks as item stacks.

 

So

ItemStack stack1 = new ItemStack(params); // replace params with what it asks for.

 

 

Damn, ninjad :P

 

Yeah, I am not sure if it would work every time though I.e. Shift clicking out of crafting table/creative mode. Crafting events would still be the easiest.

We all stuff up sometimes... But I seem to be at the bottom of that pot.

Link to comment
Share on other sites

WAIT!!! Guess what I found guys, an event 8)

 

@SubscribeEvent
public void onCrafted(PlayerEvent.ItemCraftedEvent event)
{
      // do stuff
}

 

Note this event is registered on the FMLEventBus and not the MinecraftForge event bus.

 

Man do I feel good now xD

We all stuff up sometimes... But I seem to be at the bottom of that pot.

Link to comment
Share on other sites

So I'm testing it... this produces some interesting results.

 

[spoiler=Subscribing to onCrafted:]

@SubscribeEvent
public void on(ItemCraftedEvent event)
{
	event.crafting.stackSize = 0;
	event.player.inventory.addItemStackToInventory(new ItemStack(Blocks.stone));
}

This leaves you with a ghost item when crafting and gives you a block of stone in the inventory.

Setting the stackSize to 1 and then subtracting one doesn't help either.

event.crafting is final and as such I can't just change the ItemStack.

 

For poops and giggles, I tried this:

@SubscribeEvent
public void on(ItemCraftedEvent event)
{
	event.crafting.func_150996_a(Items.apple);
}

What does it do? (I mean it's an obfuscated function it can't do anything useful.)

IT SETS THE ITEM OF THE STACK TO AN APPLE.

This is what we want!

.......unfortunately this fails (as does anything changing the itemstack) when shift clicking. So sad.

 

So the final answer is .... don't use this method for altering the itemStack output. You could probably use it to do things with the craftingMatrix though.

 

 

 

I still need to check how onCreated holds up though....

[[This is like a personal quest now]]

Link to comment
Share on other sites

Hmm.. I will have to look into that method... Why make something like that final? It doesn't seem right :/

I would expect forge to have made such a thing editable for such a day as this.

 

I am curious and will be looking into it myself now as well.

 

[EDIT]

I am now wondering.. Can you cancel the event and then post a new event but with the itemstack you want?

We all stuff up sometimes... But I seem to be at the bottom of that pot.

Link to comment
Share on other sites

@Kwibble

It doesn't have the @Cancelable annotation so I don't think so.

 

Well going back to the matter at hand, [[What do you say, are you back in the band? (sorry)]]

It might be better to use func_150996_a in the mysteryItem rather than minus-ing the stack and adding an item to the player's inventory.

 

I (really) need to test it, but doing something like

onCreated(/*whatever the params are)
{
parItemStack.func_150996_a(/*whatever item you want*/);
}

may be the best way to go about this. Just make sure to set the maxStackSize to 1.

Link to comment
Share on other sites

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.



×
×
  • Create New...

Important Information

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