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 ) public IBlockState getExtendedState( IBlockState state, IBlockAccess world, BlockPos pos )
{ {
TileDrive te = this.getTileEntity( world, pos ); TileDrive te = this.getTileEntity( world, pos );
if( te == null )
{
return super.getExtendedState( state, world, pos );
}
IExtendedBlockState extState = (IExtendedBlockState) 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 @Override
@@ -75,4 +75,14 @@ public class DriveSlotsState
} }
return new DriveSlotsState( slots ); 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 else
{ {
tis = tis.copy();
// target slots in the container... // target slots in the container...
for( final Object inventorySlot : this.inventorySlots ) for( final Object inventorySlot : this.inventorySlots )
{ {
@@ -496,7 +498,7 @@ public abstract class AEBaseContainer extends Container
{ {
if( d.getHasStack() ) if( d.getHasStack() )
{ {
final ItemStack t = d.getStack(); final ItemStack t = d.getStack().copy();
if( Platform.itemComparisons().isSameItem( tis, t ) ) // t.isItemEqual(tis)) if( Platform.itemComparisons().isSameItem( tis, t ) ) // t.isItemEqual(tis))
{ {
@@ -516,6 +518,8 @@ public abstract class AEBaseContainer extends Container
t.setCount( t.getCount() + placeAble ); t.setCount( t.getCount() + placeAble );
tis.setCount( tis.getCount() - placeAble ); tis.setCount( tis.getCount() - placeAble );
d.putStack( t );
if( tis.getCount() <= 0 ) if( tis.getCount() <= 0 )
{ {
clickSlot.putStack( ItemStack.EMPTY ); clickSlot.putStack( ItemStack.EMPTY );
@@ -548,7 +552,7 @@ public abstract class AEBaseContainer extends Container
{ {
if( d.getHasStack() ) if( d.getHasStack() )
{ {
final ItemStack t = d.getStack(); final ItemStack t = d.getStack().copy();
if( Platform.itemComparisons().isSameItem( t, tis ) ) if( Platform.itemComparisons().isSameItem( t, tis ) )
{ {
@@ -568,6 +572,8 @@ public abstract class AEBaseContainer extends Container
t.setCount( t.getCount() + placeAble ); t.setCount( t.getCount() + placeAble );
tis.setCount( tis.getCount() - placeAble ); tis.setCount( tis.getCount() - placeAble );
d.putStack( t );
if( tis.getCount() <= 0 ) if( tis.getCount() <= 0 )
{ {
clickSlot.putStack( ItemStack.EMPTY ); 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 ); this.updateSlot( clickSlot );
@@ -27,6 +27,7 @@ import net.minecraft.item.Item;
import net.minecraft.util.BlockRenderLayer; import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World; import net.minecraft.world.World;
import appeng.api.AEApi; import appeng.api.AEApi;
@@ -76,16 +77,15 @@ public class BlockQuartzOre extends AEBaseBlock
} }
@Override @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 ); Random rand = world instanceof World ? ( (World) world ).rand : new Random();
if( this.getItemDropped( state, w.rand, fortune ) != Item.getItemFromBlock( this ) ) if ( this.getItemDropped( state, rand, fortune ) != Item.getItemFromBlock( this ) )
{ {
final int xp = MathHelper.getInt( w.rand, 2, 5 ); return MathHelper.getInt( rand, 2, 5 );
this.dropXpOnBlockBreak( w, pos, xp );
} }
return super.getExpDrop( state, world, pos, fortune );
} }
@Override @Override
@@ -83,16 +83,9 @@ public class ToolNetworkTool extends AEBaseItem implements IGuiItem, IAEWrench,
{ {
final RayTraceResult mop = AppEng.proxy.getRTR(); 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? NetworkHandler.instance().sendToServer( new PacketClick( BlockPos.ORIGIN, null, 0, 0, 0, hand ) );
}
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?
}
} }
} }
+13 -3
View File
@@ -29,6 +29,7 @@ import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import appeng.api.networking.IGridNode; import appeng.api.networking.IGridNode;
import appeng.api.networking.IMachineSet;
import appeng.api.networking.events.MENetworkEvent; import appeng.api.networking.events.MENetworkEvent;
import appeng.api.networking.events.MENetworkEventSubscribe; import appeng.api.networking.events.MENetworkEventSubscribe;
import appeng.core.AELog; import appeng.core.AELog;
@@ -114,10 +115,19 @@ public class NetworkEventBus
target.invoke( cache.getCache(), e ); 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++; // stil part of grid?
target.invoke( obj.getMachine(), e ); 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 // any NBT data for empty cells instead of relying on an empty IItemContainer
if( CellInventory.isStorageCell( input.getDefinition() ) ) 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 ) ) if( meInventory != null && !this.isEmpty( meInventory ) )
{ {
return input; return input;
+1 -1
View File
@@ -488,7 +488,7 @@ public class AEBaseTile extends TileEntity implements IOrientable, ICommonTile,
public void saveChanges() public void saveChanges()
{ {
super.markDirty(); markDirty();
} }
public boolean requiresTESR() public boolean requiresTESR()
@@ -21,7 +21,6 @@ package appeng.worldgen;
import java.util.Random; import java.util.Random;
import net.minecraft.block.Block;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.chunk.IChunkProvider; import net.minecraft.world.chunk.IChunkProvider;
@@ -48,16 +47,22 @@ public final class QuartzWorldGen implements IWorldGenerator
final IBlockDefinition oreDefinition = blocks.quartzOre(); final IBlockDefinition oreDefinition = blocks.quartzOre();
final IBlockDefinition chargedDefinition = blocks.quartzOreCharged(); final IBlockDefinition chargedDefinition = blocks.quartzOreCharged();
final Block ore = oreDefinition.maybeBlock().orElse( null ); this.oreNormal = oreDefinition.maybeBlock()
final Block charged = chargedDefinition.maybeBlock().orElse( null ); .map( b -> new WorldGenMinable( b.getDefaultState(), AEConfig.instance().getQuartzOresPerCluster() ) )
.orElse( null );
this.oreNormal = new WorldGenMinable( ore.getDefaultState(), AEConfig.instance().getQuartzOresPerCluster() ); this.oreCharged = chargedDefinition.maybeBlock()
this.oreCharged = new WorldGenMinable( charged.getDefaultState(), AEConfig.instance().getQuartzOresPerCluster() ); .map( b -> new WorldGenMinable( b.getDefaultState(), AEConfig.instance().getQuartzOresPerCluster() ) )
.orElse( null );
} }
@Override @Override
public void generate( final Random r, final int chunkX, final int chunkZ, final World w, final IChunkGenerator chunkGenerator, final IChunkProvider chunkProvider ) 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; int seaLevel = w.provider.getAverageGroundLevel() + 1;
if( seaLevel < 20 ) if( seaLevel < 20 )
@@ -67,26 +72,31 @@ public final class QuartzWorldGen implements IWorldGenerator
seaLevel = w.getHeight( x, z ); seaLevel = w.getHeight( x, z );
} }
if( this.oreNormal == null || this.oreCharged == null )
{
return;
}
final double oreDepthMultiplier = AEConfig.instance().getQuartzOresClusterAmount() * seaLevel / 64; final double oreDepthMultiplier = AEConfig.instance().getQuartzOresClusterAmount() * seaLevel / 64;
final int scale = (int) Math.round( r.nextGaussian() * Math.sqrt( oreDepthMultiplier ) + oreDepthMultiplier ); 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(); boolean isCharged = false;
final WorldGenMinable whichOre = isCharged ? this.oreCharged : this.oreNormal;
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 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 ) ); 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 );
}
} }