Release merge v1.0.10-mc1.12.2.

This commit is contained in:
stfwi 2019-08-10 14:20:54 +02:00
commit 2ab59b12ae
762 changed files with 19291 additions and 175 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.9
version_engineersdecor=1.0.10

View file

@ -1,6 +1,9 @@
{
"homepage": "https://www.curseforge.com/minecraft/mc-mods/engineers-decor/",
"1.12.2": {
"1.0.10": "[R] Release based on v1.0.10-b2. Release-to-release changes: * Steel table added. * Steel floor grating added. * Treated wood side table added. * Exit Sign added. * Recipe fixes.",
"1.0.10-b2": "[A] Steel table added.\n[A] Steel floor grating added.",
"1.0.10-b1": "[A] Treated wood side table added.\n[F] Fixed recipe collision of Metal Rung Ladder (issue #37, thx ProsperCraft for reporting).\n[A] Added Exit Sign (texture design by J. Carver).",
"1.0.9": "[R] Release based on v1.0.9-b3. Release-to-release changes: * Slabs for clinker, concrete, slag bricks. * Slab slices for sheet metals, treated wood, and concretes. * Language updates. * Block hardness adaptions. * 1st/3rd person item model fixes. * Furnace initialisation issue fixed.",
"1.0.9-b3": "[A] Added missing recipes for slabs.\n[A] Added slab slices for IE sheet metals, treated wood, and concretes (stackable \"quater-slabs\").\n[M] Updated 1st/3rd person item model rotations/translations.\n[M] Hardness of valves and furni slightly increased.",
"1.0.9-b2": "[A] Added slabs for Clinker Brick, Slag Brick, Rebar Concrete, and Stained Clinker. Texture variations like the base blocks. Allow fast pick-up (see tooltip help or config).\n[F] Fixed lab/electrical furnace initialisation issue (first item inserted was smelted directly).",
@ -47,7 +50,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."
},
"promos": {
"1.12.2-recommended": "1.0.9",
"1.12.2-latest": "1.0.9"
"1.12.2-recommended": "1.0.10",
"1.12.2-latest": "1.0.10"
}
}

View file

@ -10,6 +10,23 @@ Mod sources for Minecraft version 1.12.2.
----
## Version history
-------------------------------------------------------------------
- v1.0.10 [R] Release based on v1.0.10-b2. Release-to-release changes:
* Steel table added.
* Steel floor grating added.
* Treated wood side table added.
* Exit Sign added.
* Recipe fixes.
-------------------------------------------------------------------
- v1.0.10-b2 [A] Steel table added.
[A] Steel floor grating added.
- v1.0.10-b1 [A] Treated wood side table added.
[F] Fixed recipe collision of Metal Rung Ladder (issue #37,
thx ProsperCraft for reporting).
[A] Added Exit Sign (texture design by J. Carver).
-------------------------------------------------------------------
- v1.0.9 [R] Release based on v1.0.9-b3. Release-to-release changes:
* Slabs for clinker, concrete, slag bricks.

View file

@ -31,7 +31,6 @@ import net.minecraft.util.*;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.entity.Entity;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import javax.annotation.Nonnull;

View file

@ -0,0 +1,44 @@
/*
* @file BlockDecorFloorGrating.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2019 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)
*
* Floor gratings.
*/
package wile.engineersdecor.blocks;
import net.minecraft.block.SoundType;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.BlockFaceShape;
import net.minecraft.block.state.IBlockState;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class BlockDecorFloorGrating extends BlockDecor
{
public BlockDecorFloorGrating(@Nonnull String registryName, long config, @Nullable Material material, float hardness, float resistance, @Nullable SoundType sound, @Nullable AxisAlignedBB boundingbox)
{ super(registryName, config, material, hardness, resistance, sound, (boundingbox==null) ? (new AxisAlignedBB[]{FULL_BLOCK_AABB}) : (new AxisAlignedBB[]{boundingbox})); }
@Override
public boolean isFullCube(IBlockState state)
{ return false; }
@Override
public boolean isNormalCube(IBlockState state)
{ return false; }
@Override
public boolean isOpaqueCube(IBlockState state)
{ return false; }
@Override
public BlockFaceShape getBlockFaceShape(IBlockAccess world, IBlockState state, BlockPos pos, EnumFacing face)
{ return BlockFaceShape.SOLID; }
}

View file

@ -73,6 +73,86 @@ public class ModBlocks
public static final BlockDecorGlassBlock PANZERGLASS_BLOCK = new BlockDecorGlassBlock("panzerglass_block", 0, Material.GLASS, 1f, 2000f, SoundType.GLASS);
public static final BlockDecorSlab PANZERGLASS_SLAB = new BlockDecorSlab("panzerglass_slab", BlockDecor.CFG_TRANSLUCENT, Material.GLASS, 1f, 2000f, SoundType.GLASS);
//--------------------------------------------------------------------------------------------------------------------
public static final BlockDecorCraftingTable TREATED_WOOD_CRAFTING_TABLE = new BlockDecorCraftingTable(
"treated_wood_crafting_table",
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_LOOK_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT,
Material.WOOD, 1.0f, 15f, SoundType.WOOD,
ModAuxiliaries.getPixeledAABB(1,0,1, 15,15.9,15)
);
public static final BlockDecorFurnace SMALL_LAB_FURNACE = new BlockDecorFurnace(
"small_lab_furnace",
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_LOOK_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT|
BlockDecor.CFG_ELECTRICAL,
Material.IRON, 0.5f, 15f, SoundType.METAL,
ModAuxiliaries.getPixeledAABB(1,0,1, 15,15,16)
);
public static final BlockDecorFurnaceElectrical SMALL_ELECTRICAL_FURNACE = new BlockDecorFurnaceElectrical(
"small_electrical_furnace",
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_LOOK_PLACEMENT|BlockDecor.CFG_ELECTRICAL,
Material.IRON, 0.5f, 15f, SoundType.METAL,
ModAuxiliaries.getPixeledAABB(0,0,0, 16,16,16)
);
public static final BlockDecorDropper FACTORY_DROPPER = new BlockDecorDropper(
"factory_dropper",
BlockDecor.CFG_LOOK_PLACEMENT|BlockDecor.CFG_REDSTONE_CONTROLLED,
Material.IRON, 1f, 15f, SoundType.METAL,
ModAuxiliaries.getPixeledAABB(0,0,0, 16,16,15)
);
public static final BlockDecorWasteIncinerator SMALL_WASTE_INCINERATOR = new BlockDecorWasteIncinerator(
"small_waste_incinerator",
BlockDecor.CFG_DEFAULT|BlockDecor.CFG_ELECTRICAL,
Material.IRON, 1f, 15f, SoundType.METAL,
ModAuxiliaries.getPixeledAABB(0,0,0, 16,16,16)
);
public static final BlockDecorMineralSmelter SMALL_MINERAL_SMELTER = new BlockDecorMineralSmelter(
"small_mineral_smelter",
BlockDecor.CFG_LOOK_PLACEMENT,
Material.IRON, 1f, 15f, SoundType.METAL,
ModAuxiliaries.getPixeledAABB(1.1,0,1.1, 14.9,16,14.9)
);
//--------------------------------------------------------------------------------------------------------------------
public static final BlockDecorPipeValve STRAIGHT_CHECK_VALVE = new BlockDecorPipeValve(
"straight_pipe_valve",
BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT|BlockDecor.CFG_FLIP_PLACEMENT_SHIFTCLICK|
BlockDecor.CFG_CUTOUT,
Material.IRON, 0.7f, 15f, SoundType.METAL,
ModAuxiliaries.getPixeledAABB(4,4,0, 12,12,16)
);
public static final BlockDecorPipeValve STRAIGHT_REDSTONE_VALVE = new BlockDecorPipeValve(
"straight_pipe_valve_redstone",
BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT|BlockDecor.CFG_FLIP_PLACEMENT_SHIFTCLICK|
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_REDSTONE_CONTROLLED,
Material.IRON, 0.7f, 15f, SoundType.METAL,
ModAuxiliaries.getPixeledAABB(4,4,0, 12,12,16)
);
public static final BlockDecorPipeValve STRAIGHT_REDSTONE_ANALOG_VALVE = new BlockDecorPipeValve(
"straight_pipe_valve_redstone_analog",
BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT|BlockDecor.CFG_FLIP_PLACEMENT_SHIFTCLICK|
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_REDSTONE_CONTROLLED|BlockDecor.CFG_ANALOG,
Material.IRON, 0.7f, 15f, SoundType.METAL,
ModAuxiliaries.getPixeledAABB(4,4,0, 12,12,16)
);
public static final BlockDecorPassiveFluidAccumulator PASSIVE_FLUID_ACCUMULATOR = new BlockDecorPassiveFluidAccumulator(
"passive_fluid_accumulator",
BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT|BlockDecor.CFG_FLIP_PLACEMENT_SHIFTCLICK|
BlockDecor.CFG_CUTOUT,
Material.IRON, 0.7f, 15f, SoundType.METAL,
ModAuxiliaries.getPixeledAABB(0,0,0, 16,16,16)
);
//--------------------------------------------------------------------------------------------------------------------
public static final BlockDecorStraightPole TREATED_WOOD_POLE = new BlockDecorStraightPole(
"treated_wood_pole",
@ -123,6 +203,15 @@ public class ModBlocks
ModAuxiliaries.getPixeledAABB(5,5,0, 11,11,16)
);
public static final BlockDecorHorizontalSupport STEEL_DOUBLE_T_SUPPORT = new BlockDecorHorizontalSupport(
"steel_double_t_support",
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_LOOK_PLACEMENT,
Material.IRON, 2.0f, 15f, SoundType.METAL,
ModAuxiliaries.getPixeledAABB(5,11,0, 11,16,16)
);
//--------------------------------------------------------------------------------------------------------------------
public static final BlockDecor TREATED_WOOD_TABLE = new BlockDecor(
"treated_wood_table",
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_LOOK_PLACEMENT,
@ -144,11 +233,11 @@ public class ModBlocks
ModAuxiliaries.getPixeledAABB(2,0,2, 14,15.9,14)
);
public static final BlockDecorCraftingTable TREATED_WOOD_CRAFTING_TABLE = new BlockDecorCraftingTable(
"treated_wood_crafting_table",
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_LOOK_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT,
Material.WOOD, 1.0f, 15f, SoundType.WOOD,
ModAuxiliaries.getPixeledAABB(1,0,1, 15,15.9,15)
public static final BlockDecorDirected TREATED_WOOD_WINDOWSILL = new BlockDecorDirected(
"treated_wood_windowsill",
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_FACING_PLACEMENT,
Material.WOOD, 1.0f, 10f, SoundType.WOOD,
ModAuxiliaries.getPixeledAABB(0.5,15,10.5, 15.5,16,16)
);
public static final BlockDecorDirected INSET_LIGHT_IRON = new BlockDecorDirected(
@ -158,13 +247,22 @@ public class ModBlocks
ModAuxiliaries.getPixeledAABB(5.2,5.2,15.7, 10.8,10.8,16.0)
);
public static final BlockDecorDirected TREATED_WOOD_WINDOWSILL = new BlockDecorDirected(
"treated_wood_windowsill",
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_FACING_PLACEMENT,
Material.WOOD, 1.0f, 10f, SoundType.WOOD,
ModAuxiliaries.getPixeledAABB(0.5,15,10.5, 15.5,16,16)
public static final BlockDecor STEEL_TABLE = new BlockDecor(
"steel_table",
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_LOOK_PLACEMENT,
Material.IRON, 1.0f, 15f, SoundType.METAL,
ModAuxiliaries.getPixeledAABB(0,0,0, 16,15.9,16)
);
public static final BlockDecorFloorGrating STEEL_FLOOR_GRATING = new BlockDecorFloorGrating(
"steel_floor_grating",
BlockDecor.CFG_CUTOUT,
Material.IRON, 1.0f, 15f, SoundType.METAL,
ModAuxiliaries.getPixeledAABB(0,14,0, 16,16,16)
);
//--------------------------------------------------------------------------------------------------------------------
public static final BlockDecorWindow TREATED_WOOD_WINDOW = new BlockDecorWindow(
"treated_wood_window",
BlockDecor.CFG_TRANSLUCENT|BlockDecor.CFG_LOOK_PLACEMENT,
@ -179,20 +277,7 @@ public class ModBlocks
ModAuxiliaries.getPixeledAABB(0,0,7.5, 16,16,8.5)
);
public static final BlockDecorFurnace SMALL_LAB_FURNACE = new BlockDecorFurnace(
"small_lab_furnace",
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_LOOK_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT|
BlockDecor.CFG_ELECTRICAL,
Material.IRON, 0.5f, 15f, SoundType.METAL,
ModAuxiliaries.getPixeledAABB(1,0,1, 15,15,16)
);
public static final BlockDecorFurnaceElectrical SMALL_ELECTRICAL_FURNACE = new BlockDecorFurnaceElectrical(
"small_electrical_furnace",
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_LOOK_PLACEMENT|BlockDecor.CFG_ELECTRICAL,
Material.IRON, 0.5f, 15f, SoundType.METAL,
ModAuxiliaries.getPixeledAABB(0,0,0, 16,16,16)
);
//--------------------------------------------------------------------------------------------------------------------
public static final BlockDecorDirected SIGN_MODLOGO = new BlockDecorDirected(
"sign_decor",
@ -201,66 +286,6 @@ public class ModBlocks
ModAuxiliaries.getPixeledAABB(0,0,15.6, 16,16,16)
);
public static final BlockDecorHorizontalSupport STEEL_DOUBLE_T_SUPPORT = new BlockDecorHorizontalSupport(
"steel_double_t_support",
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_LOOK_PLACEMENT,
Material.IRON, 2.0f, 15f, SoundType.METAL,
ModAuxiliaries.getPixeledAABB(5,11,0, 11,16,16)
);
public static final BlockDecorPipeValve STRAIGHT_CHECK_VALVE = new BlockDecorPipeValve(
"straight_pipe_valve",
BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT|BlockDecor.CFG_FLIP_PLACEMENT_SHIFTCLICK|
BlockDecor.CFG_CUTOUT,
Material.IRON, 0.7f, 15f, SoundType.METAL,
ModAuxiliaries.getPixeledAABB(4,4,0, 12,12,16)
);
public static final BlockDecorPipeValve STRAIGHT_REDSTONE_VALVE = new BlockDecorPipeValve(
"straight_pipe_valve_redstone",
BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT|BlockDecor.CFG_FLIP_PLACEMENT_SHIFTCLICK|
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_REDSTONE_CONTROLLED,
Material.IRON, 0.7f, 15f, SoundType.METAL,
ModAuxiliaries.getPixeledAABB(4,4,0, 12,12,16)
);
public static final BlockDecorPipeValve STRAIGHT_REDSTONE_ANALOG_VALVE = new BlockDecorPipeValve(
"straight_pipe_valve_redstone_analog",
BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT|BlockDecor.CFG_FLIP_PLACEMENT_SHIFTCLICK|
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_REDSTONE_CONTROLLED|BlockDecor.CFG_ANALOG,
Material.IRON, 0.7f, 15f, SoundType.METAL,
ModAuxiliaries.getPixeledAABB(4,4,0, 12,12,16)
);
public static final BlockDecorPassiveFluidAccumulator PASSIVE_FLUID_ACCUMULATOR = new BlockDecorPassiveFluidAccumulator(
"passive_fluid_accumulator",
BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT|BlockDecor.CFG_FLIP_PLACEMENT_SHIFTCLICK|
BlockDecor.CFG_CUTOUT,
Material.IRON, 0.7f, 15f, SoundType.METAL,
ModAuxiliaries.getPixeledAABB(0,0,0, 16,16,16)
);
public static final BlockDecorWasteIncinerator SMALL_WASTE_INCINERATOR = new BlockDecorWasteIncinerator(
"small_waste_incinerator",
BlockDecor.CFG_DEFAULT|BlockDecor.CFG_ELECTRICAL,
Material.IRON, 1f, 15f, SoundType.METAL,
ModAuxiliaries.getPixeledAABB(0,0,0, 16,16,16)
);
public static final BlockDecorDropper FACTORY_DROPPER = new BlockDecorDropper(
"factory_dropper",
BlockDecor.CFG_LOOK_PLACEMENT|BlockDecor.CFG_REDSTONE_CONTROLLED,
Material.IRON, 1f, 15f, SoundType.METAL,
ModAuxiliaries.getPixeledAABB(0,0,0, 16,16,15)
);
public static final BlockDecorMineralSmelter SMALL_MINERAL_SMELTER = new BlockDecorMineralSmelter(
"small_mineral_smelter",
BlockDecor.CFG_LOOK_PLACEMENT,
Material.IRON, 1f, 15f, SoundType.METAL,
ModAuxiliaries.getPixeledAABB(1.1,0,1.1, 14.9,16,14.9)
);
public static final BlockDecorDirected SIGN_HOTWIRE = new BlockDecorDirected(
"sign_hotwire",
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_OPPOSITE_PLACEMENT|(1<<BlockDecor.CFG_LIGHT_VALUE_SHIFT),
@ -296,6 +321,15 @@ public class ModBlocks
ModAuxiliaries.getPixeledAABB(2,2,15.6, 15,15,16)
);
public static final BlockDecorDirected SIGN_EXIT = new BlockDecorDirected(
"sign_exit",
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_OPPOSITE_PLACEMENT,
Material.WOOD, 0.1f, 1f, SoundType.WOOD,
ModAuxiliaries.getPixeledAABB(3,7,15.6, 13,13,16)
);
//--------------------------------------------------------------------------------------------------------------------
public static final BlockDecorHalfSlab HALFSLAB_REBARCONCRETE = new BlockDecorHalfSlab(
"halfslab_rebar_concrete",
BlockDecor.CFG_CUTOUT,
@ -411,6 +445,7 @@ public class ModBlocks
TREATED_WOOD_LADDER,
TREATED_WOOD_POLE,
TREATED_WOOD_TABLE,
STEEL_TABLE,
TREATED_WOOD_STOOL,
TREATED_WOOD_WINDOW,
STEEL_FRAMED_WINDOW,
@ -423,7 +458,8 @@ public class ModBlocks
THIN_STEEL_POLE_HEAD,
THICK_STEEL_POLE_HEAD,
STEEL_DOUBLE_T_SUPPORT,
SIGN_HOTWIRE, SIGN_DANGER, SIGN_DEFENSE, SIGN_FACTORY_AREA, SIGN_MODLOGO,
STEEL_FLOOR_GRATING,
SIGN_HOTWIRE, SIGN_DANGER, SIGN_DEFENSE, SIGN_FACTORY_AREA, SIGN_EXIT, SIGN_MODLOGO,
TREATED_WOOD_SIDE_TABLE,
HALFSLAB_REBARCONCRETE, HALFSLAB_CONCRETE, HALFSLAB_TREATEDWOOD,
HALFSLAB_SHEETMETALIRON, HALFSLAB_SHEETMETALSTEEL, HALFSLAB_SHEETMETALCOPPER,

View file

@ -0,0 +1,9 @@
{
"forge_marker": 1,
"defaults": { "model": "engineersdecor:sign/sign_exit_model" },
"variants": {
"normal": [{}],
"inventory": [{}],
"facing": { "north":{"y":0}, "south":{"y":180}, "west":{"y":270}, "east":{"y":90}, "up": {"x":0}, "down": {"x":0} }
}
}

View file

@ -0,0 +1,8 @@
{
"forge_marker": 1,
"defaults": { "model": "engineersdecor:furniture/steel_floor_grating_model" },
"variants": {
"normal": [{}],
"inventory": [{}]
}
}

View file

@ -0,0 +1,8 @@
{
"forge_marker": 1,
"defaults": { "model": "engineersdecor:furniture/steel_table_model" },
"variants": {
"normal": [{}],
"inventory": [{}]
}
}

View file

@ -81,10 +81,14 @@ tile.engineersdecor.thin_steel_pole_head.help=§6Steel part fitting as foot or h
tile.engineersdecor.thick_steel_pole_head.name=Straight Thick Steel Pole Head/Foot
tile.engineersdecor.thick_steel_pole_head.help=§6Steel part fitting as foot or head of the thick steel pole (6x6x16).
tile.engineersdecor.steel_double_t_support.name=Steel Double T Support
tile.engineersdecor.steel_double_t_support.help=§6Horizontal ceiling support bream fragment.
tile.engineersdecor.steel_double_t_support.help=§6Horizontal ceiling support beam fragment.
#-----------------------------------------------------------------------------------------------------------
tile.engineersdecor.treated_wood_table.name=Treated Wood Table
tile.engineersdecor.treated_wood_table.help=§6Robust four-legged wood table.§r Indoor and outdoor use.
tile.engineersdecor.steel_table.name=Steel Table
tile.engineersdecor.steel_table.help=§6Robust four-legged steel table.
tile.engineersdecor.steel_floor_grating.name=Steel Floor Grating
tile.engineersdecor.steel_floor_grating.help=§6Decorative steel floor covering.§r Top aligned.
tile.engineersdecor.treated_wood_stool.name=Treated Wood Stool
tile.engineersdecor.treated_wood_stool.help=§6Robust Wood Stool.§r Indoor and outdoor use.
tile.engineersdecor.treated_wood_crafting_table.name=Treated Wood Crafting Table
@ -155,7 +159,7 @@ tile.engineersdecor.small_mineral_smelter.help=§6High temperature, high insulat
tile.engineersdecor.sign_decor.name=Sign Plate (Engineer's decor)
tile.engineersdecor.sign_decor.help=§6This should not be craftable or visible in JEI. Used for creative tab and screenshots.
tile.engineersdecor.sign_hotwire.name=Sign "Caution Hot Wire"
tile.engineersdecor.sign_hotwire.help=§6Electrical hazard warning. Don't forget to place around HV, or you'll have a mark in the next audit.
tile.engineersdecor.sign_hotwire.help=§6Electrical hazard warning. Don't forget to place around HV, or you will have a nonconformity in the next audit.
tile.engineersdecor.sign_mindstep.name=Sign "Mind The Step"
tile.engineersdecor.sign_mindstep.help=§6Placable on walls (horizontally).
tile.engineersdecor.sign_danger.name=Sign "Caution Really Dangerous There"
@ -163,7 +167,9 @@ tile.engineersdecor.sign_danger.help=§6General danger warning.
tile.engineersdecor.sign_defense.name=Sign "Caution Defense System Ahead"
tile.engineersdecor.sign_defense.help=§6Warning sign for turrets, Tesla Coils, and traps.
tile.engineersdecor.sign_factoryarea.name=Sign "Factory Area"
tile.engineersdecor.sign_factoryarea.help=§6Marker sign for buildings or areas where the really big machines are.
tile.engineersdecor.sign_factoryarea.help=§6Marker sign for buildings or areas where the really big machines are located.
tile.engineersdecor.sign_exit.name=Exit Sign
tile.engineersdecor.sign_factoryarea.help=§6There's the door, please ...
#-----------------------------------------------------------------------------------------------------------
tile.engineersdecor.halfslab_rebar_concrete.name=Rebar Concrete Slice
tile.engineersdecor.halfslab_rebar_concrete.help=§6Vertically stackable slice.§r Right/left click with the slice stack on the top or bottom surface to add/remove slices.

View file

@ -85,6 +85,10 @@ tile.engineersdecor.steel_double_t_support.help=§6Фрагмент горизо
#-----------------------------------------------------------------------------------------------------------
tile.engineersdecor.treated_wood_table.name=Стол из обработанного дерева
tile.engineersdecor.treated_wood_table.help=§6Прочный деревянный стол с четырьмя ножками .§r Для использования в помещении и на улице.
tile.engineersdecor.steel_table.name=Steel Table
#tile.engineersdecor.steel_table.help=§6Robust four-legged steel table.
tile.engineersdecor.steel_floor_grating.name=Steel Floor Grating
#tile.engineersdecor.steel_floor_grating.help=§6Decorative steel floor covering.§r Top aligned.
tile.engineersdecor.treated_wood_stool.name=Табурет из обработанного дерева
tile.engineersdecor.treated_wood_stool.help=§6Крепкий деревянный табурет.§r Для использования в помещении и на улице.
tile.engineersdecor.treated_wood_crafting_table.name=Верстак из обработанного дерева
@ -159,6 +163,8 @@ tile.engineersdecor.sign_defense.name=Знак «Осторожно, впере
tile.engineersdecor.sign_defense.help=§6Предупреждающий знак для турелей, катушек Тесла и ловушек.
tile.engineersdecor.sign_factoryarea.name=Знак «Заводская зона»
tile.engineersdecor.sign_factoryarea.help=§6Знак для зданий или областей, где находятся действительно большие машины.
tile.engineersdecor.sign_exit.name=Exit Sign
#tile.engineersdecor.sign_factoryarea.help=§6There's the door, please ...
#-----------------------------------------------------------------------------------------------------------
tile.engineersdecor.halfslab_rebar_concrete.name=Арматура для бетона
tile.engineersdecor.halfslab_rebar_concrete.help=§6Вертикально наращиваемая часть.§rПравый/левый щелчок со стеком частей на верхней или нижней поверхности для добавления/удаления частей.

View file

@ -79,10 +79,14 @@ tile.engineersdecor.thin_steel_pole_head.name=Straight Thin Steel Pole head/foot
tile.engineersdecor.thick_steel_pole_head.name=Straight Thick Steel Pole Head/Foot
#tile.engineersdecor.thick_steel_pole_head.help=§6Steel part fitting as foot or head of the thick steel pole (6x6x16).
tile.engineersdecor.steel_double_t_support.name=Steel Double T Support
#tile.engineersdecor.steel_double_t_support.help=§6Horizontal ceiling support bream fragment.
#tile.engineersdecor.steel_double_t_support.help=§6Horizontal ceiling support beam fragment.
#-----------------------------------------------------------------------------------------------------------
tile.engineersdecor.treated_wood_table.name=经过处理的木桌
tile.engineersdecor.treated_wood_table.help=§6坚固的四足木桌.
tile.engineersdecor.steel_table.name=Steel Table
#tile.engineersdecor.steel_table.help=§6Robust four-legged steel table.
tile.engineersdecor.steel_floor_grating.name=Steel Floor Grating
#tile.engineersdecor.steel_floor_grating.help=§6Decorative steel floor covering.§r Top aligned.
tile.engineersdecor.treated_wood_stool.name=Treated Wood Stool
#tile.engineersdecor.treated_wood_stool.help=§6Robust Wood Stool.§r Indoor and outdoor use.
tile.engineersdecor.treated_wood_crafting_table.name=Treated Wood Crafting Table
@ -153,7 +157,7 @@ tile.engineersdecor.small_mineral_smelter.name=Small Mineral Melting Furnace
tile.engineersdecor.sign_decor.name=Sign Plate (Engineer's decor)
#tile.engineersdecor.sign_decor.help=§6This should not be craftable or visible in JEI. Used for creative tab and screenshots.
tile.engineersdecor.sign_hotwire.name=Sign "Caution Hot Wire"
#tile.engineersdecor.sign_hotwire.help=§6Electrical hazard warning. Don't forget to place around HV, or you'll have a mark in the next audit.
#tile.engineersdecor.sign_hotwire.help=§6Electrical hazard warning. Don't forget to place around HV, or you will have a nonconformity in the next audit.
tile.engineersdecor.sign_mindstep.name=Sign "Mind The Step"
#tile.engineersdecor.sign_mindstep.help=§6Placable on walls (horizontally).
tile.engineersdecor.sign_danger.name=Sign "Caution Really Dangerous There"
@ -161,7 +165,9 @@ tile.engineersdecor.sign_danger.name=Sign "Caution Really Dangerous There"
tile.engineersdecor.sign_defense.name=Sign "Caution Defense System Ahead"
#tile.engineersdecor.sign_defense.help=§6Warning sign for turrets, Tesla Coils, and traps.
tile.engineersdecor.sign_factoryarea.name=Sign "Factory Area"
#tile.engineersdecor.sign_factoryarea.help=§6Marker sign for buildings or areas where the really big machines are.
#tile.engineersdecor.sign_factoryarea.help=§6Marker sign for buildings or areas where the really big machines are located.
tile.engineersdecor.sign_exit.name=Exit Sign
#tile.engineersdecor.sign_factoryarea.help=§6There's the door, please ...
#-----------------------------------------------------------------------------------------------------------
tile.engineersdecor.halfslab_rebar_concrete.name=Rebar Concrete Slice
#tile.engineersdecor.halfslab_rebar_concrete.help=§6Vertically stackable slice.§r Right/left click with the slice stack on the top or bottom surface to add/remove slices.

View file

@ -0,0 +1,187 @@
{
"parent": "block/cube",
"textures": {
"s": "engineersdecor:blocks/furniture/steel_table_side_texture",
"particle": "engineersdecor:blocks/furniture/steel_table_side_texture",
"t": "engineersdecor:blocks/furniture/steel_table_top_texture"
},
"elements": [
{
"from": [0, 14, 15],
"to": [16, 16, 16],
"faces": {
"north": {"uv": [0, 0, 16, 2], "texture": "#s"},
"east": {"uv": [0, 0, 1, 2], "texture": "#s"},
"south": {"uv": [0, 0, 16, 2], "texture": "#s"},
"west": {"uv": [15, 0, 16, 2], "texture": "#s"},
"up": {"uv": [0, 15, 16, 16], "texture": "#t"},
"down": {"uv": [0, 0, 16, 1], "texture": "#s"}
}
},
{
"from": [0, 14, 0],
"to": [16, 16, 1],
"faces": {
"north": {"uv": [0, 0, 16, 2], "texture": "#s"},
"east": {"uv": [15, 0, 16, 2], "texture": "#s"},
"south": {"uv": [0, 0, 16, 2], "texture": "#s"},
"west": {"uv": [0, 0, 1, 2], "texture": "#s"},
"up": {"uv": [0, 0, 16, 1], "texture": "#t"},
"down": {"uv": [0, 15, 16, 16], "texture": "#s"}
}
},
{
"from": [15, 14, 0.75],
"to": [16, 16, 15.25],
"faces": {
"north": {"uv": [0, 0, 1, 2], "texture": "#s"},
"east": {"uv": [0.75, 0, 15.25, 2], "texture": "#s"},
"south": {"uv": [15, 0, 16, 2], "texture": "#s"},
"west": {"uv": [0.75, 0, 15.25, 2], "texture": "#s"},
"up": {"uv": [15, 0.75, 16, 15.25], "texture": "#t"},
"down": {"uv": [15, 0.75, 16, 15.25], "texture": "#s"}
}
},
{
"from": [1, 15, 13.625],
"to": [15, 15.875, 14.375],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8.375]},
"faces": {
"north": {"uv": [1, 0.125, 15, 1], "texture": "#s"},
"east": {"uv": [1.625, 0.125, 2.375, 1], "texture": "#s"},
"south": {"uv": [1, 0.125, 15, 1], "texture": "#s"},
"west": {"uv": [13.625, 0.125, 14.375, 1], "texture": "#s"},
"up": {"uv": [1, 13.625, 15, 14.375], "texture": "#t"},
"down": {"uv": [1, 1.625, 15, 2.375], "texture": "#t"}
}
},
{
"from": [1, 15, 12.125],
"to": [15, 15.875, 12.875],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8.375]},
"faces": {
"north": {"uv": [1, 0.125, 15, 1], "texture": "#s"},
"east": {"uv": [3.125, 0.125, 3.875, 1], "texture": "#s"},
"south": {"uv": [1, 0.125, 15, 1], "texture": "#s"},
"west": {"uv": [12.125, 0.125, 12.875, 1], "texture": "#s"},
"up": {"uv": [1, 12.125, 15, 12.875], "texture": "#t"},
"down": {"uv": [1, 3.125, 15, 3.875], "texture": "#t"}
}
},
{
"from": [1, 15, 10.625],
"to": [15, 15.875, 11.375],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8.375]},
"faces": {
"north": {"uv": [1, 0.125, 15, 1], "texture": "#s"},
"east": {"uv": [4.625, 0.125, 5.375, 1], "texture": "#s"},
"south": {"uv": [1, 0.125, 15, 1], "texture": "#s"},
"west": {"uv": [10.625, 0.125, 11.375, 1], "texture": "#s"},
"up": {"uv": [1, 10.625, 15, 11.375], "texture": "#t"},
"down": {"uv": [1, 4.625, 15, 5.375], "texture": "#t"}
}
},
{
"from": [1, 15, 9.125],
"to": [15, 15.875, 9.875],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8.375]},
"faces": {
"north": {"uv": [1, 0.125, 15, 1], "texture": "#s"},
"east": {"uv": [6.125, 0.125, 6.875, 1], "texture": "#s"},
"south": {"uv": [1, 0.125, 15, 1], "texture": "#s"},
"west": {"uv": [9.125, 0.125, 9.875, 1], "texture": "#s"},
"up": {"uv": [1, 9.125, 15, 9.875], "texture": "#t"},
"down": {"uv": [1, 6.125, 15, 6.875], "texture": "#t"}
}
},
{
"from": [1, 15, 7.625],
"to": [15, 15.875, 8.375],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8.375]},
"faces": {
"north": {"uv": [1, 0.125, 15, 1], "texture": "#s"},
"east": {"uv": [7.625, 0.125, 8.375, 1], "texture": "#s"},
"south": {"uv": [1, 0.125, 15, 1], "texture": "#s"},
"west": {"uv": [7.625, 0.125, 8.375, 1], "texture": "#s"},
"up": {"uv": [1, 7.625, 15, 8.375], "texture": "#t"},
"down": {"uv": [1, 7.625, 15, 8.375], "texture": "#t"}
}
},
{
"from": [1, 15, 6.125],
"to": [15, 15.875, 6.875],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8.375]},
"faces": {
"north": {"uv": [1, 0.125, 15, 1], "texture": "#s"},
"east": {"uv": [9.125, 0.125, 9.875, 1], "texture": "#s"},
"south": {"uv": [1, 0.125, 15, 1], "texture": "#s"},
"west": {"uv": [6.125, 0.125, 6.875, 1], "texture": "#s"},
"up": {"uv": [1, 6.125, 15, 6.875], "texture": "#t"},
"down": {"uv": [1, 9.125, 15, 9.875], "texture": "#t"}
}
},
{
"from": [1, 15, 4.625],
"to": [15, 15.875, 5.375],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8.375]},
"faces": {
"north": {"uv": [1, 0.125, 15, 1], "texture": "#s"},
"east": {"uv": [10.625, 0.125, 11.375, 1], "texture": "#s"},
"south": {"uv": [1, 0.125, 15, 1], "texture": "#s"},
"west": {"uv": [4.625, 0.125, 5.375, 1], "texture": "#s"},
"up": {"uv": [1, 4.625, 15, 5.375], "texture": "#t"},
"down": {"uv": [1, 10.625, 15, 11.375], "texture": "#t"}
}
},
{
"from": [1, 15, 3.125],
"to": [15, 15.875, 3.875],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8.375]},
"faces": {
"north": {"uv": [1, 0.125, 15, 1], "texture": "#s"},
"east": {"uv": [12.125, 0.125, 12.875, 1], "texture": "#s"},
"south": {"uv": [1, 0.125, 15, 1], "texture": "#s"},
"west": {"uv": [3.125, 0.125, 3.875, 1], "texture": "#s"},
"up": {"uv": [1, 3.125, 15, 3.875], "texture": "#t"},
"down": {"uv": [1, 12.125, 15, 12.875], "texture": "#t"}
}
},
{
"from": [1, 15, 1.625],
"to": [15, 15.875, 2.375],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8.375]},
"faces": {
"north": {"uv": [1, 0.125, 15, 1], "texture": "#s"},
"east": {"uv": [13.625, 0.125, 14.375, 1], "texture": "#s"},
"south": {"uv": [1, 0.125, 15, 1], "texture": "#s"},
"west": {"uv": [1.625, 0.125, 2.375, 1], "texture": "#s"},
"up": {"uv": [1, 1.625, 15, 2.375], "texture": "#t"},
"down": {"uv": [1, 13.625, 15, 14.375], "texture": "#t"}
}
},
{
"from": [0, 14, 1],
"to": [1, 16, 15],
"faces": {
"north": {"uv": [15, 0, 16, 2], "texture": "#s"},
"east": {"uv": [1, 0, 15, 2], "texture": "#s"},
"south": {"uv": [0, 0, 1, 2], "texture": "#s"},
"west": {"uv": [1, 0, 15, 2], "texture": "#s"},
"up": {"uv": [0, 1, 1, 15], "texture": "#t"},
"down": {"uv": [0, 1, 1, 15], "texture": "#s"}
}
}
],
"display": {
"ground": {
"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,383 @@
{
"parent": "block/cube",
"textures": {
"s": "engineersdecor:blocks/furniture/steel_table_side_texture",
"particle": "engineersdecor:blocks/furniture/steel_table_side_texture",
"t": "engineersdecor:blocks/furniture/steel_table_top_texture"
},
"elements": [
{
"from": [0, 0, 0],
"to": [2, 14, 1],
"faces": {
"north": {"texture": "#s"},
"east": {"texture": "#s"},
"south": {"texture": "#s"},
"west": {"texture": "#s"},
"up": {"texture": "#s"},
"down": {"texture": "#s", "cullface": "down"}
}
},
{
"from": [14, 0, 0],
"to": [16, 14, 1],
"faces": {
"north": {"texture": "#s"},
"east": {"texture": "#s"},
"south": {"texture": "#s"},
"west": {"texture": "#s"},
"up": {"texture": "#s"},
"down": {"texture": "#s", "cullface": "down"}
}
},
{
"from": [14, 0, 15],
"to": [16, 14, 16],
"faces": {
"north": {"texture": "#s"},
"east": {"texture": "#s"},
"south": {"texture": "#s"},
"west": {"texture": "#s"},
"up": {"texture": "#s"},
"down": {"texture": "#s", "cullface": "down"}
}
},
{
"from": [0, 0, 15],
"to": [2, 14, 16],
"faces": {
"north": {"texture": "#s"},
"east": {"texture": "#s"},
"south": {"texture": "#s"},
"west": {"texture": "#s"},
"up": {"texture": "#s"},
"down": {"texture": "#s", "cullface": "down"}
}
},
{
"from": [0, 0, 14],
"to": [1, 14, 15],
"faces": {
"north": {"texture": "#s"},
"east": {"texture": "#s"},
"south": {"texture": "#s"},
"west": {"texture": "#s"},
"up": {"texture": "#s"},
"down": {"texture": "#s", "cullface": "down"}
}
},
{
"from": [0, 0, 1],
"to": [1, 14, 2],
"faces": {
"north": {"texture": "#s"},
"east": {"texture": "#s"},
"south": {"texture": "#s"},
"west": {"texture": "#s"},
"up": {"texture": "#s"},
"down": {"texture": "#s", "cullface": "down"}
}
},
{
"from": [15, 0, 1],
"to": [16, 14, 2],
"faces": {
"north": {"texture": "#s"},
"east": {"texture": "#s"},
"south": {"texture": "#s"},
"west": {"texture": "#s"},
"up": {"texture": "#s"},
"down": {"texture": "#s", "cullface": "down"}
}
},
{
"from": [15, 0, 14],
"to": [16, 14, 15],
"faces": {
"north": {"texture": "#s"},
"east": {"texture": "#s"},
"south": {"texture": "#s"},
"west": {"texture": "#s"},
"up": {"texture": "#s"},
"down": {"texture": "#s", "cullface": "down"}
}
},
{
"from": [0, 14, 14],
"to": [16, 15.875, 16],
"faces": {
"north": {"texture": "#s"},
"east": {"texture": "#s"},
"south": {"texture": "#s"},
"west": {"texture": "#s"},
"up": {"texture": "#t"},
"down": {"texture": "#s"}
}
},
{
"from": [0, 14, 0],
"to": [16, 15.875, 2],
"faces": {
"north": {"texture": "#s"},
"east": {"texture": "#s"},
"south": {"texture": "#s"},
"west": {"texture": "#s"},
"up": {"texture": "#t"},
"down": {"texture": "#s"}
}
},
{
"from": [14, 14, 2],
"to": [16, 15.875, 14],
"faces": {
"north": {"texture": "#s"},
"east": {"texture": "#s"},
"south": {"texture": "#s"},
"west": {"texture": "#s"},
"up": {"texture": "#t"},
"down": {"texture": "#s"}
}
},
{
"from": [2, 15.5, 12.75],
"to": [14, 15.875, 13.25],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8.25]},
"faces": {
"north": {"texture": "#s"},
"east": {"texture": "#s"},
"south": {"texture": "#s"},
"west": {"texture": "#s"},
"up": {"texture": "#t"},
"down": {"texture": "#t"}
}
},
{
"from": [2, 15.5, 13.75],
"to": [14, 15.875, 14],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8.25]},
"faces": {
"north": {"texture": "#s"},
"east": {"texture": "#s"},
"south": {"texture": "#s"},
"west": {"texture": "#s"},
"up": {"texture": "#t"},
"down": {"texture": "#t"}
}
},
{
"from": [2, 15.5, 11.75],
"to": [14, 15.875, 12.25],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8.25]},
"faces": {
"north": {"texture": "#s"},
"east": {"texture": "#s"},
"south": {"texture": "#s"},
"west": {"texture": "#s"},
"up": {"texture": "#t"},
"down": {"texture": "#t"}
}
},
{
"from": [2, 15.5, 10.75],
"to": [14, 15.875, 11.25],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8.25]},
"faces": {
"north": {"texture": "#s"},
"east": {"texture": "#s"},
"south": {"texture": "#s"},
"west": {"texture": "#s"},
"up": {"texture": "#t"},
"down": {"texture": "#t"}
}
},
{
"from": [2, 15.5, 9.75],
"to": [14, 15.875, 10.25],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8.25]},
"faces": {
"north": {"texture": "#s"},
"east": {"texture": "#s"},
"south": {"texture": "#s"},
"west": {"texture": "#s"},
"up": {"texture": "#t"},
"down": {"texture": "#t"}
}
},
{
"from": [2, 15.5, 8.75],
"to": [14, 15.875, 9.25],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8.25]},
"faces": {
"north": {"texture": "#s"},
"east": {"texture": "#s"},
"south": {"texture": "#s"},
"west": {"texture": "#s"},
"up": {"texture": "#t"},
"down": {"texture": "#t"}
}
},
{
"from": [2, 15.5, 7.75],
"to": [14, 15.875, 8.25],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8.25]},
"faces": {
"north": {"texture": "#s"},
"east": {"texture": "#s"},
"south": {"texture": "#s"},
"west": {"texture": "#s"},
"up": {"texture": "#t"},
"down": {"texture": "#t"}
}
},
{
"from": [2, 15.5, 6.75],
"to": [14, 15.875, 7.25],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8.25]},
"faces": {
"north": {"texture": "#s"},
"east": {"texture": "#s"},
"south": {"texture": "#s"},
"west": {"texture": "#s"},
"up": {"texture": "#t"},
"down": {"texture": "#t"}
}
},
{
"from": [2, 15.5, 5.75],
"to": [14, 15.875, 6.25],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8.25]},
"faces": {
"north": {"texture": "#s"},
"east": {"texture": "#s"},
"south": {"texture": "#s"},
"west": {"texture": "#s"},
"up": {"texture": "#t"},
"down": {"texture": "#t"}
}
},
{
"from": [2, 15.5, 4.75],
"to": [14, 15.875, 5.25],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8.25]},
"faces": {
"north": {"texture": "#s"},
"east": {"texture": "#s"},
"south": {"texture": "#s"},
"west": {"texture": "#s"},
"up": {"texture": "#t"},
"down": {"texture": "#t"}
}
},
{
"from": [2, 15.5, 3.75],
"to": [14, 15.875, 4.25],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8.25]},
"faces": {
"north": {"texture": "#s"},
"east": {"texture": "#s"},
"south": {"texture": "#s"},
"west": {"texture": "#s"},
"up": {"texture": "#t"},
"down": {"texture": "#t"}
}
},
{
"from": [2, 15.5, 2.75],
"to": [14, 15.875, 3.25],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8.25]},
"faces": {
"north": {"texture": "#s"},
"east": {"texture": "#s"},
"south": {"texture": "#s"},
"west": {"texture": "#s"},
"up": {"texture": "#t"},
"down": {"texture": "#t"}
}
},
{
"from": [2, 15.5, 2],
"to": [14, 15.875, 2.25],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8.25]},
"faces": {
"north": {"texture": "#s"},
"east": {"texture": "#s"},
"south": {"texture": "#s"},
"west": {"texture": "#s"},
"up": {"texture": "#t"},
"down": {"texture": "#t"}
}
},
{
"from": [0, 14, 2],
"to": [2, 15.875, 14],
"faces": {
"north": {"texture": "#s"},
"east": {"texture": "#s"},
"south": {"texture": "#s"},
"west": {"texture": "#s"},
"up": {"texture": "#t"},
"down": {"texture": "#s"}
}
},
{
"from": [14, 13.5, 14],
"to": [15, 14, 15],
"faces": {
"north": {"texture": "#s"},
"east": {"texture": "#s"},
"south": {"texture": "#s"},
"west": {"texture": "#s"},
"up": {"texture": "#s"},
"down": {"texture": "#s"}
}
},
{
"from": [1, 13.5, 14],
"to": [2, 14, 15],
"faces": {
"north": {"texture": "#s"},
"east": {"texture": "#s"},
"south": {"texture": "#s"},
"west": {"texture": "#s"},
"up": {"texture": "#s"},
"down": {"texture": "#s"}
}
},
{
"from": [14, 13.5, 1],
"to": [15, 14, 2],
"faces": {
"north": {"texture": "#s"},
"east": {"texture": "#s"},
"south": {"texture": "#s"},
"west": {"texture": "#s"},
"up": {"texture": "#s"},
"down": {"texture": "#s"}
}
},
{
"from": [1, 13.5, 1],
"to": [2, 14, 2],
"faces": {
"north": {"texture": "#s"},
"east": {"texture": "#s"},
"south": {"texture": "#s"},
"west": {"texture": "#s"},
"up": {"texture": "#s"},
"down": {"texture": "#s"}
}
}
],
"display": {
"ground": {
"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,45 @@
{
"parent": "block/cube",
"textures": {
"s": "engineersdecor:blocks/iestyle/treated_wood_rough_texture",
"particle": "engineersdecor:blocks/iestyle/treated_wood_rough_texture",
"f": "engineersdecor:blocks/sign/sign_exit_texture"
},
"elements": [
{
"from": [3, 7, 0],
"to": [13, 13, 0.5],
"faces": {
"north": {"uv": [3, 3, 13, 9], "texture": "#s"},
"east": {"uv": [15.5, 3, 16, 9], "texture": "#s"},
"south": {"uv": [0, 2, 16, 12], "texture": "#f"},
"west": {"uv": [0, 3, 0.5, 9], "texture": "#s"},
"up": {"uv": [3, 0, 13, 0.5], "texture": "#s"},
"down": {"uv": [3, 15.5, 13, 16], "texture": "#s"}
}
}
],
"display": {
"thirdperson_righthand": {
"rotation": [27, -68, 7],
"translation": [-3, -1, -0.75],
"scale": [0.4, 0.4, 0.4]
},
"firstperson_righthand": {
"rotation": [1, -58, 7],
"translation": [0.5, 0, 0],
"scale": [0.4, 0.4, 0.4]
},
"ground": {
"translation": [0, 0, 7],
"scale": [0.7, 0.7, 0.7]
},
"gui": {
"translation": [0, 0.5, 0]
},
"fixed": {
"rotation": [0, 180, 0],
"translation": [0, 0, -7.8]
}
}
}

View file

@ -0,0 +1,25 @@
{
"conditions": [
{
"type": "engineersdecor:grc",
"result": "engineersdecor:steel_floor_grating",
"required": ["engineersdecor:thin_steel_pole"]
}
],
"type": "minecraft:crafting_shaped",
"pattern": [
"S S",
" S ",
"S S"
],
"key": {
"S": {
"item": "engineersdecor:thin_steel_pole",
"data": 0
}
},
"result": {
"item": "engineersdecor:steel_floor_grating",
"count": 4
}
}

View file

@ -0,0 +1,29 @@
{
"conditions": [
{
"type": "engineersdecor:grc",
"result": "engineersdecor:steel_table",
"required": ["engineersdecor:steel_floor_grating", "engineersdecor:thin_steel_pole"]
}
],
"type": "minecraft:crafting_shaped",
"pattern": [
"WWW",
"S S",
"S S"
],
"key": {
"W": {
"item": "engineersdecor:steel_floor_grating",
"data": 0
},
"S": {
"item": "engineersdecor:thin_steel_pole",
"data": 0
}
},
"result": {
"item": "engineersdecor:steel_table",
"count": 4
}
}

View file

@ -0,0 +1,29 @@
{
"conditions": [
{
"type": "engineersdecor:grc",
"result": "engineersdecor:treated_wood_side_table",
"required": ["immersiveengineering:material", "engineersdecor:treated_wood_pole"]
}
],
"type": "minecraft:crafting_shaped",
"pattern": [
"SSS",
" P ",
"PPP"
],
"key": {
"S": {
"item": "#slabTreatedWood",
"data": 0
},
"P": {
"item": "engineersdecor:treated_wood_pole",
"data": 0
}
},
"result": {
"item": "engineersdecor:treated_wood_side_table",
"count": 1
}
}

View file

@ -0,0 +1,16 @@
{
"conditions": [
{
"type": "engineersdecor:grc",
"result": "engineersdecor:sign_exit",
"required": ["engineersdecor:sign_factoryarea"]
}
],
"type": "minecraft:crafting_shapeless",
"ingredients": [
{ "item": "engineersdecor:sign_factoryarea" }
],
"result": {
"item": "engineersdecor:sign_exit"
}
}

View file

@ -3,12 +3,12 @@
{
"type": "engineersdecor:grc",
"result": "engineersdecor:sign_hotwire",
"required": ["engineersdecor:sign_factoryarea"]
"required": ["engineersdecor:sign_exit"]
}
],
"type": "minecraft:crafting_shapeless",
"ingredients": [
{ "item": "engineersdecor:sign_factoryarea" }
{ "item": "engineersdecor:sign_exit" }
],
"result": {
"item": "engineersdecor:sign_hotwire"

View file

@ -0,0 +1,30 @@
{
"conditions": [
{
"type": "engineersdecor:grc",
"result": "engineersdecor:treated_wood_side_table",
"missing": ["immersiveengineering:material"],
"required": ["engineersdecor:treated_wood_pole"]
}
],
"type": "minecraft:crafting_shaped",
"pattern": [
"SSS",
" P ",
"PPP"
],
"key": {
"S": {
"item": "#slabWood",
"data": 0
},
"P": {
"item": "engineersdecor:treated_wood_pole",
"data": 0
}
},
"result": {
"item": "engineersdecor:treated_wood_side_table",
"count": 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 384 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 386 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 934 B

View file

@ -63,13 +63,24 @@ minecraft {
}
}
}
data {
workingDirectory project.file('run')
property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP'
property 'forge.logging.console.level', 'debug'
args '--mod', 'engineersdecor', '--all', '--output', file('src/generated/resources/')
mods {
engineersdecor {
source sourceSets.main
}
}
}
}
}
dependencies {
minecraft "net.minecraftforge:forge:${version_forge_minecraft}"
compileOnly fg.deobf("mezz.jei:jei-${version_minecraft}:${version_jei}:api")
runtimeOnly fg.deobf("mezz.jei:jei-${version_minecraft}:${version_jei}")
compileOnly fg.deobf("mezz.jei:jei-${version_jei}:api")
runtimeOnly fg.deobf("mezz.jei:jei-${version_jei}")
}
jar {

View file

@ -1,11 +1,11 @@
# @file gradle.properties
org.gradle.daemon=false
org.gradle.jvmargs=-Xmx8G
version_minecraft=1.14.3
version_forge_minecraft=1.14.3-27.0.25
version_fml_mappings=20190621-1.14.2
version_jei=6.0.0.7
version_engineersdecor=1.0.9-b4
version_minecraft=1.14.4
version_forge_minecraft=1.14.4-28.0.40
version_fml_mappings=20190719-1.14.3
version_jei=1.14.3:6.0.0.8
version_engineersdecor=1.0.9-b10
#
# jar signing data loaded from signing.properties in the project root.
#

View file

@ -1,6 +1,11 @@
{
"homepage": "https://www.curseforge.com/minecraft/mc-mods/engineers-decor/",
"1.14.3": {
"1.14.4": {
"1.0.9-b9": "[U] Update to Forge 1.14.4-28.0.40/20190719-1.14.3 for Forge testing.",
"1.0.9-b8": "[U] UPDATE TO 1.14.4. Forge 1.14.4-28.0.11/20190719-1.14.3.",
"1.0.9-b7": "[U] Updated to Forge 1.14.3-27.0.60/20190719-1.14.3.\n[F] Disabled all early implemented fuild handling of valves and the Fluid Accumulator to prevent world loading hang-ups (issue #42, thx TheOhmegha for reporting). Will be re-enabled after fluid handling released in Forge.\n[F] Fixed blockstate model locations for signs and crafting table (issue #43, thx ProsperCraft for the beta test).",
"1.0.9-b6": "[U] Updated to Forge 1.14.3-27.0.50/20190621-1.14.2.",
"1.0.9-b5": "[A] Added missing recipes for slabs, stained clinker, half-slabs, valves.\n[M] Standalone recipes adapted.\n[F] Lang files: Fixed double newline escape.\n[A] Implicit opt-out of hard IE dependent blocks ported (e.g. Concrete Wall).\n[M] Basic mod config features, opt-outs and tweaks ported.",
"1.0.9-b4": "[E] Experimental: Config skel ported (!not all options have effect yet).\n[E] Experimental: JEI integration for opt-outs and crafting table ported (also addresses issue #38).",
"1.0.9-b3": "[F] Additional item drop fixes when blocks are destroyed (issue #39).",
"1.0.9-b2": "[U] Updated to Forge 1.14.3-27.0.25/20190621-1.14.2.\n[F] Fixed recipe collision of Metal Rung Ladder (issue #37, thx ProsperCraft for reporting).\n[F] Fixed opening crafting table, furni, dropper server crash issue #35 (thx ProsperCraft also here).\n[F] Fixed missing pole/support item drops (issue #36, ProsperCraft).",
@ -13,7 +18,7 @@
"1.0.7-b3": "[A] Initial 1.14.2 port of decorative blocks."
},
"promos": {
"1.14.3-recommended": "",
"1.14.3-latest": "1.0.9-b4"
"1.14.4-recommended": "",
"1.14.4-latest": "1.0.9-b9"
}
}

View file

@ -10,50 +10,73 @@ Mod sources for Minecraft version 1.14.3.
----
## Version history
- v1.0.9-b4 [E] Experimental: Config skel ported (!not all options have effect yet).
[E] Experimental: JEI integration for opt-outs and crafting table ported
(also addresses issue #38).
~ v1.0.9-b10 [U]
- v1.0.9-b3 [F] Additional item drop fixes when blocks are destroyed (issue #39).
- v1.0.9-b9 [U] Update to Forge 1.14.4-28.0.40/20190719-1.14.3 for Forge
testing.
- v1.0.9-b2 [U] Updated to Forge 1.14.3-27.0.25/20190621-1.14.2.
[F] Fixed recipe collision of Metal Rung Ladder (issue #37,
thx ProsperCraft for reporting).
[F] Fixed opening crafting table, furni, dropper server crash
issue #35 (thx ProsperCraft also here).
[F] Fixed missing pole/support item drops (issue #36, ProsperCraft).
- v1.0.9-b8 [U] UPDATE TO 1.14.4. Forge 1.14.4-28.0.11/20190719-1.14.3.
- v1.0.9-b1 [U] Updated to MC1.14.3, Forge 1.14.3-27.0.17/20190621-1.14.2.
[A] Added Small Mineral Smelter.
- v1.0.9-b7 [U] Updated to Forge 1.14.3-27.0.60/20190719-1.14.3.
[F] Disabled all early implemented fuild handling of valves
and the Fluid Accumulator to prevent world loading
hang-ups (issue #42, thx TheOhmegha for reporting).
Will be re-enabled after fluid handling released in Forge.
[F] Fixed blockstate model locations for signs and crafting
table (issue #43, thx ProsperCraft for the beta test).
- v1.0.8-b3 [A] Ported slabs and slab slices from 1.12.2.
[A] IE independent ("standalone") recipes ported.
- v1.0.9-b6 [U] Updated to Forge 1.14.3-27.0.50/20190621-1.14.2.
- v1.0.8-b2 [U] Updated to Forge BETA 1.14.2-26.0.63/20190621-1.14.2,
code adapted to new mappings.
[M] Updated 1st/3rd person item model rotations/translations.
- v1.0.9-b5 [A] Added missing recipes for slabs, stained clinker, half-slabs, valves.
[M] Standalone recipes adapted.
[F] Lang files: Fixed double newline escape.
[A] Implicit opt-out of hard IE dependent blocks ported (e.g. Concrete Wall).
[M] Basic mod config features, opt-outs and tweaks ported.
- v1.0.8-b1 [V] Feature set of 1.12 ported.
[A] CTRL-SHIFT tooltips ported.
[A] Ported stained clinker block/stairs.
[M] Updated textures.
[I] Issue: Scoped recipe constants still not working.
- v1.0.9-b4 [E] Experimental: Config skel ported (!not all options have effect yet).
[E] Experimental: JEI integration for opt-outs and crafting table ported
(also addresses issue #38).
- v1.0.7-b5 [U] Updated to Forge BETA 1.14.2-26.0.35/20190608-1.14.2.
[A] Factory dropper functionality ported.
[A] Small lab furnace functionality ported.
[A] Small electrical lab furnace functionality ported.
[A] Small waste incinerator functionality ported.
[A] Fluid valves, Passive Fluid Accumulator ported.
[I] Issue: Scoped recipe constants still not working.
- v1.0.9-b3 [F] Additional item drop fixes when blocks are destroyed (issue #39).
- v1.0.7-b4 [U] Updated to Forge BETA 1.14.2-26.0.32/20190608-1.14.2.
[A] Sitting on the stool ported.
[A] Ladder climbing speed boost ported.
[A] Crafting table functionality ported.
[I] Issue: Scoped recipe constants not working yet with
the current Forge version (or somehow changed).
- v1.0.9-b2 [U] Updated to Forge 1.14.3-27.0.25/20190621-1.14.2.
[F] Fixed recipe collision of Metal Rung Ladder (issue #37,
thx ProsperCraft for reporting).
[F] Fixed opening crafting table, furni, dropper server crash
issue #35 (thx ProsperCraft also here).
[F] Fixed missing pole/support item drops (issue #36, ProsperCraft).
- v1.0.7-b3 [A] Initial 1.14.2 port of decorative blocks.
- v1.0.9-b1 [U] Updated to MC1.14.3, Forge 1.14.3-27.0.17/20190621-1.14.2.
[A] Added Small Mineral Smelter.
- v1.0.8-b3 [A] Ported slabs and slab slices from 1.12.2.
[A] IE independent ("standalone") recipes ported.
- v1.0.8-b2 [U] Updated to Forge BETA 1.14.2-26.0.63/20190621-1.14.2,
code adapted to new mappings.
[M] Updated 1st/3rd person item model rotations/translations.
- v1.0.8-b1 [V] Feature set of 1.12 ported.
[A] CTRL-SHIFT tooltips ported.
[A] Ported stained clinker block/stairs.
[M] Updated textures.
[I] Issue: Scoped recipe constants still not working.
- v1.0.7-b5 [U] Updated to Forge BETA 1.14.2-26.0.35/20190608-1.14.2.
[A] Factory dropper functionality ported.
[A] Small lab furnace functionality ported.
[A] Small electrical lab furnace functionality ported.
[A] Small waste incinerator functionality ported.
[A] Fluid valves, Passive Fluid Accumulator ported.
[I] Issue: Scoped recipe constants still not working.
- v1.0.7-b4 [U] Updated to Forge BETA 1.14.2-26.0.32/20190608-1.14.2.
[A] Sitting on the stool ported.
[A] Ladder climbing speed boost ported.
[A] Crafting table functionality ported.
[I] Issue: Scoped recipe constants not working yet with
the current Forge version (or somehow changed).
- v1.0.7-b3 [A] Initial 1.14.2 port of decorative blocks.
----

View file

@ -0,0 +1,18 @@
/*
* BluSunrize
* Copyright (c) 2017
*
* This code is licensed under "Blu's License of Common Sense"
* Details can be found in the license file in the root folder of this project
*/
package blusunrize.immersiveengineering.api.fluid;
import net.minecraft.util.Direction;
public interface IFluidPipe
{
boolean canOutputPressurized(boolean consumePower);
boolean hasOutputConnection(Direction side);
}

View file

@ -0,0 +1,662 @@
/*
* @file ModContent.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2018 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)
*
* Definition and initialisation of blocks of this
* module, along with their tile entities if applicable.
*
* Note: Straight forward definition of different blocks/entities
* to make recipes, models and texture definitions easier.
*/
package wile.engineersdecor;
import org.apache.commons.lang3.ArrayUtils;
import wile.engineersdecor.blocks.*;
import wile.engineersdecor.detail.ModAuxiliaries;
import net.minecraft.client.gui.ScreenManager;
import net.minecraft.inventory.container.ContainerType;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityClassification;
import net.minecraft.entity.EntityType;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.block.material.MaterialColor;
import net.minecraft.block.Block;
import net.minecraft.block.SoundType;
import net.minecraft.block.material.Material;
import net.minecraft.item.Item;
import net.minecraft.item.BlockItem;
import net.minecraft.util.ResourceLocation;
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 java.util.ArrayList;
import java.util.List;
import java.util.Collections;
import javax.annotation.Nonnull;
@SuppressWarnings("unused")
public class ModContent
{
//--------------------------------------------------------------------------------------------------------------------
// Blocks
//--------------------------------------------------------------------------------------------------------------------
public static final BlockDecorFull CLINKER_BRICK_BLOCK = (BlockDecorFull)(new BlockDecorFull(
BlockDecor.CFG_DEFAULT,
Block.Properties.create(Material.ROCK, MaterialColor.STONE).hardnessAndResistance(3f, 50f).sound(SoundType.STONE)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "clinker_brick_block"));
public static final BlockDecorSlab CLINKER_BRICK_SLAB = (BlockDecorSlab)(new BlockDecorSlab(
BlockDecor.CFG_DEFAULT,
Block.Properties.create(Material.ROCK, MaterialColor.STONE).hardnessAndResistance(3f, 50f).sound(SoundType.STONE)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "clinker_brick_slab"));
public static final BlockDecorStairs CLINKER_BRICK_STAIRS = (BlockDecorStairs)(new BlockDecorStairs(
BlockDecor.CFG_DEFAULT,
CLINKER_BRICK_BLOCK.getDefaultState(),
Block.Properties.create(Material.ROCK, MaterialColor.STONE).hardnessAndResistance(3f, 50f).sound(SoundType.STONE)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "clinker_brick_stairs"));
public static final BlockDecorWall CLINKER_BRICK_WALL = (BlockDecorWall)(new BlockDecorWall(
BlockDecor.CFG_DEFAULT,
Block.Properties.create(Material.ROCK, MaterialColor.STONE).hardnessAndResistance(3f, 50f).sound(SoundType.STONE)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "clinker_brick_wall"));
// -------------------------------------------------------------------------------------------------------------------
public static final BlockDecorFull CLINKER_BRICK_STAINED_BLOCK = (BlockDecorFull)(new BlockDecorFull(
BlockDecor.CFG_DEFAULT,
Block.Properties.create(Material.ROCK, MaterialColor.STONE).hardnessAndResistance(3f, 50f).sound(SoundType.STONE)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "clinker_brick_stained_block"));
public static final BlockDecorSlab CLINKER_BRICK_STAINED_SLAB = (BlockDecorSlab)(new BlockDecorSlab(
BlockDecor.CFG_DEFAULT,
Block.Properties.create(Material.ROCK, MaterialColor.STONE).hardnessAndResistance(3f, 50f).sound(SoundType.STONE)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "clinker_brick_stained_slab"));
public static final BlockDecorStairs CLINKER_BRICK_STAINED_STAIRS = (BlockDecorStairs)(new BlockDecorStairs(
BlockDecor.CFG_DEFAULT,
CLINKER_BRICK_BLOCK.getDefaultState(),
Block.Properties.create(Material.ROCK, MaterialColor.STONE).hardnessAndResistance(3f, 50f).sound(SoundType.STONE)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "clinker_brick_stained_stairs"));
// -------------------------------------------------------------------------------------------------------------------
public static final BlockDecorFull SLAG_BRICK_BLOCK = (BlockDecorFull)(new BlockDecorFull(
BlockDecor.CFG_DEFAULT,
Block.Properties.create(Material.ROCK, MaterialColor.STONE).hardnessAndResistance(3f, 50f).sound(SoundType.STONE)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "slag_brick_block"));
public static final BlockDecorSlab SLAG_BRICK_SLAB = (BlockDecorSlab)(new BlockDecorSlab(
BlockDecor.CFG_DEFAULT,
Block.Properties.create(Material.ROCK, MaterialColor.STONE).hardnessAndResistance(3f, 50f).sound(SoundType.STONE)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "slag_brick_slab"));
public static final BlockDecorStairs SLAG_BRICK_STAIRS = (BlockDecorStairs)(new BlockDecorStairs(
BlockDecor.CFG_DEFAULT,
SLAG_BRICK_BLOCK.getDefaultState(),
Block.Properties.create(Material.ROCK, MaterialColor.STONE).hardnessAndResistance(3f, 50f).sound(SoundType.STONE)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "slag_brick_stairs"));
public static final BlockDecorWall SLAG_BRICK_WALL = (BlockDecorWall)(new BlockDecorWall(
BlockDecor.CFG_DEFAULT,
Block.Properties.create(Material.ROCK, MaterialColor.STONE).hardnessAndResistance(3f, 50f).sound(SoundType.STONE)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "slag_brick_wall"));
// -------------------------------------------------------------------------------------------------------------------
public static final BlockDecorFull REBAR_CONCRETE_BLOCK = (BlockDecorFull)(new BlockDecorFull(
BlockDecor.CFG_DEFAULT,
Block.Properties.create(Material.ROCK, MaterialColor.STONE).hardnessAndResistance(5f, 2000f).sound(SoundType.STONE)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "rebar_concrete"));
public static final BlockDecorSlab REBAR_CONCRETE_SLAB = (BlockDecorSlab)(new BlockDecorSlab(
BlockDecor.CFG_DEFAULT,
Block.Properties.create(Material.ROCK, MaterialColor.STONE).hardnessAndResistance(5f, 2000f).sound(SoundType.STONE)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "rebar_concrete_slab"));
public static final BlockDecorStairs REBAR_CONCRETE_STAIRS = (BlockDecorStairs)(new BlockDecorStairs(
BlockDecor.CFG_DEFAULT,
REBAR_CONCRETE_BLOCK.getDefaultState(),
Block.Properties.create(Material.ROCK, MaterialColor.STONE).hardnessAndResistance(5f, 2000f).sound(SoundType.STONE)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "rebar_concrete_stairs"));
public static final BlockDecorWall REBAR_CONCRETE_WALL = (BlockDecorWall)(new BlockDecorWall(
BlockDecor.CFG_DEFAULT,
Block.Properties.create(Material.ROCK, MaterialColor.STONE).hardnessAndResistance(5f, 2000f).sound(SoundType.STONE)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "rebar_concrete_wall"));
public static final BlockDecorHalfSlab HALFSLAB_REBARCONCRETE = (BlockDecorHalfSlab)(new BlockDecorHalfSlab(
BlockDecor.CFG_DEFAULT,
Block.Properties.create(Material.ROCK, MaterialColor.STONE).hardnessAndResistance(5f, 2000f).sound(SoundType.STONE)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "halfslab_rebar_concrete"));
// -------------------------------------------------------------------------------------------------------------------
public static final BlockDecorFull REBAR_CONCRETE_TILE = (BlockDecorFull)(new BlockDecorFull(
BlockDecor.CFG_DEFAULT,
Block.Properties.create(Material.ROCK, MaterialColor.STONE).hardnessAndResistance(5f, 2000f).sound(SoundType.STONE)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "rebar_concrete_tile"));
public static final BlockDecorSlab REBAR_CONCRETE_TILE_SLAB = (BlockDecorSlab)(new BlockDecorSlab(
BlockDecor.CFG_DEFAULT,
Block.Properties.create(Material.ROCK, MaterialColor.STONE).hardnessAndResistance(5f, 2000f).sound(SoundType.STONE)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "rebar_concrete_tile_slab"));
public static final BlockDecorStairs REBAR_CONCRETE_TILE_STAIRS = (BlockDecorStairs)(new BlockDecorStairs(
BlockDecor.CFG_DEFAULT,
REBAR_CONCRETE_TILE.getDefaultState(),
Block.Properties.create(Material.ROCK, MaterialColor.STONE).hardnessAndResistance(5f, 2000f).sound(SoundType.STONE)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "rebar_concrete_tile_stairs"));
// -------------------------------------------------------------------------------------------------------------------
public static final BlockDecorGlassBlock PANZERGLASS_BLOCK = (BlockDecorGlassBlock)(new BlockDecorGlassBlock(
BlockDecor.CFG_DEFAULT,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(5f, 2000f).sound(SoundType.METAL)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "panzerglass_block"));
public static final BlockDecorSlab PANZERGLASS_SLAB = (BlockDecorSlab)(new BlockDecorSlab(
BlockDecor.CFG_TRANSLUCENT,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(5f, 2000f).sound(SoundType.METAL)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "panzerglass_slab"));
// -------------------------------------------------------------------------------------------------------------------
public static final BlockDecorLadder METAL_RUNG_LADDER = (BlockDecorLadder)(new BlockDecorLadder(
BlockDecor.CFG_DEFAULT,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(1.0f, 25f).sound(SoundType.METAL)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "metal_rung_ladder"));
public static final BlockDecorLadder METAL_RUNG_STEPS = (BlockDecorLadder)(new BlockDecorLadder(
BlockDecor.CFG_DEFAULT,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(1.0f, 25f).sound(SoundType.METAL)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "metal_rung_steps"));
public static final BlockDecorLadder TREATED_WOOD_LADDER = (BlockDecorLadder)(new BlockDecorLadder(
BlockDecor.CFG_DEFAULT,
Block.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(1.0f, 25f).sound(SoundType.WOOD)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "treated_wood_ladder"));
// -------------------------------------------------------------------------------------------------------------------
public static final BlockDecor TREATED_WOOD_TABLE = (BlockDecor)(new BlockDecor(
BlockDecor.CFG_CUTOUT,
Block.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(2f, 15f).sound(SoundType.WOOD),
ModAuxiliaries.getPixeledAABB(1,0,1, 15,15.9,15)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "treated_wood_table"));
public static final BlockDecorChair TREATED_WOOD_STOOL = (BlockDecorChair)(new BlockDecorChair(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_LOOK_PLACEMENT,
Block.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(2f, 15f).sound(SoundType.WOOD),
ModAuxiliaries.getPixeledAABB(4.1,0,4.1, 11.8,8.8,11.8)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "treated_wood_stool"));
public static final BlockDecorDirected TREATED_WOOD_WINDOWSILL = (BlockDecorDirected)(new BlockDecorDirected(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_FACING_PLACEMENT,
Block.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(2f, 15f).sound(SoundType.WOOD),
ModAuxiliaries.getPixeledAABB(0.5,15,10.5, 15.5,16,16)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "treated_wood_windowsill"));
public static final BlockDecorDirected INSET_LIGHT_IRON = (BlockDecorDirected)(new BlockDecorDirected(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_OPPOSITE_PLACEMENT,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL).lightValue(15),
ModAuxiliaries.getPixeledAABB(5.2,5.2,15.7, 10.8,10.8,16.0)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "iron_inset_light"));
// -------------------------------------------------------------------------------------------------------------------
public static final BlockDecorWindow TREATED_WOOD_WINDOW = (BlockDecorWindow)(new BlockDecorWindow(
BlockDecor.CFG_LOOK_PLACEMENT,
Block.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(2f, 15f).sound(SoundType.GLASS),
ModAuxiliaries.getPixeledAABB(0,0,7, 16,16,9)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "treated_wood_window"));
public static final BlockDecorWindow STEEL_FRAMED_WINDOW = (BlockDecorWindow)(new BlockDecorWindow(
BlockDecor.CFG_LOOK_PLACEMENT,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.GLASS),
ModAuxiliaries.getPixeledAABB(0,0,7.5, 16,16,8.5)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "steel_framed_window"));
// -------------------------------------------------------------------------------------------------------------------
public static final BlockDecorStraightPole TREATED_WOOD_POLE = (BlockDecorStraightPole)(new BlockDecorStraightPole(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_FLIP_PLACEMENT_IF_SAME,
Block.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(2f, 15f).sound(SoundType.WOOD),
ModAuxiliaries.getPixeledAABB(5.8,5.8,0, 10.2,10.2,16)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "treated_wood_pole"));
public static final BlockDecorStraightPole TREATED_WOOD_POLE_HEAD = (BlockDecorStraightPole)(new BlockDecorStraightPole(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_FLIP_PLACEMENT_IF_SAME,
Block.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(2f, 15f).sound(SoundType.WOOD),
ModAuxiliaries.getPixeledAABB(5.8,5.8,0, 10.2,10.2,16)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "treated_wood_pole_head"));
public static final BlockDecorStraightPole TREATED_WOOD_POLE_SUPPORT = (BlockDecorStraightPole)(new BlockDecorStraightPole(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_FLIP_PLACEMENT_IF_SAME,
Block.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(2f, 15f).sound(SoundType.WOOD),
ModAuxiliaries.getPixeledAABB(5.8,5.8,0, 10.2,10.2,16)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "treated_wood_pole_support"));
public static final BlockDecorStraightPole THIN_STEEL_POLE = (BlockDecorStraightPole)(new BlockDecorStraightPole(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_FACING_PLACEMENT,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL),
ModAuxiliaries.getPixeledAABB(6,6,0, 10,10,16)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "thin_steel_pole"));
public static final BlockDecorStraightPole THIN_STEEL_POLE_HEAD = (BlockDecorStraightPole)(new BlockDecorStraightPole(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_FLIP_PLACEMENT_IF_SAME,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL),
ModAuxiliaries.getPixeledAABB(6,6,0, 10,10,16)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "thin_steel_pole_head"));
public static final BlockDecorStraightPole THICK_STEEL_POLE = (BlockDecorStraightPole)(new BlockDecorStraightPole(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_FACING_PLACEMENT,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL),
ModAuxiliaries.getPixeledAABB(5,5,0, 11,11,16)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "thick_steel_pole"));
public static final BlockDecorStraightPole THICK_STEEL_POLE_HEAD = (BlockDecorStraightPole)(new BlockDecorStraightPole(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_FLIP_PLACEMENT_IF_SAME,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL),
ModAuxiliaries.getPixeledAABB(5,5,0, 11,11,16)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "thick_steel_pole_head"));
public static final BlockDecorHorizontalSupport STEEL_DOUBLE_T_SUPPORT = (BlockDecorHorizontalSupport)(new BlockDecorHorizontalSupport(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_LOOK_PLACEMENT,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL),
ModAuxiliaries.getPixeledAABB(5,11,0, 11,16,16)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "steel_double_t_support"));
// -------------------------------------------------------------------------------------------------------------------
public static final BlockDecorDirected SIGN_MODLOGO = (BlockDecorDirected)(new BlockDecorDirected(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_OPPOSITE_PLACEMENT,
Block.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(1f, 1000f).sound(SoundType.WOOD).lightValue(1),
ModAuxiliaries.getPixeledAABB(0,0,15.6, 16,16,16.0)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "sign_decor"));
public static final BlockDecorDirected SIGN_HOTWIRE = (BlockDecorDirected)(new BlockDecorDirected(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_OPPOSITE_PLACEMENT,
Block.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(1f, 1f).sound(SoundType.WOOD),
ModAuxiliaries.getPixeledAABB(2,2,15.6, 14,14,16)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "sign_hotwire"));
public static final BlockDecorDirected SIGN_DANGER = (BlockDecorDirected)(new BlockDecorDirected(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_OPPOSITE_PLACEMENT,
Block.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(1f, 1f).sound(SoundType.WOOD),
ModAuxiliaries.getPixeledAABB(2,2,15.6, 14,14,16)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "sign_danger"));
public static final BlockDecorDirected SIGN_DEFENSE = (BlockDecorDirected)(new BlockDecorDirected(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_OPPOSITE_PLACEMENT,
Block.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(1f, 1f).sound(SoundType.WOOD),
ModAuxiliaries.getPixeledAABB(2,2,15.6, 14,14,16)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "sign_defense"));
public static final BlockDecorDirected SIGN_FACTORY_AREA = (BlockDecorDirected)(new BlockDecorDirected(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_OPPOSITE_PLACEMENT,
Block.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(1f, 1f).sound(SoundType.WOOD),
ModAuxiliaries.getPixeledAABB(2,2,15.6, 14,14,16)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "sign_factoryarea"));
// -------------------------------------------------------------------------------------------------------------------
public static final BlockDecorCraftingTable TREATED_WOOD_CRAFTING_TABLE = (BlockDecorCraftingTable)(new BlockDecorCraftingTable(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_LOOK_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT,
Block.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(1f, 15f).sound(SoundType.WOOD),
ModAuxiliaries.getPixeledAABB(1,0,1, 15,15.9,15)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "treated_wood_crafting_table"));
public static final BlockDecorFurnace SMALL_LAB_FURNACE = (BlockDecorFurnace)(new BlockDecorFurnace(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_LOOK_PLACEMENT,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(1f, 15f).sound(SoundType.METAL),
ModAuxiliaries.getPixeledAABB(1,0,1, 15,15,16.0)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "small_lab_furnace"));
public static final BlockDecorFurnaceElectrical SMALL_ELECTRICAL_FURNACE = (BlockDecorFurnaceElectrical)(new BlockDecorFurnaceElectrical(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_LOOK_PLACEMENT|BlockDecor.CFG_ELECTRICAL,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL),
ModAuxiliaries.getPixeledAABB(0,0,0, 16,16,16)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "small_electrical_furnace"));
public static final BlockDecorDropper FACTORY_DROPPER = (BlockDecorDropper)(new BlockDecorDropper(
BlockDecor.CFG_LOOK_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT|BlockDecor.CFG_REDSTONE_CONTROLLED,
Block.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(2f, 15f).sound(SoundType.METAL),
ModAuxiliaries.getPixeledAABB(0,0,0, 16,16,15)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "factory_dropper"));
public static final BlockDecorWasteIncinerator SMALL_WASTE_INCINERATOR = (BlockDecorWasteIncinerator)(new BlockDecorWasteIncinerator(
BlockDecor.CFG_DEFAULT|BlockDecor.CFG_ELECTRICAL,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL),
ModAuxiliaries.getPixeledAABB(0,0,0, 16,16,16)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "small_waste_incinerator"));
public static final BlockDecorMineralSmelter SMALL_MINERAL_SMELTER = (BlockDecorMineralSmelter)(new BlockDecorMineralSmelter(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_LOOK_PLACEMENT|BlockDecor.CFG_ELECTRICAL,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL),
ModAuxiliaries.getPixeledAABB(1.1,0,1.1, 14.9,16,14.9)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "small_mineral_smelter"));
public static final BlockDecorPipeValve STRAIGHT_CHECK_VALVE = (BlockDecorPipeValve)(new BlockDecorPipeValve(
BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT|BlockDecor.CFG_FLIP_PLACEMENT_SHIFTCLICK|BlockDecor.CFG_CUTOUT,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL),
ModAuxiliaries.getPixeledAABB(4,4,0, 12,12,16)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "straight_pipe_valve"));
public static final BlockDecorPipeValve STRAIGHT_REDSTONE_VALVE = (BlockDecorPipeValve)(new BlockDecorPipeValve(
BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT|BlockDecor.CFG_FLIP_PLACEMENT_SHIFTCLICK|BlockDecor.CFG_CUTOUT|BlockDecor.CFG_REDSTONE_CONTROLLED,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL),
ModAuxiliaries.getPixeledAABB(4,4,0, 12,12,16)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "straight_pipe_valve_redstone"));
public static final BlockDecorPipeValve STRAIGHT_REDSTONE_ANALOG_VALVE = (BlockDecorPipeValve)(new BlockDecorPipeValve(
BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT|BlockDecor.CFG_FLIP_PLACEMENT_SHIFTCLICK|BlockDecor.CFG_CUTOUT|BlockDecor.CFG_REDSTONE_CONTROLLED|BlockDecor.CFG_ANALOG,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL),
ModAuxiliaries.getPixeledAABB(4,4,0, 12,12,16)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "straight_pipe_valve_redstone_analog"));
public static final BlockDecorPassiveFluidAccumulator PASSIVE_FLUID_ACCUMULATOR = (BlockDecorPassiveFluidAccumulator)(new BlockDecorPassiveFluidAccumulator(
BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT|BlockDecor.CFG_FLIP_PLACEMENT_SHIFTCLICK|BlockDecor.CFG_CUTOUT,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL),
ModAuxiliaries.getPixeledAABB(0,0,0, 16,16,16)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "passive_fluid_accumulator"));
// -------------------------------------------------------------------------------------------------------------------
public static final BlockDecorWall CONCRETE_WALL = (BlockDecorWall)(new BlockDecorWall(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HARD_IE_DEPENDENT,
Block.Properties.create(Material.ROCK, MaterialColor.STONE).hardnessAndResistance(2f, 50f).sound(SoundType.STONE)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "concrete_wall"));
public static final BlockDecorHalfSlab HALFSLAB_CONCRETE = (BlockDecorHalfSlab)(new BlockDecorHalfSlab(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HARD_IE_DEPENDENT,
Block.Properties.create(Material.ROCK, MaterialColor.STONE).hardnessAndResistance(1f, 10f).sound(SoundType.STONE)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "halfslab_concrete"));
public static final BlockDecorHalfSlab HALFSLAB_TREATEDWOOD = (BlockDecorHalfSlab)(new BlockDecorHalfSlab(
BlockDecor.CFG_CUTOUT,
Block.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(1f, 4f).sound(SoundType.WOOD)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "halfslab_treated_wood"));
public static final BlockDecorHalfSlab HALFSLAB_SHEETMETALIRON = (BlockDecorHalfSlab)(new BlockDecorHalfSlab(
BlockDecor.CFG_CUTOUT,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(1f, 10f).sound(SoundType.METAL)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "halfslab_sheetmetal_iron"));
public static final BlockDecorHalfSlab HALFSLAB_SHEETMETALSTEEL = (BlockDecorHalfSlab)(new BlockDecorHalfSlab(
BlockDecor.CFG_CUTOUT,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(1f, 10f).sound(SoundType.METAL)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "halfslab_sheetmetal_steel"));
public static final BlockDecorHalfSlab HALFSLAB_SHEETMETALCOPPER = (BlockDecorHalfSlab)(new BlockDecorHalfSlab(
BlockDecor.CFG_CUTOUT,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(1f, 10f).sound(SoundType.METAL)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "halfslab_sheetmetal_copper"));
public static final BlockDecorHalfSlab HALFSLAB_SHEETMETALGOLD = (BlockDecorHalfSlab)(new BlockDecorHalfSlab(
BlockDecor.CFG_CUTOUT,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(1f, 10f).sound(SoundType.METAL)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "halfslab_sheetmetal_gold"));
public static final BlockDecorHalfSlab HALFSLAB_SHEETMETALALUMINIUM = (BlockDecorHalfSlab)(new BlockDecorHalfSlab(
BlockDecor.CFG_CUTOUT,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(1f, 10f).sound(SoundType.METAL)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "halfslab_sheetmetal_aluminum"));
// -------------------------------------------------------------------------------------------------------------------
private static final Block modBlocks[] = {
SMALL_LAB_FURNACE,
FACTORY_DROPPER,
SMALL_ELECTRICAL_FURNACE,
SMALL_WASTE_INCINERATOR,
SMALL_MINERAL_SMELTER,
CLINKER_BRICK_BLOCK,
CLINKER_BRICK_SLAB,
CLINKER_BRICK_STAIRS,
CLINKER_BRICK_WALL,
CLINKER_BRICK_STAINED_BLOCK,
CLINKER_BRICK_STAINED_SLAB,
CLINKER_BRICK_STAINED_STAIRS,
SLAG_BRICK_BLOCK,
SLAG_BRICK_SLAB,
SLAG_BRICK_STAIRS,
SLAG_BRICK_WALL,
REBAR_CONCRETE_BLOCK,
REBAR_CONCRETE_SLAB,
REBAR_CONCRETE_STAIRS,
REBAR_CONCRETE_WALL,
REBAR_CONCRETE_TILE,
REBAR_CONCRETE_TILE_SLAB,
REBAR_CONCRETE_TILE_STAIRS,
HALFSLAB_REBARCONCRETE,
HALFSLAB_CONCRETE,
//HALFSLAB_TREATEDWOOD,
//HALFSLAB_SHEETMETALIRON
//HALFSLAB_SHEETMETALSTEEL,
//HALFSLAB_SHEETMETALCOPPER,
//HALFSLAB_SHEETMETALGOLD,
//HALFSLAB_SHEETMETALALUMINIUM,
CONCRETE_WALL,
METAL_RUNG_LADDER,
METAL_RUNG_STEPS,
TREATED_WOOD_LADDER,
TREATED_WOOD_POLE,
TREATED_WOOD_TABLE,
PANZERGLASS_BLOCK,
PANZERGLASS_SLAB,
INSET_LIGHT_IRON,
TREATED_WOOD_STOOL,
TREATED_WOOD_WINDOWSILL,
TREATED_WOOD_CRAFTING_TABLE,
STEEL_FRAMED_WINDOW,
TREATED_WOOD_WINDOW,
TREATED_WOOD_POLE_HEAD,
TREATED_WOOD_POLE_SUPPORT,
SIGN_MODLOGO,
THIN_STEEL_POLE,
THIN_STEEL_POLE_HEAD,
THICK_STEEL_POLE,
THICK_STEEL_POLE_HEAD,
SIGN_HOTWIRE,
SIGN_DANGER,
STEEL_DOUBLE_T_SUPPORT,
SIGN_DEFENSE,
SIGN_FACTORY_AREA
};
private static final Block devBlocks[] = {
STRAIGHT_CHECK_VALVE,
STRAIGHT_REDSTONE_VALVE,
STRAIGHT_REDSTONE_ANALOG_VALVE,
PASSIVE_FLUID_ACCUMULATOR,
};
//--------------------------------------------------------------------------------------------------------------------
// Tile entities bound exclusively to the blocks above
//--------------------------------------------------------------------------------------------------------------------
public static final TileEntityType<?> TET_TREATED_WOOD_CRAFTING_TABLE = TileEntityType.Builder
.create(BlockDecorCraftingTable.BTileEntity::new, TREATED_WOOD_CRAFTING_TABLE)
.build(null)
.setRegistryName(ModEngineersDecor.MODID, "te_treated_wood_crafting_table");
public static final TileEntityType<?> TET_SMALL_LAB_FURNACE = TileEntityType.Builder
.create(BlockDecorFurnace.BTileEntity::new, SMALL_LAB_FURNACE)
.build(null)
.setRegistryName(ModEngineersDecor.MODID, "te_small_lab_furnace");
public static final TileEntityType<?> TET_SMALL_ELECTRICAL_FURNACE = TileEntityType.Builder
.create(BlockDecorFurnaceElectrical.BTileEntity::new, SMALL_ELECTRICAL_FURNACE)
.build(null)
.setRegistryName(ModEngineersDecor.MODID, "te_small_electrical_furnace");
public static final TileEntityType<?> TET_FACTORY_DROPPER = TileEntityType.Builder
.create(BlockDecorDropper.BTileEntity::new, FACTORY_DROPPER)
.build(null)
.setRegistryName(ModEngineersDecor.MODID, "te_factory_dropper");
public static final TileEntityType<?> TET_WASTE_INCINERATOR = TileEntityType.Builder
.create(BlockDecorWasteIncinerator.BTileEntity::new, SMALL_WASTE_INCINERATOR)
.build(null)
.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)
.build(null)
.setRegistryName(ModEngineersDecor.MODID, "te_pipe_valve");
public static final TileEntityType<?> TET_PASSIVE_FLUID_ACCUMULATOR = TileEntityType.Builder
.create(BlockDecorPassiveFluidAccumulator.BTileEntity::new, PASSIVE_FLUID_ACCUMULATOR)
.build(null)
.setRegistryName(ModEngineersDecor.MODID, "te_passive_fluid_accumulator");
public static final TileEntityType<?> TET_MINERAL_SMELTER = TileEntityType.Builder
.create(BlockDecorMineralSmelter.BTileEntity::new, SMALL_MINERAL_SMELTER)
.build(null)
.setRegistryName(ModEngineersDecor.MODID, "te_small_mineral_smelter");
private static final TileEntityType<?> tile_entity_types[] = {
TET_TREATED_WOOD_CRAFTING_TABLE,
TET_SMALL_LAB_FURNACE,
TET_FACTORY_DROPPER,
TET_SMALL_ELECTRICAL_FURNACE,
TET_WASTE_INCINERATOR,
TET_STRAIGHT_PIPE_VALVE,
TET_PASSIVE_FLUID_ACCUMULATOR,
TET_MINERAL_SMELTER
};
//--------------------------------------------------------------------------------------------------------------------
// Entities bound exclusively to the blocks above
//--------------------------------------------------------------------------------------------------------------------
public static final EntityType<? extends Entity> ET_CHAIR = EntityType.Builder
.create(BlockDecorChair.EntityChair::new, EntityClassification.MISC)
.immuneToFire().size(1e-3f, 1e-3f).disableSerialization()
.setShouldReceiveVelocityUpdates(false).setUpdateInterval(4)
.setCustomClientFactory(BlockDecorChair.EntityChair::customClientFactory)
.build(new ResourceLocation(ModEngineersDecor.MODID, "et_chair").toString())
.setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "et_chair"))
;
private static final EntityType<?> entity_types[] = {
ET_CHAIR
};
//--------------------------------------------------------------------------------------------------------------------
// Container registration
//--------------------------------------------------------------------------------------------------------------------
public static final ContainerType<BlockDecorCraftingTable.BContainer> CT_TREATED_WOOD_CRAFTING_TABLE;
public static final ContainerType<BlockDecorDropper.BContainer> CT_FACTORY_DROPPER;
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;
static {
CT_TREATED_WOOD_CRAFTING_TABLE = (new ContainerType<BlockDecorCraftingTable.BContainer>(BlockDecorCraftingTable.BContainer::new));
CT_TREATED_WOOD_CRAFTING_TABLE.setRegistryName(ModEngineersDecor.MODID,"ct_treated_wood_crafting_table");
CT_FACTORY_DROPPER = (new ContainerType<BlockDecorDropper.BContainer>(BlockDecorDropper.BContainer::new));
CT_FACTORY_DROPPER.setRegistryName(ModEngineersDecor.MODID,"ct_factory_dropper");
CT_SMALL_LAB_FURNACE = (new ContainerType<BlockDecorFurnace.BContainer>(BlockDecorFurnace.BContainer::new));
CT_SMALL_LAB_FURNACE.setRegistryName(ModEngineersDecor.MODID,"ct_small_lab_furnace");
CT_SMALL_ELECTRICAL_FURNACE = (new ContainerType<BlockDecorFurnaceElectrical.BContainer>(BlockDecorFurnaceElectrical.BContainer::new));
CT_SMALL_ELECTRICAL_FURNACE.setRegistryName(ModEngineersDecor.MODID,"ct_small_electrical_furnace");
CT_WASTE_INCINERATOR = (new ContainerType<BlockDecorWasteIncinerator.BContainer>(BlockDecorWasteIncinerator.BContainer::new));
CT_WASTE_INCINERATOR.setRegistryName(ModEngineersDecor.MODID,"ct_small_waste_incinerator");
}
// DON'T FORGET TO REGISTER THE GUI in registerContainerGuis(), no list/map format found yet for that.
private static final ContainerType<?> container_types[] = {
CT_TREATED_WOOD_CRAFTING_TABLE,
CT_FACTORY_DROPPER,
CT_SMALL_LAB_FURNACE,
CT_SMALL_ELECTRICAL_FURNACE,
CT_WASTE_INCINERATOR
};
//--------------------------------------------------------------------------------------------------------------------
// Initialisation events
//--------------------------------------------------------------------------------------------------------------------
private static ArrayList<Block> registeredBlocks = new ArrayList<>();
public static boolean isExperimentalBlock(Block block)
{ return ArrayUtils.contains(devBlocks, block); }
@Nonnull
public static List<Block> getRegisteredBlocks()
{ return Collections.unmodifiableList(registeredBlocks); }
public static final void registerBlocks(final RegistryEvent.Register<Block> event)
{
ArrayList<Block> allBlocks = new ArrayList<>();
Collections.addAll(allBlocks, modBlocks);
if(ModAuxiliaries.isModLoaded("immersiveengineering")) ModAuxiliaries.logInfo("Immersive Engineering also installed ...");
// @todo: config not available yet, other registration control for experimental features needed.
Collections.addAll(allBlocks, devBlocks);
registeredBlocks.addAll(allBlocks);
for(Block e:registeredBlocks) event.getRegistry().register(e);
ModAuxiliaries.logInfo("Registered " + Integer.toString(registeredBlocks.size()) + " blocks.");
}
public static final void registerItemBlocks(final RegistryEvent.Register<Item> event)
{
int n = 0;
for(Block e:registeredBlocks) {
ResourceLocation rl = e.getRegistryName();
if(rl == null) continue;
event.getRegistry().register(new BlockItem(e, (new BlockItem.Properties().group(ModEngineersDecor.ITEMGROUP))).setRegistryName(rl));
++n;
}
}
public static final void registerTileEntities(final RegistryEvent.Register<TileEntityType<?>> event)
{
int n_registered = 0;
for(final TileEntityType<?> e:tile_entity_types) {
event.getRegistry().register(e);
++n_registered;
}
ModAuxiliaries.logInfo("Registered " + Integer.toString(n_registered) + " tile entities.");
}
public static final void registerEntities(final RegistryEvent.Register<EntityType<?>> event)
{
int n_registered = 0;
for(final EntityType<?> e:entity_types) {
if((e==ET_CHAIR) && (!registeredBlocks.contains(TREATED_WOOD_STOOL))) continue;
event.getRegistry().register(e);
++n_registered;
}
ModAuxiliaries.logInfo("Registered " + Integer.toString(n_registered) + " entities bound to blocks.");
}
public static final void registerContainers(final RegistryEvent.Register<ContainerType<?>> event)
{
int n_registered = 0;
for(final ContainerType<?> e:container_types) {
event.getRegistry().register(e);
++n_registered;
}
ModAuxiliaries.logInfo("Registered " + Integer.toString(n_registered) + " containers bound to tile entities.");
}
@OnlyIn(Dist.CLIENT)
public static final void registerContainerGuis(final FMLClientSetupEvent event)
{
ScreenManager.registerFactory(CT_TREATED_WOOD_CRAFTING_TABLE, BlockDecorCraftingTable.BGui::new);
ScreenManager.registerFactory(CT_FACTORY_DROPPER, BlockDecorDropper.BGui::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

@ -0,0 +1,152 @@
package wile.engineersdecor;
import wile.engineersdecor.detail.ModConfig;
import wile.engineersdecor.detail.RecipeCondModSpecific;
import wile.engineersdecor.detail.Networking;
import wile.engineersdecor.blocks.*;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.container.ContainerType;
import net.minecraft.item.ItemGroup;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
import net.minecraft.block.Block;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraftforge.common.crafting.CraftingHelper;
import net.minecraftforge.event.entity.living.LivingEvent;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.fml.ModLoadingContext;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.event.lifecycle.InterModEnqueueEvent;
import net.minecraftforge.fml.event.lifecycle.InterModProcessEvent;
import net.minecraftforge.fml.event.server.FMLServerStartingEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import javax.annotation.Nullable;
@Mod("engineersdecor")
public class ModEngineersDecor
{
public static final String MODID = "engineersdecor";
public static final int VERSION_DATAFIXER = 0;
private static final Logger LOGGER = LogManager.getLogger();
public ModEngineersDecor()
{
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::onSetup);
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::onSendImc);
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::onRecvImc);
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::onClientSetup);
ModLoadingContext.get().registerConfig(net.minecraftforge.fml.config.ModConfig.Type.COMMON, ModConfig.COMMON_CONFIG_SPEC);
ModLoadingContext.get().registerConfig(net.minecraftforge.fml.config.ModConfig.Type.CLIENT, ModConfig.CLIENT_CONFIG_SPEC);
MinecraftForge.EVENT_BUS.register(this);
}
public static final Logger logger() { return LOGGER; }
//
// Events
//
private void onSetup(final FMLCommonSetupEvent event)
{
LOGGER.info("Registering recipe condition processor ...");
CraftingHelper.register(new ResourceLocation(MODID, "grc"), new RecipeCondModSpecific());
Networking.init();
}
private void onClientSetup(final FMLClientSetupEvent event)
{ ModContent.registerContainerGuis(event); }
private void onSendImc(final InterModEnqueueEvent event)
{}
private void onRecvImc(final InterModProcessEvent event)
{}
@SubscribeEvent
public void onServerStarting(FMLServerStartingEvent event)
{}
@Mod.EventBusSubscriber(bus=Mod.EventBusSubscriber.Bus.MOD)
public static class RegistryEvents
{
@SubscribeEvent
public static void onBlocksRegistry(final RegistryEvent.Register<Block> event)
{ ModContent.registerBlocks(event); }
@SubscribeEvent
public static void onItemRegistry(final RegistryEvent.Register<Item> event)
{ ModContent.registerItemBlocks(event); }
@SubscribeEvent
public static void onTileEntityRegistry(final RegistryEvent.Register<TileEntityType<?>> event)
{ ModContent.registerTileEntities(event); }
@SubscribeEvent
public static void onRegisterEntityTypes(final RegistryEvent.Register<EntityType<?>> event)
{ ModContent.registerEntities(event); }
@SubscribeEvent
public static void onRegisterContainerTypes(final RegistryEvent.Register<ContainerType<?>> event)
{ ModContent.registerContainers(event); }
}
//
// Sided proxy functionality (skel)
//
public static ISidedProxy proxy = DistExecutor.runForDist(()->ClientProxy::new, ()->ServerProxy::new);
public interface ISidedProxy
{
default @Nullable PlayerEntity getPlayerClientSide() { return null; }
default @Nullable World getWorldClientSide() { return null; }
default @Nullable Minecraft mc() { return null; }
}
public static final class ClientProxy implements ISidedProxy
{
public @Nullable PlayerEntity getPlayerClientSide() { return Minecraft.getInstance().player; }
public @Nullable World getWorldClientSide() { return Minecraft.getInstance().world; }
public @Nullable Minecraft mc() { return Minecraft.getInstance(); }
}
public static final class ServerProxy implements ISidedProxy
{
public @Nullable PlayerEntity getPlayerClientSide() { return null; }
public @Nullable World getWorldClientSide() { return null; }
public @Nullable Minecraft mc() { return null; }
}
//
// Item group / creative tab
//
public static final ItemGroup ITEMGROUP = (new ItemGroup("tab" + MODID) {
@OnlyIn(Dist.CLIENT)
public ItemStack createIcon()
{ return new ItemStack(ModContent.SIGN_MODLOGO); }
});
//
// Player update event
//
@SubscribeEvent
public void onPlayerEvent(final LivingEvent.LivingUpdateEvent event)
{
if(!(event.getEntity() instanceof PlayerEntity)) return;
final PlayerEntity player = (PlayerEntity)event.getEntity();
if(player.world == null) return;
if(player.isOnLadder()) BlockDecorLadder.onPlayerUpdateEvent(player);
}
}

View file

@ -0,0 +1,133 @@
/*
* @file BlockDecorFull.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2019 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)
*
* Common functionality class for decor blocks.
* Mainly needed for:
* - MC block defaults.
* - Tooltip functionality
* - Model initialisation
*/
package wile.engineersdecor.blocks;
import wile.engineersdecor.detail.ModAuxiliaries;
import net.minecraft.entity.item.ItemEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.fluid.IFluidState;
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.shapes.ISelectionContext;
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.util.math.shapes.VoxelShapes;
import net.minecraft.block.Block;
import net.minecraft.block.material.PushReaction;
import net.minecraft.block.BlockState;
import net.minecraft.item.ItemStack;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.storage.loot.LootContext;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.util.*;
import net.minecraft.util.text.ITextComponent;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import javax.annotation.Nullable;
import java.util.Collections;
import java.util.List;
public class BlockDecor extends Block implements IDecorBlock
{
public static final long CFG_DEFAULT = 0x0000000000000000L; // no special config
public static final long CFG_CUTOUT = 0x0000000000000001L; // cutout rendering
public static final long CFG_HORIZIONTAL = 0x0000000000000002L; // horizontal block, affects bounding box calculation at construction time and placement
public static final long CFG_LOOK_PLACEMENT = 0x0000000000000004L; // placed in direction the player is looking when placing.
public static final long CFG_FACING_PLACEMENT = 0x0000000000000008L; // placed on the facing the player has clicked.
public static final long CFG_OPPOSITE_PLACEMENT = 0x0000000000000010L; // placed placed in the opposite direction of the face the player clicked.
public static final long CFG_FLIP_PLACEMENT_IF_SAME = 0x0000000000000020L; // placement direction flipped if an instance of the same class was clicked
public static final long CFG_FLIP_PLACEMENT_SHIFTCLICK = 0x0000000000000040L; // placement direction flipped if player is sneaking
public static final long CFG_TRANSLUCENT = 0x0000000000000080L; // indicates a block/pane is glass like (transparent, etc)
public static final long CFG_ELECTRICAL = 0x0000000000010000L; // Denotes if a component is mainly flux driven.
public static final long CFG_REDSTONE_CONTROLLED = 0x0000000000020000L; // Denotes if a component has somehow a redstone control input
public static final long CFG_ANALOG = 0x0000000000040000L; // Denotes if a component has analog behaviour
public static final long CFG_HARD_IE_DEPENDENT = 0x8000000000000000L; // The block is implicitly opt'ed out if IE is not installed
public final long config;
public final VoxelShape vshape;
public BlockDecor(long config, Block.Properties properties)
{ this(config, properties, ModAuxiliaries.getPixeledAABB(0, 0, 0, 16, 16,16 )); }
public BlockDecor(long config, Block.Properties properties, AxisAlignedBB aabb)
{ super(properties); this.config = config; this.vshape = VoxelShapes.create(aabb); }
public BlockDecor(long config, Block.Properties properties, VoxelShape voxel_shape)
{ super(properties); this.config = config; this.vshape = voxel_shape; }
@Override
@OnlyIn(Dist.CLIENT)
public void addInformation(ItemStack stack, @Nullable IBlockReader world, List<ITextComponent> tooltip, ITooltipFlag flag)
{ ModAuxiliaries.Tooltip.addInformation(stack, world, tooltip, flag, true); }
@Override
@OnlyIn(Dist.CLIENT)
public BlockRenderLayer getRenderLayer()
{ return ((config & CFG_CUTOUT)!=0) ? BlockRenderLayer.CUTOUT : BlockRenderLayer.SOLID; }
@Override
@SuppressWarnings("deprecation")
public VoxelShape getShape(BlockState state, IBlockReader source, BlockPos pos, ISelectionContext selectionContext)
{ return vshape; }
@Override
@SuppressWarnings("deprecation")
public VoxelShape getCollisionShape(BlockState state, IBlockReader world, BlockPos pos, ISelectionContext selectionContext)
{ return vshape; }
@Override
public boolean canSpawnInBlock()
{ return false; }
@Override
@SuppressWarnings("deprecation")
public PushReaction getPushReaction(BlockState state)
{ return PushReaction.NORMAL; }
@Override
@SuppressWarnings("deprecation")
public void onReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean isMoving)
{
if(state.hasTileEntity() && (state.getBlock() != newState.getBlock())) {
world.removeTileEntity(pos);
world.updateComparatorOutputLevel(pos, this);
}
}
public static boolean dropBlock(BlockState state, World world, BlockPos pos, boolean explosion)
{
if(!(state.getBlock() instanceof IDecorBlock)) { world.removeBlock(pos, false); return true; }
if(!world.isRemote()) {
((IDecorBlock)state.getBlock()).dropList(state, world, pos, explosion).forEach(stack->world.addEntity(new ItemEntity(world, pos.getX()+0.5, pos.getY()+0.5, pos.getZ()+0.5, stack)));
}
if(state.getBlock().hasTileEntity(state)) world.removeTileEntity(pos);
world.removeBlock(pos, false);
return true;
}
@Override
public boolean removedByPlayer(BlockState state, World world, BlockPos pos, PlayerEntity player, boolean willHarvest, IFluidState fluid)
{ return dropBlock(state, world, pos, false); }
@Override
public void onExplosionDestroy(World world, BlockPos pos, Explosion explosion)
{ dropBlock(world.getBlockState(pos), world, pos, false); }
@Override
@SuppressWarnings("deprecation")
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder)
{ return Collections.singletonList(ItemStack.EMPTY); } // { return Collections.singletonList(new ItemStack(this.asItem())); } //
}

View file

@ -0,0 +1,190 @@
/*
* @file BlockDecorFull.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2019 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)
*
* Full block characteristics class.
*/
package wile.engineersdecor.blocks;
import wile.engineersdecor.ModContent;
import wile.engineersdecor.ModEngineersDecor;
import net.minecraft.entity.*;
import net.minecraft.entity.monster.*;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.network.IPacket;
import net.minecraft.util.math.*;
import net.minecraft.world.IWorldReader;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.*;
import net.minecraft.world.World;
import net.minecraftforge.fml.network.FMLPlayMessages;
import net.minecraftforge.fml.network.NetworkHooks;
import java.util.List;
import java.util.Random;
public class BlockDecorChair extends BlockDecorDirected
{
private static boolean sitting_enabled = true;
private static double sitting_probability = 0.1;
private static double standup_probability = 0.01;
public static void on_config(boolean without_sitting, boolean without_mob_sitting, double sitting_probability_percent, double standup_probability_percent)
{
sitting_enabled = (!without_sitting);
sitting_probability = (without_sitting||without_mob_sitting) ? 0.0 : MathHelper.clamp(sitting_probability_percent/100, 0, 0.9);
standup_probability = (without_sitting||without_mob_sitting) ? 1.0 : MathHelper.clamp(standup_probability_percent/100, 1e-6, 1e-2);
ModEngineersDecor.logger().info("Config chairs: " + sitting_enabled + ", sit: " + sitting_probability, ", stand up: " + standup_probability);
}
public BlockDecorChair(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
{ super(config, builder.tickRandomly(), unrotatedAABB); }
@Override
@SuppressWarnings("deprecation")
public boolean onBlockActivated(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockRayTraceResult rayTraceResult)
{
if(sitting_enabled && (!world.isRemote)) { EntityChair.sit(world, player, pos); }
return true;
}
@Override
@SuppressWarnings("deprecation")
public void onEntityCollision(BlockState state, World world, BlockPos pos, Entity entity)
{
if(sitting_enabled && (Math.random() < sitting_probability) && (entity instanceof MobEntity)) EntityChair.sit(world, (LivingEntity)entity, pos);
}
@Override
public int tickRate(IWorldReader world)
{ return 10; }
@Override
@SuppressWarnings("deprecation")
public void tick(BlockState state, World world, BlockPos pos, Random rnd)
{
if((!sitting_enabled) || (sitting_probability < 1e-6)) return;
final List<LivingEntity> entities = world.getEntitiesWithinAABB(MobEntity.class, new AxisAlignedBB(pos).grow(2,1,2).expand(0,1,0), e->true);
if(entities.isEmpty()) return;
int index = rnd.nextInt(entities.size());
if((index < 0) || (index >= entities.size())) return;
EntityChair.sit(world, entities.get(index), pos);
}
//--------------------------------------------------------------------------------------------------------------------
// Riding entity for sitting
//--------------------------------------------------------------------------------------------------------------------
public static class EntityChair extends Entity
{
public static final double x_offset = 0.5d;
public static final double y_offset = 0.4d;
public static final double z_offset = 0.5d;
private int t_sit = 0;
public BlockPos chair_pos = new BlockPos(0,0,0);
public EntityChair(EntityType<? extends Entity> entityType, World world)
{
super(entityType, world);
preventEntitySpawning=true;
setMotion(Vec3d.ZERO);
canUpdate(true);
noClip=true;
}
public EntityChair(World world)
{ this(ModContent.ET_CHAIR, world); }
public static EntityChair customClientFactory(FMLPlayMessages.SpawnEntity spkt, World world)
{ return new EntityChair(world); }
public IPacket<?> createSpawnPacket()
{ return NetworkHooks.getEntitySpawningPacket(this); }
public static boolean accepts_mob(LivingEntity entity)
{
if(!(entity instanceof net.minecraft.entity.monster.MonsterEntity)) return false;
if((entity.getType().getSize().height > 2.5) || (entity.getType().getSize().height > 2.0)) return false;
if(entity instanceof ZombieEntity) return true;
if(entity instanceof ZombieVillagerEntity) return true;
if(entity instanceof ZombiePigmanEntity) return true;
if(entity instanceof HuskEntity) return true;
if(entity instanceof StrayEntity) return true;
if(entity instanceof SkeletonEntity) return true;
if(entity instanceof WitherSkeletonEntity) return true;
return false;
}
public static void sit(World world, LivingEntity sitter, BlockPos pos)
{
if(!sitting_enabled) return;
if((world==null) || (world.isRemote) || (sitter==null) || (pos==null)) return;
if((!(sitter instanceof PlayerEntity)) && (!accepts_mob(sitter))) return;
if(!world.getEntitiesWithinAABB(EntityChair.class, new AxisAlignedBB(pos)).isEmpty()) return;
if(sitter.isBeingRidden() || (!sitter.isAlive()) || (sitter.isPassenger()) ) return;
if((!world.isAirBlock(pos.up())) || (!world.isAirBlock(pos.up(2)))) return;
boolean on_top_of_block_position = true;
boolean use_next_negative_y_position = false;
EntityChair chair = new EntityChair(world);
chair.chair_pos = pos;
chair.t_sit = 5;
chair.prevPosX = chair.posX;
chair.prevPosY = chair.posY;
chair.prevPosZ = chair.posZ;
chair.setPosition(pos.getX()+x_offset,pos.getY()+y_offset,pos.getZ()+z_offset);
world.addEntity(chair);
sitter.startRiding(chair, true);
}
@Override
protected void registerData() {}
@Override
protected void readAdditional(CompoundNBT compound) {}
@Override
protected void writeAdditional(CompoundNBT compound) {}
@Override
protected boolean canTriggerWalking()
{ return false; }
@Override
public boolean canBePushed()
{ return false; }
@Override
public double getMountedYOffset()
{ return 0.0; }
@Override
public void tick()
{
if(world.isRemote) return;
super.tick();
if(--t_sit > 0) return;
Entity sitter = getPassengers().isEmpty() ? null : getPassengers().get(0);
if((sitter==null) || (!sitter.isAlive())) {
this.remove();
return;
}
boolean abort = (!sitting_enabled);
final BlockState state = world.getBlockState(chair_pos);
if((state==null) || (!(state.getBlock() instanceof BlockDecorChair))) abort = true;
if(!world.isAirBlock(chair_pos.up())) abort = true;
if((!(sitter instanceof PlayerEntity)) && (Math.random() < standup_probability)) abort = true;
if(abort) {
for(Entity e:getPassengers()) {
if(e.isAlive()) e.stopRiding();
}
this.remove();
}
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,104 @@
/*
* @file BlockDecorDirected.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2019 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)
*
* Smaller (cutout) block with a defined facing.
*/
package wile.engineersdecor.blocks;
import wile.engineersdecor.detail.ModAuxiliaries;
import net.minecraft.entity.EntityType;
import net.minecraft.state.StateContainer;
import net.minecraft.util.math.shapes.ISelectionContext;
import net.minecraft.util.math.shapes.VoxelShapes;
import net.minecraft.item.BlockItemUseContext;
import net.minecraft.state.DirectionProperty;
import net.minecraft.block.Block;
import net.minecraft.block.DirectionalBlock;
import net.minecraft.block.BlockState;
import net.minecraft.world.IBlockReader;
import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.Direction;
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
public class BlockDecorDirected extends BlockDecor
{
public static final DirectionProperty FACING = DirectionalBlock.FACING;
protected final ArrayList<VoxelShape> AABBs;
public BlockDecorDirected(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
{
super(config, builder);
setDefaultState(stateContainer.getBaseState().with(FACING, Direction.UP));
final boolean is_horizontal = ((config & BlockDecor.CFG_HORIZIONTAL)!=0);
AABBs = new ArrayList<VoxelShape>(Arrays.asList(
VoxelShapes.create(ModAuxiliaries.getRotatedAABB(unrotatedAABB, Direction.DOWN, is_horizontal)),
VoxelShapes.create(ModAuxiliaries.getRotatedAABB(unrotatedAABB, Direction.UP, is_horizontal)),
VoxelShapes.create(ModAuxiliaries.getRotatedAABB(unrotatedAABB, Direction.NORTH, is_horizontal)),
VoxelShapes.create(ModAuxiliaries.getRotatedAABB(unrotatedAABB, Direction.SOUTH, is_horizontal)),
VoxelShapes.create(ModAuxiliaries.getRotatedAABB(unrotatedAABB, Direction.WEST, is_horizontal)),
VoxelShapes.create(ModAuxiliaries.getRotatedAABB(unrotatedAABB, Direction.EAST, is_horizontal)),
VoxelShapes.create(unrotatedAABB),
VoxelShapes.create(unrotatedAABB)
));
}
@Override
@OnlyIn(Dist.CLIENT)
public BlockRenderLayer getRenderLayer()
{ return ((config & CFG_CUTOUT)!=0) ? BlockRenderLayer.CUTOUT : BlockRenderLayer.SOLID; }
@Override
public boolean canSpawnInBlock()
{ return false; }
@Override
@SuppressWarnings("deprecation")
public boolean canEntitySpawn(BlockState state, IBlockReader world, BlockPos pos, EntityType<?> entityType)
{ return false; }
@Override
public VoxelShape getShape(BlockState state, IBlockReader source, BlockPos pos, ISelectionContext selectionContext)
{ return AABBs.get((state.get(FACING)).getIndex() & 0x7); }
@Override
public VoxelShape getCollisionShape(BlockState state, IBlockReader world, BlockPos pos, ISelectionContext selectionContext)
{ return getShape(state, world, pos, selectionContext); }
@Override
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder)
{ builder.add(FACING); }
@Override
@Nullable
public BlockState getStateForPlacement(BlockItemUseContext context)
{
Direction facing = context.getFace();
if((config & (CFG_HORIZIONTAL|CFG_LOOK_PLACEMENT)) == (CFG_HORIZIONTAL|CFG_LOOK_PLACEMENT)) {
// horizontal placement in direction the player is looking
facing = context.getPlacementHorizontalFacing();
} else if((config & (CFG_HORIZIONTAL|CFG_LOOK_PLACEMENT)) == (CFG_HORIZIONTAL)) {
// horizontal placement on a face
if(((facing==Direction.UP)||(facing==Direction.DOWN))) return null;
} else if((config & CFG_LOOK_PLACEMENT)!=0) {
// placement in direction the player is looking, with up and down
facing = context.getNearestLookingDirection();
} else {
// default: placement on the face the player clicking
}
if((config & CFG_OPPOSITE_PLACEMENT)!=0) facing = facing.getOpposite();
if(((config & CFG_FLIP_PLACEMENT_SHIFTCLICK) != 0) && (context.getPlayer().isSneaking())) facing = facing.getOpposite();
return getDefaultState().with(FACING, facing);
}
}

View file

@ -0,0 +1,112 @@
/*
* @file BlockDecorDirectedHorizontal.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2019 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)
*
* Smaller directed block with direction set narrowed
* to horizontal directions.
*/
package wile.engineersdecor.blocks;
import net.minecraft.block.HorizontalBlock;
import net.minecraft.util.Mirror;
import net.minecraft.util.Rotation;
import net.minecraft.entity.EntityType;
import net.minecraft.state.StateContainer;
import net.minecraft.util.math.shapes.ISelectionContext;
import net.minecraft.item.BlockItemUseContext;
import net.minecraft.state.DirectionProperty;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.util.math.shapes.VoxelShapes;
import net.minecraft.world.IBlockReader;
import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.Direction;
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import wile.engineersdecor.detail.ModAuxiliaries;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
public class BlockDecorDirectedHorizontal extends BlockDecor
{
public static final DirectionProperty HORIZONTAL_FACING = HorizontalBlock.HORIZONTAL_FACING;
protected final ArrayList<VoxelShape> AABBs;
public BlockDecorDirectedHorizontal(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
{
super(config|CFG_HORIZIONTAL, builder, unrotatedAABB);
setDefaultState(stateContainer.getBaseState().with(HORIZONTAL_FACING, Direction.NORTH));
AABBs = new ArrayList<VoxelShape>(Arrays.asList(
VoxelShapes.create(ModAuxiliaries.getRotatedAABB(unrotatedAABB, Direction.DOWN, true)),
VoxelShapes.create(ModAuxiliaries.getRotatedAABB(unrotatedAABB, Direction.UP, true)),
VoxelShapes.create(ModAuxiliaries.getRotatedAABB(unrotatedAABB, Direction.NORTH, true)),
VoxelShapes.create(ModAuxiliaries.getRotatedAABB(unrotatedAABB, Direction.SOUTH, true)),
VoxelShapes.create(ModAuxiliaries.getRotatedAABB(unrotatedAABB, Direction.WEST, true)),
VoxelShapes.create(ModAuxiliaries.getRotatedAABB(unrotatedAABB, Direction.EAST, true)),
VoxelShapes.create(unrotatedAABB),
VoxelShapes.create(unrotatedAABB)
));
}
@Override
@OnlyIn(Dist.CLIENT)
public BlockRenderLayer getRenderLayer()
{ return ((config & CFG_CUTOUT)!=0) ? BlockRenderLayer.CUTOUT : BlockRenderLayer.SOLID; }
@Override
public boolean canSpawnInBlock()
{ return false; }
@Override
@SuppressWarnings("deprecation")
public boolean canEntitySpawn(BlockState state, IBlockReader world, BlockPos pos, EntityType<?> entityType)
{ return false; }
@Override
public VoxelShape getShape(BlockState state, IBlockReader source, BlockPos pos, ISelectionContext selectionContext)
{ return AABBs.get((state.get(HORIZONTAL_FACING)).getIndex() & 0x7); }
@Override
public VoxelShape getCollisionShape(BlockState state, IBlockReader world, BlockPos pos, ISelectionContext selectionContext)
{ return getShape(state, world, pos, selectionContext); }
@Override
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder)
{ builder.add(HORIZONTAL_FACING); }
@Override
@Nullable
public BlockState getStateForPlacement(BlockItemUseContext context)
{
Direction facing = context.getFace();
if((config & CFG_LOOK_PLACEMENT) != 0) {
// horizontal placement in direction the player is looking
facing = context.getPlacementHorizontalFacing();
} else {
// horizontal placement on a face
facing = ((facing==Direction.UP)||(facing==Direction.DOWN)) ? (context.getPlacementHorizontalFacing()) : facing;
}
if((config & CFG_OPPOSITE_PLACEMENT)!=0) facing = facing.getOpposite();
if(((config & CFG_FLIP_PLACEMENT_SHIFTCLICK) != 0) && (context.getPlayer().isSneaking())) facing = facing.getOpposite();
return getDefaultState().with(HORIZONTAL_FACING, facing);
}
@Override
@SuppressWarnings("deprecation")
public BlockState rotate(BlockState state, Rotation rot)
{ return state.with(HORIZONTAL_FACING, rot.rotate(state.get(HORIZONTAL_FACING))); }
@Override
@SuppressWarnings("deprecation")
public BlockState mirror(BlockState state, Mirror mirrorIn)
{ return state.rotate(mirrorIn.toRotation(state.get(HORIZONTAL_FACING))); }
}

View file

@ -0,0 +1,902 @@
/*
* @file BlockDecorDropper.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2019 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)
*
* Dropper factory automation suitable.
*/
package wile.engineersdecor.blocks;
import wile.engineersdecor.ModContent;
import wile.engineersdecor.ModEngineersDecor;
import wile.engineersdecor.detail.Networking;
import net.minecraft.tileentity.ITickableTileEntity;
import net.minecraft.inventory.container.INamedContainerProvider;
import net.minecraft.block.DoorBlock;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.container.Slot;
import net.minecraft.state.BooleanProperty;
import net.minecraft.state.StateContainer;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.math.*;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.world.IBlockReader;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.world.World;
import net.minecraft.entity.item.ItemEntity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.item.*;
import net.minecraft.inventory.*;
import net.minecraft.client.gui.screen.inventory.ContainerScreen;
import net.minecraft.util.SoundEvents;
import net.minecraft.util.*;
import net.minecraft.util.text.ITextComponent;
import net.minecraftforge.fml.network.NetworkHooks;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.common.util.FakePlayer;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.items.wrapper.SidedInvWrapper;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import com.mojang.blaze3d.platform.GlStateManager;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
public class BlockDecorDropper extends BlockDecorDirected
{
public static final BooleanProperty OPEN = DoorBlock.OPEN;
public BlockDecorDropper(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
{ super(config, builder, unrotatedAABB); }
@Override
@OnlyIn(Dist.CLIENT)
public BlockRenderLayer getRenderLayer()
{ return BlockRenderLayer.SOLID; }
@Override
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder)
{ builder.add(FACING, OPEN); }
@Override
@Nullable
public BlockState getStateForPlacement(BlockItemUseContext context)
{ return super.getStateForPlacement(context).with(OPEN, false); }
@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 BlockDecorDropper.BTileEntity(); }
@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 BlockDecorDropper.BTileEntity)) return;
((BlockDecorDropper.BTileEntity)te).readnbt(te_nbt, false);
((BlockDecorDropper.BTileEntity)te).reset_rtstate();
((BlockDecorDropper.BTileEntity)te).markDirty();
}
@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 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();
}
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 BlockDecorDropper.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();
}
//--------------------------------------------------------------------------------------------------------------------
// Tile entity
//--------------------------------------------------------------------------------------------------------------------
public static class BTileEntity extends TileEntity implements ITickableTileEntity, INameable, IInventory, INamedContainerProvider, ISidedInventory
{
public static final int NUM_OF_FIELDS = 16;
public static final int TICK_INTERVAL = 32;
public static final int NUM_OF_SLOTS = 15;
public static final int INPUT_SLOTS_FIRST = 0;
public static final int INPUT_SLOTS_SIZE = 12;
public static final int CTRL_SLOTS_FIRST = INPUT_SLOTS_SIZE;
public static final int CTRL_SLOTS_SIZE = 3;
public static final int SHUTTER_CLOSE_DELAY = 40;
public static final int MAX_DROP_COUNT = 32;
public static final int DROP_PERIOD_OFFSET = 10;
///
public static final int DROPLOGIC_FILTER_ANDGATE = 0x1;
public static final int DROPLOGIC_EXTERN_ANDGATE = 0x2;
public static final int DROPLOGIC_SILENT_DROP = 0x4;
public static final int DROPLOGIC_SILENT_OPEN = 0x8;
///
private int filter_matches_[] = new int[CTRL_SLOTS_SIZE];
private int open_timer_ = 0;
private int drop_timer_ = 0;
private boolean triggered_ = false;
private boolean block_power_signal_ = false;
private boolean block_power_updated_ = false;
private int drop_speed_ = 10;
private int drop_noise_ = 0;
private int drop_xdev_ = 0;
private int drop_ydev_ = 0;
private int drop_count_ = 1;
private int drop_logic_ = DROPLOGIC_EXTERN_ANDGATE;
private int drop_period_ = 0;
private int drop_slot_index_ = 0;
private int tick_timer_ = 0;
protected NonNullList<ItemStack> stacks_;
public static void on_config(int cooldown_ticks)
{
// ModEngineersDecor.logger.info("Config factory dropper:");
}
public BTileEntity()
{ this(ModContent.TET_FACTORY_DROPPER); }
public BTileEntity(TileEntityType<?> te_type)
{
super(te_type);
stacks_ = NonNullList.<ItemStack>withSize(NUM_OF_SLOTS, ItemStack.EMPTY);
reset_rtstate();
}
public CompoundNBT clear_getnbt()
{
CompoundNBT nbt = new CompoundNBT();
writenbt(nbt, false);
for(int i=0; i<stacks_.size(); ++i) stacks_.set(i, ItemStack.EMPTY);
reset_rtstate();
triggered_ = false;
block_power_updated_ = false;
return nbt;
}
public void reset_rtstate()
{
block_power_signal_ = false;
block_power_updated_ = false;
for(int i=0; i<filter_matches_.length; ++i) filter_matches_[i] = 0;
}
public void readnbt(CompoundNBT nbt, boolean update_packet)
{
stacks_ = NonNullList.<ItemStack>withSize(NUM_OF_SLOTS, ItemStack.EMPTY);
ItemStackHelper.loadAllItems(nbt, stacks_);
while(stacks_.size() < NUM_OF_SLOTS) stacks_.add(ItemStack.EMPTY);
block_power_signal_ = nbt.getBoolean("powered");
open_timer_ = nbt.getInt("open_timer");
drop_speed_ = nbt.getInt("drop_speed");
drop_noise_ = nbt.getInt("drop_noise");
drop_xdev_ = nbt.getInt("drop_xdev");
drop_ydev_ = nbt.getInt("drop_ydev");
drop_slot_index_ = nbt.getInt("drop_slot_index");
drop_count_ = MathHelper.clamp(nbt.getInt("drop_count"), 1, MAX_DROP_COUNT);
drop_logic_ = nbt.getInt("drop_logic");
drop_period_ = nbt.getInt("drop_period");
}
protected void writenbt(CompoundNBT nbt, boolean update_packet)
{
ItemStackHelper.saveAllItems(nbt, stacks_);
nbt.putBoolean("powered", block_power_signal_);
nbt.putInt("open_timer", open_timer_);
nbt.putInt("drop_speed", drop_speed_);
nbt.putInt("drop_noise", drop_noise_);
nbt.putInt("drop_xdev", drop_xdev_);
nbt.putInt("drop_ydev", drop_ydev_);
nbt.putInt("drop_slot_index", drop_slot_index_);
nbt.putInt("drop_count", drop_count_);
nbt.putInt("drop_logic", drop_logic_);
nbt.putInt("drop_period", drop_period_);
}
public void block_updated()
{
// RS power check, both edges
boolean powered = world.isBlockPowered(pos);
if(block_power_signal_ != powered) block_power_updated_ = true;
block_power_signal_ = powered;
tick_timer_ = 1;
}
public boolean is_input_slot(int index)
{ return (index >= INPUT_SLOTS_FIRST) && (index < (INPUT_SLOTS_FIRST+INPUT_SLOTS_SIZE)); }
// TileEntity ------------------------------------------------------------------------------
@Override
public void read(CompoundNBT nbt)
{ super.read(nbt); readnbt(nbt, false); }
@Override
public CompoundNBT write(CompoundNBT nbt)
{ super.write(nbt); writenbt(nbt, false); return nbt; }
// INamable ----------------------------------------------------------------------------------------------
@Override
public ITextComponent getName()
{ final Block block=getBlockState().getBlock(); return new StringTextComponent((block!=null) ? block.getTranslationKey() : "Factory dropper"); }
@Override
public boolean hasCustomName()
{ return false; }
@Override
public ITextComponent getCustomName()
{ return getName(); }
// INamedContainerProvider ------------------------------------------------------------------------------
@Override
public ITextComponent getDisplayName()
{ return INameable.super.getDisplayName(); }
@Override
public Container createMenu(int id, PlayerInventory inventory, PlayerEntity player )
{ return new BContainer(id, inventory, this, IWorldPosCallable.of(world, pos), fields); }
// IInventory -------------------------------------------------------------------------------------------
@Override
public int getSizeInventory()
{ return stacks_.size(); }
@Override
public boolean isEmpty()
{ for(ItemStack stack: stacks_) { if(!stack.isEmpty()) return false; } return true; }
@Override
public ItemStack getStackInSlot(int index)
{ return (index < getSizeInventory()) ? stacks_.get(index) : ItemStack.EMPTY; }
@Override
public ItemStack decrStackSize(int index, int count)
{ return ItemStackHelper.getAndSplit(stacks_, index, count); }
@Override
public ItemStack removeStackFromSlot(int index)
{ return ItemStackHelper.getAndRemove(stacks_, index); }
@Override
public void setInventorySlotContents(int index, ItemStack stack)
{
stacks_.set(index, stack);
if(stack.getCount() > getInventoryStackLimit()) stack.setCount(getInventoryStackLimit());
if(tick_timer_ > 8) tick_timer_ = 8;
markDirty();
}
@Override
public int getInventoryStackLimit()
{ return 64; }
@Override
public void markDirty()
{ super.markDirty(); }
@Override
public boolean isUsableByPlayer(PlayerEntity player)
{ return getPos().distanceSq(player.getPosition()) < 36; }
@Override
public void openInventory(PlayerEntity player)
{}
@Override
public void closeInventory(PlayerEntity player)
{ markDirty(); }
@Override
public boolean isItemValidForSlot(int index, ItemStack stack)
{ return true; }
@Override
public void clear()
{ stacks_.clear(); }
// Fields -----------------------------------------------------------------------------------------------
protected final IIntArray fields = new IntArray(BTileEntity.NUM_OF_FIELDS)
{
@Override
public int get(int id)
{
switch(id) {
case 0: return drop_speed_;
case 1: return drop_xdev_;
case 2: return drop_ydev_;
case 3: return drop_noise_;
case 4: return drop_count_;
case 5: return drop_logic_;
case 6: return drop_period_;
case 9: return drop_timer_;
case 10: return open_timer_;
case 11: return block_power_signal_ ? 1 : 0;
case 12: return filter_matches_[0];
case 13: return filter_matches_[1];
case 14: return filter_matches_[2];
case 15: return drop_slot_index_;
default: return 0;
}
}
@Override
public void set(int id, int value)
{
switch(id) {
case 0: drop_speed_ = MathHelper.clamp(value, 0, 100); return;
case 1: drop_xdev_ = MathHelper.clamp(value, -100, 100); return;
case 2: drop_ydev_ = MathHelper.clamp(value, -100, 100); return;
case 3: drop_noise_ = MathHelper.clamp(value, 0, 100); return;
case 4: drop_count_ = MathHelper.clamp(value, 1, MAX_DROP_COUNT); return;
case 5: drop_logic_ = value; return;
case 6: drop_period_ = MathHelper.clamp(value, 0, 100); return;
case 9: drop_timer_ = MathHelper.clamp(value, 0, 400); return;
case 10: open_timer_ = MathHelper.clamp(value, 0, 400); return;
case 11: block_power_signal_ = (value != 0); return;
case 12: filter_matches_[0] = (value & 0x3); return;
case 13: filter_matches_[1] = (value & 0x3); return;
case 14: filter_matches_[2] = (value & 0x3); return;
case 15: drop_slot_index_ = MathHelper.clamp(value, INPUT_SLOTS_FIRST, INPUT_SLOTS_FIRST+INPUT_SLOTS_SIZE-1); return;
default: return;
}
}
};
// ISidedInventory --------------------------------------------------------------------------------------
LazyOptional<? extends IItemHandler>[] item_handlers = SidedInvWrapper.create(this, Direction.UP);
private static final int[] SIDED_INV_SLOTS;
static {
SIDED_INV_SLOTS = new int[INPUT_SLOTS_SIZE];
for(int i=0; i<INPUT_SLOTS_SIZE; ++i) SIDED_INV_SLOTS[i] = i+INPUT_SLOTS_FIRST;
}
@Override
public int[] getSlotsForFace(Direction side)
{ return SIDED_INV_SLOTS; }
@Override
public boolean canInsertItem(int index, ItemStack stack, Direction direction)
{ return is_input_slot(index) && isItemValidForSlot(index, stack); }
@Override
public boolean canExtractItem(int index, ItemStack stack, Direction direction)
{ return false; }
// Capability export ------------------------------------------------------------------------------------
@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();
}
return super.getCapability(capability, facing);
}
// ITickable and aux methods ----------------------------------------------------------------------------
private static void drop(World world, BlockPos pos, Direction facing, ItemStack stack, int speed_percent, int xdeviation, int ydeviation, int noise_percent)
{
final double ofs = facing==Direction.DOWN ? 0.8 : 0.7;
Vec3d v0 = new Vec3d(facing.getXOffset(), facing.getYOffset(), facing.getZOffset());
final ItemEntity ei = new ItemEntity(world, (pos.getX()+0.5)+(ofs*v0.x), (pos.getY()+0.5)+(ofs*v0.y), (pos.getZ()+0.5)+(ofs*v0.z), stack);
if((xdeviation != 0) || (ydeviation != 0)) {
double vdx = 1e-2 * MathHelper.clamp(xdeviation, -100, 100);
double vdy = 1e-2 * MathHelper.clamp(ydeviation, -100, 100);
switch(facing) { // switch-case faster than coorsys fwd transform
case DOWN: v0 = v0.add( vdx, 0,-vdy); break;
case NORTH: v0 = v0.add( vdx, vdy, 0); break;
case SOUTH: v0 = v0.add(-vdx, vdy, 0); break;
case EAST: v0 = v0.add(0, vdy, vdx); break;
case WEST: v0 = v0.add(0, vdy, -vdx); break;
case UP: v0 = v0.add( vdx, 0, vdy); break;
}
}
if(noise_percent > 0) {
v0 = v0.add(
((world.rand.nextDouble()-0.5) * 1e-3 * noise_percent),
((world.rand.nextDouble()-0.5) * 1e-3 * noise_percent),
((world.rand.nextDouble()-0.5) * 1e-3 * noise_percent)
);
}
if(speed_percent < 5) speed_percent = 5;
double speed = 1e-2 * speed_percent;
if(noise_percent > 0) speed += (world.rand.nextDouble()-0.5) * 1e-4 * noise_percent;
v0 = v0.normalize().scale(speed);
ei.setMotion(v0.x, v0.y, v0.z);
ei.velocityChanged = true;
world.addEntity(ei);
}
@Nullable
BlockState update_blockstate()
{
BlockState state = world.getBlockState(pos);
if(!(state.getBlock() instanceof BlockDecorDropper)) return null;
boolean open = (open_timer_ > 0);
if(state.get(OPEN) != open) {
state = state.with(OPEN, open);
world.setBlockState(pos, state, 2|16);
if((drop_logic_ & DROPLOGIC_SILENT_OPEN) == 0) {
if(open) {
world.playSound(null, pos, SoundEvents.BLOCK_WOODEN_TRAPDOOR_OPEN, SoundCategory.BLOCKS, 0.08f, 3f);
} else {
world.playSound(null, pos, SoundEvents.BLOCK_WOODEN_TRAPDOOR_CLOSE, SoundCategory.BLOCKS, 0.08f, 3f);
}
}
}
return state;
}
private static int next_slot(int i)
{ return (i<INPUT_SLOTS_SIZE-1) ? (i+1) : INPUT_SLOTS_FIRST; }
@Override
public void tick()
{
if(world.isRemote) return;
if(--open_timer_ < 0) open_timer_ = 0;
if((drop_timer_ > 0) && ((--drop_timer_) == 0)) markDirty();
if(--tick_timer_ > 0) return;
tick_timer_ = TICK_INTERVAL;
boolean dirty = block_power_updated_;
boolean redstone_trigger = (block_power_signal_ && block_power_updated_);
boolean filter_trigger;
boolean trigger;
// Trigger logic
{
boolean droppable_slot_found = false;
for(int i=INPUT_SLOTS_FIRST; i<(INPUT_SLOTS_FIRST+INPUT_SLOTS_SIZE); ++i) {
if(stacks_.get(i).getCount() >= drop_count_) { droppable_slot_found = true; break; }
}
int filter_nset = 0;
// From filters / inventory checks
{
int last_filter_matches_[] = filter_matches_.clone();
boolean slot_assigned = false;
for(int ci=0; ci<CTRL_SLOTS_SIZE; ++ci) {
filter_matches_[ci] = 0;
final ItemStack cmp_stack = stacks_.get(CTRL_SLOTS_FIRST+ci);
if(cmp_stack.isEmpty()) continue;
filter_matches_[ci] = 1;
final int cmp_stack_count = cmp_stack.getCount();
int inventory_item_count = 0;
int slot = drop_slot_index_;
for(int i=INPUT_SLOTS_FIRST; i<(INPUT_SLOTS_FIRST+INPUT_SLOTS_SIZE); ++i) {
final ItemStack inp_stack = stacks_.get(slot);
if(!inp_stack.isItemEqual(cmp_stack)) { slot = next_slot(slot); continue; }
inventory_item_count += inp_stack.getCount();
if(inventory_item_count < cmp_stack_count) { slot = next_slot(slot); continue; }
filter_matches_[ci] = 2;
break;
}
}
int nmatched = 0;
for(int i=0; i<filter_matches_.length; ++i) {
if(filter_matches_[i] > 0) ++filter_nset;
if(filter_matches_[i] > 1) ++nmatched;
if(filter_matches_[i] != last_filter_matches_[i]) dirty = true;
}
filter_trigger = ((filter_nset >0) && (nmatched > 0));
if(((drop_logic_ & DROPLOGIC_FILTER_ANDGATE) != 0) && (nmatched != filter_nset)) filter_trigger = false;
}
// gates
{
if(filter_nset > 0) {
trigger = ((drop_logic_ & DROPLOGIC_EXTERN_ANDGATE) != 0) ? (filter_trigger && redstone_trigger) : (filter_trigger || redstone_trigger);
} else {
trigger = redstone_trigger;
}
if(triggered_) { triggered_ = false; trigger = true; }
if(!droppable_slot_found) {
if(open_timer_> 10) open_timer_ = 10; // override if dropping is not possible at all.
} else if(trigger || filter_trigger || redstone_trigger) {
open_timer_ = SHUTTER_CLOSE_DELAY;
}
}
// edge detection for next cycle
{
boolean tr = world.isBlockPowered(pos);
block_power_updated_ = (block_power_signal_ != tr);
block_power_signal_ = tr;
if(block_power_updated_) dirty = true;
}
}
// block state update
final BlockState state = update_blockstate();
if(state == null) { block_power_signal_= false; return; }
// dispense action
if(trigger && (drop_timer_ <= 0)) {
// drop stack for non-filter triggers
ItemStack drop_stacks[] = {ItemStack.EMPTY,ItemStack.EMPTY,ItemStack.EMPTY};
if(!filter_trigger) {
for(int i=0; i<INPUT_SLOTS_SIZE; ++i) {
if(drop_slot_index_ >= INPUT_SLOTS_SIZE) drop_slot_index_ = 0;
int ic = drop_slot_index_;
drop_slot_index_ = next_slot(drop_slot_index_);
ItemStack ds = stacks_.get(ic);
if((!ds.isEmpty()) && (ds.getCount() >= drop_count_)) {
drop_stacks[0] = ds.split(drop_count_);
stacks_.set(ic, ds);
break;
}
}
} else {
for(int fi=0; fi<filter_matches_.length; ++fi) {
if(filter_matches_[fi] > 1) {
drop_stacks[fi] = stacks_.get(CTRL_SLOTS_FIRST+fi).copy();
int ntoremove = drop_stacks[fi].getCount();
for(int i=INPUT_SLOTS_SIZE-1; (i>=0) && (ntoremove>0); --i) {
ItemStack stack = stacks_.get(i);
if(!stack.isItemEqual(drop_stacks[fi])) continue;
if(stack.getCount() <= ntoremove) {
ntoremove -= stack.getCount();
stacks_.set(i, ItemStack.EMPTY);
} else {
stack.shrink(ntoremove);
ntoremove = 0;
stacks_.set(i, stack);
}
}
if(ntoremove > 0) drop_stacks[fi].shrink(ntoremove);
}
}
}
// drop action
boolean dropped = false;
for(int i = 0; i < drop_stacks.length; ++i) {
if(drop_stacks[i].isEmpty()) continue;
dirty = true;
drop(world, pos, state.get(FACING), drop_stacks[i], drop_speed_, drop_xdev_, drop_ydev_, drop_noise_);
dropped = true;
}
// cooldown
if(dropped) drop_timer_ = DROP_PERIOD_OFFSET + drop_period_ * 2; // 0.1s time base -> 100%===10s
// drop sound
if(dropped && ((drop_logic_ & DROPLOGIC_SILENT_DROP) == 0)) {
world.playSound(null, pos, SoundEvents.BLOCK_WOOD_HIT, SoundCategory.BLOCKS, 0.1f, 4f);
}
// advance to next nonempty slot.
for(int i = 0; i < INPUT_SLOTS_SIZE; ++i) {
if(!stacks_.get(drop_slot_index_).isEmpty()) break;
drop_slot_index_ = next_slot(drop_slot_index_);
}
}
if(dirty) markDirty();
if(trigger && (tick_timer_ > 10)) tick_timer_ = 10;
}
}
//--------------------------------------------------------------------------------------------------------------------
// container
//--------------------------------------------------------------------------------------------------------------------
public static class BContainer extends Container implements Networking.INetworkSynchronisableContainer
{
private static final int PLAYER_INV_START_SLOTNO = BTileEntity.NUM_OF_SLOTS;
private final PlayerEntity player_;
private final IInventory inventory_;
private final IWorldPosCallable wpc_;
private final IIntArray fields_;
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)); }
private BContainer(int cid, PlayerInventory player_inventory, IInventory block_inventory, IWorldPosCallable wpc, IIntArray fields)
{
super(ModContent.CT_FACTORY_DROPPER, cid);
fields_ = fields;
wpc_ = wpc;
player_ = player_inventory.player;
inventory_ = block_inventory;
int i=-1;
// input slots (stacks 0 to 11)
for(int y=0; y<2; ++y) {
for(int x=0; x<6; ++x) {
int xpos = 10+x*18, ypos = 6+y*17;
addSlot(new Slot(inventory_, ++i, xpos, ypos));
}
}
// filter slots (stacks 12 to 14)
addSlot(new Slot(inventory_, ++i, 19, 48));
addSlot(new Slot(inventory_, ++i, 55, 48));
addSlot(new Slot(inventory_, ++i, 91, 48));
// player slots
for(int x=0; x<9; ++x) {
addSlot(new Slot(player_inventory, x, 8+x*18, 144)); // player slots: 0..8
}
for(int y=0; y<3; ++y) {
for(int x=0; x<9; ++x) {
addSlot(new Slot(player_inventory, x+y*9+9, 8+x*18, 86+y*18)); // player slots: 9..35
}
}
this.trackIntArray(fields_); // === Add reference holders
}
@Override
public boolean canInteractWith(PlayerEntity player)
{ return inventory_.isUsableByPlayer(player); }
@Override
public ItemStack transferStackInSlot(PlayerEntity player, int index)
{
Slot slot = getSlot(index);
if((slot==null) || (!slot.getHasStack())) return ItemStack.EMPTY;
ItemStack slot_stack = slot.getStack();
ItemStack transferred = slot_stack.copy();
if((index>=0) && (index<PLAYER_INV_START_SLOTNO)) {
// Device slots
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.INPUT_SLOTS_SIZE, false)) return ItemStack.EMPTY;
} else {
// invalid slot
return ItemStack.EMPTY;
}
if(slot_stack.isEmpty()) {
slot.putStack(ItemStack.EMPTY);
} else {
slot.onSlotChanged();
}
if(slot_stack.getCount() == transferred.getCount()) return ItemStack.EMPTY;
slot.onTake(player, slot_stack);
return transferred;
}
// INetworkSynchronisableContainer ---------------------------------------------------------
@OnlyIn(Dist.CLIENT)
public void onGuiAction(CompoundNBT nbt)
{ Networking.PacketContainerSyncClientToServer.sendToServer(windowId, nbt); }
@OnlyIn(Dist.CLIENT)
public void onGuiAction(String key, int value)
{
CompoundNBT nbt = new CompoundNBT();
nbt.putInt(key, value);
Networking.PacketContainerSyncClientToServer.sendToServer(windowId, nbt);
}
@Override
public void onServerPacketReceived(int windowId, CompoundNBT nbt)
{}
@Override
public void onClientPacketReceived(int windowId, PlayerEntity player, CompoundNBT nbt)
{
if(!(inventory_ instanceof BTileEntity)) return;
BTileEntity te = (BTileEntity)inventory_;
if(nbt.contains("drop_speed")) te.drop_speed_ = MathHelper.clamp(nbt.getInt("drop_speed"), 0, 100);
if(nbt.contains("drop_xdev")) te.drop_xdev_ = MathHelper.clamp(nbt.getInt("drop_xdev"), -100, 100);
if(nbt.contains("drop_ydev")) te.drop_ydev_ = MathHelper.clamp(nbt.getInt("drop_ydev"), -100, 100);
if(nbt.contains("drop_count")) te.drop_count_ = MathHelper.clamp(nbt.getInt("drop_count"), 1, BTileEntity.MAX_DROP_COUNT);
if(nbt.contains("drop_period")) te.drop_period_ = MathHelper.clamp(nbt.getInt("drop_period"), 0, 100);
if(nbt.contains("drop_logic")) te.drop_logic_ = nbt.getInt("drop_logic");
if(nbt.contains("manual_rstrigger") && (nbt.getInt("manual_rstrigger")!=0)) { te.block_power_signal_=true; te.block_power_updated_=true; te.tick_timer_=1; }
if(nbt.contains("manual_trigger") && (nbt.getInt("manual_trigger")!=0)) { te.tick_timer_ = 1; te.triggered_ = true; }
te.markDirty();
}
}
//--------------------------------------------------------------------------------------------------------------------
// GUI
//--------------------------------------------------------------------------------------------------------------------
@OnlyIn(Dist.CLIENT)
public static class BGui extends ContainerScreen<BContainer>
{
protected final PlayerEntity player_;
public BGui(BContainer container, PlayerInventory player_inventory, ITextComponent title)
{ super(container, player_inventory, title); this.player_ = player_inventory.player; }
@Override
public void init()
{ super.init(); }
@Override
public void render(int mouseX, int mouseY, float partialTicks)
{
renderBackground();
super.render(mouseX, mouseY, partialTicks);
renderHoveredToolTip(mouseX, mouseY);
}
@Override
public boolean mouseClicked(double mouseX, double mouseY, int mouseButton)
{
BContainer container = (BContainer)getContainer();
int mx = (int)(mouseX - getGuiLeft() + .5), my = (int)(mouseY - getGuiTop() + .5);
if((!isPointInRegion(114, 1, 61, 79, mouseX, mouseY))) {
return super.mouseClicked(mouseX, mouseY, mouseButton);
} else if(isPointInRegion(130, 10, 12, 25, mouseX, mouseY)) {
int force_percent = 100 - MathHelper.clamp(((my-10)*100)/25, 0, 100);
container.onGuiAction("drop_speed", force_percent);
} else if(isPointInRegion(145, 10, 25, 25, mouseX, mouseY)) {
int xdev = MathHelper.clamp( (int)Math.round(((double)((mx-157) * 100)) / 12), -100, 100);
int ydev = MathHelper.clamp(-(int)Math.round(((double)((my- 22) * 100)) / 12), -100, 100);
if(Math.abs(xdev) < 9) xdev = 0;
if(Math.abs(ydev) < 9) ydev = 0;
CompoundNBT nbt = new CompoundNBT();
nbt.putInt("drop_xdev", xdev);
nbt.putInt("drop_ydev", ydev);
container.onGuiAction(nbt);
} else if(isPointInRegion(129, 40, 44, 10, mouseX, mouseY)) {
int ndrop = (mx-135);
if(ndrop < -1) {
ndrop = container.field(4) - 1; // -
} else if(ndrop >= 34) {
ndrop = container.field(4) + 1; // +
} else {
ndrop = MathHelper.clamp(1+ndrop, 1, BTileEntity.MAX_DROP_COUNT); // slider
}
container.onGuiAction("drop_count", ndrop);
} else if(isPointInRegion(129, 50, 44, 10, mouseX, mouseY)) {
int period = (mx-135);
if(period < -1) {
period = container.field(6) - 3; // -
} else if(period >= 34) {
period = container.field(6) + 3; // +
} else {
period = (int)(0.5 + ((100.0 * period)/34));
}
period = MathHelper.clamp(period, 0, 100);
container.onGuiAction("drop_period", period);
} else if(isPointInRegion(114, 51, 9, 9, mouseX, mouseY)) {
container.onGuiAction("manual_rstrigger", 1);
} else if(isPointInRegion(162, 66, 7, 9, mouseX, mouseY)) {
container.onGuiAction("manual_trigger", 1);
} else if(isPointInRegion(132, 66, 9, 9, mouseX, mouseY)) {
container.onGuiAction("drop_logic", container.field(5) ^ BTileEntity.DROPLOGIC_FILTER_ANDGATE);
} else if(isPointInRegion(148, 66, 9, 9, mouseX, mouseY)) {
container.onGuiAction("drop_logic", container.field(5) ^ BTileEntity.DROPLOGIC_EXTERN_ANDGATE);
}
return true;
}
@Override
protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY)
{
GlStateManager.color4f(1f, 1f, 1f, 1f);
this.minecraft.getTextureManager().bindTexture(new ResourceLocation(ModEngineersDecor.MODID, "textures/gui/factory_dropper_gui.png"));
final int x0=getGuiLeft(), y0=getGuiTop(), w=getXSize(), h=getYSize();
blit(x0, y0, 0, 0, w, h);
BContainer container = (BContainer)getContainer();
// active drop slot
{
int drop_slot_index = container.field(15);
if((drop_slot_index < 0) || (drop_slot_index >= 16)) drop_slot_index = 0;
int x = (x0+9+((drop_slot_index % 6) * 18));
int y = (y0+5+((drop_slot_index / 6) * 17));
blit(x, y, 180, 45, 18, 18);
}
// filter LEDs
{
for(int i=0; i<3; ++i) {
int xt = 180 + (6 * container.field(12+i)), yt = 38;
int x = x0 + 31 + (i * 36), y = y0 + 65;
blit(x, y, xt, yt, 6, 6);
}
}
// force adjustment
{
int hy = 2 + (((100-container.field(0)) * 21) / 100);
int x = x0+135, y = y0+12, xt = 181;
int yt = 4 + (23-hy);
blit(x, y, xt, yt, 3, hy);
}
// angle adjustment
{
int x = x0 + 157 - 3 + ((container.field(1) * 12) / 100);
int y = y0 + 22 - 3 - ((container.field(2) * 12) / 100);
blit(x, y, 180, 30, 7, 7);
}
// drop count
{
int x = x0 + 134 - 2 + (container.field(4));
int y = y0 + 45;
blit(x, y, 190, 31, 5, 5);
}
// drop period
{
int px = (int)Math.round(((33.0 * container.field(6)) / 100) + 1);
int x = x0 + 134 - 2 + MathHelper.clamp(px, 0, 33);
int y = y0 + 56;
blit(x, y, 190, 31, 5, 5);
}
// redstone input
{
if(container.field(11) != 0) {
blit(x0+114, y0+51, 189, 18, 9, 9);
}
}
// trigger logic
{
int filter_gate_offset = ((container.field(5) & BTileEntity.DROPLOGIC_FILTER_ANDGATE) != 0) ? 11 : 0;
int extern_gate_offset = ((container.field(5) & BTileEntity.DROPLOGIC_EXTERN_ANDGATE) != 0) ? 11 : 0;
blit(x0+132, y0+66, 179+filter_gate_offset, 66, 9, 9);
blit(x0+148, y0+66, 179+extern_gate_offset, 66, 9, 9);
}
// drop timer running indicator
{
if((container.field(9) > BTileEntity.DROP_PERIOD_OFFSET) && ((System.currentTimeMillis() % 1000) < 500)) {
blit(x0+149, y0+51, 201, 39, 3, 3);
}
}
}
}
}

View file

@ -0,0 +1,18 @@
/*
* @file BlockDecorFull.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2019 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)
*
* Full block characteristics class. Explicitly overrides some
* `Block` methods to return faster due to exclusive block properties.
*/
package wile.engineersdecor.blocks;
import net.minecraft.block.Block;
public class BlockDecorFull extends BlockDecor
{
public BlockDecorFull(long config, Block.Properties properties)
{ super(config, properties); }
}

View file

@ -0,0 +1,991 @@
/*
* @file BlockFurnace.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2019 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)
*
* ED Lab furnace.
*/
package wile.engineersdecor.blocks;
import wile.engineersdecor.ModContent;
import wile.engineersdecor.ModEngineersDecor;
import wile.engineersdecor.detail.ExtItems;
import wile.engineersdecor.detail.Networking;
import net.minecraft.tileentity.*;
import net.minecraft.inventory.container.*;
import net.minecraft.item.crafting.AbstractCookingRecipe;
import net.minecraft.item.crafting.IRecipeType;
import net.minecraft.block.RedstoneTorchBlock;
import net.minecraft.client.gui.screen.inventory.ContainerScreen;
import net.minecraft.entity.item.ExperienceOrbEntity;
import net.minecraft.item.crafting.FurnaceRecipe;
import net.minecraft.item.crafting.IRecipe;
import net.minecraft.particles.ParticleTypes;
import net.minecraft.stats.Stats;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.world.IBlockReader;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.util.SoundEvents;
import net.minecraft.state.BooleanProperty;
import net.minecraft.state.StateContainer;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.world.World;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.item.Items;
import net.minecraft.item.*;
import net.minecraft.inventory.*;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.*;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.energy.CapabilityEnergy;
import net.minecraftforge.fml.hooks.BasicEventHooks;
import net.minecraftforge.fml.network.NetworkHooks;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.common.util.FakePlayer;
import net.minecraftforge.energy.IEnergyStorage;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.wrapper.SidedInvWrapper;
import com.mojang.blaze3d.platform.GlStateManager;
import javax.annotation.Nullable;
import java.util.*;
public class BlockDecorFurnace extends BlockDecorDirected
{
public static final BooleanProperty LIT = RedstoneTorchBlock.LIT;
public BlockDecorFurnace(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
{
super(config, builder, unrotatedAABB);
setDefaultState(stateContainer.getBaseState().with(FACING, Direction.NORTH).with(LIT, false));
}
@Override
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder)
{ super.fillStateContainer(builder); builder.add(LIT); }
@Override
@SuppressWarnings("deprecation")
public int getLightValue(BlockState state)
{ return state.get(LIT) ? super.getLightValue(state) : 0; }
@Override
@Nullable
public BlockState getStateForPlacement(BlockItemUseContext context)
{ return getDefaultState().with(FACING, context.getPlacementHorizontalFacing().getOpposite()).with(LIT, false); }
@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 BlockDecorFurnace.BTileEntity(); }
@Override
public void onBlockPlacedBy(World world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack)
{
world.setBlockState(pos, state.with(LIT, false));
if(world.isRemote) return;
if((!stack.hasTag()) || (!stack.getTag().contains("inventory"))) return;
CompoundNBT inventory_nbt = stack.getTag().getCompound("inventory");
if(inventory_nbt.isEmpty()) return;
final TileEntity te = world.getTileEntity(pos);
if(!(te instanceof BlockDecorFurnace.BTileEntity)) return;
final BlockDecorFurnace.BTileEntity bte = ((BlockDecorFurnace.BTileEntity)te);
bte.readnbt(inventory_nbt);
bte.markDirty();
world.setBlockState(pos, state.with(LIT, bte.burning()));
}
@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 BTileEntity)) return stacks;
if(!explosion) {
ItemStack stack = new ItemStack(this, 1);
CompoundNBT inventory_nbt = ((BTileEntity)te).reset_getnbt();
if(!inventory_nbt.isEmpty()) {
CompoundNBT nbt = new CompoundNBT();
nbt.put("inventory", inventory_nbt);
stack.setTag(nbt);
}
stacks.add(stack);
} else {
for(ItemStack stack: ((BTileEntity)te).stacks_) stacks.add(stack);
((BTileEntity)te).reset();
}
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 BlockDecorFurnace.BTileEntity)) return true;
if((!(player instanceof ServerPlayerEntity) && (!(player instanceof FakePlayer)))) return true;
NetworkHooks.openGui((ServerPlayerEntity)player,(INamedContainerProvider)te);
player.addStat(Stats.INTERACT_WITH_FURNACE);
return true;
}
@Override
@OnlyIn(Dist.CLIENT)
public void animateTick(BlockState state, World world, BlockPos pos, Random rnd)
{
if((state.getBlock()!=this) || (!state.get(LIT))) return;
final double rv = rnd.nextDouble();
if(rv > 0.5) return;
final double x=0.5+pos.getX(), y=0.5+pos.getY(), z=0.5+pos.getZ();
final double xc=0.52, xr=rnd.nextDouble()*0.4-0.2, yr=(y-0.3+rnd.nextDouble()*0.2);
if(rv < 0.1d) world.playSound(x, y, z, SoundEvents.BLOCK_FURNACE_FIRE_CRACKLE, SoundCategory.BLOCKS, 0.4f, 0.5f, false);
switch(state.get(FACING)) {
case WEST: world.addParticle(ParticleTypes.SMOKE, x-xc, yr, z+xr, 0.0, 0.0, 0.0); break;
case EAST: world.addParticle(ParticleTypes.SMOKE, x+xc, yr, z+xr, 0.0, 0.0, 0.0); break;
case NORTH: world.addParticle(ParticleTypes.SMOKE, x+xr, yr, z-xc, 0.0, 0.0, 0.0); break;
default: world.addParticle(ParticleTypes.SMOKE, x+xr, yr, z+xc, 0.0, 0.0, 0.0); break;
}
}
//--------------------------------------------------------------------------------------------------------------------
// Tile entity
//--------------------------------------------------------------------------------------------------------------------
public static class BTileEntity extends TileEntity implements ITickableTileEntity, INameable, IInventory, INamedContainerProvider, ISidedInventory, IEnergyStorage
{
public static final IRecipeType<FurnaceRecipe> RECIPE_TYPE = IRecipeType.SMELTING;
public static final int NUM_OF_FIELDS = 5;
public static final int TICK_INTERVAL = 4;
public static final int FIFO_INTERVAL = 20;
public static final int STD_SMELTING_TIME = 200;
public static final int MAX_BURNTIME = 0x7fff;
public static final int DEFAULT_BOOST_ENERGY = 32;
public static final int NUM_OF_SLOTS = 11;
public static final int SMELTING_INPUT_SLOT_NO = 0;
public static final int SMELTING_FUEL_SLOT_NO = 1;
public static final int SMELTING_OUTPUT_SLOT_NO = 2;
public static final int FIFO_INPUT_0_SLOT_NO = 3;
public static final int FIFO_INPUT_1_SLOT_NO = 4;
public static final int FIFO_FUEL_0_SLOT_NO = 5;
public static final int FIFO_FUEL_1_SLOT_NO = 6;
public static final int FIFO_OUTPUT_0_SLOT_NO = 7;
public static final int FIFO_OUTPUT_1_SLOT_NO = 8;
public static final int AUX_0_SLOT_NO = 9;
public static final int AUX_1_SLOT_NO =10;
// Config ----------------------------------------------------------------------------------
private static double proc_fuel_efficiency_ = 1.0;
private static double proc_speed_ = 1.2;
private static int boost_energy_consumption = DEFAULT_BOOST_ENERGY * TICK_INTERVAL;
public static void on_config(int speed_percent, int fuel_efficiency_percent, int boost_energy_per_tick)
{
proc_speed_ = ((double)MathHelper.clamp(speed_percent, 10, 500)) / 100;
proc_fuel_efficiency_ = ((double) MathHelper.clamp(fuel_efficiency_percent, 10, 500)) / 100;
boost_energy_consumption = TICK_INTERVAL * MathHelper.clamp(boost_energy_per_tick, 16, 512);
ModEngineersDecor.logger().info("Config lab furnace speed:" + (proc_speed_*100) + "%, efficiency:" + (proc_fuel_efficiency_*100) + "%");
}
// BTileEntity -----------------------------------------------------------------------------
private int tick_timer_;
private int fifo_timer_;
private int burntime_left_;
private int fuel_burntime_;
private double proc_time_elapsed_;
private int proc_time_needed_;
private int field_is_burning_;
private int field_proc_time_elapsed_;
private int boost_energy_; // small, not saved in nbt.
private boolean heater_inserted_ = false;
protected NonNullList<ItemStack> stacks_;
protected @Nullable IRecipe current_recipe_ = null;
private final List<String> recent_recipes_ = new ArrayList<>();
public BTileEntity()
{ this(ModContent.TET_SMALL_LAB_FURNACE); }
public BTileEntity(TileEntityType<?> te_type)
{ super(te_type); reset(); }
public CompoundNBT reset_getnbt()
{
CompoundNBT nbt = new CompoundNBT();
writenbt(nbt);
reset();
return nbt;
}
public void reset()
{
stacks_ = NonNullList.<ItemStack>withSize(NUM_OF_SLOTS, ItemStack.EMPTY);
proc_time_elapsed_ = 0;
proc_time_needed_ = 0;
burntime_left_ = 0;
fuel_burntime_ = 0;
fifo_timer_ = 0;
tick_timer_ = 0;
current_recipe_ = null;
}
public void readnbt(CompoundNBT nbt)
{
ItemStackHelper.loadAllItems(nbt, stacks_);
while(stacks_.size() < NUM_OF_SLOTS) stacks_.add(ItemStack.EMPTY);
burntime_left_ = nbt.getInt("BurnTime");
proc_time_elapsed_ = nbt.getInt("CookTime");
proc_time_needed_ = nbt.getInt("CookTimeTotal");
fuel_burntime_ = nbt.getInt("FuelBurnTime");
CompoundNBT rr = nbt.getCompound("Recipes");
for(int i=0; i<rr.size(); ++i) {
String recipe_id = rr.getString(Integer.toString(i));
if(recipe_id.isEmpty()) break; // no further processing, nbt data set broken.
recent_recipes_.add(recipe_id);
}
}
private void writenbt(CompoundNBT nbt)
{
nbt.putInt("BurnTime", MathHelper.clamp(burntime_left_,0 , MAX_BURNTIME));
nbt.putInt("CookTime", MathHelper.clamp((int)proc_time_elapsed_, 0, MAX_BURNTIME));
nbt.putInt("CookTimeTotal", MathHelper.clamp(proc_time_needed_, 0, MAX_BURNTIME));
nbt.putInt("FuelBurnTime", MathHelper.clamp(fuel_burntime_, 0, MAX_BURNTIME));
ItemStackHelper.saveAllItems(nbt, stacks_);
CompoundNBT rr = new CompoundNBT();
for(int i=0; i<recent_recipes_.size(); ++i) rr.putString(Integer.toString(i), recent_recipes_.get(i));
nbt.put("Recipes", rr);
}
// TileEntity ------------------------------------------------------------------------------
@Override
public void read(CompoundNBT nbt)
{ super.read(nbt); readnbt(nbt); }
@Override
public CompoundNBT write(CompoundNBT nbt)
{ super.write(nbt); writenbt(nbt); return nbt; }
// INamedContainerProvider / INameable ------------------------------------------------------
@Override
public ITextComponent getName()
{ final Block block=getBlockState().getBlock(); return new StringTextComponent((block!=null) ? block.getTranslationKey() : "Lab furnace"); }
@Override
public boolean hasCustomName()
{ return false; }
@Override
public ITextComponent getCustomName()
{ return getName(); }
// IContainerProvider ----------------------------------------------------------------------
@Override
public ITextComponent getDisplayName()
{ return INameable.super.getDisplayName(); }
@Override
public Container createMenu(int id, PlayerInventory inventory, PlayerEntity player )
{ return new BlockDecorFurnace.BContainer(id, inventory, this, IWorldPosCallable.of(world, pos), fields); }
// IInventory ------------------------------------------------------------------------------
@Override
public int getSizeInventory()
{ return stacks_.size(); }
@Override
public boolean isEmpty()
{ for(ItemStack stack: stacks_) { if(!stack.isEmpty()) return false; } return true; }
@Override
public ItemStack getStackInSlot(int index)
{ return (index < getSizeInventory()) ? stacks_.get(index) : ItemStack.EMPTY; }
@Override
public ItemStack decrStackSize(int index, int count)
{ return ItemStackHelper.getAndSplit(stacks_, index, count); }
@Override
public ItemStack removeStackFromSlot(int index)
{ return ItemStackHelper.getAndRemove(stacks_, index); }
@Override
public void setInventorySlotContents(int index, ItemStack stack)
{
ItemStack slot_stack = stacks_.get(index);
boolean already_in_slot = (!stack.isEmpty()) && (stack.isItemEqual(slot_stack)) && (ItemStack.areItemStackTagsEqual(stack, slot_stack));
stacks_.set(index, stack);
if(stack.getCount() > getInventoryStackLimit()) stack.setCount(getInventoryStackLimit());
if((index == SMELTING_INPUT_SLOT_NO) && (!already_in_slot)) {
proc_time_needed_ = getSmeltingTimeNeeded(world, stack);
proc_time_elapsed_ = 0;
markDirty();
}
}
@Override
public int getInventoryStackLimit()
{ return 64; }
@Override
public void markDirty()
{ super.markDirty(); }
@Override
public boolean isUsableByPlayer(PlayerEntity player)
{ return getPos().distanceSq(player.getPosition()) < 36; }
@Override
public void openInventory(PlayerEntity player)
{}
@Override
public void closeInventory(PlayerEntity player)
{ markDirty(); }
@Override
public boolean isItemValidForSlot(int index, ItemStack stack)
{
switch(index) {
case SMELTING_OUTPUT_SLOT_NO:
case FIFO_OUTPUT_0_SLOT_NO:
case FIFO_OUTPUT_1_SLOT_NO:
return false;
case SMELTING_INPUT_SLOT_NO:
case FIFO_INPUT_0_SLOT_NO:
case FIFO_INPUT_1_SLOT_NO:
return true;
case AUX_0_SLOT_NO:
case AUX_1_SLOT_NO:
return true;
default: {
ItemStack slot_stack = stacks_.get(FIFO_FUEL_1_SLOT_NO);
return isFuel(world, stack) || FurnaceFuelSlot.isBucket(stack) && (slot_stack.getItem() != Items.BUCKET);
}
}
}
@Override
public void clear()
{ stacks_.clear(); }
// Fields -----------------------------------------------------------------------------------------------
protected final IIntArray fields = new IntArray(BTileEntity.NUM_OF_FIELDS)
{
@Override
public int get(int id)
{
switch(id) {
case 0: return BTileEntity.this.burntime_left_;
case 1: return BTileEntity.this.fuel_burntime_;
case 2: return (int)BTileEntity.this.field_proc_time_elapsed_;
case 3: return BTileEntity.this.proc_time_needed_;
case 4: return BTileEntity.this.field_is_burning_;
default: return 0;
}
}
@Override
public void set(int id, int value)
{
switch(id) {
case 0: BTileEntity.this.burntime_left_ = value; break;
case 1: BTileEntity.this.fuel_burntime_ = value; break;
case 2: BTileEntity.this.field_proc_time_elapsed_ = value; break;
case 3: BTileEntity.this.proc_time_needed_ = value; break;
case 4: BTileEntity.this.field_is_burning_ = value;
}
}
};
// ISidedInventory ----------------------------------------------------------------------------
private static final int[] SLOTS_TOP = new int[] {FIFO_INPUT_1_SLOT_NO};
private static final int[] SLOTS_BOTTOM = new int[] {FIFO_OUTPUT_1_SLOT_NO};
private static final int[] SLOTS_SIDES = new int[] {FIFO_FUEL_1_SLOT_NO};
@Override
public int[] getSlotsForFace(Direction side)
{
if(side == Direction.DOWN) return SLOTS_BOTTOM;
if(side == Direction.UP) return SLOTS_TOP;
return SLOTS_SIDES;
}
@Override
public boolean canInsertItem(int index, ItemStack itemStackIn, Direction direction)
{ return isItemValidForSlot(index, itemStackIn); }
@Override
public boolean canExtractItem(int index, ItemStack stack, Direction direction)
{
if((direction!=Direction.DOWN) || ((index!=SMELTING_FUEL_SLOT_NO) && (index!=FIFO_FUEL_0_SLOT_NO) && (index!=FIFO_FUEL_1_SLOT_NO) )) return true;
return (stack.getItem()==Items.BUCKET);
}
// IEnergyStorage ----------------------------------------------------------------------------
@Override
public boolean canExtract()
{ return false; }
@Override
public boolean canReceive()
{ return true; }
@Override
public int getMaxEnergyStored()
{ return boost_energy_consumption; }
@Override
public int getEnergyStored()
{ return boost_energy_; }
@Override
public int extractEnergy(int maxExtract, boolean simulate)
{ return 0; }
@Override
public int receiveEnergy(int maxReceive, boolean simulate)
{ // only speedup support, no buffering, not in nbt -> no markdirty
if((boost_energy_ >= boost_energy_consumption) || (maxReceive < boost_energy_consumption)) return 0;
if(!simulate) boost_energy_ = boost_energy_consumption;
return boost_energy_consumption;
}
// Capability export ----------------------------------------------------------------------------
LazyOptional<? extends IItemHandler>[] item_handlers = SidedInvWrapper.create(this, Direction.UP, Direction.DOWN, Direction.NORTH);
protected LazyOptional<IEnergyStorage> energy_handler_ = LazyOptional.of(() -> (IEnergyStorage)this);
@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();
}
}
return super.getCapability(capability, facing);
}
// ITickableTileEntity -------------------------------------------------------------------------
@Override
public void tick()
{
if(--tick_timer_ > 0) return;
tick_timer_ = TICK_INTERVAL;
final boolean was_burning = burning();
if(was_burning) burntime_left_ -= TICK_INTERVAL;
if(burntime_left_ < 0) burntime_left_ = 0;
if(world.isRemote) return;
boolean dirty = false;
if(--fifo_timer_ <= 0) {
fifo_timer_ = FIFO_INTERVAL/TICK_INTERVAL;
// note, intentionally not using bitwise OR piping.
if(transferItems(FIFO_OUTPUT_0_SLOT_NO, FIFO_OUTPUT_1_SLOT_NO, 1)) dirty = true;
if(transferItems(SMELTING_OUTPUT_SLOT_NO, FIFO_OUTPUT_0_SLOT_NO, 1)) dirty = true;
if(transferItems(FIFO_FUEL_0_SLOT_NO, SMELTING_FUEL_SLOT_NO, 1)) dirty = true;
if(transferItems(FIFO_FUEL_1_SLOT_NO, FIFO_FUEL_0_SLOT_NO, 1)) dirty = true;
if(transferItems(FIFO_INPUT_0_SLOT_NO, SMELTING_INPUT_SLOT_NO, 1)) dirty = true;
if(transferItems(FIFO_INPUT_1_SLOT_NO, FIFO_INPUT_0_SLOT_NO, 1)) dirty = true;
heater_inserted_ = (ExtItems.IE_EXTERNAL_HEATER==null) // without IE always allow electrical boost
|| (stacks_.get(AUX_0_SLOT_NO).getItem()==ExtItems.IE_EXTERNAL_HEATER)
|| (stacks_.get(AUX_1_SLOT_NO).getItem()==ExtItems.IE_EXTERNAL_HEATER);
if(!burning()) cleanupRecentRecipes();
}
ItemStack fuel = stacks_.get(SMELTING_FUEL_SLOT_NO);
if(burning() || (!fuel.isEmpty()) && (!(stacks_.get(SMELTING_INPUT_SLOT_NO)).isEmpty())) {
IRecipe last_recipe = currentRecipe();
updateCurrentRecipe();
if(currentRecipe() != last_recipe) {
proc_time_elapsed_ = 0;
proc_time_needed_ = getSmeltingTimeNeeded(world, stacks_.get(SMELTING_INPUT_SLOT_NO));
}
if(!burning() && canSmeltCurrentItem()) {
burntime_left_ = (int)MathHelper.clamp((proc_fuel_efficiency_ * getFuelBurntime(world, fuel)), 0, MAX_BURNTIME);
fuel_burntime_ = (int)MathHelper.clamp(((double)burntime_left_)/((proc_speed_ > 0) ? proc_speed_ : 1), 1, MAX_BURNTIME);
if(burning()) {
dirty = true;
if(!fuel.isEmpty()) {
Item fuel_item = fuel.getItem();
fuel.shrink(1);
if(fuel.isEmpty()) stacks_.set(SMELTING_FUEL_SLOT_NO, fuel_item.getContainerItem(fuel));
}
}
}
if(burning() && canSmeltCurrentItem()) {
proc_time_elapsed_ += TICK_INTERVAL * proc_speed_;
if(heater_inserted_ && (boost_energy_ >= boost_energy_consumption)) { boost_energy_ = 0; proc_time_elapsed_ += TICK_INTERVAL; }
if(proc_time_elapsed_ >= proc_time_needed_) {
proc_time_elapsed_ = 0;
proc_time_needed_ = getSmeltingTimeNeeded(world, stacks_.get(SMELTING_INPUT_SLOT_NO));
smeltCurrentItem();
dirty = true;
}
} else {
proc_time_elapsed_ = 0;
}
} else if((!burning()) && (proc_time_elapsed_ > 0)) {
proc_time_elapsed_ = MathHelper.clamp(proc_time_elapsed_-2, 0, proc_time_needed_);
}
if(was_burning != burning()) {
dirty = true;
final BlockState state = world.getBlockState(pos);
if(state.getBlock() instanceof BlockDecorFurnace) {
world.setBlockState(pos, state.with(LIT, burning()));
}
}
if(dirty) {
markDirty();
}
field_is_burning_ = this.burning() ? 1 : 0;
field_proc_time_elapsed_ = (int)proc_time_elapsed_;
}
// Furnace -------------------------------------------------------------------------------------
@Nullable
public static final <T extends AbstractCookingRecipe> T getSmeltingResult(IRecipeType<T> recipe_type, World world, ItemStack stack)
{
if(stack.isEmpty()) return null;
Inventory inventory = new Inventory(3);
inventory.setInventorySlotContents(0, stack);
return world.getRecipeManager().getRecipe(recipe_type, inventory, world).orElse(null);
}
@Nullable
protected IRecipe currentRecipe()
{ return current_recipe_; }
public boolean burning()
{ return burntime_left_ > 0; }
public int getSmeltingTimeNeeded(World world, ItemStack stack)
{
if(stack.isEmpty()) return 0;
AbstractCookingRecipe recipe = getSmeltingResult(RECIPE_TYPE, world, stack);
if(recipe == null) return 0;
int t = recipe.getCookTime();
return (t<=0) ? STD_SMELTING_TIME : t;
}
private boolean transferItems(final int index_from, final int index_to, int count)
{
ItemStack from = stacks_.get(index_from);
if(from.isEmpty()) return false;
ItemStack to = stacks_.get(index_to);
if(from.getCount() < count) count = from.getCount();
if(count <= 0) return false;
boolean changed = true;
if(to.isEmpty()) {
stacks_.set(index_to, from.split(count));
} else if(to.getCount() >= to.getMaxStackSize()) {
changed = false;
} else if((!from.isItemEqual(to)) || (!ItemStack.areItemStackTagsEqual(from, to))) {
changed = false;
} else {
if((to.getCount()+count) >= to.getMaxStackSize()) {
from.shrink(to.getMaxStackSize()-to.getCount());
to.setCount(to.getMaxStackSize());
} else {
from.shrink(count);
to.grow(count);
}
}
if(from.isEmpty() && from!=ItemStack.EMPTY) {
stacks_.set(index_from, ItemStack.EMPTY);
changed = true;
}
return changed;
}
protected boolean canSmeltCurrentItem()
{
if((currentRecipe()==null) || (stacks_.get(SMELTING_INPUT_SLOT_NO).isEmpty())) return false;
final ItemStack recipe_result_items = getSmeltingResult(stacks_.get(SMELTING_INPUT_SLOT_NO));
if(recipe_result_items.isEmpty()) return false;
final ItemStack result_stack = stacks_.get(SMELTING_OUTPUT_SLOT_NO);
if(result_stack.isEmpty()) return true;
if(!result_stack.isItemEqual(recipe_result_items)) return false;
if(result_stack.getCount() + recipe_result_items.getCount() <= getInventoryStackLimit() && result_stack.getCount() + recipe_result_items.getCount() <= result_stack.getMaxStackSize()) return true;
return result_stack.getCount() + recipe_result_items.getCount() <= recipe_result_items.getMaxStackSize();
}
protected void smeltCurrentItem()
{
if(!canSmeltCurrentItem()) return;
final ItemStack smelting_input_stack = stacks_.get(SMELTING_INPUT_SLOT_NO);
final ItemStack recipe_result_items = getSmeltingResult(smelting_input_stack);
final ItemStack smelting_output_stack = stacks_.get(SMELTING_OUTPUT_SLOT_NO);
final ItemStack fuel_stack = stacks_.get(SMELTING_FUEL_SLOT_NO);
if(smelting_output_stack.isEmpty()) {
stacks_.set(SMELTING_OUTPUT_SLOT_NO, recipe_result_items.copy());
} else if(smelting_output_stack.getItem() == recipe_result_items.getItem()) {
smelting_output_stack.grow(recipe_result_items.getCount());
}
smelting_input_stack.shrink(1);
}
public static int getFuelBurntime(World world, ItemStack stack)
{
if(stack.isEmpty()) return 0;
Item item = stack.getItem();
int t = stack.getBurnTime();
return net.minecraftforge.event.ForgeEventFactory.getItemBurnTime(stack, (t>=0) ? t : AbstractFurnaceTileEntity.getBurnTimes().getOrDefault(item, 0));
}
public static boolean isFuel(World world, ItemStack stack)
{ return getFuelBurntime(world, stack) > 0; }
public float getSmeltingExperience(ItemStack stack)
{
// This method is not often needed, so the time managing dealing with the recent
// recipes is mainly invested here.
float xp = stack.getItem().getSmeltingExperience(stack);
if(xp >= 0) return xp;
for(int i=0; i<recent_recipes_.size(); ++i) {
IRecipe r = world.getRecipeManager().getRecipe(new ResourceLocation(recent_recipes_.get(i))).orElse(null);
if((!(r instanceof AbstractCookingRecipe))) continue; // recipe not available (e.g. at the moment).
if(!(stack.isItemEqual(r.getRecipeOutput()))) continue;
xp = ((AbstractCookingRecipe)r).getExperience();
}
return (xp <= 0) ? 0 : xp;
}
public ItemStack getSmeltingResult(final ItemStack stack)
{ return (currentRecipe()==null) ? (ItemStack.EMPTY) : (currentRecipe().getRecipeOutput()); }
public static boolean canSmelt(World world, final ItemStack stack)
{ return getSmeltingResult(RECIPE_TYPE, world, stack) != null; }
protected void updateCurrentRecipe()
{ setCurrentRecipe(getSmeltingResult(RECIPE_TYPE, world, stacks_.get(SMELTING_INPUT_SLOT_NO))); }
protected void setCurrentRecipe(IRecipe<?> recipe)
{
if(recipe == null) { current_recipe_ = null; return; }
current_recipe_ = recipe;
String recipe_id = recipe.getId().toString();
if(!recent_recipes_.contains(recipe_id)) recent_recipes_.add(recipe_id);
}
private void cleanupRecentRecipes()
{
if(recent_recipes_.isEmpty()) return;
if(!stacks_.get(SMELTING_INPUT_SLOT_NO).isEmpty()) return;
if(!stacks_.get(SMELTING_OUTPUT_SLOT_NO).isEmpty()) return;
if(!stacks_.get(FIFO_OUTPUT_0_SLOT_NO).isEmpty()) return;
if(!stacks_.get(FIFO_OUTPUT_1_SLOT_NO).isEmpty()) return;
recent_recipes_.clear();
}
}
//--------------------------------------------------------------------------------------------------------------------
// container slots
//--------------------------------------------------------------------------------------------------------------------
public static class BContainer extends Container implements Networking.INetworkSynchronisableContainer
{
// Slots --------------------------------------------------------------------------------------------
public static class BSlotInpFifo extends Slot
{
public BSlotInpFifo(IInventory inv, int index, int xpos, int ypos)
{ super(inv, index, xpos, ypos); }
}
public static class BSlotFuelFifo extends Slot
{
public BSlotFuelFifo(IInventory inv, int index, int xpos, int ypos)
{ super(inv, index, xpos, ypos); }
}
public static class BSlotOutFifo extends BSlotResult
{
public BSlotOutFifo(PlayerEntity player, IInventory inventory, int index, int xpos, int ypos)
{ super(player, inventory, index, xpos, ypos); }
}
public static class BSlotResult extends Slot
{
private final IInventory inventory_;
private final PlayerEntity player_;
private int removeCount = 0;
public BSlotResult(PlayerEntity player, IInventory inventory, int index, int xpos, int ypos)
{ super(inventory, index, xpos, ypos); inventory_ = inventory; player_ = player; }
@Override
public boolean isItemValid(ItemStack stack)
{ return false; }
@Override
public ItemStack decrStackSize(int amount)
{ removeCount += getHasStack() ? Math.min(amount, getStack().getCount()) : 0; return super.decrStackSize(amount); }
@Override
public ItemStack onTake(PlayerEntity thePlayer, ItemStack stack)
{ onCrafting(stack); super.onTake(thePlayer, stack); return stack; }
@Override
protected void onCrafting(ItemStack stack, int amount)
{ removeCount += amount; onCrafting(stack); }
@Override
protected void onCrafting(ItemStack stack)
{
stack.onCrafting(player_.world, player_, removeCount);
if((!player_.world.isRemote) && (inventory_ instanceof BTileEntity)) {
BTileEntity te = (BTileEntity)inventory_;
int xp = removeCount;
float sxp = te.getSmeltingExperience(stack);
if(sxp == 0) {
xp = 0;
} else if(sxp < 1.0) {
xp = (int)((sxp*xp) + Math.round(Math.random()+0.75));
}
while(xp > 0) {
int k = ExperienceOrbEntity.getXPSplit(xp);
xp -= k;
player_.world.addEntity((new ExperienceOrbEntity(player_.world, player_.posX, player_.posY+0.5, player_.posZ+0.5, k)));
}
}
removeCount = 0;
BasicEventHooks.firePlayerSmeltedEvent(player_, stack);
}
}
public static class BFuelSlot extends Slot
{
private final BContainer container_;
public BFuelSlot(IInventory inventory, int index, int xpos, int ypos, BContainer container)
{ super(inventory, index, xpos, ypos); container_=container; }
@Override
public boolean isItemValid(ItemStack stack)
{ return isBucket(stack) || (BTileEntity.isFuel(container_.world(), stack)); }
@Override
public int getItemStackLimit(ItemStack stack)
{ return isBucket(stack) ? 1 : super.getItemStackLimit(stack); }
protected static boolean isBucket(ItemStack stack)
{ return (stack.getItem()==Items.BUCKET); }
}
// Container ----------------------------------------------------------------------------------------
private static final int PLAYER_INV_START_SLOTNO = 11;
protected final PlayerEntity player_;
protected final IInventory inventory_;
protected final IWorldPosCallable wpc_;
private final IIntArray fields_;
private final IRecipeType<? extends AbstractCookingRecipe> recipe_type_;
public int field(int index) { return fields_.get(index); }
public PlayerEntity player() { return player_ ; }
public IInventory inventory() { return inventory_ ; }
public World world() { return player_.world; }
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)); }
private BContainer(int cid, PlayerInventory player_inventory, IInventory block_inventory, IWorldPosCallable wpc, IIntArray fields)
{
super(ModContent.CT_SMALL_LAB_FURNACE, cid);
player_ = player_inventory.player;
inventory_ = block_inventory;
wpc_ = wpc;
fields_ = fields;
recipe_type_ = BTileEntity.RECIPE_TYPE;
addSlot(new Slot(inventory_, 0, 59, 17)); // smelting input
addSlot(new BFuelSlot(inventory_, 1, 59, 53, this)); // fuel
addSlot(new BSlotResult(player_, inventory_, 2, 101, 35)); // smelting result
addSlot(new BSlotInpFifo(inventory_, 3, 34, 17)); // input fifo 0
addSlot(new BSlotInpFifo(inventory_, 4, 16, 17)); // input fifo 1
addSlot(new BSlotFuelFifo(inventory_, 5, 34, 53)); // fuel fifo 0
addSlot(new BSlotFuelFifo(inventory_, 6, 16, 53)); // fuel fifo 1
addSlot(new BSlotOutFifo(player_inventory.player, inventory_, 7, 126, 35)); // out fifo 0
addSlot(new BSlotOutFifo(player_inventory.player, inventory_, 8, 144, 35)); // out fifo 1
addSlot(new Slot(inventory_, 9, 126, 61)); // aux slot 1
addSlot(new Slot(inventory_, 10, 144, 61)); // aux slot 2
for(int x=0; x<9; ++x) {
addSlot(new Slot(player_inventory, x, 8+x*18, 144)); // player slots: 0..8
}
for(int y=0; y<3; ++y) {
for(int x=0; x<9; ++x) {
addSlot(new Slot(player_inventory, x+y*9+9, 8+x*18, 86+y*18)); // player slots: 9..35
}
}
this.trackIntArray(fields_); // === Add reference holders
}
@Override
public boolean canInteractWith(PlayerEntity player)
{ return inventory_.isUsableByPlayer(player); }
@Override
public ItemStack transferStackInSlot(PlayerEntity player, int index)
{
Slot slot = getSlot(index);
if((slot==null) || (!slot.getHasStack())) return ItemStack.EMPTY;
ItemStack slot_stack = slot.getStack();
ItemStack transferred = slot_stack.copy();
if((index==2) || (index==7) || (index==8)) {
// Output slots
if(!mergeItemStack(slot_stack, PLAYER_INV_START_SLOTNO, PLAYER_INV_START_SLOTNO+36, true)) return ItemStack.EMPTY;
slot.onSlotChange(slot_stack, transferred);
} else if((index==0) || (index==3) || (index==4)) {
// Input slots
if(!mergeItemStack(slot_stack, PLAYER_INV_START_SLOTNO, PLAYER_INV_START_SLOTNO+36, false)) return ItemStack.EMPTY;
} else if((index==1) || (index==5) || (index==6)) {
// Fuel slots
if(!mergeItemStack(slot_stack, PLAYER_INV_START_SLOTNO, PLAYER_INV_START_SLOTNO+36, false)) return ItemStack.EMPTY;
} else if((index==9) || (index==10)) {
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 inventory
if(BTileEntity.canSmelt(world(), slot_stack)) {
if(
(!mergeItemStack(slot_stack, 0, 1, false)) && // smelting input
(!mergeItemStack(slot_stack, 3, 4, false)) && // fifo0
(!mergeItemStack(slot_stack, 4, 5, false)) // fifo1
) return ItemStack.EMPTY;
} else if(BTileEntity.isFuel(player_.world, slot_stack)) {
if(
(!mergeItemStack(slot_stack, 1, 2, false)) && // fuel input
(!mergeItemStack(slot_stack, 5, 6, false)) && // fuel fifo0
(!mergeItemStack(slot_stack, 6, 7, false)) // fuel fifo1
) return ItemStack.EMPTY;
} else if((index >= PLAYER_INV_START_SLOTNO) && (index < PLAYER_INV_START_SLOTNO+27)) {
// player inventory --> player hotbar
if(!mergeItemStack(slot_stack, PLAYER_INV_START_SLOTNO+27, PLAYER_INV_START_SLOTNO+36, false)) return ItemStack.EMPTY;
} else if((index >= PLAYER_INV_START_SLOTNO+27) && (index < PLAYER_INV_START_SLOTNO+36) && (!mergeItemStack(slot_stack, PLAYER_INV_START_SLOTNO, PLAYER_INV_START_SLOTNO+27, false))) {
// player hotbar --> player inventory
return ItemStack.EMPTY;
}
} else {
// invalid slot
return ItemStack.EMPTY;
}
if(slot_stack.isEmpty()) {
slot.putStack(ItemStack.EMPTY);
} else {
slot.onSlotChanged();
}
if(slot_stack.getCount() == transferred.getCount()) return ItemStack.EMPTY;
slot.onTake(player, slot_stack);
//if(!player.world.isRemote) detectAndSendChanges();
return transferred;
}
// INetworkSynchronisableContainer ---------------------------------------------------------
@OnlyIn(Dist.CLIENT)
public void onGuiAction(CompoundNBT nbt)
{ Networking.PacketContainerSyncClientToServer.sendToServer(windowId, nbt); }
@OnlyIn(Dist.CLIENT)
public void onGuiAction(String key, int value)
{
CompoundNBT nbt = new CompoundNBT();
nbt.putInt(key, value);
Networking.PacketContainerSyncClientToServer.sendToServer(windowId, nbt);
}
@Override
public void onServerPacketReceived(int windowId, CompoundNBT nbt)
{}
@Override
public void onClientPacketReceived(int windowId, PlayerEntity player, CompoundNBT nbt)
{}
}
//--------------------------------------------------------------------------------------------------------------------
// GUI
//--------------------------------------------------------------------------------------------------------------------
@OnlyIn(Dist.CLIENT)
public static class BGui extends ContainerScreen<BContainer>
{
protected final PlayerEntity player_;
public BGui(BContainer container, PlayerInventory player_inventory, ITextComponent title)
{ super(container, player_inventory, title); this.player_ = player_inventory.player; }
@Override
public void init()
{ super.init(); }
@Override
public void render(int mouseX, int mouseY, float partialTicks)
{
renderBackground();
super.render(mouseX, mouseY, partialTicks);
renderHoveredToolTip(mouseX, mouseY);
}
@Override
protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY)
{
GlStateManager.color4f(1.0F, 1.0F, 1.0F, 1.0F);
this.minecraft.getTextureManager().bindTexture(new ResourceLocation(ModEngineersDecor.MODID, "textures/gui/small_lab_furnace_gui.png"));
final int x0=guiLeft, y0=this.guiTop, w=xSize, h=ySize;
blit(x0, y0, 0, 0, w, h);
if(getContainer().field(4) != 0) {
final int k = flame_px(13);
blit(x0+59, y0+36+12-k, 176, 12-k, 14, k+1);
}
blit(x0+79, y0+36, 176, 15, 1+progress_px(17), 15);
}
private int progress_px(int pixels)
{ final int tc=getContainer().field(2), T=getContainer().field(3); return ((T>0) && (tc>0)) ? (tc * pixels / T) : (0); }
private int flame_px(int pixels)
{ int ibt = getContainer().field(1); return ((getContainer().field(0) * pixels) / ((ibt>0) ? (ibt) : (BTileEntity.STD_SMELTING_TIME))); }
}
}

View file

@ -0,0 +1,777 @@
/*
* @file BlockDecorFurnaceElectrical.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2019 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)
*
* ED small electrical pass-through furnace.
*/
package wile.engineersdecor.blocks;
import wile.engineersdecor.ModContent;
import wile.engineersdecor.ModEngineersDecor;
import wile.engineersdecor.detail.Networking;
import net.minecraft.inventory.container.*;
import net.minecraft.item.crafting.AbstractCookingRecipe;
import net.minecraft.item.crafting.FurnaceRecipe;
import net.minecraft.item.crafting.IRecipe;
import net.minecraft.item.crafting.IRecipeType;
import net.minecraft.tileentity.ITickableTileEntity;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.block.Block;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.world.IBlockReader;
import net.minecraft.block.BlockState;
import net.minecraft.world.World;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.entity.LivingEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.item.Items;
import net.minecraft.item.*;
import net.minecraft.inventory.*;
import net.minecraft.client.gui.screen.inventory.ContainerScreen;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.*;
import net.minecraft.stats.Stats;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.common.util.FakePlayer;
import net.minecraftforge.fml.network.NetworkHooks;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.energy.CapabilityEnergy;
import net.minecraftforge.energy.IEnergyStorage;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemHandlerHelper;
import com.mojang.blaze3d.platform.GlStateManager;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Random;
public class BlockDecorFurnaceElectrical extends BlockDecorFurnace
{
public BlockDecorFurnaceElectrical(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
{ super(config, builder, unrotatedAABB); }
@Override
@Nullable
public TileEntity createTileEntity(BlockState state, IBlockReader world)
{ return new BlockDecorFurnaceElectrical.BTileEntity(); }
@Override
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 BlockDecorFurnaceElectrical.BTileEntity)) return true;
if((!(player instanceof ServerPlayerEntity) && (!(player instanceof FakePlayer)))) return true;
NetworkHooks.openGui((ServerPlayerEntity)player,(INamedContainerProvider)te);
player.addStat(Stats.INTERACT_WITH_FURNACE);
return true;
}
@Override
public void onBlockPlacedBy(World world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack)
{
world.setBlockState(pos, state.with(LIT, false));
if(world.isRemote) return;
if((!stack.hasTag()) || (!stack.getTag().contains("inventory"))) return;
CompoundNBT inventory_nbt = stack.getTag().getCompound("inventory");
if(inventory_nbt.isEmpty()) return;
final TileEntity te = world.getTileEntity(pos);
if(!(te instanceof BlockDecorFurnaceElectrical.BTileEntity)) return;
BTileEntity bte = (BlockDecorFurnaceElectrical.BTileEntity)te;
bte.readnbt(inventory_nbt);
bte.markDirty();
world.setBlockState(pos, state.with(LIT, bte.burning()));
}
@Override
@OnlyIn(Dist.CLIENT)
public void animateTick(BlockState state, World world, BlockPos pos, Random rnd)
{}
//--------------------------------------------------------------------------------------------------------------------
// Tile entity
//--------------------------------------------------------------------------------------------------------------------
public static class BTileEntity extends BlockDecorFurnace.BTileEntity implements ITickableTileEntity, INameable, IInventory, INamedContainerProvider, ISidedInventory, IEnergyStorage
{
public static final IRecipeType<FurnaceRecipe> RECIPE_TYPE = IRecipeType.SMELTING;
public static final int NUM_OF_FIELDS = 7;
public static final int TICK_INTERVAL = 4;
public static final int FIFO_INTERVAL = 20;
public static final int HEAT_CAPACITY = 200;
public static final int HEAT_INCREMENT = 20;
public static final int MAX_ENERGY_TRANSFER = 256;
public static final int MAX_ENERGY_BUFFER = 32000;
public static final int MAX_SPEED_SETTING = 2;
public static final int NUM_OF_SLOTS = 7;
public static final int SMELTING_INPUT_SLOT_NO = 0;
public static final int SMELTING_AUX_SLOT_NO = 1;
public static final int SMELTING_OUTPUT_SLOT_NO = 2;
public static final int FIFO_INPUT_0_SLOT_NO = 3;
public static final int FIFO_INPUT_1_SLOT_NO = 4;
public static final int FIFO_OUTPUT_0_SLOT_NO = 5;
public static final int FIFO_OUTPUT_1_SLOT_NO = 6;
public static final int DEFAULT_SPEED_PERCENT = 200;
public static final int DEFAULT_ENERGY_CONSUMPTION = 16;
public static final int DEFAULT_SCALED_ENERGY_CONSUMPTION = DEFAULT_ENERGY_CONSUMPTION * HEAT_INCREMENT * DEFAULT_SPEED_PERCENT / 100;
// Config ----------------------------------------------------------------------------------
private static boolean with_automatic_inventory_pulling_ = false;
private static int energy_consumption_ = DEFAULT_SCALED_ENERGY_CONSUMPTION;
private static int transfer_energy_consumption_ = DEFAULT_SCALED_ENERGY_CONSUMPTION / 8;
private static int proc_speed_percent_ = DEFAULT_SPEED_PERCENT;
public static void on_config(int speed_percent, int standard_energy_per_tick, boolean with_automatic_inventory_pulling)
{
proc_speed_percent_ = MathHelper.clamp(speed_percent, 10, 500);
energy_consumption_ = MathHelper.clamp(standard_energy_per_tick, 10, 256) * HEAT_INCREMENT * proc_speed_percent_ / 100;
transfer_energy_consumption_ = MathHelper.clamp(energy_consumption_ / 8, 8, HEAT_INCREMENT);
with_automatic_inventory_pulling_ = with_automatic_inventory_pulling;
ModEngineersDecor.logger().info("Config electrical furnace speed:" + proc_speed_percent_ + ", power consumption:" + energy_consumption_);
}
// BTileEntity -----------------------------------------------------------------------------
private int burntime_left_;
private int proc_time_elapsed_;
private int proc_time_needed_;
private int energy_stored_;
private int field_max_energy_stored_;
private int field_isburning_;
private int speed_;
private int tick_timer_;
private int fifo_timer_;
public BTileEntity()
{ this(ModContent.TET_SMALL_ELECTRICAL_FURNACE); }
public BTileEntity(TileEntityType<?> te_type)
{ super(te_type); }
public void reset()
{
super.reset();
stacks_ = NonNullList.<ItemStack>withSize(NUM_OF_SLOTS, ItemStack.EMPTY);
burntime_left_ = 0;
proc_time_elapsed_ = 0;
proc_time_needed_ = 0;
fifo_timer_ = 0;
tick_timer_ = 0;
energy_stored_ = 0;
speed_ = 0;
field_max_energy_stored_ = getMaxEnergyStored();
field_isburning_ = 0;
}
public void readnbt(CompoundNBT nbt)
{
ItemStackHelper.loadAllItems(nbt, this.stacks_);
while(this.stacks_.size() < NUM_OF_SLOTS) this.stacks_.add(ItemStack.EMPTY);
burntime_left_ = nbt.getInt("BurnTime");
proc_time_elapsed_ = nbt.getInt("CookTime");
proc_time_needed_ = nbt.getInt("CookTimeTotal");
energy_stored_ = nbt.getInt("Energy");
speed_ = nbt.getInt("SpeedSetting");
}
protected void writenbt(CompoundNBT nbt)
{
nbt.putInt("BurnTime", MathHelper.clamp(burntime_left_, 0, HEAT_CAPACITY));
nbt.putInt("CookTime", MathHelper.clamp(proc_time_elapsed_, 0, MAX_BURNTIME));
nbt.putInt("CookTimeTotal", MathHelper.clamp(proc_time_needed_, 0, MAX_BURNTIME));
nbt.putInt("Energy", MathHelper.clamp(energy_stored_, 0, MAX_ENERGY_BUFFER));
nbt.putInt("SpeedSetting", MathHelper.clamp(speed_, -1, MAX_SPEED_SETTING));
ItemStackHelper.saveAllItems(nbt, stacks_);
}
// INameable -------------------------------------------------------------------------------
@Override
public ITextComponent getName()
{ final Block block=getBlockState().getBlock(); return new StringTextComponent((block!=null) ? block.getTranslationKey() : "Small electrical furnace"); }
// IContainerProvider ----------------------------------------------------------------------
@Override
public Container createMenu(int id, PlayerInventory inventory, PlayerEntity player )
{ return new BlockDecorFurnaceElectrical.BContainer(id, inventory, this, IWorldPosCallable.of(world, pos), fields); }
// IInventory ------------------------------------------------------------------------------
@Override
public boolean isItemValidForSlot(int index, ItemStack stack)
{
switch(index) {
case SMELTING_INPUT_SLOT_NO:
case FIFO_INPUT_0_SLOT_NO:
case FIFO_INPUT_1_SLOT_NO:
return true;
default:
return false;
}
}
@Override
public ItemStack getStackInSlot(int index)
{ return ((index < 0) || (index >= SIDED_INV_SLOTS.length)) ? ItemStack.EMPTY : stacks_.get(SIDED_INV_SLOTS[index]); }
// Fields -----------------------------------------------------------------------------------------------
protected final IIntArray fields = new IntArray(BTileEntity.NUM_OF_FIELDS)
{
@Override
public int get(int id)
{
switch(id) {
case 0: return BTileEntity.this.burntime_left_;
case 1: return BTileEntity.this.energy_stored_;
case 2: return BTileEntity.this.proc_time_elapsed_;
case 3: return BTileEntity.this.proc_time_needed_;
case 4: return BTileEntity.this.speed_;
case 5: return BTileEntity.this.field_max_energy_stored_;
case 6: return BTileEntity.this.field_isburning_;
default: return 0;
}
}
@Override
public void set(int id, int value)
{
switch(id) {
case 0: BTileEntity.this.burntime_left_ = value; break;
case 1: BTileEntity.this.energy_stored_ = value; break;
case 2: BTileEntity.this.proc_time_elapsed_ = value; break;
case 3: BTileEntity.this.proc_time_needed_ = value; break;
case 4: BTileEntity.this.speed_ = value; break;
case 5: BTileEntity.this.field_max_energy_stored_ = value; break;
case 6: BTileEntity.this.field_isburning_ = value; break;
}
}
};
// ISidedInventory ----------------------------------------------------------------------------
private static final int[] SIDED_INV_SLOTS = new int[] {
SMELTING_INPUT_SLOT_NO, SMELTING_AUX_SLOT_NO, SMELTING_OUTPUT_SLOT_NO,
FIFO_INPUT_0_SLOT_NO, FIFO_INPUT_1_SLOT_NO, FIFO_OUTPUT_0_SLOT_NO, FIFO_OUTPUT_1_SLOT_NO
};
@Override
public int[] getSlotsForFace(Direction side)
{ return SIDED_INV_SLOTS; }
@Override
public boolean canInsertItem(int index, ItemStack itemStackIn, Direction direction)
{ return isItemValidForSlot(index, itemStackIn); }
@Override
public boolean canExtractItem(int index, ItemStack stack, Direction direction)
{ return ((index!=SMELTING_INPUT_SLOT_NO) && (index!=FIFO_INPUT_0_SLOT_NO) && (index!=FIFO_INPUT_1_SLOT_NO)) || (stack.getItem()==Items.BUCKET); }
// IEnergyStorage ----------------------------------------------------------------------------
@Override
public boolean canExtract()
{ return false; }
@Override
public boolean canReceive()
{ return true; }
@Override
public int getMaxEnergyStored()
{ return MAX_ENERGY_BUFFER; }
@Override
public int getEnergyStored()
{ return energy_stored_; }
@Override
public int extractEnergy(int maxExtract, boolean simulate)
{ return 0; }
@Override
public int receiveEnergy(int maxReceive, boolean simulate)
{
if(energy_stored_ >= MAX_ENERGY_BUFFER) return 0;
int n = Math.min(maxReceive, (MAX_ENERGY_BUFFER - energy_stored_));
if(n > MAX_ENERGY_TRANSFER) n = MAX_ENERGY_TRANSFER;
if(!simulate) {energy_stored_ += n; markDirty(); }
return n;
}
// IItemHandler --------------------------------------------------------------------------------
protected static class BItemHandler implements IItemHandler
{
private BTileEntity te;
BItemHandler(BTileEntity te)
{ this.te = te; }
@Override
public int getSlots()
{ return SIDED_INV_SLOTS.length; }
@Override
@Nonnull
public ItemStack getStackInSlot(int index)
{ return te.getStackInSlot(index); }
@Override
public int getSlotLimit(int index)
{ return te.getInventoryStackLimit(); }
@Override
public boolean isItemValid(int slot, @Nonnull ItemStack stack)
{ return true; }
@Override
@Nonnull
public ItemStack insertItem(int index, @Nonnull ItemStack stack, boolean simulate)
{
if(stack.isEmpty()) return ItemStack.EMPTY;
if((index < 0) || (index >= SIDED_INV_SLOTS.length)) return ItemStack.EMPTY;
int slotno = SIDED_INV_SLOTS[index];
ItemStack slotstack = getStackInSlot(slotno);
if(!slotstack.isEmpty()) {
if(slotstack.getCount() >= Math.min(slotstack.getMaxStackSize(), getSlotLimit(index))) return stack;
if(!ItemHandlerHelper.canItemStacksStack(stack, slotstack)) return stack;
if(!te.canInsertItem(slotno, stack, Direction.UP) || (!te.isItemValidForSlot(slotno, stack))) return stack;
int n = Math.min(stack.getMaxStackSize(), getSlotLimit(index)) - slotstack.getCount();
if(stack.getCount() <= n) {
if(!simulate) {
ItemStack copy = stack.copy();
copy.grow(slotstack.getCount());
te.setInventorySlotContents(slotno, copy);
}
return ItemStack.EMPTY;
} else {
stack = stack.copy();
if(!simulate) {
ItemStack copy = stack.split(n);
copy.grow(slotstack.getCount());
te.setInventorySlotContents(slotno, copy);
return stack;
} else {
stack.shrink(n);
return stack;
}
}
} else {
if(!te.canInsertItem(slotno, stack, Direction.UP) || (!te.isItemValidForSlot(slotno, stack))) return stack;
int n = Math.min(stack.getMaxStackSize(), getSlotLimit(index));
if(n < stack.getCount()) {
stack = stack.copy();
if(!simulate) {
te.setInventorySlotContents(slotno, stack.split(n));
return stack;
} else {
stack.shrink(n);
return stack;
}
} else {
if(!simulate) te.setInventorySlotContents(slotno, stack);
return ItemStack.EMPTY;
}
}
}
@Override
@Nonnull
public ItemStack extractItem(int index, int amount, boolean simulate)
{
if(amount == 0) return ItemStack.EMPTY;
if((index < 0) || (index >= SIDED_INV_SLOTS.length)) return ItemStack.EMPTY;
int slotno = SIDED_INV_SLOTS[index];
ItemStack stackInSlot = getStackInSlot(slotno);
if(stackInSlot.isEmpty()) return ItemStack.EMPTY;
if(!te.canExtractItem(slotno, stackInSlot, Direction.DOWN)) return ItemStack.EMPTY;
if(simulate) {
if(stackInSlot.getCount() < amount) return stackInSlot.copy();
ItemStack ostack = stackInSlot.copy();
ostack.setCount(amount);
return ostack;
} else {
ItemStack ostack = te.decrStackSize(slotno, Math.min(stackInSlot.getCount(), amount));
te.markDirty();
return ostack;
}
}
}
// Capability export ----------------------------------------------------------------------------
protected LazyOptional<IItemHandler> item_handler_ = LazyOptional.of(() -> new BItemHandler(this));
protected LazyOptional<IEnergyStorage> energy_handler_ = LazyOptional.of(() -> (IEnergyStorage)this);
@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();
}
return super.getCapability(capability, facing);
}
// ITickableTileEntity -------------------------------------------------------------------------
@Override
public void tick()
{
if(--tick_timer_ > 0) return;
tick_timer_ = TICK_INTERVAL;
final boolean was_burning = burning();
if(was_burning) burntime_left_ -= TICK_INTERVAL;
if(burntime_left_ < 0) burntime_left_ = 0;
if(world.isRemote) return;
boolean update_blockstate = (was_burning != burning());
boolean dirty = update_blockstate;
boolean shift_in = false;
boolean shift_out = false;
if(--fifo_timer_ <= 0) {
fifo_timer_ = FIFO_INTERVAL/TICK_INTERVAL;
if(transferItems(FIFO_OUTPUT_0_SLOT_NO, FIFO_OUTPUT_1_SLOT_NO, 64)) { dirty = true; } else { shift_out = true; }
if(transferItems(SMELTING_OUTPUT_SLOT_NO, FIFO_OUTPUT_0_SLOT_NO, 64)) dirty = true;
if(transferItems(FIFO_INPUT_0_SLOT_NO, SMELTING_INPUT_SLOT_NO, 64)) dirty = true;
if(transferItems(FIFO_INPUT_1_SLOT_NO, FIFO_INPUT_0_SLOT_NO, 64)) { dirty = true; } else { shift_in = true; }
}
if((!(stacks_.get(SMELTING_INPUT_SLOT_NO)).isEmpty()) && (energy_stored_ >= energy_consumption_)) {
IRecipe last_recipe = currentRecipe();
updateCurrentRecipe();
if(currentRecipe() != last_recipe) {
proc_time_elapsed_ = 0;
proc_time_needed_ = getSmeltingTimeNeeded(world, stacks_.get(SMELTING_INPUT_SLOT_NO));
}
final boolean can_smelt = canSmeltCurrentItem();
if((!can_smelt) && (getSmeltingResult(stacks_.get(SMELTING_INPUT_SLOT_NO)).isEmpty())) {
// bypass
if(transferItems(SMELTING_INPUT_SLOT_NO, SMELTING_OUTPUT_SLOT_NO, 1)) dirty = true;
} else {
// smelt
if(!burning() && can_smelt) {
if(heat_up()) { dirty = true; update_blockstate = true; }
}
if(burning() && can_smelt) {
if(heat_up()) dirty = true;
proc_time_elapsed_ += (TICK_INTERVAL * proc_speed_percent_/100);
if(proc_time_elapsed_ >= proc_time_needed_) {
proc_time_elapsed_ = 0;
proc_time_needed_ = getSmeltingTimeNeeded(world, stacks_.get(SMELTING_INPUT_SLOT_NO));
smeltCurrentItem();
dirty = true;
shift_out = true;
}
} else {
proc_time_elapsed_ = 0;
}
}
} else if(proc_time_elapsed_ > 0) {
proc_time_elapsed_ -= ((stacks_.get(SMELTING_INPUT_SLOT_NO)).isEmpty() ? 20 : 1);
if(proc_time_elapsed_ < 0) { proc_time_elapsed_ = 0; shift_out = true; update_blockstate = true; }
}
if(update_blockstate) {
dirty = true;
sync_blockstate();
}
if(adjacent_inventory_shift(shift_in, shift_out)) dirty = true;
if(dirty) markDirty();
field_max_energy_stored_ = getMaxEnergyStored();
field_isburning_ = burning() ? 1 : 0;
//if(this.energy_stored_ < this.getMaxEnergyStored() / 5) this.energy_stored_ = this.getMaxEnergyStored();
}
// Furnace --------------------------------------------------------------------------------------
protected void updateCurrentRecipe() //// Change this for other recipe registry (e.g. craft tweaker modified).
{ setCurrentRecipe(getSmeltingResult(RECIPE_TYPE, world, stacks_.get(SMELTING_INPUT_SLOT_NO))); }
public boolean burning()
{ return burntime_left_ > 0; }
private boolean transferItems(final int index_from, final int index_to, int count)
{
ItemStack from = stacks_.get(index_from);
if(from.isEmpty()) return false;
ItemStack to = stacks_.get(index_to);
if(from.getCount() < count) count = from.getCount();
if(count <= 0) return false;
boolean changed = true;
if(to.isEmpty()) {
stacks_.set(index_to, from.split(count));
} else if(to.getCount() >= to.getMaxStackSize()) {
changed = false;
} else if((!from.isItemEqual(to)) || (!ItemStack.areItemStackTagsEqual(from, to))) {
changed = false;
} else {
if((to.getCount()+count) >= to.getMaxStackSize()) {
from.shrink(to.getMaxStackSize()-to.getCount());
to.setCount(to.getMaxStackSize());
} else {
from.shrink(count);
to.grow(count);
}
}
if(from.isEmpty() && from!=ItemStack.EMPTY) {
stacks_.set(index_from, ItemStack.EMPTY);
changed = true;
}
return changed;
}
private boolean adjacent_inventory_shift(boolean inp, boolean out)
{
boolean dirty = false;
if(energy_stored_ < transfer_energy_consumption_) return false;
final BlockState state = world.getBlockState(pos);
if(!(state.getBlock() instanceof BlockDecorFurnaceElectrical)) return false;
final Direction out_facing = state.get(FACING);
if(out && (!stacks_.get(FIFO_OUTPUT_1_SLOT_NO).isEmpty())) {
TileEntity te = world.getTileEntity(pos.offset(out_facing));
if(te!=null) {
IItemHandler hnd = te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, out_facing).orElse(null);
if(hnd != null) {
ItemStack remaining = ItemHandlerHelper.insertItemStacked(hnd, stacks_.get(FIFO_OUTPUT_1_SLOT_NO).copy(), false);
stacks_.set(FIFO_OUTPUT_1_SLOT_NO, remaining);
energy_stored_ -= transfer_energy_consumption_;
dirty = true;
}
}
}
if(with_automatic_inventory_pulling_) {
final Direction inp_facing = state.get(FACING).getOpposite();
if(inp && (stacks_.get(FIFO_INPUT_1_SLOT_NO).isEmpty())) {
TileEntity te = world.getTileEntity(pos.offset(inp_facing));
if(te!=null) {
IItemHandler hnd = te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, inp_facing).orElse(null);
if(hnd != null) {
for(int i=0; i< hnd.getSlots(); ++i) {
ItemStack adj_stack = hnd.getStackInSlot(i);
if(!adj_stack.isEmpty()) {
ItemStack my_stack = adj_stack.copy();
if(my_stack.getCount() > getInventoryStackLimit()) my_stack.setCount(getInventoryStackLimit());
adj_stack.shrink(my_stack.getCount());
stacks_.set(FIFO_INPUT_1_SLOT_NO, my_stack);
energy_stored_ -= transfer_energy_consumption_;
dirty = true;
break;
}
}
}
}
}
}
return dirty;
}
// returns TE dirty
private boolean heat_up()
{
if(energy_stored_ < (energy_consumption_)) return false;
if(burntime_left_ >= (HEAT_CAPACITY-HEAT_INCREMENT)) return false;
energy_stored_ -= energy_consumption_;
burntime_left_ += HEAT_INCREMENT;
this.markDirty();
return true;
}
private void sync_blockstate()
{
final BlockState state = world.getBlockState(pos);
if((state.getBlock() instanceof BlockDecorFurnaceElectrical) && (state.get(LIT) != burning())) {
world.setBlockState(pos, state.with(LIT, burning()), 2);
}
}
}
//--------------------------------------------------------------------------------------------------------------------
// container
//--------------------------------------------------------------------------------------------------------------------
public static class BContainer extends Container implements Networking.INetworkSynchronisableContainer
{
private static final int PLAYER_INV_START_SLOTNO = 7;
protected final PlayerEntity player_;
protected final IInventory inventory_;
protected final IWorldPosCallable wpc_;
private final IIntArray fields_;
private final IRecipeType<? extends AbstractCookingRecipe> recipe_type_;
public int field(int index) { return fields_.get(index); }
public PlayerEntity player() { return player_ ; }
public IInventory inventory() { return inventory_ ; }
public World world() { return player_.world; }
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)); }
private BContainer(int cid, PlayerInventory player_inventory, IInventory block_inventory, IWorldPosCallable wpc, IIntArray fields)
{
super(ModContent.CT_SMALL_ELECTRICAL_FURNACE, cid);
player_ = player_inventory.player;
inventory_ = block_inventory;
wpc_ = wpc;
fields_ = fields;
recipe_type_ = BTileEntity.RECIPE_TYPE;
addSlot(new Slot(inventory_, 0, 59, 28)); // smelting input
addSlot(new Slot(inventory_, 1, 16, 52)); // aux
addSlot(new BlockDecorFurnace.BContainer.BSlotResult(player_, inventory_, 2, 101, 28)); // smelting result
addSlot(new BlockDecorFurnace.BContainer.BSlotInpFifo(inventory_, 3, 34, 28)); // input fifo 0
addSlot(new BlockDecorFurnace.BContainer.BSlotInpFifo(inventory_, 4, 16, 28)); // input fifo 1
addSlot(new BlockDecorFurnace.BContainer.BSlotOutFifo(player_, inventory_, 5, 126, 28)); // out fifo 0
addSlot(new BlockDecorFurnace.BContainer.BSlotOutFifo(player_, inventory_, 6, 144, 28)); // out fifo 1
for(int x=0; x<9; ++x) {
addSlot(new Slot(player_inventory, x, 8+x*18, 144)); // player slots: 0..8
}
for(int y=0; y<3; ++y) {
for(int x=0; x<9; ++x) {
addSlot(new Slot(player_inventory, x+y*9+9, 8+x*18, 86+y*18)); // player slots: 9..35
}
}
this.trackIntArray(fields_); // === Add reference holders
}
@Override
public boolean canInteractWith(PlayerEntity player)
{ return inventory_.isUsableByPlayer(player); }
@Override
public ItemStack transferStackInSlot(PlayerEntity player, int index)
{
Slot slot = getSlot(index);
if((slot==null) || (!slot.getHasStack())) return ItemStack.EMPTY;
ItemStack slot_stack = slot.getStack();
ItemStack transferred = slot_stack.copy();
if((index==2) || (index==5) || (index==6)) {
// Output slots
if(!mergeItemStack(slot_stack, PLAYER_INV_START_SLOTNO, PLAYER_INV_START_SLOTNO+36, true)) return ItemStack.EMPTY;
slot.onSlotChange(slot_stack, transferred);
} else if((index==0) || (index==3) || (index==4)) {
// Input slots
if(!mergeItemStack(slot_stack, PLAYER_INV_START_SLOTNO, PLAYER_INV_START_SLOTNO+36, false)) return ItemStack.EMPTY;
} else if(index==1) {
// Bypass slot
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 inventory
if(BTileEntity.canSmelt(world(), slot_stack)) {
if(
(!mergeItemStack(slot_stack, 0, 1, false)) && // smelting input
(!mergeItemStack(slot_stack, 3, 4, false)) && // fifo0
(!mergeItemStack(slot_stack, 4, 5, false)) // fifo1
) return ItemStack.EMPTY;
} else if((index >= PLAYER_INV_START_SLOTNO) && (index < PLAYER_INV_START_SLOTNO+27)) {
// player inventory --> player hotbar
if(!mergeItemStack(slot_stack, PLAYER_INV_START_SLOTNO+27, PLAYER_INV_START_SLOTNO+36, false)) return ItemStack.EMPTY;
} else if((index >= PLAYER_INV_START_SLOTNO+27) && (index < PLAYER_INV_START_SLOTNO+36) && (!mergeItemStack(slot_stack, PLAYER_INV_START_SLOTNO, PLAYER_INV_START_SLOTNO+27, false))) {
// player hotbar --> player inventory
return ItemStack.EMPTY;
}
} else {
// invalid slot
return ItemStack.EMPTY;
}
if(slot_stack.isEmpty()) {
slot.putStack(ItemStack.EMPTY);
} else {
slot.onSlotChanged();
}
if(slot_stack.getCount() == transferred.getCount()) return ItemStack.EMPTY;
slot.onTake(player, slot_stack);
return transferred;
}
// INetworkSynchronisableContainer ---------------------------------------------------------
@OnlyIn(Dist.CLIENT)
public void onGuiAction(CompoundNBT nbt)
{ Networking.PacketContainerSyncClientToServer.sendToServer(windowId, nbt); }
@OnlyIn(Dist.CLIENT)
public void onGuiAction(String key, int value)
{ CompoundNBT nbt=new CompoundNBT(); nbt.putInt(key, value); Networking.PacketContainerSyncClientToServer.sendToServer(windowId, nbt); }
@Override
public void onServerPacketReceived(int windowId, CompoundNBT nbt)
{}
@Override
public void onClientPacketReceived(int windowId, PlayerEntity player, CompoundNBT nbt)
{}
}
//--------------------------------------------------------------------------------------------------------------------
// GUI
//--------------------------------------------------------------------------------------------------------------------
@OnlyIn(Dist.CLIENT)
public static class BGui extends ContainerScreen<BContainer>
{
protected final PlayerEntity player_;
public BGui(BContainer container, PlayerInventory player_inventory, ITextComponent title)
{ super(container, player_inventory, title); this.player_ = player_inventory.player; }
@Override
public void init()
{ super.init(); }
@Override
public void render(int mouseX, int mouseY, float partialTicks)
{
renderBackground();
super.render(mouseX, mouseY, partialTicks);
renderHoveredToolTip(mouseX, mouseY);
}
@Override
protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY)
{
GlStateManager.color4f(1.0F, 1.0F, 1.0F, 1.0F);
minecraft.getTextureManager().bindTexture(new ResourceLocation(ModEngineersDecor.MODID, "textures/gui/small_electrical_furnace_gui.png"));
final int x0=(width-xSize)/2, y0=(height-ySize)/2, w=xSize, h=ySize;
blit(x0, y0, 0, 0, w, h);
if(getContainer().field(6)!=0) {
final int hi = 13;
final int k = heat_px(hi);
blit(x0+61, y0+53+hi-k, 177, hi-k, 13, k);
}
blit(x0+79, y0+30, 176, 15, 1+progress_px(17), 15);
int we = energy_px(32, 8);
if(we>0) blit(x0+88, y0+53, 185, 30, we, 13);
}
private int progress_px(int pixels)
{ final int tc=getContainer().field(2), T=getContainer().field(3); return ((T>0) && (tc>0)) ? (tc * pixels / T) : (0); }
private int heat_px(int pixels)
{
int k = ((getContainer().field(0) * (pixels+1)) / (BlockDecorFurnaceElectrical.BTileEntity.HEAT_CAPACITY));
return (k < pixels) ? k : pixels;
}
private int energy_px(int maxwidth, int quantization)
{
int emax = getContainer().field(5);
int k = ((maxwidth * getContainer().field(1) * 9) / 8) /((emax>0?emax:1)+1);
k = (k >= maxwidth-2) ? maxwidth : k;
if(quantization > 0) k = ((k+(quantization/2))/quantization) * quantization;
return k;
}
}
}

View file

@ -0,0 +1,69 @@
/*
* @file BlockDecorFull.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2019 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)
*
* Full block characteristics class. Explicitly overrides some
* `Block` methods to return faster due to exclusive block properties.
*/
package wile.engineersdecor.blocks;
import wile.engineersdecor.detail.ModAuxiliaries;
import net.minecraft.block.Block;
import net.minecraft.block.material.PushReaction;
import net.minecraft.block.BlockState;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.entity.EntityType;
import net.minecraft.item.ItemStack;
import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.world.IBlockReader;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import javax.annotation.Nullable;
import java.util.List;
public class BlockDecorGlassBlock extends BlockDecor
{
public BlockDecorGlassBlock(long config, Block.Properties properties)
{ super(config, properties); }
@Override
@OnlyIn(Dist.CLIENT)
public void addInformation(ItemStack stack, @Nullable IBlockReader world, List<ITextComponent> tooltip, ITooltipFlag flag)
{ ModAuxiliaries.Tooltip.addInformation(stack, world, tooltip, flag, true); }
@Override
@OnlyIn(Dist.CLIENT)
public BlockRenderLayer getRenderLayer()
{ return BlockRenderLayer.TRANSLUCENT; }
@Override
@OnlyIn(Dist.CLIENT)
@SuppressWarnings("deprecation")
public boolean isSideInvisible(BlockState state, BlockState adjacentBlockState, Direction side)
{ return (adjacentBlockState.getBlock()==this) ? true : super.isSideInvisible(state, adjacentBlockState, side); }
@Override
public boolean propagatesSkylightDown(BlockState state, IBlockReader reader, BlockPos pos)
{ return true; }
@Override
public boolean canSpawnInBlock()
{ return false; }
@Override
@SuppressWarnings("deprecation")
public boolean canEntitySpawn(BlockState state, IBlockReader world, BlockPos pos, EntityType<?> entityType)
{ return false; }
@Override
@SuppressWarnings("deprecation")
public PushReaction getPushReaction(BlockState state)
{ return PushReaction.NORMAL; }
}

View file

@ -0,0 +1,195 @@
/*
* @file BlockDecorHalfSlab.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2019 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)
*
* Half slab ("slab slices") characteristics class. Actually
* it's now a quater slab, but who cares.
*/
package wile.engineersdecor.blocks;
import wile.engineersdecor.detail.ModAuxiliaries;
import wile.engineersdecor.detail.ModConfig;
import net.minecraft.block.*;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.state.IntegerProperty;
import net.minecraft.util.*;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.shapes.VoxelShapes;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.world.World;
import net.minecraft.entity.EntityType;
import net.minecraft.state.StateContainer;
import net.minecraft.util.math.shapes.ISelectionContext;
import net.minecraft.item.BlockItemUseContext;
import net.minecraft.block.BlockState;
import net.minecraft.world.IBlockReader;
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class BlockDecorHalfSlab extends BlockDecor
{
public static final IntegerProperty PARTS = IntegerProperty.create("parts", 0, 14);
protected static final VoxelShape AABBs[] = {
VoxelShapes.create(new AxisAlignedBB(0, 0./16, 0, 1, 2./16, 1)),
VoxelShapes.create(new AxisAlignedBB(0, 0./16, 0, 1, 4./16, 1)),
VoxelShapes.create(new AxisAlignedBB(0, 0./16, 0, 1, 6./16, 1)),
VoxelShapes.create(new AxisAlignedBB(0, 0./16, 0, 1, 8./16, 1)),
VoxelShapes.create(new AxisAlignedBB(0, 0./16, 0, 1, 10./16, 1)),
VoxelShapes.create(new AxisAlignedBB(0, 0./16, 0, 1, 12./16, 1)),
VoxelShapes.create(new AxisAlignedBB(0, 0./16, 0, 1, 14./16, 1)),
VoxelShapes.create(new AxisAlignedBB(0, 0./16, 0, 1, 16./16, 1)),
VoxelShapes.create(new AxisAlignedBB(0, 2./16, 0, 1, 16./16, 1)),
VoxelShapes.create(new AxisAlignedBB(0, 4./16, 0, 1, 16./16, 1)),
VoxelShapes.create(new AxisAlignedBB(0, 6./16, 0, 1, 16./16, 1)),
VoxelShapes.create(new AxisAlignedBB(0, 8./16, 0, 1, 16./16, 1)),
VoxelShapes.create(new AxisAlignedBB(0, 10./16, 0, 1, 16./16, 1)),
VoxelShapes.create(new AxisAlignedBB(0, 12./16, 0, 1, 16./16, 1)),
VoxelShapes.create(new AxisAlignedBB(0, 14./16, 0, 1, 16./16, 1)),
VoxelShapes.create(new AxisAlignedBB(0,0,0,1,1,1)) // <- with 4bit fill
};
protected static final int num_slabs_contained_in_parts_[] = {
1,2,3,4,5,6,7,8,7,6,5,4,3,2,1 ,0x1 // <- with 4bit fill
};
public BlockDecorHalfSlab(long config, Block.Properties builder)
{ super(config, builder); }
protected boolean is_cube(BlockState state)
{ return state.get(PARTS) == 0x07; }
@Override
@OnlyIn(Dist.CLIENT)
public void addInformation(ItemStack stack, @Nullable IBlockReader world, List<ITextComponent> tooltip, ITooltipFlag flag)
{
if(!ModAuxiliaries.Tooltip.addInformation(stack, world, tooltip, flag, true)) return;
// if(!ModConfig.optout.without_direct_slab_pickup) {
ModAuxiliaries.Tooltip.addInformation("engineersdecor.tooltip.slabpickup", "engineersdecor.tooltip.slabpickup", tooltip, flag, true);
// }
}
@Override
@OnlyIn(Dist.CLIENT)
public BlockRenderLayer getRenderLayer()
{ return (((config & CFG_TRANSLUCENT)!=0) ? (BlockRenderLayer.TRANSLUCENT) : (BlockRenderLayer.CUTOUT)); }
@Override
public boolean canSpawnInBlock()
{ return false; }
@Override
@SuppressWarnings("deprecation")
public boolean canEntitySpawn(BlockState state, IBlockReader world, BlockPos pos, EntityType<?> entityType)
{ return false; }
@Override
public VoxelShape getShape(BlockState state, IBlockReader source, BlockPos pos, ISelectionContext selectionContext)
{ return AABBs[state.get(PARTS) & 0xf]; }
@Override
public VoxelShape getCollisionShape(BlockState state, IBlockReader world, BlockPos pos, ISelectionContext selectionContext)
{ return getShape(state, world, pos, selectionContext); }
@Override
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder)
{ builder.add(PARTS); }
@Override
@Nullable
public BlockState getStateForPlacement(BlockItemUseContext context)
{
final Direction facing = context.getFace();
double y = context.getHitVec().getY();
return getDefaultState().with(PARTS, ((facing==Direction.UP) || ((facing!=Direction.DOWN) && (y < 0.6))) ? 0 : 14);
}
@Override
@SuppressWarnings("deprecation")
public BlockState rotate(BlockState state, Rotation rot)
{ return state; }
@Override
@SuppressWarnings("deprecation")
public BlockState mirror(BlockState state, Mirror mirrorIn)
{ return state; }
@Override
public List<ItemStack> dropList(BlockState state, World world, BlockPos pos, boolean explosion)
{ return new ArrayList<ItemStack>(Collections.singletonList(new ItemStack(this.asItem(), num_slabs_contained_in_parts_[state.get(PARTS) & 0xf]))); }
@Override
@SuppressWarnings("deprecation")
public boolean onBlockActivated(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockRayTraceResult rayTraceResult)
{
Direction face = rayTraceResult.getFace();
final ItemStack stack = player.getHeldItem(hand);
if(stack.isEmpty() || (Block.getBlockFromItem(stack.getItem()) != this)) return false;
if((face != Direction.UP) && (face != Direction.DOWN)) return false;
int parts = state.get(PARTS);
if((face != Direction.UP) && (parts > 7)) {
world.setBlockState(pos, state.with(PARTS, parts-1), 3);
} else if((face != Direction.DOWN) && (parts < 7)) {
world.setBlockState(pos, state.with(PARTS, parts+1), 3);
} else {
return (parts != 7);
}
if(world.isRemote) return true;
if(!player.isCreative()) {
stack.shrink(1);
if(player.inventory != null) player.inventory.markDirty();
}
SoundType st = this.getSoundType(state, world, pos, null);
world.playSound(null, pos, st.getPlaceSound(), SoundCategory.BLOCKS, (st.getVolume()+1f)/2.5f, 0.9f*st.getPitch());
return true;
}
@Override
@SuppressWarnings("deprecation")
public void onBlockClicked(BlockState state, World world, BlockPos pos, PlayerEntity player)
{
if((world.isRemote) ) return; // || (ModConfig.optout.without_direct_slab_pickup)
final ItemStack stack = player.getHeldItemMainhand();
if(stack.isEmpty() || (Block.getBlockFromItem(stack.getItem()) != this)) return;
if(stack.getCount() >= stack.getMaxStackSize()) return;
Vec3d lv = player.getLookVec();
Direction facing = Direction.getFacingFromVector((float)lv.x, (float)lv.y, (float)lv.z);
if((facing != Direction.UP) && (facing != Direction.DOWN)) return;
if(state.getBlock() != this) return;
int parts = state.get(PARTS);
if((facing == Direction.DOWN) && (parts <= 7)) {
if(parts > 0) {
world.setBlockState(pos, state.with(PARTS, parts-1), 3);
} else {
world.removeBlock(pos, false);
}
} else if((facing == Direction.UP) && (parts >= 7)) {
if(parts < 14) {
world.setBlockState(pos, state.with(PARTS, parts + 1), 3);
} else {
world.removeBlock(pos, false);
}
} else {
return;
}
if(!player.isCreative()) {
stack.grow(1);
if(player.inventory != null) player.inventory.markDirty(); // @todo: check if inventory can actually be null
}
SoundType st = this.getSoundType(state, world, pos, null);
world.playSound(player, pos, st.getPlaceSound(), SoundCategory.BLOCKS, (st.getVolume()+1f)/2.5f, 0.9f*st.getPitch());
}
}

View file

@ -0,0 +1,134 @@
/*
* @file BlockDecorHorizontalSupport.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2019 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)
*
* Horizontal ceiling support. Symmetric x axis, fixed in
* xz plane, therefore boolean placement state.
*/
package wile.engineersdecor.blocks;
import wile.engineersdecor.ModContent;
import wile.engineersdecor.detail.ModAuxiliaries;
import net.minecraft.entity.EntityType;
import net.minecraft.util.math.shapes.ISelectionContext;
import net.minecraft.block.Block;
import net.minecraft.item.BlockItemUseContext;
import net.minecraft.state.BooleanProperty;
import net.minecraft.state.IntegerProperty;
import net.minecraft.state.StateContainer;
import net.minecraft.util.*;
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.util.math.shapes.VoxelShapes;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.IWorld;
import net.minecraft.world.World;
import net.minecraft.block.BlockState;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
public class BlockDecorHorizontalSupport extends BlockDecor
{
public static final BooleanProperty EASTWEST = BooleanProperty.create("eastwest");
public static final BooleanProperty LEFTBEAM = BooleanProperty.create("leftbeam");
public static final BooleanProperty RIGHTBEAM = BooleanProperty.create("rightbeam");
public static final IntegerProperty DOWNCONNECT = IntegerProperty.create("downconnect", 0, 2);
protected final ArrayList<VoxelShape> AABBs;
public BlockDecorHorizontalSupport(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
{
super(config|CFG_HORIZIONTAL, builder);
AABBs = new ArrayList<VoxelShape>(Arrays.asList(
// Effective bounding box
VoxelShapes.create(ModAuxiliaries.getRotatedAABB(unrotatedAABB.grow(2.0/16, 0, 0), Direction.NORTH, true)),
VoxelShapes.create(ModAuxiliaries.getRotatedAABB(unrotatedAABB.grow(2.0/16, 0, 0), Direction.WEST, true)),
// Displayed bounding box
VoxelShapes.create(ModAuxiliaries.getRotatedAABB(unrotatedAABB, Direction.NORTH, true)),
VoxelShapes.create(ModAuxiliaries.getRotatedAABB(unrotatedAABB, Direction.WEST, true))
));
}
@Override
@OnlyIn(Dist.CLIENT)
public BlockRenderLayer getRenderLayer()
{ return BlockRenderLayer.CUTOUT; }
@Override
public boolean canSpawnInBlock()
{ return false; }
@Override
@SuppressWarnings("deprecation")
public boolean canEntitySpawn(BlockState state, IBlockReader world, BlockPos pos, EntityType<?> entityType)
{ return false; }
@Override
public VoxelShape getShape(BlockState state, IBlockReader source, BlockPos pos, ISelectionContext selectionContext)
{ return AABBs.get(state.get(EASTWEST) ? 0x1 : 0x0); }
@Override
public VoxelShape getCollisionShape(BlockState state, IBlockReader world, BlockPos pos, ISelectionContext selectionContext)
{ return getShape(state, world, pos, selectionContext); }
@Override
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder)
{ builder.add(EASTWEST, RIGHTBEAM, LEFTBEAM, DOWNCONNECT); }
@Override
@Nullable
public BlockState getStateForPlacement(BlockItemUseContext context)
{ return temp_block_update_until_better(getDefaultState().with(EASTWEST, context.getPlacementHorizontalFacing().getAxis()==Direction.Axis.X), context.getWorld(), context.getPos()); }
private BlockState temp_block_update_until_better(BlockState state, IWorld world, BlockPos pos)
{
// @todo: split EW / NS in case blocks
boolean ew = state.get(EASTWEST);
final BlockState rstate = world.getBlockState((!ew) ? (pos.east()) : (pos.south()) );
final BlockState lstate = world.getBlockState((!ew) ? (pos.west()) : (pos.north()) );
final BlockState dstate = world.getBlockState(pos.down());
int down_connector = 0;
if((dstate.getBlock() instanceof BlockDecorStraightPole)) {
final Direction dfacing = dstate.get(BlockDecorStraightPole.FACING);
final BlockDecorStraightPole pole = (BlockDecorStraightPole)dstate.getBlock();
if((dfacing.getAxis() == Direction.Axis.Y)) {
if((pole== ModContent.THICK_STEEL_POLE) || ((pole==ModContent.THICK_STEEL_POLE_HEAD) && (dfacing==Direction.UP))) {
down_connector = 2;
} else if((pole==ModContent.THIN_STEEL_POLE) || ((pole==ModContent.THIN_STEEL_POLE_HEAD) && (dfacing==Direction.UP))) {
down_connector = 1;
}
}
}
return state.with(RIGHTBEAM, (rstate.getBlock()==this) && (rstate.get(EASTWEST) != ew))
.with(LEFTBEAM , (lstate.getBlock()==this) && (lstate.get(EASTWEST) != ew))
.with(DOWNCONNECT , down_connector);
}
@Override
@SuppressWarnings("deprecation")
public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState facingState, IWorld world, BlockPos pos, BlockPos facingPos)
{ return temp_block_update_until_better(state, world, pos); }
@Deprecated
@SuppressWarnings("deprecation")
public void neighborChanged(BlockState state, World world, BlockPos pos, Block block, BlockPos fromPos)
{ world.setBlockState(pos, temp_block_update_until_better(state, world, pos)); }
@Override
@SuppressWarnings("deprecation")
public BlockState rotate(BlockState state, Rotation rot)
{ return (rot==Rotation.CLOCKWISE_180) ? state : state.with(EASTWEST, !state.get(EASTWEST)); }
@Override
@SuppressWarnings("deprecation")
public BlockState mirror(BlockState state, Mirror mirrorIn)
{ return state; }
}

View file

@ -0,0 +1,105 @@
/*
* @file BlockDecorLadder.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2019 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)
*
* Ladder block. The implementation is based on the vanilla
* net.minecraft.block.BlockLadder. Minor changes to enable
* later configuration (for block list based construction
* time configuration), does not drop when the block behind
* is broken, etc.
*/
package wile.engineersdecor.blocks;
import wile.engineersdecor.detail.ModAuxiliaries;
import net.minecraft.fluid.IFluidState;
import net.minecraft.world.Explosion;
import net.minecraft.world.World;
import net.minecraft.entity.EntityType;
import net.minecraft.util.math.Vec3d;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.block.BlockState;
import net.minecraft.block.*;
import net.minecraft.block.material.PushReaction;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.util.math.shapes.VoxelShapes;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.world.IBlockReader;
import net.minecraft.util.*;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import javax.annotation.Nullable;
import java.util.List;
public class BlockDecorLadder extends LadderBlock implements IDecorBlock
{
protected static final AxisAlignedBB EDLADDER_UNROTATED_AABB = ModAuxiliaries.getPixeledAABB(3, 0, 0, 13, 16, 3);
protected static final VoxelShape EDLADDER_SOUTH_AABB = VoxelShapes.create(ModAuxiliaries.getRotatedAABB(EDLADDER_UNROTATED_AABB, Direction.SOUTH, false));
protected static final VoxelShape EDLADDER_EAST_AABB = VoxelShapes.create(ModAuxiliaries.getRotatedAABB(EDLADDER_UNROTATED_AABB, Direction.EAST, false));
protected static final VoxelShape EDLADDER_WEST_AABB = VoxelShapes.create(ModAuxiliaries.getRotatedAABB(EDLADDER_UNROTATED_AABB, Direction.WEST, false));
protected static final VoxelShape EDLADDER_NORTH_AABB = VoxelShapes.create(ModAuxiliaries.getRotatedAABB(EDLADDER_UNROTATED_AABB, Direction.NORTH, false));
private static boolean without_speed_boost_ = false;
public static void on_config(boolean without_speed_boost)
{ without_speed_boost_ = without_speed_boost; }
public BlockDecorLadder(long config, Block.Properties builder)
{ super(builder); }
@Override
@OnlyIn(Dist.CLIENT)
public void addInformation(ItemStack stack, @Nullable IBlockReader world, List<ITextComponent> tooltip, ITooltipFlag flag)
{ ModAuxiliaries.Tooltip.addInformation(stack, world, tooltip, flag, true); }
public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos)
{
switch ((Direction)state.get(FACING)) {
case NORTH: return EDLADDER_NORTH_AABB;
case SOUTH: return EDLADDER_SOUTH_AABB;
case WEST: return EDLADDER_WEST_AABB;
default: return EDLADDER_EAST_AABB;
}
}
@Override
public boolean canSpawnInBlock()
{ return false; }
@Override
@SuppressWarnings("deprecation")
public boolean canEntitySpawn(BlockState state, IBlockReader world, BlockPos pos, EntityType<?> entityType)
{ return false; }
@Override
@SuppressWarnings("deprecation")
public PushReaction getPushReaction(BlockState state)
{ return PushReaction.NORMAL; }
// Player update event, forwarded from the main mod instance.
public static void onPlayerUpdateEvent(final PlayerEntity player)
{
if((without_speed_boost_) || (player.onGround) || (!player.isOnLadder()) || (player.isSneaking()) || (player.isSpectator())) return;
double lvy = player.getLookVec().y;
if(Math.abs(lvy) < 0.94) return;
final BlockPos pos = new BlockPos(player.posX, player.posY, player.posZ);
final BlockState state = player.world.getBlockState(pos);
if(!(state.getBlock() instanceof BlockDecorLadder)) return;
player.fallDistance = 0;
player.setMotionMultiplier(state, new Vec3d(0.2, (lvy>0)?(3):(6), 0.2));
}
@Override
public boolean removedByPlayer(BlockState state, World world, BlockPos pos, PlayerEntity player, boolean willHarvest, IFluidState fluid)
{ return BlockDecor.dropBlock(state, world, pos, false); }
@Override
public void onExplosionDestroy(World world, BlockPos pos, Explosion explosion)
{ BlockDecor.dropBlock(world.getBlockState(pos), world, pos, true); }
}

View file

@ -0,0 +1,656 @@
/*
* @file BlockDecorMineralSmelter.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2019 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)
*
* Small highly insulated stone liquification furnace
* (magmatic phase).
*/
package wile.engineersdecor.blocks;
import wile.engineersdecor.ModContent;
import wile.engineersdecor.ModEngineersDecor;
import wile.engineersdecor.detail.ModConfig;
import net.minecraft.entity.LivingEntity;
import net.minecraft.inventory.ISidedInventory;
import net.minecraft.inventory.ItemStackHelper;
import net.minecraft.item.Item;
import net.minecraft.item.Items;
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.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.StateContainer;
import net.minecraft.item.BlockItemUseContext;
import net.minecraft.block.BlockState;
import net.minecraft.world.IBlockReader;
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.capability.IFluidHandler;
import net.minecraftforge.fluids.capability.IFluidTankProperties;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.*;
public class BlockDecorMineralSmelter extends BlockDecorDirectedHorizontal
{
public static final int PHASE_MAX = 3;
public static final IntegerProperty PHASE = IntegerProperty.create("phase", 0, PHASE_MAX);
public BlockDecorMineralSmelter(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
{ super(config, builder, unrotatedAABB); }
@Override
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder)
{ super.fillStateContainer(builder); builder.add(PHASE); }
@Override
@Nullable
public BlockState getStateForPlacement(BlockItemUseContext context)
{ return super.getStateForPlacement(context).with(PHASE, 0); }
@Override
@SuppressWarnings("deprecation")
public boolean hasComparatorInputOverride(BlockState state)
{ return true; }
@Override
@SuppressWarnings("deprecation")
public int getComparatorInputOverride(BlockState state, World world, BlockPos pos)
{ return MathHelper.clamp((state.get(PHASE)*5), 0, 15); }
@Override
public boolean hasTileEntity(BlockState state)
{ return true; }
@Override
@Nullable
public TileEntity createTileEntity(BlockState state, IBlockReader world)
{ return new BlockDecorMineralSmelter.BTileEntity(); }
@Override
public void onBlockPlacedBy(World world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack)
{}
@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 BTileEntity te = getTe(world, pos);
if(te == null) return stacks;
te.reset_process();
stacks.add(new ItemStack(this, 1));
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;
if(player.isSneaking()) return false;
BTileEntity te = getTe(world, pos);
if(te==null) return true;
final ItemStack stack = player.getHeldItem(hand);
boolean dirty = false;
if(te.accepts_lava_container(stack)) {
if(stack.isItemEqualIgnoreDurability(BTileEntity.BUCKET_STACK)) { // check how this works with item capabilities or so
if(te.fluid_level() >= BTileEntity.MAX_BUCKET_EXTRACT_FLUID_LEVEL) {
if(stack.getCount() > 1) {
int target_stack_index = -1;
for(int i=0; i<player.inventory.getSizeInventory(); ++i) {
if(player.inventory.getStackInSlot(i).isEmpty()) {
target_stack_index = i;
break;
}
}
if(target_stack_index >= 0) {
te.reset_process();
stack.shrink(1);
player.setHeldItem(hand, stack);
player.inventory.setInventorySlotContents(target_stack_index, BTileEntity.LAVA_BUCKET_STACK.copy());
world.playSound(null, pos, SoundEvents.ITEM_BUCKET_FILL_LAVA, SoundCategory.BLOCKS, 1f, 1f);
dirty = true;
}
} else {
te.reset_process();
player.setHeldItem(hand, BTileEntity.LAVA_BUCKET_STACK.copy());
world.playSound(null, pos, SoundEvents.ITEM_BUCKET_FILL_LAVA, SoundCategory.BLOCKS, 1f, 1f);
dirty = true;
}
}
}
} else if(stack.getItem() == Items.AIR) {
final ItemStack istack = te.getStackInSlot(1).copy();
if(te.phase() > BTileEntity.PHASE_WARMUP) player.setFire(1);
if(!istack.isEmpty()) {
istack.setCount(1);
player.setHeldItem(hand, istack);
te.reset_process();
dirty = true;
}
} else if(te.insert(stack.copy(),false)) {
stack.shrink(1);
dirty = true;
}
if(dirty) player.inventory.markDirty();
return true;
}
@Override
@OnlyIn(Dist.CLIENT)
public void animateTick(BlockState state, World world, BlockPos pos, Random rnd)
{
if(state.getBlock()!=this) return;
IParticleData particle = ParticleTypes.SMOKE;
switch(state.get(PHASE)) {
case BTileEntity.PHASE_WARMUP:
return;
case BTileEntity.PHASE_HOT:
if(rnd.nextInt(10) > 4) return;
break;
case BTileEntity.PHASE_MAGMABLOCK:
if(rnd.nextInt(10) > 7) return;
particle = ParticleTypes.LARGE_SMOKE;
break;
case BTileEntity.PHASE_LAVA:
if(rnd.nextInt(10) > 2) return;
particle = ParticleTypes.LAVA;
break;
default:
return;
}
final double x=0.5+pos.getX(), y=0.5+pos.getY(), z=0.5+pos.getZ();
final double xr=rnd.nextDouble()*0.4-0.2, yr=rnd.nextDouble()*0.5, zr=rnd.nextDouble()*0.4-0.2;
world.addParticle(particle, x+xr, y+yr, z+zr, 0.0, 0.0, 0.0);
}
@Nullable
private BTileEntity getTe(World world, BlockPos pos)
{ final TileEntity te=world.getTileEntity(pos); return (!(te instanceof BTileEntity)) ? (null) : ((BTileEntity)te); }
//--------------------------------------------------------------------------------------------------------------------
// Tile entity
//--------------------------------------------------------------------------------------------------------------------
public static class BTileEntity extends TileEntity implements INameable, ITickableTileEntity, ISidedInventory, IEnergyStorage, ICapabilityProvider // IFluidTankProperties,
{
public static final int TICK_INTERVAL = 20;
public static final int MAX_FLUID_LEVEL = 1000;
public static final int MAX_BUCKET_EXTRACT_FLUID_LEVEL = 900;
public static final int MAX_ENERGY_BUFFER = 32000;
public static final int MAX_ENERGY_TRANSFER = 8192;
public static final int DEFAULT_ENERGY_CONSUMPTION = 92;
public static final int DEFAULT_HEATUP_RATE = 2; // -> 50s for one smelting process
public static final int PHASE_WARMUP = 0;
public static final int PHASE_HOT = 1;
public static final int PHASE_MAGMABLOCK = 2;
public static final int PHASE_LAVA = 3;
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 int energy_consumption = DEFAULT_ENERGY_CONSUMPTION;
private static int heatup_rate = DEFAULT_HEATUP_RATE;
private static int cooldown_rate = 1;
private static Set<Item> accepted_minerals = new HashSet<Item>();
private static Set<Item> accepted_lava_contrainers = new HashSet<Item>();
private int tick_timer_;
private int energy_stored_;
private int progress_;
private int fluid_level_;
private boolean force_block_update_;
private NonNullList<ItemStack> stacks_ = NonNullList.<ItemStack>withSize(2, ItemStack.EMPTY);
static {
// Lava containers
accepted_lava_contrainers.add(Items.BUCKET);
}
public static void on_config(int energy_consumption, int heatup_per_second)
{
energy_consumption = MathHelper.clamp(energy_consumption, 32, 4096);
heatup_rate = MathHelper.clamp(heatup_per_second, 1, 5);
cooldown_rate = MathHelper.clamp(heatup_per_second/2, 1, 5);
ModEngineersDecor.logger().info("Config mineal smelter energy consumption:" + energy_consumption + "rf/t, heat-up rate: " + heatup_rate + "%/s.");
}
public BTileEntity()
{ this(ModContent.TET_MINERAL_SMELTER); }
public BTileEntity(TileEntityType<?> te_type)
{ super(te_type); }
public int progress()
{ return progress_; }
public int phase()
{
if(progress_ >= 100) return PHASE_LAVA;
if(progress_ >= 90) return PHASE_MAGMABLOCK;
if(progress_ >= 5) return PHASE_HOT;
return PHASE_WARMUP;
}
public int fluid_level()
{ return fluid_level_; }
public int fluid_level_drain(int amount)
{ amount = MathHelper.clamp(amount, 0, fluid_level_); fluid_level_ -= amount; return amount; }
public int comparator_signal()
{ return phase() * 5; } // -> 0..15
private boolean accepts_lava_container(ItemStack stack)
{ return accepted_lava_contrainers.contains(stack.getItem()); }
private boolean accepts_input(ItemStack stack)
{
if(!stacks_.get(0).isEmpty()) return false;
if(fluid_level() > MAX_BUCKET_EXTRACT_FLUID_LEVEL) {
return accepts_lava_container(stack);
} else {
if(stack.getItem().getTags().contains(new ResourceLocation(ModEngineersDecor.MODID, "accepted_mineral_smelter_input"))) return true;
return accepted_minerals.contains(stack.getItem());
}
}
public boolean insert(final ItemStack stack, boolean simulate)
{
if(stack.isEmpty() || (!accepts_input(stack))) return false;
if(!simulate) {
ItemStack st = stack.copy();
st.setCount(st.getMaxStackSize());
stacks_.set(0, st);
if(!accepts_lava_container(stack)) progress_ = 0;
force_block_update_ = true;
}
return true;
}
public ItemStack extract(boolean simulate)
{
ItemStack stack = stacks_.get(1).copy();
if(stack.isEmpty()) return ItemStack.EMPTY;
if(!simulate) reset_process();
return stack;
}
protected void reset_process()
{
stacks_ = NonNullList.<ItemStack>withSize(2, ItemStack.EMPTY);
force_block_update_ = true;
fluid_level_ = 0;
tick_timer_ = 0;
progress_ = 0;
}
public void readnbt(CompoundNBT nbt)
{
energy_stored_ = nbt.getInt("energy");
progress_ = nbt.getInt("progress");
fluid_level_ = nbt.getInt("fluidlevel");
ItemStackHelper.loadAllItems(nbt, stacks_);
if(stacks_.size() != 2) reset_process();
}
protected void writenbt(CompoundNBT nbt)
{
nbt.putInt("energy", MathHelper.clamp(energy_stored_,0 , MAX_ENERGY_BUFFER));
nbt.putInt("progress", MathHelper.clamp(progress_,0 , 100));
nbt.putInt("fluidlevel", MathHelper.clamp(fluid_level_,0 , MAX_FLUID_LEVEL));
ItemStackHelper.saveAllItems(nbt, stacks_);
}
// TileEntity ------------------------------------------------------------------------------
@Override
public void read(CompoundNBT nbt)
{ super.read(nbt); readnbt(nbt); }
@Override
public CompoundNBT write(CompoundNBT nbt)
{ super.write(nbt); writenbt(nbt); return nbt; }
// INamedContainerProvider / INameable ------------------------------------------------------
@Override
public ITextComponent getName()
{ final Block block=getBlockState().getBlock(); return new StringTextComponent((block!=null) ? block.getTranslationKey() : "Lab furnace"); }
@Override
public boolean hasCustomName()
{ return false; }
@Override
public ITextComponent getCustomName()
{ return getName(); }
// IInventory ------------------------------------------------------------------------------
@Override
public int getSizeInventory()
{ return stacks_.size(); }
@Override
public boolean isEmpty()
{ for(ItemStack stack: stacks_) { if(!stack.isEmpty()) return false; } return true; }
@Override
public ItemStack getStackInSlot(int index)
{ return ((index >= 0) && (index < getSizeInventory())) ? stacks_.get(index) : ItemStack.EMPTY; }
@Override
public ItemStack decrStackSize(int index, int count)
{ return ItemStackHelper.getAndSplit(stacks_, index, count); }
@Override
public ItemStack removeStackFromSlot(int index)
{ return ItemStackHelper.getAndRemove(stacks_, index); }
@Override
public void setInventorySlotContents(int index, ItemStack stack)
{ if(stack.getCount()>getInventoryStackLimit()){stack.setCount(getInventoryStackLimit());} stacks_.set(index, stack); markDirty(); }
@Override
public int getInventoryStackLimit()
{ return 1; }
@Override
public void markDirty()
{ super.markDirty(); }
@Override
public boolean isUsableByPlayer(PlayerEntity player)
{ return ((world.getTileEntity(pos) == this) && (player.getDistanceSq(pos.getX()+0.5d, pos.getY()+0.5d, pos.getZ()+0.5d) <= 64.0d)); }
@Override
public void openInventory(PlayerEntity player)
{}
@Override
public void closeInventory(PlayerEntity player)
{ markDirty(); }
@Override
public boolean isItemValidForSlot(int index, ItemStack stack)
{ return ((index==0) && accepts_input(stack)) || (index==1); }
@Override
public void clear()
{ reset_process(); }
// ISidedInventory ----------------------------------------------------------------------------
private static final int[] SIDED_INV_SLOTS = new int[] {0,1};
@Override
public int[] getSlotsForFace(Direction side)
{ return SIDED_INV_SLOTS; }
@Override
public boolean canInsertItem(int index, ItemStack stack, Direction direction)
{ return (index==0) && isItemValidForSlot(index, stack); }
@Override
public boolean canExtractItem(int index, ItemStack stack, Direction direction)
{ return (index==1) && (!stacks_.get(1).isEmpty()); }
// IItemHandler --------------------------------------------------------------------------------
private LazyOptional<IItemHandler> item_handler_ = LazyOptional.of(() -> (IItemHandler)new BItemHandler(this));
protected static class BItemHandler implements IItemHandler
{
private BTileEntity te;
BItemHandler(BTileEntity te)
{ this.te = te; }
@Override
public int getSlots()
{ return 2; }
@Override
public int getSlotLimit(int index)
{ return te.getInventoryStackLimit(); }
@Override
public boolean isItemValid(int slot, @Nonnull ItemStack stack)
{ return te.isItemValidForSlot(slot, stack); }
@Override
@Nonnull
public ItemStack insertItem(int index, @Nonnull ItemStack stack, boolean simulate)
{
ItemStack rstack = stack.copy();
if((index!=0) || (!te.insert(stack.copy(), simulate))) return rstack;
rstack.shrink(1);
return rstack;
}
@Override
@Nonnull
public ItemStack extractItem(int index, int amount, boolean simulate)
{ return (index!=1) ? ItemStack.EMPTY : te.extract(simulate); }
@Override
@Nonnull
public ItemStack getStackInSlot(int index)
{ return te.getStackInSlot(index); }
}
// IFluidHandler --------------------------------------------------------------------------------
private LazyOptional<IFluidHandler> fluid_handler_ = LazyOptional.of(() -> (IFluidHandler)new BFluidHandler(this));
// @todo: REPLACE lava=null with whatever will work
private static class BFluidHandler implements IFluidHandler, IFluidTankProperties
{
private final FluidStack lava;
private final BTileEntity te;
private final IFluidTankProperties[] props_ = {this};
BFluidHandler(BTileEntity te) {
this.te = te;
//lava = new FluidStack(ForgeRegistries.FLUIDS.getValue(new ResourceLocation("minecraft:lava")), 1);
// lava = new FluidStack(Blocks.LAVA.getFluidState(Blocks.LAVA.getDefaultState()).getFluid(), 1);
// lava = new FluidStack(Fluids.EMPTY, 1);
//new net.minecraftforge.fluids.FluidStack(net.minecraft.fluid.Fluids.LAVA, 1);
lava=null;
}
@Override @Nullable public FluidStack getContents() { return new FluidStack(lava, te.fluid_level()); }
@Override public IFluidTankProperties[] getTankProperties() { return props_; }
@Override public int fill(FluidStack resource, boolean doFill) { return 0; }
@Override public int getCapacity() { return 1000; }
@Override public boolean canFill() { return false; }
@Override public boolean canDrain() { return true; }
@Override public boolean canFillFluidType(FluidStack fluidStack) { return false; }
@Override public boolean canDrainFluidType(FluidStack fluidStack) { return fluidStack.isFluidEqual(lava); }
@Override @Nullable public FluidStack drain(FluidStack resource, boolean doDrain)
{
if((te.fluid_level() <= 0) || (!resource.isFluidEqual(lava))) return null;
FluidStack fs = getContents();
if(doDrain) te.fluid_level_drain(fs.amount);
return fs;
}
@Override @Nullable public FluidStack drain(int maxDrain, boolean doDrain)
{
if(te.fluid_level() <= 0) return null;
maxDrain = (doDrain) ? (te.fluid_level_drain(maxDrain)) : (Math.min(maxDrain, te.fluid_level()));
return new FluidStack(lava, maxDrain);
}
}
// IEnergyStorage ----------------------------------------------------------------------------
protected LazyOptional<IEnergyStorage> energy_handler_ = LazyOptional.of(() -> (IEnergyStorage)this);
@Override
public boolean canExtract()
{ return false; }
@Override
public boolean canReceive()
{ return true; }
@Override
public int getMaxEnergyStored()
{ return MAX_ENERGY_BUFFER; }
@Override
public int getEnergyStored()
{ return energy_stored_; }
@Override
public int extractEnergy(int maxExtract, boolean simulate)
{ return 0; }
@Override
public int receiveEnergy(int maxReceive, boolean simulate)
{
if(energy_stored_ >= MAX_ENERGY_BUFFER) return 0;
int n = Math.min(maxReceive, (MAX_ENERGY_BUFFER - energy_stored_));
if(n > MAX_ENERGY_TRANSFER) n = MAX_ENERGY_TRANSFER;
if(!simulate) {energy_stored_ += n; markDirty(); }
return n;
}
// Capability export ----------------------------------------------------------------------------
// @todo: INCLUDE FLUID HANDLER WHEN FORGE FluidStack/Fluid ISSUE fixed
@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();
}
}
return super.getCapability(capability, facing);
}
// ITickable ------------------------------------------------------------------------------------
@Override
public void tick()
{
if(world.isRemote) return;
if(--tick_timer_ > 0) return;
tick_timer_ = TICK_INTERVAL;
boolean dirty = false;
final int last_phase = phase();
final ItemStack istack = stacks_.get(0);
if(istack.isEmpty() && (fluid_level()==0)) {
progress_ = 0;
} else if((energy_stored_ <= 0) || (world.isBlockPowered(pos))) {
progress_ = MathHelper.clamp(progress_-cooldown_rate, 0,100);
} else if(progress_ >= 100) {
progress_ = 100;
energy_stored_ = MathHelper.clamp(energy_stored_-((energy_consumption*TICK_INTERVAL)/20), 0, MAX_ENERGY_BUFFER);
} else {
energy_stored_ = MathHelper.clamp(energy_stored_-(energy_consumption*TICK_INTERVAL), 0, MAX_ENERGY_BUFFER);
progress_ = MathHelper.clamp(progress_+heatup_rate, 0, 100);
}
int new_phase = phase();
boolean is_lava_container = accepts_lava_container(istack);
if(is_lava_container || (new_phase != last_phase)) {
if(is_lava_container) {
// That stays in the slot until its extracted or somone takes it out.
if(istack.isItemEqual(BUCKET_STACK)) {
if(!stacks_.get(1).isItemEqual(LAVA_BUCKET_STACK)) {
if(fluid_level() >= MAX_BUCKET_EXTRACT_FLUID_LEVEL) {
stacks_.set(1, LAVA_BUCKET_STACK);
world.playSound(null, pos, SoundEvents.ITEM_BUCKET_FILL_LAVA, SoundCategory.BLOCKS, 0.2f, 1.3f);
} else {
stacks_.set(1, istack.copy());
}
dirty = true;
}
} else {
stacks_.set(1, istack.copy());
// Out stack -> Somehow the filled container or container with fluid+fluid_level().
}
} else if(new_phase > last_phase) {
switch(new_phase) {
case PHASE_LAVA:
fluid_level_ = MAX_FLUID_LEVEL;
stacks_.set(1, ItemStack.EMPTY);
stacks_.set(0, ItemStack.EMPTY);
world.playSound(null, pos, SoundEvents.BLOCK_LAVA_AMBIENT, SoundCategory.BLOCKS, 0.2f, 1.0f);
dirty = true;
break;
case PHASE_MAGMABLOCK:
stacks_.set(1, MAGMA_STACK.copy());
world.playSound(null, pos, SoundEvents.BLOCK_FIRE_AMBIENT, SoundCategory.BLOCKS, 0.2f, 0.8f);
dirty = true;
break;
case PHASE_HOT:
world.playSound(null, pos, SoundEvents.BLOCK_FIRE_AMBIENT, SoundCategory.BLOCKS, 0.2f, 0.8f);
break;
}
} else {
switch(new_phase) {
case PHASE_MAGMABLOCK:
stacks_.set(0, (fluid_level_ >= MAX_BUCKET_EXTRACT_FLUID_LEVEL) ? (MAGMA_STACK.copy()) : (ItemStack.EMPTY));
stacks_.set(1, stacks_.get(0).copy());
fluid_level_ = 0;
world.playSound(null, pos, SoundEvents.BLOCK_LAVA_EXTINGUISH, SoundCategory.BLOCKS, 0.5f, 1.1f);
dirty = true;
break;
case PHASE_HOT:
if(istack.isItemEqual(MAGMA_STACK)) {
stacks_.set(1, new ItemStack(Blocks.OBSIDIAN));
} else {
stacks_.set(1, new ItemStack(Blocks.COBBLESTONE));
}
world.playSound(null, pos, SoundEvents.BLOCK_LAVA_EXTINGUISH, SoundCategory.BLOCKS, 0.3f, 0.9f);
dirty = true;
break;
case PHASE_WARMUP:
world.playSound(null, pos, SoundEvents.BLOCK_LAVA_EXTINGUISH, SoundCategory.BLOCKS, 0.3f, 0.7f);
break;
}
}
}
BlockState state = world.getBlockState(pos);
if((state.getBlock() instanceof BlockDecorMineralSmelter) && (force_block_update_ || (state.get(PHASE) != new_phase))) {
state = state.with(PHASE, new_phase);
world.setBlockState(pos, state,3|16);
world.notifyNeighborsOfStateChange(getPos(), state.getBlock());
force_block_update_ = false;
}
if(dirty) markDirty();
}
}
}

View file

@ -0,0 +1,274 @@
/*
* @file BlockDecorPassiveFluidAccumulator.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2019 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)
*
* A device that collects fluids from adjacent tank outputs
* when a pump drains on the (only) output side. Shall support
* high flow rates, and a vavuum suction delay. Shall not drain
* high amounts of fluid from the adjacent tanks when no fluid
* is requested at the output port. Shall drain balanced from
* the adjacent input sides.
*/
package wile.engineersdecor.blocks;
import wile.engineersdecor.ModContent;
import wile.engineersdecor.detail.ModAuxiliaries;
import net.minecraft.tileentity.ITickableTileEntity;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.Hand;
import net.minecraft.world.IBlockReader;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World;
import net.minecraft.util.Direction;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.common.capabilities.ICapabilityProvider;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.fluids.capability.IFluidTankProperties;
import net.minecraftforge.fluids.FluidStack;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
public class BlockDecorPassiveFluidAccumulator extends BlockDecorDirected
{
public BlockDecorPassiveFluidAccumulator(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
{ super(config, builder, unrotatedAABB); }
@Override
public boolean hasTileEntity(BlockState state)
{ return true; }
@Override
@Nullable
public TileEntity createTileEntity(BlockState state, IBlockReader world)
{ return new BlockDecorPassiveFluidAccumulator.BTileEntity(); }
@Override
@SuppressWarnings("deprecation")
public boolean onBlockActivated(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockRayTraceResult rayTraceResult)
{
if(world.isRemote) return true;
TileEntity te = world.getTileEntity(pos);
if(!(te instanceof BTileEntity)) return true;
((BTileEntity)te).send_device_stats(player);
return true;
}
@Override
@SuppressWarnings("deprecation")
public void neighborChanged(BlockState state, World world, BlockPos pos, Block block, BlockPos fromPos, boolean unused)
{
// @todo double check if this is actually needed
TileEntity te = world.getTileEntity(pos);
if(te instanceof BlockDecorPipeValve.BTileEntity) ((BTileEntity)te).block_changed();
}
//--------------------------------------------------------------------------------------------------------------------
// Tile entity
//--------------------------------------------------------------------------------------------------------------------
public static class BTileEntity extends TileEntity // implements ITickableTileEntity, IFluidHandler, IFluidTankProperties, ICapabilityProvider
{
protected static int tick_idle_interval = 20; // ca 1000ms, simulates suction delay and saves CPU when not drained.
protected static int max_flowrate = 1000;
//private final IFluidTankProperties[] fluid_props_ = {this};
private Direction block_facing_ = Direction.NORTH;
private FluidStack tank_ = null;
private int last_drain_request_amount_ = 0;
private int vacuum_ = 0;
private int tick_timer_ = 0;
private int round_robin_ = 0;
private boolean initialized_ = false;
private int total_volume_filled_ = 0;
private int total_volume_drained_ = 0;
public void send_device_stats(PlayerEntity player)
{
int t_vol = (tank_==null) ? 0 : (tank_.amount);
ModAuxiliaries.playerChatMessage(player,"" + t_vol + "mB");
}
public void block_changed()
{ initialized_ = false; tick_timer_ = MathHelper.clamp(tick_timer_ , 0, tick_idle_interval); }
// // Output flow handler ---------------------------------------------------------------------
//
// private static class InputFillHandler implements IFluidHandler, IFluidTankProperties
// {
// private final BTileEntity parent_;
// private final IFluidTankProperties[] props_ = {this};
// InputFillHandler(BTileEntity parent) { parent_ = parent; }
// @Override public int fill(FluidStack resource, boolean doFill) { return 0; }
// @Override @Nullable public FluidStack drain(FluidStack resource, boolean doDrain) { return null; }
// @Override @Nullable public FluidStack drain(int maxDrain, boolean doDrain) { return null; }
// @Override @Nullable public FluidStack getContents() { return null; }
// @Override public IFluidTankProperties[] getTankProperties() { return props_; }
// @Override public int getCapacity() { return max_flowrate; }
// @Override public boolean canFill() { return true; }
// @Override public boolean canDrain() { return false; }
// @Override public boolean canFillFluidType(FluidStack fluidStack) { return true; }
// @Override public boolean canDrainFluidType(FluidStack fluidStack) { return false; }
// }
//
// TileEntity ------------------------------------------------------------------------------
public BTileEntity()
{ this(ModContent.TET_PASSIVE_FLUID_ACCUMULATOR); }
public BTileEntity(TileEntityType<?> te_type)
{ super(te_type); }
// @Override
// public void read(CompoundNBT nbt)
// {
// super.read(nbt);
// tank_ = (!nbt.contains("tank")) ? (null) : (FluidStack.loadFluidStackFromNBT(nbt.getCompound("tank")));
// }
//
// @Override
// public CompoundNBT write(CompoundNBT nbt)
// {
// super.write(nbt);
// if(tank_ != null) nbt.put("tank", tank_.writeToNBT(new CompoundNBT()));
// return nbt;
// }
//
// // ICapabilityProvider --------------------------------------------------------------------
//
// private final LazyOptional<IFluidHandler> fluid_handler_ = LazyOptional.of(() -> (IFluidHandler)this);
// private final LazyOptional<IFluidHandler> fill_handler_ = LazyOptional.of(() -> new InputFillHandler(this));
//
// @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(facing == block_facing_) return fluid_handler_.cast();
// return fill_handler_.cast();
// }
// }
// return super.getCapability(capability, facing);
// }
//
// // IFluidHandler of the output port --------------------------------------------------------
//
// @Override
// public IFluidTankProperties[] getTankProperties()
// { return fluid_props_; }
//
// @Override
// public int fill(FluidStack resource, boolean doFill)
// { return 0; }
//
// @Override
// @Nullable
// public FluidStack drain(FluidStack resource, boolean doDrain)
// {
// if((resource==null) || (tank_==null)) return null;
// return (!(tank_.isFluidEqual(resource))) ? (null) : drain(resource.amount, doDrain);
// }
//
// @Override
// @Nullable
// public FluidStack drain(int maxDrain, boolean doDrain)
// {
// if(!initialized_) return null;
// if(doDrain && (maxDrain > 0)) last_drain_request_amount_ = maxDrain;
// if(tank_==null) return null;
// maxDrain = MathHelper.clamp(maxDrain ,0 , tank_.amount);
// if(!doDrain) return tank_.copy();
// FluidStack res = tank_.copy();
// res.amount = maxDrain;
// tank_.amount -= maxDrain;
// if(tank_.amount <= 0) tank_= null;
// total_volume_drained_ += res.amount;
// return res;
// }
//
// // IFluidTankProperties --------------------------------------------------------------------
//
// @Override @Nullable public FluidStack getContents() { return (tank_==null) ? (null) : (tank_.copy()); }
// @Override public int getCapacity() { return max_flowrate; }
// @Override public boolean canFill() { return false; }
// @Override public boolean canDrain() { return true; }
// @Override public boolean canFillFluidType(FluidStack fluidStack) { return false; }
// @Override public boolean canDrainFluidType(FluidStack fluidStack) { return true; }
//
// // ITickable--------------------------------------------------------------------------------
//
// public void tick()
// {
// if((world.isRemote) || (--tick_timer_ > 0)) return;
// tick_timer_ = tick_idle_interval;
// if(!initialized_) {
// initialized_ = true;
// BlockState state = world.getBlockState(pos);
// if((state==null) || (!(state.getBlock() instanceof BlockDecorPassiveFluidAccumulator))) return;
// block_facing_ = state.get(FACING);
// }
// int n_requested = last_drain_request_amount_;
// last_drain_request_amount_ = 0;
// if(n_requested > 0) {
// vacuum_ += 2;
// if(vacuum_ > 5) vacuum_ = 5;
// } else {
// if((--vacuum_) <= 0) {
// vacuum_ = 0;
// if(tank_!=null) {
// return; // nothing to do, noone's draining.
// } else {
// n_requested = 10; // drip in
// }
// }
// }
// boolean has_refilled = false;
// n_requested += (vacuum_ * 50);
// int tank_buffer_needed = n_requested;
// if(tank_buffer_needed > max_flowrate) tank_buffer_needed = max_flowrate;
// for(int i=0; i<6; ++i) {
// if(++round_robin_ > 5) round_robin_ = 0;
// if(n_requested <= 0) break;
// if(((tank_!=null) && (tank_.amount >= tank_buffer_needed))) break;
// final Direction f = Direction.byIndex(round_robin_);
// if(f == block_facing_) continue;
// final TileEntity te = world.getTileEntity(pos.offset(f));
// if((te==null) || (te instanceof BTileEntity)) continue;
// final IFluidHandler fh = te.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, f.getOpposite()).orElse(null);
// if(fh==null) continue;
// if(tank_==null) {
// FluidStack res = fh.drain(n_requested, true);
// if((res == null) || (res.amount==0)) continue;
// total_volume_filled_ += res.amount;
// tank_ = res.copy();
// has_refilled = true;
// } else {
// if((tank_.amount + n_requested) > max_flowrate) n_requested = (max_flowrate - tank_.amount);
// FluidStack rq = tank_.copy();
// rq.amount = n_requested;
// FluidStack res = fh.drain(rq, true);
// if(res == null) continue;
// tank_.amount += res.amount;
// total_volume_filled_ += res.amount;
// has_refilled = true;
// if(tank_.amount >= max_flowrate) break;
// }
// }
// if(has_refilled) tick_timer_ = 0;
// }
}
}

View file

@ -0,0 +1,342 @@
/*
* @file BlockDecorPipeValve.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2019 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)
*
* Basically a piece of pipe that does not connect to
* pipes on the side, and conducts fluids only in one way.
*/
package wile.engineersdecor.blocks;
import wile.engineersdecor.ModContent;
import wile.engineersdecor.ModEngineersDecor;
import blusunrize.immersiveengineering.api.fluid.IFluidPipe;
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.IBlockReader;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.item.ItemStack;
import net.minecraft.entity.LivingEntity;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
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.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.common.capabilities.ICapabilityProvider;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.fluids.capability.IFluidTankProperties;
import net.minecraftforge.fluids.FluidStack;
import javax.annotation.Nullable;
public class BlockDecorPipeValve extends BlockDecorDirected
{
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 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");
}
public BlockDecorPipeValve(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
{ super(config, builder, unrotatedAABB); }
private BlockState get_rsconnector_state(BlockState state, IWorld world, BlockPos pos, @Nullable BlockPos fromPos)
{
if((config & (CFG_REDSTONE_CONTROLLED))==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;
}
private void update_te(World 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
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder)
{ builder.add(FACING, 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)
{
update_te(world, state, pos);
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; }
@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 IFluidHandler, IFluidTankProperties, ICapabilityProvider, IFluidPipe
{
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 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; }
// }
// }
// }
}
// 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)
// {
// 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);
// nbt.putInt("facing", block_facing_.getIndex());
// nbt.putLong("conf", block_config_);
// return nbt;
// }
//
// // ICapabilityProvider --------------------------------------------------------------------
//
// private static final BackFlowHandler back_flow_handler_singleton_ = new BackFlowHandler();
// private LazyOptional<IFluidHandler> back_flow_handler_ = LazyOptional.of(() -> (IFluidHandler)back_flow_handler_singleton_);
// private LazyOptional<IFluidHandler> fluid_handler_ = LazyOptional.of(() -> (IFluidHandler)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();
// if(facing == block_facing_.getOpposite()) return back_flow_handler_.cast();
// }
// }
// return super.getCapability(capability, facing);
// }
//
// // IFluidHandler/IFluidTankProperties ---------------------------------------------------------------
//
// @Nullable
// private IFluidHandler forward_fluid_handler()
// {
// 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);
// }
//
// @Override
// public int fill(FluidStack resource, boolean doFill)
// {
// if((filling_) || (!filling_enabled_)) return 0;
// if((block_config_ & CFG_REDSTONE_CONTROLLED) != 0) {
// int rs = world.getRedstonePowerFromNeighbors(pos);
// if(rs <= 0) return 0;
// if(((block_config_ & CFG_ANALOG) != 0) && (rs < 15)) resource.amount = MathHelper.clamp(rs * redstone_flow_slope_mb, 1, resource.amount);
// }
// FluidStack res = resource.copy();
// if(res.amount > fluid_maxflow_mb) res.amount = fluid_maxflow_mb;
// final IFluidHandler fh = forward_fluid_handler();
// if(fh==null) return 0;
// 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 = world.getTileEntity(pos.offset(block_facing_));
// if(te instanceof IFluidPipe) {
// // forward pressureized tag
// if(res.tag == null) res.tag = new CompoundNBT();
// res.tag.putBoolean("pressurized", true);
// }
// }
// int n_filled = forward_fluid_handler().fill(res, doFill);
// filling_ = false;
// return n_filled;
// }
//
// @Override
// @Nullable
// public FluidStack drain(FluidStack resource, boolean doDrain)
// { return null; }
//
// @Override
// @Nullable
// public FluidStack drain(int maxDrain, boolean doDrain)
// { return null; }
//
// @Override
// public IFluidTankProperties[] getTankProperties()
// { return fluid_props_; }
//
// // IFluidTankProperties --
//
// @Override
// @Nullable
// public FluidStack getContents()
// { return null; }
//
// public int getCapacity()
// { return 1000; }
//
// @Override
// public boolean canFill()
// { return true; }
//
// @Override
// public boolean canDrain()
// { return false; }
//
// @Override
// public boolean canFillFluidType(FluidStack fluidStack)
// { return true; }
//
// @Override
// public boolean canDrainFluidType(FluidStack fluidStack)
// { return false; }
//
// // Back flow prevention handler --
//
// private static class BackFlowHandler implements IFluidHandler, IFluidTankProperties
// {
// private final IFluidTankProperties[] props_ = {this};
// @Override public IFluidTankProperties[] getTankProperties() { return props_; }
// @Override public int fill(FluidStack resource, boolean doFill) { return 0; }
// @Override @Nullable public FluidStack drain(FluidStack resource, boolean doDrain) { return null; }
// @Override @Nullable public FluidStack drain(int maxDrain, boolean doDrain) { return null; }
// @Override @Nullable public FluidStack getContents() { return null; }
// @Override public int getCapacity() { return 0; }
// @Override public boolean canFill() { return false; }
// @Override public boolean canDrain() { return false; }
// @Override public boolean canFillFluidType(FluidStack fluidStack) { return false; }
// @Override public boolean canDrainFluidType(FluidStack fluidStack) { return false; }
// }
//
// // 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

@ -0,0 +1,174 @@
/*
* @file BlockDecorSlab.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2019 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)
*
* Standard half block horizontal slab characteristics class.
*/
package wile.engineersdecor.blocks;
import net.minecraft.util.math.*;
import wile.engineersdecor.detail.ModAuxiliaries;
import wile.engineersdecor.detail.ModConfig;
import net.minecraft.block.*;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.state.IntegerProperty;
import net.minecraft.util.*;
import net.minecraft.util.math.shapes.VoxelShapes;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.world.World;
import net.minecraft.entity.EntityType;
import net.minecraft.state.StateContainer;
import net.minecraft.util.math.shapes.ISelectionContext;
import net.minecraft.item.BlockItemUseContext;
import net.minecraft.block.BlockState;
import net.minecraft.world.IBlockReader;
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class BlockDecorSlab extends BlockDecor
{
public static final IntegerProperty PARTS = IntegerProperty.create("parts", 0, 2);
public static final IntegerProperty TEXTURE_VARIANT = IntegerProperty.create("tvariant", 0, 3);
protected static final VoxelShape AABBs[] = {
VoxelShapes.create(new AxisAlignedBB(0, 0./16, 0, 1, 8./16, 1)), // bottom slab
VoxelShapes.create(new AxisAlignedBB(0, 8./16, 0, 1, 16./16, 1)), // top slab
VoxelShapes.create(new AxisAlignedBB(0, 0./16, 0, 1, 16./16, 1)), // both slabs
VoxelShapes.create(new AxisAlignedBB(0, 0./16, 0, 1, 16./16, 1)) // << 2bit fill
};
protected static final int num_slabs_contained_in_parts_[] = { 1,1,2,2 };
protected boolean is_cube(BlockState state)
{ return state.get(PARTS) >= 2; }
public BlockDecorSlab(long config, Block.Properties builder)
{ super(config, builder); }
@Override
@OnlyIn(Dist.CLIENT)
public BlockRenderLayer getRenderLayer()
{ return (((config & CFG_TRANSLUCENT)!=0) ? (BlockRenderLayer.TRANSLUCENT) : (BlockRenderLayer.CUTOUT)); }
@Override
@OnlyIn(Dist.CLIENT)
public void addInformation(ItemStack stack, @Nullable IBlockReader world, List<ITextComponent> tooltip, ITooltipFlag flag)
{
if(!ModAuxiliaries.Tooltip.addInformation(stack, world, tooltip, flag, true)) return;
// if(!ModConfig.optout.without_direct_slab_pickup) {
ModAuxiliaries.Tooltip.addInformation("engineersdecor.tooltip.slabpickup", "engineersdecor.tooltip.slabpickup", tooltip, flag, true);
// }
}
@Override
public boolean canSpawnInBlock()
{ return false; }
@Override
@SuppressWarnings("deprecation")
public boolean canEntitySpawn(BlockState state, IBlockReader world, BlockPos pos, EntityType<?> entityType)
{ return false; }
@Override
public VoxelShape getShape(BlockState state, IBlockReader source, BlockPos pos, ISelectionContext selectionContext)
{ return AABBs[state.get(PARTS) & 0x3]; }
@Override
public VoxelShape getCollisionShape(BlockState state, IBlockReader world, BlockPos pos, ISelectionContext selectionContext)
{ return getShape(state, world, pos, selectionContext); }
@Override
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder)
{ builder.add(PARTS, TEXTURE_VARIANT); }
@Override
@Nullable
public BlockState getStateForPlacement(BlockItemUseContext context)
{
final Direction facing = context.getFace();
double y = context.getHitVec().getY();
int rnd = MathHelper.clamp((int)(MathHelper.getPositionRandom(context.getPos()) % 4), 0, 3);
return getDefaultState().with(PARTS, ((facing==Direction.UP) || ((facing!=Direction.DOWN) && (y < 0.6))) ? 0 : 1).with(TEXTURE_VARIANT, rnd);
}
@Override
@SuppressWarnings("deprecation")
public BlockState rotate(BlockState state, Rotation rot)
{ return state; }
@Override
@SuppressWarnings("deprecation")
public BlockState mirror(BlockState state, Mirror mirrorIn)
{ return state; }
@Override
public List<ItemStack> dropList(BlockState state, World world, BlockPos pos, boolean explosion)
{ return new ArrayList<ItemStack>(Collections.singletonList(new ItemStack(this.asItem(), num_slabs_contained_in_parts_[state.get(PARTS) & 0x3]))); }
@Override
@SuppressWarnings("deprecation")
public boolean onBlockActivated(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockRayTraceResult rayTraceResult)
{
Direction face = rayTraceResult.getFace();
final ItemStack stack = player.getHeldItem(hand);
if(stack.isEmpty() || (Block.getBlockFromItem(stack.getItem()) != this)) return false;
int parts = state.get(PARTS);
if(((face == Direction.UP) && (parts == 0)) || ((face == Direction.DOWN) && (parts == 1))) {
world.setBlockState(pos, state.with(PARTS, 2), 3);
} else {
return false; // "not handled" -> let parent decide if a new slab has to be placed on top/bottom.
}
if(world.isRemote) return true;
if(!player.isCreative()) {
stack.shrink(1);
if(player.inventory != null) player.inventory.markDirty();
}
SoundType st = this.getSoundType(state, world, pos, null);
world.playSound(null, pos, st.getPlaceSound(), SoundCategory.BLOCKS, (st.getVolume()+1f)/2.5f, 0.9f*st.getPitch());
return true;
}
@Override
@SuppressWarnings("deprecation")
public void onBlockClicked(BlockState state, World world, BlockPos pos, PlayerEntity player)
{
if((world.isRemote)) return; // || (ModConfig.optout.without_direct_slab_pickup)
final ItemStack stack = player.getHeldItemMainhand();
if(stack.isEmpty() || (Block.getBlockFromItem(stack.getItem()) != this)) return;
if(stack.getCount() >= stack.getMaxStackSize()) return;
Vec3d lv = player.getLookVec();
Direction facing = Direction.getFacingFromVector((float)lv.x, (float)lv.y, (float)lv.z);
if((facing != Direction.UP) && (facing != Direction.DOWN)) return;
if(state.getBlock() != this) return;
int parts = state.get(PARTS);
if(facing == Direction.DOWN) {
if(parts == 2) {
world.setBlockState(pos, state.with(PARTS, 0), 3);
} else {
world.removeBlock(pos, false);
}
} else if(facing == Direction.UP) {
if(parts == 2) {
world.setBlockState(pos, state.with(PARTS, 1), 3);
} else {
world.removeBlock(pos, false);
}
}
if(!player.isCreative()) {
stack.grow(1);
if(player.inventory != null) player.inventory.markDirty();
}
SoundType st = this.getSoundType(state, world, pos, null);
world.playSound(player, pos, st.getPlaceSound(), SoundCategory.BLOCKS, (st.getVolume()+1f)/2.5f, 0.9f*st.getPitch());
}
}

View file

@ -0,0 +1,63 @@
/*
* @file BlockDecorStairs.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2019 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)
*
* Stairs and roof blocks, almost entirely based on vanilla stairs.
*/
package wile.engineersdecor.blocks;
import wile.engineersdecor.detail.ModAuxiliaries;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.fluid.IFluidState;
import net.minecraft.world.Explosion;
import net.minecraft.world.World;
import net.minecraft.entity.EntityType;
import net.minecraft.util.math.BlockPos;
import net.minecraft.block.*;
import net.minecraft.block.material.PushReaction;
import net.minecraft.block.BlockState;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.item.ItemStack;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.world.IBlockReader;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import javax.annotation.Nullable;
import java.util.List;
public class BlockDecorStairs extends StairsBlock implements IDecorBlock
{
public BlockDecorStairs(long config, BlockState state, Block.Properties properties)
{ super(state, properties); }
@Override
@OnlyIn(Dist.CLIENT)
public void addInformation(ItemStack stack, @Nullable IBlockReader world, List<ITextComponent> tooltip, ITooltipFlag flag)
{ ModAuxiliaries.Tooltip.addInformation(stack, world, tooltip, flag, true); }
@Override
public boolean canSpawnInBlock()
{ return false; }
@Override
@SuppressWarnings("deprecation")
public boolean canEntitySpawn(BlockState state, IBlockReader world, BlockPos pos, EntityType<?> entityType)
{ return false; }
@Override
@SuppressWarnings("deprecation")
public PushReaction getPushReaction(BlockState state)
{ return PushReaction.NORMAL; }
@Override
public boolean removedByPlayer(BlockState state, World world, BlockPos pos, PlayerEntity player, boolean willHarvest, IFluidState fluid)
{ return BlockDecor.dropBlock(state, world, pos, false); }
@Override
public void onExplosionDestroy(World world, BlockPos pos, Explosion explosion)
{ BlockDecor.dropBlock(world.getBlockState(pos), world, pos, true); }
}

View file

@ -0,0 +1,41 @@
/*
* @file BlockDecorStraightPole.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2019 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)
*
* Smaller (cutout) block with a defined facing.
*/
package wile.engineersdecor.blocks;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.item.BlockItemUseContext;
import net.minecraft.world.World;
import net.minecraft.util.Direction;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import javax.annotation.Nullable;
public class BlockDecorStraightPole extends BlockDecorDirected
{
public BlockDecorStraightPole(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
{ super(config, builder, unrotatedAABB); }
@Override
@Nullable
public BlockState getStateForPlacement(BlockItemUseContext context)
{
Direction facing = context.getFace();
BlockState state = getDefaultState().with(FACING, facing);
if((config & CFG_FLIP_PLACEMENT_IF_SAME) != 0) {
World world = context.getWorld();
BlockPos pos = context.getPos();
if(world.getBlockState(pos.offset(facing.getOpposite())).getBlock() instanceof BlockDecorStraightPole) {
state = state.with(FACING, state.get(FACING).getOpposite());
}
}
return state;
}
}

View file

@ -0,0 +1,115 @@
/*
* @file BlockDecorWall.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2019 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)
*
* Wall blocks.
*/
package wile.engineersdecor.blocks;
import wile.engineersdecor.detail.ModAuxiliaries;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.fluid.IFluidState;
import net.minecraft.world.Explosion;
import net.minecraft.world.World;
import net.minecraft.entity.EntityType;
import net.minecraft.util.math.shapes.ISelectionContext;
import net.minecraft.state.StateContainer;
import net.minecraft.util.math.MathHelper;
import net.minecraft.block.*;
import net.minecraft.block.material.PushReaction;
import net.minecraft.block.BlockState;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.fluid.Fluids;
import net.minecraft.item.ItemStack;
import net.minecraft.state.IntegerProperty;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.IWorld;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import javax.annotation.Nullable;
import java.util.List;
public class BlockDecorWall extends WallBlock implements IDecorBlock
{
private final VoxelShape[] shape_voxels;
private final VoxelShape[] collision_shape_voxels;
public static final IntegerProperty TEXTURE_VARIANT = IntegerProperty.create("tvariant", 0, 7);
public BlockDecorWall(long config, Block.Properties builder)
{
super(builder);
this.shape_voxels = buildWallShapes(4.0F, 4.0F, 16.0F, 0.0F, 16.0F);
this.collision_shape_voxels = buildWallShapes(4.0F, 4.0F, 24.0F, 0.0F, 24.0F);
}
@Override
@OnlyIn(Dist.CLIENT)
public void addInformation(ItemStack stack, @Nullable IBlockReader world, List<ITextComponent> tooltip, ITooltipFlag flag)
{ ModAuxiliaries.Tooltip.addInformation(stack, world, tooltip, flag, true); }
protected VoxelShape[] buildWallShapes(float pole_width_x, float pole_width_z, float pole_height, float side_min_y, float side_max_y)
{ return super.makeShapes(pole_width_x, pole_width_z, pole_height, side_min_y, side_max_y); }
@Override
public VoxelShape getShape(BlockState state, IBlockReader world, BlockPos pos, ISelectionContext selectionContext)
{ return shape_voxels[this.getIndex(state)]; }
@Override
public VoxelShape getCollisionShape(BlockState state, IBlockReader world, BlockPos pos, ISelectionContext selectionContext)
{ return collision_shape_voxels[this.getIndex(state)]; }
@Override
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder)
{ super.fillStateContainer(builder); builder.add(TEXTURE_VARIANT); }
private boolean attachesTo(BlockState facingState, IWorld world, BlockPos facingPos, Direction side)
{
final Block block = facingState.getBlock();
if((block instanceof FenceGateBlock) || (block instanceof WallBlock)) return true;
// return this.func_220113_a(facingState, Block.func_220056_d(facingState, world, facingPos, side), side);
// @todo: CHANGE HERE WHEN DEOBF METHOD IS AVAILABLE
return false;
}
@Override
public BlockState updatePostPlacement(BlockState state, Direction side, BlockState facingState, IWorld world, BlockPos currentPos, BlockPos facingPos)
{
if(state.get(WATERLOGGED)) world.getPendingFluidTicks().scheduleTick(currentPos, Fluids.WATER, Fluids.WATER.getTickRate(world));
if(side == Direction.DOWN) return super.updatePostPlacement(state, side, facingState, world, currentPos, facingPos);
boolean n = (side==Direction.NORTH) ? this.attachesTo(facingState, world, facingPos, side) : state.get(NORTH);
boolean e = (side==Direction.EAST) ? this.attachesTo(facingState, world, facingPos, side) : state.get(EAST);
boolean s = (side==Direction.SOUTH) ? this.attachesTo(facingState, world, facingPos, side) : state.get(SOUTH);
boolean w = (side==Direction.WEST) ? this.attachesTo(facingState, world, facingPos, side) : state.get(WEST);
boolean not_straight = (!n || !s || e || w) && (n || s || !e || !w);
return state.with(UP, not_straight).with(NORTH, n).with(EAST, e).with(SOUTH, s).with(WEST, w).with(TEXTURE_VARIANT, ((int)MathHelper.getPositionRandom(currentPos)) & 0x7);
}
@Override
@SuppressWarnings("deprecation")
public boolean canEntitySpawn(BlockState state, IBlockReader world, BlockPos pos, EntityType<?> entityType)
{ return false; }
@Override
public boolean canSpawnInBlock()
{ return false; }
@Override
@SuppressWarnings("deprecation")
public PushReaction getPushReaction(BlockState state)
{ return PushReaction.NORMAL; }
@Override
public boolean removedByPlayer(BlockState state, World world, BlockPos pos, PlayerEntity player, boolean willHarvest, IFluidState fluid)
{ return BlockDecor.dropBlock(state, world, pos, false); }
@Override
public void onExplosionDestroy(World world, BlockPos pos, Explosion explosion)
{ BlockDecor.dropBlock(world.getBlockState(pos), world, pos, true); }
}

View file

@ -0,0 +1,718 @@
/*
* @file BlockDecorWasteIncinerator.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2019 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)
*
* Trash/void/nullifier device with internal fifos.
*/
package wile.engineersdecor.blocks;
import wile.engineersdecor.ModContent;
import wile.engineersdecor.ModEngineersDecor;
import net.minecraft.inventory.container.INamedContainerProvider;
import net.minecraft.tileentity.ITickableTileEntity;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.container.Slot;
import net.minecraft.particles.ParticleTypes;
import net.minecraft.state.BooleanProperty;
import net.minecraft.state.StateContainer;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.world.IBlockReader;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.world.World;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.util.SoundEvents;
import net.minecraft.item.*;
import net.minecraft.inventory.*;
import net.minecraft.client.gui.screen.inventory.ContainerScreen;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.*;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.common.util.FakePlayer;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fml.network.NetworkHooks;
import net.minecraftforge.energy.CapabilityEnergy;
import net.minecraftforge.energy.IEnergyStorage;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemHandlerHelper;
import com.mojang.blaze3d.platform.GlStateManager;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class BlockDecorWasteIncinerator extends BlockDecor
{
public static final BooleanProperty LIT = BlockDecorFurnace.LIT;
public BlockDecorWasteIncinerator(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
{ super(config, builder, unrotatedAABB); }
@Override
@OnlyIn(Dist.CLIENT)
public BlockRenderLayer getRenderLayer()
{ return BlockRenderLayer.SOLID; }
@Override
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder)
{ builder.add(LIT); }
@Override
@Nullable
public BlockState getStateForPlacement(BlockItemUseContext context)
{ return super.getStateForPlacement(context).with(LIT, false); }
@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 BlockDecorWasteIncinerator.BTileEntity(); }
@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 BlockDecorWasteIncinerator.BTileEntity)) return;
((BlockDecorWasteIncinerator.BTileEntity)te).readnbt(te_nbt);
((BlockDecorWasteIncinerator.BTileEntity)te).markDirty();
}
@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 BTileEntity)) return stacks;
if(!explosion) {
ItemStack stack = new ItemStack(this, 1);
CompoundNBT te_nbt = ((BTileEntity) te).reset_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_) stacks.add(stack);
((BTileEntity)te).reset_getnbt();
}
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 BTileEntity)) return true;
if((!(player instanceof ServerPlayerEntity) && (!(player instanceof FakePlayer)))) return true;
NetworkHooks.openGui((ServerPlayerEntity)player,(INamedContainerProvider)te);
return true;
}
@Override
@OnlyIn(Dist.CLIENT)
public void animateTick(BlockState state, World world, BlockPos pos, Random rnd)
{
if((state.getBlock()!=this) || (!state.get(LIT))) return;
final double rv = rnd.nextDouble();
if(rv > 0.5) return;
final double x=0.5+pos.getX(), y=0.5+pos.getY(), z=0.5+pos.getZ();
final double xr=rnd.nextDouble()*0.4-0.2, yr=rnd.nextDouble()*0.5, zr=rnd.nextDouble()*0.4-0.2;
world.addParticle(ParticleTypes.SMOKE, x+xr, y+yr, z+zr, 0.0, 0.0, 0.0);
}
//--------------------------------------------------------------------------------------------------------------------
// Tile entity
//--------------------------------------------------------------------------------------------------------------------
public static class BTileEntity extends TileEntity implements ITickableTileEntity, INameable, IInventory, INamedContainerProvider, ISidedInventory, IEnergyStorage
{
public static final int NUM_OF_FIELDS = 1;
public static final int TICK_INTERVAL = 20;
public static final int ENERGIZED_TICK_INTERVAL = 5;
public static final int MAX_ENERGY_BUFFER = 16000;
public static final int MAX_ENERGY_TRANSFER = 256;
public static final int DEFAULT_ENERGY_CONSUMPTION = 16;
public static final int NUM_OF_SLOTS = 16;
public static final int INPUT_SLOT_NO = 0;
public static final int BURN_SLOT_NO = NUM_OF_SLOTS-1;
// Config ----------------------------------------------------------------------------------
private static int energy_consumption = DEFAULT_ENERGY_CONSUMPTION;
public static void on_config(int speed_percent, int fuel_efficiency_percent, int boost_energy_per_tick)
{
energy_consumption = MathHelper.clamp(boost_energy_per_tick, 16, 512);
ModEngineersDecor.logger().info("Config waste incinerator boost energy consumption:" + energy_consumption);
}
// BTileEntity -----------------------------------------------------------------------------
private int tick_timer_;
private int check_timer_;
private int energy_stored_;
protected NonNullList<ItemStack> stacks_ = NonNullList.<ItemStack>withSize(NUM_OF_SLOTS, ItemStack.EMPTY);
public BTileEntity()
{ this(ModContent.TET_WASTE_INCINERATOR); }
public BTileEntity(TileEntityType<?> te_type)
{ super(te_type); reset(); }
public CompoundNBT reset_getnbt()
{
CompoundNBT nbt = new CompoundNBT();
writenbt(nbt);
reset();
return nbt;
}
protected void reset()
{
stacks_ = NonNullList.<ItemStack>withSize(NUM_OF_SLOTS, ItemStack.EMPTY);
check_timer_ = 0;
tick_timer_ = 0;
}
public void readnbt(CompoundNBT compound)
{
NonNullList<ItemStack> stacks = NonNullList.<ItemStack>withSize(NUM_OF_SLOTS, ItemStack.EMPTY);
ItemStackHelper.loadAllItems(compound, stacks);
while(stacks.size() < NUM_OF_SLOTS) stacks.add(ItemStack.EMPTY);
stacks_ = stacks;
energy_stored_ = compound.getInt("Energy");
}
protected void writenbt(CompoundNBT compound)
{
compound.putInt("Energy", MathHelper.clamp(energy_stored_,0 , MAX_ENERGY_BUFFER));
ItemStackHelper.saveAllItems(compound, stacks_);
}
// TileEntity ------------------------------------------------------------------------------
@Override
public void read(CompoundNBT compound)
{ super.read(compound); readnbt(compound); }
@Override
public CompoundNBT write(CompoundNBT compound)
{ super.write(compound); writenbt(compound); return compound; }
// INameable ---------------------------------------------------------------------------
@Override
public ITextComponent getName()
{ final Block block=getBlockState().getBlock(); return new StringTextComponent((block!=null) ? block.getTranslationKey() : "Small Waste Incinerator"); }
@Override
public boolean hasCustomName()
{ return false; }
@Override
public ITextComponent getCustomName()
{ return getName(); }
// IContainerProvider ----------------------------------------------------------------------
@Override
public ITextComponent getDisplayName()
{ return INameable.super.getDisplayName(); }
@Override
public Container createMenu(int id, PlayerInventory inventory, PlayerEntity player )
{ return new BlockDecorWasteIncinerator.BContainer(id, inventory, this, IWorldPosCallable.of(world, pos), fields); }
// IInventory ------------------------------------------------------------------------------
@Override
public int getSizeInventory()
{ return stacks_.size(); }
@Override
public boolean isEmpty()
{ for(ItemStack stack: stacks_) { if(!stack.isEmpty()) return false; } return true; }
@Override
public ItemStack getStackInSlot(int index)
{ return ((index >= 0) && (index < getSizeInventory())) ? stacks_.get(index) : ItemStack.EMPTY; }
@Override
public ItemStack decrStackSize(int index, int count)
{ return ItemStackHelper.getAndSplit(stacks_, index, count); }
@Override
public ItemStack removeStackFromSlot(int index)
{ return ItemStackHelper.getAndRemove(stacks_, index); }
@Override
public void setInventorySlotContents(int index, ItemStack stack)
{
if(stack.getCount() > getInventoryStackLimit()) stack.setCount(getInventoryStackLimit());
stacks_.set(index, stack);
markDirty();
}
@Override
public int getInventoryStackLimit()
{ return 64; }
@Override
public void markDirty()
{ super.markDirty(); }
@Override
public boolean isUsableByPlayer(PlayerEntity player)
{ return getPos().distanceSq(player.getPosition()) < 36; }
@Override
public void openInventory(PlayerEntity player)
{}
@Override
public void closeInventory(PlayerEntity player)
{ markDirty(); }
@Override
public boolean isItemValidForSlot(int index, ItemStack stack)
{ return (index==0); }
@Override
public void clear()
{ stacks_.clear(); }
// Fields -----------------------------------------------------------------------------------------------
protected final IIntArray fields = new IntArray(BTileEntity.NUM_OF_FIELDS)
{
@Override
public int get(int id)
{
switch(id) {
default: return 0;
}
}
@Override
public void set(int id, int value)
{
switch(id) {
default: break;
}
}
};
// ISidedInventory ----------------------------------------------------------------------------
private static final int[] SIDED_INV_SLOTS = new int[] { INPUT_SLOT_NO };
@Override
public int[] getSlotsForFace(Direction side)
{ return SIDED_INV_SLOTS; }
@Override
public boolean canInsertItem(int index, ItemStack itemStackIn, Direction direction)
{ return isItemValidForSlot(index, itemStackIn); }
@Override
public boolean canExtractItem(int index, ItemStack stack, Direction direction)
{ return false; }
// IEnergyStorage ----------------------------------------------------------------------------
@Override
public boolean canExtract()
{ return false; }
@Override
public boolean canReceive()
{ return true; }
@Override
public int getMaxEnergyStored()
{ return MAX_ENERGY_BUFFER; }
@Override
public int getEnergyStored()
{ return energy_stored_; }
@Override
public int extractEnergy(int maxExtract, boolean simulate)
{ return 0; }
@Override
public int receiveEnergy(int maxReceive, boolean simulate)
{
if(energy_stored_ >= MAX_ENERGY_BUFFER) return 0;
int n = Math.min(maxReceive, (MAX_ENERGY_BUFFER - energy_stored_));
if(n > MAX_ENERGY_TRANSFER) n = MAX_ENERGY_TRANSFER;
if(!simulate) {energy_stored_ += n; markDirty(); }
return n;
}
// IItemHandler --------------------------------------------------------------------------------
protected static class BItemHandler implements IItemHandler
{
private BTileEntity te;
BItemHandler(BTileEntity te)
{ this.te = te; }
@Override
public int getSlots()
{ return 1; }
@Override
public int getSlotLimit(int index)
{ return te.getInventoryStackLimit(); }
@Override
public boolean isItemValid(int slot, @Nonnull ItemStack stack)
{ return true; }
@Override
@Nonnull
public ItemStack insertItem(int index, @Nonnull ItemStack stack, boolean simulate)
{
if(stack.isEmpty()) return ItemStack.EMPTY;
if(index != 0) return ItemStack.EMPTY;
int slotno = 0;
ItemStack slotstack = getStackInSlot(slotno);
if(!slotstack.isEmpty())
{
if(slotstack.getCount() >= Math.min(slotstack.getMaxStackSize(), getSlotLimit(index))) return stack;
if(!ItemHandlerHelper.canItemStacksStack(stack, slotstack)) return stack;
if(!te.canInsertItem(slotno, stack, Direction.UP) || (!te.isItemValidForSlot(slotno, stack))) return stack;
int n = Math.min(stack.getMaxStackSize(), getSlotLimit(index)) - slotstack.getCount();
if(stack.getCount() <= n) {
if(!simulate) {
ItemStack copy = stack.copy();
copy.grow(slotstack.getCount());
te.setInventorySlotContents(slotno, copy);
}
return ItemStack.EMPTY;
} else {
stack = stack.copy();
if(!simulate) {
ItemStack copy = stack.split(n);
copy.grow(slotstack.getCount());
te.setInventorySlotContents(slotno, copy);
return stack;
} else {
stack.shrink(n);
return stack;
}
}
} else {
if(!te.canInsertItem(slotno, stack, Direction.UP) || (!te.isItemValidForSlot(slotno, stack))) return stack;
int n = Math.min(stack.getMaxStackSize(), getSlotLimit(index));
if(n < stack.getCount()) {
stack = stack.copy();
if(!simulate) {
te.setInventorySlotContents(slotno, stack.split(n));
return stack;
} else {
stack.shrink(n);
return stack;
}
} else {
if(!simulate) te.setInventorySlotContents(slotno, stack);
return ItemStack.EMPTY;
}
}
}
@Override
@Nonnull
public ItemStack extractItem(int index, int amount, boolean simulate)
{ return ItemStack.EMPTY; }
@Override
@Nonnull
public ItemStack getStackInSlot(int index)
{ return te.getStackInSlot(index); }
}
// Capability export ----------------------------------------------------------------------------
protected LazyOptional<IItemHandler> item_handler_ = LazyOptional.of(() -> new BTileEntity.BItemHandler(this));
protected LazyOptional<IEnergyStorage> energy_handler_ = LazyOptional.of(() -> (IEnergyStorage)this);
@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();
}
return super.getCapability(capability, facing);
}
// ITickableTileEntity ---------------------------------------------------------------------------
@Override
public void tick()
{
if(--tick_timer_ > 0) return;
tick_timer_ = TICK_INTERVAL;
if(world.isRemote) return;
boolean dirty = false;
ItemStack processing_stack = stacks_.get(BURN_SLOT_NO);
final boolean was_processing = !processing_stack.isEmpty();
boolean is_processing = was_processing;
boolean new_stack_processing = false;
if((!stacks_.get(0).isEmpty()) && transferItems(0, 1, getInventoryStackLimit())) dirty = true;
ItemStack first_stack = stacks_.get(0);
boolean shift = !first_stack.isEmpty();
if(is_processing) {
processing_stack.shrink(1);
if(processing_stack.getCount() <= 0) {
processing_stack = ItemStack.EMPTY;
is_processing = false;
}
stacks_.set(BURN_SLOT_NO, processing_stack);
if(energy_stored_ >= (energy_consumption * TICK_INTERVAL)) {
energy_stored_ -= (energy_consumption * TICK_INTERVAL);
tick_timer_ = ENERGIZED_TICK_INTERVAL;
}
dirty = true;
}
if(shift) {
int max_shift_slot_no = BURN_SLOT_NO-1;
for(int i=1; i<BURN_SLOT_NO-1; ++i) { if(stacks_.get(i).isEmpty()) { max_shift_slot_no=i; break; } }
if(max_shift_slot_no < (BURN_SLOT_NO-1)) {
// re-stack
boolean stacked = false;
for(int i=1; i<=max_shift_slot_no; ++i) {
if(transferItems(i-1, i, getInventoryStackLimit())) {
dirty = true;
stacked = true;
break;
}
}
if(!stacked) {
shiftStacks(0, max_shift_slot_no);
}
} else if(!is_processing) {
shiftStacks(0, BURN_SLOT_NO);
dirty = true;
}
}
if((was_processing != is_processing) || (new_stack_processing)) {
if(new_stack_processing) world.playSound(null, pos, SoundEvents.BLOCK_LAVA_AMBIENT, SoundCategory.BLOCKS, 0.05f, 2.4f);
final BlockState state = world.getBlockState(pos);
if(state.getBlock() instanceof BlockDecorWasteIncinerator) {
world.setBlockState(pos, state.with(LIT, is_processing), 2|16);
}
}
if(dirty) markDirty();
}
// Aux methods ----------------------------------------------------------------------------------
private ItemStack shiftStacks(final int index_from, final int index_to)
{
if(index_from >= index_to) return ItemStack.EMPTY;
ItemStack out_stack = ItemStack.EMPTY;
ItemStack stack = stacks_.get(index_from);
for(int i=index_from+1; i<=index_to; ++i) {
out_stack = stacks_.get(i);
stacks_.set(i, stack);
stack = out_stack;
}
stacks_.set(index_from, ItemStack.EMPTY);
return out_stack;
}
private boolean transferItems(final int index_from, final int index_to, int count)
{
ItemStack from = stacks_.get(index_from);
if(from.isEmpty()) return false;
ItemStack to = stacks_.get(index_to);
if(from.getCount() < count) count = from.getCount();
if(count <= 0) return false;
boolean changed = true;
if(to.isEmpty()) {
stacks_.set(index_to, from.split(count));
} else if(to.getCount() >= to.getMaxStackSize()) {
changed = false;
} else if((!from.isItemEqual(to)) || (!ItemStack.areItemStackTagsEqual(from, to))) {
changed = false;
} else {
if((to.getCount()+count) >= to.getMaxStackSize()) {
from.shrink(to.getMaxStackSize()-to.getCount());
to.setCount(to.getMaxStackSize());
} else {
from.shrink(count);
to.grow(count);
}
}
if(from.isEmpty() && from!=ItemStack.EMPTY) {
stacks_.set(index_from, ItemStack.EMPTY);
changed = true;
}
return changed;
}
}
//--------------------------------------------------------------------------------------------------------------------
// GUI
//--------------------------------------------------------------------------------------------------------------------
@OnlyIn(Dist.CLIENT)
public static class BGui extends ContainerScreen<BContainer>
{
protected final PlayerEntity player_;
public BGui(BContainer container, PlayerInventory player_inventory, ITextComponent title)
{ super(container, player_inventory, title); this.player_ = player_inventory.player; }
@Override
public void init()
{ super.init(); }
@Override
public void render(int mouseX, int mouseY, float partialTicks)
{
renderBackground();
super.render(mouseX, mouseY, partialTicks);
renderHoveredToolTip(mouseX, mouseY);
}
@Override
protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY)
{
GlStateManager.color4f(1.0F, 1.0F, 1.0F, 1.0F);
this.minecraft.getTextureManager().bindTexture(new ResourceLocation(ModEngineersDecor.MODID, "textures/gui/small_waste_incinerator_gui.png"));
final int x0=guiLeft, y0=this.guiTop, w=xSize, h=ySize;
blit(x0, y0, 0, 0, w, h);
}
}
//--------------------------------------------------------------------------------------------------------------------
// container
//--------------------------------------------------------------------------------------------------------------------
public static class BContainer extends Container
{
private static final int PLAYER_INV_START_SLOTNO = BTileEntity.NUM_OF_SLOTS;
protected final PlayerEntity player_;
protected final IInventory inventory_;
protected final IWorldPosCallable wpc_;
private final IIntArray fields_;
private int proc_time_needed_;
public int field(int index) { return fields_.get(index); }
public PlayerEntity player() { return player_ ; }
public IInventory inventory() { return inventory_ ; }
public World world() { return player_.world; }
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)); }
private BContainer(int cid, PlayerInventory player_inventory, IInventory block_inventory, IWorldPosCallable wpc, IIntArray fields)
{
super(ModContent.CT_WASTE_INCINERATOR, cid);
player_ = player_inventory.player;
inventory_ = block_inventory;
wpc_ = wpc;
fields_ = fields;
int i=-1;
addSlot(new Slot(inventory_, ++i, 13, 9));
addSlot(new Slot(inventory_, ++i, 37, 12));
addSlot(new Slot(inventory_, ++i, 54, 13));
addSlot(new Slot(inventory_, ++i, 71, 14));
addSlot(new Slot(inventory_, ++i, 88, 15));
addSlot(new Slot(inventory_, ++i, 105, 16));
addSlot(new Slot(inventory_, ++i, 122, 17));
addSlot(new Slot(inventory_, ++i, 139, 18));
addSlot(new Slot(inventory_, ++i, 144, 38));
addSlot(new Slot(inventory_, ++i, 127, 39));
addSlot(new Slot(inventory_, ++i, 110, 40));
addSlot(new Slot(inventory_, ++i, 93, 41));
addSlot(new Slot(inventory_, ++i, 76, 42));
addSlot(new Slot(inventory_, ++i, 59, 43));
addSlot(new Slot(inventory_, ++i, 42, 44));
addSlot(new Slot(inventory_, ++i, 17, 58));
for(int x=0; x<9; ++x) {
addSlot(new Slot(player_inventory, x, 8+x*18, 144)); // player slots: 0..8
}
for(int y=0; y<3; ++y) {
for(int x=0; x<9; ++x) {
addSlot(new Slot(player_inventory, x+y*9+9, 8+x*18, 86+y*18)); // player slots: 9..35
}
}
}
@Override
public boolean canInteractWith(PlayerEntity player)
{ return inventory_.isUsableByPlayer(player); }
@Override
public ItemStack transferStackInSlot(PlayerEntity player, int index)
{
Slot slot = getSlot(index);
if((slot==null) || (!slot.getHasStack())) return ItemStack.EMPTY;
ItemStack slot_stack = slot.getStack();
ItemStack transferred = slot_stack.copy();
if((index>=0) && (index<PLAYER_INV_START_SLOTNO)) {
// Device slots
if(!mergeItemStack(slot_stack, PLAYER_INV_START_SLOTNO, PLAYER_INV_START_SLOTNO+36, true)) return ItemStack.EMPTY;
} else if((index >= PLAYER_INV_START_SLOTNO) && (index <= PLAYER_INV_START_SLOTNO+36)) {
// Player slot
if(!mergeItemStack(slot_stack, 0, PLAYER_INV_START_SLOTNO-1, true)) return ItemStack.EMPTY;
} else {
// invalid slot
return ItemStack.EMPTY;
}
if(slot_stack.isEmpty()) {
slot.putStack(ItemStack.EMPTY);
} else {
slot.onSlotChanged();
}
if(slot_stack.getCount() == transferred.getCount()) return ItemStack.EMPTY;
slot.onTake(player, slot_stack);
return transferred;
}
}
}

View file

@ -0,0 +1,32 @@
/*
* @file BlockDecorWindow.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2019 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)
*
* Mod windows.
*/
package wile.engineersdecor.blocks;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
public class BlockDecorWindow extends BlockDecorDirected
{
public BlockDecorWindow(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
{ super(config, builder, unrotatedAABB); }
@Override
@OnlyIn(Dist.CLIENT)
public BlockRenderLayer getRenderLayer()
{ return BlockRenderLayer.TRANSLUCENT; }
@Override
@OnlyIn(Dist.CLIENT)
public boolean canRenderInLayer(BlockState state, BlockRenderLayer layer)
{ return (layer==BlockRenderLayer.CUTOUT) || (layer==BlockRenderLayer.TRANSLUCENT); }
}

View file

@ -0,0 +1,25 @@
/*
* @file IDecorBlock.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2019 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)
*
* Interface for tagging and common default behaviour.
*/
package wile.engineersdecor.blocks;
import net.minecraft.block.BlockState;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import java.util.Collections;
import java.util.List;
interface IDecorBlock
{
default List<ItemStack> dropList(BlockState state, World world, BlockPos pos, boolean explosion)
{ return Collections.singletonList((!world.isRemote()) ? (new ItemStack(state.getBlock().asItem())) : (ItemStack.EMPTY)); }
}

View file

@ -0,0 +1,21 @@
/*
* @file ExtItems.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2019 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)
*
* Object holder based item references.
*/
package wile.engineersdecor.detail;
import net.minecraft.item.Item;
import net.minecraftforge.registries.ObjectHolder;
public class ExtItems
{
@ObjectHolder("immersiveengineering:metal_device1")
public static final Item IE_EXTERNAL_HEATER = null;
public static final void onPostInit()
{}
}

View file

@ -0,0 +1,196 @@
/*
* @file ModAuxiliaries.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2018 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)
*
* General commonly used functionality.
*
* @TODO KEYBOARD INPUT
*/
package wile.engineersdecor.detail;
import wile.engineersdecor.ModEngineersDecor;
import net.minecraft.client.util.InputMappings;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.SharedConstants;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.world.IBlockReader;
import net.minecraft.item.ItemStack;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.util.text.TranslationTextComponent;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraftforge.fml.ModList;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import org.lwjgl.glfw.GLFW;
import javax.annotation.Nullable;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ModAuxiliaries
{
/**
* Text localisation wrapper, implicitly prepends `ModEngineersDecor.MODID` to the
* translation keys. Forces formatting argument, nullable if no special formatting shall be applied..
*/
public static TranslationTextComponent localizable(String modtrkey, @Nullable TextFormatting color, Object... args)
{
TranslationTextComponent tr = new TranslationTextComponent(ModEngineersDecor.MODID+"."+modtrkey, args);
if(color!=null) tr.getStyle().setColor(color);
return tr;
}
public static TranslationTextComponent localizable(String modtrkey)
{ return localizable(modtrkey, null); }
public static TranslationTextComponent localizable_block_key(String blocksubkey)
{ return new TranslationTextComponent("block."+ModEngineersDecor.MODID+"."+blocksubkey); }
@OnlyIn(Dist.CLIENT)
public static String localize(String translationKey, Object... args)
{
TranslationTextComponent tr = new TranslationTextComponent(translationKey, args);
tr.getStyle().setColor(TextFormatting.RESET);
final String ft = tr.getFormattedText();
if(ft.contains("${")) {
// Non-recursive, non-argument lang file entry cross referencing.
Pattern pt = Pattern.compile("\\$\\{([\\w\\.]+)\\}");
Matcher mt = pt.matcher(ft);
StringBuffer sb = new StringBuffer();
while(mt.find()) mt.appendReplacement(sb, (new TranslationTextComponent(mt.group(1))).getFormattedText().trim());
mt.appendTail(sb);
return sb.toString();
} else {
return ft;
}
}
/**
* Returns true if a given key is translated for the current language.
*/
@OnlyIn(Dist.CLIENT)
public static boolean hasTranslation(String key)
{ return net.minecraft.client.resources.I18n.hasKey(key); }
public static final class Tooltip
{
@OnlyIn(Dist.CLIENT)
public static boolean extendedTipCondition()
{
return (
InputMappings.isKeyDown(ModEngineersDecor.proxy.mc().mainWindow.getHandle(), GLFW.GLFW_KEY_LEFT_SHIFT) ||
InputMappings.isKeyDown(ModEngineersDecor.proxy.mc().mainWindow.getHandle(), GLFW.GLFW_KEY_RIGHT_SHIFT)
);
}
@OnlyIn(Dist.CLIENT)
public static boolean helpCondition()
{
return extendedTipCondition() && (
InputMappings.isKeyDown(ModEngineersDecor.proxy.mc().mainWindow.getHandle(), GLFW.GLFW_KEY_LEFT_CONTROL) ||
InputMappings.isKeyDown(ModEngineersDecor.proxy.mc().mainWindow.getHandle(), GLFW.GLFW_KEY_RIGHT_CONTROL)
);
}
/**
* Adds an extended tooltip or help tooltip depending on the key states of CTRL and SHIFT.
* Returns true if the localisable help/tip was added, false if not (either not CTL/SHIFT or
* no translation found).
*/
@OnlyIn(Dist.CLIENT)
public static boolean addInformation(@Nullable String advancedTooltipTranslationKey, @Nullable String helpTranslationKey, List<ITextComponent> tooltip, ITooltipFlag flag, boolean addAdvancedTooltipHints)
{
// Note: intentionally not using keybinding here, this must be `control` or `shift`. MC uses lwjgl Keyboard,
// so using this also here should be ok.
final boolean help_available = (helpTranslationKey != null) && ModAuxiliaries.hasTranslation(helpTranslationKey + ".help");
final boolean tip_available = (advancedTooltipTranslationKey != null) && ModAuxiliaries.hasTranslation(helpTranslationKey + ".tip");
if((!help_available) && (!tip_available)) return false;
if(helpCondition()) {
if(!help_available) return false;
String s = localize(helpTranslationKey + ".help");
if(s.isEmpty()) return false;
tooltip.add(new StringTextComponent(s)); // @todo: check how to optimise that (to use TranslationTextComponent directly without compat losses)
return true;
} else if(extendedTipCondition()) {
if(!tip_available) return false;
String s = localize(advancedTooltipTranslationKey + ".tip");
if(s.isEmpty()) return false;
tooltip.add(new StringTextComponent(s));
return true;
} else if(addAdvancedTooltipHints) {
String s = "";
if(tip_available) s += localize(ModEngineersDecor.MODID + ".tooltip.hint.extended") + (help_available ? " " : "");
if(help_available) s += localize(ModEngineersDecor.MODID + ".tooltip.hint.help");
tooltip.add(new StringTextComponent(s));
}
return false;
}
/**
* Adds an extended tooltip or help tooltip for a given stack depending on the key states of CTRL and SHIFT.
* Format in the lang file is (e.g. for items): "item.MODID.REGISTRYNAME.tip" and "item.MODID.REGISTRYNAME.help".
* Return value see method pattern above.
*/
@OnlyIn(Dist.CLIENT)
public static boolean addInformation(ItemStack stack, @Nullable IBlockReader world, List<ITextComponent> tooltip, ITooltipFlag flag, boolean addAdvancedTooltipHints)
{ return addInformation(stack.getTranslationKey(), stack.getTranslationKey(), tooltip, flag, addAdvancedTooltipHints); }
}
public static final AxisAlignedBB getPixeledAABB(double x0, double y0, double z0, double x1, double y1, double z1)
{ return new AxisAlignedBB(x0/16.0, y0/16.0, z0/16.0, x1/16.0, y1/16.0, z1/16.0); }
public static final AxisAlignedBB getRotatedAABB(AxisAlignedBB bb, Direction new_facing, boolean horizontal_rotation)
{
if(!horizontal_rotation) {
switch(new_facing.getIndex()) {
case 0: return new AxisAlignedBB(1-bb.maxX, 1-bb.maxZ, 1-bb.maxY, 1-bb.minX, 1-bb.minZ, 1-bb.minY); // D
case 1: return new AxisAlignedBB(1-bb.maxX, bb.minZ, bb.minY, 1-bb.minX, bb.maxZ, bb.maxY); // U
case 2: return new AxisAlignedBB(1-bb.maxX, bb.minY, 1-bb.maxZ, 1-bb.minX, bb.maxY, 1-bb.minZ); // N
case 3: return new AxisAlignedBB( bb.minX, bb.minY, bb.minZ, bb.maxX, bb.maxY, bb.maxZ); // S --> bb
case 4: return new AxisAlignedBB(1-bb.maxZ, bb.minY, bb.minX, 1-bb.minZ, bb.maxY, bb.maxX); // W
case 5: return new AxisAlignedBB( bb.minZ, bb.minY, 1-bb.maxX, bb.maxZ, bb.maxY, 1-bb.minX); // E
}
} else {
switch(new_facing.getIndex()) {
case 0: return new AxisAlignedBB( bb.minX, bb.minY, bb.minZ, bb.maxX, bb.maxY, bb.maxZ); // D --> bb
case 1: return new AxisAlignedBB( bb.minX, bb.minY, bb.minZ, bb.maxX, bb.maxY, bb.maxZ); // U --> bb
case 2: return new AxisAlignedBB( bb.minX, bb.minY, bb.minZ, bb.maxX, bb.maxY, bb.maxZ); // N --> bb
case 3: return new AxisAlignedBB(1-bb.maxX, bb.minY, 1-bb.maxZ, 1-bb.minX, bb.maxY, 1-bb.minZ); // S
case 4: return new AxisAlignedBB( bb.minZ, bb.minY, 1-bb.maxX, bb.maxZ, bb.maxY, 1-bb.minX); // W
case 5: return new AxisAlignedBB(1-bb.maxZ, bb.minY, bb.minX, 1-bb.minZ, bb.maxY, bb.maxX); // E
}
}
return bb;
}
public static final boolean isModLoaded(final String registry_name)
{ return ModList.get().isLoaded(registry_name); }
public static final void logInfo(final String msg)
{ ModEngineersDecor.logger().info(msg); }
public static final void logWarn(final String msg)
{ ModEngineersDecor.logger().warn(msg); }
public static final void logError(final String msg)
{ ModEngineersDecor.logger().error(msg); }
@SuppressWarnings("unused")
public static void playerChatMessage(final PlayerEntity player, final String message)
{
String s = message.trim();
if(!s.isEmpty()) player.sendMessage(new TranslationTextComponent(s));
}
public static final boolean isDevelopmentMode()
{ return SharedConstants.developmentMode; }
public interface IExperimentalFeature {}
}

View file

@ -0,0 +1,501 @@
/*
* @file ModConfig.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2018 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)
*
* Main class for module settings. Handles reading and
* saving the config file.
*/
package wile.engineersdecor.detail;
import wile.engineersdecor.ModContent;
import wile.engineersdecor.ModEngineersDecor;
import net.minecraft.block.Block;
import net.minecraft.item.Item;
import net.minecraftforge.common.ForgeConfigSpec;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import org.apache.commons.lang3.tuple.Pair;
import wile.engineersdecor.blocks.*;
import javax.annotation.Nullable;
import java.util.ArrayList;
public class ModConfig
{
//--------------------------------------------------------------------------------------------------------------------
public static final CommonConfig COMMON;
public static final ServerConfig SERVER;
public static final ClientConfig CLIENT;
public static final ForgeConfigSpec COMMON_CONFIG_SPEC;
public static final ForgeConfigSpec SERVER_CONFIG_SPEC;
public static final ForgeConfigSpec CLIENT_CONFIG_SPEC;
static {
final Pair<CommonConfig, ForgeConfigSpec> common_ = (new ForgeConfigSpec.Builder()).configure(CommonConfig::new);
COMMON_CONFIG_SPEC = common_.getRight();
COMMON = common_.getLeft();
final Pair<ServerConfig, ForgeConfigSpec> server_ = (new ForgeConfigSpec.Builder()).configure(ServerConfig::new);
SERVER_CONFIG_SPEC = server_.getRight();
SERVER = server_.getLeft();
final Pair<ClientConfig, ForgeConfigSpec> client_ = (new ForgeConfigSpec.Builder()).configure(ClientConfig::new);
CLIENT_CONFIG_SPEC = client_.getRight();
CLIENT = client_.getLeft();
}
@SubscribeEvent
public static void onLoad(final net.minecraftforge.fml.config.ModConfig.Loading configEvent)
{ apply(); ModEngineersDecor.logger().info("Loaded config file {}", configEvent.getConfig().getFileName()); }
@SubscribeEvent
public static void onFileChange(final net.minecraftforge.fml.config.ModConfig.ConfigReloading configEvent)
{ ModEngineersDecor.logger().info("Config file changed {}", configEvent.getConfig().getFileName()); }
//--------------------------------------------------------------------------------------------------------------------
public static class ClientConfig
{
public final ForgeConfigSpec.BooleanValue without_tooltips;
ClientConfig(ForgeConfigSpec.Builder builder)
{
builder.comment("Settings not loaded on servers.")
.push("client");
// --- OPTOUTS ------------------------------------------------------------
{
builder.comment("Opt-out settings")
.push("optout");
without_tooltips = builder
.translation(ModEngineersDecor.MODID + ".config.without_tooltips")
.comment("Disable CTRL-SHIFT item tooltip display.")
.define("without_tooltips", false);
}
builder.pop();
}
}
//--------------------------------------------------------------------------------------------------------------------
public static class ServerConfig
{
ServerConfig(ForgeConfigSpec.Builder builder)
{
builder.comment("Settings not loaded on clients.")
.push("server");
builder.pop();
}
}
//--------------------------------------------------------------------------------------------------------------------
public static class CommonConfig
{
// Optout
public final ForgeConfigSpec.ConfigValue<String> pattern_excludes;
public final ForgeConfigSpec.ConfigValue<String> pattern_includes;
public final ForgeConfigSpec.BooleanValue without_clinker_bricks;
public final ForgeConfigSpec.BooleanValue without_slag_bricks;
public final ForgeConfigSpec.BooleanValue without_rebar_concrete;
public final ForgeConfigSpec.BooleanValue without_walls;
public final ForgeConfigSpec.BooleanValue without_stairs;
public final ForgeConfigSpec.BooleanValue without_ie_concrete_wall;
public final ForgeConfigSpec.BooleanValue without_panzer_glass;
public final ForgeConfigSpec.BooleanValue without_crafting_table;
public final ForgeConfigSpec.BooleanValue without_lab_furnace;
public final ForgeConfigSpec.BooleanValue without_electrical_furnace;
public final ForgeConfigSpec.BooleanValue without_treated_wood_furniture;
public final ForgeConfigSpec.BooleanValue without_windows;
public final ForgeConfigSpec.BooleanValue without_light_sources;
public final ForgeConfigSpec.BooleanValue without_ladders;
public final ForgeConfigSpec.BooleanValue without_chair_sitting;
public final ForgeConfigSpec.BooleanValue without_mob_chair_sitting;
public final ForgeConfigSpec.BooleanValue without_ladder_speed_boost;
public final ForgeConfigSpec.BooleanValue without_crafting_table_history;
public final ForgeConfigSpec.BooleanValue without_valves;
public final ForgeConfigSpec.BooleanValue without_passive_fluid_accumulator;
public final ForgeConfigSpec.BooleanValue without_waste_incinerator;
public final ForgeConfigSpec.BooleanValue without_sign_plates;
public final ForgeConfigSpec.BooleanValue without_factory_dropper;
public final ForgeConfigSpec.BooleanValue without_slabs;
public final ForgeConfigSpec.BooleanValue without_halfslabs;
public final ForgeConfigSpec.BooleanValue without_direct_slab_pickup;
public final ForgeConfigSpec.BooleanValue without_poles;
public final ForgeConfigSpec.BooleanValue without_hsupports;
// Misc
public final ForgeConfigSpec.BooleanValue with_experimental;
public final ForgeConfigSpec.BooleanValue without_recipes;
// Tweaks
public final ForgeConfigSpec.IntValue furnace_smelting_speed_percent;
public final ForgeConfigSpec.IntValue furnace_fuel_efficiency_percent;
public final ForgeConfigSpec.IntValue furnace_boost_energy_consumption;
public final ForgeConfigSpec.IntValue e_furnace_speed_percent;
public final ForgeConfigSpec.IntValue e_furnace_power_consumption;
public final ForgeConfigSpec.BooleanValue e_furnace_automatic_pulling;
public final ForgeConfigSpec.DoubleValue chair_mob_sitting_probability_percent;
public final ForgeConfigSpec.DoubleValue chair_mob_standup_probability_percent;
public final ForgeConfigSpec.BooleanValue with_crafting_quickmove_buttons;
public final ForgeConfigSpec.IntValue pipevalve_max_flowrate;
public final ForgeConfigSpec.IntValue pipevalve_redstone_gain;
CommonConfig(ForgeConfigSpec.Builder builder)
{
builder.comment("Settings affecting the logical server side, but are also configurable in single player.")
.push("server");
// --- OPTOUTS ------------------------------------------------------------
{
builder.comment("Opt-out settings")
.push("optout");
pattern_excludes = builder
.translation(ModEngineersDecor.MODID + ".config.pattern_excludes")
.comment("Opt-out any block by its registry name ('*' wildcard matching, "
+ "comma separated list, whitespaces ignored. You must match the whole name, "
+ "means maybe add '*' also at the begin and end. Example: '*wood*,*steel*' "
+ "excludes everything that has 'wood' or 'steel' in the registry name. "
+ "The matching result is also traced in the log file. ")
.define("pattern_excludes", "");
pattern_includes = builder
.translation(ModEngineersDecor.MODID + ".config.pattern_includes")
.comment("Prevent blocks from being opt'ed by registry name ('*' wildcard matching, "
+ "comma separated list, whitespaces ignored. Evaluated before all other opt-out checks. "
+ "You must match the whole name, means maybe add '*' also at the begin and end. Example: "
+ "'*wood*,*steel*' includes everything that has 'wood' or 'steel' in the registry name."
+ "The matching result is also traced in the log file.")
.define("pattern_includes", "");
without_clinker_bricks = builder
.translation(ModEngineersDecor.MODID + ".config.without_clinker_bricks")
.comment("Disable clinker bricks and derived blocks.")
.define("without_clinker_bricks", false);
without_slag_bricks = builder
.translation(ModEngineersDecor.MODID + ".config.without_slag_bricks")
.comment("Disable slag bricks and derived blocks.")
.define("without_slag_bricks", false);
without_rebar_concrete = builder
.translation(ModEngineersDecor.MODID + ".config.without_rebar_concrete")
.comment("Disable rebar concrete and derived blocks.")
.define("without_rebar_concrete", false);
without_walls = builder
.translation(ModEngineersDecor.MODID + ".config.without_walls")
.comment("Disable all mod wall blocks.")
.define("without_walls", false);
without_stairs = builder
.translation(ModEngineersDecor.MODID + ".config.without_stairs")
.comment("Disable all mod stairs blocks.")
.define("without_stairs", false);
without_ie_concrete_wall = builder
.translation(ModEngineersDecor.MODID + ".config.without_ie_concrete_wall")
.comment("Disable IE concrete wall.")
.define("without_ie_concrete_wall", false);
without_panzer_glass = builder
.translation(ModEngineersDecor.MODID + ".config.without_panzer_glass")
.comment("Disable panzer glass and derived blocks.")
.define("without_panzer_glass", false);
without_crafting_table = builder
.translation(ModEngineersDecor.MODID + ".config.without_crafting_table")
.comment("Disable treated wood crafting table.")
.define("without_crafting_table", false);
without_lab_furnace = builder
.translation(ModEngineersDecor.MODID + ".config.without_lab_furnace")
.comment("Disable small lab furnace.")
.define("without_lab_furnace", false);
without_electrical_furnace = builder
.translation(ModEngineersDecor.MODID + ".config.without_electrical_furnace")
.comment("Disable small electrical pass-through furnace.")
.define("without_electrical_furnace", false);
without_treated_wood_furniture = builder
.translation(ModEngineersDecor.MODID + ".config.without_treated_wood_furniture")
.comment("Disable treated wood table, stool, windowsill, etc.")
.define("without_treated_wood_furniture", false);
without_windows = builder
.translation(ModEngineersDecor.MODID + ".config.without_windows")
.comment("Disable treated wood window, etc.")
.define("without_windows", false);
without_light_sources = builder
.translation(ModEngineersDecor.MODID + ".config.without_light_sources")
.comment("Disable light sources")
.define("without_light_sources", false);
without_ladders = builder
.translation(ModEngineersDecor.MODID + ".config.without_ladders")
.comment("Disable ladders")
.define("without_ladders", false);
without_chair_sitting = builder
.translation(ModEngineersDecor.MODID + ".config.without_chair_sitting")
.comment("Disable possibility to sit on stools and chairs.")
.define("without_chair_sitting", false);
without_mob_chair_sitting = builder
.translation(ModEngineersDecor.MODID + ".config.without_mob_chair_sitting")
.comment("Disable that mobs will sit on chairs and stools.")
.define("without_mob_chair_sitting", false);
without_ladder_speed_boost = builder
.translation(ModEngineersDecor.MODID + ".config.without_ladder_speed_boost")
.comment("Disable the speed boost of ladders in this mod.")
.define("without_ladder_speed_boost", false);
without_crafting_table_history = builder
.translation(ModEngineersDecor.MODID + ".config.without_crafting_table_history")
.comment("Disable history refabrication feature of the treated wood crafting table.")
.define("without_crafting_table_history", false);
without_valves = builder
.translation(ModEngineersDecor.MODID + ".config.without_valves")
.comment("Disable check valve, and redstone controlled valves.")
.define("without_valves", false);
without_passive_fluid_accumulator = builder
.translation(ModEngineersDecor.MODID + ".config.without_passive_fluid_accumulator")
.comment("Disable the passive fluid accumulator.")
.define("without_passive_fluid_accumulator", false);
without_waste_incinerator = builder
.translation(ModEngineersDecor.MODID + ".config.without_waste_incinerator")
.comment("Disable item disposal/trash/void incinerator device.")
.define("without_waste_incinerator", false);
without_sign_plates = builder
.translation(ModEngineersDecor.MODID + ".config.without_sign_plates")
.comment("Disable decorative sign plates (caution, hazards, etc).")
.define("without_sign_plates", false);
without_factory_dropper = builder
.translation(ModEngineersDecor.MODID + ".config.without_factory_dropper")
.comment("Disable the factory dropper.")
.define("without_factory_dropper", false);
without_slabs = builder
.translation(ModEngineersDecor.MODID + ".config.without_slabs")
.comment("Disable horizontal half-block slab.")
.define("without_slabs", false);
without_halfslabs = builder
.translation(ModEngineersDecor.MODID + ".config.without_halfslabs")
.comment("Disable stackable 1/8 block slices.")
.define("without_halfslabs", false);
without_direct_slab_pickup = builder
.translation(ModEngineersDecor.MODID + ".config.without_direct_slab_pickup")
.comment("Disable directly picking up layers from slabs and slab " +
" slices by left clicking while looking up/down.")
.define("without_direct_slab_pickup", false);
without_poles = builder
.translation(ModEngineersDecor.MODID + ".config.without_poles")
.comment("Disable poles of any material.")
.define("without_poles", false);
without_hsupports = builder
.translation(ModEngineersDecor.MODID + ".config.without_hsupports")
.comment("Disable horizontal supports like the double-T support.")
.define("without_hsupports", false);
without_recipes = builder
.translation(ModEngineersDecor.MODID + ".config.without_recipes")
.comment("Disable all internal recipes, allowing to use alternative pack recipes.")
.define("without_recipes", false);
builder.pop();
}
// --- MISC ---------------------------------------------------------------
{
builder.comment("Miscellaneous settings")
.push("miscellaneous");
with_experimental = builder
.translation(ModEngineersDecor.MODID + ".config.with_experimental")
.comment("Enables experimental features. Use at own risk.")
.define("with_experimental", false);
builder.pop();
}
// --- TWEAKS -------------------------------------------------------------
{
builder.comment("Tweaks")
.push("tweaks");
furnace_smelting_speed_percent = builder
.translation(ModEngineersDecor.MODID + ".config.furnace_smelting_speed_percent")
.comment("Defines, in percent, how fast the lab furnace smelts compared to " +
"a vanilla furnace. 100% means vanilla furnace speed, 150% means the " +
"lab furnace is faster. The value can be changed on-the-fly for tuning.")
.defineInRange("furnace_smelting_speed_percent", 130, 50, 500);
furnace_fuel_efficiency_percent = builder
.translation(ModEngineersDecor.MODID + ".config.furnace_fuel_efficiency_percent")
.comment("Defines, in percent, how fuel efficient the lab furnace is, compared " +
"to a vanilla furnace. 100% means vanilla furnace consumiton, 200% means " +
"the lab furnace needs about half the fuel of a vanilla furnace, " +
"The value can be changed on-the-fly for tuning.")
.defineInRange("furnace_fuel_efficiency_percent", 100, 50, 250);
furnace_boost_energy_consumption = builder
.translation(ModEngineersDecor.MODID + ".config.furnace_boost_energy_consumption")
.comment("Defines the energy consumption (per tick) for speeding up the smelting process. " +
"If IE is installed, an external heater has to be inserted into an auxiliary slot " +
"of the lab furnace. The power source needs to be able to provide at least 4 times " +
"this consumption (fixed threshold value). The value can be changed on-the-fly for tuning. " +
"The default value corresponds to the IE heater consumption.")
.defineInRange("furnace_boost_energy_consumption", 24, 16, 256);
chair_mob_sitting_probability_percent = builder
.translation(ModEngineersDecor.MODID + ".config.chair_mob_sitting_probability_percent")
.comment("Defines, in percent, how high the probability is that a mob sits on a chair " +
"when colliding with it. Can be changed on-the-fly for tuning.")
.defineInRange("chair_mob_sitting_probability_percent", 10.0, 0.0, 80.0);
chair_mob_standup_probability_percent = builder
.translation(ModEngineersDecor.MODID + ".config.chair_mob_standup_probability_percent")
.comment("Defines, in percent, probable it is that a mob leaves a chair when sitting " +
"on it. The 'dice is rolled' about every 20 ticks. There is also a minimum " +
"Sitting time of about 3s. The config value can be changed on-the-fly for tuning.")
.defineInRange("chair_mob_standup_probability_percent", 1.0, 1e-3, 10.0);
with_crafting_quickmove_buttons = builder
.translation(ModEngineersDecor.MODID + ".config.with_crafting_quickmove_buttons")
.comment("Enables small quick-move arrows from/to player/block storage. " +
"Makes the UI a bit too busy, therefore disabled by default.")
.define("with_crafting_quickmove_buttons", false);
pipevalve_max_flowrate = builder
.translation(ModEngineersDecor.MODID + ".config.pipevalve_max_flowrate")
.comment("Defines how many millibuckets can be transferred (per tick) through the valves. " +
"That is technically the 'storage size' specified for blocks that want to fill " +
"fluids into the valve (the valve has no container and forward that to the output " +
"block), The value can be changed on-the-fly for tuning. ")
.defineInRange("pipevalve_max_flowrate", 1000, 1, 10000);
pipevalve_redstone_gain = builder
.translation(ModEngineersDecor.MODID + ".config.pipevalve_redstone_gain")
.comment("Defines how many millibuckets per redstone signal strength can be transferred per tick " +
"through the analog redstone controlled valves. Note: power 0 is always off, power 15 is always " +
"the max flow rate. Between power 1 and 14 this scaler will result in a flow = 'redstone slope' * 'current redstone power'. " +
"The value can be changed on-the-fly for tuning. ")
.defineInRange("pipevalve_redstone_gain", 20, 1, 10000);
e_furnace_speed_percent = builder
.translation(ModEngineersDecor.MODID + ".config.e_furnace_speed_percent")
.comment("Defines, in percent, how fast the electrical furnace smelts compared to " +
"a vanilla furnace. 100% means vanilla furnace speed, 150% means the " +
"electrical furnace is faster. The value can be changed on-the-fly for tuning.")
.defineInRange("e_furnace_speed_percent", BlockDecorFurnaceElectrical.BTileEntity.DEFAULT_SPEED_PERCENT, 50, 500);
e_furnace_power_consumption = builder
.translation(ModEngineersDecor.MODID + ".config.e_furnace_power_consumption")
.comment("Defines how much RF per tick the the electrical furnace consumed (average) for smelting. " +
"The feeders transferring items from/to adjacent have this consumption/8 for each stack transaction. " +
"The default value is only slightly higher than a furnace with an IE external heater (and no burning fuel inside)." +
"The config value can be changed on-the-fly for tuning.")
.defineInRange("e_furnace_power_consumption", BlockDecorFurnaceElectrical.BTileEntity.DEFAULT_ENERGY_CONSUMPTION, 10, 256);
e_furnace_automatic_pulling = builder
.translation(ModEngineersDecor.MODID + ".config.e_furnace_automatic_pulling")
.comment("Defines if the electrical furnace automatically pulls items from an inventory at the input side." +
"The config value can be changed on-the-fly for tuning.")
.define("e_furnace_automatic_pulling", false);
builder.pop();
}
}
}
//--------------------------------------------------------------------------------------------------------------------
// Optout checks
//--------------------------------------------------------------------------------------------------------------------
public static final boolean isOptedOut(final @Nullable Block block)
{ return isOptedOut(block, false); }
public static final boolean isOptedOut(final @Nullable Block block, boolean with_log_details)
{
if(block == null) return true;
if(block == ModContent.SIGN_MODLOGO) return true;
if(COMMON == null) return false;
try {
if(!COMMON.with_experimental.get()) {
if(block instanceof ModAuxiliaries.IExperimentalFeature) return true;
if(ModContent.isExperimentalBlock(block)) return true;
}
final String rn = block.getRegistryName().getPath();
// Hard IE dependent blocks
if(!immersiveengineering_installed) {
if(block == ModContent.CONCRETE_WALL) return true;
if((block instanceof BlockDecor) && ((((BlockDecor)block).config & BlockDecor.CFG_HARD_IE_DEPENDENT) != 0)) return true;
}
// Force-include/exclude pattern matching
try {
for(String e:includes_) {
if(rn.matches(e)) {
if(with_log_details) ModEngineersDecor.logger().info("Optout force include: " + rn);
return false;
}
}
for(String e:excludes_) {
if(rn.matches(e)) {
if(with_log_details) ModEngineersDecor.logger().info("Optout force exclude: " + rn);
return true;
}
}
} catch(Throwable ex) {
ModEngineersDecor.logger().error("optout include pattern failed, disabling.");
includes_.clear();
excludes_.clear();
}
// Early non-opt out type based evaluation
if(block instanceof BlockDecorCraftingTable) return COMMON.without_crafting_table.get();
if(block instanceof BlockDecorFurnaceElectrical) return COMMON.without_electrical_furnace.get();
if((block instanceof BlockDecorFurnace) && (!(block instanceof BlockDecorFurnaceElectrical))) return COMMON.without_lab_furnace.get();
if(block instanceof BlockDecorPassiveFluidAccumulator) return COMMON.without_passive_fluid_accumulator.get();
if(block instanceof BlockDecorWasteIncinerator) return COMMON.without_waste_incinerator.get();
if(block instanceof BlockDecorDropper) return COMMON.without_factory_dropper.get();
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 BlockDecorHorizontalSupport) return COMMON.without_hsupports.get();
// Type based evaluation where later filters may match, too
if(COMMON.without_slabs.get() && (block instanceof BlockDecorSlab)) return true;
if(COMMON.without_stairs.get() && (block instanceof BlockDecorStairs)) return true;
if(COMMON.without_walls.get() && (block instanceof BlockDecorWall)) return true;
if(COMMON.without_poles.get() && (block instanceof BlockDecorStraightPole)) return true;
// String matching based evaluation
if(COMMON.without_clinker_bricks.get() && (rn.startsWith("clinker_brick_"))) return true;
if(COMMON.without_slag_bricks.get() && rn.startsWith("slag_brick_")) return true;
if(COMMON.without_rebar_concrete.get() && rn.startsWith("rebar_concrete")) return true;
if(COMMON.without_ie_concrete_wall.get() && rn.startsWith("concrete_wall")) return true;
if(COMMON.without_panzer_glass.get() && rn.startsWith("panzerglass_")) return true;
if(COMMON.without_light_sources.get() && rn.endsWith("_light")) return true;
if(COMMON.without_sign_plates.get() && rn.startsWith("sign_")) return true;
if(COMMON.without_treated_wood_furniture.get()) {
if(block instanceof BlockDecorChair) return true;
if(rn.equals("treated_wood_table")) return true;
if(rn.equals("treated_wood_stool")) return true;
if(rn.equals("treated_wood_windowsill")) return true;
}
} catch(Exception ex) {
ModEngineersDecor.logger().error("Exception evaluating the optout config: '" + ex.getMessage() + "'");
}
return false;
}
public static final boolean isOptedOut(final @Nullable Item item)
{
if(item == null) return true;
if(SERVER == null) return false;
return false;
}
//--------------------------------------------------------------------------------------------------------------------
// Cache
//--------------------------------------------------------------------------------------------------------------------
private static final ArrayList<String> includes_ = new ArrayList<String>();
private static final ArrayList<String> excludes_ = new ArrayList<String>();
public static boolean without_crafting_table = false;
public static boolean immersiveengineering_installed = false;
public static final void apply()
{
BlockDecorFurnace.BTileEntity.on_config(COMMON.furnace_smelting_speed_percent.get(), COMMON.furnace_fuel_efficiency_percent.get(), COMMON.furnace_boost_energy_consumption.get());
BlockDecorChair.on_config(COMMON.without_chair_sitting.get(), COMMON.without_mob_chair_sitting.get(), COMMON.chair_mob_sitting_probability_percent.get(), COMMON.chair_mob_standup_probability_percent.get());
BlockDecorLadder.on_config(COMMON.without_ladder_speed_boost.get());
BlockDecorCraftingTable.on_config(COMMON.without_crafting_table_history.get(), false, COMMON.with_crafting_quickmove_buttons.get());
BlockDecorPipeValve.on_config(COMMON.pipevalve_max_flowrate.get(), COMMON.pipevalve_redstone_gain.get());
BlockDecorFurnaceElectrical.BTileEntity.on_config(COMMON.e_furnace_speed_percent.get(), COMMON.e_furnace_power_consumption.get(), COMMON.e_furnace_automatic_pulling.get());
without_crafting_table = isOptedOut(ModContent.TREATED_WOOD_CRAFTING_TABLE);
immersiveengineering_installed = ModAuxiliaries.isModLoaded("immersiveengineering");
{
String inc = COMMON.pattern_includes.get().toLowerCase().replaceAll(ModEngineersDecor.MODID+":", "").replaceAll("[^*_,a-z0-9]", "");
if(COMMON.pattern_includes.get() != inc) COMMON.pattern_includes.set(inc);
if(!inc.isEmpty()) ModEngineersDecor.logger().info("Pattern includes: '" + inc + "'");
String[] incl = inc.split(",");
includes_.clear();
for(int i=0; i< incl.length; ++i) {
incl[i] = incl[i].replaceAll("[*]", ".*?");
if(!incl[i].isEmpty()) includes_.add(incl[i]);
}
}
{
String exc = COMMON.pattern_includes.get().toLowerCase().replaceAll(ModEngineersDecor.MODID+":", "").replaceAll("[^*_,a-z0-9]", "");
if(!exc.isEmpty()) ModEngineersDecor.logger().info("Pattern excludes: '" + exc + "'");
String[] excl = exc.split(",");
excludes_.clear();
for(int i=0; i< excl.length; ++i) {
excl[i] = excl[i].replaceAll("[*]", ".*?");
if(!excl[i].isEmpty()) excludes_.add(excl[i]);
}
}
}
}

View file

@ -0,0 +1,245 @@
/*
* @file Networking.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2019 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)
*
* Main client/server message handling.
*/
package wile.engineersdecor.detail;
import wile.engineersdecor.ModEngineersDecor;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.common.util.FakePlayer;
import net.minecraftforge.fml.network.NetworkEvent;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.world.World;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.inventory.container.Container;
import net.minecraft.network.PacketBuffer;
import net.minecraftforge.fml.network.NetworkRegistry;
import net.minecraftforge.fml.network.simple.SimpleChannel;
import net.minecraftforge.fml.network.NetworkDirection;
import java.util.function.Supplier;
public class Networking
{
private static final String PROTOCOL = "1";
private static final SimpleChannel DEFAULT_CHANNEL = NetworkRegistry.ChannelBuilder
.named(new ResourceLocation(ModEngineersDecor.MODID, "default_ch"))
.clientAcceptedVersions(PROTOCOL::equals).serverAcceptedVersions(PROTOCOL::equals).networkProtocolVersion(() -> PROTOCOL)
.simpleChannel();
public static void init()
{
int discr = -1;
DEFAULT_CHANNEL.registerMessage(++discr, PacketTileNotifyClientToServer.class, PacketTileNotifyClientToServer::compose, PacketTileNotifyClientToServer::parse, PacketTileNotifyClientToServer.Handler::handle);
DEFAULT_CHANNEL.registerMessage(++discr, PacketTileNotifyServerToClient.class, PacketTileNotifyServerToClient::compose, PacketTileNotifyServerToClient::parse, PacketTileNotifyServerToClient.Handler::handle);
DEFAULT_CHANNEL.registerMessage(++discr, PacketContainerSyncClientToServer.class, PacketContainerSyncClientToServer::compose, PacketContainerSyncClientToServer::parse, PacketContainerSyncClientToServer.Handler::handle);
DEFAULT_CHANNEL.registerMessage(++discr, PacketContainerSyncServerToClient.class, PacketContainerSyncServerToClient::compose, PacketContainerSyncServerToClient::parse, PacketContainerSyncServerToClient.Handler::handle);
}
//--------------------------------------------------------------------------------------------------------------------
// Tile entity notifications
//--------------------------------------------------------------------------------------------------------------------
public interface IPacketTileNotifyReceiver
{
default void onServerPacketReceived(CompoundNBT nbt) {}
default void onClientPacketReceived(PlayerEntity player, CompoundNBT nbt) {}
}
public static class PacketTileNotifyClientToServer
{
CompoundNBT nbt = null;
BlockPos pos = BlockPos.ZERO;
public static void sendToServer(BlockPos pos, CompoundNBT nbt)
{ if((pos!=null) && (nbt!=null)) DEFAULT_CHANNEL.sendToServer(new PacketTileNotifyClientToServer(pos, nbt)); }
public static void sendToServer(TileEntity te, CompoundNBT nbt)
{ if((te!=null) && (nbt!=null)) DEFAULT_CHANNEL.sendToServer(new PacketTileNotifyClientToServer(te, nbt)); }
public PacketTileNotifyClientToServer()
{}
public PacketTileNotifyClientToServer(BlockPos pos, CompoundNBT nbt)
{ this.nbt = nbt; this.pos = pos; }
public PacketTileNotifyClientToServer(TileEntity te, CompoundNBT nbt)
{ this.nbt = nbt; pos = te.getPos(); }
public static PacketTileNotifyClientToServer parse(final PacketBuffer buf)
{ return new PacketTileNotifyClientToServer(buf.readBlockPos(), buf.readCompoundTag()); }
public static void compose(final PacketTileNotifyClientToServer pkt, final PacketBuffer buf)
{ buf.writeBlockPos(pkt.pos); buf.writeCompoundTag(pkt.nbt); }
public static class Handler
{
public static void handle(final PacketTileNotifyClientToServer pkt, final Supplier<NetworkEvent.Context> ctx)
{
ctx.get().enqueueWork(() -> {
PlayerEntity player = ctx.get().getSender();
World world = player.world;
if(world == null) return;
final TileEntity te = world.getTileEntity(pkt.pos);
if(!(te instanceof IPacketTileNotifyReceiver)) return;
((IPacketTileNotifyReceiver)te).onClientPacketReceived(ctx.get().getSender(), pkt.nbt);
});
ctx.get().setPacketHandled(true);
}
}
}
public static class PacketTileNotifyServerToClient
{
CompoundNBT nbt = null;
BlockPos pos = BlockPos.ZERO;
public static void sendToPlayer(PlayerEntity player, TileEntity te, CompoundNBT nbt)
{
if((!(player instanceof ServerPlayerEntity)) || (player instanceof FakePlayer) || (te==null) || (nbt==null)) return;
DEFAULT_CHANNEL.sendTo(new PacketTileNotifyServerToClient(te, nbt), ((ServerPlayerEntity)player).connection.netManager, NetworkDirection.PLAY_TO_CLIENT);
}
public PacketTileNotifyServerToClient()
{}
public PacketTileNotifyServerToClient(BlockPos pos, CompoundNBT nbt)
{ this.nbt=nbt; this.pos=pos; }
public PacketTileNotifyServerToClient(TileEntity te, CompoundNBT nbt)
{ this.nbt=nbt; pos=te.getPos(); }
public static PacketTileNotifyServerToClient parse(final PacketBuffer buf)
{ return new PacketTileNotifyServerToClient(buf.readBlockPos(), buf.readCompoundTag()); }
public static void compose(final PacketTileNotifyServerToClient pkt, final PacketBuffer buf)
{ buf.writeBlockPos(pkt.pos); buf.writeCompoundTag(pkt.nbt); }
public static class Handler
{
public static void handle(final PacketTileNotifyServerToClient pkt, final Supplier<NetworkEvent.Context> ctx)
{
ctx.get().enqueueWork(() -> {
World world = ModEngineersDecor.proxy.getWorldClientSide();
if(world == null) return;
final TileEntity te = world.getTileEntity(pkt.pos);
if(!(te instanceof IPacketTileNotifyReceiver)) return;
((IPacketTileNotifyReceiver)te).onServerPacketReceived(pkt.nbt);
});
ctx.get().setPacketHandled(true);
}
}
}
//--------------------------------------------------------------------------------------------------------------------
// (GUI) Container synchrsonisation
//--------------------------------------------------------------------------------------------------------------------
public interface INetworkSynchronisableContainer
{
void onServerPacketReceived(int windowId, CompoundNBT nbt);
void onClientPacketReceived(int windowId, PlayerEntity player, CompoundNBT nbt);
}
public static class PacketContainerSyncClientToServer
{
int id = -1;
CompoundNBT nbt = null;
public static void sendToServer(int windowId, CompoundNBT nbt)
{ if(nbt!=null) DEFAULT_CHANNEL.sendToServer(new PacketContainerSyncClientToServer(windowId, nbt)); }
public static void sendToServer(Container container, CompoundNBT nbt)
{ if(nbt!=null) DEFAULT_CHANNEL.sendToServer(new PacketContainerSyncClientToServer(container.windowId, nbt)); }
public PacketContainerSyncClientToServer()
{}
public PacketContainerSyncClientToServer(int id, CompoundNBT nbt)
{ this.nbt = nbt; this.id = id; }
public static PacketContainerSyncClientToServer parse(final PacketBuffer buf)
{ return new PacketContainerSyncClientToServer(buf.readInt(), buf.readCompoundTag()); }
public static void compose(final PacketContainerSyncClientToServer pkt, final PacketBuffer buf)
{ buf.writeInt(pkt.id); buf.writeCompoundTag(pkt.nbt); }
public static class Handler
{
public static void handle(final PacketContainerSyncClientToServer pkt, final Supplier<NetworkEvent.Context> ctx)
{
ctx.get().enqueueWork(() -> {
PlayerEntity player = ctx.get().getSender();
if(!(player.openContainer instanceof INetworkSynchronisableContainer)) return;
if(player.openContainer.windowId != pkt.id) return;
((INetworkSynchronisableContainer)player.openContainer).onClientPacketReceived(pkt.id, player,pkt.nbt);
});
ctx.get().setPacketHandled(true);
}
}
}
public static class PacketContainerSyncServerToClient
{
int id = -1;
CompoundNBT nbt = null;
public static void sendToPlayer(PlayerEntity player, int windowId, CompoundNBT nbt)
{
if((!(player instanceof ServerPlayerEntity)) || (player instanceof FakePlayer) || (nbt==null)) return;
DEFAULT_CHANNEL.sendTo(new PacketContainerSyncServerToClient(windowId, nbt), ((ServerPlayerEntity)player).connection.netManager, NetworkDirection.PLAY_TO_CLIENT);
}
public static void sendToPlayer(PlayerEntity player, Container container, CompoundNBT nbt)
{
if((!(player instanceof ServerPlayerEntity)) || (player instanceof FakePlayer) || (nbt==null)) return;
DEFAULT_CHANNEL.sendTo(new PacketContainerSyncServerToClient(container.windowId, nbt), ((ServerPlayerEntity)player).connection.netManager, NetworkDirection.PLAY_TO_CLIENT);
}
// Container listners are private, and add/remove listener overriding seems not too nice, as
// removeListner is client only???
//public static <C extends Container & INetworkSynchronisableContainer> void sendToListeners(C container, CompoundNBT nbt)
//{
// for(IContainerListener listener: container.getListeners()) {
// if(!(listener instanceof ServerPlayerEntity)) continue;
// DEFAULT_CHANNEL.sendTo(new PacketContainerSyncServerToClient(container.windowId, nbt), ((ServerPlayerEntity)listener).connection.netManager, NetworkDirection.PLAY_TO_CLIENT);
// }
//}
public PacketContainerSyncServerToClient()
{}
public PacketContainerSyncServerToClient(int id, CompoundNBT nbt)
{ this.nbt=nbt; this.id=id; }
public static PacketContainerSyncServerToClient parse(final PacketBuffer buf)
{ return new PacketContainerSyncServerToClient(buf.readInt(), buf.readCompoundTag()); }
public static void compose(final PacketContainerSyncServerToClient pkt, final PacketBuffer buf)
{ buf.writeInt(pkt.id); buf.writeCompoundTag(pkt.nbt); }
public static class Handler
{
public static void handle(final PacketContainerSyncServerToClient pkt, final Supplier<NetworkEvent.Context> ctx)
{
ctx.get().enqueueWork(() -> {
PlayerEntity player = ModEngineersDecor.proxy.getPlayerClientSide();
if(!(player.openContainer instanceof INetworkSynchronisableContainer)) return;
if(player.openContainer.windowId != pkt.id) return;
((INetworkSynchronisableContainer)player.openContainer).onServerPacketReceived(pkt.id,pkt.nbt);
});
ctx.get().setPacketHandled(true);
}
}
}
}

View file

@ -0,0 +1,70 @@
/*
* @file RecipeCondRegistered.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2018 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)
*
* Recipe condition to enable opt'ing out JSON based recipes, referenced
* in assets/engineersdecor/recipes/_factories.json with full path (therefore
* I had to make a separate file for that instead of a few lines in
* ModAuxiliaries).
*/
package wile.engineersdecor.detail;
import net.minecraft.block.Block;
import net.minecraft.item.Item;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.common.crafting.IConditionSerializer;
import net.minecraftforge.registries.IForgeRegistry;
import net.minecraftforge.registries.ForgeRegistries;
import com.google.gson.*;
import javax.annotation.Nullable;
import javax.annotation.Nonnull;
import java.util.function.BooleanSupplier;
public class RecipeCondModSpecific implements IConditionSerializer
{
public static final BooleanSupplier RECIPE_INCLUDE = ()->true;
public static final BooleanSupplier RECIPE_EXCLUDE = ()->false;
@Override
public @Nonnull BooleanSupplier parse(@Nullable JsonObject json) {
try {
if(json==null) return RECIPE_EXCLUDE;
final IForgeRegistry<Block> block_registry = ForgeRegistries.BLOCKS;
final IForgeRegistry<Item> item_registry = ForgeRegistries.ITEMS;
final JsonArray items = json.getAsJsonArray("required");
if(items!=null) {
for(JsonElement e: items) {
if(!e.isJsonPrimitive()) continue;
final ResourceLocation rl = new ResourceLocation(((JsonPrimitive)e).getAsString());
if((!block_registry.containsKey(rl)) && (!item_registry.containsKey(rl))) return RECIPE_EXCLUDE; // required item not registered
}
}
final JsonPrimitive result = json.getAsJsonPrimitive("result");
if(result != null) {
final ResourceLocation rl = new ResourceLocation(result.getAsString());
if((!block_registry.containsKey(rl)) && (!item_registry.containsKey(rl))) return RECIPE_EXCLUDE; // required result not registered
}
final JsonArray missing = json.getAsJsonArray("missing");
if((missing!=null) && (missing.size() > 0)) {
for(JsonElement e: missing) {
if(!e.isJsonPrimitive()) continue;
final ResourceLocation rl = new ResourceLocation(((JsonPrimitive)e).getAsString());
// At least one item missing, enable this recipe as alternative recipe for another one that check the missing item as required item.
// --> e.g. if IE not installed there is no slag. One recipe requires slag, and another one (for the same result) is used if there
// is no slag.
if((!block_registry.containsKey(rl)) && (!item_registry.containsKey(rl))) return RECIPE_INCLUDE;
}
return RECIPE_EXCLUDE; // all required there, but there is no item missing, so another recipe
} else {
return RECIPE_INCLUDE; // no missing given, means include if result and required are all there.
}
} catch(Throwable ex) {
ModAuxiliaries.logError("rsgauges::ResultRegisteredCondition failed: " + ex.toString());
}
return RECIPE_EXCLUDE; // skip on exception.
}
}

View file

@ -0,0 +1,63 @@
/*
* @file JEIPlugin.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2019 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)
*
* JEI plugin (see https://github.com/mezz/JustEnoughItems/wiki/Creating-Plugins)
*/
package wile.engineersdecor.eapi.jei;
import mezz.jei.api.constants.VanillaRecipeCategoryUid;
import mezz.jei.api.registration.IRecipeTransferRegistration;
import wile.engineersdecor.ModEngineersDecor;
import wile.engineersdecor.blocks.BlockDecorCraftingTable;
import wile.engineersdecor.detail.ModConfig;
import wile.engineersdecor.ModContent;
import mezz.jei.api.constants.VanillaTypes;
import mezz.jei.api.runtime.IJeiRuntime;
import net.minecraft.block.Block;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import java.util.ArrayList;
import java.util.List;
@mezz.jei.api.JeiPlugin
public class JEIPlugin implements mezz.jei.api.IModPlugin
{
@Override
public ResourceLocation getPluginUid()
{ return new ResourceLocation(ModEngineersDecor.MODID, "jei_plugin_uid"); }
@Override
public void registerRecipeTransferHandlers(IRecipeTransferRegistration registration)
{
if(!ModConfig.without_crafting_table) {
try {
registration.addRecipeTransferHandler(
BlockDecorCraftingTable.BContainer.class,
VanillaRecipeCategoryUid.CRAFTING,
1, 9, 10, 44
);
} catch(Throwable e) {
ModEngineersDecor.logger().warn("Exception in JEI crafting table handler registration: '" + e.getMessage() + "'.");
}
}
}
@Override
public void onRuntimeAvailable(IJeiRuntime jeiRuntime)
{
List<ItemStack> blacklisted = new ArrayList<>();
for(Block e: ModContent.getRegisteredBlocks()) {
if(ModConfig.isOptedOut(e)) {
blacklisted.add(new ItemStack(e.asItem()));
}
}
try {
jeiRuntime.getIngredientManager().removeIngredientsAtRuntime(VanillaTypes.ITEM, blacklisted);
} catch(Exception e) {
ModEngineersDecor.logger().warn("Exception in JEI opt-out processing: '" + e.getMessage() + "', skipping further JEI optout processing.");
}
}
}

View file

@ -0,0 +1,31 @@
# @file mods.toml
# @spec TOML v0.5.0 (https://github.com/toml-lang/toml)
modLoader="javafml" # forge FML java
loaderVersion="[25,)"
issueTrackerURL="https://github.com/stfwi/engineers-decor/issues/"
[[mods]]
modId="engineersdecor"
version="${file.jarVersion}"
displayName="Engineer's Decor"
description="Adds cosmetic blocks for the engineer's workshop, factory and home."
authors="wilechaote"
credits="BluSunrize, malte0811, et al., the Forge Smiths, the Modders of the World."
updateJSONURL="https://raw.githubusercontent.com/stfwi/engineers-decor/develop/meta/update.json"
displayURL="https://github.com/stfwi/engineers-decor/"
logoFile="engineersdecor.png" # Double check: A file name (in the root of the mod JAR) containing a logo for display
[[dependencies.engineersdecor]]
modId="forge"
mandatory=true
versionRange="[25,)" #mandatory
ordering="NONE"
side="BOTH"
[[dependencies.engineersdecor]]
modId="minecraft"
mandatory=true
versionRange="[1.14.4]"
ordering="NONE"
side="BOTH"

View file

@ -0,0 +1,14 @@
{
"variants": {
"": [
{ "model": "engineersdecor:block/brick/clinker_brick_model0" },
{ "model": "engineersdecor:block/brick/clinker_brick_model1" },
{ "model": "engineersdecor:block/brick/clinker_brick_model2" },
{ "model": "engineersdecor:block/brick/clinker_brick_model3" },
{ "model": "engineersdecor:block/brick/clinker_brick_model4" },
{ "model": "engineersdecor:block/brick/clinker_brick_model5" },
{ "model": "engineersdecor:block/brick/clinker_brick_model6" },
{ "model": "engineersdecor:block/brick/clinker_brick_model7" }
]
}
}

View file

@ -0,0 +1,40 @@
{
"variants": {
"parts=0,tvariant=0": {
"model": "engineersdecor:block/slab/specific/clinker_brick_slab_s0v0_model"
},
"parts=0,tvariant=1": {
"model": "engineersdecor:block/slab/specific/clinker_brick_slab_s0v1_model"
},
"parts=0,tvariant=2": {
"model": "engineersdecor:block/slab/specific/clinker_brick_slab_s0v2_model"
},
"parts=0,tvariant=3": {
"model": "engineersdecor:block/slab/specific/clinker_brick_slab_s0v3_model"
},
"parts=1,tvariant=0": {
"model": "engineersdecor:block/slab/specific/clinker_brick_slab_s1v0_model"
},
"parts=1,tvariant=1": {
"model": "engineersdecor:block/slab/specific/clinker_brick_slab_s1v1_model"
},
"parts=1,tvariant=2": {
"model": "engineersdecor:block/slab/specific/clinker_brick_slab_s1v2_model"
},
"parts=1,tvariant=3": {
"model": "engineersdecor:block/slab/specific/clinker_brick_slab_s1v3_model"
},
"parts=2,tvariant=0": {
"model": "engineersdecor:block/slab/specific/clinker_brick_slab_s2v0_model"
},
"parts=2,tvariant=1": {
"model": "engineersdecor:block/slab/specific/clinker_brick_slab_s2v1_model"
},
"parts=2,tvariant=2": {
"model": "engineersdecor:block/slab/specific/clinker_brick_slab_s2v2_model"
},
"parts=2,tvariant=3": {
"model": "engineersdecor:block/slab/specific/clinker_brick_slab_s2v3_model"
}
}
}

View file

@ -0,0 +1,14 @@
{
"variants": {
"": [
{ "model": "engineersdecor:block/brick/clinker_brick_stained_model0" },
{ "model": "engineersdecor:block/brick/clinker_brick_stained_model1" },
{ "model": "engineersdecor:block/brick/clinker_brick_stained_model2" },
{ "model": "engineersdecor:block/brick/clinker_brick_stained_model3" },
{ "model": "engineersdecor:block/brick/clinker_brick_stained_model4" },
{ "model": "engineersdecor:block/brick/clinker_brick_stained_model5" },
{ "model": "engineersdecor:block/brick/clinker_brick_stained_model6" },
{ "model": "engineersdecor:block/brick/clinker_brick_stained_model7" }
]
}
}

View file

@ -0,0 +1,40 @@
{
"variants": {
"parts=0,tvariant=0": {
"model": "engineersdecor:block/slab/specific/clinker_brick_stained_slab_s0v0_model"
},
"parts=0,tvariant=1": {
"model": "engineersdecor:block/slab/specific/clinker_brick_stained_slab_s0v1_model"
},
"parts=0,tvariant=2": {
"model": "engineersdecor:block/slab/specific/clinker_brick_stained_slab_s0v2_model"
},
"parts=0,tvariant=3": {
"model": "engineersdecor:block/slab/specific/clinker_brick_stained_slab_s0v3_model"
},
"parts=1,tvariant=0": {
"model": "engineersdecor:block/slab/specific/clinker_brick_stained_slab_s1v0_model"
},
"parts=1,tvariant=1": {
"model": "engineersdecor:block/slab/specific/clinker_brick_stained_slab_s1v1_model"
},
"parts=1,tvariant=2": {
"model": "engineersdecor:block/slab/specific/clinker_brick_stained_slab_s1v2_model"
},
"parts=1,tvariant=3": {
"model": "engineersdecor:block/slab/specific/clinker_brick_stained_slab_s1v3_model"
},
"parts=2,tvariant=0": {
"model": "engineersdecor:block/slab/specific/clinker_brick_stained_slab_s2v0_model"
},
"parts=2,tvariant=1": {
"model": "engineersdecor:block/slab/specific/clinker_brick_stained_slab_s2v1_model"
},
"parts=2,tvariant=2": {
"model": "engineersdecor:block/slab/specific/clinker_brick_stained_slab_s2v2_model"
},
"parts=2,tvariant=3": {
"model": "engineersdecor:block/slab/specific/clinker_brick_stained_slab_s2v3_model"
}
}
}

View file

@ -0,0 +1,44 @@
{
"variants": {
"facing=east,half=bottom,shape=straight": { "model": "engineersdecor:block/brick/clinker_brick_stained_stairs" },
"facing=west,half=bottom,shape=straight": { "model": "engineersdecor:block/brick/clinker_brick_stained_stairs", "y": 180, "uvlock": true },
"facing=south,half=bottom,shape=straight": { "model": "engineersdecor:block/brick/clinker_brick_stained_stairs", "y": 90, "uvlock": true },
"facing=north,half=bottom,shape=straight": { "model": "engineersdecor:block/brick/clinker_brick_stained_stairs", "y": 270, "uvlock": true },
"facing=east,half=bottom,shape=outer_right": { "model": "engineersdecor:block/brick/clinker_brick_stained_stairs_outer" },
"facing=west,half=bottom,shape=outer_right": { "model": "engineersdecor:block/brick/clinker_brick_stained_stairs_outer", "y": 180, "uvlock": true },
"facing=south,half=bottom,shape=outer_right": { "model": "engineersdecor:block/brick/clinker_brick_stained_stairs_outer", "y": 90, "uvlock": true },
"facing=north,half=bottom,shape=outer_right": { "model": "engineersdecor:block/brick/clinker_brick_stained_stairs_outer", "y": 270, "uvlock": true },
"facing=east,half=bottom,shape=outer_left": { "model": "engineersdecor:block/brick/clinker_brick_stained_stairs_outer", "y": 270, "uvlock": true },
"facing=west,half=bottom,shape=outer_left": { "model": "engineersdecor:block/brick/clinker_brick_stained_stairs_outer", "y": 90, "uvlock": true },
"facing=south,half=bottom,shape=outer_left": { "model": "engineersdecor:block/brick/clinker_brick_stained_stairs_outer" },
"facing=north,half=bottom,shape=outer_left": { "model": "engineersdecor:block/brick/clinker_brick_stained_stairs_outer", "y": 180, "uvlock": true },
"facing=east,half=bottom,shape=inner_right": { "model": "engineersdecor:block/brick/clinker_brick_stained_stairs_inner" },
"facing=west,half=bottom,shape=inner_right": { "model": "engineersdecor:block/brick/clinker_brick_stained_stairs_inner", "y": 180, "uvlock": true },
"facing=south,half=bottom,shape=inner_right": { "model": "engineersdecor:block/brick/clinker_brick_stained_stairs_inner", "y": 90, "uvlock": true },
"facing=north,half=bottom,shape=inner_right": { "model": "engineersdecor:block/brick/clinker_brick_stained_stairs_inner", "y": 270, "uvlock": true },
"facing=east,half=bottom,shape=inner_left": { "model": "engineersdecor:block/brick/clinker_brick_stained_stairs_inner", "y": 270, "uvlock": true },
"facing=west,half=bottom,shape=inner_left": { "model": "engineersdecor:block/brick/clinker_brick_stained_stairs_inner", "y": 90, "uvlock": true },
"facing=south,half=bottom,shape=inner_left": { "model": "engineersdecor:block/brick/clinker_brick_stained_stairs_inner" },
"facing=north,half=bottom,shape=inner_left": { "model": "engineersdecor:block/brick/clinker_brick_stained_stairs_inner", "y": 180, "uvlock": true },
"facing=east,half=top,shape=straight": { "model": "engineersdecor:block/brick/clinker_brick_stained_stairs", "x": 180, "uvlock": true },
"facing=west,half=top,shape=straight": { "model": "engineersdecor:block/brick/clinker_brick_stained_stairs", "x": 180, "y": 180, "uvlock": true },
"facing=south,half=top,shape=straight": { "model": "engineersdecor:block/brick/clinker_brick_stained_stairs", "x": 180, "y": 90, "uvlock": true },
"facing=north,half=top,shape=straight": { "model": "engineersdecor:block/brick/clinker_brick_stained_stairs", "x": 180, "y": 270, "uvlock": true },
"facing=east,half=top,shape=outer_right": { "model": "engineersdecor:block/brick/clinker_brick_stained_stairs_outer", "x": 180, "y": 90, "uvlock": true },
"facing=west,half=top,shape=outer_right": { "model": "engineersdecor:block/brick/clinker_brick_stained_stairs_outer", "x": 180, "y": 270, "uvlock": true },
"facing=south,half=top,shape=outer_right": { "model": "engineersdecor:block/brick/clinker_brick_stained_stairs_outer", "x": 180, "y": 180, "uvlock": true },
"facing=north,half=top,shape=outer_right": { "model": "engineersdecor:block/brick/clinker_brick_stained_stairs_outer", "x": 180, "uvlock": true },
"facing=east,half=top,shape=outer_left": { "model": "engineersdecor:block/brick/clinker_brick_stained_stairs_outer", "x": 180, "uvlock": true },
"facing=west,half=top,shape=outer_left": { "model": "engineersdecor:block/brick/clinker_brick_stained_stairs_outer", "x": 180, "y": 180, "uvlock": true },
"facing=south,half=top,shape=outer_left": { "model": "engineersdecor:block/brick/clinker_brick_stained_stairs_outer", "x": 180, "y": 90, "uvlock": true },
"facing=north,half=top,shape=outer_left": { "model": "engineersdecor:block/brick/clinker_brick_stained_stairs_outer", "x": 180, "y": 270, "uvlock": true },
"facing=east,half=top,shape=inner_right": { "model": "engineersdecor:block/brick/clinker_brick_stained_stairs_inner", "x": 180, "y": 90, "uvlock": true },
"facing=west,half=top,shape=inner_right": { "model": "engineersdecor:block/brick/clinker_brick_stained_stairs_inner", "x": 180, "y": 270, "uvlock": true },
"facing=south,half=top,shape=inner_right": { "model": "engineersdecor:block/brick/clinker_brick_stained_stairs_inner", "x": 180, "y": 180, "uvlock": true },
"facing=north,half=top,shape=inner_right": { "model": "engineersdecor:block/brick/clinker_brick_stained_stairs_inner", "x": 180, "uvlock": true },
"facing=east,half=top,shape=inner_left": { "model": "engineersdecor:block/brick/clinker_brick_stained_stairs_inner", "x": 180, "uvlock": true },
"facing=west,half=top,shape=inner_left": { "model": "engineersdecor:block/brick/clinker_brick_stained_stairs_inner", "x": 180, "y": 180, "uvlock": true },
"facing=south,half=top,shape=inner_left": { "model": "engineersdecor:block/brick/clinker_brick_stained_stairs_inner", "x": 180, "y": 90, "uvlock": true },
"facing=north,half=top,shape=inner_left": { "model": "engineersdecor:block/brick/clinker_brick_stained_stairs_inner", "x": 180, "y": 270, "uvlock": true }
}
}

View file

@ -0,0 +1,44 @@
{
"variants": {
"facing=east,half=bottom,shape=straight": { "model": "engineersdecor:block/brick/clinker_brick_stairs" },
"facing=west,half=bottom,shape=straight": { "model": "engineersdecor:block/brick/clinker_brick_stairs", "y": 180, "uvlock": true },
"facing=south,half=bottom,shape=straight": { "model": "engineersdecor:block/brick/clinker_brick_stairs", "y": 90, "uvlock": true },
"facing=north,half=bottom,shape=straight": { "model": "engineersdecor:block/brick/clinker_brick_stairs", "y": 270, "uvlock": true },
"facing=east,half=bottom,shape=outer_right": { "model": "engineersdecor:block/brick/clinker_brick_stairs_outer" },
"facing=west,half=bottom,shape=outer_right": { "model": "engineersdecor:block/brick/clinker_brick_stairs_outer", "y": 180, "uvlock": true },
"facing=south,half=bottom,shape=outer_right": { "model": "engineersdecor:block/brick/clinker_brick_stairs_outer", "y": 90, "uvlock": true },
"facing=north,half=bottom,shape=outer_right": { "model": "engineersdecor:block/brick/clinker_brick_stairs_outer", "y": 270, "uvlock": true },
"facing=east,half=bottom,shape=outer_left": { "model": "engineersdecor:block/brick/clinker_brick_stairs_outer", "y": 270, "uvlock": true },
"facing=west,half=bottom,shape=outer_left": { "model": "engineersdecor:block/brick/clinker_brick_stairs_outer", "y": 90, "uvlock": true },
"facing=south,half=bottom,shape=outer_left": { "model": "engineersdecor:block/brick/clinker_brick_stairs_outer" },
"facing=north,half=bottom,shape=outer_left": { "model": "engineersdecor:block/brick/clinker_brick_stairs_outer", "y": 180, "uvlock": true },
"facing=east,half=bottom,shape=inner_right": { "model": "engineersdecor:block/brick/clinker_brick_stairs_inner" },
"facing=west,half=bottom,shape=inner_right": { "model": "engineersdecor:block/brick/clinker_brick_stairs_inner", "y": 180, "uvlock": true },
"facing=south,half=bottom,shape=inner_right": { "model": "engineersdecor:block/brick/clinker_brick_stairs_inner", "y": 90, "uvlock": true },
"facing=north,half=bottom,shape=inner_right": { "model": "engineersdecor:block/brick/clinker_brick_stairs_inner", "y": 270, "uvlock": true },
"facing=east,half=bottom,shape=inner_left": { "model": "engineersdecor:block/brick/clinker_brick_stairs_inner", "y": 270, "uvlock": true },
"facing=west,half=bottom,shape=inner_left": { "model": "engineersdecor:block/brick/clinker_brick_stairs_inner", "y": 90, "uvlock": true },
"facing=south,half=bottom,shape=inner_left": { "model": "engineersdecor:block/brick/clinker_brick_stairs_inner" },
"facing=north,half=bottom,shape=inner_left": { "model": "engineersdecor:block/brick/clinker_brick_stairs_inner", "y": 180, "uvlock": true },
"facing=east,half=top,shape=straight": { "model": "engineersdecor:block/brick/clinker_brick_stairs", "x": 180, "uvlock": true },
"facing=west,half=top,shape=straight": { "model": "engineersdecor:block/brick/clinker_brick_stairs", "x": 180, "y": 180, "uvlock": true },
"facing=south,half=top,shape=straight": { "model": "engineersdecor:block/brick/clinker_brick_stairs", "x": 180, "y": 90, "uvlock": true },
"facing=north,half=top,shape=straight": { "model": "engineersdecor:block/brick/clinker_brick_stairs", "x": 180, "y": 270, "uvlock": true },
"facing=east,half=top,shape=outer_right": { "model": "engineersdecor:block/brick/clinker_brick_stairs_outer", "x": 180, "y": 90, "uvlock": true },
"facing=west,half=top,shape=outer_right": { "model": "engineersdecor:block/brick/clinker_brick_stairs_outer", "x": 180, "y": 270, "uvlock": true },
"facing=south,half=top,shape=outer_right": { "model": "engineersdecor:block/brick/clinker_brick_stairs_outer", "x": 180, "y": 180, "uvlock": true },
"facing=north,half=top,shape=outer_right": { "model": "engineersdecor:block/brick/clinker_brick_stairs_outer", "x": 180, "uvlock": true },
"facing=east,half=top,shape=outer_left": { "model": "engineersdecor:block/brick/clinker_brick_stairs_outer", "x": 180, "uvlock": true },
"facing=west,half=top,shape=outer_left": { "model": "engineersdecor:block/brick/clinker_brick_stairs_outer", "x": 180, "y": 180, "uvlock": true },
"facing=south,half=top,shape=outer_left": { "model": "engineersdecor:block/brick/clinker_brick_stairs_outer", "x": 180, "y": 90, "uvlock": true },
"facing=north,half=top,shape=outer_left": { "model": "engineersdecor:block/brick/clinker_brick_stairs_outer", "x": 180, "y": 270, "uvlock": true },
"facing=east,half=top,shape=inner_right": { "model": "engineersdecor:block/brick/clinker_brick_stairs_inner", "x": 180, "y": 90, "uvlock": true },
"facing=west,half=top,shape=inner_right": { "model": "engineersdecor:block/brick/clinker_brick_stairs_inner", "x": 180, "y": 270, "uvlock": true },
"facing=south,half=top,shape=inner_right": { "model": "engineersdecor:block/brick/clinker_brick_stairs_inner", "x": 180, "y": 180, "uvlock": true },
"facing=north,half=top,shape=inner_right": { "model": "engineersdecor:block/brick/clinker_brick_stairs_inner", "x": 180, "uvlock": true },
"facing=east,half=top,shape=inner_left": { "model": "engineersdecor:block/brick/clinker_brick_stairs_inner", "x": 180, "uvlock": true },
"facing=west,half=top,shape=inner_left": { "model": "engineersdecor:block/brick/clinker_brick_stairs_inner", "x": 180, "y": 180, "uvlock": true },
"facing=south,half=top,shape=inner_left": { "model": "engineersdecor:block/brick/clinker_brick_stairs_inner", "x": 180, "y": 90, "uvlock": true },
"facing=north,half=top,shape=inner_left": { "model": "engineersdecor:block/brick/clinker_brick_stairs_inner", "x": 180, "y": 270, "uvlock": true }
}
}

View file

@ -0,0 +1,9 @@
{
"multipart": [
{ "when": { "up": "true" }, "apply": { "model": "engineersdecor:block/brick/clinker_brick_wall_post" } },
{ "when": { "north": "true" }, "apply": { "model": "engineersdecor:block/brick/clinker_brick_wall_side", "uvlock": true } },
{ "when": { "east": "true" }, "apply": { "model": "engineersdecor:block/brick/clinker_brick_wall_side", "y": 90, "uvlock": true } },
{ "when": { "south": "true" }, "apply": { "model": "engineersdecor:block/brick/clinker_brick_wall_side", "y": 180, "uvlock": true } },
{ "when": { "west": "true" }, "apply": { "model": "engineersdecor:block/brick/clinker_brick_wall_side", "y": 270, "uvlock": true } }
]
}

View file

@ -0,0 +1,9 @@
{
"multipart": [
{ "when": { "up": "true" }, "apply": { "model": "engineersdecor:block/concrete/concrete_wall_post" } },
{ "when": { "north": "true" }, "apply": { "model": "engineersdecor:block/concrete/concrete_wall_side", "uvlock": true } },
{ "when": { "east": "true" }, "apply": { "model": "engineersdecor:block/concrete/concrete_wall_side", "y": 90, "uvlock": true } },
{ "when": { "south": "true" }, "apply": { "model": "engineersdecor:block/concrete/concrete_wall_side", "y": 180, "uvlock": true } },
{ "when": { "west": "true" }, "apply": { "model": "engineersdecor:block/concrete/concrete_wall_side", "y": 270, "uvlock": true } }
]
}

View file

@ -0,0 +1,10 @@
{
"forge_marker": 1,
"defaults": {
"model": "engineersdecor:block/device/factory_dropper_model"
},
"variants": {
"facing": { "north":{"y":0}, "south":{"y":180}, "west":{"y":270}, "east":{"y":90}, "up": {"x":-90}, "down": {"x":90} },
"open": { "false":{}, "true":{ "model": "engineersdecor:block/device/factory_dropper_model_open" } }
}
}

View file

@ -0,0 +1,49 @@
{
"variants": {
"parts=0": {
"model": "engineersdecor:block/slab/specific/halfslab_clinker_brick_s0_model"
},
"parts=1": {
"model": "engineersdecor:block/slab/specific/halfslab_clinker_brick_s1_model"
},
"parts=2": {
"model": "engineersdecor:block/slab/specific/halfslab_clinker_brick_s2_model"
},
"parts=3": {
"model": "engineersdecor:block/slab/specific/halfslab_clinker_brick_s3_model"
},
"parts=4": {
"model": "engineersdecor:block/slab/specific/halfslab_clinker_brick_s4_model"
},
"parts=5": {
"model": "engineersdecor:block/slab/specific/halfslab_clinker_brick_s5_model"
},
"parts=6": {
"model": "engineersdecor:block/slab/specific/halfslab_clinker_brick_s6_model"
},
"parts=7": {
"model": "engineersdecor:block/slab/specific/halfslab_clinker_brick_s7_model"
},
"parts=8": {
"model": "engineersdecor:block/slab/specific/halfslab_clinker_brick_s8_model"
},
"parts=9": {
"model": "engineersdecor:block/slab/specific/halfslab_clinker_brick_s9_model"
},
"parts=10": {
"model": "engineersdecor:block/slab/specific/halfslab_clinker_brick_sa_model"
},
"parts=11": {
"model": "engineersdecor:block/slab/specific/halfslab_clinker_brick_sb_model"
},
"parts=12": {
"model": "engineersdecor:block/slab/specific/halfslab_clinker_brick_sc_model"
},
"parts=13": {
"model": "engineersdecor:block/slab/specific/halfslab_clinker_brick_sd_model"
},
"parts=14": {
"model": "engineersdecor:block/slab/specific/halfslab_clinker_brick_se_model"
}
}
}

View file

@ -0,0 +1,49 @@
{
"variants": {
"parts=0": {
"model": "engineersdecor:block/slab/specific/halfslab_concrete_s0_model"
},
"parts=1": {
"model": "engineersdecor:block/slab/specific/halfslab_concrete_s1_model"
},
"parts=2": {
"model": "engineersdecor:block/slab/specific/halfslab_concrete_s2_model"
},
"parts=3": {
"model": "engineersdecor:block/slab/specific/halfslab_concrete_s3_model"
},
"parts=4": {
"model": "engineersdecor:block/slab/specific/halfslab_concrete_s4_model"
},
"parts=5": {
"model": "engineersdecor:block/slab/specific/halfslab_concrete_s5_model"
},
"parts=6": {
"model": "engineersdecor:block/slab/specific/halfslab_concrete_s6_model"
},
"parts=7": {
"model": "engineersdecor:block/slab/specific/halfslab_concrete_s7_model"
},
"parts=8": {
"model": "engineersdecor:block/slab/specific/halfslab_concrete_s8_model"
},
"parts=9": {
"model": "engineersdecor:block/slab/specific/halfslab_concrete_s9_model"
},
"parts=10": {
"model": "engineersdecor:block/slab/specific/halfslab_concrete_sa_model"
},
"parts=11": {
"model": "engineersdecor:block/slab/specific/halfslab_concrete_sb_model"
},
"parts=12": {
"model": "engineersdecor:block/slab/specific/halfslab_concrete_sc_model"
},
"parts=13": {
"model": "engineersdecor:block/slab/specific/halfslab_concrete_sd_model"
},
"parts=14": {
"model": "engineersdecor:block/slab/specific/halfslab_concrete_se_model"
}
}
}

View file

@ -0,0 +1,49 @@
{
"variants": {
"parts=0": {
"model": "engineersdecor:block/slab/specific/halfslab_rebar_concrete_s0_model"
},
"parts=1": {
"model": "engineersdecor:block/slab/specific/halfslab_rebar_concrete_s1_model"
},
"parts=2": {
"model": "engineersdecor:block/slab/specific/halfslab_rebar_concrete_s2_model"
},
"parts=3": {
"model": "engineersdecor:block/slab/specific/halfslab_rebar_concrete_s3_model"
},
"parts=4": {
"model": "engineersdecor:block/slab/specific/halfslab_rebar_concrete_s4_model"
},
"parts=5": {
"model": "engineersdecor:block/slab/specific/halfslab_rebar_concrete_s5_model"
},
"parts=6": {
"model": "engineersdecor:block/slab/specific/halfslab_rebar_concrete_s6_model"
},
"parts=7": {
"model": "engineersdecor:block/slab/specific/halfslab_rebar_concrete_s7_model"
},
"parts=8": {
"model": "engineersdecor:block/slab/specific/halfslab_rebar_concrete_s8_model"
},
"parts=9": {
"model": "engineersdecor:block/slab/specific/halfslab_rebar_concrete_s9_model"
},
"parts=10": {
"model": "engineersdecor:block/slab/specific/halfslab_rebar_concrete_sa_model"
},
"parts=11": {
"model": "engineersdecor:block/slab/specific/halfslab_rebar_concrete_sb_model"
},
"parts=12": {
"model": "engineersdecor:block/slab/specific/halfslab_rebar_concrete_sc_model"
},
"parts=13": {
"model": "engineersdecor:block/slab/specific/halfslab_rebar_concrete_sd_model"
},
"parts=14": {
"model": "engineersdecor:block/slab/specific/halfslab_rebar_concrete_se_model"
}
}
}

View file

@ -0,0 +1,49 @@
{
"variants": {
"parts=0": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_aluminum_s0_model"
},
"parts=1": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_aluminum_s1_model"
},
"parts=2": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_aluminum_s2_model"
},
"parts=3": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_aluminum_s3_model"
},
"parts=4": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_aluminum_s4_model"
},
"parts=5": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_aluminum_s5_model"
},
"parts=6": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_aluminum_s6_model"
},
"parts=7": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_aluminum_s7_model"
},
"parts=8": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_aluminum_s8_model"
},
"parts=9": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_aluminum_s9_model"
},
"parts=10": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_aluminum_sa_model"
},
"parts=11": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_aluminum_sb_model"
},
"parts=12": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_aluminum_sc_model"
},
"parts=13": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_aluminum_sd_model"
},
"parts=14": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_aluminum_se_model"
}
}
}

View file

@ -0,0 +1,49 @@
{
"variants": {
"parts=0": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_copper_s0_model"
},
"parts=1": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_copper_s1_model"
},
"parts=2": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_copper_s2_model"
},
"parts=3": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_copper_s3_model"
},
"parts=4": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_copper_s4_model"
},
"parts=5": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_copper_s5_model"
},
"parts=6": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_copper_s6_model"
},
"parts=7": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_copper_s7_model"
},
"parts=8": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_copper_s8_model"
},
"parts=9": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_copper_s9_model"
},
"parts=10": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_copper_sa_model"
},
"parts=11": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_copper_sb_model"
},
"parts=12": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_copper_sc_model"
},
"parts=13": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_copper_sd_model"
},
"parts=14": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_copper_se_model"
}
}
}

View file

@ -0,0 +1,49 @@
{
"variants": {
"parts=0": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_gold_s0_model"
},
"parts=1": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_gold_s1_model"
},
"parts=2": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_gold_s2_model"
},
"parts=3": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_gold_s3_model"
},
"parts=4": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_gold_s4_model"
},
"parts=5": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_gold_s5_model"
},
"parts=6": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_gold_s6_model"
},
"parts=7": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_gold_s7_model"
},
"parts=8": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_gold_s8_model"
},
"parts=9": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_gold_s9_model"
},
"parts=10": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_gold_sa_model"
},
"parts=11": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_gold_sb_model"
},
"parts=12": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_gold_sc_model"
},
"parts=13": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_gold_sd_model"
},
"parts=14": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_gold_se_model"
}
}
}

View file

@ -0,0 +1,49 @@
{
"variants": {
"parts=0": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_iron_s0_model"
},
"parts=1": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_iron_s1_model"
},
"parts=2": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_iron_s2_model"
},
"parts=3": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_iron_s3_model"
},
"parts=4": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_iron_s4_model"
},
"parts=5": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_iron_s5_model"
},
"parts=6": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_iron_s6_model"
},
"parts=7": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_iron_s7_model"
},
"parts=8": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_iron_s8_model"
},
"parts=9": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_iron_s9_model"
},
"parts=10": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_iron_sa_model"
},
"parts=11": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_iron_sb_model"
},
"parts=12": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_iron_sc_model"
},
"parts=13": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_iron_sd_model"
},
"parts=14": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_iron_se_model"
}
}
}

View file

@ -0,0 +1,49 @@
{
"variants": {
"parts=0": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_steel_s0_model"
},
"parts=1": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_steel_s1_model"
},
"parts=2": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_steel_s2_model"
},
"parts=3": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_steel_s3_model"
},
"parts=4": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_steel_s4_model"
},
"parts=5": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_steel_s5_model"
},
"parts=6": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_steel_s6_model"
},
"parts=7": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_steel_s7_model"
},
"parts=8": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_steel_s8_model"
},
"parts=9": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_steel_s9_model"
},
"parts=10": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_steel_sa_model"
},
"parts=11": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_steel_sb_model"
},
"parts=12": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_steel_sc_model"
},
"parts=13": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_steel_sd_model"
},
"parts=14": {
"model": "engineersdecor:block/slab/specific/halfslab_sheetmetal_steel_se_model"
}
}
}

View file

@ -0,0 +1,49 @@
{
"variants": {
"parts=0": {
"model": "engineersdecor:block/slab/specific/halfslab_treated_wood_s0_model"
},
"parts=1": {
"model": "engineersdecor:block/slab/specific/halfslab_treated_wood_s1_model"
},
"parts=2": {
"model": "engineersdecor:block/slab/specific/halfslab_treated_wood_s2_model"
},
"parts=3": {
"model": "engineersdecor:block/slab/specific/halfslab_treated_wood_s3_model"
},
"parts=4": {
"model": "engineersdecor:block/slab/specific/halfslab_treated_wood_s4_model"
},
"parts=5": {
"model": "engineersdecor:block/slab/specific/halfslab_treated_wood_s5_model"
},
"parts=6": {
"model": "engineersdecor:block/slab/specific/halfslab_treated_wood_s6_model"
},
"parts=7": {
"model": "engineersdecor:block/slab/specific/halfslab_treated_wood_s7_model"
},
"parts=8": {
"model": "engineersdecor:block/slab/specific/halfslab_treated_wood_s8_model"
},
"parts=9": {
"model": "engineersdecor:block/slab/specific/halfslab_treated_wood_s9_model"
},
"parts=10": {
"model": "engineersdecor:block/slab/specific/halfslab_treated_wood_sa_model"
},
"parts=11": {
"model": "engineersdecor:block/slab/specific/halfslab_treated_wood_sb_model"
},
"parts=12": {
"model": "engineersdecor:block/slab/specific/halfslab_treated_wood_sc_model"
},
"parts=13": {
"model": "engineersdecor:block/slab/specific/halfslab_treated_wood_sd_model"
},
"parts=14": {
"model": "engineersdecor:block/slab/specific/halfslab_treated_wood_se_model"
}
}
}

View file

@ -0,0 +1,14 @@
{
"forge_marker": 1,
"defaults": {
"model": "engineersdecor:block/light/inset_light_model",
"textures": {
"light": "engineersdecor:block/light/lamp_glass_warm_square_texture",
"side": "engineersdecor:block/iestyle/steel_texture",
"particle": "engineersdecor:block/iestyle/steel_texture"
}
},
"variants": {
"facing": { "north":{"y":0}, "south":{"y":180}, "west":{"y":270}, "east":{"y":90}, "up": {"x":-90}, "down": {"x":90} }
}
}

View file

@ -0,0 +1,8 @@
{
"variants": {
"facing=north": { "model": "engineersdecor:block/ladder/metal_rung_ladder_model" },
"facing=south": { "model": "engineersdecor:block/ladder/metal_rung_ladder_model", "y":180 },
"facing=west": { "model": "engineersdecor:block/ladder/metal_rung_ladder_model", "y":270 },
"facing=east": { "model": "engineersdecor:block/ladder/metal_rung_ladder_model", "y":90 }
}
}

View file

@ -0,0 +1,8 @@
{
"variants": {
"facing=north": { "model": "engineersdecor:block/ladder/metal_rung_steps_model" },
"facing=south": { "model": "engineersdecor:block/ladder/metal_rung_steps_model", "y":180 },
"facing=west": { "model": "engineersdecor:block/ladder/metal_rung_steps_model", "y":270 },
"facing=east": { "model": "engineersdecor:block/ladder/metal_rung_steps_model", "y":90 }
}
}

View file

@ -0,0 +1,10 @@
{
"variants": {
"": [
{ "model": "engineersdecor:block/glass/panzerglass_block_model", "textures": { "all": "engineersdecor:block/glass/panzerglass_block_texture0" }},
{ "model": "engineersdecor:block/glass/panzerglass_block_model", "textures": { "all": "engineersdecor:block/glass/panzerglass_block_texture1" }},
{ "model": "engineersdecor:block/glass/panzerglass_block_model", "textures": { "all": "engineersdecor:block/glass/panzerglass_block_texture2" }},
{ "model": "engineersdecor:block/glass/panzerglass_block_model", "textures": { "all": "engineersdecor:block/glass/panzerglass_block_texture3" }}
]
}
}

View file

@ -0,0 +1,40 @@
{
"variants": {
"parts=0,tvariant=0": {
"model": "engineersdecor:block/slab/specific/panzerglass_slab_s0v0_model"
},
"parts=0,tvariant=1": {
"model": "engineersdecor:block/slab/specific/panzerglass_slab_s0v1_model"
},
"parts=0,tvariant=2": {
"model": "engineersdecor:block/slab/specific/panzerglass_slab_s0v2_model"
},
"parts=0,tvariant=3": {
"model": "engineersdecor:block/slab/specific/panzerglass_slab_s0v3_model"
},
"parts=1,tvariant=0": {
"model": "engineersdecor:block/slab/specific/panzerglass_slab_s1v0_model"
},
"parts=1,tvariant=1": {
"model": "engineersdecor:block/slab/specific/panzerglass_slab_s1v1_model"
},
"parts=1,tvariant=2": {
"model": "engineersdecor:block/slab/specific/panzerglass_slab_s1v2_model"
},
"parts=1,tvariant=3": {
"model": "engineersdecor:block/slab/specific/panzerglass_slab_s1v3_model"
},
"parts=2,tvariant=0": {
"model": "engineersdecor:block/slab/specific/panzerglass_slab_s2v0_model"
},
"parts=2,tvariant=1": {
"model": "engineersdecor:block/slab/specific/panzerglass_slab_s2v1_model"
},
"parts=2,tvariant=2": {
"model": "engineersdecor:block/slab/specific/panzerglass_slab_s2v2_model"
},
"parts=2,tvariant=3": {
"model": "engineersdecor:block/slab/specific/panzerglass_slab_s2v3_model"
}
}
}

View file

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

View file

@ -0,0 +1,14 @@
{
"variants": {
"": [
{ "model": "engineersdecor:block/concrete/rebar_concrete_model0" },
{ "model": "engineersdecor:block/concrete/rebar_concrete_model1" },
{ "model": "engineersdecor:block/concrete/rebar_concrete_model2" },
{ "model": "engineersdecor:block/concrete/rebar_concrete_model3" },
{ "model": "engineersdecor:block/concrete/rebar_concrete_model4" },
{ "model": "engineersdecor:block/concrete/rebar_concrete_model5" },
{ "model": "engineersdecor:block/concrete/rebar_concrete_model6" },
{ "model": "engineersdecor:block/concrete/rebar_concrete_model7" }
]
}
}

View file

@ -0,0 +1,40 @@
{
"variants": {
"parts=0,tvariant=0": {
"model": "engineersdecor:block/slab/specific/rebar_concrete_slab_s0v0_model"
},
"parts=0,tvariant=1": {
"model": "engineersdecor:block/slab/specific/rebar_concrete_slab_s0v1_model"
},
"parts=0,tvariant=2": {
"model": "engineersdecor:block/slab/specific/rebar_concrete_slab_s0v2_model"
},
"parts=0,tvariant=3": {
"model": "engineersdecor:block/slab/specific/rebar_concrete_slab_s0v3_model"
},
"parts=1,tvariant=0": {
"model": "engineersdecor:block/slab/specific/rebar_concrete_slab_s1v0_model"
},
"parts=1,tvariant=1": {
"model": "engineersdecor:block/slab/specific/rebar_concrete_slab_s1v1_model"
},
"parts=1,tvariant=2": {
"model": "engineersdecor:block/slab/specific/rebar_concrete_slab_s1v2_model"
},
"parts=1,tvariant=3": {
"model": "engineersdecor:block/slab/specific/rebar_concrete_slab_s1v3_model"
},
"parts=2,tvariant=0": {
"model": "engineersdecor:block/slab/specific/rebar_concrete_slab_s2v0_model"
},
"parts=2,tvariant=1": {
"model": "engineersdecor:block/slab/specific/rebar_concrete_slab_s2v1_model"
},
"parts=2,tvariant=2": {
"model": "engineersdecor:block/slab/specific/rebar_concrete_slab_s2v2_model"
},
"parts=2,tvariant=3": {
"model": "engineersdecor:block/slab/specific/rebar_concrete_slab_s2v3_model"
}
}
}

View file

@ -0,0 +1,44 @@
{
"variants": {
"facing=east,half=bottom,shape=straight": { "model": "engineersdecor:block/concrete/rebar_concrete_stairs" },
"facing=west,half=bottom,shape=straight": { "model": "engineersdecor:block/concrete/rebar_concrete_stairs", "y": 180, "uvlock": true },
"facing=south,half=bottom,shape=straight": { "model": "engineersdecor:block/concrete/rebar_concrete_stairs", "y": 90, "uvlock": true },
"facing=north,half=bottom,shape=straight": { "model": "engineersdecor:block/concrete/rebar_concrete_stairs", "y": 270, "uvlock": true },
"facing=east,half=bottom,shape=outer_right": { "model": "engineersdecor:block/concrete/rebar_concrete_stairs_outer" },
"facing=west,half=bottom,shape=outer_right": { "model": "engineersdecor:block/concrete/rebar_concrete_stairs_outer", "y": 180, "uvlock": true },
"facing=south,half=bottom,shape=outer_right": { "model": "engineersdecor:block/concrete/rebar_concrete_stairs_outer", "y": 90, "uvlock": true },
"facing=north,half=bottom,shape=outer_right": { "model": "engineersdecor:block/concrete/rebar_concrete_stairs_outer", "y": 270, "uvlock": true },
"facing=east,half=bottom,shape=outer_left": { "model": "engineersdecor:block/concrete/rebar_concrete_stairs_outer", "y": 270, "uvlock": true },
"facing=west,half=bottom,shape=outer_left": { "model": "engineersdecor:block/concrete/rebar_concrete_stairs_outer", "y": 90, "uvlock": true },
"facing=south,half=bottom,shape=outer_left": { "model": "engineersdecor:block/concrete/rebar_concrete_stairs_outer" },
"facing=north,half=bottom,shape=outer_left": { "model": "engineersdecor:block/concrete/rebar_concrete_stairs_outer", "y": 180, "uvlock": true },
"facing=east,half=bottom,shape=inner_right": { "model": "engineersdecor:block/concrete/rebar_concrete_stairs_inner" },
"facing=west,half=bottom,shape=inner_right": { "model": "engineersdecor:block/concrete/rebar_concrete_stairs_inner", "y": 180, "uvlock": true },
"facing=south,half=bottom,shape=inner_right": { "model": "engineersdecor:block/concrete/rebar_concrete_stairs_inner", "y": 90, "uvlock": true },
"facing=north,half=bottom,shape=inner_right": { "model": "engineersdecor:block/concrete/rebar_concrete_stairs_inner", "y": 270, "uvlock": true },
"facing=east,half=bottom,shape=inner_left": { "model": "engineersdecor:block/concrete/rebar_concrete_stairs_inner", "y": 270, "uvlock": true },
"facing=west,half=bottom,shape=inner_left": { "model": "engineersdecor:block/concrete/rebar_concrete_stairs_inner", "y": 90, "uvlock": true },
"facing=south,half=bottom,shape=inner_left": { "model": "engineersdecor:block/concrete/rebar_concrete_stairs_inner" },
"facing=north,half=bottom,shape=inner_left": { "model": "engineersdecor:block/concrete/rebar_concrete_stairs_inner", "y": 180, "uvlock": true },
"facing=east,half=top,shape=straight": { "model": "engineersdecor:block/concrete/rebar_concrete_stairs", "x": 180, "uvlock": true },
"facing=west,half=top,shape=straight": { "model": "engineersdecor:block/concrete/rebar_concrete_stairs", "x": 180, "y": 180, "uvlock": true },
"facing=south,half=top,shape=straight": { "model": "engineersdecor:block/concrete/rebar_concrete_stairs", "x": 180, "y": 90, "uvlock": true },
"facing=north,half=top,shape=straight": { "model": "engineersdecor:block/concrete/rebar_concrete_stairs", "x": 180, "y": 270, "uvlock": true },
"facing=east,half=top,shape=outer_right": { "model": "engineersdecor:block/concrete/rebar_concrete_stairs_outer", "x": 180, "y": 90, "uvlock": true },
"facing=west,half=top,shape=outer_right": { "model": "engineersdecor:block/concrete/rebar_concrete_stairs_outer", "x": 180, "y": 270, "uvlock": true },
"facing=south,half=top,shape=outer_right": { "model": "engineersdecor:block/concrete/rebar_concrete_stairs_outer", "x": 180, "y": 180, "uvlock": true },
"facing=north,half=top,shape=outer_right": { "model": "engineersdecor:block/concrete/rebar_concrete_stairs_outer", "x": 180, "uvlock": true },
"facing=east,half=top,shape=outer_left": { "model": "engineersdecor:block/concrete/rebar_concrete_stairs_outer", "x": 180, "uvlock": true },
"facing=west,half=top,shape=outer_left": { "model": "engineersdecor:block/concrete/rebar_concrete_stairs_outer", "x": 180, "y": 180, "uvlock": true },
"facing=south,half=top,shape=outer_left": { "model": "engineersdecor:block/concrete/rebar_concrete_stairs_outer", "x": 180, "y": 90, "uvlock": true },
"facing=north,half=top,shape=outer_left": { "model": "engineersdecor:block/concrete/rebar_concrete_stairs_outer", "x": 180, "y": 270, "uvlock": true },
"facing=east,half=top,shape=inner_right": { "model": "engineersdecor:block/concrete/rebar_concrete_stairs_inner", "x": 180, "y": 90, "uvlock": true },
"facing=west,half=top,shape=inner_right": { "model": "engineersdecor:block/concrete/rebar_concrete_stairs_inner", "x": 180, "y": 270, "uvlock": true },
"facing=south,half=top,shape=inner_right": { "model": "engineersdecor:block/concrete/rebar_concrete_stairs_inner", "x": 180, "y": 180, "uvlock": true },
"facing=north,half=top,shape=inner_right": { "model": "engineersdecor:block/concrete/rebar_concrete_stairs_inner", "x": 180, "uvlock": true },
"facing=east,half=top,shape=inner_left": { "model": "engineersdecor:block/concrete/rebar_concrete_stairs_inner", "x": 180, "uvlock": true },
"facing=west,half=top,shape=inner_left": { "model": "engineersdecor:block/concrete/rebar_concrete_stairs_inner", "x": 180, "y": 180, "uvlock": true },
"facing=south,half=top,shape=inner_left": { "model": "engineersdecor:block/concrete/rebar_concrete_stairs_inner", "x": 180, "y": 90, "uvlock": true },
"facing=north,half=top,shape=inner_left": { "model": "engineersdecor:block/concrete/rebar_concrete_stairs_inner", "x": 180, "y": 270, "uvlock": true }
}
}

View file

@ -0,0 +1,14 @@
{
"variants": {
"": [
{ "model": "engineersdecor:block/concrete/rebar_concrete_tile_model0" },
{ "model": "engineersdecor:block/concrete/rebar_concrete_tile_model1" },
{ "model": "engineersdecor:block/concrete/rebar_concrete_tile_model2" },
{ "model": "engineersdecor:block/concrete/rebar_concrete_tile_model3" },
{ "model": "engineersdecor:block/concrete/rebar_concrete_tile_model4" },
{ "model": "engineersdecor:block/concrete/rebar_concrete_tile_model5" },
{ "model": "engineersdecor:block/concrete/rebar_concrete_tile_model6" },
{ "model": "engineersdecor:block/concrete/rebar_concrete_tile_model7" }
]
}
}

View file

@ -0,0 +1,40 @@
{
"variants": {
"parts=0,tvariant=0": {
"model": "engineersdecor:block/slab/specific/rebar_concrete_tile_slab_s0v0_model"
},
"parts=0,tvariant=1": {
"model": "engineersdecor:block/slab/specific/rebar_concrete_tile_slab_s0v1_model"
},
"parts=0,tvariant=2": {
"model": "engineersdecor:block/slab/specific/rebar_concrete_tile_slab_s0v2_model"
},
"parts=0,tvariant=3": {
"model": "engineersdecor:block/slab/specific/rebar_concrete_tile_slab_s0v3_model"
},
"parts=1,tvariant=0": {
"model": "engineersdecor:block/slab/specific/rebar_concrete_tile_slab_s1v0_model"
},
"parts=1,tvariant=1": {
"model": "engineersdecor:block/slab/specific/rebar_concrete_tile_slab_s1v1_model"
},
"parts=1,tvariant=2": {
"model": "engineersdecor:block/slab/specific/rebar_concrete_tile_slab_s1v2_model"
},
"parts=1,tvariant=3": {
"model": "engineersdecor:block/slab/specific/rebar_concrete_tile_slab_s1v3_model"
},
"parts=2,tvariant=0": {
"model": "engineersdecor:block/slab/specific/rebar_concrete_tile_slab_s2v0_model"
},
"parts=2,tvariant=1": {
"model": "engineersdecor:block/slab/specific/rebar_concrete_tile_slab_s2v1_model"
},
"parts=2,tvariant=2": {
"model": "engineersdecor:block/slab/specific/rebar_concrete_tile_slab_s2v2_model"
},
"parts=2,tvariant=3": {
"model": "engineersdecor:block/slab/specific/rebar_concrete_tile_slab_s2v3_model"
}
}
}

View file

@ -0,0 +1,44 @@
{
"variants": {
"facing=east,half=bottom,shape=straight": { "model": "engineersdecor:block/concrete/rebar_concrete_tile_stairs" },
"facing=west,half=bottom,shape=straight": { "model": "engineersdecor:block/concrete/rebar_concrete_tile_stairs", "y": 180, "uvlock": true },
"facing=south,half=bottom,shape=straight": { "model": "engineersdecor:block/concrete/rebar_concrete_tile_stairs", "y": 90, "uvlock": true },
"facing=north,half=bottom,shape=straight": { "model": "engineersdecor:block/concrete/rebar_concrete_tile_stairs", "y": 270, "uvlock": true },
"facing=east,half=bottom,shape=outer_right": { "model": "engineersdecor:block/concrete/rebar_concrete_tile_stairs_outer" },
"facing=west,half=bottom,shape=outer_right": { "model": "engineersdecor:block/concrete/rebar_concrete_tile_stairs_outer", "y": 180, "uvlock": true },
"facing=south,half=bottom,shape=outer_right": { "model": "engineersdecor:block/concrete/rebar_concrete_tile_stairs_outer", "y": 90, "uvlock": true },
"facing=north,half=bottom,shape=outer_right": { "model": "engineersdecor:block/concrete/rebar_concrete_tile_stairs_outer", "y": 270, "uvlock": true },
"facing=east,half=bottom,shape=outer_left": { "model": "engineersdecor:block/concrete/rebar_concrete_tile_stairs_outer", "y": 270, "uvlock": true },
"facing=west,half=bottom,shape=outer_left": { "model": "engineersdecor:block/concrete/rebar_concrete_tile_stairs_outer", "y": 90, "uvlock": true },
"facing=south,half=bottom,shape=outer_left": { "model": "engineersdecor:block/concrete/rebar_concrete_tile_stairs_outer" },
"facing=north,half=bottom,shape=outer_left": { "model": "engineersdecor:block/concrete/rebar_concrete_tile_stairs_outer", "y": 180, "uvlock": true },
"facing=east,half=bottom,shape=inner_right": { "model": "engineersdecor:block/concrete/rebar_concrete_tile_stairs_inner" },
"facing=west,half=bottom,shape=inner_right": { "model": "engineersdecor:block/concrete/rebar_concrete_tile_stairs_inner", "y": 180, "uvlock": true },
"facing=south,half=bottom,shape=inner_right": { "model": "engineersdecor:block/concrete/rebar_concrete_tile_stairs_inner", "y": 90, "uvlock": true },
"facing=north,half=bottom,shape=inner_right": { "model": "engineersdecor:block/concrete/rebar_concrete_tile_stairs_inner", "y": 270, "uvlock": true },
"facing=east,half=bottom,shape=inner_left": { "model": "engineersdecor:block/concrete/rebar_concrete_tile_stairs_inner", "y": 270, "uvlock": true },
"facing=west,half=bottom,shape=inner_left": { "model": "engineersdecor:block/concrete/rebar_concrete_tile_stairs_inner", "y": 90, "uvlock": true },
"facing=south,half=bottom,shape=inner_left": { "model": "engineersdecor:block/concrete/rebar_concrete_tile_stairs_inner" },
"facing=north,half=bottom,shape=inner_left": { "model": "engineersdecor:block/concrete/rebar_concrete_tile_stairs_inner", "y": 180, "uvlock": true },
"facing=east,half=top,shape=straight": { "model": "engineersdecor:block/concrete/rebar_concrete_tile_stairs", "x": 180, "uvlock": true },
"facing=west,half=top,shape=straight": { "model": "engineersdecor:block/concrete/rebar_concrete_tile_stairs", "x": 180, "y": 180, "uvlock": true },
"facing=south,half=top,shape=straight": { "model": "engineersdecor:block/concrete/rebar_concrete_tile_stairs", "x": 180, "y": 90, "uvlock": true },
"facing=north,half=top,shape=straight": { "model": "engineersdecor:block/concrete/rebar_concrete_tile_stairs", "x": 180, "y": 270, "uvlock": true },
"facing=east,half=top,shape=outer_right": { "model": "engineersdecor:block/concrete/rebar_concrete_tile_stairs_outer", "x": 180, "y": 90, "uvlock": true },
"facing=west,half=top,shape=outer_right": { "model": "engineersdecor:block/concrete/rebar_concrete_tile_stairs_outer", "x": 180, "y": 270, "uvlock": true },
"facing=south,half=top,shape=outer_right": { "model": "engineersdecor:block/concrete/rebar_concrete_tile_stairs_outer", "x": 180, "y": 180, "uvlock": true },
"facing=north,half=top,shape=outer_right": { "model": "engineersdecor:block/concrete/rebar_concrete_tile_stairs_outer", "x": 180, "uvlock": true },
"facing=east,half=top,shape=outer_left": { "model": "engineersdecor:block/concrete/rebar_concrete_tile_stairs_outer", "x": 180, "uvlock": true },
"facing=west,half=top,shape=outer_left": { "model": "engineersdecor:block/concrete/rebar_concrete_tile_stairs_outer", "x": 180, "y": 180, "uvlock": true },
"facing=south,half=top,shape=outer_left": { "model": "engineersdecor:block/concrete/rebar_concrete_tile_stairs_outer", "x": 180, "y": 90, "uvlock": true },
"facing=north,half=top,shape=outer_left": { "model": "engineersdecor:block/concrete/rebar_concrete_tile_stairs_outer", "x": 180, "y": 270, "uvlock": true },
"facing=east,half=top,shape=inner_right": { "model": "engineersdecor:block/concrete/rebar_concrete_tile_stairs_inner", "x": 180, "y": 90, "uvlock": true },
"facing=west,half=top,shape=inner_right": { "model": "engineersdecor:block/concrete/rebar_concrete_tile_stairs_inner", "x": 180, "y": 270, "uvlock": true },
"facing=south,half=top,shape=inner_right": { "model": "engineersdecor:block/concrete/rebar_concrete_tile_stairs_inner", "x": 180, "y": 180, "uvlock": true },
"facing=north,half=top,shape=inner_right": { "model": "engineersdecor:block/concrete/rebar_concrete_tile_stairs_inner", "x": 180, "uvlock": true },
"facing=east,half=top,shape=inner_left": { "model": "engineersdecor:block/concrete/rebar_concrete_tile_stairs_inner", "x": 180, "uvlock": true },
"facing=west,half=top,shape=inner_left": { "model": "engineersdecor:block/concrete/rebar_concrete_tile_stairs_inner", "x": 180, "y": 180, "uvlock": true },
"facing=south,half=top,shape=inner_left": { "model": "engineersdecor:block/concrete/rebar_concrete_tile_stairs_inner", "x": 180, "y": 90, "uvlock": true },
"facing=north,half=top,shape=inner_left": { "model": "engineersdecor:block/concrete/rebar_concrete_tile_stairs_inner", "x": 180, "y": 270, "uvlock": true }
}
}

View file

@ -0,0 +1,9 @@
{
"multipart": [
{ "when": { "up": "true" }, "apply": { "model": "engineersdecor:block/concrete/rebar_concrete_wall_post" } },
{ "when": { "north": "true" }, "apply": { "model": "engineersdecor:block/concrete/rebar_concrete_wall_side", "uvlock": true } },
{ "when": { "east": "true" }, "apply": { "model": "engineersdecor:block/concrete/rebar_concrete_wall_side", "y": 90, "uvlock": true } },
{ "when": { "south": "true" }, "apply": { "model": "engineersdecor:block/concrete/rebar_concrete_wall_side", "y": 180, "uvlock": true } },
{ "when": { "west": "true" }, "apply": { "model": "engineersdecor:block/concrete/rebar_concrete_wall_side", "y": 270, "uvlock": true } }
]
}

View file

@ -0,0 +1,7 @@
{
"forge_marker": 1,
"defaults": { "model": "engineersdecor:block/sign/sign_danger_model" },
"variants": {
"facing": { "north":{"y":0}, "south":{"y":180}, "west":{"y":270}, "east":{"y":90}, "up": {"x":-90}, "down": {"x":90} }
}
}

View file

@ -0,0 +1,7 @@
{
"forge_marker": 1,
"defaults": { "model": "engineersdecor:block/sign/sign_decor_model" },
"variants": {
"facing": { "north":{"y":0}, "south":{"y":180}, "west":{"y":270}, "east":{"y":90}, "up": {"x":-90}, "down": {"x":90} }
}
}

View file

@ -0,0 +1,7 @@
{
"forge_marker": 1,
"defaults": { "model": "engineersdecor:block/sign/sign_defense_model" },
"variants": {
"facing": { "north":{"y":0}, "south":{"y":180}, "west":{"y":270}, "east":{"y":90}, "up": {"x":0}, "down": {"x":0} }
}
}

View file

@ -0,0 +1,7 @@
{
"forge_marker": 1,
"defaults": { "model": "engineersdecor:block/sign/sign_factoryarea_model" },
"variants": {
"facing": { "north":{"y":0}, "south":{"y":180}, "west":{"y":270}, "east":{"y":90}, "up": {"x":0}, "down": {"x":0} }
}
}

View file

@ -0,0 +1,7 @@
{
"forge_marker": 1,
"defaults": { "model": "engineersdecor:block/sign/sign_hotwire_model" },
"variants": {
"facing": { "north":{"y":0}, "south":{"y":180}, "west":{"y":270}, "east":{"y":90}, "up": {"x":-90}, "down": {"x":90} }
}
}

View file

@ -0,0 +1,7 @@
{
"forge_marker": 1,
"defaults": { "model": "engineersdecor:block/sign/sign_mindstep_model" },
"variants": {
"facing": { "north":{"y":0}, "south":{"y":180}, "west":{"y":270}, "east":{"y":90}, "up": {"x":0}, "down": {"x":0} }
}
}

View file

@ -0,0 +1,14 @@
{
"variants": {
"": [
{ "model": "engineersdecor:block/brick/slag_brick_model0" },
{ "model": "engineersdecor:block/brick/slag_brick_model1" },
{ "model": "engineersdecor:block/brick/slag_brick_model2" },
{ "model": "engineersdecor:block/brick/slag_brick_model3" },
{ "model": "engineersdecor:block/brick/slag_brick_model4" },
{ "model": "engineersdecor:block/brick/slag_brick_model5" },
{ "model": "engineersdecor:block/brick/slag_brick_model6" },
{ "model": "engineersdecor:block/brick/slag_brick_model7" }
]
}
}

View file

@ -0,0 +1,40 @@
{
"variants": {
"parts=0,tvariant=0": {
"model": "engineersdecor:block/slab/specific/slag_brick_slab_s0v0_model"
},
"parts=0,tvariant=1": {
"model": "engineersdecor:block/slab/specific/slag_brick_slab_s0v1_model"
},
"parts=0,tvariant=2": {
"model": "engineersdecor:block/slab/specific/slag_brick_slab_s0v2_model"
},
"parts=0,tvariant=3": {
"model": "engineersdecor:block/slab/specific/slag_brick_slab_s0v3_model"
},
"parts=1,tvariant=0": {
"model": "engineersdecor:block/slab/specific/slag_brick_slab_s1v0_model"
},
"parts=1,tvariant=1": {
"model": "engineersdecor:block/slab/specific/slag_brick_slab_s1v1_model"
},
"parts=1,tvariant=2": {
"model": "engineersdecor:block/slab/specific/slag_brick_slab_s1v2_model"
},
"parts=1,tvariant=3": {
"model": "engineersdecor:block/slab/specific/slag_brick_slab_s1v3_model"
},
"parts=2,tvariant=0": {
"model": "engineersdecor:block/slab/specific/slag_brick_slab_s2v0_model"
},
"parts=2,tvariant=1": {
"model": "engineersdecor:block/slab/specific/slag_brick_slab_s2v1_model"
},
"parts=2,tvariant=2": {
"model": "engineersdecor:block/slab/specific/slag_brick_slab_s2v2_model"
},
"parts=2,tvariant=3": {
"model": "engineersdecor:block/slab/specific/slag_brick_slab_s2v3_model"
}
}
}

Some files were not shown because too many files have changed in this diff Show more