Milking machine added. Window placement improved. Pipe valve textures adapted. 1.14: Pipe valve early load replaced with lazy init (issue #69). Mineral Smelter gravity fluid transfer added.

This commit is contained in:
stfwi 2019-12-08 16:53:36 +01:00
parent 01ca043d41
commit 6dacc0922d
31 changed files with 709 additions and 249 deletions

View file

@ -4,4 +4,4 @@ org.gradle.jvmargs=-Xmx8G
version_minecraft=1.12.2
version_forge=14.23.5.2768
version_jei=4.10.0.198
version_engineersdecor=1.0.16
version_engineersdecor=1.0.17-b1

View file

@ -1,6 +1,7 @@
{
"homepage": "https://www.curseforge.com/minecraft/mc-mods/engineers-decor/",
"1.12.2": {
"1.0.17-b1": "[A] Added Milking Machine.\n[M] Window placement improved.\n[M] Made Pipe Valve textures slightly darker to fit IE pipes better when shaded.",
"1.0.16": "[R] Release based on v1.0.16-b3. Release-to-release changes: * Added Gas Concrete blocks/walls/stairs/slabs/slab slices. * Added Fluid Collection Funnel * Crafting yield for Clinker/Slag bricks increased. * Block Placer improvements (cocoa planting) and fixes. * Block breaker compat improvements and fixes. * Recipe compat auto detection fixes. * Feature opt-out and tweak config options for mod packs improved.",
"1.0.16-b3": "[M] Increased slag brick recipe yield to 8.\n[A] Small Block Placer can plant Cocoa.\n[F] Fixed Small Block Placer seed detection issue (issue #64, thx Federsavo).\n[F] Fixed incorrectly enabled alternative recipes for fluid accumulator and check valve when IE is installed.\n[M] Slightly nerfed the Small Solar Panel default peak power output (does not affect existing configurations).",
"1.0.16-b2": "[A] Added Gas Concrete (including slab, wall, stairs, and slab slice).\n[A] Added explicit RF-power-required option for Small Block Breaker and Small Tree Cutter (issue #63).\n[M] Increased clinker brick recipe yield to 8 for the master builders needs.\n[F] Fixed item-on-ground display glitch (issue #61, thx Federsavo for the hint).\n[F] Fixed sign bounding boxes (issue #62, thx angela/themartin).",
@ -70,6 +71,6 @@
},
"promos": {
"1.12.2-recommended": "1.0.16",
"1.12.2-latest": "1.0.16"
"1.12.2-latest": "1.0.17-b1"
}
}

View file

@ -10,6 +10,10 @@ Mod sources for Minecraft version 1.12.2.
----
## Version history
- v1.0.17-b1 [A] Added Milking Machine.
[M] Window placement improved.
[M] Made Pipe Valve textures slightly darker to fit IE pipes better when shaded.
-------------------------------------------------------------------
- v1.0.16 [R] Release based on v1.0.16-b3. Release-to-release changes:
* Added Gas Concrete blocks/walls/stairs/slabs/slab slices.

View file

@ -12,12 +12,11 @@
*/
package wile.engineersdecor;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.annotation.Nonnull;
import wile.engineersdecor.blocks.*;
import wile.engineersdecor.detail.ModAuxiliaries;
import wile.engineersdecor.detail.ModConfig;
import wile.engineersdecor.detail.ModTesrs;
import wile.engineersdecor.items.ItemDecor;
import net.minecraft.block.Block;
import net.minecraft.block.SoundType;
import net.minecraft.block.material.Material;
@ -32,11 +31,11 @@ import net.minecraftforge.fml.client.registry.ClientRegistry;
import net.minecraftforge.fml.common.registry.GameRegistry;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import wile.engineersdecor.blocks.*;
import wile.engineersdecor.detail.ModAuxiliaries;
import wile.engineersdecor.detail.ModConfig;
import wile.engineersdecor.detail.ModTesrs;
import wile.engineersdecor.items.ItemDecor;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.annotation.Nonnull;
@SuppressWarnings("unused")
public class ModContent
@ -545,6 +544,7 @@ public class ModContent
STRAIGHT_CHECK_VALVE, STRAIGHT_REDSTONE_VALVE, STRAIGHT_REDSTONE_ANALOG_VALVE, STRAIGHT_PIPE_VALVE_TEI,
SMALL_FLUID_FUNNEL,SMALL_FLUID_FUNNEL_TEI,
PASSIVE_FLUID_ACCUMULATOR, PASSIVE_FLUID_ACCUMULATOR_TEI,
SMALL_MILKING_MACHINE,SMALL_MILKING_MACHINE_TEI,
CLINKER_BRICK_BLOCK,
CLINKER_BRICK_SLAB,
CLINKER_BRICK_STAIRS,
@ -603,7 +603,6 @@ public class ModContent
PANZERGLASS_SLAB, // @todo: check if another class is needed due to is_side_visible
TREATED_WOOD_FLOOR, // @todo: check if textures need improvement
TEST_BLOCK,TEST_BLOCK_TEI,
SMALL_MILKING_MACHINE,SMALL_MILKING_MACHINE_TEI
};
//--------------------------------------------------------------------------------------------------------------------

View file

@ -11,11 +11,14 @@ package wile.engineersdecor.blocks;
import net.minecraft.block.SoundType;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import javax.annotation.Nonnull;
@ -23,7 +26,6 @@ import javax.annotation.Nullable;
public class BlockDecorWindow extends BlockDecorDirected
{
public BlockDecorWindow(@Nonnull String registryName, long config, @Nullable Material material, float hardness, float resistance, @Nullable SoundType sound, @Nonnull AxisAlignedBB unrotatedAABB)
{ super(registryName, config, material, hardness, resistance, sound, unrotatedAABB); }
@ -58,4 +60,22 @@ public class BlockDecorWindow extends BlockDecorDirected
public boolean doesSideBlockRendering(IBlockState state, IBlockAccess world, BlockPos pos, EnumFacing face)
{ return false; }
@Override
public IBlockState getStateForPlacement(World world, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer, EnumHand hand)
{
facing = placer.getHorizontalFacing();
if(Math.abs(placer.getLookVec().y) > 0.9) {
facing = EnumFacing.getDirectionFromEntityLiving(pos, placer);
} else {
for(EnumFacing f: EnumFacing.values()) {
IBlockState st = world.getBlockState(pos.offset(f));
if(st.getBlock() == this) {
facing = st.getValue(FACING);
break;
}
}
}
return getDefaultState().withProperty(FACING, facing);
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 624 B

After

Width:  |  Height:  |  Size: 605 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 615 B

After

Width:  |  Height:  |  Size: 591 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 544 B

After

Width:  |  Height:  |  Size: 513 B

Before After
Before After

View file

@ -2,7 +2,7 @@
org.gradle.daemon=false
org.gradle.jvmargs=-Xmx8G
version_minecraft=1.14.4
version_forge_minecraft=1.14.4-28.1.90
version_forge_minecraft=1.14.4-28.1.104
version_fml_mappings=20190719-1.14.3
version_jei=1.14.4:6.0.0.10
version_engineersdecor=1.0.16-b7
version_engineersdecor=1.0.17-b1

View file

@ -1,6 +1,7 @@
{
"homepage": "https://www.curseforge.com/minecraft/mc-mods/engineers-decor/",
"1.14.4": {
"1.0.17-b1": "[A] Added Milking Machine.\n[A] Added Mineral Smelter gravity fluid transfer.\n[M] Window placement improved.\n[M] Made Pipe Valve textures slightly darker to fit IE pipes better when shaded.\n[F] Levers can be directly attached to redstone controller Pipe Valves.\n[F] Replaced Pipe Valve early load with lazy initialized data (issue #69, thx @Siriuo).",
"1.0.16-b7": "[M] Forge blockstates ported from 1.12 transformed to vanilla.",
"1.0.16-b6": "[A] Made slab slice left-click pickup optional (default enabled).\n[A] Added config option for device drops in creative mode (addresses #67),\n[F] Fixed Panzer Glass Block submerged display (issue #68, thx WenXin20).",
"1.0.16-b5": "[F] Fixed recipe condition bug (issue #65, thx Nachtflame for the report, and gigaherz & killjoy for the help).",
@ -37,6 +38,6 @@
},
"promos": {
"1.14.4-recommended": "",
"1.14.4-latest": "1.0.16-b7"
"1.14.4-latest": "1.0.17-b1"
}
}

View file

@ -11,6 +11,13 @@ Mod sources for Minecraft version 1.14.4.
## Version history
- v1.0.17-b1 [A] Added Milking Machine.
[A] Added Mineral Smelter gravity fluid transfer.
[M] Window placement improved.
[M] Made Pipe Valve textures slightly darker to fit IE pipes better when shaded.
[F] Levers can be directly attached to redstone controller Pipe Valves.
[F] Replaced Pipe Valve early load with lazy initialized data (issue #69, thx @Siriuo).
- v1.0.16-b7 [M] Forge blockstates ported from 1.12 transformed to vanilla.
- v1.0.16-b6 [A] Made slab slice left-click pickup optional (default enabled).

View file

@ -33,7 +33,6 @@ import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import net.minecraftforge.event.RegistryEvent;
import org.apache.commons.lang3.ArrayUtils;
import java.util.ArrayList;
import java.util.List;
@ -525,6 +524,14 @@ public class ModContent
// -------------------------------------------------------------------------------------------------------------------
public static final BlockDecorTest TEST_BLOCK = (BlockDecorTest)(new BlockDecorTest(
BlockDecor.CFG_LOOK_PLACEMENT|BlockDecor.CFG_FLIP_PLACEMENT_SHIFTCLICK|BlockDecor.CFG_ELECTRICAL|BlockDecor.CFG_REDSTONE_CONTROLLED,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(0f, 32000f).sound(SoundType.METAL),
ModAuxiliaries.getPixeledAABB(0,0,0, 16,16,16)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "test_block"));
// -------------------------------------------------------------------------------------------------------------------
private static final Block modBlocks[] = {
TREATED_WOOD_CRAFTING_TABLE,
SMALL_LAB_FURNACE,
@ -537,6 +544,7 @@ public class ModContent
SMALL_SOLAR_PANEL,
SMALL_WASTE_INCINERATOR,
SMALL_MINERAL_SMELTER,
SMALL_MILKING_MACHINE,
STRAIGHT_CHECK_VALVE,
STRAIGHT_REDSTONE_VALVE,
STRAIGHT_REDSTONE_ANALOG_VALVE,
@ -608,7 +616,7 @@ public class ModContent
};
private static final Block devBlocks[] = {
SMALL_MILKING_MACHINE
//TEST_BLOCK
};
//--------------------------------------------------------------------------------------------------------------------
@ -690,6 +698,10 @@ public class ModContent
.build(null)
.setRegistryName(ModEngineersDecor.MODID, "te_small_tree_cutter");
public static final TileEntityType<?> TET_TEST_BLOCK = TileEntityType.Builder
.create(BlockDecorPipeValve.BTileEntity::new, TEST_BLOCK)
.build(null)
.setRegistryName(ModEngineersDecor.MODID, "te_test_block");
private static final TileEntityType<?> tile_entity_types[] = {
TET_TREATED_WOOD_CRAFTING_TABLE,
@ -707,6 +719,7 @@ public class ModContent
TET_STRAIGHT_PIPE_VALVE,
TET_PASSIVE_FLUID_ACCUMULATOR,
TET_SMALL_FLUID_FUNNEL,
TET_TEST_BLOCK
};
//--------------------------------------------------------------------------------------------------------------------

View file

@ -148,7 +148,7 @@ public class BlockDecorFluidFunnel extends BlockDecor
public static final int MAX_TRACKING_STEPS_PER_CYCLE_INTENSIVE = 1024;
public static final int MAX_TRACK_RADIUS_SQ = MAX_TRACK_RADIUS*MAX_TRACK_RADIUS;
public static final int INTENSIVE_SEARCH_TRIGGER_THRESHOLD = 16;
private FluidStack tank_ = FluidStack.EMPTY.copy();
private FluidStack tank_ = FluidStack.EMPTY;
private int tick_timer_ = 0;
private int collection_timer_ = 0;
private int no_fluid_found_counter_ = 0;
@ -168,7 +168,7 @@ public class BlockDecorFluidFunnel extends BlockDecor
public void readnbt(CompoundNBT nbt)
{
tank_ = (!nbt.contains("tank")) ? (FluidStack.EMPTY.copy()) : (FluidStack.loadFluidStackFromNBT(nbt.getCompound("tank")));
tank_ = (!nbt.contains("tank")) ? (FluidStack.EMPTY) : (FluidStack.loadFluidStackFromNBT(nbt.getCompound("tank")));
}
public void writenbt(CompoundNBT nbt)
@ -200,19 +200,19 @@ public class BlockDecorFluidFunnel extends BlockDecor
@Override public FluidStack drain(FluidStack resource, FluidAction action)
{
if((resource==null) || (te.tank_.isEmpty())) return FluidStack.EMPTY.copy();
return (!(te.tank_.isFluidEqual(resource))) ? (FluidStack.EMPTY.copy()) : drain(resource.getAmount(), action);
if((resource==null) || (te.tank_.isEmpty())) return FluidStack.EMPTY;
return (!(te.tank_.isFluidEqual(resource))) ? (FluidStack.EMPTY) : drain(resource.getAmount(), action);
}
@Override public FluidStack drain(int maxDrain, FluidAction action)
{
if(te.tank_.isEmpty()) return FluidStack.EMPTY;
FluidStack res = te.tank_.copy();
if(res.isEmpty()) return res;
maxDrain = MathHelper.clamp(maxDrain ,0 , te.tank_.getAmount());
res.setAmount(maxDrain);
if(action != FluidAction.EXECUTE) return res;
te.tank_.setAmount(te.tank_.getAmount()-maxDrain);
if(te.tank_.getAmount() <= 0) te.tank_ = FluidStack.EMPTY.copy();
if(te.tank_.getAmount() <= 0) te.tank_ = FluidStack.EMPTY;
return res;
}
}

View file

@ -269,12 +269,12 @@ public class BlockDecorMilker extends BlockDecorDirectedHorizontal
@Override
public FluidStack drain(FluidStack resource, FluidAction action)
{ return (!resource.isFluidEqual(milk_fluid_)) ? (FluidStack.EMPTY.copy()) : drain(resource.getAmount(), action); }
{ return (!resource.isFluidEqual(milk_fluid_)) ? (FluidStack.EMPTY) : drain(resource.getAmount(), action); }
@Override
public FluidStack drain(int maxDrain, FluidAction action)
{
if(te.fluid_level() <= 0) return FluidStack.EMPTY.copy();
if(te.fluid_level() <= 0) return FluidStack.EMPTY;
FluidStack fs = milk_fluid_.copy();
fs.setAmount(Math.min(fs.getAmount(), te.fluid_level()));
if(action==FluidAction.EXECUTE) te.tank_level_ -= fs.getAmount();
@ -300,7 +300,7 @@ public class BlockDecorMilker extends BlockDecorDirectedHorizontal
// ITickable ------------------------------------------------------------------------------------
private void log(String s)
{} // System.out.println("Milker|" + s); may be enabled with config, for dev was println
{} // println("Milker|" + s); may be enabled with config, for dev was println
private static ItemStack milk_filled_container_item(ItemStack stack)
{ return milk_containers_.entrySet().stream().filter(e->e.getKey().isItemEqual(stack)).map(Map.Entry::getValue).findFirst().orElse(ItemStack.EMPTY); }
@ -510,7 +510,7 @@ public class BlockDecorMilker extends BlockDecorDirectedHorizontal
{
@FunctionalInterface public interface TargetPositionInValidCheck { boolean test(SingleMoveGoal goal, IWorldReader world, BlockPos pos); }
@FunctionalInterface public interface StrollEvent { void apply(SingleMoveGoal goal, IWorldReader world, Vec3d pos); }
private static void log(String s) {} // System.out.println(s);
private static void log(String s) {} // println(s);
private static final int motion_timeout = 20*20;
private boolean aborted_;

View file

@ -9,38 +9,42 @@
*/
package wile.engineersdecor.blocks;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import wile.engineersdecor.ModContent;
import wile.engineersdecor.ModEngineersDecor;
import net.minecraft.entity.LivingEntity;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.World;
import net.minecraft.block.*;
import net.minecraft.tileentity.ITickableTileEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.inventory.ISidedInventory;
import net.minecraft.inventory.ItemStackHelper;
import net.minecraft.item.Item;
import net.minecraft.item.Items;
import net.minecraft.item.ItemStack;
import net.minecraft.item.BlockItemUseContext;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.particles.IParticleData;
import net.minecraft.particles.ParticleTypes;
import net.minecraft.tileentity.ITickableTileEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.*;
import net.minecraft.util.math.*;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.block.*;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.state.IntegerProperty;
import net.minecraft.util.*;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.world.World;
import net.minecraft.state.IntegerProperty;
import net.minecraft.state.StateContainer;
import net.minecraft.item.BlockItemUseContext;
import net.minecraft.block.BlockState;
import net.minecraft.world.IBlockReader;
import net.minecraft.fluid.Fluids;
import net.minecraftforge.common.capabilities.ICapabilityProvider;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.energy.CapabilityEnergy;
import net.minecraftforge.energy.IEnergyStorage;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidUtil;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler.FluidAction;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
@ -213,6 +217,7 @@ public class BlockDecorMineralSmelter extends BlockDecorDirectedHorizontal
private static final ItemStack MAGMA_STACK = new ItemStack(Blocks.MAGMA_BLOCK);
private static final ItemStack BUCKET_STACK = new ItemStack(Items.BUCKET);
private static final ItemStack LAVA_BUCKET_STACK = new ItemStack(Items.LAVA_BUCKET);
private static final FluidStack LAVA_BUCKET_FLUID_STACK = new FluidStack(Fluids.LAVA, 1000);
private static int energy_consumption = DEFAULT_ENERGY_CONSUMPTION;
private static int heatup_rate = DEFAULT_HEATUP_RATE;
private static int cooldown_rate = 1;
@ -485,7 +490,7 @@ public class BlockDecorMineralSmelter extends BlockDecorDirectedHorizontal
@Override
public FluidStack drain(FluidStack resource, FluidAction action)
{
if(!resource.isFluidEqual(lava) || (te.fluid_level() <= 0)) return FluidStack.EMPTY.copy();
if(!resource.isFluidEqual(lava) || (te.fluid_level() <= 0)) return FluidStack.EMPTY;
FluidStack stack = new FluidStack(lava, te.fluid_level());
if(action == FluidAction.EXECUTE) te.fluid_level_drain(te.fluid_level());
return stack;
@ -494,7 +499,7 @@ public class BlockDecorMineralSmelter extends BlockDecorDirectedHorizontal
@Override
public FluidStack drain(int maxDrain, FluidAction action)
{
if(te.fluid_level() <= 0) return FluidStack.EMPTY.copy();
if(te.fluid_level() <= 0) return FluidStack.EMPTY;
maxDrain = (action==FluidAction.EXECUTE) ? (te.fluid_level_drain(maxDrain)) : (Math.min(maxDrain, te.fluid_level()));
return new FluidStack(lava, maxDrain);
}
@ -633,7 +638,21 @@ public class BlockDecorMineralSmelter extends BlockDecorDirectedHorizontal
break;
}
}
} else if((phase()==PHASE_LAVA) && (fluid_level() >= MAX_BUCKET_EXTRACT_FLUID_LEVEL)) {
// Fluid transfer check
final IFluidHandler fh = FluidUtil.getFluidHandler(world, getPos().down(), Direction.UP).orElse(null);
if(fh != null) {
int n = fh.fill(LAVA_BUCKET_FLUID_STACK.copy(), FluidAction.SIMULATE);
if(n >= LAVA_BUCKET_FLUID_STACK.getAmount()/2) {
n = fh.fill(LAVA_BUCKET_FLUID_STACK.copy(), FluidAction.EXECUTE);
if(n > 0) {
reset_process();
world.playSound(null, pos, SoundEvents.BLOCK_LAVA_EXTINGUISH, SoundCategory.BLOCKS, 0.3f, 0.7f);
}
}
}
}
// Block state
BlockState state = world.getBlockState(pos);
if((state.getBlock() instanceof BlockDecorMineralSmelter) && (force_block_update_ || (state.get(PHASE) != new_phase))) {
state = state.with(PHASE, new_phase);

View file

@ -112,7 +112,7 @@ public class BlockDecorPassiveFluidAccumulator extends BlockDecorDirected
public void read(CompoundNBT nbt)
{
super.read(nbt);
tank_ = (!nbt.contains("tank")) ? (FluidStack.EMPTY.copy()) : (FluidStack.loadFluidStackFromNBT(nbt.getCompound("tank")));
tank_ = (!nbt.contains("tank")) ? (FluidStack.EMPTY) : (FluidStack.loadFluidStackFromNBT(nbt.getCompound("tank")));
}
@Override
@ -134,8 +134,8 @@ public class BlockDecorPassiveFluidAccumulator extends BlockDecorDirected
@Override public int getTankCapacity(int tank) { return max_flowrate; }
@Override public boolean isFluidValid(int tank, @Nonnull FluidStack stack) { return true; }
@Override public int fill(FluidStack resource, FluidAction action) { return 0; }
@Override public FluidStack drain(FluidStack resource, FluidAction action) { return FluidStack.EMPTY.copy(); }
@Override public FluidStack drain(int maxDrain, FluidAction action) { return FluidStack.EMPTY.copy(); }
@Override public FluidStack drain(FluidStack resource, FluidAction action) { return FluidStack.EMPTY; }
@Override public FluidStack drain(int maxDrain, FluidAction action) { return FluidStack.EMPTY; }
}
// Output flow handler ---------------------------------------------------------------------
@ -152,21 +152,21 @@ public class BlockDecorPassiveFluidAccumulator extends BlockDecorDirected
@Override public FluidStack drain(FluidStack resource, FluidAction action)
{
if((resource==null) || (te.tank_.isEmpty())) return FluidStack.EMPTY.copy();
return (!(te.tank_.isFluidEqual(resource))) ? (FluidStack.EMPTY.copy()) : drain(resource.getAmount(), action);
if((resource==null) || (te.tank_.isEmpty())) return FluidStack.EMPTY;
return (!(te.tank_.isFluidEqual(resource))) ? (FluidStack.EMPTY) : drain(resource.getAmount(), action);
}
@Override public FluidStack drain(int maxDrain, FluidAction action)
{
if(!te.initialized_) FluidStack.EMPTY.copy();
if(!te.initialized_) return FluidStack.EMPTY;
if((action==FluidAction.EXECUTE) && (maxDrain > 0)) te.last_drain_request_amount_ = maxDrain;
if(te.tank_.isEmpty()) return FluidStack.EMPTY.copy();
if(te.tank_.isEmpty()) return FluidStack.EMPTY;
maxDrain = MathHelper.clamp(maxDrain ,0 , te.tank_.getAmount());
FluidStack res = te.tank_.copy();
if(action!=FluidAction.EXECUTE) return res;
res.setAmount(maxDrain);
te.tank_.setAmount(te.tank_.getAmount()-maxDrain);
if(te.tank_.getAmount() <= 0) te.tank_ = FluidStack.EMPTY.copy();
if(te.tank_.getAmount() <= 0) te.tank_ = FluidStack.EMPTY;
te.total_volume_drained_ += res.getAmount();
return res;
}
@ -232,7 +232,7 @@ public class BlockDecorPassiveFluidAccumulator extends BlockDecorDirected
if(fh==null) continue;
if(tank_.isEmpty()) {
FluidStack res = fh.drain(n_requested, FluidAction.EXECUTE).copy();
if(res.getAmount()==0) continue;
if(res.isEmpty()) continue;
total_volume_filled_ += res.getAmount();
tank_ = res.copy();
has_refilled = true;
@ -240,7 +240,9 @@ public class BlockDecorPassiveFluidAccumulator extends BlockDecorDirected
if((tank_.getAmount() + n_requested) > max_flowrate) n_requested = (max_flowrate - tank_.getAmount());
FluidStack rq = tank_.copy();
rq.setAmount(n_requested);
FluidStack res = fh.drain(rq, FluidAction.EXECUTE);
FluidStack res = fh.drain(rq, FluidAction.SIMULATE);
if(!res.isFluidEqual(rq)) continue;
res = fh.drain(rq, FluidAction.EXECUTE);
if(res.isEmpty()) continue;
tank_.setAmount(tank_.getAmount()+res.getAmount());
total_volume_filled_ += res.getAmount();

View file

@ -11,24 +11,27 @@ package wile.engineersdecor.blocks;
import wile.engineersdecor.ModContent;
import wile.engineersdecor.ModEngineersDecor;
import net.minecraft.block.IWaterLoggable;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.state.BooleanProperty;
import net.minecraft.world.IWorld;
import net.minecraft.item.BlockItemUseContext;
import net.minecraft.state.StateContainer;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.world.World;
import net.minecraft.world.IBlockReader;
import net.minecraft.state.BooleanProperty;
import net.minecraft.state.StateContainer;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.item.ItemStack;
import net.minecraft.entity.LivingEntity;
import net.minecraft.block.IWaterLoggable;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
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.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.shapes.ISelectionContext;
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.util.math.shapes.VoxelShapes;
import net.minecraftforge.common.capabilities.ICapabilityProvider;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fluids.FluidStack;
@ -82,12 +85,16 @@ public class BlockDecorPipeValve extends BlockDecorDirected implements IWaterLog
return state;
}
private void update_te(World world, BlockState state, BlockPos pos)
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);
}
@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, WATERLOGGED); }
@ -103,7 +110,10 @@ public class BlockDecorPipeValve extends BlockDecorDirected implements IWaterLog
@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); }
{
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)
@ -112,19 +122,6 @@ public class BlockDecorPipeValve extends BlockDecorDirected implements IWaterLog
world.notifyNeighborsOfStateChange(pos,this);
}
@Deprecated
@SuppressWarnings("deprecation")
public void neighborChanged(BlockState state, World world, BlockPos pos, Block block, BlockPos fromPos)
{
Direction fc = state.get(FACING);
if(fromPos.equals(pos.offset(fc)) || fromPos.equals(pos.offset(fc.getOpposite()))) {
update_te(world, state, pos);
} else {
BlockState connector_state = get_rsconnector_state(state, world, pos, fromPos);
if(!state.equals(connector_state)) world.setBlockState(pos, connector_state);
}
}
@Override
public boolean hasTileEntity(BlockState state)
{ return true; }
@ -146,50 +143,34 @@ public class BlockDecorPipeValve extends BlockDecorDirected implements IWaterLog
{
protected static int fluid_maxflow_mb = 1000;
protected static int redstone_flow_slope_mb = 1000/15;
// private final IFluidTankProperties[] fluid_props_ = {this};
private Direction block_facing_ = Direction.NORTH;
private Direction block_facing_ = null;
private boolean filling_ = false;
private boolean getlocked_ = false;
private boolean filling_enabled_ = true;
private long block_config_ = 0;
public BTileEntity()
{ this(ModContent.TET_STRAIGHT_PIPE_VALVE); }
public BTileEntity(TileEntityType<?> te_type)
{ super(te_type); }
public void block_reconfigure(Direction facing, long block_config)
{
block_facing_ = facing;
block_config_ = block_config;
filling_enabled_ = false;
// IFluidHandler fh = forward_fluid_handler();
// if(fh!=null) {
// if(fh.getTankProperties().length==0) {
// filling_enabled_ = true; // we don't know, so in doubt try filling.
// } else {
// for(IFluidTankProperties fp:fh.getTankProperties()) {
// if((fp!=null) && (fp.canFill())) { filling_enabled_ = true; break; }
// }
// }
// }
}
private Direction block_facing()
{
if(block_facing_ == null) {
BlockState st = getWorld().getBlockState(getPos());
block_facing_ = (st.getBlock() instanceof BlockDecorPipeValve) ? st.get(FACING) : Direction.NORTH;
}
return block_facing_;
}
// TileEntity ------------------------------------------------------------------------------
@Override
public void onLoad()
{
if(!hasWorld()) return;
final BlockState state = world.getBlockState(pos);
if((!(state.getBlock() instanceof BlockDecorPipeValve))) return;
block_reconfigure(state.get(FACING), block_config_);
world.notifyNeighborsOfStateChange(pos, state.getBlock());
}
@Override
public void read(CompoundNBT nbt)
{
@ -203,7 +184,7 @@ public class BlockDecorPipeValve extends BlockDecorDirected implements IWaterLog
public CompoundNBT write(CompoundNBT nbt)
{
super.write(nbt);
nbt.putInt("facing", block_facing_.getIndex());
if(block_facing_!=null) nbt.putInt("facing", block_facing_.getIndex());
nbt.putLong("conf", block_config_);
return nbt;
}
@ -218,8 +199,8 @@ public class BlockDecorPipeValve extends BlockDecorDirected implements IWaterLog
{
if(!this.removed && (facing != null)) {
if(capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) {
if(facing == block_facing_) return fluid_handler_.cast();
if(facing == block_facing_.getOpposite()) return back_flow_handler_.cast();
if(facing == block_facing()) return back_flow_handler_.cast();
if(facing == block_facing().getOpposite()) return fluid_handler_.cast();
}
}
return super.getCapability(capability, facing);
@ -230,9 +211,9 @@ public class BlockDecorPipeValve extends BlockDecorDirected implements IWaterLog
@Nullable
private IFluidHandler forward_fluid_handler()
{
final TileEntity te = world.getTileEntity(pos.offset(block_facing_));
final TileEntity te = world.getTileEntity(pos.offset(block_facing()));
if(te == null) return null;
return te.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, block_facing_.getOpposite()).orElse(null);
return te.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, block_facing().getOpposite()).orElse(null);
}
// Forward flow handler --
@ -244,13 +225,15 @@ public class BlockDecorPipeValve extends BlockDecorDirected implements IWaterLog
@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 FluidStack drain(FluidStack resource, FluidAction action) { return FluidStack.EMPTY.copy(); }
@Override public FluidStack drain(int maxDrain, FluidAction action) { return FluidStack.EMPTY.copy(); }
@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_) || (!te.filling_enabled_)) return 0;
if(te.filling_) return 0;
final IFluidHandler fh = te.forward_fluid_handler();
if(fh==null) return 0;
if((te.block_config_ & CFG_REDSTONE_CONTROLLED) != 0) {
int rs = te.world.getRedstonePowerFromNeighbors(te.pos);
if(rs <= 0) return 0;
@ -258,17 +241,15 @@ public class BlockDecorPipeValve extends BlockDecorDirected implements IWaterLog
}
FluidStack res = resource.copy();
if(res.getAmount() > fluid_maxflow_mb) res.setAmount(fluid_maxflow_mb);
final IFluidHandler fh = te.forward_fluid_handler();
if(fh==null) return 0;
te.filling_ = true; // in case someone does not check the cap, but just "forwards back" what is beeing filled right now.
//if(res.amount > 50) {
//final TileEntity te = te.world.getTileEntity(te.pos.offset(te.block_facing_));
//if(te instanceof IFluidPipe) {
// // forward pressureized tag
// if(res.tag == null) res.tag = new CompoundNBT();
// res.tag.putBoolean("pressurized", true);
//}
//}
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;
@ -284,21 +265,21 @@ public class BlockDecorPipeValve extends BlockDecorDirected implements IWaterLog
@Override public int getTankCapacity(int tank) { return 0; }
@Override public boolean isFluidValid(int tank, @Nonnull FluidStack stack) { return false; }
@Override public int fill(FluidStack resource, FluidAction action) { return 0; }
@Override public FluidStack drain(FluidStack resource, FluidAction action) { return FluidStack.EMPTY.copy(); }
@Override public FluidStack drain(int maxDrain, FluidAction action) { return FluidStack.EMPTY.copy(); }
@Override public FluidStack drain(FluidStack resource, FluidAction action) { return FluidStack.EMPTY; }
@Override public FluidStack drain(int maxDrain, FluidAction action) { return FluidStack.EMPTY; }
}
// IFluidPipe
// IE IFluidPipe
// @Override
// public boolean hasOutputConnection(Direction side)
// { return (side == block_facing_); }
// { 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_));
// 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);

View file

@ -418,12 +418,19 @@ public class BlockDecorPlacer extends BlockDecorDirected
{ return (i<NUM_OF_SLOTS-1) ? (i+1) : 0; }
private boolean spit_out(Direction facing)
{ return spit_out(facing, false); }
private boolean spit_out(Direction facing, boolean all)
{
ItemStack stack = stacks_.get(current_slot_index_);
ItemStack drop = stack.copy();
if(!all) {
stack.shrink(1);
stacks_.set(current_slot_index_, stack);
drop.setCount(1);
} else {
stacks_.set(current_slot_index_, ItemStack.EMPTY);
}
for(int i=0; i<8; ++i) {
BlockPos p = pos.offset(facing, i);
if(!world.isAirBlock(p)) continue;
@ -486,7 +493,7 @@ public class BlockDecorPlacer extends BlockDecorDirected
block = Blocks.AIR;
no_space = true;
}
// System.out.println("PLACE " + current_stack + " --> " + block + " at " + placement_pos.subtract(pos) + "( item=" + item + ")");
// println("PLACE " + current_stack + " --> " + block + " at " + placement_pos.subtract(pos) + "( item=" + item + ")");
if(block != Blocks.AIR) {
try {
BlockItemUseContext use_context = null;
@ -524,9 +531,9 @@ public class BlockDecorPlacer extends BlockDecorDirected
// The block really needs a player or other issues happened during placement.
// A hard crash should not be fired here, instead spit out the item to indicated that this
// block is not compatible.
System.out.println("Exception while trying to place " + e);
ModEngineersDecor.logger().error("Exception while trying to place " + ((block==null)?(""):(""+block)) + ", spitting out. Exception is: " + e);
world.removeBlock(placement_pos, false);
return spit_out(facing);
return spit_out(facing, true);
}
}
if((!no_space) && (!current_stack.isEmpty())) {

View file

@ -0,0 +1,312 @@
/*
* @file BlockDecorTest.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2019 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)
*
* Creative mod testing block
*/
package wile.engineersdecor.blocks;
import wile.engineersdecor.ModContent;
import wile.engineersdecor.detail.ModAuxiliaries;
import wile.engineersdecor.detail.ModAuxiliaries.IExperimentalFeature;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.World;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.ITickableTileEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.fluid.Fluids;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.util.Hand;
import net.minecraft.util.Direction;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.shapes.ISelectionContext;
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.util.math.shapes.VoxelShapes;
import net.minecraftforge.common.capabilities.ICapabilityProvider;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.IFluidHandler.FluidAction;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandlerItem;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
public class BlockDecorTest extends BlockDecorDirected implements IExperimentalFeature
{
public BlockDecorTest(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
{ super(config, builder, unrotatedAABB); }
@Override
public VoxelShape getCollisionShape(BlockState state, IBlockReader world, BlockPos pos, ISelectionContext selectionContext)
{ return VoxelShapes.fullCube(); }
@Override
public boolean hasTileEntity(BlockState state)
{ return true; }
@Override
@Nullable
public TileEntity createTileEntity(BlockState state, IBlockReader world)
{ return new BTileEntity(); }
@Override
public boolean canConnectRedstone(BlockState state, IBlockReader world, BlockPos pos, @Nullable Direction side)
{ return true; }
@Override
public boolean hasDynamicDropList()
{ return true; }
@Override
public List<ItemStack> dropList(BlockState state, World world, BlockPos pos, boolean explosion)
{
// @todo ... there was something like single element list or so ...
ArrayList<ItemStack> list = new ArrayList<ItemStack>();
list.add(new ItemStack(this, 1));
return list;
}
@Override
@SuppressWarnings("deprecation")
public boolean onBlockActivated(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockRayTraceResult hit)
{
TileEntity te = world.getTileEntity(pos);
if(!(te instanceof BTileEntity)) return false;
((BTileEntity)te).activated(player, hand, hit);
return true;
}
//--------------------------------------------------------------------------------------------------------------------
// Tile entity
//--------------------------------------------------------------------------------------------------------------------
public static class BTileEntity extends TileEntity implements ITickableTileEntity, ICapabilityProvider //, IItemHandler, IEnergyStorage
{
private int tick_interval_ = 10;
private int passive_tank_capacity_ = 32000;
private FluidStack passive_tank_ = FluidStack.EMPTY;
private FluidStack passive_drain_fluidstack_ = new FluidStack(Fluids.WATER, 1000);
private int passive_drain_max_flowrate_ = 1000;
private int passive_fill_max_flowrate_ = 1000;
private int passive_num_drained_general_mb_ = 0;
private int passive_num_drained_specific_mb_ = 0;
private int passive_num_filled_specific_mb_ = 0;
private int passive_num_fh_interactions_ = 0;
private FluidStack active_fill_fluidstack_ = FluidStack.EMPTY;
private int active_num_filled_ = 0;
private int tick_timer_ = 0;
// ------------------------------------------------------------------------------------------
public BTileEntity()
{ this(ModContent.TET_TEST_BLOCK); }
public BTileEntity(TileEntityType<?> te_type)
{ super(te_type); }
// ------------------------------------------------------------------------------------------
private Direction block_facing()
{
BlockState st = getWorld().getBlockState(getPos());
return (st.getBlock() instanceof BlockDecorTest) ? st.get(FACING) : Direction.NORTH;
}
private String dump_fluid_stack(FluidStack fs)
{
String s = "";
if(fs.getFluid().getRegistryName().getNamespace() != "minecraft") s += fs.getFluid().getRegistryName().getNamespace()+":";
s += fs.getFluid().getRegistryName().getPath();
s += " x" + fs.getAmount();
return "[" + s + "]";
}
public void activated(PlayerEntity player, Hand hand, BlockRayTraceResult hit)
{
if(world.isRemote()) return;
final ItemStack held_stack = player.getHeldItem(hand);
// Empty hand -> statistics
{
if(held_stack.isEmpty()) {
String message = "";
if(passive_num_filled_specific_mb_>0 || passive_num_drained_specific_mb_>0 || passive_num_drained_general_mb_>0) {
message += "Fluid handler: filled:" + passive_num_filled_specific_mb_ + ", drained:" + (passive_num_drained_specific_mb_+ passive_num_drained_general_mb_) + ", interactions:" + passive_num_fh_interactions_ + "\n";
}
if(active_num_filled_>0) {
message += "Fluid insertion:" + active_num_filled_ + "mb, (current:" + dump_fluid_stack(active_fill_fluidstack_) + ")\n";
}
if(message.isEmpty()) {
message = "No fluid, energy, or item interactions done yet.";
}
ModAuxiliaries.playerChatMessage(player, message);
return;
}
}
// Fluid container -> set fluid to insert, increase/decrease amount.
{
final IFluidHandlerItem fhi = held_stack.getCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY).orElse(null);
if((fhi != null)) {
int ntanks = fhi.getTanks();
if(ntanks == 0) return;
int capacity = fhi.getTankCapacity(0);
FluidStack fs = fhi.drain(capacity, FluidAction.SIMULATE);
if(!fs.isEmpty()) {
if(active_fill_fluidstack_.isEmpty()) {
active_fill_fluidstack_ = fs.copy();
ModAuxiliaries.playerChatMessage(player, "Fluid insertion fluid set: " + dump_fluid_stack(active_fill_fluidstack_));
} else if(fs.isFluidEqual(active_fill_fluidstack_)) {
active_fill_fluidstack_.grow(fs.getAmount());
ModAuxiliaries.playerChatMessage(player, "Fluid insertion flowrate increased: " + dump_fluid_stack(active_fill_fluidstack_));
} else {
int amount = active_fill_fluidstack_.getAmount();
active_fill_fluidstack_ = fs.copy();
active_fill_fluidstack_.setAmount(amount);
ModAuxiliaries.playerChatMessage(player, "Fluid insertion fluid changed: " + dump_fluid_stack(active_fill_fluidstack_));
}
} else {
if(!active_fill_fluidstack_.isEmpty()) {
active_fill_fluidstack_.shrink(1000);
if(active_fill_fluidstack_.isEmpty()) active_fill_fluidstack_ = FluidStack.EMPTY;
ModAuxiliaries.playerChatMessage(player, "Fluid insertion flowrate decreased: " + dump_fluid_stack(active_fill_fluidstack_));
} else {
ModAuxiliaries.playerChatMessage(player, "Fluid insertion disabled.");
}
}
passive_drain_fluidstack_ = active_fill_fluidstack_.copy(); // currently no difference
return;
}
}
}
// TileEntity ------------------------------------------------------------------------------
@Override
public void read(CompoundNBT nbt)
{
super.read(nbt);
if(nbt.contains("passive_tank")) passive_tank_ = FluidStack.loadFluidStackFromNBT(nbt.getCompound("passive_tank"));
if(nbt.contains("passive_drain")) passive_drain_fluidstack_ = FluidStack.loadFluidStackFromNBT(nbt.getCompound("passive_drain"));
if(nbt.contains("active")) active_fill_fluidstack_ = FluidStack.loadFluidStackFromNBT(nbt.getCompound("active"));
}
@Override
public CompoundNBT write(CompoundNBT nbt)
{
super.write(nbt);
if(!passive_tank_.isEmpty()) nbt.put("passive_tank", passive_tank_.writeToNBT(new CompoundNBT()));
if(!passive_drain_fluidstack_.isEmpty()) nbt.put("passive_drain", passive_drain_fluidstack_.writeToNBT(new CompoundNBT()));
if(!active_fill_fluidstack_.isEmpty()) nbt.put("active", active_fill_fluidstack_.writeToNBT(new CompoundNBT()));
return nbt;
}
// ICapabilityProvider --------------------------------------------------------------------
private LazyOptional<IFluidHandler> fluid_handler_ = LazyOptional.of(() -> (IFluidHandler)new MainFluidHandler(this));
@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();
}
}
return super.getCapability(capability, facing);
}
// IFluidHandler ---------------------------------------------------------------------------
private static class MainFluidHandler implements IFluidHandler
{
private BTileEntity te;
public MainFluidHandler(BTileEntity te)
{ this.te = te; }
@Override public int getTanks()
{ return 1; }
@Override public FluidStack getFluidInTank(int tank)
{ return FluidStack.EMPTY; }
@Override public int getTankCapacity(int tank)
{ return te.passive_tank_capacity_; }
@Override public FluidStack drain(FluidStack resource, FluidAction action)
{
++te.passive_num_fh_interactions_;
if(resource.isEmpty()) return FluidStack.EMPTY;
if(!resource.isFluidEqual(te.passive_drain_fluidstack_)) return FluidStack.EMPTY;
FluidStack st = resource.copy();
st.setAmount(MathHelper.clamp(st.getAmount(), 0, te.passive_drain_max_flowrate_));
if(st.isEmpty()) return FluidStack.EMPTY;
if(action==FluidAction.EXECUTE) te.passive_num_drained_specific_mb_ += st.getAmount();
return st;
}
@Override public FluidStack drain(int maxDrain, FluidAction action)
{
++te.passive_num_fh_interactions_;
maxDrain = MathHelper.clamp(maxDrain, 0, te.passive_drain_max_flowrate_);
if((te.passive_drain_fluidstack_.isEmpty()) || (maxDrain<=0)) return FluidStack.EMPTY;
if(action==FluidAction.EXECUTE) te.passive_num_drained_general_mb_ += maxDrain;
FluidStack st = te.passive_drain_fluidstack_.copy();
st.setAmount(maxDrain);
return st;
}
@Override public boolean isFluidValid(int tank, @Nonnull FluidStack stack)
{ return true; }
@Override public int fill(FluidStack resource, FluidAction action)
{
++te.passive_num_fh_interactions_;
int amount = MathHelper.clamp(resource.getAmount(), 0, te.passive_fill_max_flowrate_);
if(action == FluidAction.EXECUTE) {
te.passive_num_filled_specific_mb_ += amount;
if(te.passive_tank_.isFluidEqual(resource)) {
int level = (int)MathHelper.clamp((long)te.passive_tank_.getAmount() + (long)amount, (long)0, (long)Integer.MAX_VALUE);
te.passive_tank_.setAmount(level);
}
}
return amount;
}
}
// ITickableTileEntity ----------------------------------------------------------------------
private void fluid_insertion()
{
if(active_fill_fluidstack_.isEmpty()) return;
final TileEntity te = world.getTileEntity(pos.offset(block_facing()));
if(te == null) return;
final IFluidHandler fh = te.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, block_facing().getOpposite()).orElse(null);
if(fh == null) return;
int filled = fh.fill(active_fill_fluidstack_.copy(), FluidAction.EXECUTE);
active_num_filled_ += filled;
}
@Override
public void tick()
{
if(world.isRemote) return;
if(--tick_timer_ > 0) return;
tick_interval_ = MathHelper.clamp(tick_interval_ ,1 , 200);
tick_timer_ = tick_interval_;
fluid_insertion();
}
}
}

View file

@ -11,12 +11,16 @@ package wile.engineersdecor.blocks;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.IWaterLoggable;
import net.minecraft.item.BlockItemUseContext;
import net.minecraft.state.StateContainer;
import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.Direction;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import javax.annotation.Nullable;
public class BlockDecorWindow extends BlockDecorDirected implements IWaterLoggable
{
public BlockDecorWindow(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
@ -35,4 +39,24 @@ public class BlockDecorWindow extends BlockDecorDirected implements IWaterLoggab
@Override
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder)
{ super.fillStateContainer(builder); builder.add(WATERLOGGED); }
@Override
@Nullable
public BlockState getStateForPlacement(BlockItemUseContext context)
{
Direction facing = context.getPlacementHorizontalFacing();
if(Math.abs(context.getPlayer().getLookVec().y) > 0.9) {
facing = context.getNearestLookingDirection();
} else {
for(Direction f: Direction.values()) {
BlockState st = context.getWorld().getBlockState(context.getPos().offset(f));
if(st.getBlock() == this) {
facing = st.get(FACING);
break;
}
}
}
return super.getStateForPlacement(context).with(FACING, facing);
}
}

View file

@ -1,7 +1,7 @@
# @file mods.toml
# @spec TOML v0.5.0 (https://github.com/toml-lang/toml)
modLoader="javafml" # forge FML java
loaderVersion="[25,)"
modLoader="javafml"
loaderVersion="[28,)"
issueTrackerURL="https://github.com/stfwi/engineers-decor/issues/"
[[mods]]

View file

@ -0,0 +1,10 @@
{
"variants": {
"facing=north": { "model": "engineersdecor:block/generic/test_block_model" },
"facing=south": { "model": "engineersdecor:block/generic/test_block_model", "y":180 },
"facing=west": { "model": "engineersdecor:block/generic/test_block_model", "y":270 },
"facing=east": { "model": "engineersdecor:block/generic/test_block_model", "y":90 },
"facing=up": { "model": "engineersdecor:block/generic/test_block_model", "x":270 },
"facing=down": { "model": "engineersdecor:block/generic/test_block_model", "x":90 }
}
}

View file

@ -0,0 +1,39 @@
{
"parent": "block/block",
"textures": {
"top": "engineersdecor:block/furnace/small_electrical_furnace_top",
"particle": "engineersdecor:block/furnace/small_electrical_furnace_top",
"bottom": "engineersdecor:block/furnace/small_electrical_furnace_bottom",
"left": "engineersdecor:block/furnace/small_electrical_furnace_left",
"right": "engineersdecor:block/furnace/small_electrical_furnace_right",
"front": "engineersdecor:block/furnace/small_electrical_furnace_front",
"back": "engineersdecor:block/furnace/small_electrical_furnace_back"
},
"elements": [
{
"from": [0, 0, 0],
"to": [16, 16, 16],
"faces": {
"north": {"texture": "#front"},
"east": {"texture": "#right"},
"south": {"texture": "#back"},
"west": {"texture": "#left"},
"up": {"texture": "#top"},
"down": {"texture": "#bottom"}
}
}
],
"display": {
"ground": {
"translation": [0, 1.75, 0],
"scale": [0.2, 0.2, 0.2]
},
"gui": {
"rotation": [30, 225, 0],
"scale": [0.625, 0.625, 0.625]
},
"fixed": {
"scale": [0.5, 0.5, 0.5]
}
}
}

View file

@ -0,0 +1,12 @@
{
"parent": "engineersdecor:block/generic/directed_cube",
"textures": {
"top": "engineersdecor:block/furnace/small_electrical_furnace_bottom",
"particle": "engineersdecor:block/furnace/small_electrical_furnace_bottom",
"bottom": "engineersdecor:block/furnace/small_electrical_furnace_bottom",
"left": "engineersdecor:block/furnace/small_electrical_furnace_bottom",
"right": "engineersdecor:block/furnace/small_electrical_furnace_bottom",
"front": "engineersdecor:block/furnace/small_electrical_furnace_top",
"back": "engineersdecor:block/furnace/small_electrical_furnace_bottom"
}
}

View file

@ -1 +1 @@
{ "parent": "engineersdecor:block/pipe/straight_pipe_valve_model" }
{ "parent": "engineersdecor:block/pipe/straight_pipe_valve_redstone_analog_model" }

View file

@ -0,0 +1 @@
{ "parent": "engineersdecor:block/generic/test_block_model" }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 624 B

After

Width:  |  Height:  |  Size: 605 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 615 B

After

Width:  |  Height:  |  Size: 591 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 544 B

After

Width:  |  Height:  |  Size: 513 B

Before After
Before After

View file

@ -2,11 +2,12 @@
"homepage": "https://www.curseforge.com/minecraft/mc-mods/engineers-decor/",
"promos": {
"1.12.2-recommended": "1.0.16",
"1.12.2-latest": "1.0.16",
"1.12.2-latest": "1.0.17-b1",
"1.14.4-recommended": "",
"1.14.4-latest": "1.0.16-b7"
"1.14.4-latest": "1.0.17-b1"
},
"1.12.2": {
"1.0.17-b1": "[A] Added Milking Machine.\n[M] Window placement improved.\n[M] Made Pipe Valve textures slightly darker to fit IE pipes better when shaded.",
"1.0.16": "[R] Release based on v1.0.16-b3. Release-to-release changes: * Added Gas Concrete blocks/walls/stairs/slabs/slab slices. * Added Fluid Collection Funnel * Crafting yield for Clinker/Slag bricks increased. * Block Placer improvements (cocoa planting) and fixes. * Block breaker compat improvements and fixes. * Recipe compat auto detection fixes. * Feature opt-out and tweak config options for mod packs improved.",
"1.0.16-b3": "[M] Increased slag brick recipe yield to 8.\n[A] Small Block Placer can plant Cocoa.\n[F] Fixed Small Block Placer seed detection issue (issue #64, thx Federsavo).\n[F] Fixed incorrectly enabled alternative recipes for fluid accumulator and check valve when IE is installed.\n[M] Slightly nerfed the Small Solar Panel default peak power output (does not affect existing configurations).",
"1.0.16-b2": "[A] Added Gas Concrete (including slab, wall, stairs, and slab slice).\n[A] Added explicit RF-power-required option for Small Block Breaker and Small Tree Cutter (issue #63).\n[M] Increased clinker brick recipe yield to 8 for the master builders needs.\n[F] Fixed item-on-ground display glitch (issue #61, thx Federsavo for the hint).\n[F] Fixed sign bounding boxes (issue #62, thx angela/themartin).",
@ -75,6 +76,7 @@
"1.0.0-b1": "[A] Initial structure.\n[A] Added clinker bricks and clinker brick stairs.\n[A] Added slag bricks and slag brick stairs.\n[A] Added metal rung ladder.\n[A] Added staggered metal steps ladder.\n[A] Added treated wood ladder.\n[A] Added treated wood pole.\n[A] Added treated wood table."
},
"1.14.4": {
"1.0.17-b1": "[A] Added Milking Machine.\n[A] Added Mineral Smelter gravity fluid transfer.\n[M] Window placement improved.\n[M] Made Pipe Valve textures slightly darker to fit IE pipes better when shaded.\n[F] Levers can be directly attached to redstone controller Pipe Valves.\n[F] Replaced Pipe Valve early load with lazy initialized data (issue #69, thx @Siriuo).",
"1.0.16-b7": "[M] Forge blockstates ported from 1.12 transformed to vanilla.",
"1.0.16-b6": "[A] Made slab slice left-click pickup optional (default enabled).\n[A] Added config option for device drops in creative mode (addresses #67),\n[F] Fixed Panzer Glass Block submerged display (issue #68, thx WenXin20).",
"1.0.16-b5": "[F] Fixed recipe condition bug (issue #65, thx Nachtflame for the report, and gigaherz & killjoy for the help).",

View file

@ -227,15 +227,17 @@ commits.
### Community references
Mods covering similar features, or may fit well together with IE and the decorations of this mod:
Mods covering similar features, or may fit well together with IE and the decorations or features of this mod:
- [Immersive Engineering](https://github.com/BluSunrize/ImmersiveEngineering/): Without IE, my
little mod here does not make much sense ;). It works without IE, but quite a few blocks are
not craftable.
little mod here does not make much sense ;). It works without IE ("standalone recipes" are automatically
selected), but the vanilla-ingredient based recipes are not as good compared to the available IE items.
- [Engineer's doors](https://www.curseforge.com/minecraft/mc-mods/engineers-doors) has brilliant
doors, trapdoors, and fence doors, all made of the IE materials.
- [Immersive Posts](https://www.curseforge.com/minecraft/mc-mods/immersiveposts) provides extensible wire posts.
- [Dirty Bricks](https://www.curseforge.com/minecraft/texture-packs/dirty-bricks-vanilla-add-on) applies
position dependent variations to the vanilla bricks, similar to the clinkers and slag bricks in this
mod.
@ -243,6 +245,10 @@ Mods covering similar features, or may fit well together with IE and the decorat
- [Chisel](https://www.curseforge.com/minecraft/mc-mods/chisel) needless to say, Chisel has a variety
of factory blocks.
- [Actually Additions](https://www.curseforge.com/minecraft/mc-mods/actually-additions) and [Cyclic](https://www.curseforge.com/minecraft/mc-mods/cyclic)
also have a block breakers and block placers.
### Screenshots
![Concrete](documentation/engineers-decor-v100a-concrete-stuff.png)