Compare commits

...

8 Commits

Author SHA1 Message Date
fscan fa2b4fabc7 Fix ConcurrentModificatonException in NetworkEventBus (#3660) 2018-08-01 00:35:44 +02:00
Saereth f8d5f4ddb1 Fixes #3478: Changes the way xp drops from Certus Ore blocks (#3482) 2018-06-26 23:36:21 +02:00
fscan f8dfa2619e Fixes #3535: Prevent crash when either quartz types are disabled (#3542)
* Fixes crash when either quartz types are disabled and prevent cascading worldgen.
* Also fixes  #3486
2018-06-26 15:31:03 +02:00
fscan c1d1dc947f Fixes #3548: AEBaseTile now respect overridden markDirty implementations. (#3550) 2018-06-26 10:33:56 +02:00
fscan 6bb465be0b Fixes #3449: Prevent CellInventory#getCell() from mutating the cell itemstack definition (#3552)
CellInventory#getCell() initalizes the ItemStack with an empty NBT and therefore was messing with the item definition.
2018-06-26 10:32:58 +02:00
fscan 8902af9766 Fixes #3459: Open the inventory if raytrace misses (#3549) 2018-06-26 10:31:17 +02:00
fscan 2b592dd40e Fixes DriveBakedModel to not crash when SLOT_STATE is null (#3545)
Uses a null object in case the TE is not available for whichever reason.
2018-06-18 19:03:28 +02:00
fscan 41e7558b24 Fixes interface shift-clicking to generate correct onChangeInventory events (#3544) 2018-06-18 19:01:17 +02:00
9 changed files with 72 additions and 48 deletions
@@ -74,13 +74,8 @@ public class BlockDrive extends AEBaseTileBlock
public IBlockState getExtendedState( IBlockState state, IBlockAccess world, BlockPos pos )
{
TileDrive te = this.getTileEntity( world, pos );
if( te == null )
{
return super.getExtendedState( state, world, pos );
}
IExtendedBlockState extState = (IExtendedBlockState) super.getExtendedState( state, world, pos );
return extState.withProperty( SLOTS_STATE, DriveSlotsState.fromChestOrDrive( te ) );
return extState.withProperty( SLOTS_STATE, te == null ? DriveSlotsState.createEmpty( 10 ) : DriveSlotsState.fromChestOrDrive( te ) );
}
@Override
@@ -75,4 +75,14 @@ public class DriveSlotsState
}
return new DriveSlotsState( slots );
}
public static DriveSlotsState createEmpty( int slotCount )
{
DriveSlotState[] slots = new DriveSlotState[slotCount];
for( int i = 0; i < slotCount; i++ )
{
slots[i] = DriveSlotState.EMPTY;
}
return new DriveSlotsState( slots );
}
}
@@ -436,6 +436,8 @@ public abstract class AEBaseContainer extends Container
}
else
{
tis = tis.copy();
// target slots in the container...
for( final Object inventorySlot : this.inventorySlots )
{
@@ -496,7 +498,7 @@ public abstract class AEBaseContainer extends Container
{
if( d.getHasStack() )
{
final ItemStack t = d.getStack();
final ItemStack t = d.getStack().copy();
if( Platform.itemComparisons().isSameItem( tis, t ) ) // t.isItemEqual(tis))
{
@@ -516,6 +518,8 @@ public abstract class AEBaseContainer extends Container
t.setCount( t.getCount() + placeAble );
tis.setCount( tis.getCount() - placeAble );
d.putStack( t );
if( tis.getCount() <= 0 )
{
clickSlot.putStack( ItemStack.EMPTY );
@@ -548,7 +552,7 @@ public abstract class AEBaseContainer extends Container
{
if( d.getHasStack() )
{
final ItemStack t = d.getStack();
final ItemStack t = d.getStack().copy();
if( Platform.itemComparisons().isSameItem( t, tis ) )
{
@@ -568,6 +572,8 @@ public abstract class AEBaseContainer extends Container
t.setCount( t.getCount() + placeAble );
tis.setCount( tis.getCount() - placeAble );
d.putStack( t );
if( tis.getCount() <= 0 )
{
clickSlot.putStack( ItemStack.EMPTY );
@@ -626,7 +632,7 @@ public abstract class AEBaseContainer extends Container
}
}
clickSlot.putStack( !tis.isEmpty() ? tis.copy() : ItemStack.EMPTY );
clickSlot.putStack( !tis.isEmpty() ? tis : ItemStack.EMPTY );
}
this.updateSlot( clickSlot );
@@ -27,6 +27,7 @@ import net.minecraft.item.Item;
import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import appeng.api.AEApi;
@@ -76,16 +77,15 @@ public class BlockQuartzOre extends AEBaseBlock
}
@Override
public void dropBlockAsItemWithChance( final World w, final BlockPos pos, final IBlockState state, final float chance, final int fortune )
public int getExpDrop( IBlockState state, IBlockAccess world, BlockPos pos, int fortune )
{
super.dropBlockAsItemWithChance( w, pos, state, chance, fortune );
if( this.getItemDropped( state, w.rand, fortune ) != Item.getItemFromBlock( this ) )
{
final int xp = MathHelper.getInt( w.rand, 2, 5 );
this.dropXpOnBlockBreak( w, pos, xp );
Random rand = world instanceof World ? ( (World) world ).rand : new Random();
if ( this.getItemDropped( state, rand, fortune ) != Item.getItemFromBlock( this ) )
{
return MathHelper.getInt( rand, 2, 5 );
}
return super.getExpDrop( state, world, pos, fortune );
}
@Override
@@ -83,16 +83,9 @@ public class ToolNetworkTool extends AEBaseItem implements IGuiItem, IAEWrench,
{
final RayTraceResult mop = AppEng.proxy.getRTR();
if( mop == null )
if( mop == null || mop.typeOfHit == RayTraceResult.Type.MISS )
{
this.onItemUseFirst( p, w, new BlockPos( 0, 0, 0 ), null, 0, 0, 0, hand ); // eh?
}
else
{
if( w.getBlockState( mop.getBlockPos() ).getBlock().isAir( w.getBlockState( mop.getBlockPos() ), w, mop.getBlockPos() ) )
{
this.onItemUseFirst( p, w, new BlockPos( 0, 0, 0 ), null, 0, 0, 0, hand ); // eh?
}
NetworkHandler.instance().sendToServer( new PacketClick( BlockPos.ORIGIN, null, 0, 0, 0, hand ) );
}
}
+13 -3
View File
@@ -29,6 +29,7 @@ import java.util.Map;
import java.util.Map.Entry;
import appeng.api.networking.IGridNode;
import appeng.api.networking.IMachineSet;
import appeng.api.networking.events.MENetworkEvent;
import appeng.api.networking.events.MENetworkEventSubscribe;
import appeng.core.AELog;
@@ -114,10 +115,19 @@ public class NetworkEventBus
target.invoke( cache.getCache(), e );
}
for( final IGridNode obj : g.getMachines( subscriber.getKey() ) )
// events may create or remove grid nodes in rare cases
final IMachineSet machines = g.getMachines( subscriber.getKey() );
final List<IGridNode> work = new ArrayList<>( machines.size() );
machines.forEach( work::add );
for( final IGridNode obj : work )
{
x++;
target.invoke( obj.getMachine(), e );
// stil part of grid?
if( machines.contains( obj ) )
{
x++;
target.invoke( obj.getMachine(), e );
}
}
}
}
@@ -223,7 +223,7 @@ public class CellInventory implements ICellInventory
// any NBT data for empty cells instead of relying on an empty IItemContainer
if( CellInventory.isStorageCell( input.getDefinition() ) )
{
final IMEInventory meInventory = getCell( input.getDefinition(), null );
final IMEInventory meInventory = getCell( input.createItemStack(), null );
if( meInventory != null && !this.isEmpty( meInventory ) )
{
return input;
+1 -1
View File
@@ -488,7 +488,7 @@ public class AEBaseTile extends TileEntity implements IOrientable, ICommonTile,
public void saveChanges()
{
super.markDirty();
markDirty();
}
public boolean requiresTESR()
@@ -21,7 +21,6 @@ package appeng.worldgen;
import java.util.Random;
import net.minecraft.block.Block;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.chunk.IChunkProvider;
@@ -48,16 +47,22 @@ public final class QuartzWorldGen implements IWorldGenerator
final IBlockDefinition oreDefinition = blocks.quartzOre();
final IBlockDefinition chargedDefinition = blocks.quartzOreCharged();
final Block ore = oreDefinition.maybeBlock().orElse( null );
final Block charged = chargedDefinition.maybeBlock().orElse( null );
this.oreNormal = new WorldGenMinable( ore.getDefaultState(), AEConfig.instance().getQuartzOresPerCluster() );
this.oreCharged = new WorldGenMinable( charged.getDefaultState(), AEConfig.instance().getQuartzOresPerCluster() );
this.oreNormal = oreDefinition.maybeBlock()
.map( b -> new WorldGenMinable( b.getDefaultState(), AEConfig.instance().getQuartzOresPerCluster() ) )
.orElse( null );
this.oreCharged = chargedDefinition.maybeBlock()
.map( b -> new WorldGenMinable( b.getDefaultState(), AEConfig.instance().getQuartzOresPerCluster() ) )
.orElse( null );
}
@Override
public void generate( final Random r, final int chunkX, final int chunkZ, final World w, final IChunkGenerator chunkGenerator, final IChunkProvider chunkProvider )
{
if( this.oreNormal == null && this.oreCharged == null )
{
return;
}
int seaLevel = w.provider.getAverageGroundLevel() + 1;
if( seaLevel < 20 )
@@ -67,26 +72,31 @@ public final class QuartzWorldGen implements IWorldGenerator
seaLevel = w.getHeight( x, z );
}
if( this.oreNormal == null || this.oreCharged == null )
{
return;
}
final double oreDepthMultiplier = AEConfig.instance().getQuartzOresClusterAmount() * seaLevel / 64;
final int scale = (int) Math.round( r.nextGaussian() * Math.sqrt( oreDepthMultiplier ) + oreDepthMultiplier );
for( int x = 0; x < ( r.nextBoolean() ? scale * 2 : scale ) / 2; ++x )
for( int cnt = 0; cnt < ( r.nextBoolean() ? scale * 2 : scale ) / 2; ++cnt )
{
final boolean isCharged = r.nextFloat() > AEConfig.instance().getSpawnChargedChance();
final WorldGenMinable whichOre = isCharged ? this.oreCharged : this.oreNormal;
boolean isCharged = false;
if( WorldGenRegistry.INSTANCE.isWorldGenEnabled( isCharged ? WorldGenType.CHARGED_CERTUS_QUARTZ : WorldGenType.CERTUS_QUARTZ, w ) )
if( this.oreCharged != null )
{
final int cx = chunkX * 16 + r.nextInt( 22 );
isCharged = r.nextFloat() > AEConfig.instance().getSpawnChargedChance();
}
final WorldGenMinable whichOre = isCharged ? this.oreCharged : this.oreNormal;
if( whichOre != null && shouldGenerate( isCharged, w ) )
{
final int cx = chunkX * 16 + r.nextInt( 16 );
final int cy = r.nextInt( 40 * seaLevel / 64 ) + r.nextInt( 22 * seaLevel / 64 ) + 12 * seaLevel / 64;
final int cz = chunkZ * 16 + r.nextInt( 22 );
final int cz = chunkZ * 16 + r.nextInt( 16 );
whichOre.generate( w, r, new BlockPos( cx, cy, cz ) );
}
}
}
private static boolean shouldGenerate( final boolean isCharged, final World w )
{
return WorldGenRegistry.INSTANCE.isWorldGenEnabled( isCharged ? WorldGenType.CHARGED_CERTUS_QUARTZ : WorldGenType.CERTUS_QUARTZ, w );
}
}