1.14/1.15 Dev snapshot: Labled Crate GUI quickmove, recipe fixes, valve caching removed, missing cap invalidation added.

This commit is contained in:
stfwi 2020-03-30 14:18:45 +02:00
parent 05b9f7c31f
commit fd358d98dc
80 changed files with 1544 additions and 905 deletions

View file

@ -30,7 +30,7 @@ default: mod
all: clean clean-all mod | install
mod: data
mod:
@echo "[1.14] Building mod using gradle ..."
@$(GRADLE) build $(GRADLE_OPTS)
@ -78,7 +78,7 @@ dist-check:
@echo "[1.14] Running dist checks ..."
@djs tasks.js dist-check
dist-files: clean-all init mod
dist-files: clean-all init data mod
@echo "[1.14] Distribution files ..."
@mkdir -p dist
@cp build/libs/$(MOD_JAR_PREFIX)* dist/

View file

@ -1,5 +1,6 @@
// @file build.gradle
// Engineer's decor mod gradle build relay (mc1.14.4)
import net.minecraftforge.gradle.common.task.SignJar
buildscript {
repositories {
maven { url = 'https://files.minecraftforge.net/maven' }
@ -14,7 +15,7 @@ apply plugin: 'net.minecraftforge.gradle'
apply plugin: 'eclipse'
apply plugin: 'maven-publish'
sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8'
//-----------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------------------------
version = "${version_engineersdecor}"
group = "wile.engineersdecor"
archivesBaseName = "engineersdecor-${version_minecraft}"
@ -90,6 +91,29 @@ jar {
def reobfFile = file("$buildDir/reobfJar/output.jar")
def reobfArtifact = artifacts.add('default', reobfFile) { type 'jar'; builtBy 'reobfJar'; }
def signing = { ->
def sp = new Properties()
sp.keystore_file = project.keystore_file
sp.keystore_alias = project.keystore_alias
sp.keystore_pass = project.keystore_pass
sp.keystore_keypass = project.keystore_keypass
sp.fingerprint_sha1 = project.fingerprint_sha1
if(file("signing.properties").exists()) file("signing.properties").withInputStream { sp.load(it) }
return sp
}();
task signJar(type: SignJar, dependsOn: jar) {
onlyIf { signing.hasProperty("keystore_file") }
if(signing.hasProperty("keystore_file")) {
keyStore = signing.getProperty("keystore_file")
alias = signing.getProperty("keystore_alias")
storePass = signing.getProperty("keystore_pass")
keyPass = signing.getProperty("keystore_keypass")
inputFile = jar.archivePath
outputFile = jar.archivePath
}
}
build.dependsOn signJar
publishing {
publications { mavenJava(MavenPublication) { artifact reobfArtifact } }
repositories { maven { url "file:///${project.projectDir}/mcmodsrepo" } }

View file

@ -11,7 +11,11 @@ Mod sources for Minecraft version 1.14.4.
## Version history
~ v1.0.20-b3 [M]
~ v1.0.20-b3 [M] Labeled Crate: GUI quick-move-all (ctrl-shift click) smart move tweaked, Manual page added.
[F] Fixed IE ingredients based default recipes for Factory Dropper and Small Electrical Furnace.
[M] Factory Hopper: GUI quick-move-all added.
[M] Code structure, simplifications, cap invalidation fixes.
[M] Valves: Removed performance caching for testing purposes.
- v1.0.20-b2 [U] Forge version requirement set to >= 28.2.3.
[A] Added Labeled Crate (storage crate with built-in item frame).

View file

@ -440,7 +440,7 @@ public class ModContent
}
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "small_block_breaker"));
public static final BlockDecorHopper FACTORY_HOPPER = (BlockDecorHopper)(new BlockDecorHopper(
public static final BlockDecorHopper.DecorHopperBlock FACTORY_HOPPER = (BlockDecorHopper.DecorHopperBlock)(new BlockDecorHopper.DecorHopperBlock(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL), ()->{
final AxisAlignedBB[] down_aabbs = new AxisAlignedBB[]{
@ -532,8 +532,8 @@ public class ModContent
}
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "small_tree_cutter"));
public static final BlockDecorPipeValve STRAIGHT_CHECK_VALVE = (BlockDecorPipeValve)(new BlockDecorPipeValve(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT|BlockDecor.CFG_FLIP_PLACEMENT_SHIFTCLICK,
public static final BlockDecorPipeValve.DecorPipeValveBlock STRAIGHT_CHECK_VALVE = (BlockDecorPipeValve.DecorPipeValveBlock)(new BlockDecorPipeValve.DecorPipeValveBlock(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT,
BlockDecorPipeValve.CFG_CHECK_VALVE,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL),
new AxisAlignedBB[]{
@ -544,8 +544,8 @@ public class ModContent
}
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "straight_pipe_valve"));
public static final BlockDecorPipeValve STRAIGHT_REDSTONE_VALVE = (BlockDecorPipeValve)(new BlockDecorPipeValve(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT|BlockDecor.CFG_FLIP_PLACEMENT_SHIFTCLICK,
public static final BlockDecorPipeValve.DecorPipeValveBlock STRAIGHT_REDSTONE_VALVE = (BlockDecorPipeValve.DecorPipeValveBlock)(new BlockDecorPipeValve.DecorPipeValveBlock(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT,
BlockDecorPipeValve.CFG_REDSTONE_CONTROLLED_VALVE,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL),
new AxisAlignedBB[]{
@ -556,8 +556,8 @@ public class ModContent
}
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "straight_pipe_valve_redstone"));
public static final BlockDecorPipeValve STRAIGHT_REDSTONE_ANALOG_VALVE = (BlockDecorPipeValve)(new BlockDecorPipeValve(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT|BlockDecor.CFG_FLIP_PLACEMENT_SHIFTCLICK,
public static final BlockDecorPipeValve.DecorPipeValveBlock STRAIGHT_REDSTONE_ANALOG_VALVE = (BlockDecorPipeValve.DecorPipeValveBlock)(new BlockDecorPipeValve.DecorPipeValveBlock(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT,
BlockDecorPipeValve.CFG_REDSTONE_CONTROLLED_VALVE|BlockDecorPipeValve.CFG_ANALOG_VALVE,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL),
new AxisAlignedBB[]{
@ -788,7 +788,7 @@ public class ModContent
.setRegistryName(ModEngineersDecor.MODID, "te_small_block_breaker");
public static final TileEntityType<?> TET_FACTORY_HOPPER = TileEntityType.Builder
.create(BlockDecorHopper.BTileEntity::new, FACTORY_HOPPER)
.create(BlockDecorHopper.DecorHopperTileEntity::new, FACTORY_HOPPER)
.build(null)
.setRegistryName(ModEngineersDecor.MODID, "te_factory_hopper");
@ -798,7 +798,7 @@ public class ModContent
.setRegistryName(ModEngineersDecor.MODID, "te_small_waste_incinerator");
public static final TileEntityType<?> TET_STRAIGHT_PIPE_VALVE = TileEntityType.Builder
.create(BlockDecorPipeValve.BTileEntity::new, STRAIGHT_CHECK_VALVE, STRAIGHT_REDSTONE_VALVE, STRAIGHT_REDSTONE_ANALOG_VALVE)
.create(BlockDecorPipeValve.DecorPipeValveTileEntity::new, STRAIGHT_CHECK_VALVE, STRAIGHT_REDSTONE_VALVE, STRAIGHT_REDSTONE_ANALOG_VALVE)
.build(null)
.setRegistryName(ModEngineersDecor.MODID, "te_pipe_valve");
@ -833,7 +833,7 @@ public class ModContent
.setRegistryName(ModEngineersDecor.MODID, "te_small_tree_cutter");
public static final TileEntityType<?> TET_TEST_BLOCK = TileEntityType.Builder
.create(BlockDecorPipeValve.BTileEntity::new, TEST_BLOCK)
.create(BlockDecorPipeValve.DecorPipeValveTileEntity::new, TEST_BLOCK)
.build(null)
.setRegistryName(ModEngineersDecor.MODID, "te_test_block");
@ -881,7 +881,7 @@ public class ModContent
public static final ContainerType<BlockDecorCraftingTable.CraftingTableContainer> CT_TREATED_WOOD_CRAFTING_TABLE;
public static final ContainerType<BlockDecorDropper.BContainer> CT_FACTORY_DROPPER;
public static final ContainerType<BlockDecorPlacer.BContainer> CT_FACTORY_PLACER;
public static final ContainerType<BlockDecorHopper.BContainer> CT_FACTORY_HOPPER;
public static final ContainerType<BlockDecorHopper.DecorHopperContainer> CT_FACTORY_HOPPER;
public static final ContainerType<BlockDecorFurnace.BContainer> CT_SMALL_LAB_FURNACE;
public static final ContainerType<BlockDecorFurnaceElectrical.BContainer> CT_SMALL_ELECTRICAL_FURNACE;
public static final ContainerType<BlockDecorWasteIncinerator.BContainer> CT_WASTE_INCINERATOR;
@ -894,7 +894,7 @@ public class ModContent
CT_FACTORY_DROPPER.setRegistryName(ModEngineersDecor.MODID,"ct_factory_dropper");
CT_FACTORY_PLACER = (new ContainerType<BlockDecorPlacer.BContainer>(BlockDecorPlacer.BContainer::new));
CT_FACTORY_PLACER.setRegistryName(ModEngineersDecor.MODID,"ct_factory_placer");
CT_FACTORY_HOPPER = (new ContainerType<BlockDecorHopper.BContainer>(BlockDecorHopper.BContainer::new));
CT_FACTORY_HOPPER = (new ContainerType<BlockDecorHopper.DecorHopperContainer>(BlockDecorHopper.DecorHopperContainer::new));
CT_FACTORY_HOPPER.setRegistryName(ModEngineersDecor.MODID,"ct_factory_hopper");
CT_SMALL_LAB_FURNACE = (new ContainerType<BlockDecorFurnace.BContainer>(BlockDecorFurnace.BContainer::new));
CT_SMALL_LAB_FURNACE.setRegistryName(ModEngineersDecor.MODID,"ct_small_lab_furnace");
@ -996,7 +996,7 @@ public class ModContent
ScreenManager.registerFactory(CT_LABELED_CRATE, BlockDecorLabeledCrate.LabeledCrateGui::new);
ScreenManager.registerFactory(CT_FACTORY_DROPPER, BlockDecorDropper.BGui::new);
ScreenManager.registerFactory(CT_FACTORY_PLACER, BlockDecorPlacer.BGui::new);
ScreenManager.registerFactory(CT_FACTORY_HOPPER, BlockDecorHopper.BGui::new);
ScreenManager.registerFactory(CT_FACTORY_HOPPER, BlockDecorHopper.DecorHopperGui::new);
ScreenManager.registerFactory(CT_SMALL_LAB_FURNACE, BlockDecorFurnace.BGui::new);
ScreenManager.registerFactory(CT_SMALL_ELECTRICAL_FURNACE, BlockDecorFurnaceElectrical.BGui::new);
ScreenManager.registerFactory(CT_WASTE_INCINERATOR, BlockDecorWasteIncinerator.BGui::new);

View file

@ -191,6 +191,13 @@ public class BlockDecorBreaker extends StandardBlocks.HorizontalWaterLoggable im
public CompoundNBT write(CompoundNBT nbt)
{ super.write(nbt); writenbt(nbt); return nbt; }
@Override
public void remove()
{
super.remove();
energy_handler_.invalidate();
}
// IEnergyStorage ----------------------------------------------------------------------------
protected LazyOptional<IEnergyStorage> energy_handler_ = LazyOptional.of(() -> (IEnergyStorage)this);
@ -228,11 +235,7 @@ public class BlockDecorBreaker extends StandardBlocks.HorizontalWaterLoggable im
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing)
{
if(!this.removed && (facing != null)) {
if(capability== CapabilityEnergy.ENERGY) {
return energy_handler_.cast();
}
}
if(capability == CapabilityEnergy.ENERGY) return energy_handler_.cast();
return super.getCapability(capability, facing);
}

View file

@ -1567,7 +1567,6 @@ public class BlockDecorCraftingTable
{ super(inv, index, x, y); }
}
// Crafting inventory (needed to allow SlotCrafting to have a InventoryCrafting) -----------------------------------
private static class CraftingTableGrid extends CraftingInventory
{

View file

@ -54,6 +54,7 @@ import net.minecraftforge.items.IItemHandler;
import com.mojang.blaze3d.platform.GlStateManager;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@ -308,6 +309,13 @@ public class BlockDecorDropper extends StandardBlocks.Directed implements IDecor
public CompoundNBT write(CompoundNBT nbt)
{ super.write(nbt); writenbt(nbt, false); return nbt; }
@Override
public void remove()
{
super.remove();
Arrays.stream(item_handlers).forEach(LazyOptional::invalidate);
}
// INamable ----------------------------------------------------------------------------------------------
@Override
@ -465,9 +473,7 @@ public class BlockDecorDropper extends StandardBlocks.Directed implements IDecor
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing)
{
if(!this.removed && (facing != null)) {
if(capability==CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return item_handlers[0].cast();
}
if(capability==CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return item_handlers[0].cast();
return super.getCapability(capability, facing);
}

View file

@ -186,6 +186,13 @@ public class BlockDecorFluidFunnel extends StandardBlocks.BaseBlock implements I
public CompoundNBT write(CompoundNBT nbt)
{ super.write(nbt); writenbt(nbt); return nbt; }
@Override
public void remove()
{
super.remove();
fluid_handler_.invalidate();
}
// ICapabilityProvider / Output flow handler ----------------------------------------------------------
private static class OutputFluidHandler implements IFluidHandler

View file

@ -314,6 +314,14 @@ public class BlockDecorFurnace extends StandardBlocks.Horizontal implements IDec
public CompoundNBT write(CompoundNBT nbt)
{ super.write(nbt); writenbt(nbt); return nbt; }
@Override
public void remove()
{
super.remove();
Arrays.stream(item_handlers).forEach(LazyOptional::invalidate);
energy_handler_.invalidate();
}
// INamedContainerProvider / INameable ------------------------------------------------------
@Override
@ -512,7 +520,7 @@ public class BlockDecorFurnace extends StandardBlocks.Horizontal implements IDec
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing)
{
if(!this.removed && (facing != null)) {
if(facing != null) {
if(capability==CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
if(facing == Direction.UP) return item_handlers[0].cast();
if(facing == Direction.DOWN) return item_handlers[1].cast();

View file

@ -55,6 +55,7 @@ import com.mojang.blaze3d.platform.GlStateManager;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Arrays;
import java.util.Random;
@ -220,6 +221,15 @@ public class BlockDecorFurnaceElectrical extends BlockDecorFurnace implements ID
public CompoundNBT write(CompoundNBT nbt)
{ super.write(nbt); writenbt(nbt); return nbt; }
@Override
public void remove()
{
super.remove();
Arrays.stream(item_handlers).forEach(LazyOptional::invalidate);
item_handler_.invalidate();
energy_handler_.invalidate();
}
// INameable -------------------------------------------------------------------------------
@Override
@ -443,10 +453,8 @@ public class BlockDecorFurnaceElectrical extends BlockDecorFurnace implements ID
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing)
{
if(!this.removed && (facing != null)) {
if(capability==CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return item_handler_.cast();
if(capability== CapabilityEnergy.ENERGY) return energy_handler_.cast();
}
if(capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return item_handler_.cast();
if(capability == CapabilityEnergy.ENERGY) return energy_handler_.cast();
return super.getCapability(capability, facing);
}

View file

@ -11,7 +11,9 @@ package wile.engineersdecor.blocks;
import wile.engineersdecor.ModContent;
import wile.engineersdecor.ModEngineersDecor;
import wile.engineersdecor.libmc.blocks.StandardBlocks;
import wile.engineersdecor.libmc.detail.Auxiliaries;
import wile.engineersdecor.libmc.detail.Inventories;
import wile.engineersdecor.libmc.detail.Inventories.SlotRange;
import wile.engineersdecor.libmc.detail.Networking;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.World;
@ -33,6 +35,7 @@ import net.minecraft.inventory.*;
import net.minecraft.inventory.container.INamedContainerProvider;
import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.container.Slot;
import net.minecraft.inventory.container.ClickType;
import net.minecraft.util.*;
import net.minecraft.util.math.*;
import net.minecraft.util.math.shapes.VoxelShape;
@ -52,133 +55,147 @@ import net.minecraftforge.items.IItemHandler;
import com.mojang.blaze3d.platform.GlStateManager;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Supplier;
public class BlockDecorHopper extends StandardBlocks.Directed implements IDecorBlock
public class BlockDecorHopper
{
public BlockDecorHopper(long config, Block.Properties builder, final Supplier<ArrayList<VoxelShape>> shape_supplier)
{ super(config, builder, shape_supplier); }
@Override
@SuppressWarnings("deprecation")
public boolean hasComparatorInputOverride(BlockState state)
{ return true; }
@Override
public VoxelShape getCollisionShape(BlockState state, IBlockReader world, BlockPos pos, ISelectionContext context)
{ return VoxelShapes.fullCube(); }
@Override
@SuppressWarnings("deprecation")
public int getComparatorInputOverride(BlockState blockState, World world, BlockPos pos)
{ return Container.calcRedstone(world.getTileEntity(pos)); }
@Override
public boolean hasTileEntity(BlockState state)
{ return true; }
@Override
@Nullable
public TileEntity createTileEntity(BlockState state, IBlockReader world)
{ return new BlockDecorHopper.BTileEntity(); }
@Override
public void onBlockPlacedBy(World world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack)
public static void on_config(int cooldown_ticks)
{
if(world.isRemote) return;
if((!stack.hasTag()) || (!stack.getTag().contains("tedata"))) return;
CompoundNBT te_nbt = stack.getTag().getCompound("tedata");
if(te_nbt.isEmpty()) return;
final TileEntity te = world.getTileEntity(pos);
if(!(te instanceof BTileEntity)) return;
((BTileEntity)te).readnbt(te_nbt, false);
((BTileEntity)te).reset_rtstate();
((BTileEntity)te).markDirty();
// ModEngineersDecor.logger.info("Config factory hopper:");
}
@Override
public boolean hasDynamicDropList()
{ return true; }
//--------------------------------------------------------------------------------------------------------------------
// Block
//--------------------------------------------------------------------------------------------------------------------
@Override
public List<ItemStack> dropList(BlockState state, World world, BlockPos pos, boolean explosion)
public static class DecorHopperBlock extends StandardBlocks.Directed implements IDecorBlock
{
final List<ItemStack> stacks = new ArrayList<ItemStack>();
if(world.isRemote) return stacks;
final TileEntity te = world.getTileEntity(pos);
if(!(te instanceof BTileEntity)) return stacks;
if(!explosion) {
ItemStack stack = new ItemStack(this, 1);
CompoundNBT te_nbt = ((BTileEntity)te).clear_getnbt();
if(!te_nbt.isEmpty()) {
CompoundNBT nbt = new CompoundNBT();
nbt.put("tedata", te_nbt);
stack.setTag(nbt);
}
stacks.add(stack);
} else {
for(ItemStack stack: ((BTileEntity)te).stacks_) {
if(!stack.isEmpty()) stacks.add(stack);
}
((BTileEntity)te).reset_rtstate();
public DecorHopperBlock(long config, Block.Properties builder, final Supplier<ArrayList<VoxelShape>> shape_supplier)
{ super(config, builder, shape_supplier); }
@Override
@SuppressWarnings("deprecation")
public boolean hasComparatorInputOverride(BlockState state)
{ return true; }
@Override
public VoxelShape getCollisionShape(BlockState state, IBlockReader world, BlockPos pos, ISelectionContext context)
{ return VoxelShapes.fullCube(); }
@Override
@SuppressWarnings("deprecation")
public int getComparatorInputOverride(BlockState blockState, World world, BlockPos pos)
{ return Container.calcRedstone(world.getTileEntity(pos)); }
@Override
public boolean hasTileEntity(BlockState state)
{ return true; }
@Override
@Nullable
public TileEntity createTileEntity(BlockState state, IBlockReader world)
{ return new DecorHopperTileEntity(); }
@Override
public void onBlockPlacedBy(World world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack)
{
if(world.isRemote) return;
if((!stack.hasTag()) || (!stack.getTag().contains("tedata"))) return;
CompoundNBT te_nbt = stack.getTag().getCompound("tedata");
if(te_nbt.isEmpty()) return;
final TileEntity te = world.getTileEntity(pos);
if(!(te instanceof DecorHopperTileEntity)) return;
((DecorHopperTileEntity)te).readnbt(te_nbt, false);
((DecorHopperTileEntity)te).reset_rtstate();
((DecorHopperTileEntity)te).markDirty();
}
return stacks;
@Override
public boolean hasDynamicDropList()
{ return true; }
@Override
public List<ItemStack> dropList(BlockState state, World world, BlockPos pos, boolean explosion)
{
final List<ItemStack> stacks = new ArrayList<ItemStack>();
if(world.isRemote) return stacks;
final TileEntity te = world.getTileEntity(pos);
if(!(te instanceof DecorHopperTileEntity)) return stacks;
if(!explosion) {
ItemStack stack = new ItemStack(this, 1);
CompoundNBT te_nbt = ((DecorHopperTileEntity)te).clear_getnbt();
if(!te_nbt.isEmpty()) {
CompoundNBT nbt = new CompoundNBT();
nbt.put("tedata", te_nbt);
stack.setTag(nbt);
}
stacks.add(stack);
} else {
for(ItemStack stack: ((DecorHopperTileEntity)te).stacks_) {
if(!stack.isEmpty()) stacks.add(stack);
}
((DecorHopperTileEntity)te).reset_rtstate();
}
return stacks;
}
@Override
@SuppressWarnings("deprecation")
public boolean onBlockActivated(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockRayTraceResult rayTraceResult)
{
if(world.isRemote) return true;
final TileEntity te = world.getTileEntity(pos);
if(!(te instanceof DecorHopperTileEntity)) return true;
if((!(player instanceof ServerPlayerEntity) && (!(player instanceof FakePlayer)))) return true;
NetworkHooks.openGui((ServerPlayerEntity)player,(INamedContainerProvider)te);
return true;
}
@Override
@SuppressWarnings("deprecation")
public void neighborChanged(BlockState state, World world, BlockPos pos, Block block, BlockPos fromPos, boolean unused)
{
if(!(world instanceof World) || (((World) world).isRemote)) return;
TileEntity te = world.getTileEntity(pos);
if(!(te instanceof DecorHopperTileEntity)) return;
((DecorHopperTileEntity)te).block_updated();
}
@Override
public void onFallenUpon(World world, BlockPos pos, Entity entity, float fallDistance)
{
super.onFallenUpon(world, pos, entity, fallDistance);
if(!(entity instanceof ItemEntity)) return;
TileEntity te = world.getTileEntity(pos);
if(!(te instanceof DecorHopperTileEntity)) return;
((DecorHopperTileEntity)te).collection_timer_ = 0;
}
@Override
@SuppressWarnings("deprecation")
public boolean canProvidePower(BlockState state)
{ return true; }
@Override
@SuppressWarnings("deprecation")
public int getWeakPower(BlockState blockState, IBlockReader blockAccess, BlockPos pos, Direction side)
{ return 0; }
@Override
@SuppressWarnings("deprecation")
public int getStrongPower(BlockState blockState, IBlockReader blockAccess, BlockPos pos, Direction side)
{ return 0; }
}
@Override
@SuppressWarnings("deprecation")
public boolean onBlockActivated(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockRayTraceResult rayTraceResult)
{
if(world.isRemote) return true;
final TileEntity te = world.getTileEntity(pos);
if(!(te instanceof BTileEntity)) return true;
if((!(player instanceof ServerPlayerEntity) && (!(player instanceof FakePlayer)))) return true;
NetworkHooks.openGui((ServerPlayerEntity)player,(INamedContainerProvider)te);
return true;
}
@Override
@SuppressWarnings("deprecation")
public void neighborChanged(BlockState state, World world, BlockPos pos, Block block, BlockPos fromPos, boolean unused)
{
if(!(world instanceof World) || (((World) world).isRemote)) return;
TileEntity te = world.getTileEntity(pos);
if(!(te instanceof BTileEntity)) return;
((BTileEntity)te).block_updated();
}
@Override
public void onFallenUpon(World world, BlockPos pos, Entity entity, float fallDistance)
{
super.onFallenUpon(world, pos, entity, fallDistance);
if(!(entity instanceof ItemEntity)) return;
TileEntity te = world.getTileEntity(pos);
if(!(te instanceof BTileEntity)) return;
((BTileEntity)te).collection_timer_ = 0;
}
@Override
@SuppressWarnings("deprecation")
public boolean canProvidePower(BlockState state)
{ return true; }
@Override
@SuppressWarnings("deprecation")
public int getWeakPower(BlockState blockState, IBlockReader blockAccess, BlockPos pos, Direction side)
{ return 0; }
@Override
@SuppressWarnings("deprecation")
public int getStrongPower(BlockState blockState, IBlockReader blockAccess, BlockPos pos, Direction side)
{ return 0; }
//--------------------------------------------------------------------------------------------------------------------
// Tile entity
//--------------------------------------------------------------------------------------------------------------------
public static class BTileEntity extends TileEntity implements ITickableTileEntity, INameable, IInventory, INamedContainerProvider, ISidedInventory
public static class DecorHopperTileEntity extends TileEntity implements ITickableTileEntity, INameable, IInventory, INamedContainerProvider, ISidedInventory
{
public static final int NUM_OF_FIELDS = 7;
public static final int TICK_INTERVAL = 10;
@ -203,19 +220,14 @@ public class BlockDecorHopper extends StandardBlocks.Directed implements IDecorB
private int tick_timer_ = 0;
protected NonNullList<ItemStack> stacks_;
public static void on_config(int cooldown_ticks)
{
// ModEngineersDecor.logger.info("Config factory hopper:");
}
public BTileEntity()
public DecorHopperTileEntity()
{
this(ModContent.TET_FACTORY_HOPPER);
stacks_ = NonNullList.<ItemStack>withSize(NUM_OF_SLOTS, ItemStack.EMPTY);
reset_rtstate();
}
public BTileEntity(TileEntityType<?> te_type)
public DecorHopperTileEntity(TileEntityType<?> te_type)
{
super(te_type);
stacks_ = NonNullList.<ItemStack>withSize(NUM_OF_SLOTS, ItemStack.EMPTY);
@ -287,6 +299,13 @@ public class BlockDecorHopper extends StandardBlocks.Directed implements IDecorB
public CompoundNBT write(CompoundNBT nbt)
{ super.write(nbt); writenbt(nbt, false); return nbt; }
@Override
public void remove()
{
super.remove();
Arrays.stream(item_handlers).forEach(LazyOptional::invalidate);
}
// INamable ----------------------------------------------------------------------------------------------
@Override
@ -309,7 +328,7 @@ public class BlockDecorHopper extends StandardBlocks.Directed implements IDecorB
@Override
public Container createMenu(int id, PlayerInventory inventory, PlayerEntity player )
{ return new BContainer(id, inventory, this, IWorldPosCallable.of(world, pos), fields); }
{ return new DecorHopperContainer(id, inventory, this, IWorldPosCallable.of(world, pos), fields); }
// IInventory --------------------------------------------------------------------------------------------
@ -372,7 +391,7 @@ public class BlockDecorHopper extends StandardBlocks.Directed implements IDecorB
// Fields -----------------------------------------------------------------------------------------------
protected final IIntArray fields = new IntArray(BTileEntity.NUM_OF_FIELDS)
protected final IIntArray fields = new IntArray(DecorHopperTileEntity.NUM_OF_FIELDS)
{
@Override
public int get(int id)
@ -430,9 +449,7 @@ public class BlockDecorHopper extends StandardBlocks.Directed implements IDecorB
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing)
{
if(!this.removed && (facing != null)) {
if(capability==CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return item_handlers[0].cast();
}
if(capability==CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return item_handlers[0].cast();
return super.getCapability(capability, facing);
}
@ -491,8 +508,8 @@ public class BlockDecorHopper extends StandardBlocks.Directed implements IDecorB
if(te instanceof HopperTileEntity) {
Direction f = world.getBlockState(pos.offset(facing)).get(HopperBlock.FACING);
if(f==facing.getOpposite()) return false; // no back transfer
} else if(te instanceof BTileEntity) {
Direction f = world.getBlockState(pos.offset(facing)).get(FACING);
} else if(te instanceof DecorHopperTileEntity) {
Direction f = world.getBlockState(pos.offset(facing)).get(DecorHopperBlock.FACING);
if(f==facing.getOpposite()) return false;
}
ItemStack insert_stack = current_stack.copy();
@ -610,7 +627,7 @@ public class BlockDecorHopper extends StandardBlocks.Directed implements IDecorB
boolean trigger = (rssignal && ((block_power_updated_) || (!pulse_mode)));
final BlockState state = world.getBlockState(pos);
if(state == null) { block_power_signal_= false; return; }
final Direction hopper_facing = state.get(FACING);
final Direction hopper_facing = state.get(DecorHopperBlock.FACING);
// Trigger edge detection for next cycle
{
boolean tr = world.isBlockPowered(pos);
@ -650,9 +667,16 @@ public class BlockDecorHopper extends StandardBlocks.Directed implements IDecorB
// container
//--------------------------------------------------------------------------------------------------------------------
public static class BContainer extends Container implements Networking.INetworkSynchronisableContainer
public static class DecorHopperContainer extends Container implements Networking.INetworkSynchronisableContainer
{
private static final int PLAYER_INV_START_SLOTNO = BTileEntity.NUM_OF_SLOTS;
private static final int PLAYER_INV_START_SLOTNO = DecorHopperTileEntity.NUM_OF_SLOTS;
private static final int NUM_OF_CONTAINER_SLOTS = DecorHopperTileEntity.NUM_OF_SLOTS + 36;
protected static final int STORAGE_SLOT_BEGIN = 0;
protected static final int STORAGE_SLOT_END = DecorHopperTileEntity.NUM_OF_SLOTS;
protected static final int PLAYER_SLOT_BEGIN = DecorHopperTileEntity.NUM_OF_SLOTS;
protected static final int PLAYER_SLOT_END = DecorHopperTileEntity.NUM_OF_SLOTS+36;
private final SlotRange player_inventory_slot_range;
private final SlotRange hopper_slot_range;
private final PlayerEntity player_;
private final IInventory inventory_;
private final IWorldPosCallable wpc_;
@ -660,16 +684,19 @@ public class BlockDecorHopper extends StandardBlocks.Directed implements IDecorB
public final int field(int index) { return fields_.get(index); }
public BContainer(int cid, PlayerInventory player_inventory)
{ this(cid, player_inventory, new Inventory(BTileEntity.NUM_OF_SLOTS), IWorldPosCallable.DUMMY, new IntArray(BTileEntity.NUM_OF_FIELDS)); }
public DecorHopperContainer(int cid, PlayerInventory player_inventory)
{ this(cid, player_inventory, new Inventory(DecorHopperTileEntity.NUM_OF_SLOTS), IWorldPosCallable.DUMMY, new IntArray(DecorHopperTileEntity.NUM_OF_FIELDS)); }
private BContainer(int cid, PlayerInventory player_inventory, IInventory block_inventory, IWorldPosCallable wpc, IIntArray fields)
private DecorHopperContainer(int cid, PlayerInventory player_inventory, IInventory block_inventory, IWorldPosCallable wpc, IIntArray fields)
{
super(ModContent.CT_FACTORY_HOPPER, cid);
fields_ = fields;
wpc_ = wpc;
player_ = player_inventory.player;
inventory_ = block_inventory;
hopper_slot_range = new SlotRange(inventory_, 0, DecorHopperTileEntity.NUM_OF_SLOTS);
player_inventory_slot_range = new SlotRange(player_inventory, 0, 36);
int i=-1;
// input slots (stacks 0 to 17)
for(int y=0; y<3; ++y) {
@ -706,7 +733,7 @@ public class BlockDecorHopper extends StandardBlocks.Directed implements IDecorB
if(!mergeItemStack(slot_stack, PLAYER_INV_START_SLOTNO, PLAYER_INV_START_SLOTNO+36, false)) return ItemStack.EMPTY;
} else if((index >= PLAYER_INV_START_SLOTNO) && (index <= PLAYER_INV_START_SLOTNO+36)) {
// Player slot
if(!mergeItemStack(slot_stack, 0, BTileEntity.NUM_OF_SLOTS, false)) return ItemStack.EMPTY;
if(!mergeItemStack(slot_stack, 0, DecorHopperTileEntity.NUM_OF_SLOTS, false)) return ItemStack.EMPTY;
} else {
// invalid slot
return ItemStack.EMPTY;
@ -735,6 +762,13 @@ public class BlockDecorHopper extends StandardBlocks.Directed implements IDecorB
Networking.PacketContainerSyncClientToServer.sendToServer(windowId, nbt);
}
@OnlyIn(Dist.CLIENT)
public void onGuiAction(String message, CompoundNBT nbt)
{
nbt.putString("action", message);
Networking.PacketContainerSyncClientToServer.sendToServer(windowId, nbt);
}
@Override
public void onServerPacketReceived(int windowId, CompoundNBT nbt)
{}
@ -742,13 +776,56 @@ public class BlockDecorHopper extends StandardBlocks.Directed implements IDecorB
@Override
public void onClientPacketReceived(int windowId, PlayerEntity player, CompoundNBT nbt)
{
if(!(inventory_ instanceof BTileEntity)) return;
BTileEntity te = (BTileEntity)inventory_;
if(nbt.contains("xsize")) te.transfer_count_ = MathHelper.clamp(nbt.getInt("xsize"), 1, BTileEntity.MAX_TRANSFER_COUNT);
if(!(inventory_ instanceof DecorHopperTileEntity)) return;
DecorHopperTileEntity te = (DecorHopperTileEntity)inventory_;
if(nbt.contains("xsize")) te.transfer_count_ = MathHelper.clamp(nbt.getInt("xsize"), 1, DecorHopperTileEntity.MAX_TRANSFER_COUNT);
if(nbt.contains("period")) te.transfer_period_ = MathHelper.clamp(nbt.getInt("period"), 0, 100);
if(nbt.contains("range")) te.collection_range_ = MathHelper.clamp(nbt.getInt("range"), 0, BTileEntity.MAX_COLLECTION_RANGE);
if(nbt.contains("range")) te.collection_range_ = MathHelper.clamp(nbt.getInt("range"), 0, DecorHopperTileEntity.MAX_COLLECTION_RANGE);
if(nbt.contains("logic")) te.logic_ = nbt.getInt("logic");
if(nbt.contains("manual_trigger") && (nbt.getInt("manual_trigger")!=0)) { te.block_power_signal_=true; te.block_power_updated_=true; te.tick_timer_=1; }
if(nbt.contains("action")) {
boolean changed = false;
final int slotId = nbt.contains("slot") ? nbt.getInt("slot") : -1;
switch(nbt.getString("action")) {
case DecorHopperGui.QUICK_MOVE_ALL: {
if((slotId >= STORAGE_SLOT_BEGIN) && (slotId < STORAGE_SLOT_END) && (getSlot(slotId).getHasStack())) {
final Slot slot = getSlot(slotId);
ItemStack remaining = slot.getStack();
slot.putStack(ItemStack.EMPTY);
final ItemStack ref_stack = remaining.copy();
ref_stack.setCount(ref_stack.getMaxStackSize());
for(int i=hopper_slot_range.end_slot-hopper_slot_range.start_slot; (i>0) && (!remaining.isEmpty()); --i) {
remaining = player_inventory_slot_range.insert(remaining, false, 0, true, true);
if(!remaining.isEmpty()) break;
remaining = hopper_slot_range.extract(ref_stack);
}
if(!remaining.isEmpty()) {
slot.putStack(remaining); // put back
}
} else if((slotId >= PLAYER_SLOT_BEGIN) && (slotId < PLAYER_SLOT_END) && (getSlot(slotId).getHasStack())) {
final Slot slot = getSlot(slotId);
ItemStack remaining = slot.getStack();
slot.putStack(ItemStack.EMPTY);
final ItemStack ref_stack = remaining.copy();
ref_stack.setCount(ref_stack.getMaxStackSize());
for(int i=player_inventory_slot_range.end_slot-player_inventory_slot_range.start_slot; (i>0) && (!remaining.isEmpty()); --i) {
remaining = hopper_slot_range.insert(remaining, false, 0, false, true);
if(!remaining.isEmpty()) break;
remaining = player_inventory_slot_range.extract(ref_stack);
}
if(!remaining.isEmpty()) {
slot.putStack(remaining); // put back
}
}
changed = true;
} break;
}
if(changed) {
inventory_.markDirty();
player.inventory.markDirty();
detectAndSendChanges();
}
}
te.markDirty();
}
@ -759,11 +836,13 @@ public class BlockDecorHopper extends StandardBlocks.Directed implements IDecorB
//--------------------------------------------------------------------------------------------------------------------
@OnlyIn(Dist.CLIENT)
public static class BGui extends ContainerScreen<BContainer>
public static class DecorHopperGui extends ContainerScreen<DecorHopperContainer>
{
protected static final String QUICK_MOVE_ALL = "quick-move-all";
protected final PlayerEntity player_;
public BGui(BContainer container, PlayerInventory player_inventory, ITextComponent title)
public DecorHopperGui(DecorHopperContainer container, PlayerInventory player_inventory, ITextComponent title)
{ super(container, player_inventory, title); this.player_ = player_inventory.player; }
@Override
@ -778,10 +857,22 @@ public class BlockDecorHopper extends StandardBlocks.Directed implements IDecorB
renderHoveredToolTip(mouseX, mouseY);
}
@Override
protected void handleMouseClick(Slot slot, int slotId, int button, ClickType type)
{
if((type == ClickType.QUICK_MOVE) && (slot!=null) && slot.getHasStack() && Auxiliaries.isShiftDown() && Auxiliaries.isCtrlDown()) {
CompoundNBT nbt = new CompoundNBT();
nbt.putInt("slot", slotId);
container.onGuiAction(QUICK_MOVE_ALL, nbt);
} else {
super.handleMouseClick(slot, slotId, button, type);
}
}
@Override
public boolean mouseClicked(double mouseX, double mouseY, int mouseButton)
{
BContainer container = (BContainer)getContainer();
DecorHopperContainer container = (DecorHopperContainer)getContainer();
int mx = (int)(mouseX - getGuiLeft() + .5), my = (int)(mouseY - getGuiTop() + .5);
if((!isPointInRegion(126, 1, 49, 60, mouseX, mouseY))) {
return super.mouseClicked(mouseX, mouseY, mouseButton);
@ -792,8 +883,8 @@ public class BlockDecorHopper extends StandardBlocks.Directed implements IDecorB
} else if(range >= 34) {
range = container.field(0) + 1; // +
} else {
range = (int)(0.5 + ((((double)BTileEntity.MAX_COLLECTION_RANGE) * range)/34)); // slider
range = MathHelper.clamp(range, 0, BTileEntity.MAX_COLLECTION_RANGE);
range = (int)(0.5 + ((((double)DecorHopperTileEntity.MAX_COLLECTION_RANGE) * range)/34)); // slider
range = MathHelper.clamp(range, 0, DecorHopperTileEntity.MAX_COLLECTION_RANGE);
}
container.onGuiAction("range", range);
} else if(isPointInRegion(128, 21, 44, 10, mouseX, mouseY)) {
@ -814,15 +905,15 @@ public class BlockDecorHopper extends StandardBlocks.Directed implements IDecorB
} else if(ndrop >= 34) {
ndrop = container.field(1) + 1; // +
} else {
ndrop = MathHelper.clamp(1+ndrop, 1, BTileEntity.MAX_TRANSFER_COUNT); // slider
ndrop = MathHelper.clamp(1+ndrop, 1, DecorHopperTileEntity.MAX_TRANSFER_COUNT); // slider
}
container.onGuiAction("xsize", ndrop);
} else if(isPointInRegion(133, 49, 9, 9, mouseX, mouseY)) {
container.onGuiAction("manual_trigger", 1);
} else if(isPointInRegion(145, 49, 9, 9, mouseX, mouseY)) {
container.onGuiAction("logic", container.field(2) ^ BTileEntity.LOGIC_INVERTED);
container.onGuiAction("logic", container.field(2) ^ DecorHopperTileEntity.LOGIC_INVERTED);
} else if(isPointInRegion(159, 49, 7, 9, mouseX, mouseY)) {
container.onGuiAction("logic", container.field(2) ^ BTileEntity.LOGIC_CONTINUOUS);
container.onGuiAction("logic", container.field(2) ^ DecorHopperTileEntity.LOGIC_CONTINUOUS);
}
return true;
}
@ -834,11 +925,11 @@ public class BlockDecorHopper extends StandardBlocks.Directed implements IDecorB
this.minecraft.getTextureManager().bindTexture(new ResourceLocation(ModEngineersDecor.MODID, "textures/gui/factory_hopper_gui.png"));
final int x0=getGuiLeft(), y0=getGuiTop(), w=getXSize(), h=getYSize();
blit(x0, y0, 0, 0, w, h);
BContainer container = (BContainer)getContainer();
DecorHopperContainer container = (DecorHopperContainer)getContainer();
// active slot
{
int slot_index = container.field(6);
if((slot_index < 0) || (slot_index >= BTileEntity.NUM_OF_SLOTS)) slot_index = 0;
if((slot_index < 0) || (slot_index >= DecorHopperTileEntity.NUM_OF_SLOTS)) slot_index = 0;
int x = (x0+10+((slot_index % 6) * 18));
int y = (y0+8+((slot_index / 6) * 17));
blit(x, y, 200, 8, 18, 18);
@ -846,7 +937,7 @@ public class BlockDecorHopper extends StandardBlocks.Directed implements IDecorB
// collection range
{
int lut[] = { 133, 141, 149, 157, 166 };
int px = lut[MathHelper.clamp(container.field(0), 0, BTileEntity.MAX_COLLECTION_RANGE)];
int px = lut[MathHelper.clamp(container.field(0), 0, DecorHopperTileEntity.MAX_COLLECTION_RANGE)];
int x = x0 + px - 2;
int y = y0 + 14;
blit(x, y, 179, 40, 5, 5);
@ -872,14 +963,14 @@ public class BlockDecorHopper extends StandardBlocks.Directed implements IDecorB
}
// trigger logic
{
int inverter_offset = ((container.field(2) & BTileEntity.LOGIC_INVERTED) != 0) ? 11 : 0;
int inverter_offset = ((container.field(2) & DecorHopperTileEntity.LOGIC_INVERTED) != 0) ? 11 : 0;
blit(x0+145, y0+49, 177+inverter_offset, 49, 9, 9);
int pulse_mode_offset = ((container.field(2) & BTileEntity.LOGIC_CONTINUOUS ) != 0) ? 9 : 0;
int pulse_mode_offset = ((container.field(2) & DecorHopperTileEntity.LOGIC_CONTINUOUS ) != 0) ? 9 : 0;
blit(x0+159, y0+49, 199+pulse_mode_offset, 49, 9, 9);
}
// delay timer running indicator
{
if((container.field(4) > BTileEntity.PERIOD_OFFSET) && ((System.currentTimeMillis() % 1000) < 500)) {
if((container.field(4) > DecorHopperTileEntity.PERIOD_OFFSET) && ((System.currentTimeMillis() % 1000) < 500)) {
blit(x0+148, y0+22, 187, 22, 3, 3);
}
}

View file

@ -39,9 +39,11 @@ import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TranslationTextComponent;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.play.server.SUpdateTileEntityPacket;
import net.minecraft.client.gui.screen.inventory.ContainerScreen;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.common.util.FakePlayer;
@ -55,16 +57,23 @@ import com.mojang.blaze3d.platform.GlStateManager;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
public class BlockDecorLabeledCrate
{
private static boolean with_gui_mouse_handling = true;
private static final HashSet<Item> unstorable_containers = new HashSet<Item>();
public static void on_config(boolean without_gui_mouse_handling)
{
with_gui_mouse_handling = !without_gui_mouse_handling;
// Currently no config, using a tag for this small feature may be uselessly stressing the registry.
unstorable_containers.clear();
unstorable_containers.add(ModContent.LABELED_CRATE.asItem());
unstorable_containers.add(Items.SHULKER_BOX);
}
//--------------------------------------------------------------------------------------------------------------------
@ -150,6 +159,39 @@ public class BlockDecorLabeledCrate
@Override
public PushReaction getPushReaction(BlockState state)
{ return PushReaction.BLOCK; }
@Override
@OnlyIn(Dist.CLIENT)
public void addInformation(final ItemStack stack, @Nullable IBlockReader world, List<ITextComponent> tooltip, ITooltipFlag flag)
{
if(!Auxiliaries.Tooltip.extendedTipCondition() || Auxiliaries.Tooltip.helpCondition()) {
super.addInformation(stack, world, tooltip, flag);
return;
}
NonNullList<ItemStack> items = NonNullList.withSize(LabeledCrateTileEntity.NUM_OF_SLOTS, ItemStack.EMPTY);
int num_used_slots = 0;
int total_items = 0;
if(stack.hasTag() && stack.getTag().contains("tedata")) {
final CompoundNBT nbt = stack.getTag().getCompound("tedata");
if(nbt.contains("Items")) {
ItemStackHelper.loadAllItems(nbt, items);
for(int i=0; i<LabeledCrateTileEntity.ITEMFRAME_SLOTNO; ++i) {
final ItemStack st = items.get(i);
if(st.isEmpty()) continue;
++num_used_slots;
total_items += st.getCount();
}
}
}
int num_free_slots = LabeledCrateTileEntity.ITEMFRAME_SLOTNO - num_used_slots;
ItemStack frameStack = items.get(LabeledCrateTileEntity.ITEMFRAME_SLOTNO);
tooltip.add(Auxiliaries.localizable(getTranslationKey()+".tip", null, new Object[] {
(frameStack.isEmpty() ? (new StringTextComponent("-/-")) : (new TranslationTextComponent(frameStack.getTranslationKey()))),
num_used_slots,
num_free_slots,
total_items
}));
}
}
//--------------------------------------------------------------------------------------------------------------------
@ -188,19 +230,22 @@ public class BlockDecorLabeledCrate
public void readnbt(CompoundNBT compound)
{
NonNullList<ItemStack> stacks = NonNullList.<ItemStack>withSize(NUM_OF_SLOTS, ItemStack.EMPTY);
ItemStackHelper.loadAllItems(compound, stacks);
if(!compound.isEmpty()) ItemStackHelper.loadAllItems(compound, stacks);
while(stacks.size() < NUM_OF_SLOTS) stacks.add(ItemStack.EMPTY);
stacks_ = stacks;
}
protected void writenbt(CompoundNBT compound)
{
ItemStackHelper.saveAllItems(compound, stacks_);
if(!stacks_.stream().allMatch(ItemStack::isEmpty)) ItemStackHelper.saveAllItems(compound, stacks_);
}
public ItemStack getItemFrameStack()
{ return (stacks_.size() > ITEMFRAME_SLOTNO) ? (stacks_.get(ITEMFRAME_SLOTNO)) : (ItemStack.EMPTY); }
protected static boolean inacceptable(ItemStack stack)
{ return (stack.hasTag() && (!stack.getTag().isEmpty()) && (unstorable_containers.contains(stack.getItem()))); }
// TileEntity ------------------------------------------------------------------------------
@Override
@ -211,6 +256,13 @@ public class BlockDecorLabeledCrate
public CompoundNBT write(CompoundNBT compound)
{ super.write(compound); writenbt(compound); return compound; }
@Override
public void remove()
{
super.remove();
item_handler_.invalidate();
}
@Override
public CompoundNBT getUpdateTag()
{ CompoundNBT nbt = super.getUpdateTag(); writenbt(nbt); return nbt; }
@ -313,7 +365,7 @@ public class BlockDecorLabeledCrate
@Override
public boolean isItemValidForSlot(int index, ItemStack stack)
{ return (index != ITEMFRAME_SLOTNO); }
{ return (index != ITEMFRAME_SLOTNO) && (!inacceptable(stack)); }
@Override
public void clear()
@ -380,14 +432,15 @@ public class BlockDecorLabeledCrate
@Override
public boolean isItemValid(int slot, @Nonnull ItemStack stack)
{ return true; }
{ return te.isItemValidForSlot(slot, stack); }
@Override
@Nonnull
public ItemStack insertItem(int slotno, @Nonnull ItemStack stack, boolean simulate)
{
if(stack.isEmpty()) return ItemStack.EMPTY;
if((slotno < 0) || ((slotno >= NUM_OF_SLOTS)) || ((slotno == ITEMFRAME_SLOTNO)) ) return ItemStack.EMPTY;
if((slotno < 0) || ((slotno >= NUM_OF_SLOTS)) || ((slotno == ITEMFRAME_SLOTNO)) ) return stack;
if((!isItemValid(slotno, stack))) return stack;
ItemStack slotstack = getStackInSlot(slotno);
if(!slotstack.isEmpty()) {
if(slotstack.getCount() >= Math.min(slotstack.getMaxStackSize(), getSlotLimit(slotno))) return stack;
@ -456,9 +509,7 @@ public class BlockDecorLabeledCrate
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing)
{
if(!this.removed) {
if(capability==CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return item_handler_.cast();
}
if(capability==CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return item_handler_.cast();
return super.getCapability(capability, facing);
}
}
@ -478,11 +529,19 @@ public class BlockDecorLabeledCrate
@Override
public int getSlotStackLimit()
{ return 64; }
@Override
public boolean isItemValid(ItemStack stack)
{ return !LabeledCrateTileEntity.inacceptable(stack); }
}
//------------------------------------------------------------------------------------------------------------------
private static final int PLAYER_INV_START_SLOTNO = LabeledCrateTileEntity.NUM_OF_SLOTS;
private static final int NUM_OF_CONTAINER_SLOTS = LabeledCrateTileEntity.NUM_OF_SLOTS + 36;
protected static final int STORAGE_SLOT_BEGIN = 0;
protected static final int STORAGE_SLOT_END = LabeledCrateTileEntity.ITEMFRAME_SLOTNO;
protected static final int PLAYER_SLOT_BEGIN = LabeledCrateTileEntity.NUM_OF_SLOTS;
protected static final int PLAYER_SLOT_END = LabeledCrateTileEntity.NUM_OF_SLOTS+36;
protected final PlayerEntity player_;
protected final IInventory inventory_;
protected final IWorldPosCallable wpc_;
@ -583,11 +642,6 @@ public class BlockDecorLabeledCrate
public void onServerPacketReceived(int windowId, CompoundNBT nbt)
{}
protected static final int STORAGE_SLOT_BEGIN = 0;
protected static final int STORAGE_SLOT_END = LabeledCrateTileEntity.ITEMFRAME_SLOTNO;
protected static final int PLAYER_SLOT_BEGIN = LabeledCrateTileEntity.NUM_OF_SLOTS;
protected static final int PLAYER_SLOT_END = LabeledCrateTileEntity.NUM_OF_SLOTS+36;
@Override
public void onClientPacketReceived(int windowId, PlayerEntity player, CompoundNBT nbt)
{
@ -695,7 +749,7 @@ public class BlockDecorLabeledCrate
{
if(!with_gui_mouse_handling) {
super.handleMouseClick(slot, slotId, button, type);
} else if((type == ClickType.QUICK_MOVE) && slot.getHasStack() && Auxiliaries.isShiftDown() && Auxiliaries.isCtrlDown()) {
} else if((type == ClickType.QUICK_MOVE) && (slot!=null) && slot.getHasStack() && Auxiliaries.isShiftDown() && Auxiliaries.isCtrlDown()) {
CompoundNBT nbt = new CompoundNBT();
nbt.putInt("slot", slotId);
action(QUICK_MOVE_ALL, nbt);

View file

@ -239,6 +239,14 @@ public class BlockDecorMilker extends StandardBlocks.Horizontal implements IDeco
public CompoundNBT write(CompoundNBT nbt)
{ super.write(nbt); writenbt(nbt, false); return nbt; }
@Override
public void remove()
{
super.remove();
energy_handler_.invalidate();
fluid_handler_.invalidate();
}
// IEnergyStorage ----------------------------------------------------------------------------
protected LazyOptional<IEnergyStorage> energy_handler_ = LazyOptional.of(() -> (IEnergyStorage)this);
@ -323,13 +331,8 @@ public class BlockDecorMilker extends StandardBlocks.Horizontal implements IDeco
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing)
{
if(!this.removed && (facing != null)) {
if((capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) && has_milk_fluid()) {
return fluid_handler_.cast();
} else if((capability == CapabilityEnergy.ENERGY) && (energy_consumption>0)) {
return energy_handler_.cast();
}
}
if((capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) && has_milk_fluid()) return fluid_handler_.cast();
if((capability == CapabilityEnergy.ENERGY) && (energy_consumption>0)) return energy_handler_.cast();
return super.getCapability(capability, facing);
}

View file

@ -340,6 +340,15 @@ public class BlockDecorMineralSmelter extends StandardBlocks.Horizontal implemen
public CompoundNBT write(CompoundNBT nbt)
{ super.write(nbt); writenbt(nbt); return nbt; }
@Override
public void remove()
{
super.remove();
energy_handler_.invalidate();
fluid_handler_.invalidate();
item_handler_.invalidate();
}
// INamedContainerProvider / INameable ------------------------------------------------------
@Override
@ -543,15 +552,9 @@ public class BlockDecorMineralSmelter extends StandardBlocks.Horizontal implemen
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing)
{
if(!this.removed && (facing != null)) {
if(capability== CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
return item_handler_.cast();
} else if(capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) {
return fluid_handler_.cast();
} else if(capability== CapabilityEnergy.ENERGY) {
return energy_handler_.cast();
}
}
if(capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return item_handler_.cast();
if(capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) return fluid_handler_.cast();
if(capability == CapabilityEnergy.ENERGY) return energy_handler_.cast();
return super.getCapability(capability, facing);
}

View file

@ -71,7 +71,7 @@ public class BlockDecorPassiveFluidAccumulator extends StandardBlocks.Directed i
public void neighborChanged(BlockState state, World world, BlockPos pos, Block block, BlockPos fromPos, boolean unused)
{
TileEntity te = world.getTileEntity(pos);
if(te instanceof BlockDecorPipeValve.BTileEntity) ((BTileEntity)te).block_changed();
if(te instanceof BTileEntity) ((BTileEntity)te).block_changed();
}
//--------------------------------------------------------------------------------------------------------------------
@ -124,6 +124,14 @@ public class BlockDecorPassiveFluidAccumulator extends StandardBlocks.Directed i
return nbt;
}
@Override
public void remove()
{
super.remove();
fill_handler_.invalidate();
fluid_handler_.invalidate();
}
// Input flow handler ---------------------------------------------------------------------
private static class InputFillHandler implements IFluidHandler
@ -181,11 +189,12 @@ public class BlockDecorPassiveFluidAccumulator extends StandardBlocks.Directed i
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing)
{
if((initialized_) && (!this.removed) && (facing != null)) {
if(capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) {
if(capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) {
if(initialized_) {
if(facing == block_facing_) return fluid_handler_.cast();
return fill_handler_.cast();
if(facing != null) return fill_handler_.cast();
}
return LazyOptional.empty();
}
return super.getCapability(capability, facing);
}

View file

@ -23,10 +23,10 @@ import net.minecraft.tileentity.TileEntityType;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.item.BlockItemUseContext;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.entity.LivingEntity;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.Direction;
import net.minecraft.util.Rotation;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.shapes.ISelectionContext;
@ -42,159 +42,161 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class BlockDecorPipeValve extends StandardBlocks.DirectedWaterLoggable implements IDecorBlock
public class BlockDecorPipeValve
{
public static final BooleanProperty RS_CN_N = BooleanProperty.create("rs_n");
public static final BooleanProperty RS_CN_S = BooleanProperty.create("rs_s");
public static final BooleanProperty RS_CN_E = BooleanProperty.create("rs_e");
public static final BooleanProperty RS_CN_W = BooleanProperty.create("rs_w");
public static final BooleanProperty RS_CN_U = BooleanProperty.create("rs_u");
public static final BooleanProperty RS_CN_D = BooleanProperty.create("rs_d");
public static final int CFG_CHECK_VALVE = 0x0;
public static final int CFG_ANALOG_VALVE = 0x1;
public static final int CFG_REDSTONE_CONTROLLED_VALVE = 0x2;
public final int valve_config;
public static final int CFG_CHECK_VALVE = 0x1;
public static final int CFG_ANALOG_VALVE = 0x2;
public static final int CFG_REDSTONE_CONTROLLED_VALVE = 0x4;
public static void on_config(int container_size_decl, int redstone_slope)
{
BTileEntity.fluid_maxflow_mb = MathHelper.clamp(container_size_decl, 1, 10000);
BTileEntity.redstone_flow_slope_mb = MathHelper.clamp(redstone_slope, 1, 10000);
ModEngineersDecor.logger().info("Config pipe valve: maxflow:" + BTileEntity.fluid_maxflow_mb + "mb, redstone amp:" + BTileEntity.redstone_flow_slope_mb + "mb/sig");
DecorPipeValveTileEntity.fluid_maxflow_mb = MathHelper.clamp(container_size_decl, 1, 10000);
DecorPipeValveTileEntity.redstone_flow_slope_mb = MathHelper.clamp(redstone_slope, 1, 10000);
ModEngineersDecor.logger().info("Config pipe valve: maxflow:" + DecorPipeValveTileEntity.fluid_maxflow_mb + "mb, redstone amp:" + DecorPipeValveTileEntity.redstone_flow_slope_mb + "mb/sig");
}
public BlockDecorPipeValve(long config, int valve_config, Block.Properties builder, final AxisAlignedBB[] unrotatedAABB)
{ super(config, builder, unrotatedAABB); this.valve_config = valve_config; }
//--------------------------------------------------------------------------------------------------------------------
// Block
//--------------------------------------------------------------------------------------------------------------------
private BlockState get_rsconnector_state(BlockState state, IWorld world, BlockPos pos, @Nullable BlockPos fromPos)
public static class DecorPipeValveBlock extends StandardBlocks.DirectedWaterLoggable implements IDecorBlock
{
if((valve_config & (CFG_REDSTONE_CONTROLLED_VALVE))==0) return state;
Direction.Axis bfa = state.get(FACING).getAxis();
int bfi = state.get(FACING).getIndex();
for(Direction f:Direction.values()) {
boolean cn = (f.getAxis() != bfa);
if(cn) {
BlockPos nbp = pos.offset(f);
if((fromPos != null) && (!nbp.equals(fromPos))) continue; // do not change connectors except form the frompos.
BlockState nbs = world.getBlockState(nbp);
if(!nbs.canProvidePower()) cn = false; // @todo check if there is a direction selective canProvidePower().
}
switch(f) {
case NORTH: state = state.with(RS_CN_N, cn); break;
case SOUTH: state = state.with(RS_CN_S, cn); break;
case EAST: state = state.with(RS_CN_E, cn); break;
case WEST: state = state.with(RS_CN_W, cn); break;
case UP: state = state.with(RS_CN_U, cn); break;
case DOWN: state = state.with(RS_CN_D, cn); break;
public static final BooleanProperty RS_CN_N = BooleanProperty.create("rs_n");
public static final BooleanProperty RS_CN_S = BooleanProperty.create("rs_s");
public static final BooleanProperty RS_CN_E = BooleanProperty.create("rs_e");
public static final BooleanProperty RS_CN_W = BooleanProperty.create("rs_w");
public static final BooleanProperty RS_CN_U = BooleanProperty.create("rs_u");
public static final BooleanProperty RS_CN_D = BooleanProperty.create("rs_d");
public final int valve_config;
public DecorPipeValveBlock(long config, int valve_config, Block.Properties builder, final AxisAlignedBB[] unrotatedAABB)
{ super(config, builder, unrotatedAABB); this.valve_config = valve_config; }
private BlockState get_rsconnector_state(BlockState state, IWorld world, BlockPos pos, @Nullable BlockPos fromPos)
{
if((valve_config & (CFG_REDSTONE_CONTROLLED_VALVE))==0) return state;
Direction.Axis bfa = state.get(FACING).getAxis();
int bfi = state.get(FACING).getIndex();
for(Direction f:Direction.values()) {
boolean cn = (f.getAxis() != bfa);
if(cn) {
BlockPos nbp = pos.offset(f);
if((fromPos != null) && (!nbp.equals(fromPos))) continue; // do not change connectors except form the frompos.
BlockState nbs = world.getBlockState(nbp);
if(!nbs.canProvidePower()) cn = false; // @todo check if there is a direction selective canProvidePower().
}
switch(f) {
case NORTH: state = state.with(RS_CN_N, cn); break;
case SOUTH: state = state.with(RS_CN_S, cn); break;
case EAST: state = state.with(RS_CN_E, cn); break;
case WEST: state = state.with(RS_CN_W, cn); break;
case UP: state = state.with(RS_CN_U, cn); break;
case DOWN: state = state.with(RS_CN_D, cn); break;
}
}
return state;
}
return state;
@Override
public VoxelShape getCollisionShape(BlockState state, IBlockReader world, BlockPos pos, ISelectionContext selectionContext)
{ return VoxelShapes.fullCube(); }
@Override
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder)
{ super.fillStateContainer(builder); builder.add(RS_CN_N, RS_CN_S, RS_CN_E, RS_CN_W, RS_CN_U, RS_CN_D); }
@Override
@Nullable
public BlockState getStateForPlacement(BlockItemUseContext context)
{
return super.getStateForPlacement(context).with(RS_CN_N, false).with(RS_CN_S, false).with(RS_CN_E, false)
.with(RS_CN_W, false).with(RS_CN_U, false).with(RS_CN_D, false);
}
@Override
@SuppressWarnings("deprecation")
public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState facingState, IWorld world, BlockPos pos, BlockPos facingPos)
{ return get_rsconnector_state(state, world, pos, null); }
@Override
public void onBlockPlacedBy(World world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack)
{ world.notifyNeighborsOfStateChange(pos,this); }
@Override
public boolean hasTileEntity(BlockState state)
{ return true; }
@Override
@Nullable
public TileEntity createTileEntity(BlockState state, IBlockReader world)
{ return new DecorPipeValveTileEntity(); }
@Override
public BlockState rotate(BlockState state, IWorld world, BlockPos pos, Rotation direction)
{ return get_rsconnector_state(state, world, pos, null); } // don't rotate at all
@Override
public boolean canConnectRedstone(BlockState state, IBlockReader world, BlockPos pos, @Nullable Direction side)
{ return (side!=null) && (side!=state.get(FACING)) && (side!=state.get(FACING).getOpposite()); }
@Override
@SuppressWarnings("deprecation")
public boolean canProvidePower(BlockState state)
{ return true; }
@Override
@SuppressWarnings("deprecation")
public int getWeakPower(BlockState blockState, IBlockReader blockAccess, BlockPos pos, Direction side)
{ return 0; }
@Override
@SuppressWarnings("deprecation")
public int getStrongPower(BlockState blockState, IBlockReader blockAccess, BlockPos pos, Direction side)
{ return 0; }
}
private void update_te(IWorld world, BlockState state, BlockPos pos)
{
TileEntity te = world.getTileEntity(pos);
if(te instanceof BlockDecorPipeValve.BTileEntity) ((BlockDecorPipeValve.BTileEntity)te).block_reconfigure(state.get(FACING), config, valve_config);
}
@Override
public VoxelShape getCollisionShape(BlockState state, IBlockReader world, BlockPos pos, ISelectionContext selectionContext)
{ return VoxelShapes.fullCube(); }
@Override
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder)
{ super.fillStateContainer(builder); builder.add(RS_CN_N, RS_CN_S, RS_CN_E, RS_CN_W, RS_CN_U, RS_CN_D); }
@Override
@Nullable
public BlockState getStateForPlacement(BlockItemUseContext context)
{
return super.getStateForPlacement(context).with(RS_CN_N, false).with(RS_CN_S, false).with(RS_CN_E, false)
.with(RS_CN_W, false).with(RS_CN_U, false).with(RS_CN_D, false);
}
@Override
@SuppressWarnings("deprecation")
public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState facingState, IWorld world, BlockPos pos, BlockPos facingPos)
{
update_te(world, state, pos);
return get_rsconnector_state(state, world, pos, null);
}
@Override
public void onBlockPlacedBy(World world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack)
{
update_te(world, state, pos);
world.notifyNeighborsOfStateChange(pos,this);
}
@Override
public boolean hasTileEntity(BlockState state)
{ return true; }
@Override
@Nullable
public TileEntity createTileEntity(BlockState state, IBlockReader world)
{ return new BlockDecorPipeValve.BTileEntity(); }
@Override
public boolean canConnectRedstone(BlockState state, IBlockReader world, BlockPos pos, @Nullable Direction side)
{ return (side!=null) && (side!=state.get(FACING)) && (side!=state.get(FACING).getOpposite()); }
//--------------------------------------------------------------------------------------------------------------------
// Tile entity
//--------------------------------------------------------------------------------------------------------------------
public static class BTileEntity extends TileEntity implements ICapabilityProvider //, IFluidPipe
public static class DecorPipeValveTileEntity extends TileEntity implements ICapabilityProvider //, IFluidPipe
{
protected static int fluid_maxflow_mb = 1000;
protected static int redstone_flow_slope_mb = 1000/15;
private Direction block_facing_ = null;
private boolean filling_ = false;
private boolean getlocked_ = false;
private long block_config_ = 0;
private long valve_config_ = 0;
public BTileEntity()
public DecorPipeValveTileEntity()
{ this(ModContent.TET_STRAIGHT_PIPE_VALVE); }
public BTileEntity(TileEntityType<?> te_type)
public DecorPipeValveTileEntity(TileEntityType<?> te_type)
{ super(te_type); }
public void block_reconfigure(Direction facing, long block_config, int valve_config)
{
block_facing_ = facing;
block_config_ = block_config;
valve_config_ = valve_config;
}
private Direction block_facing()
{
if(block_facing_ == null) {
BlockState st = getWorld().getBlockState(getPos());
block_facing_ = (st.getBlock() instanceof BlockDecorPipeValve) ? st.get(FACING) : Direction.NORTH;
BlockState st = getWorld().getBlockState(getPos());
return (st.getBlock() instanceof DecorPipeValveBlock) ? st.get(DecorPipeValveBlock.FACING) : Direction.NORTH;
}
private long valve_config()
{
if(valve_config_ <= 0) {
final Block block = getWorld().getBlockState(getPos()).getBlock();
if(block instanceof DecorPipeValveBlock) valve_config_ = ((DecorPipeValveBlock)block).valve_config;
}
return block_facing_;
return valve_config_;
}
// TileEntity ------------------------------------------------------------------------------
// TileEntity -----------------------------------------------------------------------------
@Override
public void read(CompoundNBT nbt)
public void remove()
{
super.read(nbt);
int i = nbt.getInt("facing");
if((i>=0) || (i<6)) block_facing_ = Direction.byIndex(i);
block_config_ = nbt.getLong("conf");
}
@Override
public CompoundNBT write(CompoundNBT nbt)
{
super.write(nbt);
if(block_facing_!=null) nbt.putInt("facing", block_facing_.getIndex());
nbt.putLong("conf", block_config_);
return nbt;
super.remove();
back_flow_handler_.invalidate();
fluid_handler_.invalidate();
}
// ICapabilityProvider --------------------------------------------------------------------
@ -205,10 +207,12 @@ public class BlockDecorPipeValve extends StandardBlocks.DirectedWaterLoggable im
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing)
{
if(!this.removed && (facing != null)) {
if(!removed) {
if(capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) {
if(facing == block_facing()) return back_flow_handler_.cast();
if(facing == block_facing().getOpposite()) return fluid_handler_.cast();
Direction bf = block_facing();
if(facing == bf) return back_flow_handler_.cast();
if(facing == bf.getOpposite()) return fluid_handler_.cast();
return LazyOptional.empty();
}
}
return super.getCapability(capability, facing);
@ -228,24 +232,24 @@ public class BlockDecorPipeValve extends StandardBlocks.DirectedWaterLoggable im
private static class MainFlowHandler implements IFluidHandler
{
private BTileEntity te;
public MainFlowHandler(BTileEntity te) { this.te = te; }
private DecorPipeValveTileEntity te;
public MainFlowHandler(DecorPipeValveTileEntity te) { this.te = te; }
@Override public int getTanks() { return 0; }
@Override public FluidStack getFluidInTank(int tank) { return FluidStack.EMPTY; }
@Override public int getTankCapacity(int tank) { return fluid_maxflow_mb; }
@Override public boolean isFluidValid(int tank, @Nonnull FluidStack stack) { return true; }
@Override public FluidStack drain(FluidStack resource, FluidAction action) { return FluidStack.EMPTY; }
@Override public FluidStack drain(int maxDrain, FluidAction action) { return FluidStack.EMPTY; }
@Override public boolean isFluidValid(int tank, @Nonnull FluidStack stack) { return true; }
@Override public int fill(FluidStack resource, FluidAction action)
{
if(te.filling_) return 0;
final IFluidHandler fh = te.forward_fluid_handler();
if(fh==null) return 0;
if((te.valve_config_ & CFG_REDSTONE_CONTROLLED_VALVE) != 0) {
if((te.valve_config() & CFG_REDSTONE_CONTROLLED_VALVE) != 0) {
int rs = te.world.getRedstonePowerFromNeighbors(te.pos);
if(rs <= 0) return 0;
if(((te.valve_config_ & CFG_ANALOG_VALVE) != 0) && (rs < 15)) resource.setAmount(MathHelper.clamp(rs * redstone_flow_slope_mb, 1, resource.getAmount()));
if(((te.valve_config() & CFG_ANALOG_VALVE) != 0) && (rs < 15)) resource.setAmount(MathHelper.clamp(rs * redstone_flow_slope_mb, 1, resource.getAmount()));
}
FluidStack res = resource.copy();
if(res.getAmount() > fluid_maxflow_mb) res.setAmount(fluid_maxflow_mb);
@ -276,24 +280,5 @@ public class BlockDecorPipeValve extends StandardBlocks.DirectedWaterLoggable im
@Override public FluidStack drain(FluidStack resource, FluidAction action) { return FluidStack.EMPTY; }
@Override public FluidStack drain(int maxDrain, FluidAction action) { return FluidStack.EMPTY; }
}
// IE IFluidPipe
// @Override
// public boolean hasOutputConnection(Direction side)
// { return (side == block_facing()); }
//
// @Override
// public boolean canOutputPressurized(boolean consumePower)
// {
// if(getlocked_ || (!filling_enabled_)) return false;
// final TileEntity te = world.getTileEntity(pos.offset(block_facing()));
// if(!(te instanceof IFluidPipe)) return false;
// getlocked_ = true; // not sure if IE explicitly pre-detects loops, so let's lock recurion here, too.
// boolean r = ((IFluidPipe)te).canOutputPressurized(consumePower);
// getlocked_ = false;
// return r;
// }
}
}

View file

@ -51,6 +51,7 @@ import net.minecraftforge.fml.network.NetworkHooks;
import com.mojang.blaze3d.platform.GlStateManager;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@ -256,6 +257,13 @@ public class BlockDecorPlacer extends StandardBlocks.Directed implements IDecorB
public CompoundNBT write(CompoundNBT nbt)
{ super.write(nbt); writenbt(nbt, false); return nbt; }
@Override
public void remove()
{
super.remove();
Arrays.stream(item_handlers).forEach(LazyOptional::invalidate);
}
// INamable ----------------------------------------------------------------------------------------------
@Override
@ -392,9 +400,7 @@ public class BlockDecorPlacer extends StandardBlocks.Directed implements IDecorB
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing)
{
if(!this.removed && (facing != null)) {
if(capability==CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return item_handlers[0].cast();
}
if(capability==CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return item_handlers[0].cast();
return super.getCapability(capability, facing);
}

View file

@ -161,11 +161,7 @@ public class BlockDecorSolarPanel extends StandardBlocks.BaseBlock implements ID
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing)
{
if(!this.removed && (facing != null)) {
if(capability== CapabilityEnergy.ENERGY) {
return energy_handler_.cast();
}
}
if(capability== CapabilityEnergy.ENERGY) return energy_handler_.cast();
return super.getCapability(capability, facing);
}
@ -179,6 +175,13 @@ public class BlockDecorSolarPanel extends StandardBlocks.BaseBlock implements ID
public CompoundNBT write(CompoundNBT nbt)
{ super.write(nbt); writenbt(nbt, false); return nbt; }
@Override
public void remove()
{
super.remove();
energy_handler_.invalidate();
}
@Override
public void tick()
{

View file

@ -213,6 +213,13 @@ public class BlockDecorTest extends StandardBlocks.Directed implements IExperime
return nbt;
}
@Override
public void remove()
{
super.remove();
fluid_handler_.invalidate();
}
// ICapabilityProvider --------------------------------------------------------------------
private LazyOptional<IFluidHandler> fluid_handler_ = LazyOptional.of(() -> (IFluidHandler)new MainFluidHandler(this));
@ -220,10 +227,9 @@ public class BlockDecorTest extends StandardBlocks.Directed implements IExperime
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing)
{
if(!this.removed && (facing != null)) {
if(capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) {
if(facing != block_facing()) return fluid_handler_.cast();
}
if(capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) {
if(facing != block_facing()) return fluid_handler_.cast();
return LazyOptional.empty();
}
return super.getCapability(capability, facing);
}

View file

@ -153,6 +153,13 @@ public class BlockDecorTreeCutter extends StandardBlocks.Horizontal implements I
public CompoundNBT write(CompoundNBT nbt)
{ super.write(nbt); writenbt(nbt); return nbt; }
@Override
public void remove()
{
super.remove();
energy_handler_.invalidate();
}
// IEnergyStorage ----------------------------------------------------------------------------
protected LazyOptional<IEnergyStorage> energy_handler_ = LazyOptional.of(() -> (IEnergyStorage)this);
@ -190,11 +197,7 @@ public class BlockDecorTreeCutter extends StandardBlocks.Horizontal implements I
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing)
{
if(!this.removed && (facing != null)) {
if(capability== CapabilityEnergy.ENERGY) {
return energy_handler_.cast();
}
}
if(capability == CapabilityEnergy.ENERGY) return energy_handler_.cast();
return super.getCapability(capability, facing);
}

View file

@ -239,6 +239,14 @@ public class BlockDecorWasteIncinerator extends StandardBlocks.BaseBlock impleme
public CompoundNBT write(CompoundNBT compound)
{ super.write(compound); writenbt(compound); return compound; }
@Override
public void remove()
{
super.remove();
energy_handler_.invalidate();
item_handler_.invalidate();
}
// INameable ---------------------------------------------------------------------------
@Override
@ -481,10 +489,8 @@ public class BlockDecorWasteIncinerator extends StandardBlocks.BaseBlock impleme
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing)
{
if(!this.removed && (facing != null)) {
if(capability==CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return item_handler_.cast();
if(capability== CapabilityEnergy.ENERGY) return energy_handler_.cast();
}
if(capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return item_handler_.cast();
if(capability == CapabilityEnergy.ENERGY) return energy_handler_.cast();
return super.getCapability(capability, facing);
}

View file

@ -544,10 +544,10 @@ public class ModConfig
if(block instanceof BlockDecorHalfSlab) return COMMON.without_halfslabs.get();
if(block instanceof BlockDecorLadder) return COMMON.without_ladders.get();
if(block instanceof BlockDecorWindow) return COMMON.without_windows.get();
if(block instanceof BlockDecorPipeValve) return COMMON.without_valves.get();
if(block instanceof BlockDecorPipeValve.DecorPipeValveBlock) return COMMON.without_valves.get();
if(block instanceof BlockDecorHorizontalSupport) return COMMON.without_hsupports.get();
if(block instanceof BlockDecorFloorGrating) return COMMON.without_floor_grating.get();
if(block instanceof BlockDecorHopper) return COMMON.without_factory_hopper.get();
if(block instanceof BlockDecorHopper.DecorHopperBlock) return COMMON.without_factory_hopper.get();
if(block instanceof BlockDecorFluidFunnel) return COMMON.without_fluid_funnel.get();
if(block instanceof BlockDecorSolarPanel) return COMMON.without_solar_panel.get();
if(block instanceof BlockDecorMineralSmelter) return COMMON.without_mineral_smelter.get();

View file

@ -1,5 +1,5 @@
/*
* @file BlockDecorFull.java
* @file StandardBlocks.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2019 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)

View file

@ -1,5 +1,5 @@
/*
* @file BlockDecorWall.java
* @file StandardFenceBlock.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2019 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)
@ -8,7 +8,6 @@
*/
package wile.engineersdecor.libmc.blocks;
import net.minecraft.util.math.shapes.VoxelShapes;
import wile.engineersdecor.libmc.detail.Auxiliaries;
import net.minecraft.world.*;
import net.minecraft.fluid.IFluidState;
@ -24,6 +23,7 @@ import net.minecraft.item.BlockItemUseContext;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.shapes.VoxelShapes;
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.util.text.ITextComponent;
import net.minecraftforge.api.distmarker.Dist;

View file

@ -45,7 +45,7 @@ public class Auxiliaries
{
private static String modid;
private static Logger logger;
private static Supplier<CompoundNBT> server_config_supplier = ()->new CompoundNBT();
private static Supplier<CompoundNBT> server_config_supplier = CompoundNBT::new;
public static void init(String modid, Logger logger, Supplier<CompoundNBT> server_config_supplier)
{
@ -64,6 +64,13 @@ public class Auxiliaries
public static Logger logger()
{ return logger; }
public static void debug(Object... params)
{
StringBuilder sb = new StringBuilder();
for(Object o:params) sb.append((o==null) ? "<null>" : o.toString()).append(' ');
logger().info(sb.toString().trim());
}
// -------------------------------------------------------------------------------------------------------------------
// Sideness, system/environment, tagging interfaces
// -------------------------------------------------------------------------------------------------------------------

View file

@ -95,6 +95,28 @@ public class Inventories
public SlotRange(IInventory inv, int start, int end)
{ inventory=inv; start_slot=start; end_slot=end; }
/**
* Returns the number of stacks that match the given stack with NBT.
*/
public int stackMatchCount(final ItemStack ref_stack)
{
int n = 0; // ... std::accumulate() the old school way.
for(int i = start_slot; i < end_slot; ++i) {
if(areItemStacksIdentical(ref_stack, inventory.getStackInSlot(i))) ++n;
}
return n;
}
public int totalMatchingItemCount(final ItemStack ref_stack)
{
int n = 0;
for(int i = start_slot; i < end_slot; ++i) {
ItemStack stack = inventory.getStackInSlot(i);
if(areItemStacksIdentical(ref_stack, stack)) n += stack.getCount();
}
return n;
}
/**
* Moves as much items from the stack to the slots in range [start_slot, end_slot] of the inventory,
* filling up existing stacks first, then (player inventory only) checks appropriate empty slots next
@ -109,11 +131,24 @@ public class Inventories
final ItemStack mvstack = stack_to_move.copy();
if((mvstack.isEmpty()) || (start_slot < 0) || (end_slot > inventory.getSizeInventory())) return checked(mvstack);
int limit_left = (limit>0) ? (Math.min(limit, mvstack.getMaxStackSize())) : (mvstack.getMaxStackSize());
// first iteration: fillup existing stacks
boolean matches[] = new boolean[end_slot];
boolean empties[] = new boolean[end_slot];
int num_matches = 0;
for(int i = start_slot; i < end_slot; ++i) {
final int sno = reverse ? (end_slot-1-i) : (i);
final ItemStack stack = inventory.getStackInSlot(sno);
if((stack.isEmpty()) || (areItemStacksDifferent(stack, mvstack))) continue;
if(stack.isEmpty() || (!inventory.isItemValidForSlot(sno, mvstack))) {
empties[sno] = true;
} else if(areItemStacksIdentical(stack, mvstack)) {
matches[sno] = true;
++num_matches;
}
}
// first iteration: fillup existing stacks
for(int i = start_slot; i < end_slot; ++i) {
final int sno = reverse ? (end_slot-1-i) : (i);
if(empties[sno] || !matches[sno]) continue;
final ItemStack stack = inventory.getStackInSlot(sno);
int nmax = Math.min(limit_left, stack.getMaxStackSize() - stack.getCount());
if(mvstack.getCount() <= nmax) {
stack.setCount(stack.getCount()+mvstack.getCount());
@ -127,26 +162,53 @@ public class Inventories
}
}
if(only_fillup) return checked(mvstack);
if((force_group_stacks) || (inventory instanceof PlayerInventory)) {
// second iteration: use appropriate empty slots
for(int i = start_slot+1; i < end_slot-1; ++i) {
final int sno = reverse ? (end_slot-1-i) : (i);
final ItemStack stack = inventory.getStackInSlot(sno);
if(!stack.isEmpty()) continue;
if((areItemStacksDifferent(inventory.getStackInSlot(sno+1), mvstack)) && (areItemStacksDifferent(inventory.getStackInSlot(sno-1), mvstack))) continue;
int nmax = Math.min(limit_left, mvstack.getCount());
ItemStack moved = mvstack.copy();
moved.setCount(nmax);
mvstack.shrink(nmax);
inventory.setInventorySlotContents(sno, moved);
return checked(mvstack);
if((num_matches>0) && ((force_group_stacks) || (inventory instanceof PlayerInventory))) {
// second iteration: use appropriate empty slots,
// a) between
{
int insert_start = -1;
int insert_end = -1;
int i = start_slot+1;
for(;i < end_slot-1; ++i) {
final int sno = reverse ? (end_slot-1-i) : (i);
if(insert_start < 0) {
if(matches[sno]) insert_start = sno;
} else if(matches[sno]) {
insert_end = sno;
}
}
for(i=insert_start;i < insert_end; ++i) {
final int sno = reverse ? (end_slot-1-i) : (i);
if(!empties[sno]) continue;
int nmax = Math.min(limit_left, mvstack.getCount());
ItemStack moved = mvstack.copy();
moved.setCount(nmax);
mvstack.shrink(nmax);
inventory.setInventorySlotContents(sno, moved);
return checked(mvstack);
}
}
// b) before/after
{
for(int i = start_slot+1; i < end_slot-1; ++i) {
final int sno = reverse ? (end_slot-1-i) : (i);
if(!matches[sno]) continue;
int ii = (empties[sno-1]) ? (sno-1) : (empties[sno+1] ? (sno+1) : -1);
if(ii >= 0) {
int nmax = Math.min(limit_left, mvstack.getCount());
ItemStack moved = mvstack.copy();
moved.setCount(nmax);
mvstack.shrink(nmax);
inventory.setInventorySlotContents(ii, moved);
return checked(mvstack);
}
}
}
}
// third iteration: use any empty slots
for(int i = start_slot; i < end_slot; ++i) {
final int sno = reverse ? (end_slot-1-i) : (i);
final ItemStack stack = inventory.getStackInSlot(sno);
if(!stack.isEmpty()) continue;
if(!empties[sno]) continue;
int nmax = Math.min(limit_left, mvstack.getCount());
ItemStack placed = mvstack.copy();
placed.setCount(nmax);

View file

@ -31,13 +31,13 @@ import java.util.function.Predicate;
public class OptionalRecipeCondition implements ICondition
{
private static ResourceLocation NAME;
private static Logger LOGGER;
private final List<ResourceLocation> all_required;
private final List<ResourceLocation> any_missing;
private final List<ResourceLocation> all_required_tags;
private final List<ResourceLocation> any_missing_tags;
private final @Nullable ResourceLocation result;
private final boolean result_is_tag;
private final boolean experimental;
private static boolean with_experimental = false;
@ -45,11 +45,9 @@ public class OptionalRecipeCondition implements ICondition
private static Predicate<Block> block_optouts = (block)->false;
private static Predicate<Item> item_optouts = (item)->false;
public static void init(String modid, Logger logger)
{
NAME = new ResourceLocation(modid, "optional");
LOGGER = logger;
}
public static void on_config(boolean enable_experimental, boolean disable_all_recipes,
@ -63,13 +61,14 @@ public class OptionalRecipeCondition implements ICondition
}
public OptionalRecipeCondition(ResourceLocation result, List<ResourceLocation> required, List<ResourceLocation> missing, List<ResourceLocation> required_tags, List<ResourceLocation> missing_tags, boolean isexperimental)
public OptionalRecipeCondition(ResourceLocation result, List<ResourceLocation> required, List<ResourceLocation> missing, List<ResourceLocation> required_tags, List<ResourceLocation> missing_tags, boolean isexperimental, boolean result_is_tag)
{
all_required = required;
any_missing = missing;
all_required_tags = required_tags;
any_missing_tags = missing_tags;
this.result = result;
this.result_is_tag = result_is_tag;
experimental=isexperimental;
}
@ -112,6 +111,7 @@ public class OptionalRecipeCondition implements ICondition
if(!all_required_tags.isEmpty()) {
for(ResourceLocation rl:all_required_tags) {
if(!ItemTags.getCollection().getTagMap().containsKey(rl)) return false;
if(ItemTags.getCollection().getTagMap().get(rl).getAllElements().isEmpty()) return false;
}
}
if(!any_missing.isEmpty()) {
@ -123,13 +123,13 @@ public class OptionalRecipeCondition implements ICondition
if(!any_missing_tags.isEmpty()) {
for(ResourceLocation rl:any_missing_tags) {
if(!ItemTags.getCollection().getTagMap().containsKey(rl)) return true;
if(ItemTags.getCollection().getTagMap().get(rl).getAllElements().isEmpty()) return true;
}
return false;
}
return true;
}
public static class Serializer implements IConditionSerializer<OptionalRecipeCondition>
{
public static final Serializer INSTANCE = new Serializer();
@ -147,7 +147,9 @@ public class OptionalRecipeCondition implements ICondition
for(ResourceLocation e:condition.any_missing) missing.add(e.toString());
json.add("required", required);
json.add("missing", missing);
if(condition.result != null) json.addProperty("result", condition.result.toString());
if(condition.result != null) {
json.addProperty("result", (condition.result_is_tag ? "#" : "") + condition.result.toString());
}
}
@Override
@ -159,7 +161,16 @@ public class OptionalRecipeCondition implements ICondition
List<ResourceLocation> missing_tags = new ArrayList<>();
ResourceLocation result = null;
boolean experimental = false;
if(json.has("result")) result = new ResourceLocation(json.get("result").getAsString());
boolean result_is_tag = false;
if(json.has("result")) {
String s = json.get("result").getAsString();
if(s.startsWith("#")) {
result = new ResourceLocation(s.substring(1));
result_is_tag = true;
} else {
result = new ResourceLocation(s);
}
}
if(json.has("required")) {
for(JsonElement e:JSONUtils.getJsonArray(json, "required")) {
String s = e.getAsString();
@ -181,7 +192,7 @@ public class OptionalRecipeCondition implements ICondition
}
}
if(json.has("experimental")) experimental = json.get("experimental").getAsBoolean();
return new OptionalRecipeCondition(result, required, missing, required_tags, missing_tags, experimental);
return new OptionalRecipeCondition(result, required, missing, required_tags, missing_tags, experimental, result_is_tag);
}
}
}

View file

@ -1,5 +1,5 @@
/*
* @file OverlayEventHandler.java
* @file Overlay.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2018 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)

View file

@ -1,3 +1,11 @@
/*
* @file SidedProxy.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2018 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)
*
* General client/server sideness selection proxy.
*/
package wile.engineersdecor.libmc.detail;
import net.minecraft.client.Minecraft;

View file

@ -4,8 +4,8 @@
"language.region": "United States",
"itemGroup.tabengineersdecor": "Engineer's Decor",
"engineersdecor.config.title": "Engineer's Decor Config",
"engineersdecor.tooltip.hint.extended": "§6[§9SHIFT§r More Info§6]§r",
"engineersdecor.tooltip.hint.help": "§6[§9CTRL-SHIFT§r Help§6]§r",
"engineersdecor.tooltip.hint.extended": "§6[§9shift§r More§6]§r",
"engineersdecor.tooltip.hint.help": "§6[§9ctrl-shift§r Help§6]§r",
"engineersdecor.tooltip.slabpickup.help": "§rFast pickup by left-clicking while looking up/down and holding this slab.",
"engineersdecor.tooltip.requires_rf_power": "Requires RF power.",
"engineersdecor.tooltip.massive_speed_boost_with_rf_power": "Apply RF power to magnificently increase the speed.",
@ -59,6 +59,7 @@
"block.engineersdecor.slag_brick_block.help": "§6A gray-brown brick block with position dependent texture variations.",
"block.engineersdecor.labeled_crate": "Labeled Crate",
"block.engineersdecor.labeled_crate.help": "§6A storage crate with 9x6 slots and a built-in item frame at the front.§r\nPlace an item into the frame slot at the bottom right of the GUI to define the shown label.",
"block.engineersdecor.labeled_crate.tip": "§6Label:§r %1$s\n%2$s slots used / %3$s free\n%4$s total items stored",
"block.engineersdecor.rebar_concrete": "Rebar Concrete Block",
"block.engineersdecor.rebar_concrete.help": "§6Steel reinforced concrete block.§r Expensive but Creeper-proof like obsidian.",
"block.engineersdecor.gas_concrete": "Gas Concrete Block",

View file

@ -53,6 +53,7 @@
"engineersdecor.config.e_furnace_power_consumption": "Электропечь: потребление энергии",
"block.engineersdecor.labeled_crate": "Labeled Crate",
"block.engineersdecor.labeled_crate.help": "§6A storage crate with 9x6 slots and a built-in item frame at the front.§r\nPlace an item into the frame slot at the bottom right of the GUI to define the shown label.",
"block.engineersdecor.labeled_crate.tip": "§6Label:§r %1$s\n%2$s slots used / %3$s free\n%4$s total items stored",
"block.engineersdecor.clinker_brick_block": "Клинкерный кирпич",
"block.engineersdecor.clinker_brick_block.help": "§6Кирпичный блок с вариациями текстуры, зависящими от положения.§r\nВыглядит темнее и интенсивнее, чем Кирпичный блок.",
"block.engineersdecor.clinker_brick_stained_block": "Грязный клинкерный кирпич",

View file

@ -53,6 +53,7 @@
"engineersdecor.config.e_furnace_power_consumption": "电炉:能量消耗",
"block.engineersdecor.labeled_crate": "Labeled Crate",
"block.engineersdecor.labeled_crate.help": "§6A storage crate with 9x6 slots and a built-in item frame at the front.§r\nPlace an item into the frame slot at the bottom right of the GUI to define the shown label.",
"block.engineersdecor.labeled_crate.tip": "§6Label:§r %1$s\n%2$s slots used / %3$s free\n%4$s total items stored",
"block.engineersdecor.clinker_brick_block": "过烧砖块",
"block.engineersdecor.clinker_brick_block.help": "§6一种放在不同位置贴图有不同变化的砖块。§r\n比原版砖看起来颜色更深色度也更高。",
"block.engineersdecor.clinker_brick_stained_block": "污渍过烧砖块",

View file

@ -1,31 +1,20 @@
{
"textures": {
"rsside": "engineersdecor:block/pipe/straight_pipe_valve_side_redstone_texture",
"particle": "engineersdecor:block/pipe/straight_pipe_valve_side_redstone_texture",
"particle": "engineersdecor:block/pipe/straight_pipe_valve_side_texture",
"rsside": "engineersdecor:block/pipe/straight_pipe_valve_side_texture",
"rsend": "engineersdecor:block/pipe/straight_pipe_valve_side_redstone_cn_texture"
},
"elements": [
{
"from": [5, 5, 2],
"from": [5, 5, 0],
"to": [11, 11, 3],
"faces": {
"north": {"uv": [5, 5, 11, 11], "rotation": 90, "texture": "#rsend"},
"east": {"uv": [13, 5, 14, 11], "texture": "#rsside"},
"west": {"uv": [13, 5, 14, 11], "rotation": 180, "texture": "#rsside"},
"up": {"uv": [13, 5, 14, 11], "rotation": 270, "texture": "#rsside"},
"down": {"uv": [13, 5, 14, 11], "rotation": 90, "texture": "#rsside"}
}
},
{
"from": [4, 4, 0],
"to": [12, 12, 2],
"faces": {
"north": {"uv": [4, 4, 12, 12], "rotation": 90, "texture": "#rsend"},
"east": {"uv": [13, 4, 16, 12], "texture": "#rsside"},
"south": {"uv": [4, 4, 12, 12], "texture": "#rsend"},
"west": {"uv": [13, 4, 16, 12], "rotation": 180, "texture": "#rsside"},
"up": {"uv": [13, 4, 16, 12], "rotation": 270, "texture": "#rsside"},
"down": {"uv": [13, 4, 16, 12], "rotation": 90, "texture": "#rsside"}
"east": {"uv": [10, 5, 13, 11], "texture": "#rsside"},
"south": {"uv": [5, 5, 11, 11], "texture": "#rsend"},
"west": {"uv": [3, 5, 6, 11], "texture": "#rsside"},
"up": {"uv": [5, 0, 11, 3], "texture": "#rsside"},
"down": {"uv": [5, 13, 11, 16], "texture": "#rsside"}
}
}
],
@ -41,7 +30,7 @@
"scale": [0.4, 0.4, 0.4]
},
"ground": {
"translation": [0, 1.75, 0],
"translation": [0, 1.75, 0],
"scale": [0.2, 0.2, 0.2]
},
"gui": {

View file

@ -0,0 +1,18 @@
{
"name": "Labeled Crate",
"icon": "engineersdecor:labeled_crate",
"category": "crafting",
"sortnum": 5020,
"pages": [
{
"type": "spotlight",
"title": "Labeled Crate",
"item": "engineersdecor:labeled_crate",
"text": "A high capacity storage crate with space for a custom label at the front.$(br2)In addition to the 54 inventory slots, one slot at the bottom right can be used to define the object shown in the built-in Item Frame."
},
{
"type": "text",
"text": "$(o)§nQuick Move All Tweaks$()$(br)When using Quick-Move-All (aka shift-ctrl-left-click) on a slot for moving all identical items between the crate storage and the player inventory, the GUI will fill up existing stacks, and then try to insert further stacks into empty slots next to already existing stacks. If no appropriate locations are found, the stacks are moved into the player inventory, and as last option into the hotbar."
}
]
}

View file

@ -2,7 +2,7 @@
"name": "Small Electrical Furnace",
"icon": "engineersdecor:small_electrical_furnace",
"category": "crafting",
"sortnum": 5030,
"sortnum": 5040,
"pages": [
{
"type": "spotlight",

View file

@ -2,7 +2,7 @@
"name": "Small Laboratory Furnace",
"icon": "engineersdecor:small_lab_furnace",
"category": "crafting",
"sortnum": 5020,
"sortnum": 5030,
"pages": [
{
"type": "spotlight",

View file

@ -2,7 +2,7 @@
"name": "Mineral Melting Furnace",
"icon": "engineersdecor:small_mineral_smelter",
"category": "crafting",
"sortnum": 5040,
"sortnum": 5050,
"pages": [
{
"type": "spotlight",

View file

@ -19,7 +19,7 @@
"key": {
"D": { "item": "minecraft:dropper" },
"P": { "tag" : "forge:plates/iron" },
"W": { "item": "forge:treated_wood" }
"W": { "tag" : "forge:treated_wood" }
},
"result": {
"item": "engineersdecor:factory_dropper",

View file

@ -6,20 +6,19 @@
{
"type": "engineersdecor:optional",
"result": "engineersdecor:panzerglass_block",
"required": ["#forge:glass", "#forge:rods/steel", "#forge:gems/diamond"]
"required": ["#forge:glass", "#forge:rods/iron"]
}
],
"recipe": {
"type": "minecraft:crafting_shaped",
"pattern": [
"SGS",
"GDG",
"GSG",
"SGS"
],
"key": {
"G": { "tag": "forge:glass" },
"S": { "tag": "forge:rods/steel" },
"D": { "tag": "forge:gems/diamond" }
"S": { "tag": "forge:rods/iron" }
},
"result": {
"item": "engineersdecor:panzerglass_block",

View file

@ -17,7 +17,7 @@
"PPP"
],
"key": {
"F": { "tag" : "minecraft:furnace" },
"F": { "item": "minecraft:furnace" },
"C": { "item": "immersiveengineering:connector_lv" },
"H": { "item": "immersiveengineering:conveyor_basic" },
"P": { "tag" : "forge:plates/iron" }

View file

@ -1,5 +1,6 @@
// @file build.gradle
// Engineer's decor mod gradle build relay (mc1.15.1)
import net.minecraftforge.gradle.common.task.SignJar
buildscript {
repositories {
maven { url = 'https://files.minecraftforge.net/maven' }
@ -14,7 +15,7 @@ apply plugin: 'net.minecraftforge.gradle'
apply plugin: 'eclipse'
apply plugin: 'maven-publish'
sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8'
//-----------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------------------------
version = "${version_engineersdecor}"
group = "wile.engineersdecor"
archivesBaseName = "engineersdecor-${version_minecraft}"
@ -90,6 +91,29 @@ jar {
def reobfFile = file("$buildDir/reobfJar/output.jar")
def reobfArtifact = artifacts.add('default', reobfFile) { type 'jar'; builtBy 'reobfJar' }
def signing = { ->
def sp = new Properties()
sp.keystore_file = project.keystore_file
sp.keystore_alias = project.keystore_alias
sp.keystore_pass = project.keystore_pass
sp.keystore_keypass = project.keystore_keypass
sp.fingerprint_sha1 = project.fingerprint_sha1
if(file("signing.properties").exists()) file("signing.properties").withInputStream { sp.load(it) }
return sp
}();
task signJar(type: SignJar, dependsOn: jar) {
onlyIf { signing.hasProperty("keystore_file") }
if(signing.hasProperty("keystore_file")) {
keyStore = signing.getProperty("keystore_file")
alias = signing.getProperty("keystore_alias")
storePass = signing.getProperty("keystore_pass")
keyPass = signing.getProperty("keystore_keypass")
inputFile = jar.archivePath
outputFile = jar.archivePath
}
}
build.dependsOn signJar
publishing {
publications { mavenJava(MavenPublication) { artifact reobfArtifact } }
repositories { maven { url "file:///${project.projectDir}/mcmodsrepo" } }

View file

@ -2,7 +2,7 @@
org.gradle.daemon=false
org.gradle.jvmargs=-Xmx8G
version_minecraft=1.15.2
version_forge_minecraft=1.15.2-31.1.25
version_forge_minecraft=1.15.2-31.1.27
version_fml_mappings=20200225-1.15.1
version_jei=1.15.2:6.0.0.2
version_engineersdecor=1.0.20-b2
version_engineersdecor=1.0.20-b3

View file

@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.3-bin.zip

View file

@ -11,6 +11,12 @@ Mod sources for Minecraft version 1.15.1.
## Version history
~ v1.0.20-b3 [M] Labeled Crate: GUI quick-move-all (ctrl-shift click) smart move tweaked, Manual page added.
[F] Fixed IE ingredients based default recipes for Factory Dropper and Small Electrical Furnace.
[M] Factory Hopper: GUI quick-move-all added.
[M] Code structure, simplifications, cap invalidation fixes.
[M] Valves: Removed performance caching for testing purposes.
- v1.0.20-b2 [A] Added Labeled Crate (storage crate with built-in item frame).
- v1.0.20-b1 [A] Electrical Furnace: Added four-position speed switch (off, 100%, 150%, 200%), power consumption

View file

@ -444,7 +444,7 @@ public class ModContent
}
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "small_block_breaker"));
public static final BlockDecorHopper FACTORY_HOPPER = (BlockDecorHopper)(new BlockDecorHopper(
public static final BlockDecorHopper.DecorHopperBlock FACTORY_HOPPER = (BlockDecorHopper.DecorHopperBlock)(new BlockDecorHopper.DecorHopperBlock(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL).notSolid(),()->{
final AxisAlignedBB[] down_aabbs = new AxisAlignedBB[]{
@ -536,7 +536,7 @@ public class ModContent
}
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "small_tree_cutter"));
public static final BlockDecorPipeValve STRAIGHT_CHECK_VALVE = (BlockDecorPipeValve)(new BlockDecorPipeValve(
public static final BlockDecorPipeValve.DecorPipeValveBlock STRAIGHT_CHECK_VALVE = (BlockDecorPipeValve.DecorPipeValveBlock)(new BlockDecorPipeValve.DecorPipeValveBlock(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT|BlockDecor.CFG_FLIP_PLACEMENT_SHIFTCLICK,
BlockDecorPipeValve.CFG_CHECK_VALVE,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL).notSolid(),
@ -548,7 +548,7 @@ public class ModContent
}
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "straight_pipe_valve"));
public static final BlockDecorPipeValve STRAIGHT_REDSTONE_VALVE = (BlockDecorPipeValve)(new BlockDecorPipeValve(
public static final BlockDecorPipeValve.DecorPipeValveBlock STRAIGHT_REDSTONE_VALVE = (BlockDecorPipeValve.DecorPipeValveBlock)(new BlockDecorPipeValve.DecorPipeValveBlock(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT|BlockDecor.CFG_FLIP_PLACEMENT_SHIFTCLICK,
BlockDecorPipeValve.CFG_REDSTONE_CONTROLLED_VALVE,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL).notSolid(),
@ -560,7 +560,7 @@ public class ModContent
}
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "straight_pipe_valve_redstone"));
public static final BlockDecorPipeValve STRAIGHT_REDSTONE_ANALOG_VALVE = (BlockDecorPipeValve)(new BlockDecorPipeValve(
public static final BlockDecorPipeValve.DecorPipeValveBlock STRAIGHT_REDSTONE_ANALOG_VALVE = (BlockDecorPipeValve.DecorPipeValveBlock)(new BlockDecorPipeValve.DecorPipeValveBlock(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT|BlockDecor.CFG_FLIP_PLACEMENT_SHIFTCLICK,
BlockDecorPipeValve.CFG_REDSTONE_CONTROLLED_VALVE|BlockDecorPipeValve.CFG_ANALOG_VALVE,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL).notSolid(),
@ -792,7 +792,7 @@ public class ModContent
.setRegistryName(ModEngineersDecor.MODID, "te_small_block_breaker");
public static final TileEntityType<?> TET_FACTORY_HOPPER = TileEntityType.Builder
.create(BlockDecorHopper.BTileEntity::new, FACTORY_HOPPER)
.create(BlockDecorHopper.DecorHopperTileEntity::new, FACTORY_HOPPER)
.build(null)
.setRegistryName(ModEngineersDecor.MODID, "te_factory_hopper");
@ -802,7 +802,7 @@ public class ModContent
.setRegistryName(ModEngineersDecor.MODID, "te_small_waste_incinerator");
public static final TileEntityType<?> TET_STRAIGHT_PIPE_VALVE = TileEntityType.Builder
.create(BlockDecorPipeValve.BTileEntity::new, STRAIGHT_CHECK_VALVE, STRAIGHT_REDSTONE_VALVE, STRAIGHT_REDSTONE_ANALOG_VALVE)
.create(BlockDecorPipeValve.DecorPipeValveTileEntity::new, STRAIGHT_CHECK_VALVE, STRAIGHT_REDSTONE_VALVE, STRAIGHT_REDSTONE_ANALOG_VALVE)
.build(null)
.setRegistryName(ModEngineersDecor.MODID, "te_pipe_valve");
@ -837,7 +837,7 @@ public class ModContent
.setRegistryName(ModEngineersDecor.MODID, "te_small_tree_cutter");
public static final TileEntityType<?> TET_TEST_BLOCK = TileEntityType.Builder
.create(BlockDecorPipeValve.BTileEntity::new, TEST_BLOCK)
.create(BlockDecorPipeValve.DecorPipeValveTileEntity::new, TEST_BLOCK)
.build(null)
.setRegistryName(ModEngineersDecor.MODID, "te_test_block");
@ -887,7 +887,7 @@ public class ModContent
public static final ContainerType<BlockDecorCraftingTable.CraftingTableContainer> CT_TREATED_WOOD_CRAFTING_TABLE;
public static final ContainerType<BlockDecorDropper.BContainer> CT_FACTORY_DROPPER;
public static final ContainerType<BlockDecorPlacer.BContainer> CT_FACTORY_PLACER;
public static final ContainerType<BlockDecorHopper.BContainer> CT_FACTORY_HOPPER;
public static final ContainerType<BlockDecorHopper.DecorHopperContainer> CT_FACTORY_HOPPER;
public static final ContainerType<BlockDecorFurnace.BContainer> CT_SMALL_LAB_FURNACE;
public static final ContainerType<BlockDecorFurnaceElectrical.BContainer> CT_SMALL_ELECTRICAL_FURNACE;
public static final ContainerType<BlockDecorWasteIncinerator.BContainer> CT_WASTE_INCINERATOR;
@ -900,7 +900,7 @@ public class ModContent
CT_FACTORY_DROPPER.setRegistryName(ModEngineersDecor.MODID,"ct_factory_dropper");
CT_FACTORY_PLACER = (new ContainerType<BlockDecorPlacer.BContainer>(BlockDecorPlacer.BContainer::new));
CT_FACTORY_PLACER.setRegistryName(ModEngineersDecor.MODID,"ct_factory_placer");
CT_FACTORY_HOPPER = (new ContainerType<BlockDecorHopper.BContainer>(BlockDecorHopper.BContainer::new));
CT_FACTORY_HOPPER = (new ContainerType<BlockDecorHopper.DecorHopperContainer>(BlockDecorHopper.DecorHopperContainer::new));
CT_FACTORY_HOPPER.setRegistryName(ModEngineersDecor.MODID,"ct_factory_hopper");
CT_SMALL_LAB_FURNACE = (new ContainerType<BlockDecorFurnace.BContainer>(BlockDecorFurnace.BContainer::new));
CT_SMALL_LAB_FURNACE.setRegistryName(ModEngineersDecor.MODID,"ct_small_lab_furnace");
@ -1002,7 +1002,7 @@ public class ModContent
ScreenManager.registerFactory(CT_LABELED_CRATE, BlockDecorLabeledCrate.LabeledCrateGui::new);
ScreenManager.registerFactory(CT_FACTORY_DROPPER, BlockDecorDropper.BGui::new);
ScreenManager.registerFactory(CT_FACTORY_PLACER, BlockDecorPlacer.BGui::new);
ScreenManager.registerFactory(CT_FACTORY_HOPPER, BlockDecorHopper.BGui::new);
ScreenManager.registerFactory(CT_FACTORY_HOPPER, BlockDecorHopper.DecorHopperGui::new);
ScreenManager.registerFactory(CT_SMALL_LAB_FURNACE, BlockDecorFurnace.BGui::new);
ScreenManager.registerFactory(CT_SMALL_ELECTRICAL_FURNACE, BlockDecorFurnaceElectrical.BGui::new);
ScreenManager.registerFactory(CT_WASTE_INCINERATOR, BlockDecorWasteIncinerator.BGui::new);

View file

@ -189,6 +189,13 @@ public class BlockDecorBreaker extends BlockDecor.HorizontalWaterLoggable implem
public CompoundNBT write(CompoundNBT nbt)
{ super.write(nbt); writenbt(nbt); return nbt; }
@Override
public void remove()
{
super.remove();
energy_handler_.invalidate();
}
// IEnergyStorage ----------------------------------------------------------------------------
protected LazyOptional<IEnergyStorage> energy_handler_ = LazyOptional.of(() -> (IEnergyStorage)this);
@ -226,11 +233,7 @@ public class BlockDecorBreaker extends BlockDecor.HorizontalWaterLoggable implem
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing)
{
if(!this.removed && (facing != null)) {
if(capability== CapabilityEnergy.ENERGY) {
return energy_handler_.cast();
}
}
if(capability == CapabilityEnergy.ENERGY) return energy_handler_.cast();
return super.getCapability(capability, facing);
}

View file

@ -53,6 +53,7 @@ import net.minecraftforge.items.IItemHandler;
import com.mojang.blaze3d.systems.RenderSystem;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@ -305,6 +306,13 @@ public class BlockDecorDropper extends BlockDecor.Directed implements IDecorBloc
public CompoundNBT write(CompoundNBT nbt)
{ super.write(nbt); writenbt(nbt, false); return nbt; }
@Override
public void remove()
{
super.remove();
Arrays.stream(item_handlers).forEach(LazyOptional::invalidate);
}
// INamable ----------------------------------------------------------------------------------------------
@Override
@ -462,9 +470,7 @@ public class BlockDecorDropper extends BlockDecor.Directed implements IDecorBloc
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing)
{
if(!this.removed && (facing != null)) {
if(capability==CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return item_handlers[0].cast();
}
if(capability==CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return item_handlers[0].cast();
return super.getCapability(capability, facing);
}

View file

@ -189,6 +189,13 @@ public class BlockDecorFluidFunnel extends BlockDecor implements IDecorBlock
public CompoundNBT write(CompoundNBT nbt)
{ super.write(nbt); writenbt(nbt); return nbt; }
@Override
public void remove()
{
super.remove();
fluid_handler_.invalidate();
}
// ICapabilityProvider / Output flow handler ----------------------------------------------------------
private static class OutputFluidHandler implements IFluidHandler

View file

@ -312,6 +312,14 @@ public class BlockDecorFurnace extends BlockDecor.Horizontal implements IDecorBl
public CompoundNBT write(CompoundNBT nbt)
{ super.write(nbt); writenbt(nbt); return nbt; }
@Override
public void remove()
{
super.remove();
Arrays.stream(item_handlers).forEach(LazyOptional::invalidate);
energy_handler_.invalidate();
}
// INamedContainerProvider / INameable ------------------------------------------------------
@Override
@ -510,14 +518,12 @@ public class BlockDecorFurnace extends BlockDecor.Horizontal implements IDecorBl
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing)
{
if(!this.removed && (facing != null)) {
if(capability==CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
if(facing == Direction.UP) return item_handlers[0].cast();
if(facing == Direction.DOWN) return item_handlers[1].cast();
return item_handlers[2].cast();
} else if(capability== CapabilityEnergy.ENERGY) {
return energy_handler_.cast();
}
if(capability==CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
if(facing == Direction.UP) return item_handlers[0].cast();
if(facing == Direction.DOWN) return item_handlers[1].cast();
return item_handlers[2].cast();
} else if(capability== CapabilityEnergy.ENERGY) {
return energy_handler_.cast();
}
return super.getCapability(capability, facing);
}

View file

@ -54,6 +54,7 @@ import net.minecraftforge.items.ItemHandlerHelper;
import com.mojang.blaze3d.systems.RenderSystem;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Arrays;
import java.util.Random;
@ -219,6 +220,15 @@ public class BlockDecorFurnaceElectrical extends BlockDecorFurnace implements ID
public CompoundNBT write(CompoundNBT nbt)
{ super.write(nbt); writenbt(nbt); return nbt; }
@Override
public void remove()
{
super.remove();
Arrays.stream(item_handlers).forEach(LazyOptional::invalidate);
item_handler_.invalidate();
energy_handler_.invalidate();
}
// INameable -------------------------------------------------------------------------------
@Override
@ -442,10 +452,8 @@ public class BlockDecorFurnaceElectrical extends BlockDecorFurnace implements ID
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing)
{
if(!this.removed && (facing != null)) {
if(capability==CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return item_handler_.cast();
if(capability== CapabilityEnergy.ENERGY) return energy_handler_.cast();
}
if(capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return item_handler_.cast();
if(capability == CapabilityEnergy.ENERGY) return energy_handler_.cast();
return super.getCapability(capability, facing);
}

View file

@ -10,8 +10,10 @@ package wile.engineersdecor.blocks;
import wile.engineersdecor.ModContent;
import wile.engineersdecor.ModEngineersDecor;
import wile.engineersdecor.libmc.detail.Auxiliaries;
import wile.engineersdecor.libmc.detail.Inventories;
import wile.engineersdecor.libmc.detail.Networking;
import wile.engineersdecor.libmc.detail.Inventories.SlotRange;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.World;
import net.minecraft.block.Block;
@ -32,6 +34,7 @@ import net.minecraft.inventory.*;
import net.minecraft.inventory.container.INamedContainerProvider;
import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.container.Slot;
import net.minecraft.inventory.container.ClickType;
import net.minecraft.util.*;
import net.minecraft.util.math.*;
import net.minecraft.util.math.shapes.VoxelShape;
@ -51,132 +54,145 @@ import net.minecraftforge.items.IItemHandler;
import com.mojang.blaze3d.systems.RenderSystem;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Supplier;
public class BlockDecorHopper extends BlockDecor.Directed implements IDecorBlock
public class BlockDecorHopper
{
public BlockDecorHopper(long config, Block.Properties builder, final Supplier<ArrayList<VoxelShape>> shape_supplier)
{ super(config, builder, shape_supplier); }
@Override
public VoxelShape getCollisionShape(BlockState state, IBlockReader world, BlockPos pos, ISelectionContext context)
{ return VoxelShapes.fullCube(); }
@Override
@SuppressWarnings("deprecation")
public boolean hasComparatorInputOverride(BlockState state)
{ return true; }
@Override
@SuppressWarnings("deprecation")
public int getComparatorInputOverride(BlockState blockState, World world, BlockPos pos)
{ return Container.calcRedstone(world.getTileEntity(pos)); }
@Override
public boolean hasTileEntity(BlockState state)
{ return true; }
@Override
@Nullable
public TileEntity createTileEntity(BlockState state, IBlockReader world)
{ return new BlockDecorHopper.BTileEntity(); }
@Override
public void onBlockPlacedBy(World world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack)
public static void on_config(int cooldown_ticks)
{
if(world.isRemote) return;
if((!stack.hasTag()) || (!stack.getTag().contains("tedata"))) return;
CompoundNBT te_nbt = stack.getTag().getCompound("tedata");
if(te_nbt.isEmpty()) return;
final TileEntity te = world.getTileEntity(pos);
if(!(te instanceof BTileEntity)) return;
((BTileEntity)te).readnbt(te_nbt, false);
((BTileEntity)te).reset_rtstate();
((BTileEntity)te).markDirty();
// ModEngineersDecor.logger.info("Config factory hopper:");
}
@Override
public boolean hasDynamicDropList()
{ return true; }
//--------------------------------------------------------------------------------------------------------------------
// Block
//--------------------------------------------------------------------------------------------------------------------
@Override
public List<ItemStack> dropList(BlockState state, World world, BlockPos pos, boolean explosion)
public static class DecorHopperBlock extends BlockDecor.Directed implements IDecorBlock
{
final List<ItemStack> stacks = new ArrayList<ItemStack>();
if(world.isRemote) return stacks;
final TileEntity te = world.getTileEntity(pos);
if(!(te instanceof BTileEntity)) return stacks;
if(!explosion) {
ItemStack stack = new ItemStack(this, 1);
CompoundNBT te_nbt = ((BTileEntity)te).clear_getnbt();
if(!te_nbt.isEmpty()) {
CompoundNBT nbt = new CompoundNBT();
nbt.put("tedata", te_nbt);
stack.setTag(nbt);
}
stacks.add(stack);
} else {
for(ItemStack stack: ((BTileEntity)te).stacks_) {
if(!stack.isEmpty()) stacks.add(stack);
}
((BTileEntity)te).reset_rtstate();
public DecorHopperBlock(long config, Block.Properties builder, final Supplier<ArrayList<VoxelShape>> shape_supplier)
{ super(config, builder, shape_supplier); }
@Override
public VoxelShape getCollisionShape(BlockState state, IBlockReader world, BlockPos pos, ISelectionContext context)
{ return VoxelShapes.fullCube(); }
@Override
@SuppressWarnings("deprecation")
public boolean hasComparatorInputOverride(BlockState state)
{ return true; }
@Override
@SuppressWarnings("deprecation")
public int getComparatorInputOverride(BlockState blockState, World world, BlockPos pos)
{ return Container.calcRedstone(world.getTileEntity(pos)); }
@Override
public boolean hasTileEntity(BlockState state)
{ return true; }
@Override
@Nullable
public TileEntity createTileEntity(BlockState state, IBlockReader world)
{ return new DecorHopperTileEntity(); }
@Override
public void onBlockPlacedBy(World world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack)
{
if(world.isRemote) return;
if((!stack.hasTag()) || (!stack.getTag().contains("tedata"))) return;
CompoundNBT te_nbt = stack.getTag().getCompound("tedata");
if(te_nbt.isEmpty()) return;
final TileEntity te = world.getTileEntity(pos);
if(!(te instanceof DecorHopperTileEntity)) return;
((DecorHopperTileEntity)te).readnbt(te_nbt, false);
((DecorHopperTileEntity)te).reset_rtstate();
((DecorHopperTileEntity)te).markDirty();
}
return stacks;
@Override
public boolean hasDynamicDropList()
{ return true; }
@Override
public List<ItemStack> dropList(BlockState state, World world, BlockPos pos, boolean explosion)
{
final List<ItemStack> stacks = new ArrayList<ItemStack>();
if(world.isRemote) return stacks;
final TileEntity te = world.getTileEntity(pos);
if(!(te instanceof DecorHopperTileEntity)) return stacks;
if(!explosion) {
ItemStack stack = new ItemStack(this, 1);
CompoundNBT te_nbt = ((DecorHopperTileEntity)te).clear_getnbt();
if(!te_nbt.isEmpty()) {
CompoundNBT nbt = new CompoundNBT();
nbt.put("tedata", te_nbt);
stack.setTag(nbt);
}
stacks.add(stack);
} else {
for(ItemStack stack: ((DecorHopperTileEntity)te).stacks_) {
if(!stack.isEmpty()) stacks.add(stack);
}
((DecorHopperTileEntity)te).reset_rtstate();
}
return stacks;
}
@Override
public ActionResultType onBlockActivated(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockRayTraceResult rayTraceResult)
{
if(world.isRemote) return ActionResultType.SUCCESS;
final TileEntity te = world.getTileEntity(pos);
if(!(te instanceof DecorHopperTileEntity)) return ActionResultType.FAIL;
if((!(player instanceof ServerPlayerEntity) && (!(player instanceof FakePlayer)))) return ActionResultType.FAIL;
NetworkHooks.openGui((ServerPlayerEntity)player,(INamedContainerProvider)te);
return ActionResultType.SUCCESS;
}
@Override
@SuppressWarnings("deprecation")
public void neighborChanged(BlockState state, World world, BlockPos pos, Block block, BlockPos fromPos, boolean unused)
{
if(!(world instanceof World) || (((World) world).isRemote)) return;
TileEntity te = world.getTileEntity(pos);
if(!(te instanceof DecorHopperTileEntity)) return;
((DecorHopperTileEntity)te).block_updated();
}
@Override
public void onFallenUpon(World world, BlockPos pos, Entity entity, float fallDistance)
{
super.onFallenUpon(world, pos, entity, fallDistance);
if(!(entity instanceof ItemEntity)) return;
TileEntity te = world.getTileEntity(pos);
if(!(te instanceof DecorHopperTileEntity)) return;
((DecorHopperTileEntity)te).collection_timer_ = 0;
}
@Override
@SuppressWarnings("deprecation")
public boolean canProvidePower(BlockState state)
{ return true; }
@Override
@SuppressWarnings("deprecation")
public int getWeakPower(BlockState blockState, IBlockReader blockAccess, BlockPos pos, Direction side)
{ return 0; }
@Override
@SuppressWarnings("deprecation")
public int getStrongPower(BlockState blockState, IBlockReader blockAccess, BlockPos pos, Direction side)
{ return 0; }
}
@Override
public ActionResultType onBlockActivated(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockRayTraceResult rayTraceResult)
{
if(world.isRemote) return ActionResultType.SUCCESS;
final TileEntity te = world.getTileEntity(pos);
if(!(te instanceof BTileEntity)) return ActionResultType.FAIL;
if((!(player instanceof ServerPlayerEntity) && (!(player instanceof FakePlayer)))) return ActionResultType.FAIL;
NetworkHooks.openGui((ServerPlayerEntity)player,(INamedContainerProvider)te);
return ActionResultType.SUCCESS;
}
@Override
@SuppressWarnings("deprecation")
public void neighborChanged(BlockState state, World world, BlockPos pos, Block block, BlockPos fromPos, boolean unused)
{
if(!(world instanceof World) || (((World) world).isRemote)) return;
TileEntity te = world.getTileEntity(pos);
if(!(te instanceof BTileEntity)) return;
((BTileEntity)te).block_updated();
}
@Override
public void onFallenUpon(World world, BlockPos pos, Entity entity, float fallDistance)
{
super.onFallenUpon(world, pos, entity, fallDistance);
if(!(entity instanceof ItemEntity)) return;
TileEntity te = world.getTileEntity(pos);
if(!(te instanceof BTileEntity)) return;
((BTileEntity)te).collection_timer_ = 0;
}
@Override
@SuppressWarnings("deprecation")
public boolean canProvidePower(BlockState state)
{ return true; }
@Override
@SuppressWarnings("deprecation")
public int getWeakPower(BlockState blockState, IBlockReader blockAccess, BlockPos pos, Direction side)
{ return 0; }
@Override
@SuppressWarnings("deprecation")
public int getStrongPower(BlockState blockState, IBlockReader blockAccess, BlockPos pos, Direction side)
{ return 0; }
//--------------------------------------------------------------------------------------------------------------------
// Tile entity
//--------------------------------------------------------------------------------------------------------------------
public static class BTileEntity extends TileEntity implements ITickableTileEntity, INameable, IInventory, INamedContainerProvider, ISidedInventory
public static class DecorHopperTileEntity extends TileEntity implements ITickableTileEntity, INameable, IInventory, INamedContainerProvider, ISidedInventory
{
public static final int NUM_OF_FIELDS = 7;
public static final int TICK_INTERVAL = 10;
@ -201,19 +217,14 @@ public class BlockDecorHopper extends BlockDecor.Directed implements IDecorBlock
private int tick_timer_ = 0;
protected NonNullList<ItemStack> stacks_;
public static void on_config(int cooldown_ticks)
{
// ModEngineersDecor.logger.info("Config factory hopper:");
}
public BTileEntity()
public DecorHopperTileEntity()
{
this(ModContent.TET_FACTORY_HOPPER);
stacks_ = NonNullList.<ItemStack>withSize(NUM_OF_SLOTS, ItemStack.EMPTY);
reset_rtstate();
}
public BTileEntity(TileEntityType<?> te_type)
public DecorHopperTileEntity(TileEntityType<?> te_type)
{
super(te_type);
stacks_ = NonNullList.<ItemStack>withSize(NUM_OF_SLOTS, ItemStack.EMPTY);
@ -285,6 +296,13 @@ public class BlockDecorHopper extends BlockDecor.Directed implements IDecorBlock
public CompoundNBT write(CompoundNBT nbt)
{ super.write(nbt); writenbt(nbt, false); return nbt; }
@Override
public void remove()
{
super.remove();
Arrays.stream(item_handlers).forEach(LazyOptional::invalidate);
}
// INamable ----------------------------------------------------------------------------------------------
@Override
@ -307,7 +325,7 @@ public class BlockDecorHopper extends BlockDecor.Directed implements IDecorBlock
@Override
public Container createMenu(int id, PlayerInventory inventory, PlayerEntity player )
{ return new BContainer(id, inventory, this, IWorldPosCallable.of(world, pos), fields); }
{ return new DecorHopperContainer(id, inventory, this, IWorldPosCallable.of(world, pos), fields); }
// IInventory --------------------------------------------------------------------------------------------
@ -370,7 +388,7 @@ public class BlockDecorHopper extends BlockDecor.Directed implements IDecorBlock
// Fields -----------------------------------------------------------------------------------------------
protected final IIntArray fields = new IntArray(BTileEntity.NUM_OF_FIELDS)
protected final IIntArray fields = new IntArray(DecorHopperTileEntity.NUM_OF_FIELDS)
{
@Override
public int get(int id)
@ -428,9 +446,7 @@ public class BlockDecorHopper extends BlockDecor.Directed implements IDecorBlock
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing)
{
if(!this.removed && (facing != null)) {
if(capability==CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return item_handlers[0].cast();
}
if(capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return item_handlers[0].cast();
return super.getCapability(capability, facing);
}
@ -489,8 +505,8 @@ public class BlockDecorHopper extends BlockDecor.Directed implements IDecorBlock
if(te instanceof HopperTileEntity) {
Direction f = world.getBlockState(pos.offset(facing)).get(HopperBlock.FACING);
if(f==facing.getOpposite()) return false; // no back transfer
} else if(te instanceof BTileEntity) {
Direction f = world.getBlockState(pos.offset(facing)).get(FACING);
} else if(te instanceof DecorHopperTileEntity) {
Direction f = world.getBlockState(pos.offset(facing)).get(DecorHopperBlock.FACING);
if(f==facing.getOpposite()) return false;
}
ItemStack insert_stack = current_stack.copy();
@ -608,7 +624,7 @@ public class BlockDecorHopper extends BlockDecor.Directed implements IDecorBlock
boolean trigger = (rssignal && ((block_power_updated_) || (!pulse_mode)));
final BlockState state = world.getBlockState(pos);
if(state == null) { block_power_signal_= false; return; }
final Direction hopper_facing = state.get(FACING);
final Direction hopper_facing = state.get(DecorHopperBlock.FACING);
// Trigger edge detection for next cycle
{
boolean tr = world.isBlockPowered(pos);
@ -648,9 +664,16 @@ public class BlockDecorHopper extends BlockDecor.Directed implements IDecorBlock
// container
//--------------------------------------------------------------------------------------------------------------------
public static class BContainer extends Container implements Networking.INetworkSynchronisableContainer
public static class DecorHopperContainer extends Container implements Networking.INetworkSynchronisableContainer
{
private static final int PLAYER_INV_START_SLOTNO = BTileEntity.NUM_OF_SLOTS;
private static final int PLAYER_INV_START_SLOTNO = DecorHopperTileEntity.NUM_OF_SLOTS;
private static final int NUM_OF_CONTAINER_SLOTS = DecorHopperTileEntity.NUM_OF_SLOTS + 36;
protected static final int STORAGE_SLOT_BEGIN = 0;
protected static final int STORAGE_SLOT_END = DecorHopperTileEntity.NUM_OF_SLOTS;
protected static final int PLAYER_SLOT_BEGIN = DecorHopperTileEntity.NUM_OF_SLOTS;
protected static final int PLAYER_SLOT_END = DecorHopperTileEntity.NUM_OF_SLOTS+36;
private final SlotRange player_inventory_slot_range;
private final SlotRange hopper_slot_range;
private final PlayerEntity player_;
private final IInventory inventory_;
private final IWorldPosCallable wpc_;
@ -658,16 +681,18 @@ public class BlockDecorHopper extends BlockDecor.Directed implements IDecorBlock
public final int field(int index) { return fields_.get(index); }
public BContainer(int cid, PlayerInventory player_inventory)
{ this(cid, player_inventory, new Inventory(BTileEntity.NUM_OF_SLOTS), IWorldPosCallable.DUMMY, new IntArray(BTileEntity.NUM_OF_FIELDS)); }
public DecorHopperContainer(int cid, PlayerInventory player_inventory)
{ this(cid, player_inventory, new Inventory(DecorHopperTileEntity.NUM_OF_SLOTS), IWorldPosCallable.DUMMY, new IntArray(DecorHopperTileEntity.NUM_OF_FIELDS)); }
private BContainer(int cid, PlayerInventory player_inventory, IInventory block_inventory, IWorldPosCallable wpc, IIntArray fields)
private DecorHopperContainer(int cid, PlayerInventory player_inventory, IInventory block_inventory, IWorldPosCallable wpc, IIntArray fields)
{
super(ModContent.CT_FACTORY_HOPPER, cid);
fields_ = fields;
wpc_ = wpc;
player_ = player_inventory.player;
inventory_ = block_inventory;
hopper_slot_range = new SlotRange(inventory_, 0, DecorHopperTileEntity.NUM_OF_SLOTS);
player_inventory_slot_range = new SlotRange(player_inventory, 0, 36);
int i=-1;
// input slots (stacks 0 to 17)
for(int y=0; y<3; ++y) {
@ -704,7 +729,7 @@ public class BlockDecorHopper extends BlockDecor.Directed implements IDecorBlock
if(!mergeItemStack(slot_stack, PLAYER_INV_START_SLOTNO, PLAYER_INV_START_SLOTNO+36, false)) return ItemStack.EMPTY;
} else if((index >= PLAYER_INV_START_SLOTNO) && (index <= PLAYER_INV_START_SLOTNO+36)) {
// Player slot
if(!mergeItemStack(slot_stack, 0, BTileEntity.NUM_OF_SLOTS, false)) return ItemStack.EMPTY;
if(!mergeItemStack(slot_stack, 0, DecorHopperTileEntity.NUM_OF_SLOTS, false)) return ItemStack.EMPTY;
} else {
// invalid slot
return ItemStack.EMPTY;
@ -733,6 +758,13 @@ public class BlockDecorHopper extends BlockDecor.Directed implements IDecorBlock
Networking.PacketContainerSyncClientToServer.sendToServer(windowId, nbt);
}
@OnlyIn(Dist.CLIENT)
public void onGuiAction(String message, CompoundNBT nbt)
{
nbt.putString("action", message);
Networking.PacketContainerSyncClientToServer.sendToServer(windowId, nbt);
}
@Override
public void onServerPacketReceived(int windowId, CompoundNBT nbt)
{}
@ -740,13 +772,56 @@ public class BlockDecorHopper extends BlockDecor.Directed implements IDecorBlock
@Override
public void onClientPacketReceived(int windowId, PlayerEntity player, CompoundNBT nbt)
{
if(!(inventory_ instanceof BTileEntity)) return;
BTileEntity te = (BTileEntity)inventory_;
if(nbt.contains("xsize")) te.transfer_count_ = MathHelper.clamp(nbt.getInt("xsize"), 1, BTileEntity.MAX_TRANSFER_COUNT);
if(!(inventory_ instanceof DecorHopperTileEntity)) return;
DecorHopperTileEntity te = (DecorHopperTileEntity)inventory_;
if(nbt.contains("xsize")) te.transfer_count_ = MathHelper.clamp(nbt.getInt("xsize"), 1, DecorHopperTileEntity.MAX_TRANSFER_COUNT);
if(nbt.contains("period")) te.transfer_period_ = MathHelper.clamp(nbt.getInt("period"), 0, 100);
if(nbt.contains("range")) te.collection_range_ = MathHelper.clamp(nbt.getInt("range"), 0, BTileEntity.MAX_COLLECTION_RANGE);
if(nbt.contains("range")) te.collection_range_ = MathHelper.clamp(nbt.getInt("range"), 0, DecorHopperTileEntity.MAX_COLLECTION_RANGE);
if(nbt.contains("logic")) te.logic_ = nbt.getInt("logic");
if(nbt.contains("manual_trigger") && (nbt.getInt("manual_trigger")!=0)) { te.block_power_signal_=true; te.block_power_updated_=true; te.tick_timer_=1; }
if(nbt.contains("action")) {
boolean changed = false;
final int slotId = nbt.contains("slot") ? nbt.getInt("slot") : -1;
switch(nbt.getString("action")) {
case DecorHopperGui.QUICK_MOVE_ALL: {
if((slotId >= STORAGE_SLOT_BEGIN) && (slotId < STORAGE_SLOT_END) && (getSlot(slotId).getHasStack())) {
final Slot slot = getSlot(slotId);
ItemStack remaining = slot.getStack();
slot.putStack(ItemStack.EMPTY);
final ItemStack ref_stack = remaining.copy();
ref_stack.setCount(ref_stack.getMaxStackSize());
for(int i=hopper_slot_range.end_slot-hopper_slot_range.start_slot; (i>0) && (!remaining.isEmpty()); --i) {
remaining = player_inventory_slot_range.insert(remaining, false, 0, true, true);
if(!remaining.isEmpty()) break;
remaining = hopper_slot_range.extract(ref_stack);
}
if(!remaining.isEmpty()) {
slot.putStack(remaining); // put back
}
} else if((slotId >= PLAYER_SLOT_BEGIN) && (slotId < PLAYER_SLOT_END) && (getSlot(slotId).getHasStack())) {
final Slot slot = getSlot(slotId);
ItemStack remaining = slot.getStack();
slot.putStack(ItemStack.EMPTY);
final ItemStack ref_stack = remaining.copy();
ref_stack.setCount(ref_stack.getMaxStackSize());
for(int i=player_inventory_slot_range.end_slot-player_inventory_slot_range.start_slot; (i>0) && (!remaining.isEmpty()); --i) {
remaining = hopper_slot_range.insert(remaining, false, 0, false, true);
if(!remaining.isEmpty()) break;
remaining = player_inventory_slot_range.extract(ref_stack);
}
if(!remaining.isEmpty()) {
slot.putStack(remaining); // put back
}
}
changed = true;
} break;
}
if(changed) {
inventory_.markDirty();
player.inventory.markDirty();
detectAndSendChanges();
}
}
te.markDirty();
}
@ -757,11 +832,12 @@ public class BlockDecorHopper extends BlockDecor.Directed implements IDecorBlock
//--------------------------------------------------------------------------------------------------------------------
@OnlyIn(Dist.CLIENT)
public static class BGui extends ContainerScreen<BContainer>
public static class DecorHopperGui extends ContainerScreen<DecorHopperContainer>
{
protected static final String QUICK_MOVE_ALL = "quick-move-all";
protected final PlayerEntity player_;
public BGui(BContainer container, PlayerInventory player_inventory, ITextComponent title)
public DecorHopperGui(DecorHopperContainer container, PlayerInventory player_inventory, ITextComponent title)
{ super(container, player_inventory, title); this.player_ = player_inventory.player; }
@Override
@ -776,10 +852,22 @@ public class BlockDecorHopper extends BlockDecor.Directed implements IDecorBlock
renderHoveredToolTip(mouseX, mouseY);
}
@Override
protected void handleMouseClick(Slot slot, int slotId, int button, ClickType type)
{
if((type == ClickType.QUICK_MOVE) && (slot!=null) && slot.getHasStack() && Auxiliaries.isShiftDown() && Auxiliaries.isCtrlDown()) {
CompoundNBT nbt = new CompoundNBT();
nbt.putInt("slot", slotId);
container.onGuiAction(QUICK_MOVE_ALL, nbt);
} else {
super.handleMouseClick(slot, slotId, button, type);
}
}
@Override
public boolean mouseClicked(double mouseX, double mouseY, int mouseButton)
{
BContainer container = (BContainer)getContainer();
DecorHopperContainer container = (DecorHopperContainer)getContainer();
int mx = (int)(mouseX - getGuiLeft() + .5), my = (int)(mouseY - getGuiTop() + .5);
if((!isPointInRegion(126, 1, 49, 60, mouseX, mouseY))) {
return super.mouseClicked(mouseX, mouseY, mouseButton);
@ -790,8 +878,8 @@ public class BlockDecorHopper extends BlockDecor.Directed implements IDecorBlock
} else if(range >= 34) {
range = container.field(0) + 1; // +
} else {
range = (int)(0.5 + ((((double)BTileEntity.MAX_COLLECTION_RANGE) * range)/34)); // slider
range = MathHelper.clamp(range, 0, BTileEntity.MAX_COLLECTION_RANGE);
range = (int)(0.5 + ((((double)DecorHopperTileEntity.MAX_COLLECTION_RANGE) * range)/34)); // slider
range = MathHelper.clamp(range, 0, DecorHopperTileEntity.MAX_COLLECTION_RANGE);
}
container.onGuiAction("range", range);
} else if(isPointInRegion(128, 21, 44, 10, mouseX, mouseY)) {
@ -812,15 +900,15 @@ public class BlockDecorHopper extends BlockDecor.Directed implements IDecorBlock
} else if(ndrop >= 34) {
ndrop = container.field(1) + 1; // +
} else {
ndrop = MathHelper.clamp(1+ndrop, 1, BTileEntity.MAX_TRANSFER_COUNT); // slider
ndrop = MathHelper.clamp(1+ndrop, 1, DecorHopperTileEntity.MAX_TRANSFER_COUNT); // slider
}
container.onGuiAction("xsize", ndrop);
} else if(isPointInRegion(133, 49, 9, 9, mouseX, mouseY)) {
container.onGuiAction("manual_trigger", 1);
} else if(isPointInRegion(145, 49, 9, 9, mouseX, mouseY)) {
container.onGuiAction("logic", container.field(2) ^ BTileEntity.LOGIC_INVERTED);
container.onGuiAction("logic", container.field(2) ^ DecorHopperTileEntity.LOGIC_INVERTED);
} else if(isPointInRegion(159, 49, 7, 9, mouseX, mouseY)) {
container.onGuiAction("logic", container.field(2) ^ BTileEntity.LOGIC_CONTINUOUS);
container.onGuiAction("logic", container.field(2) ^ DecorHopperTileEntity.LOGIC_CONTINUOUS);
}
return true;
}
@ -833,11 +921,11 @@ public class BlockDecorHopper extends BlockDecor.Directed implements IDecorBlock
this.minecraft.getTextureManager().bindTexture(new ResourceLocation(ModEngineersDecor.MODID, "textures/gui/factory_hopper_gui.png"));
final int x0=getGuiLeft(), y0=getGuiTop(), w=getXSize(), h=getYSize();
blit(x0, y0, 0, 0, w, h);
BContainer container = (BContainer)getContainer();
DecorHopperContainer container = (DecorHopperContainer)getContainer();
// active slot
{
int slot_index = container.field(6);
if((slot_index < 0) || (slot_index >= BTileEntity.NUM_OF_SLOTS)) slot_index = 0;
if((slot_index < 0) || (slot_index >= DecorHopperTileEntity.NUM_OF_SLOTS)) slot_index = 0;
int x = (x0+10+((slot_index % 6) * 18));
int y = (y0+8+((slot_index / 6) * 17));
blit(x, y, 200, 8, 18, 18);
@ -845,7 +933,7 @@ public class BlockDecorHopper extends BlockDecor.Directed implements IDecorBlock
// collection range
{
int lut[] = { 133, 141, 149, 157, 166 };
int px = lut[MathHelper.clamp(container.field(0), 0, BTileEntity.MAX_COLLECTION_RANGE)];
int px = lut[MathHelper.clamp(container.field(0), 0, DecorHopperTileEntity.MAX_COLLECTION_RANGE)];
int x = x0 + px - 2;
int y = y0 + 14;
blit(x, y, 179, 40, 5, 5);
@ -871,14 +959,14 @@ public class BlockDecorHopper extends BlockDecor.Directed implements IDecorBlock
}
// trigger logic
{
int inverter_offset = ((container.field(2) & BTileEntity.LOGIC_INVERTED) != 0) ? 11 : 0;
int inverter_offset = ((container.field(2) & DecorHopperTileEntity.LOGIC_INVERTED) != 0) ? 11 : 0;
blit(x0+145, y0+49, 177+inverter_offset, 49, 9, 9);
int pulse_mode_offset = ((container.field(2) & BTileEntity.LOGIC_CONTINUOUS ) != 0) ? 9 : 0;
int pulse_mode_offset = ((container.field(2) & DecorHopperTileEntity.LOGIC_CONTINUOUS ) != 0) ? 9 : 0;
blit(x0+159, y0+49, 199+pulse_mode_offset, 49, 9, 9);
}
// delay timer running indicator
{
if((container.field(4) > BTileEntity.PERIOD_OFFSET) && ((System.currentTimeMillis() % 1000) < 500)) {
if((container.field(4) > DecorHopperTileEntity.PERIOD_OFFSET) && ((System.currentTimeMillis() % 1000) < 500)) {
blit(x0+148, y0+22, 187, 22, 3, 3);
}
}

View file

@ -39,9 +39,11 @@ import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TranslationTextComponent;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.play.server.SUpdateTileEntityPacket;
import net.minecraft.client.gui.screen.inventory.ContainerScreen;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.common.util.FakePlayer;
@ -55,16 +57,22 @@ import com.mojang.blaze3d.platform.GlStateManager;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
public class BlockDecorLabeledCrate
{
private static boolean with_gui_mouse_handling = true;
private static final HashSet<Item> unstorable_containers = new HashSet<Item>();
public static void on_config(boolean without_gui_mouse_handling)
{
with_gui_mouse_handling = !without_gui_mouse_handling;
// Currently no config, using a tag for this small feature may be uselessly stressing the registry.
unstorable_containers.clear();
unstorable_containers.add(ModContent.LABELED_CRATE.asItem());
unstorable_containers.add(Items.SHULKER_BOX);
}
//--------------------------------------------------------------------------------------------------------------------
@ -150,6 +158,39 @@ public class BlockDecorLabeledCrate
@Override
public PushReaction getPushReaction(BlockState state)
{ return PushReaction.BLOCK; }
@Override
@OnlyIn(Dist.CLIENT)
public void addInformation(final ItemStack stack, @Nullable IBlockReader world, List<ITextComponent> tooltip, ITooltipFlag flag)
{
if(!Auxiliaries.Tooltip.extendedTipCondition() || Auxiliaries.Tooltip.helpCondition()) {
super.addInformation(stack, world, tooltip, flag);
return;
}
NonNullList<ItemStack> items = NonNullList.withSize(LabeledCrateTileEntity.NUM_OF_SLOTS, ItemStack.EMPTY);
int num_used_slots = 0;
int total_items = 0;
if(stack.hasTag() && stack.getTag().contains("tedata")) {
final CompoundNBT nbt = stack.getTag().getCompound("tedata");
if(nbt.contains("Items")) {
ItemStackHelper.loadAllItems(nbt, items);
for(int i=0; i<LabeledCrateTileEntity.ITEMFRAME_SLOTNO; ++i) {
final ItemStack st = items.get(i);
if(st.isEmpty()) continue;
++num_used_slots;
total_items += st.getCount();
}
}
}
int num_free_slots = LabeledCrateTileEntity.ITEMFRAME_SLOTNO - num_used_slots;
ItemStack frameStack = items.get(LabeledCrateTileEntity.ITEMFRAME_SLOTNO);
tooltip.add(Auxiliaries.localizable(getTranslationKey()+".tip", null, new Object[] {
(frameStack.isEmpty() ? (new StringTextComponent("-/-")) : (new TranslationTextComponent(frameStack.getTranslationKey()))),
num_used_slots,
num_free_slots,
total_items
}));
}
}
//--------------------------------------------------------------------------------------------------------------------
@ -188,19 +229,22 @@ public class BlockDecorLabeledCrate
public void readnbt(CompoundNBT compound)
{
NonNullList<ItemStack> stacks = NonNullList.<ItemStack>withSize(NUM_OF_SLOTS, ItemStack.EMPTY);
ItemStackHelper.loadAllItems(compound, stacks);
if(!compound.isEmpty()) ItemStackHelper.loadAllItems(compound, stacks);
while(stacks.size() < NUM_OF_SLOTS) stacks.add(ItemStack.EMPTY);
stacks_ = stacks;
}
protected void writenbt(CompoundNBT compound)
{
ItemStackHelper.saveAllItems(compound, stacks_);
if(!stacks_.stream().allMatch(ItemStack::isEmpty)) ItemStackHelper.saveAllItems(compound, stacks_);
}
public ItemStack getItemFrameStack()
{ return (stacks_.size() > ITEMFRAME_SLOTNO) ? (stacks_.get(ITEMFRAME_SLOTNO)) : (ItemStack.EMPTY); }
protected static boolean inacceptable(ItemStack stack)
{ return (stack.hasTag() && (!stack.getTag().isEmpty()) && (unstorable_containers.contains(stack.getItem()))); }
// TileEntity ------------------------------------------------------------------------------
@Override
@ -211,6 +255,13 @@ public class BlockDecorLabeledCrate
public CompoundNBT write(CompoundNBT compound)
{ super.write(compound); writenbt(compound); return compound; }
@Override
public void remove()
{
super.remove();
item_handler_.invalidate();
}
@Override
public CompoundNBT getUpdateTag()
{ CompoundNBT nbt = super.getUpdateTag(); writenbt(nbt); return nbt; }
@ -313,7 +364,7 @@ public class BlockDecorLabeledCrate
@Override
public boolean isItemValidForSlot(int index, ItemStack stack)
{ return (index != ITEMFRAME_SLOTNO); }
{ return (index != ITEMFRAME_SLOTNO) && (!inacceptable(stack)); }
@Override
public void clear()
@ -380,14 +431,15 @@ public class BlockDecorLabeledCrate
@Override
public boolean isItemValid(int slot, @Nonnull ItemStack stack)
{ return true; }
{ return te.isItemValidForSlot(slot, stack); }
@Override
@Nonnull
public ItemStack insertItem(int slotno, @Nonnull ItemStack stack, boolean simulate)
{
if(stack.isEmpty()) return ItemStack.EMPTY;
if((slotno < 0) || ((slotno >= NUM_OF_SLOTS)) || ((slotno == ITEMFRAME_SLOTNO)) ) return ItemStack.EMPTY;
if((slotno < 0) || ((slotno >= NUM_OF_SLOTS)) || ((slotno == ITEMFRAME_SLOTNO)) ) return stack;
if((!isItemValid(slotno, stack))) return stack;
ItemStack slotstack = getStackInSlot(slotno);
if(!slotstack.isEmpty()) {
if(slotstack.getCount() >= Math.min(slotstack.getMaxStackSize(), getSlotLimit(slotno))) return stack;
@ -456,9 +508,7 @@ public class BlockDecorLabeledCrate
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing)
{
if(!this.removed) {
if(capability==CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return item_handler_.cast();
}
if(capability==CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return item_handler_.cast();
return super.getCapability(capability, facing);
}
}
@ -478,11 +528,19 @@ public class BlockDecorLabeledCrate
@Override
public int getSlotStackLimit()
{ return 64; }
@Override
public boolean isItemValid(ItemStack stack)
{ return !LabeledCrateTileEntity.inacceptable(stack); }
}
//------------------------------------------------------------------------------------------------------------------
private static final int PLAYER_INV_START_SLOTNO = LabeledCrateTileEntity.NUM_OF_SLOTS;
private static final int NUM_OF_CONTAINER_SLOTS = LabeledCrateTileEntity.NUM_OF_SLOTS + 36;
protected static final int STORAGE_SLOT_BEGIN = 0;
protected static final int STORAGE_SLOT_END = LabeledCrateTileEntity.ITEMFRAME_SLOTNO;
protected static final int PLAYER_SLOT_BEGIN = LabeledCrateTileEntity.NUM_OF_SLOTS;
protected static final int PLAYER_SLOT_END = LabeledCrateTileEntity.NUM_OF_SLOTS+36;
protected final PlayerEntity player_;
protected final IInventory inventory_;
protected final IWorldPosCallable wpc_;
@ -570,7 +628,6 @@ public class BlockDecorLabeledCrate
return transferred;
}
// Container client/server synchronisation --------------------------------------------------
@OnlyIn(Dist.CLIENT)
@ -584,11 +641,6 @@ public class BlockDecorLabeledCrate
public void onServerPacketReceived(int windowId, CompoundNBT nbt)
{}
protected static final int STORAGE_SLOT_BEGIN = 0;
protected static final int STORAGE_SLOT_END = LabeledCrateTileEntity.ITEMFRAME_SLOTNO;
protected static final int PLAYER_SLOT_BEGIN = LabeledCrateTileEntity.NUM_OF_SLOTS;
protected static final int PLAYER_SLOT_END = LabeledCrateTileEntity.NUM_OF_SLOTS+36;
@Override
public void onClientPacketReceived(int windowId, PlayerEntity player, CompoundNBT nbt)
{
@ -683,7 +735,6 @@ public class BlockDecorLabeledCrate
blit(x0, y0, 0, 0, w, h);
}
//------------------------------------------------------------------------------------------------------------------
protected void action(String message)
@ -697,7 +748,7 @@ public class BlockDecorLabeledCrate
{
if(!with_gui_mouse_handling) {
super.handleMouseClick(slot, slotId, button, type);
} else if((type == ClickType.QUICK_MOVE) && slot.getHasStack() && Auxiliaries.isShiftDown() && Auxiliaries.isCtrlDown()) {
} else if((type == ClickType.QUICK_MOVE) && (slot!=null) && slot.getHasStack() && Auxiliaries.isShiftDown() && Auxiliaries.isCtrlDown()) {
CompoundNBT nbt = new CompoundNBT();
nbt.putInt("slot", slotId);
action(QUICK_MOVE_ALL, nbt);

View file

@ -237,6 +237,14 @@ public class BlockDecorMilker extends BlockDecor.Horizontal implements IDecorBlo
public CompoundNBT write(CompoundNBT nbt)
{ super.write(nbt); writenbt(nbt, false); return nbt; }
@Override
public void remove()
{
super.remove();
energy_handler_.invalidate();
fluid_handler_.invalidate();
}
// IEnergyStorage ----------------------------------------------------------------------------
protected LazyOptional<IEnergyStorage> energy_handler_ = LazyOptional.of(() -> (IEnergyStorage)this);
@ -321,13 +329,8 @@ public class BlockDecorMilker extends BlockDecor.Horizontal implements IDecorBlo
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing)
{
if(!this.removed && (facing != null)) {
if((capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) && has_milk_fluid()) {
return fluid_handler_.cast();
} else if((capability == CapabilityEnergy.ENERGY) && (energy_consumption>0)) {
return energy_handler_.cast();
}
}
if((capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) && has_milk_fluid()) return fluid_handler_.cast();
if((capability == CapabilityEnergy.ENERGY) && (energy_consumption>0)) return energy_handler_.cast();
return super.getCapability(capability, facing);
}

View file

@ -339,6 +339,15 @@ public class BlockDecorMineralSmelter extends BlockDecor.Horizontal implements I
public CompoundNBT write(CompoundNBT nbt)
{ super.write(nbt); writenbt(nbt); return nbt; }
@Override
public void remove()
{
super.remove();
energy_handler_.invalidate();
fluid_handler_.invalidate();
item_handler_.invalidate();
}
// INamedContainerProvider / INameable ------------------------------------------------------
@Override
@ -542,15 +551,9 @@ public class BlockDecorMineralSmelter extends BlockDecor.Horizontal implements I
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing)
{
if(!this.removed && (facing != null)) {
if(capability== CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
return item_handler_.cast();
} else if(capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) {
return fluid_handler_.cast();
} else if(capability== CapabilityEnergy.ENERGY) {
return energy_handler_.cast();
}
}
if(capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return item_handler_.cast();
if(capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) return fluid_handler_.cast();
if(capability == CapabilityEnergy.ENERGY) return energy_handler_.cast();
return super.getCapability(capability, facing);
}

View file

@ -71,7 +71,7 @@ public class BlockDecorPassiveFluidAccumulator extends BlockDecor.Directed imple
public void neighborChanged(BlockState state, World world, BlockPos pos, Block block, BlockPos fromPos, boolean unused)
{
TileEntity te = world.getTileEntity(pos);
if(te instanceof BlockDecorPipeValve.BTileEntity) ((BTileEntity)te).block_changed();
if(te instanceof BTileEntity) ((BTileEntity)te).block_changed();
}
//--------------------------------------------------------------------------------------------------------------------
@ -124,6 +124,14 @@ public class BlockDecorPassiveFluidAccumulator extends BlockDecor.Directed imple
return nbt;
}
@Override
public void remove()
{
super.remove();
fill_handler_.invalidate();
fluid_handler_.invalidate();
}
// Input flow handler ---------------------------------------------------------------------
private static class InputFillHandler implements IFluidHandler
@ -181,11 +189,12 @@ public class BlockDecorPassiveFluidAccumulator extends BlockDecor.Directed imple
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing)
{
if((initialized_) && (!this.removed) && (facing != null)) {
if(capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) {
if(capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) {
if(initialized_) {
if(facing == block_facing_) return fluid_handler_.cast();
return fill_handler_.cast();
if(facing != null) return fill_handler_.cast();
}
return LazyOptional.empty();
}
return super.getCapability(capability, facing);
}

View file

@ -22,10 +22,10 @@ import net.minecraft.tileentity.TileEntityType;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.item.BlockItemUseContext;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.entity.LivingEntity;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.Direction;
import net.minecraft.util.Rotation;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.shapes.ISelectionContext;
@ -39,160 +39,168 @@ import net.minecraftforge.fluids.capability.IFluidHandler;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class BlockDecorPipeValve extends BlockDecor.DirectedWaterLoggable implements IDecorBlock
public class BlockDecorPipeValve
{
public static final BooleanProperty RS_CN_N = BooleanProperty.create("rs_n");
public static final BooleanProperty RS_CN_S = BooleanProperty.create("rs_s");
public static final BooleanProperty RS_CN_E = BooleanProperty.create("rs_e");
public static final BooleanProperty RS_CN_W = BooleanProperty.create("rs_w");
public static final BooleanProperty RS_CN_U = BooleanProperty.create("rs_u");
public static final BooleanProperty RS_CN_D = BooleanProperty.create("rs_d");
public static final int CFG_CHECK_VALVE = 0x0;
public static final int CFG_ANALOG_VALVE = 0x1;
public static final int CFG_REDSTONE_CONTROLLED_VALVE = 0x2;
public final int valve_config;
public static final int CFG_CHECK_VALVE = 0x1;
public static final int CFG_ANALOG_VALVE = 0x2;
public static final int CFG_REDSTONE_CONTROLLED_VALVE = 0x4;
public static void on_config(int container_size_decl, int redstone_slope)
{
BTileEntity.fluid_maxflow_mb = MathHelper.clamp(container_size_decl, 1, 10000);
BTileEntity.redstone_flow_slope_mb = MathHelper.clamp(redstone_slope, 1, 10000);
ModEngineersDecor.logger().info("Config pipe valve: maxflow:" + BTileEntity.fluid_maxflow_mb + "mb, redstone amp:" + BTileEntity.redstone_flow_slope_mb + "mb/sig");
DecorPipeValveTileEntity.fluid_maxflow_mb = MathHelper.clamp(container_size_decl, 1, 10000);
DecorPipeValveTileEntity.redstone_flow_slope_mb = MathHelper.clamp(redstone_slope, 1, 10000);
ModEngineersDecor.logger().info("Config pipe valve: maxflow:" + DecorPipeValveTileEntity.fluid_maxflow_mb + "mb, redstone amp:" + DecorPipeValveTileEntity.redstone_flow_slope_mb + "mb/sig");
}
public BlockDecorPipeValve(long config, int valve_config, Block.Properties builder, final AxisAlignedBB[] unrotatedAABB)
{ super(config, builder, unrotatedAABB); this.valve_config = valve_config; }
//--------------------------------------------------------------------------------------------------------------------
// Block
//--------------------------------------------------------------------------------------------------------------------
private BlockState get_rsconnector_state(BlockState state, IWorld world, BlockPos pos, @Nullable BlockPos fromPos)
public static class DecorPipeValveBlock extends BlockDecor.DirectedWaterLoggable implements IDecorBlock
{
if((valve_config & (CFG_REDSTONE_CONTROLLED_VALVE))==0) return state;
Direction.Axis bfa = state.get(FACING).getAxis();
int bfi = state.get(FACING).getIndex();
for(Direction f:Direction.values()) {
boolean cn = (f.getAxis() != bfa);
if(cn) {
BlockPos nbp = pos.offset(f);
if((fromPos != null) && (!nbp.equals(fromPos))) continue; // do not change connectors except form the frompos.
BlockState nbs = world.getBlockState(nbp);
if(!nbs.canProvidePower()) cn = false; // @todo check if there is a direction selective canProvidePower().
}
switch(f) {
case NORTH: state = state.with(RS_CN_N, cn); break;
case SOUTH: state = state.with(RS_CN_S, cn); break;
case EAST: state = state.with(RS_CN_E, cn); break;
case WEST: state = state.with(RS_CN_W, cn); break;
case UP: state = state.with(RS_CN_U, cn); break;
case DOWN: state = state.with(RS_CN_D, cn); break;
}
public static final BooleanProperty RS_CN_N = BooleanProperty.create("rs_n");
public static final BooleanProperty RS_CN_S = BooleanProperty.create("rs_s");
public static final BooleanProperty RS_CN_E = BooleanProperty.create("rs_e");
public static final BooleanProperty RS_CN_W = BooleanProperty.create("rs_w");
public static final BooleanProperty RS_CN_U = BooleanProperty.create("rs_u");
public static final BooleanProperty RS_CN_D = BooleanProperty.create("rs_d");
public final int valve_config;
public static void on_config(int container_size_decl, int redstone_slope)
{
DecorPipeValveTileEntity.fluid_maxflow_mb = MathHelper.clamp(container_size_decl, 1, 10000);
DecorPipeValveTileEntity.redstone_flow_slope_mb = MathHelper.clamp(redstone_slope, 1, 10000);
ModEngineersDecor.logger().info("Config pipe valve: maxflow:" + DecorPipeValveTileEntity.fluid_maxflow_mb + "mb, redstone amp:" + DecorPipeValveTileEntity.redstone_flow_slope_mb + "mb/sig");
}
return state;
public DecorPipeValveBlock(long config, int valve_config, Block.Properties builder, final AxisAlignedBB[] unrotatedAABB)
{ super(config, builder, unrotatedAABB); this.valve_config = valve_config; }
private BlockState get_rsconnector_state(BlockState state, IWorld world, BlockPos pos, @Nullable BlockPos fromPos)
{
if((valve_config & (CFG_REDSTONE_CONTROLLED_VALVE))==0) return state;
Direction.Axis bfa = state.get(FACING).getAxis();
int bfi = state.get(FACING).getIndex();
for(Direction f:Direction.values()) {
boolean cn = (f.getAxis() != bfa);
if(cn) {
BlockPos nbp = pos.offset(f);
if((fromPos != null) && (!nbp.equals(fromPos))) continue; // do not change connectors except form the frompos.
BlockState nbs = world.getBlockState(nbp);
if(!nbs.canProvidePower()) cn = false; // @todo check if there is a direction selective canProvidePower().
}
switch(f) {
case NORTH: state = state.with(RS_CN_N, cn); break;
case SOUTH: state = state.with(RS_CN_S, cn); break;
case EAST: state = state.with(RS_CN_E, cn); break;
case WEST: state = state.with(RS_CN_W, cn); break;
case UP: state = state.with(RS_CN_U, cn); break;
case DOWN: state = state.with(RS_CN_D, cn); break;
}
}
return state;
}
@Override
public VoxelShape getCollisionShape(BlockState state, IBlockReader world, BlockPos pos, ISelectionContext selectionContext)
{ return VoxelShapes.fullCube(); }
@Override
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder)
{ super.fillStateContainer(builder); builder.add(RS_CN_N, RS_CN_S, RS_CN_E, RS_CN_W, RS_CN_U, RS_CN_D); }
@Override
@Nullable
public BlockState getStateForPlacement(BlockItemUseContext context)
{
return super.getStateForPlacement(context).with(RS_CN_N, false).with(RS_CN_S, false).with(RS_CN_E, false)
.with(RS_CN_W, false).with(RS_CN_U, false).with(RS_CN_D, false);
}
@Override
@SuppressWarnings("deprecation")
public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState facingState, IWorld world, BlockPos pos, BlockPos facingPos)
{ return get_rsconnector_state(state, world, pos, null); }
@Override
public void onBlockPlacedBy(World world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack)
{ world.notifyNeighborsOfStateChange(pos,this); }
@Override
public boolean hasTileEntity(BlockState state)
{ return true; }
@Override
@Nullable
public TileEntity createTileEntity(BlockState state, IBlockReader world)
{ return new DecorPipeValveTileEntity(); }
@Override
public BlockState rotate(BlockState state, IWorld world, BlockPos pos, Rotation direction)
{ return get_rsconnector_state(state, world, pos, null); } // don't rotate at all
@Override
public boolean canConnectRedstone(BlockState state, IBlockReader world, BlockPos pos, @Nullable Direction side)
{ return (side!=null) && (side!=state.get(FACING)) && (side!=state.get(FACING).getOpposite()); }
@Override
@SuppressWarnings("deprecation")
public boolean canProvidePower(BlockState state)
{ return true; }
@Override
@SuppressWarnings("deprecation")
public int getWeakPower(BlockState blockState, IBlockReader blockAccess, BlockPos pos, Direction side)
{ return 0; }
@Override
@SuppressWarnings("deprecation")
public int getStrongPower(BlockState blockState, IBlockReader blockAccess, BlockPos pos, Direction side)
{ return 0; }
}
private void update_te(IWorld world, BlockState state, BlockPos pos)
{
TileEntity te = world.getTileEntity(pos);
if(te instanceof BlockDecorPipeValve.BTileEntity) ((BlockDecorPipeValve.BTileEntity)te).block_reconfigure(state.get(FACING), config, valve_config);
}
@Override
public VoxelShape getCollisionShape(BlockState state, IBlockReader world, BlockPos pos, ISelectionContext selectionContext)
{ return VoxelShapes.fullCube(); }
@Override
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder)
{ super.fillStateContainer(builder); builder.add(RS_CN_N, RS_CN_S, RS_CN_E, RS_CN_W, RS_CN_U, RS_CN_D); }
@Override
@Nullable
public BlockState getStateForPlacement(BlockItemUseContext context)
{
return super.getStateForPlacement(context).with(RS_CN_N, false).with(RS_CN_S, false).with(RS_CN_E, false)
.with(RS_CN_W, false).with(RS_CN_U, false).with(RS_CN_D, false);
}
@Override
@SuppressWarnings("deprecation")
public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState facingState, IWorld world, BlockPos pos, BlockPos facingPos)
{
update_te(world, state, pos);
return get_rsconnector_state(state, world, pos, null);
}
@Override
public void onBlockPlacedBy(World world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack)
{
update_te(world, state, pos);
world.notifyNeighborsOfStateChange(pos,this);
}
@Override
public boolean hasTileEntity(BlockState state)
{ return true; }
@Override
@Nullable
public TileEntity createTileEntity(BlockState state, IBlockReader world)
{ return new BlockDecorPipeValve.BTileEntity(); }
@Override
public boolean canConnectRedstone(BlockState state, IBlockReader world, BlockPos pos, @Nullable Direction side)
{ return (side!=null) && (side!=state.get(FACING)) && (side!=state.get(FACING).getOpposite()); }
//--------------------------------------------------------------------------------------------------------------------
// Tile entity
//--------------------------------------------------------------------------------------------------------------------
public static class BTileEntity extends TileEntity implements ICapabilityProvider //, IFluidPipe
public static class DecorPipeValveTileEntity extends TileEntity implements ICapabilityProvider //, IFluidPipe
{
protected static int fluid_maxflow_mb = 1000;
protected static int redstone_flow_slope_mb = 1000/15;
private Direction block_facing_ = null;
private boolean filling_ = false;
private boolean getlocked_ = false;
private long block_config_ = 0;
private int valve_config_;
public BTileEntity()
public DecorPipeValveTileEntity()
{ this(ModContent.TET_STRAIGHT_PIPE_VALVE); }
public BTileEntity(TileEntityType<?> te_type)
public DecorPipeValveTileEntity(TileEntityType<?> te_type)
{ super(te_type); }
public void block_reconfigure(Direction facing, long block_config, int valve_config)
{
block_facing_ = facing;
block_config_ = block_config;
valve_config_ = valve_config;
}
private Direction block_facing()
{
if(block_facing_ == null) {
BlockState st = getWorld().getBlockState(getPos());
block_facing_ = (st.getBlock() instanceof BlockDecorPipeValve) ? st.get(FACING) : Direction.NORTH;
BlockState st = getWorld().getBlockState(getPos());
return (st.getBlock() instanceof DecorPipeValveBlock) ? st.get(DecorPipeValveBlock.FACING) : Direction.NORTH;
}
private long valve_config()
{
if(valve_config_ <= 0) {
final Block block = getWorld().getBlockState(getPos()).getBlock();
if(block instanceof DecorPipeValveBlock) valve_config_ = ((DecorPipeValveBlock)block).valve_config;
}
return block_facing_;
return valve_config_;
}
// TileEntity ------------------------------------------------------------------------------
// TileEntity -----------------------------------------------------------------------------
@Override
public void read(CompoundNBT nbt)
public void remove()
{
super.read(nbt);
int i = nbt.getInt("facing");
if((i>=0) || (i<6)) block_facing_ = Direction.byIndex(i);
block_config_ = nbt.getLong("conf");
}
@Override
public CompoundNBT write(CompoundNBT nbt)
{
super.write(nbt);
if(block_facing_!=null) nbt.putInt("facing", block_facing_.getIndex());
nbt.putLong("conf", block_config_);
return nbt;
super.remove();
back_flow_handler_.invalidate();
fluid_handler_.invalidate();
}
// ICapabilityProvider --------------------------------------------------------------------
@ -203,11 +211,11 @@ public class BlockDecorPipeValve extends BlockDecor.DirectedWaterLoggable implem
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing)
{
if(!this.removed && (facing != null)) {
if(capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) {
if(facing == block_facing()) return back_flow_handler_.cast();
if(facing == block_facing().getOpposite()) return fluid_handler_.cast();
}
if(capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) {
Direction bf = block_facing();
if(facing == bf) return back_flow_handler_.cast();
if(facing == bf.getOpposite()) return fluid_handler_.cast();
return LazyOptional.empty();
}
return super.getCapability(capability, facing);
}
@ -226,36 +234,28 @@ public class BlockDecorPipeValve extends BlockDecor.DirectedWaterLoggable implem
private static class MainFlowHandler implements IFluidHandler
{
private BTileEntity te;
public MainFlowHandler(BTileEntity te) { this.te = te; }
private DecorPipeValveTileEntity te;
public MainFlowHandler(DecorPipeValveTileEntity te) { this.te = te; }
@Override public int getTanks() { return 0; }
@Override public FluidStack getFluidInTank(int tank) { return FluidStack.EMPTY; }
@Override public int getTankCapacity(int tank) { return fluid_maxflow_mb; }
@Override public boolean isFluidValid(int tank, @Nonnull FluidStack stack) { return true; }
@Override public FluidStack drain(FluidStack resource, FluidAction action) { return FluidStack.EMPTY; }
@Override public FluidStack drain(int maxDrain, FluidAction action) { return FluidStack.EMPTY; }
@Override public boolean isFluidValid(int tank, @Nonnull FluidStack stack) { return true; }
@Override public int fill(FluidStack resource, FluidAction action)
{
if(te.filling_) return 0;
final IFluidHandler fh = te.forward_fluid_handler();
if(fh==null) return 0;
if((te.valve_config_ & CFG_REDSTONE_CONTROLLED_VALVE) != 0) {
if((te.valve_config() & CFG_REDSTONE_CONTROLLED_VALVE) != 0) {
int rs = te.world.getRedstonePowerFromNeighbors(te.pos);
if(rs <= 0) return 0;
if(((te.valve_config_ & CFG_ANALOG_VALVE) != 0) && (rs < 15)) resource.setAmount(MathHelper.clamp(rs * redstone_flow_slope_mb, 1, resource.getAmount()));
if(((te.valve_config() & CFG_ANALOG_VALVE) != 0) && (rs < 15)) resource.setAmount(MathHelper.clamp(rs * redstone_flow_slope_mb, 1, resource.getAmount()));
}
FluidStack res = resource.copy();
if(res.getAmount() > fluid_maxflow_mb) res.setAmount(fluid_maxflow_mb);
te.filling_ = true;
// IE fluid pipe not available yet
// if(res.getAmount() > 50) {
// final TileEntity fte = te.world.getTileEntity(te.pos.offset(te.block_facing()));
// if(!(fte instanceof IFluidPipe)) {
// CompoundNBT tag = res.getTag();
// if((tag != null) && (tag.contains("pressurized"))) tag.remove("pressurized"); // remove pressureized tag if no IFluidPipe
// }
// }
int n_filled = fh.fill(res, action);
te.filling_ = false;
return n_filled;
@ -274,24 +274,5 @@ public class BlockDecorPipeValve extends BlockDecor.DirectedWaterLoggable implem
@Override public FluidStack drain(FluidStack resource, FluidAction action) { return FluidStack.EMPTY; }
@Override public FluidStack drain(int maxDrain, FluidAction action) { return FluidStack.EMPTY; }
}
// IE IFluidPipe
// @Override
// public boolean hasOutputConnection(Direction side)
// { return (side == block_facing()); }
//
// @Override
// public boolean canOutputPressurized(boolean consumePower)
// {
// if(getlocked_ || (!filling_enabled_)) return false;
// final TileEntity te = world.getTileEntity(pos.offset(block_facing()));
// if(!(te instanceof IFluidPipe)) return false;
// getlocked_ = true; // not sure if IE explicitly pre-detects loops, so let's lock recurion here, too.
// boolean r = ((IFluidPipe)te).canOutputPressurized(consumePower);
// getlocked_ = false;
// return r;
// }
}
}

View file

@ -50,6 +50,7 @@ import net.minecraftforge.fml.network.NetworkHooks;
import com.mojang.blaze3d.systems.RenderSystem;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@ -254,6 +255,13 @@ public class BlockDecorPlacer extends BlockDecor.Directed implements IDecorBlock
public CompoundNBT write(CompoundNBT nbt)
{ super.write(nbt); writenbt(nbt, false); return nbt; }
@Override
public void remove()
{
super.remove();
Arrays.stream(item_handlers).forEach(LazyOptional::invalidate);
}
// INamable ----------------------------------------------------------------------------------------------
@Override
@ -390,9 +398,7 @@ public class BlockDecorPlacer extends BlockDecor.Directed implements IDecorBlock
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing)
{
if(!this.removed && (facing != null)) {
if(capability==CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return item_handlers[0].cast();
}
if(capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return item_handlers[0].cast();
return super.getCapability(capability, facing);
}

View file

@ -152,11 +152,7 @@ public class BlockDecorSolarPanel extends BlockDecor implements IDecorBlock
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing)
{
if(!this.removed && (facing != null)) {
if(capability== CapabilityEnergy.ENERGY) {
return energy_handler_.cast();
}
}
if(capability== CapabilityEnergy.ENERGY) return energy_handler_.cast();
return super.getCapability(capability, facing);
}
@ -170,6 +166,13 @@ public class BlockDecorSolarPanel extends BlockDecor implements IDecorBlock
public CompoundNBT write(CompoundNBT nbt)
{ super.write(nbt); writenbt(nbt, false); return nbt; }
@Override
public void remove()
{
super.remove();
energy_handler_.invalidate();
}
@Override
public void tick()
{

View file

@ -211,6 +211,13 @@ public class BlockDecorTest extends BlockDecor.Directed implements Auxiliaries.I
return nbt;
}
@Override
public void remove()
{
super.remove();
fluid_handler_.invalidate();
}
// ICapabilityProvider --------------------------------------------------------------------
private LazyOptional<IFluidHandler> fluid_handler_ = LazyOptional.of(() -> (IFluidHandler)new MainFluidHandler(this));
@ -218,10 +225,9 @@ public class BlockDecorTest extends BlockDecor.Directed implements Auxiliaries.I
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing)
{
if(!this.removed && (facing != null)) {
if(capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) {
if(facing != block_facing()) return fluid_handler_.cast();
}
if(capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) {
if(facing != block_facing()) return fluid_handler_.cast();
return LazyOptional.empty();
}
return super.getCapability(capability, facing);
}

View file

@ -151,6 +151,13 @@ public class BlockDecorTreeCutter extends BlockDecor.Horizontal implements IDeco
public CompoundNBT write(CompoundNBT nbt)
{ super.write(nbt); writenbt(nbt); return nbt; }
@Override
public void remove()
{
super.remove();
energy_handler_.invalidate();
}
// IEnergyStorage ----------------------------------------------------------------------------
protected LazyOptional<IEnergyStorage> energy_handler_ = LazyOptional.of(() -> (IEnergyStorage)this);
@ -188,11 +195,7 @@ public class BlockDecorTreeCutter extends BlockDecor.Horizontal implements IDeco
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing)
{
if(!this.removed && (facing != null)) {
if(capability== CapabilityEnergy.ENERGY) {
return energy_handler_.cast();
}
}
if(capability== CapabilityEnergy.ENERGY) return energy_handler_.cast();
return super.getCapability(capability, facing);
}

View file

@ -236,6 +236,14 @@ public class BlockDecorWasteIncinerator extends BlockDecor implements IDecorBloc
public CompoundNBT write(CompoundNBT compound)
{ super.write(compound); writenbt(compound); return compound; }
@Override
public void remove()
{
super.remove();
energy_handler_.invalidate();
item_handler_.invalidate();
}
// INameable ---------------------------------------------------------------------------
@Override
@ -478,10 +486,8 @@ public class BlockDecorWasteIncinerator extends BlockDecor implements IDecorBloc
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing)
{
if(!this.removed && (facing != null)) {
if(capability==CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return item_handler_.cast();
if(capability== CapabilityEnergy.ENERGY) return energy_handler_.cast();
}
if(capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return item_handler_.cast();
if(capability == CapabilityEnergy.ENERGY) return energy_handler_.cast();
return super.getCapability(capability, facing);
}

View file

@ -543,10 +543,10 @@ public class ModConfig
if(block instanceof BlockDecorHalfSlab) return COMMON.without_halfslabs.get();
if(block instanceof BlockDecorLadder) return COMMON.without_ladders.get();
if(block instanceof BlockDecorWindow) return COMMON.without_windows.get();
if(block instanceof BlockDecorPipeValve) return COMMON.without_valves.get();
if(block instanceof BlockDecorPipeValve.DecorPipeValveBlock) return COMMON.without_valves.get();
if(block instanceof BlockDecorHorizontalSupport) return COMMON.without_hsupports.get();
if(block instanceof BlockDecorFloorGrating) return COMMON.without_floor_grating.get();
if(block instanceof BlockDecorHopper) return COMMON.without_factory_hopper.get();
if(block instanceof BlockDecorHopper.DecorHopperBlock) return COMMON.without_factory_hopper.get();
if(block instanceof BlockDecorFluidFunnel) return COMMON.without_fluid_funnel.get();
if(block instanceof BlockDecorSolarPanel) return COMMON.without_solar_panel.get();
if(block instanceof BlockDecorMineralSmelter) return COMMON.without_mineral_smelter.get();

View file

@ -1,5 +1,5 @@
/*
* @file BlockDecorFull.java
* @file StandardBlocks.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2019 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)
@ -12,9 +12,6 @@
*/
package wile.engineersdecor.libmc.blocks;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.shapes.IBooleanFunction;
import net.minecraft.world.server.ServerWorld;
import wile.engineersdecor.libmc.detail.Auxiliaries;
import net.minecraft.block.*;
import net.minecraft.entity.EntityType;
@ -27,13 +24,16 @@ import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.fluid.IFluidState;
import net.minecraft.fluid.Fluids;
import net.minecraft.world.IWorld;
import net.minecraft.world.server.ServerWorld;
import net.minecraft.world.Explosion;
import net.minecraft.world.World;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.shapes.ISelectionContext;
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.util.math.shapes.VoxelShapes;
import net.minecraft.util.math.shapes.IBooleanFunction;
import net.minecraft.block.material.PushReaction;
import net.minecraft.item.BlockItemUseContext;
import net.minecraft.item.ItemStack;

View file

@ -1,5 +1,5 @@
/*
* @file BlockDecorWall.java
* @file StandardFenceBlock.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2019 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)

View file

@ -95,6 +95,28 @@ public class Inventories
public SlotRange(IInventory inv, int start, int end)
{ inventory=inv; start_slot=start; end_slot=end; }
/**
* Returns the number of stacks that match the given stack with NBT.
*/
public int stackMatchCount(final ItemStack ref_stack)
{
int n = 0; // ... std::accumulate() the old school way.
for(int i = start_slot; i < end_slot; ++i) {
if(areItemStacksIdentical(ref_stack, inventory.getStackInSlot(i))) ++n;
}
return n;
}
public int totalMatchingItemCount(final ItemStack ref_stack)
{
int n = 0;
for(int i = start_slot; i < end_slot; ++i) {
ItemStack stack = inventory.getStackInSlot(i);
if(areItemStacksIdentical(ref_stack, stack)) n += stack.getCount();
}
return n;
}
/**
* Moves as much items from the stack to the slots in range [start_slot, end_slot] of the inventory,
* filling up existing stacks first, then (player inventory only) checks appropriate empty slots next
@ -109,11 +131,24 @@ public class Inventories
final ItemStack mvstack = stack_to_move.copy();
if((mvstack.isEmpty()) || (start_slot < 0) || (end_slot > inventory.getSizeInventory())) return checked(mvstack);
int limit_left = (limit>0) ? (Math.min(limit, mvstack.getMaxStackSize())) : (mvstack.getMaxStackSize());
// first iteration: fillup existing stacks
boolean matches[] = new boolean[end_slot];
boolean empties[] = new boolean[end_slot];
int num_matches = 0;
for(int i = start_slot; i < end_slot; ++i) {
final int sno = reverse ? (end_slot-1-i) : (i);
final ItemStack stack = inventory.getStackInSlot(sno);
if((stack.isEmpty()) || (areItemStacksDifferent(stack, mvstack))) continue;
if(stack.isEmpty() || (!inventory.isItemValidForSlot(sno, mvstack))) {
empties[sno] = true;
} else if(areItemStacksIdentical(stack, mvstack)) {
matches[sno] = true;
++num_matches;
}
}
// first iteration: fillup existing stacks
for(int i = start_slot; i < end_slot; ++i) {
final int sno = reverse ? (end_slot-1-i) : (i);
if(empties[sno] || !matches[sno]) continue;
final ItemStack stack = inventory.getStackInSlot(sno);
int nmax = Math.min(limit_left, stack.getMaxStackSize() - stack.getCount());
if(mvstack.getCount() <= nmax) {
stack.setCount(stack.getCount()+mvstack.getCount());
@ -127,26 +162,53 @@ public class Inventories
}
}
if(only_fillup) return checked(mvstack);
if((force_group_stacks) || (inventory instanceof PlayerInventory)) {
// second iteration: use appropriate empty slots
for(int i = start_slot+1; i < end_slot-1; ++i) {
final int sno = reverse ? (end_slot-1-i) : (i);
final ItemStack stack = inventory.getStackInSlot(sno);
if(!stack.isEmpty()) continue;
if((areItemStacksDifferent(inventory.getStackInSlot(sno+1), mvstack)) && (areItemStacksDifferent(inventory.getStackInSlot(sno-1), mvstack))) continue;
int nmax = Math.min(limit_left, mvstack.getCount());
ItemStack moved = mvstack.copy();
moved.setCount(nmax);
mvstack.shrink(nmax);
inventory.setInventorySlotContents(sno, moved);
return checked(mvstack);
if((num_matches>0) && ((force_group_stacks) || (inventory instanceof PlayerInventory))) {
// second iteration: use appropriate empty slots,
// a) between
{
int insert_start = -1;
int insert_end = -1;
int i = start_slot+1;
for(;i < end_slot-1; ++i) {
final int sno = reverse ? (end_slot-1-i) : (i);
if(insert_start < 0) {
if(matches[sno]) insert_start = sno;
} else if(matches[sno]) {
insert_end = sno;
}
}
for(i=insert_start;i < insert_end; ++i) {
final int sno = reverse ? (end_slot-1-i) : (i);
if(!empties[sno]) continue;
int nmax = Math.min(limit_left, mvstack.getCount());
ItemStack moved = mvstack.copy();
moved.setCount(nmax);
mvstack.shrink(nmax);
inventory.setInventorySlotContents(sno, moved);
return checked(mvstack);
}
}
// b) before/after
{
for(int i = start_slot+1; i < end_slot-1; ++i) {
final int sno = reverse ? (end_slot-1-i) : (i);
if(!matches[sno]) continue;
int ii = (empties[sno-1]) ? (sno-1) : (empties[sno+1] ? (sno+1) : -1);
if(ii >= 0) {
int nmax = Math.min(limit_left, mvstack.getCount());
ItemStack moved = mvstack.copy();
moved.setCount(nmax);
mvstack.shrink(nmax);
inventory.setInventorySlotContents(ii, moved);
return checked(mvstack);
}
}
}
}
// third iteration: use any empty slots
for(int i = start_slot; i < end_slot; ++i) {
final int sno = reverse ? (end_slot-1-i) : (i);
final ItemStack stack = inventory.getStackInSlot(sno);
if(!stack.isEmpty()) continue;
if(!empties[sno]) continue;
int nmax = Math.min(limit_left, mvstack.getCount());
ItemStack placed = mvstack.copy();
placed.setCount(nmax);

View file

@ -36,6 +36,7 @@ public class OptionalRecipeCondition implements ICondition
private final List<ResourceLocation> all_required_tags;
private final List<ResourceLocation> any_missing_tags;
private final @Nullable ResourceLocation result;
private final boolean result_is_tag;
private final boolean experimental;
private static boolean with_experimental = false;
@ -43,7 +44,6 @@ public class OptionalRecipeCondition implements ICondition
private static Predicate<Block> block_optouts = (block)->false;
private static Predicate<Item> item_optouts = (item)->false;
public static void init(String modid, Logger logger)
{
NAME = new ResourceLocation(modid, "optional");
@ -60,13 +60,14 @@ public class OptionalRecipeCondition implements ICondition
}
public OptionalRecipeCondition(ResourceLocation result, List<ResourceLocation> required, List<ResourceLocation> missing, List<ResourceLocation> required_tags, List<ResourceLocation> missing_tags, boolean isexperimental)
public OptionalRecipeCondition(ResourceLocation result, List<ResourceLocation> required, List<ResourceLocation> missing, List<ResourceLocation> required_tags, List<ResourceLocation> missing_tags, boolean isexperimental, boolean result_is_tag)
{
all_required = required;
any_missing = missing;
all_required_tags = required_tags;
any_missing_tags = missing_tags;
this.result = result;
this.result_is_tag = result_is_tag;
experimental=isexperimental;
}
@ -109,6 +110,7 @@ public class OptionalRecipeCondition implements ICondition
if(!all_required_tags.isEmpty()) {
for(ResourceLocation rl:all_required_tags) {
if(!ItemTags.getCollection().getTagMap().containsKey(rl)) return false;
if(ItemTags.getCollection().getTagMap().get(rl).getAllElements().isEmpty()) return false;
}
}
if(!any_missing.isEmpty()) {
@ -120,13 +122,13 @@ public class OptionalRecipeCondition implements ICondition
if(!any_missing_tags.isEmpty()) {
for(ResourceLocation rl:any_missing_tags) {
if(!ItemTags.getCollection().getTagMap().containsKey(rl)) return true;
if(ItemTags.getCollection().getTagMap().get(rl).getAllElements().isEmpty()) return true;
}
return false;
}
return true;
}
public static class Serializer implements IConditionSerializer<OptionalRecipeCondition>
{
public static final Serializer INSTANCE = new Serializer();
@ -144,7 +146,9 @@ public class OptionalRecipeCondition implements ICondition
for(ResourceLocation e:condition.any_missing) missing.add(e.toString());
json.add("required", required);
json.add("missing", missing);
if(condition.result != null) json.addProperty("result", condition.result.toString());
if(condition.result != null) {
json.addProperty("result", (condition.result_is_tag ? "#" : "") + condition.result.toString());
}
}
@Override
@ -156,7 +160,16 @@ public class OptionalRecipeCondition implements ICondition
List<ResourceLocation> missing_tags = new ArrayList<>();
ResourceLocation result = null;
boolean experimental = false;
if(json.has("result")) result = new ResourceLocation(json.get("result").getAsString());
boolean result_is_tag = false;
if(json.has("result")) {
String s = json.get("result").getAsString();
if(s.startsWith("#")) {
result = new ResourceLocation(s.substring(1));
result_is_tag = true;
} else {
result = new ResourceLocation(s);
}
}
if(json.has("required")) {
for(JsonElement e:JSONUtils.getJsonArray(json, "required")) {
String s = e.getAsString();
@ -178,7 +191,7 @@ public class OptionalRecipeCondition implements ICondition
}
}
if(json.has("experimental")) experimental = json.get("experimental").getAsBoolean();
return new OptionalRecipeCondition(result, required, missing, required_tags, missing_tags, experimental);
return new OptionalRecipeCondition(result, required, missing, required_tags, missing_tags, experimental, result_is_tag);
}
}
}

View file

@ -1,5 +1,5 @@
/*
* @file OverlayEventHandler.java
* @file Overlay.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2018 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)

View file

@ -1,3 +1,11 @@
/*
* @file SidedProxy.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2018 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)
*
* General client/server sideness selection proxy.
*/
package wile.engineersdecor.libmc.detail;
import net.minecraft.client.Minecraft;

View file

@ -4,8 +4,8 @@
"language.region": "United States",
"itemGroup.tabengineersdecor": "Engineer's Decor",
"engineersdecor.config.title": "Engineer's Decor Config",
"engineersdecor.tooltip.hint.extended": "§6[§9SHIFT§r More Info§6]§r",
"engineersdecor.tooltip.hint.help": "§6[§9CTRL-SHIFT§r Help§6]§r",
"engineersdecor.tooltip.hint.extended": "§6[§9shift§r More§6]§r",
"engineersdecor.tooltip.hint.help": "§6[§9ctrl-shift§r Help§6]§r",
"engineersdecor.tooltip.slabpickup.help": "§rFast pickup by left-clicking while looking up/down and holding this slab.",
"engineersdecor.tooltip.requires_rf_power": "Requires RF power.",
"engineersdecor.tooltip.massive_speed_boost_with_rf_power": "Apply RF power to magnificently increase the speed.",
@ -137,6 +137,7 @@
"block.engineersdecor.treated_wood_crafting_table.help": "§6Robust and weather-proof.§r Eight storage slots, keeps inventory, no vanilla recipe book.\n Click up/down arrow buttons for crafting history selection, output slot for item placement, X-button to clear crafting grid and history. Shift-click stack: player-to-storage stack transfer when crafting grid empty, otherwise player-to-grid stack transfer. Automatically distributes the clicked stack. Shift-Ctrl-click stack: Move all same stacks. Mouse wheel over crafting slot: Increase/decrease crafting grid items.",
"block.engineersdecor.labeled_crate": "Labeled Crate",
"block.engineersdecor.labeled_crate.help": "§6A storage crate with 9x6 slots and a built-in item frame at the front.§r\nPlace an item into the frame slot at the bottom right of the GUI to define the shown label.",
"block.engineersdecor.labeled_crate.tip": "§6Label:§r %1$s\n%2$s slots used / %3$s free\n%4$s total items stored",
"block.engineersdecor.treated_wood_side_table": "Treated Wood Side Table",
"block.engineersdecor.treated_wood_side_table.help": "§6Needed after the work's done.",
"block.engineersdecor.iron_inset_light": "Inset Light",

View file

@ -137,6 +137,7 @@
"block.engineersdecor.treated_wood_crafting_table.help": "§6Прочный и устойчивый к погодным условиям. Восемь слотов для хранения. Хранит инвентарь. Нажимайте кнопки со стрелками вверх/вниз для выбора из истории, выходной слот для размещения предметов, X-кнопка очистить сетку крафта и историю. Shift-клик по стеку: передача стека от игрока в хранилище при создании если сетка пуста, в противном случае перенос от игрока в сетку. Автоматически распределяет кликаемый стек. Shift-Ctrl-клик по стаку: перемещает одинаковые стаки. Колёсико мыши: добавляет/отнимает предметы в сетке.",
"block.engineersdecor.labeled_crate": "Labeled Crate",
"block.engineersdecor.labeled_crate.help": "§6A storage crate with 9x6 slots and a built-in item frame at the front.§r\nPlace an item into the frame slot at the bottom right of the GUI to define the shown label.",
"block.engineersdecor.labeled_crate.tip": "§6Label:§r %1$s\n%2$s slots used / %3$s free\n%4$s total items stored",
"block.engineersdecor.treated_wood_side_table": "Столик из обработанного дерева",
"block.engineersdecor.treated_wood_side_table.help": "§6Нужен после того, как работа выполнена.",
"block.engineersdecor.iron_inset_light": "Встраиваемый осветитель",

View file

@ -137,6 +137,7 @@
"block.engineersdecor.treated_wood_crafting_table.help": "§6坚固防风防雨。§r内含八个存储格破坏后保留内容物没有原版合成书。\n 单击上/下箭头按钮可选择合成历史单击输出格自动放置物品单击X按钮 清除合成栏和历史。Shift单击一叠物品合成格空时转移到存储格 非空时到合成栏。会自动分配转移的物品。",
"block.engineersdecor.labeled_crate": "Labeled Crate",
"block.engineersdecor.labeled_crate.help": "§6A storage crate with 9x6 slots and a built-in item frame at the front.§r\nPlace an item into the frame slot at the bottom right of the GUI to define the shown label.",
"block.engineersdecor.labeled_crate.tip": "§6Label:§r %1$s\n%2$s slots used / %3$s free\n%4$s total items stored",
"block.engineersdecor.treated_wood_side_table": "防腐木茶几",
"block.engineersdecor.treated_wood_side_table.help": "§6干完活后需要喝杯茶。",
"block.engineersdecor.iron_inset_light": "嵌入灯",

View file

@ -1,31 +1,20 @@
{
"textures": {
"rsside": "engineersdecor:block/pipe/straight_pipe_valve_side_redstone_texture",
"particle": "engineersdecor:block/pipe/straight_pipe_valve_side_redstone_texture",
"particle": "engineersdecor:block/pipe/straight_pipe_valve_side_texture",
"rsside": "engineersdecor:block/pipe/straight_pipe_valve_side_texture",
"rsend": "engineersdecor:block/pipe/straight_pipe_valve_side_redstone_cn_texture"
},
"elements": [
{
"from": [5, 5, 2],
"from": [5, 5, 0],
"to": [11, 11, 3],
"faces": {
"north": {"uv": [5, 5, 11, 11], "rotation": 90, "texture": "#rsend"},
"east": {"uv": [13, 5, 14, 11], "texture": "#rsside"},
"west": {"uv": [13, 5, 14, 11], "rotation": 180, "texture": "#rsside"},
"up": {"uv": [13, 5, 14, 11], "rotation": 270, "texture": "#rsside"},
"down": {"uv": [13, 5, 14, 11], "rotation": 90, "texture": "#rsside"}
}
},
{
"from": [4, 4, 0],
"to": [12, 12, 2],
"faces": {
"north": {"uv": [4, 4, 12, 12], "rotation": 90, "texture": "#rsend"},
"east": {"uv": [13, 4, 16, 12], "texture": "#rsside"},
"south": {"uv": [4, 4, 12, 12], "texture": "#rsend"},
"west": {"uv": [13, 4, 16, 12], "rotation": 180, "texture": "#rsside"},
"up": {"uv": [13, 4, 16, 12], "rotation": 270, "texture": "#rsside"},
"down": {"uv": [13, 4, 16, 12], "rotation": 90, "texture": "#rsside"}
"east": {"uv": [10, 5, 13, 11], "texture": "#rsside"},
"south": {"uv": [5, 5, 11, 11], "texture": "#rsend"},
"west": {"uv": [3, 5, 6, 11], "texture": "#rsside"},
"up": {"uv": [5, 0, 11, 3], "texture": "#rsside"},
"down": {"uv": [5, 13, 11, 16], "texture": "#rsside"}
}
}
],
@ -41,7 +30,7 @@
"scale": [0.4, 0.4, 0.4]
},
"ground": {
"translation": [0, 1.75, 0],
"translation": [0, 1.75, 0],
"scale": [0.2, 0.2, 0.2]
},
"gui": {

View file

@ -0,0 +1,18 @@
{
"name": "Labeled Crate",
"icon": "engineersdecor:labeled_crate",
"category": "crafting",
"sortnum": 5020,
"pages": [
{
"type": "spotlight",
"title": "Labeled Crate",
"item": "engineersdecor:labeled_crate",
"text": "A high capacity storage crate with space for a custom label at the front.$(br2)In addition to the 54 inventory slots, one slot at the bottom right can be used to define the object shown in the built-in Item Frame."
},
{
"type": "text",
"text": "$(o)§nQuick Move All$()$(br)When using Quick-Move-All (aka shift-ctrl-left-click) on a slot for moving all identical items between the crate storage and the player inventory, the GUI will fill up existing stacks, and then try to insert further stacks into empty slots next to already existing stacks. If no appropriate locations are found, the stacks are moved into the player inventory, and as last option into the hotbar."
}
]
}

View file

@ -2,7 +2,7 @@
"name": "Small Electrical Furnace",
"icon": "engineersdecor:small_electrical_furnace",
"category": "crafting",
"sortnum": 5030,
"sortnum": 5040,
"pages": [
{
"type": "spotlight",

View file

@ -2,7 +2,7 @@
"name": "Small Laboratory Furnace",
"icon": "engineersdecor:small_lab_furnace",
"category": "crafting",
"sortnum": 5020,
"sortnum": 5030,
"pages": [
{
"type": "spotlight",

View file

@ -2,7 +2,7 @@
"name": "Mineral Melting Furnace",
"icon": "engineersdecor:small_mineral_smelter",
"category": "crafting",
"sortnum": 5040,
"sortnum": 5050,
"pages": [
{
"type": "spotlight",

View file

@ -19,7 +19,7 @@
"key": {
"D": { "item": "minecraft:dropper" },
"P": { "tag" : "forge:plates/iron" },
"W": { "item": "forge:treated_wood" }
"W": { "tag" : "forge:treated_wood" }
},
"result": {
"item": "engineersdecor:factory_dropper",

View file

@ -6,20 +6,19 @@
{
"type": "engineersdecor:optional",
"result": "engineersdecor:panzerglass_block",
"required": ["#forge:glass", "#forge:rods/steel", "#forge:gems/diamond"]
"required": ["#forge:glass", "#forge:rods/iron"]
}
],
"recipe": {
"type": "minecraft:crafting_shaped",
"pattern": [
"SGS",
"GDG",
"GSG",
"SGS"
],
"key": {
"G": { "tag": "forge:glass" },
"S": { "tag": "forge:rods/steel" },
"D": { "tag": "forge:gems/diamond" }
"S": { "tag": "forge:rods/iron" }
},
"result": {
"item": "engineersdecor:panzerglass_block",

View file

@ -17,7 +17,7 @@
"PPP"
],
"key": {
"F": { "tag" : "minecraft:furnace" },
"F": { "item" : "minecraft:furnace" },
"C": { "item": "immersiveengineering:connector_lv" },
"H": { "item": "immersiveengineering:conveyor_basic" },
"P": { "tag" : "forge:plates/iron" }

View file

@ -32,6 +32,9 @@ looking manufacturing contraptions. Current feature set:
the crafting output slot to increase or decrease the stack sizes (shift and/or ctrl
higher step size). Shows the placed items on the top of the table.
- *Labeled Crate*: A storage crate with 9x6 slots and a built-in item frame. As known
from IE Crates it keeps its inventory when broken.
- *Small Laboratory Furnace*: Solid fuel consuming, updraught. Slightly hotter and
better isolated than a cobblestone furnace, therefore more efficient. Has internal
hopper FiFos for input, output, and fuel (two stacks each). Two auxilliary slots