1.14: UPDATE TO 1.14.4. Initial source structure released.

This commit is contained in:
stfwi 2019-07-20 19:52:54 +02:00
parent 8ecf02d3e8
commit 2b203abe0e
732 changed files with 18165 additions and 4 deletions

View file

@ -63,6 +63,17 @@ 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
}
}
}
}
}

View file

@ -2,10 +2,10 @@
org.gradle.daemon=false
org.gradle.jvmargs=-Xmx8G
version_minecraft=1.14.3
version_forge_minecraft=1.14.3-27.0.60
version_forge_minecraft=1.14.4-28.0.2
version_fml_mappings=20190719-1.14.3
version_jei=6.0.0.7
version_engineersdecor=1.0.9-b7
version_engineersdecor=1.0.9-b8
#
# jar signing data loaded from signing.properties in the project root.
#

View file

@ -10,6 +10,8 @@ Mod sources for Minecraft version 1.14.3.
----
## Version history
~ v1.0.9-b8 [U] UPDATE TO 1.14.4. Forge 1.14.4-28.0.2/20190719-1.14.3.
- 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

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)
.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"
}
}
}

View file

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

View file

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

View file

@ -0,0 +1,16 @@
{
"variants": {
"facing=north,lit=false": { "model": "engineersdecor:block/furnace/small_electrical_furnace_model", "y": 0 },
"facing=south,lit=false": { "model": "engineersdecor:block/furnace/small_electrical_furnace_model", "y": 180 },
"facing=west,lit=false": { "model": "engineersdecor:block/furnace/small_electrical_furnace_model", "y": 270 },
"facing=east,lit=false": { "model": "engineersdecor:block/furnace/small_electrical_furnace_model", "y": 90 },
"facing=up,lit=false": { "model": "engineersdecor:block/furnace/small_electrical_furnace_model", "y": 0 },
"facing=down,lit=false": { "model": "engineersdecor:block/furnace/small_electrical_furnace_model", "y": 0 },
"facing=north,lit=true": { "model": "engineersdecor:block/furnace/small_electrical_furnace_model_lit", "y": 0 },
"facing=south,lit=true": { "model": "engineersdecor:block/furnace/small_electrical_furnace_model_lit", "y": 180 },
"facing=west,lit=true": { "model": "engineersdecor:block/furnace/small_electrical_furnace_model_lit", "y": 270 },
"facing=east,lit=true": { "model": "engineersdecor:block/furnace/small_electrical_furnace_model_lit", "y": 90 },
"facing=up,lit=true": { "model": "engineersdecor:block/furnace/small_electrical_furnace_model_lit", "y": 0 },
"facing=down,lit=true": { "model": "engineersdecor:block/furnace/small_electrical_furnace_model_lit", "y": 0 }
}
}

View file

@ -0,0 +1,16 @@
{
"variants": {
"facing=north,lit=false": { "model": "engineersdecor:block/furnace/small_lab_furnace_model", "y": 0 },
"facing=south,lit=false": { "model": "engineersdecor:block/furnace/small_lab_furnace_model", "y": 180 },
"facing=west,lit=false": { "model": "engineersdecor:block/furnace/small_lab_furnace_model", "y": 270 },
"facing=east,lit=false": { "model": "engineersdecor:block/furnace/small_lab_furnace_model", "y": 90 },
"facing=up,lit=false": { "model": "engineersdecor:block/furnace/small_lab_furnace_model", "y": 0 },
"facing=down,lit=false": { "model": "engineersdecor:block/furnace/small_lab_furnace_model", "y": 0 },
"facing=north,lit=true": { "model": "engineersdecor:block/furnace/small_lab_furnace_model_lit", "y": 0 },
"facing=south,lit=true": { "model": "engineersdecor:block/furnace/small_lab_furnace_model_lit", "y": 180 },
"facing=west,lit=true": { "model": "engineersdecor:block/furnace/small_lab_furnace_model_lit", "y": 270 },
"facing=east,lit=true": { "model": "engineersdecor:block/furnace/small_lab_furnace_model_lit", "y": 90 },
"facing=up,lit=true": { "model": "engineersdecor:block/furnace/small_lab_furnace_model", "y": 0 },
"facing=down,lit=true": { "model": "engineersdecor:block/furnace/small_lab_furnace_model", "y": 0 }
}
}

View file

@ -0,0 +1,20 @@
{
"variants": {
"facing=north,phase=0": { "model": "engineersdecor:block/furnace/small_mineral_smelter_model", "y": 0 },
"facing=south,phase=0": { "model": "engineersdecor:block/furnace/small_mineral_smelter_model", "y": 180 },
"facing=west,phase=0": { "model": "engineersdecor:block/furnace/small_mineral_smelter_model", "y": 270 },
"facing=east,phase=0": { "model": "engineersdecor:block/furnace/small_mineral_smelter_model", "y": 90 },
"facing=north,phase=1": { "model": "engineersdecor:block/furnace/small_mineral_smelter_model_s1", "y": 0 },
"facing=south,phase=1": { "model": "engineersdecor:block/furnace/small_mineral_smelter_model_s1", "y": 180 },
"facing=west,phase=1": { "model": "engineersdecor:block/furnace/small_mineral_smelter_model_s1", "y": 270 },
"facing=east,phase=1": { "model": "engineersdecor:block/furnace/small_mineral_smelter_model_s1", "y": 90 },
"facing=north,phase=2": { "model": "engineersdecor:block/furnace/small_mineral_smelter_model_s2", "y": 0 },
"facing=south,phase=2": { "model": "engineersdecor:block/furnace/small_mineral_smelter_model_s2", "y": 180 },
"facing=west,phase=2": { "model": "engineersdecor:block/furnace/small_mineral_smelter_model_s2", "y": 270 },
"facing=east,phase=2": { "model": "engineersdecor:block/furnace/small_mineral_smelter_model_s2", "y": 90 },
"facing=north,phase=3": { "model": "engineersdecor:block/furnace/small_mineral_smelter_model_s3", "y": 0 },
"facing=south,phase=3": { "model": "engineersdecor:block/furnace/small_mineral_smelter_model_s3", "y": 180 },
"facing=west,phase=3": { "model": "engineersdecor:block/furnace/small_mineral_smelter_model_s3", "y": 270 },
"facing=east,phase=3": { "model": "engineersdecor:block/furnace/small_mineral_smelter_model_s3", "y": 90 }
}
}

View file

@ -0,0 +1,6 @@
{
"variants": {
"lit=false": { "model": "engineersdecor:block/furnace/small_waste_incinerator_model" },
"lit=true" : { "model": "engineersdecor:block/furnace/small_waste_incinerator_model_lit" }
}
}

View file

@ -0,0 +1,19 @@
{ "multipart": [
{ "when": { "eastwest":"false" },
"apply": { "model": "engineersdecor:block/hsupport/steel_double_t_support_model", "y": 0 }
},{ "when": { "eastwest":"true" },
"apply": { "model": "engineersdecor:block/hsupport/steel_double_t_support_model", "y": 90 }
},{ "when": { "eastwest":"true", "rightbeam": "true" },
"apply": { "model": "engineersdecor:block/hsupport/steel_double_t_support_xconnect_model", "y": 90 }
},{ "when": { "eastwest":"true", "leftbeam": "true" },
"apply": { "model": "engineersdecor:block/hsupport/steel_double_t_support_xconnect_model", "y": -90 }
},{ "when": { "eastwest":"false", "rightbeam": "true" },
"apply": { "model": "engineersdecor:block/hsupport/steel_double_t_support_xconnect_model", "y": 0 }
},{ "when": { "eastwest":"false", "leftbeam": "true" },
"apply": { "model": "engineersdecor:block/hsupport/steel_double_t_support_xconnect_model", "y": 180 }
},{ "when": { "downconnect" : "1" },
"apply": { "model": "engineersdecor:block/hsupport/steel_double_t_support_xconnect_thin_pole_model" }
},{ "when": { "downconnect" : "2" },
"apply": { "model": "engineersdecor:block/hsupport/steel_double_t_support_xconnect_thin_pole_model" }
}
]}

View file

@ -0,0 +1,9 @@
{
"forge_marker": 1,
"defaults": {
"model": "engineersdecor:block/furniture/steel_framed_window_model"
},
"variants": {
"facing": { "north": {"y":0}, "south": {"y":0}, "west": {"y":90}, "east": {"y":90}, "up": {"x":90}, "down": {"x":90} }
}
}

View file

@ -0,0 +1,8 @@
{ "multipart": [
{ "when": { "facing":"north" }, "apply": { "model": "engineersdecor:block/pipe/straight_pipe_valve_model", "y": 0 } },
{ "when": { "facing":"south" }, "apply": { "model": "engineersdecor:block/pipe/straight_pipe_valve_model", "y": 180 } },
{ "when": { "facing":"west" }, "apply": { "model": "engineersdecor:block/pipe/straight_pipe_valve_model", "y": 270 } },
{ "when": { "facing":"east" }, "apply": { "model": "engineersdecor:block/pipe/straight_pipe_valve_model", "y": 90 } },
{ "when": { "facing":"up" }, "apply": { "model": "engineersdecor:block/pipe/straight_pipe_valve_model", "x": -90 } },
{ "when": { "facing":"down" }, "apply": { "model": "engineersdecor:block/pipe/straight_pipe_valve_model", "x": 90 } }
]}

View file

@ -0,0 +1,14 @@
{ "multipart": [
{ "when": { "facing":"north" }, "apply": { "model": "engineersdecor:block/pipe/straight_pipe_valve_redstone_model", "y": 0 } },
{ "when": { "facing":"south" }, "apply": { "model": "engineersdecor:block/pipe/straight_pipe_valve_redstone_model", "y": 180 } },
{ "when": { "facing":"west" }, "apply": { "model": "engineersdecor:block/pipe/straight_pipe_valve_redstone_model", "y": 270 } },
{ "when": { "facing":"east" }, "apply": { "model": "engineersdecor:block/pipe/straight_pipe_valve_redstone_model", "y": 90 } },
{ "when": { "facing":"up" }, "apply": { "model": "engineersdecor:block/pipe/straight_pipe_valve_redstone_model", "x": -90 } },
{ "when": { "facing":"down" }, "apply": { "model": "engineersdecor:block/pipe/straight_pipe_valve_redstone_model", "x": 90 } },
{ "when": { "rs_n":"true" }, "apply": { "model": "engineersdecor:block/pipe/straight_pipe_valve_rs_connector_submodel", "y": 0 } },
{ "when": { "rs_s":"true" }, "apply": { "model": "engineersdecor:block/pipe/straight_pipe_valve_rs_connector_submodel", "y": 180 } },
{ "when": { "rs_w":"true" }, "apply": { "model": "engineersdecor:block/pipe/straight_pipe_valve_rs_connector_submodel", "y": 270 } },
{ "when": { "rs_e":"true" }, "apply": { "model": "engineersdecor:block/pipe/straight_pipe_valve_rs_connector_submodel", "y": 90 } },
{ "when": { "rs_u":"true" }, "apply": { "model": "engineersdecor:block/pipe/straight_pipe_valve_rs_connector_submodel", "x": -90 } },
{ "when": { "rs_d":"true" }, "apply": { "model": "engineersdecor:block/pipe/straight_pipe_valve_rs_connector_submodel", "x": 90 } }
]}

View file

@ -0,0 +1,14 @@
{ "multipart": [
{ "when": { "facing":"north" }, "apply": { "model": "engineersdecor:block/pipe/straight_pipe_valve_redstone_analog_model", "y": 0 } },
{ "when": { "facing":"south" }, "apply": { "model": "engineersdecor:block/pipe/straight_pipe_valve_redstone_analog_model", "y": 180 } },
{ "when": { "facing":"west" }, "apply": { "model": "engineersdecor:block/pipe/straight_pipe_valve_redstone_analog_model", "y": 270 } },
{ "when": { "facing":"east" }, "apply": { "model": "engineersdecor:block/pipe/straight_pipe_valve_redstone_analog_model", "y": 90 } },
{ "when": { "facing":"up" }, "apply": { "model": "engineersdecor:block/pipe/straight_pipe_valve_redstone_analog_model", "x": -90 } },
{ "when": { "facing":"down" }, "apply": { "model": "engineersdecor:block/pipe/straight_pipe_valve_redstone_analog_model", "x": 90 } },
{ "when": { "rs_n":"true" }, "apply": { "model": "engineersdecor:block/pipe/straight_pipe_valve_rs_connector_submodel", "y": 0 } },
{ "when": { "rs_s":"true" }, "apply": { "model": "engineersdecor:block/pipe/straight_pipe_valve_rs_connector_submodel", "y": 180 } },
{ "when": { "rs_w":"true" }, "apply": { "model": "engineersdecor:block/pipe/straight_pipe_valve_rs_connector_submodel", "y": 270 } },
{ "when": { "rs_e":"true" }, "apply": { "model": "engineersdecor:block/pipe/straight_pipe_valve_rs_connector_submodel", "y": 90 } },
{ "when": { "rs_u":"true" }, "apply": { "model": "engineersdecor:block/pipe/straight_pipe_valve_rs_connector_submodel", "x": -90 } },
{ "when": { "rs_d":"true" }, "apply": { "model": "engineersdecor:block/pipe/straight_pipe_valve_rs_connector_submodel", "x": 90 } }
]}

View file

@ -0,0 +1,14 @@
{
"forge_marker": 1,
"defaults": {
"model": "engineersdecor:block/pole/straight_thick_metal_pole_model",
"textures": {
"particle": "engineersdecor:block/pole/thick_steel_pole_side_texture",
"side": "engineersdecor:block/pole/thick_steel_pole_side_texture",
"top": "engineersdecor:block/pole/thick_steel_pole_top_texture"
}
},
"variants": {
"facing": { "north": {"y":180}, "south": {"y":0}, "west": {"y":90}, "east": {"y":270}, "up": {"x":90}, "down": {"x":270}}
}
}

View file

@ -0,0 +1,15 @@
{
"forge_marker": 1,
"defaults": {
"model": "engineersdecor:block/pole/straight_thick_metal_pole_head_model",
"x":-90,
"textures": {
"particle": "engineersdecor:blocks/pole/thick_steel_pole_side_texture",
"side": "engineersdecor:blocks/pole/thick_steel_pole_side_texture",
"top": "engineersdecor:blocks/pole/thick_steel_pole_top_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,14 @@
{
"forge_marker": 1,
"defaults": {
"model": "engineersdecor:block/pole/straight_thin_metal_pole_model",
"textures": {
"particle": "engineersdecor:block/pole/thin_steel_pole_side_texture",
"side": "engineersdecor:block/pole/thin_steel_pole_side_texture",
"top": "engineersdecor:block/pole/thin_steel_pole_top_texture"
}
},
"variants": {
"facing": { "north": {"y":180}, "south": {"y":0}, "west": {"y":90}, "east": {"y":270}, "up": {"x":90}, "down": {"x":270}}
}
}

View file

@ -0,0 +1,15 @@
{
"forge_marker": 1,
"defaults": {
"model": "engineersdecor:block/pole/straight_thin_metal_pole_head_model",
"x":-90,
"textures": {
"particle": "engineersdecor:blocks/pole/thin_steel_pole_side_texture",
"side": "engineersdecor:blocks/pole/thin_steel_pole_side_texture",
"top": "engineersdecor:blocks/pole/thin_steel_pole_top_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,7 @@
{
"forge_marker": 1,
"defaults": { "model": "engineersdecor:block/crafting_table/treated_wood_crafting_table_model" },
"variants": {
"facing": { "north": {"y":0}, "south": {"y":180}, "west": {"y":-90}, "east": {"y":90}, "up":{}, "down":{} }
}
}

View file

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

View file

@ -0,0 +1,14 @@
{
"forge_marker": 1,
"defaults": {
"model": "engineersdecor:block/pole/straight_pole_model",
"textures": {
"particle": "engineersdecor:block/pole/treated_wood_pole_side_texture",
"side": "engineersdecor:block/pole/treated_wood_pole_side_texture",
"top": "engineersdecor:block/pole/treated_wood_pole_top_texture"
}
},
"variants": {
"facing": { "north": {"y":180}, "south": {"y":0}, "west": {"y":90}, "east": {"y":270}, "up": {"x":90}, "down": {"x":270}}
}
}

View file

@ -0,0 +1,15 @@
{
"forge_marker": 1,
"defaults": {
"model": "engineersdecor:block/pole/straight_pole_head_model",
"x":-90,
"textures": {
"particle": "engineersdecor:block/pole/treated_wood_pole_side_texture",
"side": "engineersdecor:block/pole/treated_wood_pole_side_texture",
"top": "engineersdecor:block/pole/treated_wood_pole_top_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,15 @@
{
"forge_marker": 1,
"defaults": {
"model": "engineersdecor:block/pole/straight_pole_support_model",
"x":-90,
"textures": {
"particle": "engineersdecor:block/pole/treated_wood_pole_side_texture",
"side": "engineersdecor:block/pole/treated_wood_pole_side_texture",
"top": "engineersdecor:block/pole/treated_wood_pole_top_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,5 @@
{
"forge_marker": 1,
"defaults": { "model": "engineersdecor:block/furniture/treated_wood_stool_model" },
"variants": { "": [{}] }
}

View file

@ -0,0 +1,5 @@
{
"forge_marker": 1,
"defaults": { "model": "engineersdecor:block/furniture/treated_wood_table_model" },
"variants": { "": [{}] }
}

View file

@ -0,0 +1,9 @@
{
"forge_marker": 1,
"defaults": {
"model": "engineersdecor:block/furniture/treated_wood_window_model"
},
"variants": {
"facing": { "north": {"y":0}, "south": {"y":0}, "west": {"y":90}, "east": {"y":90}, "up": {"x":90}, "down": {"x":90} }
}
}

View file

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

View file

@ -0,0 +1,178 @@
{
"language": "English",
"language.code": "en_us",
"language.region": "United States",
"itemGroup.tabengineersdecor": "Engineer's Decor",
"engineersdecor.config.title": "Engineer's Decor Config",
"engineersdecor.tooltip.hint.extended": "§6[§9SHIFT§r More Info§6]§r",
"engineersdecor.tooltip.hint.help": "§6[§9CTRL-SHIFT§r Help§6]§r",
"engineersdecor.tooltip.slabpickup.help": "§rFast pickup by left-clicking while looking up/down and holding this slab.",
"engineersdecor.config.pattern_excludes": "Pattern excludes",
"engineersdecor.config.pattern_includes": "Pattern includes",
"engineersdecor.config.without_clinker_bricks": "Without clinker bricks",
"engineersdecor.config.without_slag_bricks": "Without slag bricks",
"engineersdecor.config.without_rebar_concrete": "Without rebar concrete",
"engineersdecor.config.without_walls": "Without walls",
"engineersdecor.config.without_stairs": "Without stairs",
"engineersdecor.config.without_ie_concrete_wall": "Without concrete wall",
"engineersdecor.config.without_panzer_glass": "Without panzer glass",
"engineersdecor.config.without_crafting_table": "Without crafting table",
"engineersdecor.config.without_lab_furnace": "Without lab furnace",
"engineersdecor.config.without_electrical_furnace": "Without electrical furnace",
"engineersdecor.config.without_treated_wood_furniture": "Without tr. wood furniture",
"engineersdecor.config.without_windows": "Without windows",
"engineersdecor.config.without_light_sources": "Without lights",
"engineersdecor.config.without_ladders": "Without ladders",
"engineersdecor.config.without_chair_sitting": "Without chair sitting",
"engineersdecor.config.without_mob_chair_sitting": "Without chair mob sitting",
"engineersdecor.config.without_ladder_speed_boost": "Without ladder speed boost",
"engineersdecor.config.without_crafting_table_history": "Without crafting table history",
"engineersdecor.config.without_valves": "Without valves",
"engineersdecor.config.without_passive_fluid_accumulator": "Without fluid accumulator",
"engineersdecor.config.without_waste_incinerator": "Without waste incinerator",
"engineersdecor.config.without_sign_plates": "Without signs",
"engineersdecor.config.without_factory_dropper": "Without factory dropper",
"engineersdecor.config.without_slabs": "Without slabs",
"engineersdecor.config.without_halfslabs": "Without slab slices",
"engineersdecor.config.without_direct_slab_pickup": "Without slab pickup",
"engineersdecor.config.without_poles": "Without poles",
"engineersdecor.config.without_hsupports": "Without h. supports",
"engineersdecor.config.without_tooltips": "Without tooltips",
"engineersdecor.config.without_recipes": "Without recipes",
"engineersdecor.config.furnace_smelting_speed_percent": "Furnace: Smelting speed %",
"engineersdecor.config.furnace_fuel_efficiency_percent": "Furnace: Fuel efficiency %",
"engineersdecor.config.furnace_boost_energy_consumption": "Furnace: Boost energy",
"engineersdecor.config.chair_mob_sitting_probability_percent": "Chairs: Sitting chance %",
"engineersdecor.config.chair_mob_standup_probability_percent": "\"Chairs: Stand up chance %\"",
"engineersdecor.config.with_crafting_quickmove_buttons": "Crafting table: Move buttons",
"engineersdecor.config.pipevalve_max_flowrate": "Valves: Max flow rate",
"engineersdecor.config.pipevalve_redstone_gain": "Valves: Redstone slope",
"engineersdecor.config.e_furnace_speed_percent": "E-furnace: Smelting speed %",
"engineersdecor.config.e_furnace_power_consumption": "E-furnace: Power consumption",
"block.engineersdecor.clinker_brick_block": "Clinker Brick Block",
"block.engineersdecor.clinker_brick_block.help": "§6A brick block with position dependent texture variations.§r\nLooks slightly darker and more color intensive than the vanilla brick block.",
"block.engineersdecor.clinker_brick_stained_block": "Stained Clinker Brick Block",
"block.engineersdecor.clinker_brick_stained_block.help": "§6A brick block with position dependent texture variations.§r\nLooks slightly darker and more color intensive than the vanilla brick block. Has more visible traces of grime or stain.",
"block.engineersdecor.slag_brick_block": "Slag Brick Block",
"block.engineersdecor.slag_brick_block.help": "§6A gray-brown brick block with position dependent texture variations.",
"block.engineersdecor.rebar_concrete": "Rebar Concrete Block",
"block.engineersdecor.rebar_concrete.help": "§6Steel reinforced concrete block.§r Expensive but Creeper-proof like obsidian.",
"block.engineersdecor.panzerglass_block": "Panzer Glass Block",
"block.engineersdecor.panzerglass_block.help": "§6Reinforced glass block.§r Expensive, explosion-proof. Dark gray tint, faint structural lines visible, multi texture for seemless look.",
"block.engineersdecor.rebar_concrete_tile": "Rebar Concrete Tile",
"block.engineersdecor.rebar_concrete_tile.help": "§6Steel reinforced concrete tile.§r Expensive but Creeper-proof like obsidian.",
"block.engineersdecor.clinker_brick_slab": "Clinker Brick Slab",
"block.engineersdecor.clinker_brick_slab.help": "§6Slab made from a Clinker Block.§r\nLooks slightly darker and more color intensive than the vanilla brick.",
"block.engineersdecor.clinker_brick_stained_slab": "Stained Clinker Brick Slab",
"block.engineersdecor.clinker_brick_stained_slab.help": "§6Slab made from a Stained Clinker Block.",
"block.engineersdecor.slag_brick_slab": "Slag Brick Slab",
"block.engineersdecor.slag_brick_slab.help": "§6A gray-brown brick slab.",
"block.engineersdecor.rebar_concrete_slab": "Rebar Concrete Slab",
"block.engineersdecor.rebar_concrete_slab.help": "§6Steel reinforced concrete slab.§r Expensive but Creeper-proof like obsidian.",
"block.engineersdecor.rebar_concrete_tile_slab": "Rebar Concrete Tile Slab",
"block.engineersdecor.rebar_concrete_tile_slab.help": "§6Steel reinforced concrete tile slab.§r Expensive but Creeper-proof like obsidian.",
"block.engineersdecor.panzerglass_slab": "Panzer Glass Slab",
"block.engineersdecor.panzerglass_slab.help": "§6Reinforced glass slab.§r Expensive, explosion-proof. Dark gray tint, faint structural lines visible.",
"block.engineersdecor.rebar_concrete_wall": "Rebar Concrete Wall",
"block.engineersdecor.rebar_concrete_wall.help": "§6Steel reinforced concrete wall.§r Expensive but Creeper-proof like obsidian.",
"block.engineersdecor.concrete_wall": "Concrete Wall",
"block.engineersdecor.concrete_wall.help": "§6Wall made of solid concrete.",
"block.engineersdecor.clinker_brick_wall": "Clinker Brick Wall",
"block.engineersdecor.clinker_brick_wall.help": "§6Simplistic Clinker Brick Wall.",
"block.engineersdecor.slag_brick_wall": "Slag Brick Wall",
"block.engineersdecor.slag_brick_wall.help": "§6Simplistic Slag Brick Wall.",
"block.engineersdecor.metal_rung_ladder": "Metal Rung Ladder",
"block.engineersdecor.metal_rung_ladder.help": "§6Typical industrial wall ladder, consisting of horizontal metal rod rungs.§r Look up/down to climb faster.",
"block.engineersdecor.metal_rung_steps": "Staggered Metal Steps",
"block.engineersdecor.metal_rung_steps.help": "§6Staggered rod rungs affixed to a wall, allowing to climb up, fall down, and so on.§r Look up/down to climb faster.",
"block.engineersdecor.treated_wood_ladder": "Treated Wood Ladder",
"block.engineersdecor.treated_wood_ladder.help": "§6Weather-proof wooden ladder.§r Look up/down to climb faster.",
"block.engineersdecor.clinker_brick_stairs": "Clinker Brick Stairs",
"block.engineersdecor.clinker_brick_stairs.help": "§6Looks slightly darker and more color intensive than the vanilla brick block.",
"block.engineersdecor.clinker_brick_stained_stairs": "Stained Clinker Brick Stairs",
"block.engineersdecor.clinker_brick_stained_stairs.help": "§6Looks slightly darker and more color intensive than the vanilla brick block. Has more visible traces of grime or stain.",
"block.engineersdecor.slag_brick_stairs": "Clinker Brick Stairs",
"block.engineersdecor.slag_brick_stairs.help": "§6Looks slightly darker and more color intensive than the vanilla brick block.",
"block.engineersdecor.rebar_concrete_stairs": "Rebar Concrete Stairs",
"block.engineersdecor.rebar_concrete_stairs.help": "§6Steel reinforced concrete stairs.§r Expensive but Creeper-proof like obsidian.",
"block.engineersdecor.rebar_concrete_tile_stairs": "Rebar Concrete Tile Stairs",
"block.engineersdecor.rebar_concrete_tile_stairs.help": "§6Steel reinforced concrete tile stairs.§r Expensive but Creeper-proof like obsidian.",
"block.engineersdecor.treated_wood_pole": "Straight Treated Wood Pole",
"block.engineersdecor.treated_wood_pole.help": "§6Straight pole fragment with a diameter of a wire relay.§r\n Can be useful as alternative to the wire posts if special lengths are needed, or as support for structures.",
"block.engineersdecor.treated_wood_pole_head": "Straight Treated Wood Pole Head/Foot",
"block.engineersdecor.treated_wood_pole_head.help": "§6Wooden part fitting as foot or head of straight poles.",
"block.engineersdecor.treated_wood_pole_support": "Straight Treated Wood Pole Support",
"block.engineersdecor.treated_wood_pole_support.help": "§6Heavy duty wooden support part fitting as foot or head of straight poles.",
"block.engineersdecor.thick_steel_pole": "Straight Thick Steel Pole",
"block.engineersdecor.thick_steel_pole.help": "§6Straight hollow pole fragment (6x6x16) for structural support purposes.",
"block.engineersdecor.thin_steel_pole": "Straight Thin Steel Pole",
"block.engineersdecor.thin_steel_pole.help": "§6Straight hollow pole fragment (4x4x16) for structural support purposes.",
"block.engineersdecor.thin_steel_pole_head": "Straight Thin Steel Pole head/foot",
"block.engineersdecor.thin_steel_pole_head.help": "§6Steel part fitting as foot or head of the thin steel pole (4x4x16).",
"block.engineersdecor.thick_steel_pole_head": "Straight Thick Steel Pole Head/Foot",
"block.engineersdecor.thick_steel_pole_head.help": "§6Steel part fitting as foot or head of the thick steel pole (6x6x16).",
"block.engineersdecor.steel_double_t_support": "Steel Double T Support",
"block.engineersdecor.steel_double_t_support.help": "§6Horizontal ceiling support beam fragment.",
"block.engineersdecor.treated_wood_table": "Treated Wood Table",
"block.engineersdecor.treated_wood_table.help": "§6Robust four-legged wood table.§r Indoor and outdoor use.",
"block.engineersdecor.treated_wood_stool": "Treated Wood Stool",
"block.engineersdecor.treated_wood_stool.help": "§6Robust Wood Stool.§r Indoor and outdoor use.",
"block.engineersdecor.treated_wood_crafting_table": "Treated Wood Crafting Table",
"block.engineersdecor.treated_wood_crafting_table.help": "§6Robust and weather-proof.§r Eight storage slots, keeps inventory, no vanilla recipe book.\n Click up/down arrow buttons for crafting history selection, output slot for item placement, X-button to clear crafting grid and history. Shift-click stack: player-to-storage stack transfer when crafting grid empty, otherwise player-to-grid stack transfer. Automatically distributes the clicked stack.",
"block.engineersdecor.treated_wood_side_table": "Treated Wood Side Table",
"block.engineersdecor.treated_wood_side_table.help": "§6Needed after the work's done.",
"block.engineersdecor.iron_inset_light": "Inset Light",
"block.engineersdecor.iron_inset_light.help": "§6Small glowstone light source, sunk into the floor, ceiling or wall.§r\n Useful to light up places where electrical light installations are problematic. Light level like a torch.",
"block.engineersdecor.treated_wood_window": "Treated Wood Window",
"block.engineersdecor.treated_wood_window.help": "§6Wood framed triple glazed window. Well insulating.§r Does not connect to adjacent blocks like glass panes.",
"block.engineersdecor.treated_wood_windowsill": "Treated Wood Window Sill",
"block.engineersdecor.treated_wood_windowsill.help": "§6Simple window decoration.",
"block.engineersdecor.steel_framed_window": "Steel Framed Window",
"block.engineersdecor.steel_framed_window.help": "§6Steel framed triple glazed window. Well insulating. §r Does not connect to adjacent blocks like glass panes.",
"block.engineersdecor.small_lab_furnace": "Small Laboratory Furnace",
"block.engineersdecor.small_lab_furnace.help": "§6Small metal cased lab kiln.§r Solid fuel consuming, updraught. Slightly hotter and better isolated than a cobblestone furnace, therefore more efficient. Two auxiliary slots e.g. for storage. Two stack internal hopper fifos for input, output, and fuel. Place an external heater into a aux slot and connect power for electrical smelting speed boost.",
"block.engineersdecor.small_electrical_furnace": "Small Electrical Furnace",
"block.engineersdecor.small_electrical_furnace.help": "§6Small metal cased pass-through furnace.§r Automatically draws items from the input side and puts items into the inventory at the output side. Items can be inserted or drawn from all sides using hoppers. Implicitly bypasses items that cannot be smelted or cooked to the output. Slightly more energy efficient and faster than a heated cobblestone furnace. Fifos and feeders transfer whole stacks. Feeders require a bit of power.",
"block.engineersdecor.small_waste_incinerator": "Small Waste Incinerator",
"block.engineersdecor.small_waste_incinerator.help": "§6Trash with internal fifo slots.§r Items can be inserted on all sides, and are kept until there is no space left in the fifo. After that the oldest stack will be incinerated. Apply electrical RF/FE power to increase the processing speed. Keeps its inventory when being relocated.",
"block.engineersdecor.straight_pipe_valve": "Fluid Pipe Check Valve",
"block.engineersdecor.straight_pipe_valve.help": "§6Straight fluid pipe fragment.§r Conducts fluids only in one direction. Does not connect to the sides. Reduces flow rate. Sneak to place in reverse direction.",
"block.engineersdecor.straight_pipe_valve_redstone": "Redstone Controlled Fluid Valve",
"block.engineersdecor.straight_pipe_valve_redstone.help": "§6Straight fluid pipe fragment.§r Conducts fluids only in one direction. Does not connect to the sides. Sneak to place in reverse direction. Blocks if not redstone powered.",
"block.engineersdecor.straight_pipe_valve_redstone_analog": "Redstone Analog Fluid Valve",
"block.engineersdecor.straight_pipe_valve_redstone_analog.help": "§6Straight fluid pipe fragment.§r Conducts fluids only in one direction. Does not connect to the sides. Sneak to place in reverse direction. Blocks if not redstone powered, reduces the flow rate linear from power 1 to 14, opens to maximum possible valve flow rate for power 15.",
"block.engineersdecor.passive_fluid_accumulator": "Passive Fluid Accumulator",
"block.engineersdecor.passive_fluid_accumulator.help": "§6Vacuum suction based fluid collector.§r Has one output, all other sides are input. Drains fluids from adjacent tanks when being drained from the output port by a pump.",
"block.engineersdecor.factory_dropper": "Factory Dropper",
"block.engineersdecor.factory_dropper.help": "§6Dropper suitable for advanced factory automation.§r Has twelve round-robin selected slots. Drop force, angle, stack size, and cool-down delay adjustable in the GUI. Three stack compare slots with logical AND or OR can be used as internal trigger source. Internal trigger can be AND'ed or OR'ed with the external redstone signal trigger. Trigger simulation buttons for testing. Pre-opens shutter door when internal trigger conditions are met. Drops all matching stacks simultaneously. Click on all elements in the GUI to see how it works.",
"block.engineersdecor.small_mineral_smelter": "Small Mineral Melting Furnace",
"block.engineersdecor.small_mineral_smelter.help": "§6High temperature, high insulation electrical stone melting furnace.§r\n Heats up mineral blocks to magma blocks, and finally to lava. Due to the miniturized device size the process is rather inefficient - much time and energy is needed to liquefy a stone block.",
"block.engineersdecor.sign_decor": "Sign Plate (Engineer's decor)",
"block.engineersdecor.sign_decor.help": "§6This should not be craftable or visible in JEI. Used for creative tab and screenshots.",
"block.engineersdecor.sign_hotwire": "Sign \"Caution Hot Wire\"",
"block.engineersdecor.sign_hotwire.help": "§6Electrical hazard warning. Don't forget to place around HV, or you will have a nonconformity in the next audit.",
"block.engineersdecor.sign_mindstep": "Sign \"Mind The Step\"",
"block.engineersdecor.sign_mindstep.help": "§6Placable on walls (horizontally).",
"block.engineersdecor.sign_danger": "Sign \"Caution Really Dangerous There\"",
"block.engineersdecor.sign_danger.help": "§6General danger warning.",
"block.engineersdecor.sign_defense": "Sign \"Caution Defense System Ahead\"",
"block.engineersdecor.sign_defense.help": "§6Warning sign for turrets, Tesla Coils, and traps.",
"block.engineersdecor.sign_factoryarea": "Sign \"Factory Area\"",
"block.engineersdecor.sign_factoryarea.help": "§6Marker sign for buildings or areas where the really big machines are located.",
"block.engineersdecor.halfslab_rebar_concrete": "Rebar Concrete Slice",
"block.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.",
"block.engineersdecor.halfslab_concrete": "Concrete Slice",
"block.engineersdecor.halfslab_concrete.help": "§6Vertically stackable slice.§r Right/left click with the slice stack on the top or bottom surface to add/remove slices.",
"block.engineersdecor.halfslab_treated_wood": "Treated Wood Slice",
"block.engineersdecor.halfslab_treated_wood.help": "§6Vertically stackable slice.§r Right/left click with the slice stack on the top or bottom surface to add/remove slices.",
"block.engineersdecor.halfslab_sheetmetal_iron": "Iron Sheet Metal Slice",
"block.engineersdecor.halfslab_sheetmetal_iron.help": "§6Vertically stackable slice.§r Right/left click with the slice stack on the top or bottom surface to add/remove slices.",
"block.engineersdecor.halfslab_sheetmetal_steel": "Steel Sheet Metal Slice",
"block.engineersdecor.halfslab_sheetmetal_steel.help": "§6Vertically stackable slice.§r Right/left click with the slice stack on the top or bottom surface to add/remove slices.",
"block.engineersdecor.halfslab_sheetmetal_copper": "Copper Sheet Metal Slice",
"block.engineersdecor.halfslab_sheetmetal_copper.help": "§6Vertically stackable slice.§r Right/left click with the slice stack on the top or bottom surface to add/remove slices.",
"block.engineersdecor.halfslab_sheetmetal_gold": "Gold Sheet Metal Slice",
"block.engineersdecor.halfslab_sheetmetal_gold.help": "§6Vertically stackable slice.§r Right/left click with the slice stack on the top or bottom surface to add/remove slices.",
"block.engineersdecor.halfslab_sheetmetal_aluminum": "Aluminum Sheet Metal Slice",
"block.engineersdecor.halfslab_sheetmetal_aluminum.help": "§6Vertically stackable slice.§r Right/left click with the slice stack on the top or bottom surface to add/remove slices."
}

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