diff --git a/src/main/java/dan200/computercraft/shared/computer/blocks/BlockComputerBase.java b/src/main/java/dan200/computercraft/shared/computer/blocks/BlockComputerBase.java index fb738a8d4..975453553 100644 --- a/src/main/java/dan200/computercraft/shared/computer/blocks/BlockComputerBase.java +++ b/src/main/java/dan200/computercraft/shared/computer/blocks/BlockComputerBase.java @@ -6,6 +6,7 @@ package dan200.computercraft.shared.computer.blocks; +import dan200.computercraft.ComputerCraft; import dan200.computercraft.core.computer.ComputerSide; import dan200.computercraft.shared.common.BlockGeneric; import dan200.computercraft.shared.common.IBundledRedstoneBlock; @@ -16,19 +17,26 @@ import dan200.computercraft.shared.util.NamedTileEntityType; import net.minecraft.block.BlockState; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.fluid.IFluidState; import net.minecraft.item.ItemStack; +import net.minecraft.stats.Stats; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.Direction; +import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.RayTraceResult; import net.minecraft.world.IBlockReader; +import net.minecraft.world.ServerWorld; import net.minecraft.world.World; +import net.minecraft.world.storage.loot.LootContext; +import net.minecraft.world.storage.loot.LootParameters; import javax.annotation.Nonnull; +import javax.annotation.Nullable; public abstract class BlockComputerBase extends BlockGeneric implements IBundledRedstoneBlock { + private static final ResourceLocation DROP = new ResourceLocation( ComputerCraft.MOD_ID, "computer" ); + private final ComputerFamily family; protected BlockComputerBase( Properties settings, ComputerFamily family, NamedTileEntityType type ) @@ -118,44 +126,40 @@ public abstract class BlockComputerBase extends Bloc return super.getPickBlock( state, target, world, pos, player ); } - /* TODO: THIS!! @Override - @Deprecated - public final void dropBlockAsItemWithChance( @Nonnull BlockState state, World world, @Nonnull BlockPos pos, float change, int fortune ) + public void harvestBlock( @Nonnull World world, PlayerEntity player, @Nonnull BlockPos pos, BlockState state, @Nullable TileEntity tile, @Nonnull ItemStack tool ) { + // Don't drop blocks here - see onBlockHarvested. + player.addStat( Stats.BLOCK_MINED.get( this ) ); + player.addExhaustion( 0.005F ); } @Override - public final void getDrops( BlockState state, NonNullList drops, World world, BlockPos pos, int fortune ) + public void onBlockHarvested( World world, @Nonnull BlockPos pos, BlockState state, @Nonnull PlayerEntity player ) { + if( !(world instanceof ServerWorld) ) return; + + // We drop the item here instead of doing it in the harvest method, as we should + // drop computers for creative players too. + TileEntity tile = world.getTileEntity( pos ); if( tile instanceof TileComputerBase ) { - ItemStack stack = getItem( (TileComputerBase) tile ); - if( !stack.isEmpty() ) drops.add( stack ); - } - } - */ - - @Override - public boolean removedByPlayer( BlockState state, World world, BlockPos pos, PlayerEntity player, boolean willHarvest, IFluidState fluid ) - { - if( !world.isRemote ) - { - // We drop the item here instead of doing it in the harvest method, as we - // need to drop it for creative players too. - TileEntity tile = world.getTileEntity( pos ); - if( tile instanceof TileComputerBase ) + TileComputerBase computer = (TileComputerBase) tile; + LootContext.Builder context = new LootContext.Builder( (ServerWorld) world ) + .withRandom( world.rand ) + .withParameter( LootParameters.POSITION, pos ) + .withParameter( LootParameters.TOOL, player.getHeldItemMainhand() ) + .withParameter( LootParameters.THIS_ENTITY, player ) + .withNullableParameter( LootParameters.BLOCK_ENTITY, tile ) + .withDynamicDrop( DROP, ( ctx, out ) -> out.accept( getItem( computer ) ) ); + for( ItemStack item : state.getDrops( context ) ) { - TileComputerBase computer = (TileComputerBase) tile; - if( !player.abilities.isCreativeMode || computer.getLabel() != null ) - { - spawnAsEntity( world, pos, getItem( computer ) ); - } + spawnAsEntity( world, pos, item ); } - } - return super.removedByPlayer( state, world, pos, player, willHarvest, fluid ); + state.spawnAdditionalDrops( world, pos, player.getHeldItemMainhand() ); + } } @Override diff --git a/src/main/java/dan200/computercraft/shared/data/BlockNamedEntityLootCondition.java b/src/main/java/dan200/computercraft/shared/data/BlockNamedEntityLootCondition.java new file mode 100644 index 000000000..b8edf002c --- /dev/null +++ b/src/main/java/dan200/computercraft/shared/data/BlockNamedEntityLootCondition.java @@ -0,0 +1,44 @@ +/* + * This file is part of ComputerCraft - http://www.computercraft.info + * Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission. + * Send enquiries to dratcliffe@gmail.com + */ + +package dan200.computercraft.shared.data; + +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.INameable; +import net.minecraft.world.storage.loot.LootContext; +import net.minecraft.world.storage.loot.LootParameter; +import net.minecraft.world.storage.loot.LootParameters; +import net.minecraft.world.storage.loot.conditions.ILootCondition; + +import javax.annotation.Nonnull; +import java.util.Collections; +import java.util.Set; + +/** + * A loot condition which checks if the tile entity has a name. + */ +public final class BlockNamedEntityLootCondition implements ILootCondition +{ + public static final BlockNamedEntityLootCondition INSTANCE = new BlockNamedEntityLootCondition(); + + private BlockNamedEntityLootCondition() + { + } + + @Override + public boolean test( LootContext lootContext ) + { + TileEntity tile = lootContext.get( LootParameters.BLOCK_ENTITY ); + return tile instanceof INameable && ((INameable) tile).hasCustomName(); + } + + @Nonnull + @Override + public Set> getRequiredParameters() + { + return Collections.singleton( LootParameters.BLOCK_ENTITY ); + } +} diff --git a/src/main/java/dan200/computercraft/shared/data/ConstantLootConditionSerializer.java b/src/main/java/dan200/computercraft/shared/data/ConstantLootConditionSerializer.java new file mode 100644 index 000000000..4649b4c08 --- /dev/null +++ b/src/main/java/dan200/computercraft/shared/data/ConstantLootConditionSerializer.java @@ -0,0 +1,43 @@ +/* + * This file is part of ComputerCraft - http://www.computercraft.info + * Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission. + * Send enquiries to dratcliffe@gmail.com + */ + +package dan200.computercraft.shared.data; + +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonObject; +import com.google.gson.JsonSerializationContext; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.storage.loot.conditions.ILootCondition; + +import javax.annotation.Nonnull; + +public final class ConstantLootConditionSerializer extends ILootCondition.AbstractSerializer +{ + private final T instance; + + private ConstantLootConditionSerializer( ResourceLocation id, Class klass, T instance ) + { + super( id, klass ); + this.instance = instance; + } + + public static ILootCondition.AbstractSerializer of( ResourceLocation id, Class klass, T instance ) + { + return new ConstantLootConditionSerializer<>( id, klass, instance ); + } + + @Override + public void serialize( @Nonnull JsonObject json, @Nonnull T object, @Nonnull JsonSerializationContext context ) + { + } + + @Nonnull + @Override + public T deserialize( @Nonnull JsonObject json, @Nonnull JsonDeserializationContext context ) + { + return instance; + } +} diff --git a/src/main/java/dan200/computercraft/shared/data/PlayerCreativeLootCondition.java b/src/main/java/dan200/computercraft/shared/data/PlayerCreativeLootCondition.java new file mode 100644 index 000000000..5c8d45c3b --- /dev/null +++ b/src/main/java/dan200/computercraft/shared/data/PlayerCreativeLootCondition.java @@ -0,0 +1,44 @@ +/* + * This file is part of ComputerCraft - http://www.computercraft.info + * Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission. + * Send enquiries to dratcliffe@gmail.com + */ + +package dan200.computercraft.shared.data; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.world.storage.loot.LootContext; +import net.minecraft.world.storage.loot.LootParameter; +import net.minecraft.world.storage.loot.LootParameters; +import net.minecraft.world.storage.loot.conditions.ILootCondition; + +import javax.annotation.Nonnull; +import java.util.Collections; +import java.util.Set; + +/** + * A loot condition which checks if the entity is in creative mode. + */ +public final class PlayerCreativeLootCondition implements ILootCondition +{ + public static final PlayerCreativeLootCondition INSTANCE = new PlayerCreativeLootCondition(); + + private PlayerCreativeLootCondition() + { + } + + @Override + public boolean test( LootContext lootContext ) + { + Entity entity = lootContext.get( LootParameters.THIS_ENTITY ); + return entity instanceof PlayerEntity && ((PlayerEntity) entity).abilities.isCreativeMode; + } + + @Nonnull + @Override + public Set> getRequiredParameters() + { + return Collections.singleton( LootParameters.THIS_ENTITY ); + } +} diff --git a/src/main/java/dan200/computercraft/shared/proxy/ComputerCraftProxyCommon.java b/src/main/java/dan200/computercraft/shared/proxy/ComputerCraftProxyCommon.java index 45a641ca3..67fdc4b88 100644 --- a/src/main/java/dan200/computercraft/shared/proxy/ComputerCraftProxyCommon.java +++ b/src/main/java/dan200/computercraft/shared/proxy/ComputerCraftProxyCommon.java @@ -19,6 +19,9 @@ import dan200.computercraft.shared.common.DefaultBundledRedstoneProvider; import dan200.computercraft.shared.computer.core.IComputer; import dan200.computercraft.shared.computer.core.IContainerComputer; import dan200.computercraft.shared.computer.core.ServerComputer; +import dan200.computercraft.shared.data.BlockNamedEntityLootCondition; +import dan200.computercraft.shared.data.ConstantLootConditionSerializer; +import dan200.computercraft.shared.data.PlayerCreativeLootCondition; import dan200.computercraft.shared.media.items.RecordMedia; import dan200.computercraft.shared.network.NetworkHandler; import dan200.computercraft.shared.peripheral.commandblock.CommandBlockPeripheral; @@ -29,6 +32,8 @@ import net.minecraft.item.Item; import net.minecraft.item.MusicDiscItem; import net.minecraft.tileentity.CommandBlockTileEntity; import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.storage.loot.conditions.LootConditionManager; import net.minecraftforge.event.entity.player.PlayerContainerEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.client.event.ConfigChangedEvent; @@ -51,6 +56,18 @@ public final class ComputerCraftProxyCommon ArgumentSerializers.register(); + LootConditionManager.registerCondition( ConstantLootConditionSerializer.of( + new ResourceLocation( ComputerCraft.MOD_ID, "block_named" ), + BlockNamedEntityLootCondition.class, + BlockNamedEntityLootCondition.INSTANCE + ) ); + + LootConditionManager.registerCondition( ConstantLootConditionSerializer.of( + new ResourceLocation( ComputerCraft.MOD_ID, "player_creative" ), + PlayerCreativeLootCondition.class, + PlayerCreativeLootCondition.INSTANCE + ) ); + // if( Loader.isModLoaded( ModCharset.MODID ) ) IntegrationCharset.register(); } diff --git a/src/main/resources/data/computercraft/loot_tables/blocks/computer_advanced.json b/src/main/resources/data/computercraft/loot_tables/blocks/computer_advanced.json index 4e5d283e1..26cde0f50 100644 --- a/src/main/resources/data/computercraft/loot_tables/blocks/computer_advanced.json +++ b/src/main/resources/data/computercraft/loot_tables/blocks/computer_advanced.json @@ -4,8 +4,15 @@ { "name": "main", "rolls": 1, - "entries": [ - { "type": "minecraft:dynamic", "name": "computercraft:computer" } + "entries": [ { "type": "minecraft:dynamic", "name": "computercraft:computer" } ], + "conditions": [ + { + "condition": "alternative", + "terms": [ + { "condition": "computercraft:block_named" }, + { "condition": "minecraft:inverted", "term": { "condition": "computercraft:player_creative" } } + ] + } ] } ] diff --git a/src/main/resources/data/computercraft/loot_tables/blocks/computer_command.json b/src/main/resources/data/computercraft/loot_tables/blocks/computer_command.json index 4e5d283e1..26cde0f50 100644 --- a/src/main/resources/data/computercraft/loot_tables/blocks/computer_command.json +++ b/src/main/resources/data/computercraft/loot_tables/blocks/computer_command.json @@ -4,8 +4,15 @@ { "name": "main", "rolls": 1, - "entries": [ - { "type": "minecraft:dynamic", "name": "computercraft:computer" } + "entries": [ { "type": "minecraft:dynamic", "name": "computercraft:computer" } ], + "conditions": [ + { + "condition": "alternative", + "terms": [ + { "condition": "computercraft:block_named" }, + { "condition": "minecraft:inverted", "term": { "condition": "computercraft:player_creative" } } + ] + } ] } ] diff --git a/src/main/resources/data/computercraft/loot_tables/blocks/computer_normal.json b/src/main/resources/data/computercraft/loot_tables/blocks/computer_normal.json index 53f9a6cfe..26cde0f50 100644 --- a/src/main/resources/data/computercraft/loot_tables/blocks/computer_normal.json +++ b/src/main/resources/data/computercraft/loot_tables/blocks/computer_normal.json @@ -4,7 +4,16 @@ { "name": "main", "rolls": 1, - "entries": [ { "type": "minecraft:dynamic", "name": "computercraft:computer" } ] + "entries": [ { "type": "minecraft:dynamic", "name": "computercraft:computer" } ], + "conditions": [ + { + "condition": "alternative", + "terms": [ + { "condition": "computercraft:block_named" }, + { "condition": "minecraft:inverted", "term": { "condition": "computercraft:player_creative" } } + ] + } + ] } ] } diff --git a/src/main/resources/data/computercraft/loot_tables/blocks/disk_drive.json b/src/main/resources/data/computercraft/loot_tables/blocks/disk_drive.json index 74fbfa470..6575281bb 100644 --- a/src/main/resources/data/computercraft/loot_tables/blocks/disk_drive.json +++ b/src/main/resources/data/computercraft/loot_tables/blocks/disk_drive.json @@ -6,12 +6,6 @@ "rolls": 1, "entries": [ { "type": "minecraft:item", "name": "computercraft:disk_drive" } ], "conditions": [ { "condition": "minecraft:survives_explosion" } ] - }, - { - "name": "contents", - "rolls": 1, - "entries": [ { "type": "minecraft:dynamic", "name": "computercraft:contents" } ], - "conditions": [ { "condition": "minecraft:survives_explosion" } ] } ] } diff --git a/src/main/resources/data/computercraft/loot_tables/blocks/printer.json b/src/main/resources/data/computercraft/loot_tables/blocks/printer.json index 11fb6a8fc..fff10863c 100644 --- a/src/main/resources/data/computercraft/loot_tables/blocks/printer.json +++ b/src/main/resources/data/computercraft/loot_tables/blocks/printer.json @@ -6,12 +6,6 @@ "rolls": 1, "entries": [ { "type": "minecraft:item", "name": "computercraft:printer" } ], "conditions": [ { "condition": "minecraft:survives_explosion" } ] - }, - { - "name": "contents", - "rolls": 1, - "entries": [ { "type": "minecraft:dynamic", "name": "computercraft:contents" } ], - "conditions": [ { "condition": "minecraft:survives_explosion" } ] } ] } diff --git a/src/main/resources/data/computercraft/loot_tables/blocks/turtle_advanced.json b/src/main/resources/data/computercraft/loot_tables/blocks/turtle_advanced.json index ed51e388f..26cde0f50 100644 --- a/src/main/resources/data/computercraft/loot_tables/blocks/turtle_advanced.json +++ b/src/main/resources/data/computercraft/loot_tables/blocks/turtle_advanced.json @@ -4,15 +4,16 @@ { "name": "main", "rolls": 1, - "entries": [ - { "type": "minecraft:dynamic", "name": "computercraft:computer" } + "entries": [ { "type": "minecraft:dynamic", "name": "computercraft:computer" } ], + "conditions": [ + { + "condition": "alternative", + "terms": [ + { "condition": "computercraft:block_named" }, + { "condition": "minecraft:inverted", "term": { "condition": "computercraft:player_creative" } } + ] + } ] - }, - { - "name": "contents", - "rolls": 1, - "entries": [ { "type": "minecraft:dynamic", "name": "computercraft:contents" } ], - "conditions": [ { "condition": "minecraft:survives_explosion" } ] } ] } diff --git a/src/main/resources/data/computercraft/loot_tables/blocks/turtle_normal.json b/src/main/resources/data/computercraft/loot_tables/blocks/turtle_normal.json index e44c9cbc7..26cde0f50 100644 --- a/src/main/resources/data/computercraft/loot_tables/blocks/turtle_normal.json +++ b/src/main/resources/data/computercraft/loot_tables/blocks/turtle_normal.json @@ -4,13 +4,16 @@ { "name": "main", "rolls": 1, - "entries": [ { "type": "minecraft:dynamic", "name": "computercraft:computer" } ] - }, - { - "name": "contents", - "rolls": 1, - "entries": [ { "type": "minecraft:dynamic", "name": "computercraft:contents" } ], - "conditions": [ { "condition": "minecraft:survives_explosion" } ] + "entries": [ { "type": "minecraft:dynamic", "name": "computercraft:computer" } ], + "conditions": [ + { + "condition": "alternative", + "terms": [ + { "condition": "computercraft:block_named" }, + { "condition": "minecraft:inverted", "term": { "condition": "computercraft:player_creative" } } + ] + } + ] } ] }