Compare commits

..

14 Commits

Author SHA1 Message Date
yueh d7d99c5e7e Fixes #2551: Prevent chunk rebuilds when drive is unchanged. 2016-11-01 11:22:35 +01:00
yueh b6d3be41e1 Fixes #2542: Prevent memory card from opening a GUI
Some additional cleanup of AEBaseTileBlock#onBlockActivated()
2016-11-01 10:29:46 +01:00
Sebastian Hartte 071ee83b7a Fixes #2548: Disable item.csv export on the server side, because we're unable to access creative tab information on the server. 2016-11-01 01:39:42 +01:00
Sebastian Hartte dfe7a29c92 Fixes #2546: When touching an annihilation plane horizontally, use the middle of the entities bounding box on the y-axis to determine whether it is touching the annihilation plane side or not. Otherwise entities did not get picked up when they were *exactly* on the same y-level as the annihilation plane. 2016-11-01 01:05:16 +01:00
Sebastian Hartte 2b02dc19c0 Fixes #2547: Crystal growing and forming fluix crystals was not possible on top of an annihilation plane (or any block with a not-quite-full bounding box), because the crystals thought they were not in water. Fixed by using the center of the crystal bounding box to determine water-status, instead of the bottom center. 2016-11-01 01:03:59 +01:00
shartte 9bf296bec9 Fixes AppVeyor Link 2016-11-01 00:02:35 +01:00
shartte 5db7fc8e8c Show P2P-Tunnel Link Status on WAILA (#2545)
Implemented QoL improvement for P2P tunnels by showing their link status via WAILA.
2016-10-31 23:55:14 +01:00
Sebastian Hartte c7eb696d60 Further improves robustness of facades. 2016-10-30 23:42:14 +01:00
Sebastian Hartte 4f53f5910b Fixes #2536: Mark host for save when placing facades. 2016-10-30 15:29:51 +01:00
Sebastian Hartte 971fc3d243 Fixes #2533 and #2531: Slight overhaul to how Facades store the associated item and retrieve the sprite. 2016-10-30 15:19:48 +01:00
Sebastian Hartte c2b5a58dd2 Fixes #2532: Work around bug in Forge lighting pipeline and UnpackedBakedQuad. 2016-10-30 13:15:42 +01:00
Sebastian Hartte 53c32cc296 #2527: Implements charging of tools via RF (Forge Energy) and Tesla. Tested with Tesla Essentials and EnderIO. 2016-10-30 02:38:20 +02:00
Sebastian Hartte 89299cdb3c Fixes #2525: Light P2P Tunnels not using the correct source for the light value. 2016-10-30 01:41:24 +02:00
Sebastian Hartte 2972f0ddc8 Fixes #2528: World light level not being updated when light-level of cable bus changed after removing parts. 2016-10-30 01:41:03 +02:00
28 changed files with 558 additions and 456 deletions
+1 -1
View File
@@ -53,7 +53,7 @@ Downloads can be found on [CurseForge](http://www.curse.com/mc-mods/minecraft/22
[Download Latest Nightly Build](https://ci.appveyor.com/api/projects/shartte/applied-energistics-2/artifacts/ae2-rv4-nightly.zip?branch=master)
Nightly builds for the Minecraft 1.10.2 branch of AE2 (rv4-alpha) are available from [AppVeyor](https://ci.appveyor.com/api/projects/shartte/applied-energistics-2/history). These builds are only for testing purposes and might lead to loss of data, and will contain significant bugs. Please see below on how you can report bugs you find during testing.
Nightly builds for the Minecraft 1.10.2 branch of AE2 (rv4-alpha) are available from [AppVeyor](https://ci.appveyor.com/project/shartte/applied-energistics-2/history). These builds are only for testing purposes and might lead to loss of data, and will contain significant bugs. Please see below on how you can report bugs you find during testing.
## Installation
+72 -66
View File
@@ -271,87 +271,93 @@ public abstract class AEBaseTileBlock extends AEBaseBlock implements ITileEntity
@Override
public boolean onBlockActivated( final World w, final BlockPos pos, final IBlockState state, final EntityPlayer player, final EnumHand hand, final @Nullable ItemStack heldItem, final EnumFacing side, final float hitX, final float hitY, final float hitZ )
{
if( player != null )
if( player != null && heldItem != null )
{
if( heldItem != null )
if( Platform.isWrench( player, heldItem, pos ) && player.isSneaking() )
{
if( Platform.isWrench( player, heldItem, pos ) && player.isSneaking() )
final IBlockState blockState = w.getBlockState( pos );
final Block block = blockState.getBlock();
if( block == null )
{
final IBlockState ids = w.getBlockState( pos );
final Block id = ids.getBlock();
if( id != null )
{
final AEBaseTile tile = this.getTileEntity( w, pos );
final ItemStack[] drops = Platform.getBlockDrops( w, pos );
if( tile == null )
{
return false;
}
if( tile instanceof TileCableBus || tile instanceof TileSkyChest )
{
return false;
}
final ItemStack op = new ItemStack( this );
for( final ItemStack ol : drops )
{
if( Platform.isSameItemType( ol, op ) )
{
final NBTTagCompound tag = tile.downloadSettings( SettingsFrom.DISMANTLE_ITEM );
if( tag != null )
{
ol.setTagCompound( tag );
}
}
}
if( id.removedByPlayer( ids, w, pos, player, false ) )
{
final List<ItemStack> l = Lists.newArrayList( drops );
Platform.spawnDrops( w, pos, l );
w.setBlockToAir( pos );
}
}
return false;
}
if( heldItem.getItem() instanceof IMemoryCard && !( this instanceof BlockCableBus ) )
final AEBaseTile tile = this.getTileEntity( w, pos );
if( tile == null )
{
final IMemoryCard memoryCard = (IMemoryCard) heldItem.getItem();
if( player.isSneaking() )
return false;
}
if( tile instanceof TileCableBus || tile instanceof TileSkyChest )
{
return false;
}
final ItemStack[] itemDropCandidates = Platform.getBlockDrops( w, pos );
final ItemStack op = new ItemStack( this );
for( final ItemStack ol : itemDropCandidates )
{
if( Platform.isSameItemType( ol, op ) )
{
final AEBaseTile t = this.getTileEntity( w, pos );
if( t != null )
final NBTTagCompound tag = tile.downloadSettings( SettingsFrom.DISMANTLE_ITEM );
if( tag != null )
{
final String name = this.getUnlocalizedName();
final NBTTagCompound data = t.downloadSettings( SettingsFrom.MEMORY_CARD );
if( data != null )
{
memoryCard.setMemoryCardContents( heldItem, name, data );
memoryCard.notifyUser( player, MemoryCardMessages.SETTINGS_SAVED );
return true;
}
ol.setTagCompound( tag );
}
}
}
if( block.removedByPlayer( blockState, w, pos, player, false ) )
{
final List<ItemStack> itemsToDrop = Lists.newArrayList( itemDropCandidates );
Platform.spawnDrops( w, pos, itemsToDrop );
w.setBlockToAir( pos );
}
return false;
}
if( heldItem.getItem() instanceof IMemoryCard && !( this instanceof BlockCableBus ) )
{
final IMemoryCard memoryCard = (IMemoryCard) heldItem.getItem();
final AEBaseTile tileEntity = this.getTileEntity( w, pos );
if( tileEntity == null )
{
return false;
}
final String name = this.getUnlocalizedName();
if( player.isSneaking() )
{
final NBTTagCompound data = tileEntity.downloadSettings( SettingsFrom.MEMORY_CARD );
if( data != null )
{
memoryCard.setMemoryCardContents( heldItem, name, data );
memoryCard.notifyUser( player, MemoryCardMessages.SETTINGS_SAVED );
}
}
else
{
final String savedName = memoryCard.getSettingsName( heldItem );
final NBTTagCompound data = memoryCard.getData( heldItem );
if( this.getUnlocalizedName().equals( savedName ) )
{
tileEntity.uploadSettings( SettingsFrom.MEMORY_CARD, data );
memoryCard.notifyUser( player, MemoryCardMessages.SETTINGS_LOADED );
}
else
{
final String name = memoryCard.getSettingsName( heldItem );
final NBTTagCompound data = memoryCard.getData( heldItem );
if( this.getUnlocalizedName().equals( name ) )
{
final AEBaseTile t = this.getTileEntity( w, pos );
t.uploadSettings( SettingsFrom.MEMORY_CARD, data );
memoryCard.notifyUser( player, MemoryCardMessages.SETTINGS_LOADED );
}
else
{
memoryCard.notifyUser( player, MemoryCardMessages.INVALID_MACHINE );
}
return false;
memoryCard.notifyUser( player, MemoryCardMessages.INVALID_MACHINE );
}
}
return true;
}
}
@@ -19,6 +19,8 @@
package appeng.capabilities;
import net.darkhax.tesla.api.ITeslaConsumer;
import net.darkhax.tesla.api.ITeslaHolder;
import net.minecraft.nbt.NBTBase;
import net.minecraft.util.EnumFacing;
import net.minecraftforge.common.capabilities.Capability;
@@ -41,6 +43,12 @@ public final class Capabilities
@CapabilityInject( IStorageMonitorableAccessor.class )
public static Capability<IStorageMonitorableAccessor> STORAGE_MONITORABLE_ACCESSOR;
@CapabilityInject(ITeslaConsumer.class)
public static Capability<ITeslaConsumer> TESLA_CONSUMER;
@CapabilityInject(ITeslaHolder.class)
public static Capability<ITeslaHolder> TESLA_HOLDER;
/**
* Register AE2 provided capabilities.
*/
@@ -23,7 +23,6 @@ import java.util.Collections;
import java.util.List;
import javax.annotation.Nullable;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.block.model.IBakedModel;
@@ -108,11 +107,7 @@ public class FacadeDispatcherBakedModel implements IBakedModel
ItemFacade itemFacade = (ItemFacade) stack.getItem();
Block block = itemFacade.getBlock( stack );
int meta = itemFacade.getMeta( stack );
// This is kinda fascinating, how do we get the meta from the itemblock
IBlockState state = block.getStateFromMeta( meta );
IBlockState state = itemFacade.getTextureBlockState( stack );
return new FacadeWithBlockBakedModel( baseModel, state, format );
}
@@ -42,6 +42,8 @@ import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraftforge.client.ForgeHooksClient;
import net.minecraftforge.client.MinecraftForgeClient;
import appeng.api.AEApi;
import appeng.api.util.AEAxisAlignedBB;
@@ -100,23 +102,41 @@ public class FacadeBuilder
public static TextureAtlasSprite getSprite( IBakedModel blockModel, IBlockState state, EnumFacing facing, long rand)
{
for( BakedQuad bakedQuad : blockModel.getQuads( state, facing, rand ) )
{
return bakedQuad.getSprite();
}
TextureAtlasSprite firstFound = null;
for( BakedQuad bakedQuad : blockModel.getQuads( state, null, rand ) )
BlockRenderLayer orgLayer = MinecraftForgeClient.getRenderLayer();
try
{
if( firstFound == null )
// Some other mods also distinguish between layers, so we're doing this in a loop from most likely to least likely
for( BlockRenderLayer layer : BlockRenderLayer.values() )
{
firstFound = bakedQuad.getSprite();
}
if( bakedQuad.getFace() == facing )
{
return bakedQuad.getSprite();
ForgeHooksClient.setRenderLayer( layer );
for( BakedQuad bakedQuad : blockModel.getQuads( state, facing, rand ) )
{
return bakedQuad.getSprite();
}
for( BakedQuad bakedQuad : blockModel.getQuads( state, null, rand ) )
{
if( firstFound == null )
{
firstFound = bakedQuad.getSprite();
}
if( bakedQuad.getFace() == facing )
{
return bakedQuad.getSprite();
}
}
}
}
finally
{
ForgeHooksClient.setRenderLayer( orgLayer );
}
return firstFound;
}
@@ -88,8 +88,23 @@ public class AutoRotatingModel implements IBakedModel
builder.setQuadOrientation( null );
}
BakedQuad q = builder.build();
rotated.add( q );
BakedQuad unpackedQuad = builder.build();
// Make a copy of it to resolve the vertex data and throw away the unpacked stuff
// This also fixes a bug in Forge's UnpackedBakedQuad, which unpacks a byte-based normal like 0,0,-1
// to 0,0,-0.99607843. We replace these normals with the proper 0,0,-1 when rotation, which
// causes a bug in the AO lighter, if an unpacked quad pipes this value back to it.
// Packing it back to the vanilla vertex format will fix this inconsistency because it converts
// the normal back to a byte-based format, which then re-applies Forge's own bug when piping it
// to the AO lighter, thus fixing our problem.
BakedQuad packedQuad = new BakedQuad( unpackedQuad.getVertexData(),
quad.getTintIndex(),
unpackedQuad.getFace(),
quad.getSprite(),
quad.shouldApplyDiffuseLighting(),
quad.getFormat()
);
rotated.add( packedQuad );
}
return rotated;
}
+10 -4
View File
@@ -22,7 +22,6 @@ package appeng.core;
import java.io.File;
import java.util.List;
import java.util.concurrent.TimeUnit;
import javax.annotation.Nonnull;
import com.google.common.base.Stopwatch;
@@ -197,10 +196,17 @@ public final class AppEng
if( this.exportConfig.isExportingItemNamesEnabled() )
{
final ExportProcess process = new ExportProcess( this.recipeDirectory, this.exportConfig );
final Thread exportProcessThread = new Thread( process );
if( FMLCommonHandler.instance().getSide().isClient() )
{
final ExportProcess process = new ExportProcess( this.recipeDirectory, this.exportConfig );
final Thread exportProcessThread = new Thread( process );
this.startService( "AE2 CSV Export", exportProcessThread );
this.startService( "AE2 CSV Export", exportProcessThread );
}
else
{
AELog.info( "Disabling item.csv export for custom recipes, since creative tab information is only available on the client." );
}
}
this.registration.initialize( event, this.recipeDirectory, this.customRecipeConfig );
@@ -26,6 +26,8 @@ public enum WailaText
DeviceOnline, DeviceOffline, DeviceMissingChannel,
P2PUnlinked, P2PInputOneOutput, P2PInputManyOutputs, P2POutput,
Locked, Unlocked, Showing,
Contains, Channels;
@@ -77,7 +77,7 @@ public final class EntityChargedQuartz extends AEBaseEntityItem
this.delay++;
final int j = MathHelper.floor_double( this.posX );
final int i = MathHelper.floor_double( this.posY );
final int i = MathHelper.floor_double( (this.getEntityBoundingBox().minY + this.getEntityBoundingBox().maxY) / 2.0D );
final int k = MathHelper.floor_double( this.posZ );
IBlockState state = this.worldObj.getBlockState( new BlockPos( j, i, k ) );
@@ -70,7 +70,7 @@ public final class EntityGrowingCrystal extends EntityItem
if( gc instanceof IGrowableCrystal ) // if it changes this just stops being an issue...
{
final int j = MathHelper.floor_double( this.posX );
final int i = MathHelper.floor_double( this.posY );
final int i = MathHelper.floor_double( (this.getEntityBoundingBox().minY + this.getEntityBoundingBox().maxY) / 2.0D );
final int k = MathHelper.floor_double( this.posZ );
final IBlockState state = this.worldObj.getBlockState( new BlockPos( j, i, k ) );
+9 -21
View File
@@ -21,12 +21,11 @@ package appeng.facade;
import javax.annotation.Nullable;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.init.Blocks;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import appeng.api.AEApi;
@@ -121,10 +120,7 @@ public class FacadePart implements IFacadePart, IBoxProvider
return true;
}
final ItemStack is = this.getTextureItem();
final Block blk = Block.getBlockFromItem( is.getItem() );
return !blk.isOpaqueCube( blk.getDefaultState() );
return this.getBlockState().isOpaqueCube();
}
@Nullable
@@ -147,25 +143,17 @@ public class FacadePart implements IFacadePart, IBoxProvider
@Override
public IBlockState getBlockState()
{
ItemStack itemStack = getTextureItem();
final Item maybeFacade = this.facade.getItem();
if( !(itemStack.getItem() instanceof ItemBlock ) )
// AE Facade
if( maybeFacade instanceof IFacadeItem )
{
return null;
final IFacadeItem facade = (IFacadeItem) maybeFacade;
return facade.getTextureBlockState( this.facade );
}
ItemBlock itemBlock = (ItemBlock) itemStack.getItem();
// Try to get the block state based on the item stack's meta. If this fails, don't consider it for a facade
// This for example fails for Pistons because they hardcoded an invalid meta value in vanilla
try
{
return itemBlock.getBlock().getStateFromMeta( itemStack.getItemDamage() );
}
catch( Exception e )
{
return null;
}
return Blocks.GLASS.getDefaultState();
}
@Override
+2 -3
View File
@@ -19,7 +19,7 @@
package appeng.facade;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.item.ItemStack;
import appeng.api.util.AEPartLocation;
@@ -32,7 +32,6 @@ public interface IFacadeItem
ItemStack getTextureItem( ItemStack is );
int getMeta( ItemStack is );
IBlockState getTextureBlockState( ItemStack is );
Block getBlock( ItemStack is );
}
@@ -39,6 +39,7 @@ import mcp.mobius.waila.api.IWailaDataProvider;
import appeng.api.parts.IPart;
import appeng.integration.modules.waila.part.ChannelWailaDataProvider;
import appeng.integration.modules.waila.part.IPartWailaDataProvider;
import appeng.integration.modules.waila.part.P2PStateWailaDataProvider;
import appeng.integration.modules.waila.part.PartAccessor;
import appeng.integration.modules.waila.part.PartStackWailaDataProvider;
import appeng.integration.modules.waila.part.PowerStateWailaDataProvider;
@@ -78,9 +79,10 @@ public final class PartWailaDataProvider implements IWailaDataProvider
final IPartWailaDataProvider channel = new ChannelWailaDataProvider();
final IPartWailaDataProvider storageMonitor = new StorageMonitorWailaDataProvider();
final IPartWailaDataProvider powerState = new PowerStateWailaDataProvider();
final IPartWailaDataProvider p2pState = new P2PStateWailaDataProvider();
final IPartWailaDataProvider partStack = new PartStackWailaDataProvider();
this.providers = Lists.newArrayList( channel, storageMonitor, powerState, partStack );
this.providers = Lists.newArrayList( channel, storageMonitor, powerState, partStack, p2pState );
}
@Override
@@ -0,0 +1,158 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.integration.modules.waila.part;
import java.util.List;
import com.google.common.collect.Iterators;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import mcp.mobius.waila.api.IWailaConfigHandler;
import mcp.mobius.waila.api.IWailaDataAccessor;
import appeng.api.parts.IPart;
import appeng.core.localization.WailaText;
import appeng.me.GridAccessException;
import appeng.parts.p2p.PartP2PTunnel;
/**
* Provides information about a P2P tunnel to WAILA.
*/
public final class P2PStateWailaDataProvider extends BasePartWailaDataProvider
{
private static final int STATE_UNLINKED = 0;
private static final int STATE_OUTPUT = 1;
private static final int STATE_INPUT = 2;
public static final String TAG_P2P_STATE = "p2p_state";
/**
* Adds state to the tooltip
*
* @param part part with state
* @param currentToolTip to be added to tooltip
* @param accessor wrapper for various information
* @param config config settings
*
* @return modified tooltip
*/
@Override
public List<String> getWailaBody( final IPart part, final List<String> currentToolTip, final IWailaDataAccessor accessor, final IWailaConfigHandler config )
{
if( part instanceof PartP2PTunnel )
{
NBTTagCompound nbtData = accessor.getNBTData();
if( nbtData.hasKey( TAG_P2P_STATE ) )
{
int[] stateArr = nbtData.getIntArray( TAG_P2P_STATE );
if( stateArr.length == 2 )
{
int state = stateArr[0];
int outputs = stateArr[1];
switch( state )
{
case STATE_UNLINKED:
currentToolTip.add( WailaText.P2PUnlinked.getLocal() );
break;
case STATE_OUTPUT:
currentToolTip.add( WailaText.P2POutput.getLocal() );
break;
case STATE_INPUT:
currentToolTip.add( getOutputText( outputs ) );
break;
}
}
}
}
return currentToolTip;
}
@Override
public NBTTagCompound getNBTData( EntityPlayerMP player, IPart part, TileEntity te, NBTTagCompound tag, World world, BlockPos pos )
{
if( part instanceof PartP2PTunnel )
{
PartP2PTunnel tunnel = (PartP2PTunnel) part;
// The default state
int state = STATE_UNLINKED;
int outputCount = 0;
if( !tunnel.isOutput() )
{
outputCount = getOutputCount( tunnel );
if( outputCount > 0 )
{
// Only set it to INPUT if we know there are any outputs
state = STATE_INPUT;
}
}
else
{
PartP2PTunnel input = tunnel.getInput();
if( input != null )
{
state = STATE_OUTPUT;
}
}
tag.setIntArray( TAG_P2P_STATE, new int[] {
state,
outputCount
} );
}
return tag;
}
private static int getOutputCount( PartP2PTunnel tunnel )
{
try
{
return Iterators.size( tunnel.getOutputs().iterator() );
}
catch( GridAccessException e )
{
// Well... unknown size it is!
return 0;
}
}
private static String getOutputText( int outputs )
{
if( outputs <= 1 )
{
return WailaText.P2PInputOneOutput.getLocal();
}
else
{
return String.format( WailaText.P2PInputManyOutputs.getLocal(), outputs );
}
}
}
@@ -38,11 +38,9 @@ import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumBlockRenderType;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.common.property.IExtendedBlockState;
import net.minecraftforge.fml.common.registry.GameRegistry;
import appeng.api.AEApi;
import appeng.api.exceptions.MissingDefinition;
@@ -190,9 +188,6 @@ public class ItemFacade extends AEBaseItem implements IFacadeItem, IAlphaPassIte
ds[0] = Item.getIdFromItem( l.getItem() );
ds[1] = metadata;
data.setIntArray( "x", ds );
final ResourceLocation ui = Item.REGISTRY.getNameForObject( l.getItem() );
data.setString( "modid", ui.getResourceDomain() );
data.setString( "itemname", ui.getResourcePath() );
is.setTagCompound( data );
return is;
}
@@ -211,56 +206,63 @@ public class ItemFacade extends AEBaseItem implements IFacadeItem, IAlphaPassIte
}
@Override
public ItemStack getTextureItem( final ItemStack is )
public ItemStack getTextureItem( ItemStack is )
{
final Block blk = this.getBlock( is );
if( blk != null )
NBTTagCompound nbt = is.getTagCompound();
if( nbt == null )
{
return new ItemStack( blk, 1, this.getMeta( is ) );
return null;
}
return null;
// First item is numeric item id, second is damage
int[] ids = nbt.getIntArray( "x" );
if( ids.length != 2 )
{
return null;
}
Item baseItem = Item.REGISTRY.getObjectById( ids[0] );
if( baseItem == null )
{
return null;
}
return new ItemStack( baseItem, 1, ids[1] );
}
@Override
public int getMeta( final ItemStack is )
public IBlockState getTextureBlockState( ItemStack is )
{
final NBTTagCompound data = is.getTagCompound();
if( data != null )
{
final int[] blk = data.getIntArray( "x" );
if( blk != null && blk.length == 2 )
{
return blk[1];
}
}
return 0;
}
@Override
public Block getBlock( final ItemStack is )
{
final NBTTagCompound data = is.getTagCompound();
if( data != null )
{
if( data.hasKey( "modid" ) && data.hasKey( "itemname" ) )
{
if( data.getString( "modid" ).equals( "minecraft" ) )
{
return Block.getBlockFromName( data.getString( "itemname" ) );
}
ItemStack baseItemStack = getTextureItem( is );
return GameRegistry.findBlock( data.getString( "modid" ), data.getString( "itemname" ) );
}
else
{
final int[] blk = data.getIntArray( "x" );
if( blk != null && blk.length == 2 )
{
return Block.getBlockById( blk[0] );
}
}
if( baseItemStack == null )
{
return Blocks.GLASS.getDefaultState();
}
return Blocks.GLASS;
Block block = Block.getBlockFromItem( baseItemStack.getItem() );
if( block == null )
{
return Blocks.GLASS.getDefaultState();
}
try
{
return block.getStateFromMeta( baseItemStack.getItemDamage() );
}
catch( Exception e )
{
AELog.warn( "Block {} has broken getStateFromMeta method for meta {}", block.getRegistryName(), baseItemStack.getItemDamage() );
return Blocks.GLASS.getDefaultState();
}
}
public List<ItemStack> getFacades()
@@ -294,19 +296,14 @@ public class ItemFacade extends AEBaseItem implements IFacadeItem, IAlphaPassIte
@Override
public boolean useAlphaPass( final ItemStack is )
{
final ItemStack out = this.getTextureItem( is );
IBlockState blockState = this.getTextureBlockState( is );
if( out == null || out.getItem() == null )
if( blockState == null )
{
return false;
}
final Block blk = Block.getBlockFromItem( out.getItem() );
if( blk != null && blk.canRenderInLayer( BlockRenderLayer.TRANSLUCENT ) )
{
return true;
}
return false;
Block blk = blockState.getBlock();
return blk.canRenderInLayer( BlockRenderLayer.TRANSLUCENT );
}
}
@@ -27,6 +27,7 @@ import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.common.capabilities.ICapabilityProvider;
import appeng.api.config.AccessRestriction;
import appeng.api.config.PowerUnits;
@@ -145,27 +146,6 @@ public abstract class AERootPoweredItem extends AEBaseItem implements IAEItemPow
return currentStorage;
}
/**
* inject external
*/
double injectExternalPower( final PowerUnits input, final ItemStack is, final double amount, final boolean simulate )
{
if( simulate )
{
final int requiredEU = (int) PowerUnits.AE.convertTo( PowerUnits.EU, this.getAEMaxPower( is ) - this.getAECurrentPower( is ) );
if( amount < requiredEU )
{
return 0;
}
return amount - requiredEU;
}
else
{
final double powerRemainder = this.injectAEPower( is, PowerUnits.EU.convertTo( PowerUnits.AE, amount ) );
return PowerUnits.AE.convertTo( PowerUnits.EU, powerRemainder );
}
}
@Override
public double injectAEPower( final ItemStack is, final double amt )
{
@@ -196,6 +176,12 @@ public abstract class AERootPoweredItem extends AEBaseItem implements IAEItemPow
return AccessRestriction.WRITE;
}
@Override
public ICapabilityProvider initCapabilities( ItemStack stack, NBTTagCompound nbt )
{
return new PoweredItemCapabilities( stack, this );
}
private enum batteryOperation
{
STORAGE, INJECT, EXTRACT
@@ -0,0 +1,158 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.items.tools.powered.powersink;
import javax.annotation.Nullable;
import net.darkhax.tesla.api.ITeslaConsumer;
import net.darkhax.tesla.api.ITeslaHolder;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.ICapabilityProvider;
import net.minecraftforge.energy.CapabilityEnergy;
import net.minecraftforge.energy.IEnergyStorage;
import appeng.api.config.PowerUnits;
import appeng.api.implementations.items.IAEItemPowerStorage;
import appeng.capabilities.Capabilities;
/**
* The capability provider to expose chargable items to other mods.
*/
class PoweredItemCapabilities implements ICapabilityProvider, IEnergyStorage
{
private final ItemStack is;
private final IAEItemPowerStorage item;
private final Object teslaAdapter;
PoweredItemCapabilities( ItemStack is, IAEItemPowerStorage item )
{
this.is = is;
this.item = item;
if( Capabilities.TESLA_CONSUMER != null || Capabilities.TESLA_HOLDER != null )
{
this.teslaAdapter = new TeslaAdapter();
}
else
{
this.teslaAdapter = null;
}
}
@Override
public boolean hasCapability( Capability<?> capability, @Nullable EnumFacing facing )
{
return capability == CapabilityEnergy.ENERGY
|| capability == Capabilities.TESLA_CONSUMER
|| capability == Capabilities.TESLA_HOLDER;
}
@SuppressWarnings( "unchecked" )
@Override
public <T> T getCapability( Capability<T> capability, @Nullable EnumFacing facing )
{
if( capability == CapabilityEnergy.ENERGY )
{
return (T) this;
}
else if( capability == Capabilities.TESLA_CONSUMER || capability == Capabilities.TESLA_HOLDER )
{
return (T) teslaAdapter;
}
return null;
}
@Override
public int receiveEnergy( int maxReceive, boolean simulate )
{
if( simulate )
{
final int required = (int) PowerUnits.AE.convertTo( PowerUnits.RF, item.getAEMaxPower( is ) - item.getAECurrentPower( is ) );
if( maxReceive < required )
{
return 0;
}
return maxReceive - required;
}
else
{
final double powerRemainder = item.injectAEPower( is, PowerUnits.RF.convertTo( PowerUnits.AE, maxReceive ) );
return (int) PowerUnits.AE.convertTo( PowerUnits.RF, powerRemainder );
}
}
@Override
public int extractEnergy( int maxExtract, boolean simulate )
{
return 0;
}
@Override
public int getEnergyStored()
{
return (int) PowerUnits.AE.convertTo( PowerUnits.RF, item.getAECurrentPower( is ) );
}
@Override
public int getMaxEnergyStored()
{
return (int) PowerUnits.AE.convertTo( PowerUnits.RF, item.getAEMaxPower( is ) );
}
@Override
public boolean canExtract()
{
return false;
}
@Override
public boolean canReceive()
{
return true;
}
private class TeslaAdapter implements ITeslaConsumer, ITeslaHolder
{
@Override
public long givePower( long power, boolean simulated )
{
return receiveEnergy( (int) power, simulated );
}
@Override
public long getStoredPower()
{
return getEnergyStored();
}
@Override
public long getCapacity()
{
return getMaxEnergyStored();
}
}
}
@@ -1,64 +0,0 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.items.tools.powered.powersink;
//import java.util.Optional;
//
//import net.minecraft.item.ItemStack;
//
//import cofh.api.energy.IEnergyContainerItem;
//
//import appeng.api.config.PowerUnits;
//import appeng.integration.IntegrationType;
//import appeng.transformer.annotations.Integration.Interface;
//
//
//@Interface( iface = "cofh.api.energy.IEnergyContainerItem", iname = IntegrationType.RFItem )
//public abstract class RedstoneFlux extends IC2 implements IEnergyContainerItem
//{
// public RedstoneFlux( double powerCapacity, Optional<String> subName )
// {
// super( powerCapacity, subName );
// }
//
// @Override
// public int receiveEnergy( ItemStack is, int maxReceive, boolean simulate )
// {
// return maxReceive - (int) this.injectExternalPower( PowerUnits.RF, is, maxReceive, simulate );
// }
//
// @Override
// public int extractEnergy( ItemStack container, int maxExtract, boolean simulate )
// {
// return 0;
// }
//
// @Override
// public int getEnergyStored( ItemStack is )
// {
// return (int) PowerUnits.AE.convertTo( PowerUnits.RF, this.getAECurrentPower( is ) );
// }
//
// @Override
// public int getMaxEnergyStored( ItemStack is )
// {
// return (int) PowerUnits.AE.convertTo( PowerUnits.RF, this.getAEMaxPower( is ) );
// }
// }
@@ -1,56 +0,0 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.items.tools.powered.powersink;
/*
@Interface(iface = "universalelectricity.core.item.IItemElectric", modid = "IC2")
public class UniversalElectricity extends ThermalExpansion implements IItemElectric
{
*
* public UniversalElectricity(Class c, String subName) { super( c, subName ); }
*
* @Override public float recharge(ItemStack is, float energy, boolean
* doRecharge) { return (float) (energy - injectExternalPower( PowerUnits.KJ,
* is, energy, !doRecharge )); }
*
* @Override public float discharge(ItemStack is, float energy, boolean
* doDischarge) { return 0; }
*
* @Override public float getElectricityStored(ItemStack is) { return (int)
* PowerUnits.AE.convertTo( PowerUnits.KJ, getAECurrentPower( is ) ); }
*
* @Override public float getMaxElectricityStored(ItemStack is) { return (int)
* PowerUnits.AE.convertTo( PowerUnits.KJ, getAEMaxPower( is ) ); }
*
* @Override public void setElectricity(ItemStack is, float joules) { double
* currentPower = getAECurrentPower( is ); double targetPower =
* PowerUnits.KJ.convertTo( PowerUnits.AE, joules ); if ( targetPower >
* currentPower ) injectAEPower( is, targetPower - currentPower ); else
* extractAEPower( is, currentPower - targetPower ); }
*
* @Override public float getTransfer(ItemStack is) { return (float)
* PowerUnits.AE.convertTo( PowerUnits.KJ, getAEMaxPower( is ) -
* getAECurrentPower( is ) ); }
*
* @Override public float getVoltage(ItemStack itemStack) { return 120; }
}
*/
@@ -172,6 +172,7 @@ public class PartPlacement
{
if( host.getFacadeContainer().addFacade( fp ) )
{
host.markForSave();
host.markForUpdate();
if( !player.capabilities.isCreativeMode )
{
@@ -135,6 +135,7 @@ public class PartAnnihilationPlane extends PartBasicState implements IGridTickab
}
bch.addBox( 5, 5, 14, 11, 11, 15 );
// The smaller collision hitbox here is needed to allow for the entity collision event
bch.addBox( minX, minY, 15, maxX, maxY, bch.isBBCollision() ? 15 : 16 );
}
@@ -232,6 +233,9 @@ public class PartAnnihilationPlane extends PartBasicState implements IGridTickab
boolean capture = false;
final BlockPos pos = this.getTile().getPos();
// This is the middle point of the entities BB, which is better suited for comparisons that don't rely on it "touching" the plane
double posYMiddle = (entity.getEntityBoundingBox().minY + entity.getEntityBoundingBox().maxY) / 2.0D;
switch( this.getSide() )
{
case DOWN:
@@ -251,7 +255,7 @@ public class PartAnnihilationPlane extends PartBasicState implements IGridTickab
case NORTH:
if( entity.posX > pos.getX() && entity.posX < pos.getX() + 1 )
{
if( entity.posY > pos.getY() && entity.posY < pos.getY() + 1 )
if( posYMiddle > pos.getY() && posYMiddle < pos.getY() + 1 )
{
if( ( entity.posZ > pos.getZ() + 0.9 && this.getSide() == AEPartLocation.SOUTH ) || ( entity.posZ < pos.getZ() + 0.1 && this.getSide() == AEPartLocation.NORTH ) )
{
@@ -264,7 +268,7 @@ public class PartAnnihilationPlane extends PartBasicState implements IGridTickab
case WEST:
if( entity.posZ > pos.getZ() && entity.posZ < pos.getZ() + 1 )
{
if( entity.posY > pos.getY() && entity.posY < pos.getY() + 1 )
if( posYMiddle > pos.getY() && posYMiddle < pos.getY() + 1 )
{
if( ( entity.posX > pos.getX() + 0.9 && this.getSide() == AEPartLocation.EAST ) || ( entity.posX < pos.getX() + 0.1 && this.getSide() == AEPartLocation.WEST ) )
{
@@ -100,7 +100,7 @@ public class PartP2PLight extends PartP2PTunnel<PartP2PLight> implements IGridTi
final TileEntity te = this.getTile();
final World w = te.getWorld();
final int newLevel = w.getLight( te.getPos().offset( this.getSide().getFacing() ) );
final int newLevel = w.getLightFromNeighbors( te.getPos().offset( this.getSide().getFacing() ) );
if( this.lastValue != newLevel && this.getProxy().isActive() )
{
@@ -73,7 +73,7 @@ public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicSt
return null;
}
T getInput()
public T getInput()
{
if( this.getFrequency() == 0 )
{
@@ -95,7 +95,7 @@ public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicSt
return null;
}
TunnelCollection<T> getOutputs() throws GridAccessException
public TunnelCollection<T> getOutputs() throws GridAccessException
{
if( this.getProxy().isActive() )
{
@@ -187,7 +187,7 @@ public class TileCableBus extends AEBaseTile implements AEMultiTile, ICustomColl
if( newLV != this.oldLV )
{
this.oldLV = newLV;
this.worldObj.getLight( this.pos );
this.worldObj.checkLight( this.pos );
// worldObj.updateAllLightTypes( xCoord, yCoord, zCoord );
}
@@ -22,11 +22,9 @@ package appeng.tile.powersink;
import java.util.EnumSet;
import javax.annotation.Nullable;
import net.darkhax.tesla.api.ITeslaConsumer;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.EnumFacing;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.CapabilityInject;
import net.minecraftforge.energy.CapabilityEnergy;
import net.minecraftforge.energy.IEnergyStorage;
@@ -36,6 +34,7 @@ import appeng.api.config.PowerMultiplier;
import appeng.api.config.PowerUnits;
import appeng.api.networking.energy.IAEPowerStorage;
import appeng.api.networking.events.MENetworkPowerStorage.PowerEventType;
import appeng.capabilities.Capabilities;
import appeng.integration.modules.IC2;
import appeng.integration.modules.ic2.IC2PowerSink;
import appeng.tile.AEBaseInvTile;
@@ -45,8 +44,6 @@ import appeng.tile.events.TileEventType;
public abstract class AERootPoweredTile extends AEBaseInvTile implements IAEPowerStorage, IExternalPowerSink
{
@CapabilityInject(ITeslaConsumer.class)
private static Capability<ITeslaConsumer> teslaConsumerCapability;
// values that determine general function, are set by inheriting classes if
// needed. These should generally remain static.
@@ -64,7 +61,7 @@ public abstract class AERootPoweredTile extends AEBaseInvTile implements IAEPowe
public AERootPoweredTile()
{
forgeEnergyAdapter = new ForgeEnergyAdapter( this );
if( teslaConsumerCapability != null )
if( Capabilities.TESLA_CONSUMER != null )
{
teslaEnergyAdapter = new TeslaEnergyAdapter( this );
}
@@ -293,7 +290,7 @@ public abstract class AERootPoweredTile extends AEBaseInvTile implements IAEPowe
return true;
}
}
else if( capability == teslaConsumerCapability )
else if( capability == Capabilities.TESLA_CONSUMER )
{
if( this.getPowerSides().contains( facing ) )
{
@@ -315,7 +312,7 @@ public abstract class AERootPoweredTile extends AEBaseInvTile implements IAEPowe
return (T) forgeEnergyAdapter;
}
}
else if( capability == teslaConsumerCapability )
else if( capability == Capabilities.TESLA_CONSUMER )
{
if( this.getPowerSides().contains( facing ) )
{
@@ -1,125 +0,0 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.tile.powersink;
//import java.util.EnumSet;
//
//import net.minecraft.tileentity.TileEntity;
//import net.minecraftforge.common.util.ForgeDirection;
//
//import ic2.api.energy.tile.IEnergySink;
//
//import appeng.api.config.PowerUnits;
//import appeng.integration.IntegrationRegistry;
//import appeng.integration.IntegrationType;
//import appeng.integration.abstraction.IIC2;
//import appeng.transformer.annotations.Integration.Interface;
//import appeng.util.Platform;
//
//
//@Interface( iname = IntegrationType.IC2, iface = "ic2.api.energy.tile.IEnergySink" )
//public abstract class IC2 extends AERootPoweredTile implements IEnergySink
//{
//
// boolean isInIC2 = false;
//
// @Override
// public final boolean acceptsEnergyFrom( TileEntity emitter, ForgeDirection direction )
// {
// return this.getPowerSides().contains( direction );
// }
//
// @Override
// public final double getDemandedEnergy()
// {
// return this.getExternalPowerDemand( PowerUnits.EU, Double.MAX_VALUE );
// }
//
// @Override
// public final int getSinkTier()
// {
// return Integer.MAX_VALUE;
// }
//
// @Override
// public final double injectEnergy( ForgeDirection directionFrom, double amount, double voltage )
// {
// // just store the excess in the current block, if I return the waste,
// // IC2 will just disintegrate it - Oct 20th 2013
// double overflow = PowerUnits.EU.convertTo( PowerUnits.AE, this.injectExternalPower( PowerUnits.EU, amount ) );
// this.internalCurrentPower += overflow;
// return 0; // see above comment.
// }
//
// @Override
// public void invalidate()
// {
// super.invalidate();
// this.removeFromENet();
// }
//
// private void removeFromENet()
// {
// if( IntegrationRegistry.INSTANCE.isEnabled( IntegrationType.IC2 ) )
// {
// IIC2 ic2Integration = (IIC2) IntegrationRegistry.INSTANCE.getInstance( IntegrationType.IC2 );
// if( this.isInIC2 && Platform.isServer() && ic2Integration != null )
// {
// ic2Integration.removeFromEnergyNet( this );
// this.isInIC2 = false;
// }
// }
// }
//
// @Override
// public void onChunkUnload()
// {
// super.onChunkUnload();
// this.removeFromENet();
// }
//
// @Override
// public void onReady()
// {
// super.onReady();
// this.addToENet();
// }
//
// private void addToENet()
// {
// if( IntegrationRegistry.INSTANCE.isEnabled( IntegrationType.IC2 ) )
// {
// IIC2 ic2Integration = (IIC2) IntegrationRegistry.INSTANCE.getInstance( IntegrationType.IC2 );
// if( !this.isInIC2 && Platform.isServer() && ic2Integration != null )
// {
// ic2Integration.addToEnergyNet( this );
// this.isInIC2 = true;
// }
// }
// }
//
// @Override
// protected void setPowerSides( EnumSet<ForgeDirection> sides )
// {
// super.setPowerSides( sides );
// this.removeFromENet();
// this.addToENet();
// }
// }
@@ -206,15 +206,16 @@ public class TileDrive extends AENetworkInvTile implements IChestOrDrive, IPrior
private void recalculateDisplay()
{
final boolean currentActive = this.getProxy().isActive();
int newState = this.state;
if( currentActive )
{
this.state |= 0x80000000;
newState |= 0x80000000;
}
else
{
this.state &= ~0x80000000;
newState &= ~0x80000000;
}
if( this.wasActive != currentActive )
@@ -232,12 +233,12 @@ public class TileDrive extends AENetworkInvTile implements IChestOrDrive, IPrior
for( int x = 0; x < this.getCellCount(); x++ )
{
this.state |= ( this.getCellStatus( x ) << ( 3 * x ) );
newState |= ( this.getCellStatus( x ) << ( 3 * x ) );
}
final int oldState = 0;
if( oldState != this.state )
if( newState != this.state )
{
this.state = newState;
this.markForUpdate();
}
}
@@ -360,6 +360,10 @@ waila.appliedenergistics2.Unlocked=Unlocked
waila.appliedenergistics2.Showing=Showing
waila.appliedenergistics2.Contains=Contains
waila.appliedenergistics2.Channels=%1$d of %2$d Channels
waila.appliedenergistics2.P2PUnlinked=Unlinked
waila.appliedenergistics2.P2PInputOneOutput=Linked (Input Side)
waila.appliedenergistics2.P2PInputManyOutputs=Linked (Input Side) - %d Outputs
waila.appliedenergistics2.P2POutput=Linked (Output Side)
// Items
item.appliedenergistics2.storage_cell_1k.name=1k ME Storage Cell