Fixed window rendering issue (#15). Lab furnace electrical speed-up implemented.

This commit is contained in:
stfwi 2019-04-05 16:12:32 +02:00
parent 2be893eff6
commit 80bf3fd5f6
20 changed files with 634 additions and 103 deletions

View file

@ -4,4 +4,4 @@ org.gradle.jvmargs=-Xmx8G
version_minecraft=1.12.2
version_forge=14.23.5.2768
version_jei=4.10.0.198
version_engineersdecor=1.0.3-b3
version_engineersdecor=1.0.3-b4

View file

@ -1,6 +1,7 @@
{
"homepage": "https://www.curseforge.com/minecraft/mc-mods/engineers-decor/",
"1.12.2": {
"1.0.3-b4": "[A] Lab furnace supports electrical speedup when a IE external is placed in one of the two auxiliary slots.\n[F] Fixed window rendering issue (issue #15, thanks to ILLOMIURGE).\n[M] Updated ru_ru lang file (Yaroslavik).",
"1.0.3-b3": "[A] Added sitting on treated wood stool, Zombies included.\n[A] Added steel framed window.\n[A] Added treated wood pole support head/foot and heavy duty support.\n[A] Added language Russian language support, thanks to yaroslav4167.\n[A] Added config for furnace smelting speed (percent of vanilla furnace).\n[A] Added config for furnace fuel efficiency (in percent, ref is vanilla).\n[F] Treated pole model changed to circumvent potential texture bleeding.\n[M] Treated wood table bounding box aligned with the legs.\n[M] Treated wood crafting table bounding box aligned with the legs.\n[M] Treated wood window can be vertically placed for rooflights.\n[M] Treated wood window can be vertically placed for rooflights.",
"1.0.3-b2": "[A] Added config options for selective feature opt-outs (soft opt-out).\n[A] Added config skip registration of opt-out features (hard opt-out).\n[A] Added config to disable all internal recipes (for packs).\n[A] Added JEI API adapter for soft opt-outs.\n[A] Added lab furnace recipe override config to smelt ores to nuggets that would normally be smelted into ingots. Can be changed on-the-fly.",
"1.0.3-b1": "[A] Added small laboratory furnace.\n[M] Panzer glass opacity/light level set explicitly 0.",
@ -21,6 +22,6 @@
},
"promos": {
"1.12.2-recommended": "1.0.2",
"1.12.2-latest": "1.0.3-b3"
"1.12.2-latest": "1.0.3-b4"
}
}

View file

@ -10,6 +10,11 @@ Mod sources for Minecraft version 1.12.2.
----
## Revision history
- v1.0.3-b4 [A] Lab furnace supports electrical speedup when a IE external
is placed in one of the two auxiliary slots.
[F] Fixed window rendering issue (issue #15, thanks to ILLOMIURGE).
[M] Updated ru_ru lang file (Yaroslavik).
- v1.0.3-b3 [A] Added sitting on treated wood stool, Zombies included.
[A] Added steel framed window.
[A] Added treated wood pole support head/foot and heavy duty support.

View file

@ -8,38 +8,40 @@
*/
package wile.engineersdecor;
import wile.engineersdecor.detail.ModConfig;
import wile.engineersdecor.detail.ExtItems;
import wile.engineersdecor.detail.Networking;
import wile.engineersdecor.detail.RecipeCondModSpecific;
import wile.engineersdecor.blocks.*;
import net.minecraft.world.World;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.client.multiplayer.WorldClient;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.block.Block;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Item;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.entity.living.LivingEvent;
import net.minecraftforge.fml.common.network.IGuiHandler;
import net.minecraftforge.fml.common.network.NetworkRegistry;
import net.minecraftforge.fml.common.registry.EntityRegistry;
import wile.engineersdecor.blocks.*;
import wile.engineersdecor.detail.ModConfig;
import net.minecraftforge.client.event.ModelRegistryEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.SidedProxy;
import net.minecraftforge.fml.relauncher.SideOnly;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.item.ItemStack;
import net.minecraft.block.Block;
import net.minecraft.item.Item;
import net.minecraftforge.event.entity.living.LivingEvent;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.client.event.ModelRegistryEvent;
import net.minecraftforge.fml.relauncher.SideOnly;
import org.apache.logging.log4j.Logger;
import wile.engineersdecor.detail.RecipeCondModSpecific;
import javax.annotation.Nonnull;
@Mod(
modid = ModEngineersDecor.MODID,
name = ModEngineersDecor.MODNAME,
@ -63,6 +65,10 @@ public class ModEngineersDecor
@Mod.Instance
public static ModEngineersDecor instance;
//--------------------------------------------------------------------------------------------------------------------
// Side handling
//--------------------------------------------------------------------------------------------------------------------
@SidedProxy(clientSide = "wile.engineersdecor.detail.ClientProxy", serverSide = "wile.engineersdecor.detail.ServerProxy")
public static IProxy proxy;
@ -71,8 +77,13 @@ public class ModEngineersDecor
default void preInit(final FMLPreInitializationEvent e) {}
default void init(final FMLInitializationEvent e) {}
default void postInit(final FMLPostInitializationEvent e) {}
default World getWorlClientSide() { return null; }
}
//--------------------------------------------------------------------------------------------------------------------
// Init
//--------------------------------------------------------------------------------------------------------------------
@Mod.EventHandler
public void preInit(final FMLPreInitializationEvent event)
{
@ -85,6 +96,7 @@ public class ModEngineersDecor
}
proxy.preInit(event);
MinecraftForge.EVENT_BUS.register(new PlayerEventHandler());
Networking.init();
}
@Mod.EventHandler
@ -102,6 +114,7 @@ public class ModEngineersDecor
proxy.postInit(event);
if(RecipeCondModSpecific.num_skipped > 0) logger.info("Excluded " + RecipeCondModSpecific.num_skipped + " recipes due to config opt-out.");
if(ModConfig.zmisc.with_experimental) logger.info("Included experimental features due to mod config.");
ExtItems.onPostInit();
}
@Mod.EventBusSubscriber
@ -128,6 +141,10 @@ public class ModEngineersDecor
{ return new ItemStack(ModBlocks.TREATED_WOOD_LADDER); }
});
//--------------------------------------------------------------------------------------------------------------------
// Player interaction/notification
//--------------------------------------------------------------------------------------------------------------------
public static final class GuiHandler implements IGuiHandler
{
public static final int GUIID_CRAFTING_TABLE = 213101;

View file

@ -9,40 +9,54 @@
*/
package wile.engineersdecor.blocks;
import net.minecraft.client.gui.GuiButtonImage;
import wile.engineersdecor.ModEngineersDecor;
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.world.World;
import net.minecraft.world.Explosion;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.*;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.init.Items;
import net.minecraft.nbt.NBTTagCompound;
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.*;
import net.minecraft.util.math.MathHelper;
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.World;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.gui.GuiButton;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import com.google.common.collect.ImmutableList;
import wile.engineersdecor.detail.Networking;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class BlockDecorCraftingTable extends BlockDecorDirected
{
public static boolean with_assist = true;
public static final void on_config(boolean without_crafting_assist)
{
with_assist = !without_crafting_assist;
CraftingHistory.max_history_size(32);
}
public BlockDecorCraftingTable(@Nonnull String registryName, long config, @Nullable Material material, float hardness, float resistance, @Nullable SoundType sound, @Nonnull AxisAlignedBB unrotatedAABB)
{
@ -137,6 +151,142 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
public static Object getClientGuiElement(final EntityPlayer player, final World world, final BlockPos pos, final TileEntity te)
{ return (te instanceof BTileEntity) ? (new BGui(player.inventory, world, pos, (BTileEntity)te)) : null; }
//--------------------------------------------------------------------------------------------------------------------
// Crafting history
//--------------------------------------------------------------------------------------------------------------------
private static class CraftingHistory
{
public static final List<ItemStack> NOTHING = new ArrayList<ItemStack>();
private List<String> history_ = new ArrayList<String>();
private int current_ = -1;
private static int max_history_size_ = 5;
public CraftingHistory()
{}
public static int max_history_size()
{ return max_history_size_; }
public static int max_history_size(int newsize)
{ return max_history_size_ = MathHelper.clamp(newsize, 0, 32); }
public void read(final NBTTagCompound nbt)
{
try {
clear();
final NBTTagCompound subsect = nbt.getCompoundTag("history");
if(subsect.isEmpty()) return;
{
String s = subsect.getString("elements");
if((s!=null) && (s.length() > 0)) {
String[] ls = s.split("[|]");
for(String e:ls) history_.add(e.toLowerCase().trim());
}
}
current_ = (!subsect.hasKey("current")) ? (-1) : MathHelper.clamp(subsect.getInteger("current"), -1, history_.size()-1);
} catch(Throwable ex) {
ModEngineersDecor.logger.error("Exception reading crafting table history NBT, resetting, exception is:" + ex.getMessage());
clear();
}
}
public void write(final NBTTagCompound nbt)
{
final NBTTagCompound subsect = new NBTTagCompound();
subsect.setInteger("current", current_);
subsect.setString("elements", String.join("|", history_));
nbt.setTag("history", subsect);
}
public void clear()
{ current_ = -1; history_.clear(); }
public void reset_curent()
{ current_ = -1; }
public void add(final List<ItemStack> grid_stacks)
{
if(!with_assist) { clear(); return; }
String s = stacks2str(grid_stacks);
if(s.isEmpty()) return;
history_.removeIf(e->e.equals(s));
history_.add(s);
while(history_.size() > max_history_size()) history_.remove(0);
if(current_ >= history_.size()) current_ = -1;
}
public String stacks2str(final List<ItemStack> grid_stacks)
{
if((grid_stacks==null) || (grid_stacks.size() != 10)) return "";
if(grid_stacks.get(0).isEmpty()) return "";
final ArrayList<String> items = new ArrayList<String>();
for(ItemStack st:grid_stacks) {
int meta = st.getMetadata();
items.add( (st.isEmpty()) ? ("") : ((st.getItem().getRegistryName().toString().trim()) + ((meta==0)?(""):("/"+meta)) ));
}
return String.join(";", items);
}
public List<ItemStack> str2stacks(final String entry)
{
try {
if((entry == null) || (entry.isEmpty())) return NOTHING;
ArrayList<String> item_regnames = new ArrayList<String>(Arrays.asList(entry.split("[;]")));
if((item_regnames == null) || (item_regnames.size() > 10)) return NOTHING;
while(item_regnames.size() < 10) item_regnames.add("");
List<ItemStack> stacks = new ArrayList<ItemStack>();
for(String regname : item_regnames) {
ItemStack stack = ItemStack.EMPTY;
if(!regname.isEmpty()) {
int meta = 0;
if(regname.indexOf('/') >= 0) {
String[] itemdetails = regname.split("[/]");
if(itemdetails.length>0) regname = itemdetails[0];
try { if(itemdetails.length>1) meta = Integer.parseInt(itemdetails[1]); } catch(Throwable e){meta=0;} // ignore exception here
}
final Item item = Item.REGISTRY.getObject(new ResourceLocation(regname));
stack = ((item == null) || (item == Items.AIR)) ? ItemStack.EMPTY : (new ItemStack(item, 1, meta));
}
stacks.add(stack);
}
if((stacks.size() != 10) || (stacks.get(0).isEmpty())) return NOTHING; // invalid size or no result
return stacks;
} catch(Throwable ex) {
ModEngineersDecor.logger.error("History stack building failed: " + ex.getMessage());
return NOTHING;
}
}
public List<ItemStack> current()
{
if((current_ < 0) || (current_ >= history_.size())) { current_ = -1; return NOTHING; }
return str2stacks(history_.get(current_));
}
public void next()
{
if(history_.isEmpty()) { current_ = -1; return; }
current_ = ((++current_) >= history_.size()) ? (-1) : (current_);
}
public void prev()
{
if(history_.isEmpty()) { current_ = -1; return; }
current_ = ((--current_) < -1) ? (history_.size()-1) : (current_);
}
public String toString()
{
StringBuilder s = new StringBuilder("{ current:" + current_ + ", elements:[ ");
for(int i=0; i<history_.size(); ++i) s.append("{i:").append(i).append(", e:[").append(history_.get(i)).append("]} ");
s.append("]}");
return s.toString();
}
}
//--------------------------------------------------------------------------------------------------------------------
// GUI
//--------------------------------------------------------------------------------------------------------------------
@ -144,17 +294,40 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
@SideOnly(Side.CLIENT)
private static class BGui extends GuiContainer
{
public BGui(InventoryPlayer playerInventory, World world, BlockPos pos, BTileEntity te)
{ super(new BContainer(playerInventory, world, pos, te)); }
protected static final int BUTTON_NEXT = 0;
protected static final int BUTTON_PREV = 1;
protected static final int BUTTON_FROM_STORAGE = 2;
protected static final int BUTTON_TO_STORAGE = 3;
protected static final int BUTTON_FROM_PLAYER = 4;
protected static final int BUTTON_TO_PLAYER = 5;
protected static final ResourceLocation BACKGROUND = new ResourceLocation(ModEngineersDecor.MODID, "textures/gui/treated_wood_crafting_table.png");
protected final BTileEntity te;
protected final ArrayList<GuiButton> buttons = new ArrayList<GuiButton>();
public BGui(InventoryPlayer playerInventory, World world, BlockPos pos, BTileEntity te)
{ super(new BContainer(playerInventory, world, pos, te)); this.te = te; }
@Override
@SuppressWarnings("unused")
public void initGui()
{ super.initGui(); }
{
super.initGui();
final int x0=((width - xSize)/2), y0=((height - ySize)/2);
buttons.clear();
if(with_assist) {
buttons.add(addButton(new GuiButtonImage(BUTTON_NEXT, x0+156,y0+44, 12,12, 194,44, 12, BACKGROUND)));
buttons.add(addButton(new GuiButtonImage(BUTTON_PREV, x0+156,y0+30, 12,12, 180,30, 12, BACKGROUND)));
// 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)));
}
}
@Override
public void drawScreen(int mouseX, int mouseY, float partialTicks)
{
this.drawDefaultBackground();
drawDefaultBackground();
super.drawScreen(mouseX, mouseY, partialTicks);
renderHoveredToolTip(mouseX, mouseY);
}
@ -162,9 +335,94 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
@Override
protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY)
{
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
this.mc.getTextureManager().bindTexture(new ResourceLocation(ModEngineersDecor.MODID, "textures/gui/treated_wood_crafting_table.png"));
drawTexturedModalRect(((this.width - this.xSize)/2), ((this.height - this.ySize)/2), 0, 0, this.xSize, this.ySize);
GlStateManager.color(1f, 1f, 1f, 1f);
mc.getTextureManager().bindTexture(BACKGROUND);
final int x0=((width - xSize)/2), y0=((height - ySize)/2);
drawTexturedModalRect(x0, y0, 0, 0, xSize, ySize);
if(with_assist) {
List<ItemStack> crafting_template = te.history.current();
if((crafting_template == null) || (crafting_template.isEmpty())) return;
if(inventorySlots.getSlot(0).getHasStack()) return;
{
int i = 0;
for(Tuple<Integer, Integer> e : ((BContainer) inventorySlots).CRAFTING_SLOT_POSITIONS) {
if((inventorySlots.getSlot(i).getHasStack())) {
if(!inventorySlots.getSlot(i).getStack().getItem().equals(crafting_template.get(i).getItem())) {
return; // user has placed another recipe
}
}
++i;
}
}
{
int i = 0;
for(Tuple<Integer, Integer> e : ((BContainer) inventorySlots).CRAFTING_SLOT_POSITIONS) {
final ItemStack stack = crafting_template.get(i);
if(!stack.isEmpty()) drawTemplateItemAt(stack, x0, y0, e.getFirst(), e.getSecond());
++i;
}
}
}
}
protected void drawTemplateItemAt(ItemStack stack, int x0, int y0, int x, int y)
{
RenderHelper.disableStandardItemLighting();
RenderHelper.enableGUIStandardItemLighting();
float zl = itemRender.zLevel;
itemRender.zLevel = -50;
itemRender.renderItemIntoGUI(stack, x0+x, y0+y);
itemRender.zLevel = zl;
zLevel = 100;
GlStateManager.color(0.7f, 0.7f, 0.7f, 0.8f);
mc.getTextureManager().bindTexture(BACKGROUND);
drawTexturedModalRect(x0+x, y0+y, x, y, 16, 16);
RenderHelper.enableStandardItemLighting();
}
@Override
protected void actionPerformed(GuiButton button)
{
switch(button.id) {
case BUTTON_NEXT:
case BUTTON_PREV:
case BUTTON_FROM_STORAGE:
case BUTTON_TO_STORAGE:
case BUTTON_FROM_PLAYER:
case BUTTON_TO_PLAYER: {
NBTTagCompound nbt = new NBTTagCompound();
nbt.setInteger("button", button.id);
Networking.PacketTileNotify.sendToServer(te, nbt);
break;
}
}
}
}
//--------------------------------------------------------------------------------------------------------------------
// Crafting slot of container
//--------------------------------------------------------------------------------------------------------------------
public static class BSlotCrafting extends SlotCrafting
{
private final BTileEntity te;
private final EntityPlayer player;
public BSlotCrafting(BTileEntity te, EntityPlayer player, InventoryCrafting craftingInventory, IInventory inventoryIn, int slotIndex, int xPosition, int yPosition)
{ super(player, craftingInventory, inventoryIn, slotIndex, xPosition, yPosition); this.te = te; this.player=player; }
@Override
protected void onCrafting(ItemStack stack)
{
if((with_assist) && ((player.world!=null) && (!(player.world.isRemote))) && (!stack.isEmpty())) {
final ArrayList<ItemStack> grid = new ArrayList<ItemStack>();
grid.add(stack);
for(int i = 0; i < 9; ++i) grid.add(te.stacks.get(i));
te.history.add(grid);
te.history.reset_curent();
te.syncHistory(player);
}
super.onCrafting(stack);
}
}
@ -180,36 +438,42 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
private final BTileEntity te;
public BInventoryCrafting craftMatrix;
public InventoryCraftResult craftResult = new InventoryCraftResult();
public final ImmutableList<Tuple<Integer,Integer>> CRAFTING_SLOT_POSITIONS;
public BContainer(InventoryPlayer playerInventory, World world, BlockPos pos, BTileEntity te)
{
ArrayList<Tuple<Integer,Integer>> slotpositions = new ArrayList<Tuple<Integer,Integer>>();
this.player = playerInventory.player;
this.world = world;
this.pos = pos;
this.te = te;
this.craftMatrix = new BInventoryCrafting(this, te);
this.craftMatrix.openInventory(player);
this.addSlotToContainer(new SlotCrafting(playerInventory.player, this.craftMatrix, this.craftResult, 0, 124+14, 35));
craftMatrix = new BInventoryCrafting(this, te);
craftMatrix.openInventory(player);
addSlotToContainer(new BSlotCrafting(te, playerInventory.player, craftMatrix, craftResult, 0, 134, 35));
slotpositions.add(new Tuple<>(134, 35));
for(int y=0; y<3; ++y) {
for(int x=0; x<3; ++x) {
addSlotToContainer(new Slot(this.craftMatrix, x+y*3, 28+30+x*18, 17+y*18)); // block slots 0..8
int xpos = 60+x*18;
int ypos = 17+y*18;
addSlotToContainer(new Slot(craftMatrix, x+y*3, xpos, ypos)); // block slots 0..8
slotpositions.add(new Tuple<>(xpos, ypos));
}
}
CRAFTING_SLOT_POSITIONS = ImmutableList.copyOf(slotpositions);
for(int y=0; y<3; ++y) {
for (int x=0; x<9; ++x) {
this.addSlotToContainer(new Slot(playerInventory, x+y*9+9, 8+x*18, 86+y*18)); // player slots: 9..35
addSlotToContainer(new Slot(playerInventory, x+y*9+9, 8+x*18, 86+y*18)); // player slots: 9..35
}
}
for (int x=0; x<9; ++x) {
this.addSlotToContainer(new Slot(playerInventory, x, 8+x*18, 144)); // player slots: 0..8
for(int x=0; x<9; ++x) {
addSlotToContainer(new Slot(playerInventory, x, 8+x*18, 144)); // player slots: 0..8
}
for(int y=0; y<4; ++y) {
for (int x=0; x<2; ++x) {
this.addSlotToContainer(new Slot(this.craftMatrix, x+y*2+9, 8+x*18, 9+y*18)); // block slots 9..17
addSlotToContainer(new Slot(craftMatrix, x+y*2+9, 8+x*18, 9+y*18)); // block slots 9..17
}
}
this.onCraftMatrixChanged(this.craftMatrix);
onCraftMatrixChanged(craftMatrix);
}
@Override
@ -220,7 +484,7 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
public void onCraftMatrixChanged(IInventory inv)
{
try {
slotChangedCraftingGrid(this.world, this.player, this.craftMatrix, this.craftResult);
slotChangedCraftingGrid(world, player, craftMatrix, craftResult);
} catch(Throwable exc) {
ModEngineersDecor.logger.error("Recipe failed:", exc);
}
@ -243,12 +507,12 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
@Override
public boolean canMergeSlot(ItemStack stack, Slot slot)
{ return (slot.inventory != this.craftResult) && (super.canMergeSlot(stack, slot)); }
{ return (slot.inventory != craftResult) && (super.canMergeSlot(stack, slot)); }
@Override
public ItemStack transferStackInSlot(EntityPlayer playerIn, int index)
{
Slot slot = this.inventorySlots.get(index);
Slot slot = inventorySlots.get(index);
if((slot == null) || (!slot.getHasStack())) return ItemStack.EMPTY;
ItemStack slotstack = slot.getStack();
ItemStack stack = slotstack.copy();
@ -333,12 +597,13 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
//--------------------------------------------------------------------------------------------------------------------
// Tile entity
//--------------------------------------------------------------------------------------------------------------------
public static class BTileEntity extends TileEntity implements IInventory
public static class BTileEntity extends TileEntity implements IInventory, Networking.IPacketReceiver
{
public static final int NUM_OF_CRAFTING_SLOTS = 9;
public static final int NUM_OF_STORAGE_SLOTS = 9;
public static final int NUM_OF_STORAGE_SLOTS = 8;
public static final int NUM_OF_SLOTS = NUM_OF_CRAFTING_SLOTS+NUM_OF_STORAGE_SLOTS;
protected NonNullList<ItemStack> stacks;
protected final CraftingHistory history = new CraftingHistory();
public BTileEntity()
{ stacks = NonNullList.<ItemStack>withSize(NUM_OF_SLOTS, ItemStack.EMPTY); }
@ -349,12 +614,63 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
public void readnbt(NBTTagCompound compound)
{
reset();
ItemStackHelper.loadAllItems(compound, this.stacks);
while(this.stacks.size() < NUM_OF_SLOTS) this.stacks.add(ItemStack.EMPTY);
ItemStackHelper.loadAllItems(compound, stacks);
while(stacks.size() < NUM_OF_SLOTS) stacks.add(ItemStack.EMPTY);
history.read(compound);
}
private void writenbt(NBTTagCompound compound)
{ ItemStackHelper.saveAllItems(compound, this.stacks); }
{
ItemStackHelper.saveAllItems(compound, stacks);
history.write(compound);
}
// Networking.IPacketReceiver --------------------------------------------------------------
@Override
public void onClientPacketReceived(EntityPlayer player, NBTTagCompound nbt)
{
if(with_assist && nbt.hasKey("button")) {
switch(nbt.getInteger("button")) {
case BGui.BUTTON_NEXT:
history.next();
syncHistory(player);
break;
case BGui.BUTTON_PREV:
history.prev();
syncHistory(player);
break;
case BGui.BUTTON_FROM_STORAGE:
//System.out.println("BUTTON_FROM_STORAGE");
break;
case BGui.BUTTON_TO_STORAGE:
//System.out.println("BUTTON_TO_STORAGE");
break;
case BGui.BUTTON_FROM_PLAYER:
//System.out.println("BUTTON_FROM_PLAYER");
break;
case BGui.BUTTON_TO_PLAYER:
//System.out.println("BUTTON_TO_PLAYER");
break;
}
}
}
@Override
public void onServerPacketReceived(NBTTagCompound nbt)
{
if(nbt.hasKey("historydata")) history.read(nbt.getCompoundTag("historydata"));
}
private void syncHistory(EntityPlayer player)
{
if(!with_assist) return;
NBTTagCompound history_nbt = new NBTTagCompound();
history.write(history_nbt);
NBTTagCompound rnbt = new NBTTagCompound();
rnbt.setTag("historydata", history_nbt);
Networking.PacketTileNotify.sendToPlayer(player, this, rnbt);
}
// TileEntity ------------------------------------------------------------------------------
@ -363,12 +679,16 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
{ return (os.getBlock() != ns.getBlock()) || (!(ns.getBlock() instanceof BlockDecorCraftingTable)); }
@Override
public void readFromNBT(NBTTagCompound compound)
{ super.readFromNBT(compound); readnbt(compound); }
public void readFromNBT(NBTTagCompound nbt)
{ super.readFromNBT(nbt); readnbt(nbt); }
@Override
public NBTTagCompound writeToNBT(NBTTagCompound compound)
{ super.writeToNBT(compound); writenbt(compound); return compound; }
public NBTTagCompound writeToNBT(NBTTagCompound nbt)
{ super.writeToNBT(nbt); writenbt(nbt); return nbt; }
@Override
public NBTTagCompound getUpdateTag()
{ NBTTagCompound nbt = new NBTTagCompound(); super.writeToNBT(nbt); writenbt(nbt); return nbt; }
// IWorldNamable ---------------------------------------------------------------------------

View file

@ -11,6 +11,8 @@ package wile.engineersdecor.blocks;
import com.google.common.collect.Maps;
import net.minecraft.entity.item.EntityXPOrb;
import net.minecraft.init.SoundEvents;
import net.minecraftforge.energy.CapabilityEnergy;
import net.minecraftforge.energy.IEnergyStorage;
import wile.engineersdecor.ModEngineersDecor;
import net.minecraft.stats.StatList;
import net.minecraft.block.properties.PropertyBool;
@ -46,12 +48,12 @@ import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.wrapper.SidedInvWrapper;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import wile.engineersdecor.detail.ExtItems;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Map;
import java.util.Random;
public class BlockDecorFurnace extends BlockDecorDirected
{
public static final PropertyBool LIT = PropertyBool.create("lit");
@ -428,11 +430,12 @@ public class BlockDecorFurnace extends BlockDecorDirected
// Tile entity
//--------------------------------------------------------------------------------------------------------------------
public static class BTileEntity extends TileEntity implements ITickable, ISidedInventory
public static class BTileEntity extends TileEntity implements ITickable, ISidedInventory, IEnergyStorage
{
public static final int TICK_INTERVAL = 4;
public static final int FIFO_INTERVAL = 20;
public static final int MAX_BURNTIME = 0x7fff;
public static final int DEFAULT_BOOST_ENERGY = 32;
public static final int VANILLA_FURNACE_SPEED_INTERVAL = 200;
public static final int DEFAULT_SPEED_INTERVAL = 150;
public static final int NUM_OF_SLOTS = 11;
@ -454,9 +457,9 @@ public class BlockDecorFurnace extends BlockDecorDirected
private final IItemHandler sided_itemhandler_top_ = new SidedInvWrapper(this, EnumFacing.UP);
private final IItemHandler sided_itemhandler_down_ = new SidedInvWrapper(this, EnumFacing.DOWN);
private final IItemHandler sided_itemhandler_sides_ = new SidedInvWrapper(this, EnumFacing.WEST);
private static int proc_speed_interval_ = DEFAULT_SPEED_INTERVAL;
private static double proc_fuel_efficiency_ = 1.0;
private static int proc_speed_interval_ = DEFAULT_SPEED_INTERVAL;
private static int boost_energy_consumption = DEFAULT_BOOST_ENERGY * TICK_INTERVAL;
private int tick_timer_;
private int fifo_timer_;
@ -464,13 +467,16 @@ public class BlockDecorFurnace extends BlockDecorDirected
private int fuel_burntime_;
private int proc_time_elapsed_;
private int proc_time_needed_;
private int boost_energy_; // small, not saved in nbt.
private boolean heater_inserted_ = false;
private NonNullList<ItemStack> stacks_;
public static void on_config(int speed_percent, int fuel_efficiency_percent)
public static void on_config(int speed_percent, int fuel_efficiency_percent, int boost_energy_per_tick)
{
double ratio = (100.0 / MathHelper.clamp(speed_percent, 10, 500)) ;
proc_speed_interval_ = MathHelper.clamp((int)(ratio * VANILLA_FURNACE_SPEED_INTERVAL), 20, 400);
proc_fuel_efficiency_ = ((double) MathHelper.clamp(fuel_efficiency_percent, 10, 500)) / 100;
boost_energy_consumption = TICK_INTERVAL * MathHelper.clamp(boost_energy_per_tick, 16, 512);
ModEngineersDecor.logger.info("Config lab furnace interval:" + proc_speed_interval_ + ", efficiency:" + proc_fuel_efficiency_);
}
@ -663,6 +669,9 @@ public class BlockDecorFurnace extends BlockDecorDirected
if(transferItems(FIFO_FUEL_1_SLOT_NO, FIFO_FUEL_0_SLOT_NO, 1)) dirty = true;
if(transferItems(FIFO_INPUT_0_SLOT_NO, SMELTING_INPUT_SLOT_NO, 1)) dirty = true;
if(transferItems(FIFO_INPUT_1_SLOT_NO, FIFO_INPUT_0_SLOT_NO, 1)) dirty = true;
heater_inserted_ = (ExtItems.IE_EXTERNAL_HEATER==null) // without IE always allow electrical boost
|| (stacks_.get(AUX_0_SLOT_NO).getItem()==ExtItems.IE_EXTERNAL_HEATER)
|| (stacks_.get(AUX_1_SLOT_NO).getItem()==ExtItems.IE_EXTERNAL_HEATER);
}
ItemStack fuel = stacks_.get(SMELTING_FUEL_SLOT_NO);
if(isBurning() || (!fuel.isEmpty()) && (!(stacks_.get(SMELTING_INPUT_SLOT_NO)).isEmpty())) {
@ -680,6 +689,7 @@ public class BlockDecorFurnace extends BlockDecorDirected
}
if(isBurning() && canSmelt()) {
proc_time_elapsed_ += TICK_INTERVAL;
if(heater_inserted_ && (boost_energy_ >= boost_energy_consumption)) { boost_energy_ = 0; proc_time_elapsed_ += TICK_INTERVAL; }
if(proc_time_elapsed_ >= proc_time_needed_) {
proc_time_elapsed_ = 0;
proc_time_needed_ = getCookTime(stacks_.get(SMELTING_INPUT_SLOT_NO));
@ -775,6 +785,8 @@ public class BlockDecorFurnace extends BlockDecorDirected
public static boolean isItemFuel(ItemStack stack)
{ return TileEntityFurnace.isItemFuel(stack); }
// ISidedInventory ----------------------------------------------------------------------------
@Override
public int[] getSlotsForFace(EnumFacing side)
{
@ -794,17 +806,51 @@ public class BlockDecorFurnace extends BlockDecorDirected
return (stack.getItem()==Items.BUCKET);
}
// IEnergyStorage ----------------------------------------------------------------------------
public boolean canExtract()
{ return false; }
public boolean canReceive()
{ return true; }
public int getMaxEnergyStored()
{ return boost_energy_consumption; }
public int getEnergyStored()
{ return boost_energy_; }
public int extractEnergy(int maxExtract, boolean simulate)
{ return 0; }
public int receiveEnergy(int maxReceive, boolean simulate)
{ // only speedup support, no buffering, not in nbt -> no markdirty
if((boost_energy_ >= boost_energy_consumption) || (maxReceive < boost_energy_consumption)) return 0;
if(!simulate) boost_energy_ = boost_energy_consumption;
return boost_energy_consumption;
}
// Capability export ----------------------------------------------------------------------------
@Override
public boolean hasCapability(Capability<?> cap, EnumFacing facing)
{ return ((cap==CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) || (cap==CapabilityEnergy.ENERGY)) || super.hasCapability(cap, facing); }
@Override
@SuppressWarnings("unchecked")
@Nullable
public <T> T getCapability(Capability<T> capability, @Nullable EnumFacing facing)
{
if((facing == null) || (capability != CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)) return super.getCapability(capability, facing);
if(facing == EnumFacing.DOWN) return (T) sided_itemhandler_down_;
if(facing == EnumFacing.UP) return (T) sided_itemhandler_top_;
return (T) sided_itemhandler_sides_;
if((facing != null) && (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)) {
if(facing == EnumFacing.DOWN) return (T) sided_itemhandler_down_;
if(facing == EnumFacing.UP) return (T) sided_itemhandler_top_;
return (T) sided_itemhandler_sides_;
} else if(capability == CapabilityEnergy.ENERGY) {
return (T)this;
} else {
return super.getCapability(capability, facing);
}
}
}
//--------------------------------------------------------------------------------------------------------------------

View file

@ -53,7 +53,4 @@ public class BlockDecorWindow extends BlockDecorDirected
public boolean doesSideBlockRendering(IBlockState state, IBlockAccess world, BlockPos pos, EnumFacing face)
{ return false; }
@Override
public boolean canRenderInLayer(IBlockState state, BlockRenderLayer layer)
{ return (layer==BlockRenderLayer.TRANSLUCENT) || (layer==BlockRenderLayer.CUTOUT); }
}

View file

@ -8,20 +8,19 @@
*/
package wile.engineersdecor.detail;
import net.minecraft.world.World;
import wile.engineersdecor.ModEngineersDecor;
import net.minecraft.client.Minecraft;
import net.minecraftforge.client.model.obj.OBJLoader;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
public class ClientProxy implements ModEngineersDecor.IProxy
{
@Override
public void preInit(FMLPreInitializationEvent e)
{ OBJLoader.INSTANCE.addDomain(ModEngineersDecor.MODID); }
public void init(FMLInitializationEvent e)
{}
public void postInit(FMLPostInitializationEvent e)
{}
@Override
public World getWorlClientSide()
{ return Minecraft.getMinecraft().world; }
}

View file

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

View file

@ -8,15 +8,15 @@
*/
package wile.engineersdecor.detail;
import net.minecraft.util.EnumFacing;
import wile.engineersdecor.ModEngineersDecor;
import net.minecraft.item.ItemStack;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.world.World;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.text.TextComponentTranslation;
import net.minecraft.util.text.TextFormatting;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import org.lwjgl.input.Keyboard;

View file

@ -9,15 +9,15 @@
*/
package wile.engineersdecor.detail;
import net.minecraft.block.Block;
import wile.engineersdecor.ModEngineersDecor;
import wile.engineersdecor.blocks.*;
import net.minecraftforge.common.config.Config;
import net.minecraftforge.common.config.ConfigManager;
import net.minecraft.block.Block;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.client.event.ConfigChangedEvent;
import wile.engineersdecor.blocks.*;
import javax.annotation.Nullable;
@ -165,6 +165,17 @@ public class ModConfig
@Config.RangeInt(min=50, max=250)
public int furnace_fuel_efficiency_percent = 100;
@Config.Comment({
"Defines the energy consumption (per tick) for speeding up the smelting process. " +
"If IE is installed, an external heater has to be inserted into an auxiliary slot " +
"of the lab furnace. The power source needs to be able to provide at least 4 times " +
"this consumption (fixed threshold value). The value can be changed on-the-fly for tuning. " +
"The default value corresponds to the IE heater consumption."
})
@Config.Name("Furnace: Boost energy")
@Config.RangeInt(min=16, max=256)
public int furnace_boost_energy_consumption = 24;
@Config.Comment({
"Defines, in percent, how high the probability is that a mob sits on a chair " +
"when colliding with it. Can be changed on-the-fly for tuning."
@ -234,11 +245,12 @@ public class ModConfig
public static final void apply()
{
BlockDecorFurnace.BTileEntity.on_config(tweaks.furnace_smelting_speed_percent, tweaks.furnace_fuel_efficiency_percent);
BlockDecorFurnace.BTileEntity.on_config(tweaks.furnace_smelting_speed_percent, tweaks.furnace_fuel_efficiency_percent, tweaks.furnace_boost_energy_consumption);
ModRecipes.furnaceRecipeOverrideReset();
if(tweaks.furnace_smelts_nuggets) ModRecipes.furnaceRecipeOverrideSmeltsOresToNuggets();
BlockDecorChair.on_config(optout.without_chair_sitting, optout.without_mob_chair_sitting, tweaks.chair_mob_sitting_probability_percent, tweaks.chair_mob_standup_probability_percent);
BlockDecorLadder.on_config(optout.without_ladder_speed_boost);
BlockDecorCraftingTable.on_config(!zmisc.with_experimental);
}
}

View file

@ -0,0 +1,119 @@
/*
* @file Networking.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2019 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)
*
* Main client/server message handling.
*/
package wile.engineersdecor.detail;
import wile.engineersdecor.ModEngineersDecor;
import net.minecraft.client.Minecraft;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.util.math.BlockPos;
import net.minecraftforge.fml.common.network.ByteBufUtils;
import net.minecraftforge.fml.common.network.NetworkRegistry;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
import net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper;
import net.minecraftforge.fml.relauncher.Side;
import io.netty.buffer.ByteBuf;
public class Networking
{
private static SimpleNetworkWrapper snw = null;
public static void init()
{
if(snw != null) return;
int discr = -1;
snw = NetworkRegistry.INSTANCE.newSimpleChannel(ModEngineersDecor.MODID);
snw.registerMessage(PacketTileNotify.ServerHandler.class, PacketTileNotify.class, ++discr, Side.SERVER);
snw.registerMessage(PacketTileNotify.ClientHandler.class, PacketTileNotify.class, ++discr, Side.CLIENT);
}
public interface IPacketReceiver
{
default void onServerPacketReceived(NBTTagCompound nbt) {}
default void onClientPacketReceived(EntityPlayer player, NBTTagCompound nbt) {}
}
//--------------------------------------------------------------------------------------------------------------------
// Tile entity notifications
//--------------------------------------------------------------------------------------------------------------------
public static class PacketTileNotify implements IMessage
{
NBTTagCompound nbt = null;
BlockPos pos = BlockPos.ORIGIN;
public static void sendToServer(TileEntity te, NBTTagCompound nbt)
{ if((te != null) && (nbt!=null)) snw.sendToServer(new PacketTileNotify(te, nbt)); }
public static void sendToPlayer(EntityPlayer player, TileEntity te, NBTTagCompound nbt)
{ if((player instanceof EntityPlayerMP) && (te != null) && (nbt!=null)) snw.sendTo(new PacketTileNotify(te, nbt), (EntityPlayerMP)player); }
public PacketTileNotify(TileEntity te, NBTTagCompound nbt)
{ this.nbt=nbt; pos=te.getPos(); }
public PacketTileNotify()
{}
@Override
public void fromBytes(ByteBuf buf)
{ pos=BlockPos.fromLong(buf.readLong()); nbt= ByteBufUtils.readTag(buf); }
@Override
public void toBytes(ByteBuf buf)
{ buf.writeLong(pos.toLong()); ByteBufUtils.writeTag(buf, nbt); }
public static class ServerHandler implements IMessageHandler<PacketTileNotify, IMessage>
{
@Override
public IMessage onMessage(PacketTileNotify pkt, MessageContext ctx)
{
EntityPlayer player = ctx.getServerHandler().player;
WorldServer world = ctx.getServerHandler().player.getServerWorld();
world.addScheduledTask(() -> {
try {
if(!world.isBlockLoaded(pkt.pos)) return;
TileEntity te = world.getTileEntity(pkt.pos);
if(!(te instanceof IPacketReceiver)) return;
((IPacketReceiver)te).onClientPacketReceived(player, pkt.nbt);
} catch(Throwable ex) {
ModEngineersDecor.logger.error("Failed to process TE notify packet: " + ex.getMessage());
}
});
return null;
}
}
public static class ClientHandler implements IMessageHandler<PacketTileNotify, IMessage>
{
@Override
public IMessage onMessage(PacketTileNotify pkt, MessageContext ctx)
{
Minecraft.getMinecraft().addScheduledTask(() -> {
try {
final World world = ModEngineersDecor.proxy.getWorlClientSide();
if(!(world instanceof World)) return;
TileEntity te = world.getTileEntity(pkt.pos);
if(!(te instanceof IPacketReceiver)) return;
((IPacketReceiver) te).onServerPacketReceived(pkt.nbt);
} catch(Throwable ex) {
ModEngineersDecor.logger.error("Failed to process TE notify packet: " + ex.getMessage());
}
});
return null;
}
}
}
}

View file

@ -19,7 +19,6 @@ import net.minecraftforge.common.crafting.IConditionFactory;
import net.minecraftforge.common.crafting.JsonContext;
import net.minecraftforge.registries.IForgeRegistry;
import net.minecraftforge.fml.common.registry.ForgeRegistries;
import com.google.gson.*;
import java.util.function.BooleanSupplier;

View file

@ -9,18 +9,6 @@
package wile.engineersdecor.detail;
import wile.engineersdecor.ModEngineersDecor;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
public class ServerProxy implements ModEngineersDecor.IProxy
{
public void preInit(FMLPreInitializationEvent e)
{}
public void init(FMLInitializationEvent e)
{}
public void postInit(FMLPostInitializationEvent e)
{}
}
{}

View file

@ -65,17 +65,22 @@ tile.engineersdecor.treated_wood_crafting_table.name=Treated wood crafting table
tile.engineersdecor.treated_wood_crafting_table.help=§6Robust and weather-proof. Eight storage slots. Keeps inventory.
tile.engineersdecor.iron_inset_light.name=Inset light
tile.engineersdecor.iron_inset_light.help=§6Small glowstone light source, sunk into the floor, ceiling or wall.§r\n\
Useful to light up places where electrical light installations are problematic.\
Light level like a torch.
Useful to light up places where electrical light installations are problematic.\
Light level like a torch.
tile.engineersdecor.treated_wood_window.name=Treated wood window
tile.engineersdecor.treated_wood_window.help=§6Wood framed tripple glazed window. Well insulating.§r Does not connect to adjacent blocks like glass panes.
tile.engineersdecor.treated_wood_windowsill.name=Treated wood window sill
tile.engineersdecor.treated_wood_windowsill.help=§6Simple window decoration.
tile.engineersdecor.small_lab_furnace.name=Small laboratry furnace
tile.engineersdecor.small_lab_furnace.help=§6Small metal cased lab kiln.§r Solid fuel consuming, updraught. Slightly hotter and better isolated than a cobblestone furnace, therefore more efficient. Two stack internal hopper fifos for input, output, and fuel.
tile.engineersdecor.steel_framed_window.name=Steel framed window
tile.engineersdecor.steel_framed_window.help=§6Steel framed tripple glazed window. Well insulating. §r Does not connect to adjacent blocks like glass panes.
#-----------------------------------------------------------------------------------------------------------
tile.engineersdecor.small_lab_furnace.name=Small laboratry furnace
tile.engineersdecor.small_lab_furnace.help=§6Small metal cased lab kiln.§r Solid fuel consuming, updraught. \
Slightly hotter and better isolated than a cobblestone furnace, therefore more efficient. \
Two auxiliary slots e.g. for storage. Two stack internal hopper fifos for input, output, \
and fuel. Place an external heater into a aux slot and connect power for electrical \
smelting speed boost.
#-----------------------------------------------------------------------------------------------------------
tile.engineersdecor.iron_sheet_roof.name=Iron sheet metal roof (experimental)
tile.engineersdecor.iron_sheet_roof.help=§6Well, I just can't get that model right in a way that I could like it. Gimme some time.
#-----------------------------------------------------------------------------------------------------------

View file

@ -53,9 +53,9 @@ tile.engineersdecor.treated_wood_pole.help=§6Надёжный столб с д
Может быть полезен в качестве альтернативы электро-столбам, если требуется особая специальная длина, \
или как опора для конструкций.
tile.engineersdecor.treated_wood_pole_head.name=Прямой обработанный деревянный столб верхняя часть/основание
#tile.engineersdecor.treated_wood_pole_head.help=§6Деревянная часть, подходящая как набалдашник или основание прямых столбов.
#tile.engineersdecor.treated_wood_pole_head.help=§6Wooden part fitting as foot or head of straight poles.
tile.engineersdecor.treated_wood_pole_support.name=Прямой обработанный деревянный столб
#tile.engineersdecor.treated_wood_pole_support.help=§6Усиленная деревянная опорная часть, подходящая как основание или набалдашник прямых опор.
#tile.engineersdecor.treated_wood_pole_support.help=§6Heavy duty wooden support part fitting as foot or head of straight poles.
#-----------------------------------------------------------------------------------------------------------
tile.engineersdecor.treated_wood_table.name=Стол из обработанного дерева
tile.engineersdecor.treated_wood_table.help=§6Прочный деревянный стол с четырьмя ножками .§r Для использования в помещении и на улице.
@ -71,10 +71,11 @@ tile.engineersdecor.treated_wood_window.name=Обработанное дерев
tile.engineersdecor.treated_wood_window.help=§6Деревянный каркас окна с тройным остеклением. Ну и шумоизоляция.
tile.engineersdecor.treated_wood_windowsill.name=Обработанный деревянный подоконник
tile.engineersdecor.treated_wood_windowsill.help=§6Простое оформление окон.
tile.engineersdecor.steel_framed_window.name=Окно со стальной рамой
#tile.engineersdecor.steel_framed_window.help=§6Steel framed tripple glazed window. Well insulating. §r Does not connect to adjacent blocks like glass panes.
#-----------------------------------------------------------------------------------------------------------
tile.engineersdecor.small_lab_furnace.name=Компактная лабораторная печь
tile.engineersdecor.small_lab_furnace.help=§6Лабораторная печь в металлическом корпусе.§r Подача твёрдого топлива - сверху. Немного горячее чем каменная, поэтому быстрее. Два внутренних слота для ввода, выхода и топлива.
tile.engineersdecor.steel_framed_window.name=Окно со стальной рамой
#tile.engineersdecor.steel_framed_window.help=§6Стальной стеклопакет с тройной прослойкой. Хорошо изолирует. §r Не соединяется со смежными блоками, такими как стеклянные панели.
#-----------------------------------------------------------------------------------------------------------
tile.engineersdecor.iron_sheet_roof.name=Кровля из листового металла
tile.engineersdecor.iron_sheet_roof.help=§6Ну, это кровля.

Binary file not shown.

After

Width:  |  Height:  |  Size: 560 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 578 B

After

Width:  |  Height:  |  Size: 560 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Before After
Before After