Workbench - Actual crafting! YAY!
This commit is contained in:
parent
218a93ef9f
commit
f121e8bd3d
6 changed files with 338 additions and 12 deletions
|
@ -25,4 +25,12 @@ public interface I_RecipeRequirements
|
|||
|
||||
boolean checkInventory( IInventory inventory );
|
||||
|
||||
|
||||
boolean checkInventory( IInventory inventory , int amount );
|
||||
|
||||
|
||||
public int getMaxOutput( IInventory inventory );
|
||||
|
||||
|
||||
void removeFromInventory( IInventory inventory, int amount );
|
||||
}
|
|
@ -90,10 +90,17 @@ class RRequirements
|
|||
|
||||
@Override
|
||||
public boolean checkInventory( final IInventory inventory )
|
||||
{
|
||||
return this.checkInventory( inventory , 1 );
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean checkInventory( final IInventory inventory , final int amount )
|
||||
{
|
||||
final int nInvItems = inventory.getSizeInventory( );
|
||||
for ( int i = 0 ; i < this.quantities.length ; i++ ) {
|
||||
int nLeft = this.quantities[ i ];
|
||||
int nLeft = this.quantities[ i ] * amount;
|
||||
|
||||
for ( int j = 0 ; j < nInvItems && nLeft > 0 ; j++ ) {
|
||||
final ItemStack invStack = inventory.getStackInSlot( j );
|
||||
|
@ -108,4 +115,48 @@ class RRequirements
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getMaxOutput( final IInventory inventory )
|
||||
{
|
||||
final int nInvItems = inventory.getSizeInventory( );
|
||||
int maxQuantity = Integer.MAX_VALUE;
|
||||
for ( int i = 0 ; i < this.quantities.length && maxQuantity > 0 ; i++ ) {
|
||||
int nFound = 0;
|
||||
|
||||
for ( int j = 0 ; j < nInvItems ; j++ ) {
|
||||
final ItemStack invStack = inventory.getStackInSlot( j );
|
||||
if ( this.checkItemStack( i , invStack ) ) {
|
||||
nFound += invStack.stackSize;
|
||||
}
|
||||
}
|
||||
|
||||
maxQuantity = Math.min( maxQuantity , nFound / this.quantities[ i ] );
|
||||
}
|
||||
return maxQuantity;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void removeFromInventory( final IInventory inventory , final int amount )
|
||||
{
|
||||
final int nInvItems = inventory.getSizeInventory( );
|
||||
for ( int i = 0 ; i < this.quantities.length ; i++ ) {
|
||||
int nLeft = this.quantities[ i ] * amount;
|
||||
for ( int j = 0 ; j < nInvItems && nLeft > 0 ; j++ ) {
|
||||
final ItemStack invStack = inventory.getStackInSlot( j );
|
||||
if ( this.checkItemStack( i , invStack ) ) {
|
||||
final int used = Math.min( nLeft , invStack.stackSize );
|
||||
nLeft -= used;
|
||||
if ( invStack.stackSize == used ) {
|
||||
inventory.setInventorySlotContents( j , invStack.getItem( ).getContainerItem( invStack ) );
|
||||
} else {
|
||||
invStack.stackSize -= used;
|
||||
}
|
||||
}
|
||||
}
|
||||
assert nLeft == 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,21 @@
|
|||
package mmm.tech.base.workbench;
|
||||
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import mmm.MmmTech;
|
||||
import mmm.core.api.recipes.I_CraftingRecipeWrapper;
|
||||
import mmm.recipes.RCraftingWrappers;
|
||||
import mmm.utils.UInventoryDisplay;
|
||||
import mmm.utils.gui.UGContainer;
|
||||
import mmm.utils.gui.UGSlotDisplay;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.InventoryPlayer;
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.inventory.InventoryCraftResult;
|
||||
import net.minecraft.inventory.Slot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
|
@ -20,7 +27,9 @@ public class TBWBContainer
|
|||
public final TBWBTileEntity tileEntity;
|
||||
public final World world;
|
||||
public final BlockPos position;
|
||||
public final UInventoryDisplay recipe;
|
||||
public final UInventoryDisplay recipeDisplay;
|
||||
public final InventoryCraftResult recipeOutput;
|
||||
private I_CraftingRecipeWrapper recipeWrapper;
|
||||
|
||||
|
||||
public TBWBContainer( final InventoryPlayer playerInv , final TBWBTileEntity tileEntity )
|
||||
|
@ -35,12 +44,19 @@ public class TBWBContainer
|
|||
this.addGrid( Slot::new , tileEntity.storage , 8 , 15 );
|
||||
|
||||
this.slotGroups.nextGroup( );
|
||||
this.recipe = new UInventoryDisplay( "Recipe" , 10 );
|
||||
this.addGrid( UGSlotDisplay::new , this.recipe , //
|
||||
this.recipeDisplay = new UInventoryDisplay( "Recipe" , 10 );
|
||||
this.addGrid( UGSlotDisplay::new , this.recipeDisplay , //
|
||||
3 , 3 , 0 , 86 , 32 );
|
||||
this.addSlotToContainer( new UGSlotDisplay( this.recipe , 9 , 174 , 50 ) );
|
||||
|
||||
this.slotGroups.nextGroup( );
|
||||
this.recipeOutput = new InventoryCraftResult( );
|
||||
this.addSlotToContainer( new TBWBCraftingSlot( playerInv.player , this , //
|
||||
this.recipeOutput , 0 , 174 , 50 ) );
|
||||
|
||||
this.slotGroups.endGroups( );
|
||||
|
||||
this.recipeWrapper = RCraftingWrappers.RECIPES.get( 0 );
|
||||
this.onRecipeChanged( );
|
||||
}
|
||||
|
||||
|
||||
|
@ -53,20 +69,120 @@ public class TBWBContainer
|
|||
}
|
||||
|
||||
|
||||
public void setCurrentRecipe( final I_CraftingRecipeWrapper wrapper , final boolean setDefault )
|
||||
@Nullable
|
||||
public ItemStack transferStackInSlot( EntityPlayer playerIn , int index )
|
||||
{
|
||||
this.recipe.clear( );
|
||||
if ( wrapper == null ) {
|
||||
// XXX log if confirm is set
|
||||
return;
|
||||
Slot slot = (Slot) this.inventorySlots.get( index );
|
||||
if ( slot == null || !slot.getHasStack( ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
wrapper.addInputsToDisplay( this.recipe );
|
||||
this.recipe.setInventorySlotContents( 9 , wrapper.getOutput( ) );
|
||||
ItemStack slotStack = slot.getStack( );
|
||||
ItemStack outStack = slotStack.copy( );
|
||||
|
||||
int group = this.slotGroups.getGroup( index );
|
||||
if ( group == 3 ) {
|
||||
// Craft as many as possible
|
||||
if ( this.recipeWrapper == null ) {
|
||||
return null;
|
||||
}
|
||||
IInventory storage = this.getStorage( );
|
||||
if ( storage == null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Can we?
|
||||
if ( !this.recipeWrapper.getRequirements( ).checkInventory( storage ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Merge it and remove ingredients
|
||||
if ( !this.mergeItemStack( outStack , 0 , 36 , false ) ) {
|
||||
return null;
|
||||
}
|
||||
( (TBWBCraftingSlot) slot ).handleCrafting( 1 );
|
||||
|
||||
// Drop any items that didn't fit in the inventory
|
||||
if ( outStack.stackSize != 0 ) {
|
||||
playerIn.dropItem( outStack , false );
|
||||
return null;
|
||||
}
|
||||
|
||||
return slotStack;
|
||||
|
||||
}
|
||||
|
||||
if ( group == 0 ) {
|
||||
// Player inventory to storage
|
||||
if ( !this.mergeItemStack( slotStack , 36 , 51 , false ) ) {
|
||||
return null;
|
||||
}
|
||||
} else if ( group == 1 ) {
|
||||
// Storage to player inventory
|
||||
if ( !this.mergeItemStack( slotStack , 0 , 36 , false ) ) {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ( slotStack.stackSize == 0 ) {
|
||||
slot.putStack( (ItemStack) null );
|
||||
} else {
|
||||
slot.onSlotChanged( );
|
||||
}
|
||||
|
||||
if ( slotStack.stackSize == outStack.stackSize ) {
|
||||
return null;
|
||||
}
|
||||
slot.onPickupFromSlot( playerIn , slotStack );
|
||||
return outStack;
|
||||
}
|
||||
|
||||
|
||||
public boolean canMergeSlot( ItemStack stack , Slot slotIn )
|
||||
{
|
||||
return slotIn.inventory != this.recipeOutput && super.canMergeSlot( stack , slotIn );
|
||||
}
|
||||
|
||||
|
||||
public void setCurrentRecipe( final I_CraftingRecipeWrapper wrapper , final boolean setDefault )
|
||||
{
|
||||
this.recipeWrapper = wrapper;
|
||||
|
||||
onRecipeChanged( );
|
||||
|
||||
if ( setDefault ) {
|
||||
// this.tileEntity.setDefaultRecipe( wrapper.getIdentifier( ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void onRecipeChanged( )
|
||||
{
|
||||
this.recipeDisplay.clear( );
|
||||
if ( this.recipeWrapper == null ) {
|
||||
// XXX log if confirm is set
|
||||
return;
|
||||
}
|
||||
this.recipeWrapper.addInputsToDisplay( this.recipeDisplay );
|
||||
this.recipeOutput.setInventorySlotContents( 0 , this.recipeWrapper.getOutput( ) );
|
||||
}
|
||||
|
||||
|
||||
public IInventory getStorage( )
|
||||
{
|
||||
TileEntity te = this.world.getTileEntity( position );
|
||||
if ( te instanceof TBWBTileEntity ) {
|
||||
return ( (TBWBTileEntity) te ).storage;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public I_CraftingRecipeWrapper getCurrentRecipe( )
|
||||
{
|
||||
return this.recipeWrapper;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
87
src/java/mmm/tech/base/workbench/TBWBCraftingSlot.java
Normal file
87
src/java/mmm/tech/base/workbench/TBWBCraftingSlot.java
Normal file
|
@ -0,0 +1,87 @@
|
|||
package mmm.tech.base.workbench;
|
||||
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import mmm.core.api.recipes.I_CraftingRecipeWrapper;
|
||||
import mmm.utils.UAchievements;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.inventory.Slot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.fml.common.FMLCommonHandler;
|
||||
|
||||
|
||||
|
||||
public class TBWBCraftingSlot
|
||||
extends Slot
|
||||
{
|
||||
|
||||
private final EntityPlayer player;
|
||||
private final TBWBContainer container;
|
||||
|
||||
|
||||
public TBWBCraftingSlot( final EntityPlayer player , final TBWBContainer container , final IInventory inventory ,
|
||||
final int index , final int x , final int y )
|
||||
{
|
||||
super( inventory , index , x , y );
|
||||
this.player = player;
|
||||
this.container = container;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isItemValid( @Nullable final ItemStack stack )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ItemStack decrStackSize( final int amount )
|
||||
{
|
||||
if ( !this.getHasStack( ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final I_CraftingRecipeWrapper wrapper = this.container.getCurrentRecipe( );
|
||||
if ( wrapper == null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final ItemStack stack = this.getStack( );
|
||||
final int qt = Math.max( amount - amount % stack.stackSize , stack.stackSize ) / stack.stackSize;
|
||||
final IInventory storage = this.container.getStorage( );
|
||||
if ( storage == null || !wrapper.getRequirements( ).checkInventory( storage , qt ) ) {
|
||||
return null;
|
||||
}
|
||||
return this.handleCrafting( qt );
|
||||
}
|
||||
|
||||
|
||||
public ItemStack handleCrafting( final int quantity )
|
||||
{
|
||||
if ( !this.getHasStack( ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final I_CraftingRecipeWrapper wrapper = this.container.getCurrentRecipe( );
|
||||
if ( wrapper == null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final IInventory storage = this.container.getStorage( );
|
||||
if ( storage == null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final ItemStack stack = this.getStack( ).copy( );
|
||||
stack.stackSize *= quantity;
|
||||
|
||||
FMLCommonHandler.instance( ).firePlayerCraftingEvent( this.player , stack , this.inventory );
|
||||
stack.onCrafting( this.player.worldObj , this.player , quantity );
|
||||
UAchievements.checkCraftingAchievements( this.player , stack.getItem( ) );
|
||||
wrapper.getRequirements( ).removeFromInventory( storage , quantity );
|
||||
return stack;
|
||||
}
|
||||
}
|
52
src/java/mmm/utils/UAchievements.java
Normal file
52
src/java/mmm/utils/UAchievements.java
Normal file
|
@ -0,0 +1,52 @@
|
|||
package mmm.utils;
|
||||
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.init.Items;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemHoe;
|
||||
import net.minecraft.item.ItemPickaxe;
|
||||
import net.minecraft.item.ItemSword;
|
||||
import net.minecraft.stats.AchievementList;
|
||||
|
||||
|
||||
|
||||
public class UAchievements
|
||||
{
|
||||
|
||||
public static void checkCraftingAchievements( final EntityPlayer playerIn , final Item item )
|
||||
{
|
||||
if ( item == Item.getItemFromBlock( Blocks.CRAFTING_TABLE ) ) {
|
||||
playerIn.addStat( AchievementList.BUILD_WORK_BENCH );
|
||||
|
||||
} else if ( item instanceof ItemPickaxe ) {
|
||||
playerIn.addStat( AchievementList.BUILD_PICKAXE );
|
||||
if ( ( (ItemPickaxe) item ).getToolMaterial( ) != Item.ToolMaterial.WOOD ) {
|
||||
playerIn.addStat( AchievementList.BUILD_BETTER_PICKAXE );
|
||||
}
|
||||
|
||||
} else if ( item == Item.getItemFromBlock( Blocks.FURNACE ) ) {
|
||||
playerIn.addStat( AchievementList.BUILD_FURNACE );
|
||||
|
||||
} else if ( item instanceof ItemHoe ) {
|
||||
playerIn.addStat( AchievementList.BUILD_HOE );
|
||||
|
||||
} else if ( item == Items.BREAD ) {
|
||||
playerIn.addStat( AchievementList.MAKE_BREAD );
|
||||
|
||||
} else if ( item == Items.CAKE ) {
|
||||
playerIn.addStat( AchievementList.BAKE_CAKE );
|
||||
|
||||
} else if ( item instanceof ItemSword ) {
|
||||
playerIn.addStat( AchievementList.BUILD_SWORD );
|
||||
|
||||
} else if ( item == Item.getItemFromBlock( Blocks.ENCHANTING_TABLE ) ) {
|
||||
playerIn.addStat( AchievementList.ENCHANTMENTS );
|
||||
|
||||
} else if ( item == Item.getItemFromBlock( Blocks.BOOKSHELF ) ) {
|
||||
playerIn.addStat( AchievementList.BOOKCASE );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -100,4 +100,16 @@ public class UGSlotGroups
|
|||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public int getGroup( int slotIndex )
|
||||
{
|
||||
int nGroups = this.firstSlots.size( );
|
||||
for ( int i = 1 ; i < nGroups ; i++ ) {
|
||||
if ( slotIndex < this.firstSlots.getInt( i ) ) {
|
||||
return i - 1;
|
||||
}
|
||||
}
|
||||
return nGroups - 1;
|
||||
}
|
||||
}
|
||||
|
|
Reference in a new issue