Alloy furnace - Alloying!
This commit is contained in:
parent
b68a081350
commit
b5176a9f49
6 changed files with 382 additions and 7 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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
|
||||
* <p>
|
||||
* In order to do that, we need to check that:
|
||||
* <ul>
|
||||
* <li>the current recipe's requirements are present in the input slot, AND
|
||||
* <li>either there is a free output slot OR there is an output slot with the current output
|
||||
* which can accept enough items.
|
||||
* </ul>
|
||||
*
|
||||
* @return <code>true</code> 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 );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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( );
|
||||
}
|
||||
|
|
|
@ -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 )
|
||||
|
|
Reference in a new issue