diff --git a/src/java/mmm/materials/MAlloyRecipe.java b/src/java/mmm/materials/MAlloyRecipe.java index 7ee07e3..4069428 100644 --- a/src/java/mmm/materials/MAlloyRecipe.java +++ b/src/java/mmm/materials/MAlloyRecipe.java @@ -7,6 +7,7 @@ import java.util.HashMap; import mmm.Mmm; import mmm.utils.UItemId; import net.minecraft.block.Block; +import net.minecraft.inventory.IInventory; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.util.ResourceLocation; @@ -234,4 +235,33 @@ public class MAlloyRecipe return this.output.getItem( ).getItemStackDisplayName( this.output ); } + + public boolean checkInventory( final IInventory input ) + { + return this.checkInventory( input , 0 , input.getSizeInventory( ) ); + } + + + public boolean checkInventory( final IInventory input , final int first , final int last ) + { + for ( int i = 0 ; i < this.inputs.length ; i++ ) { + final ItemStack inputStack = this.inputs[ i ]; + int found = 0; + for ( int slot = first ; slot < last ; slot++ ) { + final ItemStack stackInSlot = input.getStackInSlot( slot ); + if ( stackInSlot == null || !inputStack.isItemEqual( stackInSlot ) ) { + continue; + } + found += stackInSlot.stackSize; + if ( found >= inputStack.stackSize ) { + break; + } + } + if ( found < inputStack.stackSize ) { + return false; + } + } + return true; + } + } diff --git a/src/java/mmm/tech/base/TBAlloyFurnaceBlock.java b/src/java/mmm/tech/base/TBAlloyFurnaceBlock.java index 82505ff..44504b7 100644 --- a/src/java/mmm/tech/base/TBAlloyFurnaceBlock.java +++ b/src/java/mmm/tech/base/TBAlloyFurnaceBlock.java @@ -22,6 +22,7 @@ import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.SoundEvents; +import net.minecraft.inventory.InventoryHelper; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; @@ -50,6 +51,8 @@ public class TBAlloyFurnaceBlock public static final PropertyDirection FACING = BlockHorizontal.FACING; + private static boolean keepInventory = false; + public final boolean active; @@ -79,6 +82,32 @@ public class TBAlloyFurnaceBlock } + public static void setState( final boolean burning , final World world , final BlockPos pos ) + { + final IBlockState iblockstate = world.getBlockState( pos ); + final TileEntity tileentity = world.getTileEntity( pos ); + + TBAlloyFurnaceBlock.keepInventory = true; + if ( burning ) { + world.setBlockState( pos , TechBase.ALLOY_FURNACE_BLOCK_ACTIVE.getDefaultState( ).withProperty( + TBAlloyFurnaceBlock.FACING , iblockstate.getValue( TBAlloyFurnaceBlock.FACING ) ) , 3 ); + world.setBlockState( pos , TechBase.ALLOY_FURNACE_BLOCK_ACTIVE.getDefaultState( ).withProperty( + TBAlloyFurnaceBlock.FACING , iblockstate.getValue( TBAlloyFurnaceBlock.FACING ) ) , 3 ); + } else { + world.setBlockState( pos , TechBase.ALLOY_FURNACE_BLOCK_INACTIVE.getDefaultState( ).withProperty( + TBAlloyFurnaceBlock.FACING , iblockstate.getValue( TBAlloyFurnaceBlock.FACING ) ) , 3 ); + world.setBlockState( pos , TechBase.ALLOY_FURNACE_BLOCK_INACTIVE.getDefaultState( ).withProperty( + TBAlloyFurnaceBlock.FACING , iblockstate.getValue( TBAlloyFurnaceBlock.FACING ) ) , 3 ); + } + TBAlloyFurnaceBlock.keepInventory = false; + + if ( tileentity != null ) { + tileentity.validate( ); + world.setTileEntity( pos , tileentity ); + } + } + + // ************************************************************************************************* // RENDERING AND COLLISIONS // ************************************************************************************************* @@ -265,15 +294,34 @@ public class TBAlloyFurnaceBlock // ************************************************************************************************* @Override - public boolean onBlockActivated( World worldIn , BlockPos pos , IBlockState state , EntityPlayer playerIn , - EnumHand hand , ItemStack heldItem , EnumFacing side , float hitX , float hitY , float hitZ ) + public boolean onBlockActivated( final World worldIn , final BlockPos pos , final IBlockState state , + final EntityPlayer playerIn , final EnumHand hand , final ItemStack heldItem , final EnumFacing side , + final float hitX , final float hitY , final float hitZ ) { - TileEntity te = worldIn.getTileEntity( pos ); - if ( !(te instanceof TBAlloyFurnaceTileEntity ) || playerIn.isSneaking( ) ) { + final TileEntity te = worldIn.getTileEntity( pos ); + if ( ! ( te instanceof TBAlloyFurnaceTileEntity ) || playerIn.isSneaking( ) ) { return false; } playerIn.openGui( Mmm.get( ) , 0 , worldIn , pos.getX( ) , pos.getY( ) , pos.getZ( ) ); return true; } + + @Override + public void breakBlock( final World worldIn , final BlockPos pos , final IBlockState state ) + { + if ( !TBAlloyFurnaceBlock.keepInventory ) { + final TileEntity tileEntity = worldIn.getTileEntity( pos ); + + if ( tileEntity instanceof TBAlloyFurnaceTileEntity ) { + final TBAlloyFurnaceTileEntity afte = (TBAlloyFurnaceTileEntity) tileEntity; + InventoryHelper.dropInventoryItems( worldIn , pos , afte.input ); + InventoryHelper.dropInventoryItems( worldIn , pos , afte.fuel ); + InventoryHelper.dropInventoryItems( worldIn , pos , afte.output ); + } + } + + super.breakBlock( worldIn , pos , state ); + } + } diff --git a/src/java/mmm/tech/base/TBAlloyFurnaceGui.java b/src/java/mmm/tech/base/TBAlloyFurnaceGui.java index 2e0303e..574f50f 100644 --- a/src/java/mmm/tech/base/TBAlloyFurnaceGui.java +++ b/src/java/mmm/tech/base/TBAlloyFurnaceGui.java @@ -12,6 +12,7 @@ import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.tileentity.TileEntity; import net.minecraft.util.ResourceLocation; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; @@ -194,6 +195,27 @@ public class TBAlloyFurnaceGui this.mc.getTextureManager( ).bindTexture( TBAlloyFurnaceGui.TEXTURES[ this.selectedTab.ordinal( ) ] ); this.drawTexturedModalRect( this.guiLeft , this.guiTop , 0 , 0 , this.xSize , this.ySize ); + if ( this.selectedTab == Tab.MAIN ) { + int x = ( this.width - this.xSize ) / 2; + int y = ( this.height - this.ySize ) / 2; + + TileEntity atPos = this.container.world.getTileEntity( this.container.position ); + if ( atPos instanceof TBAlloyFurnaceTileEntity ) { + TBAlloyFurnaceTileEntity te = (TBAlloyFurnaceTileEntity) atPos; + // Burn + if ( te.isBurning( ) ) { + int burn = te.getBurnProgress( 13 ); + this.drawTexturedModalRect( x + 89 , y + 38 + 13 - burn , 176 , 28 - burn , 14 , burn + 1 ); + } + + // Alloying progress + if ( te.isAlloying( ) ) { + int alloy = te.getAlloyingProgress( 47 ); + this.drawTexturedModalRect( x + 73 , y + 17 , 176 , 29 , alloy + 1 , 16 ); + } + } + } + // Active tab this.mc.getTextureManager( ).bindTexture( TBAlloyFurnaceGui.TEXTURES[ 0 ] ); this.drawTab( this.selectedTab ); diff --git a/src/java/mmm/tech/base/TBAlloyFurnaceTileEntity.java b/src/java/mmm/tech/base/TBAlloyFurnaceTileEntity.java index 9a8fa56..fc3ff26 100644 --- a/src/java/mmm/tech/base/TBAlloyFurnaceTileEntity.java +++ b/src/java/mmm/tech/base/TBAlloyFurnaceTileEntity.java @@ -4,10 +4,13 @@ package mmm.tech.base; import mmm.materials.MAlloyRecipe; import mmm.utils.UInventoryGrid; import net.minecraft.block.state.IBlockState; +import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.NetworkManager; import net.minecraft.network.play.server.SPacketUpdateTileEntity; import net.minecraft.tileentity.TileEntity; +import net.minecraft.tileentity.TileEntityFurnace; +import net.minecraft.util.ITickable; import net.minecraft.util.ResourceLocation; import net.minecraftforge.common.util.Constants.NBT; @@ -15,6 +18,7 @@ import net.minecraftforge.common.util.Constants.NBT; public class TBAlloyFurnaceTileEntity extends TileEntity + implements ITickable { public final UInventoryGrid input; @@ -23,6 +27,11 @@ public class TBAlloyFurnaceTileEntity public MAlloyRecipe recipe; + private MAlloyRecipe alloying; + private int alloyCurrent; + private int burnCurrent; + private int burnTotal; + public TBAlloyFurnaceTileEntity( ) { @@ -52,7 +61,6 @@ public class TBAlloyFurnaceTileEntity compound.setTag( "Fuel" , this.fuel.serializeNBT( ) ); compound.setTag( "Output" , this.output.serializeNBT( ) ); this.writeSyncData( compound ); - System.err.println( "tag " + compound.toString( ) ); return compound; } @@ -86,6 +94,61 @@ public class TBAlloyFurnaceTileEntity } + @Override + public void update( ) + { + if ( this.worldObj.isRemote ) { + return; + } + + final boolean wasBurning = this.isBurning( ); + boolean dirty = false; + + if ( wasBurning ) { + dirty = true; + this.burnCurrent--; + + if ( this.alloying != null ) { + this.alloyCurrent--; + if ( this.alloyCurrent == 0 ) { + this.addOutput( ); + if ( this.canAlloy( ) ) { + this.startAlloying( ); + } else { + this.alloying = null; + } + } + } + + if ( this.burnCurrent == 0 ) { + if ( this.alloying != null ) { + if ( !this.startBurning( this.alloyCurrent ) ) { + // XXX produce slag + this.alloying = null; + this.alloyCurrent = this.burnCurrent = this.burnTotal = 0; + } + } else { + this.burnTotal = this.burnCurrent = 0; + } + } + + } else if ( this.canAlloy( ) && this.startBurning( this.recipe.burnTime ) ) { + this.startAlloying( ); + dirty = true; + } + + if ( this.isBurning( ) != wasBurning ) { + TBAlloyFurnaceBlock.setState( this.isBurning( ) , this.worldObj , this.pos ); + } + + if ( dirty ) { + this.markDirty( ); + final IBlockState state = this.worldObj.getBlockState( this.pos ); + this.worldObj.notifyBlockUpdate( this.pos , state , state , 3 ); + } + } + + public void setRecipe( final ResourceLocation location ) { MAlloyRecipe recipe = MAlloyRecipe.REGISTRY.getRecipe( location ); @@ -106,6 +169,195 @@ public class TBAlloyFurnaceTileEntity } + public boolean isBurning( ) + { + return this.burnTotal != 0; + } + + + public int getBurnProgress( int max ) + { + int t = this.burnTotal; + if ( t == 0 ) { + t = 200; + } + return Math.min( max , this.burnCurrent * max / t ); + } + + + /** + * Find the most appropriate fuel for the specified burn time. + * + * @param requiredBurnTime + * the burn time we need + * + * @return the fuel slot's index, or -1 if there is no fuel. + */ + private int getBestFuel( final int requiredBurnTime ) + { + int bestStack = -1 , bestDiff = Integer.MAX_VALUE; + for ( int i = 0 ; i < this.fuel.slotsCount ; i++ ) { + final ItemStack fuel = this.fuel.inventoryContents[ i ]; + if ( fuel == null || fuel.stackSize == 0 ) { + continue; + } + final int fuelBurnTime = TileEntityFurnace.getItemBurnTime( fuel ); + final int diff = Math.abs( requiredBurnTime - fuelBurnTime ); + if ( diff < bestDiff ) { + bestStack = i; + bestDiff = diff; + } + } + return bestStack; + } + + + private boolean startBurning( final int requiredBurnTime ) + { + final int fuelSlot = this.getBestFuel( requiredBurnTime ); + if ( fuelSlot == -1 ) { + return false; + } + + final ItemStack fuelStack = this.fuel.inventoryContents[ fuelSlot ]; + this.burnCurrent = this.burnTotal = TileEntityFurnace.getItemBurnTime( fuelStack ); + + fuelStack.stackSize--; + if ( fuelStack.stackSize == 0 ) { + final ItemStack replace = fuelStack.getItem( ).getContainerItem( fuelStack ); + this.fuel.inventoryContents[ fuelSlot ] = replace; + } + + return true; + } + + + /** + * Checks if alloying is possible + *
+ * In order to do that, we need to check that: + *
true
if alloying is possible
+ */
+ public boolean canAlloy( )
+ {
+ if ( !this.recipe.checkInventory( this.input ) ) {
+ return false;
+ }
+
+ final ItemStack output = this.recipe.output;
+ final int fullStack = Math.min( this.output.getInventoryStackLimit( ) , output.getMaxStackSize( ) );
+ int freeSpace = 0;
+
+ for ( int i = 0 ; i < this.output.slotsCount && freeSpace < output.stackSize ; i++ ) {
+ final ItemStack outputSlot = this.output.inventoryContents[ i ];
+ if ( outputSlot == null ) {
+ freeSpace += fullStack;
+ } else if ( outputSlot.isItemEqual( output ) ) {
+ freeSpace += fullStack - outputSlot.stackSize;
+ }
+ }
+
+ return freeSpace >= output.stackSize;
+ }
+
+
+ public boolean isAlloying( )
+ {
+ return this.alloying != null;
+ }
+
+
+ public int getAlloyingProgress( int max )
+ {
+ if ( this.alloying == null ) {
+ return max;
+ }
+
+ int t = this.alloying.burnTime;
+ if ( t == 0 ) {
+ t = 200;
+ }
+ return Math.min( max , ( t - this.alloyCurrent ) * max / t );
+ }
+
+
+ private void startAlloying( )
+ {
+ this.removeRecipeInput( );
+ this.alloying = this.recipe;
+ this.alloyCurrent = this.recipe.burnTime;
+ }
+
+
+ private void removeRecipeInput( )
+ {
+ final ItemStack[] rIn = this.recipe.inputs;
+ final int inSlots = this.input.slotsCount;
+ for ( int i = 0 ; i < rIn.length ; i++ ) {
+ final ItemStack inputStack = rIn[ i ];
+ int found = 0;
+ for ( int slot = 0 ; slot < inSlots ; slot++ ) {
+ final ItemStack stackInSlot = this.input.inventoryContents[ slot ];
+ if ( stackInSlot == null || !inputStack.isItemEqual( stackInSlot ) ) {
+ continue;
+ }
+
+ final int take = Math.min( inputStack.stackSize - found , stackInSlot.stackSize );
+ found += take;
+ stackInSlot.stackSize -= take;
+ if ( stackInSlot.stackSize == 0 ) {
+ final ItemStack replace = stackInSlot.getItem( ).getContainerItem( stackInSlot );
+ this.input.inventoryContents[ slot ] = replace;
+ }
+
+ if ( found == inputStack.stackSize ) {
+ break;
+ }
+ }
+ }
+ }
+
+
+ private void addOutput( )
+ {
+ final ItemStack wanted = this.alloying.output;
+ final int maxStackSize = Math.min( this.output.getInventoryStackLimit( ) , wanted.getMaxStackSize( ) );
+ int added = 0;
+ for ( int i = 0 ; i < this.output.slotsCount ; i++ ) {
+ ItemStack outputStack = this.output.inventoryContents[ i ];
+ int canAdd;
+ if ( outputStack == null ) {
+ canAdd = maxStackSize;
+ outputStack = new ItemStack( wanted.getItem( ) , 0 , wanted.getItemDamage( ) );
+ this.output.inventoryContents[ i ] = outputStack;
+
+ } else if ( outputStack.isItemEqual( wanted ) ) {
+ canAdd = maxStackSize - outputStack.stackSize;
+
+ } else {
+ canAdd = 0;
+ }
+
+ if ( canAdd == 0 ) {
+ continue;
+ }
+
+ final int doAdd = Math.min( canAdd , wanted.stackSize - added );
+ added += doAdd;
+ outputStack.stackSize += doAdd;
+ if ( added == wanted.stackSize ) {
+ break;
+ }
+ }
+ }
+
+
private void readSyncData( final NBTTagCompound compound )
{
final String recipeName = compound.getString( "Recipe" );
@@ -113,12 +365,35 @@ public class TBAlloyFurnaceTileEntity
if ( this.recipe == null ) {
this.recipe = MAlloyRecipe.REGISTRY.getRecipes( ).get( 0 );
}
+
+ this.burnCurrent = compound.getInteger( "BurnCurrent" );
+ this.burnTotal = compound.getInteger( "BurnTotal" );
+
+ final String alloyingRecipeName = compound.getString( "AlloyRecipe" );
+ if ( "".equals( alloyingRecipeName ) ) {
+ this.alloying = null;
+ } else {
+ this.alloying = MAlloyRecipe.REGISTRY.getRecipe( new ResourceLocation( recipeName ) );
+ }
+ if ( this.alloying == null ) {
+ this.alloyCurrent = 0;
+ } else {
+ this.alloyCurrent = compound.getInteger( "AlloyCurrent" );
+ }
}
private void writeSyncData( final NBTTagCompound compound )
{
compound.setString( "Recipe" , this.recipe.name.toString( ) );
+ if ( this.alloying != null ) {
+ compound.setString( "AlloyRecipe" , this.alloying.name.toString( ) );
+ compound.setInteger( "AlloyCurrent" , this.alloyCurrent );
+ }
+ if ( this.burnTotal != 0 ) {
+ compound.setInteger( "BurnTotal" , this.burnTotal );
+ compound.setInteger( "BurnCurrent" , this.burnCurrent );
+ }
}
}
diff --git a/src/java/mmm/tech/base/TechBase.java b/src/java/mmm/tech/base/TechBase.java
index 87c73d9..92317cf 100644
--- a/src/java/mmm/tech/base/TechBase.java
+++ b/src/java/mmm/tech/base/TechBase.java
@@ -32,7 +32,7 @@ public class TechBase
URegistry.addServerMessage( TBAlloyFurnaceMessage.class );
// FIXME test, remove this later
- MAlloyRecipe.build( ).setName( "test" ).setBurnTime( 200 ).setExperience( .05f )
+ MAlloyRecipe.build( ).setName( "test" ).setBurnTime( 50 ).setExperience( .05f )
.setOutput( Items.COOKED_CHICKEN , 10 ).addInput( Items.COOKED_BEEF ).addInput( Items.COOKED_PORKCHOP )
.register( );
}
diff --git a/src/java/mmm/utils/UInventoryGrid.java b/src/java/mmm/utils/UInventoryGrid.java
index a6eabe8..763cb48 100644
--- a/src/java/mmm/utils/UInventoryGrid.java
+++ b/src/java/mmm/utils/UInventoryGrid.java
@@ -24,7 +24,7 @@ public class UInventoryGrid
public final int width;
public final int height;
public final int slotsCount;
- private final ItemStack[] inventoryContents;
+ public final ItemStack[] inventoryContents;
public UInventoryGrid( final String name , final int width , final int height )