v1.0.18 release merge.

This commit is contained in:
stfwi 2020-05-09 16:05:39 +02:00
commit 99394e64c1
764 changed files with 27643 additions and 11838 deletions

1
.gitignore vendored
View file

@ -35,3 +35,4 @@ signing.*
/*/src/main/java/archive
/*/src/main/resources/assets/minecraft
/*/tests
_*

View file

@ -83,8 +83,7 @@ start-server:
sanatize:
@echo "[1.12] Running sanatising tasks ..."
@djs tasks.js trailing-whitespaces
@djs tasks.js tabs-to-spaces
@djs tasks.js sanatize
@djs tasks.js sync-languages
@djs tasks.js version-check
@djs tasks.js update-json

View file

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

View file

@ -1,6 +1,18 @@
{
"homepage": "https://www.curseforge.com/minecraft/mc-mods/engineers-decor/",
"1.12.2": {
"1.0.20": "[R] Release based on v1.0.20-b6. Release-to-release changes: * Manual back ported. * Steel Mesh Fence Gate back ported. * E-Furnace speed selection switch back ported. * Labeled Crate back ported. * Minor bug fixes, compatibility changes.",
"1.0.20-b6": "[F] Implemented compat related to issue #91.",
"1.0.20-b5": "[A] Back-ported Patchouli based Manual (you need to install Vazkii_'s Patchouli, too).\n[A] Back-ported Steel Mesh Fence Gate.\n[M] Minor back-porting compatibility refractoring.",
"1.0.20-b4": "[F] Fixed TE registration bug for Crate registry-optout (issue #91, thx tyon2006).",
"1.0.20-b3": "[/] Version skipped for 1.12.2.",
"1.0.20-b2": "[A] Backported Electrical Furnace GUI speed selection switch.\n[A] Backported Labeled Crate (storage crate with built-in item frame).",
"1.0.20-b1": "[/] Version skipped for 1.12.2.",
"1.0.19": "[R] Release based on v1.0.19-b4. Release-to-release changes: * Transfer fixes for Tree Cutter / Block Breaker, and Factory hopper. * Cleanups, feature backports * Visual fixes and improvements\n[A] Backport of status display for Tree Cutter, Block Breaker and Solar Panel.",
"1.0.19-b4": "[A] Creative tab opt-out visibility handling added (issue #90, thx pimalel233).",
"1.0.19-b3": "[A] Factory Hopper: Added bottom item handler (CR#227).",
"1.0.19-b2": "[F] Fixed Floor Grating item pass-through jitters (thx Cid).\n[M] Removed obsolete recipe collision testing recipes.",
"1.0.19-b1": "[F] Fixed Tree Cutter / Block Breaker not accepting small energy transfers (thx WindFox, issue #82).",
"1.0.18": "[R] Release based on v1.0.18-b2. Release-to-release changes: * Tree cutter config fixes. * Treated Wood Crafting Table mouse tweaks. * Lang updates.\n[M] Lang update ru_ru (PR#77, thanks Smollet777).",
"1.0.18-b2": "[A] Added Treated Wood Crafting table tweaks (ctrl-shift moves all same stacks from the inventory, mouse wheel over crafting slot increases/decreases crafting grid stacks).\n[F] EN Lang file fixed (issue #76, thx Riverstar907).\n[F] Fixed Tree Cutter not respecting power-required config (thx federsavo, issue #77).",
"1.0.18-b1": "[M] Lang ru_ru updated (Smollet777).",
@ -76,7 +88,7 @@
"1.0.0-b1": "[A] Initial structure.\n[A] Added clinker bricks and clinker brick stairs.\n[A] Added slag bricks and slag brick stairs.\n[A] Added metal rung ladder.\n[A] Added staggered metal steps ladder.\n[A] Added treated wood ladder.\n[A] Added treated wood pole.\n[A] Added treated wood table."
},
"promos": {
"1.12.2-recommended": "1.0.18",
"1.12.2-latest": "1.0.18"
"1.12.2-recommended": "1.0.20",
"1.12.2-latest": "1.0.20"
}
}

View file

@ -10,6 +10,49 @@ Mod sources for Minecraft version 1.12.2.
----
## Version history
~ v1.1.0-b1 [M]
-------------------------------------------------------------------
- v1.0.20 [R] Release based on v1.0.20-b6. Release-to-release changes:
* Manual back ported.
* Steel Mesh Fence Gate back ported.
* E-Furnace speed selection switch back ported.
* Labeled Crate back ported.
* Minor bug fixes, compatibility changes.
-------------------------------------------------------------------
- v1.0.20-b6 [F] Implemented compat related to issue #91.
- v1.0.20-b5 [A] Back-ported Patchouli based Manual (you need to install Vazkii_'s Patchouli, too).
[A] Back-ported Steel Mesh Fence Gate.
[M] Minor back-porting compatibility refractoring.
- v1.0.20-b4 [F] Fixed TE registration bug for Crate registry-optout (issue #91, thx tyon2006).
- v1.0.20-b3 [/] Version skipped for 1.12.2.
- v1.0.20-b2 [A] Backported Electrical Furnace GUI speed selection switch.
[A] Backported Labeled Crate (storage crate with built-in item frame).
- v1.0.20-b1 [/] Version skipped for 1.12.2.
-------------------------------------------------------------------
- v1.0.19 [R] Release based on v1.0.19-b4. Release-to-release changes:
* Transfer fixes for Tree Cutter / Block Breaker, and Factory hopper.
* Cleanups, feature backports
* Visual fixes and improvements
-------------------------------------------------------------------
[A] Backport of status display for Tree Cutter, Block Breaker and Solar Panel.
- v1.0.19-b4 [A] Creative tab opt-out visibility handling added (issue #90, thx pimalel233).
- v1.0.19-b3 [A] Factory Hopper: Added bottom item handler (CR#227).
- v1.0.19-b2 [F] Fixed Floor Grating item pass-through jitters (thx Cid).
[M] Removed obsolete recipe collision testing recipes.
- v1.0.19-b1 [F] Fixed Tree Cutter / Block Breaker not accepting small energy transfers (thx WindFox, issue #82).
-------------------------------------------------------------------
- v1.0.18 [R] Release based on v1.0.18-b2. Release-to-release changes:
* Tree cutter config fixes.

View file

@ -22,7 +22,6 @@ import net.minecraft.block.SoundType;
import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.model.ModelLoader;
@ -31,7 +30,9 @@ import net.minecraftforge.fml.client.registry.ClientRegistry;
import net.minecraftforge.fml.common.registry.GameRegistry;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import javax.annotation.Nonnull;
@ -211,6 +212,13 @@ public class ModContent
ModAuxiliaries.getPixeledAABB(0,0,0, 16,16,16)
);
public static final BlockDecorLabeledCrate.DecorLabeledCrateBlock LABELED_CRATE = new BlockDecorLabeledCrate.DecorLabeledCrateBlock(
"labeled_crate",
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_LOOK_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT,
Material.WOOD, 0.5f, 128f, SoundType.METAL,
ModAuxiliaries.getPixeledAABB(0,0,0, 16,16,16)
);
//--------------------------------------------------------------------------------------------------------------------
public static final BlockDecorStraightPole TREATED_WOOD_POLE = new BlockDecorStraightPole(
@ -273,7 +281,14 @@ public class ModContent
public static final BlockDecorFence STEEL_MESH_FENCE = new BlockDecorFence(
"steel_mesh_fence",
BlockDecor.CFG_DEFAULT, Material.IRON, 2f, 15f, SoundType.METAL
BlockDecor.CFG_CUTOUT, Material.IRON, 2f, 15f, SoundType.METAL
);
public static final BlockDecorDoubleGate STEEL_MESH_FENCE_GATE = new BlockDecorDoubleGate(
"steel_mesh_fence_gate",
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_LOOK_PLACEMENT,
Material.IRON, 2f, 15f, SoundType.METAL,
ModAuxiliaries.getPixeledAABB(0,0,6.5, 16,16,9.5)
);
//--------------------------------------------------------------------------------------------------------------------
@ -338,7 +353,7 @@ public class ModContent
"steel_floor_grating",
BlockDecor.CFG_CUTOUT,
Material.IRON, 1.0f, 15f, SoundType.METAL,
ModAuxiliaries.getPixeledAABB(0,14,0, 16,16,16)
ModAuxiliaries.getPixeledAABB(0,14,0, 16,15.9,16)
);
//--------------------------------------------------------------------------------------------------------------------
@ -473,56 +488,62 @@ public class ModContent
{
public final Class<? extends TileEntity> clazz;
public final ResourceLocation key;
public TileEntityRegistrationData(Class<? extends TileEntity> c, String k) { clazz=c; key = new ResourceLocation(ModEngineersDecor.MODID, k); }
public final Block[] blocks;
public TileEntityRegistrationData(Class<? extends TileEntity> c, String k, Block... b)
{ clazz=c; key = new ResourceLocation(ModEngineersDecor.MODID, k); blocks=b; }
}
private static final TileEntityRegistrationData TREATED_WOOD_CRAFTING_TABLE_TEI = new TileEntityRegistrationData(
BlockDecorCraftingTable.BTileEntity.class, "te_crafting_table"
BlockDecorCraftingTable.BTileEntity.class, "te_crafting_table", TREATED_WOOD_CRAFTING_TABLE
);
private static final TileEntityRegistrationData LABELED_CRATE_TEI = new TileEntityRegistrationData(
BlockDecorLabeledCrate.LabeledCrateTileEntity.class, "te_labeled_crate", LABELED_CRATE
);
private static final TileEntityRegistrationData SMALL_LAB_FURNACE_TEI = new TileEntityRegistrationData(
BlockDecorFurnace.BTileEntity.class, "te_small_lab_furnace"
BlockDecorFurnace.BTileEntity.class, "te_small_lab_furnace", SMALL_ELECTRICAL_FURNACE
);
private static final TileEntityRegistrationData SMALL_ELECTRICAL_FURNACE_TEI = new TileEntityRegistrationData(
BlockDecorFurnaceElectrical.BTileEntity.class, "te_electrical_lab_furnace"
BlockDecorFurnaceElectrical.BTileEntity.class, "te_electrical_lab_furnace", SMALL_ELECTRICAL_FURNACE
);
private static final TileEntityRegistrationData STRAIGHT_PIPE_VALVE_TEI = new TileEntityRegistrationData(
BlockDecorPipeValve.BTileEntity.class, "te_pipe_valve"
BlockDecorPipeValve.BTileEntity.class, "te_pipe_valve", STRAIGHT_CHECK_VALVE,STRAIGHT_REDSTONE_ANALOG_VALVE,STRAIGHT_REDSTONE_VALVE
);
private static final TileEntityRegistrationData PASSIVE_FLUID_ACCUMULATOR_TEI = new TileEntityRegistrationData(
BlockDecorPassiveFluidAccumulator.BTileEntity.class, "te_passive_fluid_accumulator"
BlockDecorPassiveFluidAccumulator.BTileEntity.class, "te_passive_fluid_accumulator", PASSIVE_FLUID_ACCUMULATOR
);
private static final TileEntityRegistrationData SMALL_FLUID_FUNNEL_TEI = new TileEntityRegistrationData(
BlockDecorFluidFunnel.BTileEntity.class, "te_small_fluid_funnel"
BlockDecorFluidFunnel.BTileEntity.class, "te_small_fluid_funnel", SMALL_FLUID_FUNNEL
);
private static final TileEntityRegistrationData WASTE_INCINERATOR_TEI = new TileEntityRegistrationData(
BlockDecorWasteIncinerator.BTileEntity.class, "te_small_waste_incinerator"
BlockDecorWasteIncinerator.BTileEntity.class, "te_small_waste_incinerator", SMALL_WASTE_INCINERATOR
);
private static final TileEntityRegistrationData FACTORY_DROPPER_TEI = new TileEntityRegistrationData(
BlockDecorDropper.BTileEntity.class, "te_factory_dropper"
BlockDecorDropper.BTileEntity.class, "te_factory_dropper", FACTORY_DROPPER
);
private static final TileEntityRegistrationData FACTORY_HOPPER_TEI = new TileEntityRegistrationData(
BlockDecorHopper.BTileEntity.class, "te_factory_hopper"
BlockDecorHopper.BTileEntity.class, "te_factory_hopper", FACTORY_HOPPER
);
private static final TileEntityRegistrationData FACTORY_PLACER_TEI = new TileEntityRegistrationData(
BlockDecorPlacer.BTileEntity.class, "te_factory_placer"
BlockDecorPlacer.BTileEntity.class, "te_factory_placer", FACTORY_PLACER
);
private static final TileEntityRegistrationData SMALL_MINERAL_SMELTER_TEI = new TileEntityRegistrationData(
BlockDecorMineralSmelter.BTileEntity.class, "te_small_mineral_smelter"
BlockDecorMineralSmelter.BTileEntity.class, "te_small_mineral_smelter", SMALL_MINERAL_SMELTER
);
private static final TileEntityRegistrationData SMALL_MILKING_MACHINE_TEI = new TileEntityRegistrationData(
BlockDecorMilker.BTileEntity.class, "te_small_milking_machine"
BlockDecorMilker.BTileEntity.class, "te_small_milking_machine", SMALL_MILKING_MACHINE
);
private static final TileEntityRegistrationData SMALL_SOLAR_PANEL_TEI = new TileEntityRegistrationData(
BlockDecorSolarPanel.BTileEntity.class, "te_small_solar_panel"
BlockDecorSolarPanel.BTileEntity.class, "te_small_solar_panel", SMALL_SOLAR_PANEL
);
private static final TileEntityRegistrationData SMALL_TREE_CUTTER_TEI = new TileEntityRegistrationData(
BlockDecorTreeCutter.BTileEntity.class, "te_small_tree_cutter"
BlockDecorTreeCutter.BTileEntity.class, "te_small_tree_cutter", SMALL_TREE_CUTTER
);
private static final TileEntityRegistrationData SMALL_BLOCK_BREAKER_TEI = new TileEntityRegistrationData(
BlockDecorBreaker.BTileEntity.class, "te_small_block_breaker"
BlockDecorBreaker.BTileEntity.class, "te_small_block_breaker", SMALL_BLOCK_BREAKER
);
private static final TileEntityRegistrationData TEST_BLOCK_TEI = new TileEntityRegistrationData(
BlockDecorTest.BTileEntity.class, "te_testblock"
BlockDecorTest.BTileEntity.class, "te_testblock", TEST_BLOCK
);
//--------------------------------------------------------------------------------------------------------------------
@ -531,6 +552,7 @@ public class ModContent
private static final Object content[] = {
TREATED_WOOD_CRAFTING_TABLE, TREATED_WOOD_CRAFTING_TABLE_TEI,
LABELED_CRATE, LABELED_CRATE_TEI,
SMALL_LAB_FURNACE, SMALL_LAB_FURNACE_TEI,
SMALL_ELECTRICAL_FURNACE, SMALL_ELECTRICAL_FURNACE_TEI,
FACTORY_HOPPER,FACTORY_HOPPER_TEI,
@ -591,6 +613,7 @@ public class ModContent
STEEL_DOUBLE_T_SUPPORT,
STEEL_FLOOR_GRATING,
STEEL_MESH_FENCE,
STEEL_MESH_FENCE_GATE,
SIGN_HOTWIRE, SIGN_DANGER, SIGN_DEFENSE, SIGN_FACTORY_AREA, SIGN_EXIT, SIGN_MODLOGO,
TREATED_WOOD_SIDE_TABLE,
HALFSLAB_REBARCONCRETE, HALFSLAB_CONCRETE, HALFSLAB_GAS_CONCRETE, HALFSLAB_TREATEDWOOD,
@ -672,6 +695,7 @@ public class ModContent
}
registeredBlocks.add((Block) e);
} else if(e instanceof TileEntityRegistrationData) {
if((woor) && Arrays.stream(((TileEntityRegistrationData)e).blocks).allMatch(ModConfig::isOptedOut)) continue;
registeredTileEntityInits.add((TileEntityRegistrationData)e);
}
}
@ -705,6 +729,9 @@ public class ModContent
if(!ModConfig.isOptedOut(TREATED_WOOD_CRAFTING_TABLE)) {
ClientRegistry.bindTileEntitySpecialRenderer(BlockDecorCraftingTable.BTileEntity.class, new ModTesrs.TesrDecorCraftingTable());
}
if(!ModConfig.isOptedOut(LABELED_CRATE)) {
ClientRegistry.bindTileEntitySpecialRenderer(BlockDecorLabeledCrate.LabeledCrateTileEntity.class, new ModTesrs.TesrDecorLabeledCrate());
}
if(!ModConfig.isOptedOut(TEST_BLOCK)) {
ClientRegistry.bindTileEntitySpecialRenderer(BlockDecorTest.BTileEntity.class, new ModTesrs.TesrDecorTest());
}
@ -714,13 +741,7 @@ public class ModContent
// Invoked from CommonProxy.registerItems()
public static final void registerItemBlocks(RegistryEvent.Register<Item> event)
{
int n = 0;
for(Block e:registeredBlocks) {
ResourceLocation rl = e.getRegistryName();
if(rl == null) continue;
event.getRegistry().register(new ItemBlock(e).setRegistryName(rl));
++n;
}
for(Block e:registeredBlocks) event.getRegistry().register(new ItemDecor(e));
}
}

View file

@ -161,6 +161,7 @@ public class ModEngineersDecor
public static final int GUIID_FACTORY_DROPPER = 213105;
public static final int GUIID_FACTORY_HOPPER = 213106;
public static final int GUIID_FACTORY_PLACER = 213107;
public static final int GUIID_LABELED_CRATE = 213108;
@Override
public Object getServerGuiElement(final int guiid, final EntityPlayer player, final World world, int x, int y, int z)
@ -175,6 +176,7 @@ public class ModEngineersDecor
case GUIID_FACTORY_DROPPER: return BlockDecorDropper.getServerGuiElement(player, world, pos, te);
case GUIID_FACTORY_HOPPER: return BlockDecorHopper.getServerGuiElement(player, world, pos, te);
case GUIID_FACTORY_PLACER: return BlockDecorPlacer.getServerGuiElement(player, world, pos, te);
case GUIID_LABELED_CRATE: return BlockDecorLabeledCrate.getServerGuiElement(player, world, pos, te);
}
return null;
}
@ -193,6 +195,7 @@ public class ModEngineersDecor
case GUIID_FACTORY_DROPPER: return BlockDecorDropper.getClientGuiElement(player, world, pos, te);
case GUIID_FACTORY_HOPPER: return BlockDecorHopper.getClientGuiElement(player, world, pos, te);
case GUIID_FACTORY_PLACER: return BlockDecorPlacer.getClientGuiElement(player, world, pos, te);
case GUIID_LABELED_CRATE: return BlockDecorLabeledCrate.getClientGuiElement(player, world, pos, te);
}
return null;
}

View file

@ -9,6 +9,7 @@
package wile.engineersdecor.blocks;
import wile.engineersdecor.ModEngineersDecor;
import wile.engineersdecor.detail.ModAuxiliaries;
import net.minecraft.world.World;
import net.minecraft.block.Block;
import net.minecraft.block.properties.PropertyBool;
@ -17,7 +18,9 @@ import net.minecraft.block.SoundType;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.init.Blocks;
import net.minecraft.init.SoundEvents;
import net.minecraft.util.math.AxisAlignedBB;
@ -96,6 +99,16 @@ public class BlockDecorBreaker extends BlockDecorDirectedHorizontal
((BTileEntity)te).block_updated();
}
@Override
public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ)
{
if(world.isRemote) return true;
TileEntity te = world.getTileEntity(pos);
if(!(te instanceof BTileEntity)) return true;
((BTileEntity)te).state_message(player);
return true;
}
//--------------------------------------------------------------------------------------------------------------------
// Tile entity
//--------------------------------------------------------------------------------------------------------------------
@ -110,17 +123,20 @@ public class BlockDecorBreaker extends BlockDecorDirectedHorizontal
public static final int DEFAULT_MIN_BREAKING_TIME = 15;
public static final int MAX_BREAKING_TIME = 800;
private static int boost_energy_consumption = DEFAULT_BOOST_ENERGY;
private static int energy_max = 10000;
private static int breaking_reluctance = DEFAULT_BREAKING_RELUCTANCE;
private static int min_breaking_time = DEFAULT_MIN_BREAKING_TIME;
private static boolean requires_power = false;
private int tick_timer_;
private int active_timer_;
private int proc_time_elapsed_;
private int boost_energy_;
private int time_needed_;
private int energy_;
public static void on_config(int boost_energy_per_tick, int breaking_time_per_hardness, int min_breaking_time_ticks, boolean power_required)
{
boost_energy_consumption = TICK_INTERVAL * MathHelper.clamp(boost_energy_per_tick, 16, 512);
energy_max = Math.max(boost_energy_consumption * 10, 10000);
breaking_reluctance = MathHelper.clamp(breaking_time_per_hardness, 5, 50);
min_breaking_time = MathHelper.clamp(min_breaking_time_ticks, 10, 100);
requires_power = power_required;
@ -133,12 +149,36 @@ public class BlockDecorBreaker extends BlockDecorDirectedHorizontal
public void block_updated()
{ if(tick_timer_ > 2) tick_timer_ = 2; }
public void state_message(EntityPlayer player)
{
String soc = Integer.toString(MathHelper.clamp((energy_*100/energy_max),0,100));
String progress = "";
if((proc_time_elapsed_ > 0) && (time_needed_ > 0) && (active_timer_ > 0)) {
progress = " | " + Integer.toString((int)MathHelper.clamp((((double)proc_time_elapsed_) / ((double)time_needed_) * 100), 0, 100)) + "%%";
}
ModAuxiliaries.playerChatMessage(player, soc + "%%/" + energy_max + "RF" + progress);
}
public void readnbt(NBTTagCompound nbt)
{ energy_ = nbt.getInteger("energy"); }
private void writenbt(NBTTagCompound nbt)
{ nbt.setInteger("energy", energy_); }
// TileEntity ------------------------------------------------------------------------------
@Override
public boolean shouldRefresh(World world, BlockPos pos, IBlockState os, IBlockState ns)
{ return (os.getBlock() != ns.getBlock()) || (!(ns.getBlock() instanceof BlockDecorBreaker)); }
@Override
public void readFromNBT(NBTTagCompound nbt)
{ super.readFromNBT(nbt); readnbt(nbt); }
@Override
public NBTTagCompound writeToNBT(NBTTagCompound nbt)
{ super.writeToNBT(nbt); writenbt(nbt); return nbt; }
// IEnergyStorage ----------------------------------------------------------------------------
@Override
@ -151,11 +191,11 @@ public class BlockDecorBreaker extends BlockDecorDirectedHorizontal
@Override
public int getMaxEnergyStored()
{ return boost_energy_consumption; }
{ return boost_energy_consumption*2; }
@Override
public int getEnergyStored()
{ return boost_energy_; }
{ return energy_; }
@Override
public int extractEnergy(int maxExtract, boolean simulate)
@ -164,9 +204,9 @@ public class BlockDecorBreaker extends BlockDecorDirectedHorizontal
@Override
public int receiveEnergy(int maxReceive, boolean simulate)
{
if((boost_energy_ >= boost_energy_consumption) || (maxReceive < boost_energy_consumption)) return 0;
if(!simulate) boost_energy_ = boost_energy_consumption;
return boost_energy_consumption;
maxReceive = MathHelper.clamp(maxReceive, 0, Math.max(energy_max-energy_, 0));
if(!simulate) energy_ += maxReceive;
return maxReceive;
}
// Capability export ----------------------------------------------------------------------------
@ -253,11 +293,11 @@ public class BlockDecorBreaker extends BlockDecorDirectedHorizontal
tick_timer_ = IDLE_TICK_INTERVAL;
return;
}
int time_needed = (int)(target_state.getBlockHardness(world, pos) * breaking_reluctance) + min_breaking_time;
if(boost_energy_ >= boost_energy_consumption) {
boost_energy_ = 0;
time_needed_ = MathHelper.clamp((int)(target_state.getBlockHardness(world, pos) * breaking_reluctance) + min_breaking_time, min_breaking_time, MAX_BREAKING_TIME);
if(energy_ >= boost_energy_consumption) {
energy_ -= boost_energy_consumption;
proc_time_elapsed_ += TICK_INTERVAL * (1+BOOST_FACTOR);
time_needed += min_breaking_time * (3*BOOST_FACTOR/5);
time_needed_ += min_breaking_time * (3*BOOST_FACTOR/5);
active_timer_ = 2;
} else if(!requires_power) {
proc_time_elapsed_ += TICK_INTERVAL;
@ -266,8 +306,10 @@ public class BlockDecorBreaker extends BlockDecorDirectedHorizontal
--active_timer_;
}
boolean active = (active_timer_ > 0);
time_needed = MathHelper.clamp(time_needed, min_breaking_time, MAX_BREAKING_TIME);
if(proc_time_elapsed_ >= time_needed) {
if(requires_power && !active) {
proc_time_elapsed_ = Math.max(0, proc_time_elapsed_ - 2*TICK_INTERVAL);
}
if(proc_time_elapsed_ >= time_needed_) {
proc_time_elapsed_ = 0;
breakBlock(target_state, target_pos, world);
active = false;

View file

@ -352,20 +352,6 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
@SideOnly(Side.CLIENT)
private static class BGui extends GuiContainer
{
protected static final int BUTTON_NEXT = 0;
protected static final int BUTTON_PREV = 1;
protected static final int BUTTON_CLEAR_GRID = 2;
protected static final int BUTTON_NEXT_COLLISION_RECIPE = 3;
protected static final int BUTTON_FROM_STORAGE = 4;
protected static final int BUTTON_TO_STORAGE = 5;
protected static final int BUTTON_FROM_PLAYER = 6;
protected static final int BUTTON_TO_PLAYER = 7;
protected static final int ACTION_PLACE_CURRENT_HISTORY_SEL = 8;
protected static final int ACTION_PLACE_SHIFTCLICKED_STACK = 9;
protected static final int ACTION_MOVE_ALL_STACKS = 10;
protected static final int ACTION_INCREASE_CRAFTING_STACKS = 11;
protected static final int ACTION_DECREASE_CRAFTING_STACKS = 12;
protected static final ResourceLocation BACKGROUND = new ResourceLocation(ModEngineersDecor.MODID, "textures/gui/treated_wood_crafting_table.png");
protected final BTileEntity te;
protected final EntityPlayer player;
@ -383,15 +369,15 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
final int x0=((width - xSize)/2), y0=((height - ySize)/2);
buttons.clear();
if(with_assist) {
buttons.add(addButton(new GuiButtonImage(BUTTON_NEXT, x0+158,y0+44, 12,12, 194,44, 12, BACKGROUND)));
buttons.add(addButton(new GuiButtonImage(BUTTON_PREV, x0+158,y0+30, 12,12, 180,30, 12, BACKGROUND)));
buttons.add(addButton(new GuiButtonImage(BUTTON_CLEAR_GRID, x0+158,y0+58, 12,12, 194,8, 12, BACKGROUND)));
buttons.add(addButton(new GuiButtonImage(BUTTON_NEXT_COLLISION_RECIPE, x0+132,y0+18, 20,10, 183,95, 12, BACKGROUND)));
buttons.add(addButton(new GuiButtonImage(BContainer.BUTTON_NEXT, x0+158,y0+44, 12,12, 194,44, 12, BACKGROUND)));
buttons.add(addButton(new GuiButtonImage(BContainer.BUTTON_PREV, x0+158,y0+30, 12,12, 180,30, 12, BACKGROUND)));
buttons.add(addButton(new GuiButtonImage(BContainer.BUTTON_CLEAR_GRID, x0+158,y0+58, 12,12, 194,8, 12, BACKGROUND)));
buttons.add(addButton(new GuiButtonImage(BContainer.BUTTON_NEXT_COLLISION_RECIPE, x0+132,y0+18, 20,10, 183,95, 12, BACKGROUND)));
if(with_assist_quickmove_buttons) {
buttons.add(addButton(new GuiButtonImage(BUTTON_FROM_STORAGE, x0+49, y0+34, 9,17, 219,34, 17, BACKGROUND)));
buttons.add(addButton(new GuiButtonImage(BUTTON_TO_STORAGE, x0+49, y0+52, 9,17, 208,16, 17, BACKGROUND)));
buttons.add(addButton(new GuiButtonImage(BUTTON_FROM_PLAYER, x0+77, y0+71, 17,9, 198,71, 9, BACKGROUND)));
buttons.add(addButton(new GuiButtonImage(BUTTON_TO_PLAYER, x0+59, y0+71, 17,9, 180,71, 9, BACKGROUND)));
buttons.add(addButton(new GuiButtonImage(BContainer.BUTTON_FROM_STORAGE, x0+49, y0+34, 9,17, 219,34, 17, BACKGROUND)));
buttons.add(addButton(new GuiButtonImage(BContainer.BUTTON_TO_STORAGE, x0+49, y0+52, 9,17, 208,16, 17, BACKGROUND)));
buttons.add(addButton(new GuiButtonImage(BContainer.BUTTON_FROM_PLAYER, x0+77, y0+71, 17,9, 198,71, 9, BACKGROUND)));
buttons.add(addButton(new GuiButtonImage(BContainer.BUTTON_TO_PLAYER, x0+59, y0+71, 17,9, 180,71, 9, BACKGROUND)));
}
}
}
@ -412,8 +398,8 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
public void drawScreen(int mouseX, int mouseY, float partialTicks)
{
if(with_assist) {
buttons.get(BUTTON_NEXT_COLLISION_RECIPE).visible = te.has_recipe_collision();
buttons.get(BUTTON_NEXT_COLLISION_RECIPE).enabled = te.has_recipe_collision();
buttons.get(BContainer.BUTTON_NEXT_COLLISION_RECIPE).visible = te.has_recipe_collision();
buttons.get(BContainer.BUTTON_NEXT_COLLISION_RECIPE).enabled = te.has_recipe_collision();
}
drawDefaultBackground();
super.drawScreen(mouseX, mouseY, partialTicks);
@ -503,15 +489,15 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
protected void actionPerformed(GuiButton button)
{
switch(button.id) {
case BUTTON_NEXT:
case BUTTON_PREV:
case BUTTON_CLEAR_GRID:
case BUTTON_FROM_STORAGE:
case BUTTON_TO_STORAGE:
case BUTTON_FROM_PLAYER:
case BUTTON_TO_PLAYER:
case ACTION_PLACE_CURRENT_HISTORY_SEL:
case BUTTON_NEXT_COLLISION_RECIPE: {
case BContainer.BUTTON_NEXT:
case BContainer.BUTTON_PREV:
case BContainer.BUTTON_CLEAR_GRID:
case BContainer.BUTTON_FROM_STORAGE:
case BContainer.BUTTON_TO_STORAGE:
case BContainer.BUTTON_FROM_PLAYER:
case BContainer.BUTTON_TO_PLAYER:
case BContainer.ACTION_PLACE_CURRENT_HISTORY_SEL:
case BContainer.BUTTON_NEXT_COLLISION_RECIPE: {
NBTTagCompound nbt = new NBTTagCompound();
nbt.setInteger("action", button.id);
Networking.PacketTileNotify.sendToServer(te, nbt);
@ -548,7 +534,7 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
if(palce_in_crafting_grid) {
// Explicit grid placement.
NBTTagCompound nbt = new NBTTagCompound();
nbt.setInteger("action", ACTION_PLACE_SHIFTCLICKED_STACK);
nbt.setInteger("action", BContainer.ACTION_PLACE_SHIFTCLICKED_STACK);
nbt.setInteger("containerslot", slotId);
if(ModAuxiliaries.isCtrlDown()) nbt.setBoolean("move-all", true);
Networking.PacketTileNotify.sendToServer(te, nbt);
@ -557,7 +543,7 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
// Move all same items from the inventory of the clicked slot
// (or the crafting grid) to the corresponding target inventory.
NBTTagCompound nbt = new NBTTagCompound();
nbt.setInteger("action", ACTION_MOVE_ALL_STACKS);
nbt.setInteger("action", BContainer.ACTION_MOVE_ALL_STACKS);
nbt.setInteger("containerslot", slotId);
Networking.PacketTileNotify.sendToServer(te, nbt);
return;
@ -579,20 +565,20 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
if(count > 0) {
if((count < resultSlot.getStack().getMaxStackSize()) && (count < resultSlot.getSlotStackLimit())) {
NBTTagCompound nbt = new NBTTagCompound();
nbt.setInteger("action", ACTION_INCREASE_CRAFTING_STACKS);
nbt.setInteger("action", BContainer.ACTION_INCREASE_CRAFTING_STACKS);
if(limit > 1) nbt.setInteger("limit", limit);
Networking.PacketTileNotify.sendToServer(te, nbt);
}
} else if(!te.history.current().isEmpty()) {
NBTTagCompound nbt = new NBTTagCompound();
nbt.setInteger("action", ACTION_PLACE_CURRENT_HISTORY_SEL);
nbt.setInteger("action", BContainer.ACTION_PLACE_CURRENT_HISTORY_SEL);
Networking.PacketTileNotify.sendToServer(te, nbt);
}
} else if(wheel_inc < 0) {
if(count > 0) {
NBTTagCompound nbt = new NBTTagCompound();
if(limit > 1) nbt.setInteger("limit", limit);
nbt.setInteger("action", ACTION_DECREASE_CRAFTING_STACKS);
nbt.setInteger("action", BContainer.ACTION_DECREASE_CRAFTING_STACKS);
Networking.PacketTileNotify.sendToServer(te, nbt);
}
}
@ -605,7 +591,7 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
final Slot resultSlot = this.getSlotUnderMouse(); // double check
if(!(resultSlot instanceof BSlotCrafting)) return;
NBTTagCompound nbt = new NBTTagCompound();
nbt.setInteger("action", ACTION_PLACE_CURRENT_HISTORY_SEL);
nbt.setInteger("action", BContainer.ACTION_PLACE_CURRENT_HISTORY_SEL);
Networking.PacketTileNotify.sendToServer(te, nbt);
}
}
@ -644,6 +630,21 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
public static class BContainer extends Container
{
protected static final int BUTTON_NEXT = 0;
protected static final int BUTTON_PREV = 1;
protected static final int BUTTON_CLEAR_GRID = 2;
protected static final int BUTTON_NEXT_COLLISION_RECIPE = 3;
protected static final int BUTTON_FROM_STORAGE = 4;
protected static final int BUTTON_TO_STORAGE = 5;
protected static final int BUTTON_FROM_PLAYER = 6;
protected static final int BUTTON_TO_PLAYER = 7;
protected static final int ACTION_PLACE_CURRENT_HISTORY_SEL = 8;
protected static final int ACTION_PLACE_SHIFTCLICKED_STACK = 9;
protected static final int ACTION_MOVE_ALL_STACKS = 10;
protected static final int ACTION_INCREASE_CRAFTING_STACKS = 11;
protected static final int ACTION_DECREASE_CRAFTING_STACKS = 12;
private final World world;
private final BlockPos pos;
private final EntityPlayer player;
@ -1287,39 +1288,39 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
boolean player_inventory_changed = false;
if(with_assist && nbt.hasKey("action")) {
switch(nbt.getInteger("action")) {
case BGui.BUTTON_NEXT: {
case BContainer.BUTTON_NEXT: {
history.next();
syncHistory(player);
// implicitly clear the grid, so that the player can see the refab, and that no recipe is active.
if(clear_grid_to_player(player)) { te_changed = true; player_inventory_changed = true; }
if(clear_grid_to_storage(player)) te_changed = true;
} break;
case BGui.BUTTON_PREV: {
case BContainer.BUTTON_PREV: {
history.prev();
syncHistory(player);
if(clear_grid_to_player(player)) { te_changed = true; player_inventory_changed = true; }
if(clear_grid_to_storage(player)) te_changed = true;
} break;
case BGui.BUTTON_CLEAR_GRID: {
case BContainer.BUTTON_CLEAR_GRID: {
history.reset_selection();
syncHistory(player);
if(clear_grid_to_player(player)) { te_changed = true; player_inventory_changed = true; }
if(clear_grid_to_storage(player)) te_changed = true;
} break;
case BGui.BUTTON_TO_STORAGE: {
case BContainer.BUTTON_TO_STORAGE: {
if(clear_grid_to_storage(player)) te_changed = true;
} break;
case BGui.BUTTON_TO_PLAYER: {
case BContainer.BUTTON_TO_PLAYER: {
if(clear_grid_to_player(player)) { te_changed = true; player_inventory_changed = true; }
} break;
case BGui.BUTTON_FROM_STORAGE: {
case BContainer.BUTTON_FROM_STORAGE: {
if(place_stacks(new SlotRange[]{
new SlotRange(this, STORAGE_SLOTS_BEGIN, STORAGE_SLOTS_BEGIN+NUM_OF_STORAGE_SLOTS)
}, refab_crafting_stacks(), player) != PlacementResult.UNCHANGED) {
te_changed = true;
}
} break;
case BGui.BUTTON_FROM_PLAYER: {
case BContainer.BUTTON_FROM_PLAYER: {
if(place_stacks(new SlotRange[]{
new SlotRange(player.inventory, 9, 36),
new SlotRange(player.inventory, 0, 9)
@ -1327,7 +1328,7 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
te_changed = true; player_inventory_changed = true;
}
} break;
case BGui.ACTION_PLACE_CURRENT_HISTORY_SEL: {
case BContainer.ACTION_PLACE_CURRENT_HISTORY_SEL: {
if(place_stacks(new SlotRange[]{
new SlotRange(player.inventory, 0, 9),
new SlotRange(player.inventory, 9, 36),
@ -1336,7 +1337,7 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
te_changed = true;
}
} break;
case BGui.ACTION_PLACE_SHIFTCLICKED_STACK: {
case BContainer.ACTION_PLACE_SHIFTCLICKED_STACK: {
final int container_slot_id = nbt.getInteger("containerslot");
if((container_slot_id < 10) || (container_slot_id > 53)) {
break; // out of range
@ -1363,7 +1364,7 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
}
}
} break;
case BGui.ACTION_MOVE_ALL_STACKS: {
case BContainer.ACTION_MOVE_ALL_STACKS: {
final int container_slot_id = nbt.getInteger("containerslot");
if((container_slot_id < 1) || (container_slot_id > 53)) {
break; // out of range
@ -1408,19 +1409,19 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
}
}
} break;
case BGui.BUTTON_NEXT_COLLISION_RECIPE: {
case BContainer.BUTTON_NEXT_COLLISION_RECIPE: {
if(player.openContainer instanceof BContainer) {
((BContainer)player.openContainer).select_next_collision_recipe(this, player);
}
} break;
case BGui.ACTION_DECREASE_CRAFTING_STACKS: {
case BContainer.ACTION_DECREASE_CRAFTING_STACKS: {
te_changed = player_inventory_changed = decrease_grid_stacks(new SlotRange[]{
new SlotRange(player.inventory, 9, 36),
new SlotRange(player.inventory, 0, 9),
new SlotRange(this, STORAGE_SLOTS_BEGIN, STORAGE_SLOTS_BEGIN+NUM_OF_STORAGE_SLOTS)
}, MathHelper.clamp(nbt.getInteger("limit"), 1, 8));
} break;
case BGui.ACTION_INCREASE_CRAFTING_STACKS: {
case BContainer.ACTION_INCREASE_CRAFTING_STACKS: {
te_changed = player_inventory_changed = increase_grid_stacks(new SlotRange[]{
new SlotRange(player.inventory, 9, 36),
new SlotRange(player.inventory, 0, 9),

View file

@ -0,0 +1,188 @@
/*
* @file BlockDecorDoubleGate.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2019 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)
*
* Gate blocks that can be one or two segments high.
*/
package wile.engineersdecor.blocks;
import net.minecraft.entity.Entity;
import wile.engineersdecor.detail.ModAuxiliaries;
import net.minecraft.block.*;
import net.minecraft.block.material.Material;
import net.minecraft.block.properties.PropertyBool;
import net.minecraft.block.properties.PropertyInteger;
import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.Item;
import net.minecraft.util.EnumHand;
import net.minecraft.world.World;
import net.minecraft.world.IBlockAccess;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.pathfinding.PathNodeType;
import net.minecraft.block.BlockFenceGate;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class BlockDecorDoubleGate extends BlockDecorDirectedHorizontal
{
private static final AxisAlignedBB AABB_EMPTY = new AxisAlignedBB(0,0,0, 0,0,0.1);
public static final PropertyInteger SEGMENT = PropertyInteger.create("segment", 0, 1);
public static final PropertyBool OPEN = BlockFenceGate.OPEN;
public static final int SEGMENT_LOWER = 0;
public static final int SEGMENT_UPPER = 1;
private final ArrayList<AxisAlignedBB> collision_shapes_;
private final ArrayList<AxisAlignedBB> shapes_;
public BlockDecorDoubleGate(@Nonnull String registryName, long config, @Nullable Material material, float hardness, float resistance, @Nullable SoundType sound, @Nonnull AxisAlignedBB unrotatedAABB)
{
super(registryName, config, material, hardness, resistance, sound, unrotatedAABB);
AxisAlignedBB caabb = unrotatedAABB.expand(0, 0.5, 0);
collision_shapes_ = new ArrayList<AxisAlignedBB>(Arrays.asList(
NULL_AABB,
NULL_AABB,
ModAuxiliaries.getRotatedAABB(caabb, EnumFacing.NORTH, true),
ModAuxiliaries.getRotatedAABB(caabb, EnumFacing.SOUTH, true),
ModAuxiliaries.getRotatedAABB(caabb, EnumFacing.WEST, true),
ModAuxiliaries.getRotatedAABB(caabb, EnumFacing.EAST, true),
NULL_AABB,
NULL_AABB
));
shapes_ = new ArrayList<AxisAlignedBB>(Arrays.asList(
AABB_EMPTY,
AABB_EMPTY,
ModAuxiliaries.getRotatedAABB(unrotatedAABB, EnumFacing.NORTH, true),
ModAuxiliaries.getRotatedAABB(unrotatedAABB, EnumFacing.SOUTH, true),
ModAuxiliaries.getRotatedAABB(unrotatedAABB, EnumFacing.WEST, true),
ModAuxiliaries.getRotatedAABB(unrotatedAABB, EnumFacing.EAST, true),
AABB_EMPTY,
AABB_EMPTY
));
}
@Override
@SuppressWarnings("deprecation")
public IBlockState getStateFromMeta(int meta)
{ return super.getStateFromMeta(meta).withProperty(OPEN, (meta&0x4)!=0).withProperty(SEGMENT, ((meta&0x8)!=0) ? SEGMENT_UPPER:SEGMENT_LOWER); }
@Override
public int getMetaFromState(IBlockState state)
{ return super.getMetaFromState(state) | (state.getValue(OPEN)?0x4:0x0) | (state.getValue(SEGMENT)==SEGMENT_UPPER ? 0x8:0x0); }
@Override
protected BlockStateContainer createBlockState()
{ return new BlockStateContainer(this, FACING, OPEN, SEGMENT); }
@Override
@SuppressWarnings("deprecation")
public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos)
{ return shapes_.get(state.getValue(FACING).getIndex() & 0x7); }
@Override
public AxisAlignedBB getCollisionBoundingBox(IBlockState state, IBlockAccess world, BlockPos pos)
{ return state.getValue(OPEN) ? NULL_AABB : collision_shapes_.get(state.getValue(FACING).getIndex() & 0x7); }
@Override
@SuppressWarnings("deprecation")
public void addCollisionBoxToList(IBlockState state, World world, BlockPos pos, AxisAlignedBB entityBox, List<AxisAlignedBB> collidingBoxes, @Nullable Entity entityIn, boolean isActualState)
{ if(!state.getValue(OPEN)) addCollisionBoxToList(pos, entityBox, collidingBoxes, collision_shapes_.get(state.getValue(FACING).getIndex() & 0x7)); }
@Override
public IBlockState getStateForPlacement(World world, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer, EnumHand hand)
{ return getInitialState(super.getStateForPlacement(world, pos, facing, hitX, hitY, hitZ, meta, placer, hand), world, pos); }
@Override
public boolean isPassable(IBlockAccess world, BlockPos pos)
{ return world.getBlockState(pos).getValue(OPEN); }
@Override
public net.minecraft.pathfinding.PathNodeType getAiPathNodeType(IBlockState state, IBlockAccess world, BlockPos pos)
{ return state.getValue(OPEN) ? PathNodeType.OPEN : PathNodeType.FENCE; }
@Override
@SuppressWarnings("deprecation")
public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, EnumFacing face, float hitX, float hitY, float hitZ)
{
if((face==EnumFacing.UP) || (face==EnumFacing.DOWN) && (player.getHeldItem(hand).getItem()==Item.getItemFromBlock(this))) return false;
if(world.isRemote) return true;
final boolean open = !state.getValue(OPEN);
world.setBlockState(pos, state.withProperty(OPEN, open),2|8|16);
if(state.getValue(SEGMENT) == SEGMENT_UPPER) {
final IBlockState adjacent = world.getBlockState(pos.down());
if(adjacent.getBlock()==this) world.setBlockState(pos.down(), adjacent.withProperty(OPEN, open), 2|8|16);
} else {
final IBlockState adjacent = world.getBlockState(pos.up());
if(adjacent.getBlock()==this) world.setBlockState(pos.up(), adjacent.withProperty(OPEN, open), 2|8|16);
}
world.playSound(null, pos, open ? SoundEvents.BLOCK_IRON_DOOR_OPEN:SoundEvents.BLOCK_IRON_DOOR_CLOSE, SoundCategory.BLOCKS, 0.7f, 1.4f);
return true;
}
@Override
@SuppressWarnings("deprecation")
public void neighborChanged(IBlockState state, World world, BlockPos pos, Block block, BlockPos fromPos)
{
if(world.isRemote) return;
boolean powered = false;
IBlockState adjacent;
BlockPos adjacent_pos;
if(state.getValue(SEGMENT) == SEGMENT_UPPER) {
adjacent_pos = pos.down();
adjacent = world.getBlockState(adjacent_pos);
if(adjacent.getBlock()!=this) adjacent = null;
if(world.getRedstonePower(pos.up(), EnumFacing.UP) > 0) {
powered = true;
} else if((adjacent!=null) && (world.isBlockPowered(pos.down(2)))) {
powered = true;
}
} else {
adjacent_pos = pos.up();
adjacent = world.getBlockState(adjacent_pos);
if(adjacent.getBlock()!=this) adjacent = null;
if(world.isBlockPowered(pos)) {
powered = true;
} else if((adjacent!=null) && (world.getRedstonePower(pos.up(2), EnumFacing.UP) > 0)) {
powered = true;
}
}
boolean sound = false;
if(powered != state.getValue(OPEN)) {
world.setBlockState(pos, state.withProperty(OPEN, powered), 2|8|16);
sound = true;
}
if((adjacent != null) && (powered != adjacent.getValue(OPEN))) {
world.setBlockState(adjacent_pos, adjacent.withProperty(OPEN, powered), 2|8|16);
sound = true;
}
if(sound) {
world.playSound(null, pos, powered?SoundEvents.BLOCK_IRON_DOOR_OPEN:SoundEvents.BLOCK_IRON_DOOR_CLOSE, SoundCategory.BLOCKS, 0.7f, 1.4f);
}
}
// -------------------------------------------------------------------------------------------------------------------
private IBlockState getInitialState(IBlockState state, IBlockAccess world, BlockPos pos)
{
final IBlockState down = world.getBlockState(pos.down());
if(down.getBlock() == this) return state.withProperty(SEGMENT, SEGMENT_UPPER).withProperty(OPEN, down.getValue(OPEN)).withProperty(FACING, down.getValue(FACING));
final IBlockState up = world.getBlockState(pos.up());
if(up.getBlock() == this) return state.withProperty(SEGMENT, SEGMENT_LOWER).withProperty(OPEN, up.getValue(OPEN)).withProperty(FACING, up.getValue(FACING));
return state.withProperty(SEGMENT, SEGMENT_LOWER).withProperty(OPEN, false);
}
}

View file

@ -17,12 +17,12 @@ import net.minecraft.entity.item.EntityItem;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.List;
public class BlockDecorFloorGrating extends BlockDecor
{
@ -45,45 +45,27 @@ public class BlockDecorFloorGrating extends BlockDecor
public BlockFaceShape getBlockFaceShape(IBlockAccess world, IBlockState state, BlockPos pos, EnumFacing face)
{ return BlockFaceShape.UNDEFINED; }
@Override
public void addCollisionBoxToList(IBlockState state, World world, BlockPos pos, AxisAlignedBB entityBox, List<AxisAlignedBB> collidingBoxes, @Nullable Entity entity, boolean isActualState)
{ if(!(entity instanceof EntityItem)) super.addCollisionBoxToList(state, world, pos, entityBox, collidingBoxes, entity, isActualState); }
@Override
public void onFallenUpon(World world, BlockPos pos, Entity entity, float fallDistance)
{
if(!(entity instanceof EntityItem)) {
entity.fall(fallDistance, 1.0F);
} else {
entity.motionX = 0;
entity.motionY = -0.1;
entity.motionZ = 0;
entity.setPositionAndUpdate(pos.getX()+0.5, entity.posY-0.3, pos.getZ()+0.5);
}
}
@Override
public void onLanded(World world, Entity entity)
{
if(!(entity instanceof EntityItem)) {
super.onLanded(world, entity);
} else {
entity.motionX = 0;
entity.motionY = -0.1;
entity.motionZ = 0;
entity.setPositionAndUpdate(entity.posX, entity.posY-0.3, entity.posZ);
}
}
@Override
public void onEntityCollision(World world, BlockPos pos, IBlockState state, Entity entity)
{
if(!(entity instanceof EntityItem)) return;
entity.motionX = 0;
entity.motionZ = 0;
if((entity.posY-pos.getY()) > 0.7) {
if(entity.motionY > -0.2) entity.motionY = -0.2;
entity.setPositionAndUpdate(pos.getX()+0.5, entity.posY-0.3, pos.getZ()+0.5);
final boolean colliding = ((entity.posY-pos.getY()) > 0.7);
if(colliding || (entity.motionY > 0)) {
double x = pos.getX() + 0.5;
double y = MathHelper.clamp(entity.posY-0.3, pos.getY(), pos.getY()+0.6);
double z = pos.getZ() + 0.5;
if(colliding) {
entity.motionX = 0;
entity.motionZ = 0;
entity.motionY = -0.3;
if((entity.posY-pos.getY()) > 0.8) y = pos.getY() + 0.6;
entity.prevPosX = x+0.1;
entity.prevPosY = y+0.1;
entity.prevPosZ = z+0.1;
}
entity.motionY = MathHelper.clamp(entity.motionY, -0.3, 0);
entity.fallDistance = 0;
entity.setPositionAndUpdate(x,y,z);
}
}
}

View file

@ -344,7 +344,6 @@ public class BlockDecorFluidFunnel extends BlockDecor
if(trail.isEmpty()) break; // reset search
if(num_adjacent==0) pos = trail.pop();
}
//println("FAIL=" + steps + " - " + (pos.subtract(collection_pos))); String s = new String(); for(BlockPos p:checked) s += "\n" + p; System.out.println(s);
if(intensive_search_counter_ > 2) world.setBlockToAir(pos);
last_pick_pos_ = collection_pos;
search_offsets_ = null; // try other search order

View file

@ -9,6 +9,8 @@
package wile.engineersdecor.blocks;
import net.minecraft.init.Blocks;
import wile.engineersdecor.ModContent;
import wile.engineersdecor.ModEngineersDecor;
import net.minecraft.block.SoundType;
@ -38,9 +40,11 @@ import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemHandlerHelper;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import wile.engineersdecor.detail.Networking;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.IOException;
import java.util.Random;
public class BlockDecorFurnaceElectrical extends BlockDecorFurnace
@ -134,6 +138,13 @@ public class BlockDecorFurnaceElectrical extends BlockDecorFurnace
drawTexturedModalRect(x0+79, y0+30, 176, 15, 1+progress_px(17), 15);
int we = energy_px(32, 8);
if(we>0) drawTexturedModalRect(x0+88, y0+53, 185, 30, we, 13);
switch(te.getField(4)) {
case 0: drawTexturedModalRect(x0+144, y0+57, 180, 57, 6, 9); break;
case 1: drawTexturedModalRect(x0+142, y0+58, 190, 58, 9, 6); break;
case 2: drawTexturedModalRect(x0+144, y0+56, 200, 57, 6, 9); break;
case 3: drawTexturedModalRect(x0+143, y0+58, 210, 58, 9, 6); break;
default: break;
}
}
private int progress_px(int pixels)
@ -153,10 +164,33 @@ public class BlockDecorFurnaceElectrical extends BlockDecorFurnace
return k;
}
@Override
protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException
{
BContainer container = (BContainer)inventorySlots;
int mx = (int)(mouseX - getGuiLeft() + .5), my = (int)(mouseY - getGuiTop() + .5);
int speed = -1;
if((!isPointInRegion(136, 48, 28, 28, mouseX, mouseY))) {
super.mouseClicked(mouseX, mouseY, mouseButton);
} else if(isPointInRegion(144, 64, 6, 10, mouseX, mouseY)) {
speed = 0;
} else if(isPointInRegion(134, 58, 10, 6, mouseX, mouseY)) {
speed = 1;
} else if(isPointInRegion(144, 48, 6, 10, mouseX, mouseY)) {
speed = 2;
} else if(isPointInRegion(150, 58, 10, 6, mouseX, mouseY)) {
speed = 3;
}
if(speed >= 0) {
NBTTagCompound nbt = new NBTTagCompound();
nbt.setInteger("speed", speed);
Networking.PacketTileNotify.sendToServer(te, nbt);
}
}
}
//--------------------------------------------------------------------------------------------------------------------
// container
// Container
//--------------------------------------------------------------------------------------------------------------------
public static class BContainer extends Container
@ -274,7 +308,7 @@ public class BlockDecorFurnaceElectrical extends BlockDecorFurnace
// Tile entity
//--------------------------------------------------------------------------------------------------------------------
public static class BTileEntity extends BlockDecorFurnace.BTileEntity implements ITickable, ISidedInventory, IEnergyStorage
public static class BTileEntity extends BlockDecorFurnace.BTileEntity implements ITickable, ISidedInventory, IEnergyStorage, Networking.IPacketReceiver
{
public static final int TICK_INTERVAL = 4;
public static final int FIFO_INTERVAL = 20;
@ -295,9 +329,25 @@ public class BlockDecorFurnaceElectrical extends BlockDecorFurnace
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 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;
private static double speed_setting_factor_[] = {0.0, 1.0, 1.5, 2.0};
private static boolean with_automatic_inventory_pulling_ = false;
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_;
@ -305,14 +355,7 @@ public class BlockDecorFurnaceElectrical extends BlockDecorFurnace
private int speed_;
private int tick_timer_;
private int fifo_timer_;
public static void on_config(int speed_percent, int standard_energy_per_tick)
{
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);
ModEngineersDecor.logger.info("Config electrical furnace speed:" + proc_speed_percent_ + ", power consumption:" + energy_consumption_);
}
private boolean enabled_ = false;
public BTileEntity()
{ super(); reset(); }
@ -326,7 +369,7 @@ public class BlockDecorFurnaceElectrical extends BlockDecorFurnace
fifo_timer_ = 0;
tick_timer_ = 0;
energy_stored_= 0;
speed_ = 0;
speed_ = 1;
}
public void readnbt(NBTTagCompound compound)
@ -339,6 +382,7 @@ public class BlockDecorFurnaceElectrical extends BlockDecorFurnace
proc_time_needed_ = compound.getInteger("CookTimeTotal");
energy_stored_ = compound.getInteger("Energy");
speed_ = compound.getInteger("SpeedSetting");
speed_ = (speed_ < 0) ? (1) : ((speed_>3) ? 3 : speed_);
}
protected void writenbt(NBTTagCompound compound)
@ -602,8 +646,24 @@ public class BlockDecorFurnaceElectrical extends BlockDecorFurnace
return super.getCapability(capability, facing);
}
// IPacketReceiver -------------------------------------------------------------------------------
@Override
public void onServerPacketReceived(NBTTagCompound nbt)
{}
@Override
public void onClientPacketReceived(EntityPlayer player, NBTTagCompound nbt)
{
if(nbt.hasKey("speed")) speed_ = MathHelper.clamp(nbt.getInteger("speed"), 0, 3);
markDirty();
}
// ITickable ------------------------------------------------------------------------------------
private boolean is_accepted_hopper(final ItemStack stack)
{ return (stack.getItem() == Item.getItemFromBlock(Blocks.HOPPER)) || (stack.getItem() == Item.getItemFromBlock(ModContent.FACTORY_HOPPER)); }
private boolean adjacent_inventory_shift(boolean inp, boolean out)
{
boolean dirty = false;
@ -622,20 +682,22 @@ public class BlockDecorFurnaceElectrical extends BlockDecorFurnace
dirty = true;
}
}
if(inp && (stacks_.get(FIFO_INPUT_1_SLOT_NO).isEmpty())) {
TileEntity te = world.getTileEntity(pos.offset(inp_facing));
if((te!=null) && (te.hasCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, out_facing))) {
IItemHandler hnd = te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, out_facing);
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;
if(with_automatic_inventory_pulling_ || is_accepted_hopper(stacks_.get(SMELTING_AUX_SLOT_NO))) {
if(inp && (stacks_.get(FIFO_INPUT_1_SLOT_NO).isEmpty())) {
TileEntity te = world.getTileEntity(pos.offset(inp_facing));
if((te!=null) && (te.hasCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, out_facing))) {
IItemHandler hnd = te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, out_facing);
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;
}
}
}
}
@ -646,14 +708,24 @@ public class BlockDecorFurnaceElectrical extends BlockDecorFurnace
// returns TE dirty
private boolean heat_up()
{
if(energy_stored_ < (energy_consumption_)) return false;
if(energy_stored_ < (energy_consumption())) return false;
if(burntime_left_ >= (HEAT_CAPACITY-HEAT_INCREMENT)) return false;
energy_stored_ -= energy_consumption_;
energy_stored_ -= energy_consumption();
burntime_left_ += HEAT_INCREMENT;
this.markDirty();
return true;
}
int energy_consumption()
{
switch(speed_) {
case 1: return energy_consumption_;
case 2: return energy_consumption_ * 2;
case 3: return energy_consumption_ * 4;
default: return 0;
}
}
private void sync_blockstate()
{
final IBlockState state = world.getBlockState(pos);
@ -682,9 +754,14 @@ public class BlockDecorFurnaceElectrical extends BlockDecorFurnace
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(energy_stored_ < energy_consumption()) {
enabled_ = false;
} else if(energy_stored_ >= (MAX_ENERGY_BUFFER/2)) {
enabled_ = true;
}
final ItemStack last_inp_stack = current_smelting_input_stack_;
current_smelting_input_stack_ = stacks_.get(SMELTING_INPUT_SLOT_NO);
if((!current_smelting_input_stack_.isEmpty()) && (energy_stored_ >= energy_consumption_)) {
if((!current_smelting_input_stack_.isEmpty()) && (enabled_) && (speed_>0) && (speed_<4)) {
if(!current_smelting_input_stack_.isItemEqual(current_smelting_input_stack_)) {
proc_time_elapsed_ = 0;
proc_time_needed_ = getCookTime(current_smelting_input_stack_);
@ -700,7 +777,7 @@ public class BlockDecorFurnaceElectrical extends BlockDecorFurnace
}
if(isBurning() && can_smelt) {
if(heat_up()) dirty = true;
proc_time_elapsed_ += (TICK_INTERVAL * proc_speed_percent_/100);
proc_time_elapsed_ += (TICK_INTERVAL * proc_speed_percent_ * speed_setting_factor_[speed_] / 100);
if(proc_time_elapsed_ >= proc_time_needed_) {
proc_time_elapsed_ = 0;
proc_time_needed_ = getCookTime(current_smelting_input_stack_);

View file

@ -612,6 +612,7 @@ public class BlockDecorHopper extends BlockDecorDirected
// ISidedInventory ----------------------------------------------------------------------------
private final IItemHandler item_handler_ = new SidedInvWrapper(this, EnumFacing.UP);
private final IItemHandler down_item_handler_ = new SidedInvWrapper(this, EnumFacing.DOWN);
private static final int[] SIDED_INV_SLOTS;
static {
SIDED_INV_SLOTS = new int[NUM_OF_SLOTS];
@ -628,7 +629,7 @@ public class BlockDecorHopper extends BlockDecorDirected
@Override
public boolean canExtractItem(int index, ItemStack stack, EnumFacing direction)
{ return false; }
{ return direction==EnumFacing.DOWN; }
// Capability export ----------------------------------------------------------------------------
@ -641,7 +642,9 @@ public class BlockDecorHopper extends BlockDecorDirected
@Nullable
public <T> T getCapability(Capability<T> capability, @Nullable EnumFacing facing)
{
if(capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return (T)item_handler_;
if(capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
return (facing == EnumFacing.DOWN) ? ((T)down_item_handler_) : ((T)item_handler_);
}
return super.getCapability(capability, facing);
}

View file

@ -0,0 +1,593 @@
/*
* @file BlockDecorLabeledCrate.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2019 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)
*
* Storage crate with a content hint.
*/
package wile.engineersdecor.blocks;
import net.minecraft.block.Block;
import net.minecraft.block.SoundType;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.*;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.play.server.SPacketUpdateTileEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.NonNullList;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextComponentTranslation;
import net.minecraft.world.Explosion;
import net.minecraft.world.World;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemHandlerHelper;
import wile.engineersdecor.ModEngineersDecor;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class BlockDecorLabeledCrate
{
public static void on_config(int stack_limit)
{
}
//--------------------------------------------------------------------------------------------------------------------
// Block
//--------------------------------------------------------------------------------------------------------------------
public static class DecorLabeledCrateBlock extends BlockDecorDirectedHorizontal
{
public DecorLabeledCrateBlock(@Nonnull String registryName, long config, @Nullable Material material, float hardness, float resistance, @Nullable SoundType sound, @Nonnull AxisAlignedBB unrotatedAABB)
{ super(registryName, config, material, hardness, resistance, sound, unrotatedAABB); }
@Override
public boolean hasTileEntity(IBlockState state)
{ return true; }
@Override
@Nullable
public TileEntity createTileEntity(World world, IBlockState state)
{ return new LabeledCrateTileEntity(); }
@Override
public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ)
{
if(world.isRemote) return true;
player.openGui(ModEngineersDecor.instance, ModEngineersDecor.GuiHandler.GUIID_LABELED_CRATE, world, pos.getX(), pos.getY(), pos.getZ());
return true;
}
@Override
public void onBlockPlacedBy(World world, BlockPos pos, IBlockState state, EntityLivingBase placer, ItemStack stack)
{
if(world.isRemote) return;
if((!stack.hasTagCompound()) || (!stack.getTagCompound().hasKey("inventory"))) return;
NBTTagCompound inventory_nbt = stack.getTagCompound().getCompoundTag("inventory");
if(inventory_nbt.isEmpty()) return;
final TileEntity te = world.getTileEntity(pos);
if(!(te instanceof LabeledCrateTileEntity)) return;
((LabeledCrateTileEntity)te).readnbt(inventory_nbt);
((LabeledCrateTileEntity)te).markDirty();
}
private ItemStack itemize_with_inventory(World world, BlockPos pos)
{
TileEntity te = world.getTileEntity(pos);
if(!(te instanceof LabeledCrateTileEntity)) return ItemStack.EMPTY;
ItemStack stack = new ItemStack(this, 1);
NBTTagCompound inventory_nbt = new NBTTagCompound();
ItemStackHelper.saveAllItems(inventory_nbt, ((LabeledCrateTileEntity)te).stacks_, false);
if(!inventory_nbt.isEmpty()) {
NBTTagCompound nbt = new NBTTagCompound();
nbt.setTag("inventory", inventory_nbt);
stack.setTagCompound(nbt);
}
return stack;
}
@Override
public boolean removedByPlayer(IBlockState state, World world, BlockPos pos, EntityPlayer player, boolean willHarvest)
{
if(world.isRemote) return true;
final ItemStack stack = itemize_with_inventory(world, pos);
if(stack != ItemStack.EMPTY) {
world.spawnEntity(new EntityItem(world, pos.getX()+0.5, pos.getY()+0.5, pos.getZ()+0.5, stack));
world.setBlockToAir(pos);
world.removeTileEntity(pos);
return false;
} else {
return super.removedByPlayer(state, world, pos, player, willHarvest);
}
}
@Override
public void onBlockExploded(World world, BlockPos pos, Explosion explosion)
{
if(world.isRemote) return;
TileEntity te = world.getTileEntity(pos);
if(!(te instanceof LabeledCrateTileEntity)) return;
for(ItemStack stack: ((LabeledCrateTileEntity)te).stacks_) {
if(!stack.isEmpty()) world.spawnEntity(new EntityItem(world, pos.getX(), pos.getY(), pos.getZ(), stack));
}
((LabeledCrateTileEntity)te).reset();
super.onBlockExploded(world, pos, explosion);
}
@Override
@SuppressWarnings("deprecation")
public boolean hasComparatorInputOverride(IBlockState state)
{ return true; }
@Override
@SuppressWarnings("deprecation")
public int getComparatorInputOverride(IBlockState blockState, World world, BlockPos pos)
{ return Container.calcRedstone(world.getTileEntity(pos)); }
}
//--------------------------------------------------------------------------------------------------------------------
// Tile entity
//--------------------------------------------------------------------------------------------------------------------
public static class LabeledCrateTileEntity extends TileEntity implements ISidedInventory
{
public static final int NUM_OF_FIELDS = 1;
public static final int NUM_OF_SLOTS = 55;
public static final int ITEMFRAME_SLOTNO = 54;
// LabeledCrateTileEntity --------------------------------------------------------------------------
protected NonNullList<ItemStack> stacks_ = NonNullList.<ItemStack>withSize(NUM_OF_SLOTS, ItemStack.EMPTY);
public LabeledCrateTileEntity()
{ reset(); }
protected void reset()
{ stacks_ = NonNullList.<ItemStack>withSize(NUM_OF_SLOTS, ItemStack.EMPTY); }
public void readnbt(NBTTagCompound 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;
}
protected void writenbt(NBTTagCompound compound)
{ ItemStackHelper.saveAllItems(compound, stacks_); }
public ItemStack getItemFrameStack()
{ return (stacks_.size() > ITEMFRAME_SLOTNO)?(stacks_.get(ITEMFRAME_SLOTNO)):(ItemStack.EMPTY); }
// TileEntity ------------------------------------------------------------------------------
@Override
public boolean shouldRefresh(World world, BlockPos pos, IBlockState os, IBlockState ns)
{ return (os.getBlock()!=ns.getBlock())||(!(ns.getBlock() instanceof DecorLabeledCrateBlock));}
@Override
public void readFromNBT(NBTTagCompound compound)
{ super.readFromNBT(compound); readnbt(compound); }
@Override
public NBTTagCompound writeToNBT(NBTTagCompound compound)
{ super.writeToNBT(compound); writenbt(compound); return compound; }
@Override
public NBTTagCompound getUpdateTag()
{ NBTTagCompound nbt = super.getUpdateTag(); writenbt(nbt); return nbt; }
@Override
@Nullable
public SPacketUpdateTileEntity getUpdatePacket()
{ return new SPacketUpdateTileEntity(pos, 1, getUpdateTag()); }
@Override
public void onDataPacket(NetworkManager net, SPacketUpdateTileEntity pkt) // on client
{ super.readFromNBT(pkt.getNbtCompound()); readnbt(pkt.getNbtCompound()); super.onDataPacket(net, pkt); }
@Override
public void handleUpdateTag(NBTTagCompound tag) // on client
{ readFromNBT(tag); }
// INameable ---------------------------------------------------------------------------
@Override
public String getName()
{ final Block block = getBlockType(); return (block!=null)?(block.getTranslationKey()+".name"):(""); }
@Override
public boolean hasCustomName()
{ return false; }
@Override
public ITextComponent getDisplayName()
{ return new TextComponentTranslation(getName(), new Object[0]); }
// 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();
if(!getWorld().isRemote) {
// This should result in sending TE data (getUpdateTag etc) to the client for the TER.
IBlockState state = world.getBlockState(getPos());
getWorld().notifyBlockUpdate(getPos(), state, state, 2|16|32);
}
}
@Override
public int getInventoryStackLimit()
{ return 64; }
@Override
public void markDirty()
{ super.markDirty(); }
@Override
public boolean isUsableByPlayer(EntityPlayer player)
{ return getPos().distanceSq(player.getPosition()) < 36; }
@Override
public void openInventory(EntityPlayer player)
{}
@Override
public void closeInventory(EntityPlayer player)
{ markDirty(); }
@Override
public boolean isItemValidForSlot(int index, ItemStack stack)
{ return (index!=ITEMFRAME_SLOTNO); }
@Override
public void clear()
{ stacks_.clear(); }
// Fields -----------------------------------------------------------------------------------------------
@Override
public int getField(int id)
{ return 0; }
@Override
public void setField(int id, int value)
{}
@Override
public int getFieldCount()
{ return 0; }
// ISidedInventory ----------------------------------------------------------------------------
private static final int[] SIDED_INV_SLOTS;
static {
SIDED_INV_SLOTS = new int[LabeledCrateTileEntity.NUM_OF_SLOTS-1];
for(int i = 0; i < SIDED_INV_SLOTS.length; ++i) SIDED_INV_SLOTS[i] = i;
}
@Override
public int[] getSlotsForFace(EnumFacing side)
{ return SIDED_INV_SLOTS; }
@Override
public boolean canInsertItem(int index, ItemStack stack, EnumFacing direction)
{ return true; }
@Override
public boolean canExtractItem(int index, ItemStack stack, EnumFacing direction)
{ return true; }
// IItemHandler --------------------------------------------------------------------------------
protected static class BItemHandler implements IItemHandler
{
private LabeledCrateTileEntity te;
BItemHandler(LabeledCrateTileEntity te)
{
this.te = te;
}
@Override
public int getSlots()
{
return ITEMFRAME_SLOTNO;
} // iframe slot is the last
@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 slotno, @Nonnull ItemStack stack, boolean simulate)
{
if(stack.isEmpty()) return ItemStack.EMPTY;
if((slotno < 0)||((slotno >= NUM_OF_SLOTS))||((slotno==ITEMFRAME_SLOTNO))) return ItemStack.EMPTY;
ItemStack slotstack = getStackInSlot(slotno);
if(!slotstack.isEmpty()) {
if(slotstack.getCount() >= Math.min(slotstack.getMaxStackSize(), getSlotLimit(slotno))) return stack;
if(!ItemHandlerHelper.canItemStacksStack(stack, slotstack)) return stack;
if(!te.canInsertItem(slotno, stack, EnumFacing.UP)||(!te.isItemValidForSlot(slotno, stack))) return stack;
int n = Math.min(stack.getMaxStackSize(), getSlotLimit(slotno))-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.splitStack(n);
copy.grow(slotstack.getCount());
te.setInventorySlotContents(slotno, copy);
return stack;
}
else {
stack.shrink(n);
return stack;
}
}
}
else {
if(!te.canInsertItem(slotno, stack, EnumFacing.UP)||(!te.isItemValidForSlot(slotno, stack))) return stack;
int n = Math.min(stack.getMaxStackSize(), getSlotLimit(slotno));
if(n < stack.getCount()) {
stack = stack.copy();
if(!simulate) {
te.setInventorySlotContents(slotno, stack.splitStack(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((index < 0)||((index >= NUM_OF_SLOTS))||((index==ITEMFRAME_SLOTNO))) return ItemStack.EMPTY;
if(!simulate) return ItemStackHelper.getAndSplit(te.stacks_, index, amount);
ItemStack stack = te.stacks_.get(index).copy();
if(stack.getCount() > amount) stack.setCount(amount);
return stack;
}
@Override
@Nonnull
public ItemStack getStackInSlot(int index)
{
return te.getStackInSlot(index);
}
}
// Capability export ----------------------------------------------------------------------------
private final IItemHandler item_handler_ = new BItemHandler(this);
@Override
public boolean hasCapability(Capability<?> cap, EnumFacing facing)
{
return (cap==CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)||super.hasCapability(cap, facing);
}
@Override
@SuppressWarnings("unchecked")
@Nullable
public <T> T getCapability(Capability<T> capability, @Nullable EnumFacing facing)
{
if(capability==CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return (T)item_handler_;
return super.getCapability(capability, facing);
}
}
//--------------------------------------------------------------------------------------------------------------------
// GUI
//--------------------------------------------------------------------------------------------------------------------
@SideOnly(Side.CLIENT)
private static class BGui extends GuiContainer
{
private final LabeledCrateTileEntity te;
public BGui(InventoryPlayer playerInventory, World world, BlockPos pos, LabeledCrateTileEntity te)
{
super(new BContainer(playerInventory, world, pos, te));
this.te = te;
xSize = 213;
ySize = 206;
}
@Override
public void initGui()
{ super.initGui(); }
@Override
public void drawScreen(int mouseX, int mouseY, float partialTicks)
{
drawDefaultBackground();
super.drawScreen(mouseX, mouseY, partialTicks);
renderHoveredToolTip(mouseX, mouseY);
}
@Override
protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY)
{
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
mc.getTextureManager().bindTexture(new ResourceLocation(ModEngineersDecor.MODID, "textures/gui/labeled_crate_gui.png"));
final int x0=guiLeft, y0=guiTop, w=xSize, h=ySize;
drawTexturedModalRect(x0, y0, 0, 0, w, h);
}
}
//--------------------------------------------------------------------------------------------------------------------
// Container
//--------------------------------------------------------------------------------------------------------------------
public static class BContainer extends Container
{
//------------------------------------------------------------------------------------------------------------------
private static final int PLAYER_INV_START_SLOTNO = LabeledCrateTileEntity.NUM_OF_SLOTS;
private final World world;
private final BlockPos pos;
private final EntityPlayer player;
private final LabeledCrateTileEntity te;
//------------------------------------------------------------------------------------------------------------------
public BContainer(InventoryPlayer playerInventory, World world, BlockPos pos, LabeledCrateTileEntity te)
{
this.player = playerInventory.player;
this.world = world;
this.pos = pos;
this.te = te;
int i=-1;
// storage slots (stacks 0 to 53)
for(int y=0; y<6; ++y) {
for(int x=0; x<9; ++x) {
int xpos = 28+x*18, ypos = 10+y*18;
addSlotToContainer(new Slot(te, ++i, xpos, ypos));
}
}
// picture frame slot (54)
addSlotToContainer(new Slot(te, ++i, 191, 100) {
@Override public int getSlotStackLimit(){return 1;}
});
// player slots
for(int x=0; x<9; ++x) {
addSlotToContainer(new Slot(playerInventory, x, 28+x*18, 183)); // player slots: 0..8
}
for(int y=0; y<3; ++y) {
for(int x=0; x<9; ++x) {
addSlotToContainer(new Slot(playerInventory, x+y*9+9, 28+x*18, 125+y*18)); // player slots: 9..35
}
}
}
@Override
public void addListener(IContainerListener listener)
{ super.addListener(listener); listener.sendAllWindowProperties(this, te); }
@Override
public void detectAndSendChanges()
{ super.detectAndSendChanges(); }
@Override
@SideOnly(Side.CLIENT)
public void updateProgressBar(int id, int data)
{ te.setField(id, data); }
@Override
public boolean canInteractWith(EntityPlayer player)
{ return (world.getBlockState(pos).getBlock() instanceof DecorLabeledCrateBlock) && (player.getDistanceSq(pos) <= 64); }
@Override
public boolean canMergeSlot(ItemStack stack, Slot slot)
{ return (slot.getSlotStackLimit() > 1); }
@Override
public void onContainerClosed(EntityPlayer player)
{ super.onContainerClosed(player); }
@Override
public ItemStack transferStackInSlot(EntityPlayer 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)) {
// Crate 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, PLAYER_INV_START_SLOTNO-1, 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;
}
}
//--------------------------------------------------------------------------------------------------------------------
// ModEngineersDecor.GuiHandler connectors
//--------------------------------------------------------------------------------------------------------------------
public static Object getServerGuiElement(final EntityPlayer player, final World world, final BlockPos pos, final TileEntity te)
{ return (te instanceof LabeledCrateTileEntity) ? (new BContainer(player.inventory, world, pos, (LabeledCrateTileEntity)te)) : null; }
public static Object getClientGuiElement(final EntityPlayer player, final World world, final BlockPos pos, final TileEntity te)
{ return (te instanceof LabeledCrateTileEntity) ? (new BGui(player.inventory, world, pos, (LabeledCrateTileEntity)te)) : null; }
}

View file

@ -8,10 +8,8 @@
*/
package wile.engineersdecor.blocks;
import net.minecraft.util.math.MathHelper;
import net.minecraftforge.energy.CapabilityEnergy;
import net.minecraftforge.energy.IEnergyStorage;
import wile.engineersdecor.ModEngineersDecor;
import wile.engineersdecor.detail.ModAuxiliaries;
import net.minecraft.block.properties.PropertyInteger;
import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.block.material.Material;
@ -19,6 +17,7 @@ import net.minecraft.block.state.BlockFaceShape;
import net.minecraft.block.state.IBlockState;
import net.minecraft.block.SoundType;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ITickable;
@ -28,6 +27,10 @@ import net.minecraft.util.EnumHand;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraftforge.energy.CapabilityEnergy;
import net.minecraftforge.energy.IEnergyStorage;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@ -93,6 +96,16 @@ public class BlockDecorSolarPanel extends BlockDecor
public TileEntity createTileEntity(World world, IBlockState state)
{ return new BlockDecorSolarPanel.BTileEntity(); }
@Override
public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ)
{
if(world.isRemote) return true;
TileEntity te = world.getTileEntity(pos);
if(!(te instanceof BTileEntity)) return true;
((BTileEntity)te).state_message(player);
return true;
}
//--------------------------------------------------------------------------------------------------------------------
// Tile entity
//--------------------------------------------------------------------------------------------------------------------
@ -105,9 +118,12 @@ public class BlockDecorSolarPanel extends BlockDecor
private static final EnumFacing transfer_directions_[] = {EnumFacing.DOWN, EnumFacing.EAST, EnumFacing.SOUTH, EnumFacing.WEST, EnumFacing.NORTH };
private static int peak_power_per_tick_ = DEFAULT_PEAK_POWER;
private static int max_power_storage_ = 10000;
private static int max_feed_power = 128;
private int current_production_ = 0;
private int tick_timer_ = 0;
private int recalc_timer_ = 0;
private int accumulated_power_ = 0;
private int current_feedin_ = 0;
public static void on_config(int peak_power_per_tick)
{
@ -126,6 +142,12 @@ public class BlockDecorSolarPanel extends BlockDecor
protected void writenbt(NBTTagCompound nbt, boolean update_packet)
{ nbt.setInteger("energy", accumulated_power_); }
public void state_message(EntityPlayer player)
{
String soc = Integer.toString(MathHelper.clamp((accumulated_power_*100/max_power_storage_),0,100));
ModAuxiliaries.playerChatMessage(player, soc + "%%/" + max_power_storage_ + "RF | +" + + current_production_ + "RF/t | -" + current_feedin_ + "RF/t");
}
// TileEntity ------------------------------------------------------------------------------
@Override
@ -145,7 +167,7 @@ public class BlockDecorSolarPanel extends BlockDecor
{
if((world.isRemote) || (--tick_timer_ > 0)) return;
tick_timer_ = TICK_INTERVAL;
if(!world.canSeeSky(pos)) { tick_timer_ = TICK_INTERVAL * 5; return; }
current_feedin_ = 0;
if(accumulated_power_ > 0) {
for(int i=0; (i<transfer_directions_.length) && (accumulated_power_>0); ++i) {
final EnumFacing f = transfer_directions_[i];
@ -153,9 +175,19 @@ public class BlockDecorSolarPanel extends BlockDecor
if((te==null) || (!(te.hasCapability(CapabilityEnergy.ENERGY, f.getOpposite())))) continue;
IEnergyStorage es = te.getCapability(CapabilityEnergy.ENERGY, f.getOpposite());
if(!es.canReceive()) continue;
accumulated_power_ = MathHelper.clamp(accumulated_power_-es.receiveEnergy(accumulated_power_, false),0, accumulated_power_);
int fed = es.receiveEnergy(max_feed_power * TICK_INTERVAL, false);
accumulated_power_ = MathHelper.clamp(accumulated_power_-fed,0, accumulated_power_);
current_feedin_ += fed;
}
}
current_feedin_ /= TICK_INTERVAL;
if(!world.canSeeSky(pos)) {
tick_timer_ = TICK_INTERVAL * 5;
current_production_ = 0;
IBlockState state = world.getBlockState(pos);
if(state.getValue((EXPOSITION))!=2) world.setBlockState(pos, state.withProperty(EXPOSITION, 2));
return;
}
if(--recalc_timer_ > 0) return;
recalc_timer_ = ACCUMULATION_INTERVAL + ((int)(Math.random()+.5));
IBlockState state = world.getBlockState(pos);
@ -169,9 +201,10 @@ public class BlockDecorSolarPanel extends BlockDecor
else if(theta < 190) e = 4;
IBlockState nstate = state.withProperty(EXPOSITION, e);
if(nstate != state) world.setBlockState(pos, nstate, 1|2);
double rf = Math.abs(1.0-(((double)Math.abs(MathHelper.clamp(theta, 0, 180)-90))/90));
rf = Math.sqrt(rf) * world.getSunBrightnessFactor(1f) * ((TICK_INTERVAL*ACCUMULATION_INTERVAL)+2) * peak_power_per_tick_;
accumulated_power_ = Math.min(accumulated_power_+(int)rf, max_power_storage_);
final double eff = (1.0-((world.getRainStrength(1f)*0.6)+(world.getThunderStrength(1f)*0.3)));
final double rf = Math.sin((Math.PI/2) * Math.sqrt(((double)(((theta<0)||(theta>180))?(0):((theta>90)?(180-theta):(theta))))/90));
current_production_ = ((int)(Math.min(rf*rf*eff, 1) * peak_power_per_tick_));
accumulated_power_ = Math.min(accumulated_power_ + (current_production_*(TICK_INTERVAL*ACCUMULATION_INTERVAL)), max_power_storage_);
}
}
}

View file

@ -9,6 +9,7 @@
package wile.engineersdecor.blocks;
import wile.engineersdecor.ModEngineersDecor;
import wile.engineersdecor.detail.ModAuxiliaries;
import wile.engineersdecor.detail.TreeCutting;
import net.minecraft.block.properties.PropertyBool;
import net.minecraft.block.state.BlockStateContainer;
@ -17,18 +18,19 @@ import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.world.World;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.init.SoundEvents;
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.nbt.NBTTagCompound;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.energy.CapabilityEnergy;
import net.minecraftforge.energy.IEnergyStorage;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Random;
@ -86,6 +88,16 @@ public class BlockDecorTreeCutter extends BlockDecorDirectedHorizontal
}
}
@Override
public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ)
{
if(world.isRemote) return true;
TileEntity te = world.getTileEntity(pos);
if(!(te instanceof BTileEntity)) return true;
((BTileEntity)te).state_message(player);
return true;
}
//--------------------------------------------------------------------------------------------------------------------
// Tile entity
//--------------------------------------------------------------------------------------------------------------------
@ -97,6 +109,7 @@ public class BlockDecorTreeCutter extends BlockDecorDirectedHorizontal
public static final int BOOST_FACTOR = 6;
public static final int DEFAULT_BOOST_ENERGY = 64;
public static final int DEFAULT_CUTTING_TIME_NEEDED = 60; // 60 secs, so that people don't come to the bright idea to carry one with them.
private static int energy_max = DEFAULT_BOOST_ENERGY * 20;
private static int boost_energy_consumption = DEFAULT_BOOST_ENERGY;
private static int cutting_time_needed = 20 * DEFAULT_CUTTING_TIME_NEEDED;
private static boolean requires_power = false;
@ -104,11 +117,12 @@ public class BlockDecorTreeCutter extends BlockDecorDirectedHorizontal
private int tick_timer_;
private int active_timer_;
private int proc_time_elapsed_; // small, not saved in nbt.
private int boost_energy_; // small, not saved in nbt.
private int energy_; // small, not saved in nbt.
public static void on_config(int boost_energy_per_tick, int cutting_time_seconds, boolean power_required)
{
boost_energy_consumption = TICK_INTERVAL * MathHelper.clamp(boost_energy_per_tick, 16, 512);
energy_max = Math.max(boost_energy_consumption * 10, 10000);
cutting_time_needed = 20 * MathHelper.clamp(cutting_time_seconds, 10, 240);
requires_power = power_required;
ModEngineersDecor.logger.info("Config tree cutter: Boost energy consumption:" + boost_energy_consumption + "rf/t" + (requires_power?" (power required for operation) ":"") + ", cutting time " + cutting_time_needed + "t." );
@ -117,12 +131,36 @@ public class BlockDecorTreeCutter extends BlockDecorDirectedHorizontal
public BTileEntity()
{}
public void state_message(EntityPlayer player)
{
String soc = Integer.toString(MathHelper.clamp((energy_*100/energy_max),0,100));
String progress = "";
if((active_timer_ > 0) && (cutting_time_needed > 0)) {
progress = " | " + Integer.toString((int)MathHelper.clamp((((double)proc_time_elapsed_) / ((double)cutting_time_needed) * 100), 0, 100)) + "%%";
}
ModAuxiliaries.playerChatMessage(player, soc + "%%/" + energy_max + "RF" + progress);
}
public void readnbt(NBTTagCompound nbt)
{ energy_ = nbt.getInteger("energy"); }
private void writenbt(NBTTagCompound nbt)
{ nbt.setInteger("energy", energy_); }
// TileEntity ------------------------------------------------------------------------------
@Override
public boolean shouldRefresh(World world, BlockPos pos, IBlockState os, IBlockState ns)
{ return (os.getBlock() != ns.getBlock()) || (!(ns.getBlock() instanceof BlockDecorTreeCutter)); }
@Override
public void readFromNBT(NBTTagCompound nbt)
{ super.readFromNBT(nbt); readnbt(nbt); }
@Override
public NBTTagCompound writeToNBT(NBTTagCompound nbt)
{ super.writeToNBT(nbt); writenbt(nbt); return nbt; }
// IEnergyStorage ----------------------------------------------------------------------------
@Override
@ -135,11 +173,11 @@ public class BlockDecorTreeCutter extends BlockDecorDirectedHorizontal
@Override
public int getMaxEnergyStored()
{ return boost_energy_consumption; }
{ return boost_energy_consumption*2; }
@Override
public int getEnergyStored()
{ return boost_energy_; }
{ return energy_; }
@Override
public int extractEnergy(int maxExtract, boolean simulate)
@ -147,10 +185,10 @@ public class BlockDecorTreeCutter extends BlockDecorDirectedHorizontal
@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;
{
maxReceive = MathHelper.clamp(maxReceive, 0, Math.max((energy_max) - energy_, 0));
if(!simulate) energy_ += maxReceive;
return maxReceive;
}
// Capability export ----------------------------------------------------------------------------
@ -197,8 +235,8 @@ public class BlockDecorTreeCutter extends BlockDecorDirectedHorizontal
return;
}
proc_time_elapsed_ += TICK_INTERVAL;
if(boost_energy_ >= boost_energy_consumption) {
boost_energy_ = 0;
if(energy_ >= boost_energy_consumption) {
energy_ -= boost_energy_consumption;
proc_time_elapsed_ += TICK_INTERVAL*BOOST_FACTOR;
active_timer_ = 2;
} else if(!requires_power) {

View file

@ -178,7 +178,7 @@ public class BlockDecorWall extends BlockDecor
{
final IBlockState state = world.getBlockState(other);
final Block block = state.getBlock();
if((block instanceof BlockDecorWall) || (block instanceof BlockFenceGate) || (block instanceof BlockDecorFence)) return true;
if((block instanceof BlockDecorWall) || (block instanceof BlockFenceGate) || (block instanceof BlockDecorFence) || (block instanceof BlockDecorDoubleGate)) return true;
if(world.getBlockState(pos.offset(facing)).getBlock()!=this) return false;
if(block instanceof BlockFence) return true;
final BlockFaceShape shp = state.getBlockFaceShape(world, other, facing);

View file

@ -14,6 +14,7 @@ import wile.engineersdecor.ModEngineersDecor;
import wile.engineersdecor.blocks.*;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.block.Block;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.Item;
import net.minecraftforge.common.config.Config;
import net.minecraftforge.common.config.ConfigManager;
@ -78,6 +79,11 @@ public class ModConfig
@Config.RequiresMcRestart
public boolean without_rebar_concrete = false;
@Config.Comment({"Disable gas concrete and derived blocks."})
@Config.Name("Without gas concrete")
@Config.RequiresMcRestart
public boolean without_gas_concrete = false;
@Config.Comment({"Disable all mod wall blocks."})
@Config.Name("Without walls")
@Config.RequiresMcRestart
@ -554,6 +560,7 @@ public class ModConfig
if(optout.without_clinker_bricks && (rn.startsWith("clinker_brick_"))) return true;
if(optout.without_slag_bricks && rn.startsWith("slag_brick_")) return true;
if(optout.without_rebar_concrete && rn.startsWith("rebar_concrete")) return true;
if(optout.without_gas_concrete && rn.startsWith("gas_concrete")) return true;
if(optout.without_ie_concrete_wall && rn.startsWith("concrete_wall")) return true;
if(optout.without_panzer_glass && rn.startsWith("panzerglass_")) return true;
if(optout.without_light_sources && rn.endsWith("_light")) return true;
@ -561,8 +568,11 @@ public class ModConfig
if(optout.without_treated_wood_furniture) {
if(block instanceof BlockDecorChair) return true;
if(rn.equals("treated_wood_table")) return true;
if(rn.equals("treated_wood_side_table")) return true;
if(rn.equals("treated_wood_stool")) return true;
if(rn.equals("treated_wood_windowsill")) return true;
if(rn.equals("treated_wood_broad_windowsill")) return true;
if(rn.equals("steel_table")) return true;
}
return false;
}
@ -570,6 +580,7 @@ public class ModConfig
public static final boolean isOptedOut(final @Nullable Item item)
{
if((item == null) || (optout == null)) return true;
if(item instanceof ItemBlock) return isOptedOut(((ItemBlock)item).getBlock());
return false;
}
@ -606,7 +617,7 @@ public class ModConfig
BlockDecorLadder.on_config(optout.without_ladder_speed_boost);
BlockDecorCraftingTable.on_config(optout.without_crafting_table_history, false, tweaks.with_crafting_quickmove_buttons, tweaks.without_crafting_mouse_scrolling);
BlockDecorPipeValve.on_config(tweaks.pipevalve_max_flowrate, tweaks.pipevalve_redstone_slope);
BlockDecorFurnaceElectrical.BTileEntity.on_config(tweaks.e_furnace_speed_percent, tweaks.e_furnace_power_consumption);
BlockDecorFurnaceElectrical.BTileEntity.on_config(tweaks.e_furnace_speed_percent, tweaks.e_furnace_power_consumption, false);
BlockDecorSolarPanel.BTileEntity.on_config(tweaks.solar_panel_peak_power);
BlockDecorBreaker.BTileEntity.on_config(tweaks.block_breaker_power_consumption, tweaks.block_breaker_reluctance, tweaks.block_breaker_min_breaking_time, tweaks.block_breaker_requires_power);
BlockDecorTreeCutter.BTileEntity.on_config(tweaks.tree_cuttter_energy_consumption, tweaks.tree_cuttter_cutting_time_needed, tweaks.tree_cuttter_requires_power);

View file

@ -27,6 +27,8 @@ import net.minecraft.item.ItemStack;
import net.minecraft.util.math.MathHelper;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import wile.engineersdecor.blocks.BlockDecorLabeledCrate;
import wile.engineersdecor.blocks.BlockDecorLabeledCrate.DecorLabeledCrateBlock;
import wile.engineersdecor.blocks.BlockDecorTest;
public class ModTesrs
@ -82,13 +84,58 @@ public class ModTesrs
}
} catch(Throwable e) {
if(--tesr_error_counter<=0) {
ModEngineersDecor.logger.error("TESR was disabled because broken, exception was: " + e.getMessage());
ModEngineersDecor.logger.error("Crafting Table TESR was disabled because broken, exception was: " + e.getMessage());
ModEngineersDecor.logger.error(e.getStackTrace());
}
}
}
}
//--------------------------------------------------------------------------------------------------------------------
// Labeled Crate
//--------------------------------------------------------------------------------------------------------------------
@SideOnly(Side.CLIENT)
public static class TesrDecorLabeledCrate extends TileEntitySpecialRenderer<BlockDecorLabeledCrate.LabeledCrateTileEntity>
{
private static int tesr_error_counter = 4;
private static double scaler = 0.35;
double tr[][]= { // [hdirection=S-W-N-E][param]
{ +8.0/32, -8.0/32, +15.5/32, 180.0 }, // N
{ -15.5/32, -8.0/32, +8.0/32, 90.0 }, // E
{ -8.0/32, -8.0/32, -15.5/32, 0.0 }, // S param=tx,ty,tz,ry
{ +15.5/32, -8.0/32, -8.0/32, 270.0 }, // W
};
@Override
public void render(final BlockDecorLabeledCrate.LabeledCrateTileEntity te, final double x, final double y, final double z, final float partialTicks, final int destroyStage, final float alpha)
{
if(tesr_error_counter<=0) return;
try {
final ItemStack stack = te.getItemFrameStack();
if(stack.isEmpty()) return;
final int di = MathHelper.clamp(te.getWorld().getBlockState(te.getPos()).getValue(DecorLabeledCrateBlock.FACING).getHorizontalIndex(), 0, 3);
double ox = tr[di][0], oy = tr[di][1], oz = tr[di][2], ry = tr[di][3];
GlStateManager.pushMatrix();
GlStateManager.disableLighting();
RenderHelper.enableStandardItemLighting();
GlStateManager.translate(x+0.5+ox, y+0.5+oy, z+0.5+oz);
GlStateManager.rotate((float)ry, 0, 1, 0);
GlStateManager.scale(scaler, scaler, scaler);
Minecraft.getMinecraft().getRenderItem().renderItem(stack, TransformType.FIXED);
RenderHelper.disableStandardItemLighting();
GlStateManager.enableLighting();
GlStateManager.popMatrix();
} catch(Throwable e) {
if(--tesr_error_counter<=0) {
ModEngineersDecor.logger.error("Labeled Crate TESR was disabled (because broken), exception was: " + e.getMessage());
}
}
}
}
//--------------------------------------------------------------------------------------------------------------------
// Test Block
//--------------------------------------------------------------------------------------------------------------------
@SideOnly(Side.CLIENT)

View file

@ -8,28 +8,31 @@
*/
package wile.engineersdecor.items;
import wile.engineersdecor.ModEngineersDecor;
import wile.engineersdecor.detail.ModAuxiliaries;
import wile.engineersdecor.detail.ModConfig;
import net.minecraft.client.renderer.block.model.ModelBakery;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.item.Item;
import net.minecraft.block.Block;
import net.minecraft.item.ItemBlock;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import wile.engineersdecor.ModEngineersDecor;
import wile.engineersdecor.detail.ModAuxiliaries;
import javax.annotation.Nullable;
import java.util.List;
public class ItemDecor extends Item
public class ItemDecor extends ItemBlock
{
ItemDecor(String registryName)
public ItemDecor(Block block)
{
super();
setRegistryName(ModEngineersDecor.MODID, registryName);
setTranslationKey(ModEngineersDecor.MODID + "." + registryName);
super(block);
setRegistryName(block.getRegistryName());
setTranslationKey(ModEngineersDecor.MODID + "." + block.getRegistryName().getPath());
setMaxStackSize(64);
setCreativeTab(ModEngineersDecor.CREATIVE_TAB_ENGINEERSDECOR);
setHasSubtypes(false);
@ -48,4 +51,7 @@ public class ItemDecor extends Item
public void addInformation(ItemStack stack, @Nullable World world, List<String> tooltip, ITooltipFlag flag)
{ ModAuxiliaries.Tooltip.addInformation(stack, world, tooltip, flag, true); }
@Nullable
public CreativeTabs getCreativeTab()
{ return ModConfig.isOptedOut(this) ? null : super.getCreativeTab(); }
}

View file

@ -0,0 +1,347 @@
/*
* @file Inventories.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2019 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)
*
* General inventory item handling functionality.
*/
package wile.engineersdecor.libmc.detail;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.world.World;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.ISidedInventory;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemHandlerHelper;
import net.minecraftforge.items.wrapper.InvWrapper;
import net.minecraftforge.items.wrapper.SidedInvWrapper;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
public class Inventories
{
public static boolean areItemStacksIdentical(ItemStack a, ItemStack b)
{ return (a.getItem()==b.getItem()) && ItemStack.areItemStackTagsEqual(a, b); }
public static boolean areItemStacksDifferent(ItemStack a, ItemStack b)
{ return (a.getItem()!=b.getItem()) || (!ItemStack.areItemStackTagsEqual(a, b)); }
public static IItemHandler itemhandler(World world, BlockPos pos, @Nullable EnumFacing side)
{
TileEntity te = world.getTileEntity(pos);
if(te==null) return null;
IItemHandler ih = te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, side);
if(ih!=null) return ih;
if((side!=null) && (te instanceof ISidedInventory)) return new SidedInvWrapper((ISidedInventory)te, side);
if(te instanceof IInventory) return new InvWrapper((IInventory)te);
return null;
}
public static ItemStack insert(IItemHandler inventory, ItemStack stack , boolean simulate)
{ return ItemHandlerHelper.insertItemStacked(inventory, stack, simulate); }
public static ItemStack insert(TileEntity te, @Nullable EnumFacing side, ItemStack stack, boolean simulate)
{
if(te==null) return stack;
IItemHandler hnd = te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, side);
if(hnd != null) {
hnd = (IItemHandler)te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, side);
} else if((side!=null) && (te instanceof ISidedInventory)) {
hnd = new SidedInvWrapper((ISidedInventory)te, side);
} else if(te instanceof IInventory) {
hnd = new InvWrapper((IInventory)te);
}
return (hnd==null) ? stack : ItemHandlerHelper.insertItemStacked(hnd, stack, simulate);
}
public static ItemStack extract(IItemHandler inventory, @Nullable ItemStack match, int amount, boolean simulate)
{
if((inventory==null) || (amount<=0)) return ItemStack.EMPTY;
final int max = inventory.getSlots();
ItemStack out_stack = ItemStack.EMPTY;
for(int i=0; i<max; ++i) {
final ItemStack stack = inventory.getStackInSlot(i);
if(stack.isEmpty()) continue;
if(out_stack.isEmpty()) {
if((match!=null) && areItemStacksDifferent(stack, match)) continue;
out_stack = inventory.extractItem(i, amount, simulate);
} else if(areItemStacksIdentical(stack, out_stack)) {
ItemStack es = inventory.extractItem(i, (amount-out_stack.getCount()), simulate);
out_stack.grow(es.getCount());
}
if(out_stack.getCount() >= amount) break;
}
return out_stack;
}
private static ItemStack checked(ItemStack stack)
{ return stack.isEmpty() ? ItemStack.EMPTY : stack; } // explicit EMPTY return
public static class SlotRange
{
public final IInventory inventory;
public final int start_slot, end_slot;
public SlotRange(IInventory inv, int start, int end)
{ inventory=inv; start_slot=start; end_slot=end; }
/**
* Returns the number of stacks that match the given stack with NBT.
*/
public int stackMatchCount(final ItemStack ref_stack)
{
int n = 0; // ... std::accumulate() the old school way.
for(int i = start_slot; i < end_slot; ++i) {
if(areItemStacksIdentical(ref_stack, inventory.getStackInSlot(i))) ++n;
}
return n;
}
public int totalMatchingItemCount(final ItemStack ref_stack)
{
int n = 0;
for(int i = start_slot; i < end_slot; ++i) {
ItemStack stack = inventory.getStackInSlot(i);
if(areItemStacksIdentical(ref_stack, stack)) n += stack.getCount();
}
return n;
}
/**
* Moves as much items from the stack to the slots in range [start_slot, end_slot] of the inventory,
* filling up existing stacks first, then (player inventory only) checks appropriate empty slots next
* to stacks that have that item already, and last uses any empty slot that can be found.
* Returns the stack that is still remaining in the referenced `stack`.
*/
public ItemStack insert(final ItemStack stack_to_move, boolean only_fillup, int limit)
{ return insert(stack_to_move, only_fillup, limit, false, false); }
public ItemStack insert(final ItemStack stack_to_move, boolean only_fillup, int limit, boolean reverse, boolean force_group_stacks)
{
final ItemStack mvstack = stack_to_move.copy();
if((mvstack.isEmpty()) || (start_slot < 0) || (end_slot > inventory.getSizeInventory())) return checked(mvstack);
int limit_left = (limit>0) ? (Math.min(limit, mvstack.getMaxStackSize())) : (mvstack.getMaxStackSize());
boolean matches[] = new boolean[end_slot];
boolean empties[] = new boolean[end_slot];
int num_matches = 0;
for(int i = start_slot; i < end_slot; ++i) {
final int sno = reverse ? (end_slot-1-i) : (i);
final ItemStack stack = inventory.getStackInSlot(sno);
if(stack.isEmpty() || (!inventory.isItemValidForSlot(sno, mvstack))) {
empties[sno] = true;
} else if(areItemStacksIdentical(stack, mvstack)) {
matches[sno] = true;
++num_matches;
}
}
// first iteration: fillup existing stacks
for(int i = start_slot; i < end_slot; ++i) {
final int sno = reverse ? (end_slot-1-i) : (i);
if(empties[sno] || !matches[sno]) continue;
final ItemStack stack = inventory.getStackInSlot(sno);
int nmax = Math.min(limit_left, stack.getMaxStackSize() - stack.getCount());
if(mvstack.getCount() <= nmax) {
stack.setCount(stack.getCount()+mvstack.getCount());
inventory.setInventorySlotContents(sno, stack);
return ItemStack.EMPTY;
} else {
stack.grow(nmax);
mvstack.shrink(nmax);
inventory.setInventorySlotContents(sno, stack);
limit_left -= nmax;
}
}
if(only_fillup) return checked(mvstack);
if((num_matches>0) && ((force_group_stacks) || (inventory instanceof InventoryPlayer))) {
// second iteration: use appropriate empty slots,
// a) between
{
int insert_start = -1;
int insert_end = -1;
int i = start_slot+1;
for(;i < end_slot-1; ++i) {
final int sno = reverse ? (end_slot-1-i) : (i);
if(insert_start < 0) {
if(matches[sno]) insert_start = sno;
} else if(matches[sno]) {
insert_end = sno;
}
}
for(i=insert_start;i < insert_end; ++i) {
final int sno = reverse ? (end_slot-1-i) : (i);
if(!empties[sno]) continue;
int nmax = Math.min(limit_left, mvstack.getCount());
ItemStack moved = mvstack.copy();
moved.setCount(nmax);
mvstack.shrink(nmax);
inventory.setInventorySlotContents(sno, moved);
return checked(mvstack);
}
}
// b) before/after
{
for(int i = start_slot+1; i < end_slot-1; ++i) {
final int sno = reverse ? (end_slot-1-i) : (i);
if(!matches[sno]) continue;
int ii = (empties[sno-1]) ? (sno-1) : (empties[sno+1] ? (sno+1) : -1);
if(ii >= 0) {
int nmax = Math.min(limit_left, mvstack.getCount());
ItemStack moved = mvstack.copy();
moved.setCount(nmax);
mvstack.shrink(nmax);
inventory.setInventorySlotContents(ii, moved);
return checked(mvstack);
}
}
}
}
// third iteration: use any empty slots
for(int i = start_slot; i < end_slot; ++i) {
final int sno = reverse ? (end_slot-1-i) : (i);
if(!empties[sno]) continue;
int nmax = Math.min(limit_left, mvstack.getCount());
ItemStack placed = mvstack.copy();
placed.setCount(nmax);
mvstack.shrink(nmax);
inventory.setInventorySlotContents(sno, placed);
return checked(mvstack);
}
return checked(mvstack);
}
/**
* Moves as much items from the slots in range [start_slot, end_slot] of the inventory into a new stack.
* Implicitly shrinks the inventory stacks and the `request_stack`.
*/
public ItemStack extract(final ItemStack request_stack)
{
if(request_stack.isEmpty()) return ItemStack.EMPTY;
final IInventory inventory = this.inventory;
List<ItemStack> matches = new ArrayList<>();
for(int i = start_slot; i < end_slot; ++i) {
final ItemStack stack = inventory.getStackInSlot(i);
if((!stack.isEmpty()) && (areItemStacksIdentical(stack, request_stack))) {
if(stack.hasTagCompound()) {
final NBTTagCompound nbt = stack.getTagCompound();
int n = nbt.getSize();
if((n > 0) && (nbt.hasKey("Damage"))) --n;
if(n > 0) continue;
}
matches.add(stack);
}
}
matches.sort(Comparator.comparingInt(ItemStack::getCount));
if(matches.isEmpty()) return ItemStack.EMPTY;
int n_left = request_stack.getCount();
ItemStack fetched_stack = matches.get(0).splitStack(n_left);
n_left -= fetched_stack.getCount();
for(int i=1; (i<matches.size()) && (n_left>0); ++i) {
ItemStack stack = matches.get(i).splitStack(n_left);
n_left -= stack.getCount();
fetched_stack.grow(stack.getCount());
}
return checked(fetched_stack);
}
}
public static class InventoryRange implements IInventory
{
public final IInventory inventory;
public final int offset, size;
public InventoryRange(IInventory inventory, int offset, int size)
{ this.inventory = inventory; this.offset = offset; this.size = size; }
@Override
public void clear()
{ inventory.clear(); }
@Override
public int getSizeInventory()
{ return size; }
@Override
public boolean isEmpty()
{ for(int i=0; i<size; ++i) if(!inventory.getStackInSlot(offset+i).isEmpty()){return false;} return true; }
@Override
public ItemStack getStackInSlot(int index)
{ return inventory.getStackInSlot(offset+index); }
@Override
public ItemStack decrStackSize(int index, int count)
{ return inventory.decrStackSize(offset+index, count); }
@Override
public ItemStack removeStackFromSlot(int index)
{ return inventory.removeStackFromSlot(offset+index); }
@Override
public void setInventorySlotContents(int index, ItemStack stack)
{ inventory.setInventorySlotContents(offset+index, stack); }
@Override
public int getInventoryStackLimit()
{ return inventory.getInventoryStackLimit(); }
@Override
public void markDirty()
{ inventory.markDirty(); }
@Override
public boolean isUsableByPlayer(EntityPlayer player)
{ return inventory.isUsableByPlayer(player); }
@Override
public void openInventory(EntityPlayer player)
{ inventory.openInventory(player); }
@Override
public void closeInventory(EntityPlayer player)
{ inventory.closeInventory(player); }
@Override
public boolean isItemValidForSlot(int index, ItemStack stack)
{ return inventory.isItemValidForSlot(offset+index, stack); }
@Override
public int getField(int index)
{ return 0; }
@Override
public void setField(int index, int value)
{}
@Override
public int getFieldCount()
{ return 0; }
@Override
public String getName()
{ return inventory.getName(); }
@Override
public boolean hasCustomName()
{ return inventory.hasCustomName(); }
@Override
public ITextComponent getDisplayName()
{ return inventory.getDisplayName(); }
}
}

View file

@ -0,0 +1,11 @@
{
"forge_marker": 1,
"defaults": {
"model": "engineersdecor:misc/labeled_crate_model"
},
"variants": {
"normal": [{}],
"inventory": [{}],
"facing": { "north": {"y":0}, "south": {"y":180}, "west": {"y":-90}, "east": {"y":90}, "up":{}, "down":{} }
}
}

View file

@ -0,0 +1,21 @@
{
"variants": {
"facing=north,open=false,segment=0": { "model": "engineersdecor:fence/steel_mesh_fence_gate_bottom_model" },
"facing=north,open=true,segment=0": { "model": "engineersdecor:fence/steel_mesh_fence_gate_bottom_model_open" },
"facing=south,open=false,segment=0": { "model": "engineersdecor:fence/steel_mesh_fence_gate_bottom_model" , "y":180 },
"facing=south,open=true,segment=0": { "model": "engineersdecor:fence/steel_mesh_fence_gate_bottom_model_open", "y":180 },
"facing=west,open=false,segment=0": { "model": "engineersdecor:fence/steel_mesh_fence_gate_bottom_model" , "y":270 },
"facing=west,open=true,segment=0": { "model": "engineersdecor:fence/steel_mesh_fence_gate_bottom_model_open", "y":270 },
"facing=east,open=false,segment=0": { "model": "engineersdecor:fence/steel_mesh_fence_gate_bottom_model" , "y":90 },
"facing=east,open=true,segment=0": { "model": "engineersdecor:fence/steel_mesh_fence_gate_bottom_model_open", "y":90 },
"facing=north,open=false,segment=1": { "model": "engineersdecor:fence/steel_mesh_fence_gate_top_model" },
"facing=north,open=true,segment=1": { "model": "engineersdecor:fence/steel_mesh_fence_gate_top_model_open" },
"facing=south,open=false,segment=1": { "model": "engineersdecor:fence/steel_mesh_fence_gate_top_model" , "y":180 },
"facing=south,open=true,segment=1": { "model": "engineersdecor:fence/steel_mesh_fence_gate_top_model_open", "y":180 },
"facing=west,open=false,segment=1": { "model": "engineersdecor:fence/steel_mesh_fence_gate_top_model" , "y":270 },
"facing=west,open=true,segment=1": { "model": "engineersdecor:fence/steel_mesh_fence_gate_top_model_open", "y":270 },
"facing=east,open=false,segment=1": { "model": "engineersdecor:fence/steel_mesh_fence_gate_top_model" , "y":90 },
"facing=east,open=true,segment=1": { "model": "engineersdecor:fence/steel_mesh_fence_gate_top_model_open", "y":90 }
}
}

View file

@ -108,6 +108,8 @@ tile.engineersdecor.treated_wood_crafting_table.help=§6Robust and weather-proof
to clear crafting grid and history. Shift-click stack: player-to-storage stack transfer when crafting \
grid empty, otherwise player-to-grid stack transfer. Automatically distributes the clicked stack. \
Shift-Ctrl-click stack: Move all same stacks. Mouse wheel over crafting slot: Increase/decrease crafting grid items.
tile.engineersdecor.labeled_crate.name=Labeled Crate
tile.engineersdecor.labeled_crate.help=§6§6A storage crate with 9x6 slots and a built-in item frame at the front.§r\nPlace an item into the frame slot at the bottom right of the GUI to define the shown label.
tile.engineersdecor.treated_wood_side_table.name=Treated Wood Side Table
tile.engineersdecor.treated_wood_side_table.help=§6Needed after the work's done.
tile.engineersdecor.iron_inset_light.name=Inset Light
@ -126,6 +128,9 @@ tile.engineersdecor.steel_framed_window.name=Steel Framed Window
tile.engineersdecor.steel_framed_window.help=§6Steel framed triple glazed window. Well insulating. §r Does not connect to adjacent blocks like glass panes.
tile.engineersdecor.steel_mesh_fence.name=Steel Mesh Fence
tile.engineersdecor.steel_mesh_fence.help=§6Industrial style fence.§r\nDoes not connect do regular fences.
tile.engineersdecor.steel_mesh_fence_gate.name=Steel Mesh Fence Gate
tile.engineersdecor.steel_mesh_fence_gate.help=§6Industrial style fence gate that fits well to the Steel Mesh Fence.§r\nCan be placed as single or double size gate.
#-----------------------------------------------------------------------------------------------------------
tile.engineersdecor.small_lab_furnace.name=Small Laboratory Furnace
tile.engineersdecor.small_lab_furnace.help=§6Small metal cased lab kiln.§r Solid fuel consuming, updraught. \

View file

@ -108,6 +108,8 @@ tile.engineersdecor.treated_wood_crafting_table.help=§6Прочный и уст
  очистить сетку крафта и историю. Shift-клик по стеку: передача стека от игрока в хранилище при создании \
если сетка пуста, в противном случае перенос от игрока в сетку. Автоматически распределяет кликаемый стек. \
Shift-Ctrl-клик по стаку: перемещает одинаковые стаки. Колёсико мыши: добавляет/отнимает предметы в сетке.
tile.engineersdecor.labeled_crate.name=Labeled Crate
tile.engineersdecor.labeled_crate.help=§6§6A storage crate with 9x6 slots and a built-in item frame at the front.§r\nPlace an item into the frame slot at the bottom right of the GUI to define the shown label.
tile.engineersdecor.treated_wood_side_table.name=Столик из обработанного дерева
tile.engineersdecor.treated_wood_side_table.help=§6Нужен после того, как работа выполнена.
tile.engineersdecor.iron_inset_light.name=Встраиваемый осветитель
@ -126,6 +128,9 @@ tile.engineersdecor.steel_framed_window.name=Окно со стальной ра
tile.engineersdecor.steel_framed_window.help=§6Стальной каркас окна с тройным остеклением. Хорошо изолирует. §r Не подключается к смежным блокам, таким как стеклянные панели.
tile.engineersdecor.steel_mesh_fence.name=Забор из стальной сетки
tile.engineersdecor.steel_mesh_fence.help=§6Забор в индустриальном стиле.§r\nНе стыкуется с обычными заборами.
tile.engineersdecor.steel_mesh_fence_gate.name=Steel Mesh Fence Gate
tile.engineersdecor.steel_mesh_fence_gate.help=§6Industrial style fence gate that fits well to the Steel Mesh Fence.§r\nCan be placed as single or double size gate.
#-----------------------------------------------------------------------------------------------------------
tile.engineersdecor.small_lab_furnace.name=Компактная лабораторная печь
tile.engineersdecor.small_lab_furnace.help=§6Лабораторная печь в металлическом корпусе.§r Подача твёрдого топлива сверху. \

View file

@ -107,6 +107,8 @@ tile.engineersdecor.treated_wood_crafting_table.help=§6坚固防风防雨。
单击上/下箭头按钮可选择合成历史单击输出格自动放置物品单击X按钮\
清除合成栏和历史。Shift单击一叠物品合成格空时转移到存储格\
非空时到合成栏。会自动分配转移的物品。
tile.engineersdecor.labeled_crate.name=Labeled Crate
tile.engineersdecor.labeled_crate.help=§6§6A storage crate with 9x6 slots and a built-in item frame at the front.§r\nPlace an item into the frame slot at the bottom right of the GUI to define the shown label.
tile.engineersdecor.treated_wood_side_table.name=防腐木茶几
tile.engineersdecor.treated_wood_side_table.help=§6干完活后需要喝杯茶。
tile.engineersdecor.iron_inset_light.name=嵌入灯
@ -126,6 +128,9 @@ tile.engineersdecor.steel_framed_window.name=钢框窗
tile.engineersdecor.steel_framed_window.help=§6钢框三层玻璃窗。绝缘良好。§r不像玻璃板一样连接到相邻方块。
tile.engineersdecor.steel_mesh_fence.name=钢丝栅栏
tile.engineersdecor.steel_mesh_fence.help=§6工业式栅栏。§r\n不与普通栅栏连接。
tile.engineersdecor.steel_mesh_fence_gate.name=Steel Mesh Fence Gate
tile.engineersdecor.steel_mesh_fence_gate.help=§6Industrial style fence gate that fits well to the Steel Mesh Fence.§r\nCan be placed as single or double size gate.
#-----------------------------------------------------------------------------------------------------------
tile.engineersdecor.small_lab_furnace.name=小型实验室炉
tile.engineersdecor.small_lab_furnace.help=§6小型金属壳实验室窑。§r消耗固体燃料向上排气。\

View file

@ -0,0 +1,267 @@
{
"textures": {
"p": "engineersdecor:blocks/fence/steel_mesh_pole_side",
"t": "engineersdecor:blocks/fence/steel_mesh_top",
"particle": "engineersdecor:blocks/fence/steel_mesh_fence",
"s": "engineersdecor:blocks/fence/steel_mesh_fence"
},
"elements": [
{
"from": [3.125, 13.625, 9.4375],
"to": [12.8125, 13.98, 9.625],
"rotation": {"angle": 0, "axis": "y", "origin": [3.375, 8.5, 9.625]},
"faces": {
"north": {"uv": [0.0625, 2.02, 15.5, 2.375], "texture": "#s"},
"south": {"uv": [0.5, 2.02, 15.9375, 2.375], "texture": "#s"},
"up": {"uv": [7.8125, 0.0625, 8, 15.5], "rotation": 90, "texture": "#s"},
"down": {"uv": [7.8125, 0.5, 8, 15.9375], "rotation": 270, "texture": "#s"}
}
},
{
"from": [3.125, 9.625, 9.4375],
"to": [12.8125, 9.98, 9.625],
"rotation": {"angle": 0, "axis": "y", "origin": [3.375, 8.5, 9.625]},
"faces": {
"north": {"uv": [0.0625, 6.02, 15.5, 6.375], "texture": "#s"},
"south": {"uv": [0.5, 6.02, 15.9375, 6.375], "texture": "#s"},
"up": {"uv": [7.8125, 0.0625, 8, 15.5], "rotation": 90, "texture": "#s"},
"down": {"uv": [7.8125, 0.5, 8, 15.9375], "rotation": 270, "texture": "#s"}
}
},
{
"from": [3.125, 5.625, 9.4375],
"to": [12.8125, 5.98, 9.625],
"rotation": {"angle": 0, "axis": "y", "origin": [3.375, 8.5, 9.625]},
"faces": {
"north": {"uv": [0.0625, 10.02, 15.5, 10.375], "texture": "#s"},
"south": {"uv": [0.5, 10.02, 15.9375, 10.375], "texture": "#s"},
"up": {"uv": [7.8125, 0.0625, 8, 15.5], "rotation": 90, "texture": "#s"},
"down": {"uv": [7.8125, 0.5, 8, 15.9375], "rotation": 270, "texture": "#s"}
}
},
{
"from": [3.125, 1.625, 9.4375],
"to": [12.8125, 1.98, 9.625],
"rotation": {"angle": 0, "axis": "y", "origin": [3.375, 8.5, 9.625]},
"faces": {
"north": {"uv": [0.0625, 14.02, 15.5, 14.375], "texture": "#s"},
"east": {"uv": [8, 14.02, 8.1875, 14.375], "texture": "#s"},
"south": {"uv": [0.5, 14.02, 15.9375, 14.375], "texture": "#s"},
"west": {"uv": [7.8125, 14.02, 8, 14.375], "texture": "#s"},
"up": {"uv": [7.8125, 0.0625, 8, 15.5], "rotation": 90, "texture": "#s"},
"down": {"uv": [7.8125, 0.5, 8, 15.9375], "rotation": 270, "texture": "#s"}
}
},
{
"from": [3.125, 11.625, 9.625],
"to": [12.8125, 11.98, 9.8125],
"rotation": {"angle": 0, "axis": "y", "origin": [3.375, 8.5, 9.625]},
"faces": {
"north": {"uv": [0.0625, 4.02, 15.5, 4.375], "texture": "#s"},
"south": {"uv": [0.5, 4.02, 15.9375, 4.375], "texture": "#s"},
"up": {"uv": [8, 0.0625, 8.1875, 15.5], "rotation": 90, "texture": "#s"},
"down": {"uv": [8, 0.5, 8.1875, 15.9375], "rotation": 270, "texture": "#s"}
}
},
{
"from": [3.125, 12.625, 9.875],
"to": [5.3125, 13.23, 10.1875],
"rotation": {"angle": 0, "axis": "y", "origin": [3.375, 9.5, 10]},
"faces": {
"north": {"uv": [10.6875, 2.77, 12.875, 3.375], "texture": "#s"},
"east": {"uv": [5.8125, 2.77, 6, 3.375], "texture": "#s"},
"south": {"uv": [3.125, 2.77, 5.3125, 3.375], "texture": "#s"},
"west": {"uv": [10, 2.77, 10.1875, 3.375], "texture": "#s"},
"up": {"uv": [3.125, 10, 5.3125, 10.1875], "rotation": 90, "texture": "#s"},
"down": {"uv": [3.125, 5.8125, 5.3125, 6], "rotation": 270, "texture": "#s"}
}
},
{
"from": [3.125, 12.625, 9],
"to": [5.3125, 13.23, 9.3125],
"rotation": {"angle": 0, "axis": "y", "origin": [3.375, 9.5, 9.125]},
"faces": {
"north": {"uv": [10.6875, 2.77, 12.875, 3.375], "texture": "#s"},
"east": {"uv": [5.8125, 2.77, 6, 3.375], "texture": "#s"},
"south": {"uv": [3.125, 2.77, 5.3125, 3.375], "texture": "#s"},
"west": {"uv": [10, 2.77, 10.1875, 3.375], "texture": "#s"},
"up": {"uv": [3.125, 10, 5.3125, 10.1875], "rotation": 90, "texture": "#s"},
"down": {"uv": [3.125, 5.8125, 5.3125, 6], "rotation": 270, "texture": "#s"}
}
},
{
"from": [3.5, 7.625, 9.625],
"to": [12.9375, 7.98, 9.8125],
"rotation": {"angle": 0, "axis": "y", "origin": [3.375, 8.5, 9.625]},
"faces": {
"north": {"uv": [0.0625, 8.02, 15.5, 8.375], "texture": "#s"},
"south": {"uv": [0.5, 8.02, 15.9375, 8.375], "texture": "#s"},
"up": {"uv": [8, 0.0625, 8.1875, 15.5], "rotation": 90, "texture": "#s"},
"down": {"uv": [8, 0.5, 8.1875, 15.9375], "rotation": 270, "texture": "#s"}
}
},
{
"from": [3.5, 3.625, 9.625],
"to": [12.9375, 3.98, 9.8125],
"rotation": {"angle": 0, "axis": "y", "origin": [3.375, 8.5, 9.625]},
"faces": {
"north": {"uv": [0.0625, 12.02, 15.5, 12.375], "texture": "#s"},
"south": {"uv": [0.5, 12.02, 15.9375, 12.375], "texture": "#s"},
"up": {"uv": [8, 0.0625, 8.1875, 15.5], "rotation": 90, "texture": "#s"},
"down": {"uv": [8, 0.5, 8.1875, 15.9375], "rotation": 270, "texture": "#s"}
}
},
{
"from": [12.25, 1, 9.25],
"to": [13, 16, 10],
"rotation": {"angle": 0, "axis": "y", "origin": [3.375, 8.5, 9.625]},
"faces": {
"north": {"uv": [1.5, 0, 2.25, 15], "texture": "#s"},
"south": {"uv": [13.75, 0, 14.5, 15], "texture": "#s"},
"west": {"uv": [7.625, 0, 8.375, 15], "texture": "#s"},
"up": {"uv": [7.625, 1.5, 8.375, 2.25], "rotation": 90, "texture": "#s"},
"down": {"uv": [7.625, 13.75, 8.375, 14.5], "rotation": 270, "texture": "#s"}
}
},
{
"from": [3.75, 15, 9.25],
"to": [12.25, 16, 10],
"rotation": {"angle": 0, "axis": "y", "origin": [3.375, 8.5, 9.625]},
"faces": {
"north": {"uv": [2.25, 0, 10.75, 1], "texture": "#s"},
"south": {"uv": [2.25, 0, 10.75, 1], "texture": "#s"},
"up": {"uv": [7.625, 2.25, 8.375, 13.75], "rotation": 90, "texture": "#s"},
"down": {"uv": [7.625, 2.25, 8.375, 13.75], "rotation": 270, "texture": "#s"}
}
},
{
"from": [3.75, 1, 9.25],
"to": [12.25, 2, 10],
"rotation": {"angle": 0, "axis": "y", "origin": [3.375, -5.5, 9.625]},
"faces": {
"north": {"uv": [2.25, 0, 10.75, 1], "texture": "#s"},
"east": {"uv": [7.625, 0, 8.375, 1], "texture": "#s"},
"south": {"uv": [2.25, 0, 10.75, 1], "texture": "#s"},
"west": {"uv": [7.625, 0, 8.375, 1], "texture": "#s"},
"up": {"uv": [7.625, 2.25, 8.375, 13.75], "rotation": 90, "texture": "#s"},
"down": {"uv": [7.625, 2.25, 8.375, 13.75], "rotation": 270, "texture": "#s"}
}
},
{
"from": [3, 1, 9.25],
"to": [3.75, 16, 10],
"rotation": {"angle": 0, "axis": "y", "origin": [3.375, 8.5, 9.625]},
"faces": {
"north": {"uv": [13.75, 0, 14.5, 15], "texture": "#s"},
"east": {"uv": [7.625, 0, 8.375, 15], "texture": "#s"},
"south": {"uv": [1.5, 0, 2.25, 15], "texture": "#s"},
"up": {"uv": [7.625, 13.75, 8.375, 14.5], "rotation": 90, "texture": "#s"},
"down": {"uv": [7.625, 1.5, 8.375, 2.25], "rotation": 270, "texture": "#s"}
}
},
{
"from": [13, 0, 6.5],
"to": [16, 16, 9.5],
"faces": {
"north": {"uv": [6.5, 0, 9.5, 16], "texture": "#p"},
"east": {"uv": [6.5, 0, 9.5, 16], "texture": "#p"},
"south": {"uv": [6.5, 0, 9.5, 16], "texture": "#p"},
"west": {"uv": [6.5, 0, 9.5, 16], "texture": "#p"},
"up": {"uv": [6.5, 6.5, 9.5, 9.5], "rotation": 90, "texture": "#t"},
"down": {"uv": [6.5, 6.5, 9.5, 9.5], "rotation": 270, "texture": "#t"}
}
},
{
"from": [0, 0, 6.5],
"to": [3, 16, 9.5],
"rotation": {"angle": 0, "axis": "y", "origin": [-5, 8, 8]},
"faces": {
"north": {"uv": [6.5, 0, 9.5, 16], "texture": "#p"},
"east": {"uv": [6.5, 0, 9.5, 16], "texture": "#p"},
"south": {"uv": [6.5, 0, 9.5, 16], "texture": "#p"},
"west": {"uv": [6.5, 0, 9.5, 16], "texture": "#p"},
"up": {"uv": [6.5, 6.5, 9.5, 9.5], "rotation": 90, "texture": "#t"},
"down": {"uv": [6.5, 6.5, 9.5, 9.5], "rotation": 270, "texture": "#t"}
}
},
{
"from": [0.5, 0, 9.5],
"to": [3, 16, 10.5],
"rotation": {"angle": 0, "axis": "y", "origin": [-5, 8, 11]},
"faces": {
"east": {"uv": [6, 0, 7, 16], "texture": "#p"},
"south": {"uv": [0, 0, 3, 16], "texture": "#p"},
"west": {"uv": [10, 0, 11, 16], "texture": "#p"},
"up": {"uv": [6, 12, 9, 13], "texture": "#t"},
"down": {"uv": [0, 5.5, 3, 6.5], "texture": "#t"}
}
},
{
"from": [13, 0, 9.5],
"to": [15.5, 16, 10.5],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 11]},
"faces": {
"east": {"uv": [6, 0, 7, 16], "texture": "#p"},
"south": {"uv": [0, 0, 3, 16], "texture": "#p"},
"west": {"uv": [10, 0, 11, 16], "texture": "#p"},
"up": {"uv": [6, 12, 9, 13], "texture": "#t"},
"down": {"uv": [0, 5.5, 3, 6.5], "texture": "#t"}
}
},
{
"from": [11.75, 1.375, 9.5],
"to": [12.125, 15.855, 9.75],
"rotation": {"angle": 0, "axis": "y", "origin": [3.375, 8.5, 9.625]},
"faces": {
"north": {"uv": [3.875, 0.145, 4.25, 15], "texture": "#s"},
"east": {"uv": [7.875, 0.145, 8.125, 15], "texture": "#s"},
"south": {"uv": [11.75, 0.145, 12.125, 15], "texture": "#s"},
"west": {"uv": [7.875, 0.145, 8.125, 15], "texture": "#s"}
}
},
{
"from": [7.75, 1.375, 9.5],
"to": [8.125, 15.855, 9.75],
"rotation": {"angle": 0, "axis": "y", "origin": [3.375, 8.5, 9.625]},
"faces": {
"north": {"uv": [7.875, 0.145, 8.25, 15], "texture": "#s"},
"east": {"uv": [7.875, 0.145, 8.125, 15], "texture": "#s"},
"south": {"uv": [7.75, 0.145, 8.125, 15], "texture": "#s"},
"west": {"uv": [7.875, 0.145, 8.125, 15], "texture": "#s"}
}
},
{
"from": [3.75, 1.375, 9.5],
"to": [4.125, 15.855, 9.75],
"rotation": {"angle": 0, "axis": "y", "origin": [3.375, 8.5, 9.625]},
"faces": {
"north": {"uv": [11.875, 0.145, 12.25, 15], "texture": "#s"},
"east": {"uv": [7.875, 0.145, 8.125, 15], "texture": "#s"},
"south": {"uv": [3.75, 0.145, 4.125, 15], "texture": "#s"},
"west": {"uv": [7.875, 0.145, 8.125, 15], "texture": "#s"}
}
},
{
"from": [9.75, 1.375, 9.5],
"to": [10.125, 15.855, 9.75],
"rotation": {"angle": 0, "axis": "y", "origin": [3.375, 8.5, 9.625]},
"faces": {
"north": {"uv": [5.875, 0.145, 6.25, 15], "texture": "#s"},
"east": {"uv": [7.875, 0.145, 8.125, 15], "texture": "#s"},
"south": {"uv": [9.75, 0.145, 10.125, 15], "texture": "#s"},
"west": {"uv": [7.875, 0.145, 8.125, 15], "texture": "#s"}
}
},
{
"from": [5.75, 1.375, 9.5],
"to": [6.125, 15.855, 9.75],
"rotation": {"angle": 0, "axis": "y", "origin": [3.375, 8.5, 9.625]},
"faces": {
"north": {"uv": [9.875, 0.145, 10.25, 15], "texture": "#s"},
"east": {"uv": [7.875, 0.145, 8.125, 15], "texture": "#s"},
"south": {"uv": [5.75, 0.145, 6.125, 15], "texture": "#s"},
"west": {"uv": [7.875, 0.145, 8.125, 15], "texture": "#s"}
}
}
]
}

View file

@ -0,0 +1,267 @@
{
"textures": {
"p": "engineersdecor:blocks/fence/steel_mesh_pole_side",
"t": "engineersdecor:blocks/fence/steel_mesh_top",
"particle": "engineersdecor:blocks/fence/steel_mesh_fence",
"s": "engineersdecor:blocks/fence/steel_mesh_fence"
},
"elements": [
{
"from": [12.625, 13.625, 0.125],
"to": [12.8125, 13.98, 9.8125],
"rotation": {"angle": 0, "axis": "y", "origin": [12.625, 8.5, 9.625]},
"faces": {
"east": {"uv": [0.0625, 2.02, 15.5, 2.375], "texture": "#s"},
"west": {"uv": [0.5, 2.02, 15.9375, 2.375], "texture": "#s"},
"up": {"uv": [7.8125, 0.0625, 8, 15.5], "rotation": 180, "texture": "#s"},
"down": {"uv": [7.8125, 0.5, 8, 15.9375], "rotation": 180, "texture": "#s"}
}
},
{
"from": [12.625, 9.625, 0.125],
"to": [12.8125, 9.98, 9.8125],
"rotation": {"angle": 0, "axis": "y", "origin": [12.625, 8.5, 9.625]},
"faces": {
"east": {"uv": [0.0625, 6.02, 15.5, 6.375], "texture": "#s"},
"west": {"uv": [0.5, 6.02, 15.9375, 6.375], "texture": "#s"},
"up": {"uv": [7.8125, 0.0625, 8, 15.5], "rotation": 180, "texture": "#s"},
"down": {"uv": [7.8125, 0.5, 8, 15.9375], "rotation": 180, "texture": "#s"}
}
},
{
"from": [12.625, 5.625, 0.125],
"to": [12.8125, 5.98, 9.8125],
"rotation": {"angle": 0, "axis": "y", "origin": [12.625, 8.5, 9.625]},
"faces": {
"east": {"uv": [0.0625, 10.02, 15.5, 10.375], "texture": "#s"},
"west": {"uv": [0.5, 10.02, 15.9375, 10.375], "texture": "#s"},
"up": {"uv": [7.8125, 0.0625, 8, 15.5], "rotation": 180, "texture": "#s"},
"down": {"uv": [7.8125, 0.5, 8, 15.9375], "rotation": 180, "texture": "#s"}
}
},
{
"from": [12.625, 1.625, 0.125],
"to": [12.8125, 1.98, 9.8125],
"rotation": {"angle": 0, "axis": "y", "origin": [12.625, 8.5, 9.625]},
"faces": {
"north": {"uv": [7.8125, 14.02, 8, 14.375], "texture": "#s"},
"east": {"uv": [0.0625, 14.02, 15.5, 14.375], "texture": "#s"},
"south": {"uv": [8, 14.02, 8.1875, 14.375], "texture": "#s"},
"west": {"uv": [0.5, 14.02, 15.9375, 14.375], "texture": "#s"},
"up": {"uv": [7.8125, 0.0625, 8, 15.5], "rotation": 180, "texture": "#s"},
"down": {"uv": [7.8125, 0.5, 8, 15.9375], "rotation": 180, "texture": "#s"}
}
},
{
"from": [12.4375, 11.625, 0.125],
"to": [12.625, 11.98, 9.8125],
"rotation": {"angle": 0, "axis": "y", "origin": [12.625, 8.5, 9.625]},
"faces": {
"east": {"uv": [0.0625, 4.02, 15.5, 4.375], "texture": "#s"},
"west": {"uv": [0.5, 4.02, 15.9375, 4.375], "texture": "#s"},
"up": {"uv": [8, 0.0625, 8.1875, 15.5], "rotation": 180, "texture": "#s"},
"down": {"uv": [8, 0.5, 8.1875, 15.9375], "rotation": 180, "texture": "#s"}
}
},
{
"from": [12.0625, 12.625, 0.125],
"to": [12.375, 13.23, 2.3125],
"rotation": {"angle": 0, "axis": "y", "origin": [12.625, 8.5, 9.625]},
"faces": {
"north": {"uv": [10, 2.77, 10.1875, 3.375], "texture": "#s"},
"east": {"uv": [10.6875, 2.77, 12.875, 3.375], "texture": "#s"},
"south": {"uv": [5.8125, 2.77, 6, 3.375], "texture": "#s"},
"west": {"uv": [3.125, 2.77, 5.3125, 3.375], "texture": "#s"},
"up": {"uv": [3.125, 10, 5.3125, 10.1875], "rotation": 180, "texture": "#s"},
"down": {"uv": [3.125, 5.8125, 5.3125, 6], "rotation": 180, "texture": "#s"}
}
},
{
"from": [12.9375, 12.625, 0.125],
"to": [13.25, 13.23, 2.3125],
"rotation": {"angle": 0, "axis": "y", "origin": [12.625, 8.5, 9.625]},
"faces": {
"north": {"uv": [10, 2.77, 10.1875, 3.375], "texture": "#s"},
"east": {"uv": [10.6875, 2.77, 12.875, 3.375], "texture": "#s"},
"south": {"uv": [5.8125, 2.77, 6, 3.375], "texture": "#s"},
"west": {"uv": [3.125, 2.77, 5.3125, 3.375], "texture": "#s"},
"up": {"uv": [3.125, 10, 5.3125, 10.1875], "rotation": 180, "texture": "#s"},
"down": {"uv": [3.125, 5.8125, 5.3125, 6], "rotation": 180, "texture": "#s"}
}
},
{
"from": [12.4375, 7.625, 0.5],
"to": [12.625, 7.98, 9.9375],
"rotation": {"angle": 0, "axis": "y", "origin": [12.625, 8.5, 9.625]},
"faces": {
"east": {"uv": [0.0625, 8.02, 15.5, 8.375], "texture": "#s"},
"west": {"uv": [0.5, 8.02, 15.9375, 8.375], "texture": "#s"},
"up": {"uv": [8, 0.0625, 8.1875, 15.5], "rotation": 180, "texture": "#s"},
"down": {"uv": [8, 0.5, 8.1875, 15.9375], "rotation": 180, "texture": "#s"}
}
},
{
"from": [12.4375, 3.625, 0.5],
"to": [12.625, 3.98, 9.9375],
"rotation": {"angle": 0, "axis": "y", "origin": [12.625, 8.5, 9.625]},
"faces": {
"east": {"uv": [0.0625, 12.02, 15.5, 12.375], "texture": "#s"},
"west": {"uv": [0.5, 12.02, 15.9375, 12.375], "texture": "#s"},
"up": {"uv": [8, 0.0625, 8.1875, 15.5], "rotation": 180, "texture": "#s"},
"down": {"uv": [8, 0.5, 8.1875, 15.9375], "rotation": 180, "texture": "#s"}
}
},
{
"from": [12.25, 1, 9.25],
"to": [13, 16, 10],
"rotation": {"angle": 0, "axis": "y", "origin": [12.625, 8.5, 9.625]},
"faces": {
"north": {"uv": [7.625, 0, 8.375, 15], "texture": "#s"},
"east": {"uv": [1.5, 0, 2.25, 15], "texture": "#s"},
"south": {"uv": [7.625, 0, 8.375, 15], "texture": "#s"},
"west": {"uv": [13.75, 0, 14.5, 15], "texture": "#s"},
"up": {"uv": [7.625, 1.5, 8.375, 2.25], "rotation": 180, "texture": "#s"},
"down": {"uv": [7.625, 13.75, 8.375, 14.5], "rotation": 180, "texture": "#s"}
}
},
{
"from": [12.25, 15, 0.75],
"to": [13, 16, 9.25],
"rotation": {"angle": 0, "axis": "y", "origin": [12.625, 8.5, 9.625]},
"faces": {
"east": {"uv": [2.25, 0, 10.75, 1], "texture": "#s"},
"west": {"uv": [2.25, 0, 10.75, 1], "texture": "#s"},
"up": {"uv": [7.625, 2.25, 8.375, 13.75], "rotation": 180, "texture": "#s"},
"down": {"uv": [7.625, 2.25, 8.375, 13.75], "rotation": 180, "texture": "#s"}
}
},
{
"from": [12.25, 1, 0.75],
"to": [13, 2, 9.25],
"rotation": {"angle": 0, "axis": "y", "origin": [12.625, 8.5, 9.625]},
"faces": {
"east": {"uv": [2.25, 0, 10.75, 1], "texture": "#s"},
"west": {"uv": [2.25, 0, 10.75, 1], "texture": "#s"},
"up": {"uv": [7.625, 2.25, 8.375, 13.75], "rotation": 180, "texture": "#s"},
"down": {"uv": [7.625, 2.25, 8.375, 13.75], "rotation": 180, "texture": "#s"}
}
},
{
"from": [12.25, 1, 0],
"to": [13, 16, 0.75],
"rotation": {"angle": 0, "axis": "y", "origin": [12.625, 8.5, 9.625]},
"faces": {
"north": {"uv": [7.625, 0, 8.375, 15], "texture": "#s"},
"east": {"uv": [13.75, 0, 14.5, 15], "texture": "#s"},
"south": {"uv": [7.625, 0, 8.375, 15], "texture": "#s"},
"west": {"uv": [1.5, 0, 2.25, 15], "texture": "#s"},
"up": {"uv": [7.625, 13.75, 8.375, 14.5], "rotation": 180, "texture": "#s"},
"down": {"uv": [7.625, 1.5, 8.375, 2.25], "rotation": 180, "texture": "#s"}
}
},
{
"from": [13, 0, 6.5],
"to": [16, 16, 9.5],
"faces": {
"north": {"uv": [6.5, 0, 9.5, 16], "texture": "#p"},
"east": {"uv": [6.5, 0, 9.5, 16], "texture": "#p"},
"south": {"uv": [6.5, 0, 9.5, 16], "texture": "#p"},
"west": {"uv": [6.5, 0, 9.5, 16], "texture": "#p"},
"up": {"uv": [6.5, 6.5, 9.5, 9.5], "rotation": 90, "texture": "#t"},
"down": {"uv": [6.5, 6.5, 9.5, 9.5], "rotation": 270, "texture": "#t"}
}
},
{
"from": [0, 0, 6.5],
"to": [3, 16, 9.5],
"rotation": {"angle": 0, "axis": "y", "origin": [-5, 8, 8]},
"faces": {
"north": {"uv": [6.5, 0, 9.5, 16], "texture": "#p"},
"east": {"uv": [6.5, 0, 9.5, 16], "texture": "#p"},
"south": {"uv": [6.5, 0, 9.5, 16], "texture": "#p"},
"west": {"uv": [6.5, 0, 9.5, 16], "texture": "#p"},
"up": {"uv": [6.5, 6.5, 9.5, 9.5], "rotation": 90, "texture": "#t"},
"down": {"uv": [6.5, 6.5, 9.5, 9.5], "rotation": 270, "texture": "#t"}
}
},
{
"from": [0.5, 0, 9.5],
"to": [3, 16, 10.5],
"rotation": {"angle": 0, "axis": "y", "origin": [-5, 8, 11]},
"faces": {
"east": {"uv": [6, 0, 7, 16], "texture": "#p"},
"south": {"uv": [0, 0, 3, 16], "texture": "#p"},
"west": {"uv": [10, 0, 11, 16], "texture": "#p"},
"up": {"uv": [6, 12, 9, 13], "texture": "#t"},
"down": {"uv": [0, 5.5, 3, 6.5], "texture": "#t"}
}
},
{
"from": [13, 0, 9.5],
"to": [15.5, 16, 10.5],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 11]},
"faces": {
"east": {"uv": [6, 0, 7, 16], "texture": "#p"},
"south": {"uv": [0, 0, 3, 16], "texture": "#p"},
"west": {"uv": [10, 0, 11, 16], "texture": "#p"},
"up": {"uv": [6, 12, 9, 13], "texture": "#t"},
"down": {"uv": [0, 5.5, 3, 6.5], "texture": "#t"}
}
},
{
"from": [12.5, 1.375, 8.75],
"to": [12.75, 15.855, 9.125],
"rotation": {"angle": 0, "axis": "y", "origin": [12.625, 8.5, 9.625]},
"faces": {
"north": {"uv": [7.875, 0.145, 8.125, 15], "texture": "#s"},
"east": {"uv": [3.875, 0.145, 4.25, 15], "texture": "#s"},
"south": {"uv": [7.875, 0.145, 8.125, 15], "texture": "#s"},
"west": {"uv": [11.75, 0.145, 12.125, 15], "texture": "#s"}
}
},
{
"from": [12.5, 1.375, 4.75],
"to": [12.75, 15.855, 5.125],
"rotation": {"angle": 0, "axis": "y", "origin": [12.625, 8.5, 9.625]},
"faces": {
"north": {"uv": [7.875, 0.145, 8.125, 15], "texture": "#s"},
"east": {"uv": [7.875, 0.145, 8.25, 15], "texture": "#s"},
"south": {"uv": [7.875, 0.145, 8.125, 15], "texture": "#s"},
"west": {"uv": [7.75, 0.145, 8.125, 15], "texture": "#s"}
}
},
{
"from": [12.5, 1.375, 0.75],
"to": [12.75, 15.855, 1.125],
"rotation": {"angle": 0, "axis": "y", "origin": [12.625, 8.5, 9.625]},
"faces": {
"north": {"uv": [7.875, 0.145, 8.125, 15], "texture": "#s"},
"east": {"uv": [11.875, 0.145, 12.25, 15], "texture": "#s"},
"south": {"uv": [7.875, 0.145, 8.125, 15], "texture": "#s"},
"west": {"uv": [3.75, 0.145, 4.125, 15], "texture": "#s"}
}
},
{
"from": [12.5, 1.375, 6.75],
"to": [12.75, 15.855, 7.125],
"rotation": {"angle": 0, "axis": "y", "origin": [12.625, 8.5, 9.625]},
"faces": {
"north": {"uv": [7.875, 0.145, 8.125, 15], "texture": "#s"},
"east": {"uv": [5.875, 0.145, 6.25, 15], "texture": "#s"},
"south": {"uv": [7.875, 0.145, 8.125, 15], "texture": "#s"},
"west": {"uv": [9.75, 0.145, 10.125, 15], "texture": "#s"}
}
},
{
"from": [12.5, 1.375, 2.75],
"to": [12.75, 15.855, 3.125],
"rotation": {"angle": 0, "axis": "y", "origin": [12.625, 8.5, 9.625]},
"faces": {
"north": {"uv": [7.875, 0.145, 8.125, 15], "texture": "#s"},
"east": {"uv": [9.875, 0.145, 10.25, 15], "texture": "#s"},
"south": {"uv": [7.875, 0.145, 8.125, 15], "texture": "#s"},
"west": {"uv": [5.75, 0.145, 6.125, 15], "texture": "#s"}
}
}
]
}

View file

@ -0,0 +1,319 @@
{
"parent": "block/block",
"ambientocclusion": false,
"textures": {
"particle": "engineersdecor:blocks/fence/steel_mesh_fence",
"s": "engineersdecor:blocks/fence/steel_mesh_fence",
"t": "engineersdecor:blocks/fence/steel_mesh_top"
},
"elements": [
{
"from": [7.5, 0, 3],
"to": [8.5, 16, 4],
"faces": {
"north": {"uv": [7.5, 0, 8.5, 16], "texture": "#s"},
"east": {"uv": [12, 0, 13, 16], "texture": "#s"},
"south": {"uv": [7.5, 0, 8.5, 16], "texture": "#s"},
"west": {"uv": [3, 0, 4, 16], "texture": "#s"},
"up": {"uv": [7.5, 3, 8.5, 4], "texture": "#t"},
"down": {"uv": [7.5, 12, 8.5, 13], "texture": "#s"}
}
},
{
"from": [7.5, 0, 12],
"to": [8.5, 16, 13],
"faces": {
"north": {"uv": [7.5, 0, 8.5, 16], "texture": "#s"},
"east": {"uv": [3, 0, 4, 16], "texture": "#s"},
"south": {"uv": [7.5, 0, 8.5, 16], "texture": "#s"},
"west": {"uv": [12, 0, 13, 16], "texture": "#s"},
"up": {"uv": [7.5, 12, 8.5, 13], "texture": "#t"},
"down": {"uv": [7.5, 3, 8.5, 4], "texture": "#s"}
}
},
{
"from": [7.5, 15, 4],
"to": [8.5, 16, 12],
"faces": {
"east": {"uv": [4, 0, 12, 1], "texture": "#s"},
"west": {"uv": [4, 0, 12, 1], "texture": "#s"},
"up": {"uv": [7.5, 4, 8.5, 12], "texture": "#t"},
"down": {"uv": [7.5, 4, 8.5, 12], "texture": "#s"}
}
},
{
"from": [7.5, 7, 4],
"to": [8.5, 9, 5],
"faces": {
"east": {"uv": [11, 7, 12, 9], "texture": "#s"},
"south": {"uv": [7.5, 7, 8.5, 9], "texture": "#s"},
"west": {"uv": [4, 7, 5, 9], "texture": "#s"},
"up": {"uv": [7.5, 4, 8.5, 5], "texture": "#t"},
"down": {"uv": [7.5, 11, 8.5, 12], "texture": "#s"}
}
},
{
"from": [7.5, 0, 4],
"to": [8.5, 0.5, 12],
"faces": {
"east": {"uv": [4, 15.5, 12, 16], "texture": "#s"},
"west": {"uv": [4, 15.5, 12, 16], "texture": "#s"},
"up": {"uv": [7.5, 4, 8.5, 12], "texture": "#t"},
"down": {"uv": [7.5, 4, 8.5, 12], "texture": "#s"}
}
},
{
"from": [8, 4.125, 3.5],
"to": [8.125, 4.5, 12.5],
"faces": {
"east": {"uv": [3.5, 11.5, 12.5, 11.875], "texture": "#s"},
"west": {"uv": [3.5, 11.5, 12.5, 11.875], "texture": "#s"},
"up": {"uv": [8, 3.5, 8.125, 12.5], "texture": "#t"},
"down": {"uv": [8, 3.5, 8.125, 12.5], "texture": "#s"}
}
},
{
"from": [7.925, 0, 5.8125],
"to": [8.05, 15.375, 6.1875],
"faces": {
"north": {"uv": [7.95, 0.625, 8.075, 16], "texture": "#s"},
"east": {"uv": [9.8125, 0.625, 10.1875, 16], "texture": "#s"},
"south": {"uv": [7.925, 0.625, 8.05, 16], "texture": "#t"},
"west": {"uv": [5.8125, 0.625, 6.1875, 16], "texture": "#s"}
}
},
{
"from": [8, 8.125, 3.5],
"to": [8.125, 8.5, 12.5],
"faces": {
"east": {"uv": [3.5, 7.5, 12.5, 7.875], "texture": "#s"},
"west": {"uv": [3.5, 7.5, 12.5, 7.875], "texture": "#s"},
"up": {"uv": [8, 3.5, 8.125, 12.5], "texture": "#t"},
"down": {"uv": [8, 3.5, 8.125, 12.5], "texture": "#s"}
}
},
{
"from": [7.925, 0, 9.8125],
"to": [8.05, 15.375, 10.1875],
"faces": {
"north": {"uv": [7.95, 0.625, 8.075, 16], "texture": "#s"},
"east": {"uv": [5.8125, 0.625, 6.1875, 16], "texture": "#s"},
"south": {"uv": [7.925, 0.625, 8.05, 16], "texture": "#t"},
"west": {"uv": [9.8125, 0.625, 10.1875, 16], "texture": "#s"}
}
},
{
"from": [8, 12.125, 3.5],
"to": [8.125, 12.5, 12.5],
"faces": {
"east": {"uv": [3.5, 3.5, 12.5, 3.875], "texture": "#s"},
"west": {"uv": [3.5, 3.5, 12.5, 3.875], "texture": "#s"},
"up": {"uv": [8, 3.5, 8.125, 12.5], "texture": "#t"},
"down": {"uv": [8, 3.5, 8.125, 12.5], "texture": "#s"}
}
},
{
"from": [8, 2.125, 3.5],
"to": [8.125, 2.5, 12.5],
"faces": {
"east": {"uv": [3.5, 13.5, 12.5, 13.875], "texture": "#s"},
"west": {"uv": [3.5, 13.5, 12.5, 13.875], "texture": "#s"},
"up": {"uv": [8, 3.5, 8.125, 12.5], "texture": "#t"},
"down": {"uv": [8, 3.5, 8.125, 12.5], "texture": "#s"}
}
},
{
"from": [7.925, 0, 3.8125],
"to": [8.05, 15.375, 4.1875],
"faces": {
"north": {"uv": [7.95, 0.625, 8.075, 16], "texture": "#s"},
"east": {"uv": [11.8125, 0.625, 12.1875, 16], "texture": "#s"},
"south": {"uv": [7.925, 0.625, 8.05, 16], "texture": "#t"},
"west": {"uv": [3.8125, 0.625, 4.1875, 16], "texture": "#s"}
}
},
{
"from": [8, 6.125, 3.5],
"to": [8.125, 6.5, 12.5],
"faces": {
"east": {"uv": [3.5, 9.5, 12.5, 9.875], "texture": "#s"},
"west": {"uv": [3.5, 9.5, 12.5, 9.875], "texture": "#s"},
"up": {"uv": [8, 3.5, 8.125, 12.5], "texture": "#t"},
"down": {"uv": [8, 3.5, 8.125, 12.5], "texture": "#s"}
}
},
{
"from": [7.925, 0, 7.8125],
"to": [8.05, 15.375, 8.1875],
"faces": {
"north": {"uv": [7.95, 0.625, 8.075, 16], "texture": "#s"},
"east": {"uv": [7.8125, 0.625, 8.1875, 16], "texture": "#s"},
"south": {"uv": [7.925, 0.625, 8.05, 16], "texture": "#t"},
"west": {"uv": [7.8125, 0.625, 8.1875, 16], "texture": "#s"}
}
},
{
"from": [8, 10.125, 3.5],
"to": [8.125, 10.5, 12.5],
"faces": {
"east": {"uv": [3.5, 5.5, 12.5, 5.875], "texture": "#s"},
"west": {"uv": [3.5, 5.5, 12.5, 5.875], "texture": "#s"},
"up": {"uv": [8, 3.5, 8.125, 12.5], "texture": "#t"},
"down": {"uv": [8, 3.5, 8.125, 12.5], "texture": "#s"}
}
},
{
"from": [7.925, 0, 11.8125],
"to": [8.05, 15.375, 12.1875],
"faces": {
"north": {"uv": [7.95, 0.625, 8.075, 16], "texture": "#s"},
"east": {"uv": [3.8125, 0.625, 4.1875, 16], "texture": "#s"},
"south": {"uv": [7.925, 0.625, 8.05, 16], "texture": "#t"},
"west": {"uv": [11.8125, 0.625, 12.1875, 16], "texture": "#s"}
}
},
{
"from": [8, 14.125, 3.5],
"to": [8.125, 14.5, 12.5],
"faces": {
"east": {"uv": [3.5, 1.5, 12.5, 1.875], "texture": "#s"},
"west": {"uv": [3.5, 1.5, 12.5, 1.875], "texture": "#s"},
"up": {"uv": [8, 3.5, 8.125, 12.5], "texture": "#t"},
"down": {"uv": [8, 3.5, 8.125, 12.5], "texture": "#s"}
}
},
{
"from": [7.875, 1.125, 3.5],
"to": [8, 1.5, 12.5],
"faces": {
"east": {"uv": [3.5, 14.5, 12.5, 14.875], "texture": "#s"},
"west": {"uv": [3.5, 14.5, 12.5, 14.875], "texture": "#s"},
"up": {"uv": [7.875, 3.5, 8, 12.5], "texture": "#t"},
"down": {"uv": [7.875, 3.5, 8, 12.5], "texture": "#s"}
}
},
{
"from": [7.875, 5.125, 3.5],
"to": [8, 5.5, 12.5],
"faces": {
"east": {"uv": [3.5, 10.5, 12.5, 10.875], "texture": "#s"},
"west": {"uv": [3.5, 10.5, 12.5, 10.875], "texture": "#s"},
"up": {"uv": [7.875, 3.5, 8, 12.5], "texture": "#t"},
"down": {"uv": [7.875, 3.5, 8, 12.5], "texture": "#s"}
}
},
{
"from": [7.925, 0, 6.8125],
"to": [8.05, 15.375, 7.1875],
"faces": {
"north": {"uv": [7.95, 0.625, 8.075, 16], "texture": "#s"},
"east": {"uv": [8.8125, 0.625, 9.1875, 16], "texture": "#s"},
"south": {"uv": [7.925, 0.625, 8.05, 16], "texture": "#t"},
"west": {"uv": [6.8125, 0.625, 7.1875, 16], "texture": "#s"}
}
},
{
"from": [7.875, 9.125, 3.5],
"to": [8, 9.5, 12.5],
"faces": {
"east": {"uv": [3.5, 6.5, 12.5, 6.875], "texture": "#s"},
"west": {"uv": [3.5, 6.5, 12.5, 6.875], "texture": "#s"},
"up": {"uv": [7.875, 3.5, 8, 12.5], "texture": "#t"},
"down": {"uv": [7.875, 3.5, 8, 12.5], "texture": "#s"}
}
},
{
"from": [7.925, 0, 10.8125],
"to": [8.05, 15.375, 11.1875],
"faces": {
"north": {"uv": [7.95, 0.625, 8.075, 16], "texture": "#s"},
"east": {"uv": [4.8125, 0.625, 5.1875, 16], "texture": "#s"},
"south": {"uv": [7.925, 0.625, 8.05, 16], "texture": "#t"},
"west": {"uv": [10.8125, 0.625, 11.1875, 16], "texture": "#s"}
}
},
{
"from": [7.875, 13.125, 3.5],
"to": [8, 13.5, 12.5],
"faces": {
"east": {"uv": [3.5, 2.5, 12.5, 2.875], "texture": "#s"},
"west": {"uv": [3.5, 2.5, 12.5, 2.875], "texture": "#s"},
"up": {"uv": [7.875, 3.5, 8, 12.5], "texture": "#t"},
"down": {"uv": [7.875, 3.5, 8, 12.5], "texture": "#s"}
}
},
{
"from": [7.875, 3.125, 3.5],
"to": [8, 3.5, 12.5],
"faces": {
"east": {"uv": [3.5, 12.5, 12.5, 12.875], "texture": "#s"},
"west": {"uv": [3.5, 12.5, 12.5, 12.875], "texture": "#s"},
"up": {"uv": [7.875, 3.5, 8, 12.5], "texture": "#t"},
"down": {"uv": [7.875, 3.5, 8, 12.5], "texture": "#s"}
}
},
{
"from": [7.925, 0, 4.8125],
"to": [8.05, 15.375, 5.1875],
"faces": {
"north": {"uv": [7.95, 0.625, 8.075, 16], "texture": "#s"},
"east": {"uv": [10.8125, 0.625, 11.1875, 16], "texture": "#s"},
"south": {"uv": [7.925, 0.625, 8.05, 16], "texture": "#t"},
"west": {"uv": [4.8125, 0.625, 5.1875, 16], "texture": "#s"}
}
},
{
"from": [7.875, 7.125, 3.5],
"to": [8, 7.5, 12.5],
"faces": {
"east": {"uv": [3.5, 8.5, 12.5, 8.875], "texture": "#s"},
"west": {"uv": [3.5, 8.5, 12.5, 8.875], "texture": "#s"},
"up": {"uv": [7.875, 3.5, 8, 12.5], "texture": "#t"},
"down": {"uv": [7.875, 3.5, 8, 12.5], "texture": "#s"}
}
},
{
"from": [7.925, 0, 8.8125],
"to": [8.05, 15.375, 9.1875],
"faces": {
"north": {"uv": [7.95, 0.625, 8.075, 16], "texture": "#s"},
"east": {"uv": [6.8125, 0.625, 7.1875, 16], "texture": "#s"},
"south": {"uv": [7.925, 0.625, 8.05, 16], "texture": "#t"},
"west": {"uv": [8.8125, 0.625, 9.1875, 16], "texture": "#s"}
}
},
{
"from": [7.875, 11.125, 3.5],
"to": [8, 11.5, 12.5],
"faces": {
"east": {"uv": [3.5, 4.5, 12.5, 4.875], "texture": "#s"},
"west": {"uv": [3.5, 4.5, 12.5, 4.875], "texture": "#s"},
"up": {"uv": [7.875, 3.5, 8, 12.5], "texture": "#t"},
"down": {"uv": [7.875, 3.5, 8, 12.5], "texture": "#s"}
}
}
],
"display": {
"thirdperson_righthand": {
"rotation": [9, 35, 0],
"translation": [0, 0, -1],
"scale": [0.4, 0.4, 0.4]
},
"firstperson_righthand": {
"scale": [0.4, 0.4, 0.4]
},
"ground": {
"translation": [0, 1.5, 0],
"scale": [0.3, 0.3, 0.3]
},
"gui": {
"rotation": [30, 135, 0],
"translation": [-0.25, 0.5, 0],
"scale": [0.7, 0.7, 0.7]
},
"fixed": {
"rotation": [0, 90, 0],
"translation": [0, 0, -0.25]
}
}
}

View file

@ -0,0 +1,220 @@
{
"textures": {
"p": "engineersdecor:blocks/fence/steel_mesh_pole_side",
"t": "engineersdecor:blocks/fence/steel_mesh_top",
"particle": "engineersdecor:blocks/fence/steel_mesh_fence",
"s": "engineersdecor:blocks/fence/steel_mesh_fence"
},
"elements": [
{
"from": [3.125, 12.625, 9.4375],
"to": [12.8125, 12.98, 9.625],
"rotation": {"angle": 0, "axis": "y", "origin": [3.375, 7.5, 9.625]},
"faces": {
"north": {"uv": [0.0625, 2.02, 15.5, 2.375], "texture": "#s"},
"south": {"uv": [0.5, 2.02, 15.9375, 2.375], "texture": "#s"},
"up": {"uv": [7.8125, 0.0625, 8, 15.5], "rotation": 90, "texture": "#s"},
"down": {"uv": [7.8125, 0.5, 8, 15.9375], "rotation": 270, "texture": "#s"}
}
},
{
"from": [3.125, 8.625, 9.4375],
"to": [12.8125, 8.98, 9.625],
"rotation": {"angle": 0, "axis": "y", "origin": [3.375, 7.5, 9.625]},
"faces": {
"north": {"uv": [0.0625, 6.02, 15.5, 6.375], "texture": "#s"},
"south": {"uv": [0.5, 6.02, 15.9375, 6.375], "texture": "#s"},
"up": {"uv": [7.8125, 0.0625, 8, 15.5], "rotation": 90, "texture": "#s"},
"down": {"uv": [7.8125, 0.5, 8, 15.9375], "rotation": 270, "texture": "#s"}
}
},
{
"from": [3.125, 4.625, 9.4375],
"to": [12.8125, 4.98, 9.625],
"rotation": {"angle": 0, "axis": "y", "origin": [3.375, 7.5, 9.625]},
"faces": {
"north": {"uv": [0.0625, 10.02, 15.5, 10.375], "texture": "#s"},
"south": {"uv": [0.5, 10.02, 15.9375, 10.375], "texture": "#s"},
"up": {"uv": [7.8125, 0.0625, 8, 15.5], "rotation": 90, "texture": "#s"},
"down": {"uv": [7.8125, 0.5, 8, 15.9375], "rotation": 270, "texture": "#s"}
}
},
{
"from": [3.125, 0.625, 9.4375],
"to": [12.8125, 0.98, 9.625],
"rotation": {"angle": 0, "axis": "y", "origin": [3.375, 7.5, 9.625]},
"faces": {
"north": {"uv": [0.0625, 14.02, 15.5, 14.375], "texture": "#s"},
"south": {"uv": [0.5, 14.02, 15.9375, 14.375], "texture": "#s"},
"up": {"uv": [7.8125, 0.0625, 8, 15.5], "rotation": 90, "texture": "#s"},
"down": {"uv": [7.8125, 0.5, 8, 15.9375], "rotation": 270, "texture": "#s"}
}
},
{
"from": [3.125, 10.625, 9.625],
"to": [12.8125, 10.98, 9.8125],
"rotation": {"angle": 0, "axis": "y", "origin": [3.375, 7.5, 9.625]},
"faces": {
"north": {"uv": [0.0625, 4.02, 15.5, 4.375], "texture": "#s"},
"south": {"uv": [0.5, 4.02, 15.9375, 4.375], "texture": "#s"},
"up": {"uv": [8, 0.0625, 8.1875, 15.5], "rotation": 90, "texture": "#s"},
"down": {"uv": [8, 0.5, 8.1875, 15.9375], "rotation": 270, "texture": "#s"}
}
},
{
"from": [3.5, 6.625, 9.625],
"to": [12.9375, 6.98, 9.8125],
"rotation": {"angle": 0, "axis": "y", "origin": [3.375, 7.5, 9.625]},
"faces": {
"north": {"uv": [0.0625, 8.02, 15.5, 8.375], "texture": "#s"},
"south": {"uv": [0.5, 8.02, 15.9375, 8.375], "texture": "#s"},
"up": {"uv": [8, 0.0625, 8.1875, 15.5], "rotation": 90, "texture": "#s"},
"down": {"uv": [8, 0.5, 8.1875, 15.9375], "rotation": 270, "texture": "#s"}
}
},
{
"from": [3.5, 2.625, 9.625],
"to": [12.9375, 2.98, 9.8125],
"rotation": {"angle": 0, "axis": "y", "origin": [3.375, 7.5, 9.625]},
"faces": {
"north": {"uv": [0.0625, 12.02, 15.5, 12.375], "texture": "#s"},
"south": {"uv": [0.5, 12.02, 15.9375, 12.375], "texture": "#s"},
"up": {"uv": [8, 0.0625, 8.1875, 15.5], "rotation": 90, "texture": "#s"},
"down": {"uv": [8, 0.5, 8.1875, 15.9375], "rotation": 270, "texture": "#s"}
}
},
{
"from": [12.25, 0, 9.25],
"to": [13, 15, 10],
"rotation": {"angle": 0, "axis": "y", "origin": [3.375, 7.5, 9.625]},
"faces": {
"north": {"uv": [1.5, 0, 2.25, 15], "texture": "#s"},
"south": {"uv": [13.75, 0, 14.5, 15], "texture": "#s"},
"west": {"uv": [7.625, 0, 8.375, 15], "texture": "#s"},
"up": {"uv": [7.625, 1.5, 8.375, 2.25], "rotation": 90, "texture": "#s"}
}
},
{
"from": [3.75, 14, 9.25],
"to": [12.25, 15, 10],
"rotation": {"angle": 0, "axis": "y", "origin": [3.375, 7.5, 9.625]},
"faces": {
"north": {"uv": [2.25, 0, 13.75, 1], "texture": "#s"},
"south": {"uv": [2.25, 0, 13.75, 1], "texture": "#s"},
"up": {"uv": [7.625, 2.25, 8.375, 13.75], "rotation": 90, "texture": "#s"},
"down": {"uv": [7.625, 2.25, 8.375, 13.75], "rotation": 270, "texture": "#s"}
}
},
{
"from": [3, 0, 9.25],
"to": [3.75, 15, 10],
"rotation": {"angle": 0, "axis": "y", "origin": [3.375, 7.5, 9.625]},
"faces": {
"north": {"uv": [13.75, 0, 14.5, 15], "texture": "#s"},
"east": {"uv": [7.625, 0, 8.375, 15], "texture": "#s"},
"south": {"uv": [1.5, 0, 2.25, 15], "texture": "#s"},
"up": {"uv": [7.625, 13.75, 8.375, 14.5], "rotation": 90, "texture": "#s"}
}
},
{
"from": [13, 0, 6.5],
"to": [16, 16, 9.5],
"faces": {
"north": {"uv": [6.5, 0, 9.5, 16], "texture": "#p"},
"east": {"uv": [6.5, 0, 9.5, 16], "texture": "#p"},
"south": {"uv": [6.5, 0, 9.5, 16], "texture": "#p"},
"west": {"uv": [6.5, 0, 9.5, 16], "texture": "#p"},
"up": {"uv": [6.5, 6.5, 9.5, 9.5], "rotation": 90, "texture": "#t"}
}
},
{
"from": [0, 0, 6.5],
"to": [3, 16, 9.5],
"rotation": {"angle": 0, "axis": "y", "origin": [-5, 8, 8]},
"faces": {
"north": {"uv": [6.5, 0, 9.5, 16], "texture": "#p"},
"east": {"uv": [6.5, 0, 9.5, 16], "texture": "#p"},
"south": {"uv": [6.5, 0, 9.5, 16], "texture": "#p"},
"west": {"uv": [6.5, 0, 9.5, 16], "texture": "#p"},
"up": {"uv": [6.5, 6.5, 9.5, 9.5], "rotation": 90, "texture": "#t"}
}
},
{
"from": [0.5, 0, 9.5],
"to": [3, 16, 10.5],
"rotation": {"angle": 0, "axis": "y", "origin": [-5, 8, 11]},
"faces": {
"east": {"uv": [6, 0, 7, 16], "texture": "#p"},
"south": {"uv": [0, 0, 3, 16], "texture": "#p"},
"west": {"uv": [10, 0, 11, 16], "texture": "#p"},
"up": {"uv": [6, 12, 9, 13], "texture": "#t"}
}
},
{
"from": [13, 0, 9.5],
"to": [15.5, 16, 10.5],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 11]},
"faces": {
"east": {"uv": [6, 0, 7, 16], "texture": "#p"},
"south": {"uv": [0, 0, 3, 16], "texture": "#p"},
"west": {"uv": [10, 0, 11, 16], "texture": "#p"},
"up": {"uv": [6, 12, 9, 13], "texture": "#t"}
}
},
{
"from": [11.75, 0, 9.5],
"to": [12.125, 14.855, 9.75],
"rotation": {"angle": 0, "axis": "y", "origin": [3.375, 7.5, 9.625]},
"faces": {
"north": {"uv": [3.875, 0.145, 4.25, 15], "texture": "#s"},
"east": {"uv": [7.875, 0.145, 8.125, 15], "texture": "#s"},
"south": {"uv": [11.75, 0.145, 12.125, 15], "texture": "#s"},
"west": {"uv": [7.875, 0.145, 8.125, 15], "texture": "#s"}
}
},
{
"from": [7.75, 0, 9.5],
"to": [8.125, 14.855, 9.75],
"rotation": {"angle": 0, "axis": "y", "origin": [3.375, 7.5, 9.625]},
"faces": {
"north": {"uv": [7.875, 0.145, 8.25, 15], "texture": "#s"},
"east": {"uv": [7.875, 0.145, 8.125, 15], "texture": "#s"},
"south": {"uv": [7.75, 0.145, 8.125, 15], "texture": "#s"},
"west": {"uv": [7.875, 0.145, 8.125, 15], "texture": "#s"}
}
},
{
"from": [3.75, 0, 9.5],
"to": [4.125, 14.855, 9.75],
"rotation": {"angle": 0, "axis": "y", "origin": [3.375, 7.5, 9.625]},
"faces": {
"north": {"uv": [11.875, 0.145, 12.25, 15], "texture": "#s"},
"east": {"uv": [7.875, 0.145, 8.125, 15], "texture": "#s"},
"south": {"uv": [3.75, 0.145, 4.125, 15], "texture": "#s"},
"west": {"uv": [7.875, 0.145, 8.125, 15], "texture": "#s"}
}
},
{
"from": [9.75, 0, 9.5],
"to": [10.125, 14.855, 9.75],
"rotation": {"angle": 0, "axis": "y", "origin": [3.375, 7.5, 9.625]},
"faces": {
"north": {"uv": [5.875, 0.145, 6.25, 15], "texture": "#s"},
"east": {"uv": [7.875, 0.145, 8.125, 15], "texture": "#s"},
"south": {"uv": [9.75, 0.145, 10.125, 15], "texture": "#s"},
"west": {"uv": [7.875, 0.145, 8.125, 15], "texture": "#s"}
}
},
{
"from": [5.75, 0, 9.5],
"to": [6.125, 14.855, 9.75],
"rotation": {"angle": 0, "axis": "y", "origin": [3.375, 7.5, 9.625]},
"faces": {
"north": {"uv": [9.875, 0.145, 10.25, 15], "texture": "#s"},
"east": {"uv": [7.875, 0.145, 8.125, 15], "texture": "#s"},
"south": {"uv": [5.75, 0.145, 6.125, 15], "texture": "#s"},
"west": {"uv": [7.875, 0.145, 8.125, 15], "texture": "#s"}
}
}
]
}

View file

@ -0,0 +1,222 @@
{
"textures": {
"p": "engineersdecor:blocks/fence/steel_mesh_pole_side",
"t": "engineersdecor:blocks/fence/steel_mesh_top",
"particle": "engineersdecor:blocks/fence/steel_mesh_fence",
"s": "engineersdecor:blocks/fence/steel_mesh_fence"
},
"elements": [
{
"from": [12.625, 12.625, 0.125],
"to": [12.8125, 12.98, 9.8125],
"rotation": {"angle": 0, "axis": "y", "origin": [12.625, 7.5, 9.625]},
"faces": {
"east": {"uv": [0.0625, 2.02, 15.5, 2.375], "texture": "#s"},
"west": {"uv": [0.5, 2.02, 15.9375, 2.375], "texture": "#s"},
"up": {"uv": [7.8125, 0.0625, 8, 15.5], "rotation": 180, "texture": "#s"},
"down": {"uv": [7.8125, 0.5, 8, 15.9375], "rotation": 180, "texture": "#s"}
}
},
{
"from": [12.625, 8.625, 0.125],
"to": [12.8125, 8.98, 9.8125],
"rotation": {"angle": 0, "axis": "y", "origin": [12.625, 7.5, 9.625]},
"faces": {
"east": {"uv": [0.0625, 6.02, 15.5, 6.375], "texture": "#s"},
"west": {"uv": [0.5, 6.02, 15.9375, 6.375], "texture": "#s"},
"up": {"uv": [7.8125, 0.0625, 8, 15.5], "rotation": 180, "texture": "#s"},
"down": {"uv": [7.8125, 0.5, 8, 15.9375], "rotation": 180, "texture": "#s"}
}
},
{
"from": [12.625, 4.625, 0.125],
"to": [12.8125, 4.98, 9.8125],
"rotation": {"angle": 0, "axis": "y", "origin": [12.625, 7.5, 9.625]},
"faces": {
"east": {"uv": [0.0625, 10.02, 15.5, 10.375], "texture": "#s"},
"west": {"uv": [0.5, 10.02, 15.9375, 10.375], "texture": "#s"},
"up": {"uv": [7.8125, 0.0625, 8, 15.5], "rotation": 180, "texture": "#s"},
"down": {"uv": [7.8125, 0.5, 8, 15.9375], "rotation": 180, "texture": "#s"}
}
},
{
"from": [12.625, 0.625, 0.125],
"to": [12.8125, 0.98, 9.8125],
"rotation": {"angle": 0, "axis": "y", "origin": [12.625, 7.5, 9.625]},
"faces": {
"east": {"uv": [0.0625, 14.02, 15.5, 14.375], "texture": "#s"},
"west": {"uv": [0.5, 14.02, 15.9375, 14.375], "texture": "#s"},
"up": {"uv": [7.8125, 0.0625, 8, 15.5], "rotation": 180, "texture": "#s"},
"down": {"uv": [7.8125, 0.5, 8, 15.9375], "rotation": 180, "texture": "#s"}
}
},
{
"from": [12.4375, 10.625, 0.125],
"to": [12.625, 10.98, 9.8125],
"rotation": {"angle": 0, "axis": "y", "origin": [12.625, 7.5, 9.625]},
"faces": {
"east": {"uv": [0.0625, 4.02, 15.5, 4.375], "texture": "#s"},
"west": {"uv": [0.5, 4.02, 15.9375, 4.375], "texture": "#s"},
"up": {"uv": [8, 0.0625, 8.1875, 15.5], "rotation": 180, "texture": "#s"},
"down": {"uv": [8, 0.5, 8.1875, 15.9375], "rotation": 180, "texture": "#s"}
}
},
{
"from": [12.4375, 6.625, 0.5],
"to": [12.625, 6.98, 9.9375],
"rotation": {"angle": 0, "axis": "y", "origin": [12.625, 7.5, 9.625]},
"faces": {
"east": {"uv": [0.0625, 8.02, 15.5, 8.375], "texture": "#s"},
"west": {"uv": [0.5, 8.02, 15.9375, 8.375], "texture": "#s"},
"up": {"uv": [8, 0.0625, 8.1875, 15.5], "rotation": 180, "texture": "#s"},
"down": {"uv": [8, 0.5, 8.1875, 15.9375], "rotation": 180, "texture": "#s"}
}
},
{
"from": [12.4375, 2.625, 0.5],
"to": [12.625, 2.98, 9.9375],
"rotation": {"angle": 0, "axis": "y", "origin": [12.625, 7.5, 9.625]},
"faces": {
"east": {"uv": [0.0625, 12.02, 15.5, 12.375], "texture": "#s"},
"west": {"uv": [0.5, 12.02, 15.9375, 12.375], "texture": "#s"},
"up": {"uv": [8, 0.0625, 8.1875, 15.5], "rotation": 180, "texture": "#s"},
"down": {"uv": [8, 0.5, 8.1875, 15.9375], "rotation": 180, "texture": "#s"}
}
},
{
"from": [12.25, 0, 9.25],
"to": [13, 15, 10],
"rotation": {"angle": 0, "axis": "y", "origin": [12.625, 7.5, 9.625]},
"faces": {
"north": {"uv": [7.625, 0, 8.375, 15], "texture": "#s"},
"east": {"uv": [1.5, 0, 2.25, 15], "texture": "#s"},
"south": {"uv": [7.625, 0, 8.375, 15], "texture": "#s"},
"west": {"uv": [13.75, 0, 14.5, 15], "texture": "#s"},
"up": {"uv": [7.625, 1.5, 8.375, 2.25], "rotation": 180, "texture": "#s"}
}
},
{
"from": [12.25, 14, 0.75],
"to": [13, 15, 9.25],
"rotation": {"angle": 0, "axis": "y", "origin": [12.625, 7.5, 9.625]},
"faces": {
"east": {"uv": [2.25, 0, 10.75, 1], "texture": "#s"},
"west": {"uv": [2.25, 0, 10.75, 1], "texture": "#s"},
"up": {"uv": [7.625, 2.25, 8.375, 10.75], "rotation": 180, "texture": "#s"},
"down": {"uv": [7.625, 2.25, 8.375, 13.75], "rotation": 180, "texture": "#s"}
}
},
{
"from": [12.25, 0, 0],
"to": [13, 15, 0.75],
"rotation": {"angle": 0, "axis": "y", "origin": [12.625, 7.5, 9.625]},
"faces": {
"north": {"uv": [7.625, 0, 8.375, 15], "texture": "#s"},
"east": {"uv": [13.75, 0, 14.5, 15], "texture": "#s"},
"south": {"uv": [7.625, 0, 8.375, 15], "texture": "#s"},
"west": {"uv": [1.5, 0, 2.25, 15], "texture": "#s"},
"up": {"uv": [7.625, 13.75, 8.375, 14.5], "rotation": 180, "texture": "#s"}
}
},
{
"from": [13, 0, 6.5],
"to": [16, 16, 9.5],
"faces": {
"north": {"uv": [6.5, 0, 9.5, 16], "texture": "#p"},
"east": {"uv": [6.5, 0, 9.5, 16], "texture": "#p"},
"south": {"uv": [6.5, 0, 9.5, 16], "texture": "#p"},
"west": {"uv": [6.5, 0, 9.5, 16], "texture": "#p"},
"up": {"uv": [6.5, 6.5, 9.5, 9.5], "rotation": 90, "texture": "#t"}
}
},
{
"from": [0, 0, 6.5],
"to": [3, 16, 9.5],
"rotation": {"angle": 0, "axis": "y", "origin": [-5, 8, 8]},
"faces": {
"north": {"uv": [6.5, 0, 9.5, 16], "texture": "#p"},
"east": {"uv": [6.5, 0, 9.5, 16], "texture": "#p"},
"south": {"uv": [6.5, 0, 9.5, 16], "texture": "#p"},
"west": {"uv": [6.5, 0, 9.5, 16], "texture": "#p"},
"up": {"uv": [6.5, 6.5, 9.5, 9.5], "rotation": 90, "texture": "#t"}
}
},
{
"from": [0.5, 0, 9.5],
"to": [3, 16, 10.5],
"rotation": {"angle": 0, "axis": "y", "origin": [-5, 8, 11]},
"faces": {
"east": {"uv": [6, 0, 7, 16], "texture": "#p"},
"south": {"uv": [0, 0, 3, 16], "texture": "#p"},
"west": {"uv": [10, 0, 11, 16], "texture": "#p"},
"up": {"uv": [6, 12, 9, 13], "texture": "#t"}
}
},
{
"from": [13, 0, 9.5],
"to": [15.5, 16, 10.5],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 11]},
"faces": {
"east": {"uv": [6, 0, 7, 16], "texture": "#p"},
"south": {"uv": [0, 0, 3, 16], "texture": "#p"},
"west": {"uv": [10, 0, 11, 16], "texture": "#p"},
"up": {"uv": [6, 12, 9, 13], "texture": "#t"}
}
},
{
"from": [12.5, 0, 8.75],
"to": [12.75, 14.855, 9.125],
"rotation": {"angle": 0, "axis": "y", "origin": [12.625, 7.5, 9.625]},
"faces": {
"north": {"uv": [7.875, 0.145, 8.125, 15], "texture": "#s"},
"east": {"uv": [3.875, 0.145, 4.25, 15], "texture": "#s"},
"south": {"uv": [7.875, 0.145, 8.125, 15], "texture": "#s"},
"west": {"uv": [11.75, 0.145, 12.125, 15], "texture": "#s"}
}
},
{
"from": [12.5, 0, 4.75],
"to": [12.75, 14.855, 5.125],
"rotation": {"angle": 0, "axis": "y", "origin": [12.625, 7.5, 9.625]},
"faces": {
"north": {"uv": [7.875, 0.145, 8.125, 15], "texture": "#s"},
"east": {"uv": [7.875, 0.145, 8.25, 15], "texture": "#s"},
"south": {"uv": [7.875, 0.145, 8.125, 15], "texture": "#s"},
"west": {"uv": [7.75, 0.145, 8.125, 15], "texture": "#s"}
}
},
{
"from": [12.5, 0, 0.75],
"to": [12.75, 14.855, 1.125],
"rotation": {"angle": 0, "axis": "y", "origin": [12.625, 7.5, 9.625]},
"faces": {
"north": {"uv": [7.875, 0.145, 8.125, 15], "texture": "#s"},
"east": {"uv": [11.875, 0.145, 12.25, 15], "texture": "#s"},
"south": {"uv": [7.875, 0.145, 8.125, 15], "texture": "#s"},
"west": {"uv": [3.75, 0.145, 4.125, 15], "texture": "#s"}
}
},
{
"from": [12.5, 0, 6.75],
"to": [12.75, 14.855, 7.125],
"rotation": {"angle": 0, "axis": "y", "origin": [12.625, 7.5, 9.625]},
"faces": {
"north": {"uv": [7.875, 0.145, 8.125, 15], "texture": "#s"},
"east": {"uv": [5.875, 0.145, 6.25, 15], "texture": "#s"},
"south": {"uv": [7.875, 0.145, 8.125, 15], "texture": "#s"},
"west": {"uv": [9.75, 0.145, 10.125, 15], "texture": "#s"}
}
},
{
"from": [12.5, 0, 2.75],
"to": [12.75, 14.855, 3.125],
"rotation": {"angle": 0, "axis": "y", "origin": [12.625, 7.5, 9.625]},
"faces": {
"north": {"uv": [7.875, 0.145, 8.125, 15], "texture": "#s"},
"east": {"uv": [9.875, 0.145, 10.25, 15], "texture": "#s"},
"south": {"uv": [7.875, 0.145, 8.125, 15], "texture": "#s"},
"west": {"uv": [5.75, 0.145, 6.125, 15], "texture": "#s"}
}
}
]
}

View file

@ -1,8 +1,8 @@
{
"parent": "block/cube",
"textures": {
"s": "engineersdecor:blocks/furniture/steel_table_side_texture",
"particle": "engineersdecor:blocks/furniture/steel_table_side_texture",
"s": "engineersdecor:blocks/furniture/steel_table_side_texture",
"t": "engineersdecor:blocks/furniture/steel_table_top_texture"
},
"elements": [
@ -173,15 +173,28 @@
}
],
"display": {
"thirdperson_righthand": {
"rotation": [66, 0, 0],
"translation": [0.25, 0, -2.75],
"scale": [0.3, 0.3, 0.3]
},
"firstperson_righthand": {
"rotation": [-4, -1, 58],
"translation": [2.5, 0.25, 1.75],
"scale": [0.3, 0.3, 0.3]
},
"ground": {
"translation": [0, 1.75, 0],
"translation": [0, 1.75, 0],
"scale": [0.2, 0.2, 0.2]
},
"gui": {
"rotation": [30, 225, 0],
"translation": [0, -2, 0],
"scale": [0.625, 0.625, 0.625]
},
"fixed": {
"rotation": [-90, 0, 1],
"translation": [0, 0.25, 3.25],
"scale": [0.5, 0.5, 0.5]
}
}

View file

@ -0,0 +1,77 @@
{
"parent": "block/block",
"textures": {
"f": "engineersdecor:blocks/misc/labeled_crate_front_texture",
"particle": "engineersdecor:blocks/misc/labeled_crate_side_texture",
"s": "engineersdecor:blocks/misc/labeled_crate_side_texture"
},
"elements": [
{
"from": [0, 7, 0],
"to": [16, 16, 0.25],
"faces": {
"north": {"texture": "#f"},
"east": {"texture": "#s"},
"west": {"texture": "#s"},
"up": {"texture": "#s"},
"down": {"texture": "#s"}
}
},
{
"from": [0, 0, 0.25],
"to": [16, 16, 16],
"faces": {
"north": {"texture": "#f"},
"east": {"texture": "#s"},
"south": {"texture": "#s"},
"west": {"texture": "#s"},
"up": {"texture": "#s"},
"down": {"texture": "#s"}
}
},
{
"from": [7, 0, 0],
"to": [16, 7, 0.25],
"faces": {
"north": {"texture": "#f"},
"east": {"texture": "#s"},
"south": {"texture": "#s"},
"west": {"texture": "#s"},
"down": {"texture": "#s"}
}
},
{
"from": [0, 0, 0],
"to": [1, 7, 0.375],
"faces": {
"north": {"texture": "#f"},
"east": {"texture": "#s"},
"south": {"texture": "#s"},
"west": {"texture": "#s"},
"down": {"texture": "#s"}
}
},
{
"from": [1, 0, 0],
"to": [7, 1, 0.25],
"faces": {
"north": {"texture": "#f"},
"up": {"texture": "#s"},
"down": {"texture": "#s"}
}
}
],
"display": {
"ground": {
"translation": [0, 1.75, 0],
"scale": [0.2, 0.2, 0.2]
},
"gui": {
"rotation": [30, 225, 0],
"scale": [0.625, 0.625, 0.625]
},
"fixed": {
"scale": [0.5, 0.5, 0.5]
}
}
}

View file

@ -0,0 +1,34 @@
{
"parent": "item/handheld",
"textures": {
"layer0": "engineersdecor:item/manual"
},
"display": {
"thirdperson_righthand": {
"rotation": [9, -23, -105],
"translation": [-2.5, 0.75, 0],
"scale": [0.4, 0.4, 0.4]
},
"thirdperson_lefthand": {
"rotation": [78, 90, 35],
"translation": [0, 0.5, -1.75],
"scale": [0.4, 0.4, 0.4]
},
"firstperson_righthand": {
"rotation": [-21, -90, 15],
"translation": [0.88, 2.45, 1.13],
"scale": [0.68, 0.68, 0.68]
},
"firstperson_lefthand": {
"rotation": [4, 90, -15],
"translation": [1.13, 3.2, 1.13],
"scale": [0.68, 0.68, 0.68]
},
"ground": {
"scale": [0.4, 0.4, 0.4]
},
"gui": {
"translation": [0, 0.5, 0]
}
}
}

View file

@ -0,0 +1 @@
{ "parent": "engineersdecor:block/fence/steel_mesh_fence_gate_inventory" }

View file

@ -0,0 +1,9 @@
{
"name": "Engineer's Decor",
"creative_tab": "tabengineersdecor",
"subtitle": "Reference manual",
"version": 0,
"model": "engineersdecor:manual",
"show_progress": false,
"landing_text": "Tip in advance: To get a short tooltip help text for a block or device, press the CONTRTOL and SHIFT keys at the same time while hovering. That way you do not need to carry this heavy manual with you all the time. The more detailed descriptions in this book are helpful if the features are new for you, or if you like to read up about background aspects."
}

View file

@ -0,0 +1,6 @@
{
"name": "Automation",
"description": "Devices for nice looking contraptions and factory automation support.",
"icon": "engineersdecor:small_block_breaker",
"sortnum": 6000
}

View file

@ -0,0 +1,6 @@
{
"name": "Building",
"description": "Blocks for the exterior and basic interior architecture of your factory or home.",
"icon": "engineersdecor:clinker_brick_block",
"sortnum": 1000
}

View file

@ -0,0 +1,6 @@
{
"name": "Cosmetic",
"description": "Cosmetic blocks to fill empty and plain halls with life and accentuation.",
"icon": "engineersdecor:sign_hotwire",
"sortnum": 3000
}

View file

@ -0,0 +1,6 @@
{
"name": "Crafting and Smelting",
"description": "Getting things build, cooked, smelted or liquified. ",
"icon": "engineersdecor:treated_wood_crafting_table",
"sortnum": 5000
}

View file

@ -0,0 +1,6 @@
{
"name": "Fluidics",
"description": "Devices helping to deal with fluids.",
"icon": "engineersdecor:straight_pipe_valve_redstone",
"sortnum": 7000
}

View file

@ -0,0 +1,6 @@
{
"name": "Illumination",
"description": "Let's shed some light on the situation.",
"icon": "engineersdecor:iron_inset_light",
"sortnum": 4000
}

View file

@ -0,0 +1,6 @@
{
"name": "Power",
"description": "Devices related to RF power.",
"icon": "engineersdecor:small_solar_panel",
"sortnum": 8000
}

View file

@ -0,0 +1,6 @@
{
"name": "Structural",
"description": "The following chapters contain information about blocks for large and small scale structural integrity.",
"icon": "engineersdecor:thick_steel_pole_head",
"sortnum": 2000
}

View file

@ -0,0 +1,58 @@
{
"name": "Factory Dropper",
"icon": "engineersdecor:factory_dropper",
"category": "automation",
"sortnum": 6020,
"pages": [
{
"type": "spotlight",
"title": "Factory Dropper",
"item": "engineersdecor:factory_dropper",
"text": "A device to accurately drop items, suitable for automation contraptions.$(br)Metal shutters in front of the ejector protect the interior, and open only when $(t:... that is a visual indicator for you, read on ...)ready to drop$() or dropping from one of the twelve internal storage slots. After ejecting, the stack selection advances to the next suitable slot (so called $(o)round$()"
},
{
"type": "text",
"text": "$(o)robin$() operation - in the GUI the current slot is marked with a red frame). Three filter slots (stack comparators) facilitate advanced automation.$(br)The dropper can be placed in all directions, where sneak-clicking flips the placement orientation.$(br)By default the device works like a cobblestone Dropper, spitting out one item when seeing $(t: that is off->on, or better said zero to nonzero)a rising edge of the external Redstone signal$(). This behavior can be tuned, amongst other features, in the GUI.$(br)"
},
{
"type": "text",
"text": "$(l)Positioning$()$(br)You can adjust angle and drop force with $(t: ... technical term, means that the result will stay the same quite accurately, even if the value may not be precisely what it should be - that would be called accuracy then. In other words, the dropper will keep dropping where it dropped the first time.)high repeatability$(). Looking at the front face of the dropper, you see a x-y coordinate system (a red and a green line). The same is drawn in the top right area of the GUI. Clicking there will move the crosshair away from the centre, changing the spit angle from -45° to +45° left/right and up/down. At the left of the coordinate system, a spring is shown as vertical slider, which adjusts the prestress and thus the drop force."
},
{
"type": "text",
"text": "$(l)Stack Count$()$(br)The horizontal slider under the position controls (marked with 1 to 5 dots above) is used to set the number of items that are dropped simultaneously. Range is from 1 to 32.$(br)If a stack does not have that many items, it will be skipped. This is useful if you need an exact amount of items, e.g. for compressing in a $(o)IE Metal Press$(), or for in-world crafting contraptions."
},
{
"type": "text",
"text": "$(l)Drop Delay / Interval$()$(br)The horizontal slider below the stack adjustment allows to set a cool-down in 0.1s steps (delay after ejecting; the icons shall represent a dog and a snail for fast -> slow).$(br2)This can be useful if the contraption or device, which you feed with the dropped items, needs some processing time - means preventing item spam or despawning."
},
{
"type": "text",
"text": "$(l)Filter Slots$()$(br)These slots compare the stacks that you place in them with all stacks in the storage. If the item is the same, and the stack in the storage is at least as big as the one in the filter, then the filter output will be ON, and the slot LED is lit green. If no stack or a too small stack is found in the storage, then the filter slot signal is OFF, and the slot LED red. If you leave a filter slot empty, then the LED is unlit, and the output is ignored."
},
{
"type": "text",
"text": "$(l)Redstone Controls$()$(br)In the lower right area of the GUI, there is a red LED (with down-arrow) and three circuit elements wired up. The LED is lit when the device sees an external Redstone signal, and can also be used as test-trigger button. Below are two logic gates, and one trigger control logic (right).$(br)Let us start at the end of the circuit: If you click at the trigger control, the $(t: The symbols are technical representations, showing what happens if you attach a lever and switch it on. The one curve goes up with the lever signal and stays there - called STEP. The other one also rises with the lever signal, but after a short time falls again by itself, although the lever is still on - that's a PULSE.)symbol changes between $(o)pulse mode$() and $(o)continuous mode$()."
},
{
"type": "text",
"text": "The trigger control is fed by the output of a logic gate (in the middle). Click it to switch between $(t:These icons are actually the official [IEC] symbols in schematics. AND means all of the inputs have to be ON. OR means only one of them has to be ON, no matter which one, or more than one. That's why the symbol is '>=1'.)$(o)AND ('&') and OR ('>=1') logic$()$(). One of the inputs comes from the external Redstone, the other one from the filters. Lastly, you can do the same for the three wires coming from the filter slots. $(o)&$(): All of them must be on, $(o)>=1$(): At least one of them must be on.$(br2)What does this mean now? Well, you can drop items triggered or continuously. You can also"
},
{
"type": "text",
"text": "define if an external Redstone signal is absolutely needed, or if the device shall also spit automatically when filter slots match. And you can define if stacks in the filter slots shall be only dropped all together, or independently.$(br2)$(l)Shutter Indication$()$(br)The front shutter can help you to see internal conditions without opening the GUI. If you have items in the filter slots and all filters match (LEDs green), so that the dropper is"
},
{
"type": "text",
"text": "only waiting for an external Redstone signal, then the shutter will be open.$(br2)$(l)Further Details$()$(br)$(li)A blinking yellow LED above the delay slider indicates that the dropper is waiting for the delay to expire.$(li)When saying 'Redstone' OR 'filter slot output' for the second logic gate, and if the filter conditions are not met, then the dropper will instead spit an item that is not in the filter (good for cleaning)."
},
{
"type": "text",
"text": "$(li)In contrast to the previous, saying 'Redstone' AND 'filter slot output' for the 2nd logic gate, then only items from the filter will be ejected, other stacks will remain in the storage slots until they are extracted somehow."
},
{
"type": "text",
"text": ""
}
]
}

View file

@ -0,0 +1,42 @@
{
"name": "Factory Hopper",
"icon": "engineersdecor:factory_hopper",
"category": "automation",
"sortnum": 6010,
"pages": [
{
"type": "spotlight",
"title": "Factory Hopper",
"item": "engineersdecor:factory_hopper",
"text": "A Hopper device facilitating item collection and advanced automation.$(br)With additional $(t:... that is also for the sake of style: When you attach a lever or Redstone Probe Connector, these will not hang in thin air)support plates$() on the sides and an increased outlet diameter, it can insert and store more items. Sliders and Redstone controls in the GUI allow to tune the device functional behaviour."
},
{
"type": "text",
"text": "The hopper can be placed in all directions including up, in the latter case the device collects or draws items from below.$(br)When you break and relocate the hopper, stored items will stay in place, and settings will be preserved.$(br2)$(l)Collection$()$(br)The Hopper collects items from inventories or in-world into its eighteen internal storage slots, preferring to fill up existing stacks first."
},
{
"type": "text",
"text": "Vertical collection range is up to about 2.5 blocks above, or when placed upwards about 3 blocks below. The horizontal area is by default 1 (only directly above/below), and can be increased up to 4 in each direction. You can do this with the topmost slider in the GUI (the symbols shall represent a cross-section of the collection area).$(br)Unless items fall directly into the funnel, the hopper will wait until they $(t:... so called 'pickup delay'. The hopper actually waits a little bit longer)can be picked$() up, giving you precedence."
},
{
"type": "text",
"text": "$(l)Insertion$()$(br)From its internal storage the hopper frequently transfers item stacks to inventories or devices it is directed to, by default one item at a time. It tries to replenish existing stacks before filling empty slots. In case the item in the currently selected slot (marked in the GUI with a red frame) cannot be inserted, the next possible slot will be selected (round robin).$(br)The slider in the middle of the GUI (icons shall represent a"
},
{
"type": "text",
"text": "dog and a snail) can be used enforce a delay between 0.5s and 10s after inserting. When the delay has not expired yet, a yellow LED above the slider is blinking.$(br)Clicking at the bottom slider (labeled with one to five dots), the insertion stack size can be set between 1 to 32 items at a time. Only the currently selected stack is inserted, even if it contains less items than the configured count."
},
{
"type": "text",
"text": "$(l)Redstone Controls$()$(br)In the lower right area of the GUI, there is a red LED (with arrow) and two circuit elements wired up. The LED is lit when the device sees an external Redstone signal, and can also be used as test-trigger button. Connected to that input are an analog inverter, followed by a trigger control logic.$(br)By default the curve shown for the inversion control is going down, meaning that this control $(t:Input 0..15 -> output 15..0)inverts the signal$(). Click it to change this to 'not inverted'."
},
{
"type": "text",
"text": "Now the hopper will operate only $(o)when$() a Redstone signal is applied.$(br)The trigger control specifies weather the hopper operates $(o)continuously$() or $(o)(edge detection triggered) pulse$() mode. Continuous means 'Operate as long as the input is active', pulse means 'Insert only one time when the Redstone signal changes from OFF to ON'."
},
{
"type": "text",
"text": "$(l)Details$()$(br)$(li)The insertion stack size slider also defines how many items are drawn from the inventory above.$(li)The Factory Hopper does $(t:Unneeded server CPU waste)not insert$() into opposed Hoppers."
}
]
}

View file

@ -0,0 +1,34 @@
{
"name": "Factory Block Placer",
"icon": "engineersdecor:factory_placer",
"category": "automation",
"sortnum": 6030,
"pages": [
{
"type": "spotlight",
"title": "Factory Block Placer",
"item": "engineersdecor:factory_placer",
"text": "A simple automation device that places blocks or plants in front of it.$(br)18 internal storage slots hold the items to be placed, where the currently selected slot is marked with a red frame in the GUI. If the current item cannot be placed, or if that slot is empty, then the next slot is selected - e.g. when the soil"
},
{
"type": "text",
"text": "underneath is not suitable for a plant. $(t:... like Pufferfish, food, or tools. It also spits items out that are causing errors when being placed.)Items, which cannot be placed at all$(), are simply spat out to keep the storage slots clean.$(br)You can place the device in all directions, where sneak-clicking flips the placement direction.$(br2)By default, the device places items directly when it can, as long as it is not disabled with a Redstone signal. This can be tuned using the Redstone controls in the bottom right of"
},
{
"type": "text",
"text": "the GUI: There is an indicator LED for external signals, an inverter, and finally a trigger control. The indicator is lit when an external signal is currently applied, which is helpful for trouble-shooting. This signal is fed into the inversion control. By default the curve shown there is going down, meaning that this control $(t:Input 0..15 -> output 15..0)inverts the signal$(). Click it to change this to 'not inverted'. Now the placer will operate only $(o)when$() a Redstone signal is applied."
},
{
"type": "text",
"text": "Finally, the trigger control decides if the device shall work continuously, or only when the Redstone signal changes (edge detection trigger). By default this is set to $(o)continuous$(). Clicking changes this to $(o)triggered$(), means 'try to place only the moment when the signal goes off->on (not inverted) or on->off (inverted)'.$(br2)$(l)Spike Planting$()$(br)Normally blocks are placed in front of the placer. Plants can also be planted through the"
},
{
"type": "text",
"text": "soil, e.g. from underneath. This can be useful for automation (if there is no space at the surface), or also for cosmetic reasons.$(br2)A typical tree farm automation setup is to spike plant saplings through the ground, chop the grown trees with the $(o)Small Tree Cutter$(), and collect the dropped items using $(o)Factory Hoppers$(), also located below ground level. The saplings can be fed back into the placer, other drops stored"
},
{
"type": "text",
"text": "or disposed in a $(o)Small Waste Incinerator$(). Item sorting either conventionally or with an $(o)IE Item Router$()."
}
]
}

View file

@ -0,0 +1,18 @@
{
"name": "Small Block Breaker",
"icon": "engineersdecor:small_block_breaker",
"category": "automation",
"sortnum": 6040,
"pages": [
{
"type": "spotlight",
"title": "Small Block Breaker",
"item": "engineersdecor:small_block_breaker",
"text": "Destroys blocks in front of it using two counter-rotating, $(t:... description see Engineer's Tools mod ...)REDIA covered$() core drills.$(br2)It does not collect or store the dropped blocks, and needs more or less time depending on the hardness of the block to break. Providing RF power considerably accelerates that process."
},
{
"type": "text",
"text": "The dropped items are the same as if the block would be harvested with a pickaxe, axe, or shovel (without silk touch effect, fortune 0, etc).$(br)Applying a Redstone signal stops the breaker.$(br)You can place the device in horizontal directions, where sneak-clicking flips the placement direction. $(br2)$(o)[notice: The pack configuration may enforce that the device needs power. You can see that it is working when the drills rotate]$()"
}
]
}

View file

@ -0,0 +1,26 @@
{
"name": "Small Milking Machine",
"icon": "engineersdecor:small_milking_machine",
"category": "automation",
"sortnum": 6070,
"pages": [
{
"type": "spotlight",
"title": "Milking Machine",
"item": "engineersdecor:small_milking_machine",
"text": "A device dedicated to gather milk from cows in an animal welfare manner.$(br)As a modern milking robot, the decision when to milk is left to the individual cows, which occasionally pass by for 'unloading'. They only do this however when there is enough space in the cattle pen, and when it is not too crowded."
},
{
"type": "text",
"text": "The area in which cows go to the machine is 7x7 blocks in front of the milker (font is where the arm is located). Each milking process, the device fetches one bucket and stores the liquid in its internal tank. From there it can be retrieved with buckets or fluid transfer (the latter only if milk exists as fluid). Also automated item transfer is possible using $(o)Buckets$() (or compatible bottles):$(br)Place a $(o)Crate$() or $(o)Chest$() with empty buckets behind or below the machine."
},
{
"type": "text",
"text": "It will then draw these empty buckets in, and place filled buckets back into the crate, preferring to take from the back and inserting to the bottom.$(br)"
},
{
"type": "text",
"text": "Important notice: Mod packers can configure that this machine needs power, so you may have to provide that, too. $(o)(I don't have implemented a visual indication yet, greetings, the lazy mod author)$()"
}
]
}

View file

@ -0,0 +1,18 @@
{
"name": "Small Tree Cutter",
"icon": "engineersdecor:small_tree_cutter",
"category": "automation",
"sortnum": 6050,
"pages": [
{
"type": "spotlight",
"title": "Small Tree Cutter",
"item": "engineersdecor:small_tree_cutter",
"text": "A minimalistic circular saw with protection frame and wood sensor, which automatically cuts trees including leaves.$(br2)It does not collect or store the dropped wood or fruits, and requires about one minute when running from the internal passive environmental Redstone generator. By providing RF"
},
{
"type": "text",
"text": "$(t:... for the sake of style please from underneath the cutter using a capacitor ...)power externally$(), this process is accelerated to about 10 seconds.$(br)You can disable the cutter by applying a Redstone signal.$(br2) $(br2) $(br2) $(br2)$(o)[notice: The pack configuration may enforce that the device needs power. You can see that it is working when the saw rotates]$()"
}
]
}

View file

@ -0,0 +1,18 @@
{
"name": "Small Waste Incinerator",
"icon": "engineersdecor:small_waste_incinerator",
"category": "automation",
"sortnum": 6060,
"pages": [
{
"type": "spotlight",
"title": "Small Waste Incinerator",
"item": "engineersdecor:small_waste_incinerator",
"text": "This small device allows to dispose of superfluous items in a safe manner. Inserted materials slide down a ramp of 14 slots before being pushed into a lava chamber, where they are slowly disintegrated.$(br)The stacks will remain in the same slots as long as the topmost input slot is empty, otherwise they get pushed"
},
{
"type": "text",
"text": "forward by one slot. You can speed up the incineration process by applying RF power to any side of the device. When you break the block for relocation, the items will remain in place.$(br)To recover accidentally inserted items, open the device GUI and manually take the stack out."
}
]
}

View file

@ -0,0 +1,28 @@
{
"name": "Bricks",
"icon": "engineersdecor:clinker_brick_block",
"category": "buildingblocks",
"sortnum": 1010,
"pages": [
{
"type": "spotlight",
"title": "Clinker Bricks",
"item": "engineersdecor:clinker_brick_block",
"text": "Clinkers are very hot baked, slightly vitrified bricks, look darker than normal bricks, and have been a preferred building material for early industrial factories.$(br) ... and you may need a lot of them for building a factory. Therefore these blocks can be partially crafted from Nether Bricks, preventing to soon run out of clay."
},
{
"type": "text",
"text": "For a more seamless look, the block has varying textures depending on the positions where you place it. Clinkers are also available as Stairs, Walls, and Slabs.$(br2)If you need more texture variation, especially for rough areas of your factory, there are also craftable $(o)Stained Clinker Bricks$() to mix in."
},
{
"type": "spotlight",
"title": "Slag Bricks",
"item": "engineersdecor:slag_brick_block",
"text": "As one of the primary waste products in steel industries, slag debris was disposed on scree piles. One of the more unpopular byproducts were $(o)Slag Bricks$(), grayish and slightly porous bricks - but cheap.$(br)Similar to $(o)Clinker Bricks$(), these blocks have varying textures depending on the"
},
{
"type": "text",
"text": "position (and also have a bit more color than real slag bricks).$(br)You can also craft Stairs, Walls, and Slabs from $(o)Slag Bricks$()."
}
]
}

View file

@ -0,0 +1,28 @@
{
"name": "Concretes",
"icon": "engineersdecor:rebar_concrete",
"category": "buildingblocks",
"sortnum": 1020,
"pages": [
{
"type": "spotlight",
"title": "Rebar Concrete",
"item": "engineersdecor:rebar_concrete",
"text": "Rebar (\"REinforcing BAR\" concrete) is often used where structural integrity matters, i.e. bridges, basements, vaults, as well as ugly precast slab buildings. It consists of a thick steel wire mesh filled up with concrete. More rebar and higher quality steel the makes the composition stronger, but also more expensive. "
},
{
"type": "text",
"text": "The rebar concrete you see here is quite expensive. It $(t:...except maybe when a Draconic Core blows up)withstands explosions$() and is comparatively hard to break.$(br2)It comes with varying textures for seamless look (placement position dependent), and can also be transformed to Stairs, Walls, Slabs, and Slab Slices. The Wall shape differs from vanilla walls."
},
{
"type": "spotlight",
"title": "Gas Concrete",
"item": "engineersdecor:gas_concrete",
"text": "In contrast to $(o)Rebar Concrete$(), Gas Concrete is a lightweight and cheap building material. It is produced by aerating liquid concrete to make it foamy before casting. The mineral composition is more based on sand rather than coarse gravel."
},
{
"type": "text",
"text": "The Gas Concrete blocks have a smooth looking surface with texture variations, are fast to break, cheap to make, and have not much resistance against explosions.$(br)They are good material if you need to fill vast volumes like basement walls, tunnel walls, or floors.$(br)Walls, Stairs, Slabs, as well as Slab Slices can be crafted from Gas Concrete, too."
}
]
}

View file

@ -0,0 +1,18 @@
{
"name": "Gates and Doors",
"icon": "engineersdecor:steel_mesh_fence_gate",
"category": "buildingblocks",
"sortnum": 1060,
"pages": [
{
"type": "spotlight",
"title": "Steel Mesh Fence Gate",
"item": "engineersdecor:steel_mesh_fence_gate",
"text": "A fence gate fitting the style of the $(o)Steel Mesh Fence$(). It can be placed one block high for normal fencing, or doubled for higher cage fences, and will form a fence door accordingly.$(br)Redstone open/close signals are accepted for the bottom segment from all sides, for the top segment only from above."
},
{
"type": "text",
"text": ""
}
]
}

View file

@ -0,0 +1,30 @@
{
"name": "Fences and Walls",
"icon": "engineersdecor:steel_mesh_fence",
"category": "buildingblocks",
"sortnum": 1050,
"pages": [
{
"type": "spotlight",
"title": "Steel Mesh Fence",
"item": "engineersdecor:steel_mesh_fence",
"text": "An industrial fence type, known from protection barriers of transformer stations, or robot enclosures.$(br2)They connect to compatible fences or walls (means the walls shown on these pages), and intentionally not to vanilla walls and fences."
},
{
"type": "text",
"text": "They also do not connect to other blocks, except if that block continues a straight line of Mesh Fences. That way you can connect the fences to building walls, but do not have to bother that fence parts may connect unexpectedly to chests or other blocks placed next to the your fence."
},
{
"type": "spotlight",
"title": "Concrete Walls",
"item": "engineersdecor:rebar_concrete_wall",
"text": "This wall type has a different look than vanilla walls, and comes also with varying textures. It connects in the same way as the $(o)Steel Mesh Fence$().$(br)$(o)Rebar Concrete$() walls are also Creeper proof."
},
{
"type": "spotlight",
"title": "Brick Walls",
"item": "engineersdecor:clinker_brick_wall",
"text": "Similar to the Concrete Walls, Brick Walls have an individual look, and connect only to compatible fences and walls."
}
]
}

View file

@ -0,0 +1,18 @@
{
"name": "Glass",
"icon": "engineersdecor:panzerglass_block",
"category": "buildingblocks",
"sortnum": 1030,
"pages": [
{
"type": "spotlight",
"title": "Panzer Glass",
"item": "engineersdecor:panzerglass_block",
"text": "Panzer Glass is a reinforced safety glass type, consisting of changing layers of tempered or chemically treated glass, metal meshes, organic layers, and other stuff. It is used where safety matters, e.g. in the field of personal security, or in explosion hazardous industrial areas."
},
{
"type": "text",
"text": "Similar to $(o)Rebar Concrete$(), this glass is quite expensive, comparatively hard to break, and explosion-proof.$(br)The application range reaches from enclosing critical areas like storage rooms to mob farming grounds."
}
]
}

View file

@ -0,0 +1,20 @@
{
"name": "Ladders",
"icon": "engineersdecor:treated_wood_ladder",
"category": "buildingblocks",
"sortnum": 1080,
"pages": [
{
"type": "spotlight",
"title": "Wooden Ladders",
"item": "engineersdecor:treated_wood_ladder",
"text": "Solid, weather-proof ladders, placed and used like vanilla ladders.$(br2)You move faster when looking straight up or down while climbing."
},
{
"type": "spotlight",
"title": "Metal Ladders",
"item": "engineersdecor:metal_rung_ladder",
"text": "Solid metal ladders, sometimes a bit rusty.$(br2)Used and placed the same way as the wooden ladders."
}
]
}

View file

@ -0,0 +1,19 @@
{
"name": "Slab Slices",
"icon": "engineersdecor:halfslab_rebar_concrete",
"category": "buildingblocks",
"sortnum": 1040,
"pages": [
{
"type": "spotlight",
"title": "Slab Slices",
"item": "engineersdecor:halfslab_rebar_concrete",
"text": "For various blocks in this mod there are very thin horizontal slabs available.$(br2)While a normal slab fills half a block, you need eight of these thin slices for a full cube. They can be interesting for detailing roofs, floors, or making ramps."
},
{
"title": "Placement & Pickup",
"type": "text",
"text": "You place the slices by clicking on the top or bottom faces of the blocks where you want to place them. Slice blocks will grow accordingly.$(br2)When you break a block of slices, the singulated parts will be dropped. Alternatively you can left-click a slice block while holding a slice in your hand to peel one layer off. This only works while looking almost straight down or up."
}
]
}

View file

@ -0,0 +1,20 @@
{
"name": "Windows",
"icon": "engineersdecor:treated_wood_window",
"category": "buildingblocks",
"sortnum": 1070,
"pages": [
{
"type": "spotlight",
"title": "Window Types",
"item": "engineersdecor:treated_wood_window",
"text": "These 3D framed windows have slightly stained panes, and can be placed horizontally or vertically.$(br)Other than vanilla glass panes, windows have no corner pieces, and the window glass will remain intact when you break the block (no $(o)Silk Touch$() needed)."
},
{
"type": "spotlight",
"title": "Placement",
"item": "engineersdecor:steel_framed_window",
"text": "To place a window in the ceiling or the floor, you have to look almost straight up or down. This makes it easier to place windows in walls without the need of scaffolding (or accidentally placing them horizontally). When you place a window next to another one, the same orientation will be used for similar reasons."
}
]
}

View file

@ -0,0 +1,32 @@
{
"name": "Furniture",
"icon": "engineersdecor:treated_wood_table",
"category": "cosmetic",
"sortnum": 3010,
"pages": [
{
"type": "spotlight",
"title": "Steel table",
"item": "engineersdecor:steel_table",
"text": "A metal table as used in some manual assembly lines or clean rooms. The grated top face allows dust or air streams to pass through.$(br)Depending on your factory setup they can also be used as decorative supports for conveyor belts."
},
{
"type": "spotlight",
"title": "Wood tables",
"item": "engineersdecor:treated_wood_table",
"text": "More for the Engineer's home rather than a factory, you can craft a normal four-leg table and a side table to place decorative stuff on. Not much more to say - except that they are of corse weather-proof because it's treated wood."
},
{
"type": "spotlight",
"title": "Wood Stool",
"item": "engineersdecor:treated_wood_stool",
"text": "Let's face it: Comfy armchairs are lame. Members of the working population sit on plain stools without cushion, where they can jump up any time and race to their next task.$(br)For whatever reason however, this stool seems to be comfy enough that mobs sometimes sit down (so can you, too). Villagers don't, probably they are Über-Workers."
},
{
"type": "spotlight",
"title": "Wood Window Sills",
"item": "engineersdecor:treated_wood_windowsill",
"text": "Sills make nice accents on plain walls. You can craft two types of windowsill, a small one and a board sill. Latter can cary a flower pot if you like."
}
]
}

View file

@ -0,0 +1,18 @@
{
"name": "Signs",
"icon": "engineersdecor:sign_hotwire",
"category": "cosmetic",
"sortnum": 3020,
"pages": [
{
"type": "spotlight",
"title": "Signs",
"item": "engineersdecor:sign_hotwire",
"text": "You can craft some sign plates that can be attached to walls, and shall help people not loosing their orientation in larger factories. Similarly, there are signs which are simply placed for the sake of health and safety. E.g. do not forget to place a Hot Wire warning sign close to HV wire cables. If someone gets hurt you'll be responible otherwise."
},
{
"type": "text",
"text": "Also Exit Signs over the doors are helpful for the next fire drill."
}
]
}

View file

@ -0,0 +1,36 @@
{
"name": "Treated Wood Crafting Table",
"icon": "engineersdecor:treated_wood_crafting_table",
"category": "crafting",
"sortnum": 5010,
"pages": [
{
"type": "spotlight",
"title": "Crafting Table",
"item": "engineersdecor:treated_wood_crafting_table",
"text": "This engineering themed workbench allows manual 3x3 crafting. It comes with some convenience tweaks, which are not visible at the first look. These features will be explained on the next pages."
},
{
"title": "Storage",
"type": "text",
"text": "There are eight storage slots for frequently used materials at the left side of the crafting grid.$(br)All items remain in the table when you break it, and their positions are restored when you place it again. However, the items are dropped when the table is destroyed in a explosion.$(br)Items that are placed in the crafting grid are also visible on the top face of the block (outside the GUI, in-world)."
},
{
"title": "Crafting History",
"type": "text",
"text": "The $(o)up/down$() arrow buttons at the right side of the crafting grid allow you to quickly select recipes that you have recently used. The $(o)cross$() button clears the selection and moves already placed ingredients back into your inventory.$(br)Placement and crafting result will be displayed dark shaded. When you have found the right recipe click the result slot once, so that the items are automatically placed in the"
},
{
"type": "text",
"text": "crafting grid (exactly where you placed them before).$(br)If you do not have the exact ingredients in your inventory, replacements will be searched and placed instead (e.g. Spruce Planks instead of Oak Planks for a recipe that just needs any planks).$(br)Only one item of each ingredient is placed when clicking the result slot, no matter if you have crafted more the last time. You can easily increase the stack sizes (read section $(o)Item Transfer Tweaks$())."
},
{
"type": "text",
"text": "$(l)Mouse Wheel:$() You can use the mouse wheel while hovering the result slot to quickly increase or decrease the crafting grid stacks. Normal increment is 1, while holding $(o)SHIFT$() 2, $(o)CTRL$() 4, and $(o)SHIFT-CTRL$() 8. Stacks in your own inventory will be used up first (from the smallest to the largest stack to keep the inventory clean). Then the storage slots will be accessed. Items will always be placed back in your inventory, filling up existing stacks first."
},
{
"type": "text",
"text": "$(br2)$(l)Storage Quick Move:$() When the crafting grid is empty, you can quickly move stacks from or to the storage slots by $(o)SHIFT-clicking$().$(br2)$(l)Quick Move Buttons:$() You can enable small arrow buttons in the Mod (client) config. They are disabled by default to keep the GUI simple and clean."
}
]
}

View file

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

View file

@ -0,0 +1,34 @@
{
"name": "Small Electrical Furnace",
"icon": "engineersdecor:small_electrical_furnace",
"category": "crafting",
"sortnum": 5040,
"pages": [
{
"type": "spotlight",
"title": "Electrical Furnace",
"item": "engineersdecor:small_electrical_furnace",
"text": "An RF electrically operated pass-through kiln, suitable for automated manufacturing lines. Like the $(o)Small Lab Furnace$(), it has three input FiFo slots (internal hoppers) for smelting or cooking ingredients, three output Fifo slots, as well as one auxiliary slot for storage. There are no fuel slots.$(br)The internal FiFo pipeline"
},
{
"type": "text",
"text": "transports materials as whole stacks into the processing chamber. Smelted stacks are automatically inserted into the inventory at the output side (side marked orange; chests, conveyors, etc).$(br)Power can be provided at all sides of the device.$(br)If an item is inserted that the furnace cannot process, it will be by-passed from the input to the output FiFo, instead of blocking the furnace."
},
{
"type": "text",
"text": "To get information weather the furnace is currently working and fed, attach a $(o)Redstone Probe Connector$() (or $(o)Redstone Comparator$()). If all slots in the input FiFo are empty or the furnace is unpowered, then the output is zero. For each non-empty input slot the power increases by 5 (if powered that is).$(br)If you need to relocate the device, you can break it with a pick. Items will remain in place."
},
{
"type": "text",
"text": "$(l)Speed override switch$()$(br)A four-position switch in the bottom right area of the GUI allows to alter the processing speed of the furnace. Default is position 1 (normal). At high power expenses, you can alter this: $(br)$(li)Position 0: OFF$(li)Position 1: x1.0 -> RF x1$(li)Position 2: x1.5 -> RF x2$(li)Position 3: x2.0 -> RF x4$(br2)(Positions 0..4 are down, left, top, right)."
},
{
"type": "text",
"text": "$(l)Automatic feeding support$()$(br)Placing a Hopper or Factory Hopper into the auxiliary slot at the bottom left of the GUI allows to automatically draw items from inventories at the input side (marked blue). The feeding mechanism will operate only when the first input FiFo slot is empty.$(br)$(o)Side note: The furnace passes stacks that it cannot process directly to the output, so it does not get stuck when some unsmeltable items are pulled in.$()"
},
{
"type": "text",
"text": ""
}
]
}

View file

@ -0,0 +1,26 @@
{
"name": "Small Laboratory Furnace",
"icon": "engineersdecor:small_lab_furnace",
"category": "crafting",
"sortnum": 5030,
"pages": [
{
"type": "spotlight",
"title": "Laboratory Furnace",
"item": "engineersdecor:small_lab_furnace",
"text": "Various manual kilns are used in industries for prototyping, preparing materials or alloys for further processing or analysis, and also to $(t:[believe me, I saw that with me own eyes])make pizza$().$(br)This Laboratory Furnace can be crafted early as a fuel efficient and fast alternative to the cobblestone furnace."
},
{
"type": "text",
"text": "As shown in the GUI, it has additional hopper slots (FiFo slots) for the fuel input, the smelting/cooking input, and the output. Items are transported one-by-one from the left to the right. Hence, three stacks can be processed before you need to refill and extract (you get the smelting XP when doing this by hand).$(br)The two auxiliary slots at the bottom-right can be used as general purpose storage (e.g. for coal reserves), but also to enable additional features (read on)."
},
{
"type": "text",
"text": "When you break the furnace to relocate it or for putting it in your inventory, all items inside stay in place.$(br)Item transfer input for fuel is at the sides, smelting input at the top, and the output and bucket extraction at the bottom (same as cobblestone furnace).$(br2)The comparator output reflects number of $(o)smelting input slots$() that are not empty (0,5,10,15). Also if there is no $(o)fuel$() left, the comparator output will be also zero."
},
{
"type": "text",
"text": "$(l)RF power speed-up:$() When putting an $(o)$(t:Immersive Engineering)IE$() $(o)External Heater$() into one ot the two auxiliary slots and provide RF power to the Lab Furnace, it processes $(t:Configurable, best to try it out for the pack you are playing)much faster$()."
}
]
}

View file

@ -0,0 +1,18 @@
{
"name": "Mineral Melting Furnace",
"icon": "engineersdecor:small_mineral_smelter",
"category": "crafting",
"sortnum": 5050,
"pages": [
{
"type": "spotlight",
"title": "Mineral Melting Furnace",
"item": "engineersdecor:small_mineral_smelter",
"text": "A small, highly insulated, high temperature furnace, which can be used to liquify stone-like materials (preferably Diorite). The process takes a moderate amount of RF energy and time. When inserting a block, either manually or automatically, it will be heated up for a while, then decompose to $(o)Magma Stone$(), and finally liquefy to $(o)Lava$()."
},
{
"type": "text",
"text": "If you cut off the RF power to the device, or disable it with a Redstone signal, $(o)Lava$() will cool down and re-crystallise to $(o)Magma Stone$(), and then to $(o)Obsidian$().$(br)To retrieve blocks from the melter, $(t:... careful, don't burn your hands)right click it$() or use extraction devices (like e.g. Hoppers). Lava extraction can be done using a bucket or automated fluid transfer.$(br)Use a $(o)Redstone Comparator$() to get an $(t:FSO=Full Scale Output, means values are scaled from 0 to 15)FSO$() indication of the current process phase $(t:0, 5, 10, and 15)(cold, hot, magma, lava)$()."
}
]
}

View file

@ -0,0 +1,18 @@
{
"name": "Passive Fluid Accumulator",
"icon": "engineersdecor:passive_fluid_accumulator",
"category": "fluidics",
"sortnum": 7040,
"pages": [
{
"type": "spotlight",
"title": "Fluid Accumulator",
"item": "engineersdecor:passive_fluid_accumulator",
"text": "This passive collector is useful to drain multiple tanks with one pump. It is basically an empty liquid container with one outlet connector for a suction pump, as well as five inlets for adjacent tanks.$(br)When the pump drains the Fluid Accumulator, the connected tanks will be drained in turn."
},
{
"type": "text",
"text": "The Fluid Accumulator supports pressurised (\"high speed\") fluid transfer of $(o)Immersive Engineering$() pumps, and can drain tanks very quickly. Note that the initial flow rate is low, because the container volume needs to be filled up first by the pump vacuum.$(br2)To place the device, click on the input side of the pump (the outlet is on the face you click). Shift-click placement flips the placement direction."
}
]
}

View file

@ -0,0 +1,18 @@
{
"name": "Fluid Collection Funnel",
"icon": "engineersdecor:small_fluid_funnel",
"category": "fluidics",
"sortnum": 7050,
"pages": [
{
"type": "spotlight",
"title": "Fluid Collection Funnel",
"item": "engineersdecor:small_fluid_funnel",
"text": "This device consists of a grating at the top, a funnel, and a small tank. Placed in the floor of a factory, it provides additional safety by collecting spilled liquids like Diesel, Petrol/Gazoline, Creosote, and other hazardous fluids. Small gauges on the sides indicate the tank fill level. The tank material can withstand hot liquids like lava."
},
{
"type": "text",
"text": "Outlets are at the bottom and the sides, where there is a slow gravity fluid transfer at the bottom outlet. Using a comparator you can determine the fill level (0 empty, 15 full).$(br)When collecting flowing fluids, $(t:To prevent wasting server performance, the device has a tendency -with random reset- to collect source blocks around the last collected location.)the liquid is traced back to its next topmost source block$(), which will be removed.$(br)Digging down next to a Nether lava lake and placing a funnel, a 'crater' of flowing lava will be slowly formed. Also long 'lavafalls' can be removed by placing a funnel underneath."
}
]
}

View file

@ -0,0 +1,18 @@
{
"name": "Fluid Pipe Check Valve",
"icon": "engineersdecor:straight_pipe_valve",
"category": "fluidics",
"sortnum": 7010,
"pages": [
{
"type": "spotlight",
"title": "Fluid Check Valve",
"item": "engineersdecor:straight_pipe_valve",
"text": "This check valve contains a prestressed spring plate that can be pushed from the back, but not from the front face. Therefore it allows liquids to pass through only in one direction.$(br)Its main purpose is to prevent backflows in fluid pipe systems."
},
{
"type": "text",
"text": "The valve can be inserted between $(o)Fluid Pipes$(), as well as directly to fluid inputs or outputs of devices. The yellow arrow marks the flow direction.$(br2)To place the valve, click on the face it shall be directed to. Sneak-click if you need the opposite flow direction (e.g. when clicking at a fluid output face). Maximum flow rate is $(o)$(t:The value is configurable and may vary)1000mB per tick$()."
}
]
}

View file

@ -0,0 +1,18 @@
{
"name": "Redstone Fluid Valve",
"icon": "engineersdecor:straight_pipe_valve_redstone",
"category": "fluidics",
"sortnum": 7020,
"pages": [
{
"type": "spotlight",
"title": "Redstone Fluid Valve",
"item": "engineersdecor:straight_pipe_valve_redstone",
"text": "Similar to $(o)Fluid Pipe Check Valves$(), $(o)Redstone Fluid Valves$() allow liquids to pass through only in the forward direction. An additional redstone-mechanical mechanism also inhibits forward flows by locking the prestressed spring plate, unless a Redstone signal is applied."
},
{
"type": "text",
"text": "This valve type is useful if you need to enable or disable fluid replenishments of devices, or e.g. if you like to switch between process fluids in an automated system."
}
]
}

View file

@ -0,0 +1,18 @@
{
"name": "Redstone Analog Fluid Valve",
"icon": "engineersdecor:straight_pipe_valve_redstone_analog",
"category": "fluidics",
"sortnum": 7030,
"pages": [
{
"type": "spotlight",
"title": "Analog Fluid Valve",
"item": "engineersdecor:straight_pipe_valve_redstone_analog",
"text": "$(o)Redstone Analog Fluid Valves$() are, like $(o)Redstone Fluid Valve$(), used to control allocation and distribution in pipe systems.$(br2)Analog valves can, in addition to switching valves, limited the flow rate depending on the Redstone signal strength."
},
{
"type": "text",
"text": "Possible uses cases are tuning the processing speed of a machine crafting with fluids, prioritising fluid paths, or defining the concentration of a mixture.$(br)Redstone signal strength 0 blocks all flows, 15 opens the valve completely $(t:Configurable, may vary)(max flow rate 1000mB/t)$(). Values from 1 to 14 open the valve in $(t:Configurable, may vary)20mB/t steps (20 to 280)$().$(br)Placement rules are like the $(o)Fluid Pipe Check Valve$()."
}
]
}

View file

@ -0,0 +1,20 @@
{
"name": "Inset Lights",
"icon": "engineersdecor:iron_inset_light",
"category": "illumination",
"sortnum": 4010,
"pages": [
{
"type": "spotlight",
"title": "Inset Spotlight",
"item": "engineersdecor:iron_inset_light",
"text": "This passive light source can be placed on ceilings or walls, and comes in handy where proper electrical illumination is not an option. For instance, stairways, narrow corridors, small inspection chambers, as well as air shafts are such problematic locations.$(br)Light level is 15, you will need Glowstone for crafting."
},
{
"type": "spotlight",
"title": "Floor Edge Light",
"item": "engineersdecor:iron_floor_edge_light",
"text": "Edge lights are useful for orientation, as well as for lighting up spaces between larger machines.$(br)Big machines may block the light cones of flood lights, causing dangerously dark spots (see the 'Health and Safety' handbook, chapter 'Explosion Hazzard')."
}
]
}

View file

@ -0,0 +1,26 @@
{
"name": "Small Solar Panel",
"icon": "engineersdecor:small_solar_panel",
"category": "power",
"sortnum": 8010,
"pages": [
{
"type": "spotlight",
"title": "Small Solar Panel",
"item": "engineersdecor:small_solar_panel",
"text": "Like the name suggests, this device transforms sunlight to RF power.$(br)The monocrystalline Redstone layer of the panel has an effeciency of 22%, so the output power is small.$(br)Its main application range lies in generating auxiliary power for remote places, where cabeling is too expensive or problematic."
},
{
"type": "text",
"text": "The panel has an internal capacitor with charge pump. When exposed to the sun, this capacitor will start to charge up. The power output is enabled after it is at least 20% charged, and will remain active until the capacitor is empty again. Hence, the output of the panel pulsed.$(br)To use the panel efficiently, place a capacitor or battery underneath it. To increase the total power production you need to place a whole solar field with power transfer infrastructure."
},
{
"type": "text",
"text": "Peak production is at noon. From dawn to dusk the power curve is nonlinearly rising and falling. Further efficiency factors are weather and local light conditions.$(br2)The output power over 24h is comparable to a Thermo-Electric Generator.$(br2)In summary, it is free power that also can be bumped up a bit, but you have to invest in the infrastructure, and you"
},
{
"type": "text",
"text": "need to be careful to have reserves for bad weather. For heavy machinery more reliable power sources like $(o)Diesel Generators$() are recommended."
}
]
}

View file

@ -0,0 +1,18 @@
{
"name": "Floor Gratings",
"icon": "engineersdecor:steel_floor_grating",
"category": "structural",
"sortnum": 2030,
"pages": [
{
"type": "spotlight",
"title": "Steel Floor Grating",
"item": "engineersdecor:steel_floor_grating",
"text": "Metal gratings are popular in industries, not only due the good ratio between material consumption vs carrying capacity, but also for their peculiarity to prevent dust and other particles from piling up.$(br)Hence, items fall through the $(o)Steel Floor Grating$() shown above, while you can safely"
},
{
"type": "text",
"text": "stand on it.$(br)In case this helps your contraption: The items always fall through the centre of the grating, and are slowed down if they are too fast."
}
]
}

View file

@ -0,0 +1,20 @@
{
"name": "Steel Supports",
"icon": "engineersdecor:thick_steel_pole_head",
"category": "structural",
"sortnum": 2020,
"pages": [
{
"type": "spotlight",
"title": "Steel Poles",
"item": "engineersdecor:thick_steel_pole",
"text": "Hollow steel poles (like the one shown above) have an 'O' cross section to save weight and material whilst providing a good structural integrity.$(br)There is a thick and a thin variant, depending on your needs. Unlike fence posts, they do not connect to blocks at the side, and can be placed vertically or horizontally."
},
{
"type": "spotlight",
"title": "Double-T Support",
"item": "engineersdecor:steel_double_t_support",
"text": "Named by the look of its cross section (two 'T's), this is a commonly used tradeoff between material/weight and maximum load.$(br)Double-T supports are placed only horizontally (top aligned), connect to adjacent Double-T supports, and also to $(o)Steel Poles$() below."
}
]
}

View file

@ -0,0 +1,20 @@
{
"name": "Wooden Supports",
"icon": "engineersdecor:treated_wood_pole_support",
"category": "structural",
"sortnum": 2010,
"pages": [
{
"type": "spotlight",
"title": "Treated Wood Pole",
"item": "engineersdecor:treated_wood_pole",
"text": "Wooden poles are straight decorative supports that can be placed in all directions. They are slightly thicker than fence posts and do not connect to blocks at the sides. The orientation is defined by the face that you click when placing the block."
},
{
"type": "spotlight",
"title": "Pole Head",
"item": "engineersdecor:treated_wood_pole_head",
"text": "Pole heads form nice looking end pieces for poles. There are two variants: A small one and a big one, where ladder suggests heavy loads, and does not fit everywhere (simply try out if it does). Pole heads will be automatically directed towards placed poles, except you sneak-click, which flips the placement direction."
}
]
}

View file

@ -281,7 +281,7 @@
},
{
"conditions": [
{ "type": "engineersdecor:grc", "missing": ["immersiveengineering:stone_decoration"] }
{ "type": "engineersdecor:optional", "missing": ["immersiveengineering:stone_decoration"] }
],
"ingredient": [
{ "item": "minecraft:concrete", "data": 32767 },

View file

@ -1,5 +1,5 @@
{
"conditions": {
"grc": "wile.engineersdecor.detail.RecipeCondModSpecific"
"optional": "wile.engineersdecor.detail.RecipeCondModSpecific"
}
}

View file

@ -1,7 +1,7 @@
{
"conditions": [
{
"type": "engineersdecor:grc",
"type": "engineersdecor:optional",
"result": "engineersdecor:factory_dropper",
"missing": ["immersiveengineering:material"]
}

View file

@ -1,7 +1,7 @@
{
"conditions": [
{
"type": "engineersdecor:grc",
"type": "engineersdecor:optional",
"result": "engineersdecor:factory_hopper",
"missing": ["immersiveengineering:material"]
}

View file

@ -1,7 +1,7 @@
{
"conditions": [
{
"type": "engineersdecor:grc",
"type": "engineersdecor:optional",
"result": "engineersdecor:factory_placer",
"missing": ["immersiveengineering:material"]
}

View file

@ -1,7 +1,7 @@
{
"conditions": [
{
"type": "engineersdecor:grc",
"type": "engineersdecor:optional",
"result": "engineersdecor:gas_concrete",
"missing": ["immersiveengineering:stone_decoration"]
}

View file

@ -1,7 +1,7 @@
{
"conditions": [
{
"type": "engineersdecor:grc",
"type": "engineersdecor:optional",
"result": "engineersdecor:iron_inset_light",
"missing": ["immersiveengineering:material"]
}

View file

@ -0,0 +1,33 @@
{
"conditions": [
{
"type": "engineersdecor:optional",
"result": "engineersdecor:labeled_crate",
"missing": ["immersiveengineering:material"]
}
],
"type": "minecraft:crafting_shaped",
"pattern": [
"RCR",
"CFC",
"RCR"
],
"key": {
"R": {
"item": "minecraft:iron_nugget",
"data": 0
},
"C": {
"item": "minecraft:chest",
"data": 0
},
"F": {
"item": "minecraft:item_frame",
"data": 0
}
},
"result": {
"item": "engineersdecor:labeled_crate",
"count": 1
}
}

View file

@ -1,7 +1,7 @@
{
"conditions": [
{
"type": "engineersdecor:grc",
"type": "engineersdecor:optional",
"result": "engineersdecor:metal_rung_ladder",
"missing": ["immersiveengineering:material"]
}

View file

@ -1,7 +1,7 @@
{
"conditions": [
{
"type": "engineersdecor:grc",
"type": "engineersdecor:optional",
"result": "engineersdecor:metal_rung_steps",
"missing": ["immersiveengineering:material"]
}

View file

@ -1,7 +1,7 @@
{
"conditions": [
{
"type": "engineersdecor:grc",
"type": "engineersdecor:optional",
"result": "engineersdecor:panzerglass_block",
"missing": ["immersiveengineering:stone_decoration"]
}

View file

@ -1,7 +1,7 @@
{
"conditions": [
{
"type": "engineersdecor:grc",
"type": "engineersdecor:optional",
"result": "engineersdecor:passive_fluid_accumulator",
"required": ["engineersdecor:straight_pipe_valve"],
"missing": ["immersiveengineering:material"]

View file

@ -1,7 +1,7 @@
{
"conditions": [
{
"type": "engineersdecor:grc",
"type": "engineersdecor:optional",
"result": "engineersdecor:rebar_concrete",
"missing": ["immersiveengineering:stone_decoration"]
}

View file

@ -1,7 +1,7 @@
{
"conditions": [
{
"type": "engineersdecor:grc",
"type": "engineersdecor:optional",
"result": "engineersdecor:sign_hotwire",
"missing": ["immersiveengineering:stone_decoration"]
}

View file

@ -1,7 +1,7 @@
{
"conditions": [
{
"type": "engineersdecor:grc",
"type": "engineersdecor:optional",
"result": "engineersdecor:clinker_brick_block",
"missing": ["immersiveengineering:material"]
}

View file

@ -1,7 +1,7 @@
{
"conditions": [
{
"type": "engineersdecor:grc",
"type": "engineersdecor:optional",
"result": "engineersdecor:small_block_breaker",
"missing": ["immersiveengineering:material"]
}

View file

@ -1,7 +1,7 @@
{
"conditions": [
{
"type": "engineersdecor:grc",
"type": "engineersdecor:optional",
"result": "engineersdecor:small_electrical_furnace",
"required": ["engineersdecor:small_lab_furnace"],
"missing": ["immersiveengineering:material"]

View file

@ -1,7 +1,7 @@
{
"conditions": [
{
"type": "engineersdecor:grc",
"type": "engineersdecor:optional",
"result": "engineersdecor:small_fluid_funnel",
"missing": ["immersiveengineering:metal_device1"]
}

View file

@ -1,7 +1,7 @@
{
"conditions": [
{
"type": "engineersdecor:grc",
"type": "engineersdecor:optional",
"result": "engineersdecor:small_lab_furnace",
"missing": ["immersiveengineering:material"]
}

View file

@ -1,7 +1,7 @@
{
"conditions": [
{
"type": "engineersdecor:grc",
"type": "engineersdecor:optional",
"result": "engineersdecor:small_milking_machine",
"missing": ["immersiveengineering:material"]
}

View file

@ -1,7 +1,7 @@
{
"conditions": [
{
"type": "engineersdecor:grc",
"type": "engineersdecor:optional",
"result": "engineersdecor:small_mineral_smelter",
"required": ["engineersdecor:panzerglass_block"],
"missing": ["immersiveengineering:metal_device1"]

View file

@ -1,7 +1,7 @@
{
"conditions": [
{
"type": "engineersdecor:grc",
"type": "engineersdecor:optional",
"result": "engineersdecor:small_solar_panel",
"missing": ["immersiveengineering:metal_device1"]
}

View file

@ -1,7 +1,7 @@
{
"conditions": [
{
"type": "engineersdecor:grc",
"type": "engineersdecor:optional",
"result": "engineersdecor:small_tree_cutter",
"missing": ["immersiveengineering:material"]
}

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